mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 18:41:56 +01:00
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:
parent
1f7aa03e42
commit
b67f86728b
3 changed files with 38 additions and 8 deletions
|
@ -924,3 +924,5 @@ vio/test-ssl
|
||||||
vio/test-sslclient
|
vio/test-sslclient
|
||||||
vio/test-sslserver
|
vio/test-sslserver
|
||||||
vio/viotest-ssl
|
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 < '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;
|
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
|
-- A,B,C) Predicates referencing mixed classes of attributes
|
||||||
-- plans
|
-- 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;
|
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 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');
|
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
|
-- DISTINCT queries with GROUP-BY
|
||||||
|
|
|
@ -6861,8 +6861,9 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
|
|
||||||
|
|
||||||
/* Check (SA3,WA1) for the where clause. */
|
/* Check (SA3) for the where clause. */
|
||||||
if (!check_group_min_max_predicates(join->conds, min_max_arg_item,
|
if (join->conds && min_max_arg_item &&
|
||||||
|
!check_group_min_max_predicates(join->conds, min_max_arg_item,
|
||||||
(index_info->flags & HA_SPATIAL) ?
|
(index_info->flags & HA_SPATIAL) ?
|
||||||
Field::itMBR : Field::itRAW))
|
Field::itMBR : Field::itRAW))
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
|
@ -6920,8 +6921,7 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
|
||||||
Field::imagetype image_type)
|
Field::imagetype image_type)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("check_group_min_max_predicates");
|
DBUG_ENTER("check_group_min_max_predicates");
|
||||||
if (!cond) /* If no WHERE clause, then all is OK. */
|
DBUG_ASSERT(cond && min_max_arg_item);
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
|
|
||||||
Item::Type cond_type= cond->type();
|
Item::Type cond_type= cond->type();
|
||||||
if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
|
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);
|
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);
|
DBUG_ASSERT(cond_type == Item::FUNC_ITEM);
|
||||||
|
|
||||||
/* Test if cond references only group-by or non-group fields. */
|
/* 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()));
|
DBUG_PRINT("info", ("cur_arg: %s", cur_arg->full_name()));
|
||||||
if (cur_arg->type() == Item::FIELD_ITEM)
|
if (cur_arg->type() == Item::FIELD_ITEM)
|
||||||
{
|
{
|
||||||
if (min_max_arg_item && /* pred references min_max_arg_item. */
|
if (min_max_arg_item->eq(cur_arg, 1))
|
||||||
min_max_arg_item->eq(cur_arg, 1))
|
|
||||||
{/*
|
{/*
|
||||||
Check if pred is a range condition that compares the MIN/MAX argument
|
If pred references the MIN/MAX argument check whether pred is a range
|
||||||
with a constant.
|
condition that compares the MIN/MAX argument with a constant.
|
||||||
*/
|
*/
|
||||||
Item_func::Functype pred_type= pred->functype();
|
Item_func::Functype pred_type= pred->functype();
|
||||||
if (pred_type != Item_func::EQUAL_FUNC &&
|
if (pred_type != Item_func::EQUAL_FUNC &&
|
||||||
|
|
Loading…
Add table
Reference in a new issue