Commit 15692ce9 authored by unknown's avatar unknown

Fix for BUG#6303 + fix for discovered bug with sub-queries when analyzin...

Fix for BUG#6303 + fix for discovered bug with sub-queries when analyzin queries for MIN/MAX optimization (WL#1724).


BitKeeper/etc/ignore:
  Added stamp-h1.in stamp-h2.in to the ignore list
mysql-test/t/group_min_max.test:
  - Added test for BUG#6303
  - Added test for MIN/MAX optimizable queries with subqueries
sql/opt_range.cc:
  - check_group_min_max_predicates should not be called when there is no MIN/MAX function
  - skip queries from GROUP BY with MIN/MAX optimization when there is a subselect in the WHERE clause
parent fdaaf0da
......@@ -924,3 +924,5 @@ vio/test-ssl
vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
stamp-h1.in
stamp-h2.in
......@@ -372,6 +372,17 @@ select a1,a2,b,min(c),max(c) from t2 where (c > 'b111') and (c <= 'g112') group
select a1,a2,b,min(c),max(c) from t2 where (c < 'c5') or (c = 'g412') or (c = 'k421') group by a1,a2,b;
select a1,a2,b,min(c),max(c) from t2 where ((c > 'b111') and (c <= 'g112')) or ((c > 'd000') and (c <= 'i110')) group by a1,a2,b;
#-- analyze the sub-select
#explain select a1,a2,b,min(c),max(c) from t1
#where exists ( select * from t2 where t2.c = t1.c )
#group by a1,a2,b;
#-- the sub-select is unrelated to MIN/MAX
#explain select a1,a2,b,min(c),max(c) from t1
#where exists ( select * from t2 where t2.c > 'b1' )
#group by a1,a2,b;
-- A,B,C) Predicates referencing mixed classes of attributes
-- plans
explain select a1,a2,b,min(c),max(c) from t1 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
......@@ -463,6 +474,11 @@ select distinct a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a') and (c = 'i121
select distinct a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
select distinct b from t2 where (a2 >= 'b') and (b = 'a');
#-- BUG 6303
#select distinct t_00.a1
#from t1 t_00
#where exists ( select * from t2 where a1 = t_00.a1 );
--
-- DISTINCT queries with GROUP-BY
......
......@@ -6861,8 +6861,9 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
DBUG_RETURN(NULL);
/* Check (SA3,WA1) for the where clause. */
if (!check_group_min_max_predicates(join->conds, min_max_arg_item,
/* Check (SA3) for the where clause. */
if (join->conds && min_max_arg_item &&
!check_group_min_max_predicates(join->conds, min_max_arg_item,
(index_info->flags & HA_SPATIAL) ?
Field::itMBR : Field::itRAW))
DBUG_RETURN(NULL);
......@@ -6920,8 +6921,7 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
Field::imagetype image_type)
{
DBUG_ENTER("check_group_min_max_predicates");
if (!cond) /* If no WHERE clause, then all is OK. */
DBUG_RETURN(TRUE);
DBUG_ASSERT(cond && min_max_arg_item);
Item::Type cond_type= cond->type();
if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
......@@ -6938,6 +6938,19 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
DBUG_RETURN(TRUE);
}
/*
TODO:
This is a very crude fix to handle sub-selects in the WHERE clause
(Item_subselect objects). With the test below we rule out from the
optimization all queries with subselects in the WHERE clause. What has to
be done, is that here we should analyze whether the subselect references
the MIN/MAX argument field, and disallow the optimization only if this is
so.
*/
if (cond_type == Item::SUBSELECT_ITEM)
DBUG_RETURN(FALSE);
/* We presume that at this point there are no other Items than functions. */
DBUG_ASSERT(cond_type == Item::FUNC_ITEM);
/* Test if cond references only group-by or non-group fields. */
......@@ -6951,11 +6964,10 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
DBUG_PRINT("info", ("cur_arg: %s", cur_arg->full_name()));
if (cur_arg->type() == Item::FIELD_ITEM)
{
if (min_max_arg_item && /* pred references min_max_arg_item. */
min_max_arg_item->eq(cur_arg, 1))
if (min_max_arg_item->eq(cur_arg, 1))
{/*
Check if pred is a range condition that compares the MIN/MAX argument
with a constant.
If pred references the MIN/MAX argument check whether pred is a range
condition that compares the MIN/MAX argument with a constant.
*/
Item_func::Functype pred_type= pred->functype();
if (pred_type != Item_func::EQUAL_FUNC &&
......
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