summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Widenius <monty@mariadb.org>2018-04-05 13:50:12 +0300
committerMichael Widenius <monty@mariadb.org>2018-04-05 13:55:28 +0300
commit1d7b4c268941ec1facef1b82adbff329c08c464d (patch)
tree3a266523f29a932bba389d3130405f4672c08201
parent30f692f0165ada010a70f96f49f491f5215c1ca5 (diff)
downloadmariadb-git-1d7b4c268941ec1facef1b82adbff329c08c464d.tar.gz
MDEV-15738 Server crashes in my_strcasecmp_utf8 on query from I_S with UNION executed as PS
Problem was the Item_field::Item_field(THD*, Field*) had old code that put a null pointer in orig_field_names. Now, when we have proper re-prepare if table definition changes, this is not needed anymore.
-rw-r--r--mysql-test/main/prepare.result52
-rw-r--r--mysql-test/main/prepare.test42
-rw-r--r--sql/item.cc9
3 files changed, 97 insertions, 6 deletions
diff --git a/mysql-test/main/prepare.result b/mysql-test/main/prepare.result
new file mode 100644
index 00000000000..c1a2969212b
--- /dev/null
+++ b/mysql-test/main/prepare.result
@@ -0,0 +1,52 @@
+PREPARE stmt1 FROM "
+SELECT table_name FROM information_schema.tables
+WHERE table_name = 't1_first'
+UNION ALL
+SELECT table_name FROM information_schema.tables
+WHERE table_name = 't1_second'";
+execute stmt1;
+table_name
+execute stmt1;
+table_name
+create or replace table t1 (a int primary key, table_name char(40));
+insert into t1 values(1,"t1_first");
+insert into t1 values(2,"t1_second");
+PREPARE stmt2 FROM "
+SELECT table_name FROM t1
+WHERE table_name = 't1_first'
+UNION ALL
+SELECT table_name FROM t1
+WHERE table_name = 't1_second'";
+execute stmt2;
+table_name
+t1_first
+t1_second
+execute stmt2;
+table_name
+t1_first
+t1_second
+flush tables;
+execute stmt2;
+table_name
+t1_first
+t1_second
+alter table t1 add column b int;
+execute stmt2;
+table_name
+t1_first
+t1_second
+execute stmt2;
+table_name
+t1_first
+t1_second
+drop table t1;
+execute stmt2;
+ERROR 42S02: Table 'test.t1' doesn't exist
+create or replace table t1 (a int primary key, table_name char(40));
+insert into t1 values(1,"t1_first");
+execute stmt2;
+table_name
+t1_first
+deallocate prepare stmt1;
+deallocate prepare stmt2;
+drop table t1;
diff --git a/mysql-test/main/prepare.test b/mysql-test/main/prepare.test
new file mode 100644
index 00000000000..eaab376a5a2
--- /dev/null
+++ b/mysql-test/main/prepare.test
@@ -0,0 +1,42 @@
+#
+# MDEV-15738 Server crashes in my_strcasecmp_utf8 on query from I_S with UNION
+# executed as PS
+#
+
+PREPARE stmt1 FROM "
+SELECT table_name FROM information_schema.tables
+WHERE table_name = 't1_first'
+UNION ALL
+SELECT table_name FROM information_schema.tables
+WHERE table_name = 't1_second'";
+execute stmt1;
+execute stmt1;
+
+create or replace table t1 (a int primary key, table_name char(40));
+insert into t1 values(1,"t1_first");
+insert into t1 values(2,"t1_second");
+
+PREPARE stmt2 FROM "
+SELECT table_name FROM t1
+WHERE table_name = 't1_first'
+UNION ALL
+SELECT table_name FROM t1
+WHERE table_name = 't1_second'";
+
+execute stmt2;
+execute stmt2;
+flush tables;
+execute stmt2;
+alter table t1 add column b int;
+execute stmt2;
+execute stmt2;
+drop table t1;
+--error ER_NO_SUCH_TABLE
+execute stmt2;
+create or replace table t1 (a int primary key, table_name char(40));
+insert into t1 values(1,"t1_first");
+execute stmt2;
+
+deallocate prepare stmt1;
+deallocate prepare stmt2;
+drop table t1;
diff --git a/sql/item.cc b/sql/item.cc
index b32967e8944..41944d24e8c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -3077,12 +3077,9 @@ Item_field::Item_field(THD *thd, Field *f)
have_privileges(0), any_privileges(0)
{
set_field(f);
- /*
- field_name and table_name should not point to garbage
- if this item is to be reused
- */
- orig_table_name= "";
- orig_field_name= null_clex_str;
+
+ orig_table_name= table_name;
+ orig_field_name= field_name;
with_field= 1;
}