Browse Source
MDEV-5535: Cannot reopen temporary table
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.pull/180/merge
50 changed files with 2313 additions and 1258 deletions
-
1libmysqld/CMakeLists.txt
-
3mysql-test/r/create.result
-
5mysql-test/r/lock.result
-
133mysql-test/r/reopen_temp_table.result
-
10mysql-test/r/sp.result
-
22mysql-test/suite/handler/aria.result
-
7mysql-test/suite/handler/handler.inc
-
22mysql-test/suite/handler/heap.result
-
22mysql-test/suite/handler/innodb.result
-
22mysql-test/suite/handler/myisam.result
-
30mysql-test/suite/rpl/r/rpl_reopen_temp_table.result
-
43mysql-test/suite/rpl/t/rpl_reopen_temp_table.test
-
1mysql-test/t/create.test
-
5mysql-test/t/lock.test
-
128mysql-test/t/reopen_temp_table.test
-
9mysql-test/t/sp.test
-
4sql/CMakeLists.txt
-
2sql/log_event.cc
-
51sql/rpl_rli.cc
-
2sql/rpl_rli.h
-
7sql/slave.cc
-
2sql/sp_head.cc
-
8sql/sql_admin.cc
-
6sql/sql_alter.cc
-
955sql/sql_base.cc
-
26sql/sql_base.h
-
44sql/sql_cache.cc
-
28sql/sql_class.cc
-
174sql/sql_class.h
-
5sql/sql_db.cc
-
14sql/sql_handler.cc
-
9sql/sql_insert.cc
-
24sql/sql_parse.cc
-
14sql/sql_partition_admin.cc
-
8sql/sql_prepare.cc
-
3sql/sql_show.cc
-
128sql/sql_table.cc
-
2sql/sql_test.cc
-
4sql/sql_trigger.cc
-
4sql/sql_view.cc
-
5sql/sys_vars.cc
-
2sql/table.cc
-
25sql/table.h
-
4sql/table_cache.cc
-
3sql/table_cache.h
-
1499sql/temporary_tables.cc
-
12sql/wsrep_applier.cc
-
23sql/wsrep_mysqld.cc
-
9sql/wsrep_thd.cc
-
2storage/spider/spd_direct_sql.cc
@ -0,0 +1,133 @@ |
|||
# |
|||
# MDEV-5535: Cannot reopen temporary table |
|||
# |
|||
DROP DATABASE IF EXISTS temp_db; |
|||
CREATE DATABASE temp_db; |
|||
USE temp_db; |
|||
# |
|||
# Reopen temporary table |
|||
# |
|||
CREATE TEMPORARY TABLE t1(i int)ENGINE=INNODB; |
|||
INSERT INTO t1 VALUES(1), (2); |
|||
SELECT * FROM t1 a, t1 b; |
|||
i i |
|||
1 1 |
|||
2 1 |
|||
1 2 |
|||
2 2 |
|||
DROP TABLE t1; |
|||
# |
|||
# CREATE & Stored routines |
|||
# |
|||
CREATE TEMPORARY TABLE t3 AS SELECT 1 AS a; |
|||
CREATE PROCEDURE p1() |
|||
BEGIN |
|||
DROP TEMPORARY TABLE t3; |
|||
end| |
|||
CREATE FUNCTION f3() RETURNS INT |
|||
BEGIN |
|||
CALL p1(); |
|||
RETURN 1; |
|||
END| |
|||
PREPARE STMT FROM "SELECT f3() AS my_Column, a FROM t3"; |
|||
EXECUTE STMT; |
|||
ERROR HY000: Can't reopen table: 't3' |
|||
DROP TABLE t3; |
|||
DROP FUNCTION f3; |
|||
DROP PROCEDURE p1; |
|||
CREATE TEMPORARY TABLE t4 (i INT); |
|||
INSERT INTO t4 VALUES(1), (2); |
|||
CREATE FUNCTION f4() RETURNS INT |
|||
BEGIN |
|||
DROP TEMPORARY TABLE t4; |
|||
RETURN 1; |
|||
END| |
|||
SELECT f4() FROM t4; |
|||
ERROR HY000: Can't reopen table: 't4' |
|||
SELECT * FROM t4; |
|||
i |
|||
1 |
|||
2 |
|||
DROP TABLE t4; |
|||
DROP FUNCTION f4; |
|||
CREATE TEMPORARY TABLE t5 AS SELECT 1 AS a; |
|||
CREATE PROCEDURE p2() |
|||
BEGIN |
|||
DROP TEMPORARY TABLE t5; |
|||
END| |
|||
CREATE FUNCTION f5() RETURNS INT |
|||
BEGIN |
|||
CALL p2(); |
|||
RETURN 1; |
|||
END| |
|||
SELECT f5() AS my_column, a FROM t5; |
|||
ERROR HY000: Can't reopen table: 't5' |
|||
DROP TABLE t5; |
|||
DROP FUNCTION f5; |
|||
DROP PROCEDURE p2; |
|||
# |
|||
# CTAS |
|||
# |
|||
CREATE TABLE t1(i INT); |
|||
INSERT INTO t1 VALUES(1), (2); |
|||
CREATE TEMPORARY TABLE t1 |
|||
SELECT temp_1.i a, temp_2.i b FROM t1 AS temp_1, t1 AS temp_2; |
|||
SELECT * FROM t1; |
|||
a b |
|||
1 1 |
|||
2 1 |
|||
1 2 |
|||
2 2 |
|||
DROP TABLE t1; |
|||
SELECT * FROM t1; |
|||
i |
|||
1 |
|||
2 |
|||
DROP TABLE t1; |
|||
# |
|||
# HANDLER |
|||
# |
|||
CREATE TABLE t1 (a INT, KEY a(a)); |
|||
INSERT INTO t1 (a) VALUES (1), (2), (3), (4), (5); |
|||
CREATE TABLE t2 (a INT, KEY a (a)) SELECT * FROM t1; |
|||
CREATE TEMPORARY TABLE t3 (a INT, KEY a (a)) SELECT * FROM t2; |
|||
HANDLER t3 OPEN; |
|||
SELECT * FROM t1; |
|||
a |
|||
1 |
|||
2 |
|||
3 |
|||
4 |
|||
5 |
|||
LOCK TABLE t1 READ; |
|||
HANDLER t3 OPEN; |
|||
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
|||
UNLOCK TABLES; |
|||
HANDLER t3 OPEN; |
|||
ERROR 42000: Not unique table/alias: 't3' |
|||
HANDLER t3 READ NEXT; |
|||
a |
|||
1 |
|||
HANDLER t3 OPEN AS t3_1; |
|||
HANDLER t3_1 READ NEXT; |
|||
a |
|||
1 |
|||
HANDLER t3_1 READ NEXT; |
|||
a |
|||
2 |
|||
HANDLER t3 CLOSE; |
|||
HANDLER t3_1 CLOSE; |
|||
DROP TEMPORARY TABLE t3; |
|||
DROP TABLE t1, t2; |
|||
# |
|||
# INSERT-SELECT |
|||
# |
|||
CREATE TEMPORARY TABLE t4 (a INT) ENGINE=MYISAM; |
|||
INSERT INTO t4 VALUES(1), (2); |
|||
INSERT INTO t4 SELECT * FROM t4; |
|||
SELECT COUNT(*) FROM t4; |
|||
COUNT(*) |
|||
4 |
|||
DROP TABLE t4; |
|||
# Cleanup |
|||
DROP DATABASE temp_db; |
|||
@ -0,0 +1,30 @@ |
|||
include/master-slave.inc |
|||
[connection master] |
|||
connection slave; |
|||
reset master; |
|||
# |
|||
# MDEV-5535: Cannot reopen temporary table |
|||
# |
|||
connection master; |
|||
DROP TABLE IF EXISTS t1, t2, t3; |
|||
CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=INNODB; |
|||
INSERT INTO t1 VALUES (1), (2), (3), (4), (5); |
|||
CREATE TEMPORARY TABLE t2 SELECT A.c1 a, B.c1 b FROM t1 AS A, t1 AS B; |
|||
CREATE TABLE t3 SELECT * FROM t2; |
|||
SELECT COUNT(*) = 5 FROM t1; |
|||
COUNT(*) = 5 |
|||
1 |
|||
SELECT COUNT(*) = 25 FROM t2; |
|||
COUNT(*) = 25 |
|||
1 |
|||
SELECT COUNT(*) = 25 FROM t3; |
|||
COUNT(*) = 25 |
|||
1 |
|||
connection slave; |
|||
SELECT COUNT(*) = 25 FROM t3; |
|||
COUNT(*) = 25 |
|||
1 |
|||
connection master; |
|||
DROP TABLE t1, t2, t3; |
|||
connection slave; |
|||
include/rpl_end.inc |
|||
@ -0,0 +1,43 @@ |
|||
--source include/have_innodb.inc |
|||
--source include/master-slave.inc |
|||
|
|||
# Clean up old slave's binlogs (see rpl_temporary.test for explanation). |
|||
save_master_pos; |
|||
connection slave; |
|||
sync_with_master; |
|||
reset master; |
|||
|
|||
--echo # |
|||
--echo # MDEV-5535: Cannot reopen temporary table |
|||
--echo # |
|||
|
|||
connection master; |
|||
--disable_query_log |
|||
CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); |
|||
--enable_query_log |
|||
|
|||
disable_warnings; |
|||
DROP TABLE IF EXISTS t1, t2, t3; |
|||
enable_warnings; |
|||
|
|||
CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=INNODB; |
|||
INSERT INTO t1 VALUES (1), (2), (3), (4), (5); |
|||
|
|||
CREATE TEMPORARY TABLE t2 SELECT A.c1 a, B.c1 b FROM t1 AS A, t1 AS B; |
|||
|
|||
CREATE TABLE t3 SELECT * FROM t2; |
|||
|
|||
SELECT COUNT(*) = 5 FROM t1; |
|||
SELECT COUNT(*) = 25 FROM t2; |
|||
SELECT COUNT(*) = 25 FROM t3; |
|||
|
|||
sync_slave_with_master; |
|||
|
|||
SELECT COUNT(*) = 25 FROM t3; |
|||
|
|||
connection master; |
|||
DROP TABLE t1, t2, t3; |
|||
|
|||
sync_slave_with_master; |
|||
|
|||
--source include/rpl_end.inc |
|||
@ -0,0 +1,128 @@ |
|||
--source include/have_innodb.inc |
|||
|
|||
--echo # |
|||
--echo # MDEV-5535: Cannot reopen temporary table |
|||
--echo # |
|||
|
|||
--disable_warnings |
|||
DROP DATABASE IF EXISTS temp_db; |
|||
--enable_warnings |
|||
|
|||
CREATE DATABASE temp_db; |
|||
USE temp_db; |
|||
|
|||
--echo # |
|||
--echo # Reopen temporary table |
|||
--echo # |
|||
|
|||
CREATE TEMPORARY TABLE t1(i int)ENGINE=INNODB; |
|||
INSERT INTO t1 VALUES(1), (2); |
|||
SELECT * FROM t1 a, t1 b; |
|||
DROP TABLE t1; |
|||
|
|||
--echo # |
|||
--echo # CREATE & Stored routines |
|||
--echo # |
|||
|
|||
CREATE TEMPORARY TABLE t3 AS SELECT 1 AS a; |
|||
DELIMITER |; |
|||
CREATE PROCEDURE p1() |
|||
BEGIN |
|||
DROP TEMPORARY TABLE t3; |
|||
end| |
|||
CREATE FUNCTION f3() RETURNS INT |
|||
BEGIN |
|||
CALL p1(); |
|||
RETURN 1; |
|||
END| |
|||
DELIMITER ;| |
|||
PREPARE STMT FROM "SELECT f3() AS my_Column, a FROM t3"; |
|||
--error ER_CANT_REOPEN_TABLE |
|||
EXECUTE STMT; |
|||
DROP TABLE t3; |
|||
DROP FUNCTION f3; |
|||
DROP PROCEDURE p1; |
|||
|
|||
CREATE TEMPORARY TABLE t4 (i INT); |
|||
INSERT INTO t4 VALUES(1), (2); |
|||
DELIMITER |; |
|||
CREATE FUNCTION f4() RETURNS INT |
|||
BEGIN |
|||
DROP TEMPORARY TABLE t4; |
|||
RETURN 1; |
|||
END| |
|||
DELIMITER ;| |
|||
--error ER_CANT_REOPEN_TABLE |
|||
SELECT f4() FROM t4; |
|||
SELECT * FROM t4; |
|||
DROP TABLE t4; |
|||
DROP FUNCTION f4; |
|||
|
|||
CREATE TEMPORARY TABLE t5 AS SELECT 1 AS a; |
|||
DELIMITER |; |
|||
CREATE PROCEDURE p2() |
|||
BEGIN |
|||
DROP TEMPORARY TABLE t5; |
|||
END| |
|||
CREATE FUNCTION f5() RETURNS INT |
|||
BEGIN |
|||
CALL p2(); |
|||
RETURN 1; |
|||
END| |
|||
DELIMITER ;| |
|||
--error ER_CANT_REOPEN_TABLE |
|||
SELECT f5() AS my_column, a FROM t5; |
|||
DROP TABLE t5; |
|||
DROP FUNCTION f5; |
|||
DROP PROCEDURE p2; |
|||
|
|||
--echo # |
|||
--echo # CTAS |
|||
--echo # |
|||
|
|||
CREATE TABLE t1(i INT); |
|||
INSERT INTO t1 VALUES(1), (2); |
|||
CREATE TEMPORARY TABLE t1 |
|||
SELECT temp_1.i a, temp_2.i b FROM t1 AS temp_1, t1 AS temp_2; |
|||
SELECT * FROM t1; |
|||
DROP TABLE t1; |
|||
SELECT * FROM t1; |
|||
DROP TABLE t1; |
|||
|
|||
--echo # |
|||
--echo # HANDLER |
|||
--echo # |
|||
|
|||
CREATE TABLE t1 (a INT, KEY a(a)); |
|||
INSERT INTO t1 (a) VALUES (1), (2), (3), (4), (5); |
|||
CREATE TABLE t2 (a INT, KEY a (a)) SELECT * FROM t1; |
|||
CREATE TEMPORARY TABLE t3 (a INT, KEY a (a)) SELECT * FROM t2; |
|||
HANDLER t3 OPEN; |
|||
SELECT * FROM t1; |
|||
LOCK TABLE t1 READ; |
|||
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
|||
HANDLER t3 OPEN; |
|||
UNLOCK TABLES; |
|||
--error ER_NONUNIQ_TABLE |
|||
HANDLER t3 OPEN; |
|||
HANDLER t3 READ NEXT; |
|||
HANDLER t3 OPEN AS t3_1; |
|||
HANDLER t3_1 READ NEXT; |
|||
HANDLER t3_1 READ NEXT; |
|||
HANDLER t3 CLOSE; |
|||
HANDLER t3_1 CLOSE; |
|||
DROP TEMPORARY TABLE t3; |
|||
DROP TABLE t1, t2; |
|||
|
|||
--echo # |
|||
--echo # INSERT-SELECT |
|||
--echo # |
|||
|
|||
CREATE TEMPORARY TABLE t4 (a INT) ENGINE=MYISAM; |
|||
INSERT INTO t4 VALUES(1), (2); |
|||
INSERT INTO t4 SELECT * FROM t4; |
|||
SELECT COUNT(*) FROM t4; |
|||
DROP TABLE t4; |
|||
|
|||
--echo # Cleanup |
|||
DROP DATABASE temp_db; |
|||
955
sql/sql_base.cc
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
1499
sql/temporary_tables.cc
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue