Skip to content

refactor: move lambda variable scope into Physical Planning Context - #23989

Open
sweb wants to merge 2 commits into
apache:mainfrom
sweb:refactor/move-lambda-eval
Open

refactor: move lambda variable scope into Physical Planning Context#23989
sweb wants to merge 2 commits into
apache:mainfrom
sweb:refactor/move-lambda-eval

Conversation

@sweb

@sweb sweb commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

This is a clean up following #23649

What changes are included in this PR?

  • Moves the lambda-variable scope state out of ExecutionProps and into PhysicalPlanningContext, following the same pattern as the scalar-subquery state in refactor: pass PhysicalPlanningContext explicitly through planner traits #23649.

  • Puts PhysicalPlanningContext::indexes behind an Arc so the new per-lambda-body clone doesn't deep-copy the subquery index map. PhysicalPlanningContext::new's signature is unchanged.

Are these changes tested?

  • New lambda_variables_shadow_outer_scope unit test in physical_planning_context.rs covers with_qualified_lambda_variables / lambda_variable_qualifier directly, including an inner lambda shadowing an outer parameter name.

Are there any user-facing changes?

this is a breaking change for lib users.

@github-actions github-actions Bot added documentation Improvements or additions to documentation logical-expr Logical plan and expressions physical-expr Changes to the physical-expr crates labels Jul 30, 2026
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

Thank you for opening this pull request!

Reviewer note: cargo-semver-checks reported the current version number is not SemVer-compatible with the changes in this pull request (compared against the base branch).

Details
     Cloning apache/main
    Building datafusion-expr v54.1.0 (current)
       Built [  32.156s] (current)
     Parsing datafusion-expr v54.1.0 (current)
      Parsed [   0.073s] (current)
    Building datafusion-expr v54.1.0 (baseline)
       Built [  28.028s] (baseline)
     Parsing datafusion-expr v54.1.0 (baseline)
      Parsed [   0.076s] (baseline)
    Checking datafusion-expr v54.1.0 -> v54.1.0 (no change; assume patch)
     Checked [   1.243s] 223 checks: 221 pass, 2 fail, 0 warn, 30 skip

--- failure inherent_method_missing: pub method removed or renamed ---

Description:
A publicly-visible method or associated fn is no longer available under its prior name. It may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/inherent_method_missing.ron

Failed in:
  ExecutionProps::with_qualified_lambda_variables, previously in file /home/runner/work/datafusion/datafusion/target/semver-checks/git-apache_main/f3908c0f85f194482a0c30e6fbe764bb3346c13d/datafusion/expr/src/execution_props.rs:145

--- failure struct_pub_field_missing: pub struct's pub field removed or renamed ---

Description:
A publicly-visible struct has at least one public field that is no longer available under its prior name. It may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/struct_pub_field_missing.ron

Failed in:
  field lambda_variable_qualifier of struct ExecutionProps, previously in file /home/runner/work/datafusion/datafusion/target/semver-checks/git-apache_main/f3908c0f85f194482a0c30e6fbe764bb3346c13d/datafusion/expr/src/execution_props.rs:66

     Summary semver requires new major version: 2 major and 0 minor checks failed
    Finished [  62.658s] datafusion-expr
    Building datafusion-physical-expr v54.1.0 (current)
       Built [  29.117s] (current)
     Parsing datafusion-physical-expr v54.1.0 (current)
      Parsed [   0.048s] (current)
    Building datafusion-physical-expr v54.1.0 (baseline)
       Built [  28.723s] (baseline)
     Parsing datafusion-physical-expr v54.1.0 (baseline)
      Parsed [   0.050s] (baseline)
    Checking datafusion-physical-expr v54.1.0 -> v54.1.0 (no change; assume patch)
     Checked [   0.310s] 223 checks: 223 pass, 30 skip
     Summary no semver update required
    Finished [  59.443s] datafusion-physical-expr

@github-actions github-actions Bot added the auto detected api change Auto detected API change label Jul 30, 2026
@codecov-commenter

codecov-commenter commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.87%. Comparing base (62650ef) to head (1bc2fff).

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #23989      +/-   ##
==========================================
- Coverage   80.87%   80.87%   -0.01%     
==========================================
  Files        1101     1101              
  Lines      375765   375781      +16     
  Branches   375765   375781      +16     
==========================================
+ Hits       303915   303917       +2     
- Misses      53747    53755       +8     
- Partials    18103    18109       +6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sweb sweb changed the title refactor: move lambda evaluation into Physical Planning Context refactor: move lambda variable scope into Physical Planning Context Jul 30, 2026
@sweb
sweb force-pushed the refactor/move-lambda-eval branch from 0bab196 to 3b38dfa Compare July 30, 2026 08:28
@sweb

sweb commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@timsaucer may I ask you for a review? Thank you!

@timsaucer
timsaucer requested review from Copilot and timsaucer August 3, 2026 12:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Refactors physical planning to move lambda-variable qualifier state out of ExecutionProps into PhysicalPlanningContext, aligning it with prior scalar-subquery state refactors.

Changes:

  • Move lambda-variable qualifier state from ExecutionProps to PhysicalPlanningContext.
  • Put PhysicalPlanningContext::indexes behind Arc to avoid deep copies when cloning per lambda body.
  • Update docs and add a unit test for lambda variable shadowing across nested scopes.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
docs/source/library-user-guide/upgrading/55.0.0.md Documents the breaking API move from ExecutionProps to PhysicalPlanningContext (now including lambda-variable qualifier state).
datafusion/physical-expr/src/planner.rs Switches lambda-variable qualifier lookup/propagation to use PhysicalPlanningContext.
datafusion/expr/src/physical_planning_context.rs Adds lambda-variable qualifier tracking to the planning context; wraps subquery indexes in Arc; adds unit test.
datafusion/expr/src/execution_props.rs Removes lambda-variable qualifier state and helper API from ExecutionProps; updates Debug test.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +782 to +788
- Code that read `execution_props.lambda_variable_qualifier` or called
`ExecutionProps::with_qualified_lambda_variables`: nothing to migrate.
`create_physical_expr` populates the lambda qualifiers itself as it descends
into lambda bodies, so callers planning a `HigherOrderFunction` do not need to
do anything. The equivalent state now lives on `PhysicalPlanningContext`,
reachable via `PhysicalPlanningContext::lambda_variable_qualifier` and
`PhysicalPlanningContext::with_qualified_lambda_variables`.
Comment on lines +88 to +89
/// Adds a mapping for each variable to the given qualifier. Existing
/// variables with conflicting names get shadowed
Comment on lines +617 to 619
let planning_ctx = planning_ctx
.clone()
.with_qualified_lambda_variables(&qualifier, &lambda.params);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto detected api change Auto detected API change documentation Improvements or additions to documentation logical-expr Logical plan and expressions physical-expr Changes to the physical-expr crates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move lambda evaluation into Physical Planning Context

3 participants