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:
committed by
Sergei Golubchik
parent
b63604612e
commit
073c93b194
109
sql/handler.cc
109
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user