From 3cf0d6f446b51b76a53378a11a117a134158f407 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 23 Jun 2011 14:48:45 -0700 Subject: [PATCH] Fixed LP bug #800518. The function simple_pred did not take into account that a multiple equality could include ref items (more exactly items of the class Item_direct_view_ref). It caused crashes for queries over derived tables or views if the min/max optimization could be applied to these queries. --- mysql-test/r/derived.result | 16 ++++++++++++++++ mysql-test/t/derived.test | 17 +++++++++++++++++ sql/opt_sum.cc | 10 ++++++---- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index fe803ed37a5..0340ebcbe98 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -425,3 +425,19 @@ SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a; a a 3 3 DROP TABLE t1,t2; +# +# LP bug #800518: crash with a query over a derived table +# when a min/max optimization is applied +# +CREATE TABLE t1 (a int, b int, c varchar(10), INDEX idx(a,b)) ; +INSERT INTO t1 VALUES +(100, 3, 'xxx'), (200, 7, 'yyyyyyy'), (100, 1, 't'), +(200, 4, 'aaaa'), (100, 3, 'eee'), (100, 5, 'zzzzz'); +EXPLAIN +SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100; +MAX(b) +5 +DROP TABLE t1; diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index 75368925499..4bba495ca09 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -331,3 +331,20 @@ SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a; SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a; DROP TABLE t1,t2; + +--echo # +--echo # LP bug #800518: crash with a query over a derived table +--echo # when a min/max optimization is applied +--echo # + +CREATE TABLE t1 (a int, b int, c varchar(10), INDEX idx(a,b)) ; +INSERT INTO t1 VALUES + (100, 3, 'xxx'), (200, 7, 'yyyyyyy'), (100, 1, 't'), + (200, 4, 'aaaa'), (100, 3, 'eee'), (100, 5, 'zzzzz'); + +EXPLAIN +SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100; +SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100; + +DROP TABLE t1; + diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 965eb853471..78cb2fa8210 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -494,12 +494,14 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order) /* MULT_EQUAL_FUNC */ { Item_equal *item_equal= (Item_equal *) func_item; - Item_equal_fields_iterator it(*item_equal); - args[0]= it++; - if (it++) - return 0; if (!(args[1]= item_equal->get_const())) return 0; + Item_equal_fields_iterator it(*item_equal); + if (!(item= it++)) + return 0; + args[0]= item->real_item(); + if (it++) + return 0; } break; case 1: