From a3c980b381ead0ea13df8314258c7a8d11fe5cd1 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 24 Oct 2016 15:26:11 +0400 Subject: [PATCH] MDEV-10824 - Crash in CREATE OR REPLACE TABLE t1 AS SELECT spfunc() Code flow hit incorrect branch while closing table instances before removal. This branch expects thread to hold open table instance, whereas CREATE OR REPLACE doesn't actually hold open table instance. Before CREATE OR REPLACE TABLE it was impossible to hit this condition in LTM_PRELOCKED mode, thus the problem didn't expose itself during DROP TABLE or DROP DATABASE. Fixed by adjusting condition to take into account LTM_PRELOCKED mode, which can be set during CREATE OR REPLACE TABLE. --- mysql-test/r/create_or_replace.result | 11 +++++++++++ mysql-test/t/create_or_replace.test | 12 ++++++++++++ sql/sql_table.cc | 3 ++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/create_or_replace.result b/mysql-test/r/create_or_replace.result index 3a894e9fcb1..a43dc2eaca4 100644 --- a/mysql-test/r/create_or_replace.result +++ b/mysql-test/r/create_or_replace.result @@ -442,3 +442,14 @@ KILL QUERY con_id; ERROR 70100: Query execution was interrupted drop table t1; DROP TABLE t2; +# +# MDEV-10824 - Crash in CREATE OR REPLACE TABLE t1 AS SELECT spfunc() +# +CREATE TABLE t1(a INT); +CREATE FUNCTION f1() RETURNS VARCHAR(16383) RETURN 'test'; +CREATE OR REPLACE TABLE t1 AS SELECT f1(); +LOCK TABLE t1 WRITE; +CREATE OR REPLACE TABLE t1 AS SELECT f1(); +UNLOCK TABLES; +DROP FUNCTION f1; +DROP TABLE t1; diff --git a/mysql-test/t/create_or_replace.test b/mysql-test/t/create_or_replace.test index 7bba2b341c0..b37417f39d0 100644 --- a/mysql-test/t/create_or_replace.test +++ b/mysql-test/t/create_or_replace.test @@ -386,3 +386,15 @@ drop table t1; # Cleanup # DROP TABLE t2; + +--echo # +--echo # MDEV-10824 - Crash in CREATE OR REPLACE TABLE t1 AS SELECT spfunc() +--echo # +CREATE TABLE t1(a INT); +CREATE FUNCTION f1() RETURNS VARCHAR(16383) RETURN 'test'; +CREATE OR REPLACE TABLE t1 AS SELECT f1(); +LOCK TABLE t1 WRITE; +CREATE OR REPLACE TABLE t1 AS SELECT f1(); +UNLOCK TABLES; +DROP FUNCTION f1; +DROP TABLE t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7cf31ee4fe8..050a3383612 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2464,7 +2464,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, if (table_type && table_type != view_pseudo_hton) ha_lock_engine(thd, table_type); - if (thd->locked_tables_mode) + if (thd->locked_tables_mode == LTM_LOCK_TABLES || + thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES) { if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED)) {