![]() |
MySQL 9.2.0
Source Code Documentation
|
Common base class for n-ary set operations, including unary. More...
#include <query_term.h>
Public Member Functions | |
mem_root_deque< Item * > * | types_array () override |
Query_term * | child (size_t idx) const |
Get child at given index. More... | |
int64_t | last_distinct () const |
Getter for m_last_distinct , q.v. More... | |
int64_t | first_distinct () const |
Getter for m_first_distinct , q.v. More... | |
bool | is_materialized () const |
Getter for m_is_materialized , q.v. More... | |
void | set_is_materialized (bool mat) |
Setter for m_is_materialized , q.v. More... | |
Query_block * | query_block () const override |
Getter for m_block , q.v. More... | |
bool | set_block (Query_block *b) |
Setter for m_block , q.v. More... | |
void | label_children () override |
Set the correct value of Query_term::m_sibling_idx recursively for set operations. More... | |
size_t | child_count () const override |
Get the number of children this node has. More... | |
bool | open_result_tables (THD *thd, int level) override |
Open tmp tables for the tree of set operation query results, by recursing. More... | |
void | cleanup (bool full) override |
Reset resources used. More... | |
void | destroy_tree () override |
Destroy the query term tree structure. More... | |
bool | has_mixed_distinct_operators () |
Check if this set operation has a mix of DISTINCT and ALL. More... | |
bool | is_unary () const |
Check if this term is a unary set operation. More... | |
Mem_root_array< MaterializePathParameters::Operand > | setup_materialize_set_op (THD *thd, TABLE *dst_table, bool union_distinct_only, bool calc_found_rows) |
Sets up each(*) query block in this query expression for materialization into the given table by making a materialization parameter for each block (*) modulo union_distinct_only. More... | |
bool | prepare_query_term (THD *thd, Query_expression *qe, Change_current_query_block *save_query_block, mem_root_deque< Item * > *insert_field_list, Query_result *common_result, ulonglong added_options, ulonglong removed_options, ulonglong create_option) override |
a) Prepare query blocks, both leaf blocks and blocks reresenting order by/limit in query primaries with parentesized query expression body with order by clause and/or limit/offset clause (unary query terms). More... | |
bool | optimize_query_term (THD *thd, Query_expression *qe) override |
Optimize the non-leaf query blocks. More... | |
AccessPath * | make_set_op_access_path (THD *thd, Query_term_set_op *parent, Mem_root_array< AppendPathParameters > *union_all_subpaths, bool calc_found_rows) override |
Recursively constructs the access path of the set operation, possibly materializing in a tmp table if needed, cf. More... | |
VisibleFieldsIterator | types_iterator () override |
Abstract over visible column types: if query block, we offer an iterator over visible fields, for binary set operators we offer an iterator over m_types , for unary we just call the child's. More... | |
size_t | visible_column_count () const override |
Return the number of visible columns of the query term. More... | |
bool | in_right_side_in_except_or_intersect (Query_term *qt) |
![]() | |
Query_term * | pushdown_limit_order_by (Query_term_set_op *parent=nullptr) |
Called after contextualization to simplify query, c.f. More... | |
bool | validate_structure (const Query_term *parent, int depth=0) const |
Return true if structure is too deep, i.e. More... | |
std::pair< bool, bool > | redundant_order_by (Query_block *block, int level) |
Determine if we have a redundant ORDER BY in block. More... | |
virtual Query_term_type | term_type () const =0 |
Get the node tree type. More... | |
virtual const char * | operator_string () const =0 |
Get the node type description. More... | |
virtual | ~Query_term ()=default |
Node destructor. More... | |
bool | create_tmp_table (THD *thd, ulonglong create_options) |
Create a temporary table for a set operation. More... | |
Query_term_set_op * | parent () const |
Getter for m_parent , q.v. More... | |
void | set_sibling_idx (uint idx) |
Setter for m_sibling_idx , q.v. More... | |
uint | sibling_idx () |
Getter for m_sibling_idx , q.v. More... | |
virtual void | debugPrint (int level, std::ostringstream &buf) const =0 |
Print the tree rooted at this node to buf. More... | |
void | printPointers (std::ostringstream &buf) const |
Print the pointer of this node and its parent to buf. More... | |
void | set_setop_query_result (Query_result *rs) |
Setter for m_setop_query_result, q.v. More... | |
Query_result * | setop_query_result () |
Getter for m_setop_query_result, q.v. More... | |
Query_result_union * | setop_query_result_union () |
Getter for m_setop_query_result, q.v. Use only if we can down cast. More... | |
void | cleanup_query_result (bool full) |
Cleanup m_setop_query_result, q.v. More... | |
void | set_owning_operand () |
Setter for m_owning_operand, q.v. More... | |
bool | owning_operand () |
Getter for m_owning_operand, q.v. More... | |
void | set_result_table (Table_ref *tl) |
Setter for m_result_table, q.v. More... | |
Table_ref & | result_table () |
Getter for m_result_table, q.v. More... | |
void | set_fields (mem_root_deque< Item * > *fields) |
mem_root_deque< Item * > * | fields () |
Protected Member Functions | |
Query_term_set_op (MEM_ROOT *mem_root) | |
void | print (int level, std::ostringstream &buf, const char *type) const |
Common printing minion for set operations. More... | |
bool | check_joined_types () |
On top level, check that it was possible to aggregate all collations together for set operation. More... | |
Protected Attributes | |
mem_root_deque< Query_term * > | m_children |
Tree structure. More... | |
bool | m_is_materialized {true} |
true if the result of this set operation is materialized. More... | |
int64_t | m_last_distinct {0} |
Index of last query expression which has <set-op> DISTINCT on its left. More... | |
int64_t | m_first_distinct {0} |
Presently only needed by EXCEPT set operator: the index of the first DISTINCT set operand: minimum legal value is 1. More... | |
![]() | |
Query_term_set_op * | m_parent {nullptr} |
Back pointer to the node whose child we are, or nullptr (root term). More... | |
uint | m_sibling_idx {0} |
If parent is non-null, this holds the index of the current sibling. More... | |
Query_result * | m_setop_query_result {nullptr} |
The query result for this term. More... | |
bool | m_owning_operand {false} |
The operand of a n-ary set operation (that owns the common query result) has this set to true. More... | |
Table_ref * | m_result_table {nullptr} |
Result temporary table for the set operation, if applicable. More... | |
mem_root_deque< Item * > * | m_fields {nullptr} |
Used only when streaming, i.e. More... | |
Private Attributes | |
Query_block * | m_block {nullptr} |
Query block for post processing result set with ORDER BY, LIMIT for unary and binary set operations. More... | |
mem_root_deque< Item * > * | m_types {nullptr} |
List of aggregated type holder items for the set operation query term. More... | |
Friends | |
template<Visit_order visit_order, Visit_leaves visit_leaves> | |
class | Query_terms |
class | Query_term |
class | PT_set_operation |
Additional Inherited Members | |
![]() | |
static void | indent (int level, std::ostringstream &buf) |
Print blank space indentation (unit: two) to buf according to level. More... | |
static void | print_order (const THD *thd, String *str, ORDER *ord, enum_query_type query_type) |
Print into str the order indicated in ord, using standard print_for_order Used by traditional explain. More... | |
Common base class for n-ary set operations, including unary.
|
inlineexplicitprotected |
|
protected |
On top level, check that it was possible to aggregate all collations together for set operation.
We need this in case of setop DISTINCT, to detect duplicates using the proper collation.
TODO: consider removing this test in case of UNION ALL.
|
inline |
Get child at given index.
|
inlineoverridevirtual |
|
overridevirtual |
Reset resources used.
full | do full cleanup. Same semantics as for Query_expression's cleanup |
Reimplemented from Query_term.
|
inlineoverridevirtual |
Destroy the query term tree structure.
Implements Query_term.
|
inline |
Getter for m_first_distinct
, q.v.
bool Query_term_set_op::has_mixed_distinct_operators | ( | ) |
Check if this set operation has a mix of DISTINCT and ALL.
|
inline |
|
inline |
Getter for m_is_materialized
, q.v.
|
inline |
Check if this term is a unary set operation.
|
inlineoverridevirtual |
Set the correct value of Query_term::m_sibling_idx
recursively for set operations.
For Query_term_unary
, this is done in its constructor. A no-op for Query_block
. See also set_sibling_idx
.
Implements Query_term.
|
inline |
Getter for m_last_distinct
, q.v.
|
overridevirtual |
Recursively constructs the access path of the set operation, possibly materializing in a tmp table if needed, cf.
Query_term_set_op::m_is_materialized
thd | session context |
parent | the parent for which we want to create a materialized access path, or nullptr |
union_all_subpaths | if not nullptr, we are part of a UNION all, add constructed access to it. |
calc_found_rows | if true, do allow for calculation of number of found rows even in presence of LIMIT. |
Implements Query_term.
Reimplemented in Query_term_unary.
|
overridevirtual |
Open tmp tables for the tree of set operation query results, by recursing.
thd | session context |
level | level in the tree, top should be called with 0. |
Reimplemented from Query_term.
|
overridevirtual |
Optimize the non-leaf query blocks.
thd | session context |
qe | owning query expression (of this term) |
Implements Query_term.
|
overridevirtual |
a) Prepare query blocks, both leaf blocks and blocks reresenting order by/limit in query primaries with parentesized query expression body with order by clause and/or limit/offset clause (unary query terms).
Establish types for all query terms, and set up tmp table for CTE if present and for any materialized tmp tables for unary query terms.
Types for set operations are calculated bottom-up, so for a unary tmp table, we use the base block's types and names for proper resolution in cases like:
SELECT column_a FROM t1 UNION ( (SELECT column_b FROM t2 ORDER BY column_b LIMIT 3) ORDER BY column_b DESC LIMIT 2 ) ORDER BY column_a;
The second ORDER BY's column_b
should resolve to its nested column_b
selected from t2. This also means that the second order by operation does sorting using the type of column_b
, not using the common type of t1.column_a
and t2.column_b
.
If the inner SELECT above were a binary set operation, we would order by the joined types of the binary (sub)operation, recursively.
This function constructs the m_types
array for each binary set operation query term. Unary terms just use their child's type information.
We have a nested set operation structure where the leaf nodes are inner query blocks, typically SELECT clauses. These are prepared with Query_block::prepare
, called by Query_block::prepare_query_term
. We also need to prepare the nodes representing the binary set and unary operations. We have already merged nested set operation of the same kind into multi op form, so at any level the child and parent will usually be of another kind(1). We a priori create temporary tables marked with an asterisk below, modulo ALL optimizations, to consolidate the result of each multi set and unary operations. E.g.
UNION* | +----------------+----------+ | | | INTERSECT* UNARY TERM* EXCEPT* | | | +---+---+ QB +--+-+ | | | | | QB QB UNION* QB QB QB QB
(1) an exception is that we do not merge top level trailing UNION ALL nodes with preceding UNION DISTINCT in order that they can be streamed efficiently.
Note that the Query_result
is owned by the first sibling participating in the set operations, so the owning nodes of the above example are actually:
UNION | +----------------+----------+ | | | INTERSECT* UNARY TERM EXCEPT | | | +---+---+ QB* +--+-+ | | | | | QB* QB UNION QB* QB QB* QB
thd | session context |
qe | query expression query expression directly containing this query term |
save_query_block | copy of thd->lex->current_query_block() when Query_expression::prepare was called. |
insert_field_list | pointer to field list if INSERT op, NULL otherwise. |
common_result | for the top node, this is not used: we use query_result() instead. Otherwise, if it is empty, we create a query result on behalf of this node and its siblings. This node is then the designated owning operand, and is responsible for releasing it after execution. The siblings will see that common_result is not empty and use that. |
added_options | these options will be added to the query blocks. |
removed_options | options that cannot be used for this query |
create_options | options to use for creating tmp table |
We are part of upper level set op
Implements Query_term.
Reimplemented in Query_term_unary.
|
protected |
Common printing minion for set operations.
level | level in tree |
buf | the buffer to format output into |
type | descriptive string of set operation to use for printing |
|
inlineoverridevirtual |
Getter for m_block
, q.v.
Implements Query_term.
|
inline |
Setter for m_block
, q.v.
|
inline |
Setter for m_is_materialized
, q.v.
Mem_root_array< MaterializePathParameters::Operand > Query_term_set_op::setup_materialize_set_op | ( | THD * | thd, |
TABLE * | dst_table, | ||
bool | union_distinct_only, | ||
bool | calc_found_rows | ||
) |
Sets up each(*) query block in this query expression for materialization into the given table by making a materialization parameter for each block (*) modulo union_distinct_only.
thd | session context |
dst_table | the table to materialize into |
union_distinct_only | if true, materialize only UNION DISTINCT query blocks (any UNION ALL blocks are presumed handled higher up, by AppendIterator) |
calc_found_rows | if true, calculate rows found |
|
inlineoverridevirtual |
Implements Query_term.
Reimplemented in Query_term_unary.
|
inlineoverridevirtual |
Abstract over visible column types: if query block, we offer an iterator over visible fields, for binary set operators we offer an iterator over m_types
, for unary we just call the child's.
See also the accompanying visible_column_count
.
Implements Query_term.
Reimplemented in Query_term_unary.
|
inlineoverridevirtual |
Return the number of visible columns of the query term.
For query blocks this is in general a subset of Query_block::fields
Implements Query_term.
Reimplemented in Query_term_unary.
|
friend |
|
friend |
|
friend |
|
private |
Query block for post processing result set with ORDER BY, LIMIT for unary and binary set operations.
|
protected |
Tree structure.
Cardinality is one for unary, two or more for UNION, EXCEPT, INTERSECT
|
protected |
Presently only needed by EXCEPT set operator: the index of the first DISTINCT set operand: minimum legal value is 1.
If not DISTINCT, it should have the value std::numeric_limits<int64_t>::max()
. The value is set in PT_set_operation::merge_descendants
.
|
protected |
true if the result of this set operation is materialized.
A priori true unless we have a pure UNION ALL.
|
protected |
Index of last query expression which has <set-op> DISTINCT on its left.
In a list of <set-op>ed blocks, UNION is left-associative; so UNION DISTINCT eliminates duplicates in all blocks up to the first one on its right included. Which is why we only need to remember that query block. Is -1 for Unary.
|
private |
List of aggregated type holder items for the set operation query term.
Contains only information for the visible expressions of the set operation.