You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Yuzhao Chen (JIRA)" <ji...@apache.org> on 2018/10/24 05:52:00 UTC

[jira] [Created] (CALCITE-2638) Should not do constant reduction when dynamic function is as inputRef in project

Yuzhao Chen created CALCITE-2638:
------------------------------------

             Summary: Should not do constant reduction when dynamic function is as inputRef in project
                 Key: CALCITE-2638
                 URL: https://issues.apache.org/jira/browse/CALCITE-2638
             Project: Calcite
          Issue Type: Bug
          Components: core
    Affects Versions: 1.17.0
            Reporter: Yuzhao Chen
            Assignee: Julian Hyde
             Fix For: 1.18.0


When we have a dynamic function like `current_timestamp` in the query, calcite will skip constant reduction, for example, for query1:

```sql

select sal, current_timestamp as t from emp

```

The plan after rule `ReduceExpressionsRule.PROJECT_INSTANCE` is

```diff

LogicalProject(SAL=[$5], T=[CURRENT_TIMESTAMP])
  LogicalTableScan(table=[[CATALOG, SALES, EMP]])

```

This is as expect cause there is such code snippet in `ReducibleExprLocator#visitCall`:

```java

// Even if all operands are constant, the call itself may
// be non-deterministic.
if (!call.getOperator().isDeterministic()) {
  callConstancy = Constancy.NON_CONSTANT;
} else if (call.getOperator().isDynamicFunction()) {
  // We can reduce the call to a constant, but we can't
  // cache the plan if the function is dynamic.
  // For now, treat it same as non-deterministic.
  callConstancy = Constancy.NON_CONSTANT;
}

```

But for query2:

```sql

select sal, sal + 5, t from (select sal, current_timestamp as t from emp)

```

we will get a plan with rule `ReduceExpressionsRule.PROJECT_INSTANCE` as:

```diff

+ plan before

LogicalProject(SAL=[$0], EXPR$1=[+($0, 5)], T=[$1])
  LogicalProject(SAL=[$5], T=[CURRENT_TIMESTAMP])
  LogicalTableScan(table=[[CATALOG, SALES, EMP]])

 

+ plan after

LogicalProject(SAL=[$0], EXPR$1=[+($0, 5)], T=[CURRENT_TIMESTAMP])
  LogicalProject(SAL=[$5], T=[CURRENT_TIMESTAMP])
  LogicalTableScan(table=[[CATALOG, SALES, EMP]])

```

This is actually wrong cause `current_timestamp` is dynamic and we do not want to compute it again in the outer project.

The reason we did constant reduction now is that: for query2, we will get a pulled up predicates with tool function `RexUtil.isConstant`, this function decide if the call is constant by invoking `SqlOperator#isDeterministic` which is default true here. It did not do the `isDynamicFunction()` decision just like `ReducibleExprLocator` and the reduction finally happened which handle by `RexExecutor`.

 

Personally i think we should keep sync in reduction logic for `inputRef` and `RexCall` and i reuse the `analyzeCall` and apply a patch here.

[]()

 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)