From 0a29baba4bae36b947aba9001956f3c800f4205f Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 8 Nov 2010 13:34:27 +0300 Subject: [PATCH 1/2] Fix for bug #54575: crash when joining tables with unique set column(backport from 5.1) Problem: a flaw (derefencing a NULL pointer) in the LIKE optimization code may lead to a server crash in some rare cases. Fix: check the pointer before its dereferencing. mysql-test/r/func_like.result: Fix for bug #54575: crash when joining tables with unique set column - test result. mysql-test/t/func_like.test: Fix for bug #54575: crash when joining tables with unique set column - test case. sql/item_cmpfunc.cc: Fix for bug #54575: crash when joining tables with unique set column - check res2 buffer pointer before its dereferencing as it may be NULL in some cases. --- mysql-test/r/func_like.result | 14 ++++++++++++++ mysql-test/t/func_like.test | 18 ++++++++++++++++-- sql/item_cmpfunc.cc | 7 ++++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result index 7e6fedb9403..f8743d6305f 100644 --- a/mysql-test/r/func_like.result +++ b/mysql-test/r/func_like.result @@ -165,3 +165,17 @@ select 'andre%' like 'andre select _cp1251'andre%' like convert('andreÊ%' using cp1251) escape 'Ê'; _cp1251'andre%' like convert('andreÊ%' using cp1251) escape 'Ê' 1 +End of 4.1 tests +# +# Bug #54575: crash when joining tables with unique set column +# +CREATE TABLE t1(a SET('a') NOT NULL, UNIQUE KEY(a)); +CREATE TABLE t2(b INT PRIMARY KEY); +INSERT INTO t1 VALUES (); +Warnings: +Warning 1364 Field 'a' doesn't have a default value +INSERT INTO t2 VALUES (1), (2), (3); +SELECT 1 FROM t2 JOIN t1 ON 1 LIKE a GROUP BY a; +1 +DROP TABLE t1, t2; +End of 5.1 tests diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test index 4e1183afeff..50ebb2b2782 100644 --- a/mysql-test/t/func_like.test +++ b/mysql-test/t/func_like.test @@ -112,5 +112,19 @@ select 'andre%' like 'andre # select _cp1251'andre%' like convert('andreÊ%' using cp1251) escape 'Ê'; -# -# End of 4.1 tests + +--echo End of 4.1 tests + + +--echo # +--echo # Bug #54575: crash when joining tables with unique set column +--echo # +CREATE TABLE t1(a SET('a') NOT NULL, UNIQUE KEY(a)); +CREATE TABLE t2(b INT PRIMARY KEY); +INSERT INTO t1 VALUES (); +INSERT INTO t2 VALUES (1), (2), (3); +SELECT 1 FROM t2 JOIN t1 ON 1 LIKE a GROUP BY a; +DROP TABLE t1, t2; + + +--echo End of 5.1 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5c2fb9857d5..4ae381af683 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4220,13 +4220,14 @@ Item_func::optimize_type Item_func_like::select_optimize() const if (args[1]->const_item()) { String* res2= args[1]->val_str((String *)&tmp_value2); + const char *ptr2; - if (!res2) + if (!res2 || !(ptr2= res2->ptr())) return OPTIMIZE_NONE; - if (*res2->ptr() != wild_many) + if (*ptr2 != wild_many) { - if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one) + if (args[0]->result_type() != STRING_RESULT || *ptr2 != wild_one) return OPTIMIZE_OP; } } From 50a3c55ee7e378b36bca5940e382fb18674dbd9b Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Mon, 8 Nov 2010 13:51:39 +0300 Subject: [PATCH 2/2] Bug#52711 Segfault when doing EXPLAIN SELECT with union...order by (select... where...) backport from 5.1 mysql-test/r/subselect.result: backport from 5.1 mysql-test/t/subselect.test: backport from 5.1 sql/sql_select.cc: backport from 5.1 --- mysql-test/r/subselect.result | 16 ++++++++++++++++ mysql-test/t/subselect.test | 21 +++++++++++++++++++++ sql/sql_select.cc | 5 +++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 09a650c722b..7fbe4c08b08 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4527,4 +4527,20 @@ pk int_key 3 3 7 3 DROP TABLE t1,t2; +# +# Bug #52711: Segfault when doing EXPLAIN SELECT with +# union...order by (select... where...) +# +CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a)); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (1),(2); +# Should not crash +EXPLAIN +SELECT * FROM t2 UNION SELECT * FROM t2 +ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); +# Should not crash +SELECT * FROM t2 UNION SELECT * FROM t2 +ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); +DROP TABLE t1,t2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index bd12742f0f1..0956f91619d 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3506,5 +3506,26 @@ ORDER BY outr.pk; DROP TABLE t1,t2; +--echo # +--echo # Bug #52711: Segfault when doing EXPLAIN SELECT with +--echo # union...order by (select... where...) +--echo # + +CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a)); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (1),(2); + +--echo # Should not crash +--disable_result_log +EXPLAIN +SELECT * FROM t2 UNION SELECT * FROM t2 + ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); + +--echo # Should not crash +SELECT * FROM t2 UNION SELECT * FROM t2 + ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); +DROP TABLE t1,t2; +--enable_result_log --echo End of 5.0 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 53a6b699022..929ef3c8949 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -501,7 +501,7 @@ JOIN::prepare(Item ***rref_pointer_array, thd->lex->allow_sum_func= save_allow_sum_func; } - if (!thd->lex->view_prepare_mode) + if (!thd->lex->view_prepare_mode && !(select_options & SELECT_DESCRIBE)) { Item_subselect *subselect; /* Is it subselect? */ @@ -6861,7 +6861,8 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, *simple_order=0; // Must do a temp table to sort else if (!(order_tables & not_const_tables)) { - if (order->item[0]->with_subselect) + if (order->item[0]->with_subselect && + !(join->select_lex->options & SELECT_DESCRIBE)) order->item[0]->val_str(&order->item[0]->str_value); DBUG_PRINT("info",("removing: %s", order->item[0]->full_name())); continue; // skip const item