diff options
-rw-r--r-- | sql/event_parse_data.cc | 3 | ||||
-rw-r--r-- | sql/item_create.cc | 1 | ||||
-rw-r--r-- | sql/item_func.cc | 4 | ||||
-rw-r--r-- | sql/sp.cc | 18 | ||||
-rw-r--r-- | sql/sp_cache.cc | 6 | ||||
-rw-r--r-- | sql/sp_head.cc | 52 | ||||
-rw-r--r-- | sql/sp_head.h | 19 | ||||
-rw-r--r-- | sql/sql_class.h | 62 | ||||
-rw-r--r-- | sql/sql_parse.cc | 15 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 7 |
10 files changed, 93 insertions, 94 deletions
diff --git a/sql/event_parse_data.cc b/sql/event_parse_data.cc index 6c123c8e641..2cd8f5c1b59 100644 --- a/sql/event_parse_data.cc +++ b/sql/event_parse_data.cc @@ -88,9 +88,6 @@ Event_parse_data::init_name(THD *thd, sp_name *spn) name.length= spn->m_name.length; name.str= thd->strmake(spn->m_name.str, spn->m_name.length); - if (spn->m_qname.length == 0) - spn->init_qname(thd); - DBUG_VOID_RETURN; } diff --git a/sql/item_create.cc b/sql/item_create.cc index 4730e187ebe..455da1f5ba5 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -3444,7 +3444,6 @@ Create_sp_func::create_with_db(THD *thd, LEX_STRING db, LEX_STRING name, arg_count= item_list->elements; qname= new (thd->mem_root) sp_name(db, name, use_explicit_name); - qname->init_qname(thd); sp_add_used_routine(lex, thd, qname, TYPE_ENUM_FUNCTION); if (arg_count > 0) diff --git a/sql/item_func.cc b/sql/item_func.cc index 3a9f61edf2d..35bba56717e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6338,7 +6338,6 @@ Item_func_sp::Item_func_sp(THD *thd, Name_resolution_context *context_arg, Item_func(thd), context(context_arg), m_name(name), m_sp(NULL), sp_result_field(NULL) { maybe_null= 1; - m_name->init_qname(thd); dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE)); dummy_table->s= (TABLE_SHARE*) (dummy_table+1); } @@ -6350,7 +6349,6 @@ Item_func_sp::Item_func_sp(THD *thd, Name_resolution_context *context_arg, sp_result_field(NULL) { maybe_null= 1; - m_name->init_qname(thd); dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE)); dummy_table->s= (TABLE_SHARE*) (dummy_table+1); } @@ -6435,7 +6433,7 @@ Item_func_sp::init_result_field(THD *thd) if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, &thd->sp_func_cache, TRUE))) { - my_missing_function_error (m_name->m_name, m_name->m_qname.str); + my_missing_function_error (m_name->m_name, ErrConvDQName(m_name).ptr()); context->process_error(thd); DBUG_RETURN(TRUE); } diff --git a/sql/sp.cc b/sql/sp.cc index a1662cefb9e..90a9ed35899 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1848,7 +1848,6 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool is_proc) lex_db.str= thd->strmake(routine->db, lex_db.length); lex_name.str= thd->strmake(routine->table_name, lex_name.length); name= new sp_name(lex_db, lex_name, true); - name->init_qname(thd); sp_object_found= is_proc ? sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name, &thd->sp_proc_cache, FALSE) != NULL : @@ -2175,20 +2174,8 @@ int sp_cache_routine(THD *thd, enum stored_procedure_type type, sp_name *name, */ if (! thd->is_error()) { - /* - SP allows full NAME_LEN chars thus he have to allocate enough - size in bytes. Otherwise there is stack overrun could happen - if multibyte sequence is `name`. `db` is still safe because the - rest of the server checks agains NAME_LEN bytes and not chars. - Hence, the overrun happens only if the name is in length > 32 and - uses multibyte (cyrillic, greek, etc.) - */ - char n[NAME_LEN*2+2]; - - /* m_qname.str is not always \0 terminated */ - memcpy(n, name->m_qname.str, name->m_qname.length); - n[name->m_qname.length]= '\0'; - my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), n, ret); + my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), + ErrConvDQName(name).ptr(), ret); } break; } @@ -2322,7 +2309,6 @@ sp_load_for_information_schema(THD *thd, TABLE *proc_table, String *db, sp_name_str.str= name->c_ptr(); sp_name_str.length= name->length(); sp_name sp_name_obj(sp_db_str, sp_name_str, true); - sp_name_obj.init_qname(thd); *free_sp_head= 0; if ((sp= sp_cache_lookup(spc, &sp_name_obj))) { diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index bafd0f34ab6..b80cde335db 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -167,8 +167,7 @@ void sp_cache_insert(sp_cache **cp, sp_head *sp) } /* Reading a ulong variable with no lock. */ sp->set_sp_cache_version(Cversion); - DBUG_PRINT("info",("sp_cache: inserting: %.*s", (int) sp->m_qname.length, - sp->m_qname.str)); + DBUG_PRINT("info",("sp_cache: inserting: %s", ErrConvDQName(sp).ptr())); c->insert(sp); *cp= c; // Update *cp if it was NULL } @@ -192,10 +191,11 @@ void sp_cache_insert(sp_cache **cp, sp_head *sp) sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name) { + char buf[NAME_LEN * 2 + 2]; sp_cache *c= *cp; if (! c) return NULL; - return c->lookup(name->m_qname.str, name->m_qname.length); + return c->lookup(buf, name->make_qname(buf, sizeof(buf))); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 757ee6898a6..3126b3cc46d 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -401,42 +401,14 @@ error: */ sp_name::sp_name(const MDL_key *key, char *qname_buff) + :Database_qualified_name((char*)key->db_name(), key->db_name_length(), + (char*)key->name(), key->name_length()), + m_explicit_name(false) { - m_db.str= (char*)key->db_name(); - m_db.length= key->db_name_length(); - m_name.str= (char*)key->name(); - m_name.length= key->name_length(); - m_qname.str= qname_buff; if (m_db.length) - { strxmov(qname_buff, m_db.str, ".", m_name.str, NullS); - m_qname.length= m_db.length + 1 + m_name.length; - } else - { strmov(qname_buff, m_name.str); - m_qname.length= m_name.length; - } - m_explicit_name= false; -} - - -/** - Init the qualified name from the db and name. -*/ -void -sp_name::init_qname(THD *thd) -{ - const uint dot= !!m_db.length; - /* m_qname format: [database + dot] + name + '\0' */ - m_qname.length= m_db.length + dot + m_name.length; - if (!(m_qname.str= (char*) thd->alloc(m_qname.length + 1))) - return; - sprintf(m_qname.str, "%.*s%.*s%.*s", - (int) m_db.length, (m_db.length ? m_db.str : ""), - dot, ".", - (int) m_name.length, m_name.str); - DBUG_ASSERT(ok_for_lower_case_names(m_db.str)); } @@ -516,6 +488,7 @@ sp_head::operator delete(void *ptr, size_t size) throw() sp_head::sp_head() :Query_arena(&main_mem_root, STMT_INITIALIZED_FOR_SP), + Database_qualified_name(null_lex_str, null_lex_str), m_flags(0), m_sp_cache_version(0), m_creation_ctx(0), @@ -534,7 +507,7 @@ sp_head::sp_head() be rewritten soon. Remove the else part and replace 'if' with an assert when this is done. */ - m_db= m_name= m_qname= null_lex_str; + m_qname= null_lex_str; DBUG_ENTER("sp_head::sp_head"); @@ -620,13 +593,7 @@ sp_head::init_sp_name(THD *thd, sp_name *spname) m_explicit_name= spname->m_explicit_name; - if (spname->m_qname.length == 0) - spname->init_qname(thd); - - m_qname.length= spname->m_qname.length; - m_qname.str= (char*) memdup_root(thd->mem_root, - spname->m_qname.str, - spname->m_qname.length + 1); + spname->make_qname(thd, &m_qname); DBUG_VOID_RETURN; } @@ -1623,7 +1590,8 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, invoking query properly. */ my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), - "FUNCTION", m_qname.str, m_pcont->context_var_count(), argcount); + "FUNCTION", ErrConvDQName(this).ptr(), + m_pcont->context_var_count(), argcount); DBUG_RETURN(TRUE); } /* @@ -1847,7 +1815,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) if (args->elements != params) { my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "PROCEDURE", - m_qname.str, params, args->elements); + ErrConvDQName(this).ptr(), params, args->elements); DBUG_RETURN(TRUE); } @@ -1905,7 +1873,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) if (!srp) { - my_error(ER_SP_NOT_VAR_ARG, MYF(0), i+1, m_qname.str); + my_error(ER_SP_NOT_VAR_ARG, MYF(0), i+1, ErrConvDQName(this).ptr()); err_status= TRUE; break; } diff --git a/sql/sp_head.h b/sql/sp_head.h index a3a34531c89..e5bc3ca9263 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -107,30 +107,22 @@ protected: /*************************************************************************/ -class sp_name : public Sql_alloc +class sp_name : public Sql_alloc, + public Database_qualified_name { public: - - LEX_STRING m_db; - LEX_STRING m_name; - LEX_STRING m_qname; bool m_explicit_name; /**< Prepend the db name? */ sp_name(LEX_STRING db, LEX_STRING name, bool use_explicit_name) - : m_db(db), m_name(name), m_explicit_name(use_explicit_name) + : Database_qualified_name(db, name), m_explicit_name(use_explicit_name) { if (lower_case_table_names && m_db.str) m_db.length= my_casedn_str(files_charset_info, m_db.str); - m_qname.str= 0; - m_qname.length= 0; } /** Create temporary sp_name object from MDL key. */ sp_name(const MDL_key *key, char *qname_buff); - // Init. the qualified name from the db and name. - void init_qname(THD *thd); // thd for memroot allocation - ~sp_name() {} }; @@ -139,7 +131,8 @@ public: bool check_routine_name(LEX_STRING *ident); -class sp_head :private Query_arena +class sp_head :private Query_arena, + public Database_qualified_name { sp_head(const sp_head &); /**< Prevent use of these */ void operator=(sp_head &); @@ -185,8 +178,6 @@ public: sql_mode_t m_sql_mode; ///< For SHOW CREATE and execution LEX_STRING m_qname; ///< db.name bool m_explicit_name; ///< Prepend the db name? */ - LEX_STRING m_db; - LEX_STRING m_name; LEX_STRING m_params; LEX_STRING m_body; LEX_STRING m_body_utf8; diff --git a/sql/sql_class.h b/sql/sql_class.h index 5b18f99022f..0572b3791a4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5757,6 +5757,68 @@ class Sql_mode_save sql_mode_t old_mode; // SQL mode saved at construction time. }; + +/** + This class resembles the SQL Standard schema qualified object name: + <schema qualified name> ::= [ <schema name> <period> ] <qualified identifier> +*/ +class Database_qualified_name +{ +public: + LEX_STRING m_db; + LEX_STRING m_name; + Database_qualified_name(const LEX_STRING db, const LEX_STRING name) + :m_db(db), m_name(name) + { } + Database_qualified_name(char *db, size_t db_length, + char *name, size_t name_length) + { + m_db.str= db; + m_db.length= db_length; + m_name.str= name; + m_name.length= name_length; + } + + // Export db and name as a qualified name string: 'db.name' + size_t make_qname(char *dst, size_t dstlen) const + { + return my_snprintf(dst, dstlen, "%.*s.%.*s", + (int) m_db.length, m_db.str, + (int) m_name.length, m_name.str); + } + // Export db and name as a qualified name string, allocate on mem_root. + bool make_qname(THD *thd, LEX_STRING *dst) const + { + const uint dot= !!m_db.length; + /* format: [database + dot] + name + '\0' */ + dst->length= m_db.length + dot + m_name.length; + if (!(dst->str= (char*) thd->alloc(dst->length + 1))) + return true; + sprintf(dst->str, "%.*s%.*s%.*s", + (int) m_db.length, (m_db.length ? m_db.str : ""), + dot, ".", + (int) m_name.length, m_name.str); + DBUG_ASSERT(ok_for_lower_case_names(m_db.str)); + return false; + } +}; + + +class ErrConvDQName: public ErrConv +{ + const Database_qualified_name *m_name; +public: + ErrConvDQName(const Database_qualified_name *name) + :m_name(name) + { } + const char *ptr() const + { + m_name->make_qname(err_buffer, sizeof(err_buffer)); + return err_buffer; + } +}; + + #endif /* MYSQL_SERVER */ #endif /* SQL_CLASS_INCLUDED */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c75200f895e..ac7660a7451 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2854,7 +2854,7 @@ static bool do_execute_sp(THD *thd, sp_head *sp) if (!(thd->client_capabilities & CLIENT_MULTI_RESULTS)) { /* The client does not support multiple result sets being sent back */ - my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str); + my_error(ER_SP_BADSELECT, MYF(0), ErrConvDQName(sp).ptr()); return 1; } /* @@ -5760,7 +5760,7 @@ end_with_restore_list: &thd->sp_proc_cache, TRUE))) { my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE", - lex->spname->m_qname.str); + ErrConvDQName(lex->spname).ptr()); goto error; } else @@ -5820,11 +5820,11 @@ end_with_restore_list: break; case SP_KEY_NOT_FOUND: my_error(ER_SP_DOES_NOT_EXIST, MYF(0), - SP_COM_STRING(lex), lex->spname->m_qname.str); + SP_COM_STRING(lex), ErrConvDQName(lex->spname).ptr()); goto error; default: my_error(ER_SP_CANT_ALTER, MYF(0), - SP_COM_STRING(lex), lex->spname->m_qname.str); + SP_COM_STRING(lex), ErrConvDQName(lex->spname).ptr()); goto error; } break; @@ -5931,17 +5931,18 @@ end_with_restore_list: res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SP_DOES_NOT_EXIST, ER_THD(thd, ER_SP_DOES_NOT_EXIST), - SP_COM_STRING(lex), lex->spname->m_qname.str); + SP_COM_STRING(lex), + ErrConvDQName(lex->spname).ptr()); if (!res) my_ok(thd); break; } my_error(ER_SP_DOES_NOT_EXIST, MYF(0), - SP_COM_STRING(lex), lex->spname->m_qname.str); + SP_COM_STRING(lex), ErrConvDQName(lex->spname).ptr()); goto error; default: my_error(ER_SP_DROP_FAILED, MYF(0), - SP_COM_STRING(lex), lex->spname->m_qname.str); + SP_COM_STRING(lex), ErrConvDQName(lex->spname).ptr()); goto error; } break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3f04aa9b75c..3c3789200e9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2858,7 +2858,6 @@ sp_name: $$= new (thd->mem_root) sp_name($1, $3, true); if ($$ == NULL) MYSQL_YYABORT; - $$->init_qname(thd); } | ident { @@ -2873,7 +2872,6 @@ sp_name: $$= new (thd->mem_root) sp_name(db, $1, false); if ($$ == NULL) MYSQL_YYABORT; - $$->init_qname(thd); } ; @@ -12144,7 +12142,6 @@ drop: spname= new (thd->mem_root) sp_name($4, $6, true); if (spname == NULL) MYSQL_YYABORT; - spname->init_qname(thd); lex->spname= spname; } | DROP FUNCTION_SYM opt_if_exists ident @@ -12160,7 +12157,6 @@ drop: spname= new (thd->mem_root) sp_name(db, $4, false); if (spname == NULL) MYSQL_YYABORT; - spname->init_qname(thd); lex->spname= spname; } | DROP PROCEDURE_SYM opt_if_exists sp_name @@ -16755,7 +16751,8 @@ sf_tail: lex->sql_command= SQLCOM_CREATE_SPFUNCTION; sp->set_stmt_end(thd); if (!(sp->m_flags & sp_head::HAS_RETURN)) - my_yyabort_error((ER_SP_NORETURN, MYF(0), sp->m_qname.str)); + my_yyabort_error((ER_SP_NORETURN, MYF(0), + ErrConvDQName(sp).ptr())); (void) is_native_function_with_warn(thd, &sp->m_name); sp->restore_thd_mem_root(thd); } |