Repository navigation
Commit 123747e
authored
fix: keep a projection's field names when decorrelating a predicate s… (#26657)
## Which issue does this PR close?
No issue was filed; this body carries the report.
## Rationale for this change
A set comparison in a projection that has no alias fails with an
internal error:
```console
> SELECT 2 > ALL (SELECT x FROM (VALUES (1),(0)) t(x));
Internal error: Assertion failed: compatible: Failed due to a difference in schemas:
original schema: … Field { name: "Int64(2) > ALL", data_type: Boolean } …
new schema: … Field { name: "CASE WHEN EXISTS THEN Boolean(false) …" } …
```
`DecorrelatePredicateSubquery` rebuilds a projection from its
expressions, and it preserved the output
field names from `Expr::schema_name()`. That is not the name the rebuilt
projection uses, for two
reasons: `schema_name()` keeps a column's qualifier (`t.k`) while the
field is named after the bare
column, and earlier rules rewrite expressions with `map_expressions`,
which keeps the schema but can
leave an expression whose display name no longer matches its field name.
`RewriteSetComparison` does
exactly that — it replaces `x > ALL (…)` with a `CASE WHEN EXISTS …` —
so this rule rebuilt the
projection under the stale name and the optimizer's schema-invariance
check failed.
`datafusion.optimizer.skip_failed_rules` defaults to false, so the user
sees the internal error.
Not on the release line: 55.2.0 does not contain #24972, so the same
query still reports
`Physical plan does not support logical expression Exists(…)` there.
## What changes are included in this PR?
* `datafusion/optimizer/src/decorrelate_predicate_subquery.rs`: take the
field names from the
projection's own schema, and compare them against the name the rebuilt
projection would use
(`Expr::qualified_name`, i.e. the bare column name for a column, the
alias name for an alias, the
display name otherwise), so an alias is added only when it would really
differ. Comparing against
the schema name alone would alias a qualified column and lose its
qualifier — the same check
failing from the other side.
* `datafusion/sqllogictest/test_files/subquery.slt`: three cases —
unaliased, unaliased with a second
projected column, and aliased. The aliased one is a control rather than
a regression test: it
passes on `main` too, and pins the alias arm of the name comparison.
## What is the testing strategy for this PR?
The two unaliased `.slt` cases fail on `main` with `Optimizer rule
'decorrelate_predicate_subquery'
failed` and pass with the change; the aliased case is the control
described above. On the branch
merged with `main`, `subquery.slt`, `subquery_projection.slt`,
`null_aware_anti_join.slt`,
`null_aware_mark_join.slt` and `prepare.slt` all pass with 0 errors,
`cargo test -p
datafusion-optimizer` is 951 + 29 + 5 passed and 0 failed, and `cargo
fmt --all --check` is clean.
## Are there any user-facing changes?
No.1 parent 6110f74 commit 123747e
2 files changed
Lines changed: 51 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
39 | 48 | | |
| 49 | + | |
40 | 50 | | |
| 51 | + | |
41 | 52 | | |
42 | 53 | | |
43 | 54 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4094 | 4094 | | |
4095 | 4095 | | |
4096 | 4096 | | |
| 4097 | + | |
| 4098 | + | |
| 4099 | + | |
| 4100 | + | |
| 4101 | + | |
| 4102 | + | |
| 4103 | + | |
| 4104 | + | |
| 4105 | + | |
| 4106 | + | |
| 4107 | + | |
| 4108 | + | |
| 4109 | + | |
| 4110 | + | |
| 4111 | + | |
| 4112 | + | |
| 4113 | + | |
| 4114 | + | |
| 4115 | + | |
| 4116 | + | |
| 4117 | + | |
| 4118 | + | |
| 4119 | + | |
| 4120 | + | |
| 4121 | + | |
| 4122 | + | |
| 4123 | + | |
| 4124 | + | |
| 4125 | + | |
| 4126 | + | |
| 4127 | + | |
| 4128 | + | |
| 4129 | + | |
| 4130 | + | |
| 4131 | + | |
| 4132 | + | |
| 4133 | + | |
| 4134 | + | |
| 4135 | + | |
4097 | 4136 | | |
4098 | 4137 | | |
4099 | 4138 | | |
| |||
0 commit comments