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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user