[
https://issues.apache.org/jira/browse/CALCITE-7858?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Mihai Budiu resolved CALCITE-7858.
----------------------------------
Fix Version/s: 1.43.0
Assignee: Lantao Jin
Resolution: Fixed
Fixed in
[https://github.com/apache/calcite/commit/334fc71ad5db52f11af4d1d68cf9ad40ee415cc2]
Thank you for the fix [~cltlfcjin]
> ARG_MIN, ARG_MAX, MIN_BY and MAX_BY accept a non-comparable key because
> OperandTypes.ANY_COMPARABLE never fails
> ---------------------------------------------------------------------------------------------------------------
>
> Key: CALCITE-7858
> URL: https://issues.apache.org/jira/browse/CALCITE-7858
> Project: Calcite
> Issue Type: Bug
> Components: core
> Affects Versions: 1.33.0, 1.42.0
> Reporter: Lantao Jin
> Assignee: Lantao Jin
> Priority: Major
> Labels: pull-request-available
> Fix For: 1.43.0
>
>
> h2. Problem
> {{ARG_MIN(value, key)}} and {{ARG_MAX(value, key)}} (and their aliases
> {{MIN_BY}} / {{MAX_BY}}) require their second operand to be comparable, but
> the validator never enforces it. A key whose type has comparability {{NONE}}
> (for example a structured type defined by a catalog, such as
> {{ObjectSqlType}} with {{RelDataTypeComparability.NONE}}) passes validation,
> although {{MIN}} and {{MAX}} reject the same type with a clear validation
> error.
> h2. Cause
> {{OperandTypes.ANY_COMPARABLE}}, the operand checker of these functions,
> returns {{false}} for a non-comparable second operand but never throws,
> whatever {{throwOnFailure}} is:
> {code:java}
> public static final SqlOperandTypeChecker ANY_COMPARABLE =
> new SqlOperandTypeChecker() {
> @Override public boolean checkOperandTypes(SqlCallBinding callBinding,
> boolean throwOnFailure) {
> getOperandCountRange().isValidCount(callBinding.getOperandCount());
> RelDataType type = callBinding.getOperandType(1);
> return type.getComparability() == RelDataTypeComparability.ALL;
> }
> ...
> {code}
> {{SqlOperator.validateOperands}} calls {{checkOperandTypes(opBinding, true)}}
> and ignores the returned boolean, relying on the checker to throw, so the
> {{false}} is lost. The result of {{isValidCount}} is discarded in the same
> way. The checker was added with the functions in CALCITE-5283.
> h2. How to reproduce
> The test catalog's {{EMP_ADDRESS}} table has columns of the structured type
> {{ADDRESS}}, whose comparability is {{NONE}} ({{Fixture.addressType}}). In
> {{SqlValidatorTest}}:
> {code:sql}
> select arg_min(empno, home_address) from emp_address
> {code}
> On {{main}} this validates without error, and so do {{arg_max(empno,
> home_address)}} and, with the Spark library, {{min_by(...)}} and
> {{max_by(...)}}. {{MIN(home_address)}}, by contrast, is already rejected at
> validation by {{ComparableOperandTypeChecker}}:
> {noformat}
> Cannot apply 'MIN' to arguments of type 'MIN(<>)'. Supported form(s):
> 'MIN(<COMPARABLE_TYPE>)'
> {noformat}
> With the fix, the four functions fail the same way, for example:
> {noformat}
> Cannot apply 'ARG_MIN' to arguments of type 'ARG_MIN(<INTEGER>, <>)'.
> Supported form(s): ARG_MIN(<ANY>, <COMPARABLE_TYPE>)
> {noformat}
> A non-comparable *value* argument is still allowed: {{arg_min(home_address,
> empno)}} validates.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)