@@ -648,6 +648,12 @@ impl ConstEvaluator {
648648 }
649649 Expr :: Cast ( Cast { expr, data_type } )
650650 | Expr :: TryCast ( TryCast { expr, data_type } ) => {
651+ // Fast path: only struct targets need struct-specific foldability checks.
652+ // For non-struct casts, avoid deriving the source type from an empty schema.
653+ if !matches ! ( data_type, DataType :: Struct ( _) ) {
654+ return true ;
655+ }
656+
651657 if let (
652658 Ok ( DataType :: Struct ( source_fields) ) ,
653659 DataType :: Struct ( target_fields) ,
@@ -5339,4 +5345,27 @@ mod tests {
53395345 "Struct cast with empty (0-row) array should remain unchanged"
53405346 ) ;
53415347 }
5348+
5349+ #[ test]
5350+ fn test_cast_heavy_non_struct_chain_foldable ( ) {
5351+ // Exercise a cast-heavy, non-struct simplification path to protect against
5352+ // planner regressions in cast eligibility checks.
5353+ let expr = ( 0 ..64 ) . fold (
5354+ Expr :: Literal ( ScalarValue :: Int32 ( Some ( 7 ) ) , None ) ,
5355+ |acc, i| {
5356+ let target_type = if i % 2 == 0 {
5357+ DataType :: Int64
5358+ } else {
5359+ DataType :: Int32
5360+ } ;
5361+ Expr :: Cast ( Cast :: new ( Box :: new ( acc) , target_type) )
5362+ } ,
5363+ ) ;
5364+
5365+ let simplifier =
5366+ ExprSimplifier :: new ( SimplifyContext :: default ( ) . with_schema ( test_schema ( ) ) ) ;
5367+ let result = simplifier. simplify ( expr) . unwrap ( ) ;
5368+
5369+ assert_eq ! ( result, Expr :: Literal ( ScalarValue :: Int32 ( Some ( 7 ) ) , None ) ) ;
5370+ }
53425371}
0 commit comments