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