From e7578ac612f73039ea9b212de4c7bcaa8e7d874e Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 21 Jun 2011 18:00:58 -0700 Subject: [PATCH] Fixed LP bug #798621. The patch for bugs 717577 and 724942 has missed to make adjustments for the call item_equal->add_const(const_item, orig_field_item) in the function check_simple_equality that builds multiple equality for a field and a constant. As a result, when this field happens to be a view field and the corresponding Item_field object F is wrapped in an Item_direct_view_ref object R the object F is placed in the multiple equality instead of the object R. A substitution of an equal item for F potentially can cause very serious problems and in some cases can lead to crashes of the server. --- mysql-test/r/view.result | 23 +++++++++++++++++++++++ mysql-test/t/view.test | 21 +++++++++++++++++++++ sql/sql_select.cc | 4 ++-- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 9f720019303..fca298125ca 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -4184,3 +4184,26 @@ DELETE FROM v3; ERROR HY000: The target table v3 of the DELETE is not updatable DROP VIEW v1,v2,v3; DROP TABLE t1; +# +# Bug#798621: crash with a view string field equal +# to a constant +# +CREATE TABLE t1 (a varchar(32), b int) ; +INSERT INTO t1 VALUES ('j', NULL), ('c', 8), ('c', 1); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 (a varchar(32)) ; +INSERT INTO t2 VALUES ('j'), ('c'); +SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a +WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b; +a b a +c 1 c +EXPLAIN EXTENDED +SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a +WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where ((`test`.`t1`.`b` = 1) or ((`test`.`t1`.`a` = 'a') and (length(`test`.`t1`.`a`) >= `test`.`t1`.`b`))) +DROP VIEW v1; +DROP TABLE t1,t2; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 626cc506e78..d6f83bb9125 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -4134,3 +4134,24 @@ DELETE FROM v3; DROP VIEW v1,v2,v3; DROP TABLE t1; + +--echo # +--echo # Bug#798621: crash with a view string field equal +--echo # to a constant +--echo # + +CREATE TABLE t1 (a varchar(32), b int) ; +INSERT INTO t1 VALUES ('j', NULL), ('c', 8), ('c', 1); +CREATE VIEW v1 AS SELECT * FROM t1; + +CREATE TABLE t2 (a varchar(32)) ; +INSERT INTO t2 VALUES ('j'), ('c'); + +SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a + WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b; +EXPLAIN EXTENDED +SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a + WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b; + +DROP VIEW v1; +DROP TABLE t1,t2; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 682a9b2a596..9363964f846 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10334,7 +10334,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item, !((Item_field*)left_item)->get_depended_from() && right_item->const_item() && !right_item->is_expensive()) { - orig_field_item= left_item; + orig_field_item= orig_left_item; field_item= (Item_field *) left_item; const_item= right_item; } @@ -10342,7 +10342,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item, !((Item_field*)right_item)->get_depended_from() && left_item->const_item() && !left_item->is_expensive()) { - orig_field_item= right_item; + orig_field_item= orig_right_item; field_item= (Item_field *) right_item; const_item= left_item; }