Commit 5257d71e authored by Michael Widenius's avatar Michael Widenius

MDEV-6855 Assertion `cond_type == Item::FUNC_ITEM' failed in...

MDEV-6855 Assertion `cond_type == Item::FUNC_ITEM' failed in check_group_min_max_predicates with GROUP BY, aggregate in WHERE SQ, multi-part key


mysql-test/r/group_by.result:
  Test for MDEV-6855
mysql-test/t/group_by.test:
  Test for MDEV-6855
sql/item.h:
  Fixed spelling error
sql/opt_range.cc:
  Added handling of cond_type == Item::CACHE_ITEM in WHERE clauses for MIN/MAX optimization.
  Fixed indentation
parent 10ab3e68
...@@ -2493,3 +2493,17 @@ SELECT i2 FROM t1 AS t1a STRAIGHT_JOIN ( t2 INNER JOIN t1 AS t1b ON (t1b.c1 = c2 ...@@ -2493,3 +2493,17 @@ SELECT i2 FROM t1 AS t1a STRAIGHT_JOIN ( t2 INNER JOIN t1 AS t1b ON (t1b.c1 = c2
WHERE t1a.c1 = c2 GROUP BY i2; WHERE t1a.c1 = c2 GROUP BY i2;
i2 i2
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# MDEV-6855
# MIN(*) with subqueries with IS NOT NULL in WHERE clause crashed.
#
CREATE TABLE t1 (i INT, c VARCHAR(3), KEY(c,i)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (7,'foo'),(0,'bar');
CREATE TABLE t2 (j INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (0),(8),(1),(8),(9);
SELECT MAX(i), c FROM t1
WHERE c != 'qux' AND ( SELECT SUM(j) FROM t1, t2 ) IS NOT NULL GROUP BY c;
MAX(i) c
0 bar
7 foo
drop table t1,t2;
...@@ -1665,6 +1665,21 @@ WHERE t1a.c1 = c2 GROUP BY i2; ...@@ -1665,6 +1665,21 @@ WHERE t1a.c1 = c2 GROUP BY i2;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # MDEV-6855
--echo # MIN(*) with subqueries with IS NOT NULL in WHERE clause crashed.
--echo #
CREATE TABLE t1 (i INT, c VARCHAR(3), KEY(c,i)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (7,'foo'),(0,'bar');
CREATE TABLE t2 (j INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (0),(8),(1),(8),(9);
SELECT MAX(i), c FROM t1
WHERE c != 'qux' AND ( SELECT SUM(j) FROM t1, t2 ) IS NOT NULL GROUP BY c;
drop table t1,t2;
# #
# End of MariaDB 5.5 tests # End of MariaDB 5.5 tests
# #
...@@ -4038,7 +4038,7 @@ private: ...@@ -4038,7 +4038,7 @@ private:
/** /**
@todo @todo
Implement the is_null() method for this class. Currently calling is_null() Implement the is_null() method for this class. Currently calling is_null()
on any Item_cache object resolves to Item::is_null(), which reutns FALSE on any Item_cache object resolves to Item::is_null(), which returns FALSE
for any value. for any value.
*/ */
......
...@@ -12539,12 +12539,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) ...@@ -12539,12 +12539,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
SYNOPSIS SYNOPSIS
check_group_min_max_predicates() check_group_min_max_predicates()
cond [in] the expression tree being analyzed cond [in] the expression tree being analyzed
min_max_arg [in] the field referenced by the MIN/MAX function(s) min_max_arg [in] the field referenced by the MIN/MAX function(s)
image_type [in] image_type [in]
has_min_max_arg [out] true if the subtree being analyzed references min_max_arg has_min_max_arg [out] true if the subtree being analyzed references
has_other_arg [out] true if the subtree being analyzed references a column min_max_arg
other min_max_arg has_other_arg [out] true if the subtree being analyzed references a
column other min_max_arg
DESCRIPTION DESCRIPTION
The function walks recursively over the cond tree representing a WHERE The function walks recursively over the cond tree representing a WHERE
...@@ -12588,7 +12589,7 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item, ...@@ -12588,7 +12589,7 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
(2) the subtree passes the test, but it is an OR and it references both (2) the subtree passes the test, but it is an OR and it references both
the min/max argument and other columns. the min/max argument and other columns.
*/ */
if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item, //1 if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item, //1
image_type, image_type,
&has_min_max, &has_other) || &has_min_max, &has_other) ||
(func_type == Item_func::COND_OR_FUNC && has_min_max && has_other))//2 (func_type == Item_func::COND_OR_FUNC && has_min_max && has_other))//2
...@@ -12604,7 +12605,7 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item, ...@@ -12604,7 +12605,7 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
a subquery in the WHERE clause. a subquery in the WHERE clause.
*/ */
if (cond_type == Item::SUBSELECT_ITEM) if (unlikely(cond_type == Item::SUBSELECT_ITEM))
{ {
Item_subselect *subs_cond= (Item_subselect*) cond; Item_subselect *subs_cond= (Item_subselect*) cond;
if (subs_cond->is_correlated) if (subs_cond->is_correlated)
...@@ -12621,7 +12622,14 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item, ...@@ -12621,7 +12622,14 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
} }
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/*
Subquery with IS [NOT] NULL
TODO: Look into the cache_item and optimize it like we do for
subselect's above
*/
if (unlikely(cond_type == Item::CACHE_ITEM))
DBUG_RETURN(cond->const_item());
/* /*
Condition of the form 'field' is equivalent to 'field <> 0' and thus Condition of the form 'field' is equivalent to 'field <> 0' and thus
satisfies the SA3 condition. satisfies the SA3 condition.
...@@ -12638,7 +12646,9 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item, ...@@ -12638,7 +12646,9 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
/* We presume that at this point there are no other Items than functions. */ /* We presume that at this point there are no other Items than functions. */
DBUG_ASSERT(cond_type == Item::FUNC_ITEM); DBUG_ASSERT(cond_type == Item::FUNC_ITEM);
if (unlikely(cond_type != Item::FUNC_ITEM)) /* Safety */
DBUG_RETURN(FALSE);
/* Test if cond references only group-by or non-group fields. */ /* Test if cond references only group-by or non-group fields. */
Item_func *pred= (Item_func*) cond; Item_func *pred= (Item_func*) cond;
Item_func::Functype pred_type= pred->functype(); Item_func::Functype pred_type= pred->functype();
......
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