Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.1, 12.3.3
-
MariaDB 12.3.3-MariaDB-ubu2404 on Linux x86_64
Description
INSERT ... SELECT ... ON DUPLICATE KEY UPDATE raises error 1048 when its update expression assigns NULL to a NOT NULL column, even though a BEFORE UPDATE trigger replaces that NULL with 99. The equivalent VALUES form invokes the trigger successfully.
This occurs when INSERT SELECT handles a duplicate key, its update list assigns NULL to a NOT NULL column, and a BEFORE UPDATE trigger replaces that value.
Steps to reproduce
- Run the following SQL as one script in the MariaDB command-line client. The procedure handler captures the candidate error so the remaining observations and cleanup execute.
CREATE DATABASE trigger_test; |
USE trigger_test; |
SET SESSION sql_mode='STRICT_ALL_TABLES'; |
CREATE TABLE t1 (id INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB; |
CREATE TRIGGER bu BEFORE UPDATE ON t1 FOR EACH ROW SET NEW.b=COALESCE(NEW.b,99); |
INSERT INTO t1 VALUES (1,5); |
|
|
INSERT INTO t1 (id,b) VALUES (1,2) |
ON DUPLICATE KEY UPDATE b=NULL; |
SELECT 'control', b, b=99 AS oracle FROM t1 WHERE id=1; |
UPDATE t1 SET b=5 WHERE id=1; |
|
|
DELIMITER //
|
CREATE PROCEDURE run_case() |
BEGIN
|
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION |
GET DIAGNOSTICS CONDITION 1 @errno=MYSQL_ERRNO, @message=MESSAGE_TEXT;
|
SET @errno=0, @message=''; |
INSERT INTO t1 (id,b) |
SELECT 1,2 UNION ALL SELECT 2,3 |
ON DUPLICATE KEY UPDATE b=NULL; |
END// |
DELIMITER ;
|
|
|
CALL run_case();
|
SELECT 'candidate_error', @errno, @message; |
SELECT 'candidate_rows', id,b FROM t1 ORDER BY id; |
SELECT 'candidate_oracle', |
@errno=0
|
AND COUNT(*)=2 |
AND SUM(id=1 AND b=99)=1 |
AND SUM(id=2 AND b=3)=1 |
FROM t1; |
|
|
DROP DATABASE trigger_test; |
SELECT 'cleanup', COUNT(*)=0 |
FROM information_schema.schemata |
WHERE schema_name='trigger_test'; |
Actual result
The VALUES control succeeds and shows that the trigger replaces NULL with 99. The INSERT SELECT form instead raises error 1048, leaves the original row unchanged at (1,5), and does not insert (2,3):
control 99 1
|
candidate_error 1048 Column 'b' cannot be null
|
candidate_rows 1 5
|
candidate_oracle 0
|
cleanup 1
|
The script completes without a server interruption.
Expected result
The INSERT SELECT form should apply the same duplicate-key update semantics as the successful VALUES control. The BEFORE UPDATE trigger should receive NEW.b=NULL, replace it with 99, and allow the statement to finish without an error. The final rows should be exactly (1,99) and (2,3), and candidate_oracle should return 1.
Attachments
Issue Links
- relates to
-
MDEV-41775 INSERT ... VALUES omitting a NOT NULL column succeeds and inserts 0 when ON DUPLICATE KEY UPDATE assigns that column
-
- Confirmed
-