Skip to content

fix(spec): use canonical fixed[N] type string in PrimitiveType Display#2798

Open
laskoviymishka wants to merge 1 commit into
apache:mainfrom
laskoviymishka:fix-fixed-type-display
Open

fix(spec): use canonical fixed[N] type string in PrimitiveType Display#2798
laskoviymishka wants to merge 1 commit into
apache:mainfrom
laskoviymishka:fix-fixed-type-display

Conversation

@laskoviymishka

@laskoviymishka laskoviymishka commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

  • N/A — trivial spec-conformance fix. Happy to file a tracking issue if preferred.

What changes are included in this PR?

PrimitiveType's Display impl emitted fixed(N) (parentheses), diverging from the
canonical Iceberg type string fixed[N] (square brackets) used everywhere else:

  • the serde path — serialize_fixed already emits fixed[{value}] and
    deserialize_fixed parses fixed[;
  • the reference implementations — iceberg-java (Types.FixedType.toString()) and
    iceberg-go (FixedType.String()) both use fixed[N], as does PyIceberg.

Fixed was the only Display arm inconsistent with its own serialized form
(Decimal, for comparison, matches: decimal(p, s) in both). The likely origin was
a copy of the decimal(...) paren style.

This PR:

  • changes the Display arm to fixed[{size}];
  • adds test_primitive_type_display, a table-driven test over every PrimitiveType
    variant that pins all three directions — Display, Serialize, and
    Deserialize — to the same canonical string, so this class of drift is caught in
    future.

No behavioral impact on any wire/interop path: the serde (de)serialization was already
correct, and Display has no FromStr counterpart — its output is consumed only in
diagnostic/error strings. This is purely a bug fix, not a format change to persisted data.

Are these changes tested?

Yes. New unit test test_primitive_type_display in
crates/iceberg/src/spec/datatypes.rs asserts, for every primitive variant (including
Fixed(4), the Fixed(0) edge case, and Decimal boundary values):

  1. Display emits the canonical string (fixed[4], not fixed(4));
  2. Serialize produces the same string;
  3. Deserialize round-trips it back to the original type.

The pre-existing fixed(N) bug was invisible precisely because the serde path was
already correct — no round-trip test exercised Display directly. This test closes
that gap. Verified locally: cargo test -p iceberg spec::datatypes (12 pass),
cargo fmt --check, and cargo clippy all clean.

`Display` emitted `fixed(N)`, diverging from the canonical `fixed[N]`
used by the serde path and the Go/Java references. Align Display and add
a regression test pinning Display/Serialize/Deserialize to one string.
@laskoviymishka laskoviymishka marked this pull request as ready for review July 10, 2026 19:21

@huan233usc huan233usc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants