Commit e191833d authored by Alexander Barkov's avatar Alexander Barkov

MDEV-12415 Remove sp_name::m_qname

parent 0d8dc74d
......@@ -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;
}
......
......@@ -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)
......
......@@ -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);
}
......
......@@ -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)))
{
......
......@@ -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)));
}
......
......@@ -401,42 +401,14 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
*/
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;
}
......
......@@ -107,30 +107,22 @@ class Stored_program_creation_ctx :public Default_object_creation_ctx
/*************************************************************************/
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 @@ class sp_name : public Sql_alloc
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 @@ class sp_head :private Query_arena
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;
......
......@@ -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 */
......@@ -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 @@ mysql_execute_command(THD *thd)
&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 @@ mysql_execute_command(THD *thd)
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 @@ mysql_execute_command(THD *thd)
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;
......
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment