MySQL 8.4.0
Source Code Documentation
Condition_pushdown Class Reference

Class which handles pushing conditions down to a materialized derived table. More...

#include <sql_derived.h>

Classes

class  Derived_table_info
 Used to pass information during condition pushdown. More...
 

Public Member Functions

 Condition_pushdown (Item *cond, Table_ref *derived, THD *thd_arg, Opt_trace_context *trace_arg)
 
bool make_cond_for_derived ()
 Make a condition that can be pushed down to the derived table, and push it. More...
 
bool make_remainder_cond (Item *cond, Item **remainder_cond)
 Make the remainder condition. More...
 
Itemget_remainder_cond ()
 

Private Types

enum  enum_checking_purpose { CHECK_FOR_DERIVED , CHECK_FOR_HAVING , CHECK_FOR_WHERE }
 Enum that represents various stages of checking. More...
 

Private Member Functions

Itemextract_cond_for_table (Item *cond)
 This function is called multiple times to extract parts of a condition. More...
 
bool replace_columns_in_cond (Item **cond, bool is_having)
 Replace columns in a condition that will be pushed to this derived table with the derived table expressions. More...
 
bool push_past_window_functions ()
 Try to push past window functions into the HAVING clause of the derived table. More...
 
bool push_past_group_by ()
 Try to push the condition or parts of the condition past GROUP BY into the WHERE clause of the derived table. More...
 
bool attach_cond_to_derived (Item *derived_cond, Item *cond_to_attach, bool having)
 Attach condition to derived table query block. More...
 
void update_cond_count (Item *cond)
 Increment cond_count and between_count in the derived table query block based on the number of BETWEEN predicates and number of other predicates pushed down. More...
 
void check_and_remove_sj_exprs (Item *cond)
 Check if this derived table is part of a semi-join. More...
 
void remove_sj_exprs (Item *cond, NESTED_JOIN *sj_nest)
 This function examines the condition that is being pushed down to see if the expressions from the condition are a match for inner/outer expressions of the semi-join. More...
 

Private Attributes

Itemm_cond_to_check
 Condition that needs to be checked to push down to the derived table. More...
 
Table_refm_derived_table
 Derived table to push the condition to. More...
 
Itemm_cond_to_push {nullptr}
 Condition that is extracted from outer WHERE condition to be pushed to the derived table. More...
 
Itemm_orig_cond_to_push {nullptr}
 set to m_cond_to_push before cloning (for query expressions with multiple query blocks). More...
 
Itemm_having_cond {nullptr}
 Condition that would be attached to the HAVING clause of the derived table. More...
 
Itemm_where_cond {nullptr}
 Condition that would be attached to the WHERE clause of the derived table. More...
 
Itemm_remainder_cond {nullptr}
 Condition that would be left behind in the outer query block. More...
 
Query_blockm_query_block {nullptr}
 Query block to which m_cond_to_push should be pushed. More...
 
enum_checking_purpose m_checking_purpose {CHECK_FOR_DERIVED}
 
THDthd
 Current thread. More...
 
Opt_trace_contexttrace
 Optimizer trace context. More...
 

Detailed Description

Class which handles pushing conditions down to a materialized derived table.

In Query_block::prepare, if it is the outermost query block, and if we are at the end of preparation, a WHERE condition from the query block is checked to see if it can be pushed to the materialized derived table. Query_block::prepare push_conditions_to_derived_tables() For every materialized derived table, If there is a where condition in this query block, Make condition that can be pushed down to the derived table. Extract a part of the condition that has columns belonging to only this derived table. Check if this condition can be pushed past window functions if any to the HAVING clause of the derived table. Make a condition that could not be pushed past. This will remain in the outer query block. Check if this condition can be pushed past group by if present to the WHERE clause of the derived table. Make a condition that could not be pushed past. This will be part of the HAVING clause of the derived table query. Get the remainder condition which could not be pushed to the derived table. Push the condition down to derived table's query expression. REPEAT THE ABOVE for the rest of the derived tables. For every query expression inside the current query block REPEAT THE ABOVE to keep pushing as far down as possible.

Member Enumeration Documentation

◆ enum_checking_purpose

Enum that represents various stages of checking.

CHECK_FOR_DERIVED - Checking if a condition has only derived table expressions. CHECK_FOR_HAVING - Checking if condition could be pushed to HAVING clause of the derived table. CHECK_FOR_WHERE - Checking if condition could be pushed to WHERE clause of the derived table.

Enumerator
CHECK_FOR_DERIVED 
CHECK_FOR_HAVING 
CHECK_FOR_WHERE 

Constructor & Destructor Documentation

◆ Condition_pushdown()

Condition_pushdown::Condition_pushdown ( Item cond,
Table_ref derived,
THD thd_arg,
Opt_trace_context trace_arg 
)
inline

Member Function Documentation

◆ attach_cond_to_derived()

bool Condition_pushdown::attach_cond_to_derived ( Item derived_cond,
Item cond_to_attach,
bool  having 
)
private

Attach condition to derived table query block.

Parameters
[in]derived_condcondition in derived table to which another condition needs to be attached.
[in]cond_to_attachcondition that needs to be attached to the derived table query block.
[in]havingtrue if this is having condition, false if it is the where condition.
Return values
trueif error
falseon success

◆ check_and_remove_sj_exprs()

void Condition_pushdown::check_and_remove_sj_exprs ( Item cond)
private

Check if this derived table is part of a semi-join.

If so, we might be pushing down a semi-join condition attached to the outer where condition. We need to remove the expressions that are part of such a condition from semi-join inner/outer expression lists. Otherwise, once the columns of the semi-join condition get replaced with derived table expressions, these lists will also be pointing to the derived table expressions which is not correct. Updating the lists is also natural: the condition is pushed down, so it's not to be tested on the outer level anymore; leaving it in the list would make it be tested on the outer level. Once this function determines that this table is part of a semi-join, it calls remove_sj_exprs() to remove expressions found in the condition from semi-join expressions lists. Note that sj_inner_tables, sj_depends_on, sj_corr_tables are not updated, which may make us miss some semi-join strategies, but is not critical.

◆ extract_cond_for_table()

Item * Condition_pushdown::extract_cond_for_table ( Item cond)
private

This function is called multiple times to extract parts of a condition.

To extract the condition, it performs certain checks and marks the condition accordingly. When the checking purpose is CHECK_FOR_DERIVED - it checks if all columns in a condition (fully or partially) are from the derived table. When the checking purpose is CHECK_FOR_HAVING - it checks if all columns in a condition (fully or partially) are part of PARTITION clause of window functions. When the checking purpose is CHECK_FOR_WHERE - it checks if all columns in a condition (fully or partially) are part of GROUP BY.

If it is an "AND", a new AND condition is created and all the arguments to original AND condition which pass the above checks will be added as arguments to the new condition. If it is an OR, we can extract iff all the arguments pass the above checks.

Parameters
[in]condCondition that needs to be examined for extraction.
Return values
Conditionthat passes the checks.
nullptrif the condition does not pass checks.

◆ get_remainder_cond()

Item * Condition_pushdown::get_remainder_cond ( )
inline

◆ make_cond_for_derived()

bool Condition_pushdown::make_cond_for_derived ( )

Make a condition that can be pushed down to the derived table, and push it.

Returns
true if error false otherwise

◆ make_remainder_cond()

bool Condition_pushdown::make_remainder_cond ( Item cond,
Item **  remainder_cond 
)

Make the remainder condition.

Any part of the condition that is not marked will be made into a independent condition.

Parameters
[in]condcondition to look into for the marker
[in,out]remainder_condcondition that is not marked
Returns
true on error, false otherwise

Create new top level AND item

◆ push_past_group_by()

bool Condition_pushdown::push_past_group_by ( )
private

Try to push the condition or parts of the condition past GROUP BY into the WHERE clause of the derived table.

  1. For a non-grouped query, the condition is moved to the WHERE clause.
  2. For an implicitly grouped query, condition remains in the HAVING clause in order to preserve semantics.
  3. For a query with ROLLUP, the condition will remain in the HAVING clause because ROLLUP might add NULL values to the grouping columns.
  4. For other grouped queries, predicates involving grouping columns can be moved to the WHERE clause. Predicates that reference aggregate functions remain in HAVING clause. We perform the same checks for a non-standard compliant GROUP BY too. If a window function's PARTITION BY clause is on non-grouping columns (possible if GROUP BY is non-standard compliant or when these columns are functionally dependednt on the grouping columns) then the condition will stay in HAVING clause.

◆ push_past_window_functions()

bool Condition_pushdown::push_past_window_functions ( )
private

Try to push past window functions into the HAVING clause of the derived table.

Check that all columns in the condition are present as window partition columns in all the window functions of the current query block. If not, the condition cannot be pushed down to derived table.

◆ remove_sj_exprs()

void Condition_pushdown::remove_sj_exprs ( Item cond,
NESTED_JOIN sj_nest 
)
private

This function examines the condition that is being pushed down to see if the expressions from the condition are a match for inner/outer expressions of the semi-join.

If its a match, it removes such expressions from these expression lists.

Parameters
[in]condcondition that needs to be looked into
[in,out]sj_nestsemi-join nest from where the inner/outer expressions are being matched to the expressions from "cond"

◆ replace_columns_in_cond()

bool Condition_pushdown::replace_columns_in_cond ( Item **  cond,
bool  is_having 
)
private

Replace columns in a condition that will be pushed to this derived table with the derived table expressions.

If there is a HAVING condition that needs to be pushed down, we replace columns in the condition with references to the corresponding derived table expressions and for WHERE condition, we replace columns with derived table expressions.

◆ update_cond_count()

void Condition_pushdown::update_cond_count ( Item cond)
private

Increment cond_count and between_count in the derived table query block based on the number of BETWEEN predicates and number of other predicates pushed down.

Member Data Documentation

◆ m_checking_purpose

enum_checking_purpose Condition_pushdown::m_checking_purpose {CHECK_FOR_DERIVED}
private

◆ m_cond_to_check

Item* Condition_pushdown::m_cond_to_check
private

Condition that needs to be checked to push down to the derived table.

◆ m_cond_to_push

Item* Condition_pushdown::m_cond_to_push {nullptr}
private

Condition that is extracted from outer WHERE condition to be pushed to the derived table.

This will be a copy when a query expression has multiple query blocks.

◆ m_derived_table

Table_ref* Condition_pushdown::m_derived_table
private

Derived table to push the condition to.

◆ m_having_cond

Item* Condition_pushdown::m_having_cond {nullptr}
private

Condition that would be attached to the HAVING clause of the derived table.

(For each query block in the derived table if UNIONS are present).

◆ m_orig_cond_to_push

Item* Condition_pushdown::m_orig_cond_to_push {nullptr}
private

set to m_cond_to_push before cloning (for query expressions with multiple query blocks).

◆ m_query_block

Query_block* Condition_pushdown::m_query_block {nullptr}
private

Query block to which m_cond_to_push should be pushed.

◆ m_remainder_cond

Item* Condition_pushdown::m_remainder_cond {nullptr}
private

Condition that would be left behind in the outer query block.

This is the condition that could not be pushed down to the derived table.

◆ m_where_cond

Item* Condition_pushdown::m_where_cond {nullptr}
private

Condition that would be attached to the WHERE clause of the derived table.

(For each query block in the derived table if UNIONS are present).

◆ thd

THD* Condition_pushdown::thd
private

Current thread.

◆ trace

Opt_trace_context* Condition_pushdown::trace
private

Optimizer trace context.


The documentation for this class was generated from the following files: