MySQL 8.4.2
Source Code Documentation
indexed_cells.h
Go to the documentation of this file.
1/* Copyright (c) 2016, 2024, Oracle and/or its affiliates.
2
3This program is free software; you can redistribute it and/or modify it under
4the terms of the GNU General Public License, version 2.0, as published by the
5Free Software Foundation.
6
7This program is designed to work with certain software (including
8but not limited to OpenSSL) that is licensed under separate terms,
9as designated in a particular file or component or in included license
10documentation. The authors of MySQL hereby grant you an additional
11permission to link the program and your derivative works with the
12separately licensed software that they have either included with
13the program or referenced in the documentation.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
18for more details.
19
20You should have received a copy of the GNU General Public License along with
21this program; if not, write to the Free Software Foundation, Inc.,
2251 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24/** @file storage/temptable/include/temptable/indexed_cells.h
25TempTable Indexed Cells declaration. */
26
27#ifndef TEMPTABLE_INDEXED_CELLS_H
28#define TEMPTABLE_INDEXED_CELLS_H
29
30#include <array>
31#include <cstddef>
32#include <limits>
33
34#include "sql/key.h"
35#include "sql/sql_const.h"
40
41namespace temptable {
42
43class Index;
44
45/** Indexed cells represent one or more cells that are covered by an index. */
47 public:
48 /** Construct from a MySQL indexed cells (eg index_read() input buffer). */
50 /** [in] Search cells in "index_read() input" format. These must remain
51 * valid during the lifetime of the created `Indexed_cells` object. */
52 const unsigned char *mysql_search_cells,
53 /** [in] The length of `mysql_search_cells` in bytes. */
54 uint16_t mysql_search_cells_length,
55 /** [in] MySQL index, used for querying metadata. */
56 const Index &index);
57
58 /** Construct from a mysql row. The row must remain valid during the
59 * lifetime of the created `Indexed_cells` object. */
61 /** [in] MySQL row. */
62 const unsigned char *mysql_row,
63 /** [in] MySQL index whose cells this `Indexed_cells` represents. */
64 const Index &index);
65
66 /** Construct from a row in a table. The row must remain valid during the
67 * lifetime of the created `Indexed_cells` object. */
69 /** [in] Row from which to create the indexed cells. */
70 const Row &row,
71 /** [in] MySQL index, used for querying metadata. */
72 const Index &index);
73
74 /** Get the row of these indexed cells. There is no row if this Indexed_cells
75 * object has been created from a MySQL search cells (Handler::index_read()
76 * input), so this method must not be called in this case.
77 * @return row, an element of Table::m_rows */
78 Storage::Element *row() const;
79
80 /** Export the row of these indexed cells in the mysql row format
81 * (write_row()). As with the `row()` method, this one does not make sense
82 * and must not be called if the current Indexed_cells object has been
83 * created from MySQL search cells. */
85 /** [in] Metadata for the columns that constitute the exported row. */
86 const Columns &columns,
87 /** [out] Buffer to write the MySQL row into. */
88 unsigned char *mysql_row,
89 /** [in] Presumed length of the mysql row in bytes. */
90 size_t mysql_row_length) const;
91
92 /** Get the number of indexed cells.
93 * @return number of indexed cells */
94 size_t number_of_cells() const;
95
96 /** Set the number of indexed cells. It only makes sense to reduce the number
97 * in order to compare less cells for the purposes of prefix search. We treat
98 * (10) == (10, 20). */
99 void number_of_cells(size_t n);
100
101 /** Get a given indexed cell.
102 * @return cell */
103 Cell cell(
104 /** [in] Index of the cell within the indexed cells, must be in
105 * [0, number_of_cells()). */
106 size_t i,
107 /** [in] Index to which the current objects belongs, used for
108 * querying metadata. */
109 const Index &index) const;
110
111 /** Compare to another indexed cells object. Each cell is compared
112 * individually until a differing cells are found. If the compared
113 * objects contain different number of cells and all cells are equal
114 * up to the smaller object, then the objects are considered equal.
115 * E.g. (10, 15) == (10, 15, 23).
116 * @retval <0 if this < rhs
117 * @retval 0 if this == rhs
118 * @retval >0 if this > rhs */
119 int compare(
120 /** [in] Indexed cells to compare with the current object. */
121 const Indexed_cells &rhs,
122 /** [in] Index, used for querying metadata. */
123 const Index &index) const;
124
125 private:
126 /** Enum that designates where the actual user data is stored. */
127 enum class Data_location : uint8_t {
128 /** The data is in a MySQL buffer in index_read() input format (MySQL
129 * search cells). */
131 /** The data is in a MySQL buffer in write_row() format (MySQL row). */
133 /** The data is in `temptable::Row`. */
134 ROW,
135 };
136
137 /** Generate a cell from a `temptable::Row` object with a possibly reduced
138 * length, if a prefix index is used. */
139 static Cell cell_from_row(
140 /** [in] Indexed cell number in the index. E.g. if we have a row
141 * (a, b, c, d) and an index on (b, c) and we want the cell `c`,
142 * then this will be 1. */
143 size_t i,
144 /** [in] Index to which the current objects belongs, used for
145 * querying metadata. */
146 const Index &index,
147 /** [in] Row that contains the data. */
148 const Row &row);
149
150 /** Derive the Nth cell if
151 * `m_data_location == Data_location::MYSQL_BUF_INDEX_READ`.
152 * @return Nth cell */
154 /** [in] Index of the cell within the indexed cells, must be in
155 * [0, number_of_cells()). */
156 size_t i,
157 /** [in] Index, for querying metadata via the MySQL index. */
158 const Index &index) const;
159
160 /** Flag indicating whether we are interpreting MySQL buffer or we
161 * have references to a `temptable::Row` object. */
163
164 /** Number of cells that are indexed. */
166
167 static_assert(std::numeric_limits<decltype(m_number_of_cells)>::max() >=
169 "m_number_of_cells is not large enough to store the maximum "
170 "number of indexed cells");
171
172 /** MySQL search cells' length, used only when
173 * `m_data_location == MYSQL_BUF_INDEX_READ`. */
174 uint16_t m_length;
175
176 static_assert(
177 std::numeric_limits<decltype(m_length)>::max() >= MAX_KEY_LENGTH,
178 "m_length is not large enough to store the maximum length of an index");
179
180 /** Save space by putting the members in a union. Exactly one of those is
181 * used. */
182 union {
183 /** Pointer to one of:
184 * - MySQL search cells buffer (index_read() input format)
185 * used when m_data_location == MYSQL_BUF_INDEX_READ or
186 * - MySQL row in write_row() format
187 * used when m_data_location == MYSQL_BUF_WRITE_ROW. */
188 const unsigned char *m_mysql_buf;
189
190 /** Pointer to the row, used when m_data_location == ROW. */
191 const Row *m_row;
192 };
193};
194
195/** Indexed cells comparator (a < b). */
197 public:
198 explicit Indexed_cells_less(const Index &index);
199
200 bool operator()(const Indexed_cells &lhs, const Indexed_cells &rhs) const;
201
202 private:
204};
205
206/** Indexed cells hasher. */
208 public:
209 explicit Indexed_cells_hash(const Index &index);
210
211 size_t operator()(const Indexed_cells &indexed_cells) const;
212
213 private:
215};
216
217/** Indexed cells comparator (a == b). */
219 public:
220 explicit Indexed_cells_equal_to(const Index &index);
221
222 bool operator()(const Indexed_cells &lhs, const Indexed_cells &rhs) const;
223
224 private:
226};
227
228/* Implementation of inlined methods. */
229
231 /*
232 switch (m_data_location) {
233 case Data_location::MYSQL_BUF_INDEX_READ:
234 my_abort();
235 case Data_location::MYSQL_BUF_WRITE_ROW:
236 return ...;
237 case Data_location::ROW:
238 return ...;
239 }
240 my_abort(); <-- this is executed when m_data_location == Data_location::ROW
241 and compiled with "Studio 12.5 Sun C++ 5.14 SunOS_sparc 2016/05/31" !!!
242 So we use if-else instead of switch below. */
243
245 my_abort();
247 return const_cast<unsigned char *>(m_mysql_buf);
248 } else if (m_data_location == Data_location::ROW) {
249 return const_cast<Row *>(m_row);
250 }
251
252 /* Not reached. */
253 my_abort();
254}
255
257 unsigned char *mysql_row,
258 size_t mysql_row_length) const {
259 /*
260 switch (m_data_location) {
261 case Data_location::MYSQL_BUF_INDEX_READ:
262 my_abort();
263 case Data_location::MYSQL_BUF_WRITE_ROW:
264 ...
265 return;
266 case Data_location::ROW:
267 ...
268 return;
269 }
270 my_abort(); <-- this is executed when m_data_location == Data_location::ROW
271 and compiled with "Studio 12.5 Sun C++ 5.14 SunOS_sparc 2016/05/31" !!!
272 So we use if-else instead of switch below. */
273
275 my_abort();
277 memcpy(mysql_row, m_mysql_buf, mysql_row_length);
278 return;
279 } else if (m_data_location == Data_location::ROW) {
280 m_row->copy_to_mysql_row(columns, mysql_row, mysql_row_length);
281 return;
282 }
283
284 /* Not reached. */
285 my_abort();
286}
287
288inline size_t Indexed_cells::number_of_cells() const {
289 return m_number_of_cells;
290}
291
293 assert(n <= m_number_of_cells);
294
295 m_number_of_cells = static_cast<decltype(m_number_of_cells)>(n);
296}
297
299 : m_index(index) {}
300
302 const Indexed_cells &rhs) const {
303 return lhs.compare(rhs, m_index) < 0;
304}
305
307 : m_index(index) {}
308
310 : m_index(index) {}
311
313 const Indexed_cells &rhs) const {
314 return lhs.compare(rhs, m_index) == 0;
315}
316
317} /* namespace temptable */
318
319#endif /* TEMPTABLE_INDEXED_CELLS_H */
TempTable Cell declaration.
A cell is the intersection of a row and a column.
Definition: cell.h:42
Index interface.
Definition: index.h:45
Indexed cells comparator (a == b).
Definition: indexed_cells.h:218
Indexed_cells_equal_to(const Index &index)
Definition: indexed_cells.h:309
bool operator()(const Indexed_cells &lhs, const Indexed_cells &rhs) const
Definition: indexed_cells.h:312
const Index & m_index
Definition: indexed_cells.h:225
Indexed cells hasher.
Definition: indexed_cells.h:207
const Index & m_index
Definition: indexed_cells.h:214
size_t operator()(const Indexed_cells &indexed_cells) const
Definition: indexed_cells.cc:249
Indexed_cells_hash(const Index &index)
Definition: indexed_cells.h:306
Indexed cells comparator (a < b).
Definition: indexed_cells.h:196
Indexed_cells_less(const Index &index)
Definition: indexed_cells.h:298
bool operator()(const Indexed_cells &lhs, const Indexed_cells &rhs) const
Definition: indexed_cells.h:301
const Index & m_index
Definition: indexed_cells.h:203
Indexed cells represent one or more cells that are covered by an index.
Definition: indexed_cells.h:46
uint16_t m_length
MySQL search cells' length, used only when m_data_location == MYSQL_BUF_INDEX_READ.
Definition: indexed_cells.h:170
const unsigned char * m_mysql_buf
Pointer to one of:
Definition: indexed_cells.h:188
Data_location m_data_location
Flag indicating whether we are interpreting MySQL buffer or we have references to a temptable::Row ob...
Definition: indexed_cells.h:162
Cell cell_from_mysql_buf_index_read(size_t i, const Index &index) const
Derive the Nth cell if m_data_location == Data_location::MYSQL_BUF_INDEX_READ.
Definition: indexed_cells.cc:169
uint8_t m_number_of_cells
Number of cells that are indexed.
Definition: indexed_cells.h:165
Indexed_cells(const unsigned char *mysql_search_cells, uint16_t mysql_search_cells_length, const Index &index)
Construct from a MySQL indexed cells (eg index_read() input buffer).
Definition: indexed_cells.cc:44
Data_location
Enum that designates where the actual user data is stored.
Definition: indexed_cells.h:127
@ MYSQL_BUF_INDEX_READ
The data is in a MySQL buffer in index_read() input format (MySQL search cells).
@ ROW
The data is in temptable::Row.
@ MYSQL_BUF_WRITE_ROW
The data is in a MySQL buffer in write_row() format (MySQL row).
int compare(const Indexed_cells &rhs, const Index &index) const
Compare to another indexed cells object.
Definition: indexed_cells.cc:123
Cell cell(size_t i, const Index &index) const
Get a given indexed cell.
Definition: indexed_cells.cc:93
const Row * m_row
Pointer to the row, used when m_data_location == ROW.
Definition: indexed_cells.h:191
size_t number_of_cells() const
Get the number of indexed cells.
Definition: indexed_cells.h:288
Storage::Element * row() const
Get the row of these indexed cells.
Definition: indexed_cells.h:230
static Cell cell_from_row(size_t i, const Index &index, const Row &row)
Generate a cell from a temptable::Row object with a possibly reduced length, if a prefix index is use...
Definition: indexed_cells.cc:150
void export_row_to_mysql(const Columns &columns, unsigned char *mysql_row, size_t mysql_row_length) const
Export the row of these indexed cells in the mysql row format (write_row()).
Definition: indexed_cells.h:256
A row representation.
Definition: row.h:402
void copy_to_mysql_row(const Columns &columns, unsigned char *mysql_row, size_t mysql_row_length) const
Copy the row in a MySQL buffer (convert to write_row() format).
Definition: row.cc:114
void Element
Type used for elements.
Definition: storage.h:46
void my_abort()
Calls our own implementation of abort, if specified, or std's abort().
Definition: my_init.cc:261
Definition: allocator.h:45
std::vector< Column, Allocator< Column > > Columns
A type that designates all the columns of a table.
Definition: column.h:227
TempTable Row declarations.
File containing constants that can be used throughout the server.
constexpr const unsigned int MAX_REF_PARTS
Definition: sql_const.h:47
constexpr const unsigned int MAX_KEY_LENGTH
Definition: sql_const.h:48
TempTable Column declaration.
TempTable Storage.
int n
Definition: xcom_base.cc:509