1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-31 22:22:30 +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

@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
Copyright (c) 2008, 2015, MariaDB
Copyright (c) 2008, 2016, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,7 +23,10 @@
// set_handler_table_locks,
// lock_global_read_lock,
// make_global_read_lock_block_commit
#include "sql_base.h" // find_temporary_table
#include "sql_base.h" // open_tables, open_and_lock_tables,
// lock_tables, unique_table,
// close_thread_tables, is_temporary_table
// table_cache.h
#include "sql_cache.h" // QUERY_CACHE_FLAGS_SIZE, query_cache_*
#include "sql_show.h" // mysqld_list_*, mysqld_show_*,
// calc_sum_of_all_status
@@ -418,7 +421,7 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
for (TABLE_LIST *table= tables; table; table= table->next_global)
{
DBUG_ASSERT(table->db && table->table_name);
if (table->updating && !find_temporary_table(thd, table))
if (table->updating && !thd->find_tmp_table_share(table))
return 1;
}
return 0;
@@ -1967,7 +1970,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->set_query(fields, query_length);
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
if (open_temporary_tables(thd, &table_list))
if (thd->open_temporary_tables(&table_list))
break;
if (check_table_access(thd, SELECT_ACL, &table_list,
@@ -3264,7 +3267,7 @@ mysql_execute_command(THD *thd)
*/
if (sql_command_flags[lex->sql_command] & CF_PREOPEN_TMP_TABLES)
{
if (open_temporary_tables(thd, all_tables))
if (thd->open_temporary_tables(all_tables))
goto error;
}
@@ -4066,7 +4069,7 @@ end_with_restore_list:
Temporary tables should be opened for SHOW CREATE TABLE, but not
for SHOW CREATE VIEW.
*/
if (open_temporary_tables(thd, all_tables))
if (thd->open_temporary_tables(all_tables))
goto error;
/*
@@ -4274,7 +4277,8 @@ end_with_restore_list:
*/
if (first_table->lock_type != TL_WRITE_DELAYED)
{
if ((res= open_temporary_tables(thd, all_tables)))
res= (thd->open_temporary_tables(all_tables)) ? TRUE : FALSE;
if (res)
break;
}
@@ -4586,7 +4590,7 @@ end_with_restore_list:
{
if (!lex->tmp_table() &&
(!thd->is_current_stmt_binlog_format_row() ||
!find_temporary_table(thd, table)))
!thd->find_temporary_table(table)))
{
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables);
break;
@@ -4739,7 +4743,7 @@ end_with_restore_list:
CF_PREOPEN_TMP_TABLES was set and the tables would be pre-opened
in a usual way, they would have been closed.
*/
if (open_temporary_tables(thd, all_tables))
if (thd->open_temporary_tables(all_tables))
goto error;
if (lock_tables_precheck(thd, all_tables))
@@ -6780,7 +6784,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
/*
Open temporary tables to be able to detect them during privilege check.
*/
if (open_temporary_tables(thd, dst_table))
if (thd->open_temporary_tables(dst_table))
return TRUE;
if (check_access(thd, SELECT_ACL, dst_table->db,