@@ -1892,6 +1892,17 @@ impl Literal {
18921892                        date:: date_to_days ( & NaiveDate :: parse_from_str ( & s,  "%Y-%m-%d" ) ?) , 
18931893                    ) ) ) ) 
18941894                } 
1895+                 ( PrimitiveType :: Date ,  JsonValue :: Number ( number) )  => { 
1896+                     Ok ( Some ( Literal :: Primitive ( PrimitiveLiteral :: Int ( 
1897+                         number
1898+                             . as_i64 ( ) 
1899+                             . ok_or ( Error :: new ( 
1900+                                 crate :: ErrorKind :: DataInvalid , 
1901+                                 "Failed to convert json number to date (days since epoch)" , 
1902+                             ) ) ?
1903+                             . try_into ( ) ?, 
1904+                     ) ) ) ) 
1905+                 } 
18951906                ( PrimitiveType :: Time ,  JsonValue :: String ( s) )  => { 
18961907                    Ok ( Some ( Literal :: Primitive ( PrimitiveLiteral :: Long ( 
18971908                        time:: time_to_microseconds ( & NaiveTime :: parse_from_str ( & s,  "%H:%M:%S%.f" ) ?) , 
@@ -3954,4 +3965,44 @@ mod tests {
39543965
39553966        assert_eq ! ( double_sorted,  double_expected) ; 
39563967    } 
3968+ 
3969+     /// Test Date deserialization from JSON as number (days since epoch). 
3970+ /// 
3971+ /// This reproduces the scenario from Iceberg Java's TestAddFilesProcedure where: 
3972+ /// - Date partition columns have initial_default values in manifests 
3973+ /// - These values are serialized as days since epoch (e.g., 18628 for 2021-01-01) 
3974+ /// - The JSON schema includes: {"type":"date","initial-default":18628} 
3975+ /// 
3976+ /// Prior to this fix, Date values in JSON were only parsed from String format ("2021-01-01"), 
3977+ /// causing initial_default values to be lost during schema deserialization. 
3978+ /// 
3979+ /// This test ensures both formats are supported: 
3980+ /// - String format: "2021-01-01" (used in table metadata) 
3981+ /// - Number format: 18628 (used in initial-default values from add_files) 
3982+ /// 
3983+ /// See: Iceberg Java TestAddFilesProcedure.addDataPartitionedByDateToPartitioned() 
3984+ #[ test]  
3985+     fn  test_date_from_json_as_number ( )  { 
3986+         use  serde_json:: json; 
3987+ 
3988+         // Test Date as number (days since epoch) - used in initial-default from add_files 
3989+         let  date_number = json ! ( 18628 ) ;  // 2021-01-01 is 18628 days since 1970-01-01 
3990+         let  result =
3991+             Literal :: try_from_json ( date_number,  & Type :: Primitive ( PrimitiveType :: Date ) ) . unwrap ( ) ; 
3992+         assert_eq ! ( 
3993+             result, 
3994+             Some ( Literal :: Primitive ( PrimitiveLiteral :: Int ( 18628 ) ) ) 
3995+         ) ; 
3996+ 
3997+         // Test Date as string - traditional format 
3998+         let  date_string = json ! ( "2021-01-01" ) ; 
3999+         let  result =
4000+             Literal :: try_from_json ( date_string,  & Type :: Primitive ( PrimitiveType :: Date ) ) . unwrap ( ) ; 
4001+         assert_eq ! ( 
4002+             result, 
4003+             Some ( Literal :: Primitive ( PrimitiveLiteral :: Int ( 18628 ) ) ) 
4004+         ) ; 
4005+ 
4006+         // Both formats should produce the same Literal value 
4007+     } 
39574008} 
0 commit comments