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` ( ...@@ -1949,6 +1949,19 @@ t1 CREATE TABLE `t1` (
PERIOD FOR SYSTEM_TIME (`Sys_start`, `Sys_end`) PERIOD FOR SYSTEM_TIME (`Sys_start`, `Sys_end`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING ) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
drop table if exists t1; 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 ( create table t1 (
XNo INT UNSIGNED, XNo INT UNSIGNED,
Sys_start TIMESTAMP(6) GENERATED ALWAYS AS ROW START, Sys_start TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
......
...@@ -1799,6 +1799,14 @@ SHOW CREATE TABLE t1; ...@@ -1799,6 +1799,14 @@ SHOW CREATE TABLE t1;
drop table if exists 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 --error ER_SYS_START_MORE_THAN_ONCE
create table t1 ( create table t1 (
XNo INT UNSIGNED, XNo INT UNSIGNED,
......
...@@ -6552,3 +6552,53 @@ int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info) ...@@ -6552,3 +6552,53 @@ int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info)
mysql_mutex_unlock(&LOCK_global_index_stats); mysql_mutex_unlock(&LOCK_global_index_stats);
DBUG_RETURN(res); 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 ...@@ -1683,6 +1683,9 @@ struct System_versioning_info
set_period_for_system_time(NULL, NULL); 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 */ /** User has added 'WITH SYSTEM VERSIONING' to table definition */
bool declared_system_versioning; bool declared_system_versioning;
...@@ -1777,11 +1780,17 @@ struct Table_scope_and_contents_source_st ...@@ -1777,11 +1780,17 @@ struct Table_scope_and_contents_source_st
: ha_default_handlerton(thd); : ha_default_handlerton(thd);
} }
bool versioned() bool versioned() const
{ {
return system_versioning_info.versioned; 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()) if (!versioned())
return NULL; return NULL;
......
...@@ -3561,10 +3561,9 @@ struct LEX: public Query_tables_list ...@@ -3561,10 +3561,9 @@ struct LEX: public Query_tables_list
bool add_unit_in_brackets(SELECT_LEX *nselect); bool add_unit_in_brackets(SELECT_LEX *nselect);
void check_automatic_up(enum sub_select_type type); 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) ...@@ -3849,10 +3849,6 @@ mysql_execute_command(THD *thd)
copy. copy.
*/ */
Alter_info alter_info(lex->alter_info, thd->mem_root); 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 (thd->is_fatal_error)
{ {
/* If out of memory when creating a copy of alter_info. */ /* If out of memory when creating a copy of alter_info. */
...@@ -3860,6 +3856,13 @@ mysql_execute_command(THD *thd) ...@@ -3860,6 +3856,13 @@ mysql_execute_command(THD *thd)
goto end_with_restore_list; 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 */ /* Check privileges */
if ((res= create_table_precheck(thd, select_tables, create_table))) if ((res= create_table_precheck(thd, select_tables, create_table)))
goto end_with_restore_list; goto end_with_restore_list;
......
...@@ -5852,10 +5852,9 @@ create_table_option: ...@@ -5852,10 +5852,9 @@ create_table_option:
} }
| WITH SYSTEM VERSIONING | WITH SYSTEM VERSIONING
{ {
System_versioning_info *info = Lex->vers_get_info(); System_versioning_info &info= Lex->vers_get_info();
if (!info) info.declared_system_versioning= true;
MYSQL_YYABORT; info.versioned= true;
info->declared_system_versioning = true;
} }
; ;
...@@ -6060,15 +6059,14 @@ period_for_system_time: ...@@ -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 . // 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 ')' 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(); System_versioning_info &info= Lex->vers_get_info();
if (!info)
MYSQL_YYABORT;
if (!my_strcasecmp(system_charset_info, $4->c_ptr(), $6->c_ptr())) 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()); my_error(ER_SYS_START_AND_SYS_END_SAME, MYF(0), $4->c_ptr());
MYSQL_YYABORT; 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: ...@@ -6168,26 +6166,24 @@ field_def:
vcol_opt_specifier vcol_opt_attribute vcol_opt_specifier vcol_opt_attribute
| opt_generated_always AS ROW_SYM start_or_end | opt_generated_always AS ROW_SYM start_or_end
{ {
System_versioning_info *info = System_versioning_info &info= Lex->vers_get_info();
Lex->vers_get_info(); info.versioned= true;
if (!info) String *field_name= new (thd->mem_root)
MYSQL_YYABORT;
String *field_name = new (thd->mem_root)
String((const char*)Lex->last_field->field_name, system_charset_info); String((const char*)Lex->last_field->field_name, system_charset_info);
if (!field_name) if (!field_name)
MYSQL_YYABORT; MYSQL_YYABORT;
String **p = NULL; String **p= NULL;
int err_nr = 0; int err_nr= 0;
switch ($4) switch ($4)
{ {
case 1: case 1:
p = &info->generated_as_row.start; p= &info.generated_as_row.start;
err_nr = ER_SYS_START_MORE_THAN_ONCE; err_nr= ER_SYS_START_MORE_THAN_ONCE;
break; break;
case 0: case 0:
p = &info->generated_as_row.end; p= &info.generated_as_row.end;
err_nr = ER_SYS_END_MORE_THAN_ONCE; err_nr= ER_SYS_END_MORE_THAN_ONCE;
break; break;
default: default:
/* Not Reachable */ /* Not Reachable */
...@@ -6199,7 +6195,7 @@ field_def: ...@@ -6199,7 +6195,7 @@ field_def:
my_error(err_nr, MYF(0), field_name->c_ptr()); my_error(err_nr, MYF(0), field_name->c_ptr());
MYSQL_YYABORT; 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