@@ -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