MySQL 8.0.39
Source Code Documentation
|
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... | |
Item * | get_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 | |
Item * | extract_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 | |
Item * | m_cond_to_check |
Condition that needs to be checked to push down to the derived table. More... | |
Table_ref * | m_derived_table |
Derived table to push the condition to. More... | |
Item * | m_cond_to_push {nullptr} |
Condition that is extracted from outer WHERE condition to be pushed to the derived table. More... | |
Item * | m_orig_cond_to_push {nullptr} |
set to m_cond_to_push before cloning (for query expressions with multiple query blocks). More... | |
Item * | m_having_cond {nullptr} |
Condition that would be attached to the HAVING clause of the derived table. More... | |
Item * | m_where_cond {nullptr} |
Condition that would be attached to the WHERE clause of the derived table. More... | |
Item * | m_remainder_cond {nullptr} |
Condition that would be left behind in the outer query block. More... | |
Query_block * | m_query_block {nullptr} |
Query block to which m_cond_to_push should be pushed. More... | |
enum_checking_purpose | m_checking_purpose {CHECK_FOR_DERIVED} |
THD * | thd |
Current thread. More... | |
Opt_trace_context * | trace |
Optimizer trace context. More... | |
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.
|
private |
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 |
|
inline |
|
private |
Attach condition to derived table query block.
[in] | derived_cond | condition in derived table to which another condition needs to be attached. |
[in] | cond_to_attach | condition that needs to be attached to the derived table query block. |
[in] | having | true if this is having condition, false if it is the where condition. |
true | if error |
false | on success |
|
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.
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.
[in] | cond | Condition that needs to be examined for extraction. |
Condition | that passes the checks. |
nullptr | if the condition does not pass checks. |
|
inline |
bool Condition_pushdown::make_cond_for_derived | ( | ) |
Make a condition that can be pushed down to the derived table, and push it.
Make the remainder condition.
Any part of the condition that is not marked will be made into a independent condition.
[in] | cond | condition to look into for the marker |
[in,out] | remainder_cond | condition that is not marked |
Create new top level AND item
|
private |
Try to push the condition or parts of the condition past GROUP BY into the WHERE clause of the derived table.
|
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.
|
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.
[in] | cond | condition that needs to be looked into |
[in,out] | sj_nest | semi-join nest from where the inner/outer expressions are being matched to the expressions from "cond" |
|
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.
|
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.
|
private |
|
private |
Condition that needs to be checked to push down to the derived table.
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.
|
private |
Derived table to push the condition to.
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).
set to m_cond_to_push before cloning (for query expressions with multiple query blocks).
|
private |
Query block to which m_cond_to_push should be pushed.
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.
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).
|
private |
Current thread.
|
private |
Optimizer trace context.