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