mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-12387 Push conditions into materialized subqueries
The logic and the implementation scheme are similar with the MDEV-9197 Pushdown conditions into non-mergeable views/derived tables How the push down is made on the example: select * from t1 where a>3 and b>10 and (a,b) in (select x,max(y) from t2 group by x); --> select * from t1 where a>3 and b>10 and (a,b) in (select x,max(y) from t2 where x>3 group by x having max(y)>10); The implementation scheme: 1. Search for the condition cond that depends only on the fields from the left part of the IN subquery (left_part) 2. Find fields F_group in the select of the right part of the IN subquery (right_part) that are used in the GROUP BY 3. Extract from the cond condition cond_where that depends only on the fields from the left_part that stay at the same places in the left_part (have the same indexes) as the F_group fields in the projection of the right_part 4. Transform cond_where so it can be pushed into the WHERE clause of the right_part and delete cond_where from the cond 5. Transform cond so it can be pushed into the HAVING clause of the right_part The optimization is made in the Item_in_subselect::pushdown_cond_for_in_subquery() and is controlled by the variable condition_pushdown_for_subquery. New test file in_subq_cond_pushdown.test is created. There are also some changes made for setup_jtbm_semi_joins(). Now it is decomposed into the 2 procedures: setup_degenerate_jtbm_semi_joins() that is called before optimize_cond() for cond and setup_jtbm_semi_joins() that is called after optimize_cond(). New setup_jtbm_semi_joins() is made in the way so that the result of its work is the same as if it was called before optimize_cond(). The code that is common for pushdown into materialized derived and into materialized IN subqueries is factored out into pushdown_cond_for_derived(), Item_in_subselect::pushdown_cond_for_in_subquery() and st_select_lex::pushdown_cond_into_where_clause().
This commit is contained in:
@ -808,19 +808,19 @@ typedef Bounds_checked_array<Item*> Ref_ptr_array;
|
||||
|
||||
|
||||
/*
|
||||
Structure which consists of the field and the item which
|
||||
produces this field.
|
||||
Structure which consists of the field and the item that
|
||||
corresponds to this field.
|
||||
*/
|
||||
|
||||
class Grouping_tmp_field :public Sql_alloc
|
||||
class Field_pair :public Sql_alloc
|
||||
{
|
||||
public:
|
||||
Field *tmp_field;
|
||||
Item *producing_item;
|
||||
Grouping_tmp_field(Field *fld, Item *item)
|
||||
:tmp_field(fld), producing_item(item) {}
|
||||
Field *field;
|
||||
Item *corresponding_item;
|
||||
Field_pair(Field *fld, Item *item)
|
||||
:field(fld), corresponding_item(item) {}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
SELECT_LEX - store information of parsed SELECT statment
|
||||
*/
|
||||
@ -1033,7 +1033,8 @@ public:
|
||||
nesting_map name_visibility_map;
|
||||
|
||||
table_map with_dep;
|
||||
List<Grouping_tmp_field> grouping_tmp_fields;
|
||||
/* the structure to store fields that are used in the GROUP BY of this select */
|
||||
List<Field_pair> grouping_tmp_fields;
|
||||
|
||||
/* it is for correct printing SELECT options */
|
||||
thr_lock_type lock_type;
|
||||
@ -1238,9 +1239,8 @@ 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,
|
||||
TABLE_LIST *derived);
|
||||
void collect_grouping_fields(THD *thd, ORDER *grouping_list);
|
||||
void check_cond_extraction_for_grouping_fields(Item *cond);
|
||||
Item *build_cond_for_grouping_fields(THD *thd, Item *cond,
|
||||
bool no_to_clones);
|
||||
|
||||
@ -1266,6 +1266,11 @@ public:
|
||||
bool cond_pushdown_is_allowed() const
|
||||
{ return !olap && !explicit_limit && !tvc; }
|
||||
|
||||
void pushdown_cond_into_where_clause(THD *thd, Item *extracted_cond,
|
||||
Item **remaining_cond,
|
||||
Item_transformer transformer,
|
||||
uchar *arg);
|
||||
|
||||
private:
|
||||
bool m_non_agg_field_used;
|
||||
bool m_agg_func_used;
|
||||
|
Reference in New Issue
Block a user