summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/alter_table_online.result37
-rw-r--r--mysql-test/main/alter_table_online.test48
-rw-r--r--sql/sql_table.cc12
3 files changed, 97 insertions, 0 deletions
diff --git a/mysql-test/main/alter_table_online.result b/mysql-test/main/alter_table_online.result
index a0850b0b8fc..8b43281be7d 100644
--- a/mysql-test/main/alter_table_online.result
+++ b/mysql-test/main/alter_table_online.result
@@ -80,3 +80,40 @@ XA END 'xid';
XA COMMIT 'xid' ONE PHASE;
DROP TABLE t;
disconnect con1;
+connection default;
+#
+# MDEV-29068 Cascade foreign key updates do not apply in online alter
+#
+create table t1 (a int primary key) engine=InnoDB;
+insert into t1 values (1),(2),(3);
+create table t2 (b int, foreign key (b)
+references t1 (a)
+on update cascade) engine=InnoDB;
+insert into t2 values (1),(2),(3);
+alter table t2 add c int, algorithm=copy, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: COPY algorithm requires a lock. Try LOCK=SHARED
+create or replace table t2 (b int, foreign key (b)
+references t1 (a)
+on delete set null) engine=InnoDB;
+alter table t2 add c int, algorithm=copy, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: COPY algorithm requires a lock. Try LOCK=SHARED
+create or replace table t2 (b int, foreign key (b)
+references t1 (a)
+on delete no action) engine=InnoDB;
+insert into t2 values (1),(2),(3);
+alter table t2 add c int, algorithm=copy, lock=none;
+create or replace table t2 (b int, foreign key (b)
+references t1 (a)
+on update restrict) engine=InnoDB;
+insert into t2 values (1),(2),(3);
+alter table t2 add c int, algorithm=copy, lock=none;
+drop table t2, t1;
+create table t1 (a int primary key, b int unique) engine=InnoDB;
+insert into t1 values (1, 1),(2, 2),(3, 3);
+create table t2 (a int references t1 (a),
+b int references t1 (b) on update cascade) engine=InnoDB;
+insert into t2 values (1, 1),(2, 2);
+alter table t2 add c int, algorithm=copy, lock=none;
+ERROR 0A000: LOCK=NONE is not supported. Reason: COPY algorithm requires a lock. Try LOCK=SHARED
+alter table t2 add c int, algorithm=copy;
+drop table t2, t1;
diff --git a/mysql-test/main/alter_table_online.test b/mysql-test/main/alter_table_online.test
index 03cd78084fd..1561000c258 100644
--- a/mysql-test/main/alter_table_online.test
+++ b/mysql-test/main/alter_table_online.test
@@ -63,3 +63,51 @@ XA COMMIT 'xid' ONE PHASE;
DROP TABLE t;
--disconnect con1
+--connection default
+
+--echo #
+--echo # MDEV-29068 Cascade foreign key updates do not apply in online alter
+--echo #
+create table t1 (a int primary key) engine=InnoDB;
+insert into t1 values (1),(2),(3);
+create table t2 (b int, foreign key (b)
+ references t1 (a)
+ on update cascade) engine=InnoDB;
+insert into t2 values (1),(2),(3);
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t2 add c int, algorithm=copy, lock=none;
+
+create or replace table t2 (b int, foreign key (b)
+ references t1 (a)
+ on delete set null) engine=InnoDB;
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t2 add c int, algorithm=copy, lock=none;
+
+create or replace table t2 (b int, foreign key (b)
+ references t1 (a)
+ on delete no action) engine=InnoDB;
+
+insert into t2 values (1),(2),(3);
+alter table t2 add c int, algorithm=copy, lock=none;
+
+create or replace table t2 (b int, foreign key (b)
+ references t1 (a)
+ on update restrict) engine=InnoDB;
+
+insert into t2 values (1),(2),(3);
+alter table t2 add c int, algorithm=copy, lock=none;
+drop table t2, t1;
+
+create table t1 (a int primary key, b int unique) engine=InnoDB;
+insert into t1 values (1, 1),(2, 2),(3, 3);
+create table t2 (a int references t1 (a),
+ b int references t1 (b) on update cascade) engine=InnoDB;
+insert into t2 values (1, 1),(2, 2);
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+alter table t2 add c int, algorithm=copy, lock=none;
+alter table t2 add c int, algorithm=copy;
+# Cleanup
+drop table t2, t1;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 8401a905f95..883a904c449 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -10477,6 +10477,18 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
online= online && !table->s->tmp_table;
+ List<FOREIGN_KEY_INFO> fk_list;
+ table->file->get_foreign_key_list(thd, &fk_list);
+ for (auto &fk: fk_list)
+ {
+ if (fk_modifies_child(fk.delete_method)
+ || fk_modifies_child(fk.update_method))
+ {
+ online= false;
+ break;
+ }
+ }
+
#ifdef WITH_WSREP
if (WSREP(thd) &&
(thd->lex->sql_command == SQLCOM_ALTER_TABLE ||