Search in sources :

Example 1 with SqlBinaryOperator

use of org.apache.calcite.sql.SqlBinaryOperator in project drill by axbaretto.

the class FindPartitionConditions method popOpStackAndBuildFilter.

/*
   * Pop the current operation from the stack (opStack) as we are done with it.
   * If it has children, then it means the current OP itself is a PUSH
   * and hence add itself as a child to the parent OP. If no more parents
   * remains, it means that the current OP is the root condition and
   * set the root condition in that case.
   */
private void popOpStackAndBuildFilter() {
    // Parsing a special expression; handled holistically by the parent
    if (holisticExpression > 0) {
        return;
    }
    OpState currentOp = opStack.pop();
    int size = currentOp.getChildren().size();
    RexNode newFilter = null;
    if (size >= 1) {
        if (size == 1 && currentOp.getOp() instanceof SqlBinaryOperator) {
            /* The only operator for which we allow partial pushes is AND.
         * For all other operators we clear the children if one of the
         * children is a no push.
         */
            if (currentOp.getOp().getKind() == SqlKind.AND) {
                newFilter = currentOp.getChildren().get(0);
                for (OpState opState : opStack) {
                    if (opState.getOp().getKind() == SqlKind.NOT) {
                        // AND under NOT should not get pushed
                        newFilter = null;
                    }
                }
            }
        } else {
            newFilter = builder.makeCall(currentOp.getOp(), currentOp.getChildren());
        }
    }
    if (newFilter != null) {
        // add this new filter to my parent boolean operator's children
        if (!opStack.isEmpty()) {
            OpState parentOp = opStack.peek();
            parentOp.addChild(newFilter);
        } else {
            resultCondition = newFilter;
        }
    }
}
Also used : SqlBinaryOperator(org.apache.calcite.sql.SqlBinaryOperator) RexNode(org.apache.calcite.rex.RexNode)

Example 2 with SqlBinaryOperator

use of org.apache.calcite.sql.SqlBinaryOperator in project hive by apache.

the class RexNodeConverter method rewriteBetweenChildren.

public static List<RexNode> rewriteBetweenChildren(List<RexNode> childRexNodeLst, RexBuilder rexBuilder) {
    final List<RexNode> convertedChildList = Lists.newArrayList();
    SqlBinaryOperator cmpOp;
    if (childRexNodeLst.get(0).isAlwaysTrue()) {
        cmpOp = SqlStdOperatorTable.GREATER_THAN;
    } else {
        cmpOp = SqlStdOperatorTable.LESS_THAN_OR_EQUAL;
    }
    RexNode op = childRexNodeLst.get(1);
    RexNode rangeL = childRexNodeLst.get(2);
    RexNode rangeH = childRexNodeLst.get(3);
    convertedChildList.add(rexBuilder.makeCall(cmpOp, rangeL, op));
    convertedChildList.add(rexBuilder.makeCall(cmpOp, op, rangeH));
    return convertedChildList;
}
Also used : SqlBinaryOperator(org.apache.calcite.sql.SqlBinaryOperator) RexNode(org.apache.calcite.rex.RexNode)

Example 3 with SqlBinaryOperator

use of org.apache.calcite.sql.SqlBinaryOperator in project hive by apache.

the class HiveFunctionHelper method getExpression.

/**
 * {@inheritDoc}
 */
