Skip to content
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

[CALCITE-6764] Field access from a nullable ROW should be nullable (part 2) #4139

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mihaibudiu
Copy link
Contributor

We have already merged a PR fixing this issue, but I have reopened it, and this is a second PR addressing a second bug related to the same problem.

Copy link
Member

@asolimando asolimando left a comment

Choose a reason for hiding this comment

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

Nothing major but I am confused on a couple of points @mihaibudiu, can you take a look?

@mihaibudiu
Copy link
Contributor Author

@asolimando I have pushed a commit which hopefully addresses your comments.

@mihaibudiu
Copy link
Contributor Author

I will write a few more tests, so I will mark this PR as draft until I am sure it passes all of them. Hopefully this won't take too long.

@mihaibudiu mihaibudiu marked this pull request as draft January 14, 2025 01:10
@asolimando
Copy link
Member

@asolimando I have pushed a commit which hopefully addresses your comments.

Thanks @mihaibudiu, LGTM, just proposed two improved test names, the rest is good, feel free to ping me for an extra review round once the extra tests are ready, if needed

@mihaibudiu mihaibudiu marked this pull request as ready for review January 15, 2025 02:12
@mihaibudiu
Copy link
Contributor Author

The complete fix required some additions to the type factory interfaces and making a method public.
As I commented in the jira https://issues.apache.org/jira/browse/CALCITE-6764, I think that the methods from the type factory to create nullable types are broken for record types.

@mihaibudiu
Copy link
Contributor Author

@asolimando I made some changes that probably will require a new review

Copy link
Member

@asolimando asolimando left a comment

Choose a reason for hiding this comment

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

Looks mostly good to me @mihaibudiu, just confused about the fact that we are not considering anything other than Records in RelDataTypeFactoryImpl, if you could clarify that we are good for me.

@@ -179,7 +179,9 @@ RelDataType createMultisetType(
* Creates a type that is the same as another type but with possibly
* different nullability. The output type may be identical to the input
* type. For type systems without a concept of nullability, the return value
* is always the same as the input.
* is always the same as the input. This function never returns a nullable
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* is always the same as the input. This function never returns a nullable
* is always the same as the input. This function never returns a nullable

* Creates a type that is the same as another type but with possibly
* different nullability. The output type may be identical to the input
* type. For type systems without a concept of nullability, the return value
* is always the same as the input. This differs from {@link
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* is always the same as the input. This differs from {@link
* is always the same as the input. This differs from {@link

* type. For type systems without a concept of nullability, the return value
* is always the same as the input. This differs from {@link
* #createTypeWithNullability(RelDataType, boolean)} in the handling of struct
* types. This function returns a nullable struct.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* types. This function returns a nullable struct.
* types. This function returns a nullable struct.

* #createTypeWithNullability(RelDataType, boolean)} in the handling of struct
* types. This function returns a nullable struct.
*
* @param type input type
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I see that some javadoc here has this kind of formatting with extra spaces to align columns "horizontally", AFAICT this is not what we generally use in the codebase, so I'd rather not enforce this here

}
},
type.getFieldNames(), nullable);
} else {
Copy link
Member

Choose a reason for hiding this comment

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

Aren't there other non simple types like maps (MultisetSqlType)/arrays (ArraySqlType)? Is it enough in this form?

EDIT: I have just seen you have done that for the SqlTypeFactoryImpl, why here it is not needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As far as I can tell the other types are handled correctly by the factory.
Only Record types are anomalous.
This class (RelDataTypeFactoryImpl) is an abstract base class out of which SqlTypeFactoryImpl is derived. In the end, the SqlTypeFactoryImpl method gets called.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the clarification Mihai, I have no more questions, hence I will approve the PR, the rest is minor and I will leave it to your judgement

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thank you. I will address the comments and squash the commits at the same time.
I am not sure whether adding functions to an interface is a breaking change that has to be documented in history.md.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will document it anyway.

Copy link
Member

Choose a reason for hiding this comment

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

I guess so, because implementers will have to add support for it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will add this to history.md in the section on breaking changes:

*RelDataTypeFactory interface*.  The fix for [<a
href="https://issues.apache.org/jira/browse/CALCITE-6764">CALCITE-6764</a>]
introduces a new method
`RelDataTypeFactory#enforceTypeWithNullability` in the existing
`RelDataTypeFactory` interface.  The behavior of the new function is
similar to the existing API `createTypeWithNullability`; however, the
existing implementations of the `createTypeWithNullability` API cannot
create nullable record (`ROW`) types.  Nullable record types are
legitimate in several SQL dialects.

@mihaibudiu mihaibudiu added the LGTM-will-merge-soon Overall PR looks OK. Only minor things left. label Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LGTM-will-merge-soon Overall PR looks OK. Only minor things left.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants