MySQL  8.0.27
Source Code Documentation
key_spec.h
Go to the documentation of this file.
1 /* Copyright (c) 2015, 2021, 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_SPEC_INCLUDED
24 #define KEY_SPEC_INCLUDED
25 
26 #include <sys/types.h>
27 
28 #include "lex_string.h"
29 #include "m_string.h"
30 #include "my_base.h"
31 #include "sql/mem_root_array.h"
32 #include "sql/sql_list.h"
33 
34 class Create_field;
35 class Item;
36 class THD;
37 struct MEM_ROOT;
38 
39 enum keytype {
46 };
47 
48 enum fk_option {
55 };
56 
62 };
63 
65 
67  public:
69  /**
70  A flag which indicates that index algorithm was explicitly specified
71  by user.
72  */
73  bool is_algorithm_explicit = false;
74  ulong block_size = 0;
77  bool is_visible = true;
78 
79  KEY_CREATE_INFO() = default;
80 
81  explicit KEY_CREATE_INFO(bool is_visible_arg) : is_visible(is_visible_arg) {}
82 
85 };
86 
88 
90  public:
91  Key_part_spec(Item *expression, enum_order order)
92  : m_is_ascending((order == ORDER_DESC) ? false : true),
95  m_prefix_length(0),
96  m_expression(expression),
97  m_has_expression(true) {}
98 
99  Key_part_spec(const char *column_name, Item *expression, enum_order order)
100  : m_is_ascending((order == ORDER_DESC) ? false : true),
102  m_field_name(column_name),
103  m_prefix_length(0),
104  m_expression(expression),
105  m_has_expression(true) {}
106 
107  Key_part_spec(LEX_CSTRING column_name, uint prefix_length, enum_order order)
108  : m_is_ascending((order == ORDER_DESC) ? false : true),
110  m_field_name(column_name.str),
111  m_prefix_length(prefix_length),
113  m_has_expression(false) {}
114 
115  bool operator==(const Key_part_spec &other) const;
116  /**
117  Construct a copy of this Key_part_spec. field_name is copied
118  by-pointer as it is known to never change. At the same time
119  'length' may be reset in mysql_prepare_create_table, and this
120  is why we supply it with a copy.
121 
122  @return If out of memory, 0 is returned and an error is set in
123  THD.
124  */
126  return new (mem_root) Key_part_spec(*this);
127  }
128 
129  const char *get_field_name() const { return m_field_name; }
130 
132 
133  Item *get_expression() const {
134  assert(has_expression());
135  return m_expression;
136  }
137 
138  /**
139  @retval true if this is an ascending index.
140  @retval false if this is a descending index.
141  */
142  bool is_ascending() const { return m_is_ascending; }
143 
144  /**
145  @retval true if the user explicitly specified the index direction when
146  creating the index.
147  @retval false if the user didn't specify the index direction.
148  */
149  bool is_explicit() const { return m_is_explicit; }
150 
151  /**
152  Resolve the expression that this key part contains. Should only be called
153  if has_expression() returns true.
154 
155  @param thd thread handler.
156 
157  @retval true if an error occurred.
158  @retval false on success.
159  */
160  bool resolve_expression(THD *thd);
161 
162  /**
163  Set the name and the prefix length of the column this key part references.
164  The supplied column name string should have a lifetime equal to or longer
165  than this Key_part_spec
166 
167  @param name the new column that this key part points to.
168   @param prefix_length the prefix length of the index, or 0 if no length is
169  specified.
170  */
171  void set_name_and_prefix_length(const char *name, uint prefix_length);
172 
173  /**
174  @retval true if this index has an expression. In that case, this a
175  functional key part.
176  @retval false if this index doesn't have an expression. In that case this
177  key part references a normal column.
178  */
179  bool has_expression() const { return m_has_expression; }
180 
181  private:
182  /// true <=> ascending, false <=> descending.
183  const bool m_is_ascending;
184 
185  /// true <=> ASC/DESC is explicitly specified, false <=> implicit ASC
186  const bool m_is_explicit;
187 
188  /// The name of the column that this key part points to.
189  const char *m_field_name;
190 
191  /// The prefix length of this index.
193 
194  /**
195  The indexed expression if this is a functional key part. If this key part
196  points to a "normal" column, m_expression is nullptr.
197  */
199 
200  /**
201  Whether this key part has an expression or not. If so, this is a functional
202  key part.
203  */
205 };
206 
207 class Key_spec {
208  public:
209  const keytype type;
213  const bool generated;
214  /**
215  A flag to determine if we will check for duplicate indexes.
216  This typically means that the key information was specified
217  directly by the user (set by the parser) or a column
218  associated with it was dropped.
219  */
221 
222  Key_spec(MEM_ROOT *mem_root, keytype type_par, const LEX_CSTRING &name_arg,
223  const KEY_CREATE_INFO *key_info_arg, bool generated_arg,
224  bool check_for_duplicate_indexes_arg, List<Key_part_spec> &cols)
225  : type(type_par),
226  key_create_info(*key_info_arg),
227  columns(mem_root),
228  name(name_arg),
229  generated(generated_arg),
230  check_for_duplicate_indexes(check_for_duplicate_indexes_arg) {
231  columns.reserve(cols.elements);
233  Key_part_spec *column;
234  while ((column = it++)) columns.push_back(column);
235  }
236 
237  virtual ~Key_spec() = default;
238 };
239 
240 class Foreign_key_spec : public Key_spec {
241  public:
250  /**
251  Indicates whether foreign key name was provided explicitly or
252  was generated automatically.
253 
254  @todo Get rid of this flag once we implement a better way for
255  NDB SE to get generated foreign key name from SQL-layer.
256  @sa prepare_foreign_key().
257  */
258  const bool has_explicit_name;
259 
261  List<Key_part_spec> cols, const LEX_CSTRING &ref_db_arg,
262  const LEX_CSTRING &orig_ref_db_arg,
263  const LEX_CSTRING &ref_table_arg,
264  const LEX_CSTRING &orig_ref_table_arg,
265  List<Key_part_spec> *ref_cols, fk_option delete_opt_arg,
266  fk_option update_opt_arg, fk_match_opt match_opt_arg)
268  false,
269  false, // We don't check for duplicate FKs.
270  cols),
271  ref_db(ref_db_arg),
272  orig_ref_db(orig_ref_db_arg),
273  ref_table(ref_table_arg),
274  orig_ref_table(orig_ref_table_arg),
276  delete_opt(delete_opt_arg),
277  update_opt(update_opt_arg),
278  match_opt(match_opt_arg),
279  has_explicit_name(name_arg.str != nullptr) {
280  if (ref_cols) {
281  ref_columns.reserve(ref_cols->elements);
282  List_iterator<Key_part_spec> it(*ref_cols);
283  Key_part_spec *ref_column;
284  while ((ref_column = it++)) ref_columns.push_back(ref_column);
285  }
286  }
287 
288  /**
289  Check if the foreign key name has valid length and its options
290  are compatible with columns on which the FK is created.
291 
292  @param thd Thread handle
293  @param table_name Table name (for error reporting)
294  @param table_fields List of columns
295 
296  @retval false Key valid
297  @retval true Key invalid
298  */
299  bool validate(THD *thd, const char *table_name,
300  List<Create_field> &table_fields) const;
301 };
302 
303 /**
304  Test if a foreign key (= generated key) is a prefix of the given key
305  (ignoring key name, key type and order of columns)
306 
307  @note This is only used to test if an index for a FOREIGN KEY exists.
308  We only compare field names.
309 
310  @retval false Generated key is a prefix of other key
311  @retval true Not equal
312 */
313 bool foreign_key_prefix(const Key_spec *a, const Key_spec *b);
314 
315 #endif // KEY_SPEC_INCLUDED
Create_field is a description a field/column that may or may not exists in a table.
Definition: create_field.h:50
Definition: key_spec.h:240
const LEX_CSTRING ref_db
Definition: key_spec.h:242
const bool has_explicit_name
Indicates whether foreign key name was provided explicitly or was generated automatically.
Definition: key_spec.h:258
const LEX_CSTRING orig_ref_db
Definition: key_spec.h:243
const fk_option update_opt
Definition: key_spec.h:248
bool validate(THD *thd, const char *table_name, List< Create_field > &table_fields) const
Check if the foreign key name has valid length and its options are compatible with columns on which t...
Definition: key_spec.cc:106
const LEX_CSTRING orig_ref_table
Definition: key_spec.h:245
Mem_root_array< Key_part_spec * > ref_columns
Definition: key_spec.h:246
const fk_option delete_opt
Definition: key_spec.h:247
const fk_match_opt match_opt
Definition: key_spec.h:249
const LEX_CSTRING ref_table
Definition: key_spec.h:244
Foreign_key_spec(MEM_ROOT *mem_root, const LEX_CSTRING &name_arg, List< Key_part_spec > cols, const LEX_CSTRING &ref_db_arg, const LEX_CSTRING &orig_ref_db_arg, const LEX_CSTRING &ref_table_arg, const LEX_CSTRING &orig_ref_table_arg, List< Key_part_spec > *ref_cols, fk_option delete_opt_arg, fk_option update_opt_arg, fk_match_opt match_opt_arg)
Definition: key_spec.h:260
Base class that is used to represent any kind of expression in a relational query.
Definition: item.h:802
Definition: key_spec.h:66
bool is_algorithm_explicit
A flag which indicates that index algorithm was explicitly specified by user.
Definition: key_spec.h:73
ulong block_size
Definition: key_spec.h:74
LEX_CSTRING m_secondary_engine_attribute
Definition: key_spec.h:84
LEX_CSTRING m_engine_attribute
Definition: key_spec.h:83
KEY_CREATE_INFO()=default
LEX_CSTRING parser_name
Definition: key_spec.h:75
KEY_CREATE_INFO(bool is_visible_arg)
Definition: key_spec.h:81
bool is_visible
Definition: key_spec.h:77
LEX_CSTRING comment
Definition: key_spec.h:76
enum ha_key_alg algorithm
Definition: key_spec.h:68
Definition: key_spec.h:89
const bool m_is_explicit
true <=> ASC/DESC is explicitly specified, false <=> implicit ASC
Definition: key_spec.h:186
const char * get_field_name() const
Definition: key_spec.h:129
Item * get_expression() const
Definition: key_spec.h:133
void set_name_and_prefix_length(const char *name, uint prefix_length)
Set the name and the prefix length of the column this key part references.
Definition: key_spec.cc:100
uint get_prefix_length() const
Definition: key_spec.h:131
bool has_expression() const
Definition: key_spec.h:179
const char * m_field_name
The name of the column that this key part points to.
Definition: key_spec.h:189
Key_part_spec(Item *expression, enum_order order)
Definition: key_spec.h:91
uint m_prefix_length
The prefix length of this index.
Definition: key_spec.h:192
bool is_explicit() const
Definition: key_spec.h:149
bool operator==(const Key_part_spec &other) const
Definition: key_spec.cc:49
bool m_has_expression
Whether this key part has an expression or not.
Definition: key_spec.h:204
bool resolve_expression(THD *thd)
Resolve the expression that this key part contains.
Definition: key_spec.cc:90
Item * m_expression
The indexed expression if this is a functional key part.
Definition: key_spec.h:198
Key_part_spec * clone(MEM_ROOT *mem_root) const
Construct a copy of this Key_part_spec.
Definition: key_spec.h:125
Key_part_spec(const char *column_name, Item *expression, enum_order order)
Definition: key_spec.h:99
Key_part_spec(LEX_CSTRING column_name, uint prefix_length, enum_order order)
Definition: key_spec.h:107
const bool m_is_ascending
true <=> ascending, false <=> descending.
Definition: key_spec.h:183
bool is_ascending() const
Definition: key_spec.h:142
Definition: key_spec.h:207
Key_spec(MEM_ROOT *mem_root, keytype type_par, const LEX_CSTRING &name_arg, const KEY_CREATE_INFO *key_info_arg, bool generated_arg, bool check_for_duplicate_indexes_arg, List< Key_part_spec > &cols)
Definition: key_spec.h:222
virtual ~Key_spec()=default
const KEY_CREATE_INFO key_create_info
Definition: key_spec.h:210
const keytype type
Definition: key_spec.h:209
Mem_root_array< Key_part_spec * > columns
Definition: key_spec.h:211
LEX_CSTRING name
Definition: key_spec.h:212
const bool generated
Definition: key_spec.h:213
const bool check_for_duplicate_indexes
A flag to determine if we will check for duplicate indexes.
Definition: key_spec.h:220
Definition: sql_list.h:570
bool push_back(const Element_type &element)
Adds a new element at the end of the array, after its current last element.
Definition: mem_root_array.h:182
bool reserve(size_t n)
Reserves space for array elements.
Definition: mem_root_array.h:151
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:821
uint elements
Definition: sql_list.h:135
static MEM_ROOT mem_root
Definition: client_plugin.cc:109
Dialog Client Authentication nullptr
Definition: dialog.cc:352
fk_match_opt
Definition: key_spec.h:57
@ FK_MATCH_UNDEF
Definition: key_spec.h:58
@ FK_MATCH_SIMPLE
Definition: key_spec.h:61
@ FK_MATCH_FULL
Definition: key_spec.h:59
@ FK_MATCH_PARTIAL
Definition: key_spec.h:60
KEY_CREATE_INFO default_key_create_info
Definition: key_spec.cc:47
enum_order
Definition: key_spec.h:64
@ ORDER_NOT_RELEVANT
Definition: key_spec.h:64
@ ORDER_ASC
Definition: key_spec.h:64
@ ORDER_DESC
Definition: key_spec.h:64
keytype
Definition: key_spec.h:39
@ KEYTYPE_FULLTEXT
Definition: key_spec.h:43
@ KEYTYPE_FOREIGN
Definition: key_spec.h:45
@ KEYTYPE_PRIMARY
Definition: key_spec.h:40
@ KEYTYPE_MULTIPLE
Definition: key_spec.h:42
@ KEYTYPE_SPATIAL
Definition: key_spec.h:44
@ KEYTYPE_UNIQUE
Definition: key_spec.h:41
bool foreign_key_prefix(const Key_spec *a, const Key_spec *b)
Test if a foreign key (= generated key) is a prefix of the given key (ignoring key name,...
Definition: key_spec.cc:56
fk_option
Definition: key_spec.h:48
@ FK_OPTION_DEFAULT
Definition: key_spec.h:54
@ FK_OPTION_SET_NULL
Definition: key_spec.h:52
@ FK_OPTION_UNDEF
Definition: key_spec.h:49
@ FK_OPTION_RESTRICT
Definition: key_spec.h:50
@ FK_OPTION_CASCADE
Definition: key_spec.h:51
@ FK_OPTION_NO_ACTION
Definition: key_spec.h:53
constexpr const LEX_CSTRING EMPTY_CSTR
Definition: lex_string.h:46
#define NullS
Definition of the null string (a null pointer of type char *), used in some of our string handling co...
Definition: m_string.h:52
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
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1056
const char * table_name
Definition: rules_table_service.cc:55
case opt name
Definition: sslopt-case.h:32
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:78
Definition: mysql_lex_string.h:39
unsigned int uint
Definition: uca-dump.cc:29