MySQL 9.1.0
Source Code Documentation
access_path.h
Go to the documentation of this file.
1/* Copyright (c) 2020, 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
24#ifndef SQL_JOIN_OPTIMIZER_ACCESS_PATH_H
25#define SQL_JOIN_OPTIMIZER_ACCESS_PATH_H
26
27#include <assert.h>
28#include <stdint.h>
29#include <cmath>
30#include <cstddef>
31#include <type_traits>
32#include <utility>
33#include <vector>
34
35#include "my_alloc.h"
36#include "my_base.h"
37#include "my_table_map.h"
38#include "sql/item.h"
39// IWYU suggests removing row_iterator.h, but then the inlined short form of
40// CreateIteratorFromAccessPath() fails to compile. So use a pragma to keep it.
41#include "sql/iterators/row_iterator.h" // IWYU pragma: keep
46#include "sql/join_type.h"
47#include "sql/mem_root_array.h"
48#include "sql/olap.h"
49#include "sql/sql_class.h"
50#include "sql/table.h"
51
53class Filesort;
55class Item_func_match;
56class JOIN;
57class KEY;
59class QEP_TAB;
60class QUICK_RANGE;
61class SJ_TMP_TABLE;
62class Table_function;
64class Window;
65struct AccessPath;
68struct Index_lookup;
69struct KEY_PART;
70struct POSITION;
72
73/**
74 A specification that two specific relational expressions
75 (e.g., two tables, or a table and a join between two other tables)
76 should be joined together. The actual join conditions, if any,
77 live inside the “expr” object, as does the join type etc.
78 */
82
83 // If this join is made using a hash join, estimates the width
84 // of each row as stored in the hash table, in bytes.
86
87 // The set of (additional) functional dependencies that are active
88 // after this join predicate has been applied. E.g. if we're joining
89 // on t1.x = t2.x, there will be a bit for that functional dependency.
90 // We don't currently support more complex join conditions, but there's
91 // no conceptual reason why we couldn't, e.g. a join on a = b + c
92 // could give rise to the FD {b, c} → a and possibly even {a, b} → c
93 // or {a, c} → b.
94 //
95 // Used in the processing of interesting orders.
97
98 // A less compact form of functional_dependencies, used during building
99 // (FunctionalDependencySet bitmaps are only available after all functional
100 // indexes have been collected and Build() has been called).
102
103 // A semijoin on the following format:
104 //
105 // SELECT ... FROM t1 WHERE EXISTS
106 // (SELECT ... FROM t2 WHERE t1.f1=t2.f2 AND t1.f3=t2.f4 ... t1.fn=t2.fm)
107 //
108 // may be transformed into an equivalent inner join:
109 //
110 // SELECT ... FROM (SELECT DISTINCT f2, f4...fm FROM t2) d JOIN t1
111 // ON t1.f1=d.f2 AND t1.f3=d.f4 ... t1.fn=d.fm
112 //
113 // If this is a suitable semijoin: This field will identify the the
114 // grouping given by (f2, f4..fm). (@see
115 // LogicalOrderings::RemapOrderingIndex() for a description of how this
116 // value can be mapped to an actual ordering). The join
117 // optimizer will then consider deduplicating on it and applying the
118 // above transform. If no such grouping was found, this field will be -1.
120
121 // Same as ordering_idx_needed_for_semijoin_rewrite, but given to the
122 // RemoveDuplicatesIterator for doing the actual grouping. Allocated
123 // on the MEM_ROOT. Can be empty, in which case a LIMIT 1 would do.
124 Item **semijoin_group = nullptr;
126};
127
128/**
129 A filter of some sort that is not a join condition (those are stored
130 in JoinPredicate objects). AND conditions are typically split up into
131 multiple Predicates.
132 */
133struct Predicate {
135
136 // condition->used_tables(), converted to a NodeMap.
138
139 // tables referred to by the condition, plus any tables whose values
140 // can null any of those tables. (Even when reordering outer joins,
141 // at least one of those tables will still be present on the
142 // left-hand side of the outer join, so this is sufficient.)
143 //
144 // As a special case, we allow setting RAND_TABLE_BIT, even though it
145 // is normally part of a table_map, not a NodeMap.
147
149
150 // Whether this predicate is a join condition after all; it was promoted
151 // to a WHERE predicate since it was part of a cycle (see the comment in
152 // AddCycleEdges()). If it is, it is usually ignored so that we don't
153 // double-apply join conditions -- but if the join in question was not
154 // applied (because the cycle was broken at this point), the predicate
155 // would come into play. This is normally registered on the join itself
156 // (see RelationalExpression::join_predicate_bitmap), but having the bit
157 // on the predicate itself is used to avoid trying to push it down as a
158 // sargable predicate.
159 bool was_join_condition = false;
160
161 // If this is a join condition that came from a multiple equality,
162 // and we have decided to create a mesh from that multiple equality,
163 // returns the index of it into the “multiple_equalities” array
164 // in MakeJoinHypergraph(). (You don't actually need the array to
165 // use this; it's just an opaque index to deduplicate between different
166 // predicates.) Otherwise, -1.
168
169 // See the equivalent fields in JoinPredicate.
172
173 // The list of all subqueries referred to in this predicate, if any.
174 // The optimizer uses this to add their materialized/non-materialized
175 // costs when evaluating filters.
177};
178
182};
183
184/// To indicate that a row estimate is not yet made.
185inline constexpr double kUnknownRowCount = -1.0;
186
187/// To indicate that a cost estimate is not yet made. We use a large negative
188/// value to avoid getting a positive result if we by mistake add this to
189/// a real (positive) cost.
190inline constexpr double kUnknownCost = -1e12;
191
192/// Calculate the cost of reading the first row from an access path, given
193/// estimates for init cost, total cost and the number of rows returned.
194inline double FirstRowCost(double init_cost, double total_cost,
195 double output_rows) {
196 assert(init_cost >= 0.0);
197 assert(total_cost >= init_cost);
198 assert(output_rows >= 0.0);
199 if (output_rows <= 1.0) {
200 return total_cost;
201 }
202 return init_cost + (total_cost - init_cost) / output_rows;
203}
204
205/**
206 Access paths are a query planning structure that correspond 1:1 to iterators,
207 in that an access path contains pretty much exactly the information
208 needed to instantiate given iterator, plus some information that is only
209 needed during planning, such as costs. (The new join optimizer will extend
210 this somewhat in the future. Some iterators also need the query block,
211 ie., JOIN object, they are part of, but that is implicitly available when
212 constructing the tree.)
213
214 AccessPath objects build on a variant, ie., they can hold an access path of
215 any type (table scan, filter, hash join, sort, etc.), although only one at the
216 same time. Currently, they contain 32 bytes of base information that is common
217 to any access path (type identifier, costs, etc.), and then up to 40 bytes
218 that is type-specific (e.g. for a table scan, the TABLE object). It would be
219 nice if we could squeeze it down to 64 and fit a cache line exactly, but it
220 does not seem to be easy without fairly large contortions.
221
222 We could have solved this by inheritance, but the fixed-size design makes it
223 possible to replace an access path when a better one is found, without
224 introducing a new allocation, which will be important when using them as a
225 planning structure.
226 */
228 enum Type : uint8_t {
229 // Basic access paths (those with no children, at least nominally).
230 // NOTE: When adding more paths to this section, also update GetBasicTable()
231 // to handle them.
251
252 // Basic access paths that don't correspond to a specific table.
259
260 // Joins.
265
266 // Composite access paths.
282
283 // Access paths that modify tables.
287
288 /// A general enum to describe the safety of a given operation.
289 /// Currently we only use this to describe row IDs, but it can easily
290 /// be reused for safety of updating a table we're reading from
291 /// (the Halloween problem), or just generally unreproducible results
292 /// (e.g. a TABLESAMPLE changing due to external factors).
293 ///
294 /// Less safe values have higher numerical values.
295 enum Safety : uint8_t {
296 /// The given operation is always safe on this access path.
297 SAFE = 0,
298
299 /// The given operation is safe if this access path is scanned once,
300 /// but not if it's scanned multiple times (e.g. used on the inner side
301 /// of a nested-loop join). A typical example of this is a derived table
302 /// or CTE that is rematerialized on each scan, so that references to
303 /// the old values (such as row IDs) are no longer valid.
305
306 /// The given operation is unsafe on this access path, no matter how many
307 /// or few times it's scanned. Often, it may help to materialize it
308 /// (assuming the materialization itself doesn't use the operation
309 /// in question).
310 UNSAFE = 2
311 };
312
313 /// Whether it is safe to get row IDs (for sorting) from this access path.
315
316 /// Whether this access path counts as one that scans a base table,
317 /// and thus should be counted towards examined_rows. It can sometimes
318 /// seem a bit arbitrary which iterators count towards examined_rows
319 /// and which ones do not, so the only canonical reference is the tests.
320 bool count_examined_rows : 1 {false};
321
322 /// Whether this access path contains a GROUP_INDEX_SKIP_SCAN
323 bool has_group_skip_scan : 1 {false};
324
325#ifndef NDEBUG
326 /// Whether this access path is forced preferred over all others by means
327 /// of a SET DEBUG force_subplan_0x... statement.
328 bool forced_by_dbug : 1 {false};
329#endif
330
331 /// For UPDATE and DELETE statements: The node index of a table which can be
332 /// updated or deleted from immediately as the rows are read from the
333 /// iterator, if this path is only read from once. -1 if there is no such
334 /// table in this path.
335 ///
336 /// Note that this is an index into CostingReceiver's array of nodes, and is
337 /// not necessarily equal to the table number within the query block given by
338 /// Table_ref::tableno().
339 ///
340 /// The table, if any, is currently always the outermost table in the path.
341 ///
342 /// It is possible to have plans where it would be safe to operate
343 /// "immediately" on more than one table. For example, if we do a merge join,
344 /// it is safe to perform immediate deletes on tables on the inner side of the
345 /// join, since both sides are read only once. (However, we currently do not
346 /// support merge joins.)
347 ///
348 /// Another possibility is when the outer table of a nested loop join is
349 /// guaranteed to return at most one row (typically, a unique index lookup
350 /// aka. eq_ref). Then it's safe to delete immediately from both sides of the
351 /// nested loop join. But we don't to this yet.
352 ///
353 /// Hash joins read both sides exactly once, However, with hash joins, the
354 /// scans on the inner tables are not positioned on the correct row when the
355 /// result of the join is returned, so the immediate delete logic will need to
356 /// be changed to reposition the underlying scans before doing the immediate
357 /// deletes. While this can be done, it makes the benefit of immediate deletes
358 /// less obvious for these tables, and it can also be a loss in some cases,
359 /// because we lose the deduplication provided by the Unique object used for
360 /// buffered deletes (the immediate deletes could end up spending time
361 /// repositioning to already deleted rows). So we currently don't attempt to
362 /// do immediate deletes from inner tables of hash joins either.
363 ///
364 /// The outer table of a hash join can be deleted from immediately if the
365 /// inner table fits in memory. If the hash join spills to disk, though,
366 /// neither the rows of the outer table nor the rows of the inner table come
367 /// out in the order of the underlying scan, so it is not safe in general to
368 /// perform immediate deletes on the outer table of a hash join.
369 ///
370 /// If support for immediate operations on multiple tables is added,
371 /// this member could be changed from a node index to a NodeMap.
373
374 /// Which ordering the rows produced by this path follow, if any
375 /// (see interesting_orders.h). This is really a LogicalOrderings::StateIndex,
376 /// but we don't want to add a dependency on interesting_orders.h from
377 /// this file, so we use the base type instead of the typedef here.
379
380 /// If an iterator has been instantiated for this access path, points to the
381 /// iterator. Used for constructing iterators that need to talk to each other
382 /// (e.g. for recursive CTEs, or BKA join), and also for locating timing
383 /// information in EXPLAIN ANALYZE queries.
385
386 double cost() const { return m_cost; }
387
388 double init_cost() const { return m_init_cost; }
389
390 /// The cost of reading the first row.
391 double first_row_cost() const {
393 }
394
395 double init_once_cost() const { return m_init_once_cost; }
396
397 double cost_before_filter() const { return m_cost_before_filter; }
398
399 void set_cost(double val) {
400 assert(std::isfinite(val));
401 assert(val >= 0.0 || val == kUnknownCost);
402 m_cost = val;
403 }
404
405 void set_init_cost(double val) {
406 assert(std::isfinite(val));
407 assert(val >= 0.0 || val == kUnknownCost);
408 m_init_cost = val;
409 }
410
411 void set_init_once_cost(double val) {
412 assert(std::isfinite(val));
413 assert(val >= 0.0);
414 m_init_once_cost = val;
415 }
416
417 void set_cost_before_filter(double val) {
418 assert(std::isfinite(val));
419 assert(val >= 0.0 || val == kUnknownCost);
421 }
422
423 /// Return the cost of scanning the given path for the second time
424 /// (or later) in the given query block. This is really the interesting
425 /// metric, not init_once_cost in itself, but since nearly all paths
426 /// have zero init_once_cost, storing that instead allows us to skip
427 /// a lot of repeated path->init_once_cost = path->init_cost calls
428 /// in the code.
429 double rescan_cost() const { return cost() - init_once_cost(); }
430
431 /// If no filter, identical to num_output_rows.
433
434 /// Bitmap of WHERE predicates that we are including on this access path,
435 /// referring to the “predicates” array internal to the join optimizer.
436 /// Since bit masks are much cheaper to deal with than creating Item
437 /// objects, and we don't invent new conditions during join optimization
438 /// (all of them are known when we begin optimization), we stick to
439 /// manipulating bit masks during optimization, saying which filters will be
440 /// applied at this node (a 1-bit means the filter will be applied here; if
441 /// there are multiple ones, they are ANDed together).
442 ///
443 /// This is used during join optimization only; before iterators are
444 /// created, we will add FILTER access paths to represent these instead,
445 /// removing the dependency on the array. Said FILTER paths are by
446 /// convention created with materialize_subqueries = false, since the by far
447 /// most common case is that there are no subqueries in the predicate.
448 /// In other words, if you wish to represent a filter with
449 /// materialize_subqueries = true, you will need to make an explicit FILTER
450 /// node.
451 ///
452 /// See also nested_loop_join().equijoin_predicates, which is for filters
453 /// being applied _before_ nested-loop joins, but is otherwise the same idea.
455
456 /// Bitmap of sargable join predicates that have already been applied
457 /// in this access path by means of an index lookup (ref access),
458 /// again referring to “predicates”, and thus should not be counted again
459 /// for selectivity. Note that the filter may need to be applied
460 /// nevertheless (especially in case of type conversions); see
461 /// subsumed_sargable_join_predicates.
462 ///
463 /// Since these refer to the same array as filter_predicates, they will
464 /// never overlap with filter_predicates, and so we can reuse the same
465 /// memory using an alias (a union would not be allowed, since OverflowBitset
466 /// is a class with non-trivial default constructor), even though the meaning
467 /// is entirely separate. If N = num_where_predicates in the hypergraph, then
468 /// bits 0..(N-1) belong to filter_predicates, and the rest to
469 /// applied_sargable_join_predicates.
471 return filter_predicates;
472 }
474 return filter_predicates;
475 }
476
477 /// Bitmap of WHERE predicates that touch tables we have joined in,
478 /// but that we could not apply yet (for instance because they reference
479 /// other tables, or because because we could not push them down into
480 /// the nullable side of outer joins). Used during planning only
481 /// (see filter_predicates).
483
484 /// Similar to applied_sargable_join_predicates, bitmap of sargable
485 /// join predicates that have been applied and will subsume the join
486 /// predicate entirely, ie., not only should the selectivity not be
487 /// double-counted, but the predicate itself is redundant and need not
488 /// be applied as a filter. (It is an error to have a bit set here but not
489 /// in applied_sargable_join_predicates.)
491 return delayed_predicates;
492 }
494 return delayed_predicates;
495 }
496
497 /// If nonzero, a bitmap of other tables whose joined-in rows must already be
498 /// loaded when rows from this access path are evaluated; that is, this
499 /// access path must be put on the inner side of a nested-loop join (or
500 /// multiple such joins) where the outer side includes all of the given
501 /// tables.
502 ///
503 /// The most obvious case for this is dependent tables in LATERAL, but a more
504 /// common case is when we have pushed join conditions referring to those
505 /// tables; e.g., if this access path represents t1 and we have a condition
506 /// t1.x=t2.x that is pushed down into an index lookup (ref access), t2 will
507 /// be set in this bitmap. We can still join in other tables, deferring t2,
508 /// but the bit(s) will then propagate, and we cannot be on the right side of
509 /// a hash join until parameter_tables is zero again. (Also see
510 /// DisallowParameterizedJoinPath() for when we disallow such deferring,
511 /// as an optimization.)
512 ///
513 /// As a special case, we allow setting RAND_TABLE_BIT, even though it
514 /// is normally part of a table_map, not a NodeMap. In this case, it specifies
515 /// that the access path is entirely noncachable, because it depends on
516 /// something nondeterministic or an outer reference, and thus can never be on
517 /// the right side of a hash join, ever.
519
520 /// Auxiliary data used by a secondary storage engine while processing the
521 /// access path during optimization and execution. The secondary storage
522 /// engine is free to store any useful information in this member, for example
523 /// extra statistics or cost estimates. The data pointed to is fully owned by
524 /// the secondary storage engine, and it is the responsibility of the
525 /// secondary engine to manage the memory and make sure it is properly
526 /// destroyed.
527 void *secondary_engine_data{nullptr};
528
529 // Accessors for the union below.
530 auto &table_scan() {
531 assert(type == TABLE_SCAN);
532 return u.table_scan;
533 }
534 const auto &table_scan() const {
535 assert(type == TABLE_SCAN);
536 return u.table_scan;
537 }
538 auto &sample_scan() {
539 assert(type == SAMPLE_SCAN);
540 return u.sample_scan;
541 }
542 const auto &sample_scan() const {
543 assert(type == SAMPLE_SCAN);
544 return u.sample_scan;
545 }
546 auto &index_scan() {
547 assert(type == INDEX_SCAN);
548 return u.index_scan;
549 }
550 const auto &index_scan() const {
551 assert(type == INDEX_SCAN);
552 return u.index_scan;
553 }
555 assert(type == INDEX_DISTANCE_SCAN);
556 return u.index_distance_scan;
557 }
558 const auto &index_distance_scan() const {
559 assert(type == INDEX_DISTANCE_SCAN);
560 return u.index_distance_scan;
561 }
562 auto &ref() {
563 assert(type == REF);
564 return u.ref;
565 }
566 const auto &ref() const {
567 assert(type == REF);
568 return u.ref;
569 }
570 auto &ref_or_null() {
571 assert(type == REF_OR_NULL);
572 return u.ref_or_null;
573 }
574 const auto &ref_or_null() const {
575 assert(type == REF_OR_NULL);
576 return u.ref_or_null;
577 }
578 auto &eq_ref() {
579 assert(type == EQ_REF);
580 return u.eq_ref;
581 }
582 const auto &eq_ref() const {
583 assert(type == EQ_REF);
584 return u.eq_ref;
585 }
587 assert(type == PUSHED_JOIN_REF);
588 return u.pushed_join_ref;
589 }
590 const auto &pushed_join_ref() const {
591 assert(type == PUSHED_JOIN_REF);
592 return u.pushed_join_ref;
593 }
595 assert(type == FULL_TEXT_SEARCH);
596 return u.full_text_search;
597 }
598 const auto &full_text_search() const {
599 assert(type == FULL_TEXT_SEARCH);
600 return u.full_text_search;
601 }
602 auto &const_table() {
603 assert(type == CONST_TABLE);
604 return u.const_table;
605 }
606 const auto &const_table() const {
607 assert(type == CONST_TABLE);
608 return u.const_table;
609 }
610 auto &mrr() {
611 assert(type == MRR);
612 return u.mrr;
613 }
614 const auto &mrr() const {
615 assert(type == MRR);
616 return u.mrr;
617 }
618 auto &follow_tail() {
619 assert(type == FOLLOW_TAIL);
620 return u.follow_tail;
621 }
622 const auto &follow_tail() const {
623 assert(type == FOLLOW_TAIL);
624 return u.follow_tail;
625 }
627 assert(type == INDEX_RANGE_SCAN);
628 return u.index_range_scan;
629 }
630 const auto &index_range_scan() const {
631 assert(type == INDEX_RANGE_SCAN);
632 return u.index_range_scan;
633 }
634 auto &index_merge() {
635 assert(type == INDEX_MERGE);
636 return u.index_merge;
637 }
638 const auto &index_merge() const {
639 assert(type == INDEX_MERGE);
640 return u.index_merge;
641 }
643 assert(type == ROWID_INTERSECTION);
644 return u.rowid_intersection;
645 }
646 const auto &rowid_intersection() const {
647 assert(type == ROWID_INTERSECTION);
648 return u.rowid_intersection;
649 }
650 auto &rowid_union() {
651 assert(type == ROWID_UNION);
652 return u.rowid_union;
653 }
654 const auto &rowid_union() const {
655 assert(type == ROWID_UNION);
656 return u.rowid_union;
657 }
659 assert(type == INDEX_SKIP_SCAN);
660 return u.index_skip_scan;
661 }
662 const auto &index_skip_scan() const {
663 assert(type == INDEX_SKIP_SCAN);
664 return u.index_skip_scan;
665 }
667 assert(type == GROUP_INDEX_SKIP_SCAN);
668 return u.group_index_skip_scan;
669 }
670 const auto &group_index_skip_scan() const {
671 assert(type == GROUP_INDEX_SKIP_SCAN);
672 return u.group_index_skip_scan;
673 }
676 return u.dynamic_index_range_scan;
677 }
678 const auto &dynamic_index_range_scan() const {
680 return u.dynamic_index_range_scan;
681 }
684 return u.materialized_table_function;
685 }
686 const auto &materialized_table_function() const {
688 return u.materialized_table_function;
689 }
691 assert(type == UNQUALIFIED_COUNT);
692 return u.unqualified_count;
693 }
694 const auto &unqualified_count() const {
695 assert(type == UNQUALIFIED_COUNT);
696 return u.unqualified_count;
697 }
699 assert(type == TABLE_VALUE_CONSTRUCTOR);
700 return u.table_value_constructor;
701 }
702 const auto &table_value_constructor() const {
703 assert(type == TABLE_VALUE_CONSTRUCTOR);
704 return u.table_value_constructor;
705 }
707 assert(type == FAKE_SINGLE_ROW);
708 return u.fake_single_row;
709 }
710 const auto &fake_single_row() const {
711 assert(type == FAKE_SINGLE_ROW);
712 return u.fake_single_row;
713 }
714 auto &zero_rows() {
715 assert(type == ZERO_ROWS);
716 return u.zero_rows;
717 }
718 const auto &zero_rows() const {
719 assert(type == ZERO_ROWS);
720 return u.zero_rows;
721 }
723 assert(type == ZERO_ROWS_AGGREGATED);
724 return u.zero_rows_aggregated;
725 }
726 const auto &zero_rows_aggregated() const {
727 assert(type == ZERO_ROWS_AGGREGATED);
728 return u.zero_rows_aggregated;
729 }
730 auto &hash_join() {
731 assert(type == HASH_JOIN);
732 return u.hash_join;
733 }
734 const auto &hash_join() const {
735 assert(type == HASH_JOIN);
736 return u.hash_join;
737 }
738 auto &bka_join() {
739 assert(type == BKA_JOIN);
740 return u.bka_join;
741 }
742 const auto &bka_join() const {
743 assert(type == BKA_JOIN);
744 return u.bka_join;
745 }
747 assert(type == NESTED_LOOP_JOIN);
748 return u.nested_loop_join;
749 }
750 const auto &nested_loop_join() const {
751 assert(type == NESTED_LOOP_JOIN);
752 return u.nested_loop_join;
753 }
756 return u.nested_loop_semijoin_with_duplicate_removal;
757 }
760 return u.nested_loop_semijoin_with_duplicate_removal;
761 }
762 auto &filter() {
763 assert(type == FILTER);
764 return u.filter;
765 }
766 const auto &filter() const {
767 assert(type == FILTER);
768 return u.filter;
769 }
770 auto &sort() {
771 assert(type == SORT);
772 return u.sort;
773 }
774 const auto &sort() const {
775 assert(type == SORT);
776 return u.sort;
777 }
778 auto &aggregate() {
779 assert(type == AGGREGATE);
780 return u.aggregate;
781 }
782 const auto &aggregate() const {
783 assert(type == AGGREGATE);
784 return u.aggregate;
785 }
787 assert(type == TEMPTABLE_AGGREGATE);
788 return u.temptable_aggregate;
789 }
790 const auto &temptable_aggregate() const {
791 assert(type == TEMPTABLE_AGGREGATE);
792 return u.temptable_aggregate;
793 }
794 auto &limit_offset() {
795 assert(type == LIMIT_OFFSET);
796 return u.limit_offset;
797 }
798 const auto &limit_offset() const {
799 assert(type == LIMIT_OFFSET);
800 return u.limit_offset;
801 }
802 auto &stream() {
803 assert(type == STREAM);
804 return u.stream;
805 }
806 const auto &stream() const {
807 assert(type == STREAM);
808 return u.stream;
809 }
810 auto &materialize() {
811 assert(type == MATERIALIZE);
812 return u.materialize;
813 }
814 const auto &materialize() const {
815 assert(type == MATERIALIZE);
816 return u.materialize;
817 }
820 return u.materialize_information_schema_table;
821 }
824 return u.materialize_information_schema_table;
825 }
826 auto &append() {
827 assert(type == APPEND);
828 return u.append;
829 }
830 const auto &append() const {
831 assert(type == APPEND);
832 return u.append;
833 }
834 auto &window() {
835 assert(type == WINDOW);
836 return u.window;
837 }
838 const auto &window() const {
839 assert(type == WINDOW);
840 return u.window;
841 }
842 auto &weedout() {
843 assert(type == WEEDOUT);
844 return u.weedout;
845 }
846 const auto &weedout() const {
847 assert(type == WEEDOUT);
848 return u.weedout;
849 }
851 assert(type == REMOVE_DUPLICATES);
852 return u.remove_duplicates;
853 }
854 const auto &remove_duplicates() const {
855 assert(type == REMOVE_DUPLICATES);
856 return u.remove_duplicates;
857 }
860 return u.remove_duplicates_on_index;
861 }
862 const auto &remove_duplicates_on_index() const {
864 return u.remove_duplicates_on_index;
865 }
866 auto &alternative() {
867 assert(type == ALTERNATIVE);
868 return u.alternative;
869 }
870 const auto &alternative() const {
871 assert(type == ALTERNATIVE);
872 return u.alternative;
873 }
875 assert(type == CACHE_INVALIDATOR);
876 return u.cache_invalidator;
877 }
878 const auto &cache_invalidator() const {
879 assert(type == CACHE_INVALIDATOR);
880 return u.cache_invalidator;
881 }
882 auto &delete_rows() {
883 assert(type == DELETE_ROWS);
884 return u.delete_rows;
885 }
886 const auto &delete_rows() const {
887 assert(type == DELETE_ROWS);
888 return u.delete_rows;
889 }
890 auto &update_rows() {
891 assert(type == UPDATE_ROWS);
892 return u.update_rows;
893 }
894 const auto &update_rows() const {
895 assert(type == UPDATE_ROWS);
896 return u.update_rows;
897 }
898
899 double num_output_rows() const { return m_num_output_rows; }
900
901 void set_num_output_rows(double val) {
902 assert(std::isfinite(val));
903 assert(val == kUnknownRowCount || val >= 0.0);
904 m_num_output_rows = val;
905 }
906
907 private:
908 /// Expected number of output rows.
910
911 /// Expected cost to read all of this access path once.
913
914 /// Expected cost to initialize this access path; ie., cost to read
915 /// k out of N rows would be init_cost + (k/N) * (cost - init_cost).
916 /// Note that EXPLAIN prints out cost of reading the _first_ row
917 /// because it is easier for the user and also easier to measure in
918 /// EXPLAIN ANALYZE, but it is easier to do calculations with a pure
919 /// initialization cost, so that is what we use in this member.
920 /// kUnknownCost for unknown.
922
923 /// Of init_cost, how much of the initialization needs only to be done
924 /// once per query block. (This is a cost, not a proportion.)
925 /// Ie., if the access path can reuse some its initialization work
926 /// if Init() is called multiple times, this member will be nonzero.
927 /// A typical example is a materialized table with rematerialize=false;
928 /// the second time Init() is called, it's a no-op. Most paths will have
929 /// init_once_cost = 0.0, ie., repeated scans will cost the same.
930 /// We do not intend to use this field to model cache effects.
931 ///
932 /// This is currently not printed in EXPLAIN, only optimizer trace.
933 double m_init_once_cost{0.0};
934
935 /// If no filter, identical to cost. init_cost is always the same
936 /// (filters have zero initialization cost).
938
939 // We'd prefer if this could be an std::variant, but we don't have C++17 yet.
940 // It is private to force all access to be through the type-checking
941 // accessors.
942 //
943 // For information about the meaning of each value, see the corresponding
944 // row iterator constructors.
945 union {
946 struct {
949 struct {
950 TABLE *table;
954 struct {
955 TABLE *table;
956 int idx;
960 struct {
961 TABLE *table;
962 int idx;
964 bool reverse;
966 struct {
967 TABLE *table;
969 bool use_order;
970 bool reverse;
972 struct {
973 TABLE *table;
975 bool use_order;
977 struct {
978 TABLE *table;
981 struct {
982 TABLE *table;
984 bool use_order;
987 struct {
988 TABLE *table;
990 bool use_order;
994 struct {
995 TABLE *table;
998 struct {
999 TABLE *table;
1005 struct {
1006 TABLE *table;
1008 struct {
1009 // The key part(s) we are scanning on. Note that this may be an array.
1010 // You can get the table we are working on by looking into
1011 // used_key_parts[0].field->table (it is not stored directly, to avoid
1012 // going over the AccessPath size limits).
1014
1015 // The actual ranges we are scanning over (originally derived from “key”).
1016 // Not a Bounds_checked_array, to save 4 bytes on the length.
1018 unsigned num_ranges;
1019
1020 unsigned mrr_flags;
1022
1023 // Which index (in the TABLE) we are scanning over, and how many of its
1024 // key parts we are using.
1025 unsigned index;
1027
1028 // If true, the scan can return rows in rowid order.
1030
1031 // If true, the scan _should_ return rows in rowid order.
1032 // Should only be set if can_be_used_for_ror == true.
1034
1035 // If true, this plan can be used for index merge scan.
1037
1038 // See row intersection for more details.
1040
1041 // Whether we are scanning over a geometry key part.
1042 bool geometry : 1;
1043
1044 // Whether we need a reverse scan. Only supported if geometry == false.
1045 bool reverse : 1;
1046
1047 // For a reverse scan, if we are using extended key parts. It is needed,
1048 // to set correct flags when retrieving records.
1051 struct {
1052 TABLE *table;
1057 struct {
1058 TABLE *table;
1060
1061 // Clustered primary key scan, if any.
1063
1064 bool forced_by_hint;
1067
1068 // If true, the first child scan should reuse table->file instead of
1069 // creating its own. This is true if the intersection is the topmost
1070 // range scan, but _not_ if it's below a union. (The reasons for this
1071 // are unknown.) It can also be negated by logic involving
1072 // retrieve_full_rows and is_covering, again for unknown reasons.
1073 //
1074 // This is not only for performance; multi-table delete has a hidden
1075 // dependency on this behavior when running against certain types of
1076 // tables (e.g. MyISAM), as it assumes table->file is correctly positioned
1077 // when deleting (and not all table types can transfer the position of one
1078 // handler to another by using position()).
1079 bool reuse_handler;
1080
1081 // true if no row retrieval phase is necessary.
1084 struct {
1085 TABLE *table;
1087 bool forced_by_hint;
1089 struct {
1090 TABLE *table;
1091 unsigned index;
1092 unsigned num_used_key_parts;
1093 bool forced_by_hint;
1094
1095 // Large, and has nontrivial destructors, so split out into
1096 // its own allocation.
1099 struct {
1100 TABLE *table;
1101 unsigned index;
1102 unsigned num_used_key_parts;
1103 bool forced_by_hint;
1104
1105 // Large, so split out into its own allocation.
1108 struct {
1109 TABLE *table;
1110 QEP_TAB *qep_tab; // Used only for buffering.
1112 struct {
1113 TABLE *table;
1117 struct {
1119
1120 struct {
1123 struct {
1124 // No members.
1126 struct {
1127 // The child is optional. It is only used for keeping track of which
1128 // tables are pruned away by this path, and it is only needed when this
1129 // path is on the inner side of an outer join. See ZeroRowsIterator for
1130 // details. The child of a ZERO_ROWS access path will not be visited by
1131 // WalkAccessPaths(). It will be visited by WalkTablesUnderAccessPath()
1132 // only if called with include_pruned_tables = true. No iterator is
1133 // created for the child, and the child is not shown by EXPLAIN.
1135 // Used for EXPLAIN only.
1136 // TODO(sgunders): make an enum.
1137 const char *cause;
1139 struct {
1140 // Used for EXPLAIN only.
1141 // TODO(sgunders): make an enum.
1142 const char *cause;
1144
1145 struct {
1149 bool store_rowids; // Whether we are below a weedout or not.
1153 struct {
1158 bool store_rowids; // Whether we are below a weedout or not.
1161 struct {
1163 JoinType join_type; // Somewhat redundant wrt. join_predicate.
1167
1168 // Equijoin filters to apply before the join, if any.
1169 // Indexes into join_predicate->expr->equijoin_conditions.
1170 // Non-equijoin conditions are always applied.
1171 // If already_expanded_predicates is true, do not re-expand.
1173
1174 // NOTE: Due to the nontrivial constructor on equijoin_predicates,
1175 // this struct needs an initializer, or the union would not be
1176 // default-constructible. If we need more than one union member
1177 // with such an initializer, we would probably need to change
1178 // equijoin_predicates into a uint64_t type-punned to an OverflowBitset.
1179 } nested_loop_join = {nullptr, nullptr, JoinType::INNER, false, false,
1180 nullptr, {}};
1181 struct {
1183 const TABLE *table;
1185 size_t key_len;
1187
1188 struct {
1191
1192 // This parameter, unlike nearly all others, is not passed to the the
1193 // actual iterator. Instead, if true, it signifies that when creating
1194 // the iterator, all materializable subqueries in “condition” should be
1195 // materialized (with any in2exists condition removed first). In the
1196 // very rare case that there are two or more such subqueries, this is
1197 // an all-or-nothing decision, for simplicity.
1198 //
1199 // See FinalizeMaterializedSubqueries().
1202 struct {
1206
1207 // If filesort is nullptr: A new filesort will be created at the
1208 // end of optimization, using this order and flags. Otherwise: Only
1209 // used by EXPLAIN.
1216 struct {
1220 struct {
1224 TABLE *table;
1228 struct {
1230 ha_rows limit;
1234 // Only used when the LIMIT is on a UNION with SQL_CALC_FOUND_ROWS.
1235 // See Query_expression::send_records.
1238 struct {
1240 JOIN *join;
1242 TABLE *table;
1244 int ref_slice;
1246 struct {
1247 // NOTE: The only legal access paths within table_path are
1248 // TABLE_SCAN, REF, REF_OR_NULL, EQ_REF, ALTERNATIVE,
1249 // CONST_TABLE (somewhat nonsensical), INDEX_SCAN and DYNAMIC_INDEX_SCAN
1251
1252 // Large, and has nontrivial destructors, so split out
1253 // into its own allocation.
1255 /** The total cost of executing the queries that we materialize.*/
1257 /// The number of materialized rows (as opposed to the number of rows
1258 /// fetched by table_path). Needed for 'explain'.
1261 struct {
1264 Item *condition;
1266 struct {
1269 struct {
1274 int ref_slice;
1277 struct {
1282 struct {
1287 struct {
1289 TABLE *table;
1290 KEY *key;
1293 struct {
1295
1296 // For the ref.
1300 struct {
1302 const char *name;
1304 struct {
1309 struct {
1314 } u;
1315};
1316static_assert(std::is_trivially_destructible<AccessPath>::value,
1317 "AccessPath must be trivially destructible, as it is allocated "
1318 "on the MEM_ROOT and not wrapped in unique_ptr_destroy_only"
1319 "(because multiple candidates during planning could point to "
1320 "the same access paths, and refcounting would be expensive)");
1321static_assert(sizeof(AccessPath) <= 144,
1322 "We are creating a lot of access paths in the join "
1323 "optimizer, so be sure not to bloat it without noticing. "
1324 "(96 bytes for the base, 48 bytes for the variant.)");
1325
1326inline void CopyBasicProperties(const AccessPath &from, AccessPath *to) {
1328 to->set_cost(from.cost());
1329 to->set_init_cost(from.init_cost());
1332 to->safe_for_rowid = from.safe_for_rowid;
1333 to->ordering_state = from.ordering_state;
1335}
1336
1337// Trivial factory functions for all of the types of access paths above.
1338
1340 bool count_examined_rows) {
1341 AccessPath *path = new (thd->mem_root) AccessPath;
1343 path->count_examined_rows = count_examined_rows;
1344 path->table_scan().table = table;
1345 return path;
1346}
1347
1349 double sampling_percentage,
1350 bool count_examined_rows) {
1351 AccessPath *path = new (thd->mem_root) AccessPath;
1353 path->count_examined_rows = count_examined_rows;
1354 path->sample_scan().table = table;
1355 path->sample_scan().sampling_percentage = sampling_percentage;
1356 return path;
1357}
1358
1360 bool use_order, bool reverse,
1361 bool count_examined_rows) {
1362 AccessPath *path = new (thd->mem_root) AccessPath;
1364 path->count_examined_rows = count_examined_rows;
1365 path->index_scan().table = table;
1366 path->index_scan().idx = idx;
1367 path->index_scan().use_order = use_order;
1368 path->index_scan().reverse = reverse;
1369 return path;
1370}
1371
1373 bool use_order, bool reverse,
1374 bool count_examined_rows) {
1375 AccessPath *path = new (thd->mem_root) AccessPath;
1376 path->type = AccessPath::REF;
1377 path->count_examined_rows = count_examined_rows;
1378 path->ref().table = table;
1379 path->ref().ref = ref;
1380 path->ref().use_order = use_order;
1381 path->ref().reverse = reverse;
1382 return path;
1383}
1384
1386 Index_lookup *ref, bool use_order,
1387 bool count_examined_rows) {
1388 AccessPath *path = new (thd->mem_root) AccessPath;
1390 path->count_examined_rows = count_examined_rows;
1391 path->ref_or_null().table = table;
1392 path->ref_or_null().ref = ref;
1393 path->ref_or_null().use_order = use_order;
1394 return path;
1395}
1396
1398 bool count_examined_rows) {
1399 AccessPath *path = new (thd->mem_root) AccessPath;
1400 path->type = AccessPath::EQ_REF;
1401 path->count_examined_rows = count_examined_rows;
1402 path->eq_ref().table = table;
1403 path->eq_ref().ref = ref;
1404 return path;
1405}
1406
1408 Index_lookup *ref, bool use_order,
1409 bool is_unique,
1410 bool count_examined_rows) {
1411 AccessPath *path = new (thd->mem_root) AccessPath;
1413 path->count_examined_rows = count_examined_rows;
1414 path->pushed_join_ref().table = table;
1415 path->pushed_join_ref().ref = ref;
1416 path->pushed_join_ref().use_order = use_order;
1417 path->pushed_join_ref().is_unique = is_unique;
1418 return path;
1419}
1420
1423 Item_func_match *ft_func,
1424 bool use_order, bool use_limit,
1425 bool count_examined_rows) {
1426 AccessPath *path = new (thd->mem_root) AccessPath;
1428 path->count_examined_rows = count_examined_rows;
1429 path->full_text_search().table = table;
1430 path->full_text_search().ref = ref;
1431 path->full_text_search().use_order = use_order;
1432 path->full_text_search().use_limit = use_limit;
1433 path->full_text_search().ft_func = ft_func;
1434 return path;
1435}
1436
1439 bool count_examined_rows) {
1440 AccessPath *path = new (thd->mem_root) AccessPath;
1442 path->count_examined_rows = count_examined_rows;
1443 path->set_num_output_rows(1.0);
1444 path->set_cost(0.0);
1445 path->set_init_cost(0.0);
1446 path->set_init_once_cost(0.0);
1447 path->const_table().table = table;
1448 path->const_table().ref = ref;
1449 return path;
1450}
1451
1453 int mrr_flags) {
1454 AccessPath *path = new (thd->mem_root) AccessPath;
1455 path->type = AccessPath::MRR;
1456 path->mrr().table = table;
1457 path->mrr().ref = ref;
1458 path->mrr().mrr_flags = mrr_flags;
1459
1460 // This will be filled in when the BKA iterator is created.
1461 path->mrr().bka_path = nullptr;
1462
1463 return path;
1464}
1465
1467 bool count_examined_rows) {
1468 AccessPath *path = new (thd->mem_root) AccessPath;
1470 path->count_examined_rows = count_examined_rows;
1471 path->follow_tail().table = table;
1472 return path;
1473}
1474
1476 THD *thd, TABLE *table, QEP_TAB *qep_tab, bool count_examined_rows) {
1477 AccessPath *path = new (thd->mem_root) AccessPath;
1479 path->count_examined_rows = count_examined_rows;
1480 path->dynamic_index_range_scan().table = table;
1481 path->dynamic_index_range_scan().qep_tab = qep_tab;
1482 return path;
1483}
1484
1486 THD *thd, TABLE *table, Table_function *table_function,
1487 AccessPath *table_path) {
1488 AccessPath *path = new (thd->mem_root) AccessPath;
1490 path->materialized_table_function().table = table;
1491 path->materialized_table_function().table_function = table_function;
1492 path->materialized_table_function().table_path = table_path;
1493 return path;
1494}
1495
1497 AccessPath *path = new (thd->mem_root) AccessPath;
1499 return path;
1500}
1501
1503 const JOIN *join);
1504
1506 THD *thd, AccessPath *outer, AccessPath *inner, const TABLE *table,
1507 KEY *key, size_t key_len) {
1508 AccessPath *path = new (thd->mem_root) AccessPath;
1510 path->nested_loop_semijoin_with_duplicate_removal().outer = outer;
1511 path->nested_loop_semijoin_with_duplicate_removal().inner = inner;
1512 path->nested_loop_semijoin_with_duplicate_removal().table = table;
1513 path->nested_loop_semijoin_with_duplicate_removal().key = key;
1514 path->nested_loop_semijoin_with_duplicate_removal().key_len = key_len;
1515 return path;
1516}
1517
1519 Item *condition) {
1520 AccessPath *path = new (thd->mem_root) AccessPath;
1521 path->type = AccessPath::FILTER;
1522 path->filter().child = child;
1523 path->filter().condition = condition;
1524 path->filter().materialize_subqueries = false;
1525 path->has_group_skip_scan = child->has_group_skip_scan;
1526 return path;
1527}
1528
1529// Not inline, because it needs access to filesort internals
1530// (which are forward-declared in this file).
1532 ORDER *order, bool count_examined_rows);
1533
1535 olap_type olap) {
1536 AccessPath *path = new (thd->mem_root) AccessPath;
1538 path->aggregate().child = child;
1539 path->aggregate().olap = olap;
1540 path->has_group_skip_scan = child->has_group_skip_scan;
1541 return path;
1542}
1543
1545 THD *thd, AccessPath *subquery_path, JOIN *join,
1546 Temp_table_param *temp_table_param, TABLE *table, AccessPath *table_path,
1547 int ref_slice) {
1548 AccessPath *path = new (thd->mem_root) AccessPath;
1550 path->temptable_aggregate().subquery_path = subquery_path;
1551 path->temptable_aggregate().join = join;
1552 path->temptable_aggregate().temp_table_param = temp_table_param;
1553 path->temptable_aggregate().table = table;
1554 path->temptable_aggregate().table_path = table_path;
1555 path->temptable_aggregate().ref_slice = ref_slice;
1556 return path;
1557}
1558
1560 ha_rows limit, ha_rows offset,
1561 bool count_all_rows,
1562 bool reject_multiple_rows,
1563 ha_rows *send_records_override) {
1565 AccessPath *path = new (thd->mem_root) AccessPath;
1567 path->immediate_update_delete_table = child->immediate_update_delete_table;
1568 path->limit_offset().child = child;
1569 path->limit_offset().limit = limit;
1570 path->limit_offset().offset = offset;
1571 path->limit_offset().count_all_rows = count_all_rows;
1572 path->limit_offset().reject_multiple_rows = reject_multiple_rows;
1573 path->limit_offset().send_records_override = send_records_override;
1574 path->ordering_state = child->ordering_state;
1575 path->has_group_skip_scan = child->has_group_skip_scan;
1577 return path;
1578}
1579
1581 bool count_examined_rows) {
1582 AccessPath *path = new (thd->mem_root) AccessPath;
1584 path->count_examined_rows = count_examined_rows;
1585 path->set_num_output_rows(1.0);
1586 path->set_cost(0.0);
1587 path->set_init_cost(0.0);
1588 path->set_init_once_cost(0.0);
1589 return path;
1590}
1591
1593 const char *cause) {
1594 AccessPath *path = new (thd->mem_root) AccessPath;
1596 path->zero_rows().child = child;
1597 path->zero_rows().cause = cause;
1598 path->set_num_output_rows(0.0);
1599 path->set_cost(0.0);
1600 path->set_init_cost(0.0);
1601 path->set_init_once_cost(0.0);
1602 path->num_output_rows_before_filter = 0.0;
1603 path->set_cost_before_filter(0.0);
1604 return path;
1605}
1606
1607inline AccessPath *NewZeroRowsAccessPath(THD *thd, const char *cause) {
1608 return NewZeroRowsAccessPath(thd, /*child=*/nullptr, cause);
1609}
1610
1612 const char *cause) {
1613 AccessPath *path = new (thd->mem_root) AccessPath;
1615 path->zero_rows_aggregated().cause = cause;
1616 path->set_num_output_rows(1.0);
1617 path->set_cost(0.0);
1618 path->set_init_cost(0.0);
1619 return path;
1620}
1621
1623 JOIN *join,
1624 Temp_table_param *temp_table_param,
1625 TABLE *table, int ref_slice) {
1626 AccessPath *path = new (thd->mem_root) AccessPath;
1627 path->type = AccessPath::STREAM;
1628 path->stream().child = child;
1629 path->stream().join = join;
1630 path->stream().temp_table_param = temp_table_param;
1631 path->stream().table = table;
1632 path->stream().ref_slice = ref_slice;
1633 // Will be set later if we get a weedout access path as parent.
1634 path->stream().provide_rowid = false;
1635 path->has_group_skip_scan = child->has_group_skip_scan;
1636 return path;
1637}
1638
1641 JOIN *join, bool copy_items,
1642 Temp_table_param *temp_table_param) {
1643 assert(path != nullptr);
1645 MaterializePathParameters::Operand &operand = array[0];
1646 operand.subquery_path = path;
1647 operand.select_number = select_number;
1648 operand.join = join;
1650 operand.copy_items = copy_items;
1651 operand.temp_table_param = temp_table_param;
1652 return array;
1653}
1654
1658 AccessPath *table_path, Common_table_expr *cte, Query_expression *unit,
1659 int ref_slice, bool rematerialize, ha_rows limit_rows,
1660 bool reject_multiple_rows,
1665 param->m_operands = std::move(operands);
1666 if (rematerialize) {
1667 // There's no point in adding invalidators if we're rematerializing
1668 // every time anyway.
1669 param->invalidators = nullptr;
1670 } else {
1671 param->invalidators = invalidators;
1672 }
1673 param->table = table;
1674 param->cte = cte;
1675 param->unit = unit;
1676 param->ref_slice = ref_slice;
1677 param->rematerialize = rematerialize;
1678 param->limit_rows = (table == nullptr || table->is_union_or_table()
1679 ? limit_rows
1680 :
1681 // INTERSECT, EXCEPT: Enforced by TableScanIterator,
1682 // see its constructor
1683 HA_POS_ERROR);
1684 param->reject_multiple_rows = reject_multiple_rows;
1685 param->deduplication_reason = dedup_reason;
1686
1687#ifndef NDEBUG
1688 for (MaterializePathParameters::Operand &operand : param->m_operands) {
1689 assert(operand.subquery_path != nullptr);
1690 }
1691#endif
1692
1693 AccessPath *path = new (thd->mem_root) AccessPath;
1695 path->materialize().table_path = table_path;
1696 path->materialize().param = param;
1697 path->materialize().subquery_cost = kUnknownCost;
1698 path->materialize().subquery_rows = kUnknownRowCount;
1699 if (rematerialize) {
1700 path->safe_for_rowid = AccessPath::SAFE_IF_SCANNED_ONCE;
1701 } else {
1702 // The default; this is just to be explicit in the code.
1703 path->safe_for_rowid = AccessPath::SAFE;
1704 }
1705 return path;
1706}
1707
1709 THD *thd, AccessPath *table_path, Table_ref *table_list, Item *condition) {
1710 AccessPath *path = new (thd->mem_root) AccessPath;
1712 path->materialize_information_schema_table().table_path = table_path;
1713 path->materialize_information_schema_table().table_list = table_list;
1714 path->materialize_information_schema_table().condition = condition;
1715 return path;
1716}
1717
1718/// Add path costs c1 and c2, but handle kUnknownCost correctly.
1719inline double AddCost(double c1, double c2) {
1720 // If one is undefined, use the other, as we have nothing else.
1721 if (c1 == kUnknownCost) {
1722 return c2;
1723 } else if (c2 == kUnknownCost) {
1724 return c1;
1725 } else {
1726 return c1 + c2;
1727 }
1728}
1729
1730/// Add row counts c1 and c2, but handle kUnknownRowCount correctly.
1731inline double AddRowCount(double c1, double c2) {
1732 // If one is undefined, use the other, as we have nothing else.
1733 if (c1 == kUnknownRowCount) {
1734 return c2;
1735 } else if (c2 == kUnknownRowCount) {
1736 return c1;
1737 } else {
1738 return c1 + c2;
1739 }
1740}
1741
1742// The Mem_root_array must be allocated on a MEM_ROOT that lives at least for as
1743// long as the access path.
1745 THD *thd, Mem_root_array<AppendPathParameters> *children) {
1746 AccessPath *path = new (thd->mem_root) AccessPath;
1747 path->type = AccessPath::APPEND;
1748 path->append().children = children;
1749 double num_output_rows = kUnknownRowCount;
1750 for (const AppendPathParameters &child : *children) {
1751 path->set_cost(AddCost(path->cost(), child.path->cost()));
1752 path->set_init_cost(AddCost(path->init_cost(), child.path->init_cost()));
1753 path->set_init_once_cost(path->init_once_cost() +
1754 child.path->init_once_cost());
1755 num_output_rows =
1756 AddRowCount(num_output_rows, child.path->num_output_rows());
1757 }
1758 path->set_num_output_rows(num_output_rows);
1759 return path;
1760}
1761
1763 Window *window,
1764 Temp_table_param *temp_table_param,
1765 int ref_slice, bool needs_buffering) {
1766 AccessPath *path = new (thd->mem_root) AccessPath;
1767 path->type = AccessPath::WINDOW;
1768 path->window().child = child;
1769 path->window().window = window;
1770 path->window().temp_table = nullptr;
1771 path->window().temp_table_param = temp_table_param;
1772 path->window().ref_slice = ref_slice;
1773 path->window().needs_buffering = needs_buffering;
1774 path->set_num_output_rows(child->num_output_rows());
1775 return path;
1776}
1777
1779 SJ_TMP_TABLE *weedout_table) {
1780 AccessPath *path = new (thd->mem_root) AccessPath;
1781 path->type = AccessPath::WEEDOUT;
1782 path->weedout().child = child;
1783 path->weedout().weedout_table = weedout_table;
1784 path->weedout().tables_to_get_rowid_for =
1785 0; // Must be handled by the caller.
1786 return path;
1787}
1788
1790 Item **group_items,
1791 int group_items_size) {
1792 AccessPath *path = new (thd->mem_root) AccessPath;
1794 path->remove_duplicates().child = child;
1795 path->remove_duplicates().group_items = group_items;
1796 path->remove_duplicates().group_items_size = group_items_size;
1797 path->has_group_skip_scan = child->has_group_skip_scan;
1798 return path;
1799}
1800
1802 THD *thd, AccessPath *child, TABLE *table, KEY *key,
1803 unsigned loosescan_key_len) {
1804 AccessPath *path = new (thd->mem_root) AccessPath;
1806 path->remove_duplicates_on_index().child = child;
1807 path->remove_duplicates_on_index().table = table;
1808 path->remove_duplicates_on_index().key = key;
1809 path->remove_duplicates_on_index().loosescan_key_len = loosescan_key_len;
1810 path->has_group_skip_scan = child->has_group_skip_scan;
1811 return path;
1812}
1813
1815 AccessPath *table_scan_path,
1816 Index_lookup *used_ref) {
1817 AccessPath *path = new (thd->mem_root) AccessPath;
1819 path->alternative().table_scan_path = table_scan_path;
1820 path->alternative().child = child;
1821 path->alternative().used_ref = used_ref;
1822 return path;
1823}
1824
1826 const char *name) {
1827 AccessPath *path = new (thd->mem_root) AccessPath;
1829 path->cache_invalidator().child = child;
1830 path->cache_invalidator().name = name;
1831 return path;
1832}
1833
1836 table_map immediate_tables);
1837
1840 table_map immediate_tables);
1841
1842/**
1843 Modifies "path" and the paths below it so that they provide row IDs for
1844 all tables.
1845
1846 This also figures out how the row IDs should be retrieved for each table in
1847 the input to the path. If the handler of the table is positioned on the
1848 correct row while reading the input, handler::position() can be called to get
1849 the row ID from the handler. However, if the input iterator returns rows
1850 without keeping the position of the underlying handlers in sync, calling
1851 handler::position() will not be able to provide the row IDs. Specifically,
1852 hash join and BKA join do not keep the underlying handlers positioned on the
1853 right row. Therefore, this function will instruct every hash join or BKA join
1854 below "path" to maintain row IDs in the join buffer, and updating handler::ref
1855 in every input table for each row they return. Then "path" does not need to
1856 call handler::position() to get it (nor should it, since calling it would
1857 overwrite the correct row ID with a stale one).
1858
1859 The tables on which "path" should call handler::position() are stored in a
1860 `tables_to_get_rowid_for` bitset in "path". For all the other tables, it can
1861 assume that handler::ref already contains the correct row ID.
1862 */
1864
1867 bool eligible_for_batch_mode);
1868
1869// A short form of CreateIteratorFromAccessPath() that implicitly uses the THD's
1870// MEM_ROOT for storage, which is nearly always what you want. (The only caller
1871// that does anything else is DynamicRangeIterator.)
1873 THD *thd, AccessPath *path, JOIN *join, bool eligible_for_batch_mode) {
1875 eligible_for_batch_mode);
1876}
1877
1878void SetCostOnTableAccessPath(const Cost_model_server &cost_model,
1879 const POSITION *pos, bool is_after_filter,
1880 AccessPath *path);
1881
1882/**
1883 Return the TABLE* referred from 'path' if it is a basic access path,
1884 else a nullptr is returned. Temporary tables, such as those used by
1885 sorting, aggregate and subquery materialization are not returned.
1886*/
1888
1889/**
1890 Returns a map of all tables read when `path` or any of its children are
1891 executed. Only iterators that are part of the same query block as `path`
1892 are considered.
1893
1894 If a table is read that doesn't have a map, specifically the temporary
1895 tables made as part of materialization within the same query block,
1896 RAND_TABLE_BIT will be set as a convention and none of that access path's
1897 children will be included in the map. In this case, the caller will need to
1898 manually go in and find said access path, to ask it for its TABLE object.
1899
1900 If include_pruned_tables = true, tables that are hidden under a ZERO_ROWS
1901 access path (ie., pruned away due to impossible join conditions) will be
1902 included in the map. This is normally what you want, as those tables need to
1903 be included whenever you store NULL flags and the likes, but if you don't
1904 want them (perhaps to specifically check for conditions referring to pruned
1905 tables), you can set it to false.
1906 */
1907table_map GetUsedTableMap(const AccessPath *path, bool include_pruned_tables);
1908
1909/**
1910 Find the list of all tables used by this root, stopping at materializations.
1911 Used for knowing which tables to sort.
1912 */
1914
1915/**
1916 For each access path in the (sub)tree rooted at “path”, expand any use of
1917 “filter_predicates” into newly-inserted FILTER access paths, using the given
1918 predicate list. This is used after finding an optimal set of access paths,
1919 to normalize the tree so that the remaining consumers do not need to worry
1920 about filter_predicates and cost_before_filter.
1921
1922 “join” is the join that “path” is part of.
1923 */
1925 const Mem_root_array<Predicate> &predicates,
1926 unsigned num_where_predicates);
1927
1928/**
1929 Extracts the Item expression from the given “filter_predicates” corresponding
1930 to the given “mask”.
1931 */
1934 int num_where_predicates);
1935
1936/// Like ExpandFilterAccessPaths(), but expands only the single access path
1937/// at “path”.
1939 const Mem_root_array<Predicate> &predicates,
1940 unsigned num_where_predicates);
1941
1942/// Returns the tables that are part of a hash join.
1944
1945/**
1946 Get the conditions to put into the extra conditions of the HashJoinIterator.
1947 This includes the non-equijoin conditions, as well as any equijoin conditions
1948 on columns that are too big to include in the hash table. (The old optimizer
1949 handles equijoin conditions on long columns elsewhere, so the last part only
1950 applies to the hypergraph optimizer.)
1951
1952 @param mem_root The root on which to allocate memory, if needed.
1953 @param using_hypergraph_optimizer True if using the hypergraph optimizer.
1954 @param equijoin_conditions All the equijoin conditions of the join.
1955 @param other_conditions All the non-equijoin conditions of the join.
1956
1957 @return All the conditions to evaluate as "extra conditions" in
1958 HashJoinIterator, or nullptr on OOM.
1959 */
1961 MEM_ROOT *mem_root, bool using_hypergraph_optimizer,
1962 const std::vector<HashJoinCondition> &equijoin_conditions,
1963 const Mem_root_array<Item *> &other_conditions);
1964
1965/**
1966 Update status variables which count how many scans of various types are used
1967 in a query plan.
1968
1969 The following status variables are updated: Select_scan, Select_full_join,
1970 Select_range, Select_full_range_join, Select_range_check. They are also stored
1971 as performance schema statement events with the same names.
1972
1973 In addition, the performance schema statement events NO_INDEX_USED and
1974 NO_GOOD_INDEX_USED are updated, if appropriate.
1975 */
1976void CollectStatusVariables(THD *thd, const JOIN *top_join,
1977 const AccessPath &top_path);
1978
1979#endif // SQL_JOIN_OPTIMIZER_ACCESS_PATH_H
constexpr double kUnknownCost
To indicate that a cost estimate is not yet made.
Definition: access_path.h:190
AccessPath * NewStreamingAccessPath(THD *thd, AccessPath *child, JOIN *join, Temp_table_param *temp_table_param, TABLE *table, int ref_slice)
Definition: access_path.h:1622
AccessPath * NewRemoveDuplicatesAccessPath(THD *thd, AccessPath *child, Item **group_items, int group_items_size)
Definition: access_path.h:1789
AccessPath * NewInvalidatorAccessPath(THD *thd, AccessPath *child, const char *name)
Definition: access_path.h:1825
AccessPath * NewRefAccessPath(THD *thd, TABLE *table, Index_lookup *ref, bool use_order, bool reverse, bool count_examined_rows)
Definition: access_path.h:1372
AccessPath * NewDeleteRowsAccessPath(THD *thd, AccessPath *child, table_map delete_tables, table_map immediate_tables)
Definition: access_path.cc:122
void CopyBasicProperties(const AccessPath &from, AccessPath *to)
Definition: access_path.h:1326
void ExpandSingleFilterAccessPath(THD *thd, AccessPath *path, const JOIN *join, const Mem_root_array< Predicate > &predicates, unsigned num_where_predicates)
Like ExpandFilterAccessPaths(), but expands only the single access path at “path”.
Definition: access_path.cc:1532
AccessPath * NewFullTextSearchAccessPath(THD *thd, TABLE *table, Index_lookup *ref, Item_func_match *ft_func, bool use_order, bool use_limit, bool count_examined_rows)
Definition: access_path.h:1421
double AddRowCount(double c1, double c2)
Add row counts c1 and c2, but handle kUnknownRowCount correctly.
Definition: access_path.h:1731
table_map GetHashJoinTables(AccessPath *path)
Returns the tables that are part of a hash join.
Definition: access_path.cc:1657
AccessPath * NewDynamicIndexRangeScanAccessPath(THD *thd, TABLE *table, QEP_TAB *qep_tab, bool count_examined_rows)
Definition: access_path.h:1475
AccessPath * NewMaterializeAccessPath(THD *thd, Mem_root_array< MaterializePathParameters::Operand > operands, Mem_root_array< const AccessPath * > *invalidators, TABLE *table, AccessPath *table_path, Common_table_expr *cte, Query_expression *unit, int ref_slice, bool rematerialize, ha_rows limit_rows, bool reject_multiple_rows, MaterializePathParameters::DedupType dedup_reason=MaterializePathParameters::NO_DEDUP)
Definition: access_path.h:1655
AccessPath * NewZeroRowsAggregatedAccessPath(THD *thd, const char *cause)
Definition: access_path.h:1611
AccessPath * NewAlternativeAccessPath(THD *thd, AccessPath *child, AccessPath *table_scan_path, Index_lookup *used_ref)
Definition: access_path.h:1814
AccessPath * NewUpdateRowsAccessPath(THD *thd, AccessPath *child, table_map delete_tables, table_map immediate_tables)
Definition: access_path.cc:134
AccessPath * NewMRRAccessPath(THD *thd, TABLE *table, Index_lookup *ref, int mrr_flags)
Definition: access_path.h:1452
table_map GetUsedTableMap(const AccessPath *path, bool include_pruned_tables)
Returns a map of all tables read when path or any of its children are executed.
Definition: access_path.cc:272
AccessPath * NewAppendAccessPath(THD *thd, Mem_root_array< AppendPathParameters > *children)
Definition: access_path.h:1744
AccessPath * NewNestedLoopSemiJoinWithDuplicateRemovalAccessPath(THD *thd, AccessPath *outer, AccessPath *inner, const TABLE *table, KEY *key, size_t key_len)
Definition: access_path.h:1505
void CollectStatusVariables(THD *thd, const JOIN *top_join, const AccessPath &top_path)
Update status variables which count how many scans of various types are used in a query plan.
Definition: access_path.cc:1671
AccessPath * NewTemptableAggregateAccessPath(THD *thd, AccessPath *subquery_path, JOIN *join, Temp_table_param *temp_table_param, TABLE *table, AccessPath *table_path, int ref_slice)
Definition: access_path.h:1544
AccessPath * NewRemoveDuplicatesOnIndexAccessPath(THD *thd, AccessPath *child, TABLE *table, KEY *key, unsigned loosescan_key_len)
Definition: access_path.h:1801
AccessPath * NewFakeSingleRowAccessPath(THD *thd, bool count_examined_rows)
Definition: access_path.h:1580
AccessPath * NewTableValueConstructorAccessPath(const THD *thd, const JOIN *join)
Definition: access_path.cc:166
Item * ConditionFromFilterPredicates(const Mem_root_array< Predicate > &predicates, OverflowBitset mask, int num_where_predicates)
Extracts the Item expression from the given “filter_predicates” corresponding to the given “mask”.
Definition: access_path.cc:1521
AccessPath * NewFilterAccessPath(THD *thd, AccessPath *child, Item *condition)
Definition: access_path.h:1518
constexpr double kUnknownRowCount
To indicate that a row estimate is not yet made.
Definition: access_path.h:185
AccessPath * NewSortAccessPath(THD *thd, AccessPath *child, Filesort *filesort, ORDER *order, bool count_examined_rows)
Definition: access_path.cc:87
AccessPath * NewMaterializedTableFunctionAccessPath(THD *thd, TABLE *table, Table_function *table_function, AccessPath *table_path)
Definition: access_path.h:1485
const Mem_root_array< Item * > * GetExtraHashJoinConditions(MEM_ROOT *mem_root, bool using_hypergraph_optimizer, const std::vector< HashJoinCondition > &equijoin_conditions, const Mem_root_array< Item * > &other_conditions)
Get the conditions to put into the extra conditions of the HashJoinIterator.
Mem_root_array< TABLE * > CollectTables(THD *thd, AccessPath *root_path)
Find the list of all tables used by this root, stopping at materializations.
Definition: access_path.cc:303
AccessPath * NewTableScanAccessPath(THD *thd, TABLE *table, bool count_examined_rows)
Definition: access_path.h:1339
AccessPath * NewSampleScanAccessPath(THD *thd, TABLE *table, double sampling_percentage, bool count_examined_rows)
Definition: access_path.h:1348
AccessPath * NewAggregateAccessPath(THD *thd, AccessPath *child, olap_type olap)
Definition: access_path.h:1534
void ExpandFilterAccessPaths(THD *thd, AccessPath *path, const JOIN *join, const Mem_root_array< Predicate > &predicates, unsigned num_where_predicates)
For each access path in the (sub)tree rooted at “path”, expand any use of “filter_predicates” into ne...
Definition: access_path.cc:1645
double AddCost(double c1, double c2)
Add path costs c1 and c2, but handle kUnknownCost correctly.
Definition: access_path.h:1719
AccessPath * NewMaterializeInformationSchemaTableAccessPath(THD *thd, AccessPath *table_path, Table_ref *table_list, Item *condition)
Definition: access_path.h:1708
void FindTablesToGetRowidFor(AccessPath *path)
Modifies "path" and the paths below it so that they provide row IDs for all tables.
Definition: access_path.cc:1364
TABLE * GetBasicTable(const AccessPath *path)
Return the TABLE* referred from 'path' if it is a basic access path, else a nullptr is returned.
Definition: access_path.cc:215
AccessPath * NewRefOrNullAccessPath(THD *thd, TABLE *table, Index_lookup *ref, bool use_order, bool count_examined_rows)
Definition: access_path.h:1385
AccessPath * NewLimitOffsetAccessPath(THD *thd, AccessPath *child, ha_rows limit, ha_rows offset, bool count_all_rows, bool reject_multiple_rows, ha_rows *send_records_override)
Definition: access_path.h:1559
AccessPath * NewEQRefAccessPath(THD *thd, TABLE *table, Index_lookup *ref, bool count_examined_rows)
Definition: access_path.h:1397
AccessPath * NewWindowAccessPath(THD *thd, AccessPath *child, Window *window, Temp_table_param *temp_table_param, int ref_slice, bool needs_buffering)
Definition: access_path.h:1762
double FirstRowCost(double init_cost, double total_cost, double output_rows)
Calculate the cost of reading the first row from an access path, given estimates for init cost,...
Definition: access_path.h:194
AccessPath * NewFollowTailAccessPath(THD *thd, TABLE *table, bool count_examined_rows)
Definition: access_path.h:1466
AccessPath * NewConstTableAccessPath(THD *thd, TABLE *table, Index_lookup *ref, bool count_examined_rows)
Definition: access_path.h:1437
unique_ptr_destroy_only< RowIterator > CreateIteratorFromAccessPath(THD *thd, MEM_ROOT *mem_root, AccessPath *path, JOIN *join, bool eligible_for_batch_mode)
Definition: access_path.cc:515
AccessPath * NewWeedoutAccessPath(THD *thd, AccessPath *child, SJ_TMP_TABLE *weedout_table)
Definition: access_path.h:1778
AccessPath * NewPushedJoinRefAccessPath(THD *thd, TABLE *table, Index_lookup *ref, bool use_order, bool is_unique, bool count_examined_rows)
Definition: access_path.h:1407
AccessPath * NewZeroRowsAccessPath(THD *thd, AccessPath *child, const char *cause)
Definition: access_path.h:1592
AccessPath * NewUnqualifiedCountAccessPath(THD *thd)
Definition: access_path.h:1496
AccessPath * NewIndexScanAccessPath(THD *thd, TABLE *table, int idx, bool use_order, bool reverse, bool count_examined_rows)
Definition: access_path.h:1359
Mem_root_array< MaterializePathParameters::Operand > SingleMaterializeQueryBlock(THD *thd, AccessPath *path, int select_number, JOIN *join, bool copy_items, Temp_table_param *temp_table_param)
Definition: access_path.h:1640
After parsing, a Common Table Expression is accessed through a Table_ref.
Definition: table.h:4484
API for getting cost estimates for server operations that are not directly related to a table object.
Definition: opt_costmodel.h:54
Sorting related info.
Definition: filesort.h:52
A class that represents a join condition in a hash join.
Definition: item_cmpfunc.h:87
Definition: item_func.h:3539
Base class that is used to represent any kind of expression in a relational query.
Definition: item.h:930
Definition: sql_optimizer.h:133
Definition: key.h:113
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:426
Definition: overflow_bitset.h:78
Definition: sql_executor.h:256
Definition: range_optimizer.h:69
This class represents a query expression (one query block or several query blocks combined with UNION...
Definition: sql_lex.h:627
A context for reading through a single table using a chosen access method: index read,...
Definition: row_iterator.h:82
Definition: sql_executor.h:95
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
MEM_ROOT * mem_root
Definition: sql_lexer_thd.h:40
Class representing a table function.
Definition: table_function.h:53
Definition: table.h:2900
Object containing parameters used when creating and using temporary tables.
Definition: temp_table_param.h:97
Represents the (explicit) window of a SQL 2003 section 7.11 <window clause>, or the implicit (inlined...
Definition: window.h:110
static MEM_ROOT mem_root
Definition: client_plugin.cc:114
void EstimateLimitOffsetCost(AccessPath *path)
Estimate the costs and row count for a WINDOW AccessPath.
Definition: cost_model.cc:941
bool filesort(THD *thd, Filesort *filesort, RowIterator *source_iterator, table_map tables_to_get_rowid_for, ha_rows num_rows_estimate, Filesort_info *fs_info, Sort_result *sort_result, ha_rows *found_rows)
Sort a table.
Definition: filesort.cc:367
void SetCostOnTableAccessPath(const Cost_model_server &cost_model, const POSITION *pos, bool is_after_filter, AccessPath *path)
Definition: sql_executor.cc:2005
std::bitset< kMaxSupportedFDs > FunctionalDependencySet
Definition: interesting_orders_defs.h:63
JoinType
Definition: join_type.h:28
static mi_bit_type mask[]
Definition: mi_packrec.cc:141
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
std::unique_ptr< T, Destroy_only< T > > unique_ptr_destroy_only
std::unique_ptr, but only destroying.
Definition: my_alloc.h:480
This file includes constants used by all storage engines.
my_off_t ha_rows
Definition: my_base.h:1141
#define HA_POS_ERROR
Definition: my_base.h:1143
uint64_t table_map
Definition: my_table_map.h:30
static char * path
Definition: mysqldump.cc:149
static PFS_engine_table_share_proxy table
Definition: pfs.cc:61
PT & ref(PT *tp)
Definition: tablespace_impl.cc:359
uint64_t NodeMap
Since our graphs can never have more than 61 tables, node sets and edge lists are implemented using 6...
Definition: node_map.h:40
RangeReverse< Range > reverse(Range &x)
Iterate over a range in reverse.
Definition: utilities.h:132
std::string join(const detail::range auto &rng, std::string_view delim)
join elements of a range into a string separated by a delimiter.
Definition: string.h:74
int delete_tables(PFS_engine_table_share_proxy **, unsigned int) noexcept
Definition: pfs_plugin_table_v1_all_empty.cc:39
olap_type
Definition: olap.h:31
OverflowBitset is a fixed-size (once allocated) bitmap that is optimized for the common case of few e...
required string key
Definition: replication_asynchronous_connection_failover.proto:60
case opt name
Definition: sslopt-case.h:29
Access paths are a query planning structure that correspond 1:1 to iterators, in that an access path ...
Definition: access_path.h:227
auto & weedout()
Definition: access_path.h:842
auto & filter()
Definition: access_path.h:762
bool count_all_rows
Definition: access_path.h:1232
AccessPath * bka_path
Definition: access_path.h:1001
auto & ref_or_null()
Definition: access_path.h:570
auto & materialized_table_function()
Definition: access_path.h:682
AccessPath * cpk_child
Definition: access_path.h:1062
auto & rowid_union()
Definition: access_path.h:650
hypergraph::NodeMap parameter_tables
If nonzero, a bitmap of other tables whose joined-in rows must already be loaded when rows from this ...
Definition: access_path.h:518
const auto & bka_join() const
Definition: access_path.h:742
TABLE * temp_table
Definition: access_path.h:1272
OverflowBitset equijoin_predicates
Definition: access_path.h:1172
Item ** group_items
Definition: access_path.h:1284
struct AccessPath::@63::@85 table_value_constructor
double rescan_cost() const
Return the cost of scanning the given path for the second time (or later) in the given query block.
Definition: access_path.h:429
auto & materialize()
Definition: access_path.h:810
const auto & temptable_aggregate() const
Definition: access_path.h:790
OverflowBitset & subsumed_sargable_join_predicates()
Similar to applied_sargable_join_predicates, bitmap of sargable join predicates that have been applie...
Definition: access_path.h:490
auto & index_scan()
Definition: access_path.h:546
const auto & delete_rows() const
Definition: access_path.h:886
const auto & filter() const
Definition: access_path.h:766
const auto & index_distance_scan() const
Definition: access_path.h:558
auto & delete_rows()
Definition: access_path.h:882
bool reuse_handler
Definition: access_path.h:1039
struct AccessPath::@63::@108 delete_rows
KEY_PART * used_key_part
Definition: access_path.h:1013
double m_init_cost
Expected cost to initialize this access path; ie., cost to read k out of N rows would be init_cost + ...
Definition: access_path.h:921
olap_type olap
Definition: access_path.h:1218
OverflowBitset & applied_sargable_join_predicates()
Bitmap of sargable join predicates that have already been applied in this access path by means of an ...
Definition: access_path.h:470
Item * condition
Definition: access_path.h:1190
const auto & index_merge() const
Definition: access_path.h:638
struct AccessPath::@63::@80 index_skip_scan
struct AccessPath::@63::@72 full_text_search
const auto & update_rows() const
Definition: access_path.h:894
double subquery_rows
The number of materialized rows (as opposed to the number of rows fetched by table_path).
Definition: access_path.h:1259
enum AccessPath::Type type
auto & alternative()
Definition: access_path.h:866
struct AccessPath::@63::@88 zero_rows_aggregated
auto & pushed_join_ref()
Definition: access_path.h:586
struct AccessPath::@63::@78 rowid_intersection
void set_cost(double val)
Definition: access_path.h:399
AccessPath * outer
Definition: access_path.h:1146
struct AccessPath::@63::@82 dynamic_index_range_scan
auto & index_skip_scan()
Definition: access_path.h:658
bool rewrite_semi_to_inner
Definition: access_path.h:1150
const auto & zero_rows_aggregated() const
Definition: access_path.h:726
auto & group_index_skip_scan()
Definition: access_path.h:666
struct AccessPath::@63::@94 sort
struct AccessPath::@63::@71 pushed_join_ref
const auto & eq_ref() const
Definition: access_path.h:582
int group_items_size
Definition: access_path.h:1285
bool use_order
Definition: access_path.h:957
struct AccessPath::@63::@77 index_merge
bool pfs_batch_mode
Definition: access_path.h:1164
auto & temptable_aggregate()
Definition: access_path.h:786
GroupIndexSkipScanParameters * param
Definition: access_path.h:1106
auto & rowid_intersection()
Definition: access_path.h:642
double init_cost() const
Definition: access_path.h:388
bool materialize_subqueries
Definition: access_path.h:1200
AccessPath * child
Definition: access_path.h:1134
bool allow_spill_to_disk
Definition: access_path.h:1148
Index_lookup * used_ref
Definition: access_path.h:1298
auto & mrr()
Definition: access_path.h:610
auto & sample_scan()
Definition: access_path.h:538
const auto & index_scan() const
Definition: access_path.h:550
const auto & fake_single_row() const
Definition: access_path.h:710
bool reject_multiple_rows
Definition: access_path.h:1233
bool allow_clustered_primary_key_scan
Definition: access_path.h:1054
const char * name
Definition: access_path.h:1302
bool use_limit
Definition: access_path.h:991
Window * window
Definition: access_path.h:1271
table_map tables_to_get_rowid_for
Definition: access_path.h:1151
struct AccessPath::@63::@98 stream
auto & materialize_information_schema_table()
Definition: access_path.h:818
auto & bka_join()
Definition: access_path.h:738
const auto & follow_tail() const
Definition: access_path.h:622
SJ_TMP_TABLE * weedout_table
Definition: access_path.h:1279
bool has_group_skip_scan
Whether this access path contains a GROUP_INDEX_SKIP_SCAN.
Definition: access_path.h:323
struct AccessPath::@63::@67 index_distance_scan
Index_lookup * ref
Definition: access_path.h:968
const auto & window() const
Definition: access_path.h:838
void set_init_once_cost(double val)
Definition: access_path.h:411
const auto & materialized_table_function() const
Definition: access_path.h:686
auto & unqualified_count()
Definition: access_path.h:690
bool keep_current_rowid
Definition: access_path.h:1003
bool using_extended_key_parts
Definition: access_path.h:1049
auto & nested_loop_join()
Definition: access_path.h:746
const auto & full_text_search() const
Definition: access_path.h:598
struct AccessPath::@63::@105 remove_duplicates_on_index
union AccessPath::@63 u
bool can_be_used_for_ror
Definition: access_path.h:1029
float rec_per_key
Definition: access_path.h:1157
Safety safe_for_rowid
Whether it is safe to get row IDs (for sorting) from this access path.
Definition: access_path.h:314
JOIN * join
Definition: access_path.h:1222
struct AccessPath::@63::@86 fake_single_row
struct AccessPath::@63::@84 unqualified_count
unsigned index
Definition: access_path.h:1025
struct AccessPath::@63::@76 index_range_scan
unsigned mrr_buf_size
Definition: access_path.h:1021
auto & remove_duplicates()
Definition: access_path.h:850
struct AccessPath::@63::@87 zero_rows
struct AccessPath::@63::@65 sample_scan
struct AccessPath::@63::@66 index_scan
RowIterator * iterator
If an iterator has been instantiated for this access path, points to the iterator.
Definition: access_path.h:384
struct AccessPath::@63::@64 table_scan
const auto & stream() const
Definition: access_path.h:806
struct AccessPath::@63::@74 mrr
const auto & remove_duplicates() const
Definition: access_path.h:854
auto & window()
Definition: access_path.h:834
bool need_rows_in_rowid_order
Definition: access_path.h:1033
struct AccessPath::@63::@70 eq_ref
Table_ref * table_list
Definition: access_path.h:1263
const auto & unqualified_count() const
Definition: access_path.h:694
void * secondary_engine_data
Auxiliary data used by a secondary storage engine while processing the access path during optimizatio...
Definition: access_path.h:527
void set_init_cost(double val)
Definition: access_path.h:405
void set_num_output_rows(double val)
Definition: access_path.h:901
struct AccessPath::@63::@83 materialized_table_function
bool is_covering
Definition: access_path.h:1082
const auto & mrr() const
Definition: access_path.h:614
void set_cost_before_filter(double val)
Definition: access_path.h:417
bool remove_duplicates
Definition: access_path.h:1212
table_map tables_to_update
Definition: access_path.h:1311
const auto & table_value_constructor() const
Definition: access_path.h:702
KEY * key
Definition: access_path.h:1184
auto & table_value_constructor()
Definition: access_path.h:698
auto & stream()
Definition: access_path.h:802
size_t key_len
Definition: access_path.h:1185
const OverflowBitset & subsumed_sargable_join_predicates() const
Definition: access_path.h:493
const auto & zero_rows() const
Definition: access_path.h:718
const auto & append() const
Definition: access_path.h:830
ha_rows offset
Definition: access_path.h:1231
int idx
Definition: access_path.h:956
auto & hash_join()
Definition: access_path.h:730
auto & cache_invalidator()
Definition: access_path.h:874
bool force_sort_rowids
Definition: access_path.h:1214
unsigned num_used_key_parts
Definition: access_path.h:1026
unsigned num_ranges
Definition: access_path.h:1018
ORDER * order
Definition: access_path.h:1210
auto & sort()
Definition: access_path.h:770
auto & fake_single_row()
Definition: access_path.h:706
struct AccessPath::@63::@97 limit_offset
ha_rows limit
Definition: access_path.h:1211
auto & follow_tail()
Definition: access_path.h:618
double m_num_output_rows
Expected number of output rows.
Definition: access_path.h:909
const auto & sample_scan() const
Definition: access_path.h:542
const JoinPredicate * join_predicate
Definition: access_path.h:1147
const auto & const_table() const
Definition: access_path.h:606
struct AccessPath::@63::@92 nested_loop_semijoin_with_duplicate_removal
const auto & dynamic_index_range_scan() const
Definition: access_path.h:678
const auto & table_scan() const
Definition: access_path.h:534
unsigned mrr_flags
Definition: access_path.h:1020
int ref_slice
Definition: access_path.h:1226
OverflowBitset filter_predicates
Bitmap of WHERE predicates that we are including on this access path, referring to the “predicates” a...
Definition: access_path.h:454
bool can_be_used_for_imerge
Definition: access_path.h:1036
bool forced_by_hint
Definition: access_path.h:1053
auto & limit_offset()
Definition: access_path.h:794
AccessPath * inner
Definition: access_path.h:1146
QUICK_RANGE * range
Definition: access_path.h:963
bool provide_rowid
Definition: access_path.h:1243
struct AccessPath::@63::@93 filter
const auto & index_range_scan() const
Definition: access_path.h:630
const auto & ref() const
Definition: access_path.h:566
bool forced_by_dbug
Whether this access path is forced preferred over all others by means of a SET DEBUG force_subplan_0x...
Definition: access_path.h:328
Item_func_match * ft_func
Definition: access_path.h:992
ha_rows * send_records_override
Definition: access_path.h:1236
auto & table_scan()
Definition: access_path.h:530
const auto & hash_join() const
Definition: access_path.h:734
QEP_TAB * qep_tab
Definition: access_path.h:1110
Table_function * table_function
Definition: access_path.h:1114
auto & zero_rows_aggregated()
Definition: access_path.h:722
struct AccessPath::@63::@73 const_table
const auto & sort() const
Definition: access_path.h:774
struct AccessPath::@63::@95 aggregate
bool unwrap_rollup
Definition: access_path.h:1213
Type
Definition: access_path.h:228
@ FOLLOW_TAIL
Definition: access_path.h:243
@ FILTER
Definition: access_path.h:267
@ PUSHED_JOIN_REF
Definition: access_path.h:239
@ ZERO_ROWS_AGGREGATED
Definition: access_path.h:256
@ UPDATE_ROWS
Definition: access_path.h:285
@ AGGREGATE
Definition: access_path.h:269
@ BKA_JOIN
Definition: access_path.h:263
@ ZERO_ROWS
Definition: access_path.h:255
@ CONST_TABLE
Definition: access_path.h:241
@ GROUP_INDEX_SKIP_SCAN
Definition: access_path.h:249
@ SAMPLE_SCAN
Definition: access_path.h:233
@ INDEX_RANGE_SCAN
Definition: access_path.h:244
@ UNQUALIFIED_COUNT
Definition: access_path.h:258
@ EQ_REF
Definition: access_path.h:238
@ FAKE_SINGLE_ROW
Definition: access_path.h:254
@ MATERIALIZE_INFORMATION_SCHEMA_TABLE
Definition: access_path.h:274
@ WINDOW
Definition: access_path.h:276
@ REF_OR_NULL
Definition: access_path.h:237
@ MATERIALIZE
Definition: access_path.h:273
@ NESTED_LOOP_SEMIJOIN_WITH_DUPLICATE_REMOVAL
Definition: access_path.h:262
@ ROWID_UNION
Definition: access_path.h:247
@ INDEX_SKIP_SCAN
Definition: access_path.h:248
@ MRR
Definition: access_path.h:242
@ CACHE_INVALIDATOR
Definition: access_path.h:281
@ INDEX_SCAN
Definition: access_path.h:234
@ TABLE_VALUE_CONSTRUCTOR
Definition: access_path.h:253
@ WEEDOUT
Definition: access_path.h:277
@ MATERIALIZED_TABLE_FUNCTION
Definition: access_path.h:257
@ REMOVE_DUPLICATES_ON_INDEX
Definition: access_path.h:279
@ TABLE_SCAN
Definition: access_path.h:232
@ REF
Definition: access_path.h:236
@ TEMPTABLE_AGGREGATE
Definition: access_path.h:270
@ LIMIT_OFFSET
Definition: access_path.h:271
@ APPEND
Definition: access_path.h:275
@ NESTED_LOOP_JOIN
Definition: access_path.h:261
@ INDEX_MERGE
Definition: access_path.h:245
@ FULL_TEXT_SEARCH
Definition: access_path.h:240
@ ALTERNATIVE
Definition: access_path.h:280
@ STREAM
Definition: access_path.h:272
@ REMOVE_DUPLICATES
Definition: access_path.h:278
@ ROWID_INTERSECTION
Definition: access_path.h:246
@ DYNAMIC_INDEX_RANGE_SCAN
Definition: access_path.h:250
@ DELETE_ROWS
Definition: access_path.h:284
@ SORT
Definition: access_path.h:268
@ INDEX_DISTANCE_SCAN
Definition: access_path.h:235
@ HASH_JOIN
Definition: access_path.h:264
bool retrieve_full_rows
Definition: access_path.h:1065
double m_init_once_cost
Of init_cost, how much of the initialization needs only to be done once per query block.
Definition: access_path.h:933
const auto & rowid_union() const
Definition: access_path.h:654
const TABLE * table
Definition: access_path.h:1183
const auto & index_skip_scan() const
Definition: access_path.h:662
struct AccessPath::@63::@69 ref_or_null
auto & dynamic_index_range_scan()
Definition: access_path.h:674
const auto & pushed_join_ref() const
Definition: access_path.h:590
auto & remove_duplicates_on_index()
Definition: access_path.h:858
table_map immediate_tables
Definition: access_path.h:1307
double m_cost_before_filter
If no filter, identical to cost.
Definition: access_path.h:937
double cost() const
Definition: access_path.h:386
int mrr_flags
Definition: access_path.h:1002
auto & full_text_search()
Definition: access_path.h:594
const auto & materialize() const
Definition: access_path.h:814
int ordering_state
Which ordering the rows produced by this path follow, if any (see interesting_orders....
Definition: access_path.h:378
auto & eq_ref()
Definition: access_path.h:578
JoinType join_type
Definition: access_path.h:1155
struct AccessPath::@63::@106 alternative
struct AccessPath::@63::@96 temptable_aggregate
const auto & limit_offset() const
Definition: access_path.h:798
MaterializePathParameters * param
Definition: access_path.h:1254
const char * cause
Definition: access_path.h:1137
struct AccessPath::@63::@89 hash_join
auto & update_rows()
Definition: access_path.h:890
auto & index_merge()
Definition: access_path.h:634
auto & aggregate()
Definition: access_path.h:778
struct AccessPath::@63::@101 append
double m_cost
Expected cost to read all of this access path once.
Definition: access_path.h:912
struct AccessPath::@63::@99 materialize
const auto & group_index_skip_scan() const
Definition: access_path.h:670
auto & zero_rows()
Definition: access_path.h:714
AccessPath * subquery_path
Definition: access_path.h:1221
Mem_root_array< AppendPathParameters > * children
Definition: access_path.h:1267
struct AccessPath::@63::@91 nested_loop_join
const auto & nested_loop_join() const
Definition: access_path.h:750
bool already_expanded_predicates
Definition: access_path.h:1165
struct AccessPath::@63::@75 follow_tail
const auto & remove_duplicates_on_index() const
Definition: access_path.h:862
Temp_table_param * temp_table_param
Definition: access_path.h:1223
auto & nested_loop_semijoin_with_duplicate_removal()
Definition: access_path.h:754
bool reverse
Definition: access_path.h:958
AccessPath * table_scan_path
Definition: access_path.h:1294
enum tablesample_type sampling_type
Definition: access_path.h:952
struct AccessPath::@63::@79 rowid_union
const auto & materialize_information_schema_table() const
Definition: access_path.h:822
double subquery_cost
The total cost of executing the queries that we materialize.
Definition: access_path.h:1256
bool geometry
Definition: access_path.h:1042
bool count_examined_rows
Whether this access path counts as one that scans a base table, and thus should be counted towards ex...
Definition: access_path.h:320
unsigned loosescan_key_len
Definition: access_path.h:1291
auto & index_distance_scan()
Definition: access_path.h:554
auto & ref()
Definition: access_path.h:562
struct AccessPath::@63::@90 bka_join
double first_row_cost() const
The cost of reading the first row.
Definition: access_path.h:391
table_map tables_to_delete_from
Definition: access_path.h:1306
double init_once_cost() const
Definition: access_path.h:395
IndexSkipScanParameters * param
Definition: access_path.h:1097
const OverflowBitset & applied_sargable_join_predicates() const
Definition: access_path.h:473
Mem_root_array< AccessPath * > * children
Definition: access_path.h:1055
struct AccessPath::@63::@81 group_index_skip_scan
OverflowBitset delayed_predicates
Bitmap of WHERE predicates that touch tables we have joined in, but that we could not apply yet (for ...
Definition: access_path.h:482
AccessPath * table_path
Definition: access_path.h:1115
const auto & aggregate() const
Definition: access_path.h:782
TABLE * table
Definition: access_path.h:947
auto & append()
Definition: access_path.h:826
double cost_before_filter() const
Definition: access_path.h:397
struct AccessPath::@63::@109 update_rows
const auto & weedout() const
Definition: access_path.h:846
const auto & cache_invalidator() const
Definition: access_path.h:878
double sampling_percentage
Definition: access_path.h:951
bool needs_buffering
Definition: access_path.h:1275
int8_t immediate_update_delete_table
For UPDATE and DELETE statements: The node index of a table which can be updated or deleted from imme...
Definition: access_path.h:372
QUICK_RANGE ** ranges
Definition: access_path.h:1017
bool is_unique
Definition: access_path.h:985
const auto & alternative() const
Definition: access_path.h:870
Safety
A general enum to describe the safety of a given operation.
Definition: access_path.h:295
@ SAFE_IF_SCANNED_ONCE
The given operation is safe if this access path is scanned once, but not if it's scanned multiple tim...
Definition: access_path.h:304
@ UNSAFE
The given operation is unsafe on this access path, no matter how many or few times it's scanned.
Definition: access_path.h:310
@ SAFE
The given operation is always safe on this access path.
Definition: access_path.h:297
auto & const_table()
Definition: access_path.h:602
unsigned mrr_length_per_rec
Definition: access_path.h:1156
struct AccessPath::@63::@107 cache_invalidator
const auto & rowid_intersection() const
Definition: access_path.h:646
Mem_root_array< Item_values_column * > * output_refs
Definition: access_path.h:1121
auto & index_range_scan()
Definition: access_path.h:626
double num_output_rows() const
Definition: access_path.h:899
double num_output_rows_before_filter
If no filter, identical to num_output_rows.
Definition: access_path.h:432
const auto & ref_or_null() const
Definition: access_path.h:574
Filesort * filesort
Definition: access_path.h:1204
struct AccessPath::@63::@103 weedout
struct AccessPath::@63::@100 materialize_information_schema_table
bool store_rowids
Definition: access_path.h:1149
const auto & nested_loop_semijoin_with_duplicate_removal() const
Definition: access_path.h:758
Definition: access_path.h:179
JOIN * join
Definition: access_path.h:181
AccessPath * path
Definition: access_path.h:180
Definition: group_index_skip_scan_plan.h:45
Logically a part of AccessPath::index_skip_scan(), but is too large, so split out into its own struct...
Definition: index_skip_scan_plan.h:73
Structure used for index-based lookups.
Definition: sql_opt_exec_shared.h:67
A specification that two specific relational expressions (e.g., two tables, or a table and a join bet...
Definition: access_path.h:79
int semijoin_group_size
Definition: access_path.h:125
FunctionalDependencySet functional_dependencies
Definition: access_path.h:96
Mem_root_array< int > functional_dependencies_idx
Definition: access_path.h:101
RelationalExpression * expr
Definition: access_path.h:80
double selectivity
Definition: access_path.h:81
int ordering_idx_needed_for_semijoin_rewrite
Definition: access_path.h:119
Item ** semijoin_group
Definition: access_path.h:124
size_t estimated_bytes_per_row
Definition: access_path.h:85
Definition: range_optimizer.h:55
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:83
Definition: materialize_path_parameters.h:42
AccessPath * subquery_path
Definition: materialize_path_parameters.h:43
int select_number
Definition: materialize_path_parameters.h:44
JOIN * join
Definition: materialize_path_parameters.h:45
bool copy_items
Definition: materialize_path_parameters.h:47
Temp_table_param * temp_table_param
Definition: materialize_path_parameters.h:48
bool disable_deduplication_by_hash_field
Definition: materialize_path_parameters.h:46
Definition: materialize_path_parameters.h:40
bool rematerialize
True if rematerializing on every Init() call (e.g., because we have a dependency on a value from outs...
Definition: materialize_path_parameters.h:80
DedupType deduplication_reason
Definition: materialize_path_parameters.h:111
Mem_root_array< Operand > m_operands
Definition: materialize_path_parameters.h:58
Common_table_expr * cte
If materializing a CTE, points to it (see m_cte), otherwise nullptr.
Definition: materialize_path_parameters.h:65
DedupType
The context for which deduplication is being used.
Definition: materialize_path_parameters.h:106
@ NO_DEDUP
Definition: materialize_path_parameters.h:109
bool reject_multiple_rows
True if this is the top level iterator for a materialized derived table transformed from a scalar sub...
Definition: materialize_path_parameters.h:99
ha_rows limit_rows
Used for when pushing LIMIT down to MaterializeIterator; this is more efficient than having a LimitOf...
Definition: materialize_path_parameters.h:92
TABLE * table
Handle to table to materialize into.
Definition: materialize_path_parameters.h:62
int ref_slice
Definition: materialize_path_parameters.h:74
Query_expression * unit
The query expression we are materializing.
Definition: materialize_path_parameters.h:68
Mem_root_array< const AccessPath * > * invalidators
Definition: materialize_path_parameters.h:59
Definition: table.h:289
A position of table within a join order.
Definition: sql_select.h:355
A filter of some sort that is not a join condition (those are stored in JoinPredicate objects).
Definition: access_path.h:133
hypergraph::NodeMap total_eligibility_set
Definition: access_path.h:146
bool was_join_condition
Definition: access_path.h:159
Mem_root_array< int > functional_dependencies_idx
Definition: access_path.h:171
FunctionalDependencySet functional_dependencies
Definition: access_path.h:170
int source_multiple_equality_idx
Definition: access_path.h:167
hypergraph::NodeMap used_nodes
Definition: access_path.h:137
Item * condition
Definition: access_path.h:134
double selectivity
Definition: access_path.h:148
Mem_root_array< ContainedSubquery > contained_subqueries
Definition: access_path.h:176
Represents an expression tree in the relational algebra of joins.
Definition: relational_expression.h:147
Definition: table.h:1421
tablesample_type
Definition: tablesample.h:27