[ 
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)

Reply via email to