Skip to content

Missing validation for reserved sort order ID 0 during metadata JSON parsing #1963

@yshcz

Description

@yshcz

Apache Iceberg Rust version

None

Describe the bug

The spec reserved order-id: 0 for the unsorted order, but iceberg-rust parser incorrectly accepts order-id: 0 with arbitrary fields set.

Unlike other metadata validations (schema, partition spec, snapshots), this constraint is not enforced during JSON parsing, though SortOrderBuilder::build_unbound() does validate it.

This seems like a simple oversight. adding similar validation in TableMetadata::try_normalize_sort_order() should fix it.

To Reproduce

#[test]
fn test_invalid_sort_order_id_zero_with_fields() {
    let metadata = r#"
    {
        "format-version": 2,
        "table-uuid": "9c12d441-03fe-4693-9a96-a0705ddf69c1",
        "location": "s3://bucket/test/location",
        "last-sequence-number": 111,
        "last-updated-ms": 1600000000000,
        "last-column-id": 3,
        "current-schema-id": 1,
        "schemas": [
            {
                "type": "struct",
                "schema-id": 1,
                "fields": [
                    {"id": 1, "name": "x", "required": true, "type": "long"},
                    {"id": 2, "name": "y", "required": true, "type": "long"}
                ]
            }
        ],
        "default-spec-id": 0,
        "partition-specs": [{"spec-id": 0, "fields": []}],
        "last-partition-id": 999,
        "default-sort-order-id": 0,
        "sort-orders": [
            {
                "order-id": 0,
                "fields": [
                    {
                        "transform": "identity",
                        "source-id": 1,
                        "direction": "asc",
                        "null-order": "nulls-first"
                    }
                ]
            }
        ],
        "properties": {},
        "current-snapshot-id": -1,
        "snapshots": []
    }
    "#;

    let result: Result<TableMetadata, serde_json::Error> = serde_json::from_str(metadata);

    // BUG: This should fail but currently succeeds.
    assert!(
        result.is_ok(),
        "BUG: Parsing should fail for sort order ID 0 with fields, but currently succeeds"
    );

    let table_metadata = result.unwrap();
    let sort_order = table_metadata.sort_order_by_id(0).unwrap();
    assert!(
        !sort_order.fields.is_empty(),
        "BUG: Sort order 0 should not have fields per spec"
    );
}

Expected behavior

Invalid metadata should be reject

Willingness to contribute

None

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions