This is an automated email from the ASF dual-hosted git repository.
laskoviymishka pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-rust.git
The following commit(s) were added to refs/heads/main by this push:
new d05d56645 fix: mark _row_id and _last_updated_sequence_number optional
(#2959)
d05d56645 is described below
commit d05d56645979804c659aa265f6041d93ea0e6557
Author: Anoop Johnson <[email protected]>
AuthorDate: Wed Aug 5 01:27:41 2026 -0700
fix: mark _row_id and _last_updated_sequence_number optional (#2959)
The two v3 row-lineage metadata columns were defined as required, but the
spec requires readers to produce null for both in legitimate cases: when a
data file has a null first_row_id (spec Row Lineage), and for added or
modified rows before inheritance. Iceberg Java marks both
NestedField.optional accordingly.
Mark both fields optional to match. This is a prerequisite for
materializing the columns on read, where a null result must be
representable.
---
crates/iceberg/src/metadata_columns.rs | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/crates/iceberg/src/metadata_columns.rs
b/crates/iceberg/src/metadata_columns.rs
index d95b075be..aed418325 100644
--- a/crates/iceberg/src/metadata_columns.rs
+++ b/crates/iceberg/src/metadata_columns.rs
@@ -224,7 +224,7 @@ static COMMIT_SNAPSHOT_ID_FIELD: Lazy<NestedFieldRef> =
Lazy::new(|| {
/// This field represents a unique long assigned for row lineage.
static ROW_ID_FIELD: Lazy<NestedFieldRef> = Lazy::new(|| {
Arc::new(
- NestedField::required(
+ NestedField::optional(
RESERVED_FIELD_ID_ROW_ID,
RESERVED_COL_NAME_ROW_ID,
Type::Primitive(PrimitiveType::Long),
@@ -237,7 +237,7 @@ static ROW_ID_FIELD: Lazy<NestedFieldRef> = Lazy::new(|| {
/// This field represents the sequence number which last updated this row.
static LAST_UPDATED_SEQUENCE_NUMBER_FIELD: Lazy<NestedFieldRef> = Lazy::new(||
{
Arc::new(
- NestedField::required(
+ NestedField::optional(
RESERVED_FIELD_ID_LAST_UPDATED_SEQUENCE_NUMBER,
RESERVED_COL_NAME_LAST_UPDATED_SEQUENCE_NUMBER,
Type::Primitive(PrimitiveType::Long),
@@ -601,6 +601,15 @@ mod tests {
assert!(get_metadata_field(RESERVED_FIELD_ID_LAST_UPDATED_SEQUENCE_NUMBER).is_ok());
}
+ #[test]
+ fn test_row_lineage_metadata_fields_are_optional() {
+ // The spec requires readers to produce null for these columns in
+ // legitimate cases (e.g. a data file with a null first_row_id), so the
+ // fields must be optional rather than required.
+ assert!(!row_id_field().required);
+ assert!(!last_updated_sequence_number_field().required);
+ }
+
#[test]
fn test_data_table_metadata_columns() {
// Both sides of the data-table metadata check (name and field id)
must accept