diff options
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 109 |
1 files changed, 102 insertions, 7 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index bc183837903..9150b055313 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7183,8 +7183,8 @@ bool Vers_parse_info::fix_implicit(THD *thd, Alter_info *alter_info) alter_info->flags|= ALTER_PARSER_ADD_COLUMN; - system_time= start_end_t(default_start, default_end); - as_row= system_time; + period= start_end_t(default_start, default_end); + as_row= period; 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)) @@ -7375,7 +7375,7 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, DBUG_ASSERT(end.str); as_row= start_end_t(start, end); - system_time= as_row; + period= as_row; if (alter_info->create_list.elements) { @@ -7461,7 +7461,7 @@ Vers_parse_info::fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_ } as_row= start_end_t(f_start->field_name, f_end->field_name); - system_time= as_row; + period= as_row; create_info.options|= HA_VERSIONED_TABLE; return false; @@ -7486,14 +7486,14 @@ bool Vers_parse_info::check_conditions(const Lex_table_name &table_name, return true; } - if (!system_time.start || !system_time.end) + if (!period.start || !period.end) { my_error(ER_MISSING, MYF(0), table_name.str, "PERIOD FOR SYSTEM_TIME"); return true; } - if (!as_row.start.streq(system_time.start) || - !as_row.end.streq(system_time.end)) + if (!as_row.start.streq(period.start) || + !as_row.end.streq(period.end)) { my_error(ER_VERS_PERIOD_COLUMNS, MYF(0), as_row.start.str, as_row.end.str); return true; @@ -7583,3 +7583,98 @@ bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, "ROW END" : found_flag ? "ROW START" : "ROW START/END"); return true; } + +static bool check_period_field(const Create_field* f, const char* name, + const char* period_name) +{ + bool res= false; + if (!f) + { + my_error(ER_BAD_FIELD_ERROR, MYF(0), name, period_name); + res= true; + } + else if (f->type_handler()->mysql_timestamp_type() == MYSQL_TIMESTAMP_ERROR) + { + my_error(ER_WRONG_FIELD_SPEC, MYF(0), name); + res= true; + } + else if (f->vcol_info || f->flags & VERS_SYSTEM_FIELD) + { + my_error(ER_PERIOD_FIELD_WRONG_ATTRIBUTES, MYF(0), + f->field_name.str, "GENERATED ALWAYS AS"); + } + + return res; +} + +bool Table_scope_and_contents_source_st::check_fields( + THD *thd, Alter_info *alter_info, TABLE_LIST &create_table) +{ + bool res= vers_check_system_fields(thd, alter_info, create_table); + if (res) + return true; + + if (!period_info.name) + return false; + + if (tmp_table()) + { + my_error(ER_PERIOD_TEMPORARY_NOT_ALLOWED, MYF(0)); + return true; + } + + Table_period_info::start_end_t &period= period_info.period; + const Create_field *row_start= NULL; + const Create_field *row_end= NULL; + List_iterator<Create_field> it(alter_info->create_list); + while (const Create_field *f= it++) + { + if (period.start.streq(f->field_name)) row_start= f; + else if (period.end.streq(f->field_name)) row_end= f; + + if (period_info.name.streq(f->field_name)) + { + my_error(ER_DUP_FIELDNAME, MYF(0), f->field_name.str); + return true; + } + } + + res= check_period_field(row_start, period.start.str, period_info.name.str); + res= res || check_period_field(row_end, period.end.str, period_info.name.str); + if (res) + return true; + + if (row_start->type_handler() != row_end->type_handler() + || row_start->length != row_end->length) + { + my_error(ER_PERIOD_TYPES_MISMATCH, MYF(0), period_info.name.str); + res= true; + } + + return res; +} + +bool +Table_scope_and_contents_source_st::fix_create_fields(THD *thd, + Alter_info *alter_info, + const TABLE_LIST &create_table, + bool create_select) +{ + if (vers_fix_system_fields(thd, alter_info, create_table, create_select)) + return true; + + if (!period_info.name) + return false; + + Table_period_info::start_end_t &period= period_info.period; + List_iterator<Create_field> it(alter_info->create_list); + while (Create_field *f= it++) + { + if (period.start.streq(f->field_name) || period.end.streq(f->field_name)) + { + f->period= &period_info; + f->flags|= NOT_NULL_FLAG; + } + } + return false; +} |