From 9e457cbe501ca8e6d0c3939653db67ad6fceed05 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 12 Oct 2023 12:53:55 +1100 Subject: [PATCH] MDEV-32439 INSERT IGNORE on constraints result in ERROR rather than warning INSERT IGNORE had a pecular undocumented case that when one row was inserted, there was an error rather than a warning. As LOAD DATA IGNORE, UPDATE IGNORE, INSERT IGNORE SELECT, and INSERT IGNORE VALUES (single row, for foreign key violation) all behave the same way with a warning lets keep the behaviour normalized. In compatibility, previously a error was generated, now a warning is generated. This behaviour is now consistent with MySQL-8.0 too. --- mysql-test/main/check_constraint.result | 58 ++++++++++++++++++++++++- mysql-test/main/check_constraint.test | 30 ++++++++++++- mysql-test/main/view.result | 9 +++- mysql-test/main/view.test | 5 ++- sql/sql_insert.cc | 6 +-- 5 files changed, 98 insertions(+), 10 deletions(-) diff --git a/mysql-test/main/check_constraint.result b/mysql-test/main/check_constraint.result index 899192905ea..69eae2e6cea 100644 --- a/mysql-test/main/check_constraint.result +++ b/mysql-test/main/check_constraint.result @@ -308,5 +308,61 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; # -# End of 10.4 tests +# MDEV-32439 INSERT IGNORE VALUES (one row) errors on constraint +# +CREATE TABLE t1 (v1 varchar(10), v2 varchar(10), constraint unequal check (v1 != v2)); +INSERT IGNORE INTO t1 VALUES (1,1); +Warnings: +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +SHOW WARNINGS; +Level Code Message +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +INSERT IGNORE INTO t1 VALUES (1,2),(2,2); +Warnings: +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +SHOW WARNINGS; +Level Code Message +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +INSERT IGNORE INTO t1 VALUES (3,3),(4,4); +Warnings: +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +SHOW WARNINGS; +Level Code Message +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +SELECT * FROM t1; +v1 v2 +1 2 +DROP TABLE t1; +# +# MDEV-32439 INSERT IGNORE VALUES (one row) errors on constraint +# +CREATE TABLE t1 (v1 varchar(10), v2 varchar(10), constraint unequal check (v1 != v2)); +INSERT IGNORE INTO t1 VALUES (1,1); +Warnings: +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +SHOW WARNINGS; +Level Code Message +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +INSERT IGNORE INTO t1 VALUES (1,2),(2,2); +Warnings: +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +SHOW WARNINGS; +Level Code Message +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +INSERT IGNORE INTO t1 VALUES (3,3),(4,4); +Warnings: +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +SHOW WARNINGS; +Level Code Message +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +Warning 4025 CONSTRAINT `unequal` failed for `test`.`t1` +SELECT * FROM t1; +v1 v2 +1 2 +DROP TABLE t1; +# +# End of 11.4 tests # diff --git a/mysql-test/main/check_constraint.test b/mysql-test/main/check_constraint.test index f1613860b8d..86e3bf3f50a 100644 --- a/mysql-test/main/check_constraint.test +++ b/mysql-test/main/check_constraint.test @@ -232,5 +232,33 @@ show create table t1; drop table t1; --echo # ---echo # End of 10.4 tests +--echo # MDEV-32439 INSERT IGNORE VALUES (one row) errors on constraint +--echo # + +CREATE TABLE t1 (v1 varchar(10), v2 varchar(10), constraint unequal check (v1 != v2)); +INSERT IGNORE INTO t1 VALUES (1,1); +SHOW WARNINGS; +INSERT IGNORE INTO t1 VALUES (1,2),(2,2); +SHOW WARNINGS; +INSERT IGNORE INTO t1 VALUES (3,3),(4,4); +SHOW WARNINGS; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # MDEV-32439 INSERT IGNORE VALUES (one row) errors on constraint +--echo # + +CREATE TABLE t1 (v1 varchar(10), v2 varchar(10), constraint unequal check (v1 != v2)); +INSERT IGNORE INTO t1 VALUES (1,1); +SHOW WARNINGS; +INSERT IGNORE INTO t1 VALUES (1,2),(2,2); +SHOW WARNINGS; +INSERT IGNORE INTO t1 VALUES (3,3),(4,4); +SHOW WARNINGS; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 11.4 tests --echo # diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index 1858f41d9dd..3b1ba75c9a6 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -1228,10 +1228,17 @@ drop table t1; create table t1 (s1 int); create view v1 as select * from t1 where s1 < 5 with check option; insert ignore into v1 values (6); -ERROR 44000: CHECK OPTION failed `test`.`v1` +Warnings: +Warning 1369 CHECK OPTION failed `test`.`v1` +SHOW WARNINGS; +Level Code Message +Warning 1369 CHECK OPTION failed `test`.`v1` insert ignore into v1 values (6),(3); Warnings: Warning 1369 CHECK OPTION failed `test`.`v1` +SHOW WARNINGS; +Level Code Message +Warning 1369 CHECK OPTION failed `test`.`v1` select * from t1; s1 3 diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test index 34c9e4685f9..ec948cafced 100644 --- a/mysql-test/main/view.test +++ b/mysql-test/main/view.test @@ -1126,15 +1126,16 @@ drop view v2, v1; drop table t1; # -# inserting single value with check option failed always get error +# inserting single value with check option warns like 2 values # create table t1 (s1 int); create view v1 as select * from t1 where s1 < 5 with check option; #single value --- error ER_VIEW_CHECK_FAILED insert ignore into v1 values (6); +SHOW WARNINGS; #several values insert ignore into v1 values (6),(3); +SHOW WARNINGS; select * from t1; drop view v1; drop table t1; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index d68016a1b22..db525314ed3 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1129,11 +1129,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, } } - if ((res= table_list->view_check_option(thd, - (values_list.elements == 1 ? - 0 : - ignore))) == - VIEW_CHECK_SKIP) + if ((res= table_list->view_check_option(thd, ignore)) == VIEW_CHECK_SKIP) continue; else if (res == VIEW_CHECK_ERROR) {