From 95979d2baeef242c725bf41984693849b88b1906 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 29 Jun 2017 12:24:47 +0400 Subject: [PATCH] Removing duplicate code in mysql_execute_command: Adding prepare_db_action(). The code in mysql_execute_command() for SQLCOM_CREATE_DB, SQLCOM_DROP_DB and SQLCOM_ALTER_DB contained around 20 lines of similar code. Moving this code into a new function prepare_db_action(). --- sql/sql_parse.cc | 128 +++++++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 76 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 312054ec37a..bab670fd8fc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3034,6 +3034,54 @@ error: /* Used by WSREP_TO_ISOLATION_BEGIN */ } +/** + Prepare for CREATE DATABASE, ALTER DATABASE, DROP DATABASE. + + @param thd - current THD + @param want_access - access needed + @param dbname - the database name + + @retval false - Ok to proceed with CREATE/ALTER/DROP + @retval true - not OK to proceed (error, or filtered) + + Note, on slave this function returns true if the database + is in the ignore filter. The caller must distinguish this case + from other cases: bad database error, no access error. + This can be done by testing thd->is_error(). +*/ +static bool prepare_db_action(THD *thd, ulong want_access, LEX_CSTRING *dbname) +{ + if (check_db_name((LEX_STRING*)dbname)) + { + my_error(ER_WRONG_DB_NAME, MYF(0), dbname->str); + return true; + } + /* + If in a slave thread : + - CREATE DATABASE DB was certainly not preceded by USE DB. + - ALTER DATABASE DB may not be preceded by USE DB. + - DROP DATABASE DB may not be preceded by USE DB. + For that reason, db_ok() in sql/slave.cc did not check the + do_db/ignore_db. And as this query involves no tables, tables_ok() + was not called. So we have to check rules again here. + */ +#ifdef HAVE_REPLICATION + if (thd->slave_thread) + { + Rpl_filter *rpl_filter; + rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter; + if (!rpl_filter->db_ok(dbname->str) || + !rpl_filter->db_ok_with_wild_table(dbname->str)) + { + my_message(ER_SLAVE_IGNORED_TABLE, + ER_THD(thd, ER_SLAVE_IGNORED_TABLE), MYF(0)); + return true; + } + } +#endif + return check_access(thd, want_access, dbname->str, NULL, NULL, 1, 0); +} + /** Execute command saved in thd and lex->sql_command. @@ -5038,33 +5086,9 @@ end_with_restore_list: break; case SQLCOM_CREATE_DB: { - if (check_db_name((LEX_STRING*) &lex->name)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str); - break; - } - /* - If in a slave thread : - CREATE DATABASE DB was certainly not preceded by USE DB. - For that reason, db_ok() in sql/slave.cc did not check the - do_db/ignore_db. And as this query involves no tables, tables_ok() - above was not called. So we have to check rules again here. - */ -#ifdef HAVE_REPLICATION - if (thd->slave_thread) - { - rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter; - if (!rpl_filter->db_ok(lex->name.str) || - !rpl_filter->db_ok_with_wild_table(lex->name.str)) - { - my_message(ER_SLAVE_IGNORED_TABLE, ER_THD(thd, ER_SLAVE_IGNORED_TABLE), MYF(0)); - break; - } - } -#endif - if (check_access(thd, lex->create_info.or_replace() ? + if (prepare_db_action(thd, lex->create_info.or_replace() ? (CREATE_ACL | DROP_ACL) : CREATE_ACL, - lex->name.str, NULL, NULL, 1, 0)) + &lex->name)) break; WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL) res= mysql_create_db(thd, lex->name.str, @@ -5073,31 +5097,7 @@ end_with_restore_list: } case SQLCOM_DROP_DB: { - if (check_db_name((LEX_STRING*) &lex->name)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str); - break; - } - /* - If in a slave thread : - DROP DATABASE DB may not be preceded by USE DB. - For that reason, maybe db_ok() in sql/slave.cc did not check the - do_db/ignore_db. And as this query involves no tables, tables_ok() - above was not called. So we have to check rules again here. - */ -#ifdef HAVE_REPLICATION - if (thd->slave_thread) - { - rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter; - if (!rpl_filter->db_ok(lex->name.str) || - !rpl_filter->db_ok_with_wild_table(lex->name.str)) - { - my_message(ER_SLAVE_IGNORED_TABLE, ER_THD(thd, ER_SLAVE_IGNORED_TABLE), MYF(0)); - break; - } - } -#endif - if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0)) + if (prepare_db_action(thd, DROP_ACL, &lex->name)) break; WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL) res= mysql_rm_db(thd, lex->name.str, lex->if_exists()); @@ -5140,31 +5140,7 @@ end_with_restore_list: case SQLCOM_ALTER_DB: { LEX_CSTRING *db= &lex->name; - if (check_db_name((LEX_STRING*) db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db->str); - break; - } - /* - If in a slave thread : - ALTER DATABASE DB may not be preceded by USE DB. - For that reason, maybe db_ok() in sql/slave.cc did not check the - do_db/ignore_db. And as this query involves no tables, tables_ok() - above was not called. So we have to check rules again here. - */ -#ifdef HAVE_REPLICATION - if (thd->slave_thread) - { - rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter; - if (!rpl_filter->db_ok(db->str) || - !rpl_filter->db_ok_with_wild_table(db->str)) - { - my_message(ER_SLAVE_IGNORED_TABLE, ER_THD(thd, ER_SLAVE_IGNORED_TABLE), MYF(0)); - break; - } - } -#endif - if (check_access(thd, ALTER_ACL, db->str, NULL, NULL, 1, 0)) + if (prepare_db_action(thd, ALTER_ACL, db)) break; WSREP_TO_ISOLATION_BEGIN(db->str, NULL, NULL) res= mysql_alter_db(thd, db->str, &lex->create_info);