1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-5535: Cannot reopen temporary table

mysqld maintains a list of TABLE objects for all temporary
tables created within a session in THD. Here each table is
represented by a TABLE object.

A query referencing a particular temporary table for more
than once, however, failed with ER_CANT_REOPEN_TABLE error
because a TABLE_SHARE was allocate together with the TABLE,
so temporary tables always had only one TABLE per TABLE_SHARE.

This patch lift this restriction by separating TABLE and
TABLE_SHARE objects and storing TABLE_SHAREs for temporary
tables in a list in THD, and TABLEs in a list within their
respective TABLE_SHAREs.
This commit is contained in:
Nirbhay Choubey
2016-06-10 16:19:59 -04:00
parent 547511153f
commit 7305be2f7e
50 changed files with 2315 additions and 1260 deletions

View File

@ -1999,36 +1999,32 @@ lookup:
for (; block_table != block_table_end; block_table++)
{
TABLE_LIST table_list;
TABLE *tmptable;
TMP_TABLE_SHARE *tmptable;
Query_cache_table *table = block_table->parent;
/*
Check that we have not temporary tables with same names of tables
of this query. If we have such tables, we will not send data from
query cache, because temporary tables hide real tables by which
Check that we do not have temporary tables with same names as that of
base tables from this query. If we have such tables, we will not send
data from query cache, because temporary tables hide real tables by which
query in query cache was made.
*/
for (tmptable= thd->temporary_tables; tmptable ; tmptable= tmptable->next)
if ((tmptable=
thd->find_tmp_table_share_w_base_key((char *) table->data(),
table->key_length())))
{
if (tmptable->s->table_cache_key.length - TMP_TABLE_KEY_EXTRA ==
table->key_length() &&
!memcmp(tmptable->s->table_cache_key.str, table->data(),
table->key_length()))
{
DBUG_PRINT("qcache",
("Temporary table detected: '%s.%s'",
tmptable->s->db.str, tmptable->alias.c_ptr()));
unlock();
/*
We should not store result of this query because it contain
temporary tables => assign following variable to make check
faster.
*/
thd->query_cache_is_applicable= 0; // Query can't be cached
thd->lex->safe_to_cache_query= 0; // For prepared statements
BLOCK_UNLOCK_RD(query_block);
DBUG_RETURN(-1);
}
DBUG_PRINT("qcache",
("Temporary table detected: '%s.%s'",
tmptable->db.str, tmptable->table_name.str));
unlock();
/*
We should not store result of this query because it contain
temporary tables => assign following variable to make check
faster.
*/
thd->query_cache_is_applicable= 0; // Query can't be cached
thd->lex->safe_to_cache_query= 0; // For prepared statements
BLOCK_UNLOCK_RD(query_block);
DBUG_RETURN(-1);
}
bzero((char*) &table_list,sizeof(table_list));