Skip to content

datafusion-physical-expr: add DynamicFilterPhysicalExpr::update_from(Self) method - #26534

Open
jayshrivastava wants to merge 4 commits into
apache:mainfrom
jayshrivastava:js/dynamic-filter-update-from
Open

jayshrivastava wants to merge 4 commits into
apache:mainfrom
jayshrivastava:js/dynamic-filter-update-from

Conversation

@jayshrivastava

@jayshrivastava jayshrivastava commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

What changes are included in this PR?

This PR adds a helper similar to DynamicFilterPhysicalExpr::update() which takes a different DynamicFilterPhysicalExpr.

pub fn update_from(&self, source: &Self) -> Result<()> {

Rationale for this change

The use case I have is that I want to update a Arc<DynamicFilterPhysicalExpr> from a different Arc<DynamicFilterPhysicalExpr> (as opposed to the normal update() API which takes a non dynamic filter Arc<dyn PhysicalExpr>).

This requires accessing private fields like Inner. Rather than exposing private fields, I thought that adding an update_from(Self) API is cleaner.

Note that you cannot call

dynamic_filter_1.update(dynamic_filter_2.current())

because
a) it doesn't copy is_complete
b) it doesn't copy inner.expr directly. current() returns the expression with remapped columns and calling dynamic_filter_expr.update(remapped_expression); dynamic_filter_expr.current() breaks because current() cannot remap the remapped expression.

Alternatives Considered

  1. As a hack to get the private internal state, we currently incur a proto roundtrip, which makes fields like inner.expr and is_complete public. This is undesirable because it adds overhead
  2. Replace a dynamic filter entirely rather than mutate it. Currently datafusion has no API to "replace" a dynamic filter with another one in an ExecutionPlan. In a way, this is what update_from does, taking advantage of interior mutability.

What is the testing strategy for this PR?

One unit test

Are there any user-facing changes?

No.

@github-actions github-actions Bot added the physical-expr Changes to the physical-expr crates label Oct 20, 2026
@jayshrivastava
jayshrivastava marked this pull request as ready for review October 20, 2026 21:04
@jayshrivastava jayshrivastava changed the title wip datafusion-physical-expr: add DynamicFilterPhysicalExpr::update_from(Self) method Oct 20, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 24 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.94%. Comparing base (63af08d) to head (9f8db33).
⚠️ Report is 36 commits behind head on main.

Files with missing lines Patch % Lines
...ysical-expr/src/expressions/dynamic_filters/mod.rs 85.71% 2 Missing and 22 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #26534      +/-   ##
==========================================
+ Coverage   82.91%   82.94%   +0.02%     
==========================================
  Files        1155     1156       +1     
  Lines      458058   458717     +659     
  Branches   458058   458717     +659     
==========================================
+ Hits       379813   380489     +676     
+ Misses      55202    55148      -54     
- Partials    23043    23080      +37     

☔ 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.


current.generation += 1;
current.expr = source_state.expr;
current.is_complete |= source_state.is_complete;

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.

Once current.is_complete is true, consumers may stop tracking this filter because the API contract says its expression will no longer change. However, update_from can still replace the expression of an already-complete target while preserving is_complete = true.

The final step of test_update_from_notifies_waiters_and_preserves_completion appears to exercise this case: the target is complete with lit(false), then receives the incomplete snapshot containing lit(true). The target therefore remains complete but its expression changes.

Could update_from reject or ignore updates when the target is already complete? A regression assertion that the expression, generation, and watch state remain unchanged would also help protect the terminal completion contract.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

physical-expr Changes to the physical-expr crates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants