From 911c803db19de7ffd45c39ff3614abcf19c63536 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 11 Oct 2021 13:36:06 +0300 Subject: MDEV-22660 System versioning cleanups - Cleaned up Vers_parse_info::check_sys_fields(); - Renamed VERS_SYS_START_FLAG, VERS_SYS_END_FLAG to VERS_ROW_START, VERS_ROW_END. --- sql/handler.cc | 86 +++++++++++++++++++++++++--------------------------------- 1 file changed, 37 insertions(+), 49 deletions(-) (limited to 'sql/handler.cc') diff --git a/sql/handler.cc b/sql/handler.cc index c0a810a72bc..f46e51a34ce 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7122,11 +7122,11 @@ bool Vers_parse_info::is_end(const char *name) const } bool Vers_parse_info::is_start(const Create_field &f) const { - return f.flags & VERS_SYS_START_FLAG; + return f.flags & VERS_ROW_START; } bool Vers_parse_info::is_end(const Create_field &f) const { - return f.flags & VERS_SYS_END_FLAG; + return f.flags & VERS_ROW_END; } static Create_field *vers_init_sys_field(THD *thd, const char *field_name, int flags, bool integer) @@ -7186,8 +7186,8 @@ bool Vers_parse_info::fix_implicit(THD *thd, Alter_info *alter_info) system_time= start_end_t(default_start, default_end); as_row= system_time; - if (vers_create_sys_field(thd, default_start, alter_info, VERS_SYS_START_FLAG) || - vers_create_sys_field(thd, default_end, alter_info, VERS_SYS_END_FLAG)) + if (vers_create_sys_field(thd, default_start, alter_info, VERS_ROW_START) || + vers_create_sys_field(thd, default_end, alter_info, VERS_ROW_END)) { return true; } @@ -7346,7 +7346,7 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, return true; } my_error(ER_VERS_DUPLICATE_ROW_START_END, MYF(0), - f->flags & VERS_SYS_START_FLAG ? "START" : "END", f->field_name.str); + f->flags & VERS_ROW_START ? "START" : "END", f->field_name.str); return true; } } @@ -7451,13 +7451,13 @@ Vers_parse_info::fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_ while ((f= it++)) { - if (f->flags & VERS_SYS_START_FLAG) + if (f->flags & VERS_ROW_START) { f_start= f; if (f_end) break; } - else if (f->flags & VERS_SYS_END_FLAG) + else if (f->flags & VERS_ROW_END) { f_end= f; if (f_start) @@ -7519,37 +7519,31 @@ bool Vers_parse_info::check_conditions(const Lex_table_name &table_name, return false; } -static bool is_versioning_timestamp(const Create_field *f) -{ - return f->type_handler() == &type_handler_timestamp2 && - f->length == MAX_DATETIME_FULL_WIDTH; -} - -static bool is_some_bigint(const Create_field *f) -{ - return f->type_handler() == &type_handler_longlong || - f->type_handler() == &type_handler_vers_trx_id; -} -static bool is_versioning_bigint(const Create_field *f) +bool Create_field::vers_check_timestamp(const Lex_table_name &table_name) const { - return is_some_bigint(f) && f->flags & UNSIGNED_FLAG && - f->length == MY_INT64_NUM_DECIMAL_DIGITS - 1; -} + if (type_handler() == &type_handler_timestamp2 && + length == MAX_DATETIME_FULL_WIDTH) + return false; -static bool require_timestamp(const Create_field *f, Lex_table_name table_name) -{ - my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), f->field_name.str, "TIMESTAMP(6)", + my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), field_name.str, "TIMESTAMP(6)", table_name.str); return true; } -static bool require_bigint(const Create_field *f, Lex_table_name table_name) + + +bool Create_field::vers_check_bigint(const Lex_table_name &table_name) const { - my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), f->field_name.str, + if (is_some_bigint() && flags & UNSIGNED_FLAG && + length == MY_INT64_NUM_DECIMAL_DIGITS - 1) + return false; + + my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), field_name.str, "BIGINT(20) UNSIGNED", table_name.str); return true; } + bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, const Lex_table_name &db, Alter_info *alter_info, @@ -7564,37 +7558,31 @@ bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, List_iterator it(alter_info->create_list); while (Create_field *f= it++) { - if (!row_start && f->flags & VERS_SYS_START_FLAG) + if (!row_start && f->flags & VERS_ROW_START) row_start= f; - else if (!row_end && f->flags & VERS_SYS_END_FLAG) + else if (!row_end && f->flags & VERS_ROW_END) row_end= f; } - const bool expect_timestamp= - !can_native || !is_some_bigint(row_start) || !is_some_bigint(row_end); - - if (expect_timestamp) + if (!can_native || + !row_start->is_some_bigint() || + !row_end->is_some_bigint()) { - if (!is_versioning_timestamp(row_start)) - return require_timestamp(row_start, table_name); - - if (!is_versioning_timestamp(row_end)) - return require_timestamp(row_end, table_name); + if (row_start->vers_check_timestamp(table_name) || + row_end->vers_check_timestamp(table_name)) + return true; } else { - if (!is_versioning_bigint(row_start)) - return require_bigint(row_start, table_name); - - if (!is_versioning_bigint(row_end)) - return require_bigint(row_end, table_name); - } + if (row_start->vers_check_bigint(table_name) || + row_end->vers_check_bigint(table_name)) + return true; - if (is_versioning_bigint(row_start) && is_versioning_bigint(row_end) && - !TR_table::use_transaction_registry) - { - my_error(ER_VERS_TRT_IS_DISABLED, MYF(0)); - return true; + if (!TR_table::use_transaction_registry) + { + my_error(ER_VERS_TRT_IS_DISABLED, MYF(0)); + return true; + } } return false; -- cgit v1.2.1 From d31f953789def34f20d29b31add847a3c30a8ecc Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 11 Oct 2021 13:36:07 +0300 Subject: MDEV-22660 SIGSEGV on adding system versioning and modifying system column Second alter subcommand correctly removed VERS_ROW_END flag. We throw ER_VERS_PERIOD_COLUMNS in such case. --- sql/handler.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sql/handler.cc') diff --git a/sql/handler.cc b/sql/handler.cc index f46e51a34ce..bbd0f3bf515 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7564,6 +7564,12 @@ bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, row_end= f; } + if (!row_start || !row_end) + { + my_error(ER_VERS_PERIOD_COLUMNS, MYF(0), as_row.start.str, as_row.end.str); + return true; + } + if (!can_native || !row_start->is_some_bigint() || !row_end->is_some_bigint()) -- cgit v1.2.1