diff --git a/.bzrignore b/.bzrignore index c3d20201819..9d24a2443b0 100644 --- a/.bzrignore +++ b/.bzrignore @@ -924,3 +924,5 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl +stamp-h1.in +stamp-h2.in diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index 677b3ecf7ec..5b48f89470d 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -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 diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 683bf1bdc13..8f7e713e33d 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -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 &&