Skip to content

fix date as parition key parsing issue - #869

Open
yyangAtlassian wants to merge 1 commit into
apache:mainfrom
atlassian-forks:fix/paimon-date-partition-delta-conversion
Open

fix date as parition key parsing issue#869
yyangAtlassian wants to merge 1 commit into
apache:mainfrom
atlassian-forks:fix/paimon-date-partition-delta-conversion

Conversation

@yyangAtlassian

Copy link
Copy Markdown

Important Read

  • Please ensure the GitHub issue is mentioned at the beginning of the PR
    PDP side test is in AppendChangelogXTableConversionIT which expose the bit and thus end up with dt as STRING to by pass it. (not a blocker)

What is the purpose of the pull request

(For example: This pull request implements the sync for delta format.)

Brief change log

(for example:)

  • Fixed JSON parsing error when persisting state
  • Added unit tests for schema evolution

Verify this pull request

(Please pick either of the following options)

This pull request is a trivial rework / code cleanup without any test coverage.

(or)

This pull request is already covered by existing tests, such as (please describe tests).

(or)

This change added tests and can be verified as follows:

(example:)

  • Added integration tests for end-to-end.
  • Added TestConversionController to verify the change.
  • Manually verified the change by running a job locally.

* InternalRowPartitionComputer.generatePartValues}). This helper accepts both so the DATE
* partition case no longer fails with a {@link ClassCastException}.
*/
private static String convertDatePartitionValueToString(Object value) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it make sense to fix this on the Paimon side rather than in the Delta sink?

From what I can tell, PaimonPartitionExtractor.toPartitionValues wraps the raw Map<String, String> from generatePartValues in Range.scalar(...) without consulting the field's InternalType, so values arrive as Strings for every type -- DATE just happens to be the one that fails loudly. If that reading is right, Paimon -> Iceberg with a DATE partition and any INT / LONG / BOOLEAN partition key would still be wrong after this change, only quietly.

PathBasedPartitionValuesExtractor.parseValue already does that string-to-InternalType switch, so perhaps it could be shared? I may well be missing a reason the conversion has to happen at the sink -- if so, a note in the description would help.

try {
return LocalDate.parse(stringValue).toString();
} catch (DateTimeParseException ex) {
return LocalDate.ofEpochDay(Long.parseLong(stringValue)).toString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am a little wary of this fallback. "2019" would parse as epoch-day 2019 and be written as 1975-07-14, and "20191012" as year 57786 -- a wrong partition value in the Delta log rather than an error, which is hard to spot later.

Also, when both parses fail this surfaces a raw NumberFormatException rather than the NotSupportedException used just below. I believe Paimon's __DEFAULT_PARTITION__ null-partition sentinel would reach that path.

Would you be open to dropping the numeric branch and throwing a domain exception on DateTimeParseException, plus handling the null sentinel explicitly? Hudi's path-based extractor maps __HIVE_DEFAULT_PARTITION__ to null, so there may be a pattern worth following.

*/
@ParameterizedTest
@MethodSource("datePartitionValues")
void convertDatePartitionValueAcrossSourceRepresentations(Object value, String expected) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for adding coverage here. My worry is that testing the converter in isolation would not fail if the source-side representation is the underlying issue, and it would not reach the Paimon -> Iceberg path.

Would it be possible to also add a DATE case to TestPaimonPartitionExtractor (it only covers a STRING key today), and an end-to-end Paimon -> Delta case with a DATE partition column? I noticed the description mentions the PDP-side test declares dt as STRING to work around this, which seems like the case most worth pinning down.

@MethodSource("datePartitionValues")
void convertDatePartitionValueAcrossSourceRepresentations(Object value, String expected) {
// Epoch day 18181 == "2019-10-12". Integer form is produced by the Iceberg/Delta sources; the
// String form is produced by the Paimon source (InternalRowPartitionComputer.generatePartValues).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Minor: spotless:check looks like it fails on this file -- lines 81, 82 and 91 are over the 100-column limit. I ran mvn -pl xtable-core spotless:check locally to confirm. mvn spotless:apply should sort it out.

@vinishjail97

Copy link
Copy Markdown
Contributor

@yyangAtlassian Can you create a GH issues as well if possible with the exception you hit? It would be useful for the community users.

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.

2 participants