mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-7486: Condition pushdown from HAVING into WHERE
Condition can be pushed from the HAVING clause into the WHERE clause if it depends only on the fields that are used in the GROUP BY list or depends on the fields that are equal to grouping fields. Aggregate functions can't be pushed down. How the pushdown is performed on the example: SELECT t1.a,MAX(t1.b) FROM t1 GROUP BY t1.a HAVING (t1.a>2) AND (MAX(c)>12); => SELECT t1.a,MAX(t1.b) FROM t1 WHERE (t1.a>2) GROUP BY t1.a HAVING (MAX(c)>12); The implementation scheme: 1. Extract the most restrictive condition cond from the HAVING clause of the select that depends only on the fields that are used in the GROUP BY list of the select (directly or indirectly through equalities) 2. Save cond as a condition that can be pushed into the WHERE clause of the select 3. Remove cond from the HAVING clause if it is possible The optimization is implemented in the function st_select_lex::pushdown_from_having_into_where(). New test file having_cond_pushdown.test is created.
This commit is contained in:
committed by
Igor Babaev
parent
790b6f5ae2
commit
7a77b221f1
@ -999,10 +999,11 @@ typedef class st_select_lex_unit SELECT_LEX_UNIT;
|
||||
typedef Bounds_checked_array<Item*> Ref_ptr_array;
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Structure which consists of the field and the item that
|
||||
corresponds to this field.
|
||||
*/
|
||||
|
||||
class Field_pair :public Sql_alloc
|
||||
{
|
||||
public:
|
||||
@ -1012,6 +1013,10 @@ public:
|
||||
:field(fld), corresponding_item(item) {}
|
||||
};
|
||||
|
||||
Field_pair *get_corresponding_field_pair(Item *item,
|
||||
List<Field_pair> pair_list);
|
||||
Field_pair *find_matching_field_pair(Item *item, List<Field_pair> pair_list);
|
||||
|
||||
|
||||
/*
|
||||
SELECT_LEX - store information of parsed SELECT statment
|
||||
@ -1043,6 +1048,7 @@ public:
|
||||
Item *prep_having;/* saved HAVING clause for prepared statement processing */
|
||||
Item *cond_pushed_into_where; /* condition pushed into the select's WHERE */
|
||||
Item *cond_pushed_into_having; /* condition pushed into the select's HAVING */
|
||||
List<Item> attach_to_conds;
|
||||
/* Saved values of the WHERE and HAVING clauses*/
|
||||
Item::cond_result cond_value, having_value;
|
||||
/*
|
||||
@ -1467,8 +1473,11 @@ public:
|
||||
With_element *find_table_def_in_with_clauses(TABLE_LIST *table);
|
||||
bool check_unrestricted_recursive(bool only_standard_compliant);
|
||||
bool check_subqueries_with_recursive_references();
|
||||
void collect_grouping_fields(THD *thd, ORDER *grouping_list);
|
||||
void check_cond_extraction_for_grouping_fields(Item *cond);
|
||||
void collect_grouping_fields_for_derived(THD *thd, ORDER *grouping_list);
|
||||
bool collect_grouping_fields(THD *thd);
|
||||
bool collect_fields_equal_to_grouping(THD *thd);
|
||||
void check_cond_extraction_for_grouping_fields(THD *thd, Item *cond,
|
||||
Pushdown_checker excl_dep);
|
||||
Item *build_cond_for_grouping_fields(THD *thd, Item *cond,
|
||||
bool no_to_clones);
|
||||
|
||||
@ -1494,10 +1503,15 @@ public:
|
||||
bool cond_pushdown_is_allowed() const
|
||||
{ return !olap && !explicit_limit && !tvc; }
|
||||
|
||||
bool build_pushable_cond_for_having_pushdown(THD *thd,
|
||||
Item *cond,
|
||||
Pushdown_checker checker);
|
||||
void pushdown_cond_into_where_clause(THD *thd, Item *extracted_cond,
|
||||
Item **remaining_cond,
|
||||
Item_transformer transformer,
|
||||
uchar *arg);
|
||||
void mark_or_conds_to_avoid_pushdown(Item *cond);
|
||||
Item *pushdown_from_having_into_where(THD *thd, Item *having);
|
||||
|
||||
select_handler *find_select_handler(THD *thd);
|
||||
|
||||
|
Reference in New Issue
Block a user