Commit c6cc5096 authored by igor@olga.mysql.com's avatar igor@olga.mysql.com

Fixed bug #29104: assertion abort for grouping queries using views.

The abort happened when a query contained a conjunctive predicate
of the form 'view column = constant' in the WHERE condition and 
the grouping list also contained a reference to a view column yet
a different one.

Removed the failing assertion as invalid in a general case.

Also fixed a bug that prevented applying some optimization for grouping
queries using views. If the WHERE condition of such a query contains
a conjunctive condition of the form 'view column = constant' and
this view column is used in the grouping list then grouping by this
column can be eliminated. The bug blocked performing this elimination.
parent f015b433
...@@ -3476,4 +3476,28 @@ a1 c ...@@ -3476,4 +3476,28 @@ a1 c
2 0 2 0
DROP VIEW v1,v2; DROP VIEW v1,v2;
DROP TABLE t1,t2,t3,t4; DROP TABLE t1,t2,t3,t4;
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (1,2), (2,2), (1,3), (1,2);
CREATE VIEW v1 AS SELECT a, b+1 as b FROM t1;
SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b;
b SUM(a)
3 4
EXPLAIN SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a;
a SUM(b)
1 6
2 3
EXPLAIN SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort
SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a;
a SUM(b)
1 10
EXPLAIN SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
DROP VIEW v1;
DROP TABLE t1;
End of 5.0 tests. End of 5.0 tests.
...@@ -3324,4 +3324,28 @@ SELECT * FROM t1; ...@@ -3324,4 +3324,28 @@ SELECT * FROM t1;
DROP VIEW v1,v2; DROP VIEW v1,v2;
DROP TABLE t1,t2,t3,t4; DROP TABLE t1,t2,t3,t4;
#
# Bug #29104: assertion abort for a query with a view column reference
# in the GROUP BY list and a condition requiring the value
# of another view column to be equal to a constant
#
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (1,2), (2,2), (1,3), (1,2);
CREATE VIEW v1 AS SELECT a, b+1 as b FROM t1;
SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b;
EXPLAIN SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b;
SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a;
EXPLAIN SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a;
SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a;
EXPLAIN SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a;
DROP VIEW v1;
DROP TABLE t1;
--echo End of 5.0 tests. --echo End of 5.0 tests.
...@@ -1938,10 +1938,11 @@ bool Item_field::val_bool_result() ...@@ -1938,10 +1938,11 @@ bool Item_field::val_bool_result()
bool Item_field::eq(const Item *item, bool binary_cmp) const bool Item_field::eq(const Item *item, bool binary_cmp) const
{ {
if (item->type() != FIELD_ITEM) Item *real_item= ((Item *) item)->real_item();
if (real_item->type() != FIELD_ITEM)
return 0; return 0;
Item_field *item_field= (Item_field*) item; Item_field *item_field= (Item_field*) real_item;
if (item_field->field && field) if (item_field->field && field)
return item_field->field == field; return item_field->field == field;
/* /*
...@@ -5627,8 +5628,7 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference) ...@@ -5627,8 +5628,7 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
DESCRIPTION DESCRIPTION
A view column reference is considered equal to another column A view column reference is considered equal to another column
reference if the second one is a view column and if both column reference if the second one is a view column and if both column
references resolve to the same item. It is assumed that both references resolve to the same item.
items are of the same type.
RETURN RETURN
TRUE Referenced item is equal to given item TRUE Referenced item is equal to given item
...@@ -5644,8 +5644,6 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const ...@@ -5644,8 +5644,6 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
if (item_ref->ref_type() == VIEW_REF) if (item_ref->ref_type() == VIEW_REF)
{ {
Item *item_ref_ref= *(item_ref->ref); Item *item_ref_ref= *(item_ref->ref);
DBUG_ASSERT((*ref)->real_item()->type() ==
item_ref_ref->real_item()->type());
return ((*ref)->real_item() == item_ref_ref->real_item()); return ((*ref)->real_item() == item_ref_ref->real_item());
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment