-
Notifications
You must be signed in to change notification settings - Fork 1.5k
GH-2992: Gate LocalTimestamp references in AvroSchemaConverter #2993
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -22,6 +22,7 @@ | |||||||||||||
| import static java.util.Optional.of; | ||||||||||||||
| import static org.apache.parquet.avro.AvroReadSupport.READ_INT96_AS_FIXED; | ||||||||||||||
| import static org.apache.parquet.avro.AvroReadSupport.READ_INT96_AS_FIXED_DEFAULT; | ||||||||||||||
| import static org.apache.parquet.avro.AvroRecordConverter.getRuntimeAvroVersion; | ||||||||||||||
| import static org.apache.parquet.avro.AvroWriteSupport.WRITE_FIXED_AS_INT96; | ||||||||||||||
| import static org.apache.parquet.avro.AvroWriteSupport.WRITE_OLD_LIST_STRUCTURE; | ||||||||||||||
| import static org.apache.parquet.avro.AvroWriteSupport.WRITE_OLD_LIST_STRUCTURE_DEFAULT; | ||||||||||||||
|
|
@@ -488,15 +489,20 @@ private LogicalTypeAnnotation convertLogicalType(LogicalType logicalType) { | |||||||||||||
| return timeType(true, MICROS); | ||||||||||||||
| } else if (logicalType instanceof LogicalTypes.TimestampMillis) { | ||||||||||||||
| return timestampType(true, MILLIS); | ||||||||||||||
| } else if (logicalType instanceof LogicalTypes.LocalTimestampMillis) { | ||||||||||||||
| return timestampType(false, MILLIS); | ||||||||||||||
| } else if (logicalType instanceof LogicalTypes.TimestampMicros) { | ||||||||||||||
| return timestampType(true, MICROS); | ||||||||||||||
| } else if (logicalType instanceof LogicalTypes.LocalTimestampMicros) { | ||||||||||||||
| return timestampType(false, MICROS); | ||||||||||||||
| } else if (logicalType.getName().equals(LogicalTypes.uuid().getName()) && writeParquetUUID) { | ||||||||||||||
| return uuidType(); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if (avroVersionSupportsLocalTimestampTypes()) { | ||||||||||||||
| if (logicalType instanceof LogicalTypes.LocalTimestampMillis) { | ||||||||||||||
| return timestampType(false, MILLIS); | ||||||||||||||
| } else if (logicalType instanceof LogicalTypes.LocalTimestampMicros) { | ||||||||||||||
| return timestampType(false, MICROS); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| return null; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -538,7 +544,7 @@ public Optional<LogicalType> visit( | |||||||||||||
| LogicalTypeAnnotation.TimeUnit unit = timestampLogicalType.getUnit(); | ||||||||||||||
| boolean isAdjustedToUTC = timestampLogicalType.isAdjustedToUTC(); | ||||||||||||||
|
|
||||||||||||||
| if (isAdjustedToUTC) { | ||||||||||||||
| if (isAdjustedToUTC || !avroVersionSupportsLocalTimestampTypes()) { | ||||||||||||||
| switch (unit) { | ||||||||||||||
| case MILLIS: | ||||||||||||||
| return of(LogicalTypes.timestampMillis()); | ||||||||||||||
|
|
@@ -605,4 +611,14 @@ private static String namespace(String name, Map<String, Integer> names) { | |||||||||||||
| Integer nameCount = names.merge(name, 1, (oldValue, value) -> oldValue + 1); | ||||||||||||||
| return nameCount > 1 ? name + nameCount : null; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /* Avro <= 1.9 does not support conversions to LocalTimestamp{Micros, Millis} classes */ | ||||||||||||||
| private static boolean avroVersionSupportsLocalTimestampTypes() { | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think of mocking this method to capture the behavior of supporting and not-supporting local timestamps.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll give it a try with Powermock! I might start a thread on the mailing list this week discussing Avro version support more broadly, to formalize which Avro versions are currently supported/any planned EOL dates? I've been thinking it would also be good to have some automated testing of parquet-avro on different Avro versions... it would just be a little complicated to set up since we'd need either a separate Maven module per supported Avro version, or some very clever classloading :)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey @clairemcginty, that's a good idea! What do we consider the lower-bound? :D Avro 1.8.2 is May 2017, so that's pretty old, but I'm aware of some breaking API changes because we exposed some Jackson classes in the public API. To do cross-testing, we can do something similar to we do with Hadoop 2, you can get some inspiration there: Lines 638 to 643 in d4384d3
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think 1.8 is a reasonable lower bound! for context on our use case, we use the Beam library, which until very recently was tightly coupled with 1.8. Things are now more flexible, but there's a lot of inertia surrounding 1.8 -- the breaking changes surrounding logical types make it a non-trivial upgrade 😅 I'll take a look at the hadoop setup! Avro is a bit tricky because we need to both set the Avro-compiler version, and load the Avro core library, for whatever version of Avro we want to test...
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the context, that helps. I see that 1.8.2 is still in there, so that sounds reasonable to me 👍 |
||||||||||||||
| final String avroVersion = getRuntimeAvroVersion(); | ||||||||||||||
|
|
||||||||||||||
| return avroVersion == null | ||||||||||||||
| || !(avroVersion.startsWith("1.7.") | ||||||||||||||
| || avroVersion.startsWith("1.8.") | ||||||||||||||
| || avroVersion.startsWith("1.9.")); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.