Skip to content

Avro: read a file without avro.codec as uncompressed - #4296

Open
jatorre wants to merge 1 commit into
apache:mainfrom
jatorre:avro-missing-codec-is-null
Open

jatorre wants to merge 1 commit into
apache:mainfrom
jatorre:avro-missing-codec-is-null

Conversation

@jatorre

@jatorre jatorre commented Nov 6, 2026 •

Copy link
Copy Markdown

Closes #4295

Rationale for this change

AvroFileHeader.compression_codec() read a missing avro.codec entry as TableProperties.WRITE_AVRO_COMPRESSION_DEFAULT ("gzip"), an Iceberg property value rather than an Avro codec name, and raised Unsupported codec: gzip. The Avro specification makes null the default, so a file without the entry is uncompressed. iceberg-rust writes manifests that way (apache/iceberg-rust#3640), so PyIceberg could not scan a table with a snapshot committed from iceberg-rust.

The writer side (AvroOutputFile._write_header) is unchanged: it still writes the entry, mapping the Iceberg name to the Avro one.

Are these changes tested?

test_missing_codec_is_null in tests/avro/test_file.py (it fails on main with the error above). tests/avro/test_file.py and tests/avro/test_reader.py pass (41); ruff is clean. End to end: a table on a REST catalog whose second snapshot was committed from iceberg-rust (manifest without the entry). PyIceberg 0.12 as released raises Unsupported codec: gzip on scan(); with this one-line change applied to the installed 0.12 it reads all 3,000 rows.

Are there any user-facing changes?

Avro files without avro.codec are now read instead of refused.

AI disclosure: drafted with Claude Code (Claude Opus 5.5) at my direction; I ran the tests and ruff.

The Avro specification makes null the default codec. PyIceberg fell back to the Iceberg table
property default (gzip), which is not an Avro codec name, so it raised 'Unsupported codec: gzip' on
manifests written without the entry (iceberg-rust writes them so).

@AP24110011695 AP24110011695 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified locally (Windows, Python 3.12):

  • test_missing_codec_is_null and the existing codec tests pass on this branch.
  • On the pre-change code the same call raises ValueError: Unsupported codec: gzip — the fail-first claim reproduces exactly.
  • Checked all three WRITE_AVRO_COMPRESSION_DEFAULT fallback sites: the reader (AvroFileHeader.compression_codec) is the only one reading file metadata, where the Avro spec's null default is the correct semantic; the two writer sites (_write_header, AvroOutputFile.compression_codec) read write-task configuration, where the Iceberg property default is intentional — leaving them unchanged is right.
  • Blast radius is one line: files that have avro.codec take the same path as before.

Spec-based, minimal, tested, and unblocks iceberg-rust-written manifests (references apache/iceberg-rust#3640). Nice catch.

This branch has not been deployed

No deployments
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.

Avro reader treats a missing avro.codec as gzip and raises 'Unsupported codec: gzip'

2 participants