Repository navigation
[dbolympics] Subqueries in an aggregate (GROUP BY key, aggregate argument or FILTER) fail with "Physical plan does not support logical expression" #26704
Copy link
Copy link
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
A subquery (EXISTS, IN or a scalar subquery) inside an aggregate, that is in a GROUP BY key, an aggregate argument or an aggregate FILTER, fails at physical planning with This feature is not implemented: Physical plan does not support logical expression .... The same subquery in the SELECT list or in WHERE works.
To Reproduce
CREATE TABLE t1 (a INT, b VARCHAR, x INT);
INSERT INTO t1 VALUES (1, 'p', 10), (2, 'p', 20), (3, 'q', 30), (NULL, 'q', 40), (2, 'q', 50);
CREATE TABLE t2 (a INT, y INT);
INSERT INTO t2 VALUES (2, 7), (2, 9), (3, 5), (NULL, 1);
-- Query 1
SELECT count(*) FILTER (WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.a = t1.a)) AS n FROM t1;
-- Query 2
SELECT CASE WHEN EXISTS (SELECT 1 FROM t2 WHERE t2.a = t1.a) THEN 'yes' ELSE 'no' END AS has_t2, count(*) AS n
FROM t1 GROUP BY 1 ORDER BY 1;
-- Query 3
SELECT sum(CASE WHEN t1.a IN (SELECT a FROM t2) THEN t1.x ELSE 0 END) AS s FROM t1;
-- Query 4
SELECT t1.b, sum((SELECT max(t2.y) FROM t2 WHERE t2.a = t1.a)) AS s FROM t1 GROUP BY t1.b ORDER BY t1.b;
-- Query 5
SELECT count(*) FILTER (WHERE t1.a NOT IN (SELECT a FROM t2)) AS n FROM t1;Expected behavior
| Query | Subquery is in | DataFusion returns | Expected |
|---|---|---|---|
| 1 | aggregate FILTER |
Physical plan does not support logical expression Exists(...) |
3 |
| 2 | GROUP BY key |
Physical plan does not support logical expression Exists(...) |
no, 2 and yes, 3 |
| 3 | aggregate argument | Physical plan does not support logical expression InSubquery(...) |
100 |
| 4 | aggregate argument | Physical plan does not support logical expression ScalarSubquery(<subquery>) |
p, 9 and q, 14 |
| 5 | aggregate FILTER |
Physical plan does not support logical expression InSubquery(...) |
0 (t2.a has a NULL, so NOT IN is never true) |
DuckDB returns the expected results.
Additional context
- The cause:
DecorrelatePredicateSubqueryandScalarSubqueryToJoinrewrite subqueries only inFilterandProjectionnodes (decorrelate_predicate_subquery.rsmatchesLogicalPlan::ProjectionandLogicalPlan::Filter,scalar_subquery_to_join.rsthe same two). The expressions of anAggregateare never visited, so their subqueries reach the physical planner unchanged. - This shows up in the dbolympics benchmark ([dbolympics] EPIC: Review "db olympics" results #26661): 13 of its 409 queries put a subquery in an aggregate (q057, q084, q085, q091, q135, q136, q156, q178, q182, q312, q315, q370, q409).
- A fix direction that removes the cause: compute each aggregate expression that contains a subquery in a
Projectionbelow theAggregate, keeping the output names with aliases. These expressions are evaluated once per input row anyway, and the existing rules then decorrelate the subquery in thatProjection. I tried this in a prototype (one new optimizer rule placed beforeDecorrelatePredicateSubquery):- Queries 1-5 return the expected results, as do harder cases (several subqueries in one aggregate,
count(DISTINCT ...), an aggregateORDER BY, an aggregate inside a correlated subquery,NOT EXISTS, empty input). - 10 of the 13 dbolympics queries plan. The other 3 then fail on a scalar subquery with
ORDER BY ... LIMIT 1, which is a separate gap. - No other dbolympics query starts or stops failing, and all sqllogictest files and optimizer tests pass (the only expected-output change is the new rule's line in
EXPLAIN VERBOSE). - Like
ScalarSubqueryToJoin, it leaves an uncorrelated scalar subquery where it is, sinceScalarSubqueryExecalready runs it.
- Queries 1-5 return the expected results, as do harder cases (several subqueries in one aggregate,
- Not covered by that approach: a subquery in a
ROLLUP/GROUPING SETSkey. It fails differently on main today (Schema error: No field named t1.a). - Related: [dbolympics] General framework to decorrelate the subqueries #5492 (general decorrelation framework).
Willingness to contribute
I'm not planning to fix this myself, so anyone is welcome to pick it up. Feel free to ping me with questions about the cause or when you'd like a review.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
[-]Subqueries in an aggregate (GROUP BY key, aggregate argument or FILTER) fail with "Physical plan does not support logical expression"[/-][+][dbolympics] Subqueries in an aggregate (GROUP BY key, aggregate argument or FILTER) fail with "Physical plan does not support logical expression"[/+]alamb commentedon Oct 24, 2026
Affects DB Olympics, see: #26661
Amogh-2404 commentedon Oct 28, 2026
take
alamb commentedon Oct 28, 2026
@Amogh-2404 this is not a good project for a new user
alamb commentedon Oct 28, 2026
I think we should implement support support for this feature as part of the more general subquery decorrelation project described here
in my opinion WE SHOULD NOT try and extend the existing subquery rewrites to support this type of query as that risks introducing many more wrong results, see #5492 (comment)
Amogh-2404 commentedon Oct 28, 2026
Understood.
Amogh-2404 commentedon Oct 28, 2026
untake
alamb commentedon Oct 28, 2026
Thank you for your understanding