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

suibianwanwan updated CALCITE-6651:
-----------------------------------
    Description: 
In SqlToRelConverter, one part of Union is constructed by LogicalUnion.create 
and another part is created by relBuilder. And relBuilder.union will be based 
on RelBuilder.Config to determine whether the value needs to be simplify. but 
LogicalUnion.create will not. But LogicalUnion.create won't. This results in 
some values created by LogicalUnion.create not being simplified.

For example: In SqlToRelConverterTest: (This example may have some overlap with 
CALCITE-6350)
{code:java}
@Test void testUnionChar() {
  final String sql = "select 'a' t1 union SELECT 'ab' t1";
  sql(sql).ok();
} {code}
Result:
{code:java}
LogicalUnion(all=[false])  
  LogicalValues(tuples=[[{ 'a' }]])
  LogicalValues(tuples=[[{ 'ab' }]])
{code}
Expected result:
{code:java}
LogicalUnion(all=[false])  
  LogicalValues(tuples=[[{ 'a ' }]])
  LogicalValues(tuples=[[{ 'ab' }]])
{code}

  was:
The integer type implicit cast for IN sub-query is supported in CALCITE-5156.

But for SqlLiteral in IN, we should not force its type cast. In the following 
comment, in LogicalValue, we keep the type information in RelNode
{code:java}
private RexLiteral convertLiteral(SqlLiteral sqlLiteral,
    Blackboard bb, RelDataType type) {
  RexNode literalExpr = exprConverter.convertLiteral(bb, sqlLiteral);

  if (!(literalExpr instanceof RexLiteral)) {
    assert literalExpr.isA(SqlKind.CAST);
    RexNode child = ((RexCall) literalExpr).getOperands().get(0);
    assert RexLiteral.isNullLiteral(child);

    // NOTE jvs 22-Nov-2006:  we preserve type info
    // in LogicalValues digest, so it's OK to lose it here
    return (RexLiteral) child;
  }

  //.....
}{code}
Take the following SQL as an example:
{code:java}
SELECT empno
FROM emp AS e
WHERE cast(e.empno as bigint) in (130, 131, 132, 133, 134) {code}
{code:java}
LogicalProject(EMPNO=[$0])
  LogicalJoin(condition=[=($9, $10)], joinType=[inner])
    LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], EMPNO0=[CAST($0):BIGINT NOT 
NULL])
      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
    LogicalAggregate(group=[{0}])
      LogicalValues(tuples=[[{ 130 }, { 131 }, { 132 }, { 133 }, { 134 
}]]){code}
The type of the Literal is inferred from the type of the LogicalValues. 
However, if you cast the SqlLiteral to Integer during the validation process, 
it will result in the following Bad Plan. In the case of too many Values, 
optimizations such as RexSimplify, pullUpPredicate will consume a lot of time 
compared to past plans.
{code:java}
LogicalProject(EMPNO=[$0])
  LogicalJoin(condition=[=($9, $10)], joinType=[inner])
    LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], EMPNO0=[CAST($0):BIGINT NOT 
NULL])
      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
    LogicalAggregate(group=[{0}])
      LogicalUnion(all=[true])
        LogicalValues(tuples=[[{ 130 }]])
        LogicalValues(tuples=[[{ 131 }]])
        LogicalValues(tuples=[[{ 132 }]])
        LogicalValues(tuples=[[{ 133 }]])
        LogicalValues(tuples=[[{ 134 }]]) {code}

        Summary: Use RelBuilder in SqlToRelConverter to construct Union  (was: 
Ignore SqlLiteral in implicit Integer type cast)

> Use RelBuilder in SqlToRelConverter to construct Union
> ------------------------------------------------------
>
>                 Key: CALCITE-6651
>                 URL: https://issues.apache.org/jira/browse/CALCITE-6651
>             Project: Calcite
>          Issue Type: Bug
>            Reporter: suibianwanwan
>            Assignee: suibianwanwan
>            Priority: Major
>              Labels: pull-request-available
>
> In SqlToRelConverter, one part of Union is constructed by LogicalUnion.create 
> and another part is created by relBuilder. And relBuilder.union will be based 
> on RelBuilder.Config to determine whether the value needs to be simplify. but 
> LogicalUnion.create will not. But LogicalUnion.create won't. This results in 
> some values created by LogicalUnion.create not being simplified.
> For example: In SqlToRelConverterTest: (This example may have some overlap 
> with CALCITE-6350)
> {code:java}
> @Test void testUnionChar() {
>   final String sql = "select 'a' t1 union SELECT 'ab' t1";
>   sql(sql).ok();
> } {code}
> Result:
> {code:java}
> LogicalUnion(all=[false])  
>   LogicalValues(tuples=[[{ 'a' }]])
>   LogicalValues(tuples=[[{ 'ab' }]])
> {code}
> Expected result:
> {code:java}
> LogicalUnion(all=[false])  
>   LogicalValues(tuples=[[{ 'a ' }]])
>   LogicalValues(tuples=[[{ 'ab' }]])
> {code}



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

Reply via email to