1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-07 06:01:31 +03:00

MDEV-15413 Unexpected errors upon CREATE TABLE .. WITH SYSTEM VERSIONING AS SELECT ...

numerous fixes for CREATE ... SELECT with system versioning:
In CREATE ... SELECT the table is created based on the result set,
field properties do not count. That is
* field invisibility is *not* copied over
* AS ROW START/END is *not* copied over
* the history is *not* copied over
* system row_start/row_end fields can *not* be created from the SELECT part
This commit is contained in:
Sergei Golubchik
2018-04-02 19:35:27 +02:00
parent 72dd813f7e
commit 9bd3af97df
10 changed files with 114 additions and 191 deletions

View File

@ -331,9 +331,9 @@ select * from t3;
x23 x23
1 1
create or replace table t3 with system versioning select x23, row_start from t1; create or replace table t3 with system versioning select x23, row_start from t1;
ERROR HY000: Wrong parameters for `t3`: missing 'AS ROW END' ERROR 42S21: Duplicate column name 'row_start'
create or replace table t3 with system versioning select x23, row_end from t1; create or replace table t3 with system versioning select x23, row_end from t1;
ERROR HY000: Wrong parameters for `t3`: missing 'AS ROW START' ERROR 42S21: Duplicate column name 'row_end'
# Prepare checking for historical row # Prepare checking for historical row
delete from t1; delete from t1;
select row_end from t1 for system_time all into @row_end; select row_end from t1 for system_time all into @row_end;
@ -373,15 +373,19 @@ as select x25, row_start, row_end from t1 for system_time all;
show create table t2; show create table t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`x25` int(11) DEFAULT NULL `x25` int(11) DEFAULT NULL,
`row_start` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
`row_end` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
create or replace table t2 with system versioning create or replace table t2 with system versioning
as select x25, row_start, row_end from t1; as select x25, row_start rs, row_end re from t1;
show create table t2; show create table t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`x25` int(11) DEFAULT NULL `x25` int(11) DEFAULT NULL,
) ENGINE=NON_DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING `rs` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
`re` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
create or replace table t1 ( create or replace table t1 (
x26 int, x26 int,
st bigint unsigned as row start, st bigint unsigned as row start,
@ -390,17 +394,25 @@ period for system_time (st, en)
) with system versioning engine innodb; ) with system versioning engine innodb;
create or replace table t2 with system versioning engine myisam create or replace table t2 with system versioning engine myisam
as select * from t1; as select * from t1;
ERROR HY000: `st` must be of type TIMESTAMP(6) for system-versioned table `t2` show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`x26` int(11) DEFAULT NULL,
`st` bigint(20) unsigned NOT NULL DEFAULT 0,
`en` bigint(20) unsigned NOT NULL DEFAULT 0
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
create or replace table t1 (x27 int, id int) with system versioning engine NON_DEFAULT_ENGINE; create or replace table t1 (x27 int, id int) with system versioning engine NON_DEFAULT_ENGINE;
create or replace table t2 (b int, id int); create or replace table t2 (b int, id int);
create or replace table t3 with system versioning create or replace table t3 with system versioning
as select t2.b, t1.x27, t1.row_start, t1.row_end from t2 inner join t1 on t2.id=t1.id; as select t2.b, t1.x27, t1.row_start rs, t1.row_end re from t2 inner join t1 on t2.id=t1.id;
show create table t3; show create table t3;
Table Create Table Table Create Table
t3 CREATE TABLE `t3` ( t3 CREATE TABLE `t3` (
`b` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL,
`x27` int(11) DEFAULT NULL `x27` int(11) DEFAULT NULL,
) ENGINE=NON_DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING `rs` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
`re` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
## Errors ## Errors
create or replace temporary table t (x28 int) with system versioning; create or replace temporary table t (x28 int) with system versioning;
ERROR HY000: TEMPORARY tables do not support system versioning ERROR HY000: TEMPORARY tables do not support system versioning
@ -435,8 +447,10 @@ Table Create Table
t3 CREATE TABLE `t3` ( t3 CREATE TABLE `t3` (
`x30` int(11) DEFAULT NULL, `x30` int(11) DEFAULT NULL,
`y` int(11) DEFAULT NULL, `y` int(11) DEFAULT NULL,
`st` timestamp(6) NOT NULL INVISIBLE DEFAULT '0000-00-00 00:00:00.000000', `row_start` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
`en` timestamp(6) NOT NULL INVISIBLE DEFAULT '0000-00-00 00:00:00.000000' `row_end` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
`st` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
`en` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1
create or replace table t3 ( create or replace table t3 (
y int, y int,
@ -450,6 +464,8 @@ Table Create Table
t3 CREATE TABLE `t3` ( t3 CREATE TABLE `t3` (
`x30` int(11) DEFAULT NULL, `x30` int(11) DEFAULT NULL,
`y` int(11) DEFAULT NULL, `y` int(11) DEFAULT NULL,
`row_start` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
`row_end` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
`st` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE, `st` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE,
`en` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE, `en` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME (`st`, `en`) PERIOD FOR SYSTEM_TIME (`st`, `en`)
@ -466,5 +482,18 @@ execute bad;
execute bad; execute bad;
execute bad; execute bad;
# bad is good. # bad is good.
# MDEV-15413 Unexpected errors upon CREATE TABLE .. WITH SYSTEM VERSIONING AS SELECT ...
create or replace table t1 with system versioning as select 1 as i;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`i` int(1) NOT NULL
) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
create or replace table t1 (i int) with system versioning as select 1 as i;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`i` int(11) DEFAULT NULL
) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
drop database test; drop database test;
create database test; create database test;

View File

@ -396,7 +396,7 @@ create or replace table t1 (a int) with system versioning;
create or replace table t2 (b int); create or replace table t2 (b int);
create or replace view v1 as select a, row_start, row_end from t1 where a > round(rand()*1000); create or replace view v1 as select a, row_start, row_end from t1 where a > round(rand()*1000);
select * from v1 natural join t2; select * from v1 natural join t2;
a b a row_start row_end b
# #
# Issue #406, MDEV-14633 Assertion on TRT read # Issue #406, MDEV-14633 Assertion on TRT read
# #

View File

@ -247,9 +247,9 @@ create or replace table t3 with system versioning select x23 from t1;
--replace_result $default_engine DEFAULT_ENGINE --replace_result $default_engine DEFAULT_ENGINE
show create table t3; show create table t3;
select * from t3; select * from t3;
--error ER_MISSING --error ER_DUP_FIELDNAME
create or replace table t3 with system versioning select x23, row_start from t1; create or replace table t3 with system versioning select x23, row_start from t1;
--error ER_MISSING --error ER_DUP_FIELDNAME
create or replace table t3 with system versioning select x23, row_end from t1; create or replace table t3 with system versioning select x23, row_end from t1;
--echo # Prepare checking for historical row --echo # Prepare checking for historical row
@ -286,8 +286,8 @@ as select x25, row_start, row_end from t1 for system_time all;
show create table t2; show create table t2;
create or replace table t2 with system versioning create or replace table t2 with system versioning
as select x25, row_start, row_end from t1; as select x25, row_start rs, row_end re from t1;
--replace_result $non_default_engine NON_DEFAULT_ENGINE --replace_result $default_engine DEFAULT_ENGINE
show create table t2; show create table t2;
create or replace table t1 ( create or replace table t1 (
@ -296,16 +296,16 @@ create or replace table t1 (
en bigint unsigned as row end, en bigint unsigned as row end,
period for system_time (st, en) period for system_time (st, en)
) with system versioning engine innodb; ) with system versioning engine innodb;
--error ER_VERS_FIELD_WRONG_TYPE
create or replace table t2 with system versioning engine myisam create or replace table t2 with system versioning engine myisam
as select * from t1; as select * from t1;
show create table t2;
--replace_result $non_default_engine NON_DEFAULT_ENGINE --replace_result $non_default_engine NON_DEFAULT_ENGINE
eval create or replace table t1 (x27 int, id int) with system versioning engine $non_default_engine; eval create or replace table t1 (x27 int, id int) with system versioning engine $non_default_engine;
create or replace table t2 (b int, id int); create or replace table t2 (b int, id int);
create or replace table t3 with system versioning create or replace table t3 with system versioning
as select t2.b, t1.x27, t1.row_start, t1.row_end from t2 inner join t1 on t2.id=t1.id; as select t2.b, t1.x27, t1.row_start rs, t1.row_end re from t2 inner join t1 on t2.id=t1.id;
--replace_result $non_default_engine NON_DEFAULT_ENGINE --replace_result $default_engine DEFAULT_ENGINE
show create table t3; show create table t3;
--echo ## Errors --echo ## Errors
@ -363,5 +363,13 @@ prepare bad from 'create or replace table t2 with system versioning as select *
execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad; execute bad;
--echo # bad is good. --echo # bad is good.
--echo # MDEV-15413 Unexpected errors upon CREATE TABLE .. WITH SYSTEM VERSIONING AS SELECT ...
create or replace table t1 with system versioning as select 1 as i;
--replace_result $default_engine DEFAULT_ENGINE
show create table t1;
create or replace table t1 (i int) with system versioning as select 1 as i;
--replace_result $default_engine DEFAULT_ENGINE
show create table t1;
drop database test; drop database test;
create database test; create database test;

View File

@ -6887,7 +6887,7 @@ static bool vers_create_sys_field(THD *thd, const char *field_name,
const LString_i Vers_parse_info::default_start= "row_start"; const LString_i Vers_parse_info::default_start= "row_start";
const LString_i Vers_parse_info::default_end= "row_end"; const LString_i Vers_parse_info::default_end= "row_end";
bool Vers_parse_info::fix_implicit(THD *thd, Alter_info *alter_info, int *added) bool Vers_parse_info::fix_implicit(THD *thd, Alter_info *alter_info)
{ {
// If user specified some of these he must specify the others too. Do nothing. // If user specified some of these he must specify the others too. Do nothing.
if (*this) if (*this)
@ -6903,8 +6903,6 @@ bool Vers_parse_info::fix_implicit(THD *thd, Alter_info *alter_info, int *added)
{ {
return true; return true;
} }
if (added)
*added+= 2;
return false; return false;
} }
@ -6932,47 +6930,15 @@ bool Table_scope_and_contents_source_st::vers_native(THD *thd) const
} }
bool Table_scope_and_contents_source_st::vers_fix_system_fields( bool Table_scope_and_contents_source_st::vers_fix_system_fields(
THD *thd, THD *thd, Alter_info *alter_info, const TABLE_LIST &create_table,
Alter_info *alter_info, bool create_select)
const TABLE_LIST &create_table,
const TABLE_LIST *select_tables,
List<Item> *items,
bool *versioned_write)
{ {
DBUG_ASSERT(!(alter_info->flags & ALTER_DROP_SYSTEM_VERSIONING)); DBUG_ASSERT(!(alter_info->flags & ALTER_DROP_SYSTEM_VERSIONING));
int vers_tables= 0;
if (select_tables)
{
for (const TABLE_LIST *table= select_tables; table; table= table->next_local)
{
if (table->table && table->table->versioned())
vers_tables++;
}
}
DBUG_EXECUTE_IF("sysvers_force", if (!tmp_table()) { DBUG_EXECUTE_IF("sysvers_force", if (!tmp_table()) {
alter_info->flags|= ALTER_ADD_SYSTEM_VERSIONING; alter_info->flags|= ALTER_ADD_SYSTEM_VERSIONING;
options|= HA_VERSIONED_TABLE; }); options|= HA_VERSIONED_TABLE; });
// Possibly override default storage engine to match one used in source table.
if (vers_tables && alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING &&
!(used_fields & HA_CREATE_USED_ENGINE))
{
List_iterator_fast<Create_field> it(alter_info->create_list);
while (Create_field *f= it++)
{
if (vers_info.is_start(*f) || vers_info.is_end(*f))
{
if (f->field)
{
db_type= f->field->orig_table->file->ht;
}
break;
}
}
}
if (!vers_info.need_check(alter_info)) if (!vers_info.need_check(alter_info))
return false; return false;
@ -6991,15 +6957,7 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields(
return true; return true;
} }
if (vers_tables)
{
DBUG_ASSERT(options & HA_VERSIONED_TABLE);
DBUG_ASSERT(versioned_write);
*versioned_write= true;
}
List_iterator<Create_field> it(alter_info->create_list); List_iterator<Create_field> it(alter_info->create_list);
bool explicit_declared= vers_info.as_row.start || vers_info.as_row.end;
while (Create_field *f= it++) while (Create_field *f= it++)
{ {
if ((f->versioning == Column_definition::VERSIONING_NOT_SET && if ((f->versioning == Column_definition::VERSIONING_NOT_SET &&
@ -7008,81 +6966,11 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields(
{ {
f->flags|= VERS_UPDATE_UNVERSIONED_FLAG; f->flags|= VERS_UPDATE_UNVERSIONED_FLAG;
} }
/* Assign selected implicit fields when no explicit fields */
if (!vers_tables || explicit_declared)
continue;
DBUG_ASSERT(versioned_write);
if (vers_info.is_start(*f) && vers_info.default_start.streq(f->field_name))
{
if (vers_info.as_row.start)
it.remove();
else
{
vers_info.set_start(f->field_name);
*versioned_write= false;
}
continue;
}
if (vers_info.is_end(*f) && vers_info.default_end.streq(f->field_name))
{
if (vers_info.as_row.end)
it.remove();
else
{
vers_info.set_end(f->field_name);
*versioned_write= false;
}
continue;
}
} // while (Create_field *f= it++) } // while (Create_field *f= it++)
/* Assign selected system fields to explicit system fields if any */ if (vers_info.fix_implicit(thd, alter_info))
if (vers_tables)
{
it.rewind();
while (Create_field *f= it++)
{
uint flags_left= VERS_SYSTEM_FIELD;
if (flags_left && (vers_info.is_start(*f) || vers_info.is_end(*f)) && !f->field)
{
uint sys_flag= f->flags & flags_left;
flags_left-= sys_flag;
List_iterator_fast<Item> it2(*items);
while (Item *item= it2++)
{
if (item->type() != Item::FIELD_ITEM)
continue;
Field *fld= static_cast<Item_field *>(item)->field;
DBUG_ASSERT(fld);
if ((fld->flags & sys_flag) &&
lex_string_syseq(&f->field_name, &fld->field_name))
{
f->field= fld;
*versioned_write= false;
}
} // while (item)
} // if (flags_left ...
} // while (Create_field *f= it++)
} // if (vers_tables)
int added= 0;
if (vers_info.fix_implicit(thd, alter_info, &added))
return true; return true;
DBUG_ASSERT(added >= 0);
if (vers_tables)
{
DBUG_ASSERT(items);
while (added--)
{
Item_default_value *item= new (thd->mem_root)
Item_default_value(thd, thd->lex->current_context());
items->push_back(item, thd->mem_root);
}
}
int plain_cols= 0; // columns don't have WITH or WITHOUT SYSTEM VERSIONING int plain_cols= 0; // columns don't have WITH or WITHOUT SYSTEM VERSIONING
int vers_cols= 0; // columns have WITH SYSTEM VERSIONING int vers_cols= 0; // columns have WITH SYSTEM VERSIONING
it.rewind(); it.rewind();
@ -7099,25 +6987,27 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields(
if (!thd->lex->tmp_table() && if (!thd->lex->tmp_table() &&
// CREATE from SELECT (Create_fields are not yet added) // CREATE from SELECT (Create_fields are not yet added)
!select_tables && !create_select && vers_cols == 0 && (plain_cols == 0 || !vers_info))
vers_cols == 0 &&
(plain_cols == 0 || !vers_info))
{ {
my_error(ER_VERS_TABLE_MUST_HAVE_COLUMNS, MYF(0), my_error(ER_VERS_TABLE_MUST_HAVE_COLUMNS, MYF(0),
create_table.table_name.str); create_table.table_name.str);
return true; return true;
} }
if (vers_info.check_conditions(create_table.table_name.str, create_table.db))
return true;
bool native= vers_native(thd);
if (vers_info.check_sys_fields(create_table.table_name.str, alter_info, native))
return true;
return false; return false;
} }
bool Table_scope_and_contents_source_st::vers_check_system_fields(
THD *thd, Alter_info *alter_info, const TABLE_LIST &create_table)
{
if (!(options & HA_VERSIONED_TABLE))
return false;
return vers_info.check_sys_fields(create_table.table_name, create_table.db,
alter_info, vers_native(thd));
}
bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info,
HA_CREATE_INFO *create_info, TABLE *table) HA_CREATE_INFO *create_info, TABLE *table)
{ {
@ -7221,10 +7111,8 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info,
if (alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING) if (alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING)
{ {
if (check_conditions(table_name, share->db))
return true;
bool native= create_info->vers_native(thd); bool native= create_info->vers_native(thd);
if (check_sys_fields(table_name, alter_info, native)) if (check_sys_fields(table_name, share->db, alter_info, native))
return true; return true;
} }
@ -7298,19 +7186,19 @@ bool Vers_parse_info::need_check(const Alter_info *alter_info) const
alter_info->flags & ALTER_DROP_SYSTEM_VERSIONING || *this; alter_info->flags & ALTER_DROP_SYSTEM_VERSIONING || *this;
} }
bool Vers_parse_info::check_conditions(const char *table_name, bool Vers_parse_info::check_conditions(const LString &table_name,
const LString &db) const const LString &db) const
{ {
if (!as_row.start || !as_row.end) if (!as_row.start || !as_row.end)
{ {
my_error(ER_MISSING, MYF(0), table_name, my_error(ER_MISSING, MYF(0), table_name.str,
as_row.start ? "AS ROW END" : "AS ROW START"); as_row.start ? "AS ROW END" : "AS ROW START");
return true; return true;
} }
if (!system_time.start || !system_time.end) if (!system_time.start || !system_time.end)
{ {
my_error(ER_MISSING, MYF(0), table_name, "PERIOD FOR SYSTEM_TIME"); my_error(ER_MISSING, MYF(0), table_name.str, "PERIOD FOR SYSTEM_TIME");
return true; return true;
} }
@ -7329,9 +7217,12 @@ bool Vers_parse_info::check_conditions(const char *table_name,
return false; return false;
} }
bool Vers_parse_info::check_sys_fields(const char *table_name, bool Vers_parse_info::check_sys_fields(const LString &table_name, const LString &db,
Alter_info *alter_info, bool native) Alter_info *alter_info, bool native)
{ {
if (check_conditions(table_name, db))
return true;
List_iterator<Create_field> it(alter_info->create_list); List_iterator<Create_field> it(alter_info->create_list);
uint found_flag= 0; uint found_flag= 0;
while (Create_field *f= it++) while (Create_field *f= it++)
@ -7390,14 +7281,14 @@ bool Vers_parse_info::check_sys_fields(const char *table_name,
check_unit == VERS_TIMESTAMP ? check_unit == VERS_TIMESTAMP ?
"TIMESTAMP(6)" : "TIMESTAMP(6)" :
"BIGINT(20) UNSIGNED", "BIGINT(20) UNSIGNED",
table_name); table_name.str);
return true; return true;
} }
check_unit= f_check_unit; check_unit= f_check_unit;
} }
} }
my_error(ER_MISSING, MYF(0), table_name, found_flag & VERS_SYS_START_FLAG ? my_error(ER_MISSING, MYF(0), table_name.str, found_flag & VERS_SYS_START_FLAG ?
"ROW END" : found_flag ? "ROW START" : "ROW START/END"); "ROW END" : found_flag ? "ROW START" : "ROW START/END");
return true; return true;
} }

View File

@ -1949,16 +1949,13 @@ protected:
bool is_end(const char *name) const; bool is_end(const char *name) const;
bool is_start(const Create_field &f) const; bool is_start(const Create_field &f) const;
bool is_end(const Create_field &f) const; bool is_end(const Create_field &f) const;
bool fix_implicit(THD *thd, Alter_info *alter_info, int *added= NULL); bool fix_implicit(THD *thd, Alter_info *alter_info);
operator bool() const operator bool() const
{ {
return as_row.start || as_row.end || system_time.start || system_time.end; return as_row.start || as_row.end || system_time.start || system_time.end;
} }
bool need_check(const Alter_info *alter_info) const; bool need_check(const Alter_info *alter_info) const;
bool check_conditions(const char *table_name, const LString &db) const; bool check_conditions(const LString &table_name, const LString &db) const;
bool check_sys_fields(const char *table_name, Alter_info *alter_info,
bool native);
public: public:
static const LString_i default_start; static const LString_i default_start;
static const LString_i default_end; static const LString_i default_end;
@ -1967,6 +1964,8 @@ public:
HA_CREATE_INFO *create_info, TABLE *table); HA_CREATE_INFO *create_info, TABLE *table);
bool fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_info, bool fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_info,
TABLE_LIST &src_table, TABLE_LIST &table); TABLE_LIST &src_table, TABLE_LIST &table);
bool check_sys_fields(const LString &table_name, const LString &db,
Alter_info *alter_info, bool native);
/** /**
At least one field was specified 'WITH/WITHOUT SYSTEM VERSIONING'. At least one field was specified 'WITH/WITHOUT SYSTEM VERSIONING'.
@ -2054,9 +2053,10 @@ struct Table_scope_and_contents_source_st
bool vers_fix_system_fields(THD *thd, Alter_info *alter_info, bool vers_fix_system_fields(THD *thd, Alter_info *alter_info,
const TABLE_LIST &create_table, const TABLE_LIST &create_table,
const TABLE_LIST *select_table= NULL, bool create_select= false);
List<Item> *items= NULL,
bool *versioned_write= NULL); bool vers_check_system_fields(THD *thd, Alter_info *alter_info,
const TABLE_LIST &create_table);
bool vers_native(THD *thd) const; bool vers_native(THD *thd) const;

View File

@ -5145,7 +5145,6 @@ class select_insert :public select_result_interceptor {
ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not
COPY_INFO info; COPY_INFO info;
bool insert_into_view; bool insert_into_view;
bool versioned_write;
select_insert(THD *thd_arg, TABLE_LIST *table_list_par, select_insert(THD *thd_arg, TABLE_LIST *table_list_par,
TABLE *table_par, List<Item> *fields_par, TABLE *table_par, List<Item> *fields_par,
List<Item> *update_fields, List<Item> *update_values, List<Item> *update_fields, List<Item> *update_values,

View File

@ -3591,8 +3591,7 @@ select_insert::select_insert(THD *thd_arg, TABLE_LIST *table_list_par,
select_result_interceptor(thd_arg), select_result_interceptor(thd_arg),
table_list(table_list_par), table(table_par), fields(fields_par), table_list(table_list_par), table(table_par), fields(fields_par),
autoinc_value_of_last_inserted_row(0), autoinc_value_of_last_inserted_row(0),
insert_into_view(table_list_par && table_list_par->view != 0), insert_into_view(table_list_par && table_list_par->view != 0)
versioned_write(false)
{ {
bzero((char*) &info,sizeof(info)); bzero((char*) &info,sizeof(info));
info.handle_duplicates= duplic; info.handle_duplicates= duplic;
@ -3627,8 +3626,6 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
check_insert_fields(thd, table_list, *fields, values, check_insert_fields(thd, table_list, *fields, values,
!insert_into_view, 1, &map)); !insert_into_view, 1, &map));
versioned_write= table_list->table->versioned();
if (!res && fields->elements) if (!res && fields->elements)
{ {
bool saved_abort_on_warning= thd->abort_on_warning; bool saved_abort_on_warning= thd->abort_on_warning;
@ -3841,7 +3838,8 @@ int select_insert::send_data(List<Item> &values)
table->auto_increment_field_not_null= FALSE; table->auto_increment_field_not_null= FALSE;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
table->vers_write= versioned_write;
table->vers_write= table->versioned();
if (table_list) // Not CREATE ... SELECT if (table_list) // Not CREATE ... SELECT
{ {
switch (table_list->view_check_option(thd, info.ignore)) { switch (table_list->view_check_option(thd, info.ignore)) {
@ -4139,7 +4137,7 @@ TABLE *select_create::create_table_from_items(THD *thd,
/* Add selected items to field list */ /* Add selected items to field list */
List_iterator_fast<Item> it(*items); List_iterator_fast<Item> it(*items);
Item *item; Item *item;
DBUG_ENTER("create_table_from_items"); DBUG_ENTER("select_create::create_table_from_items");
tmp_table.s= &share; tmp_table.s= &share;
init_tmp_table_share(thd, &share, "", 0, "", ""); init_tmp_table_share(thd, &share, "", 0, "", "");
@ -4152,6 +4150,10 @@ TABLE *select_create::create_table_from_items(THD *thd,
if (!opt_explicit_defaults_for_timestamp) if (!opt_explicit_defaults_for_timestamp)
promote_first_timestamp_column(&alter_info->create_list); promote_first_timestamp_column(&alter_info->create_list);
if (create_info->vers_fix_system_fields(thd, alter_info, *create_table,
true))
DBUG_RETURN(NULL);
while ((item=it++)) while ((item=it++))
{ {
Field *tmp_field= item->create_field_for_create_select(&tmp_table); Field *tmp_field= item->create_field_for_create_select(&tmp_table);
@ -4188,11 +4190,8 @@ TABLE *select_create::create_table_from_items(THD *thd,
alter_info->create_list.push_back(cr_field, thd->mem_root); alter_info->create_list.push_back(cr_field, thd->mem_root);
} }
if (create_info->vers_fix_system_fields(thd, alter_info, *create_table, if (create_info->vers_check_system_fields(thd, alter_info, *create_table))
select_tables, items, &versioned_write))
{
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
}
DEBUG_SYNC(thd,"create_table_select_before_create"); DEBUG_SYNC(thd,"create_table_select_before_create");
@ -4436,11 +4435,16 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
} }
/* First field to copy */ /* First field to copy */
field= table->field+table->s->fields - values.elements; field= table->field+table->s->fields;
/* Mark all fields that are given values */ /* Mark all fields that are given values */
for (Field **f= field ; *f ; f++) for (uint n= values.elements; n; )
bitmap_set_bit(table->write_set, (*f)->field_index); {
if ((*--field)->invisible >= INVISIBLE_SYSTEM)
continue;
n--;
bitmap_set_bit(table->write_set, (*field)->field_index);
}
table->next_number_field=table->found_next_number_field; table->next_number_field=table->found_next_number_field;

View File

@ -4252,10 +4252,10 @@ mysql_execute_command(THD *thd)
} }
else else
{ {
if (create_info.vers_fix_system_fields(thd, &alter_info, *create_table)) if (create_info.vers_fix_system_fields(thd, &alter_info, *create_table) ||
{ create_info.vers_check_system_fields(thd, &alter_info, *create_table))
goto end_with_restore_list; goto end_with_restore_list;
}
/* /*
In STATEMENT format, we probably have to replicate also temporary In STATEMENT format, we probably have to replicate also temporary
tables, like mysql replication does. Also check if the requested tables, like mysql replication does. Also check if the requested

View File

@ -16517,11 +16517,7 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field,
item->result_field= new_field; item->result_field= new_field;
else else
new_field->field_name= *name; new_field->field_name= *name;
new_field->flags|= (org_field->flags & ( new_field->flags|= org_field->flags & NO_DEFAULT_VALUE_FLAG;
NO_DEFAULT_VALUE_FLAG |
VERS_SYS_START_FLAG |
VERS_SYS_END_FLAG |
VERS_UPDATE_UNVERSIONED_FLAG));
if (org_field->maybe_null() || (item && item->maybe_null)) if (org_field->maybe_null() || (item && item->maybe_null))
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
if (org_field->type() == MYSQL_TYPE_VAR_STRING || if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
@ -16786,9 +16782,6 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
NULL); NULL);
} }
if (field->field->vers_sys_field())
result->invisible= field->field->invisible;
if (orig_type == Item::REF_ITEM && orig_modify) if (orig_type == Item::REF_ITEM && orig_modify)
((Item_ref*)orig_item)->set_result_field(result); ((Item_ref*)orig_item)->set_result_field(result);
/* /*

View File

@ -3439,8 +3439,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
select_field_pos= alter_info->create_list.elements - select_field_count;
for (field_no=0; (sql_field=it++) ; field_no++) for (field_no=0; (sql_field=it++) ; field_no++)
{ {
/* /*
@ -3483,7 +3481,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
If this was a CREATE ... SELECT statement, accept a field If this was a CREATE ... SELECT statement, accept a field
redefinition if we are changing a field in the SELECT part redefinition if we are changing a field in the SELECT part
*/ */
if (field_no < select_field_pos || dup_no >= select_field_pos) if (field_no < select_field_pos || dup_no >= select_field_pos ||
dup_field->invisible >= INVISIBLE_SYSTEM)
{ {
my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name.str); my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name.str);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);