-
Notifications
You must be signed in to change notification settings - Fork 219
[Coral-Common] Convert Hive uniontype into a struct-RelDataType that conforms Trino' schema #192
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 8 commits
ad2bc8f
33cdf38
2d91f48
4f7bf56
f0f64a9
c77fb85
d4cd58e
cfb3298
612a362
40eb25e
c5210cb
2493a8a
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 |
|---|---|---|
|
|
@@ -141,11 +141,16 @@ public static RelDataType convert(StructTypeInfo structType, final RelDataTypeFa | |
| } | ||
|
|
||
| // Mimic the StructTypeInfo conversion to convert a UnionTypeInfo to the corresponding RelDataType | ||
| // The schema of output Struct conforms to https://github.com/trinodb/trino/pull/3483 | ||
| public static RelDataType convert(UnionTypeInfo unionType, RelDataTypeFactory dtFactory) { | ||
| List<RelDataType> fTypes = unionType.getAllUnionObjectTypeInfos().stream() | ||
| .map(typeInfo -> convert(typeInfo, dtFactory)).collect(Collectors.toList()); | ||
| List<String> fNames = IntStream.range(0, unionType.getAllUnionObjectTypeInfos().size()).mapToObj(i -> "tag_" + i) | ||
| List<String> fNames = IntStream.range(0, unionType.getAllUnionObjectTypeInfos().size()).mapToObj(i -> "field" + i) | ||
| .collect(Collectors.toList()); | ||
| if (fNames.size() > 0) { | ||
| fTypes.add(0, dtFactory.createSqlType(SqlTypeName.INTEGER)); | ||
|
Collaborator
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. According to the corresponding PR: querying the view will fail if the types mismatch. Enhanced coral-trino test suite helped to catch this hidden issue 😉
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. Wow that's a great catch, thanks ! I will address this.
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. Nice work for enhanced coral-trino test suite! This is awesome! We can catch more issues before hitting production. |
||
| fNames.add(0, "tag"); | ||
| } | ||
|
|
||
| RelDataType rowType = dtFactory.createStructType(fTypes, fNames); | ||
| return dtFactory.createTypeWithNullability(rowType, true); | ||
|
|
||
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 we don't need this if statement since an empty union is a wrong schema, to begin with, maybe we could add a
Preconditions.checkStateto check it.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.
currently how do we prevent empty union to appear?
The reason for this branch is to preserve the semantic of the same code block earlier. If we add a precondition check, encountering empty union will result in unchecked exception but it will simply return an empty RelDataType before the change. is that what we want ?
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.
Seems that here https://github.com/trinodb/trino/pull/3483/files# the size is not checked. Does the Avro or ORC standard say anything about 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.
ORC spec doesn't mention it while I do see
uniontype<>happening in production. Regardless, this check is there to keep parity with the original (or we could end up with an additionaltagfield).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.
So if using the current code,
uniontype<>ends up in an empty struct? I recall there are some issues with empty struct somewhere, either in Iceberg or in Spark. So I'm not sure if this whole corner case will work or not.My point is if we explicitly announce this special case's behavior is undefined, then users have the responsibility to create the correct schema, it's a tradeoff between us and the users, I'm willing to accept either way.
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.
Our references should be: 1- what the standard says (again for Avro or ORC) 2- what the Trino transformation does. Hopefully all of them align. If not, we can discuss how to move forward.
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.
Another special case is union with only a single type
uniontype<[type]>. We should consider whether we want to support it and make sure its semantics is consistent across Trino and Iceberg implementationThere 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.
There aren't any spec that I could find regarding this point in either Avro or ORC, and looks like Trino doesn't check the size either.
Taking a step back, I also don't think Coral is in right position to gate such usage. So I am leaning towards let such case pass through (which means a check like
fNames.size > 0is necessary since we seestruct<>as a legit type).I am also OK to add a precondition check to fail the translation. But again, leaning towards the former option.
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.
+1 to the current approach
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.
Discussed offline. The objective is to match the Trino schema. We should remove the check from here since it is not used there.