1
0
mirror of https://github.com/MariaDB/server.git synced 2025-10-12 12:25:37 +03:00

MDEV-17082 Application-time periods: CREATE

* add syntax `CREATE TABLE ... PERIOD FOR <apptime>`
* add table period entity
This commit is contained in:
Nikita Malyavin
2019-02-07 23:16:30 +10:00
committed by Sergei Golubchik
parent b63604612e
commit 073c93b194
18 changed files with 618 additions and 190 deletions

View File

@@ -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;
}