summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSachin <sachin.setiya@mariadb.com>2018-06-26 11:33:58 +0530
committersachin <sachin.setiya@mariadb.com>2018-07-17 18:30:01 +0530
commit0723e9a9465297c3caa512258b952391dbeb4cb6 (patch)
tree3caffa35024058bb45f3d0e29e077efbd1c38aa2
parent1cc1d0429da14a041a6240c6fce17e0d31cad8e2 (diff)
downloadmariadb-git-bb-10.2-15867.tar.gz
MDEV-16192 Table 't' is specified twice, both as a target for 'CREATE' and...bb-10.2-15867
as a separate source for data Actually MDEV-15867 and MDEV-16192 are same, Slave adds "or replace" to create table stmt. So create table t1 is create or replace on slave. So this bug is not because of replication, We can get this bug on general server if we manually add or replace to create query. Problem:- So if we try to create table t1 (same name as of temp table t1 ) via CREATE or replace TABLE t AS SELECT * FROM t; Since in this query we are creating table from select * from t1 , we call unique_table function to see whether if source and destination table are same. But there is one issue unique_table does not account if source table is tmp table in this case source and destination table can be same. Solution:- We will change find_dup_table to not to look for temp table if CHECK_DUP_SKIP_TEMP_TABLE flag is on.
-rw-r--r--mysql-test/r/create_replace_tmp.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_15867.result9
-rw-r--r--mysql-test/suite/rpl/t/rpl_15867.test11
-rw-r--r--mysql-test/t/create_replace_tmp.test4
-rw-r--r--sql/sql_base.cc6
-rw-r--r--sql/sql_base.h1
-rw-r--r--sql/sql_parse.cc4
7 files changed, 37 insertions, 2 deletions
diff --git a/mysql-test/r/create_replace_tmp.result b/mysql-test/r/create_replace_tmp.result
new file mode 100644
index 00000000000..0239f4d4817
--- /dev/null
+++ b/mysql-test/r/create_replace_tmp.result
@@ -0,0 +1,4 @@
+CREATE TEMPORARY TABLE t (i INT);
+CREATE or replace TABLE t AS SELECT * FROM t;
+DROP TEMPORARY TABLE t;
+DROP TABLE t;
diff --git a/mysql-test/suite/rpl/r/rpl_15867.result b/mysql-test/suite/rpl/r/rpl_15867.result
new file mode 100644
index 00000000000..9cb63266a29
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_15867.result
@@ -0,0 +1,9 @@
+include/master-slave.inc
+[connection master]
+CREATE TEMPORARY TABLE t (i INT);
+CREATE TABLE t AS SELECT * FROM t;
+connection slave;
+connection master;
+DROP TEMPORARY TABLE t;
+DROP TABLE t;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_15867.test b/mysql-test/suite/rpl/t/rpl_15867.test
new file mode 100644
index 00000000000..6de39041bb1
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_15867.test
@@ -0,0 +1,11 @@
+--source include/master-slave.inc
+CREATE TEMPORARY TABLE t (i INT);
+CREATE TABLE t AS SELECT * FROM t;
+
+--sync_slave_with_master
+
+# Cleanup
+--connection master
+DROP TEMPORARY TABLE t;
+DROP TABLE t;
+--source include/rpl_end.inc
diff --git a/mysql-test/t/create_replace_tmp.test b/mysql-test/t/create_replace_tmp.test
new file mode 100644
index 00000000000..0239f4d4817
--- /dev/null
+++ b/mysql-test/t/create_replace_tmp.test
@@ -0,0 +1,4 @@
+CREATE TEMPORARY TABLE t (i INT);
+CREATE or replace TABLE t AS SELECT * FROM t;
+DROP TEMPORARY TABLE t;
+DROP TABLE t;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 32e42daf7c4..0ac7a112161 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1031,6 +1031,12 @@ retry:
if (res->table && (res->table == table->table))
continue;
+ /* Skip if table is tmp table */
+ if (check_flag & CHECK_DUP_SKIP_TEMP_TABLE &&
+ res->table && res->table->s->tmp_table != NO_TMP_TABLE)
+ {
+ continue;
+ }
if (check_flag & CHECK_DUP_FOR_CREATE)
DBUG_RETURN(res);
diff --git a/sql/sql_base.h b/sql/sql_base.h
index 914cdcd4512..4f99111cbd9 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -64,6 +64,7 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
/* Flag bits for unique_table() */
#define CHECK_DUP_ALLOW_DIFFERENT_ALIAS 1
#define CHECK_DUP_FOR_CREATE 2
+#define CHECK_DUP_SKIP_TEMP_TABLE 4
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,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index df0ee2bd680..3ec7b54e0a9 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3910,8 +3910,8 @@ mysql_execute_command(THD *thd)
{
TABLE_LIST *duplicate;
if ((duplicate= unique_table(thd, lex->query_tables,
- lex->query_tables->next_global,
- CHECK_DUP_FOR_CREATE)))
+ lex->query_tables->next_global,
+ CHECK_DUP_FOR_CREATE | CHECK_DUP_SKIP_TEMP_TABLE)))
{
update_non_unique_table_error(lex->query_tables, "CREATE",
duplicate);