| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Implements a true page-level Arrow-to-Parquet writer that bypasses the RecordConsumer/ColumnWriter pipeline entirely, writing pages directly to PageWriter. Architecture: - ArrowParquetWriter: manages ParquetFileWriter, row groups, and per-column strategy selection - ArrowColumnWriter: strategy interface for per-column writing - ArrowColumnWriterFactory: selects optimal strategy based on column type, nullability, and encoding - ZeroCopyPlainWriter: wraps Arrow data buffer directly as page BytesInput (zero copy for non-null fixed-width PLAIN columns) - NullablePlainWriter: scans validity bitmap, bulk-copies non-null runs, encodes definition levels as RLE runs - LevelEncoder: produces RLE-encoded repetition/definition levels - StatsComputer: computes page statistics from Arrow buffers in a single sequential scan For non-null INT32 columns, this writer performs ZERO per-value method calls. The Arrow buffer bytes ARE the Parquet page bytes. Phase 1 scope: flat schemas, fixed-width types (INT32, INT64, FLOAT, DOUBLE, FIXED_LEN_BYTE_ARRAY), PLAIN encoding. Variable-width types and dictionary encoding are future phases. Closes apache#3733
| Back | FazBrowse Home | New Git URL |
Summary
Adds ArrowParquetWriter to the parquet-arrow module — a page-level writer that accepts Arrow VectorSchemaRoot batches and produces valid Parquet files without per-row object construction.
Closes #3733. Related: #2264, #3353.
Motivation
Multiple downstream projects (Iceberg #17748, Fluss #4047, Paimon) work with Arrow-columnar data internally but must materialize row objects to write Parquet via ParquetWriter<T>.write(T). This PR provides a direct Arrow-to-Parquet path, eliminating the row-object API mismatch. Arrow C++/Python have had this since write_table().
Design
Bypasses RecordConsumer/ColumnWriter entirely. Writes assembled pages directly to PageWriter with per-column strategy selection:
Does not extend ParquetWriter<T> because write(T) increments an internal record count by 1 per call, incompatible with batch semantics.
Key properties
Types supported
INT32, INT64, FLOAT, DOUBLE, BOOLEAN, BINARY (string), FIXED_LEN_BYTE_ARRAY — nullable and required.
Not included (follow-up PRs)
Relationship to #3530 (Performance Improvements series)
This PR is complementary to the encoding-level optimizations in #3530. Specifically:
Statistics: irreducible O(N) scan
The stats scan (min/max/NaN count) is the minimum work required to produce a valid Parquet file with predicate pushdown support. For the zero-copy path, it is the ONLY per-value work performed. Future optimizations possible:
Tests
10 round-trip tests (write via ArrowParquetWriter, read via standard ParquetReader):
Dependencies added
Discussion point
Adding parquet-hadoop as a compile dependency to parquet-arrow increases the module's dependency footprint. ParquetFileWriter and ColumnChunkPageWriteStore exist only in parquet-hadoop — no alternative implementations. Every Java Parquet writer (Iceberg, Spark, Flink) depends on parquet-hadoop. Alternative: create a new parquet-arrow-hadoop module. Open to guidance.
How to run tests