From 1d7b4c268941ec1facef1b82adbff329c08c464d Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Thu, 5 Apr 2018 13:50:12 +0300 Subject: [PATCH] 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. --- mysql-test/main/prepare.result | 52 ++++++++++++++++++++++++++++++++++ mysql-test/main/prepare.test | 42 +++++++++++++++++++++++++++ sql/item.cc | 9 ++---- 3 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 mysql-test/main/prepare.result create mode 100644 mysql-test/main/prepare.test 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; }