Commit d8c8d7b9 authored by Kosov Eugene's avatar Kosov Eugene Committed by Aleksey Midenkov

added implicitly generated fields in versioned tables support and refactored code a bit

parent 013345d1
......@@ -1949,6 +1949,19 @@ t1 CREATE TABLE `t1` (
PERIOD FOR SYSTEM_TIME (`Sys_start`, `Sys_end`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
drop table if exists t1;
# Versioning fields are set implicitly.
create table t1 (
XNo INT UNSIGNED
) WITH SYSTEM VERSIONING;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`XNo` int(10) unsigned DEFAULT NULL,
`sys_trx_start` timestamp(6) NULL GENERATED AS ROW START,
`sys_trx_end` timestamp(6) NULL GENERATED AS ROW END,
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
drop table if exists t1;
create table t1 (
XNo INT UNSIGNED,
Sys_start TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
......
......@@ -1799,6 +1799,14 @@ SHOW CREATE TABLE t1;
drop table if exists t1;
--echo # Versioning fields are set implicitly.
create table t1 (
XNo INT UNSIGNED
) WITH SYSTEM VERSIONING;
SHOW CREATE TABLE t1;
drop table if exists t1;
--error ER_SYS_START_MORE_THAN_ONCE
create table t1 (
XNo INT UNSIGNED,
......
......@@ -6552,3 +6552,53 @@ int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info)
mysql_mutex_unlock(&LOCK_global_index_stats);
DBUG_RETURN(res);
}
static bool create_string(MEM_ROOT *mem_root, String **s, const char *value)
{
*s= new (mem_root) String(value, system_charset_info);
return *s == NULL;
}
static bool create_sys_trx_field_if_missing(THD *thd, const char *field_name,
Alter_info *alter_info, String **s)
{
Create_field *f= new (thd->mem_root) Create_field();
if (!f)
return true;
f->field_name= field_name;
f->charset= system_charset_info;
f->sql_type= MYSQL_TYPE_TIMESTAMP;
f->length= 6;
f->decimals= 0;
if (f->check(thd))
return true;
if (create_string(thd->mem_root, s, field_name))
return true;
alter_info->create_list.push_back(f);
return false;
}
bool System_versioning_info::add_implicit_fields(THD *thd,
Alter_info *alter_info)
{
if (!declared_system_versioning)
return false;
// If user specified some of these he must specify the others too. Do nothing.
if (generated_as_row.start || generated_as_row.end ||
period_for_system_time.start || period_for_system_time.end)
return false;
return create_sys_trx_field_if_missing(thd, "sys_trx_start", alter_info,
&generated_as_row.start) ||
create_sys_trx_field_if_missing(thd, "sys_trx_end", alter_info,
&generated_as_row.end) ||
create_string(thd->mem_root, &period_for_system_time.start,
"sys_trx_start") ||
create_string(thd->mem_root, &period_for_system_time.end,
"sys_trx_end");
}
......@@ -1683,6 +1683,9 @@ struct System_versioning_info
set_period_for_system_time(NULL, NULL);
}
/** Returns true on failure */
bool add_implicit_fields(THD *thd, Alter_info *alter_info);
/** User has added 'WITH SYSTEM VERSIONING' to table definition */
bool declared_system_versioning;
......@@ -1777,11 +1780,17 @@ struct Table_scope_and_contents_source_st
: ha_default_handlerton(thd);
}
bool versioned()
bool versioned() const
{
return system_versioning_info.versioned;
}
const System_versioning_info *get_system_versioning_info()
const System_versioning_info *get_system_versioning_info() const
{
if (!versioned())
return NULL;
return &system_versioning_info;
}
System_versioning_info *get_system_versioning_info()
{
if (!versioned())
return NULL;
......
......@@ -3561,10 +3561,9 @@ struct LEX: public Query_tables_list
bool add_unit_in_brackets(SELECT_LEX *nselect);
void check_automatic_up(enum sub_select_type type);
System_versioning_info *vers_get_info()
System_versioning_info &vers_get_info()
{
create_info.system_versioning_info.versioned = true;
return &create_info.system_versioning_info;
return create_info.system_versioning_info;
}
};
......
......@@ -3849,10 +3849,6 @@ mysql_execute_command(THD *thd)
copy.
*/
Alter_info alter_info(lex->alter_info, thd->mem_root);
if (check_system_versioning(&create_info))
goto end_with_restore_list;
if (thd->is_fatal_error)
{
/* If out of memory when creating a copy of alter_info. */
......@@ -3860,6 +3856,13 @@ mysql_execute_command(THD *thd)
goto end_with_restore_list;
}
if (System_versioning_info *info= create_info.get_system_versioning_info())
if (info->add_implicit_fields(thd, &alter_info))
goto end_with_restore_list;
if (check_system_versioning(&create_info))
goto end_with_restore_list;
/* Check privileges */
if ((res= create_table_precheck(thd, select_tables, create_table)))
goto end_with_restore_list;
......
......@@ -5852,10 +5852,9 @@ create_table_option:
}
| WITH SYSTEM VERSIONING
{
System_versioning_info *info = Lex->vers_get_info();
if (!info)
MYSQL_YYABORT;
info->declared_system_versioning = true;
System_versioning_info &info= Lex->vers_get_info();
info.declared_system_versioning= true;
info.versioned= true;
}
;
......@@ -6060,15 +6059,14 @@ period_for_system_time:
// If FOR_SYM is followed by SYSTEM_TIME_SYM then they are merged to: FOR_SYSTEM_TIME_SYM .
PERIOD_SYM FOR_SYSTEM_TIME_SYM '(' period_for_system_time_column_id ',' period_for_system_time_column_id ')'
{
System_versioning_info *info = Lex->vers_get_info();
if (!info)
MYSQL_YYABORT;
System_versioning_info &info= Lex->vers_get_info();
if (!my_strcasecmp(system_charset_info, $4->c_ptr(), $6->c_ptr()))
{
my_error(ER_SYS_START_AND_SYS_END_SAME, MYF(0), $4->c_ptr());
MYSQL_YYABORT;
}
info->set_period_for_system_time($4, $6);
info.set_period_for_system_time($4, $6);
info.versioned= true;
}
;
......@@ -6168,26 +6166,24 @@ field_def:
vcol_opt_specifier vcol_opt_attribute
| opt_generated_always AS ROW_SYM start_or_end
{
System_versioning_info *info =
Lex->vers_get_info();
if (!info)
MYSQL_YYABORT;
String *field_name = new (thd->mem_root)
System_versioning_info &info= Lex->vers_get_info();
info.versioned= true;
String *field_name= new (thd->mem_root)
String((const char*)Lex->last_field->field_name, system_charset_info);
if (!field_name)
MYSQL_YYABORT;
String **p = NULL;
int err_nr = 0;
String **p= NULL;
int err_nr= 0;
switch ($4)
{
case 1:
p = &info->generated_as_row.start;
err_nr = ER_SYS_START_MORE_THAN_ONCE;
p= &info.generated_as_row.start;
err_nr= ER_SYS_START_MORE_THAN_ONCE;
break;
case 0:
p = &info->generated_as_row.end;
err_nr = ER_SYS_END_MORE_THAN_ONCE;
p= &info.generated_as_row.end;
err_nr= ER_SYS_END_MORE_THAN_ONCE;
break;
default:
/* Not Reachable */
......@@ -6199,7 +6195,7 @@ field_def:
my_error(err_nr, MYF(0), field_name->c_ptr());
MYSQL_YYABORT;
}
*p = field_name;
*p= field_name;
}
;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment