MySQL 9.1.0
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 <cstdint>
27#include "my_inttypes.h"
28#include "mysql.h"
29#include "sql/join_optimizer/access_path.h" // AppendPathParameters
30#include "sql/join_optimizer/materialize_path_parameters.h" // MaterializePathParameters
31#include "sql/mem_root_array.h"
32#include "sql/query_result.h"
33#include "sql/sql_list.h"
34#include "sql/sql_union.h"
35#include "sql/table.h"
36#include "sql/visible_fields.h"
37
38class Query_block;
40/**
41 This class hierarchy is used to represent SQL structures between <query
42 expression> and <query specification>. The class Query_expression
43 represents <query expression> and the class Query_block represents <query
44 specification>, <table value constructor> and <explicit table>,
45 cf. definitions in sql_lex.h. Originally, MySQL supported only one set
46 operation, UNION. This was implicitly represented by having one
47 Query_expression object own several Query_block objects via next pointers.
48 This made things simple, but limited us to left-deep nesting of unions, and
49 also from representing INTERSECTION and EXCEPT, as well as nesting several
50 layers of <query primary>s containing <query expression body>s, e.g.
51
52 (((SELECT a,b FROM t) ORDER BY a LIMIT 5) ORDER BY -b LIMIT 3) ORDER BY a;
53
54 could not be supported. With the present class hierarchy we enable the full
55 set of set operations and arbitrary nesting, as allowed by the SQL grammar,
56 viz:
57 \verbatim
58 <query expression> ::=
59 [ <with clause> ] <query expression body>
60 [ <order by clause> ] [ <limit/offset> ]
61
62 <query expression body> ::=
63 <query term>
64 | <query expression body> UNION [ ALL | DISTINCT ]
65 [ <corresponding spec> ] <query term>
66 | <query expression body> EXCEPT [ ALL | DISTINCT ]
67 [ <corresponding spec> ] <query term>
68
69 <query term> ::=
70 <query primary>
71 | <query expression body> INTERSECT [ ALL | DISTINCT ]
72 [ <corresponding spec> ] <query primary>
73
74 <query primary> ::=
75 <simple table>
76 | <left paren> <query expression body>
77 [ <order by clause> ] [ <limit/offset (*)> ]
78 <right paren>
79
80 <simple table> ::=
81 <query specification>
82 | <table value constructor>
83 | <explicit table>
84
85 (*) MySQL syntax and semantics. The standard uses /<result offset clause/> and
86 <fetch first clause>.
87
88 \endverbatim
89 Note that INTERSECT binds tighter than UNION and EXCEPT.
90 Now, let's turn to how these structures are represented in MySQL.
91 The node types are enumerated by Query_term_type. The nodes themselves
92 by the class hierarchy rooted in Query_term (abstract).
93*/
94
95/// Node type of the query term tree nodes
97 /// Represents Query specification, table value constructor and
98 /// explicit table
100 /// Represents a query primary with parentesized query expression body with
101 /// order by clause and/or limit/offset clause. If none of order by
102 /// or limit is present, we collapse this level of parentheses.
104 /// Represents the three set operations. Nodes are N-ary, i.e. a node can hold
105 /// two or more operands.
110
111/// Query term iterator template argument type: how to visit nodes in tree
113/// Query term iterator template argument type: whether to visit leaf nodes
115
116/**
117 Query term tree structure. There are five node types, cf. Query_term_type.
118 Leaf nodes are Query_block objects. We have three kinds of n-ary set operation
119 nodes corresponding to INTERSECT, UNION and EXCEPT. Finally, we have a "unary"
120 node which essentially adds a ORDER BY/LIMIT over another node.
121
122 Query blocks serve a dual purpose: they represent the query specification and
123 table constructors of the query. As such they are the leaf nodes of the query
124 tree. But they also serve as a way to realize ORDER BY and LIMIT for non-leaf
125 nodes, accessed via the function Query_term::query_block(). Therefore, every
126 non-leaf node in the tree has a companion Query_block to hold ORDER BY and
127 LIMIT information. For the leaf nodes, which are themselves query blocks, the
128 query_block() function just returns a pointer to self, i.e. the leaf nodes
129 handle ORDER BY and LIMIT themselves.
130
131 \verbatim
132 Example: ((SELECT * FROM t1 UNION SELECT * FROM t2 UNION ALL SELECT * FROM t3
133 ORDER BY a LIMIT 5) INTERSECT
134 (((SELECT * FROM t3 ORDER BY a LIMIT 4) ) EXCEPT SELECT * FROM t4)
135 ORDER BY a LIMIT 4) ORDER BY -a LIMIT 3;
136
137 ->
138 m_query_term +------------------+ slave(s)
139 +--------------|-Query_expression |------------------+
140 | +------------------+ |
141 V post_ |
142 +-------------------+processing_ +----------------------+ |
143 | Query_term_unary |block() |Query_block | |
144 | |----------->|order by -(`a) limit 3| |
145 +-------------------+ +----------------------+ |
146 |m_children |
147 | +-----------------------+ +----------------------+ |
148 | |Query_term_intersect | |Query_block | |
149 +>|last distinct index: 1 |-->|order by `a` limit 4 | |
150 +-----------------------+ +----------------------+ |
151 |m_children |
152 | +-----------------------+ +----------------------+ |
153 | |Query_term_union | |Query_block | |
154 +->|last distinct index: 1 |-->|order by `a` limit 5 | |
155 | +-----------------------+ +----------------------+ |
156 | |m_children |
157 | | +------------+ SELECT * FROM t1 /
158 | +-->|Query_block | <---------------------------------+
159 | | +------------+ ----------------------------------+ next
160 | | \
161 | | +------------+ SELECT * FROM t2 /
162 | +-->|Query_block | <---------------------------------+
163 | | +------------+ ----------------------------------+ next
164 | | \
165 | | +------------+ SELECT * FROM t3 /
166 | +-->|Query_block | <---------------------------------+
167 | +------------+ ----------------------------------+ next
168 | \
169 | +-----------------------+ +------------+ |
170 | |Query_term_except |->|Query_block | |
171 +->|last distinct index: 1 | +------------+ |
172 +-----------------------+ |
173 |m_children |
174 | +----------------------+ |
175 | |Query_block | SELECT * FROM t3 /
176 +-->|order by `a` limit 4 | <------------------------+
177 | +----------------------+ -------------------------+ next
178 | \
179 | +------------+ SELECT * FROM t4 |
180 +-->|Query_block | <------------------------------------+
181 +------------+
182 \endverbatim
183 Note that all leaf query blocks representing the query specifications are
184 linked under Query_expression via their next pointers. The nesting is achieved
185 by the arrows on the left side of the figure, via the nodes' m_children
186 members. The four classes Query_term_unary and Query_term_{union, intersect,
187 except} are modelled via the base class Query_term_set_op which contains a
188 m_children member. Each of these also contain a Query_block which will handle
189 its order by and/or limit clauses. These are similar to the old so-called
190 "fake_query_block" (which is now gone), and are not linked in with "next"
191 pointers.
192
193 The is also a back pointer from the children nodes to the parent Query_term
194 object (not shown).
195
196 In the simple case of a single query specification (or table value constructor
197 or explicit table), there is no super-structure over the Query_block linked
198 from the Query_expression, i.e. Query_expression's m_query_term member is just
199 a Query_block.
200
201 The query blocks (QT_QUERY_BLOCK nodes) corresponding to the query
202 specification (or table value constructors) are prepared and optimized by
203 running over them from the Query_expression via the slave/next pointers as
204 before. There are separate methods which handle prepare and optimization for
205 non-leaves, i.e. nodes of types QT_UNARY, QT_INTERSECT, QT_EXCEPT and
206 QT_UNION.
207
208 We also define an iterator class (Query_terms) for iterating over all
209 the nodes in the tree, see also Query_expression::query_terms() for its use.
210 When possible, we access all nodes using iterators.
211
212 The built structure can be traced with the debug trace keyword "ast", e.g.
213 as SET SESSION debug = 'd,ast:O,/tmp/mysqld.trace';
214*/
215
217 public:
218 // The next two methods used during construction of the tree.
219 /**
220 Called after contextualization to simplify query, c.f. sql_yacc.yy
221 CONTEXTUALIZE_VIEW. It also sets up the parent pointers.
222 @param parent parent of this if any
223 */
225
226 /**
227 Return true if structure is too deep, i.e. more than MAX_SELECT_NESTING.
228 As a side effect is also gives the post processing block a select number,
229 this is done late so as to get numbers higher the leaf blocks, and in
230 inside out order, so that the top set operation block will have the highest
231 number.
232 @param parent the real parent in the tree as visited recursively
233 @param depth the current depth in the tree, starting at 0 at the top.
234 It is increased with one for each time we recurse into a child.
235 @returns error if too deep structure, else false
236 */
237 bool validate_structure(const Query_term *parent, int depth = 0) const;
238
239 /**
240 Determine if we have a redundant ORDER BY in block. Used during prepare.
241 @param block the query block
242 @param level the current nesting level
243 @return tuple {bool found, bool redundant} redundant==true means ORDER BY of
244 the block is redundant and can be eliminated.
245 */
246 std::pair<bool, bool> redundant_order_by(Query_block *block, int level);
247
248 // Tree structure
249
250 /**
251 Get the node tree type.
252 @returns the tree node type
253 */
254 virtual Query_term_type term_type() const = 0;
255 /**
256 Get the node type description.
257 @returns descriptive string for each node type.
258 */
259 virtual const char *operator_string() const = 0;
260 /**
261 Node destructor
262 */
263 virtual ~Query_term() = default;
264 /**
265 Get the number of children this node has.
266 @return the number
267 */
268 virtual size_t child_count() const { return 0; }
269
270 /**
271 a) Prepare query blocks, both leaf blocks and blocks reresenting order
272 by/limit in query primaries with parentesized query expression body with
273 order by clause and/or limit/offset clause (unary query terms). Establish
274 types for all query terms, and set up tmp table for CTE if present and for
275 any materialized tmp tables for unary query terms.
276
277 Types for set operations are calculated bottom-up, so for a unary tmp table,
278 we use the base block's types and names for proper resolution in cases
279 like:
280
281 SELECT column_a FROM t1
282 UNION
283 ( (SELECT column_b FROM t2 ORDER BY column_b LIMIT 3)
284 ORDER BY column_b DESC LIMIT 2 )
285 ORDER BY column_a;
286
287 The second ORDER BY's \c column_b should resolve to its nested \c column_b
288 selected from t2. This also means that the second order by operation does
289 sorting using the type of \c column_b, not using the common type of
290 \c t1.column_a and \c t2.column_b.
291
292 If the inner SELECT above were a binary set operation, we would order by the
293 joined types of the binary (sub)operation, recursively.
294
295 This function constructs the \c m_types array for each binary set operation
296 query term. Unary terms just use their child's type information.
297
298 We have a nested set operation structure where the leaf nodes are inner
299 query blocks, typically SELECT clauses. These are prepared with
300 \c Query_block::prepare, called by \c Query_block::prepare_query_term.
301 We also need to prepare the nodes representing the binary set and unary
302 operations. We have already merged nested set operation of the same kind
303 into multi op form, so at any level the child and parent will usually be of
304 another kind(1). We a priori create temporary tables marked with an
305 asterisk below, modulo ALL optimizations, to consolidate the result of each
306 multi set and unary operations. E.g.
307
308 UNION*
309 |
310 +----------------+----------+
311 | | |
312 INTERSECT* UNARY TERM* EXCEPT*
313 | | |
314 +---+---+ QB +--+-+
315 | | | | |
316 QB QB UNION* QB QB
317 QB QB
318
319 (1) an exception is that we do not merge top level trailing UNION ALL nodes
320 with preceding UNION DISTINCT in order that they can be streamed
321 efficiently.
322
323 Note that the \c Query_result is owned by the first sibling participating in
324 the set operations, so the owning nodes of the above example are actually:
325
326 UNION
327 |
328 +----------------+----------+
329 | | |
330 INTERSECT* UNARY TERM EXCEPT
331 | | |
332 +---+---+ QB* +--+-+
333 | | | | |
334 QB* QB UNION QB* QB
335 QB* QB
336
337
338 @param thd session context
339 @param qe query expression query expression directly containing this
340 query term
341 @param save_query_block
342 copy of thd->lex->current_query_block()
343 when Query_expression::prepare was called.
344 @param insert_field_list
345 pointer to field list if INSERT op, NULL otherwise.
346 @param common_result
347 for the top node, this is not used: we use query_result()
348 instead. Otherwise, if it is empty, we create a query result
349 on behalf of this node and its siblings. This node is then the
350 designated owning operand, and is responsible for releasing it
351 after execution. The siblings will see that common_result is
352 not empty and use that.
353 @param added_options
354 these options will be added to the query blocks.
355 @param removed_options
356 options that cannot be used for this query
357 @param create_options
358 options to use for creating tmp table
359 @returns false on success, true on error
360 */
362 Change_current_query_block *save_query_block,
363 mem_root_deque<Item *> *insert_field_list,
364 Query_result *common_result,
365 ulonglong added_options,
366 ulonglong removed_options,
368
369 /**
370 Optimize the non-leaf query blocks
371 @param thd session context
372 @param qe owning query expression (of this term)
373 @returns true on error, else false
374 */
375 virtual bool optimize_query_term(THD *thd, Query_expression *qe) = 0;
376
377 /**
378 Recursively constructs the access path of the set operation, possibly
379 materializing in a tmp table if needed, cf.
380 \c Query_term_set_op::m_is_materialized
381 @param thd session context
382 @param parent the parent for which we want to create a materialized access
383 path, or nullptr
384 @param union_all_subpaths
385 if not nullptr, we are part of a UNION all, add constructed
386 access to it.
387 @param calc_found_rows
388 if true, do allow for calculation of number of found rows
389 even in presence of LIMIT.
390 @return access path, if nullptr, this is an error
391 */
394 Mem_root_array<AppendPathParameters> *union_all_subpaths,
395 bool calc_found_rows) = 0;
396
397 /// Set the correct value of \c Query_term::m_sibling_idx recursively for
398 /// set operations. For \c Query_term_unary, this is done in its constructor.
399 /// A no-op for \c Query_block. See also \c set_sibling_idx.
400 virtual void label_children() = 0;
401
402 /**
403 Create a temporary table for a set operation.
404
405 @param thd session context
406 @param create_options
407 create options for create_tmp_table
408 @return false on success, true on error
409 */
411
412 /// Abstract over visible column types: if query block, we offer an iterator
413 /// over visible fields, for binary set operators we offer an
414 /// iterator over \c m_types, for unary we just call the child's.
415 /// See also the accompanying
416 /// \c visible_column_count.
418 /// Return the number of visible columns of the query term. For query blocks
419 /// this is in general a subset of \c Query_block::fields
420 virtual size_t visible_column_count() const = 0;
421
422 /// Getter for \c m_parent, q.v.
423 Query_term_set_op *parent() const { return m_parent; }
424 /// Setter for \c m_sibling_idx, q.v.
425 void set_sibling_idx(uint idx) { m_sibling_idx = idx; }
426 /// Getter for \c m_sibling_idx, q.v.
427 uint sibling_idx() { return m_sibling_idx; }
428 /**
429 Reset resources used.
430 @param full do full cleanup. Same semantics as for Query_expression's
431 cleanup
432 */
433 virtual void cleanup(bool full [[maybe_unused]]) {
434 assert(false); // should be overridden
435 }
436
437 /// Destroy the query term tree structure
438 virtual void destroy_tree() = 0;
439
440 /**
441 Open tmp tables for the tree of set operation query results, by recursing
442 @param thd session context
443 @param level level in the tree, top should be called with 0.
444 @return true on error
445 */
446 virtual bool open_result_tables(THD *thd [[maybe_unused]],
447 int level [[maybe_unused]]) {
448 assert(false); // should be overridden
449 return false;
450 }
451
453
454 // Printable representation
455
456 /**
457 Print the tree rooted at this node to buf. Call on top level with level==0
458 @param level level we are at in tree.
459 @param buf the buffer to format output into
460 */
461 virtual void debugPrint(int level, std::ostringstream &buf) const = 0;
462 /**
463 Print blank space indentation (unit: two) to buf according to level. Minion.
464 @param level level we are at in tree.
465 @param buf the buffer to format output into
466 */
467 static void indent(int level, std::ostringstream &buf);
468 /**
469 Print the pointer of this node and its parent to buf. Minion.
470 @param buf the buffer to format output into
471 */
473 /**
474 Print into str the order indicated in ord, using standard print_for_order
475 Used by traditional explain.
476 @param thd session state
477 @param str string to accumulate formatted output into
478 @param ord the ORDER to be printed
479 @param query_type controls how printing happens
480 */
481 static void print_order(const THD *thd, String *str, ORDER *ord,
482 enum_query_type query_type);
483
484 // The next set of members his contains all that is needed to implement ORDER
485 // BY + LIMIT in several layers of unary/binary set operations: they have
486 // taken over information earlier stored in a single instance directly in
487 // Query_expression, which was then limited to single level only.
488
489 /**
490 The query_block which holds the ORDER BY and LIMIT information for this
491 set operation. Note that for the case where the root is a simple
492 query block, this will return self.
493 @returns the query block
494 */
495 virtual Query_block *query_block() const = 0;
496
497 /// Setter for m_setop_query_result, q.v.
499 /// Getter for m_setop_query_result, q.v.
501 /// Getter for m_setop_query_result, q.v. Use only if we can down cast.
503 return down_cast<Query_result_union *>(m_setop_query_result);
504 }
505 /// Cleanup m_setop_query_result, q.v.
506 void cleanup_query_result(bool full);
507
508 /// Setter for m_owning_operand, q.v.
510 /// Getter for m_owning_operand, q.v.
512
513 /// Setter for m_result_table, q.v.
515 /// Getter for m_result_table, q.v.
517
518 // Setter for m_fields, q.v.
520 // Getter for m_fields, q.v.
522
523 protected:
524 /**
525 Back pointer to the node whose child we are, or nullptr (root term).
526 */
528
529 /// If parent is non-null, this holds the index of the current sibling.
530 /// Used for efficient iterator traversal up and down the tree.
532
533 /**
534 The query result for this term. Shared between n-ary set operands, the first
535 one holds it, cf. owning_operand. Except at top level, this is always a
536 Query_result_union.
537 */
539 /**
540 The operand of a n-ary set operation (that owns the common query result) has
541 this set to true. It is always the first one.
542 */
543 bool m_owning_operand{false};
544 /**
545 Result temporary table for the set operation, if applicable
546 */
548 /**
549 Used only when streaming, i.e. for a not materialized result set
550 */
552};
553
554/// Common base class for n-ary set operations, including unary.
556 public:
558
559 /// Get child at given index.
560 Query_term *child(size_t idx) const { return m_children[idx]; }
561 /// Getter for \c m_last_distinct, q.v.
562 int64_t last_distinct() const { return m_last_distinct; }
563 /// Getter for \c m_first_distinct, q.v.
564 int64_t first_distinct() const { return m_first_distinct; }
565 /// Getter for \c m_is_materialized, q.v.
566 bool is_materialized() const { return m_is_materialized; }
567 /// Setter for \c m_is_materialized, q.v.
568 void set_is_materialized(bool mat) { m_is_materialized = mat; }
569 /// Getter for \c m_block, q.v.
570 Query_block *query_block() const override { return m_block; }
571
572 /// Setter for \c m_block, q.v.
574 assert(!m_block);
575 if (b == nullptr) return true;
576
577 m_block = b;
578 return false;
579 }
580
581 void label_children() override {
582 uint idx = 0;
583 for (auto child : m_children) {
584 child->set_sibling_idx(idx++);
586 }
587 }
588
589 size_t child_count() const override { return m_children.size(); }
590 bool open_result_tables(THD *thd, int level) override;
591 void cleanup(bool full) override;
592 void destroy_tree() override {
593 m_parent = nullptr;
594 for (Query_term *child : m_children) {
596 }
597 m_children.clear();
598 }
599 /**
600 Check if this set operation has a mix of DISTINCT and ALL.
601 @return true if so. Always false for unary
602 */
604 /**
605 Check if this term is a unary set operation
606 @return true if so
607 */
608 bool is_unary() const { return term_type() == QT_UNARY; }
609
610 // Recursively set up materialization for a query term tree. For details,
611 // see implementation.
613 THD *thd, TABLE *dst_table, bool union_distinct_only,
614 bool calc_found_rows);
615
617 Change_current_query_block *save_query_block,
618 mem_root_deque<Item *> *insert_field_list,
619 Query_result *common_result, ulonglong added_options,
620 ulonglong removed_options,
621 ulonglong create_option) override;
622
623 bool optimize_query_term(THD *thd, Query_expression *qe) override;
624
627 Mem_root_array<AppendPathParameters> *union_all_subpaths,
628 bool calc_found_rows) override;
629
631 return VisibleFields(*m_types);
632 }
633 size_t visible_column_count() const override { return m_types->size(); }
634
636 return (term_type() == QT_EXCEPT || term_type() == QT_INTERSECT) &&
637 m_children[0] != qt;
638 }
639
640 protected: // this node type is abstract
642
643 /**
644 Common printing minion for set operations.
645 @param level level in tree
646 @param buf the buffer to format output into
647 @param type descriptive string of set operation to use for printing
648 */
649 void print(int level, std::ostringstream &buf, const char *type) const;
650
651 /// On top level, check that it was possible to aggregate all collations
652 /// together for set operation. We need this in case of setop DISTINCT, to
653 /// detect duplicates using the proper collation.
654 ///
655 /// TODO: consider removing this test in case of UNION ALL.
656 bool check_joined_types();
657
658 /// Tree structure. Cardinality is one for unary, two or more for UNION,
659 /// EXCEPT, INTERSECT
661
662 /**
663 true if the result of this set operation is materialized. A priori true
664 unless we have a pure UNION ALL.
665 */
667
668 /**
669 Index of last query expression which has <set-op> DISTINCT on its left. In
670 a list of <set-op>ed blocks, UNION is left-associative; so UNION DISTINCT
671 eliminates duplicates in all blocks up to the first one on its right
672 included. Which is why we only need to remember that query block. Is -1
673 for Unary.
674 */
675 int64_t m_last_distinct{0};
676 /**
677 Presently only needed by EXCEPT set operator: the index of the first
678 DISTINCT set operand: minimum legal value is 1. If not DISTINCT, it should
679 have the value \c std::numeric_limits<int64_t>::max(). The value is set
680 in \c PT_set_operation::merge_descendants.
681 */
683
684 private:
685 /// Query block for post processing result set with ORDER BY, LIMIT for unary
686 /// and binary set operations
688
689 /**
690 List of aggregated type holder items for the set operation query term.
691 Contains only information for the visible expressions of the set operation.
692 */
694
695 // Need access to m_children:
696 template <Visit_order visit_order, Visit_leaves visit_leaves>
697 friend class Query_terms; // fast iterator
698 friend class Query_term;
699 friend class PT_set_operation; // building term tree
700};
701
702/// Node type for n-ary UNION
704 public:
705 /**
706 Constructor.
707 @param mem_root the mem_root to use for allocation
708 */
710 Query_term_type term_type() const override { return QT_UNION; }
711 const char *operator_string() const override { return "union"; }
712 void debugPrint(int level, std::ostringstream &buf) const override;
713};
714
715/// Node type for n-ary INTERSECT
717 public:
718 /**
719 Constructor.
720 @param mem_root the mem_root to use for allocation
721 */
723 Query_term_type term_type() const override { return QT_INTERSECT; }
724 const char *operator_string() const override { return "intersect"; }
725 void debugPrint(int level, std::ostringstream &buf) const override;
726};
727
728/// Node type for n-ary EXCEPT
730 public:
731 /**
732 Constructor.
733 @param mem_root the mem_root to use for allocation
734 */
736 Query_term_type term_type() const override { return QT_EXCEPT; }
737 const char *operator_string() const override { return "except"; }
738 void debugPrint(int level, std::ostringstream &buf) const override;
739};
740
741/// A <query primary> which is a parenthesized query expression (aka qe) body
742/// with order by clause and/or limit/offset clause and the qe body
743/// is not a binary set operation (union, except, intersect), but is viewed here
744/// as a degenerate set operation; i.e. a "unary".
745/// \verbatim
746/// Example: (SELECT * FROM .. ORDER BY .. LIMIT n) ORDER BY .. LIMIT m
747/// Tree:
748/// Query_expression
749/// | m_query_term
750/// Query_term_unary
751/// +--------------------+
752/// | m_block ------+----> Query_block which holds outer
753/// | : | ORDER BY and LIMIT
754/// | m_children[0] |
755/// +--------|-----------+
756/// V
757/// Query_block holds inner SELECT and its ORDER BY/LIMIT
758/// \endverbatim
759/// One extra Query_term_unary is added for each level of nesting
760/// with the top one representing the outermost ORDER BY/LIMIT/OFFSET
761///
763 public:
764 /**
765 Constructor.
766 @param mem_root the mem_root to use for allocation
767 @param t the child term
768 */
771 m_last_distinct = 0;
772 m_children.push_back(t);
773 t->set_sibling_idx(0);
774 }
775 Query_term_type term_type() const override { return QT_UNARY; }
776 const char *operator_string() const override { return "result"; }
777 void debugPrint(int level, std::ostringstream &buf) const override;
779 Change_current_query_block *save_query_block,
780 mem_root_deque<Item *> *insert_field_list,
781 Query_result *common_result, ulonglong added_options,
782 ulonglong removed_options,
783 ulonglong create_options) override;
786 Mem_root_array<AppendPathParameters> *union_all_subpaths,
787 bool calc_found_rows) override;
788
790 return m_children[0]->types_array();
791 }
792 size_t visible_column_count() const override {
793 return m_children[0]->visible_column_count();
794 }
796 return m_children[0]->types_iterator();
797 }
798};
799
800/**
801 Containing class for iterator over the query term tree. The structure is
802 in part dictated by C++ conventions for iterators.
803 @tparam visit_order indicates whether pre or post order visiting is requested
804 @tparam visit_leaves indicates whether to visit the leaf nodes (query blocks)
805*/
806template <Visit_order visit_order, Visit_leaves visit_leaves>
808 private:
809 /**
810 The iterator class itself is private. Only used directly by begin and end
811 */
813 public:
814 /**
815 Construct an iterator over the query term tree rooted in root, optionally
816 skipping the leaves. Skipping is useful for those cases where the leaves
817 are visited separately[1] and we only want to visit the set operation
818 nodes in the tree.
819 [1] By walking the Query_expression::first_query_block and
820 Query_block::next_query_block chain
821 @param root the node to start iteration from
822 */
824 : m_current(root), m_child_idx(0) {
825 if (root == nullptr) return;
826 if constexpr (visit_order == QTC_POST_ORDER) {
827 // start at left-most leaf node
829 if constexpr (visit_leaves == VL_SKIP_LEAVES) operator++();
830 }
831 }
832
834
836 assert(m_current != nullptr);
837 while (m_current != nullptr) {
838 uint children = m_current->child_count();
839 if constexpr (visit_order == QTC_PRE_ORDER) {
840 while (m_current != nullptr && m_child_idx >= children) {
841 // no more at this level, go back up
843 if (m_current != nullptr) {
844 children = m_current->child_count();
845 }
846 }
847
848 if (m_current == nullptr) return *this;
849 m_current = down_cast<Query_term_set_op *>(m_current)
850 ->m_children[m_child_idx];
851 m_child_idx = 0;
852 } else {
854 if (m_current == nullptr) return *this;
855 if (m_child_idx < m_current->child_count()) {
857 } else {
858 // return non-leaf
859 }
860 }
861 if constexpr (visit_leaves == VL_VISIT_LEAVES)
862 break;
863 else if (m_current->term_type() != QT_QUERY_BLOCK)
864 break;
865 }
866 return *this;
867 }
868
870
871 bool operator==(const Query_term_iterator &other) const {
872 return m_current == other.m_current;
873 }
874
875 bool operator!=(const Query_term_iterator &other) const {
876 return !((*this) == other);
877 }
878
879 private:
880 /// Iterator state consists of the next two member variables
882
883 /// Used to find next child node to dive into, see \c set_next_child_idx
884 uint m_child_idx{0};
885
886 /// Starting at \c m_current->m_children[m_child_index], dive down through
887 /// any left-most (index == 0) further children till we find left-most leaf
888 /// term (a \c Query_block) under the child pointed to by
889 /// \c m_child_index. After the dive, \c m_child_index will be zero, and
890 /// \c m_current will be set to the leaf term.
892 while (m_current != nullptr && m_current->term_type() != QT_QUERY_BLOCK) {
893 m_current =
894 down_cast<Query_term_set_op *>(m_current)->m_children[m_child_idx];
895 m_child_idx = 0;
896 }
897 }
898
899 /// Find the index of the next sibling, if any, of \c m_current qua child
900 /// of its parent, so we can visit it: assign it to \c m_child_idx.
901 /// Setting \c m_child_idx to a value of \c Query_term::child_count means we
902 /// signal that we are done. Also, \c m_current is set to its parent.
904 assert(m_current != nullptr);
905 if (m_current->parent() == nullptr) {
907 return;
908 }
910 m_current);
912
914 }
915 };
916
917 public:
918 /// Construct an iterator starting at root.
919 Query_terms(Query_term *root) : m_root(root) {}
920
923
924 private:
926};
927
928/* Local Variables: */
929/* mode: c++ */
930/* fill-column: 80 */
931/* End: */
932
933#endif /* QUERY_NODE_INCLUDED */
RAII class to automate saving/restoring of current_query_block()
Definition: sql_lex.h:5058
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:426
Definition: parse_tree_nodes.h:1793
This class represents a query block, aka a query specification, which is a query consisting of a SELE...
Definition: sql_lex.h:1159
This class represents a query expression (one query block or several query blocks combined with UNION...
Definition: sql_lex.h:627
Definition: sql_union.h:40
Definition: query_result.h:58
Node type for n-ary EXCEPT.
Definition: query_term.h:729
const char * operator_string() const override
Get the node type description.
Definition: query_term.h:737
Query_term_type term_type() const override
Get the node tree type.
Definition: query_term.h:736
void debugPrint(int level, std::ostringstream &buf) const override
Print the tree rooted at this node to buf.
Definition: query_term.cc:756
Query_term_except(MEM_ROOT *mem_root)
Constructor.
Definition: query_term.h:735
Node type for n-ary INTERSECT.
Definition: query_term.h:716
const char * operator_string() const override
Get the node type description.
Definition: query_term.h:724
void debugPrint(int level, std::ostringstream &buf) const override
Print the tree rooted at this node to buf.
Definition: query_term.cc:751
Query_term_intersect(MEM_ROOT *mem_root)
Constructor.
Definition: query_term.h:722
Query_term_type term_type() const override
Get the node tree type.
Definition: query_term.h:723
Common base class for n-ary set operations, including unary.
Definition: query_term.h:555
int64_t m_last_distinct
Index of last query expression which has <set-op> DISTINCT on its left.
Definition: query_term.h:675
mem_root_deque< Item * > * m_types
List of aggregated type holder items for the set operation query term.
Definition: query_term.h:693
bool in_right_side_in_except_or_intersect(Query_term *qt)
Definition: query_term.h:635
Query_term * child(size_t idx) const
Get child at given index.
Definition: query_term.h:560
mem_root_deque< Query_term * > m_children
Tree structure.
Definition: query_term.h:660
void destroy_tree() override
Destroy the query term tree structure.
Definition: query_term.h:592
bool check_joined_types()
On top level, check that it was possible to aggregate all collations together for set operation.
Definition: query_term.cc:382
bool is_materialized() const
Getter for m_is_materialized, q.v.
Definition: query_term.h:566
void cleanup(bool full) override
Reset resources used.
Definition: query_term.cc:426
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 wi...
Definition: query_term.cc:431
int64_t first_distinct() const
Getter for m_first_distinct, q.v.
Definition: query_term.h:564
size_t visible_column_count() const override
Return the number of visible columns of the query term.
Definition: query_term.h:633
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:682
void print(int level, std::ostringstream &buf, const char *type) const
Common printing minion for set operations.
Definition: query_term.cc:395
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:726
bool has_mixed_distinct_operators()
Check if this set operation has a mix of DISTINCT and ALL.
Definition: query_term.cc:377
bool set_block(Query_block *b)
Setter for m_block, q.v.
Definition: query_term.h:573
Query_term_set_op(MEM_ROOT *mem_root)
Definition: query_term.h:641
bool is_unary() const
Check if this term is a unary set operation.
Definition: query_term.h:608
Query_block * query_block() const override
Getter for m_block, q.v.
Definition: query_term.h:570
VisibleFieldsIterator types_iterator() override
Abstract over visible column types: if query block, we offer an iterator over visible fields,...
Definition: query_term.h:630
mem_root_deque< Item * > * types_array() override
Definition: query_term.h:557
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:412
void set_is_materialized(bool mat)
Setter for m_is_materialized, q.v.
Definition: query_term.h:568
bool optimize_query_term(THD *thd, Query_expression *qe) override
Optimize the non-leaf query blocks.
Definition: query_term.cc:663
bool m_is_materialized
true if the result of this set operation is materialized.
Definition: query_term.h:666
size_t child_count() const override
Get the number of children this node has.
Definition: query_term.h:589
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...
Definition: query_term.cc:680
int64_t last_distinct() const
Getter for m_last_distinct, q.v.
Definition: query_term.h:562
Query_block * m_block
Query block for post processing result set with ORDER BY, LIMIT for unary and binary set operations.
Definition: query_term.h:687
void label_children() override
Set the correct value of Query_term::m_sibling_idx recursively for set operations.
Definition: query_term.h:581
A <query primary> which is a parenthesized query expression (aka qe) body with order by clause and/or...
Definition: query_term.h:762
mem_root_deque< Item * > * types_array() override
Definition: query_term.h:789
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...
Definition: query_term.cc:346
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_options) override
a) Prepare query blocks, both leaf blocks and blocks reresenting order by/limit in query primaries wi...
Definition: query_term.cc:262
Query_term_unary(MEM_ROOT *mem_root, Query_term *t)
Constructor.
Definition: query_term.h:769
VisibleFieldsIterator types_iterator() override
Abstract over visible column types: if query block, we offer an iterator over visible fields,...
Definition: query_term.h:795
void debugPrint(int level, std::ostringstream &buf) const override
Print the tree rooted at this node to buf.
Definition: query_term.cc:364
const char * operator_string() const override
Get the node type description.
Definition: query_term.h:776
size_t visible_column_count() const override
Return the number of visible columns of the query term.
Definition: query_term.h:792
Query_term_type term_type() const override
Get the node tree type.
Definition: query_term.h:775
Node type for n-ary UNION.
Definition: query_term.h:703
void debugPrint(int level, std::ostringstream &buf) const override
Print the tree rooted at this node to buf.
Definition: query_term.cc:747
const char * operator_string() const override
Get the node type description.
Definition: query_term.h:711
Query_term_union(MEM_ROOT *mem_root)
Constructor.
Definition: query_term.h:709
Query_term_type term_type() const override
Get the node tree type.
Definition: query_term.h:710
Query term tree structure.
Definition: query_term.h:216
Query_term * pushdown_limit_order_by(Query_term_set_op *parent=nullptr)
Called after contextualization to simplify query, c.f.
Definition: query_term.cc:94
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:427
void cleanup_query_result(bool full)
Cleanup m_setop_query_result, q.v.
Definition: query_term.cc:241
Query_term_set_op * m_parent
Back pointer to the node whose child we are, or nullptr (root term).
Definition: query_term.h:527
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:446
virtual AccessPath * make_set_op_access_path(THD *thd, Query_term_set_op *parent, Mem_root_array< AppendPathParameters > *union_all_subpaths, bool calc_found_rows)=0
Recursively constructs the access path of the set operation, possibly materializing in a tmp table if...
virtual size_t visible_column_count() const =0
Return the number of visible columns of the query term.
Query_result * m_setop_query_result
The query result for this term.
Definition: query_term.h:538
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:502
void set_setop_query_result(Query_result *rs)
Setter for m_setop_query_result, q.v.
Definition: query_term.h:498
Query_result * setop_query_result()
Getter for m_setop_query_result, q.v.
Definition: query_term.h:500
void set_fields(mem_root_deque< Item * > *fields)
Definition: query_term.h:519
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:425
Table_ref & result_table()
Getter for m_result_table, q.v.
Definition: query_term.h:516
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:511
virtual bool optimize_query_term(THD *thd, Query_expression *qe)=0
Optimize the non-leaf query blocks.
mem_root_deque< Item * > * fields()
Definition: query_term.h:521
void set_owning_operand()
Setter for m_owning_operand, q.v.
Definition: query_term.h:509
Query_term_set_op * parent() const
Getter for m_parent, q.v.
Definition: query_term.h:423
void set_result_table(Table_ref *tl)
Setter for m_result_table, q.v.
Definition: query_term.h:514
virtual void cleanup(bool full)
Reset resources used.
Definition: query_term.h:433
bool create_tmp_table(THD *thd, ulonglong create_options)
Create a temporary table for a set operation.
Definition: query_term.cc:198
virtual mem_root_deque< Item * > * types_array()=0
virtual size_t child_count() const
Get the number of children this node has.
Definition: query_term.h:268
virtual ~Query_term()=default
Node destructor.
virtual 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_options)=0
a) Prepare query blocks, both leaf blocks and blocks reresenting order by/limit in query primaries wi...
uint m_sibling_idx
If parent is non-null, this holds the index of the current sibling.
Definition: query_term.h:531
Table_ref * m_result_table
Result temporary table for the set operation, if applicable.
Definition: query_term.h:547
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:63
bool validate_structure(const Query_term *parent, int depth=0) const
Return true if structure is too deep, i.e.
Definition: query_term.cc:182
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:543
virtual VisibleFieldsIterator types_iterator()=0
Abstract over visible column types: if query block, we offer an iterator over visible fields,...
void printPointers(std::ostringstream &buf) const
Print the pointer of this node and its parent to buf.
Definition: query_term.cc:256
static void indent(int level, std::ostringstream &buf)
Print blank space indentation (unit: two) to buf according to level.
Definition: query_term.cc:252
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:53
mem_root_deque< Item * > * m_fields
Used only when streaming, i.e.
Definition: query_term.h:551
The iterator class itself is private.
Definition: query_term.h:812
bool operator!=(const Query_term_iterator &other) const
Definition: query_term.h:875
Query_term_iterator & operator++()
Definition: query_term.h:835
bool operator==(const Query_term_iterator &other) const
Definition: query_term.h:871
Query_term * m_current
Iterator state consists of the next two member variables.
Definition: query_term.h:881
uint m_child_idx
Used to find next child node to dive into, see set_next_child_idx.
Definition: query_term.h:884
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:903
Query_term * operator*()
Definition: query_term.h:869
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:823
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:891
Containing class for iterator over the query term tree.
Definition: query_term.h:807
Query_term_iterator end()
Definition: query_term.h:922
Query_terms(Query_term *root)
Construct an iterator starting at root.
Definition: query_term.h:919
Query_term * m_root
Definition: query_term.h:925
Query_term_iterator begin()
Definition: query_term.h:921
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:2900
Definition: visible_fields.h:98
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
Some integer typedefs for easier portability.
unsigned long long int ulonglong
Definition: my_inttypes.h:56
This file defines the client API to MySQL and also the ABI of the dynamically linked libmysqlclient.
static bool create_options
Definition: mysqldump.cc:126
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1105
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:2872
Query_term_type
This class hierarchy is used to represent SQL structures between <query expression> and <query specif...
Definition: query_term.h:96
@ QT_UNARY
Represents a query primary with parentesized query expression body with order by clause and/or limit/...
Definition: query_term.h:103
@ QT_EXCEPT
Definition: query_term.h:107
@ QT_UNION
Definition: query_term.h:108
@ QT_INTERSECT
Represents the three set operations.
Definition: query_term.h:106
@ QT_QUERY_BLOCK
Represents Query specification, table value constructor and explicit table.
Definition: query_term.h:99
Visit_leaves
Query term iterator template argument type: whether to visit leaf nodes.
Definition: query_term.h:114
@ VL_SKIP_LEAVES
Definition: query_term.h:114
@ VL_VISIT_LEAVES
Definition: query_term.h:114
Visit_order
Query term iterator template argument type: how to visit nodes in tree.
Definition: query_term.h:112
@ QTC_PRE_ORDER
Definition: query_term.h:112
@ QTC_POST_ORDER
Definition: query_term.h:112
required string type
Definition: replication_group_member_actions.proto:34
Access paths are a query planning structure that correspond 1:1 to iterators, in that an access path ...
Definition: access_path.h:227
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:83
Definition: table.h:289
Definition: table.h:1421
An adapter class to support iteration over an iterator of Item * (typically mem_root_deque<Item *>),...
VisibleFieldsIterator VisibleFields(mem_root_deque< Item * > &fields)
Definition: visible_fields.h:119