[ 
https://issues.apache.org/jira/browse/CALCITE-7847?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Vladimir Sitnikov updated CALCITE-7847:
---------------------------------------
    Description: 
Comparing two MULTISET values whose element types differ casts both operands to 
ARRAY. On main (commit 843f468405, 1.43.0-SNAPSHOT), SqlToRelConverter 
translates

{code:sql}
select multiset[deptno] = multiset[cast(deptno as decimal(5, 2))] from dept
{code}

into

{noformat}
LogicalProject(EXPR$0=[=(CAST($SLICE($2)):DECIMAL(12, 2) NOT NULL ARRAY NOT 
NULL, CAST($SLICE($3)):DECIMAL(12, 2) NOT NULL ARRAY NOT NULL)])
{noformat}

Expected: both operands are cast to {{DECIMAL(12, 2) NOT NULL MULTISET NOT 
NULL}}.

{{AbstractTypeCoercion#commonTypeForBinaryComparison}}, which the coercion 
calls, shows the same defect for the types directly:

||type1||type2||returned||expected||
|INTEGER NOT NULL MULTISET NOT NULL|CHAR(1) NOT NULL MULTISET NOT NULL|INTEGER 
NOT NULL ARRAY NOT NULL|INTEGER NOT NULL MULTISET NOT NULL|
|RecordType(INTEGER a) (nullable)|RecordType(CHAR(1) NOT NULL a) NOT 
NULL|RecordType(INTEGER a) NOT NULL|RecordType(INTEGER a) (nullable)|

The other branches of the method, ARRAY and MAP included, return a nullable 
type when either operand is nullable (CALCITE-6741); the ROW branch returns NOT 
NULL. I did not find a query where the ROW defect changes the plan: The 
validator and SqlToRelConverter apply each operand's own nullability to the 
cast target, so it shows only to callers of the method, such as a custom 
TypeCoercion.

Cause: the ARRAY and MULTISET branch of {{commonTypeForBinaryComparison}} 
recurses into the element type for both, then always builds the result with 
{{createArrayType}}; the ROW branch returns {{createStructType(resultFields)}} 
without applying the nullability of the operands. The MULTISET branch came with 
CALCITE-6736, the ROW branch with CALCITE-6735.

  was:
Comparing two MULTISET values whose element types differ casts both operands to 
ARRAY. On main (commit 843f468405, 1.43.0-SNAPSHOT), SqlToRelConverter 
translates

{code:sql}
select multiset[deptno] = multiset[cast(deptno as decimal(5, 2))] from dept
{code}

into

{noformat}
LogicalProject(EXPR$0=[=(CAST($SLICE($2)):DECIMAL(12, 2) NOT NULL ARRAY NOT 
NULL, CAST($SLICE($3)):DECIMAL(12, 2) NOT NULL ARRAY NOT NULL)])
{noformat}

Expected: both operands are cast to {{DECIMAL(12, 2) NOT NULL MULTISET NOT 
NULL}}.

{{AbstractTypeCoercion#commonTypeForBinaryComparison}}, which the coercion 
calls, shows the same defect for the types directly:

||type1||type2||returned||expected||
|INTEGER NOT NULL MULTISET NOT NULL|CHAR(1) NOT NULL MULTISET NOT NULL|INTEGER 
NOT NULL ARRAY NOT NULL|INTEGER NOT NULL MULTISET NOT NULL|
|RecordType(INTEGER a) (nullable)|RecordType(CHAR(1) NOT NULL a) NOT 
NULL|RecordType(INTEGER a) NOT NULL|RecordType(INTEGER a) (nullable)|

The other branches of the method, ARRAY and MAP included, return a nullable 
type when either operand is nullable (CALCITE-6741); the ROW branch returns NOT 
NULL. I did not find a query where the ROW defect changes the plan: 
SqlToRelConverter expands a ROW comparison into comparisons of its fields, so 
it shows only to callers of the method, such as a custom TypeCoercion.

Cause: the ARRAY and MULTISET branch of {{commonTypeForBinaryComparison}} 
recurses into the element type for both, then always builds the result with 
{{createArrayType}}; the ROW branch returns {{createStructType(resultFields)}} 
without applying the nullability of the operands. The MULTISET branch came with 
CALCITE-6736, the ROW branch with CALCITE-6735.


> Implicit coercion casts MULTISET operands of a comparison to ARRAY, and loses 
> the nullability of ROW operands
> -------------------------------------------------------------------------------------------------------------
>
>                 Key: CALCITE-7847
>                 URL: https://issues.apache.org/jira/browse/CALCITE-7847
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.42.0
>            Reporter: Vladimir Sitnikov
>            Priority: Major
>              Labels: pull-request-available
>
> Comparing two MULTISET values whose element types differ casts both operands 
> to ARRAY. On main (commit 843f468405, 1.43.0-SNAPSHOT), SqlToRelConverter 
> translates
> {code:sql}
> select multiset[deptno] = multiset[cast(deptno as decimal(5, 2))] from dept
> {code}
> into
> {noformat}
> LogicalProject(EXPR$0=[=(CAST($SLICE($2)):DECIMAL(12, 2) NOT NULL ARRAY NOT 
> NULL, CAST($SLICE($3)):DECIMAL(12, 2) NOT NULL ARRAY NOT NULL)])
> {noformat}
> Expected: both operands are cast to {{DECIMAL(12, 2) NOT NULL MULTISET NOT 
> NULL}}.
> {{AbstractTypeCoercion#commonTypeForBinaryComparison}}, which the coercion 
> calls, shows the same defect for the types directly:
> ||type1||type2||returned||expected||
> |INTEGER NOT NULL MULTISET NOT NULL|CHAR(1) NOT NULL MULTISET NOT 
> NULL|INTEGER NOT NULL ARRAY NOT NULL|INTEGER NOT NULL MULTISET NOT NULL|
> |RecordType(INTEGER a) (nullable)|RecordType(CHAR(1) NOT NULL a) NOT 
> NULL|RecordType(INTEGER a) NOT NULL|RecordType(INTEGER a) (nullable)|
> The other branches of the method, ARRAY and MAP included, return a nullable 
> type when either operand is nullable (CALCITE-6741); the ROW branch returns 
> NOT NULL. I did not find a query where the ROW defect changes the plan: The 
> validator and SqlToRelConverter apply each operand's own nullability to the 
> cast target, so it shows only to callers of the method, such as a custom 
> TypeCoercion.
> Cause: the ARRAY and MULTISET branch of {{commonTypeForBinaryComparison}} 
> recurses into the element type for both, then always builds the result with 
> {{createArrayType}}; the ROW branch returns 
> {{createStructType(resultFields)}} without applying the nullability of the 
> operands. The MULTISET branch came with CALCITE-6736, the ROW branch with 
> CALCITE-6735.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to