Skip to content

Parquet sink coverage tails: INT96, nested types, local-timezone timestamps, auto-compaction, encoder memory accounting #20

Description

@jordepic

The native Parquet sink (encoding-only native, Flink owns IO/commit — divergences/22) honors the filesystem+parquet config surface 1:1 or falls back with a recorded reason (docs/coverage-and-fallbacks.md §5). These are the remaining fallback causes worth removing, roughly by value:

  • INT96 timestamps (the biggest: Flink's default timestamp encoding, so any timestamp-bearing table without parquet.write.int64.timestamp=true falls back). arrow-rs's ArrowWriter cannot write INT96 — its schema converter never targets it and a forced descriptor panics at write_leaf — but the low-level layer can (Int96ColumnWriter supports write_batch, statistics, and dictionaries). Since the sink already restricts itself to flat schemas, def-levels are trivial (validity bitmap), so a hand-rolled SerializedFileWriter path for INT96-bearing tables is feasible. Value layout is 12 bytes LE: nanos-of-day (8) + Julian day (4), floor semantics like the INT64 path.
  • Nested written columns (ARRAY/MAP/MULTISET/ROW): needs group-encoding parity verification against Flink's ParquetSchemaConverter (3-level lists with element, key_value maps with non-null keys that throw on null at write, MULTISET as map-to-INT32-count) plus forced descriptors for nested decimals.
  • parquet.utc-timezone=false timestamps (also a default): Flink shifts values through the JVM's local timezone via TimestampData.toTimestamp(). A chrono-tz implementation behind allowIncompatible would follow the divergences/17 precedent (tzdb-skew edges are why it must be gated).
  • auto-compaction=true: Flink swaps in a different DAG (CompactCoordinator/CompactOperator). Either reuse those operators verbatim around the native writer (the divergences/22 pattern) or decline forever and document.
  • Encoder memory accounting: each open bucket buffers an in-progress row group (up to parquet.block.size) in native memory, currently untracked by ManagedMemoryBudget. Same order as the host's parquet-mr heap buffering, but partitioned tables multiply it by active buckets per subtask.

The strict INT96/utc-timezone gates were a deliberate decision: physical-encoding differences a reader can observe fall back rather than silently diverge.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions