diff --git a/mysql-test/main/information_schema_temp_table.result b/mysql-test/main/information_schema_temp_table.result index 7591c4eca8a..125bdd99660 100644 --- a/mysql-test/main/information_schema_temp_table.result +++ b/mysql-test/main/information_schema_temp_table.result @@ -200,17 +200,34 @@ show index in t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored t 1 b 1 b A NULL NULL NULL YES BTREE NO drop database mysqltest; +use test; +show full tables; +Tables_in_test Table_type +tmp_innodb_in_test TEMPORARY TABLE +select * from tmp_innodb_in_test, tmp_innodb_in_test x; +a a +show full tables; +Tables_in_test Table_type +tmp_innodb_in_test TEMPORARY TABLE +drop temporary tables tmp_innodb_in_test; +create temporary table foo.t1 (a int); +select table_schema, table_name from information_schema.tables where table_type='temporary'; +table_schema table_name +foo t1 +mysqltest tmp_table +mysqltest t +my_db t_temp +drop temporary table foo.t1; # # MDEV-28351 Assertion `this->file->children_attached' failed in ha_myisammrg::info # -use test; CREATE TABLE t1 (a INT) ENGINE=MyISAM; insert into t1 values (1); CREATE TEMPORARY TABLE t2 (a INT) ENGINE=MERGE UNION=(t1); CREATE TABLE t3 (a INT) ENGINE=MERGE UNION=(t1); SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test'; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY -def test tmp_innodb_in_test TEMPORARY InnoDB 10 Dynamic 0 0 X X X X NULL X X NULL latin1_swedish_ci NULL X Y -def test t3 BASE TABLE MRG_MyISAM 10 Fixed 1 5 X X X X NULL X X NULL latin1_swedish_ci NULL X N def test t1 BASE TABLE MyISAM 10 Fixed 1 7 X X X X NULL X X NULL latin1_swedish_ci NULL X N +def test t2 TEMPORARY MRG_MyISAM 10 Fixed 0 0 X X X X NULL X X NULL latin1_swedish_ci NULL X Y +def test t3 BASE TABLE MRG_MyISAM 10 Fixed 1 5 X X X X NULL X X NULL latin1_swedish_ci NULL X N DROP TABLE t1,t2,t3; diff --git a/mysql-test/main/information_schema_temp_table.test b/mysql-test/main/information_schema_temp_table.test index d9dfc9977da..62e7a9ffd81 100644 --- a/mysql-test/main/information_schema_temp_table.test +++ b/mysql-test/main/information_schema_temp_table.test @@ -195,15 +195,27 @@ show index in t; # Cleanup drop database mysqltest; +use test; + +# many instances of the table temp table: +show full tables; +select * from tmp_innodb_in_test, tmp_innodb_in_test x; +show full tables; +drop temporary tables tmp_innodb_in_test; + +# non-existent db +create temporary table foo.t1 (a int); # yup, that works +select table_schema, table_name from information_schema.tables where table_type='temporary'; +drop temporary table foo.t1; --echo # --echo # MDEV-28351 Assertion `this->file->children_attached' failed in ha_myisammrg::info --echo # -use test; CREATE TABLE t1 (a INT) ENGINE=MyISAM; insert into t1 values (1); CREATE TEMPORARY TABLE t2 (a INT) ENGINE=MERGE UNION=(t1); CREATE TABLE t3 (a INT) ENGINE=MERGE UNION=(t1); +--sorted_result --replace_column 10 X 11 X 12 X 13 X 15 X 16 X 22 X SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test'; DROP TABLE t1,t2,t3; diff --git a/mysql-test/suite/engines/funcs/r/rpl_row_drop.result b/mysql-test/suite/engines/funcs/r/rpl_row_drop.result index 8753764e81e..8546960b7fb 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_row_drop.result +++ b/mysql-test/suite/engines/funcs/r/rpl_row_drop.result @@ -6,6 +6,7 @@ CREATE TABLE t2 (a int); CREATE TEMPORARY TABLE t2 (a int, b int); SHOW TABLES; Tables_in_test +t2 t1 t2 connection slave; @@ -28,6 +29,7 @@ connection master; CREATE TEMPORARY TABLE t2 (a int, b int); SHOW TABLES; Tables_in_test +t2 t1 t2 connection slave; diff --git a/scripts/sys_schema/procedures/table_exists.sql b/scripts/sys_schema/procedures/table_exists.sql index aa66c2f3c59..3224c87e749 100644 --- a/scripts/sys_schema/procedures/table_exists.sql +++ b/scripts/sys_schema/procedures/table_exists.sql @@ -154,21 +154,18 @@ BEGIN DECLARE db_quoted VARCHAR(64); DECLARE table_quoted VARCHAR(64); DECLARE v_table_type VARCHAR(30) DEFAULT ''; - DECLARE v_table_type_num INT; DECLARE CONTINUE HANDLER FOR 1050 SET v_error = TRUE; DECLARE CONTINUE HANDLER FOR 1146 SET v_error = TRUE; -- First check do we have multiple rows, what can happen if temporary table -- and/or sequence is shadowing base table for example. -- In such scenario return temporary. - SET v_table_type_num = (SELECT COUNT(TABLE_TYPE) FROM information_schema.TABLES WHERE + SET v_table_type = (SELECT GROUP_CONCAT(TABLE_TYPE) FROM information_schema.TABLES WHERE TABLE_SCHEMA = in_db AND TABLE_NAME = in_table); - IF v_table_type_num > 1 THEN + IF v_table_type LIKE '%,%' THEN SET out_exists = 'TEMPORARY'; ELSE - SET v_table_type = (SELECT TABLE_TYPE FROM information_schema.TABLES WHERE - TABLE_SCHEMA = in_db AND TABLE_NAME = in_table); IF v_table_type is NULL THEN SET v_table_type=''; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index ee552a52db2..23f5702c546 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4764,10 +4764,10 @@ restart: { TABLE *tbl= tables->table; + /* Schema tables may not have a TABLE object here. */ if (!tbl) continue; - /* Schema tables may not have a TABLE object here. */ if (tbl->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE) { /* MERGE tables need to access parent and child TABLE_LISTs. */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a6c3a4e845a..0ddd589b6a7 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -70,7 +70,6 @@ #include "lex_symbol.h" #define KEYWORD_SIZE 64 -#define IS_USER_TEMP_TABLE(A) (A->tmp_table != NO_TMP_TABLE) extern SYMBOL symbols[]; extern size_t symbols_length; @@ -5310,15 +5309,58 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) goto err; } + /* Use tmp_mem_root to allocate data for opened tables */ + init_alloc_root(PSI_INSTRUMENT_ME, &tmp_mem_root, SHOW_ALLOC_BLOCK_SIZE, + SHOW_ALLOC_BLOCK_SIZE, MY_THREAD_SPECIFIC); + + /* + Separate handling for session temporary tables from the backup state + for table IS.tables and SHOW TABLES commands. + */ + if ((schema_table_idx == SCH_TABLES || schema_table_idx == SCH_TABLE_NAMES) && + open_tables_state_backup.temporary_tables) + { + All_tmp_tables_list::Iterator it(*open_tables_state_backup.temporary_tables); + TMP_TABLE_SHARE *share_temp; + const char *lookup_db= plan->lookup_field_vals.db_value.str; + int (*cmp)(CHARSET_INFO *, const char *, const char *)= + plan->lookup_field_vals.wild_db_value + ? wild_case_compare : system_charset_info->coll->strcasecmp; + while ((share_temp= it++)) + { + if (lookup_db) + { + if (cmp(system_charset_info, share_temp->db.str, lookup_db)) + continue; + } + + TABLE *tmp_tbl= share_temp->all_tmp_tables.front(); + if (schema_table_idx == SCH_TABLE_NAMES) + { + LEX_CSTRING *table_name= &tmp_tbl->s->table_name; + restore_record(table, s->default_values); + table->field[1]->store(share_temp->db.str, share_temp->db.length, + system_charset_info); + table->field[2]->store(table_name->str, table_name->length, + system_charset_info); + if (tmp_tbl->s->table_type == TABLE_TYPE_SEQUENCE) + table->field[3]->store(STRING_WITH_LEN("TEMPORARY SEQUENCE"), + system_charset_info); + else + table->field[3]->store(STRING_WITH_LEN("TEMPORARY TABLE"), + system_charset_info); + schema_table_store_record(thd, table); + } + else /* SCH_TABLE */ + process_i_s_table_temporary_tables(thd, table, tmp_tbl); + } + } + bzero((char*) &table_acl_check, sizeof(table_acl_check)); if (make_db_list(thd, &db_names, &plan->lookup_field_vals)) goto err; - /* Use tmp_mem_root to allocate data for opened tables */ - init_alloc_root(PSI_INSTRUMENT_ME, &tmp_mem_root, SHOW_ALLOC_BLOCK_SIZE, - SHOW_ALLOC_BLOCK_SIZE, MY_THREAD_SPECIFIC); - for (size_t i=0; i < db_names.elements(); i++) { LEX_CSTRING *db_name= db_names.at(i); @@ -5333,64 +5375,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { Dynamic_array table_names(PSI_INSTRUMENT_MEM); - /* Separate handling for session temporary tables from the backup state - for table IS.tables and SHOW TABLES commands. - */ - if ((schema_table_idx == SCH_TABLES || schema_table_idx == SCH_TABLE_NAMES) && - open_tables_state_backup.temporary_tables) - { - All_tmp_tables_list::Iterator it(*open_tables_state_backup.temporary_tables); - TMP_TABLE_SHARE *share_temp; - while ((share_temp= it++)) - { - DBUG_ASSERT(IS_USER_TEMP_TABLE(share_temp)); - if (my_strcasecmp(system_charset_info, db_name->str, - share_temp->db.str)) - continue; - - All_share_tables_list::Iterator it2(share_temp->all_tmp_tables); - while (TABLE *tmp_tbl= it2++) - { - if (schema_table_idx == SCH_TABLE_NAMES) - { - LEX_CSTRING *table_name= &tmp_tbl->s->table_name; - restore_record(table, s->default_values); - table->field[schema_table->idx_field1]-> - store(db_name->str, db_name->length, system_charset_info); - table->field[schema_table->idx_field2]-> - store(table_name->str, table_name->length, - system_charset_info); - if (tmp_tbl->s->table_type == TABLE_TYPE_SEQUENCE) - table->field[3]->store(STRING_WITH_LEN("TEMPORARY SEQUENCE"), - system_charset_info); - else - table->field[3]->store(STRING_WITH_LEN("TEMPORARY TABLE"), - system_charset_info); - schema_table_store_record(thd, table); - } - else /* SCH_TABLE */ - { - if (tmp_tbl->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE) - { - /* - MyISAM MERGE table. We have to to call open on it and its - children - */ - LEX_CSTRING table_name= - { tmp_tbl->alias.ptr(), tmp_tbl->alias.length() }; - if (fill_schema_table_by_open(thd, &tmp_mem_root, FALSE, - table, schema_table, - &tmp_tbl->s->db, &table_name, - &open_tables_state_backup, - 0)) - goto err; - } - else - process_i_s_table_temporary_tables(thd, table, tmp_tbl); - } - } - } - } int res= make_table_name_list(thd, &table_names, lex, &plan->lookup_field_vals, db_name); if (unlikely(res == 2)) /* Not fatal error, continue */ @@ -5655,11 +5639,11 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, if (share->tmp_table == SYSTEM_TMP_TABLE) table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs); - else if (IS_USER_TEMP_TABLE(share) && share->table_type == TABLE_TYPE_SEQUENCE) + else if (share->tmp_table && share->table_type == TABLE_TYPE_SEQUENCE) table->field[3]->store(STRING_WITH_LEN("TEMPORARY SEQUENCE"), cs); else if (share->table_type == TABLE_TYPE_SEQUENCE) table->field[3]->store(STRING_WITH_LEN("SEQUENCE"), cs); - else if (IS_USER_TEMP_TABLE(share)) + else if (share->tmp_table) table->field[3]->store(STRING_WITH_LEN("TEMPORARY"), cs); else { diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 8d03320ea58..b46d0312d31 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -1273,7 +1273,6 @@ int ha_myisammrg::delete_all_rows() int ha_myisammrg::info(uint flag) { MYMERGE_INFO mrg_info; - DBUG_ASSERT(this->file->children_attached); (void) myrg_status(file,&mrg_info,flag); /* The following fails if one has not compiled MySQL with -DBIG_TABLES diff --git a/storage/myisammrg/myrg_info.c b/storage/myisammrg/myrg_info.c index 1d78c65066d..9cb5988d700 100644 --- a/storage/myisammrg/myrg_info.c +++ b/storage/myisammrg/myrg_info.c @@ -44,42 +44,45 @@ int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag) MYRG_TABLE *file; info->records=info->del=info->data_file_length=0; - for (file=info->open_tables ; file != info->end_table ; file++) + if (likely(info->children_attached)) { - file->file_offset=info->data_file_length; - info->data_file_length+=file->table->s->state.state.data_file_length; - info->records+=file->table->s->state.state.records; - info->del+=file->table->s->state.state.del; - DBUG_PRINT("info2",("table: %s, offset: %lu", - file->table->filename,(ulong) file->file_offset)); + for (file=info->open_tables ; file != info->end_table ; file++) + { + file->file_offset=info->data_file_length; + info->data_file_length+=file->table->s->state.state.data_file_length; + info->records+=file->table->s->state.state.records; + info->del+=file->table->s->state.state.del; + DBUG_PRINT("info2",("table: %s, offset: %lu", + file->table->filename,(ulong) file->file_offset)); + } + if (current_table) + { + /* + errkey is set to the index number of the myisam tables. But + since the MERGE table can have less keys than the MyISAM + tables, errkey cannot be be used as an index into the key_info + on the server. This value will be overwritten with MAX_KEY by + the MERGE engine. + */ + x->errkey= current_table->table->errkey; + /* + Calculate the position of the duplicate key to be the sum of the + offset of the myisam file and the offset into the file at which + the duplicate key is located. + */ + x->dupp_key_pos= current_table->file_offset + current_table->table->dupp_key_pos; + } + else + { + x->errkey= 0; + x->dupp_key_pos= 0; + } } x->records= info->records; x->deleted= info->del; x->data_file_length= info->data_file_length; x->reclength= info->reclength; x->options= info->options; - if (current_table) - { - /* - errkey is set to the index number of the myisam tables. But - since the MERGE table can have less keys than the MyISAM - tables, errkey cannot be be used as an index into the key_info - on the server. This value will be overwritten with MAX_KEY by - the MERGE engine. - */ - x->errkey= current_table->table->errkey; - /* - Calculate the position of the duplicate key to be the sum of the - offset of the myisam file and the offset into the file at which - the duplicate key is located. - */ - x->dupp_key_pos= current_table->file_offset + current_table->table->dupp_key_pos; - } - else - { - x->errkey= 0; - x->dupp_key_pos= 0; - } x->rec_per_key = info->rec_per_key_part; } DBUG_RETURN(0);