Skip to content

Commit 57f6a94

Browse files
committed
date32 from number not just string date
1 parent d3d3127 commit 57f6a94

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

crates/iceberg/src/spec/values.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)