-
Notifications
You must be signed in to change notification settings - Fork 13.9k
[FLINK-28936][sql-gateway] Fix REST endpoint can not serialize CHAR(0) by introducing a new serializer for LogicalType #20617
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
Conversation
fsk119
left a comment
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.
Thanks for your contribution. I left some comments.
.../main/java/org/apache/flink/table/gateway/api/results/serde/LogicalTypeJsonDeserializer.java
Outdated
Show resolved
Hide resolved
|
|
||
| // Common fields | ||
| public static final String FIELD_NAME_TYPE_NAME = "type"; | ||
| public static final String FIELD_NAME_NULLABLE = "nullable"; |
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.
miss FIELD_NAME_DESCRPITION
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.
As far as I know, description is not a common field shared by all logical types, so I think we don't need this.
...src/test/java/org/apache/flink/table/gateway/api/results/serde/LogicalTypeJsonSerDeTest.java
Show resolved
Hide resolved
| // ROW | ||
| public static final String FIELD_NAME_FIELDS = "fields"; | ||
| public static final String FIELD_NAME_FIELD_NAME = "name"; | ||
| public static final String FIELD_NAME_FIELD_TYPE = "fieldType"; |
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.
missing description.
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.
Added code for serialization and deserialization for RowType#description and corresponding test.
| case FLOAT: | ||
| case DOUBLE: | ||
| case DATE: | ||
| case NULL: |
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.
NullType is alway nullable. I think we dont't need to add "nullable": true in the json.
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.
Added codes to handle NullType.
...rc/main/java/org/apache/flink/table/gateway/api/results/serde/LogicalTypeJsonSerializer.java
Outdated
Show resolved
Hide resolved
|
|
||
| private static List<LogicalType> generateTestData() { | ||
| List<LogicalType> types = | ||
| Arrays.asList( |
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.
Please also add
new TimeType(),
new TimeType(3),
new LocalZonedTimestampType(false, TimestampKind.PROCTIME, 3),
new TimestampType(false, TimestampKind.ROWTIME, 3),
new ZonedTimestampType(),
new ZonedTimestampType(3),
new ZonedTimestampType(false, TimestampKind.ROWTIME, 3),
new LocalZonedTimestampType(),
new LocalZonedTimestampType(3),
new LocalZonedTimestampType(false, TimestampKind.PROCTIME, 3),
new LocalZonedTimestampType(false, TimestampKind.ROWTIME, 3),
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.
Add necessary test case.
.../main/java/org/apache/flink/table/gateway/api/results/serde/LogicalTypeJsonDeserializer.java
Outdated
Show resolved
Hide resolved
| case VARBINARY: | ||
| return length == 0 ? VarBinaryType.ofEmptyLiteral() : new VarBinaryType(length); | ||
| default: | ||
| throw new TableException("Logical type with attribute 'length' expected."); |
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.
"Can't convert json '%s' to the logical type %s."
BTW, I think it's better to throw SqlGatewayException here.
|
|
||
| private LogicalType deserializeRaw(JsonNode logicalTypeNode) { | ||
| String className = logicalTypeNode.get(FIELD_NAME_CLASS).asText(); | ||
| String specialSerializer = logicalTypeNode.get(FIELD_NAME_SERIALIZER).asText(); |
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.
rename to serializer. We don't have special serializer.
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.
Renamed.
2ed8067 to
5c4fe03
Compare
9d127f6 to
5988c33
Compare
fsk119
left a comment
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.
Thanks for your update. I left some comments.
.../src/test/java/org/apache/flink/table/gateway/rest/util/SqlGatewayRestEndpointExtension.java
Outdated
Show resolved
Hide resolved
.../src/test/java/org/apache/flink/table/gateway/rest/util/SqlGatewayRestEndpointExtension.java
Outdated
Show resolved
Hide resolved
|
|
||
| InetSocketAddress serverAddress = checkNotNull(sqlGatewayRestEndpoint.getServerAddress()); | ||
| targetAddress = serverAddress.getHostName(); | ||
| targetPort = serverAddress.getPort(); |
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.
Can we use NetUtils to get a random port? If other CI runs in the same machine, it may fail to bind the port.
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.
After checking the implementation, I found the port is 0 in default configuration used by sqlGatewayRestEndpoint.start(), and that means server would bind a random port.
| private LogicalType deserializeInternal(JsonNode logicalTypeNode) { | ||
| LogicalTypeRoot typeRoot = | ||
| LogicalTypeRoot.valueOf(logicalTypeNode.get(FIELD_NAME_TYPE_NAME).asText()); | ||
| // handle the special case of NullType |
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.
Can we describe the root reason here. For example, the NullType is always nullable.
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.
Made it clearer.
| // final constants for testing unsupported case | ||
| private final LogicalType unsupportedType = | ||
| new DayTimeIntervalType(DayTimeIntervalType.DayTimeResolution.DAY_TO_HOUR); | ||
| private final String serializerExceptionMessageFormat = | ||
| "Unable to serialize logical type '%s'. Please check the documentation for supported types."; | ||
| private final String unsupportedTypeString = "INTERVAL_DAY_TIME"; | ||
| private final String json = | ||
| String.format( | ||
| "{\"%s\": \"%s\", \"%s\": %s}", | ||
| "type", unsupportedTypeString, "nullable", "true"); | ||
| private final String deserializerExceptionMessageFormat = | ||
| "Unable to deserialize a logical type of type root '%s'. Please check the documentation for supported types."; |
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.
Local variables are enough. Move into the test case.
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.
Changed.
|
|
||
| private final ObjectMapper mapper = getObjectMapper(); | ||
|
|
||
| // final constants for testing unsupported case |
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.
Remove useless comments... I think variable names are straightforward for us.
| /** | ||
| * LogicalType isn't annotated with Jackson annotations, so it's necessary to register the | ||
| * customer serializer and deserializer when testing LogicalType Serde alone. | ||
| */ |
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.
Remove this comment. It's the Jackson's API, we don't need to tell others how to use jackson.
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.
Removed.
| * LogicalType isn't annotated with Jackson annotations, so it's necessary to register the | ||
| * customer serializer and deserializer when testing LogicalType Serde alone. | ||
| */ | ||
| private ObjectMapper getObjectMapper() { |
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.
rename to buildObjectMapper
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.
Renamed.
| new LocalZonedTimestampType(), | ||
| new LocalZonedTimestampType(3), | ||
| new LocalZonedTimestampType(false, 3), | ||
| // LocalZonedTimestampType#eaquals doesn't compare TimestampKind |
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.
Remove this ...
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.
Removed.
| // test to deserialize unsupported JSON string | ||
| String unsupportedTypeString = "INTERVAL_DAY_TIME"; | ||
| String json = | ||
| String.format( | ||
| "{\"%s\": \"%s\", \"%s\": %s}", | ||
| "type", unsupportedTypeString, "nullable", "true"); | ||
| assertThatThrownBy(() -> mapper.readValue(json, LogicalType.class)) | ||
| .satisfies( | ||
| FlinkAssertions.anyCauseMatches( | ||
| UnsupportedOperationException.class, | ||
| String.format( | ||
| "Unable to deserialize a logical type of type root '%s'. Please check the documentation for supported types.", | ||
| unsupportedTypeString))); |
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.
It's better to split into two test cases.
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.
Improved.
…) by introducing a new serializer for LogicalType
…ame to SqlGatewayRestEndpointStatementITCase).
6fef77c to
05f1385
Compare
fsk119
left a comment
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.
Thanks for your update. LGTM
…acted LogicalType (apache#20617)
[FLINK-28936][sql-gateway] Fix REST endpoint can not serialize CHAR(0) by introducing a new serializer for LogicalType
What is the purpose of the change
Fix the absence of
LogicalTypeserializer.Brief change log
LogicalTypeJsonSerializerin sql-gateway-api.LogicalTypeJsonDeserializerin sql-gateway-api.Verifying this change
This change added tests and can be verified as follows:
LogicalTypeinstance after serializing and deserializing is equal to original logical type.Does this pull request potentially affect one of the following parts:
@Public(Evolving): (yes / no)Documentation