Commit 485325e7 authored by Sergei Golubchik's avatar Sergei Golubchik

don't allow TIMESTAMP(6) versioning and FK with CASCADE or SET NULL

parent 794f71cb
--- suite/versioning/r/foreign.result
+++ suite/versioning/r/foreign,trx_id.reject
@@ -6,8 +6,8 @@
) engine innodb;
create table child(
parent_id int,
-sys_start timestamp(6) as row start invisible,
-sys_end timestamp(6) as row end invisible,
+sys_start bigint(20) unsigned as row start invisible,
+sys_end bigint(20) unsigned as row end invisible,
period for system_time(sys_start, sys_end),
foreign key(parent_id) references parent(id)
on delete restrict
@@ -39,8 +39,8 @@
) engine innodb;
create table child(
parent_id int(10) unsigned primary key,
-sys_start timestamp(6) as row start invisible,
-sys_end timestamp(6) as row end invisible,
+sys_start bigint(20) unsigned as row start invisible,
+sys_end bigint(20) unsigned as row end invisible,
period for system_time(sys_start, sys_end),
foreign key(parent_id) references parent(id)
) engine innodb with system versioning;
@@ -58,19 +58,39 @@
) engine innodb;
create table child(
parent_id int,
-sys_start timestamp(6) as row start invisible,
-sys_end timestamp(6) as row end invisible,
+sys_start bigint(20) unsigned as row start invisible,
+sys_end bigint(20) unsigned as row end invisible,
period for system_time(sys_start, sys_end),
foreign key(parent_id) references parent(id)
on delete cascade
on update cascade
) engine innodb with system versioning;
-ERROR HY000: CASCADE is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
+insert into parent values(1);
+insert into child values(1);
+delete from parent where id = 1;
+delete from child where parent_id = 1;
+delete from parent where id = 1;
+select * from child;
+parent_id
+select * from child for system_time all;
+parent_id
+1
+insert into parent values(1);
+insert into child values(1);
+update parent set id = id + 1;
+select * from child;
+parent_id
+2
+select * from child for system_time all;
+parent_id
+1
+2
+drop table child;
drop table parent;
create or replace table parent (
id int primary key,
-sys_start timestamp(6) as row start invisible,
-sys_end timestamp(6) as row end invisible,
+sys_start bigint(20) unsigned as row start invisible,
+sys_end bigint(20) unsigned as row end invisible,
period for system_time(sys_start, sys_end)
) with system versioning
engine innodb;
@@ -97,8 +117,8 @@
create or replace table child (
id int primary key,
parent_id int not null,
-row_start timestamp(6) as row start invisible,
-row_end timestamp(6) as row end invisible,
+row_start bigint(20) unsigned as row start invisible,
+row_end bigint(20) unsigned as row end invisible,
period for system_time(row_start, row_end),
constraint `parent-fk`
foreign key (parent_id) references parent (id)
@@ -106,7 +126,18 @@
on update restrict
) with system versioning
engine innodb;
-ERROR HY000: CASCADE is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
+insert into parent (id) values (3);
+insert into child (id, parent_id) values (3, 3);
+## FIXME: #415 update of foreign constraints is disabled
+delete from child;
+## FIXME END
+delete from parent;
+select * from child;
+id parent_id
+select *, row_start < row_end, row_end < MAXVAL from child for system_time all;
+id parent_id row_start < row_end row_end < MAXVAL
+3 3 1 1
+drop table child;
drop table parent;
#################
# Test SET NULL #
@@ -116,22 +147,39 @@
) engine innodb;
create table child(
parent_id int,
-sys_start timestamp(6) as row start invisible,
-sys_end timestamp(6) as row end invisible,
+sys_start bigint(20) unsigned as row start invisible,
+sys_end bigint(20) unsigned as row end invisible,
period for system_time(sys_start, sys_end),
foreign key(parent_id) references parent(id)
on delete set null
on update set null
) engine innodb with system versioning;
-ERROR HY000: SET NULL is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
+insert into parent values(1);
+insert into child values(1);
+delete from child;
+insert into child values(1);
+## FIXME: #415 update of foreign constraints is disabled
+delete from child where parent_id = 1;
+## FIXME END
+delete from parent where id = 1;
+select * from child;
+parent_id
+select * from child for system_time from timestamp 0 to timestamp now(6);
+parent_id
+1
+1
+delete from child;
+insert into parent values(1);
+insert into child values(1);
+drop table child;
drop table parent;
###########################
# Parent table is foreign #
###########################
create or replace table parent(
id int unique key,
-sys_start timestamp(6) as row start invisible,
-sys_end timestamp(6) as row end invisible,
+sys_start bigint(20) unsigned as row start invisible,
+sys_end bigint(20) unsigned as row end invisible,
period for system_time(sys_start, sys_end)
) engine innodb with system versioning;
create or replace table child(
@@ -162,16 +210,16 @@
create or replace table a (
cola int(10) primary key,
v_cola int(10) as (cola mod 10) virtual,
-sys_start timestamp(6) as row start invisible,
-sys_end timestamp(6) as row end invisible,
+sys_start bigint(20) unsigned as row start invisible,
+sys_end bigint(20) unsigned as row end invisible,
period for system_time(sys_start, sys_end)
) engine=innodb with system versioning;
create index v_cola on a (v_cola);
create or replace table b(
cola int(10),
v_cola int(10),
-sys_start timestamp(6) as row start invisible,
-sys_end timestamp(6) as row end invisible,
+sys_start bigint(20) unsigned as row start invisible,
+sys_end bigint(20) unsigned as row end invisible,
period for system_time(sys_start, sys_end)
) engine=innodb with system versioning;
alter table b add constraint `v_cola_fk`
......@@ -6,8 +6,8 @@ id int unique key
) engine innodb;
create table child(
parent_id int,
sys_start SYS_DATATYPE as row start invisible,
sys_end SYS_DATATYPE as row end invisible,
sys_start timestamp(6) as row start invisible,
sys_end timestamp(6) as row end invisible,
period for system_time(sys_start, sys_end),
foreign key(parent_id) references parent(id)
on delete restrict
......@@ -39,8 +39,8 @@ id int(10) unsigned unique key
) engine innodb;
create table child(
parent_id int(10) unsigned primary key,
sys_start SYS_DATATYPE as row start invisible,
sys_end SYS_DATATYPE as row end invisible,
sys_start timestamp(6) as row start invisible,
sys_end timestamp(6) as row end invisible,
period for system_time(sys_start, sys_end),
foreign key(parent_id) references parent(id)
) engine innodb with system versioning;
......@@ -58,43 +58,19 @@ id int unique key
) engine innodb;
create table child(
parent_id int,
sys_start SYS_DATATYPE as row start invisible,
sys_end SYS_DATATYPE as row end invisible,
sys_start timestamp(6) as row start invisible,
sys_end timestamp(6) as row end invisible,
period for system_time(sys_start, sys_end),
foreign key(parent_id) references parent(id)
on delete cascade
on update cascade
) engine innodb with system versioning;
insert into parent values(1);
insert into child values(1);
## FIXME: #415 update of foreign constraints is disabled
call mtr.add_suppression("foreign key constraints in timestamp-based temporal table");
delete from parent where id = 1;
ERROR 42000: Table 'parent' uses an extension that doesn't exist in this MariaDB version
delete from child where parent_id = 1;
## FIXME END
delete from parent where id = 1;
select * from child;
parent_id
select * from child for system_time all;
parent_id
1
insert into parent values(1);
insert into child values(1);
update parent set id = id + 1;
select * from child;
parent_id
2
select * from child for system_time all;
parent_id
1
2
drop table child;
ERROR HY000: CASCADE is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
drop table parent;
create or replace table parent (
id int primary key,
sys_start SYS_DATATYPE as row start invisible,
sys_end SYS_DATATYPE as row end invisible,
sys_start timestamp(6) as row start invisible,
sys_end timestamp(6) as row end invisible,
period for system_time(sys_start, sys_end)
) with system versioning
engine innodb;
......@@ -121,8 +97,8 @@ engine innodb;
create or replace table child (
id int primary key,
parent_id int not null,
row_start SYS_DATATYPE as row start invisible,
row_end SYS_DATATYPE as row end invisible,
row_start timestamp(6) as row start invisible,
row_end timestamp(6) as row end invisible,
period for system_time(row_start, row_end),
constraint `parent-fk`
foreign key (parent_id) references parent (id)
......@@ -130,18 +106,7 @@ on delete cascade
on update restrict
) with system versioning
engine innodb;
insert into parent (id) values (3);
insert into child (id, parent_id) values (3, 3);
## FIXME: #415 update of foreign constraints is disabled
delete from child;
## FIXME END
delete from parent;
select * from child;
id parent_id
select *, row_start < row_end, row_end < MAXVAL from child for system_time all;
id parent_id row_start < row_end row_end < MAXVAL
3 3 1 1
drop table child;
ERROR HY000: CASCADE is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
drop table parent;
#################
# Test SET NULL #
......@@ -151,39 +116,22 @@ id int unique key
) engine innodb;
create table child(
parent_id int,
sys_start SYS_DATATYPE as row start invisible,
sys_end SYS_DATATYPE as row end invisible,
sys_start timestamp(6) as row start invisible,
sys_end timestamp(6) as row end invisible,
period for system_time(sys_start, sys_end),
foreign key(parent_id) references parent(id)
on delete set null
on update set null
) engine innodb with system versioning;
insert into parent values(1);
insert into child values(1);
delete from child;
insert into child values(1);
## FIXME: #415 update of foreign constraints is disabled
delete from child where parent_id = 1;
## FIXME END
delete from parent where id = 1;
select * from child;
parent_id
select * from child for system_time from timestamp 0 to timestamp now(6);
parent_id
1
1
delete from child;
insert into parent values(1);
insert into child values(1);
drop table child;
ERROR HY000: SET NULL is not supported for TIMESTAMP(6) AS ROW START/END system-versioned tables
drop table parent;
###########################
# Parent table is foreign #
###########################
create or replace table parent(
id int unique key,
sys_start SYS_DATATYPE as row start invisible,
sys_end SYS_DATATYPE as row end invisible,
sys_start timestamp(6) as row start invisible,
sys_end timestamp(6) as row end invisible,
period for system_time(sys_start, sys_end)
) engine innodb with system versioning;
create or replace table child(
......@@ -214,16 +162,16 @@ drop table parent;
create or replace table a (
cola int(10) primary key,
v_cola int(10) as (cola mod 10) virtual,
sys_start SYS_DATATYPE as row start invisible,
sys_end SYS_DATATYPE as row end invisible,
sys_start timestamp(6) as row start invisible,
sys_end timestamp(6) as row end invisible,
period for system_time(sys_start, sys_end)
) engine=innodb with system versioning;
create index v_cola on a (v_cola);
create or replace table b(
cola int(10),
v_cola int(10),
sys_start SYS_DATATYPE as row start invisible,
sys_end SYS_DATATYPE as row end invisible,
sys_start timestamp(6) as row start invisible,
sys_end timestamp(6) as row end invisible,
period for system_time(sys_start, sys_end)
) engine=innodb with system versioning;
alter table b add constraint `v_cola_fk`
......
......@@ -11,7 +11,7 @@ name varchar(100),
salary int(10),
constraint `dept-emp-fk`
foreign key (dept_id) references dept (dept_id)
on delete cascade
on delete restrict
on update restrict
)
with system versioning;
......
......@@ -8,7 +8,6 @@ create table parent(
id int unique key
) engine innodb;
--replace_result $sys_datatype_expl SYS_DATATYPE
eval create table child(
parent_id int,
sys_start $sys_datatype_expl as row start invisible,
......@@ -46,7 +45,6 @@ create table parent(
id int(10) unsigned unique key
) engine innodb;
--replace_result $sys_datatype_expl SYS_DATATYPE
eval create table child(
parent_id int(10) unsigned primary key,
sys_start $sys_datatype_expl as row start invisible,
......@@ -72,7 +70,7 @@ create table parent(
id int unique key
) engine innodb;
--replace_result $sys_datatype_expl SYS_DATATYPE
--disable_abort_on_error
eval create table child(
parent_id int,
sys_start $sys_datatype_expl as row start invisible,
......@@ -82,16 +80,14 @@ eval create table child(
on delete cascade
on update cascade
) engine innodb with system versioning;
--enable_abort_on_error
if ($MTR_COMBINATION_TRX_ID) {
insert into parent values(1);
insert into child values(1);
--echo ## FIXME: #415 update of foreign constraints is disabled
call mtr.add_suppression("foreign key constraints in timestamp-based temporal table");
--error ER_UNSUPPORTED_EXTENSION
delete from parent where id = 1;
delete from child where parent_id = 1;
--echo ## FIXME END
delete from parent where id = 1;
select * from child;
select * from child for system_time all;
......@@ -103,9 +99,8 @@ select * from child;
select * from child for system_time all;
drop table child;
}
drop table parent;
--replace_result $sys_datatype_expl SYS_DATATYPE
eval create or replace table parent (
id int primary key,
sys_start $sys_datatype_expl as row start invisible,
......@@ -137,7 +132,7 @@ create or replace table parent (
)
engine innodb;
--replace_result $sys_datatype_expl SYS_DATATYPE
--disable_abort_on_error
eval create or replace table child (
id int primary key,
parent_id int not null,
......@@ -150,7 +145,9 @@ eval create or replace table child (
on update restrict
) with system versioning
engine innodb;
--enable_abort_on_error
if ($MTR_COMBINATION_TRX_ID) {
insert into parent (id) values (3);
insert into child (id, parent_id) values (3, 3);
--echo ## FIXME: #415 update of foreign constraints is disabled
......@@ -162,6 +159,7 @@ select * from child;
eval select *, row_start < row_end, row_end < $sys_datatype_max from child for system_time all;
drop table child;
}
drop table parent;
--echo #################
......@@ -172,7 +170,7 @@ create table parent(
id int unique key
) engine innodb;
--replace_result $sys_datatype_expl SYS_DATATYPE
--disable_abort_on_error
eval create table child(
parent_id int,
sys_start $sys_datatype_expl as row start invisible,
......@@ -182,7 +180,9 @@ eval create table child(
on delete set null
on update set null
) engine innodb with system versioning;
--enable_abort_on_error
if ($MTR_COMBINATION_TRX_ID) {
insert into parent values(1);
insert into child values(1);
delete from child;
......@@ -208,13 +208,13 @@ select * from child for system_time from timestamp 0 to timestamp now(6);
## FIXME END
drop table child;
}
drop table parent;
--echo ###########################
--echo # Parent table is foreign #
--echo ###########################
--replace_result $sys_datatype_expl SYS_DATATYPE
eval create or replace table parent(
id int unique key,
sys_start $sys_datatype_expl as row start invisible,
......@@ -254,7 +254,6 @@ drop table parent;
--echo # crash on DELETE #
--echo ###################
--replace_result $sys_datatype_expl SYS_DATATYPE
eval create or replace table a (
cola int(10) primary key,
v_cola int(10) as (cola mod 10) virtual,
......@@ -265,7 +264,6 @@ eval create or replace table a (
create index v_cola on a (v_cola);
--replace_result $sys_datatype_expl SYS_DATATYPE
eval create or replace table b(
cola int(10),
v_cola int(10),
......
......@@ -13,7 +13,7 @@ create or replace table emp (
salary int(10),
constraint `dept-emp-fk`
foreign key (dept_id) references dept (dept_id)
on delete cascade
on delete restrict
on update restrict
)
with system versioning;
......
......@@ -7343,15 +7343,13 @@ bool Vers_parse_info::check_with_conditions(const char *table_name) const
}
bool Vers_parse_info::check_sys_fields(const char *table_name,
Alter_info *alter_info,
bool native) const
Alter_info *alter_info, bool native)
{
List_iterator<Create_field> it(alter_info->create_list);
vers_sys_type_t found= VERS_UNDEFINED;
uint found_flag= 0;
while (Create_field *f= it++)
{
vers_sys_type_t check_unit= VERS_UNDEFINED;
vers_sys_type_t f_check_unit= VERS_UNDEFINED;
uint sys_flag= f->flags & VERS_SYSTEM_FIELD;
if (!sys_flag)
......@@ -7371,29 +7369,29 @@ bool Vers_parse_info::check_sys_fields(const char *table_name,
f->type_handler() == &type_handler_timestamp2) &&
f->length == MAX_DATETIME_FULL_WIDTH)
{
check_unit= VERS_TIMESTAMP;
f_check_unit= VERS_TIMESTAMP;
}
else if (native
&& f->type_handler() == &type_handler_longlong
&& (f->flags & UNSIGNED_FLAG)
&& f->length == (MY_INT64_NUM_DECIMAL_DIGITS - 1))
{
check_unit= VERS_TRX_ID;
f_check_unit= VERS_TRX_ID;
}
else
{
if (!found)
found= VERS_TIMESTAMP;
if (!check_unit)
check_unit= VERS_TIMESTAMP;
goto error;
}
if (check_unit)
if (f_check_unit)
{
if (found)
if (check_unit)
{
if (found == check_unit)
if (check_unit == f_check_unit)
{
if (found == VERS_TRX_ID && !TR_table::use_transaction_registry)
if (check_unit == VERS_TRX_ID && !TR_table::use_transaction_registry)
{
my_error(ER_VERS_TRT_IS_DISABLED, MYF(0));
return true;
......@@ -7402,13 +7400,13 @@ bool Vers_parse_info::check_sys_fields(const char *table_name,
}
error:
my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), f->field_name.str,
found == VERS_TIMESTAMP ?
check_unit == VERS_TIMESTAMP ?
"TIMESTAMP(6)" :
"BIGINT(20) UNSIGNED",
table_name);
return true;
}
found= check_unit;
check_unit= f_check_unit;
}
}
......
......@@ -1722,9 +1722,17 @@ struct Schema_specification_st
class Create_field;
enum vers_sys_type_t
{
VERS_UNDEFINED= 0,
VERS_TIMESTAMP,
VERS_TRX_ID
};
struct Vers_parse_info
{
Vers_parse_info() :
check_unit(VERS_UNDEFINED),
versioned_fields(false),
unversioned_fields(false)
{}
......@@ -1742,6 +1750,7 @@ struct Vers_parse_info
start_end_t system_time;
start_end_t as_row;
vers_sys_type_t check_unit;
void set_system_time(LString start, LString end)
{
......@@ -1773,7 +1782,7 @@ struct Vers_parse_info
bool need_check(const Alter_info *alter_info) const;
bool check_with_conditions(const char *table_name) const;
bool check_sys_fields(const char *table_name, Alter_info *alter_info,
bool native) const;
bool native);
public:
static const LString default_start;
......
......@@ -4469,6 +4469,19 @@ static bool vers_prepare_keys(THD *thd, HA_CREATE_INFO *create_info,
Key *key= NULL;
while ((key=key_it++))
{
if (key->type == Key::FOREIGN_KEY &&
create_info->vers_info.check_unit == VERS_TIMESTAMP)
{
Foreign_key *fk_key= (Foreign_key*) key;
enum enum_fk_option op;
if (fk_modifies_child(op=fk_key->update_opt) ||
fk_modifies_child(op=fk_key->delete_opt))
{
my_error(ER_VERS_NOT_SUPPORTED, MYF(0), fk_option_name(op)->str,
"TIMESTAMP(6) AS ROW START/END");
return true;
}
}
if (key->type != Key::PRIMARY && key->type != Key::UNIQUE)
continue;
......
......@@ -575,13 +575,6 @@ struct TABLE_STATISTICS_CB
bool histograms_are_read;
};
enum vers_sys_type_t
{
VERS_UNDEFINED= 0,
VERS_TIMESTAMP,
VERS_TRX_ID
};
/**
This structure is shared between different table objects. There is one
instance of table share per one table in the database.
......
......@@ -2199,14 +2199,6 @@ row_update_cascade_for_mysql(
&& (node->is_delete == PLAIN_DELETE
|| node->update->affects_versioned());
if (vers_set_fields && !thr->prebuilt->versioned_write)
{
// FIXME: timestamp-based update of row_end in run_again
trx->error_state = DB_UNSUPPORTED;
thr->fk_cascade_depth = 0;
return trx->error_state;
}
for (;;) {
if (vers_set_fields) {
// FIXME: code duplication with row_update_for_mysql()
......
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