Skip to content

[FEATURE][Java] Adapt Parquet physical IO to columnar batches #964

Closed

Description

@keksmd

Describe the enhancement requested

After #959 / PR #961 replaces the provisional row-oriented physical-batch contract with
column vectors, the Parquet backend needs the corresponding adapter migration. This issue is one
narrow downstream slice: it must not retain a compatibility Row facade.

Scope:

  • migrate graphar-io-api read-contract tests and graphar-io-parquet from
    RecordBatch.row(int) / Row to ValueVector and VectorRecordBatch;
  • preserve physical projection, strict half-open row-range reads, and required Parquet Offset Index
    behavior;
  • preserve safe binary/list/null value ownership at the vector boundary;
  • treat WriteMode.APPEND explicitly: Parquet cannot atomically append to one existing file, so the
    writer must reject it rather than silently overwriting.

Non-goals: migrating GraphAr reader/writer/validator/integration consumers (separate dependent
slices); adding Apache Arrow as a dependency; changing the Parquet decoding algorithm; or making
Parquet append work through a hidden rewrite.

Acceptance evidence:

  1. no Row or .row(...) reference remains in io-api / io-parquet;
  2. focused clean verification covers vector schema position, count, null, binary and list values;
  3. canonical fixture projection/row-range tests retain applied PROJECTION and ROW_RANGE;
  4. writer still emits readable Offset Indexes with the existing bounded-page assertion;
  5. a write with APPEND is explicitly rejected, never treated as overwrite.

Component(s): Java

Relates to #947 and #959.

Activity

  1. keksmd commented on Sep 8, 2026

    @keksmd
    ContributorAuthor

    Status and the exact gate on this slice.

    The module is ready in migrated form — no `Row` and no `.row(...)` anywhere in it; batches are `ValueVector` / `VectorRecordBatch`, and `ParquetRow` is replaced by `ParquetValueVector`. I verified it compiles and tests clean against main plus the read contract from #972:

    graphar-io-parquet ................................. SUCCESS
    ParquetPhysicalReaderFixtureTest      Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
    ParquetPhysicalWriterOffsetIndexTest  Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
    ParquetPhysicalIoEfficiencyTest       Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
    ParquetListRoundTripTest              Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
    

    It cannot be opened as a PR against main today, and the reason is a real dependency, not polish: the reader side uses PhysicalReader, ReadRequest, ReadResult, ReadReport, Projection, RowRange, Filter, Literal and ComparisonOperator, and none of those exist on main yet — they are #971 and #972. Basing this PR on an unmerged branch would make a dependent chain, so I would rather wait: once #971 and #972 land, this goes up as a standalone PR cut from main the same day.

    Ordering for the remaining Java SDK slices, so nobody has to reconstruct it from the PR queue:

    core            #967 -> PR #968   (open, mergeable, CI green)
    io-api reads    #971, #972        (open, mergeable, CI green)
    io-parquet      #964              (ready; gated on #971 and #972)
    writer          #973              (needs core + a format backend)
    validator       #974              (needs core + backend + writer)
    

    @SemyonSinchenko @SYaoJun review bandwidth on #971 and #972 would unblock the format backend, which is the layer that makes the storage work merged so far actually readable end to end.

  2. keksmd commented on Sep 9, 2026

    @keksmd
    ContributorAuthor

    Status after #968 landed: this is now the single gate for everything else in the Java SDK — the reader, the writer (#973) and the validator (#974) all verify their output by reading it back through a Parquet backend.

    Its remaining dependencies are #971 and #972 (ReadRequest, PhysicalReader, ReadReport). Both are green and rebased on current main, waiting on review. I am holding this PR until they merge rather than opening a third link in a chain; the branch is ready and builds against main plus those two.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions