-
Notifications
You must be signed in to change notification settings - Fork 860
Description
Summary
Databend panics in the decorrelate optimizer when a correlated subquery contains a set operation (UNION or UNION ALL).
The panic is:
panicked at src/query/sql/src/planner/optimizer/optimizers/operator/decorrelate/flatten_plan.rs:684:59:
called `Option::unwrap()` on a `None` value
Minimal Reproducer
This shorter query reproduces the same panic on the current local server (127.0.0.1:8001):
SELECT *
FROM (VALUES (1)) t(f1)
WHERE EXISTS (
SELECT 1
UNION
SELECT 2 WHERE f1 = 1
);Observed result:
[1104]called `Option::unwrap()` on a `None` value
The same shape also reproduces with UNION ALL:
SELECT *
FROM (VALUES (1)) t(f1)
WHERE EXISTS (
SELECT 1
UNION ALL
SELECT 2 WHERE f1 = 1
);Non-Reproducer
Removing the set operation avoids the panic:
SELECT *
FROM (VALUES (1)) t(f1)
WHERE EXISTS (
SELECT 2 WHERE f1 = 1
);This succeeds, so the bug is not caused by correlation alone. The trigger is correlation combined with a set-op subquery.
Suspected Root Cause
The panic backtrace points to the decorrelation path:
try_decorrelate_subqueryflatten_sub_aggregateflatten_sub_union_all
At src/query/sql/src/planner/optimizer/optimizers/operator/decorrelate/flatten_plan.rs:684, the optimizer assumes every correlated column already has a mapping in derived_columns:
let new = *self.derived_columns.get(&old).unwrap();Based on the reproducer and stack, one UNION branch does not populate that mapping, but the merged correlated column set still expects it, so unwrap() panics.
Trigger Pattern
The trigger appears to be all of:
- A correlated subquery.
- The subquery is rewritten by decorrelation.
- The subquery contains a set operation (
UNIONorUNION ALL). - At least one set-op branch references an outer column while another branch does not.
The minimal reproducer matches that shape exactly.
Suggested Fix Direction
Two likely fixes:
- Make
flatten_sub_union_allrobust whenderived_columnsdoes not contain a correlated column mapping. - Normalize or synthesize correlated columns consistently for every set-op branch before merging branch outputs.
A defensive guard would stop the panic, but the correct fix is to preserve column mapping consistency across all union branches during decorrelation.
Validation Command
Used to verify the reproducer:
bendsql -h 127.0.0.1 -P 8001 -u root -D default -n --output=null --query="SELECT * FROM (VALUES (1)) t(f1) WHERE EXISTS (SELECT 1 UNION SELECT 2 WHERE f1 = 1);"