MySQL 8.4.3
Source Code Documentation
query_term.h
Go to the documentation of this file.
1/* Copyright (c) 2021, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23#ifndef QUERY_NODE_INCLUDED
24#define QUERY_NODE_INCLUDED
25
26#include "sql/join_optimizer/materialize_path_parameters.h" // MaterializePathParameters
27#include "sql/sql_list.h"
28#include "sql/sql_union.h"
29#include "sql/table.h"
30
31class Query_block;
32
33/**
34 This class hierarchy is used to represent SQL structures between <query
35 expression> and <query specification>. The class Query_expression
36 represents <query expression> and the class Query_block represents <query
37 specification>, <table value constructor> and <explicit table>,
38 cf. definitions in sql_lex.h. Originally, MySQL supported only one set
39 operation, UNION. This was implicitly represented by having one
40 Query_expression object own several Query_block objects via next pointers.
41 This made things simple, but limited us to left-deep nesting of unions, and
42 also from representing INTERSECTION and EXCEPT, as well as nesting several
43 layers of <query primary>s containing <query expression body>s, e.g.
44
45 (((SELECT a,b FROM t) ORDER BY a LIMIT 5) ORDER BY -b LIMIT 3) ORDER BY a;
46
47 could not be supported. With the present class hierarchy we enable the full
48 set of set operations and arbitrary nesting, as allowed by the SQL grammar,
49 viz:
50 \verbatim
51 <query expression> ::=
52 [ <with clause> ] <query expression body>
53 [ <order by clause> ] [ <limit/offset> ]
54
55 <query expression body> ::=
56 <query term>
57 | <query expression body> UNION [ ALL | DISTINCT ]
58 [ <corresponding spec> ] <query term>
59 | <query expression body> EXCEPT [ ALL | DISTINCT ]
60 [ <corresponding spec> ] <query term>
61
62 <query term> ::=
63 <query primary>
64 | <query expression body> INTERSECT [ ALL | DISTINCT ]
65 [ <corresponding spec> ] <query primary>
66
67 <query primary> ::=
68 <simple table>
69 | <left paren> <query expression body>
70 [ <order by clause> ] [ <limit/offset (*)> ]
71 <right paren>
72
73 <simple table> ::=
74 <query specification>
75 | <table value constructor>
76 | <explicit table>
77
78 (*) MySQL syntax and semantics. The standard uses /<result offset clause/> and
79 <fetch first clause>.
80
81 \endverbatim
82 Note that INTERSECT binds tighter than UNION and EXCEPT.
83 Now, let's turn to how these structures are represented in MySQL.
84 The node types are enumerated by Query_term_type. The nodes themselves
85 by the class hierarchy rooted in Query_term (abstract).
86*/
87
88/// Node type of the query term tree nodes
90 /// Represents Query specification, table value constructor and
91 /// explicit table
93 /// Represents a query primary with parentesized query expression body with
94 /// order by clause and/or limit/offset clause. If none of order by
95 /// or limit is present, we collapse this level of parentheses.
97 /// Represents the three set operations. Nodes are N-ary, i.e. a node can hold
98 /// two or more operands.
103
104/// Query term iterator template argument type: how to visit nodes in tree
106/// Query term iterator template argument type: whether to visit leaf nodes
108
109/**
110 Query term tree structure. There are five node types, cf. Query_term_type.
111 Leaf nodes are Query_block objects. We have three kinds of n-ary set operation
112 nodes corresponding to INTERSECT, UNION and EXCEPT. Finally, we have a "unary"
113 node which essentially adds a ORDER BY/LIMIT over another node.
114
115 Query blocks serve a dual purpose: they represent the query specification and
116 table constructors of the query. As such they are the leaf nodes of the query
117 tree. But they also serve as a way to realize ORDER BY and LIMIT for non-leaf
118 nodes, accessed via the function Query_term::query_block(). Therefore, every
119 non-leaf node in the tree has a companion Query_block to hold ORDER BY and
120 LIMIT information. For the leaf nodes, which are themselves query blocks, the
121 query_block() function just returns a pointer to self, i.e. the leaf nodes
122 handle ORDER BY and LIMIT themselves.
123
124 \verbatim
125 Example: ((SELECT * FROM t1 UNION SELECT * FROM t2 UNION ALL SELECT * FROM t3
126 ORDER BY a LIMIT 5) INTERSECT
127 (((SELECT * FROM t3 ORDER BY a LIMIT 4) ) EXCEPT SELECT * FROM t4)
128 ORDER BY a LIMIT 4) ORDER BY -a LIMIT 3;
129
130 ->
131 m_query_term +------------------+ slave(s)
132 +--------------|-Query_expression |------------------+
133 | +------------------+ |
134 V post_ |
135 +-------------------+processing_ +----------------------+ |
136 | Query_term_unary |block() |Query_block | |
137 | |----------->|order by -(`a) limit 3| |
138 +-------------------+ +----------------------+ |
139 |m_children |
140 | +-----------------------+ +----------------------+ |
141 | |Query_term_intersect | |Query_block | |
142 +>|last distinct index: 1 |-->|order by `a` limit 4 | |
143 +-----------------------+ +----------------------+ |
144 |m_children |
145 | +-----------------------+ +----------------------+ |
146 | |Query_term_union | |Query_block | |
147 +->|last distinct index: 1 |-->|order by `a` limit 5 | |
148 | +-----------------------+ +----------------------+ |
149 | |m_children |
150 | | +------------+ SELECT * FROM t1 /
151 | +-->|Query_block | <---------------------------------+
152 | | +------------+ ----------------------------------+ next
153 | | \
154 | | +------------+ SELECT * FROM t2 /
155 | +-->|Query_block | <---------------------------------+
156 | | +------------+ ----------------------------------+ next
157 | | \
158 | | +------------+ SELECT * FROM t3 /
159 | +-->|Query_block | <---------------------------------+
160 | +------------+ ----------------------------------+ next
161 | \
162 | +-----------------------+ +------------+ |
163 | |Query_term_except |->|Query_block | |
164 +->|last distinct index: 1 | +------------+ |
165 +-----------------------+ |
166 |m_children |
167 | +----------------------+ |
168 | |Query_block | SELECT * FROM t3 /
169 +-->|order by `a` limit 4 | <------------------------+
170 | +----------------------+ -------------------------+ next
171 | \
172 | +------------+ SELECT * FROM t4 |
173 +-->|Query_block | <------------------------------------+
174 +------------+
175 \endverbatim
176 Note that all leaf query blocks representing the query specifications are
177 linked under Query_expression via their next pointers. The nesting is achieved
178 by the arrows on the left side of the figure, via the nodes' m_children
179 members. The four classes Query_term_unary and Query_term_{union, intersect,
180 except} are modelled via the base class Query_term_set_op which contains a
181 m_children member. Each of these also contain a Query_block which will handle
182 its order by and/or limit clauses. These are similar to the old so-called
183 "fake_query_block" (which is now gone), and are not linked in with "next"
184 pointers.
185
186 The is also a back pointer from the children nodes to the parent Query_term
187 object (not shown).
188
189 In the simple case of a single query specification (or table value constructor
190 or explicit table), there is no super-structure over the Query_block linked
191 from the Query_expression, i.e. Query_expression's m_query_term member is just
192 a Query_block.
193
194 The query blocks (QT_QUERY_BLOCK nodes) corresponding to the query
195 specification (or table value constructors) are prepared and optimized by
196 running over them from the Query_expression via the slave/next pointers as
197 before. There are separate methods which handle prepare and optimization for
198 non-leaves, i.e. nodes of types QT_UNARY, QT_INTERSECT, QT_EXCEPT and
199 QT_UNION.
200
201 We also define an iterator class (Query_terms) for iterating over all
202 the nodes in the tree, see also Query_expression::query_terms() for its use.
203 When possible, we access all nodes using iterators.
204
205 The built structure can be traced with the debug trace keyword "ast", e.g.
206 as SET SESSION debug = 'd,ast:O,/tmp/mysqld.trace';
207*/
208
210 public:
211 // The next two methods used during construction of the tree.
212 /**
213 Called after contextualization to simplify query, c.f. sql_yacc.yy
214 CONTEXTUALIZE_VIEW. It also sets up the parent pointers.
215 @param parent parent of this if any
216 */
218
219 /**
220 Return true if structure is too deep, i.e. more than MAX_SELECT_NESTING.
221 As a side effect is also gives the post processing block a select number,
222 this is done late so as to get numbers higher the leaf blocks, and in
223 inside out order, so that the top set operation block will have the highest
224 number.
225 @param parent the real parent in the tree as visited recursively
226 @param depth the current depth in the tree, starting at 0 at the top.
227 It is increased with one for each time we recurse into a child.
228 @returns error if too deep structure, else false
229 */
230 bool validate_structure(const Query_term *parent, int depth = 0) const;
231
232 /**
233 Determine if we have a redundant ORDER BY in block. Used during prepare.
234 @param block the query block
235 @param level the current nesting level
236 @return tuple {bool found, bool redundant} redundant==true means ORDER BY of
237 the block is redundant and can be eliminated.
238 */
239 std::pair<bool, bool> redundant_order_by(Query_block *block, int level);
240
241 // Tree structure
242
243 /**
244 Get the node tree type.
245 @returns the tree node type
246 */
247 virtual Query_term_type term_type() const = 0;
248 /**
249 Get the node type description.
250 @returns descriptive string for each node type.
251 */
252 virtual const char *operator_string() const = 0;
253 /**
254 Node destructor
255 */
256 virtual ~Query_term() = default;
257 /**
258 Get the number of children this node has.
259 @return the number
260 */
261 virtual size_t child_count() const { return 0; }
262
263 /// Set the correct value of \c Query_term::m_sibling_idx recursively for
264 /// set operations. For \c Query_term_unary, this is done in its constructor.
265 /// A no-op for \c Query_block. See also \c set_sibling_idx.
266 virtual void label_children() = 0;
267
268 protected:
269 /**
270 Back pointer to the node whose child we are, or nullptr (root term).
271 */
273
274 /// If parent is non-null, this holds the index of the current sibling.
275 /// Used for efficient iterator traversal up and down the tree.
277
278 public:
279 /// Getter for m_parent, q.v.
280 Query_term_set_op *parent() const { return m_parent; }
281 /// Setter for \c m_sibling_idx, q.v.
282 void set_sibling_idx(uint idx) { m_sibling_idx = idx; }
283 /// Getter for \c m_sibling_idx, q.v.
284 uint sibling_idx() { return m_sibling_idx; }
285 /**
286 Reset resources used.
287 @param full do full cleanup. Same semantics as for Query_expression's
288 cleanup
289 */
290 virtual void cleanup(bool full [[maybe_unused]]) {
291 assert(false); // should be overridden
292 }
293
294 /// Destroy the query term tree structure
295 virtual void destroy_tree() = 0;
296
297 /**
298 Open tmp tables for the tree of set operation query results, by recursing
299 @param thd session context
300 @param level level in the tree, top should be called with 0.
301 @return true on error
302 */
303 virtual bool open_result_tables(THD *thd [[maybe_unused]],
304 int level [[maybe_unused]]) {
305 assert(false); // should be overridden
306 return false;
307 }
308
309 // Printable representation
310
311 /**
312 Print the tree rooted at this node to buf. Call on top level with level==0
313 @param level level we are at in tree.
314 @param buf the buffer to format output into
315 */
316 virtual void debugPrint(int level, std::ostringstream &buf) const = 0;
317 /**
318 Print blank space indentation (unit: two) to buf according to level. Minion.
319 @param level level we are at in tree.
320 @param buf the buffer to format output into
321 */
322 static void indent(int level, std::ostringstream &buf);
323 /**
324 Print the pointer of this node and its parent to buf. Minion.
325 @param buf the buffer to format output into
326 */
328 /**
329 Print into str the order indicated in ord, using standard print_for_order
330 Used by traditional explain.
331 @param thd session state
332 @param str string to accumulate formatted output into
333 @param ord the ORDER to be printed
334 @param query_type controls how printing happens
335 */
336 static void print_order(const THD *thd, String *str, ORDER *ord,
337 enum_query_type query_type);
338
339 // The next set of members his contains all that is needed to implement ORDER
340 // BY + LIMIT in several layers of unary/binary set operations: they have
341 // taken over information earlier stored in a single instance directly in
342 // Query_expression, which was then limited to single level only.
343
344 /**
345 The query_block which holds the ORDER BY and LIMIT information for this
346 set operation. Note that for the case where the root is a simple
347 query block, this will return self.
348 @returns the query block
349 */
350 virtual Query_block *query_block() const = 0;
351
352 protected:
353 /**
354 The query result for this term. Shared between n-ary set operands, the first
355 one holds it, cf. owning_operand. Except at top level, this is always a
356 Query_result_union.
357 */
359 /**
360 The operand of a n-ary set operation (that owns the common query result) has
361 this set to true. It is always the first one.
362 */
363 bool m_owning_operand{false};
364 /**
365 Result temporary table for the set operation, if applicable
366 */
368 /**
369 Used only when streaming, i.e. not materialized result set
370 */
372
373 public:
374 /// Setter for m_setop_query_result, q.v.
376 /// Getter for m_setop_query_result, q.v.
378 /// Getter for m_setop_query_result, q.v. Use only if we can down cast.
380 return down_cast<Query_result_union *>(m_setop_query_result);
381 }
382 /// Cleanup m_setop_query_result, q.v.
383 void cleanup_query_result(bool full);
384
385 /// Setter for m_owning_operand, q.v.
387 /// Getter for m_owning_operand, q.v.
389
390 /// Setter for m_result_table, q.v.
392 /// Getter for m_result_table, q.v.
394
395 // Setter for m_fields, q.v.
397 // Getter for m_fields, q.v.
399};
400
401/// Common base class for n-ary set operations, including unary.
403 /// Replaces the old "fake" query block for post processing result set with
404 /// ORDER BY, LIMIT.
405 /// The query block(s) of the query specifications can be found via
406 /// m_children.
408
409 protected: // this node type is abstract
411
412 public:
413 /// Tree structure. Cardinality is one for unary, two or more for UNION,
414 /// EXCEPT, INTERSECT
416 /**
417 Index of last query expression which has <set-op> DISTINCT on its left. In
418 a list of <set-op>ed blocks, UNION is left-associative; so UNION DISTINCT
419 eliminates duplicates in all blocks up to the first one on its right
420 included. Which is why we only need to remember that query block. Is -1
421 for Unary.
422 */
424 /**
425 Presently only needed by EXCEPT set operator: the index of the first
426 DISTINCT set operand: minimum legal value is 1. If not DISTINCT, it should
427 have the value std::numeric_limits<int64_t>::max(). The value is set
428 in PT_set_operation::merge_descendants.
429 */
431 /**
432 true if the result of this set operation is materialized. A priori true
433 unless we have a pure UNION ALL.
434 */
436
437 /// Getter for m_block, q.v.
438 Query_block *query_block() const override { return m_block; }
439
440 /// Setter for m_block, q.v.
442 assert(!m_block);
443 if (b == nullptr) return true;
444
445 m_block = b;
446 return false;
447 }
448
449 void label_children() override {
450 uint idx = 0;
451 for (auto child : m_children) {
452 child->set_sibling_idx(idx++);
453 child->label_children();
454 }
455 }
456
457 size_t child_count() const override { return m_children.size(); }
458 bool open_result_tables(THD *thd, int level) override;
459 void cleanup(bool full) override;
460 void destroy_tree() override {
461 m_parent = nullptr;
462 for (Query_term *child : m_children) {
463 child->destroy_tree();
464 }
465 m_children.clear();
466 }
467 /**
468 Check if this set operation has a mix of DISTINCT and ALL.
469 @return true if so. Always false for unary
470 */
472 /**
473 Check if this term is a unary set operation
474 @return true if so
475 */
476 bool is_unary() const { return term_type() == QT_UNARY; }
477
478 // Recursively set up materialization for a query term tree. For details,
479 // see implementation.
481 THD *thd, TABLE *dst_table, bool union_distinct_only,
482 bool calc_found_rows);
483
484 protected:
485 /**
486 Common printing minion for set operations.
487 @param level level in tree
488 @param buf the buffer to format output into
489 @param type descriptive string of set operation to use for printing
490 */
491 void print(int level, std::ostringstream &buf, const char *type) const;
492};
493
494/// Node type for n-ary UNION
496 public:
497 /**
498 Constructor.
499 @param mem_root the mem_root to use for allocation
500 */
502 Query_term_type term_type() const override { return QT_UNION; }
503 const char *operator_string() const override { return "union"; }
504 void debugPrint(int level, std::ostringstream &buf) const override;
505};
506
507/// Node type for n-ary INTERSECT
509 public:
510 /**
511 Constructor.
512 @param mem_root the mem_root to use for allocation
513 */
515 Query_term_type term_type() const override { return QT_INTERSECT; }
516 const char *operator_string() const override { return "intersect"; }
517 void debugPrint(int level, std::ostringstream &buf) const override;
518};
519
520/// Node type for n-ary EXCEPT
522 public:
523 /**
524 Constructor.
525 @param mem_root the mem_root to use for allocation
526 */
528 Query_term_type term_type() const override { return QT_EXCEPT; }
529 const char *operator_string() const override { return "except"; }
530 void debugPrint(int level, std::ostringstream &buf) const override;
531};
532
533/// A <query primary> which is a parenthesized query expression (aka qe) body
534/// with order by clause and/or limit/offset clause and the qe body
535/// is not a binary set operation (union, except, intersect), but is viewed here
536/// as a degenerate set operation; i.e. a "unary".
537/// \verbatim
538/// Example: (SELECT * FROM .. ORDER BY .. LIMIT n) ORDER BY .. LIMIT m
539/// Tree:
540/// Query_expression
541/// | m_query_term
542/// Query_term_unary
543/// +--------------------+
544/// | m_block ------+----> Query_block which holds outer
545/// | : | ORDER BY and LIMIT
546/// | m_children[0] |
547/// +--------|-----------+
548/// V
549/// Query_block holds inner SELECT and its ORDER BY/LIMIT
550/// \endverbatim
551/// One extra Query_term_unary is added for each level of nesting
552/// with the top one representing the outermost ORDER BY/LIMIT/OFFSET
553///
555 public:
556 /**
557 Constructor.
558 @param mem_root the mem_root to use for allocation
559 @param t the child term
560 */
563 m_last_distinct = 0;
564 m_children.push_back(t);
565 t->set_sibling_idx(0);
566 }
567 Query_term_type term_type() const override { return QT_UNARY; }
568 const char *operator_string() const override { return "result"; }
569 void debugPrint(int level, std::ostringstream &buf) const override;
570};
571
572/**
573 Containing class for iterator over the query term tree. The structure is
574 in part dictated by C++ conventions for iterators.
575 @tparam visit_order indicates whether pre or post order visiting is requested
576 @tparam visit_leaves indicates whether to visit the leaf nodes (query blocks)
577*/
578template <Visit_order visit_order, Visit_leaves visit_leaves>
580 private:
581 /**
582 The iterator class itself is private. Only used directly by begin and end
583 */
585 public:
586 /**
587 Construct an iterator over the query term tree rooted in root, optionally
588 skipping the leaves. Skipping is useful for those cases where the leaves
589 are visited separately[1] and we only want to visit the set operation
590 nodes in the tree.
591 [1] By walking the Query_expression::first_query_block and
592 Query_block::next_query_block chain
593 @param root the node to start iteration from
594 */
596 : m_current(root), m_child_idx(0) {
597 if (root == nullptr) return;
598 if constexpr (visit_order == QTC_POST_ORDER) {
599 // start at left-most leaf node
601 if constexpr (visit_leaves == VL_SKIP_LEAVES) operator++();
602 }
603 }
604
606
608 assert(m_current != nullptr);
609 while (m_current != nullptr) {
610 uint children = m_current->child_count();
611 if constexpr (visit_order == QTC_PRE_ORDER) {
612 while (m_current != nullptr && m_child_idx >= children) {
613 // no more at this level, go back up
615 if (m_current != nullptr) {
616 children = m_current->child_count();
617 }
618 }
619
620 if (m_current == nullptr) return *this;
621 m_current = down_cast<Query_term_set_op *>(m_current)
622 ->m_children[m_child_idx];
623 m_child_idx = 0;
624 } else {
626 if (m_current == nullptr) return *this;
627 if (m_child_idx < m_current->child_count()) {
629 } else {
630 // return non-leaf
631 }
632 }
633 if constexpr (visit_leaves == VL_VISIT_LEAVES)
634 break;
635 else if (m_current->term_type() != QT_QUERY_BLOCK)
636 break;
637 }
638 return *this;
639 }
640
642
643 bool operator==(const Query_term_iterator &other) const {
644 return m_current == other.m_current;
645 }
646
647 bool operator!=(const Query_term_iterator &other) const {
648 return !((*this) == other);
649 }
650
651 private:
652 /// Iterator state consists of the next two member variables
654
655 /// Used to find next child node to dive into, see \c set_next_child_idx
656 uint m_child_idx{0};
657
658 /// Starting at \c m_current->m_children[m_child_index], dive down through
659 /// any left-most (index == 0) further children till we find left-most leaf
660 /// term (a \c Query_block) under the child pointed to by
661 /// \c m_child_index. After the dive, \c m_child_index will be zero, and
662 /// \c m_current will be set to the leaf term.
664 while (m_current != nullptr && m_current->term_type() != QT_QUERY_BLOCK) {
665 m_current =
666 down_cast<Query_term_set_op *>(m_current)->m_children[m_child_idx];
667 m_child_idx = 0;
668 }
669 }
670
671 /// Find the index of the next sibling, if any, of \c m_current qua child
672 /// of its parent, so we can visit it: assign it to \c m_child_idx.
673 /// Setting \c m_child_idx to a value of \c Query_term::child_count means we
674 /// signal that we are done. Also, \c m_current is set to its parent.
676 assert(m_current != nullptr);
677 if (m_current->parent() == nullptr) {
679 return;
680 }
682 m_current);
684
686 }
687 };
688
689 public:
690 /// Construct an iterator starting at root.
691 Query_terms(Query_term *root) : m_root(root) {}
692
695
696 private:
698};
699
700/* Local Variables: */
701/* mode: c++ */
702/* fill-column: 80 */
703/* End: */
704
705#endif /* QUERY_NODE_INCLUDED */
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:426
This class represents a query block, aka a query specification, which is a query consisting of a SELE...
Definition: sql_lex.h:1163
Definition: sql_union.h:40
Definition: query_result.h:58
Node type for n-ary EXCEPT.
Definition: query_term.h:521
const char * operator_string() const override
Get the node type description.
Definition: query_term.h:529
Query_term_type term_type() const override
Get the node tree type.
Definition: query_term.h:528
void debugPrint(int level, std::ostringstream &buf) const override
Print the tree rooted at this node to buf.
Definition: query_term.cc:249
Query_term_except(MEM_ROOT *mem_root)
Constructor.
Definition: query_term.h:527
Node type for n-ary INTERSECT.
Definition: query_term.h:508
const char * operator_string() const override
Get the node type description.
Definition: query_term.h:516
void debugPrint(int level, std::ostringstream &buf) const override
Print the tree rooted at this node to buf.
Definition: query_term.cc:244
Query_term_intersect(MEM_ROOT *mem_root)
Constructor.
Definition: query_term.h:514
Query_term_type term_type() const override
Get the node tree type.
Definition: query_term.h:515
Common base class for n-ary set operations, including unary.
Definition: query_term.h:402
int64_t m_last_distinct
Index of last query expression which has <set-op> DISTINCT on its left.
Definition: query_term.h:423
mem_root_deque< Query_term * > m_children
Tree structure.
Definition: query_term.h:415
void destroy_tree() override
Destroy the query term tree structure.
Definition: query_term.h:460
void cleanup(bool full) override
Reset resources used.
Definition: query_term.cc:225
int64_t m_first_distinct
Presently only needed by EXCEPT set operator: the index of the first DISTINCT set operand: minimum le...
Definition: query_term.h:430
void print(int level, std::ostringstream &buf, const char *type) const
Common printing minion for set operations.
Definition: query_term.cc:194
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 maki...
Definition: sql_union.cc:1388
bool has_mixed_distinct_operators()
Check if this set operation has a mix of DISTINCT and ALL.
Definition: query_term.cc:189
bool set_block(Query_block *b)
Setter for m_block, q.v.
Definition: query_term.h:441
Query_term_set_op(MEM_ROOT *mem_root)
Definition: query_term.h:410
bool is_unary() const
Check if this term is a unary set operation.
Definition: query_term.h:476
Query_block * query_block() const override
Getter for m_block, q.v.
Definition: query_term.h:438
bool open_result_tables(THD *thd, int level) override
Open tmp tables for the tree of set operation query results, by recursing.
Definition: query_term.cc:211
bool m_is_materialized
true if the result of this set operation is materialized.
Definition: query_term.h:435
size_t child_count() const override
Get the number of children this node has.
Definition: query_term.h:457
Query_block * m_block
Replaces the old "fake" query block for post processing result set with ORDER BY, LIMIT.
Definition: query_term.h:407
void label_children() override
Set the correct value of Query_term::m_sibling_idx recursively for set operations.
Definition: query_term.h:449
A <query primary> which is a parenthesized query expression (aka qe) body with order by clause and/or...
Definition: query_term.h:554
Query_term_unary(MEM_ROOT *mem_root, Query_term *t)
Constructor.
Definition: query_term.h:561
void debugPrint(int level, std::ostringstream &buf) const override
Print the tree rooted at this node to buf.
Definition: query_term.cc:426
const char * operator_string() const override
Get the node type description.
Definition: query_term.h:568
Query_term_type term_type() const override
Get the node tree type.
Definition: query_term.h:567
Node type for n-ary UNION.
Definition: query_term.h:495
void debugPrint(int level, std::ostringstream &buf) const override
Print the tree rooted at this node to buf.
Definition: query_term.cc:240
const char * operator_string() const override
Get the node type description.
Definition: query_term.h:503
Query_term_union(MEM_ROOT *mem_root)
Constructor.
Definition: query_term.h:501
Query_term_type term_type() const override
Get the node tree type.
Definition: query_term.h:502
Query term tree structure.
Definition: query_term.h:209
Query_term * pushdown_limit_order_by(Query_term_set_op *parent=nullptr)
Called after contextualization to simplify query, c.f.
Definition: query_term.cc:74
virtual void label_children()=0
Set the correct value of Query_term::m_sibling_idx recursively for set operations.
virtual Query_block * query_block() const =0
The query_block which holds the ORDER BY and LIMIT information for this set operation.
uint sibling_idx()
Getter for m_sibling_idx, q.v.
Definition: query_term.h:284
void cleanup_query_result(bool full)
Cleanup m_setop_query_result, q.v.
Definition: query_term.cc:178
Query_term_set_op * m_parent
Back pointer to the node whose child we are, or nullptr (root term).
Definition: query_term.h:272
virtual bool open_result_tables(THD *thd, int level)
Open tmp tables for the tree of set operation query results, by recursing.
Definition: query_term.h:303
Query_result * m_setop_query_result
The query result for this term.
Definition: query_term.h:358
Query_result_union * setop_query_result_union()
Getter for m_setop_query_result, q.v. Use only if we can down cast.
Definition: query_term.h:379
void set_setop_query_result(Query_result *rs)
Setter for m_setop_query_result, q.v.
Definition: query_term.h:375
Query_result * setop_query_result()
Getter for m_setop_query_result, q.v.
Definition: query_term.h:377
void set_fields(mem_root_deque< Item * > *fields)
Definition: query_term.h:396
virtual Query_term_type term_type() const =0
Get the node tree type.
void set_sibling_idx(uint idx)
Setter for m_sibling_idx, q.v.
Definition: query_term.h:282
Table_ref & result_table()
Getter for m_result_table, q.v.
Definition: query_term.h:393
virtual const char * operator_string() const =0
Get the node type description.
bool owning_operand()
Getter for m_owning_operand, q.v.
Definition: query_term.h:388
mem_root_deque< Item * > * fields()
Definition: query_term.h:398
void set_owning_operand()
Setter for m_owning_operand, q.v.
Definition: query_term.h:386
Query_term_set_op * parent() const
Getter for m_parent, q.v.
Definition: query_term.h:280
void set_result_table(Table_ref *tl)
Setter for m_result_table, q.v.
Definition: query_term.h:391
virtual void cleanup(bool full)
Reset resources used.
Definition: query_term.h:290
virtual size_t child_count() const
Get the number of children this node has.
Definition: query_term.h:261
virtual ~Query_term()=default
Node destructor.
uint m_sibling_idx
If parent is non-null, this holds the index of the current sibling.
Definition: query_term.h:276
Table_ref * m_result_table
Result temporary table for the set operation, if applicable.
Definition: query_term.h:367
std::pair< bool, bool > redundant_order_by(Query_block *block, int level)
Determine if we have a redundant ORDER BY in block.
Definition: query_term.cc:43
bool validate_structure(const Query_term *parent, int depth=0) const
Return true if structure is too deep, i.e.
Definition: query_term.cc:162
virtual void debugPrint(int level, std::ostringstream &buf) const =0
Print the tree rooted at this node to buf.
bool m_owning_operand
The operand of a n-ary set operation (that owns the common query result) has this set to true.
Definition: query_term.h:363
void printPointers(std::ostringstream &buf) const
Print the pointer of this node and its parent to buf.
Definition: query_term.cc:234
static void indent(int level, std::ostringstream &buf)
Print blank space indentation (unit: two) to buf according to level.
Definition: query_term.cc:230
virtual void destroy_tree()=0
Destroy the query term tree structure.
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...
Definition: query_term.cc:33
mem_root_deque< Item * > * m_fields
Used only when streaming, i.e.
Definition: query_term.h:371
The iterator class itself is private.
Definition: query_term.h:584
bool operator!=(const Query_term_iterator &other) const
Definition: query_term.h:647
Query_term_iterator & operator++()
Definition: query_term.h:607
bool operator==(const Query_term_iterator &other) const
Definition: query_term.h:643
Query_term * m_current
Iterator state consists of the next two member variables.
Definition: query_term.h:653
uint m_child_idx
Used to find next child node to dive into, see set_next_child_idx.
Definition: query_term.h:656
void prepare_for_next_sibling()
Find the index of the next sibling, if any, of m_current qua child of its parent, so we can visit it:...
Definition: query_term.h:675
Query_term * operator*()
Definition: query_term.h:641
Query_term_iterator(Query_term *root)
Construct an iterator over the query term tree rooted in root, optionally skipping the leaves.
Definition: query_term.h:595
void dive_to_leftmost_leaf_of_child()
Starting at m_current->m_children[m_child_index], dive down through any left-most (index == 0) furthe...
Definition: query_term.h:663
Containing class for iterator over the query term tree.
Definition: query_term.h:579
Query_term_iterator end()
Definition: query_term.h:694
Query_terms(Query_term *root)
Construct an iterator starting at root.
Definition: query_term.h:691
Query_term * m_root
Definition: query_term.h:697
Query_term_iterator begin()
Definition: query_term.h:693
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:167
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
Definition: table.h:2864
A (partial) implementation of std::deque allocating its blocks on a MEM_ROOT.
Definition: mem_root_deque.h:111
static MEM_ROOT mem_root
Definition: client_plugin.cc:114
enum_query_type
Query type constants (usable as bitmap flags).
Definition: enum_query_type.h:31
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1081
Definition: buf0block_hint.cc:30
std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut::allocator.
Definition: ut0new.h:2871
Query_term_type
This class hierarchy is used to represent SQL structures between <query expression> and <query specif...
Definition: query_term.h:89
@ QT_UNARY
Represents a query primary with parentesized query expression body with order by clause and/or limit/...
Definition: query_term.h:96
@ QT_EXCEPT
Definition: query_term.h:100
@ QT_UNION
Definition: query_term.h:101
@ QT_INTERSECT
Represents the three set operations.
Definition: query_term.h:99
@ QT_QUERY_BLOCK
Represents Query specification, table value constructor and explicit table.
Definition: query_term.h:92
Visit_leaves
Query term iterator template argument type: whether to visit leaf nodes.
Definition: query_term.h:107
@ VL_SKIP_LEAVES
Definition: query_term.h:107
@ VL_VISIT_LEAVES
Definition: query_term.h:107
Visit_order
Query term iterator template argument type: how to visit nodes in tree.
Definition: query_term.h:105
@ QTC_PRE_ORDER
Definition: query_term.h:105
@ QTC_POST_ORDER
Definition: query_term.h:105
required string type
Definition: replication_group_member_actions.proto:34
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:83
Definition: table.h:286
Definition: table.h:1406