summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc50
1 files changed, 28 insertions, 22 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 9b06b3cb1b1..57143080ee3 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -3846,8 +3846,6 @@ typedef struct st_sp_table
Multi-set key:
db_name\0table_name\0alias\0 - for normal tables
db_name\0table_name\0 - for temporary tables
- Note that in both cases we don't take last '\0' into account when
- we count length of key.
*/
LEX_STRING qname;
uint db_length, table_name_length;
@@ -3904,19 +3902,26 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
for (; table ; table= table->next_global)
if (!table->derived && !table->schema_table)
{
- char tname[(SAFE_NAME_LEN + 1) * 3]; // db\0table\0alias\0
- uint tlen, alen;
-
- tlen= table->db_length;
- memcpy(tname, table->db, tlen);
- tname[tlen++]= '\0';
- memcpy(tname+tlen, table->table_name, table->table_name_length);
- tlen+= table->table_name_length;
- tname[tlen++]= '\0';
- alen= strlen(table->alias);
- memcpy(tname+tlen, table->alias, alen);
- tlen+= alen;
- tname[tlen]= '\0';
+ /*
+ Structure of key for the multi-set is "db\0table\0alias\0".
+ Since "alias" part can have arbitrary length we use String
+ object to construct the key. By default String will use
+ buffer allocated on stack with NAME_LEN bytes reserved for
+ alias, since in most cases it is going to be smaller than
+ NAME_LEN bytes.
+ */
+ char tname_buff[(SAFE_NAME_LEN + 1) * 3];
+ String tname(tname_buff, sizeof(tname_buff), &my_charset_bin);
+ uint temp_table_key_length;
+
+ tname.length(0);
+ tname.append(table->db, table->db_length);
+ tname.append('\0');
+ tname.append(table->table_name, table->table_name_length);
+ tname.append('\0');
+ temp_table_key_length= tname.length();
+ tname.append(table->alias);
+ tname.append('\0');
/*
Upgrade the lock type because this table list will be used
@@ -3931,9 +3936,10 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
(and therefore should not be prelocked). Otherwise we will erroneously
treat table with same name but with different alias as non-temporary.
*/
- if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname, tlen)) ||
- ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname,
- tlen - alen - 1)) &&
+ if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname.ptr(),
+ tname.length())) ||
+ ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname.ptr(),
+ temp_table_key_length)) &&
tab->temp))
{
if (tab->lock_type < table->lock_type)
@@ -3952,11 +3958,11 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE)
{
tab->temp= TRUE;
- tab->qname.length= tlen - alen - 1;
+ tab->qname.length= temp_table_key_length;
}
else
- tab->qname.length= tlen;
- tab->qname.str= (char*) thd->memdup(tname, tab->qname.length + 1);
+ tab->qname.length= tname.length();
+ tab->qname.str= (char*) thd->memdup(tname.ptr(), tab->qname.length);
if (!tab->qname.str)
return FALSE;
tab->table_name_length= table->table_name_length;
@@ -4025,7 +4031,7 @@ sp_head::add_used_tables_to_table_list(THD *thd,
if (!(tab_buff= (char *)thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST)) *
stab->lock_count)) ||
!(key_buff= (char*)thd->memdup(stab->qname.str,
- stab->qname.length + 1)))
+ stab->qname.length)))
DBUG_RETURN(FALSE);
for (uint j= 0; j < stab->lock_count; j++)