1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

IB: FK cascade delete when parent versioned [fixes #101]

This commit is contained in:
Aleksey Midenkov
2016-12-21 05:57:00 +00:00
parent 412dd1e1f3
commit 46badf17c4
3 changed files with 63 additions and 15 deletions

View File

@@ -52,21 +52,41 @@ insert into child values(1);
delete from parent where id = 1;
select * from child;
parent_id
select * from child for system_time from timestamp '1-1-1' to timestamp now(6);
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;
update parent set id = id + 1;
select * from child;
parent_id
2
select * from child for system_time from timestamp '1-1-1' to timestamp now(6);
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
) with system versioning
engine innodb;
create or replace table child (
x int,
parent_id int not null,
constraint `parent-fk`
foreign key (parent_id) references parent (id)
on delete cascade
on update restrict
)
engine innodb;
insert into parent (id) values (1);
insert into child (x, parent_id) values (1, 1);
delete from parent;
select * from child;
x parent_id
drop table child;
drop table parent;
create table parent(
id int unique key
) engine innodb;

View File

@@ -76,13 +76,36 @@ insert into child values(1);
delete from parent where id = 1;
select * from child;
select * from child for system_time from timestamp '1-1-1' to timestamp now(6);
select * from child for system_time all;
insert into parent values(1);
insert into child values(1);
update parent set id=id+1;
update parent set id = id + 1;
select * from child;
select * from child for system_time all;
drop table child;
drop table parent;
create or replace table parent (
id int primary key
) with system versioning
engine innodb;
create or replace table child (
x int,
parent_id int not null,
constraint `parent-fk`
foreign key (parent_id) references parent (id)
on delete cascade
on update restrict
)
engine innodb;
insert into parent (id) values (1);
insert into child (x, parent_id) values (1, 1);
delete from parent;
select * from child;
select * from child for system_time from timestamp '1-1-1' to timestamp now(6);
drop table child;
drop table parent;

View File

@@ -430,7 +430,8 @@ row_ins_cascade_ancestor_updates_table(
upd_node = static_cast<upd_node_t*>(parent);
if (upd_node->table == table && upd_node->is_delete == FALSE) {
if (upd_node->table == table && upd_node->is_delete == FALSE
&& !upd_node->vers_delete) {
return(TRUE);
}
@@ -977,6 +978,8 @@ row_ins_foreign_fill_virtual(
innobase_init_vc_templ(index->table);
}
bool is_delete = node->is_delete || node->vers_delete;
for (ulint i = 0; i < n_v_fld; i++) {
dict_v_col_t* col = dict_table_get_nth_v_col(
@@ -1008,14 +1011,14 @@ row_ins_foreign_fill_virtual(
upd_field_set_v_field_no(upd_field, i, index);
if (node->is_delete
if (is_delete
? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
: (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)) {
dfield_set_null(&upd_field->new_val);
}
if (!node->is_delete
if (!is_delete
&& (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)) {
dfield_t* new_vfield = innobase_get_computed_value(
@@ -1108,7 +1111,9 @@ row_ins_foreign_check_on_constraint(
node = static_cast<upd_node_t*>(thr->run_node);
if (node->is_delete && 0 == (foreign->type
bool is_delete = node->is_delete || node->vers_delete;
if (is_delete && 0 == (foreign->type
& (DICT_FOREIGN_ON_DELETE_CASCADE
| DICT_FOREIGN_ON_DELETE_SET_NULL))) {
@@ -1119,7 +1124,7 @@ row_ins_foreign_check_on_constraint(
DBUG_RETURN(DB_ROW_IS_REFERENCED);
}
if (!node->is_delete && 0 == (foreign->type
if (!is_delete && 0 == (foreign->type
& (DICT_FOREIGN_ON_UPDATE_CASCADE
| DICT_FOREIGN_ON_UPDATE_SET_NULL))) {
@@ -1148,7 +1153,7 @@ row_ins_foreign_check_on_constraint(
cascade->foreign = foreign;
if (node->is_delete
if (is_delete
&& (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE)) {
cascade->is_delete = TRUE;
} else {
@@ -1285,7 +1290,7 @@ row_ins_foreign_check_on_constraint(
clust_index, tmp_heap);
}
if (node->is_delete
if (is_delete
? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
: (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)) {
@@ -1365,7 +1370,7 @@ row_ins_foreign_check_on_constraint(
}
}
if (!node->is_delete
if (!is_delete
&& (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)) {
/* Build the appropriate update vector which sets changing
@@ -1690,7 +1695,7 @@ row_ins_check_foreign_constraint(
if (que_node_get_type(thr->run_node) == QUE_NODE_UPDATE) {
upd_node = static_cast<upd_node_t*>(thr->run_node);
if (!(upd_node->is_delete) && upd_node->foreign == foreign) {
if (!(upd_node->is_delete) && !(upd_node->vers_delete) && upd_node->foreign == foreign) {
/* If a cascaded update is done as defined by a
foreign key constraint, do not check that
constraint for the child row. In ON UPDATE CASCADE