summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc109
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;
+}