From 19a702a85c69d241e360d1d5a040378928a3fdca Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 14 Oct 2017 15:59:54 +0200 Subject: [PATCH] MDEV-14056 DROP TEMPORARY TABLE IF EXISTS causes error 1290 with read_only option if it's a DROP TABLE, we cannot detect whether a table is temporary by looking in thd->temporary_tables - because the table might simply not exist at all. --- mysql-test/r/read_only.result | 3 +++ mysql-test/t/read_only.test | 5 +++++ sql/sql_parse.cc | 41 ++++++++++++++--------------------- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/read_only.result b/mysql-test/r/read_only.result index 807dc426696..2d0f9d730fd 100644 --- a/mysql-test/r/read_only.result +++ b/mysql-test/r/read_only.result @@ -47,6 +47,9 @@ delete t1 from t1,t3 where t1.a=t3.a; drop table t1; insert into t1 values(1); ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement +drop temporary table if exists t1; +Warnings: +Note 1051 Unknown table 't1' connection default; set global read_only=0; lock table t1 write; diff --git a/mysql-test/t/read_only.test b/mysql-test/t/read_only.test index a0bd7b49273..eb9bea803c2 100644 --- a/mysql-test/t/read_only.test +++ b/mysql-test/t/read_only.test @@ -114,6 +114,11 @@ drop table t1; --error ER_OPTION_PREVENTS_STATEMENT insert into t1 values(1); +# +# MDEV-14056 DROP TEMPORARY TABLE IF EXISTS causes error 1290 with read_only option +# +drop temporary table if exists t1; + # # Bug#11733 COMMITs should not happen if read-only is set # diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d003a13ae09..9f8a625325f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -811,8 +811,7 @@ out: @retval FALSE The statement isn't updating any relevant tables. */ -static my_bool deny_updates_if_read_only_option(THD *thd, - TABLE_LIST *all_tables) +static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables) { DBUG_ENTER("deny_updates_if_read_only_option"); @@ -821,11 +820,7 @@ static my_bool deny_updates_if_read_only_option(THD *thd, LEX *lex= thd->lex; - const my_bool user_is_super= - ((ulong)(thd->security_ctx->master_access & SUPER_ACL) == - (ulong)SUPER_ACL); - - if (user_is_super) + if (thd->security_ctx->master_access & SUPER_ACL) DBUG_RETURN(FALSE); if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA)) @@ -835,30 +830,26 @@ static my_bool deny_updates_if_read_only_option(THD *thd, if (lex->sql_command == SQLCOM_UPDATE_MULTI) DBUG_RETURN(FALSE); + if (lex->sql_command == SQLCOM_CREATE_DB || + lex->sql_command == SQLCOM_DROP_DB) + DBUG_RETURN(TRUE); + /* a table-to-be-created is not in the temp table list yet, so CREATE TABLE needs a special treatment */ - const bool update_real_tables= - lex->sql_command == SQLCOM_CREATE_TABLE - ? !(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) - : some_non_temp_table_to_be_updated(thd, all_tables); + if (lex->sql_command == SQLCOM_CREATE_TABLE) + DBUG_RETURN(!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)); - const bool create_or_drop_databases= - (lex->sql_command == SQLCOM_CREATE_DB) || - (lex->sql_command == SQLCOM_DROP_DB); + /* + a table-to-be-dropped might not exist (DROP TEMPORARY TABLE IF EXISTS), + cannot use the temp table list either. + */ + if (lex->sql_command == SQLCOM_DROP_TABLE && lex->drop_temporary) + DBUG_RETURN(FALSE); - if (update_real_tables || create_or_drop_databases) - { - /* - An attempt was made to modify one or more non-temporary tables. - */ - DBUG_RETURN(TRUE); - } - - - /* Assuming that only temporary tables are modified. */ - DBUG_RETURN(FALSE); + /* Now, check thd->temporary_tables list */ + DBUG_RETURN(some_non_temp_table_to_be_updated(thd, all_tables)); } /**