Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PARQUET-2473: Clarify records can not be split across v2 pages or PageIndex #244

Merged
merged 2 commits into from
May 31, 2024

Conversation

alamb
Copy link
Contributor

@alamb alamb commented May 19, 2024

This was sparked by a mailing list discussion: https://lists.apache.org/thread/rd8twnvg4bg3558r507rzpxckcxt5wdn

Several implementors of the Parquet spec have been confused by this point

Notes

There seems to be clear consensus that record boundaries can't span pages in V2 pages or if there is a page index, so let's make that clear in the spec to avoid future confusion

There also seemed to be consensus that Row Groups must start on record boundaries, and that the existing spec language was clear on this point, so I did not propose any changes to that language

https://issues.apache.org/jira/browse/PARQUET-2473

Jira

Commits

  • My commits all reference Jira issues in their subject lines. In addition, my commits follow the guidelines from "How to write a good git commit message":
    1. Subject is separated from body by a blank line
    2. Subject is limited to 50 characters (not including Jira issue reference)
    3. Subject does not end with a period
    4. Subject uses the imperative mood ("add", not "adding")
    5. Body wraps at 72 characters
    6. Body explains "what" and "why", not "how"

Documentation

This PR is only a clarification

  • In case of new functionality, my PR adds documentation that describes how to use it.
    • All the public functions and the classes in the PR contain Javadoc that explain what it does

@alamb alamb changed the title PARQUET-2473: Clarify records can not be split across boundaries for "v2 data pages" or if there is a page index PARQUET-2473: Clarify records can not be split across v2 pages or PageIndex May 19, 2024
@@ -625,7 +631,11 @@ struct DataPageHeaderV2 {
/** Number of NULL values, in this data page.
Number of non-null = num_values - num_nulls which is also the number of values in the data section **/
2: required i32 num_nulls
/** Number of rows in this data page. which means pages change on record boundaries (r = 0) **/
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I also propose expanding the r = 0 terminology to be explicitly repetition_level = 0 to match the conventions in the rest of the documentation

Copy link
Member

@mapleFU mapleFU left a comment

Choose a reason for hiding this comment

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

LGTM, just a nit

src/main/thrift/parquet.thrift Outdated Show resolved Hide resolved
*
* If a ColumnIndex is present, a page must begin at a record
* boundary (repetition_level = 0). Otherwise, pages may begin
* within a record (repetition_level > 0).
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we could instead state that records should not be split across pages, but that readers should tolerate this in the abscence of a page index or v2 data pages, as certain writers historically wrote such data?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with you that splitting pages will make the file less compatible, even though some writers historically did that.

However, I would like to ensure there is consensus on updating the spec to say that writers should do something before changing the spec

@alamb
Copy link
Contributor Author

alamb commented May 22, 2024

Updated to clarify that records can't repeat when an OffsetIndex is present

/**
* Number of values, including NULLs, in this data page.
*
* If a OffsetIndex is present, a page must begin at a record
Copy link
Member

Choose a reason for hiding this comment

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

Can we unify the row/record terminology? They seem to mean the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree row/record seem to mean the same thing

I double checked and it appears the rest of the file is inconsistent in the terminology as well

For example the repetition level documentation refers to records

/**
* Representation of Schemas
*/
enum FieldRepetitionType {
/** This field is required (can not be null) and each record has exactly 1 value. */
REQUIRED = 0;
/** The field is optional (can be null) and each record has 0 or 1 values. */
OPTIONAL = 1;
/** The field is repeated and can contain 0 or more values */
REPEATED = 2;
}

but there are several fields that are named num_rows that clearly refer to rows.

/** Number of values, including NULLs, in this data page. **/
1: required i32 num_values
/** Number of NULL values, in this data page.
Number of non-null = num_values - num_nulls which is also the number of values in the data section **/
2: required i32 num_nulls
/** Number of rows in this data page. which means pages change on record boundaries (r = 0) **/
3: required i32 num_rows
/** Encoding used for data in this page **/
4: required Encoding encoding

In this PR I followed the term used in the repetition level documentation as I think it is the most relevant.

I will start a conversation on the mailing list about using consistent terminology

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mailing list conversation: https://lists.apache.org/thread/0gxjk4tphxls0gcrc7lt775pf8s7gtz3

Currently the consensus seems to be to use "row"

I will make a follow on PR to change that terminology after this PR is merged.

I would like to retain the "record" terminology here to remain consistent with the current wording in the repetition levels section

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/**
* Number of rows in this data page. Every page must begin at a
* record boundary (repetition_level = 0): records must **not** be
* split across page boundaries when using V2 data pages.
Copy link
Member

Choose a reason for hiding this comment

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

So a row is a record?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

@alamb
Copy link
Contributor Author

alamb commented May 31, 2024

I think this PR is now ready to go @wgtmac . Is there anything else we are waiting on?

Copy link
Member

@wgtmac wgtmac left a comment

Choose a reason for hiding this comment

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

Sorry for missing this. I'll merge it now.

@wgtmac wgtmac merged commit 38c108c into apache:master May 31, 2024
3 checks passed
@alamb
Copy link
Contributor Author

alamb commented May 31, 2024

Sorry for missing this. I'll merge it now.

No worries -- thank you!

I'll file a JIRA shortly to improve the spec to use row terminology

@alamb alamb deleted the alamb/clarify_reptition_levels branch May 31, 2024 15:38
@alamb
Copy link
Contributor Author

alamb commented May 31, 2024

Update: here is a PR to consistently use the "row" terminology: #256

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants