1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

MDEV-12415 Remove sp_name::m_qname

This commit is contained in:
Alexander Barkov
2017-03-31 14:26:43 +04:00
parent 0d8dc74d30
commit e191833d75
10 changed files with 93 additions and 94 deletions

View File

@ -88,9 +88,6 @@ Event_parse_data::init_name(THD *thd, sp_name *spn)
name.length= spn->m_name.length; name.length= spn->m_name.length;
name.str= thd->strmake(spn->m_name.str, 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; DBUG_VOID_RETURN;
} }

View File

@ -3444,7 +3444,6 @@ Create_sp_func::create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
arg_count= item_list->elements; arg_count= item_list->elements;
qname= new (thd->mem_root) sp_name(db, name, use_explicit_name); 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); sp_add_used_routine(lex, thd, qname, TYPE_ENUM_FUNCTION);
if (arg_count > 0) if (arg_count > 0)

View File

@ -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) Item_func(thd), context(context_arg), m_name(name), m_sp(NULL), sp_result_field(NULL)
{ {
maybe_null= 1; maybe_null= 1;
m_name->init_qname(thd);
dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE)); dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
dummy_table->s= (TABLE_SHARE*) (dummy_table+1); 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) sp_result_field(NULL)
{ {
maybe_null= 1; maybe_null= 1;
m_name->init_qname(thd);
dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE)); dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
dummy_table->s= (TABLE_SHARE*) (dummy_table+1); 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, if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name,
&thd->sp_func_cache, TRUE))) &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); context->process_error(thd);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }

View File

@ -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_db.str= thd->strmake(routine->db, lex_db.length);
lex_name.str= thd->strmake(routine->table_name, lex_name.length); lex_name.str= thd->strmake(routine->table_name, lex_name.length);
name= new sp_name(lex_db, lex_name, true); 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, sp_object_found= is_proc ? sp_find_routine(thd, TYPE_ENUM_PROCEDURE,
name, &thd->sp_proc_cache, name, &thd->sp_proc_cache,
FALSE) != NULL : FALSE) != NULL :
@ -2175,20 +2174,8 @@ int sp_cache_routine(THD *thd, enum stored_procedure_type type, sp_name *name,
*/ */
if (! thd->is_error()) if (! thd->is_error())
{ {
/* my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0),
SP allows full NAME_LEN chars thus he have to allocate enough ErrConvDQName(name).ptr(), ret);
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);
} }
break; 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.str= name->c_ptr();
sp_name_str.length= name->length(); sp_name_str.length= name->length();
sp_name sp_name_obj(sp_db_str, sp_name_str, true); sp_name sp_name_obj(sp_db_str, sp_name_str, true);
sp_name_obj.init_qname(thd);
*free_sp_head= 0; *free_sp_head= 0;
if ((sp= sp_cache_lookup(spc, &sp_name_obj))) if ((sp= sp_cache_lookup(spc, &sp_name_obj)))
{ {

View File

@ -167,8 +167,7 @@ void sp_cache_insert(sp_cache **cp, sp_head *sp)
} }
/* Reading a ulong variable with no lock. */ /* Reading a ulong variable with no lock. */
sp->set_sp_cache_version(Cversion); sp->set_sp_cache_version(Cversion);
DBUG_PRINT("info",("sp_cache: inserting: %.*s", (int) sp->m_qname.length, DBUG_PRINT("info",("sp_cache: inserting: %s", ErrConvDQName(sp).ptr()));
sp->m_qname.str));
c->insert(sp); c->insert(sp);
*cp= c; // Update *cp if it was NULL *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) sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name)
{ {
char buf[NAME_LEN * 2 + 2];
sp_cache *c= *cp; sp_cache *c= *cp;
if (! c) if (! c)
return NULL; return NULL;
return c->lookup(name->m_qname.str, name->m_qname.length); return c->lookup(buf, name->make_qname(buf, sizeof(buf)));
} }

View File

@ -401,42 +401,14 @@ error:
*/ */
sp_name::sp_name(const MDL_key *key, char *qname_buff) 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) if (m_db.length)
{
strxmov(qname_buff, m_db.str, ".", m_name.str, NullS); strxmov(qname_buff, m_db.str, ".", m_name.str, NullS);
m_qname.length= m_db.length + 1 + m_name.length;
}
else else
{
strmov(qname_buff, m_name.str); 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() sp_head::sp_head()
:Query_arena(&main_mem_root, STMT_INITIALIZED_FOR_SP), :Query_arena(&main_mem_root, STMT_INITIALIZED_FOR_SP),
Database_qualified_name(null_lex_str, null_lex_str),
m_flags(0), m_flags(0),
m_sp_cache_version(0), m_sp_cache_version(0),
m_creation_ctx(0), m_creation_ctx(0),
@ -534,7 +507,7 @@ sp_head::sp_head()
be rewritten soon. Remove the else part and replace 'if' with be rewritten soon. Remove the else part and replace 'if' with
an assert when this is done. 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"); 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; m_explicit_name= spname->m_explicit_name;
if (spname->m_qname.length == 0) spname->make_qname(thd, &m_qname);
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);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -1623,7 +1590,8 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
invoking query properly. invoking query properly.
*/ */
my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), 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); DBUG_RETURN(TRUE);
} }
/* /*
@ -1847,7 +1815,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (args->elements != params) if (args->elements != params)
{ {
my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "PROCEDURE", 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); DBUG_RETURN(TRUE);
} }
@ -1905,7 +1873,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (!srp) 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; err_status= TRUE;
break; break;
} }

View File

@ -107,30 +107,22 @@ protected:
/*************************************************************************/ /*************************************************************************/
class sp_name : public Sql_alloc class sp_name : public Sql_alloc,
public Database_qualified_name
{ {
public: public:
LEX_STRING m_db;
LEX_STRING m_name;
LEX_STRING m_qname;
bool m_explicit_name; /**< Prepend the db name? */ bool m_explicit_name; /**< Prepend the db name? */
sp_name(LEX_STRING db, LEX_STRING name, bool use_explicit_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) if (lower_case_table_names && m_db.str)
m_db.length= my_casedn_str(files_charset_info, 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. */ /** Create temporary sp_name object from MDL key. */
sp_name(const MDL_key *key, char *qname_buff); 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() ~sp_name()
{} {}
}; };
@ -139,7 +131,8 @@ public:
bool bool
check_routine_name(LEX_STRING *ident); 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 */ sp_head(const sp_head &); /**< Prevent use of these */
void operator=(sp_head &); void operator=(sp_head &);
@ -185,8 +178,6 @@ public:
sql_mode_t m_sql_mode; ///< For SHOW CREATE and execution sql_mode_t m_sql_mode; ///< For SHOW CREATE and execution
LEX_STRING m_qname; ///< db.name LEX_STRING m_qname; ///< db.name
bool m_explicit_name; ///< Prepend the 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_params;
LEX_STRING m_body; LEX_STRING m_body;
LEX_STRING m_body_utf8; LEX_STRING m_body_utf8;

View File

@ -5757,6 +5757,68 @@ class Sql_mode_save
sql_mode_t old_mode; // SQL mode saved at construction time. 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 /* MYSQL_SERVER */
#endif /* SQL_CLASS_INCLUDED */ #endif /* SQL_CLASS_INCLUDED */

View File

@ -2854,7 +2854,7 @@ static bool do_execute_sp(THD *thd, sp_head *sp)
if (!(thd->client_capabilities & CLIENT_MULTI_RESULTS)) if (!(thd->client_capabilities & CLIENT_MULTI_RESULTS))
{ {
/* The client does not support multiple result sets being sent back */ /* 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; return 1;
} }
/* /*
@ -5760,7 +5760,7 @@ end_with_restore_list:
&thd->sp_proc_cache, TRUE))) &thd->sp_proc_cache, TRUE)))
{ {
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE", my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
lex->spname->m_qname.str); ErrConvDQName(lex->spname).ptr());
goto error; goto error;
} }
else else
@ -5820,11 +5820,11 @@ end_with_restore_list:
break; break;
case SP_KEY_NOT_FOUND: case SP_KEY_NOT_FOUND:
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), 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; goto error;
default: default:
my_error(ER_SP_CANT_ALTER, MYF(0), 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; goto error;
} }
break; break;
@ -5931,17 +5931,18 @@ end_with_restore_list:
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_SP_DOES_NOT_EXIST, ER_THD(thd, ER_SP_DOES_NOT_EXIST), 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) if (!res)
my_ok(thd); my_ok(thd);
break; break;
} }
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), 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; goto error;
default: default:
my_error(ER_SP_DROP_FAILED, MYF(0), 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; goto error;
} }
break; break;

View File

@ -2858,7 +2858,6 @@ sp_name:
$$= new (thd->mem_root) sp_name($1, $3, true); $$= new (thd->mem_root) sp_name($1, $3, true);
if ($$ == NULL) if ($$ == NULL)
MYSQL_YYABORT; MYSQL_YYABORT;
$$->init_qname(thd);
} }
| ident | ident
{ {
@ -2873,7 +2872,6 @@ sp_name:
$$= new (thd->mem_root) sp_name(db, $1, false); $$= new (thd->mem_root) sp_name(db, $1, false);
if ($$ == NULL) if ($$ == NULL)
MYSQL_YYABORT; MYSQL_YYABORT;
$$->init_qname(thd);
} }
; ;
@ -12144,7 +12142,6 @@ drop:
spname= new (thd->mem_root) sp_name($4, $6, true); spname= new (thd->mem_root) sp_name($4, $6, true);
if (spname == NULL) if (spname == NULL)
MYSQL_YYABORT; MYSQL_YYABORT;
spname->init_qname(thd);
lex->spname= spname; lex->spname= spname;
} }
| DROP FUNCTION_SYM opt_if_exists ident | DROP FUNCTION_SYM opt_if_exists ident
@ -12160,7 +12157,6 @@ drop:
spname= new (thd->mem_root) sp_name(db, $4, false); spname= new (thd->mem_root) sp_name(db, $4, false);
if (spname == NULL) if (spname == NULL)
MYSQL_YYABORT; MYSQL_YYABORT;
spname->init_qname(thd);
lex->spname= spname; lex->spname= spname;
} }
| DROP PROCEDURE_SYM opt_if_exists sp_name | DROP PROCEDURE_SYM opt_if_exists sp_name
@ -16755,7 +16751,8 @@ sf_tail:
lex->sql_command= SQLCOM_CREATE_SPFUNCTION; lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->set_stmt_end(thd); sp->set_stmt_end(thd);
if (!(sp->m_flags & sp_head::HAS_RETURN)) 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); (void) is_native_function_with_warn(thd, &sp->m_name);
sp->restore_thd_mem_root(thd); sp->restore_thd_mem_root(thd);
} }