Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Duplicate
-
12.3.3
-
None
-
MariaDB 12.3.3 on Linux/amd64
-
Not for Release Notes
Description
On MariaDB 12.3.3 for Linux/amd64, adding an alias to a target-table self-reference changes how an INSERT ... VALUES statement is evaluated. The unaliased expression observes the empty pre-insert table, but the aliased expression observes the first row written by the same statement and inserts a second 3 instead of NULL.
Reproducer
Save the following as case.sql:
CREATE DATABASE IF NOT EXISTS test; |
USE test; |
DROP TABLE IF EXISTS t1; |
CREATE TABLE t1 (a INT) ENGINE=InnoDB; |
|
|
-- Control: the unaliased self-reference is detected and precomputed.
|
INSERT INTO t1(a) |
VALUES (3), ((SELECT MAX(a) FROM t1)); |
SELECT 'unaliased' AS variant, |
COUNT(*) AS row_count, |
SUM(a=3) AS threes, |
SUM(a IS NULL) AS nulls |
FROM t1; |
|
|
TRUNCATE TABLE t1; |
|
|
-- Changing only the source alias must not change the snapshot.
|
INSERT INTO t1(a) |
VALUES (3), ((SELECT MAX(src.a) |
FROM t1 AS src)); |
SELECT 'aliased' AS variant, |
COUNT(*) AS row_count, |
SUM(a=3) AS threes, |
SUM(a IS NULL) AS nulls |
FROM t1; |
|
|
DROP TABLE t1; |
Execute it with:
mariadb < case.sql |
Observed result
variant row_count threes nulls
|
unaliased 2 1 1
|
variant row_count threes nulls
|
aliased 2 2 0
|
The unaliased control inserts one 3 and one NULL. With only the source alias added, the second expression returns 3, showing that it read the first row after that row had already been inserted.
Expected result
Both variants should return row_count=2, threes=1, and nulls=1. Every VALUES expression that reads the insertion target should be evaluated against the same pre-insert state, independently of the source alias. Because the table is initially empty, MAX(a) should be NULL in both variants.
This occurs when a multi-row INSERT ... VALUES contains a scalar subquery that reads the target table through an alias.
Attachments
Issue Links
- duplicates
-
MDEV-36623 INSERT INTO tbl VALUES (subquery) can read the values just inserted
-
- Open
-