#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/sql/handler.h b/sql/handler.h
---- a/sql/handler.h 2011-04-09 19:11:53.000000000 +0400
-+++ b/sql/handler.h 2011-04-10 12:16:43.000000000 +0400
-@@ -567,6 +567,7 @@
+--- a/sql/handler.h
++++ b/sql/handler.h
+@@ -570,6 +570,7 @@
SCH_EVENTS,
SCH_FILES,
SCH_GLOBAL_STATUS,
SCH_GLOBAL_VARIABLES,
SCH_KEY_COLUMN_USAGE,
SCH_OPEN_TABLES,
-@@ -588,6 +589,7 @@
+@@ -591,6 +592,7 @@
SCH_TABLE_CONSTRAINTS,
SCH_TABLE_NAMES,
SCH_TABLE_PRIVILEGES,
SCH_TRIGGERS,
SCH_USER_PRIVILEGES,
SCH_VARIABLES,
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2011-04-09 19:11:52.000000000 +0400
-+++ b/sql/mysqld.cc 2011-04-10 12:16:44.000000000 +0400
-@@ -3055,6 +3055,7 @@
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -2951,6 +2951,7 @@
{"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
{"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
{"show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
{"show_triggers", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
{"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
{"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
-diff -ruN a/sql/sql_lex.h b/sql/sql_lex.h
---- a/sql/sql_lex.h 2011-03-31 17:36:18.000000000 +0400
-+++ b/sql/sql_lex.h 2011-04-10 12:22:19.000000000 +0400
+@@ -7670,6 +7671,7 @@
+ PSI_mutex_key key_LOCK_des_key_file;
+ #endif /* HAVE_OPENSSL */
+
++PSI_mutex_key key_LOCK_temporary_tables;
+ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids,
+ key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
+ key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
+@@ -7723,6 +7725,7 @@
+ { &key_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
+ { &key_LOCK_table_share, "LOCK_table_share", PSI_FLAG_GLOBAL},
+ { &key_LOCK_thd_data, "THD::LOCK_thd_data", 0},
++ { &key_LOCK_temporary_tables, "THD::LOCK_temporary_tables", 0},
+ { &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL},
+ { &key_LOCK_uuid_generator, "LOCK_uuid_generator", PSI_FLAG_GLOBAL},
+ { &key_LOG_LOCK_log, "LOG::LOCK_log", 0},
+--- a/sql/sql_lex.h
++++ b/sql/sql_lex.h
@@ -194,6 +194,7 @@
When a command is added here, be sure it's also added in mysqld.cc
in "struct show_var_st status_vars[]= {" ...
/* This should be the last !!! */
SQLCOM_END
};
-diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
---- a/sql/sql_parse.cc 2011-03-31 17:36:18.000000000 +0400
-+++ b/sql/sql_parse.cc 2011-04-10 12:16:44.000000000 +0400
+--- a/sql/sql_parse.cc
++++ b/sql/sql_parse.cc
@@ -348,6 +348,9 @@
sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
CF_SHOW_TABLE_COMMAND |
sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
CF_SHOW_TABLE_COMMAND |
CF_REEXECUTION_FRAGILE);
-@@ -1510,6 +1513,8 @@
+@@ -1520,6 +1523,8 @@
case SCH_TABLE_NAMES:
case SCH_TABLES:
case SCH_VIEWS:
case SCH_TRIGGERS:
case SCH_EVENTS:
-@@ -2017,6 +2022,7 @@
+@@ -2110,6 +2115,7 @@
}
case SQLCOM_SHOW_DATABASES:
case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_TRIGGERS:
case SQLCOM_SHOW_TABLE_STATUS:
case SQLCOM_SHOW_OPEN_TABLES:
-@@ -4797,6 +4803,8 @@
+@@ -4919,6 +4925,8 @@
case SCH_TABLE_NAMES:
case SCH_TABLES:
case SCH_VIEWS:
case SCH_TRIGGERS:
case SCH_EVENTS:
-diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
---- a/sql/sql_show.cc 2011-04-09 19:11:52.000000000 +0400
-+++ b/sql/sql_show.cc 2011-04-10 12:16:44.000000000 +0400
-@@ -2686,6 +2686,7 @@
+--- a/sql/sql_show.cc
++++ b/sql/sql_show.cc
+@@ -2692,6 +2692,7 @@
break;
case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_TABLE_STATUS:
case SQLCOM_SHOW_TRIGGERS:
case SQLCOM_SHOW_EVENTS:
thd->make_lex_string(&lookup_field_values->db_value,
-@@ -3174,6 +3175,228 @@
+@@ -3283,6 +3284,231 @@
return (uint) OPEN_FULL_TABLE;
}
+#endif
+
+ while ((thd_item=it++)) {
++ mysql_mutex_lock(&thd_item->LOCK_temporary_tables);
+ for (tmp=thd_item->temporary_tables; tmp; tmp=tmp->next) {
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+
+ if (store_temporary_table_record(thd_item, tables->table, tmp, thd->lex->select_lex.db, table_names_only)) {
+ tmp->in_use= t;
++ mysql_mutex_unlock(&thd_item->LOCK_temporary_tables);
+ mysql_mutex_unlock(&LOCK_thread_count);
+ DBUG_RETURN(1);
+ }
+
+ tmp->in_use= t;
+ }
++ mysql_mutex_unlock(&thd_item->LOCK_temporary_tables);
+ }
+
+ mysql_mutex_unlock(&LOCK_thread_count);
/**
Try acquire high priority share metadata lock on a table (with
-@@ -6850,6 +7073,25 @@
+@@ -7046,6 +7272,25 @@
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
ST_FIELD_INFO columns_fields_info[]=
{
-@@ -7464,6 +7706,9 @@
+@@ -7660,6 +7905,9 @@
hton_fill_schema_table, 0, 0, -1, -1, 0, 0},
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
fill_status, make_old_format, 0, 0, -1, 0, 0},
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
fill_variables, make_old_format, 0, 0, -1, 0, 0},
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
-@@ -7513,6 +7758,9 @@
+@@ -7709,6 +7957,9 @@
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
{"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
{"TRIGGERS", triggers_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
OPEN_TRIGGER_ONLY|OPTIMIZE_I_S_TABLE},
-diff -ruN a/sql/sql_yacc.yy b/sql/sql_yacc.yy
---- a/sql/sql_yacc.yy 2011-03-31 17:36:18.000000000 +0400
-+++ b/sql/sql_yacc.yy 2011-04-10 12:16:43.000000000 +0400
-@@ -10869,6 +10869,15 @@
+--- a/sql/sql_yacc.yy
++++ b/sql/sql_yacc.yy
+@@ -10898,6 +10898,15 @@
if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES))
MYSQL_YYABORT;
}
| opt_full TRIGGERS_SYM opt_db wild_and_where
{
LEX *lex= Lex;
+--- a/sql/mysqld.h
++++ b/sql/mysqld.h
+@@ -234,6 +234,7 @@
+ extern PSI_mutex_key key_LOCK_des_key_file;
+ #endif
+
++extern PSI_mutex_key key_LOCK_temporary_tables;
+ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids,
+ key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
+ key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
+--- a/sql/sql_base.cc
++++ b/sql/sql_base.cc
+@@ -1651,12 +1651,16 @@
+ if (!mysql_bin_log.is_open())
+ {
+ TABLE *tmp_next;
++
++ mysql_mutex_lock(&thd->LOCK_temporary_tables);
+ for (table= thd->temporary_tables; table; table= tmp_next)
+ {
+ tmp_next= table->next;
+ close_temporary(table, 1, 1);
+ }
+ thd->temporary_tables= 0;
++ mysql_mutex_unlock(&thd->LOCK_temporary_tables);
++
+ DBUG_RETURN(FALSE);
+ }
+
+@@ -1669,6 +1673,8 @@
+
+ memcpy(buf, stub, stub_len);
+
++ mysql_mutex_lock(&thd->LOCK_temporary_tables);
++
+ /*
+ Insertion sort of temp tables by pseudo_thread_id to build ordered list
+ of sublists of equal pseudo_thread_id
+@@ -1790,6 +1796,8 @@
+ thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
+ thd->temporary_tables=0;
+
++ mysql_mutex_unlock(&thd->LOCK_temporary_tables);
++
+ DBUG_RETURN(error);
+ }
+
+@@ -2167,6 +2175,8 @@
+ table->s->db.str, table->s->table_name.str,
+ (long) table, table->alias));
+
++ mysql_mutex_lock(&thd->LOCK_temporary_tables);
++
+ if (table->prev)
+ {
+ table->prev->next= table->next;
+@@ -2193,6 +2203,9 @@
+ slave_open_temp_tables--;
+ }
+ close_temporary(table, free_share, delete_table);
++
++ mysql_mutex_unlock(&thd->LOCK_temporary_tables);
++
+ DBUG_VOID_RETURN;
+ }
+
+@@ -5932,6 +5945,7 @@
+ if (add_to_temporary_tables_list)
+ {
+ /* growing temp list at the head */
++ mysql_mutex_lock(&thd->LOCK_temporary_tables);
+ tmp_table->next= thd->temporary_tables;
+ if (tmp_table->next)
+ tmp_table->next->prev= tmp_table;
+@@ -5939,6 +5953,7 @@
+ thd->temporary_tables->prev= 0;
+ if (thd->slave_thread)
+ slave_open_temp_tables++;
++ mysql_mutex_unlock(&thd->LOCK_temporary_tables);
+ }
+ tmp_table->pos_in_table_list= 0;
+ DBUG_PRINT("tmptable", ("opened table: '%s'.'%s' 0x%lx", tmp_table->s->db.str,
+--- a/sql/sql_class.cc
++++ b/sql/sql_class.cc
+@@ -836,6 +836,8 @@
+ active_vio = 0;
+ #endif
+ mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST);
++ mysql_mutex_init(key_LOCK_temporary_tables, &LOCK_temporary_tables,
++ MY_MUTEX_INIT_FAST);
+
+ /* Variables with default values */
+ proc_info="login";
+@@ -1348,6 +1350,7 @@
+ db= NULL;
+ free_root(&transaction.mem_root,MYF(0));
+ mysql_mutex_destroy(&LOCK_thd_data);
++ mysql_mutex_destroy(&LOCK_temporary_tables);
+ #ifndef DBUG_OFF
+ dbug_sentry= THD_SENTRY_GONE;
+ #endif
+--- a/sql/sql_class.h
++++ b/sql/sql_class.h
+@@ -1002,6 +1002,11 @@
+ XXX Why are internal temporary tables added to this list?
+ */
+ TABLE *temporary_tables;
++ /**
++ Protects temporary_tables.
++ */
++ mysql_mutex_t LOCK_temporary_tables;
++
+ TABLE *derived_tables;
+ /*
+ During a MySQL session, one can lock tables in two modes: automatic
+--- /dev/null
++++ b/mysql-test/r/percona_show_temp_tables.result
+@@ -0,0 +1,58 @@
++drop table if exists t1,t2,t3;
++drop database if exists showtemp;
++create database if not exists showtemp;
++use test;
++create temporary table t1(id int);
++create temporary table t2(id int);
++create temporary table showtemp.t3(id int);
++insert into t1 values(10),(20),(30),(40);
++insert into showtemp.t3 values(999);
++show temporary tables;
++Temp_tables_in_test
++t2
++t1
++show temporary tables from test;
++Temp_tables_in_test
++t2
++t1
++show temporary tables in showtemp;
++Temp_tables_in_showtemp
++t3
++select table_schema, table_name, engine, table_rows from Information_schema.temporary_tables;
++table_schema table_name engine table_rows
++showtemp t3 MyISAM 1
++test t2 MyISAM 0
++test t1 MyISAM 4
++select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
++table_schema table_name engine table_rows
++showtemp t3 MyISAM 1
++test t2 MyISAM 0
++test t1 MyISAM 4
++select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables where table_schema='showtemp';
++table_schema table_name engine table_rows
++showtemp t3 MyISAM 1
++select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables where table_schema='temp';
++table_schema table_name engine table_rows
++drop table if exists showtemp.t2;
++create temporary table t1(id int);
++create temporary table showtemp.t2(id int);
++show temporary tables;
++Temp_tables_in_test
++t1
++select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
++table_schema table_name engine table_rows
++showtemp t2 MyISAM 0
++test t1 MyISAM 0
++showtemp t3 MyISAM 1
++test t2 MyISAM 0
++test t1 MyISAM 4
++drop table showtemp.t2;
++drop table t1;
++select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
++table_schema table_name engine table_rows
++showtemp t3 MyISAM 1
++test t2 MyISAM 0
++test t1 MyISAM 4
++drop table t1, t2;
++drop table showtemp.t3;
++drop database showtemp;
+--- /dev/null
++++ b/mysql-test/t/percona_show_temp_tables.test
+@@ -0,0 +1,65 @@
++# Uses GRANT commands that usually disabled in embedded server
++-- source include/not_embedded.inc
++
++# Save the initial number of concurrent sessions
++--source include/count_sessions.inc
++
++#
++# Test of SHOW [GLOBAL] TEMPORARY TABLES [FROM/IN] DB and
++# Information_schema.temporary_tables and global_temporary_tables
++#
++
++connect(stcon1,localhost,root,,test);
++connect(stcon2,localhost,root,,test);
++
++connection stcon1;
++
++--disable_warnings
++drop table if exists t1,t2,t3;
++drop database if exists showtemp;
++create database if not exists showtemp;
++--enable_warnings
++
++use test;
++create temporary table t1(id int);
++create temporary table t2(id int);
++create temporary table showtemp.t3(id int);
++insert into t1 values(10),(20),(30),(40);
++insert into showtemp.t3 values(999);
++
++show temporary tables;
++# "Session" is not same value always. mysql-test cannot test it always.
++#show global temporary tables;
++show temporary tables from test;
++show temporary tables in showtemp;
++select table_schema, table_name, engine, table_rows from Information_schema.temporary_tables;
++select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
++select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables where table_schema='showtemp';
++select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables where table_schema='temp';
++
++connection stcon2;
++
++--disable_warnings
++drop table if exists showtemp.t2;
++--enable_warnings
++create temporary table t1(id int);
++create temporary table showtemp.t2(id int);
++show temporary tables;
++select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
++drop table showtemp.t2;
++drop table t1;
++
++disconnect stcon2;
++
++connection stcon1;
++select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
++
++drop table t1, t2;
++drop table showtemp.t3;
++drop database showtemp;
++
++connection default;
++disconnect stcon1;
++
++# Wait till all disconnects are completed
++--source include/wait_until_count_sessions.inc