MySQL 9.1.0
Source Code Documentation
Query_term_set_op Class Reference

Common base class for n-ary set operations, including unary. More...

#include <query_term.h>

Inheritance diagram for Query_term_set_op:
[legend]

Public Member Functions

mem_root_deque< Item * > * types_array () override
 
Query_termchild (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_blockquery_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::Operandsetup_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...
 
AccessPathmake_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)
 
- Public Member Functions inherited from Query_term
Query_termpushdown_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_opparent () 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_resultsetop_query_result ()
 Getter for m_setop_query_result, q.v. More...
 
Query_result_unionsetop_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_refresult_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...
 
- Protected Attributes inherited from Query_term
Query_term_set_opm_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_resultm_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_refm_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_blockm_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 Public Member Functions inherited from Query_term
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...
 

Detailed Description

Common base class for n-ary set operations, including unary.

Constructor & Destructor Documentation

◆ Query_term_set_op()

Query_term_set_op::Query_term_set_op ( MEM_ROOT mem_root)
inlineexplicitprotected

Member Function Documentation

◆ check_joined_types()

bool Query_term_set_op::check_joined_types ( )
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.

◆ child()

Query_term * Query_term_set_op::child ( size_t  idx) const
inline

Get child at given index.

◆ child_count()

size_t Query_term_set_op::child_count ( ) const
inlineoverridevirtual

Get the number of children this node has.

Returns
the number

Reimplemented from Query_term.

◆ cleanup()

void Query_term_set_op::cleanup ( bool  full)
overridevirtual

Reset resources used.

Parameters
fulldo full cleanup. Same semantics as for Query_expression's cleanup

Reimplemented from Query_term.

◆ destroy_tree()

void Query_term_set_op::destroy_tree ( )
inlineoverridevirtual

Destroy the query term tree structure.

Implements Query_term.

◆ first_distinct()

int64_t Query_term_set_op::first_distinct ( ) const
inline

Getter for m_first_distinct, q.v.

◆ has_mixed_distinct_operators()

bool Query_term_set_op::has_mixed_distinct_operators ( )

Check if this set operation has a mix of DISTINCT and ALL.

Returns
true if so. Always false for unary

◆ in_right_side_in_except_or_intersect()

bool Query_term_set_op::in_right_side_in_except_or_intersect ( Query_term qt)
inline

◆ is_materialized()

bool Query_term_set_op::is_materialized ( ) const
inline

Getter for m_is_materialized, q.v.

◆ is_unary()

bool Query_term_set_op::is_unary ( ) const
inline

Check if this term is a unary set operation.

Returns
true if so

◆ label_children()

void Query_term_set_op::label_children ( )
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.

◆ last_distinct()

int64_t Query_term_set_op::last_distinct ( ) const
inline

Getter for m_last_distinct, q.v.

◆ make_set_op_access_path()

AccessPath * Query_term_set_op::make_set_op_access_path ( THD thd,
Query_term_set_op parent,
Mem_root_array< AppendPathParameters > *  union_all_subpaths,
bool  calc_found_rows 
)
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

Parameters
thdsession context
parentthe parent for which we want to create a materialized access path, or nullptr
union_all_subpathsif not nullptr, we are part of a UNION all, add constructed access to it.
calc_found_rowsif true, do allow for calculation of number of found rows even in presence of LIMIT.
Returns
access path, if nullptr, this is an error

Implements Query_term.

Reimplemented in Query_term_unary.

◆ open_result_tables()

bool Query_term_set_op::open_result_tables ( THD thd,
int  level 
)
overridevirtual

Open tmp tables for the tree of set operation query results, by recursing.

Parameters
thdsession context
levellevel in the tree, top should be called with 0.
Returns
true on error

Reimplemented from Query_term.

◆ optimize_query_term()

bool Query_term_set_op::optimize_query_term ( THD thd,
Query_expression qe 
)
overridevirtual

Optimize the non-leaf query blocks.

Parameters
thdsession context
qeowning query expression (of this term)
Returns
true on error, else false

Implements Query_term.

◆ prepare_query_term()

bool Query_term_set_op::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_options 
)
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
Parameters
thdsession context
qequery expression query expression directly containing this query term
save_query_blockcopy of thd->lex->current_query_block() when Query_expression::prepare was called.
insert_field_listpointer to field list if INSERT op, NULL otherwise.
common_resultfor 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_optionsthese options will be added to the query blocks.
removed_optionsoptions that cannot be used for this query
create_optionsoptions to use for creating tmp table
Returns
false on success, true on error

We are part of upper level set op

Implements Query_term.

Reimplemented in Query_term_unary.

◆ print()

void Query_term_set_op::print ( int  level,
std::ostringstream &  buf,
const char *  type 
) const
protected

Common printing minion for set operations.

Parameters
levellevel in tree
bufthe buffer to format output into
typedescriptive string of set operation to use for printing

◆ query_block()

Query_block * Query_term_set_op::query_block ( ) const
inlineoverridevirtual

Getter for m_block, q.v.

Implements Query_term.

◆ set_block()

bool Query_term_set_op::set_block ( Query_block b)
inline

Setter for m_block, q.v.

◆ set_is_materialized()

void Query_term_set_op::set_is_materialized ( bool  mat)
inline

Setter for m_is_materialized, q.v.

◆ setup_materialize_set_op()

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.

Parameters
thdsession context
dst_tablethe table to materialize into
union_distinct_onlyif true, materialize only UNION DISTINCT query blocks (any UNION ALL blocks are presumed handled higher up, by AppendIterator)
calc_found_rowsif true, calculate rows found
Returns
array of materialization parameters

◆ types_array()

mem_root_deque< Item * > * Query_term_set_op::types_array ( )
inlineoverridevirtual

Implements Query_term.

Reimplemented in Query_term_unary.

◆ types_iterator()

VisibleFieldsIterator Query_term_set_op::types_iterator ( )
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.

◆ visible_column_count()

size_t Query_term_set_op::visible_column_count ( ) const
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.

Friends And Related Function Documentation

◆ PT_set_operation

friend class PT_set_operation
friend

◆ Query_term

friend class Query_term
friend

◆ Query_terms

template<Visit_order visit_order, Visit_leaves visit_leaves>
friend class Query_terms
friend

Member Data Documentation

◆ m_block

Query_block* Query_term_set_op::m_block {nullptr}
private

Query block for post processing result set with ORDER BY, LIMIT for unary and binary set operations.

◆ m_children

mem_root_deque<Query_term *> Query_term_set_op::m_children
protected

Tree structure.

Cardinality is one for unary, two or more for UNION, EXCEPT, INTERSECT

◆ m_first_distinct

int64_t Query_term_set_op::m_first_distinct {0}
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.

◆ m_is_materialized

bool Query_term_set_op::m_is_materialized {true}
protected

true if the result of this set operation is materialized.

A priori true unless we have a pure UNION ALL.

◆ m_last_distinct

int64_t Query_term_set_op::m_last_distinct {0}
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.

◆ m_types

mem_root_deque<Item *>* Query_term_set_op::m_types {nullptr}
private

List of aggregated type holder items for the set operation query term.

Contains only information for the visible expressions of the set operation.


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