diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2022-05-22 22:00:50 +0300 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2022-05-22 22:00:50 +0300 |
commit | 643750bc53372a899eb5ae3131dee23605e3cb86 (patch) | |
tree | 4f1f78170a4853525596a72a16532ec067008e7a | |
parent | 8b99b538cd8b7442b7495d7cdc3b2b07b8e01c3b (diff) | |
download | mariadb-git-for_vanislavskiy.tar.gz |
WIP resolve sql_type and field linkagefor_vanislavskiy
-rw-r--r-- | extra/CMakeLists.txt | 5 | ||||
-rw-r--r-- | extra/frm_parser.cc | 22 | ||||
-rw-r--r-- | sql/field.cc | 90 | ||||
-rw-r--r-- | sql/field_minimal.cc | 93 | ||||
-rw-r--r-- | sql/frm.cc | 15 | ||||
-rw-r--r-- | sql/handler.cc | 84 | ||||
-rw-r--r-- | sql/sql_type.cc | 95 | ||||
-rw-r--r-- | sql/sql_type.h | 2 |
8 files changed, 215 insertions, 191 deletions
diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt index 4fd113ee71a..a724d12be9d 100644 --- a/extra/CMakeLists.txt +++ b/extra/CMakeLists.txt @@ -97,11 +97,12 @@ set(FRM_PARSER_SOURCES frm_parser.cc database_show.cc ../sql/sql_string.cc ../sql/sql_list.cc ../sql/frm.cc - ../sql/type_handler.cc + ../sql/sql_type.cc + ../sql/field_minimal.cc ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp ${CMAKE_CURRENT_BINARY_DIR}/../sql/lex_hash.h) MYSQL_ADD_EXECUTABLE(frm_parser ${FRM_PARSER_SOURCES}) -TARGET_COMPILE_DEFINITIONS(frm_parser PUBLIC FRM_PARSER) +TARGET_COMPILE_DEFINITIONS(frm_parser PUBLIC FRM_PARSER TO_BE_DELETED_ON_PRODUCTION) TARGET_INCLUDE_DIRECTORIES(frm_parser PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/../sql) TARGET_LINK_LIBRARIES(frm_parser mysys) diff --git a/extra/frm_parser.cc b/extra/frm_parser.cc index 44d263bab6e..d55d91d31be 100644 --- a/extra/frm_parser.cc +++ b/extra/frm_parser.cc @@ -53,6 +53,28 @@ void push_warning_printf(THD *thd, Sql_condition::enum_warning_level level, // } + +Compression_method compression_methods[MAX_COMPRESSION_METHODS]= +{ + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { "zlib", 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 } +}; + + int main(int argc, char **argv) { TABLE_SHARE share; diff --git a/sql/field.cc b/sql/field.cc index cde7cf722fc..315b34bc930 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -54,8 +54,6 @@ const char field_separator=','; #define DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE FLOATING_POINT_BUFFER #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128 #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128 -#define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \ - ((ulong) ((1LL << MY_MIN(arg, 4) * 8) - 1)) // Column marked for read or the field set to read out of record[0] bool Field::marked_for_read() const @@ -3327,29 +3325,6 @@ Field *Field_decimal::make_new_field(MEM_ROOT *root, TABLE *new_table, ** Field_new_decimal ****************************************************************************/ -static decimal_digits_t get_decimal_precision(uint len, decimal_digits_t dec, - bool unsigned_val) -{ - uint precision= my_decimal_length_to_precision(len, dec, unsigned_val); - return (decimal_digits_t) MY_MIN(precision, DECIMAL_MAX_PRECISION); -} - -Field_new_decimal::Field_new_decimal(uchar *ptr_arg, - uint32 len_arg, uchar *null_ptr_arg, - uchar null_bit_arg, - enum utype unireg_check_arg, - const LEX_CSTRING *field_name_arg, - decimal_digits_t dec_arg,bool zero_arg, - bool unsigned_arg) - :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg) -{ - precision= get_decimal_precision(len_arg, dec_arg, unsigned_arg); - DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) && - (dec <= DECIMAL_MAX_SCALE)); - bin_size= my_decimal_get_binary_size(precision, dec); -} - int Field_new_decimal::reset(void) { @@ -8540,22 +8515,6 @@ Binlog_type_info Field_varstring_compressed::binlog_type_info() const ** packlength slot and may be from 1-4. ****************************************************************************/ -Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, - enum utype unireg_check_arg, - const LEX_CSTRING *field_name_arg, - TABLE_SHARE *share, uint blob_pack_length, - const DTCollation &collation) - :Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length), - null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, - collation), - packlength(blob_pack_length) -{ - DBUG_ASSERT(blob_pack_length <= 4); // Only pack lengths 1-4 supported currently - flags|= BLOB_FLAG; - share->blob_fields++; - /* TODO: why do not fill table->s->blob_field array here? */ -} - void Field_blob::store_length(uchar *i_ptr, uint i_packlength, uint32 i_number) { @@ -9723,28 +9682,6 @@ bool Field_enum::can_optimize_range_or_keypart_ref(const Item_bool_func *cond, 11 one byte for 'd' */ -Field_bit::Field_bit(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, - uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg, - enum utype unireg_check_arg, - const LEX_CSTRING *field_name_arg) - : Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg), - bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7), - bytes_in_rec(len_arg / 8) -{ - DBUG_ENTER("Field_bit::Field_bit"); - DBUG_PRINT("enter", ("ptr_arg: %p, null_ptr_arg: %p, len_arg: %u, bit_len: %u, bytes_in_rec: %u", - ptr_arg, null_ptr_arg, len_arg, bit_len, bytes_in_rec)); - flags|= UNSIGNED_FLAG; - /* - Ensure that Field::eq() can distinguish between two different bit fields. - (two bit fields that are not null, may have same ptr and null_ptr) - */ - if (!null_ptr_arg) - null_bit= bit_ofs_arg; - DBUG_VOID_RETURN; -} - const DTCollation & Field_bit::dtcollation() const { @@ -10221,19 +10158,6 @@ int Field_bit::set_default() Bit field support for non-MyISAM tables. */ -Field_bit_as_char::Field_bit_as_char(uchar *ptr_arg, uint32 len_arg, - uchar *null_ptr_arg, uchar null_bit_arg, - enum utype unireg_check_arg, - const LEX_CSTRING *field_name_arg) - :Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 0, 0, - unireg_check_arg, field_name_arg) -{ - flags|= UNSIGNED_FLAG; - bit_len= 0; - bytes_in_rec= (len_arg + 7) / 8; -} - - int Field_bit_as_char::store(const char *from, size_t length, CHARSET_INFO *cs) { DBUG_ASSERT(marked_for_write_or_computed()); @@ -10742,20 +10666,6 @@ uint pack_length_to_packflag(uint type) } -uint Column_definition_attributes::pack_flag_to_pack_length() const -{ - uint type= f_packtype(pack_flag); // 0..15 - DBUG_ASSERT(type < 16); - switch (type) { - case MYSQL_TYPE_TINY: return 1; - case MYSQL_TYPE_SHORT: return 2; - case MYSQL_TYPE_LONG: return 4; - case MYSQL_TYPE_LONGLONG: return 8; - case MYSQL_TYPE_INT24: return 3; - } - return 0; // This should not happen -} - bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item) const { return item->is_of_type(Item::CONST_ITEM, TIME_RESULT); diff --git a/sql/field_minimal.cc b/sql/field_minimal.cc new file mode 100644 index 00000000000..982afa09734 --- /dev/null +++ b/sql/field_minimal.cc @@ -0,0 +1,93 @@ +#include "mariadb.h" +#include "field.h" + +static decimal_digits_t get_decimal_precision(uint len, decimal_digits_t dec, + bool unsigned_val) +{ + uint precision= my_decimal_length_to_precision(len, dec, unsigned_val); + return (decimal_digits_t) MY_MIN(precision, DECIMAL_MAX_PRECISION); +} + +Field_new_decimal::Field_new_decimal(uchar *ptr_arg, + uint32 len_arg, uchar *null_ptr_arg, + uchar null_bit_arg, + enum utype unireg_check_arg, + const LEX_CSTRING *field_name_arg, + decimal_digits_t dec_arg,bool zero_arg, + bool unsigned_arg) + :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, + unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg) +{ + precision= get_decimal_precision(len_arg, dec_arg, unsigned_arg); + DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) && + (dec <= DECIMAL_MAX_SCALE)); + bin_size= my_decimal_get_binary_size(precision, dec); +} + + +Field_bit_as_char::Field_bit_as_char(uchar *ptr_arg, uint32 len_arg, + uchar *null_ptr_arg, uchar null_bit_arg, + enum utype unireg_check_arg, + const LEX_CSTRING *field_name_arg) + :Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 0, 0, + unireg_check_arg, field_name_arg) +{ + flags|= UNSIGNED_FLAG; + bit_len= 0; + bytes_in_rec= (len_arg + 7) / 8; +} + +Field_bit::Field_bit(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg, + enum utype unireg_check_arg, + const LEX_CSTRING *field_name_arg) + : Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, + unireg_check_arg, field_name_arg), + bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7), + bytes_in_rec(len_arg / 8) +{ + DBUG_ENTER("Field_bit::Field_bit"); + DBUG_PRINT("enter", ("ptr_arg: %p, null_ptr_arg: %p, len_arg: %u, bit_len: %u, bytes_in_rec: %u", + ptr_arg, null_ptr_arg, len_arg, bit_len, bytes_in_rec)); + flags|= UNSIGNED_FLAG; + /* + Ensure that Field::eq() can distinguish between two different bit fields. + (two bit fields that are not null, may have same ptr and null_ptr) + */ + if (!null_ptr_arg) + null_bit= bit_ofs_arg; + DBUG_VOID_RETURN; +} + +uint Column_definition_attributes::pack_flag_to_pack_length() const +{ + uint type= f_packtype(pack_flag); // 0..15 + DBUG_ASSERT(type < 16); + switch (type) { + case MYSQL_TYPE_TINY: return 1; + case MYSQL_TYPE_SHORT: return 2; + case MYSQL_TYPE_LONG: return 4; + case MYSQL_TYPE_LONGLONG: return 8; + case MYSQL_TYPE_INT24: return 3; + } + return 0; // This should not happen +} + +#define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \ + ((ulong) ((1LL << MY_MIN(arg, 4) * 8) - 1)) + +Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, + enum utype unireg_check_arg, + const LEX_CSTRING *field_name_arg, + TABLE_SHARE *share, uint blob_pack_length, + const DTCollation &collation) + :Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length), + null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, + collation), + packlength(blob_pack_length) +{ + DBUG_ASSERT(blob_pack_length <= 4); // Only pack lengths 1-4 supported currently + flags|= BLOB_FLAG; + share->blob_fields++; + /* TODO: why do not fill table->s->blob_field array here? */ +} diff --git a/sql/frm.cc b/sql/frm.cc index 73a8b1ffade..2979756fa99 100644 --- a/sql/frm.cc +++ b/sql/frm.cc @@ -1832,10 +1832,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, LEX_CSTRING comment; LEX_CSTRING name; Virtual_column_info *vcol_info= 0; - #undef FRM_PARSER -#ifndef FRM_PARSER const Type_handler *handler; -#endif uint32 flags= 0; Column_definition_attributes attr; @@ -1887,10 +1884,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, vcol_info= new (&share->mem_root) Virtual_column_info(); bool opt_interval_id= (uint)vcol_screen_pos[0] == 2; enum_field_types ftype= (enum_field_types) (uchar) vcol_screen_pos[1]; -#ifndef FRM_PARSER if (!(handler= Type_handler::get_handler_by_real_type(ftype))) goto err; -#endif if (opt_interval_id) interval_nr= (uint)vcol_screen_pos[3]; else if ((uint)vcol_screen_pos[0] != 1) @@ -1909,9 +1904,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, { interval_nr= (uint) strpos[12]; enum_field_types field_type= (enum_field_types) strpos[13]; -#ifndef FRM_PARSER if (!(handler= Type_handler::get_handler_by_real_type(field_type))) { +#ifndef FRM_PARSER if (field_type == 245 && share->mysql_version >= 50700) // a.k.a MySQL 5.7 JSON { @@ -1919,6 +1914,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, const LEX_CSTRING mysql_json{STRING_WITH_LEN("MYSQL_JSON")}; handler= Type_handler::handler_by_name_or_error(thd, mysql_json); } +#endif if (!handler) goto err; // Not supported field type @@ -1928,7 +1924,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, strpos, &extra2.gis)) goto err; -#endif if (field_data_type_info_array.count()) { @@ -2090,11 +2085,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (flags & VERS_SYSTEM_FIELD) { -#ifdef FRM_PARSER - auto field_type= field -#else auto field_type= handler->real_field_type(); -#endif DBUG_EXECUTE_IF("error_vers_wrong_type", field_type= MYSQL_TYPE_BLOB;); @@ -2253,7 +2244,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } uint add_first_key_parts= 0; - #define FRM_PARSER +// #define FRM_PARSER #ifndef FRM_PARSER longlong ha_option= handler_file->ha_table_flags(); #endif diff --git a/sql/handler.cc b/sql/handler.cc index c5bd441eaf0..df95c0244db 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -8448,90 +8448,6 @@ bool Vers_parse_info::check_conditions(const Lex_table_name &table_name, return false; } -static bool is_versioning_timestamp(const Column_definition *f) -{ - return f->type_handler() == &type_handler_timestamp2 && - f->length == MAX_DATETIME_FULL_WIDTH; -} - -static bool is_some_bigint(const Column_definition *f) -{ - return f->type_handler() == &type_handler_slonglong || - f->type_handler() == &type_handler_ulonglong || - f->type_handler() == &type_handler_vers_trx_id; -} - -static bool is_versioning_bigint(const Column_definition *f) -{ - return is_some_bigint(f) && f->flags & UNSIGNED_FLAG && - f->length == MY_INT64_NUM_DECIMAL_DIGITS - 1; -} - -static void require_timestamp_error(const char *field, const char *table) -{ - my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), field, "TIMESTAMP(6)", table); -} - -static void require_trx_id_error(const char *field, const char *table) -{ - my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), field, "BIGINT(20) UNSIGNED", - table); -} - - -bool Vers_type_timestamp::check_sys_fields(const LEX_CSTRING &table_name, - const Column_definition *row_start, - const Column_definition *row_end) const -{ - if (!is_versioning_timestamp(row_start)) - { - require_timestamp_error(row_start->field_name.str, table_name.str); - return true; - } - - if (row_end->type_handler()->vers() != this || - !is_versioning_timestamp(row_end)) - { - require_timestamp_error(row_end->field_name.str, table_name.str); - return true; - } - - return false; -} - - -bool Vers_type_trx::check_sys_fields(const LEX_CSTRING &table_name, - const Column_definition *row_start, - const Column_definition *row_end) const -{ - if (!is_versioning_bigint(row_start)) - { - require_trx_id_error(row_start->field_name.str, table_name.str); - return true; - } - - if (row_end->type_handler()->vers() != this || - !is_versioning_bigint(row_end)) - { - require_trx_id_error(row_end->field_name.str, table_name.str); - return true; - } - - if (!is_some_bigint(row_start)) - { - require_timestamp_error(row_start->field_name.str, table_name.str); - return true; - } - - if (!TR_table::use_transaction_registry) - { - my_error(ER_VERS_TRT_IS_DISABLED, MYF(0)); - return true; - } - - return false; -} - bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, const Lex_table_name &db, diff --git a/sql/sql_type.cc b/sql/sql_type.cc index adfe02e633b..fd78c8c5a46 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -178,6 +178,7 @@ const Type_collection *Type_handler_row::type_collection() const } +#ifndef FRM_PARSER bool Type_handler_data::init() { #ifdef HAVE_SPATIAL @@ -2155,7 +2156,7 @@ Type_handler_hybrid_field_type::aggregate_for_num_op(const Type_aggregator *agg, return true; } - +#endif // !FRM_PARSER /***************************************************************************/ const Type_handler * @@ -2185,7 +2186,7 @@ Type_handler::get_handler_by_field_type(enum_field_types type) case MYSQL_TYPE_SET: return &type_handler_varchar; // Map to VARCHAR case MYSQL_TYPE_GEOMETRY: #ifdef HAVE_SPATIAL - return &type_handler_geometry; + return NULL; //&type_handler_geometry; #else return NULL; #endif @@ -2242,7 +2243,7 @@ Type_handler::get_handler_by_real_type(enum_field_types type) case MYSQL_TYPE_SET: return &type_handler_set; case MYSQL_TYPE_GEOMETRY: #ifdef HAVE_SPATIAL - return &type_handler_geometry; + return NULL; // &type_handler_geometry; #else return NULL; #endif @@ -2258,6 +2259,7 @@ Type_handler::get_handler_by_real_type(enum_field_types type) return NULL; } +#ifndef FRM_PARSER /** Create a DOUBLE field by default. @@ -8012,6 +8014,7 @@ void Type_handler_typelib::Item_param_set_param_func(Item_param *param, param->set_null(); // Not possible type code in the client-server protocol } +#endif // !FRM_PARSER /***************************************************************************/ @@ -8433,6 +8436,7 @@ Field *Type_handler_set:: /***************************************************************************/ +#ifndef FRM_PARSER void Type_handler:: Column_definition_attributes_frm_pack(const Column_definition_attributes *def, @@ -9458,3 +9462,88 @@ int initialize_data_type_plugin(st_plugin_int *plugin) } return 0; } +#endif // !FRM_PARSER + + +static bool is_versioning_timestamp(const Column_definition *f) +{ + return f->type_handler() == &type_handler_timestamp2 && + f->length == MAX_DATETIME_FULL_WIDTH; +} + +static bool is_some_bigint(const Column_definition *f) +{ + return f->type_handler() == &type_handler_slonglong || + f->type_handler() == &type_handler_ulonglong || + f->type_handler() == &type_handler_vers_trx_id; +} + +static bool is_versioning_bigint(const Column_definition *f) +{ + return is_some_bigint(f) && f->flags & UNSIGNED_FLAG && + f->length == MY_INT64_NUM_DECIMAL_DIGITS - 1; +} + +static void require_timestamp_error(const char *field, const char *table) +{ + my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), field, "TIMESTAMP(6)", table); +} + +static void require_trx_id_error(const char *field, const char *table) +{ + my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), field, "BIGINT(20) UNSIGNED", + table); +} + +bool Vers_type_timestamp::check_sys_fields(const LEX_CSTRING &table_name, + const Column_definition *row_start, + const Column_definition *row_end) const +{ + if (!is_versioning_timestamp(row_start)) + { + require_timestamp_error(row_start->field_name.str, table_name.str); + return true; + } + + if (row_end->type_handler()->vers() != this || + !is_versioning_timestamp(row_end)) + { + require_timestamp_error(row_end->field_name.str, table_name.str); + return true; + } + + return false; +} + + +bool Vers_type_trx::check_sys_fields(const LEX_CSTRING &table_name, + const Column_definition *row_start, + const Column_definition *row_end) const +{ + if (!is_versioning_bigint(row_start)) + { + require_trx_id_error(row_start->field_name.str, table_name.str); + return true; + } + + if (row_end->type_handler()->vers() != this || + !is_versioning_bigint(row_end)) + { + require_trx_id_error(row_end->field_name.str, table_name.str); + return true; + } + + if (!is_some_bigint(row_start)) + { + require_timestamp_error(row_start->field_name.str, table_name.str); + return true; + } + + if (!TR_table::use_transaction_registry) + { + my_error(ER_VERS_TRT_IS_DISABLED, MYF(0)); + return true; + } + + return false; +} diff --git a/sql/sql_type.h b/sql/sql_type.h index 0f74489719a..0a0ae19de82 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -7381,9 +7381,11 @@ public: // A pseudo type handler, mostly for test purposes for now class Type_handler_interval_DDhhmmssff: public Type_handler_long_blob { +#ifndef FRM_PARSER public: Item *create_typecast_item(THD *thd, Item *item, const Type_cast_attributes &attr) const override; +#endif }; |