MySQL 8.4.2
Source Code Documentation
rowid_ordered_retrieval.h
Go to the documentation of this file.
1/* Copyright (c) 2000, 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_RANGE_OPTIMIZER_ROWID_ORDERED_RETRIEVAL_H_
25#define SQL_RANGE_OPTIMIZER_ROWID_ORDERED_RETRIEVAL_H_
26
27#include <assert.h>
28#include <sys/types.h>
29#include <vector>
30
31#include "my_alloc.h"
32#include "my_inttypes.h"
33#include "priority_queue.h"
34#include "sql/handler.h"
38#include "sql/sql_list.h"
39#include "sql/table.h"
40
41class String;
42class THD;
43struct MY_BITMAP;
44
45/*
46 Rowid-Ordered Retrieval (ROR) index intersection quick select.
47 This quick select produces intersection of row sequences returned
48 by several IndexRangeScanIterators it "merges".
49
50 All merged IndexRangeScanIterators must return rowids in rowid order.
51 RowIDIntersectionIterator will return rows in rowid order, too.
52
53 All merged quick selects retrieve {rowid, covered_fields} tuples (not full
54 table records).
55 RowIDIntersectionIterator retrieves full records if it is not being used
56 by RowIDUnionIterator and all merged quick selects together don't
57 cover needed all fields.
58
59 If one of the merged quick selects is a Clustered PK range scan, it is
60 used only to filter rowid sequence produced by other merged quick selects.
61*/
62
64 public:
66 THD *thd, MEM_ROOT *return_mem_root, TABLE *table_arg,
71
72 bool Init() override;
73 int Read() override;
74 uchar *last_rowid() const override {
76 return m_last_rowid;
77 }
78
79 private:
80 /*
81 Range quick selects this intersection consists of, not including
82 cpk_quick.
83 */
85
86 /*
87 Merged quick select that uses Clustered PK, if there is one. This quick
88 select is not used for row retrieval, it is used for row retrieval.
89 */
91
92 /*
93 If true, do retrieve full table rows.
94
95 The way this works is somewhat convoluted; this is my (sgunders')
96 understanding as of September 2021:
97
98 For covering indexes (for some complicated value of “covering” if there are
99 multiple indexes involved), we always use index-only scans; otherwise,
100 the index range scan uses a normal scan (table->file->set_keyread(false)),
101 which does first a lookup into the index, and then the secondary lookup to
102 get the actual row.
103
104 However, for intersection scans, we don't actually need all sub-scans to
105 fetch the actual row; that's just a waste, especially since in most cases,
106 we won't need the row. So in this case, the _intention_ is that we'd always
107 turn on index-only scans, although it seems the code for this was never
108 written. The idea is that the intersection iterator then is responsible for
109 doing a kind of “fetch after the fact” once the intersection has yielded a
110 row (unless we're covering). This is done by
111
112 table->file->ha_rnd_pos(table->record[0], rowid);
113
114 although index merge uses position() instead of ha_rnd_pos().
115 Both seem to have the (undocumented?) side effect of actually fetching the
116 row even on an index-only scan. This is the reason why we need the
117 intersection iterator to reuse the handler reuse for MyISAM; otherwise, we'd
118 never actually get the row, since it's stored privately in MI_INFO and not
119 in the row ID.
120
121 But if there's something above the intersection scan again (which can only
122 be a union), it's the same game; when we find a row, it might be a duplicate
123 of the same row ID from another sub-iterator of the union (whether a range
124 scan or an intersection of range scans), and then it's not worth it to fetch
125 the entire row. So that's why the intersection scan needs to be told “no,
126 don't do ha_rnd_pos; your parent will be doing that if it's interested”. And
127 that is what this variable is for.
128 */
130
131 /* in top-level quick select, true if merged scans where initialized */
133
136 bool inited = false;
137
139};
140
141/*
142 Comparison function to be used RowIDUnionIterator::queue priority
143 queue.
144*/
149 down_cast<RowIDCapableRowIterator *>(a->real_iterator());
151 down_cast<RowIDCapableRowIterator *>(b->real_iterator());
152 return m_file->cmp_ref(real_a->last_rowid(), real_b->last_rowid()) > 0;
153 }
155};
156
157/*
158 Rowid-Ordered Retrieval index union select.
159 This quick select produces union of row sequences returned by several
160 quick select it "merges".
161
162 All merged quick selects must return rowids in rowid order.
163 RowIDUnionIterator will return rows in rowid order, too.
164
165 All merged quick selects are set not to retrieve full table records.
166 ROR-union quick select always retrieves full records.
167
168*/
169
171 public:
173 THD *thd, MEM_ROOT *return_mem_root, TABLE *table,
175 ~RowIDUnionIterator() override;
176
177 bool Init() override;
178 int Read() override;
179
180 private:
182
184 std::vector<RowIterator *, Malloc_allocator<RowIterator *>>,
186 queue; /* Priority queue for merge operation */
187
188 MEM_ROOT *mem_root; /* Memory pool for this and merged quick selects data. */
189 uchar *cur_rowid; /* buffer used in Read() */
190 uchar *prev_rowid; /* rowid of last row returned by Read() */
191 bool have_prev_rowid; /* true if prev_rowid has valid data */
192 uint rowid_length; /* table rowid length */
193
195 bool inited = false;
196};
197
198#endif // SQL_RANGE_OPTIMIZER_ROWID_ORDERED_RETRIEVAL_H_
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:426
Implements a priority queue using a vector-based max-heap.
Definition: priority_queue.h:104
An interface for RowIterators that have a given row ID, ie., they can be children in ROR (rowid-order...
Definition: rowid_capable_row_iterator.h:36
virtual uchar * last_rowid() const =0
Definition: rowid_ordered_retrieval.h:63
int Read() override
Read a single row.
Definition: rowid_ordered_retrieval.cc:323
bool init_ror_merged_scan()
Definition: rowid_ordered_retrieval.cc:170
const bool need_rows_in_rowid_order
Definition: rowid_ordered_retrieval.h:134
bool inited
Definition: rowid_ordered_retrieval.h:136
RowIDIntersectionIterator(THD *thd, MEM_ROOT *return_mem_root, TABLE *table_arg, bool retrieve_full_rows, bool need_rows_in_rowid_order, Mem_root_array< unique_ptr_destroy_only< RowIterator > > children, unique_ptr_destroy_only< RowIterator > cpk_child)
Definition: rowid_ordered_retrieval.cc:48
Mem_root_array< unique_ptr_destroy_only< RowIterator > > m_children
Definition: rowid_ordered_retrieval.h:84
uchar * m_last_rowid
Definition: rowid_ordered_retrieval.h:135
uchar * last_rowid() const override
Definition: rowid_ordered_retrieval.h:74
unique_ptr_destroy_only< RowIterator > m_cpk_child
Definition: rowid_ordered_retrieval.h:90
~RowIDIntersectionIterator() override
Definition: rowid_ordered_retrieval.cc:226
bool Init() override
Initialize or reinitialize the iterator.
Definition: rowid_ordered_retrieval.cc:199
bool retrieve_full_rows
Definition: rowid_ordered_retrieval.h:129
bool scans_inited
Definition: rowid_ordered_retrieval.h:132
Definition: rowid_ordered_retrieval.h:170
uchar * cur_rowid
Definition: rowid_ordered_retrieval.h:189
Priority_queue< RowIterator *, std::vector< RowIterator *, Malloc_allocator< RowIterator * > >, Quick_ror_union_less > queue
Definition: rowid_ordered_retrieval.h:186
uint rowid_length
Definition: rowid_ordered_retrieval.h:192
Mem_root_array< unique_ptr_destroy_only< RowIterator > > m_children
Definition: rowid_ordered_retrieval.h:181
RowIDUnionIterator(THD *thd, MEM_ROOT *return_mem_root, TABLE *table, Mem_root_array< unique_ptr_destroy_only< RowIterator > > children)
Definition: rowid_ordered_retrieval.cc:230
~RowIDUnionIterator() override
Definition: rowid_ordered_retrieval.cc:294
bool have_prev_rowid
Definition: rowid_ordered_retrieval.h:191
bool inited
Definition: rowid_ordered_retrieval.h:195
bool scans_inited
Definition: rowid_ordered_retrieval.h:194
uchar * prev_rowid
Definition: rowid_ordered_retrieval.h:190
int Read() override
Read a single row.
Definition: rowid_ordered_retrieval.cc:434
bool Init() override
Initialize or reinitialize the iterator.
Definition: rowid_ordered_retrieval.cc:242
MEM_ROOT * mem_root
Definition: rowid_ordered_retrieval.h:188
A context for reading through a single table using a chosen access method: index read,...
Definition: row_iterator.h:82
THD * thd() const
Definition: row_iterator.h:228
virtual RowIterator * real_iterator()
If this iterator is wrapping a different iterator (e.g.
Definition: row_iterator.h:224
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:167
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
Definition: row_iterator.h:234
TABLE * table() const
Definition: row_iterator.h:246
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4573
virtual int cmp_ref(const uchar *ref1, const uchar *ref2) const
Compare two positions.
Definition: handler.h:6110
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:477
Some integer typedefs for easier portability.
unsigned char uchar
Definition: my_inttypes.h:52
Definition: os0file.h:89
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:83
Definition: my_bitmap.h:43
Definition: rowid_ordered_retrieval.h:145
const handler * m_file
Definition: rowid_ordered_retrieval.h:154
Quick_ror_union_less(const handler *file)
Definition: rowid_ordered_retrieval.h:146
bool operator()(RowIterator *a, RowIterator *b)
Definition: rowid_ordered_retrieval.h:147
Definition: table.h:1406