summaryrefslogtreecommitdiff
path: root/sql/temporary_tables.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2019-02-06 18:01:29 -0800
committerIgor Babaev <igor@askmonty.org>2019-02-06 18:01:29 -0800
commit3f9040085a0de4976f55bc7e4a2fa5fa8d923100 (patch)
treecefa82212b688d12a7ca180f7a0a8f32715e2a79 /sql/temporary_tables.cc
parent16327fc2e76e9215059894b461e8aca7f989da00 (diff)
parente80bcd7f64fc8ff6f46c1fc0d01e9c0b0fd03064 (diff)
downloadmariadb-git-3f9040085a0de4976f55bc7e4a2fa5fa8d923100.tar.gz
Merge branch '10.4' into bb-10.4-mdev17096
Diffstat (limited to 'sql/temporary_tables.cc')
-rw-r--r--sql/temporary_tables.cc80
1 files changed, 48 insertions, 32 deletions
diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc
index f23ec7a1acc..917a85e6c3b 100644
--- a/sql/temporary_tables.cc
+++ b/sql/temporary_tables.cc
@@ -1041,39 +1041,28 @@ TABLE *THD::find_temporary_table(const char *key, uint key_length,
/* A matching TMP_TABLE_SHARE is found. */
All_share_tables_list::Iterator tables_it(share->all_tmp_tables);
- while ((table= tables_it++))
+ bool found= false;
+ while (!found && (table= tables_it++))
{
switch (state)
{
- case TMP_TABLE_IN_USE:
- if (table->query_id > 0)
- {
- result= table;
- goto done;
- }
- break;
- case TMP_TABLE_NOT_IN_USE:
- if (table->query_id == 0)
- {
- result= table;
- goto done;
- }
- break;
- case TMP_TABLE_ANY:
- {
- result= table;
- goto done;
- }
- break;
- default: /* Invalid */
- DBUG_ASSERT(0);
- goto done;
+ case TMP_TABLE_IN_USE: found= table->query_id > 0; break;
+ case TMP_TABLE_NOT_IN_USE: found= table->query_id == 0; break;
+ case TMP_TABLE_ANY: found= true; break;
}
}
+ if (table && unlikely(table->m_needs_reopen))
+ {
+ share->all_tmp_tables.remove(table);
+ free_temporary_table(table);
+ it.rewind();
+ continue;
+ }
+ result= table;
+ break;
}
}
-done:
if (locked)
{
DBUG_ASSERT(m_tmp_tables_locked);
@@ -1154,8 +1143,7 @@ TABLE *THD::open_temporary_table(TMP_TABLE_SHARE *share,
@return Success false
Failure true
*/
-bool THD::find_and_use_tmp_table(const TABLE_LIST *tl,
- TABLE **out_table)
+bool THD::find_and_use_tmp_table(const TABLE_LIST *tl, TABLE **out_table)
{
DBUG_ENTER("THD::find_and_use_tmp_table");
@@ -1165,11 +1153,9 @@ bool THD::find_and_use_tmp_table(const TABLE_LIST *tl,
key_length= create_tmp_table_def_key(key, tl->get_db_name(),
tl->get_table_name());
- result=
- use_temporary_table(find_temporary_table(key, key_length,
- TMP_TABLE_NOT_IN_USE),
- out_table);
-
+ result= use_temporary_table(find_temporary_table(key, key_length,
+ TMP_TABLE_NOT_IN_USE),
+ out_table);
DBUG_RETURN(result);
}
@@ -1540,3 +1526,33 @@ void THD::unlock_temporary_tables()
DBUG_VOID_RETURN;
}
+
+/**
+ Close unused TABLE instances for given temporary table.
+
+ @param tl [IN] TABLE_LIST
+
+ Initial use case was TRUNCATE, which expects only one instance (which is used
+ by TRUNCATE itself) to be open. Most probably some ALTER TABLE variants and
+ REPAIR may have similar expectations.
+*/
+
+void THD::close_unused_temporary_table_instances(const TABLE_LIST *tl)
+{
+ TMP_TABLE_SHARE *share= find_tmp_table_share(tl);
+
+ if (share)
+ {
+ All_share_tables_list::Iterator tables_it(share->all_tmp_tables);
+
+ while (TABLE *table= tables_it++)
+ {
+ if (table->query_id == 0)
+ {
+ /* Note: removing current list element doesn't invalidate iterator. */
+ share->all_tmp_tables.remove(table);
+ free_temporary_table(table);
+ }
+ }
+ }
+}