Search in sources :

Example 46 with RexCall

use of org.apache.calcite.rex.RexCall in project calcite by apache.

the class ReduceExpressionsRule method pushPredicateIntoCase.

/**
 * Pushes predicates into a CASE.
 *
 * <p>We have a loose definition of 'predicate': any boolean expression will
 * do, except CASE. For example '(CASE ...) = 5' or '(CASE ...) IS NULL'.
 */
public static RexCall pushPredicateIntoCase(RexCall call) {
    if (call.getType().getSqlTypeName() != SqlTypeName.BOOLEAN) {
        return call;
    }
    switch(call.getKind()) {
        case CASE:
        case AND:
        case OR:
            // don't push CASE into CASE!
            return call;
        case EQUALS:
            {
                // checks that the EQUALS operands may be splitted and
                // doesn't push EQUALS into CASE
                List<RexNode> equalsOperands = call.getOperands();
                ImmutableBitSet left = RelOptUtil.InputFinder.bits(equalsOperands.get(0));
                ImmutableBitSet right = RelOptUtil.InputFinder.bits(equalsOperands.get(1));
                if (!left.isEmpty() && !right.isEmpty() && left.intersect(right).isEmpty()) {
                    return call;
                }
            }
    }
    int caseOrdinal = -1;
    final List<RexNode> operands = call.getOperands();
    for (int i = 0; i < operands.size(); i++) {
        RexNode operand = operands.get(i);
        switch(operand.getKind()) {
            case CASE:
                caseOrdinal = i;
        }
    }
    if (caseOrdinal < 0) {
        return call;
    }
    // Convert
    // f(CASE WHEN p1 THEN v1 ... END, arg)
    // to
    // CASE WHEN p1 THEN f(v1, arg) ... END
    final RexCall case_ = (RexCall) operands.get(caseOrdinal);
    final List<RexNode> nodes = new ArrayList<>();
    for (int i = 0; i < case_.getOperands().size(); i++) {
        RexNode node = case_.getOperands().get(i);
        if (!RexUtil.isCasePredicate(case_, i)) {
            node = substitute(call, caseOrdinal, node);
        }
        nodes.add(node);
    }
    return case_.clone(call.getType(), nodes);
}
Also used : RexCall(org.apache.calcite.rex.RexCall) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) List(java.util.List) ArrayList(java.util.ArrayList) RexNode(org.apache.calcite.rex.RexNode)

Example 47 with RexCall

use of org.apache.calcite.rex.RexCall in project calcite by apache.

the class SortProjectTransposeRule method onMatch.

// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
    final Sort sort = call.rel(0);
    final Project project = call.rel(1);
    final RelOptCluster cluster = project.getCluster();
    if (sort.getConvention() != project.getConvention()) {
        return;
    }
    // Determine mapping between project input and output fields. If sort
    // relies on non-trivial expressions, we can't push.
    final Mappings.TargetMapping map = RelOptUtil.permutationIgnoreCast(project.getProjects(), project.getInput().getRowType());
    for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) {
        if (map.getTargetOpt(fc.getFieldIndex()) < 0) {
            return;
        }
        final RexNode node = project.getProjects().get(fc.getFieldIndex());
        if (node.isA(SqlKind.CAST)) {
            // Check whether it is a monotonic preserving cast, otherwise we cannot push
            final RexCall cast = (RexCall) node;
            final RexCallBinding binding = RexCallBinding.create(cluster.getTypeFactory(), cast, ImmutableList.of(RelCollations.of(RexUtil.apply(map, fc))));
            if (cast.getOperator().getMonotonicity(binding) == SqlMonotonicity.NOT_MONOTONIC) {
                return;
            }
        }
    }
    final RelCollation newCollation = cluster.traitSet().canonize(RexUtil.apply(map, sort.getCollation()));
    final Sort newSort = sort.copy(sort.getTraitSet().replace(newCollation), project.getInput(), newCollation, sort.offset, sort.fetch);
    RelNode newProject = project.copy(sort.getTraitSet(), ImmutableList.<RelNode>of(newSort));
    // Not only is newProject equivalent to sort;
    // newSort is equivalent to project's input
    // (but only if the sort is not also applying an offset/limit).
    Map<RelNode, RelNode> equiv;
    if (sort.offset == null && sort.fetch == null && cluster.getPlanner().getRelTraitDefs().contains(RelCollationTraitDef.INSTANCE)) {
        equiv = ImmutableMap.of((RelNode) newSort, project.getInput());
    } else {
        equiv = ImmutableMap.of();
    }
    call.transformTo(newProject, equiv);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RexCall(org.apache.calcite.rex.RexCall) Project(org.apache.calcite.rel.core.Project) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexCallBinding(org.apache.calcite.rex.RexCallBinding) RelCollation(org.apache.calcite.rel.RelCollation) Mappings(org.apache.calcite.util.mapping.Mappings) RelNode(org.apache.calcite.rel.RelNode) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) Sort(org.apache.calcite.rel.core.Sort) RexNode(org.apache.calcite.rex.RexNode)

Example 48 with RexCall

use of org.apache.calcite.rex.RexCall in project calcite by apache.

the class ExtractOperatorConversion method toDruidExpression.

@Override
public String toDruidExpression(RexNode rexNode, RelDataType rowType, DruidQuery query) {
    final RexCall call = (RexCall) rexNode;
    final RexLiteral flag = (RexLiteral) call.getOperands().get(0);
    final TimeUnitRange calciteUnit = (TimeUnitRange) flag.getValue();
    final RexNode arg = call.getOperands().get(1);
    final String input = DruidExpressions.toDruidExpression(arg, rowType, query);
    if (input == null) {
        return null;
    }
    final String druidUnit = EXTRACT_UNIT_MAP.get(calciteUnit);
    if (druidUnit == null) {
        return null;
    }
    return DruidExpressions.applyTimeExtract(input, druidUnit, TimeZone.getTimeZone(query.getConnectionConfig().timeZone()));
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexLiteral(org.apache.calcite.rex.RexLiteral) TimeUnitRange(org.apache.calcite.avatica.util.TimeUnitRange) RexNode(org.apache.calcite.rex.RexNode)

Example 49 with RexCall

use of org.apache.calcite.rex.RexCall in project calcite by apache.

the class NaryOperatorConverter method toDruidExpression.

@Nullable
@Override
public String toDruidExpression(RexNode rexNode, RelDataType rowType, DruidQuery druidQuery) {
    final RexCall call = (RexCall) rexNode;
    final List<String> druidExpressions = DruidExpressions.toDruidExpressions(druidQuery, rowType, call.getOperands());
    if (druidExpressions == null) {
        return null;
    }
    return DruidExpressions.nAryOperatorCall(druidOperatorName, druidExpressions);
}
Also used : RexCall(org.apache.calcite.rex.RexCall) Nullable(javax.annotation.Nullable)

Example 50 with RexCall

use of org.apache.calcite.rex.RexCall in project drill by axbaretto.

the class DrillRelOptUtil method findOperators.

/**
 * Travesal RexNode to find at least one operator in the given collection. Continue search if RexNode has a
 * RexInputRef which refers to a RexNode in project expressions.
 *
 * @param node : RexNode to search
 * @param projExprs : the list of project expressions. Empty list means there is No project operator underneath.
 * @param operators collection of operators to find
 * @return : Return null if there is NONE; return the first appearance of item/flatten RexCall.
 */
public static RexCall findOperators(final RexNode node, final List<RexNode> projExprs, final Collection<String> operators) {
    try {
        RexVisitor<Void> visitor = new RexVisitorImpl<Void>(true) {

            public Void visitCall(RexCall call) {
                if (operators.contains(call.getOperator().getName().toLowerCase())) {
                    throw new Util.FoundOne(call);
                /* throw exception to interrupt tree walk (this is similar to
                                              other utility methods in RexUtil.java */
                }
                return super.visitCall(call);
            }

            public Void visitInputRef(RexInputRef inputRef) {
                if (projExprs.size() == 0) {
                    return super.visitInputRef(inputRef);
                } else {
                    final int index = inputRef.getIndex();
                    RexNode n = projExprs.get(index);
                    if (n instanceof RexCall) {
                        RexCall r = (RexCall) n;
                        if (operators.contains(r.getOperator().getName().toLowerCase())) {
                            throw new Util.FoundOne(r);
                        }
                    }
                    return super.visitInputRef(inputRef);
                }
            }
        };
        node.accept(visitor);
        return null;
    } catch (Util.FoundOne e) {
        Util.swallow(e, null);
        return (RexCall) e.getNode();
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexInputRef(org.apache.calcite.rex.RexInputRef) RelOptUtil(org.apache.calcite.plan.RelOptUtil) SqlValidatorUtil(org.apache.calcite.sql.validate.SqlValidatorUtil) Util(org.apache.calcite.util.Util) RexVisitorImpl(org.apache.calcite.rex.RexVisitorImpl) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexCall (org.apache.calcite.rex.RexCall)213 RexNode (org.apache.calcite.rex.RexNode)172 RexInputRef (org.apache.calcite.rex.RexInputRef)61 ArrayList (java.util.ArrayList)59 RexLiteral (org.apache.calcite.rex.RexLiteral)44 Nullable (javax.annotation.Nullable)35 RelNode (org.apache.calcite.rel.RelNode)26 RelDataType (org.apache.calcite.rel.type.RelDataType)24 SqlOperator (org.apache.calcite.sql.SqlOperator)23 List (java.util.List)22 RexBuilder (org.apache.calcite.rex.RexBuilder)22 DruidExpression (org.apache.druid.sql.calcite.expression.DruidExpression)19 SqlKind (org.apache.calcite.sql.SqlKind)14 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)14 RelOptUtil (org.apache.calcite.plan.RelOptUtil)11 PostAggregator (org.apache.druid.query.aggregation.PostAggregator)11 RexCall (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall)10 RexTableInputRef (org.apache.calcite.rex.RexTableInputRef)10 TimeUnitRange (org.apache.calcite.avatica.util.TimeUnitRange)9 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)9