-
Notifications
You must be signed in to change notification settings - Fork 1.5k
PARQUET-1253: Support for new logical type representation #463
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
244bb6a
PARQUET-1253: Support for new logical type representation
nkollar 0a66346
refactor: move conversion logic to logical type classes
nkollar f8e2236
better (hopefully) name for new type
nkollar 6b4ff74
Address code review comments
nkollar f801605
Deprecate old constructors, address comment related to builder
nkollar db30adb
Address latest comments
nkollar 047feb9
Introduce type visitors for logical types, and address code review co…
nkollar d11a09c
Move factory methods to the interface for each logical type subclass
nkollar eb432f7
Incorporate new logical type parameters into schema language
nkollar 3c426d9
Address latest code review comments
nkollar 77f1d52
Make LogicalTypeToken enum and getType method package private
nkollar 6e1ea5d
Make typeParametersAsString package private
nkollar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Move factory methods to the interface for each logical type subclass
- Loading branch information
commit d11a09cd733faae7cdf6452459cd949efcffb453
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,63 +77,116 @@ static LogicalTypeAnnotation fromOriginalType(OriginalType originalType, Decimal | |
| } | ||
| switch (originalType) { | ||
| case UTF8: | ||
| return StringLogicalTypeAnnotation.create(); | ||
| return stringType(); | ||
| case MAP: | ||
| return MapLogicalTypeAnnotation.create(); | ||
| return mapType(); | ||
| case DECIMAL: | ||
| int scale = (decimalMetadata == null ? 0 : decimalMetadata.getScale()); | ||
| int precision = (decimalMetadata == null ? 0 : decimalMetadata.getPrecision()); | ||
| return DecimalLogicalTypeAnnotation.create(scale, precision); | ||
| return decimalType(scale, precision); | ||
| case LIST: | ||
| return ListLogicalTypeAnnotation.create(); | ||
| return listType(); | ||
| case DATE: | ||
| return DateLogicalTypeAnnotation.create(); | ||
| return dateType(); | ||
| case INTERVAL: | ||
| return IntervalLogicalTypeAnnotation.create(); | ||
| return intervalType(); | ||
| case TIMESTAMP_MILLIS: | ||
| return TimestampLogicalTypeAnnotation.create(true, LogicalTypeAnnotation.TimeUnit.MILLIS); | ||
| return timestampType(true, LogicalTypeAnnotation.TimeUnit.MILLIS); | ||
| case TIMESTAMP_MICROS: | ||
| return TimestampLogicalTypeAnnotation.create(true, LogicalTypeAnnotation.TimeUnit.MICROS); | ||
| return timestampType(true, LogicalTypeAnnotation.TimeUnit.MICROS); | ||
| case TIME_MILLIS: | ||
| return TimeLogicalTypeAnnotation.create(true, LogicalTypeAnnotation.TimeUnit.MILLIS); | ||
| return timeType(true, LogicalTypeAnnotation.TimeUnit.MILLIS); | ||
| case TIME_MICROS: | ||
| return TimeLogicalTypeAnnotation.create(true, LogicalTypeAnnotation.TimeUnit.MICROS); | ||
| return timeType(true, LogicalTypeAnnotation.TimeUnit.MICROS); | ||
| case UINT_8: | ||
| return IntLogicalTypeAnnotation.create(8, false); | ||
| return intType(8, false); | ||
| case UINT_16: | ||
| return IntLogicalTypeAnnotation.create(16, false); | ||
| return intType(16, false); | ||
| case UINT_32: | ||
| return IntLogicalTypeAnnotation.create(32, false); | ||
| return intType(32, false); | ||
| case UINT_64: | ||
| return IntLogicalTypeAnnotation.create(64, false); | ||
| return intType(64, false); | ||
| case INT_8: | ||
| return IntLogicalTypeAnnotation.create(8, true); | ||
| return intType(8, true); | ||
| case INT_16: | ||
| return IntLogicalTypeAnnotation.create(16, true); | ||
| return intType(16, true); | ||
| case INT_32: | ||
| return IntLogicalTypeAnnotation.create(32, true); | ||
| return intType(32, true); | ||
| case INT_64: | ||
| return IntLogicalTypeAnnotation.create(64, true); | ||
| return intType(64, true); | ||
| case ENUM: | ||
| return EnumLogicalTypeAnnotation.create(); | ||
| return enumType(); | ||
| case JSON: | ||
| return JsonLogicalTypeAnnotation.create(); | ||
| return jsonType(); | ||
| case BSON: | ||
| return BsonLogicalTypeAnnotation.create(); | ||
| return bsonType(); | ||
| case MAP_KEY_VALUE: | ||
| return MapKeyValueTypeAnnotation.create(); | ||
| return mapKeyValueType(); | ||
| default: | ||
| throw new RuntimeException("Can't convert original type to logical type, unknown original type " + originalType); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| static StringLogicalTypeAnnotation stringType() { | ||
| return StringLogicalTypeAnnotation.INSTANCE; | ||
| } | ||
|
|
||
| static MapLogicalTypeAnnotation mapType() { | ||
| return MapLogicalTypeAnnotation.INSTANCE; | ||
| } | ||
|
|
||
| static ListLogicalTypeAnnotation listType() { | ||
| return ListLogicalTypeAnnotation.INSTANCE; | ||
| } | ||
|
|
||
| static EnumLogicalTypeAnnotation enumType() { | ||
| return EnumLogicalTypeAnnotation.INSTANCE; | ||
| } | ||
|
|
||
| static DecimalLogicalTypeAnnotation decimalType(final int scale, final int precision) { | ||
| return new DecimalLogicalTypeAnnotation(scale, precision); | ||
| } | ||
|
|
||
| static DateLogicalTypeAnnotation dateType() { | ||
| return DateLogicalTypeAnnotation.INSTANCE; | ||
| } | ||
|
|
||
| static TimeLogicalTypeAnnotation timeType(final boolean isAdjustedToUTC, final TimeUnit unit) { | ||
| return new TimeLogicalTypeAnnotation(isAdjustedToUTC, unit); | ||
| } | ||
|
|
||
| static TimestampLogicalTypeAnnotation timestampType(final boolean isAdjustedToUTC, final TimeUnit unit) { | ||
| return new TimestampLogicalTypeAnnotation(isAdjustedToUTC, unit); | ||
| } | ||
|
|
||
| static IntLogicalTypeAnnotation intType(final int bitWidth, final boolean isSigned) { | ||
| Preconditions.checkArgument( | ||
| bitWidth == 8 || bitWidth == 16 || bitWidth == 32 || bitWidth == 64, | ||
| "Invalid bit width for integer logical type, " + bitWidth + " is not allowed, " + | ||
| "valid bit width values: 8, 16, 32, 64"); | ||
| return new IntLogicalTypeAnnotation(bitWidth, isSigned); | ||
| } | ||
|
|
||
| static JsonLogicalTypeAnnotation jsonType() { | ||
| return JsonLogicalTypeAnnotation.INSTANCE; | ||
| } | ||
|
|
||
| static BsonLogicalTypeAnnotation bsonType() { | ||
| return BsonLogicalTypeAnnotation.INSTANCE; | ||
| } | ||
|
|
||
| static IntervalLogicalTypeAnnotation intervalType() { | ||
| return IntervalLogicalTypeAnnotation.INSTANCE; | ||
| } | ||
|
|
||
| static MapKeyValueTypeAnnotation mapKeyValueType() { | ||
| return MapKeyValueTypeAnnotation.INSTANCE; | ||
| } | ||
|
|
||
| class StringLogicalTypeAnnotation implements LogicalTypeAnnotation { | ||
| private static final StringLogicalTypeAnnotation INSTANCE = new StringLogicalTypeAnnotation(); | ||
|
|
||
| public static LogicalTypeAnnotation create() { | ||
| return INSTANCE; | ||
| } | ||
|
|
||
| private StringLogicalTypeAnnotation() { | ||
| } | ||
|
|
||
|
|
@@ -164,18 +217,14 @@ public boolean equals(Object obj) { | |
|
|
||
| @Override | ||
| public int hashCode() { | ||
| // This type doesn't have any parameters, thus use class hashcode | ||
| // This type doesn't have any parameters, thus using class hashcode | ||
| return getClass().hashCode(); | ||
| } | ||
| } | ||
|
|
||
| class MapLogicalTypeAnnotation implements LogicalTypeAnnotation { | ||
| private static final MapLogicalTypeAnnotation INSTANCE = new MapLogicalTypeAnnotation(); | ||
|
|
||
| public static LogicalTypeAnnotation create() { | ||
| return INSTANCE; | ||
| } | ||
|
|
||
| private MapLogicalTypeAnnotation() { | ||
| } | ||
|
|
||
|
|
@@ -206,18 +255,14 @@ public boolean equals(Object obj) { | |
|
|
||
| @Override | ||
| public int hashCode() { | ||
| // This type doesn't have any parameters, thus use class hashcode | ||
| // This type doesn't have any parameters, thus using class hashcode | ||
| return getClass().hashCode(); | ||
| } | ||
| } | ||
|
|
||
| class ListLogicalTypeAnnotation implements LogicalTypeAnnotation { | ||
| private static final ListLogicalTypeAnnotation INSTANCE = new ListLogicalTypeAnnotation(); | ||
|
|
||
| public static LogicalTypeAnnotation create() { | ||
| return INSTANCE; | ||
| } | ||
|
|
||
| private ListLogicalTypeAnnotation() { | ||
| } | ||
|
|
||
|
|
@@ -248,18 +293,14 @@ public boolean equals(Object obj) { | |
|
|
||
| @Override | ||
| public int hashCode() { | ||
| // This type doesn't have any parameters, thus use class hashcode | ||
| // This type doesn't have any parameters, thus using class hashcode | ||
| return getClass().hashCode(); | ||
| } | ||
| } | ||
|
|
||
| class EnumLogicalTypeAnnotation implements LogicalTypeAnnotation { | ||
| private static final EnumLogicalTypeAnnotation INSTANCE = new EnumLogicalTypeAnnotation(); | ||
|
|
||
| public static LogicalTypeAnnotation create() { | ||
| return INSTANCE; | ||
| } | ||
|
|
||
| private EnumLogicalTypeAnnotation() { | ||
| } | ||
|
|
||
|
|
@@ -290,7 +331,7 @@ public boolean equals(Object obj) { | |
|
|
||
| @Override | ||
| public int hashCode() { | ||
| // This type doesn't have any parameters, thus use class hashcode | ||
| // This type doesn't have any parameters, thus using class hashcode | ||
| return getClass().hashCode(); | ||
| } | ||
| } | ||
|
|
@@ -299,10 +340,6 @@ class DecimalLogicalTypeAnnotation implements LogicalTypeAnnotation { | |
| private final int scale; | ||
| private final int precision; | ||
|
|
||
| public static LogicalTypeAnnotation create(int scale, int precision) { | ||
| return new DecimalLogicalTypeAnnotation(scale, precision); | ||
| } | ||
|
|
||
| private DecimalLogicalTypeAnnotation(int scale, int precision) { | ||
| this.scale = scale; | ||
| this.precision = precision; | ||
|
|
@@ -354,10 +391,6 @@ public int hashCode() { | |
| class DateLogicalTypeAnnotation implements LogicalTypeAnnotation { | ||
| private static final DateLogicalTypeAnnotation INSTANCE = new DateLogicalTypeAnnotation(); | ||
|
|
||
| public static LogicalTypeAnnotation create() { | ||
| return INSTANCE; | ||
| } | ||
|
|
||
| private DateLogicalTypeAnnotation() { | ||
| } | ||
|
|
||
|
|
@@ -388,7 +421,7 @@ public boolean equals(Object obj) { | |
|
|
||
| @Override | ||
| public int hashCode() { | ||
| // This type doesn't have any parameters, thus use class hashcode | ||
| // This type doesn't have any parameters, thus using class hashcode | ||
| return getClass().hashCode(); | ||
| } | ||
| } | ||
|
|
@@ -413,10 +446,6 @@ class TimeLogicalTypeAnnotation implements LogicalTypeAnnotation { | |
| private final boolean isAdjustedToUTC; | ||
| private final TimeUnit unit; | ||
|
|
||
| public static LogicalTypeAnnotation create(boolean isAdjustedToUTC, TimeUnit unit) { | ||
| return new TimeLogicalTypeAnnotation(isAdjustedToUTC, unit); | ||
| } | ||
|
|
||
| private TimeLogicalTypeAnnotation(boolean isAdjustedToUTC, TimeUnit unit) { | ||
| this.isAdjustedToUTC = isAdjustedToUTC; | ||
| this.unit = unit; | ||
|
|
@@ -483,10 +512,6 @@ class TimestampLogicalTypeAnnotation implements LogicalTypeAnnotation { | |
| private final boolean isAdjustedToUTC; | ||
| private final TimeUnit unit; | ||
|
|
||
| public static LogicalTypeAnnotation create(boolean isAdjustedToUTC, TimeUnit unit) { | ||
| return new TimestampLogicalTypeAnnotation(isAdjustedToUTC, unit); | ||
| } | ||
|
|
||
| private TimestampLogicalTypeAnnotation(boolean isAdjustedToUTC, TimeUnit unit) { | ||
| this.isAdjustedToUTC = isAdjustedToUTC; | ||
| this.unit = unit; | ||
|
|
@@ -553,13 +578,6 @@ class IntLogicalTypeAnnotation implements LogicalTypeAnnotation { | |
| private final int bitWidth; | ||
| private final boolean isSigned; | ||
|
|
||
| public static LogicalTypeAnnotation create(int bitWidth, boolean isSigned) { | ||
| Preconditions.checkArgument( | ||
| bitWidth == 8 || bitWidth == 16 || bitWidth == 32 || bitWidth == 64, | ||
| "Invalid bit width for integer logical type, " + bitWidth + " is not allowed, " + | ||
| "valid bit width values: 8, 16, 32, 64"); | ||
| return new IntLogicalTypeAnnotation(bitWidth, isSigned); | ||
| } | ||
|
|
||
| private IntLogicalTypeAnnotation(int bitWidth, boolean isSigned) { | ||
| this.bitWidth = bitWidth; | ||
|
|
@@ -642,10 +660,6 @@ public int hashCode() { | |
| class JsonLogicalTypeAnnotation implements LogicalTypeAnnotation { | ||
| private static final JsonLogicalTypeAnnotation INSTANCE = new JsonLogicalTypeAnnotation(); | ||
|
|
||
| public static LogicalTypeAnnotation create() { | ||
| return INSTANCE; | ||
| } | ||
|
|
||
| private JsonLogicalTypeAnnotation() { | ||
| } | ||
|
|
||
|
|
@@ -676,18 +690,14 @@ public boolean equals(Object obj) { | |
|
|
||
| @Override | ||
| public int hashCode() { | ||
| // This type doesn't have any parameters, thus use class hashcode | ||
| // This type doesn't have any parameters, thus using class hashcode | ||
| return getClass().hashCode(); | ||
| } | ||
| } | ||
|
|
||
| class BsonLogicalTypeAnnotation implements LogicalTypeAnnotation { | ||
| private static final BsonLogicalTypeAnnotation INSTANCE = new BsonLogicalTypeAnnotation(); | ||
|
|
||
| public static LogicalTypeAnnotation create() { | ||
| return INSTANCE; | ||
| } | ||
|
|
||
| private BsonLogicalTypeAnnotation() { | ||
| } | ||
|
|
||
|
|
@@ -718,7 +728,7 @@ public boolean equals(Object obj) { | |
|
|
||
| @Override | ||
| public int hashCode() { | ||
| // This type doesn't have any parameters, thus use class hashcode | ||
| // This type doesn't have any parameters, thus using class hashcode | ||
| return getClass().hashCode(); | ||
| } | ||
| } | ||
|
|
@@ -729,10 +739,6 @@ public int hashCode() { | |
| class IntervalLogicalTypeAnnotation implements LogicalTypeAnnotation { | ||
|
||
| private static IntervalLogicalTypeAnnotation INSTANCE = new IntervalLogicalTypeAnnotation(); | ||
|
|
||
| public static LogicalTypeAnnotation create() { | ||
| return INSTANCE; | ||
| } | ||
|
|
||
| private IntervalLogicalTypeAnnotation() { | ||
| } | ||
|
|
||
|
|
@@ -763,7 +769,7 @@ public boolean equals(Object obj) { | |
|
|
||
| @Override | ||
| public int hashCode() { | ||
| // This type doesn't have any parameters, thus use class hashcode | ||
| // This type doesn't have any parameters, thus using class hashcode | ||
| return getClass().hashCode(); | ||
| } | ||
| } | ||
|
|
@@ -774,10 +780,6 @@ public int hashCode() { | |
| class MapKeyValueTypeAnnotation implements LogicalTypeAnnotation { | ||
| private static MapKeyValueTypeAnnotation INSTANCE = new MapKeyValueTypeAnnotation(); | ||
|
|
||
| public static LogicalTypeAnnotation create() { | ||
| return INSTANCE; | ||
| } | ||
|
|
||
| private MapKeyValueTypeAnnotation() { | ||
| } | ||
|
|
||
|
|
@@ -808,7 +810,7 @@ public boolean equals(Object obj) { | |
|
|
||
| @Override | ||
| public int hashCode() { | ||
| // This type doesn't have any parameters, thus use class hashcode | ||
| // This type doesn't have any parameters, thus using class hashcode | ||
| return getClass().hashCode(); | ||
| } | ||
| } | ||
|
|
||
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want the user to be able to create an Interval or a MapKeyValue type? If they are only exist for backward compatibility reasons the factory method should not be public so users won't be able to create them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think MapKeyValue is here only for backward compatibility, but Interval should be supported in the future. Since these factory methods are defined on an interface, I can't easily change the visibility to private/package protected. Should I change it to an abstract class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interval is not supported in LogicalType currently, so I would not expose it yet. It is always possible to make a restricted access public but in the other way it would break backward compatibility.
Abstract class sounds reasonable to me.