[MDEV-16925] INSERT IGNORE ... ON DUPLICATE KEY UPDATE ... allowed Created: 2018-08-09  Updated: 2018-10-16  Resolved: 2018-10-16

Status: Closed
Project: MariaDB Server
Component/s: Documentation, Parser
Affects Version/s: 5.5, 10.0, 10.1, 10.3.8, 10.2, 10.3
Fix Version/s: N/A

Type: Bug Priority: Minor
Reporter: Arjen Lentz Assignee: Ian Gilfillan
Resolution: Fixed Votes: 1
Labels: upstream
Environment:

Ubuntu GNU/Linux 18.04 (Bionic Beaver) x64



 Description   

INSERT IGNORE allows an insert to come back with "ok" even if the row already exists.
INSERT ... ON DUPLICATE KEY UPDATE ... intends the UPDATE to be executed in case the row already exists.

Combining the two makes no sense, and while harmless, perhaps it would be better if the parser were to throw a syntax error for it.
Currently, it appears the server executes the ON DUPLICATE KEY, thus disregarding the IGNORE:

MariaDB [test]> create table dup (a int, b int, unique (a,b));
Query OK, 0 rows affected (0.019 sec)
 
MariaDB [test]> insert into dup values (1,20),(2,24);
Query OK, 2 rows affected (0.013 sec)
Records: 2  Duplicates: 0  Warnings: 0
 
MariaDB [test]> select * from dup;
+------+------+
| a    | b    |
+------+------+
|    1 |   20 |
|    2 |   24 |
+------+------+
2 rows in set (0.000 sec)
 
MariaDB [test]> insert ignore foo values (2,24) on duplicate key update b=23;
Query OK, 1 row affected (0.006 sec)
 
MariaDB [test]> select * from dup;
+------+------+
| a    | b    |
+------+------+
|    1 |   20 |
|    2 |   24 |
+------+------+
2 rows in set (0.000 sec)
 
MariaDB [test]> insert ignore dup values (2,24) on duplicate key update b=23;
Query OK, 2 rows affected (0.007 sec)
 
MariaDB [test]> select * from dup;
+------+------+
| a    | b    |
+------+------+
|    1 |   20 |
|    2 |   23 |
+------+------+
2 rows in set (0.001 sec)



 Comments   
Comment by Arjen Lentz [ 2018-08-09 ]

It has been noted that INSERT can chuck errors for reasons other than a duplicate key.
As the manual notes
"IGNORE has a similar effect on inserts into partitioned tables where no partition matching a given value is found. Without IGNORE, such INSERT statements are aborted with an error. When INSERT IGNORE is used, the insert operation fails silently for rows containing the unmatched value, but inserts rows that are matched."

One example would be a foreign key check failing, in this case IGNORE would see the INSERT return without error (but without inserting a row, of course).

However, when combined with ON DUPLICATE KEY may create an ambiguity.
if an fk check fails, but there is also a dup key, which one takes precedence?
That is, will the on dup key be executed in that case if IGNORE is also specified, or will the server just return without error because of the fk check fail?
If we intend to allow this syntax, then the exact behaviour for each of the possible combinations of errors should be documented.

Comment by Elena Stepanova [ 2018-09-02 ]

IGNORE can also play a role even in a pure duplicate key situation. Consider the following:

MariaDB [test]> create table t1 (pk int primary key, c varchar(8),unique(c));
Query OK, 0 rows affected (0.04 sec)
 
MariaDB [test]> insert into t1 values (1,'foo'),(2,'bar');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

MariaDB [test]> insert into t1 values (1,'qux') on duplicate key update c = 'bar';
ERROR 1062 (23000): Duplicate entry 'bar' for key 'c'
MariaDB [test]> insert ignore into t1 values (1,'qux') on duplicate key update c = 'bar';
Query OK, 0 rows affected, 1 warning (0.00 sec)
 
MariaDB [test]> show warnings;
+---------+------+-----------------------------------+
| Level   | Code | Message                           |
+---------+------+-----------------------------------+
| Warning | 1062 | Duplicate entry 'bar' for key 'c' |
+---------+------+-----------------------------------+
1 row in set (0.00 sec)
 
MariaDB [test]> select * from t1;
+----+------+
| pk | c    |
+----+------+
|  1 | foo  |
|  2 | bar  |
+----+------+
2 rows in set (0.00 sec)

I agree the behaviour should be properly documented.

Comment by Ian Gilfillan [ 2018-10-16 ]

This is documented as follows "The IGNORE and DELAYED options are ignored when you use ON DUPLICATE KEY UPDATE." at https://mariadb.com/kb/en/library/insert-on-duplicate-key-update/
I have added to https://mariadb.com/kb/en/library/insert-ignore/ as well.

Generated at Thu Feb 08 08:32:34 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.