-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Allow casted literal values in SQL functions accepting literals #15282
Allow casted literal values in SQL functions accepting literals #15282
Conversation
sql/src/main/java/org/apache/druid/sql/calcite/expression/OperatorConversions.java
Fixed
Show fixed
Hide fixed
@@ -144,7 +143,7 @@ public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFail | |||
|
|||
// Verify that 'operand' is a literal number. | |||
if (!SqlUtil.isLiteral(operand)) { |
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.
doesn't this need to allow cast?
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.
Good catch, it does. I modified the call to allow casts and added test for the same
for (int i = requiredOperands; i < operands.size(); i++) { | ||
ret.append("]"); | ||
} |
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.
this doesn't seem right. is there a test case to verify signature when there are multiple required operands?
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.
Hmm, git diff shows that I moved BasicOperandTypeChecker
-> DefaultOperandTypeChecker
. However DefaultOperandTypeChecker
was already present in OperatorConversions
that I pulled out.
I think it creates a signature like:
'functionName(requiredOperand1, requiredOperand2, [optionalOperand1, [optionalOperand2]])'
- We append
'functionName(
- Loop begins
- For each operand, if it's not the first operand, we append
,
- For each operand, if its an optional operand, we append
[
. At the end of the loop, we'd have open square brackets equal to the number of the optional operands - For each operand, we append the operand name
- Loop ends
- For the total number of optional operands, we append
]
at the end, therefore closing them out. - We append
)'
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.
- There's an
APPROX_COUNT_DISTINCT_DS_HLL
that takes 3 parameters, out of which the first one is required and the rest two are optional. - There's
BLOOM_FILTER
that takes 2 parameters and both are required - And then there's
APPROX_QUANTILE_FIXED_BUCKETS
which takes in 6 parameters out of which first 5 are required.
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.
ah yes. Now I get it. thanks for explaining the flow 😄
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 the changes. Looks good !
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.
LGTM, although I did have a suggestion for simplifying TDIGEST_GENERATE_SKETCH
as well.
OperandTypes.sequence(SIGNATURE_WITH_COMPRESSION, OperandTypes.ANY, OperandTypes.LITERAL), | ||
OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.NUMERIC) | ||
) | ||
// Validation for signatures like 'TDIGEST_GENERATE_SKETCH(column, compression)' |
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.
There's no need to have the OperandTypes.or
anymore. Just use the default checker with requiredOperandCount(1)
.
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.
Resolved! Thanks for the review
…he#15282) Functions that accept literals also allow casted literals. This shouldn't have an impact on the queries that the user writes. It enables the SQL functions to accept explicit cast, which is required with JDBC.
…) (#15298) Functions that accept literals also allow casted literals. This shouldn't have an impact on the queries that the user writes. It enables the SQL functions to accept explicit cast, which is required with JDBC. Co-authored-by: Laksh Singla <lakshsingla@gmail.com>
…he#15282) Functions that accept literals also allow casted literals. This shouldn't have an impact on the queries that the user writes. It enables the SQL functions to accept explicit cast, which is required with JDBC.
Description
For SQL functions accepting literals, casting might be allowed or disallowed, depending on whether the
OperandTypes.LITERAL
checker is used. Using it disallows casted literals like -CAST(100 AS INTEGER
.While this was an acceptable limitation as there's no use of casting a literal that the user has entered, the issue arises due to the Calcite upgrade, where the new JDBC client can't allow wildcards without an explicit cast. Therefore for a function with a signature like
FUNC(column, literal)
, we can't do the following in JDBC.Instead, we'd have to work around it using
But the second query doesn't play nice if the
FUNC
usesOperandTypes.LITERAL
. Therefore this PR allows cast in such functions by modifying the signature to not rely onOperandTypes.LITERAL
.This PR also marks
OperandTypes.LITERAL
in forbidden-apis so that the user cannot use theLITERAL
checker (until JDBC behavior is reverted, if it would).BasicOperandTypeChecker
is removed and theDefaultOperandTypeChecker
is the only checker around.Release note
Functions that accept literals also allow casted literals. This shouldn't have an impact on the queries that the user writes. It enables the SQL functions to accept explicit cast, which is required with JDBC.
This PR has: