Skip to content

fix(parquet): add reader option for unknown physical/logical type combos - #11017

Open
M-Tesla wants to merge 2 commits into
apache:mainfrom
M-Tesla:fix-10941-unknown-type-combo
Open

fix(parquet): add reader option for unknown physical/logical type combos#11017
M-Tesla wants to merge 2 commits into
apache:mainfrom
M-Tesla:fix-10941-unknown-type-combo

Conversation

@M-Tesla

@M-Tesla M-Tesla commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

parquet-format GH-607 says readers must handle unknown physical and logical type combinations (for example INT32 annotated as UUID) by treating them as an unknown logical type.

This crate currently errors in Type construction (Cannot annotate Uuid from INT32). @alamb asked for a reader option rather than changing the default.

What changes are included in this PR?

  • Default behavior is unchanged: incompatible combinations still error.
  • New option with_coerce_incompatible_logical_types(true) on ArrowReaderOptions, ReadOptionsBuilder, and ParquetMetaDataOptions.
  • With the option, the logical type is rewritten to _Unknown with sort order UNDEFINED. Column statistics are retained so callers who care can ignore them or use them with out-of-band type info.
  • Writer-side Type::build() still rejects the combination. Round-trip of the invalid annotation is out of scope, as noted in the issue.
  • Malformed known annotations (UUID on FLBA of the wrong length, List on a primitive) still error even with the option.

Are these changes tested?

  • Schema parse: INT32+UUID errors by default, coerces to _Unknown / UNDEFINED with the option. INT64+UUID and BYTE_ARRAY+UUID also get UNDEFINED rather than UNSIGNED or SIGNED. UUID FLBA(15) and List-on-primitive still error with the option.
  • End to end: int32_with_uuid_logical_type.parquet from parquet-testing. Default reader errors. With the option, the column reads as Arrow Int32 values 0 through 9, sort order is UNDEFINED, and column statistics are present.

cargo test -p parquet --lib --tests --bins. cargo clippy -p parquet --all-targets -- -D warnings.

Are there any user-facing changes?

Additive reader option. Default remains an error. No breaking API change.

AI Disclosure

Assisted with the option plumbing, GH-607 coerce path, and regression tests. Default stays an error per the issue discussion. Reviewed and verified with the checks above.

parquet-format apacheGH-607 requires readers to treat unrecognized physical and
logical type combinations as an unknown logical type. Keep the historical
error as the default, and add a reader option that exposes the physical
type and ignores column statistics.
@etseidl etseidl added the parquet Changes to the parquet crate label Sep 8, 2026

@etseidl etseidl 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.

Thanks @M-Tesla, but I think this might want some more discussion on the issue before diving into an implementation. I myself am not entirely certain what should be done in this case. I'm not particularly keen on returning None for the column statistics (and I think this change has no impact on stats in the column index). Perhaps changing the logical type to _Unknown and ensuring the sort order comes back as UNDEFINED would suffice. Consumers who care could then ignore the stats, or use them anyway if they have out-of-band info about the real type.

Comment thread parquet/src/arrow/arrow_reader/mod.rs Outdated
}

fn parquet_file_with_int32_uuid_logical_type() -> Vec<u8> {
let field = Type::primitive_type_builder("id", PhysicalType::INT32)

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.

We could instead use the file added in apache/parquet-testing#122

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you, that is a better fixture. I will switch the test to int32_with_uuid_logical_type.parquet from that parquet-testing PR.

@M-Tesla

M-Tesla commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for the review, @etseidl. I really appreciate you taking the time, especially while this behavior is still being settled.

I'll follow the approach you outlined:

  • Keep the incompatible logical type as _Unknown instead of stripping it to None
  • Leave column statistics in place, so callers can ignore them or use them if they have out-of-band type information
  • Use UNDEFINED for the sort order (the SIGNED placeholder in BasicTypeInfo was only a dummy before recomputing sort order, and I agree that is the wrong default)
  • Switch the test over to the parquet-testing file from Add file with an incompatible logical/physical type combination parquet-testing#122

I'll keep the reader option with the current default (error), matching what @alamb suggested on the issue, and I will post a short note there as well so the discussion lives with the spec question.

Thank you again for the guidance. I'll update the PR along these lines.

Keep column statistics, switch tests to the parquet-testing INT32+UUID
file, and compute sort order from _Unknown instead of a SIGNED placeholder.
@M-Tesla

M-Tesla commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @etseidl. I switched the coerce path to _Unknown with sort order UNDEFINED, kept column statistics, and moved the tests onto int32_with_uuid_logical_type.parquet from parquet-testing #122.

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

Labels

parquet Changes to the parquet crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parquet reader does not support unknown physical/logical type combinations per GH-607

2 participants