Repository navigation
Conversation
Replace name-based column matching (replace_cols_by_name, flat_name keys) in ExtractLeafExpressions / PushDownLeafProjections with a single index resolver. A bare `c` and a qualified `t.c` that name the same field now compare equal, so the merge finds an existing extraction spelled the other way instead of adding it a second time. Part of apache#25448. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
adriangb
added a commit
to adriangb/datafusion
that referenced
this pull request
Oct 29, 2026
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Which issue does this PR close?
Rationale for this change
The leaf-pushdown rules (
ExtractLeafExpressions,PushDownLeafProjections) match columns by name. A barecand a qualifiedt.ccan name the same field but do not compare equal. Two fields with the same name can be confused.One result: when a merge into an existing projection looks for an extraction that is already there, the lookup misses if the two spell the column differently. The rule then adds the same extraction a second time. With the same alias,
Projection::try_newfails withDuplicateUnqualifiedField. This is the qualified/unqualified path of #25447.What changes are included in this PR?
One resolver,
column_index(schema, col) -> Option<usize>(Nonewhen the column is missing or ambiguous). All decisions below compare indices.remap_pairs_and_columns(SubqueryAlias, Union)replace_cols_by_namewith aqualified_namemapbuild_projection_replace_map(HashMap<String, Expr>)projection_definition(proj, idx), by output indexExprequality, as spelled(Expr, alias)set,Exprin the canonical spelling of the input schemaoutput_names,existing_cols)column_indexin the output schema, thenhas_column_with_unqualified_nameresolve_againstqualified_field_from_column(first match)column_index(rejects ambiguous)volatile_output_columns/would_duplicate_volatileflat_namesetsmerge_would_duplicate_kept_exprflat_namecountsThe merge also no longer adds an extraction a second time when the existing projection already computes it under two aliases.
Still by name (follow-ups):
PushDownFilter(replace_cols_by_namethere is not changed).What is the testing strategy for this PR?
extract_leaf_expressions.rs:test_merge_finds_extraction_with_other_column_spelling: existing projection hasleaf_udf(a) AS __datafusion_extracted_1, caller asks forleaf_udf(test.a)under the same alias. Fails onmainwithDuplicateUnqualifiedField, passes here.test_merge_finds_extraction_computed_under_two_aliases.test.c + 1 AS d, the extraction now prints asleaf_udf(test.a, ...)instead ofleaf_udf(a, ...). The merge now writes columns in the canonical spelling of the input schema. Same plan, same result..sltchanges.cargo test -p datafusion-optimizer, all sqllogictests, and the leaf-pushdown differential fuzz test (LEAF_PUSHDOWN_FUZZ_CASES=2000) pass.Are there any user-facing changes?
No. Internal refactor of two optimizer rules. A merge that hits the qualified/unqualified mismatch no longer adds a duplicate extraction.
🤖 Generated with Claude Code