[ 
https://issues.apache.org/jira/browse/CALCITE-7858?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18127367#comment-18127367
 ] 

Mihai Budiu commented on CALCITE-7858:
--------------------------------------

I believe that in the Calcite runtime all types are really comparable.

> 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
>            Priority: Major
>
> 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)

Reply via email to