diff options
-rw-r--r-- | mysql-test/r/ps.result | 16 | ||||
-rw-r--r-- | mysql-test/t/ps.test | 16 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 14 |
3 files changed, 45 insertions, 1 deletions
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 81167bc85c0..77bfcb9eabb 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -5509,5 +5509,21 @@ id select_type table type possible_keys key key_len ref rows Extra NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL DEALLOCATE PREPARE stmt; DROP TABLE t1; +# +# MDEV-16128: Server crash in Item_func::print_op on 2nd execution of PS +# +CREATE TABLE t1 (a2 varchar(10)); +CREATE TABLE t2 (u1 varchar(10) CHARACTER SET utf8 ); +CREATE TABLE t3 (u2 varchar(10) CHARACTER SET utf8); +PREPARE stmt FROM "SELECT t1.* FROM (t1 JOIN t2 ON (t2.u1 = t1.a2)) WHERE (EXISTS (SELECT 1 FROM t3 WHERE t3.u2 = t1.a2))"; +EXECUTE stmt; +a2 +# Without the patch second execution of the prepared statement +# would lead to server crash. +EXECUTE stmt; +a2 +# Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1, t2, t3; # End of 10.2 tests # diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 81d8e8e0fed..233ef8c369c 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -4990,5 +4990,21 @@ EXECUTE stmt; DEALLOCATE PREPARE stmt; DROP TABLE t1; +--echo # +--echo # MDEV-16128: Server crash in Item_func::print_op on 2nd execution of PS +--echo # + +CREATE TABLE t1 (a2 varchar(10)); +CREATE TABLE t2 (u1 varchar(10) CHARACTER SET utf8 ); +CREATE TABLE t3 (u2 varchar(10) CHARACTER SET utf8); +PREPARE stmt FROM "SELECT t1.* FROM (t1 JOIN t2 ON (t2.u1 = t1.a2)) WHERE (EXISTS (SELECT 1 FROM t3 WHERE t3.u2 = t1.a2))"; +EXECUTE stmt; +--echo # Without the patch second execution of the prepared statement +--echo # would lead to server crash. +EXECUTE stmt; +--echo # Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1, t2, t3; + --echo # End of 10.2 tests --echo # diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3a76982d80e..19bd6176bd1 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -513,19 +513,31 @@ bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp) { DBUG_ASSERT(arg_count >= 2); // Item_func_nullif has arg_count == 3 + Query_arena *arena, backup; + arena= thd->activate_stmt_arena_if_needed(&backup); + if (args[0]->cmp_type() == STRING_RESULT && args[1]->cmp_type() == STRING_RESULT) { DTCollation tmp; if (agg_arg_charsets_for_comparison(tmp, args, 2)) + { + if (arena) + thd->restore_active_arena(arena, &backup); + return true; + } cmp->m_compare_collation= tmp.collation; } // Convert constants when compared to int/year field DBUG_ASSERT(functype() != LIKE_FUNC); convert_const_compared_to_int_field(thd); - return cmp->set_cmp_func(this, &args[0], &args[1], true); + bool ret= cmp->set_cmp_func(this, &args[0], &args[1], true); + if (arena) + thd->restore_active_arena(arena, &backup); + + return ret; } |