You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Ziwei Liu (Jira)" <ji...@apache.org> on 2021/12/27 11:54:00 UTC

[jira] [Commented] (CALCITE-4964) Reduce recursion when push predicate into CASE

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

Ziwei Liu commented on CALCITE-4964:
------------------------------------

The original code is 
{code:java}
@Override public RexNode visitCall(RexCall call) {
  for (;;) {
    call = (RexCall) super.visitCall(call);
    final RexCall old = call;
    call = pushPredicateIntoCase(call);
    if (call == old) {
      return call;
    }
  }
} {code}
If call != old, then new call will continue the depth-first traversal, and this traversal may not need to do.

eg:

select case 

           when value >300 and id > 100 then 1

           when value > 200 and id > 50 then 2

           else 3 as type

from src where type  = 3;

Then Filter will be EQ(CASE(...)).

After push EQ into CASE, this condition does not need to push EQ into inner predicate, so just need traverse the new call's operand.

If the when's predicate is more complicated than this example, the traversal will save more time.

 

> Reduce recursion when push predicate into CASE
> ----------------------------------------------
>
>                 Key: CALCITE-4964
>                 URL: https://issues.apache.org/jira/browse/CALCITE-4964
>             Project: Calcite
>          Issue Type: Improvement
>            Reporter: Ziwei Liu
>            Assignee: Ziwei Liu
>            Priority: Major
>
> I think CaseShuttle do not need a loop of for(;; ).When a predicate is pushed into case, we only need to check the new RexCall whether need to push predicate into the child operand, not need to do a new recursion.
> So I think CaseShuttle can be reduced like:
> {code:java}
> @Override public RexNode visitCall(RexCall call) {
>    call = (RexCall) super.visitCall(call);
>    if (call instanceof OdpsLambdaRexCall) {
>       return call;
>    }
>    final RexCall old = call;
>    call = ReduceExpressionsRule.pushPredicateIntoCase(call);
>    if (call == old) {
>      return call;
>    } else {
>       boolean containCase = false;
>       List<RexNode> newOps = new ArrayList<>(call.getOperands().size());
>       // call will be like case when c1 then f(x1 ...)
>       // check whether need push f into x1
>       for (int i = 0; i < call.getOperands().size(); i ++) {
>          RexNode op = call.getOperands().get(i);
>          RexNode newOp = op;
>          if (i % 2 == 1 || i == call.getOperands().size() - 1) {
>            if (op instanceof RexCall) {
>              newOp = ReduceExpressionsRule.pushPredicateIntoCase((RexCall) op);
>            }
>          }
>          if (op != newOp) {
>            containCase = true;
>          }
>          newOps.add(newOp);
>        }
>        if (!containCase) {
>          return call;
>        } else {
>          return call.clone(call.getType(), newOps);
>        }
>    }    
> } {code}



--
This message was sent by Atlassian Jira
(v8.20.1#820001)