Skip to content

Port DynamicFilterPhysicalExpr to use try_to_proto / try_from_proto #22434

@adriangb

Description

@adriangb

Sub-issue of #22418. Port DynamicFilterPhysicalExpr to own its protobuf (de)serialization via the try_to_proto / try_from_proto hooks added in #21929. This is the original motivator (#21807) — the goal is not just the hooks but deleting the pub-for-proto scaffolding they were added to support.

Reference: copy the Column migration in #21929. Mind the asymmetry — try_to_proto is a trait override, try_from_proto is an inherent fn.

Where it lives

datafusion/physical-expr/src/expressions/dynamic_filters.rs (crate datafusion-physical-expr).

Steps

  1. Add try_to_proto inside the impl PhysicalExpr for DynamicFilterPhysicalExpr block (trait override), feature-gated #[cfg(feature = "proto")].
    ⚠️ Not an inherent impl method — the serializer dispatches through &dyn PhysicalExpr, so an inherent method is silently never called.
  2. Add DynamicFilterPhysicalExpr::try_from_proto(node, ctx) and wire it into the matching ExprType::… arm in from_proto.rs.
  3. In this same PR, delete the DynamicFilterPhysicalExpr arms from both to_proto.rs and from_proto.rs. Deleting the arm is the only proof the hook is reached.
  4. Revert the pub-for-proto scaffolding from proto: serialize and dedupe dynamic filters v2 #21807 in this same PRInner, from_parts, inner(), original_children, remapped_children. Now that decode reads the state directly, these should disappear. Deferring this defeats the purpose of the issue. (A ready-to-cherry-pick commit was posted on PR refactor: add try_to_proto / try_from_proto to DynamicFilterPhysicalExpr #22452.)
  5. expr_id matters here — this is the one expression that sets it. Make sure try_to_proto preserves it via the encode ctx and that expression IDs stay stable across a roundtrip.

Tests

  • The three existing dynamic-filter roundtrip tests must still pass, especially test_dynamic_filter_expression_id_is_stable_between_serializations.
  • Add a direct hook test covering both directions and a bad-input case (wrong expr_type / missing child → clean error).
  • #[cfg(test)] mod tests at the end of the file (clippy items-after-test-module).

Before you push

  • Fill in every section of the PR template.
  • cargo fmt --all and cargo clippy --all-targets --all-features -- -D warnings must pass.

Checklist

  • try_to_proto in the impl PhysicalExpr block (not inherent), #[cfg(feature="proto")]
  • try_from_proto wired into from_proto.rs
  • central to_proto.rs + from_proto.rs arms deleted in this PR
  • Inner / from_parts / inner() / original_children / remapped_children reverted in this PR
  • expr_id preserved; expression-id-stability test passes
  • direct hook test incl. bad-input case; test module at end of file
  • fmt + clippy -D warnings clean; PR template filled in

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions