feat: support PAGE_ROW_COUNT_LIMIT for parquet format - #226
Open
lucasfang wants to merge 5 commits into
Open
Conversation
lxy-9602
reviewed
Aug 20, 2026
zjw1111
reviewed
Aug 20, 2026
zjw1111
left a comment
Collaborator
There was a problem hiding this comment.
The <= 0 validation in 54dda55 looks good. One remaining point on the semantics of the new option: the row limit is best effort here, not the hard bound parquet-mr gives, and its granularity is currently tied to an unrelated option. Details inline.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
Linked issue: close #225
Support splitting Parquet data pages by row count, aligned with parquet-mr's
parquet.page.row.count.limit(PARQUET-1414). Previously the Parquet writer split pages only by byte size (parquet.page.size), so a single page could contain a very large number of rows, leading to coarse page-index filtering granularity, read amplification, and page layouts inconsistent with files written by the Java side. This PR introduces a row count limit (default 20000, same as parquet-mr); a page is finished when either the row count or the byte size limit is reached first.Changes:
cmake_modules/arrow.diff: patch arrow'sparquet::WriterPropertiesto add thedata_page_row_count_limitbuilder method, getter, and the constantDEFAULT_DATA_PAGE_ROW_COUNT_LIMIT = 20000; extend the page-split condition incolumn_writer.ccwith anum_buffered_rows_ >= properties_->data_page_row_count_limit()check in addition to the byte-size check.src/paimon/format/parquet/parquet_format_defs.h: add the table option keyPARQUET_PAGE_ROW_COUNT_LIMIT = "parquet.page.row.count.limit"(the key name is identical to parquet-mr's).src/paimon/format/parquet/parquet_writer_builder.cpp:PrepareWriterPropertiesreads the option and applies it to the arrowWriterProperties, falling back to the default 20000 when unset.src/paimon/format/parquet/parquet_format_writer_test.cpp: update theTestMemoryControlassertions — with the default row-count page split in effect, all-null pages are RLE-encoded and finish early, so the writer peak memory stays far below the budget; for the non-null case the budget upper bound is relaxed to 2.5x (the budget is mostly held as finished page buffers, which BufferedPageWriter copies into its in-memory sink when the row group is flushed, transiently doubling the footprint; ~2.2x measured).Note: the limit is checked at write batch granularity, so a page may exceed the limit by up to one write batch (unlike parquet-mr, which enforces the limit exactly).
Tests
ParquetWriterBuilderTest.DefaultPrepareWriterPropertiesadds a default-value assertion (data_page_row_count_limit == 20000);ParquetWriterBuilderTest.PrepareWriterPropertiesadds an assertion that the optionparquet.page.row.count.limit=40000is propagated.ParquetFormatWriterTest.TestMemoryControladapts the memory assertions to the new default page-split behavior.paimon-parquet-format-test187/187 passed,paimon-write-inte-test117/117 passed,paimon-read-inte-test278/278 passed.API and Format
No change to the public API under
include/. Adds the table optionparquet.page.row.count.limit(default 20000). The storage format stays compatible: only the data page layout of newly written files changes (more pages, bounded rows per page); no new format feature is introduced and older readers can read the files normally.Documentation
New table option
parquet.page.row.count.limit: a best-effort limit on the number of rows in a single data page, aligned with parquet-mr's option of the same name (PARQUET-1414), default 20000; a page is finished when either this row count or the byte size (parquet.page.size) is reached first. Unlike parquet-mr, which enforces the limit exactly, the limit here is only checked at write-batch granularity, so a page may exceed it by up to one write batch (e.g., with the default limit 20000 and the default write batch size 1024, a page holds at most 20480 rows).Generative AI tooling
Generated-by: Qoder