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.
This commit is contained in:
parent
547511153f
commit
7305be2f7e
@ -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}
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
133
mysql-test/r/reopen_temp_table.result
Normal file
133
mysql-test/r/reopen_temp_table.result
Normal file
@ -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;
|
@ -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;
|
||||
@ -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
|
||||
@ -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;
|
||||
|
@ -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
|
||||
@ -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;
|
||||
@ -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
|
||||
|
@ -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"),
|
||||
@ -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;
|
||||
@ -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.
|
||||
@ -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;
|
||||
|
@ -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
|
||||
@ -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;
|
||||
@ -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
|
||||
|
@ -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
|
||||
@ -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;
|
||||
@ -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
|
||||
|
@ -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
|
||||
@ -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;
|
||||
@ -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
|
||||
|
30
mysql-test/suite/rpl/r/rpl_reopen_temp_table.result
Normal file
30
mysql-test/suite/rpl/r/rpl_reopen_temp_table.result
Normal file
@ -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
|
43
mysql-test/suite/rpl/t/rpl_reopen_temp_table.test
Normal file
43
mysql-test/suite/rpl/t/rpl_reopen_temp_table.test
Normal file
@ -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
|
@ -1618,7 +1618,6 @@ drop view t1;
|
||||
|
||||
create table t1 (a int) select 1 as a;
|
||||
create temporary table if not exists t1 (a int) select * from t1;
|
||||
--error ER_CANT_REOPEN_TABLE
|
||||
create temporary table if not exists t1 (a int) select * from t1;
|
||||
select * from t1;
|
||||
drop temporary table t1;
|
||||
|
@ -442,11 +442,6 @@ alter table t1 add column j int;
|
||||
unlock tables;
|
||||
drop table t1;
|
||||
create temporary table t1 (i int);
|
||||
--echo #
|
||||
--echo # This is just for test coverage purposes,
|
||||
--echo # when this is allowed, remove the --error.
|
||||
--echo #
|
||||
--error ER_CANT_REOPEN_TABLE
|
||||
lock tables t1 write, t1 as a read, t1 as b read;
|
||||
alter table t1 add column j int;
|
||||
unlock tables;
|
||||
|
128
mysql-test/t/reopen_temp_table.test
Normal file
128
mysql-test/t/reopen_temp_table.test
Normal file
@ -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;
|
@ -1368,11 +1368,6 @@ select f10()|
|
||||
create table t4 as select 1 as id|
|
||||
select f10()|
|
||||
|
||||
# Practical cases which we don't handle well (yet)
|
||||
#
|
||||
# Function which does not work because of well-known and documented
|
||||
# limitation of MySQL. We can't use the several instances of the
|
||||
# same temporary table in statement.
|
||||
create function f11() returns int
|
||||
begin
|
||||
drop temporary table if exists t3;
|
||||
@ -1380,9 +1375,7 @@ begin
|
||||
insert into t3 values (1), (2), (3);
|
||||
return (select count(*) from t3 as a, t3 as b);
|
||||
end|
|
||||
--error ER_CANT_REOPEN_TABLE
|
||||
select f11()|
|
||||
--error ER_CANT_REOPEN_TABLE
|
||||
select f11() from t1|
|
||||
# Test that using a single table instance at a time works
|
||||
create function f12_1() returns int
|
||||
@ -1397,6 +1390,7 @@ create function f12_2() returns int
|
||||
|
||||
drop temporary table t3|
|
||||
select f12_1()|
|
||||
drop temporary table t3|
|
||||
select f12_1() from t1 limit 1|
|
||||
|
||||
# Cleanup
|
||||
@ -8278,7 +8272,6 @@ delimiter |;
|
||||
CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ;
|
||||
END|
|
||||
delimiter ;|
|
||||
--error ER_CANT_REOPEN_TABLE
|
||||
CALL p1;
|
||||
CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 );
|
||||
DROP TABLE t3;
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Copyright (c) 2006, 2014, Oracle and/or its affiliates.
|
||||
# Copyright (c) 2010, 2015, MariaDB
|
||||
# Copyright (c) 2010, 2016, MariaDB Corporation
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -141,7 +141,7 @@ SET (SQL_SOURCE
|
||||
item_windowfunc.cc sql_window.cc
|
||||
sql_cte.cc sql_cte.h
|
||||
${WSREP_SOURCES}
|
||||
table_cache.cc encryption.cc
|
||||
table_cache.cc encryption.cc temporary_tables.cc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc
|
||||
${GEN_SOURCES}
|
||||
${GEN_DIGEST_SOURCES}
|
||||
|
@ -6159,7 +6159,7 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
|
||||
update it inside mysql_load().
|
||||
*/
|
||||
List<Item> tmp_list;
|
||||
if (open_temporary_tables(thd, &tables) ||
|
||||
if (thd->open_temporary_tables(&tables) ||
|
||||
mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
|
||||
handle_dup, ignore, net != 0))
|
||||
thd->is_slave_error= 1;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Copyright (c) 2006, 2013, Oracle and/or its affiliates.
|
||||
Copyright (c) 2010, 2013, Monty Program Ab
|
||||
Copyright (c) 2016, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -52,8 +53,8 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery)
|
||||
no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id),
|
||||
info_fd(-1), cur_log_fd(-1), relay_log(&sync_relaylog_period),
|
||||
sync_counter(0), is_relay_log_recovery(is_slave_recovery),
|
||||
save_temporary_tables(0), mi(0),
|
||||
inuse_relaylog_list(0), last_inuse_relaylog(0),
|
||||
save_temporary_tables(0),
|
||||
mi(0), inuse_relaylog_list(0), last_inuse_relaylog(0),
|
||||
cur_log_old_open_count(0), group_relay_log_pos(0),
|
||||
event_relay_log_pos(0),
|
||||
#if HAVE_valgrind
|
||||
@ -1062,24 +1063,53 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
|
||||
|
||||
void Relay_log_info::close_temporary_tables()
|
||||
{
|
||||
TABLE *table,*next;
|
||||
DBUG_ENTER("Relay_log_info::close_temporary_tables");
|
||||
|
||||
for (table=save_temporary_tables ; table ; table=next)
|
||||
{
|
||||
next=table->next;
|
||||
TMP_TABLE_SHARE *share;
|
||||
TABLE *table;
|
||||
|
||||
if (!save_temporary_tables)
|
||||
{
|
||||
/* There are no temporary tables. */
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
while ((share= save_temporary_tables->pop_front()))
|
||||
{
|
||||
/*
|
||||
Iterate over the list of tables for this TABLE_SHARE and close them.
|
||||
*/
|
||||
while ((table= share->all_tmp_tables.pop_front()))
|
||||
{
|
||||
DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",
|
||||
table->s->db.str, table->s->table_name.str));
|
||||
|
||||
/* Reset in_use as the table may have been created by another thd */
|
||||
table->in_use= 0;
|
||||
/*
|
||||
Lets not free TABLE_SHARE here as there could be multiple TABLEs opened
|
||||
for the same table (TABLE_SHARE).
|
||||
*/
|
||||
closefrm(table);
|
||||
my_free(table);
|
||||
}
|
||||
|
||||
/* Reset in_use as the table may have been created by another thd */
|
||||
table->in_use=0;
|
||||
/*
|
||||
Don't ask for disk deletion. For now, anyway they will be deleted when
|
||||
slave restarts, but it is a better intention to not delete them.
|
||||
*/
|
||||
DBUG_PRINT("info", ("table: 0x%lx", (long) table));
|
||||
close_temporary(table, 1, 0);
|
||||
|
||||
free_table_share(share);
|
||||
my_free(share);
|
||||
}
|
||||
save_temporary_tables= 0;
|
||||
|
||||
/* By now, there mustn't be any elements left in the list. */
|
||||
DBUG_ASSERT(save_temporary_tables->is_empty());
|
||||
|
||||
my_free(save_temporary_tables);
|
||||
save_temporary_tables= NULL;
|
||||
slave_open_temp_tables= 0;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -1756,6 +1786,7 @@ void rpl_group_info::cleanup_context(THD *thd, bool error)
|
||||
}
|
||||
m_table_map.clear_tables();
|
||||
slave_close_thread_tables(thd);
|
||||
|
||||
if (error)
|
||||
{
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
|
@ -148,7 +148,7 @@ public:
|
||||
|
||||
Protected by data_lock.
|
||||
*/
|
||||
TABLE *save_temporary_tables;
|
||||
All_tmp_tables_list *save_temporary_tables;
|
||||
|
||||
/*
|
||||
standard lock acquisition order to avoid deadlocks:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2015, MariaDB
|
||||
Copyright (c) 2008, 2016, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -4895,8 +4895,11 @@ err_during_init:
|
||||
/*
|
||||
TODO: see if we can do this conditionally in next_event() instead
|
||||
to avoid unneeded position re-init
|
||||
|
||||
We only reset THD::temporary_tables to 0 here and not free it, as this
|
||||
could be used by slave through Relay_log_info::save_temporary_tables.
|
||||
*/
|
||||
thd->temporary_tables = 0; // remove tempation from destructor to close them
|
||||
thd->temporary_tables= 0;
|
||||
rli->sql_driver_thd= 0;
|
||||
thd->rgi_fake= thd->rgi_slave= NULL;
|
||||
|
||||
|
@ -3077,7 +3077,7 @@ int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
|
||||
Check whenever we have access to tables for this statement
|
||||
and open and lock them before executing instructions core function.
|
||||
*/
|
||||
if (open_temporary_tables(thd, tables) ||
|
||||
if (thd->open_temporary_tables(tables) ||
|
||||
check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)
|
||||
|| open_and_lock_tables(thd, tables, TRUE, 0))
|
||||
result= -1;
|
||||
|
@ -54,7 +54,7 @@ static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
|
||||
|
||||
DEBUG_SYNC(thd, "ha_admin_try_alter");
|
||||
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
|
||||
result_code= (open_temporary_tables(thd, table_list) ||
|
||||
result_code= (thd->open_temporary_tables(table_list) ||
|
||||
mysql_recreate_table(thd, table_list, false));
|
||||
reenable_binlog(thd);
|
||||
/*
|
||||
@ -445,7 +445,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
|
||||
da->push_warning_info(&tmp_wi);
|
||||
|
||||
open_error= (open_temporary_tables(thd, table) ||
|
||||
open_error= (thd->open_temporary_tables(table) ||
|
||||
open_and_lock_tables(thd, table, TRUE, 0));
|
||||
|
||||
da->pop_warning_info();
|
||||
@ -460,7 +460,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
mode. It does make sense for the user to see such errors.
|
||||
*/
|
||||
|
||||
open_error= (open_temporary_tables(thd, table) ||
|
||||
open_error= (thd->open_temporary_tables(table) ||
|
||||
open_and_lock_tables(thd, table, TRUE, 0));
|
||||
}
|
||||
thd->prepare_derived_at_open= FALSE;
|
||||
@ -952,7 +952,7 @@ send_result_message:
|
||||
table->mdl_request.ticket= NULL;
|
||||
DEBUG_SYNC(thd, "ha_admin_open_ltable");
|
||||
table->mdl_request.set_type(MDL_SHARED_WRITE);
|
||||
if (!open_temporary_tables(thd, table) &&
|
||||
if (!thd->open_temporary_tables(table) &&
|
||||
(table->table= open_ltable(thd, table, lock_type, 0)))
|
||||
{
|
||||
uint save_flags;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2016, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -16,7 +17,6 @@
|
||||
#include "sql_parse.h" // check_access
|
||||
#include "sql_table.h" // mysql_alter_table,
|
||||
// mysql_exchange_partition
|
||||
#include "sql_base.h" // open_temporary_tables
|
||||
#include "sql_alter.h"
|
||||
#include "wsrep_mysqld.h"
|
||||
|
||||
@ -305,10 +305,8 @@ bool Sql_cmd_alter_table::execute(THD *thd)
|
||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
|
||||
|
||||
if ((!thd->is_current_stmt_binlog_format_row() ||
|
||||
!find_temporary_table(thd, first_table)))
|
||||
!thd->find_temporary_table(first_table)))
|
||||
{
|
||||
WSREP_TO_ISOLATION_BEGIN(((lex->name.str) ? select_lex->db : NULL),
|
||||
((lex->name.str) ? lex->name.str : NULL),
|
||||
|
955
sql/sql_base.cc
955
sql/sql_base.cc
File diff suppressed because it is too large
Load Diff
@ -59,8 +59,6 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
|
||||
IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE,
|
||||
IGNORE_EXCEPT_NON_UNIQUE};
|
||||
|
||||
uint create_tmp_table_def_key(THD *thd, char *key, const char *db,
|
||||
const char *table_name);
|
||||
uint get_table_def_key(const TABLE_LIST *table_list, const char **key);
|
||||
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
|
||||
uint lock_flags);
|
||||
@ -124,11 +122,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx);
|
||||
|
||||
bool get_key_map_from_key_list(key_map *map, TABLE *table,
|
||||
List<String> *index_list);
|
||||
TABLE *open_table_uncached(THD *thd, handlerton *hton,
|
||||
LEX_CUSTRING *frm, const char *path,
|
||||
const char *db, const char *table_name,
|
||||
bool add_to_temporary_tables_list,
|
||||
bool open_in_engine);
|
||||
TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name);
|
||||
TABLE *find_write_locked_table(TABLE *list, const char *db,
|
||||
const char *table_name);
|
||||
@ -138,21 +131,12 @@ thr_lock_type read_lock_type_for_table(THD *thd,
|
||||
bool routine_modifies_data);
|
||||
|
||||
my_bool mysql_rm_tmp_tables(void);
|
||||
bool rm_temporary_table(handlerton *base, const char *path);
|
||||
void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
|
||||
const MDL_savepoint &start_of_statement_svp);
|
||||
TABLE_LIST *find_table_in_list(TABLE_LIST *table,
|
||||
TABLE_LIST *TABLE_LIST::*link,
|
||||
const char *db_name,
|
||||
const char *table_name);
|
||||
TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name);
|
||||
bool find_and_use_temporary_table(THD *thd, const char *db,
|
||||
const char *table_name, TABLE **out_table);
|
||||
TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
|
||||
bool find_and_use_temporary_table(THD *thd, const TABLE_LIST *tl,
|
||||
TABLE **out_table);
|
||||
TABLE *find_temporary_table(THD *thd, const char *table_key,
|
||||
uint table_key_length);
|
||||
void close_thread_tables(THD *thd);
|
||||
void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *);
|
||||
bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
|
||||
@ -272,17 +256,8 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags,
|
||||
bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
|
||||
int decide_logging_format(THD *thd, TABLE_LIST *tables);
|
||||
void close_thread_table(THD *thd, TABLE **table_ptr);
|
||||
bool close_temporary_tables(THD *thd);
|
||||
TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
||||
bool check_alias);
|
||||
int drop_temporary_table(THD *thd, TABLE *table, bool *is_trans);
|
||||
void close_temporary_table(THD *thd, TABLE *table, bool free_share,
|
||||
bool delete_table);
|
||||
void close_temporary(TABLE *table, bool free_share, bool delete_table);
|
||||
bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
|
||||
const char *table_name);
|
||||
bool open_temporary_tables(THD *thd, TABLE_LIST *tl_list);
|
||||
bool open_temporary_table(THD *thd, TABLE_LIST *tl);
|
||||
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
|
||||
|
||||
class Open_tables_backup;
|
||||
@ -311,7 +286,6 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, uint flags);
|
||||
TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
|
||||
const char *table_name,
|
||||
bool no_error);
|
||||
void mark_tmp_table_for_reuse(TABLE *table);
|
||||
|
||||
int update_virtual_fields(THD *thd, TABLE *table,
|
||||
enum enum_vcol_update_mode vcol_update_mode= VCOL_UPDATE_FOR_READ);
|
||||
|
@ -1999,36 +1999,32 @@ lookup:
|
||||
for (; block_table != block_table_end; block_table++)
|
||||
{
|
||||
TABLE_LIST table_list;
|
||||
TABLE *tmptable;
|
||||
TMP_TABLE_SHARE *tmptable;
|
||||
Query_cache_table *table = block_table->parent;
|
||||
|
||||
/*
|
||||
Check that we have not temporary tables with same names of tables
|
||||
of this query. If we have such tables, we will not send data from
|
||||
query cache, because temporary tables hide real tables by which
|
||||
Check that we do not have temporary tables with same names as that of
|
||||
base tables from this query. If we have such tables, we will not send
|
||||
data from query cache, because temporary tables hide real tables by which
|
||||
query in query cache was made.
|
||||
*/
|
||||
for (tmptable= thd->temporary_tables; tmptable ; tmptable= tmptable->next)
|
||||
if ((tmptable=
|
||||
thd->find_tmp_table_share_w_base_key((char *) table->data(),
|
||||
table->key_length())))
|
||||
{
|
||||
if (tmptable->s->table_cache_key.length - TMP_TABLE_KEY_EXTRA ==
|
||||
table->key_length() &&
|
||||
!memcmp(tmptable->s->table_cache_key.str, table->data(),
|
||||
table->key_length()))
|
||||
{
|
||||
DBUG_PRINT("qcache",
|
||||
("Temporary table detected: '%s.%s'",
|
||||
tmptable->s->db.str, tmptable->alias.c_ptr()));
|
||||
unlock();
|
||||
/*
|
||||
We should not store result of this query because it contain
|
||||
temporary tables => assign following variable to make check
|
||||
faster.
|
||||
*/
|
||||
thd->query_cache_is_applicable= 0; // Query can't be cached
|
||||
thd->lex->safe_to_cache_query= 0; // For prepared statements
|
||||
BLOCK_UNLOCK_RD(query_block);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
DBUG_PRINT("qcache",
|
||||
("Temporary table detected: '%s.%s'",
|
||||
tmptable->db.str, tmptable->table_name.str));
|
||||
unlock();
|
||||
/*
|
||||
We should not store result of this query because it contain
|
||||
temporary tables => assign following variable to make check
|
||||
faster.
|
||||
*/
|
||||
thd->query_cache_is_applicable= 0; // Query can't be cached
|
||||
thd->lex->safe_to_cache_query= 0; // For prepared statements
|
||||
BLOCK_UNLOCK_RD(query_block);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
bzero((char*) &table_list,sizeof(table_list));
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "tztime.h" // MYSQL_TIME <-> my_time_t
|
||||
#include "sql_acl.h" // NO_ACCESS,
|
||||
// acl_getroot_no_password
|
||||
#include "sql_base.h" // close_temporary_tables
|
||||
#include "sql_base.h"
|
||||
#include "sql_handler.h" // mysql_ha_cleanup
|
||||
#include "rpl_rli.h"
|
||||
#include "rpl_filter.h"
|
||||
@ -883,7 +883,8 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
|
||||
main_da(0, false, false),
|
||||
m_stmt_da(&main_da),
|
||||
tdc_hash_pins(0),
|
||||
xid_hash_pins(0)
|
||||
xid_hash_pins(0),
|
||||
m_tmp_tables_locked(false)
|
||||
#ifdef WITH_WSREP
|
||||
,
|
||||
wsrep_applier(is_wsrep_applier),
|
||||
@ -1586,7 +1587,7 @@ void THD::cleanup(void)
|
||||
locked_tables_list.unlock_locked_tables(this);
|
||||
|
||||
delete_dynamic(&user_var_events);
|
||||
close_temporary_tables(this);
|
||||
close_temporary_tables();
|
||||
|
||||
transaction.xid_state.xa_state= XA_NOTR;
|
||||
trans_rollback(this);
|
||||
@ -4319,7 +4320,8 @@ void THD::restore_backup_open_tables_state(Open_tables_backup *backup)
|
||||
Before we will throw away current open tables state we want
|
||||
to be sure that it was properly cleaned up.
|
||||
*/
|
||||
DBUG_ASSERT(open_tables == 0 && temporary_tables == 0 &&
|
||||
DBUG_ASSERT(open_tables == 0 &&
|
||||
temporary_tables == 0 &&
|
||||
derived_tables == 0 &&
|
||||
lock == 0 &&
|
||||
locked_tables_mode == LTM_NONE &&
|
||||
@ -6982,24 +6984,6 @@ THD::signal_wakeup_ready()
|
||||
}
|
||||
|
||||
|
||||
void THD::rgi_lock_temporary_tables()
|
||||
{
|
||||
mysql_mutex_lock(&rgi_slave->rli->data_lock);
|
||||
temporary_tables= rgi_slave->rli->save_temporary_tables;
|
||||
}
|
||||
|
||||
void THD::rgi_unlock_temporary_tables()
|
||||
{
|
||||
rgi_slave->rli->save_temporary_tables= temporary_tables;
|
||||
mysql_mutex_unlock(&rgi_slave->rli->data_lock);
|
||||
}
|
||||
|
||||
bool THD::rgi_have_temporary_tables()
|
||||
{
|
||||
return rgi_slave->rli->save_temporary_tables != 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wait_for_commit::reinit()
|
||||
{
|
||||
|
176
sql/sql_class.h
176
sql/sql_class.h
@ -1264,6 +1264,61 @@ enum enum_locked_tables_mode
|
||||
LTM_PRELOCKED_UNDER_LOCK_TABLES
|
||||
};
|
||||
|
||||
/**
|
||||
The following structure is an extension to TABLE_SHARE and is
|
||||
exclusively for temporary tables.
|
||||
|
||||
@note:
|
||||
Although, TDC_element has data members (like next, prev &
|
||||
all_tables) to store the list of TABLE_SHARE & TABLE objects
|
||||
related to a particular TABLE_SHARE, they cannot be moved to
|
||||
TABLE_SHARE in order to be reused for temporary tables. This
|
||||
is because, as concurrent threads iterating through hash of
|
||||
TDC_element's may need access to all_tables, but if all_tables
|
||||
is made part of TABLE_SHARE, then TDC_element->share->all_tables
|
||||
is not always guaranteed to be valid, as TDC_element can live
|
||||
longer than TABLE_SHARE.
|
||||
*/
|
||||
struct TMP_TABLE_SHARE : public TABLE_SHARE
|
||||
{
|
||||
private:
|
||||
/*
|
||||
Link to all temporary table shares. Declared as private to
|
||||
avoid direct manipulation with those objects. One should
|
||||
use methods of I_P_List template instead.
|
||||
*/
|
||||
TMP_TABLE_SHARE *tmp_next;
|
||||
TMP_TABLE_SHARE **tmp_prev;
|
||||
|
||||
friend struct All_tmp_table_shares;
|
||||
|
||||
public:
|
||||
/*
|
||||
Doubly-linked (back-linked) lists of used and unused TABLE objects
|
||||
for this share.
|
||||
*/
|
||||
All_share_tables_list all_tmp_tables;
|
||||
};
|
||||
|
||||
/**
|
||||
Helper class which specifies which members of TMP_TABLE_SHARE are
|
||||
used for participation in the list of temporary tables.
|
||||
*/
|
||||
|
||||
struct All_tmp_table_shares
|
||||
{
|
||||
static inline TMP_TABLE_SHARE **next_ptr(TMP_TABLE_SHARE *l)
|
||||
{
|
||||
return &l->tmp_next;
|
||||
}
|
||||
static inline TMP_TABLE_SHARE ***prev_ptr(TMP_TABLE_SHARE *l)
|
||||
{
|
||||
return &l->tmp_prev;
|
||||
}
|
||||
};
|
||||
|
||||
/* Also used in rpl_rli.h. */
|
||||
typedef I_P_List <TMP_TABLE_SHARE, All_tmp_table_shares> All_tmp_tables_list;
|
||||
|
||||
/**
|
||||
Class that holds information about tables which were opened and locked
|
||||
@ -1293,15 +1348,20 @@ public:
|
||||
base tables that were opened with @see open_tables().
|
||||
*/
|
||||
TABLE *open_tables;
|
||||
|
||||
/**
|
||||
List of temporary tables used by this thread. Contains user-level
|
||||
temporary tables, created with CREATE TEMPORARY TABLE, and
|
||||
internal temporary tables, created, e.g., to resolve a SELECT,
|
||||
A list of temporary tables used by this thread. This includes
|
||||
user-level temporary tables, created with CREATE TEMPORARY TABLE,
|
||||
and internal temporary tables, created, e.g., to resolve a SELECT,
|
||||
or for an intermediate table used in ALTER.
|
||||
XXX Why are internal temporary tables added to this list?
|
||||
*/
|
||||
TABLE *temporary_tables;
|
||||
All_tmp_tables_list *temporary_tables;
|
||||
|
||||
/*
|
||||
Derived tables.
|
||||
*/
|
||||
TABLE *derived_tables;
|
||||
|
||||
/*
|
||||
During a MySQL session, one can lock tables in two modes: automatic
|
||||
or manual. In automatic mode all necessary tables are locked just before
|
||||
@ -1379,8 +1439,11 @@ public:
|
||||
|
||||
void reset_open_tables_state(THD *thd)
|
||||
{
|
||||
open_tables= temporary_tables= derived_tables= 0;
|
||||
extra_lock= lock= 0;
|
||||
open_tables= 0;
|
||||
temporary_tables= 0;
|
||||
derived_tables= 0;
|
||||
extra_lock= 0;
|
||||
lock= 0;
|
||||
locked_tables_mode= LTM_NONE;
|
||||
state_flags= 0U;
|
||||
m_reprepare_observer= NULL;
|
||||
@ -3544,13 +3607,13 @@ public:
|
||||
*/
|
||||
DBUG_PRINT("debug",
|
||||
("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
|
||||
YESNO(temporary_tables), YESNO(in_sub_stmt),
|
||||
YESNO(has_thd_temporary_tables()), YESNO(in_sub_stmt),
|
||||
show_system_thread(system_thread)));
|
||||
if (in_sub_stmt == 0)
|
||||
{
|
||||
if (wsrep_binlog_format() == BINLOG_FORMAT_ROW)
|
||||
set_current_stmt_binlog_format_row();
|
||||
else if (temporary_tables == NULL)
|
||||
else if (!has_thd_temporary_tables())
|
||||
set_current_stmt_binlog_format_stmt();
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
@ -3950,10 +4013,6 @@ private:
|
||||
LEX_STRING invoker_user;
|
||||
LEX_STRING invoker_host;
|
||||
|
||||
/* Protect against add/delete of temporary tables in parallel replication */
|
||||
void rgi_lock_temporary_tables();
|
||||
void rgi_unlock_temporary_tables();
|
||||
bool rgi_have_temporary_tables();
|
||||
public:
|
||||
/*
|
||||
Flag, mutex and condition for a thread to wait for a signal from another
|
||||
@ -3971,26 +4030,85 @@ public:
|
||||
*/
|
||||
rpl_gtid last_commit_gtid;
|
||||
|
||||
inline void lock_temporary_tables()
|
||||
{
|
||||
if (rgi_slave)
|
||||
rgi_lock_temporary_tables();
|
||||
}
|
||||
inline void unlock_temporary_tables()
|
||||
{
|
||||
if (rgi_slave)
|
||||
rgi_unlock_temporary_tables();
|
||||
}
|
||||
inline bool have_temporary_tables()
|
||||
{
|
||||
return (temporary_tables ||
|
||||
(rgi_slave && rgi_have_temporary_tables()));
|
||||
}
|
||||
|
||||
LF_PINS *tdc_hash_pins;
|
||||
LF_PINS *xid_hash_pins;
|
||||
bool fix_xid_hash_pins();
|
||||
|
||||
/* Members related to temporary tables. */
|
||||
public:
|
||||
bool has_thd_temporary_tables();
|
||||
|
||||
TABLE *create_and_open_tmp_table(handlerton *hton,
|
||||
LEX_CUSTRING *frm,
|
||||
const char *path,
|
||||
const char *db,
|
||||
const char *table_name,
|
||||
bool open_in_engine);
|
||||
|
||||
TABLE *find_temporary_table(const char *db, const char *table_name);
|
||||
TABLE *find_temporary_table(const TABLE_LIST *tl);
|
||||
|
||||
TMP_TABLE_SHARE *find_tmp_table_share_w_base_key(const char *key,
|
||||
uint key_length);
|
||||
TMP_TABLE_SHARE *find_tmp_table_share(const char *db,
|
||||
const char *table_name);
|
||||
TMP_TABLE_SHARE *find_tmp_table_share(const TABLE_LIST *tl);
|
||||
TMP_TABLE_SHARE *find_tmp_table_share(const char *key, uint key_length);
|
||||
|
||||
bool open_temporary_table(TABLE_LIST *tl);
|
||||
bool open_temporary_tables(TABLE_LIST *tl);
|
||||
|
||||
bool close_temporary_tables();
|
||||
bool rename_temporary_table(TABLE *table, const char *db,
|
||||
const char *table_name);
|
||||
bool drop_temporary_table(TABLE *table, bool *is_trans, bool delete_table);
|
||||
bool rm_temporary_table(handlerton *hton, const char *path);
|
||||
void mark_tmp_tables_as_free_for_reuse();
|
||||
void mark_tmp_table_as_free_for_reuse(TABLE *table);
|
||||
|
||||
private:
|
||||
/* Whether a lock has been acquired? */
|
||||
bool m_tmp_tables_locked;
|
||||
|
||||
/* Opened table states. */
|
||||
enum Temporary_table_state {
|
||||
TMP_TABLE_IN_USE,
|
||||
TMP_TABLE_NOT_IN_USE,
|
||||
TMP_TABLE_ANY
|
||||
};
|
||||
|
||||
bool has_temporary_tables();
|
||||
uint create_tmp_table_def_key(char *key, const char *db,
|
||||
const char *table_name);
|
||||
TMP_TABLE_SHARE *create_temporary_table(handlerton *hton, LEX_CUSTRING *frm,
|
||||
const char *path, const char *db,
|
||||
const char *table_name);
|
||||
TABLE *find_temporary_table(const char *key, uint key_length,
|
||||
Temporary_table_state state);
|
||||
TABLE *open_temporary_table(TMP_TABLE_SHARE *share, const char *alias,
|
||||
bool open_in_engine);
|
||||
bool find_and_use_tmp_table(const TABLE_LIST *tl, TABLE **out_table);
|
||||
bool use_temporary_table(TABLE *table, TABLE **out_table);
|
||||
void close_temporary_table(TABLE *table);
|
||||
bool log_events_and_free_tmp_shares();
|
||||
void free_tmp_table_share(TMP_TABLE_SHARE *share, bool delete_table);
|
||||
void free_temporary_table(TABLE *table);
|
||||
bool lock_temporary_tables();
|
||||
void unlock_temporary_tables();
|
||||
|
||||
inline uint tmpkeyval(TMP_TABLE_SHARE *share)
|
||||
{
|
||||
return uint4korr(share->table_cache_key.str +
|
||||
share->table_cache_key.length - 4);
|
||||
}
|
||||
|
||||
inline TMP_TABLE_SHARE *tmp_table_share(TABLE *table)
|
||||
{
|
||||
DBUG_ASSERT(table->s->tmp_table);
|
||||
return static_cast<TMP_TABLE_SHARE *>(table->s);
|
||||
}
|
||||
|
||||
public:
|
||||
inline ulong wsrep_binlog_format() const
|
||||
{
|
||||
return WSREP_FORMAT(variables.binlog_format);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2000, 2014, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2015, MariaDB
|
||||
Copyright (c) 2009, 2016, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -886,7 +886,8 @@ mysql_rm_db_internal(THD *thd,char *db, bool if_exists, bool silent)
|
||||
{
|
||||
LEX_STRING db_name= { table->db, table->db_length };
|
||||
LEX_STRING table_name= { table->table_name, table->table_name_length };
|
||||
if (table->open_type == OT_BASE_ONLY || !find_temporary_table(thd, table))
|
||||
if (table->open_type == OT_BASE_ONLY ||
|
||||
!thd->find_temporary_table(table))
|
||||
(void) delete_statistics_for_table(thd, &db_name, &table_name);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2001, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2011, 2015, MariaDB
|
||||
Copyright (c) 2011, 2016, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -178,9 +178,8 @@ static void mysql_ha_close_table(SQL_HANDLER *handler)
|
||||
{
|
||||
/* Must be a temporary table */
|
||||
table->file->ha_index_or_rnd_end();
|
||||
table->query_id= thd->query_id;
|
||||
table->open_by_handler= 0;
|
||||
mark_tmp_table_for_reuse(table);
|
||||
thd->mark_tmp_table_as_free_for_reuse(table);
|
||||
}
|
||||
my_free(handler->lock);
|
||||
handler->init();
|
||||
@ -294,7 +293,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
|
||||
open_ltable() or open_table() because we would like to be able
|
||||
to open a temporary table.
|
||||
*/
|
||||
error= (open_temporary_tables(thd, tables) ||
|
||||
error= (thd->open_temporary_tables(tables) ||
|
||||
open_tables(thd, &tables, &counter, 0));
|
||||
|
||||
if (error)
|
||||
@ -389,8 +388,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
|
||||
/*
|
||||
Assert that the above check prevents opening of views and merge tables.
|
||||
For temporary tables, TABLE::next can be set even if only one table
|
||||
was opened for HANDLER as it is used to link them together
|
||||
(see thd->temporary_tables).
|
||||
was opened for HANDLER as it is used to link them together.
|
||||
*/
|
||||
DBUG_ASSERT(sql_handler->table->next == NULL ||
|
||||
sql_handler->table->s->tmp_table);
|
||||
@ -1195,10 +1193,10 @@ void mysql_ha_set_explicit_lock_duration(THD *thd)
|
||||
Remove temporary tables from the HANDLER's hash table. The reason
|
||||
for having a separate function, rather than calling
|
||||
mysql_ha_rm_tables() is that it is not always feasible (e.g. in
|
||||
close_temporary_tables) to obtain a TABLE_LIST containing the
|
||||
THD::close_temporary_tables) to obtain a TABLE_LIST containing the
|
||||
temporary tables.
|
||||
|
||||
@See close_temporary_tables
|
||||
@See THD::close_temporary_tables()
|
||||
@param thd Thread identifier.
|
||||
*/
|
||||
void mysql_ha_rm_temporary_tables(THD *thd)
|
||||
|
@ -4078,7 +4078,12 @@ static TABLE *create_table_from_items(THD *thd,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (open_temporary_table(thd, create_table))
|
||||
/*
|
||||
The pointer to the newly created temporary table has been stored in
|
||||
table->create_info.
|
||||
*/
|
||||
create_table->table= create_info->table;
|
||||
if (!create_table->table)
|
||||
{
|
||||
/*
|
||||
This shouldn't happen as creation of temporary table should make
|
||||
@ -4087,7 +4092,6 @@ static TABLE *create_table_from_items(THD *thd,
|
||||
*/
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
DBUG_ASSERT(create_table->table == create_info->table);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -4461,6 +4465,7 @@ void select_create::abort_result_set()
|
||||
if (table)
|
||||
{
|
||||
bool tmp_table= table->s->tmp_table;
|
||||
|
||||
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
||||
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2015, MariaDB
|
||||
Copyright (c) 2008, 2016, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -23,7 +23,10 @@
|
||||
// set_handler_table_locks,
|
||||
// lock_global_read_lock,
|
||||
// make_global_read_lock_block_commit
|
||||
#include "sql_base.h" // find_temporary_table
|
||||
#include "sql_base.h" // open_tables, open_and_lock_tables,
|
||||
// lock_tables, unique_table,
|
||||
// close_thread_tables, is_temporary_table
|
||||
// table_cache.h
|
||||
#include "sql_cache.h" // QUERY_CACHE_FLAGS_SIZE, query_cache_*
|
||||
#include "sql_show.h" // mysqld_list_*, mysqld_show_*,
|
||||
// calc_sum_of_all_status
|
||||
@ -418,7 +421,7 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
|
||||
for (TABLE_LIST *table= tables; table; table= table->next_global)
|
||||
{
|
||||
DBUG_ASSERT(table->db && table->table_name);
|
||||
if (table->updating && !find_temporary_table(thd, table))
|
||||
if (table->updating && !thd->find_tmp_table_share(table))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -1967,7 +1970,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
thd->set_query(fields, query_length);
|
||||
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
|
||||
|
||||
if (open_temporary_tables(thd, &table_list))
|
||||
if (thd->open_temporary_tables(&table_list))
|
||||
break;
|
||||
|
||||
if (check_table_access(thd, SELECT_ACL, &table_list,
|
||||
@ -3264,7 +3267,7 @@ mysql_execute_command(THD *thd)
|
||||
*/
|
||||
if (sql_command_flags[lex->sql_command] & CF_PREOPEN_TMP_TABLES)
|
||||
{
|
||||
if (open_temporary_tables(thd, all_tables))
|
||||
if (thd->open_temporary_tables(all_tables))
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -4066,7 +4069,7 @@ end_with_restore_list:
|
||||
Temporary tables should be opened for SHOW CREATE TABLE, but not
|
||||
for SHOW CREATE VIEW.
|
||||
*/
|
||||
if (open_temporary_tables(thd, all_tables))
|
||||
if (thd->open_temporary_tables(all_tables))
|
||||
goto error;
|
||||
|
||||
/*
|
||||
@ -4274,7 +4277,8 @@ end_with_restore_list:
|
||||
*/
|
||||
if (first_table->lock_type != TL_WRITE_DELAYED)
|
||||
{
|
||||
if ((res= open_temporary_tables(thd, all_tables)))
|
||||
res= (thd->open_temporary_tables(all_tables)) ? TRUE : FALSE;
|
||||
if (res)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4586,7 +4590,7 @@ end_with_restore_list:
|
||||
{
|
||||
if (!lex->tmp_table() &&
|
||||
(!thd->is_current_stmt_binlog_format_row() ||
|
||||
!find_temporary_table(thd, table)))
|
||||
!thd->find_temporary_table(table)))
|
||||
{
|
||||
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables);
|
||||
break;
|
||||
@ -4739,7 +4743,7 @@ end_with_restore_list:
|
||||
CF_PREOPEN_TMP_TABLES was set and the tables would be pre-opened
|
||||
in a usual way, they would have been closed.
|
||||
*/
|
||||
if (open_temporary_tables(thd, all_tables))
|
||||
if (thd->open_temporary_tables(all_tables))
|
||||
goto error;
|
||||
|
||||
if (lock_tables_precheck(thd, all_tables))
|
||||
@ -6780,7 +6784,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
|
||||
/*
|
||||
Open temporary tables to be able to detect them during privilege check.
|
||||
*/
|
||||
if (open_temporary_tables(thd, dst_table))
|
||||
if (thd->open_temporary_tables(dst_table))
|
||||
return TRUE;
|
||||
|
||||
if (check_access(thd, SELECT_ACL, dst_table->db,
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2014, SkySQL Ab.
|
||||
Copyright (c) 2016, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -534,12 +535,9 @@ bool Sql_cmd_alter_table_exchange_partition::
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_ON)
|
||||
{
|
||||
/* Forward declaration */
|
||||
TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
|
||||
|
||||
if ((!thd->is_current_stmt_binlog_format_row() ||
|
||||
/* TODO: Do we really need to check for temp tables in this case? */
|
||||
!find_temporary_table(thd, table_list)) &&
|
||||
!thd->find_temporary_table(table_list)) &&
|
||||
wsrep_to_isolation_begin(thd, table_list->db, table_list->table_name,
|
||||
NULL))
|
||||
{
|
||||
@ -783,11 +781,9 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/* Forward declaration */
|
||||
TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
|
||||
|
||||
if (WSREP(thd) && (!thd->is_current_stmt_binlog_format_row() ||
|
||||
!find_temporary_table(thd, first_table)) &&
|
||||
if (WSREP(thd) &&
|
||||
(!thd->is_current_stmt_binlog_format_row() ||
|
||||
!thd->find_temporary_table(first_table)) &&
|
||||
wsrep_to_isolation_begin(
|
||||
thd, first_table->db, first_table->table_name, NULL)
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2015, MariaDB
|
||||
Copyright (c) 2008, 2016, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -1259,7 +1259,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
|
||||
*/
|
||||
if (table_list->lock_type != TL_WRITE_DELAYED)
|
||||
{
|
||||
if (open_temporary_tables(thd, table_list))
|
||||
if (thd->open_temporary_tables(table_list))
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -2028,7 +2028,7 @@ static bool mysql_test_create_view(Prepared_statement *stmt)
|
||||
Since we can't pre-open temporary tables for SQLCOM_CREATE_VIEW,
|
||||
(see mysql_create_view) we have to do it here instead.
|
||||
*/
|
||||
if (open_temporary_tables(thd, tables))
|
||||
if (thd->open_temporary_tables(tables))
|
||||
goto err;
|
||||
|
||||
if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
|
||||
@ -2280,7 +2280,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
|
||||
*/
|
||||
if (sql_command_flags[sql_command] & CF_PREOPEN_TMP_TABLES)
|
||||
{
|
||||
if (open_temporary_tables(thd, tables))
|
||||
if (thd->open_temporary_tables(tables))
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -4155,7 +4155,7 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
|
||||
'only_view_structure()'.
|
||||
*/
|
||||
lex->sql_command= SQLCOM_SHOW_FIELDS;
|
||||
result= (open_temporary_tables(thd, table_list) ||
|
||||
result= (thd->open_temporary_tables(table_list) ||
|
||||
open_normal_and_derived_tables(thd, table_list,
|
||||
(MYSQL_OPEN_IGNORE_FLUSH |
|
||||
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |
|
||||
@ -4218,6 +4218,7 @@ end:
|
||||
all tables open within this Open_tables_state.
|
||||
*/
|
||||
thd->temporary_tables= NULL;
|
||||
|
||||
close_thread_tables(thd);
|
||||
/*
|
||||
Release metadata lock we might have acquired.
|
||||
|
128
sql/sql_table.cc
128
sql/sql_table.cc
@ -25,7 +25,7 @@
|
||||
#include "sql_table.h"
|
||||
#include "sql_parse.h" // test_if_data_home_dir
|
||||
#include "sql_cache.h" // query_cache_*
|
||||
#include "sql_base.h" // open_table_uncached, lock_table_names
|
||||
#include "sql_base.h" // lock_table_names
|
||||
#include "lock.h" // mysql_unlock_tables
|
||||
#include "strfunc.h" // find_type2, find_set
|
||||
#include "sql_truncate.h" // regenerate_locked_table
|
||||
@ -2030,7 +2030,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
|
||||
LEX_STRING db_name= { table->db, table->db_length };
|
||||
LEX_STRING table_name= { table->table_name, table->table_name_length };
|
||||
if (table->open_type == OT_BASE_ONLY ||
|
||||
!find_temporary_table(thd, table))
|
||||
!thd->find_temporary_table(table))
|
||||
(void) delete_statistics_for_table(thd, &db_name, &table_name);
|
||||
}
|
||||
}
|
||||
@ -2283,23 +2283,17 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
*/
|
||||
DBUG_ASSERT(!(thd->locked_tables_mode &&
|
||||
table->open_type != OT_BASE_ONLY &&
|
||||
find_temporary_table(thd, table) &&
|
||||
thd->find_temporary_table(table) &&
|
||||
table->mdl_request.ticket != NULL));
|
||||
|
||||
/*
|
||||
drop_temporary_table may return one of the following error codes:
|
||||
. 0 - a temporary table was successfully dropped.
|
||||
. 1 - a temporary table was not found.
|
||||
. -1 - a temporary table is used by an outer statement.
|
||||
*/
|
||||
if (table->open_type == OT_BASE_ONLY || !is_temporary_table(table))
|
||||
error= 1;
|
||||
else
|
||||
{
|
||||
table_creation_was_logged= table->table->s->table_creation_was_logged;
|
||||
if ((error= drop_temporary_table(thd, table->table, &is_trans)) == -1)
|
||||
if (thd->drop_temporary_table(table->table, &is_trans, true))
|
||||
{
|
||||
DBUG_ASSERT(thd->in_sub_stmt);
|
||||
error= 1;
|
||||
goto err;
|
||||
}
|
||||
table->table= 0;
|
||||
@ -4635,7 +4629,8 @@ err:
|
||||
which was created.
|
||||
@param[out] key_count Number of keys in table which was created.
|
||||
|
||||
If one creates a temporary table, this is automatically opened
|
||||
If one creates a temporary table, its is automatically opened and its
|
||||
TABLE_SHARE is added to THD::all_temp_tables list.
|
||||
|
||||
Note that this function assumes that caller already have taken
|
||||
exclusive metadata lock on table being created or used some other
|
||||
@ -4695,20 +4690,22 @@ int create_table_impl(THD *thd,
|
||||
/* Check if table exists */
|
||||
if (create_info->tmp_table())
|
||||
{
|
||||
TABLE *tmp_table;
|
||||
if (find_and_use_temporary_table(thd, db, table_name, &tmp_table))
|
||||
goto err;
|
||||
/*
|
||||
If a table exists, it must have been pre-opened. Try looking for one
|
||||
in-use in THD::all_temp_tables list of TABLE_SHAREs.
|
||||
*/
|
||||
TABLE *tmp_table= thd->find_temporary_table(db, table_name);
|
||||
|
||||
if (tmp_table)
|
||||
{
|
||||
bool table_creation_was_logged= tmp_table->s->table_creation_was_logged;
|
||||
if (options.or_replace())
|
||||
{
|
||||
bool tmp;
|
||||
/*
|
||||
We are using CREATE OR REPLACE on an existing temporary table
|
||||
Remove the old table so that we can re-create it.
|
||||
*/
|
||||
if (drop_temporary_table(thd, tmp_table, &tmp))
|
||||
if (thd->drop_temporary_table(tmp_table, NULL, true))
|
||||
goto err;
|
||||
}
|
||||
else if (options.if_not_exists())
|
||||
@ -4847,17 +4844,12 @@ int create_table_impl(THD *thd,
|
||||
create_info->table= 0;
|
||||
if (!frm_only && create_info->tmp_table())
|
||||
{
|
||||
/*
|
||||
Open a table (skipping table cache) and add it into
|
||||
THD::temporary_tables list.
|
||||
*/
|
||||
|
||||
TABLE *table= open_table_uncached(thd, create_info->db_type, frm, path,
|
||||
db, table_name, true, true);
|
||||
TABLE *table= thd->create_and_open_tmp_table(create_info->db_type, frm,
|
||||
path, db, table_name, true);
|
||||
|
||||
if (!table)
|
||||
{
|
||||
(void) rm_temporary_table(create_info->db_type, path);
|
||||
(void) thd->rm_temporary_table(create_info->db_type, path);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -7143,7 +7135,8 @@ static bool mysql_inplace_alter_table(THD *thd,
|
||||
HA_EXTRA_NOT_USED,
|
||||
NULL);
|
||||
table_list->table= table= NULL;
|
||||
close_temporary_table(thd, altered_table, true, false);
|
||||
|
||||
thd->drop_temporary_table(altered_table, NULL, false);
|
||||
|
||||
/*
|
||||
Replace the old .FRM with the new .FRM, but keep the old name for now.
|
||||
@ -7233,7 +7226,7 @@ static bool mysql_inplace_alter_table(THD *thd,
|
||||
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
|
||||
/* QQ; do something about metadata locks ? */
|
||||
}
|
||||
close_temporary_table(thd, altered_table, true, false);
|
||||
thd->drop_temporary_table(altered_table, NULL, false);
|
||||
// Delete temporary .frm/.par
|
||||
(void) quick_rm_table(thd, create_info->db_type, alter_ctx->new_db,
|
||||
alter_ctx->tmp_name, FN_IS_TMP | NO_HA_TABLE);
|
||||
@ -8385,7 +8378,12 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
{
|
||||
if (table->s->tmp_table != NO_TMP_TABLE)
|
||||
{
|
||||
if (find_temporary_table(thd, alter_ctx.new_db, alter_ctx.new_name))
|
||||
/*
|
||||
Check whether a temporary table exists with same requested new name.
|
||||
If such table exists, there must be a corresponding TABLE_SHARE in
|
||||
THD::all_temp_tables list.
|
||||
*/
|
||||
if (thd->find_tmp_table_share(alter_ctx.new_db, alter_ctx.new_name))
|
||||
{
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias);
|
||||
DBUG_RETURN(true);
|
||||
@ -8821,11 +8819,11 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
// We assume that the table is non-temporary.
|
||||
DBUG_ASSERT(!table->s->tmp_table);
|
||||
|
||||
if (!(altered_table= open_table_uncached(thd, new_db_type, &frm,
|
||||
alter_ctx.get_tmp_path(),
|
||||
alter_ctx.new_db,
|
||||
alter_ctx.tmp_name,
|
||||
true, false)))
|
||||
if (!(altered_table=
|
||||
thd->create_and_open_tmp_table(new_db_type, &frm,
|
||||
alter_ctx.get_tmp_path(),
|
||||
alter_ctx.new_db, alter_ctx.tmp_name,
|
||||
false)))
|
||||
goto err_new_table_cleanup;
|
||||
|
||||
/* Set markers for fields in TABLE object for altered table. */
|
||||
@ -8865,7 +8863,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
{
|
||||
ha_alter_info.report_unsupported_error("LOCK=NONE/SHARED",
|
||||
"LOCK=EXCLUSIVE");
|
||||
close_temporary_table(thd, altered_table, true, false);
|
||||
thd->drop_temporary_table(altered_table, NULL, false);
|
||||
goto err_new_table_cleanup;
|
||||
}
|
||||
break;
|
||||
@ -8876,7 +8874,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
Alter_info::ALTER_TABLE_LOCK_NONE)
|
||||
{
|
||||
ha_alter_info.report_unsupported_error("LOCK=NONE", "LOCK=SHARED");
|
||||
close_temporary_table(thd, altered_table, true, false);
|
||||
thd->drop_temporary_table(altered_table, NULL, false);
|
||||
goto err_new_table_cleanup;
|
||||
}
|
||||
break;
|
||||
@ -8890,7 +8888,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
{
|
||||
ha_alter_info.report_unsupported_error("ALGORITHM=INPLACE",
|
||||
"ALGORITHM=COPY");
|
||||
close_temporary_table(thd, altered_table, true, false);
|
||||
thd->drop_temporary_table(altered_table, NULL, false);
|
||||
goto err_new_table_cleanup;
|
||||
}
|
||||
// COPY with LOCK=NONE is not supported, no point in trying.
|
||||
@ -8898,7 +8896,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
Alter_info::ALTER_TABLE_LOCK_NONE)
|
||||
{
|
||||
ha_alter_info.report_unsupported_error("LOCK=NONE", "LOCK=SHARED");
|
||||
close_temporary_table(thd, altered_table, true, false);
|
||||
thd->drop_temporary_table(altered_table, NULL, false);
|
||||
goto err_new_table_cleanup;
|
||||
}
|
||||
// Otherwise use COPY
|
||||
@ -8906,7 +8904,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
break;
|
||||
case HA_ALTER_ERROR:
|
||||
default:
|
||||
close_temporary_table(thd, altered_table, true, false);
|
||||
thd->drop_temporary_table(altered_table, NULL, false);
|
||||
goto err_new_table_cleanup;
|
||||
}
|
||||
|
||||
@ -8925,7 +8923,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
}
|
||||
else
|
||||
{
|
||||
close_temporary_table(thd, altered_table, true, false);
|
||||
thd->drop_temporary_table(altered_table, NULL, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8978,13 +8976,18 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
|
||||
if (create_info->tmp_table())
|
||||
{
|
||||
if (!open_table_uncached(thd, new_db_type, &frm,
|
||||
alter_ctx.get_tmp_path(),
|
||||
alter_ctx.new_db, alter_ctx.tmp_name,
|
||||
true, true))
|
||||
TABLE *tmp_table=
|
||||
thd->create_and_open_tmp_table(new_db_type, &frm,
|
||||
alter_ctx.get_tmp_path(),
|
||||
alter_ctx.new_db, alter_ctx.tmp_name,
|
||||
true);
|
||||
if (!tmp_table)
|
||||
{
|
||||
goto err_new_table_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Open the table since we need to copy the data. */
|
||||
if (table->s->tmp_table != NO_TMP_TABLE)
|
||||
{
|
||||
@ -8992,18 +8995,24 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
tbl.init_one_table(alter_ctx.new_db, strlen(alter_ctx.new_db),
|
||||
alter_ctx.tmp_name, strlen(alter_ctx.tmp_name),
|
||||
alter_ctx.tmp_name, TL_READ_NO_INSERT);
|
||||
/* Table is in thd->temporary_tables */
|
||||
(void) open_temporary_table(thd, &tbl);
|
||||
/*
|
||||
Table can be found in the list of open tables in THD::all_temp_tables
|
||||
list.
|
||||
*/
|
||||
tbl.table= thd->find_temporary_table(&tbl);
|
||||
new_table= tbl.table;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* table is a normal table: Create temporary table in same directory */
|
||||
/* Open our intermediate table. */
|
||||
new_table= open_table_uncached(thd, new_db_type, &frm,
|
||||
alter_ctx.get_tmp_path(),
|
||||
alter_ctx.new_db, alter_ctx.tmp_name,
|
||||
true, true);
|
||||
/*
|
||||
table is a normal table: Create temporary table in same directory.
|
||||
Open our intermediate table.
|
||||
*/
|
||||
new_table=
|
||||
thd->create_and_open_tmp_table(new_db_type, &frm,
|
||||
alter_ctx.get_tmp_path(),
|
||||
alter_ctx.new_db, alter_ctx.tmp_name,
|
||||
true);
|
||||
}
|
||||
if (!new_table)
|
||||
goto err_new_table_cleanup;
|
||||
@ -9071,10 +9080,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
new_table->s->table_creation_was_logged=
|
||||
table->s->table_creation_was_logged;
|
||||
/* Remove link to old table and rename the new one */
|
||||
close_temporary_table(thd, table, true, true);
|
||||
thd->drop_temporary_table(table, NULL, true);
|
||||
/* Should pass the 'new_name' as we store table name in the cache */
|
||||
if (rename_temporary_table(thd, new_table,
|
||||
alter_ctx.new_db, alter_ctx.new_name))
|
||||
if (thd->rename_temporary_table(new_table, alter_ctx.new_db,
|
||||
alter_ctx.new_name))
|
||||
goto err_new_table_cleanup;
|
||||
/* We don't replicate alter table statement on temporary tables */
|
||||
if (!thd->is_current_stmt_binlog_format_row() &&
|
||||
@ -9086,10 +9095,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
|
||||
/*
|
||||
Close the intermediate table that will be the new table, but do
|
||||
not delete it! Even altough MERGE tables do not have their children
|
||||
attached here it is safe to call close_temporary_table().
|
||||
not delete it! Even though MERGE tables do not have their children
|
||||
attached here it is safe to call THD::drop_temporary_table().
|
||||
*/
|
||||
close_temporary_table(thd, new_table, true, false);
|
||||
thd->drop_temporary_table(new_table, NULL, false);
|
||||
new_table= NULL;
|
||||
|
||||
DEBUG_SYNC(thd, "alter_table_before_rename_result_table");
|
||||
@ -9231,8 +9240,7 @@ err_new_table_cleanup:
|
||||
my_free(const_cast<uchar*>(frm.str));
|
||||
if (new_table)
|
||||
{
|
||||
/* close_temporary_table() frees the new_table pointer. */
|
||||
close_temporary_table(thd, new_table, true, true);
|
||||
thd->drop_temporary_table(new_table, NULL, true);
|
||||
}
|
||||
else
|
||||
(void) quick_rm_table(thd, new_db_type,
|
||||
@ -9732,7 +9740,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
|
||||
/* Allow to open real tables only. */
|
||||
table->required_type= FRMTYPE_TABLE;
|
||||
|
||||
if (open_temporary_tables(thd, table) ||
|
||||
if (thd->open_temporary_tables(table) ||
|
||||
open_and_lock_tables(thd, table, FALSE, 0))
|
||||
{
|
||||
t= NULL;
|
||||
|
@ -82,7 +82,7 @@ static my_bool print_cached_tables_callback(TDC_element *element,
|
||||
TABLE *entry;
|
||||
|
||||
mysql_mutex_lock(&element->LOCK_table_share);
|
||||
TDC_element::All_share_tables_list::Iterator it(element->all_tables);
|
||||
All_share_tables_list::Iterator it(element->all_tables);
|
||||
while ((entry= it++))
|
||||
{
|
||||
THD *in_use= entry->in_use;
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "sql_parse.h" // parse_sql
|
||||
#include "parse_file.h"
|
||||
#include "sp.h"
|
||||
#include "sql_base.h" // find_temporary_table
|
||||
#include "sql_base.h"
|
||||
#include "sql_show.h" // append_definer, append_identifier
|
||||
#include "sql_table.h" // build_table_filename,
|
||||
// check_n_cut_mysql50_prefix
|
||||
@ -507,7 +507,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||
DBUG_ASSERT(tables->next_global == 0);
|
||||
|
||||
/* We do not allow creation of triggers on temporary tables. */
|
||||
if (create && find_temporary_table(thd, tables))
|
||||
if (create && thd->find_tmp_table_share(tables))
|
||||
{
|
||||
my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias);
|
||||
goto end;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2004, 2013, Oracle and/or its affiliates.
|
||||
Copyright (c) 2011, 2015, MariaDB
|
||||
Copyright (c) 2011, 2016, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -429,7 +429,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
||||
lex->link_first_table_back(view, link_to_local);
|
||||
view->open_type= OT_BASE_ONLY;
|
||||
|
||||
if (open_temporary_tables(thd, lex->query_tables) ||
|
||||
if (thd->open_temporary_tables(lex->query_tables) ||
|
||||
open_and_lock_tables(thd, lex->query_tables, TRUE, 0))
|
||||
{
|
||||
view= lex->unlink_first_table(&link_to_local);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2012, 2015, MariaDB
|
||||
Copyright (c) 2012, 2016, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -477,7 +477,8 @@ static bool binlog_format_check(sys_var *self, THD *thd, set_var *var)
|
||||
switching @@SESSION.binlog_format from MIXED to STATEMENT when there are
|
||||
open temp tables and we are logging in row format.
|
||||
*/
|
||||
if (thd->temporary_tables && var->type == OPT_SESSION &&
|
||||
if (thd->has_thd_temporary_tables() &&
|
||||
var->type == OPT_SESSION &&
|
||||
var->save_result.ulonglong_value == BINLOG_FORMAT_STMT &&
|
||||
((thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
|
||||
thd->is_current_stmt_binlog_format_row()) ||
|
||||
|
@ -3922,7 +3922,7 @@ bool TABLE_SHARE::visit_subgraph(Wait_for_flush *wait_for_flush,
|
||||
tdc->all_tables_refs++;
|
||||
mysql_mutex_unlock(&tdc->LOCK_table_share);
|
||||
|
||||
TDC_element::All_share_tables_list::Iterator tables_it(tdc->all_tables);
|
||||
All_share_tables_list::Iterator tables_it(tdc->all_tables);
|
||||
|
||||
/*
|
||||
In case of multiple searches running in parallel, avoid going
|
||||
|
25
sql/table.h
25
sql/table.h
@ -2,6 +2,7 @@
|
||||
#define TABLE_INCLUDED
|
||||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2014, SkySQL Ab.
|
||||
Copyright (c) 2016, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -1012,7 +1013,7 @@ private:
|
||||
One should use methods of I_P_List template instead.
|
||||
*/
|
||||
TABLE *share_all_next, **share_all_prev;
|
||||
friend struct TDC_element;
|
||||
friend struct All_share_tables;
|
||||
|
||||
public:
|
||||
|
||||
@ -1435,6 +1436,19 @@ struct TABLE_share
|
||||
}
|
||||
};
|
||||
|
||||
struct All_share_tables
|
||||
{
|
||||
static inline TABLE **next_ptr(TABLE *l)
|
||||
{
|
||||
return &l->share_all_next;
|
||||
}
|
||||
static inline TABLE ***prev_ptr(TABLE *l)
|
||||
{
|
||||
return &l->share_all_prev;
|
||||
}
|
||||
};
|
||||
|
||||
typedef I_P_List <TABLE, All_share_tables> All_share_tables_list;
|
||||
|
||||
enum enum_schema_table_state
|
||||
{
|
||||
@ -2662,15 +2676,6 @@ inline bool is_infoschema_db(const char *name)
|
||||
|
||||
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings);
|
||||
|
||||
/**
|
||||
return true if the table was created explicitly.
|
||||
*/
|
||||
inline bool is_user_table(TABLE * table)
|
||||
{
|
||||
const char *name= table->s->table_name.str;
|
||||
return strncmp(name, tmp_file_prefix, tmp_file_prefix_length);
|
||||
}
|
||||
|
||||
inline void mark_as_null_row(TABLE *table)
|
||||
{
|
||||
table->null_row=1;
|
||||
|
@ -965,7 +965,7 @@ void tdc_release_share(TABLE_SHARE *share)
|
||||
|
||||
static void kill_delayed_threads_for_table(TDC_element *element)
|
||||
{
|
||||
TDC_element::All_share_tables_list::Iterator it(element->all_tables);
|
||||
All_share_tables_list::Iterator it(element->all_tables);
|
||||
TABLE *tab;
|
||||
|
||||
mysql_mutex_assert_owner(&element->LOCK_table_share);
|
||||
@ -1086,7 +1086,7 @@ bool tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
||||
if (remove_type == TDC_RT_REMOVE_NOT_OWN ||
|
||||
remove_type == TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE)
|
||||
{
|
||||
TDC_element::All_share_tables_list::Iterator it(element->all_tables);
|
||||
All_share_tables_list::Iterator it(element->all_tables);
|
||||
while ((table= it++))
|
||||
{
|
||||
my_refs++;
|
||||
|
@ -27,9 +27,6 @@ struct TDC_element
|
||||
TABLE_SHARE *share;
|
||||
|
||||
typedef I_P_List <TABLE, TABLE_share> TABLE_list;
|
||||
typedef I_P_List <TABLE, I_P_List_adapter<TABLE, &TABLE::share_all_next,
|
||||
&TABLE::share_all_prev> >
|
||||
All_share_tables_list;
|
||||
/**
|
||||
Protects ref_count, m_flush_tickets, all_tables, free_tables, flushed,
|
||||
all_tables_refs.
|
||||
|
1499
sql/temporary_tables.cc
Normal file
1499
sql/temporary_tables.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -62,7 +62,6 @@ err:
|
||||
|
||||
#include "transaction.h" // trans_commit(), trans_rollback()
|
||||
#include "rpl_rli.h" // class Relay_log_info;
|
||||
#include "sql_base.h" // close_temporary_table()
|
||||
|
||||
void wsrep_set_apply_format(THD* thd, Format_description_log_event* ev)
|
||||
{
|
||||
@ -277,14 +276,11 @@ wsrep_cb_status_t wsrep_apply_cb(void* const ctx,
|
||||
wsrep_dump_rbr_buf_with_header(thd, buf, buf_len);
|
||||
}
|
||||
|
||||
TABLE *tmp;
|
||||
while ((tmp = thd->temporary_tables))
|
||||
if (thd->has_thd_temporary_tables())
|
||||
{
|
||||
WSREP_DEBUG("Applier %lld, has temporary tables: %s.%s",
|
||||
(longlong) thd->thread_id,
|
||||
(tmp->s) ? tmp->s->db.str : "void",
|
||||
(tmp->s) ? tmp->s->table_name.str : "void");
|
||||
close_temporary_table(thd, tmp, 1, 1);
|
||||
WSREP_DEBUG("Applier %lld has temporary tables. Closing them now..",
|
||||
thd->thread_id);
|
||||
thd->close_temporary_tables();
|
||||
}
|
||||
|
||||
return rcode;
|
||||
|
@ -1085,8 +1085,6 @@ static bool wsrep_prepare_keys_for_isolation(THD* thd,
|
||||
ka->keys= 0;
|
||||
ka->keys_len= 0;
|
||||
|
||||
extern TABLE* find_temporary_table(THD*, const TABLE_LIST*);
|
||||
|
||||
if (db || table)
|
||||
{
|
||||
TABLE_LIST tmp_table;
|
||||
@ -1098,7 +1096,7 @@ static bool wsrep_prepare_keys_for_isolation(THD* thd,
|
||||
(table) ? table : "",
|
||||
MDL_INTENTION_EXCLUSIVE, MDL_STATEMENT);
|
||||
|
||||
if (!table || !find_temporary_table(thd, &tmp_table))
|
||||
if (!table || !thd->find_temporary_table(&tmp_table))
|
||||
{
|
||||
if (!(ka->keys= (wsrep_key_t*)my_malloc(sizeof(wsrep_key_t), MYF(0))))
|
||||
{
|
||||
@ -1126,7 +1124,7 @@ static bool wsrep_prepare_keys_for_isolation(THD* thd,
|
||||
|
||||
for (const TABLE_LIST* table= table_list; table; table= table->next_global)
|
||||
{
|
||||
if (!find_temporary_table(thd, table))
|
||||
if (!thd->find_temporary_table(table))
|
||||
{
|
||||
wsrep_key_t* tmp;
|
||||
tmp= (wsrep_key_t*)my_realloc(
|
||||
@ -2443,26 +2441,13 @@ bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
TABLE_LIST* src_table,
|
||||
HA_CREATE_INFO *create_info)
|
||||
{
|
||||
TABLE *tmp_table;
|
||||
bool is_tmp_table= FALSE;
|
||||
|
||||
for (tmp_table= thd->temporary_tables; tmp_table; tmp_table=tmp_table->next)
|
||||
{
|
||||
if (!strcmp(src_table->db, tmp_table->s->db.str) &&
|
||||
!strcmp(src_table->table_name, tmp_table->s->table_name.str))
|
||||
{
|
||||
is_tmp_table= TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (create_info->tmp_table())
|
||||
{
|
||||
|
||||
/* CREATE TEMPORARY TABLE LIKE must be skipped from replication */
|
||||
WSREP_DEBUG("CREATE TEMPORARY TABLE LIKE... skipped replication\n %s",
|
||||
thd->query());
|
||||
}
|
||||
else if (!is_tmp_table)
|
||||
else if (!(thd->find_temporary_table(src_table)))
|
||||
{
|
||||
/* this is straight CREATE TABLE LIKE... eith no tmp tables */
|
||||
WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL);
|
||||
@ -2477,7 +2462,7 @@ bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
bzero((void*) &tbl, sizeof(tbl));
|
||||
tbl.db= src_table->db;
|
||||
tbl.table_name= tbl.alias= src_table->table_name;
|
||||
tbl.table= tmp_table;
|
||||
tbl.table= src_table->table;
|
||||
char buf[2048];
|
||||
String query(buf, sizeof(buf), system_charset_info);
|
||||
query.length(0); // Have to zero it since constructor doesn't
|
||||
|
@ -360,13 +360,10 @@ static void wsrep_replication_process(THD *thd)
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
TABLE *tmp;
|
||||
while ((tmp = thd->temporary_tables))
|
||||
if(thd->has_thd_temporary_tables())
|
||||
{
|
||||
WSREP_WARN("Applier %lld, has temporary tables at exit: %s.%s",
|
||||
(longlong) thd->thread_id,
|
||||
(tmp->s) ? tmp->s->db.str : "void",
|
||||
(tmp->s) ? tmp->s->table_name.str : "void");
|
||||
WSREP_WARN("Applier %lld has temporary tables at exit.",
|
||||
thd->thread_id);
|
||||
}
|
||||
wsrep_return_from_bf_mode(thd, &shadow);
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -1640,7 +1640,7 @@ long long spider_direct_sql_body(
|
||||
table_list.table_name = direct_sql->table_names[roop_count];
|
||||
#endif
|
||||
if (!(direct_sql->tables[roop_count] =
|
||||
find_temporary_table(thd, &table_list)))
|
||||
thd->find_temporary_table(&table_list)))
|
||||
{
|
||||
#if MYSQL_VERSION_ID < 50500
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user