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