Details
-
Bug
-
Status: In Progress (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.1, 12.3.2
-
Operating system:
- Ubuntu 20.04.6 LTS (Focal Fossa)
- Linux kernel: 5.4.0-204-generic
- Architecture: x86_64
Hardware:
- CPU: 2 × Intel Xeon Gold 5218R @ 2.10 GHz
- 40 physical cores / 80 logical CPUs
Description
-
-
- Problem Description
With `optimizer_switch='derived_merge=off'`, the single-table path and the CTE + multi-table reconstructed path return different results for the same WHERE condition `(('2096-02-25 15:30:07' NOT IN ('b,c', c0)) IN (c1))`. The single-table path returns one row `(0, 45, 0)`, while the CTE + multi-table reconstructed path returns an empty set. The single-table path uses the `idx_s(c0)` index, whereas the multi-table reconstructed path cannot push the condition down to the index after CTE materialization, causing the same expression's implicit type conversion or comparison semantics to differ between execution paths.
- Problem Description
-
-
-
- How to Reproduce
Execute the following SQL:
- How to Reproduce
-
```sql
DROP DATABASE IF EXISTS repro_mariadb817_db12_min;
CREATE DATABASE repro_mariadb817_db12_min;
USE repro_mariadb817_db12_min;
CREATE TABLE s (
vp_rowid BIGINT NOT NULL,
c0 BIGINT NOT NULL,
c1 DATETIME NOT NULL,
PRIMARY KEY (c1),
UNIQUE KEY (vp_rowid),
KEY idx_s (c0)
) ENGINE=InnoDB;
CREATE TABLE lpart (
vp_rowid BIGINT NOT NULL PRIMARY KEY,
c0 BIGINT NOT NULL,
c1 DATETIME NOT NULL
) ENGINE=InnoDB;
CREATE TABLE rpart (
vp_rowid BIGINT NOT NULL PRIMARY KEY,
c1 DATETIME NOT NULL
) ENGINE=InnoDB;
INSERT INTO s VALUES
(1, 0, '0000-00-00 00:00:00'),
(2, 2, '2000-01-01 00:00:02'),
(3, 3, '2000-01-01 00:00:03'),
(4, 4, '2000-01-01 00:00:04'),
(5, 5, '2000-01-01 00:00:05'),
(6, 6, '2000-01-01 00:00:06'),
(7, 7, '2000-01-01 00:00:07'),
(8, 8, '2000-01-01 00:00:08');
INSERT INTO lpart SELECT * FROM s;
INSERT INTO rpart SELECT vp_rowid, c1 FROM s;
SET SESSION optimizer_switch='derived_merge=off';
– Single-table path
SELECT *
FROM (
SELECT ALL c0, 45, false
FROM s
WHERE (('2096-02-25 15:30:07' NOT IN ('b,c', c0)) IN (c1))
) q
ORDER BY 1, 2, 3;
– CTE + multi-table reconstructed path
SELECT *
FROM (
SELECT ALL c0, 45, false
FROM (
WITH l AS (SELECT * FROM lpart),
r AS (SELECT * FROM rpart)
SELECT l.vp_rowid, l.c0, r.c1
FROM l JOIN r ON l.vp_rowid = r.vp_rowid
) reconstructed
WHERE (('2096-02-25 15:30:07' NOT IN ('b,c', c0)) IN (c1))
) q
ORDER BY 1, 2, 3;
```
-
-
- Expected Behavior
The single-table path and the CTE + multi-table reconstructed path should return the same result, i.e., both should return:
- Expected Behavior
-
```
0 | 45 | 0
```
-
-
- Actual Behavior
-
- Single-table path: returns one row `0 | 45 | 0`.
- CTE + multi-table reconstructed path: returns `empty set`.
Attachments
Issue Links
- relates to
-
MDEV-41327 With `derived_merge=off`, derived table column pruning drops `c2`, and the `c3 IN (c2 << c2)` implicit cast chain makes single-table and rewritten queries return inconsistent results (1 row vs 0 rows).
-
- Confirmed
-