Skip to content

Commit

Permalink
MDEV-5535: Cannot reopen temporary table
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Nirbhay Choubey committed Jun 10, 2016
1 parent 5475111 commit 7305be2
Show file tree
Hide file tree
Showing 50 changed files with 2,313 additions and 1,258 deletions.
1 change: 1 addition & 0 deletions libmysqld/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/wsrep_dummy.cc ../sql/encryption.cc
../sql/item_windowfunc.cc ../sql/sql_window.cc
../sql/sql_cte.cc
../sql/temporary_tables.cc
${GEN_SOURCES}
${MYSYS_LIBWRAP_SOURCE}
)
Expand Down
3 changes: 2 additions & 1 deletion mysql-test/r/create.result
Original file line number Diff line number Diff line change
Expand Up @@ -1736,7 +1736,8 @@ drop view t1;
create table t1 (a int) select 1 as a;
create temporary table if not exists t1 (a int) select * from t1;
create temporary table if not exists t1 (a int) select * from t1;
ERROR HY000: Can't reopen table: 't1'
Warnings:
Note 1050 Table 't1' already exists
select * from t1;
a
1
Expand Down
5 changes: 0 additions & 5 deletions mysql-test/r/lock.result
Original file line number Diff line number Diff line change
Expand Up @@ -380,12 +380,7 @@ alter table t1 add column j int;
unlock tables;
drop table t1;
create temporary table t1 (i int);
#
# This is just for test coverage purposes,
# when this is allowed, remove the --error.
#
lock tables t1 write, t1 as a read, t1 as b read;
ERROR HY000: Can't reopen table: 't1'
alter table t1 add column j int;
unlock tables;
drop table t1;
Expand Down
133 changes: 133 additions & 0 deletions mysql-test/r/reopen_temp_table.result
Original file line number Diff line number Diff line change
@@ -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;
10 changes: 7 additions & 3 deletions mysql-test/r/sp.result
Original file line number Diff line number Diff line change
Expand Up @@ -1140,9 +1140,12 @@ insert into t3 values (1), (2), (3);
return (select count(*) from t3 as a, t3 as b);
end|
select f11()|
ERROR HY000: Can't reopen table: 'a'
f11()
9
select f11() from t1|
ERROR HY000: Can't reopen table: 'a'
f11()
9
9
create function f12_1() returns int
begin
drop temporary table if exists t3;
Expand All @@ -1156,6 +1159,7 @@ drop temporary table t3|
select f12_1()|
f12_1()
3
drop temporary table t3|
select f12_1() from t1 limit 1|
f12_1()
3
Expand Down Expand Up @@ -6933,7 +6937,7 @@ CREATE TEMPORARY TABLE t3 LIKE t1;
CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ;
END|
CALL p1;
ERROR HY000: Can't reopen table: 'A'
f1
CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 );
DROP TABLE t3;
CALL p1;
Expand Down
22 changes: 19 additions & 3 deletions mysql-test/suite/handler/aria.result
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,18 @@ handler a1 read a next;
a b
3 d
select a,b from t1;
ERROR HY000: Can't reopen table: 'a1'
a b
0 a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
9 j
9 k
handler a1 read a prev;
a b
2 c
Expand Down Expand Up @@ -745,7 +756,7 @@ ERROR HY000: Can't execute the given command because you have active locked tabl
handler t2 close;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
handler t3 open;
ERROR HY000: Can't reopen table: 't3'
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
# After UNLOCK TABLES handlers should be around and
# we should be able to continue reading through them.
unlock tables;
Expand Down Expand Up @@ -1396,7 +1407,12 @@ handler t2 read a next;
a b
3 NULL
select * from t2;
ERROR HY000: Can't reopen table: 't2'
a b
1 NULL
2 NULL
3 NULL
4 NULL
5 NULL
handler t2 read a next;
a b
4 NULL
Expand Down
7 changes: 1 addition & 6 deletions mysql-test/suite/handler/handler.inc
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,6 @@ drop table t1;
#
# Bug#30882 Dropping a temporary table inside a stored function may cause a server crash
#
# Test HANDLER statements in conjunction with temporary tables. While the temporary table
# is open by a HANDLER, no other statement can access it.
#

create temporary table t1 (a int, b char(1), key a using btree (a), key b using btree (a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
Expand All @@ -472,7 +469,6 @@ handler t1 open as a1;
handler a1 read a=(1);
handler a1 read a next;
handler a1 read a next;
--error ER_CANT_REOPEN_TABLE
select a,b from t1;
handler a1 read a prev;
handler a1 read a prev;
Expand Down Expand Up @@ -564,7 +560,7 @@ handler t1 open;
handler t1 read next;
--error ER_LOCK_OR_ACTIVE_TRANSACTION
handler t2 close;
--error ER_CANT_REOPEN_TABLE
--error ER_LOCK_OR_ACTIVE_TRANSACTION
handler t3 open;
--echo # After UNLOCK TABLES handlers should be around and
--echo # we should be able to continue reading through them.
Expand Down Expand Up @@ -1182,7 +1178,6 @@ handler t1 read a next;
select * from t1;
--echo # Sic: the position is not lost
handler t2 read a next;
--error ER_CANT_REOPEN_TABLE
select * from t2;
handler t2 read a next;
drop table t1;
Expand Down
22 changes: 19 additions & 3 deletions mysql-test/suite/handler/heap.result
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,18 @@ handler a1 read a next;
a b
3 d
select a,b from t1;
ERROR HY000: Can't reopen table: 'a1'
a b
0 a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
9 j
9 k
handler a1 read a prev;
a b
2 c
Expand Down Expand Up @@ -745,7 +756,7 @@ ERROR HY000: Can't execute the given command because you have active locked tabl
handler t2 close;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
handler t3 open;
ERROR HY000: Can't reopen table: 't3'
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
# After UNLOCK TABLES handlers should be around and
# we should be able to continue reading through them.
unlock tables;
Expand Down Expand Up @@ -1396,7 +1407,12 @@ handler t2 read a next;
a b
3 NULL
select * from t2;
ERROR HY000: Can't reopen table: 't2'
a b
1 NULL
2 NULL
3 NULL
4 NULL
5 NULL
handler t2 read a next;
a b
4 NULL
Expand Down
22 changes: 19 additions & 3 deletions mysql-test/suite/handler/innodb.result
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,18 @@ handler a1 read a next;
a b
3 d
select a,b from t1;
ERROR HY000: Can't reopen table: 'a1'
a b
0 a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
9 j
9 k
handler a1 read a prev;
a b
2 c
Expand Down Expand Up @@ -747,7 +758,7 @@ ERROR HY000: Can't execute the given command because you have active locked tabl
handler t2 close;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
handler t3 open;
ERROR HY000: Can't reopen table: 't3'
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
# After UNLOCK TABLES handlers should be around and
# we should be able to continue reading through them.
unlock tables;
Expand Down Expand Up @@ -1400,7 +1411,12 @@ handler t2 read a next;
a b
3 NULL
select * from t2;
ERROR HY000: Can't reopen table: 't2'
a b
1 NULL
2 NULL
3 NULL
4 NULL
5 NULL
handler t2 read a next;
a b
4 NULL
Expand Down
Loading

0 comments on commit 7305be2

Please sign in to comment.