@@ -258,6 +258,47 @@ pub fn serialize_physical_expr_with_converter(
258258 codec : & dyn PhysicalExtensionCodec ,
259259 proto_converter : & dyn PhysicalProtoConverterExtension ,
260260) -> Result < protobuf:: PhysicalExprNode > {
261+ // Check for DynamicFilterPhysicalExpr before snapshotting.
262+ // We need to handle it before snapshot_physical_expr because snapshot()
263+ // replaces the DynamicFilterPhysicalExpr with its inner expression.
264+ if let Some ( df) = value. as_any ( ) . downcast_ref :: < DynamicFilterPhysicalExpr > ( ) {
265+ // Capture all state atomically
266+ let snapshot = DynamicFilterSnapshot :: from ( df) ;
267+
268+ let children = snapshot
269+ . children ( )
270+ . iter ( )
271+ . map ( |child| proto_converter. physical_expr_to_proto ( child, codec) )
272+ . collect :: < Result < Vec < _ > > > ( ) ?;
273+
274+ let remapped_children = if let Some ( remapped) = snapshot. remapped_children ( ) {
275+ remapped
276+ . iter ( )
277+ . map ( |child| proto_converter. physical_expr_to_proto ( child, codec) )
278+ . collect :: < Result < Vec < _ > > > ( ) ?
279+ } else {
280+ vec ! [ ]
281+ } ;
282+
283+ let inner_expr = Box :: new (
284+ proto_converter. physical_expr_to_proto ( snapshot. inner_expr ( ) , codec) ?,
285+ ) ;
286+
287+ return Ok ( protobuf:: PhysicalExprNode {
288+ expr_id : None ,
289+ dynamic_filter_inner_id : None ,
290+ expr_type : Some ( protobuf:: physical_expr_node:: ExprType :: DynamicFilter (
291+ Box :: new ( protobuf:: PhysicalDynamicFilterNode {
292+ children,
293+ remapped_children,
294+ generation : snapshot. generation ( ) ,
295+ inner_expr : Some ( inner_expr) ,
296+ is_complete : snapshot. is_complete ( ) ,
297+ } ) ,
298+ ) ) ,
299+ } ) ;
300+ }
301+
261302 // Snapshot the expr in case it has dynamic predicate state so
262303 // it can be serialized
263304 let value = snapshot_physical_expr ( Arc :: clone ( value) ) ?;
@@ -328,42 +369,6 @@ pub fn serialize_physical_expr_with_converter(
328369 binary_expr,
329370 ) ) ,
330371 } )
331- } else if let Some ( df) = expr. downcast_ref :: < DynamicFilterPhysicalExpr > ( ) {
332- // Capture all state atomically
333- let snapshot = DynamicFilterSnapshot :: from ( df) ;
334-
335- let children = snapshot
336- . children ( )
337- . iter ( )
338- . map ( |child| proto_converter. physical_expr_to_proto ( child, codec) )
339- . collect :: < Result < Vec < _ > > > ( ) ?;
340-
341- let remapped_children = if let Some ( remapped) = snapshot. remapped_children ( ) {
342- remapped
343- . iter ( )
344- . map ( |child| proto_converter. physical_expr_to_proto ( child, codec) )
345- . collect :: < Result < Vec < _ > > > ( ) ?
346- } else {
347- vec ! [ ]
348- } ;
349-
350- let inner_expr = Box :: new (
351- proto_converter. physical_expr_to_proto ( snapshot. inner_expr ( ) , codec) ?,
352- ) ;
353-
354- Ok ( protobuf:: PhysicalExprNode {
355- expr_id : None ,
356- dynamic_filter_inner_id : None ,
357- expr_type : Some ( protobuf:: physical_expr_node:: ExprType :: DynamicFilter (
358- Box :: new ( protobuf:: PhysicalDynamicFilterNode {
359- children,
360- remapped_children,
361- generation : snapshot. generation ( ) ,
362- inner_expr : Some ( inner_expr) ,
363- is_complete : snapshot. is_complete ( ) ,
364- } ) ,
365- ) ) ,
366- } )
367372 } else if let Some ( expr) = expr. downcast_ref :: < CaseExpr > ( ) {
368373 Ok ( protobuf:: PhysicalExprNode {
369374 expr_id : None ,
0 commit comments