diff options
author | hcpp <hcpp@ydb.tech> | 2023-11-08 12:09:41 +0300 |
---|---|---|
committer | hcpp <hcpp@ydb.tech> | 2023-11-08 12:56:14 +0300 |
commit | a361f5b98b98b44ea510d274f6769164640dd5e1 (patch) | |
tree | c47c80962c6e2e7b06798238752fd3da0191a3f6 /contrib/libs/libmysql_r/sql/key_spec.h | |
parent | 9478806fde1f4d40bd5a45e7cbe77237dab613e9 (diff) | |
download | ydb-a361f5b98b98b44ea510d274f6769164640dd5e1.tar.gz |
metrics have been added
Diffstat (limited to 'contrib/libs/libmysql_r/sql/key_spec.h')
-rw-r--r-- | contrib/libs/libmysql_r/sql/key_spec.h | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/contrib/libs/libmysql_r/sql/key_spec.h b/contrib/libs/libmysql_r/sql/key_spec.h new file mode 100644 index 0000000000..56dea9fc6f --- /dev/null +++ b/contrib/libs/libmysql_r/sql/key_spec.h @@ -0,0 +1,302 @@ +/* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2.0, + as published by the Free Software Foundation. + + This program is also distributed with certain software (including + but not limited to OpenSSL) that is licensed under separate terms, + as designated in a particular file or component or in included license + documentation. The authors of MySQL hereby grant you an additional + permission to link the program and your derivative works with the + separately licensed software that they have included with MySQL. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License, version 2.0, for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef KEY_SPEC_INCLUDED +#define KEY_SPEC_INCLUDED + +#include <sys/types.h> + +#include "lex_string.h" +#include "m_string.h" +#include "my_base.h" +#include "sql/mem_root_array.h" +#include "sql/sql_list.h" + +class Create_field; +class Item; +class THD; +struct MEM_ROOT; + +enum keytype { + KEYTYPE_PRIMARY, + KEYTYPE_UNIQUE, + KEYTYPE_MULTIPLE, + KEYTYPE_FULLTEXT, + KEYTYPE_SPATIAL, + KEYTYPE_FOREIGN +}; + +enum fk_option { + FK_OPTION_UNDEF, + FK_OPTION_RESTRICT, + FK_OPTION_CASCADE, + FK_OPTION_SET_NULL, + FK_OPTION_NO_ACTION, + FK_OPTION_DEFAULT +}; + +enum fk_match_opt { + FK_MATCH_UNDEF, + FK_MATCH_FULL, + FK_MATCH_PARTIAL, + FK_MATCH_SIMPLE +}; + +enum enum_order { ORDER_NOT_RELEVANT = 1, ORDER_ASC, ORDER_DESC }; + +class KEY_CREATE_INFO { + public: + enum ha_key_alg algorithm = HA_KEY_ALG_SE_SPECIFIC; + /** + A flag which indicates that index algorithm was explicitly specified + by user. + */ + bool is_algorithm_explicit = false; + ulong block_size = 0; + LEX_CSTRING parser_name = {NullS, 0}; + LEX_CSTRING comment = {NullS, 0}; + bool is_visible = true; + + KEY_CREATE_INFO() = default; + + explicit KEY_CREATE_INFO(bool is_visible_arg) : is_visible(is_visible_arg) {} +}; + +extern KEY_CREATE_INFO default_key_create_info; + +class Key_part_spec { + public: + Key_part_spec(Item *expression, enum_order order) + : m_is_ascending((order == ORDER_DESC) ? false : true), + m_is_explicit(order != ORDER_NOT_RELEVANT), + m_field_name(nullptr), + m_prefix_length(0), + m_expression(expression), + m_has_expression(true) {} + + Key_part_spec(const char *column_name, Item *expression, enum_order order) + : m_is_ascending((order == ORDER_DESC) ? false : true), + m_is_explicit(order != ORDER_NOT_RELEVANT), + m_field_name(column_name), + m_prefix_length(0), + m_expression(expression), + m_has_expression(true) {} + + Key_part_spec(LEX_CSTRING column_name, uint prefix_length, enum_order order) + : m_is_ascending((order == ORDER_DESC) ? false : true), + m_is_explicit(order != ORDER_NOT_RELEVANT), + m_field_name(column_name.str), + m_prefix_length(prefix_length), + m_expression(nullptr), + m_has_expression(false) {} + + bool operator==(const Key_part_spec &other) const; + /** + Construct a copy of this Key_part_spec. field_name is copied + by-pointer as it is known to never change. At the same time + 'length' may be reset in mysql_prepare_create_table, and this + is why we supply it with a copy. + + @return If out of memory, 0 is returned and an error is set in + THD. + */ + Key_part_spec *clone(MEM_ROOT *mem_root) const { + return new (mem_root) Key_part_spec(*this); + } + + const char *get_field_name() const { return m_field_name; } + + uint get_prefix_length() const { return m_prefix_length; } + + Item *get_expression() const { + DBUG_ASSERT(has_expression()); + return m_expression; + } + + /** + @retval true if this is an ascending index. + @retval false if this is a descending index. + */ + bool is_ascending() const { return m_is_ascending; } + + /** + @retval true if the user explicitly specified the index direction when + creating the index. + @retval false if the user didn't specify the index direction. + */ + bool is_explicit() const { return m_is_explicit; } + + /** + Resolve the expression that this key part contains. Should only be called + if has_expression() returns true. + + @param thd thread handler. + + @retval true if an error occurred. + @retval false on success. + */ + bool resolve_expression(THD *thd); + + /** + Set the name and the prefix length of the column this key part references. + The supplied column name string should have a lifetime equal to or longer + than this Key_part_spec + + @param name the new column that this key part points to. + @param prefix_length the prefix length of the index, or 0 if no length is + specified. + */ + void set_name_and_prefix_length(const char *name, uint prefix_length); + + /** + @retval true if this index has an expression. In that case, this a + functional key part. + @retval false if this index doesn't have an expression. In that case this + key part references a normal column. + */ + bool has_expression() const { return m_has_expression; } + + private: + /// true <=> ascending, false <=> descending. + const bool m_is_ascending; + + /// true <=> ASC/DESC is explicitly specified, false <=> implicit ASC + const bool m_is_explicit; + + /// The name of the column that this key part points to. + const char *m_field_name; + + /// The prefix length of this index. + uint m_prefix_length; + + /** + The indexed expression if this is a functional key part. If this key part + points to a "normal" column, m_expression is nullptr. + */ + Item *m_expression; + + /** + Whether this key part has an expression or not. If so, this is a functional + key part. + */ + bool m_has_expression; +}; + +class Key_spec { + public: + const keytype type; + const KEY_CREATE_INFO key_create_info; + Mem_root_array<Key_part_spec *> columns; + LEX_CSTRING name; + const bool generated; + /** + A flag to determine if we will check for duplicate indexes. + This typically means that the key information was specified + directly by the user (set by the parser) or a column + associated with it was dropped. + */ + const bool check_for_duplicate_indexes; + + 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) + : type(type_par), + key_create_info(*key_info_arg), + columns(mem_root), + name(name_arg), + generated(generated_arg), + check_for_duplicate_indexes(check_for_duplicate_indexes_arg) { + columns.reserve(cols.elements); + List_iterator<Key_part_spec> it(cols); + Key_part_spec *column; + while ((column = it++)) columns.push_back(column); + } + + virtual ~Key_spec() {} +}; + +class Foreign_key_spec : public Key_spec { + public: + const LEX_CSTRING ref_db; + const LEX_CSTRING orig_ref_db; + const LEX_CSTRING ref_table; + const LEX_CSTRING orig_ref_table; + Mem_root_array<Key_part_spec *> ref_columns; + const fk_option delete_opt; + const fk_option update_opt; + const fk_match_opt match_opt; + + 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) + : Key_spec(mem_root, KEYTYPE_FOREIGN, name_arg, &default_key_create_info, + false, + false, // We don't check for duplicate FKs. + cols), + ref_db(ref_db_arg), + orig_ref_db(orig_ref_db_arg), + ref_table(ref_table_arg), + orig_ref_table(orig_ref_table_arg), + ref_columns(mem_root), + delete_opt(delete_opt_arg), + update_opt(update_opt_arg), + match_opt(match_opt_arg) { + if (ref_cols) { + ref_columns.reserve(ref_cols->elements); + List_iterator<Key_part_spec> it(*ref_cols); + Key_part_spec *ref_column; + while ((ref_column = it++)) ref_columns.push_back(ref_column); + } + } + + /** + Check if the foreign key name has valid length and its options + are compatible with columns on which the FK is created. + + @param thd Thread handle + @param table_name Table name (for error reporting) + @param table_fields List of columns + + @retval false Key valid + @retval true Key invalid + */ + bool validate(THD *thd, const char *table_name, + List<Create_field> &table_fields) const; +}; + +/** + Test if a foreign key (= generated key) is a prefix of the given key + (ignoring key name, key type and order of columns) + + @note This is only used to test if an index for a FOREIGN KEY exists. + We only compare field names. + + @retval false Generated key is a prefix of other key + @retval true Not equal +*/ +bool foreign_key_prefix(const Key_spec *a, const Key_spec *b); + +#endif // KEY_SPEC_INCLUDED |