diff --git a/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NON-STRICT.rdiff b/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NON-STRICT.rdiff new file mode 100644 index 00000000000..66e39ca633e --- /dev/null +++ b/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NON-STRICT.rdiff @@ -0,0 +1,57 @@ +--- foreign_sql_mode.result ++++ foreign_sql_mode,COPY,NON-STRICT.rdiff +@@ -3,14 +3,14 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, FOREIGN KEY(f1) REFERENCES t1(f2) ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +-ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1); + UPDATE t1 SET f2= NULL; ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f2`) ON UPDATE CASCADE) + DELETE FROM t2; + SELECT * FROM t1; + f1 f2 +-1 NULL ++1 1 + UPDATE t1 SET f2 = NULL; + SELECT * FROM t1; + f1 f2 +@@ -20,7 +20,7 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY(f1) REFERENCES t1(f1) ON UPDATE SET NULL)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +-ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL ++ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 150 "Foreign key constraint is incorrectly formed") + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1, 1); + UPDATE t1 SET f1= 2; +@@ -32,7 +32,7 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE SET NULL)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f2 INT NOT NULL; +-ERROR HY000: Column 'f2' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL ++ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 150 "Foreign key constraint is incorrectly formed") + DROP TABLE t2, t1; + # modify parent column NULL ON UPDATE CASCADE child column NOT NULL + CREATE TABLE `t#1`(f1 INT, f2 INT NOT NULL, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +@@ -40,11 +40,10 @@ + FOREIGN KEY(f1) REFERENCES `t#1`(f2) + ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE `t#1` MODIFY COLUMN f2 INT; +-ERROR HY000: Cannot change column 'f2': used in a foreign key constraint 't#2_ibfk_1' of table 'test.t#2' + INSERT INTO `t#1` VALUES(1, 1); + INSERT INTO `t#2` VALUES(1); + UPDATE `t#1` SET f2= NULL; +-ERROR 23000: Column 'f2' cannot be null ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t#2`, CONSTRAINT `t#2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t#1` (`f2`) ON UPDATE CASCADE) + DELETE FROM `t#2`; + SELECT * FROM `t#1`; + f1 f2 +@@ -60,6 +59,5 @@ + PRIMARY KEY(f1, f2), + FOREIGN KEY(f2, f3) REFERENCES t1(f2, f1) + ON UPDATE CASCADE)ENGINE=InnoDB; +-ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") + DROP TABLE IF EXISTS t2; + DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NOSTRICT.rdiff b/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NOSTRICT.rdiff new file mode 100644 index 00000000000..95df1bfa7d3 --- /dev/null +++ b/mysql-test/suite/innodb/r/foreign_sql_mode,COPY,NOSTRICT.rdiff @@ -0,0 +1,55 @@ +--- foreign_sql_mode.result 2025-01-21 17:23:46.014938931 +0530 ++++ foreign_sql_mode.reject 2025-01-21 17:24:11.783981181 +0530 +@@ -3,20 +3,20 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, FOREIGN KEY(f1) REFERENCES t1(f2) ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +-ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1); + UPDATE t1 SET f2= NULL; ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f2`) ON UPDATE CASCADE) + DELETE FROM t2; + SELECT * FROM t1; + f1 f2 +-1 NULL ++1 1 + DROP TABLE t2, t1; + # modify child column NOT NULL ON UPDATE SET NULL + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY(f1) REFERENCES t1(f1) ON UPDATE SET NULL)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +-ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL ++ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 150 "Foreign key constraint is incorrectly formed") + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1, 1); + UPDATE t1 SET f1= 2; +@@ -28,7 +28,7 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE SET NULL)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f2 INT NOT NULL; +-ERROR HY000: Column 'f2' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL ++ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 150 "Foreign key constraint is incorrectly formed") + DROP TABLE t2, t1; + # modify parent column NULL ON UPDATE CASCADE child column NOT NULL + CREATE TABLE `t#1`(f1 INT, f2 INT NOT NULL, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +@@ -36,11 +36,10 @@ + FOREIGN KEY(f1) REFERENCES `t#1`(f2) + ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE `t#1` MODIFY COLUMN f2 INT; +-ERROR HY000: Cannot change column 'f2': used in a foreign key constraint 't#2_ibfk_1' of table 'test.t#2' + INSERT INTO `t#1` VALUES(1, 1); + INSERT INTO `t#2` VALUES(1); + UPDATE `t#1` SET f2= NULL; +-ERROR 23000: Column 'f2' cannot be null ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t#2`, CONSTRAINT `t#2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t#1` (`f2`) ON UPDATE CASCADE) + DELETE FROM `t#2`; + SELECT * FROM `t#1`; + f1 f2 +@@ -56,6 +55,5 @@ + PRIMARY KEY(f1, f2), + FOREIGN KEY(f2, f3) REFERENCES t1(f2, f1) + ON UPDATE CASCADE)ENGINE=InnoDB; +-ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") + DROP TABLE IF EXISTS t2; + DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/r/foreign_sql_mode,INPLACE,NON-STRICT.rdiff b/mysql-test/suite/innodb/r/foreign_sql_mode,INPLACE,NON-STRICT.rdiff new file mode 100644 index 00000000000..8919244e810 --- /dev/null +++ b/mysql-test/suite/innodb/r/foreign_sql_mode,INPLACE,NON-STRICT.rdiff @@ -0,0 +1,39 @@ +--- foreign_sql_mode.result ++++ foreign_sql_mode,INPLACE,NON-STRICT.rdiff +@@ -3,14 +3,14 @@ + CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; + CREATE TABLE t2(f1 INT, FOREIGN KEY(f1) REFERENCES t1(f2) ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +-ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1); + UPDATE t1 SET f2= NULL; ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f2`) ON UPDATE CASCADE) + DELETE FROM t2; + SELECT * FROM t1; + f1 f2 +-1 NULL ++1 1 + UPDATE t1 SET f2 = NULL; + SELECT * FROM t1; + f1 f2 +@@ -40,11 +40,10 @@ + FOREIGN KEY(f1) REFERENCES `t#1`(f2) + ON UPDATE CASCADE)ENGINE=InnoDB; + ALTER TABLE `t#1` MODIFY COLUMN f2 INT; +-ERROR HY000: Cannot change column 'f2': used in a foreign key constraint 't#2_ibfk_1' of table 'test.t#2' + INSERT INTO `t#1` VALUES(1, 1); + INSERT INTO `t#2` VALUES(1); + UPDATE `t#1` SET f2= NULL; +-ERROR 23000: Column 'f2' cannot be null ++ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t#2`, CONSTRAINT `t#2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t#1` (`f2`) ON UPDATE CASCADE) + DELETE FROM `t#2`; + SELECT * FROM `t#1`; + f1 f2 +@@ -60,6 +59,5 @@ + PRIMARY KEY(f1, f2), + FOREIGN KEY(f2, f3) REFERENCES t1(f2, f1) + ON UPDATE CASCADE)ENGINE=InnoDB; +-ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") + DROP TABLE IF EXISTS t2; + DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/r/foreign_sql_mode.result b/mysql-test/suite/innodb/r/foreign_sql_mode.result new file mode 100644 index 00000000000..7044e402745 --- /dev/null +++ b/mysql-test/suite/innodb/r/foreign_sql_mode.result @@ -0,0 +1,65 @@ +call mtr.add_suppression("InnoDB: In ALTER TABLE .* has or is referenced in foreign key constraints which are not compatible with the new table definition."); +# modify child column NOT NULL on UPDATE CASCADE..parent column NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, FOREIGN KEY(f1) REFERENCES t1(f2) ON UPDATE CASCADE)ENGINE=InnoDB; +ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t2 VALUES(1); +UPDATE t1 SET f2= NULL; +DELETE FROM t2; +SELECT * FROM t1; +f1 f2 +1 NULL +UPDATE t1 SET f2 = NULL; +SELECT * FROM t1; +f1 f2 +1 NULL +DROP TABLE t2, t1; +# modify child column NOT NULL ON UPDATE SET NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY(f1) REFERENCES t1(f1) ON UPDATE SET NULL)ENGINE=InnoDB; +ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL; +ERROR HY000: Column 'f1' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t2 VALUES(1, 1); +UPDATE t1 SET f1= 2; +SELECT * FROM t2; +f1 f2 +NULL 1 +DROP TABLE t2, t1; +# modify child column NOT NULL ON DELETE SET NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE SET NULL)ENGINE=InnoDB; +ALTER TABLE t2 MODIFY COLUMN f2 INT NOT NULL; +ERROR HY000: Column 'f2' cannot be NOT NULL: needed in a foreign key constraint 't2_ibfk_1' SET NULL +DROP TABLE t2, t1; +# modify parent column NULL ON UPDATE CASCADE child column NOT NULL +CREATE TABLE `t#1`(f1 INT, f2 INT NOT NULL, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE `t#2`(f1 INT NOT NULL, +FOREIGN KEY(f1) REFERENCES `t#1`(f2) +ON UPDATE CASCADE)ENGINE=InnoDB; +ALTER TABLE `t#1` MODIFY COLUMN f2 INT; +ERROR HY000: Cannot change column 'f2': used in a foreign key constraint 't#2_ibfk_1' of table 'test.t#2' +INSERT INTO `t#1` VALUES(1, 1); +INSERT INTO `t#2` VALUES(1); +UPDATE `t#1` SET f2= NULL; +ERROR 23000: Column 'f2' cannot be null +DELETE FROM `t#2`; +SELECT * FROM `t#1`; +f1 f2 +1 1 +DROP TABLE `t#2`, `t#1`; +CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT, +f2 INT DEFAULT NULL, +PRIMARY KEY(f1), +FOREIGN KEY(f2) REFERENCES t1(f1))ENGINE=InnoDB; +CREATE TABLE t2 (f1 INT NOT NULL, +f2 INT NOT NULL, +f3 INT DEFAULT NULL, +PRIMARY KEY(f1, f2), +FOREIGN KEY(f2, f3) REFERENCES t1(f2, f1) +ON UPDATE CASCADE)ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/t/foreign_sql_mode.combinations b/mysql-test/suite/innodb/t/foreign_sql_mode.combinations new file mode 100644 index 00000000000..e84e17b06ac --- /dev/null +++ b/mysql-test/suite/innodb/t/foreign_sql_mode.combinations @@ -0,0 +1,2 @@ +[COPY] +[INPLACE] diff --git a/mysql-test/suite/innodb/t/foreign_sql_mode.test b/mysql-test/suite/innodb/t/foreign_sql_mode.test new file mode 100644 index 00000000000..1569348df07 --- /dev/null +++ b/mysql-test/suite/innodb/t/foreign_sql_mode.test @@ -0,0 +1,129 @@ +--source include/have_innodb.inc +--source alter_sql_mode.inc +call mtr.add_suppression("InnoDB: In ALTER TABLE .* has or is referenced in foreign key constraints which are not compatible with the new table definition."); + +let $combination=`select regexp_replace('$MTR_COMBINATIONS', 'innodb,\|,innodb', '')`; + +let $copy_algo=`select ((strcmp(substring_index('$combination', ",", 1), "COPY") = 0) or (strcmp(substring_index('$combination', ",", -1), "COPY") = 0))`; + +let $inplace_algo=`select ((strcmp(substring_index('$combination', ",", 1), "INPLACE") = 0) or (strcmp(substring_index('$combination', ",", -1), "INPLACE") = 0))`; + +let $algorithm=COPY; +if ($inplace_algo) +{ + let $algorithm=INPLACE; +} +let $sql_mode = `SELECT @@SQL_MODE`; +let $error_code = 0; +if ($sql_mode == "STRICT_TRANS_TABLES") { + let $error_code = ER_FK_COLUMN_NOT_NULL; +} + +--echo # modify child column NOT NULL on UPDATE CASCADE..parent column NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, FOREIGN KEY(f1) REFERENCES t1(f2) ON UPDATE CASCADE)ENGINE=InnoDB; +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +--error $error_code +eval ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL,ALGORITHM=$algorithm; +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t2 VALUES(1); + +let $dml_error_code = ER_ROW_IS_REFERENCED_2; +if ($sql_mode == "STRICT_TRANS_TABLES") +{ + let $dml_error_code = 0; +} + +--error $dml_error_code +UPDATE t1 SET f2= NULL; +DELETE FROM t2; +SELECT * FROM t1; +UPDATE t1 SET f2 = NULL; +SELECT * FROM t1; +DROP TABLE t2, t1; + +let $error_code= ER_ERROR_ON_RENAME; +if ($algorithm == "INPLACE") +{ + let $error_code= ER_FK_COLUMN_NOT_NULL; +} + +if ($sql_mode == "STRICT_TRANS_TABLES") +{ + let $error_code = ER_FK_COLUMN_NOT_NULL; +} + +# Modifying referenced column from NULL to NOT NULL fails when foreign +# clause is ON UPDATE SET NULL or ON DELETE SET NULL irrespective +# of SQL_MODE variable. This is the behaviour even before MDEV-34392 + +--echo # modify child column NOT NULL ON UPDATE SET NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY(f1) REFERENCES t1(f1) ON UPDATE SET NULL)ENGINE=InnoDB; +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +--replace_regex /Error on rename of '.*' to '.*'/Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME'/ +--error $error_code +eval ALTER TABLE t2 MODIFY COLUMN f1 INT NOT NULL,ALGORITHM=$algorithm; +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t2 VALUES(1, 1); +UPDATE t1 SET f1= 2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # modify child column NOT NULL ON DELETE SET NULL +CREATE TABLE t1(f1 INT, f2 INT, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE t2(f1 INT, f2 INT, FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE SET NULL)ENGINE=InnoDB; +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +--replace_regex /Error on rename of '.*' to '.*'/Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME'/ +--error $error_code +eval ALTER TABLE t2 MODIFY COLUMN f2 INT NOT NULL,ALGORITHM=$algorithm; +DROP TABLE t2, t1; + +if ($sql_mode == "STRICT_TRANS_TABLES") +{ + let $dml_error_code = ER_BAD_NULL_ERROR; +} + +let $error_code= 0; +if ($sql_mode == "STRICT_TRANS_TABLES") +{ + let $error_code = ER_FK_COLUMN_CANNOT_CHANGE_CHILD; +} + +--echo # modify parent column NULL ON UPDATE CASCADE child column NOT NULL +CREATE TABLE `t#1`(f1 INT, f2 INT NOT NULL, PRIMARY KEY(f1), KEY(f2))ENGINE=InnoDB; +CREATE TABLE `t#2`(f1 INT NOT NULL, + FOREIGN KEY(f1) REFERENCES `t#1`(f2) + ON UPDATE CASCADE)ENGINE=InnoDB; +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +--error $error_code +eval ALTER TABLE `t#1` MODIFY COLUMN f2 INT,ALGORITHM=$algorithm; +INSERT INTO `t#1` VALUES(1, 1); +INSERT INTO `t#2` VALUES(1); +--error $dml_error_code +UPDATE `t#1` SET f2= NULL; +DELETE FROM `t#2`; +SELECT * FROM `t#1`; +DROP TABLE `t#2`, `t#1`; + +let $error_code= 0; +if ($sql_mode == "STRICT_TRANS_TABLES") +{ + let $error_code = ER_CANT_CREATE_TABLE; +} + +CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT, + f2 INT DEFAULT NULL, + PRIMARY KEY(f1), + FOREIGN KEY(f2) REFERENCES t1(f1))ENGINE=InnoDB; +--error $error_code +CREATE TABLE t2 (f1 INT NOT NULL, + f2 INT NOT NULL, + f3 INT DEFAULT NULL, + PRIMARY KEY(f1, f2), + FOREIGN KEY(f2, f3) REFERENCES t1(f2, f1) + ON UPDATE CASCADE)ENGINE=InnoDB; +--disable_warnings +DROP TABLE IF EXISTS t2; +--enable_warnings +DROP TABLE IF EXISTS t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index aec81d8941e..e906d8a2a62 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9677,6 +9677,7 @@ fk_check_column_changes(THD *thd, const TABLE *table, *bad_column_name= NULL; enum fk_column_change_type result= FK_COLUMN_NO_CHANGE; + bool strict_mode= thd->is_strict_mode(); while ((column= column_it++)) { @@ -9722,7 +9723,7 @@ fk_check_column_changes(THD *thd, const TABLE *table, goto func_exit; } - if (old_field_not_null != new_field_not_null) + if (strict_mode && old_field_not_null != new_field_not_null) { if (referenced && !new_field_not_null) { diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index f0e47938178..45a76243f8a 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -44,6 +44,7 @@ Created 1/8/1996 Heikki Tuuri #include "dict0priv.h" #include "fts0priv.h" #include "srv0start.h" +#include "ha_innodb.h" /*****************************************************************//** Based on a table object, this function builds the entry to be inserted @@ -1890,6 +1891,7 @@ dict_create_add_foreigns_to_dictionary( error = DB_SUCCESS; + bool strict_mode = thd_is_strict_mode(trx->mysql_thd); for (dict_foreign_set::const_iterator it = local_fk_set.begin(); it != local_fk_set.end(); ++it) { @@ -1897,7 +1899,7 @@ dict_create_add_foreigns_to_dictionary( foreign = *it; ut_ad(foreign->id != NULL); - if (!foreign->check_fk_constraint_valid()) { + if (strict_mode && !foreign->check_fk_constraint_valid()) { error = DB_CANNOT_ADD_CONSTRAINT; } else { error = dict_create_add_foreign_to_dictionary( diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index d30c88414cd..e5824dcdb86 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -4246,13 +4246,15 @@ declared as NOT NULL @param n_drop_fk number of constraints that are being dropped @param col_name modified column name @param new_field_flags Modified field flags +@param strict_mode Whether the sql_mode is strict @retval true Not allowed (will call my_error()) @retval false Allowed */ static bool check_foreigns_nullability(const dict_table_t *user_table, dict_foreign_t **drop_fk, ulint n_drop_fk, - const char *col_name, uint32_t new_field_flags) + const char *col_name, uint32_t new_field_flags, + bool strict_mode) { ut_ad(mutex_own(&dict_sys.mutex)); @@ -4264,7 +4266,7 @@ bool check_foreigns_nullability(const dict_table_t *user_table, if (innobase_dropping_foreign(foreign, drop_fk, n_drop_fk)) continue; - if (foreign->on_update_cascade_null(col_name)) + if (strict_mode && foreign->on_update_cascade_null(col_name)) goto non_null_error; if (foreign->type & (foreign->DELETE_SET_NULL | @@ -4286,7 +4288,7 @@ non_null_error: { for (dict_foreign_t *foreign : user_table->referenced_set) { - if (foreign->on_update_cascade_not_null(col_name)) + if (strict_mode && foreign->on_update_cascade_not_null(col_name)) { char display_name[FN_REFLEN]; const int dblen= int(table_name_t(const_cast(foreign-> @@ -4388,6 +4390,7 @@ column that is being dropped or modified to NOT NULL. @param user_table InnoDB table as it is before the ALTER operation @param drop_fk constraints being dropped @param n_drop_fk number of constraints that are being dropped +@param strict_mode Whether the strict sql_mode is set @retval true Not allowed (will call my_error()) @retval false Allowed */ @@ -4399,7 +4402,8 @@ innobase_check_foreigns( const TABLE* old_table, const dict_table_t* user_table, dict_foreign_t** drop_fk, - ulint n_drop_fk) + ulint n_drop_fk, + bool strict_mode) { for (Field** fp = old_table->field; *fp; fp++) { ut_ad(!(*fp)->real_maybe_null() @@ -4424,7 +4428,8 @@ innobase_check_foreigns( if (check_foreigns_nullability(user_table, drop_fk, n_drop_fk, (*fp)->field_name.str, - it->flags)) { + it->flags, + strict_mode)) { return true; } } @@ -6462,7 +6467,8 @@ prepare_inplace_alter_table_dict( if (new_clustered) { if (innobase_check_foreigns( ha_alter_info, old_table, - user_table, ctx->drop_fk, ctx->num_to_drop_fk)) { + user_table, ctx->drop_fk, ctx->num_to_drop_fk, + thd_is_strict_mode(ctx->trx->mysql_thd))) { new_clustered_failed: DBUG_ASSERT(ctx->trx != ctx->prebuilt->trx); ctx->trx->rollback();