Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Minor
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.1, 12.3.3
-
MariaDB 12.3.3 on Linux x86_64 (Ubuntu 24.04 build)
Description
In Oracle mode, an unparenthesized chain that transitions from INTERSECT to INTERSECT ALL returns a row that is absent from the middle operand. The equivalent explicitly parenthesized expression returns the correct result, as do the same inline and prepared queries in the default SQL mode.
Steps to reproduce
Run this SQL sequence:
CREATE DATABASE IF NOT EXISTS set_test; |
USE set_test; |
|
|
CREATE TABLE a (x INT); |
CREATE TABLE b (x INT); |
CREATE TABLE c (x INT); |
|
|
INSERT INTO a VALUES (1),(2),(2); |
INSERT INTO b VALUES (1); |
INSERT INTO c VALUES (1),(2),(2); |
|
|
SET sql_mode='ORACLE'; |
|
|
SELECT 'inline_oracle' AS phase; |
SELECT x FROM a |
INTERSECT
|
SELECT x FROM b |
INTERSECT ALL |
SELECT x FROM c |
ORDER BY 1; |
|
|
SELECT 'nested_oracle' AS phase; |
(SELECT x FROM a INTERSECT SELECT x FROM b) |
INTERSECT ALL |
SELECT x FROM c |
ORDER BY 1; |
|
|
PREPARE p FROM 'SELECT x FROM a INTERSECT SELECT x FROM b INTERSECT ALL SELECT x FROM c ORDER BY 1'; |
SELECT 'prepared_oracle_1' AS phase; |
EXECUTE p; |
SELECT 'prepared_oracle_2' AS phase; |
EXECUTE p; |
DEALLOCATE PREPARE p; |
|
|
SET sql_mode=''; |
|
|
SELECT 'inline_default' AS phase; |
SELECT x FROM a |
INTERSECT
|
SELECT x FROM b |
INTERSECT ALL |
SELECT x FROM c |
ORDER BY 1; |
|
|
PREPARE p FROM 'SELECT x FROM a INTERSECT SELECT x FROM b INTERSECT ALL SELECT x FROM c ORDER BY 1'; |
SELECT 'prepared_default_1' AS phase; |
EXECUTE p; |
SELECT 'prepared_default_2' AS phase; |
EXECUTE p; |
DEALLOCATE PREPARE p; |
|
|
DROP DATABASE set_test; |
Actual result
The inline Oracle-mode query and both executions of its prepared form return rows 1 and 2. The explicitly parenthesized Oracle-mode query and all default-mode queries return only row 1:
inline_oracle
|
1
|
2
|
nested_oracle
|
1
|
prepared_oracle_1
|
1
|
2
|
prepared_oracle_2
|
1
|
2
|
inline_default
|
1
|
prepared_default_1
|
1
|
prepared_default_2
|
1
|
Expected result
For A = {1,2,2}, B = {1}, and C = {1,2,2}, A INTERSECT B contains only 1. Applying INTERSECT ALL C cannot add 2, so every query in the reproducer should return exactly one row containing 1. The parenthesized Oracle-mode result also demonstrates that the extra 2 is not explained by the input data or intended set semantics.
This occurs when Oracle SQL mode evaluates an unparenthesized set-operation chain that transitions from INTERSECT DISTINCT to INTERSECT ALL.