@@ -174,9 +174,9 @@ pub struct EngineExpressionVisitor {
174174 /// `child_list_id`. The `output_schema` handle specifies the schema to parse the JSON
175175 /// into.
176176 pub visit_parse_json : VisitParseJsonFn ,
177- /// Visits the `MapToStruct` expression belonging to the list identified by `sibling_list_id`.
178- /// The sub-expression (map column) will be in a _one_ item list identified by `child_list_id`.
179- /// The output struct schema is determined by the evaluator's result type .
177+ /// Visits a `MapToStruct` expression with default options. Expressions with configured options
178+ /// are reported through `visit_unknown` without visiting the child expression. The
179+ /// sub-expression is in the one-item list identified by `child_list_id` .
180180 pub visit_map_to_struct : VisitUnaryFn ,
181181 /// Visits the `LessThan` binary operator belonging to the list identified by
182182 /// `sibling_list_id`. The operands will be in a _two_ item list identified by
@@ -696,7 +696,10 @@ fn visit_expression_impl(
696696 schema_handle
697697 ) ;
698698 }
699- Expression :: MapToStruct ( MapToStructExpression { map_expr } ) => {
699+ Expression :: MapToStruct ( map_to_struct) if !map_to_struct. options . is_default ( ) => {
700+ visit_unknown ( visitor, sibling_list_id, "map_to_struct" )
701+ }
702+ Expression :: MapToStruct ( MapToStructExpression { map_expr, .. } ) => {
700703 let child_list_id = call ! ( visitor, make_field_list, 1 ) ;
701704 visit_expression_impl ( visitor, map_expr, child_list_id) ;
702705 call ! ( visitor, visit_map_to_struct, sibling_list_id, child_list_id) ;
@@ -771,7 +774,7 @@ fn visit_predicate_internal(predicate: &Predicate, visitor: &mut EngineExpressio
771774
772775#[ cfg( test) ]
773776mod tests {
774- use delta_kernel:: expressions:: { lit, Expression , Scalar } ;
777+ use delta_kernel:: expressions:: { lit, Expression , MapToStructOptions , Scalar } ;
775778 use rstest:: rstest;
776779
777780 use super :: * ;
@@ -791,6 +794,10 @@ mod tests {
791794 sibling_list_id : usize ,
792795 parts : Vec < String > ,
793796 } ,
797+ Unknown {
798+ sibling_list_id : usize ,
799+ name : String ,
800+ } ,
794801 }
795802
796803 #[ derive( Default ) ]
@@ -847,6 +854,18 @@ mod tests {
847854 } ) ;
848855 }
849856
857+ extern "C" fn visit_unknown_name (
858+ data : * mut c_void ,
859+ sibling_list_id : usize ,
860+ name : KernelStringSlice ,
861+ ) {
862+ let builder = unsafe { & mut * ( data as * mut TestExpressionBuilder ) } ;
863+ let name = unsafe { String :: try_from_slice ( & name) } . unwrap ( ) ;
864+ builder. events . push ( LiteralEvent :: Unknown {
865+ sibling_list_id,
866+ name,
867+ } ) ;
868+ }
850869 macro_rules! ignore_fn {
851870 ( $fn_name: ident $( , $arg_type: ty) * ) => {
852871 extern "C" fn $fn_name(
@@ -925,7 +944,7 @@ mod tests {
925944 visit_field_patch : ignore_field_patch,
926945 visit_opaque_expr : ignore_opaque_expr,
927946 visit_opaque_pred : ignore_opaque_pred,
928- visit_unknown : ignore_string_slice ,
947+ visit_unknown : visit_unknown_name ,
929948 }
930949 }
931950
@@ -992,4 +1011,25 @@ mod tests {
9921011 assert_eq ! ( top_level_id, 0 ) ;
9931012 assert_eq ! ( builder. events, vec![ expected] ) ;
9941013 }
1014+
1015+ #[ test]
1016+ fn timezone_aware_map_to_struct_visits_unknown ( ) {
1017+ let expression = Expression :: map_to_struct (
1018+ Expression :: column ( [ "partitionValues" ] ) ,
1019+ MapToStructOptions :: default ( ) . with_timestamp_timezone ( "America/Los_Angeles" ) ,
1020+ ) ;
1021+ let mut builder = TestExpressionBuilder :: default ( ) ;
1022+ let mut visitor = test_visitor ( & mut builder) ;
1023+
1024+ let top_level_id = visit_expression_internal ( & expression, & mut visitor) ;
1025+
1026+ assert_eq ! ( top_level_id, 0 ) ;
1027+ assert_eq ! (
1028+ builder. events,
1029+ vec![ LiteralEvent :: Unknown {
1030+ sibling_list_id: 0 ,
1031+ name: "map_to_struct" . to_string( ) ,
1032+ } ]
1033+ ) ;
1034+ }
9951035}
0 commit comments