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

This commit is contained in:
timour@mysql.com 2004-10-29 18:20:09 +03:00
parent 1f7aa03e42
commit b67f86728b
3 changed files with 38 additions and 8 deletions

View file

@ -924,3 +924,5 @@ vio/test-ssl
vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
stamp-h1.in
stamp-h2.in

View file

@ -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

View file

@ -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 &&