diff --git a/include/my_sys.h b/include/my_sys.h index 3180a8c37da..4a94c849ed9 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -908,6 +908,20 @@ static inline char *safe_strdup_root(MEM_ROOT *root, const char *str) extern char *strmake_root(MEM_ROOT *root,const char *str,size_t len); extern void *memdup_root(MEM_ROOT *root,const void *str, size_t len); extern LEX_CSTRING safe_lexcstrdup_root(MEM_ROOT *root, const LEX_CSTRING str); + +static inline LEX_STRING lex_string_strmake_root(MEM_ROOT *mem_root, + const char *str, size_t length) +{ + LEX_STRING tmp; + tmp.str= strmake_root(mem_root, str, length); + tmp.length= tmp.str ? length : 0; + return tmp; +} + +extern LEX_STRING lex_string_casedn_root(MEM_ROOT *root, + CHARSET_INFO *cs, + const char *str, size_t length); + extern my_bool my_compress(uchar *, size_t *, size_t *); extern my_bool my_uncompress(uchar *, size_t , size_t *); extern uchar *my_compress_alloc(const uchar *packet, size_t *len, diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 158dfc48935..67aabde5f9a 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -623,3 +623,16 @@ LEX_CSTRING safe_lexcstrdup_root(MEM_ROOT *root, const LEX_CSTRING str) res.length= str.length; return res; } + + +LEX_STRING lex_string_casedn_root(MEM_ROOT *root, CHARSET_INFO *cs, + const char *str, size_t length) +{ + size_t nbytes= length * cs->cset->casedn_multiply(cs); + LEX_STRING res= {NULL, 0}; + if (!(res.str= alloc_root(root, nbytes + 1))) + return res; + res.length= cs->cset->casedn(cs, str, length, res.str, nbytes); + res.str[res.length]= '\0'; + return res; +} diff --git a/sql/lex_ident.h b/sql/lex_ident.h index c3751fd8780..f39273b7da5 100644 --- a/sql/lex_ident.h +++ b/sql/lex_ident.h @@ -42,6 +42,7 @@ public: bool check_db_name() const; bool check_db_name_with_error() const; #ifndef DBUG_OFF + bool is_in_lower_case() const; bool ok_for_lower_case_names() const; #endif }; @@ -55,6 +56,11 @@ public: */ class Lex_ident_db: public Lex_ident_fs { + // {empty_c_string,0} is used by derived tables + bool is_empty() const + { + return length == 0 && str != NULL; + } public: Lex_ident_db() :Lex_ident_fs(NULL, 0) @@ -62,7 +68,7 @@ public: Lex_ident_db(const char *str, size_t length) :Lex_ident_fs(str, length) { - DBUG_SLOW_ASSERT(!check_db_name()); + DBUG_SLOW_ASSERT(is_empty() || !check_db_name()); } }; diff --git a/sql/sp.cc b/sql/sp.cc index daad463fae2..dffcae6ae67 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -2620,9 +2620,9 @@ bool Sp_handler:: pkgstr, name->m_name, type())) { DBUG_ASSERT(ret == SP_OK); - pkgname->copy(thd->mem_root, caller->m_db, pkgstr); *pkg_routine_handler= package_routine_handler(); - if (name->make_package_routine_name(thd->mem_root, pkgstr, name->m_name)) + if (pkgname->copy_sp_name_internal(thd->mem_root, caller->m_db, pkgstr) || + name->make_package_routine_name(thd->mem_root, pkgstr, name->m_name)) return true; } return ret != SP_OK; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index e7377730b94..5ca2c042294 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -810,7 +810,7 @@ sp_head::init(LEX *lex) } -void +bool sp_head::init_sp_name(const sp_name *spname) { DBUG_ENTER("sp_head::init_sp_name"); @@ -819,10 +819,10 @@ sp_head::init_sp_name(const sp_name *spname) DBUG_ASSERT(spname && spname->m_db.str && spname->m_db.length); - /* We have to copy strings to get them into the right memroot. */ - Database_qualified_name::copy(&main_mem_root, spname->m_db, spname->m_name); m_explicit_name= spname->m_explicit_name; - DBUG_VOID_RETURN; + /* We have to copy strings to get them into the right memroot. */ + DBUG_RETURN(copy_sp_name_internal(&main_mem_root, + spname->m_db, spname->m_name)); } void diff --git a/sql/sp_head.h b/sql/sp_head.h index 96152cf5472..91b128dc7e6 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -339,7 +339,7 @@ public: init(LEX *lex); /** Copy sp name from parser. */ - void + bool init_sp_name(const sp_name *spname); /** Set the body-definition start position. */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 792deee7f74..189979aa221 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3975,6 +3975,49 @@ Query_arena::Type Statement::type() const } +/* + Return an internal database name: + - validated with Lex_ident_db::check_db_name() + - optionally converted to lower-case when lower_case_table_names==1 + + The lower-cased copy is made on mem_root when needed. + An error is raised in case of EOM or a bad database name. + + @param src - the database name + @returns - {NULL,0} on EOM or a bad database name, + or a good database name otherwise +*/ + +Lex_ident_db +Query_arena::to_ident_db_internal_with_error(const LEX_CSTRING &src) +{ + DBUG_ASSERT(src.str); + if (src.str == any_db.str) // e.g. JSON table + return any_db; // preserve any_db - it has a special meaning + + bool casedn= lower_case_table_names == 1; + const LEX_CSTRING tmp= casedn ? make_ident_casedn(src) : src; + if (!tmp.str /*EOM*/ || + Lex_ident_fs(tmp).check_db_name_with_error()) + return Lex_ident_db(); + + return Lex_ident_db(tmp.str, tmp.length); +} + + +Lex_ident_db +Table_ident::to_ident_db_internal_with_error(Query_arena *arena) const +{ + if (is_derived_table()) + { + DBUG_ASSERT(db.str == empty_c_string && db.length == 0); + return Lex_ident_db(empty_c_string, 0); + } + // Normal table or JSON table + return arena->to_ident_db_internal_with_error(db); +} + + void Statement::set_statement(Statement *stmt) { id= stmt->id; @@ -8168,14 +8211,18 @@ void AUTHID::parse(const char *str, size_t length) } -void Database_qualified_name::copy(MEM_ROOT *mem_root, - const LEX_CSTRING &db, - const LEX_CSTRING &name) +bool Database_qualified_name::copy_sp_name_internal(MEM_ROOT *mem_root, + const LEX_CSTRING &db, + const LEX_CSTRING &name) { - m_db.length= db.length; - m_db.str= strmake_root(mem_root, db.str, db.length); - m_name.length= name.length; - m_name.str= strmake_root(mem_root, name.str, name.length); + DBUG_ASSERT(db.str); + DBUG_ASSERT(name.str); + m_db= lower_case_table_names == 1 ? + lex_string_casedn_root(mem_root, &my_charset_utf8mb3_general_ci, + db.str, db.length) : + lex_string_strmake_root(mem_root, db.str, db.length); + m_name= lex_string_strmake_root(mem_root, name.str, name.length); + return m_db.str == NULL || m_name.str == NULL; // check if EOM } diff --git a/sql/sql_class.h b/sql/sql_class.h index 5c4b7510fff..0fb388cdd19 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1355,6 +1355,45 @@ public: return false; } + /* + Make a lower-cased copy of an identifier on mem_root. + + @param src - The original identifier (usually coming from the parser) + @return - {NULL,0} in case of EOM, or a non-NULL LEX_STRING + with the lower-cased identifier copy. + */ + LEX_STRING make_ident_casedn(const LEX_CSTRING &src) + { + return lex_string_casedn_root(mem_root, &my_charset_utf8mb3_general_ci, + src.str, src.length); + } + + /* + Make an exact copy or a lower-cased copy of an identifier on mem_root. + + @param src - The original identifier (usually coming from the parser) + @param casedn - If the name should be converted to lower case + @return - {NULL,0} in case of EOM, + or a non-NULL LEX_STRING with the identifier copy. + */ + LEX_STRING make_ident_opt_casedn(const LEX_CSTRING &src, bool casedn) + { + return casedn ? make_ident_casedn(src) : + lex_string_strmake_root(mem_root, src.str, src.length); + } + + /* + Convert a LEX_CSTRING to a valid internal database name: + - validated with Lex_ident_fs::check_db_name() + - optionally lower-cased when lower_case_table_names==1 + The lower-cased copy is created on Query_arena::mem_root, when needed. + + @param name - The name to normalize. Must not be {NULL,0}. + @return - {NULL,0} on EOM or a bad database name + (with an errror is raised, + or a good database name otherwise. + */ + Lex_ident_db to_ident_db_internal_with_error(const LEX_CSTRING &name); void set_query_arena(Query_arena *set); @@ -7051,6 +7090,16 @@ public: } bool resolve_table_rowtype_ref(THD *thd, Row_definition_list &defs); bool append_to(THD *thd, String *to) const; + /* + Convert Table_ident::m_db to a valid internal database name: + - validated with Lex_ident_fs::check_db_name() + - optionally lower-cased when lower_case_table_names==1 + + @param arena - the arena to allocate the lower-cased copy on, when needed. + @return {NULL,0} in case of EOM or invalid database name, + or a good identifier otherwise. + */ + Lex_ident_db to_ident_db_internal_with_error(Query_arena *arena) const; }; @@ -7865,8 +7914,13 @@ public: !cs->strnncoll(m_name.str, m_name.length, other->m_name.str, other->m_name.length); } - void copy(MEM_ROOT *mem_root, const LEX_CSTRING &db, - const LEX_CSTRING &name); + /* + Make copies of "db" and "name" on the memory root in internal format: + - Lower-case "db" if lower-case-table-names==1. + - Preserve "name" as is. + */ + bool copy_sp_name_internal(MEM_ROOT *mem_root, const LEX_CSTRING &db, + const LEX_CSTRING &name); // Export db and name as a qualified name string: 'db.name' size_t make_qname(char *dst, size_t dstlen) const diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a0f8a14f8fa..6b5ccf58f80 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -7389,14 +7389,9 @@ sp_name *LEX::make_sp_name(THD *thd, const Lex_ident_sys_st &name1, { DBUG_ASSERT(name1.str); sp_name *res; - LEX_CSTRING norm_name1; - if (unlikely(!thd->make_lex_string(&norm_name1, name1.str, name1.length)) || - unlikely(check_db_name((LEX_STRING *) &norm_name1))) - { - my_error(ER_WRONG_DB_NAME, MYF(0), name1.str); - return NULL; - } - if (unlikely(check_routine_name(&name2)) || + const Lex_ident_db norm_name1= thd->to_ident_db_internal_with_error(name1); + if (unlikely(!norm_name1.str) || + unlikely(check_routine_name(&name2)) || unlikely(!(res= new (thd->mem_root) sp_name(&norm_name1, &name2, true)))) return NULL; return res; @@ -9309,20 +9304,16 @@ bool LEX::call_statement_start(THD *thd, const Lex_ident_sys_st *pkg, const Lex_ident_sys_st *proc) { + DBUG_ASSERT(db->str); Database_qualified_name q_db_pkg(db, pkg); Identifier_chain2 q_pkg_proc(*pkg, *proc); sp_name *spname; sql_command= SQLCOM_CALL; - if (check_db_name(reinterpret_cast - (const_cast - (static_cast(db))))) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db->str); - return true; - } - if (check_routine_name(pkg) || + const Lex_ident_db db_int= thd->to_ident_db_internal_with_error(*db); + if (!db_int.str || + check_routine_name(pkg) || check_routine_name(proc)) return true; @@ -9330,7 +9321,7 @@ bool LEX::call_statement_start(THD *thd, LEX_CSTRING pkg_dot_proc; if (q_pkg_proc.make_qname(thd->mem_root, &pkg_dot_proc) || check_ident_length(&pkg_dot_proc) || - !(spname= new (thd->mem_root) sp_name(db, &pkg_dot_proc, true))) + !(spname= new (thd->mem_root) sp_name(&db_int, &pkg_dot_proc, true))) return true; sp_handler_package_function.add_used_routine(thd->lex, thd, spname); @@ -9575,17 +9566,13 @@ Item *LEX::make_item_func_call_generic(THD *thd, Lex_ident_cli_st *cdb, version() (a vendor can specify any schema). */ - if (!name.str || check_db_name((LEX_STRING*) static_cast(&db))) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db.str); - return NULL; - } - if (check_routine_name(&name)) + const Lex_ident_db db_int= thd->to_ident_db_internal_with_error(db); + if (!db_int.str || check_routine_name(&name)) return NULL; Create_qfunc *builder= find_qualified_function_builder(thd); DBUG_ASSERT(builder); - return builder->create_with_db(thd, &db, &name, true, args); + return builder->create_with_db(thd, &db_int, &name, true, args); } @@ -9609,12 +9596,9 @@ Item *LEX::make_item_func_call_generic(THD *thd, if (db.is_null() || pkg.is_null() || func.is_null()) return NULL; // EOM - if (check_db_name((LEX_STRING*) static_cast(&db))) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db.str); - return NULL; - } - if (check_routine_name(&pkg) || + const Lex_ident_db db_int= thd->to_ident_db_internal_with_error(db); + if (!db_int.str || + check_routine_name(&pkg) || check_routine_name(&func)) return NULL; @@ -9622,7 +9606,7 @@ Item *LEX::make_item_func_call_generic(THD *thd, LEX_CSTRING pkg_dot_func; if (q_pkg_func.make_qname(thd->mem_root, &pkg_dot_func) || check_ident_length(&pkg_dot_func) || - !(qname= new (thd->mem_root) sp_name(&db, &pkg_dot_func, true))) + !(qname= new (thd->mem_root) sp_name(&db_int, &pkg_dot_func, true))) return NULL; sp_handler_package_function.add_used_routine(thd->lex, thd, qname); @@ -11427,13 +11411,18 @@ bool LEX::stmt_alter_table_exchange_partition(Table_ident *table) bool LEX::stmt_alter_table(Table_ident *table) { DBUG_ASSERT(sql_command == SQLCOM_ALTER_TABLE); - first_select_lex()->db= table->db; - if (first_select_lex()->db.str == NULL && - copy_db_to(&first_select_lex()->db)) + + if (table->db.str) + { + const Lex_ident_db db_int= thd->to_ident_db_internal_with_error(table->db); + if (!db_int.str) + return true; + first_select_lex()->db= db_int; + } + else if (copy_db_to(&first_select_lex()->db)) return true; if (unlikely(check_table_name(table->table.str, table->table.length, - false)) || - (table->db.str && unlikely(check_db_name((LEX_STRING*) &table->db)))) + false))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); return true; @@ -11502,18 +11491,19 @@ bool LEX::stmt_drop_function(const DDL_options_st &options, const Lex_ident_sys_st &db, const Lex_ident_sys_st &name) { - if (unlikely(db.str && check_db_name((LEX_STRING*) &db))) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db.str); + DBUG_ASSERT(db.str); + DBUG_ASSERT(name.str); + const Lex_ident_db db_int= thd->to_ident_db_internal_with_error(db); + if (unlikely(!db_int.str)) return true; - } + if (unlikely(sphead)) { my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"); return true; } set_command(SQLCOM_DROP_FUNCTION, options); - spname= new (thd->mem_root) sp_name(&db, &name, true); + spname= new (thd->mem_root) sp_name(&db_int, &name, true); return spname == NULL; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index dd296eed50f..8845ef155eb 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1424,8 +1424,8 @@ public: bool add_ftfunc_to_list(THD *thd, Item_func_match *func); bool add_order_to_list(THD *thd, Item *item, bool asc); bool add_gorder_to_list(THD *thd, Item *item, bool asc); - TABLE_LIST* add_table_to_list(THD *thd, Table_ident *table, - LEX_CSTRING *alias, + TABLE_LIST* add_table_to_list(THD *thd, const Table_ident *table, + const LEX_CSTRING *alias, ulong table_options, thr_lock_type flags= TL_UNLOCK, enum_mdl_type mdl_type= MDL_SHARED_READ, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 47e3307c37e..438ac2345ee 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2623,18 +2623,11 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, schema_select_lex= new (thd->mem_root) SELECT_LEX(); schema_select_lex->table_list.first= NULL; if (lower_case_table_names == 1) - lex->first_select_lex()->db.str= - thd->strdup(lex->first_select_lex()->db.str); + lex->first_select_lex()->db= + thd->make_ident_casedn(lex->first_select_lex()->db); schema_select_lex->db= lex->first_select_lex()->db; - /* - check_db_name() may change db.str if lower_case_table_names == 1, - but that's ok as the db is allocted above in this case. - */ - if (check_db_name((LEX_STRING*) &lex->first_select_lex()->db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), lex->first_select_lex()->db.str); + if (Lex_ident_fs(lex->first_select_lex()->db).check_db_name_with_error()) DBUG_RETURN(1); - } break; } #endif @@ -3045,15 +3038,11 @@ mysql_create_routine(THD *thd, LEX *lex) { DBUG_ASSERT(lex->sphead != 0); DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */ - /* - Verify that the database name is allowed, optionally - lowercase it. - */ - if (check_db_name((LEX_STRING*) &lex->sphead->m_db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str); + DBUG_ASSERT(lower_case_table_names != 1 || + Lex_ident_fs(lex->sphead->m_db).is_in_lower_case()); + + if (Lex_ident_fs(lex->sphead->m_db).check_db_name_with_error()) return true; - } if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, NULL, NULL, 0, 0)) @@ -7056,7 +7045,7 @@ bool check_global_access(THD *thd, privilege_t want_access, bool no_errors) bool check_fk_parent_table_access(THD *thd, HA_CREATE_INFO *create_info, Alter_info *alter_info, - const char* create_db) + const LEX_CSTRING &create_db) { Key *key; List_iterator key_iterator(alter_info->key_list); @@ -7079,54 +7068,37 @@ bool check_fk_parent_table_access(THD *thd, my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str); return true; } + // if lower_case_table_names is set then convert tablename to lower case. + if (lower_case_table_names && + !(table_name= thd->make_ident_casedn(fk_key->ref_table)).str) + return true; if (fk_key->ref_db.str) { - if (!(db_name.str= (char *) thd->memdup(fk_key->ref_db.str, - fk_key->ref_db.length+1))) + if (Lex_ident_fs(fk_key->ref_db).check_db_name_with_error() || + !(db_name= thd->make_ident_opt_casedn(fk_key->ref_db, + lower_case_table_names)).str) return true; - db_name.length= fk_key->ref_db.length; - - // Check if database name is valid or not. - if (check_db_name((LEX_STRING*) &db_name)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str); - return true; - } } else { if (!thd->db.str) { - DBUG_ASSERT(create_db); - db_name.length= strlen(create_db); - if (!(db_name.str= (char *) thd->memdup(create_db, - db_name.length+1))) + DBUG_ASSERT(create_db.str); + if (Lex_ident_fs(create_db).check_db_name_with_error() || + !(db_name= thd->make_ident_opt_casedn(create_db, + lower_case_table_names)).str) return true; - - if (check_db_name((LEX_STRING*) &db_name)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str); - return true; - } } else { - if (thd->lex->copy_db_to(&db_name)) + if (thd->lex->copy_db_to(&db_name) || + (lower_case_table_names && + !(db_name= thd->make_ident_casedn(db_name)).str)) return true; } } - // if lower_case_table_names is set then convert tablename to lower case. - if (lower_case_table_names) - { - char *name; - table_name.str= name= (char *) thd->memdup(fk_key->ref_table.str, - fk_key->ref_table.length+1); - table_name.length= my_casedn_str(files_charset_info, name); - db_name.length= my_casedn_str(files_charset_info, (char*) db_name.str); - } - parent_table.init_one_table(&db_name, &table_name, 0, TL_IGNORE); /* @@ -7892,11 +7864,30 @@ bool add_to_list(THD *thd, SQL_I_List &list, Item *item,bool asc) 0 Error @retval \# Pointer to TABLE_LIST element added to the total table list + + + This method can be called in contexts when the "table" argument has a longer + life cycle than TABLE_LIST and belongs to a different MEM_ROOT than + the current THD::mem_root. + + For example, it's called from Table_ident::resolve_table_rowtype_ref() + during sp_head::rcontext_create() during a CALL statement. + "table" in this case belongs to sp_pcontext, which must stay valid + (inside its SP cache sp_head entry) after the end of the current statement. + + Let's allocate normalized copies of table.db and table.table on the current + THD::mem_root and store them in the TABLE_LIST. + + We should not touch "table" and replace table.db and table.table to their + normalized copies allocated on the current THD::mem_root, because it'll be + freed at the end of the current statement, while table.db and table.table + should stay valid. Let's keep them in the original state. + */ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, - Table_ident *table, - LEX_CSTRING *alias, + const Table_ident *table, + const LEX_CSTRING *alias, ulong table_options, thr_lock_type lock_type, enum_mdl_type mdl_type, @@ -7928,11 +7919,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (unlikely(table->is_derived_table() == FALSE && table->db.str && !(table_options & TL_OPTION_TABLE_FUNCTION) && - check_db_name((LEX_STRING*) &table->db))) - { - my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str); + Lex_ident_fs(table->db).check_db_name_with_error())) DBUG_RETURN(0); - } if (!alias) /* Alias is case sensitive */ { @@ -7960,16 +7948,17 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->alias= alias_str; ptr->is_alias= alias ? TRUE : FALSE; + ptr->table_name= table->table; + if (lower_case_table_names) { - if (table->table.length) - table->table.length= my_casedn_str(files_charset_info, - (char*) table->table.str); - if (ptr->db.length && ptr->db.str != any_db.str) - ptr->db.length= my_casedn_str(files_charset_info, (char*) ptr->db.str); + if (!(ptr->table_name= thd->make_ident_casedn(ptr->table_name)).str) + DBUG_RETURN(0); + if (ptr->db.length && ptr->db.str != any_db.str && + !(ptr->db= thd->make_ident_casedn(ptr->db)).str) + DBUG_RETURN(0); } - ptr->table_name= table->table; ptr->lock_type= lock_type; ptr->mdl_type= mdl_type; ptr->table_options= table_options; @@ -9693,7 +9682,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, } if (check_fk_parent_table_access(thd, &lex->create_info, &lex->alter_info, - create_table->db.str)) + create_table->db)) goto err; error= FALSE; diff --git a/sql/sql_parse.h b/sql/sql_parse.h index ecd4c36b39a..94dc19094ca 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -50,7 +50,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, bool check_fk_parent_table_access(THD *thd, HA_CREATE_INFO *create_info, Alter_info *alter_info, - const char* create_db); + const LEX_CSTRING &create_db); bool parse_sql(THD *thd, Parser_state *parser_state, Object_creation_ctx *creation_ctx, bool do_pfs_digest=false); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index dd93605305e..cd3a9cd27d6 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -10409,7 +10409,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, till this point for the alter operation. */ if ((alter_info->flags & ALTER_ADD_FOREIGN_KEY) && - check_fk_parent_table_access(thd, create_info, alter_info, new_db->str)) + check_fk_parent_table_access(thd, create_info, alter_info, *new_db)) DBUG_RETURN(true); /* diff --git a/sql/table.cc b/sql/table.cc index a365d64011e..28b16bac47d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5146,57 +5146,16 @@ uint calculate_key_len(TABLE *table, uint key, const uchar *buf, */ bool Lex_ident_fs::ok_for_lower_case_names() const { - if (!lower_case_table_names || !str) - return true; - DBNameBuffer buf(*this, lower_case_table_names); + return !lower_case_table_names || !str || is_in_lower_case(); +} + +bool Lex_ident_fs::is_in_lower_case() const +{ + DBNameBuffer buf(*this, true); return cmp(*this, buf.to_lex_cstring()) == 0; } #endif -/* - Check if database name is valid - - SYNPOSIS - check_db_name() - org_name Name of database - - NOTES - If lower_case_table_names is set to 1 then database name is converted - to lower case - - RETURN - 0 ok - 1 error -*/ - -bool check_db_name(LEX_STRING *org_name) -{ - char *name= org_name->str; - size_t name_length= org_name->length; - bool disallow_path_chars; - - if ((disallow_path_chars= check_mysql50_prefix(name))) - { - name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH; - name_length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH; - } - - if (!name_length || name_length > NAME_LEN) - return 1; - - if (lower_case_table_names == 1 && name != any_db.str) - { - org_name->length= name_length= my_casedn_str(files_charset_info, name); - if (disallow_path_chars) - org_name->length+= MYSQL50_TABLE_NAME_PREFIX_LENGTH; - } - if (db_name_is_in_ignore_db_dirs_list(name)) - return 1; - - return check_table_name(name, name_length, disallow_path_chars); -} - - /* Allow anything as a table name, as long as it doesn't contain an ' ' at the end diff --git a/sql/table.h b/sql/table.h index a0d25bc3002..91c117dbca3 100644 --- a/sql/table.h +++ b/sql/table.h @@ -3398,7 +3398,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, void open_table_error(TABLE_SHARE *share, enum open_frm_error error, int db_errno); void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); -bool check_db_name(LEX_STRING *db); + bool check_column_name(const char *name); bool check_period_name(const char *name); bool check_table_name(const char *name, size_t length, bool check_for_path_chars);