@@ -2854,39 +2854,55 @@ fn test_cache_cleared_after_expr_deserialization() -> Result<()> {
28542854 let field_a = Field :: new ( "a" , DataType :: Int64 , false ) ;
28552855 let schema = Arc :: new ( Schema :: new ( vec ! [ field_a] ) ) ;
28562856
2857- // Create a column expression
2857+ // Create a binary expression where both sides are the same Arc
2858+ // This allows us to test deduplication within a single deserialization
28582859 let col_expr: Arc < dyn PhysicalExpr > = Arc :: new ( Column :: new ( "a" , 0 ) ) ;
2860+ let binary_expr: Arc < dyn PhysicalExpr > = Arc :: new ( BinaryExpr :: new (
2861+ Arc :: clone ( & col_expr) ,
2862+ Operator :: Plus ,
2863+ Arc :: clone ( & col_expr) , // Same Arc - will be deduplicated
2864+ ) ) ;
28592865
28602866 let ctx = SessionContext :: new ( ) ;
28612867 let codec = DefaultPhysicalExtensionCodec { } ;
28622868 let proto_converter = DefaultPhysicalProtoConverter :: new ( ) ;
28632869
28642870 // Serialize the expression
2865- let proto = proto_converter. physical_expr_to_proto ( & col_expr , & codec) ?;
2871+ let proto = proto_converter. physical_expr_to_proto ( & binary_expr , & codec) ?;
28662872
2867- // Create a single converter and reuse it for multiple expression deserializations
2873+ // Create a single converter and reuse it for multiple deserializations
28682874 let deser_converter = DefaultPhysicalProtoConverter :: new ( ) ;
28692875
28702876 // Verify cache starts empty
28712877 assert_eq ! ( deser_converter. cache_size( ) , 0 , "Cache should start empty" ) ;
28722878
28732879 // First expression deserialization
2874- let _expr1 = deser_converter. proto_to_physical_expr (
2880+ let expr1 = deser_converter. proto_to_physical_expr (
28752881 & proto,
28762882 ctx. task_ctx ( ) . as_ref ( ) ,
28772883 & schema,
28782884 & codec,
28792885 ) ?;
28802886
2887+ // Check that deduplication worked within the deserialization
2888+ let binary1 = expr1
2889+ . as_any ( )
2890+ . downcast_ref :: < BinaryExpr > ( )
2891+ . expect ( "Expected BinaryExpr" ) ;
2892+ assert ! (
2893+ Arc :: ptr_eq( binary1. left( ) , binary1. right( ) ) ,
2894+ "Expected both sides to share the same Arc after deduplication"
2895+ ) ;
2896+
28812897 // Cache should be cleared after expression deserialization completes
28822898 assert_eq ! (
28832899 deser_converter. cache_size( ) ,
28842900 0 ,
28852901 "Cache should be cleared after first expression deserialization"
28862902 ) ;
28872903
2888- // Second expression deserialization with same converter should also work
2889- let _expr2 = deser_converter. proto_to_physical_expr (
2904+ // Second expression deserialization with same converter
2905+ let expr2 = deser_converter. proto_to_physical_expr (
28902906 & proto,
28912907 ctx. task_ctx ( ) . as_ref ( ) ,
28922908 & schema,
@@ -2900,5 +2916,25 @@ fn test_cache_cleared_after_expr_deserialization() -> Result<()> {
29002916 "Cache should be cleared after second expression deserialization"
29012917 ) ;
29022918
2919+ // Check that the second expression was also deserialized correctly
2920+ let binary2 = expr2
2921+ . as_any ( )
2922+ . downcast_ref :: < BinaryExpr > ( )
2923+ . expect ( "Expected BinaryExpr" ) ;
2924+ assert ! (
2925+ Arc :: ptr_eq( binary2. left( ) , binary2. right( ) ) ,
2926+ "Expected both sides to share the same Arc after deduplication"
2927+ ) ;
2928+
2929+ // Check that there was no deduplication across deserializations
2930+ assert ! (
2931+ !Arc :: ptr_eq( binary1. left( ) , binary2. left( ) ) ,
2932+ "Expected expressions from different deserializations to be different Arcs"
2933+ ) ;
2934+ assert ! (
2935+ !Arc :: ptr_eq( binary1. right( ) , binary2. right( ) ) ,
2936+ "Expected expressions from different deserializations to be different Arcs"
2937+ ) ;
2938+
29032939 Ok ( ( ) )
29042940}
0 commit comments