MySQL 8.0.30
Source Code Documentation
key.h
Go to the documentation of this file.
1/* Copyright (c) 2006, 2022, 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 also distributed 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 included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef KEY_INCLUDED
24#define KEY_INCLUDED
25
26#include <assert.h>
27#include <stddef.h>
28#include <sys/types.h>
29
30#include "lex_string.h"
31#include "my_base.h" /* ha_rows, ha_key_alg */
32
33#include "my_inttypes.h"
34#include "sql/key_spec.h" /* fk_option */
35#include "sql/sql_plugin_ref.h" /* plugin_ref */
36
37class Field;
38class String;
39struct MY_BITMAP;
40struct TABLE;
41
43 public:
44 const char *name;
45 const char *unique_index_name;
54};
55
56class KEY_PART_INFO { /* Info about a key part */
57 public:
58 Field *field{nullptr};
59 uint offset{0}; /* offset in record (from 0) */
60 uint null_offset{0}; /* Offset to null_bit in record */
61 /* Length of key part in bytes, excluding NULL flag and length bytes */
63 /*
64 Number of bytes required to store the keypart value. This may be
65 different from the "length" field as it also counts
66 - possible NULL-flag byte (see HA_KEY_NULL_LENGTH)
67 - possible HA_KEY_BLOB_LENGTH bytes needed to store actual value length.
68 */
70 uint16 fieldnr{0}; /* Fieldnum in UNIREG */
71 uint16 key_part_flag{0}; /* 0 or HA_REVERSE_SORT */
73 uint8 null_bit{0}; /* Position to null_bit */
74 /**
75 True - if key part allows trivial binary comparison,
76 False - if charset collation function needs to be involved.
77
78 @note Not set for KEY_PART_INFO which are used for creating tables,
79 only set when table is opened or for internal temporary tables.
80
81 This value is set a bit too optimistically and disregards the way
82 in which value is stored in record (e.g. it is true for BLOB types).
83 So in practice key_cmp_if_same() also has to check key_part_flag for
84 presence of HA_BLOB_PART, HA_VAR_LENGTH_PART and HA_BIT_PART flags.
85 */
86 bool bin_cmp{false};
87 void init_from_field(Field *fld); /** Fill data from given field */
88 void init_flags(); /** Set key_part_flag from field */
89};
90
91/**
92 Data type for records per key estimates that are stored in the
93 KEY::rec_per_key_float[] array.
94*/
95typedef float rec_per_key_t;
96
97/**
98 If an entry for a key part in KEY::rec_per_key_float[] has this value,
99 then the storage engine has not provided a value for it and the rec_per_key
100 value for this key part is unknown.
101*/
102#define REC_PER_KEY_UNKNOWN -1.0f
103
104/**
105 If the "in memory estimate" for a table (in
106 ha_statistics.table_in_mem_estimate) or index (in
107 KEY::m_in_memory_estimate) is not known or not set by the storage
108 engine, then it should have the following value.
109*/
110#define IN_MEMORY_ESTIMATE_UNKNOWN -1.0
111
112class KEY {
113 public:
114 /** Tot length of key */
116 /** dupp key and pack flags */
117 ulong flags{0};
118 /** dupp key and pack flags for actual key parts */
119 ulong actual_flags{0};
120 /** How many key_parts */
122 /** How many key_parts including hidden parts */
124 /**
125 Key parts allocated for primary key parts extension but
126 not used due to some reasons(no primary key, duplicated key parts)
127 */
129 /** Should normally be = actual_key_parts */
132 /// @cond Doxygen_is_confused
133 enum ha_key_alg algorithm { HA_KEY_ALG_SE_SPECIFIC };
134 /// @endcond
135 /**
136 A flag which indicates that index algorithm for this key was explicitly
137 specified by user. So, for example, it should be mentioned in SHOW CREATE
138 TABLE output.
139 */
141 /**
142 Note that parser is used when the table is opened for use, and
143 parser_name is used when the table is being created.
144 */
145 /** Fulltext [pre]parser */
147 /** Fulltext [pre]parser name */
149
151 /** Name of key */
152 const char *name{nullptr};
153
154 /**
155 Array of AVG(number of records with the same field value) for 1st ... Nth
156 key part. 0 means 'not known'. For internally created temporary tables,
157 this member can be nullptr.
158 */
159 ulong *rec_per_key{nullptr};
160
161 /**
162 @retval true if this is a functional index (at least one of the key parts
163 is a functional key part).
164 @retval false if this isn't a functional index.
165 */
166 bool is_functional_index() const;
167
168 // Can't use in-class initialization as long as we memset-initialize
169 // the struct
172
173 private:
174 /**
175 Estimate for how much of the index data that is currently
176 available in a memory buffer. Valid range is [0..1]. This will be
177 initialized to a IN_MEMORY_ESTIMATE_UNKNOWN. If it still has this
178 value when used, it means that the storage engine has not supplied
179 a value.
180 */
182
183 /**
184 Array of AVG(number of records with the same field value) for 1st ... Nth
185 key part. For internally created temporary tables, this member can be
186 nullptr. This is the same information as stored in the above
187 rec_per_key array but using float values instead of integer
188 values. If the storage engine has supplied values in this array,
189 these will be used. Otherwise the value in rec_per_key will be
190 used. @todo In the next release the rec_per_key array above
191 should be removed and only this should be used.
192 */
194
195 public:
196 /**
197 True if this index is visible to the query optimizer. The optimizer may
198 only use visible indexes.
199 */
200 bool is_visible{false};
201
202 TABLE *table{nullptr};
203 LEX_CSTRING comment{nullptr, 0};
204
205 /**
206 Check if records per key estimate is available for given key part.
207
208 @param key_part_no key part number, must be in [0, KEY::actual_key_parts)
209
210 @return true if records per key estimate is available, false otherwise
211 */
212
213 bool has_records_per_key(uint key_part_no) const {
214 assert(key_part_no < actual_key_parts);
215
216 return ((rec_per_key_float &&
217 rec_per_key_float[key_part_no] != REC_PER_KEY_UNKNOWN) ||
218 (rec_per_key && rec_per_key[key_part_no] != 0));
219 }
220
221 /**
222 Retrieve an estimate for the average number of records per distinct value,
223 when looking only at the first key_part_no+1 columns.
224
225 If no record per key estimate is available for this key part,
226 REC_PER_KEY_UNKNOWN is returned.
227
228 @param key_part_no key part number, must be in [0, KEY::actual_key_parts)
229
230 @return Number of records having the same key value
231 @retval REC_PER_KEY_UNKNOWN no records per key estimate available
232 @retval != REC_PER_KEY_UNKNOWN record per key estimate
233 */
234
235 rec_per_key_t records_per_key(uint key_part_no) const {
236 assert(key_part_no < actual_key_parts);
237
238 /*
239 If the storage engine has provided rec per key estimates as float
240 then use this. If not, use the integer version.
241 */
242 if (rec_per_key_float[key_part_no] != REC_PER_KEY_UNKNOWN)
243 return rec_per_key_float[key_part_no];
244
245 return (rec_per_key[key_part_no] != 0)
246 ? static_cast<rec_per_key_t>(rec_per_key[key_part_no])
248 }
249
250 /**
251 Set the records per key estimate for a key part.
252
253 The records per key estimate must be in [1.0,..> or take the value
254 REC_PER_KEY_UNKNOWN.
255
256 @param key_part_no the number of key parts that the estimate includes,
257 must be in [0, KEY::actual_key_parts)
258 @param rec_per_key_est new records per key estimate
259 */
260
261 void set_records_per_key(uint key_part_no, rec_per_key_t rec_per_key_est) {
262 assert(key_part_no < actual_key_parts);
263 assert(rec_per_key_est == REC_PER_KEY_UNKNOWN || rec_per_key_est >= 1.0);
264 assert(rec_per_key_float != nullptr);
265
266 rec_per_key_float[key_part_no] = rec_per_key_est;
267 }
268
269 /**
270 Check if this key supports storing records per key information.
271
272 @return true if it has support for storing records per key information,
273 false otherwise.
274 */
275
277 if (rec_per_key_float != nullptr && rec_per_key != nullptr) return true;
278
279 return false;
280 }
281
282 /**
283 Assign storage for the rec per key arrays to the KEY object.
284
285 This is used when allocating memory and creating KEY objects. The
286 caller is responsible for allocating the correct size for the
287 two arrays. If needed, the caller is also responsible for
288 de-allocating the memory when the KEY object is no longer used.
289
290 @param rec_per_key_arg pointer to allocated array for storing
291 records per key using ulong
292 @param rec_per_key_float_arg pointer to allocated array for storing
293 records per key using float
294 */
295
296 void set_rec_per_key_array(ulong *rec_per_key_arg,
297 rec_per_key_t *rec_per_key_float_arg) {
298 rec_per_key = rec_per_key_arg;
299 rec_per_key_float = rec_per_key_float_arg;
300 }
301
302 /**
303 Move rec_per_key arrays from old to new position.
304
305 Ignore if arrays have not been set up yet.
306
307 @param rec_per_key_arg pointer to adjusted rec per key array
308 @param rec_per_key_float_arg pointer to adjusted rec per key array (float)
309 */
310
311 void move_rec_per_key(ulong *rec_per_key_arg,
312 rec_per_key_t *rec_per_key_float_arg) {
313 if (rec_per_key_float == nullptr || rec_per_key == nullptr) return;
314
315 rec_per_key_t *old_rec_per_key_float = rec_per_key_float;
316 ulong *old_rec_per_key = rec_per_key;
317 set_rec_per_key_array(rec_per_key_arg, rec_per_key_float_arg);
318 for (uint i = 0; i < actual_key_parts; i++) {
319 rec_per_key[i] = old_rec_per_key[i];
320 rec_per_key_float[i] = old_rec_per_key_float[i];
321 }
322 }
323
324 /**
325 Retrieve the estimate for how much of the index data that is available
326 in a memory buffer.
327
328 The returned estimate will be in the interval [0..1].
329
330 @return Estimate for how much of index data is available in memory buffer
331 @retval IN_MEMORY_ESTIMATE_UNKNOWN no estimate available
332 @retval != IN_MEMORY_ESTIMATE_UNKNOWN estimate
333 */
334
335 double in_memory_estimate() const {
337 (m_in_memory_estimate >= 0.0 && m_in_memory_estimate <= 1.0));
338
340 }
341
342 /**
343 Set the estimate for how much of this index that is currently in a
344 memory buffer.
345
346 The estimate must be in the interval [0..1] or take the value
347 IN_MEMORY_ESTIMATE_UNKNOWN.
348 */
349
352 (in_memory_estimate >= 0.0 && in_memory_estimate <= 1.0));
353
355 }
356};
357
358int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
359 uint *key_length, uint *keypart);
360void key_copy(uchar *to_key, const uchar *from_record, const KEY *key_info,
362void key_restore(uchar *to_record, const uchar *from_key, const KEY *key_info,
364bool key_cmp_if_same(const TABLE *table, const uchar *key, uint index,
366void key_unpack(String *to, TABLE *table, KEY *key);
367void field_unpack(String *to, Field *field, uint max_length, bool prefix_key);
368bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields);
369int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length);
370int key_cmp2(KEY_PART_INFO *key_part, const uchar *key1, uint key1_length,
371 const uchar *key2, uint key2_length);
372int key_rec_cmp(KEY **key_info, uchar *a, uchar *b);
373
374#endif /* KEY_INCLUDED */
Definition: key.h:42
LEX_CSTRING ref_db
Definition: key.h:49
uint key_parts
Definition: key.h:46
const char * name
Definition: key.h:44
LEX_CSTRING * fk_key_part
Definition: key.h:48
fk_option update_opt
Definition: key.h:52
const char * unique_index_name
Definition: key.h:45
fk_match_opt match_opt
Definition: key.h:53
LEX_CSTRING ref_table
Definition: key.h:50
fk_option delete_opt
Definition: key.h:51
LEX_CSTRING * key_part
Definition: key.h:47
Definition: field.h:573
Definition: key.h:56
void init_flags()
Fill data from given field.
Definition: table.cc:667
uint8 type
Definition: key.h:72
uint offset
Definition: key.h:59
void init_from_field(Field *fld)
Initialize KEY_PART_INFO from the given field.
Definition: table.cc:683
uint null_offset
Definition: key.h:60
uint16 fieldnr
Definition: key.h:70
uint16 length
Definition: key.h:62
uint16 store_length
Definition: key.h:69
Field * field
Definition: key.h:58
uint16 key_part_flag
Definition: key.h:71
uint8 null_bit
Definition: key.h:73
bool bin_cmp
True - if key part allows trivial binary comparison, False - if charset collation function needs to b...
Definition: key.h:86
Definition: key.h:112
ulong flags
dupp key and pack flags
Definition: key.h:117
ulong actual_flags
dupp key and pack flags for actual key parts
Definition: key.h:119
double in_memory_estimate() const
Retrieve the estimate for how much of the index data that is available in a memory buffer.
Definition: key.h:335
LEX_CSTRING comment
Definition: key.h:203
bool is_functional_index() const
Definition: key.cc:49
bool is_algorithm_explicit
A flag which indicates that index algorithm for this key was explicitly specified by user.
Definition: key.h:140
double m_in_memory_estimate
Estimate for how much of the index data that is currently available in a memory buffer.
Definition: key.h:181
KEY_PART_INFO * key_part
Definition: key.h:150
const char * name
Name of key.
Definition: key.h:152
rec_per_key_t records_per_key(uint key_part_no) const
Retrieve an estimate for the average number of records per distinct value, when looking only at the f...
Definition: key.h:235
bool is_visible
True if this index is visible to the query optimizer.
Definition: key.h:200
void set_records_per_key(uint key_part_no, rec_per_key_t rec_per_key_est)
Set the records per key estimate for a key part.
Definition: key.h:261
void move_rec_per_key(ulong *rec_per_key_arg, rec_per_key_t *rec_per_key_float_arg)
Move rec_per_key arrays from old to new position.
Definition: key.h:311
void set_in_memory_estimate(double in_memory_estimate)
Set the estimate for how much of this index that is currently in a memory buffer.
Definition: key.h:350
uint user_defined_key_parts
How many key_parts.
Definition: key.h:121
LEX_CSTRING engine_attribute
Definition: key.h:170
uint block_size
Definition: key.h:131
uint usable_key_parts
Should normally be = actual_key_parts.
Definition: key.h:130
rec_per_key_t * rec_per_key_float
Array of AVG(number of records with the same field value) for 1st ... Nth key part.
Definition: key.h:193
LEX_CSTRING secondary_engine_attribute
Definition: key.h:171
void set_rec_per_key_array(ulong *rec_per_key_arg, rec_per_key_t *rec_per_key_float_arg)
Assign storage for the rec per key arrays to the KEY object.
Definition: key.h:296
uint actual_key_parts
How many key_parts including hidden parts.
Definition: key.h:123
uint key_length
Tot length of key.
Definition: key.h:115
TABLE * table
Definition: key.h:202
plugin_ref parser
Note that parser is used when the table is opened for use, and parser_name is used when the table is ...
Definition: key.h:146
bool supports_records_per_key() const
Check if this key supports storing records per key information.
Definition: key.h:276
uint unused_key_parts
Key parts allocated for primary key parts extension but not used due to some reasons(no primary key,...
Definition: key.h:128
ulong * rec_per_key
Array of AVG(number of records with the same field value) for 1st ... Nth key part.
Definition: key.h:159
bool has_records_per_key(uint key_part_no) const
Check if records per key estimate is available for given key part.
Definition: key.h:213
LEX_CSTRING parser_name
Fulltext [pre]parser name.
Definition: key.h:148
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:166
static uint16 key1[1001]
Definition: hp_test2.cc:46
int key_rec_cmp(KEY **key_info, uchar *a, uchar *b)
Compare two records in index order.
Definition: key.cc:582
int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length)
Compare key in record buffer to a given key.
Definition: key.cc:447
#define REC_PER_KEY_UNKNOWN
If an entry for a key part in KEY::rec_per_key_float[] has this value, then the storage engine has no...
Definition: key.h:102
void key_restore(uchar *to_record, const uchar *from_key, const KEY *key_info, uint key_length)
Restore a key from some buffer to record.
Definition: key.cc:178
void field_unpack(String *to, Field *field, uint max_length, bool prefix_key)
Unpack a field and append it.
Definition: key.cc:309
bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)
Definition: key.cc:404
#define IN_MEMORY_ESTIMATE_UNKNOWN
If the "in memory estimate" for a table (in ha_statistics.table_in_mem_estimate) or index (in KEY::m_...
Definition: key.h:110
void key_copy(uchar *to_key, const uchar *from_record, const KEY *key_info, uint key_length)
Copy part of a record that forms a key or key prefix to a buffer.
Definition: key.cc:134
int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field, uint *key_length, uint *keypart)
Definition: key.cc:85
int key_cmp2(KEY_PART_INFO *key_part, const uchar *key1, uint key1_length, const uchar *key2, uint key2_length)
Compare two given keys.
Definition: key.cc:498
void key_unpack(String *to, TABLE *table, KEY *key)
Definition: key.cc:365
float rec_per_key_t
Data type for records per key estimates that are stored in the KEY::rec_per_key_float[] array.
Definition: key.h:95
bool key_cmp_if_same(const TABLE *table, const uchar *key, uint index, uint key_length)
Compare if a key has changed.
Definition: key.cc:266
fk_match_opt
Definition: key_spec.h:57
fk_option
Definition: key_spec.h:48
static uint key_length
Definition: mi_test1.cc:42
static uchar key2[100]
Definition: mi_test2.cc:58
This file includes constants used by all storage engines.
ha_key_alg
Definition: my_base.h:96
@ HA_KEY_ALG_SE_SPECIFIC
Used for cases when key algorithm which is supported by SE can't be described by one of other classes...
Definition: my_base.h:105
Some integer typedefs for easier portability.
uint8_t uint8
Definition: my_inttypes.h:62
unsigned char uchar
Definition: my_inttypes.h:51
uint16_t uint16
Definition: my_inttypes.h:64
required string key
Definition: replication_asynchronous_connection_failover.proto:59
Definition: mysql_lex_string.h:39
Definition: my_bitmap.h:42
Definition: table.h:1394
Definition: mi_test3.cc:54
Definition: sql_plugin_ref.h:44
unsigned int uint
Definition: uca-dump.cc:29