@Override
public RexNode getExpression(String functionText, FunctionInfo fi, List<RexNode> inputs, RelDataType returnType) throws SemanticException {
    // See if this is an explicit cast.
    RexNode expr = RexNodeConverter.handleExplicitCast(fi.getGenericUDF(), returnType, inputs, rexBuilder);
    if (expr == null) {
        // This is not a cast; process the function.
        ImmutableList.Builder<RelDataType> argsTypes = ImmutableList.builder();
        for (RexNode input : inputs) {
            argsTypes.add(input.getType());
        }
        SqlOperator calciteOp = SqlFunctionConverter.getCalciteOperator(functionText, fi.getGenericUDF(), argsTypes.build(), returnType);
        if (calciteOp.getKind() == SqlKind.CASE) {
            // If it is a case operator, we need to rewrite it
            inputs = RexNodeConverter.rewriteCaseChildren(functionText, inputs, rexBuilder);
            // Adjust branch types by inserting explicit casts if the actual is ambiguous
            inputs = RexNodeConverter.adjustCaseBranchTypes(inputs, returnType, rexBuilder);
            checkForStatefulFunctions(inputs);
        } else if (HiveExtractDate.ALL_FUNCTIONS.contains(calciteOp)) {
            // If it is a extract operator, we need to rewrite it
            inputs = RexNodeConverter.rewriteExtractDateChildren(calciteOp, inputs, rexBuilder);
        } else if (HiveFloorDate.ALL_FUNCTIONS.contains(calciteOp)) {
            // If it is a floor <date> operator, we need to rewrite it
            inputs = RexNodeConverter.rewriteFloorDateChildren(calciteOp, inputs, rexBuilder);
        } else if (calciteOp.getKind() == SqlKind.IN) {
            // if it is a single item in an IN clause, transform A IN (B) to A = B
            // from IN [A,B] => EQUALS [A,B]
            // if it is more than an single item in an IN clause,
            // transform from IN [A,B,C] => OR [EQUALS [A,B], EQUALS [A,C]]
            // Rewrite to OR is done only if number of operands are less than
            // the threshold configured
            boolean rewriteToOr = true;
            if (maxNodesForInToOrTransformation != 0) {
                if (inputs.size() > maxNodesForInToOrTransformation) {
                    rewriteToOr = false;
                }
            }
            if (rewriteToOr) {
                // If there are non-deterministic functions, we cannot perform this rewriting
                List<RexNode> newInputs = RexNodeConverter.transformInToOrOperands(inputs, rexBuilder);
                if (newInputs != null) {
                    inputs = newInputs;
                    if (inputs.size() == 1) {
                        inputs.add(rexBuilder.makeLiteral(false));
                    }
                    calciteOp = SqlStdOperatorTable.OR;
                }
            }
        } else if (calciteOp.getKind() == SqlKind.COALESCE && inputs.size() > 1) {
            // Rewrite COALESCE as a CASE
            // This allows to be further reduced to OR, if possible
            calciteOp = SqlStdOperatorTable.CASE;
            inputs = RexNodeConverter.rewriteCoalesceChildren(inputs, rexBuilder);
            // Adjust branch types by inserting explicit casts if the actual is ambiguous
            inputs = RexNodeConverter.adjustCaseBranchTypes(inputs, returnType, rexBuilder);
            checkForStatefulFunctions(inputs);
        } else if (calciteOp == HiveToDateSqlOperator.INSTANCE) {
            inputs = RexNodeConverter.rewriteToDateChildren(inputs, rexBuilder);
        } else if (calciteOp.getKind() == SqlKind.BETWEEN) {
            assert inputs.get(0).isAlwaysTrue() || inputs.get(0).isAlwaysFalse();
            boolean invert = inputs.get(0).isAlwaysTrue();
            SqlBinaryOperator cmpOp;
            if (invert) {
                calciteOp = SqlStdOperatorTable.OR;
                cmpOp = SqlStdOperatorTable.GREATER_THAN;
            } else {
                calciteOp = SqlStdOperatorTable.AND;
                cmpOp = SqlStdOperatorTable.LESS_THAN_OR_EQUAL;
            }
            RexNode op = inputs.get(1);
            RexNode rangeL = inputs.get(2);
            RexNode rangeH = inputs.get(3);
            inputs = new ArrayList<>();
            inputs.add(rexBuilder.makeCall(cmpOp, rangeL, op));
            inputs.add(rexBuilder.makeCall(cmpOp, op, rangeH));
        } else if (calciteOp == HiveUnixTimestampSqlOperator.INSTANCE && inputs.size() > 0) {
            // unix_timestamp(args) -> to_unix_timestamp(args)
            calciteOp = HiveToUnixTimestampSqlOperator.INSTANCE;
        }
        expr = rexBuilder.makeCall(returnType, calciteOp, inputs);
    }
    if (expr instanceof RexCall && !expr.isA(SqlKind.CAST)) {
        RexCall call = (RexCall) expr;
        expr = rexBuilder.makeCall(returnType, call.getOperator(), RexUtil.flatten(call.getOperands(), call.getOperator()));
    }
    return expr;
}
Also used : RexCall(org.apache.calcite.rex.RexCall) SqlBinaryOperator(org.apache.calcite.sql.SqlBinaryOperator) ImmutableList(com.google.common.collect.ImmutableList) HiveUnixTimestampSqlOperator(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveUnixTimestampSqlOperator) HiveToUnixTimestampSqlOperator(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveToUnixTimestampSqlOperator) SqlOperator(org.apache.calcite.sql.SqlOperator) HiveToDateSqlOperator(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveToDateSqlOperator) RelDataType(org.apache.calcite.rel.type.RelDataType) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) RexNode(org.apache.calcite.rex.RexNode)

Example 4 with SqlBinaryOperator

use of org.apache.calcite.sql.SqlBinaryOperator in project drill by apache.

the class FindPartitionConditions method popOpStackAndBuildFilter.

/*
   * Pop the current operation from the stack (opStack) as we are done with it.
   * If it has children, then it means the current OP itself is a PUSH
   * and hence add itself as a child to the parent OP. If no more parents
   * remains, it means that the current OP is the root condition and
   * set the root condition in that case.
   */
private void popOpStackAndBuildFilter() {
    // Parsing a special expression; handled holistically by the parent
    if (holisticExpression > 0) {
        return;
    }
    OpState currentOp = opStack.pop();
    int size = currentOp.getChildren().size();
    RexNode newFilter = null;
    if (size >= 1) {
        if (size == 1 && currentOp.getOp() instanceof SqlBinaryOperator) {
            /* The only operator for which we allow partial pushes is AND.
         * For all other operators we clear the children if one of the
         * children is a no push.
         */
            if (currentOp.getOp().getKind() == SqlKind.AND) {
                newFilter = currentOp.getChildren().get(0);
                for (OpState opState : opStack) {
                    if (opState.getOp().getKind() == SqlKind.NOT) {
                        // AND under NOT should not get pushed
                        newFilter = null;
                    }
                }
            }
        } else {
            newFilter = builder.makeCall(currentOp.getOp(), currentOp.getChildren());
        }
    }
    if (newFilter != null) {
        // add this new filter to my parent boolean operator's children
        if (!opStack.isEmpty()) {
            OpState parentOp = opStack.peek();
            parentOp.addChild(newFilter);
        } else {
            resultCondition = newFilter;
        }
    }
}
Also used : SqlBinaryOperator(org.apache.calcite.sql.SqlBinaryOperator) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexNode (org.apache.calcite.rex.RexNode)4 SqlBinaryOperator (org.apache.calcite.sql.SqlBinaryOperator)4 ImmutableList (com.google.common.collect.ImmutableList)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 RelDataType (org.apache.calcite.rel.type.RelDataType)1 RexCall (org.apache.calcite.rex.RexCall)1 SqlOperator (org.apache.calcite.sql.SqlOperator)1 HiveToDateSqlOperator (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveToDateSqlOperator)1 HiveToUnixTimestampSqlOperator (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveToUnixTimestampSqlOperator)1 HiveUnixTimestampSqlOperator (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveUnixTimestampSqlOperator)1