Search in sources :

Example 6 with RexSimplify

use of org.apache.calcite.rex.RexSimplify in project hive by apache.

the class HiveFilterSetOpTransposeRule method onMatch.

// ~ Methods ----------------------------------------------------------------
// implement RelOptRule
// We override the rule in order to do union all branch elimination
public void onMatch(RelOptRuleCall call) {
    Filter filterRel = call.rel(0);
    SetOp setOp = call.rel(1);
    RexNode condition = filterRel.getCondition();
    // create filters on top of each setop child, modifying the filter
    // condition to reference each setop child
    RexBuilder rexBuilder = filterRel.getCluster().getRexBuilder();
    final RelBuilder relBuilder = call.builder();
    List<RelDataTypeField> origFields = setOp.getRowType().getFieldList();
    int[] adjustments = new int[origFields.size()];
    final List<RelNode> newSetOpInputs = new ArrayList<>();
    RelNode lastInput = null;
    for (int index = 0; index < setOp.getInputs().size(); index++) {
        RelNode input = setOp.getInput(index);
        RexNode newCondition = condition.accept(new RelOptUtil.RexInputConverter(rexBuilder, origFields, input.getRowType().getFieldList(), adjustments));
        if (setOp instanceof Union && setOp.all) {
            final RelMetadataQuery mq = call.getMetadataQuery();
            final RelOptPredicateList predicates = mq.getPulledUpPredicates(input);
            if (predicates != null) {
                ImmutableList.Builder<RexNode> listBuilder = ImmutableList.builder();
                listBuilder.addAll(predicates.pulledUpPredicates);
                listBuilder.add(newCondition);
                RexExecutor executor = Util.first(filterRel.getCluster().getPlanner().getExecutor(), RexUtil.EXECUTOR);
                final RexSimplify simplify = new RexSimplify(rexBuilder, RelOptPredicateList.EMPTY, executor);
                final RexNode cond = RexUtil.composeConjunction(rexBuilder, listBuilder.build());
                final RexNode x = simplify.simplifyUnknownAs(cond, RexUnknownAs.FALSE);
                if (x.isAlwaysFalse()) {
                    // branch so it won't read any data.
                    if (index == setOp.getInputs().size() - 1) {
                        lastInput = relBuilder.push(input).filter(newCondition).build();
                    }
                    // remove this branch
                    continue;
                }
            }
        }
        newSetOpInputs.add(relBuilder.push(input).filter(newCondition).build());
    }
    if (newSetOpInputs.size() > 1) {
        // create a new setop whose children are the filters created above
        SetOp newSetOp = setOp.copy(setOp.getTraitSet(), newSetOpInputs);
        call.transformTo(newSetOp);
    } else {
        // We have to keep at least a branch before we support empty values() in Hive
        RelNode result = newSetOpInputs.size() == 1 ? newSetOpInputs.get(0) : lastInput;
        call.transformTo(relBuilder.push(result).convert(filterRel.getRowType(), false).build());
    }
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) SetOp(org.apache.calcite.rel.core.SetOp) RelBuilder(org.apache.calcite.tools.RelBuilder) ImmutableList(com.google.common.collect.ImmutableList) RelOptUtil(org.apache.calcite.plan.RelOptUtil) ArrayList(java.util.ArrayList) Union(org.apache.calcite.rel.core.Union) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) Filter(org.apache.calcite.rel.core.Filter) RexSimplify(org.apache.calcite.rex.RexSimplify) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) RexExecutor(org.apache.calcite.rex.RexExecutor) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 7 with RexSimplify

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

the class ReduceExpressionsRule method reduceExpressions.

/**
 * Reduces a list of expressions.
 *
 * <p>The {@code matchNullability} flag comes into play when reducing a
 * expression whose type is nullable. Suppose we are reducing an expression
 * {@code CASE WHEN 'a' = 'a' THEN 1 ELSE NULL END}. Before reduction the
 * type is {@code INTEGER} (nullable), but after reduction the literal 1 has
 * type {@code INTEGER NOT NULL}.
 *
 * <p>In some situations it is more important to preserve types; in this
 * case you should use {@code matchNullability = true} (which used to be
 * the default behavior of this method), and it will cast the literal to
 * {@code INTEGER} (nullable).
 *
 * <p>In other situations, you would rather propagate the new stronger type,
 * because it may allow further optimizations later; pass
 * {@code matchNullability = false} and no cast will be added, but you may
 * need to adjust types elsewhere in the expression tree.
 *
 * @param rel     Relational expression
 * @param expList List of expressions, modified in place
 * @param predicates Constraints known to hold on input expressions
 * @param unknownAsFalse Whether UNKNOWN will be treated as FALSE
 * @param matchNullability Whether Calcite should add a CAST to a literal
 *                         resulting from simplification and expression if the
 *                         expression had nullable type and the literal is
 *                         NOT NULL
 *
 * @return whether reduction found something to change, and succeeded
 */
protected static boolean reduceExpressions(RelNode rel, List<RexNode> expList, RelOptPredicateList predicates, boolean unknownAsFalse, boolean matchNullability) {
    final RelOptCluster cluster = rel.getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    final RexExecutor executor = Util.first(cluster.getPlanner().getExecutor(), RexUtil.EXECUTOR);
    final RexSimplify simplify = new RexSimplify(rexBuilder, predicates, unknownAsFalse, executor);
    // Simplify predicates in place
    boolean reduced = reduceExpressionsInternal(rel, simplify, expList, predicates);
    final ExprSimplifier simplifier = new ExprSimplifier(simplify, matchNullability);
    boolean simplified = false;
    for (int i = 0; i < expList.size(); i++) {
        RexNode expr2 = simplifier.apply(expList.get(i));
        if (!expr2.toString().equals(expList.get(i).toString())) {
            expList.remove(i);
            expList.add(i, expr2);
            simplified = true;
        }
    }
    return reduced || simplified;
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RexSimplify(org.apache.calcite.rex.RexSimplify) RexExecutor(org.apache.calcite.rex.RexExecutor) RexBuilder(org.apache.calcite.rex.RexBuilder) ExprSimplifier(org.apache.calcite.rex.RexUtil.ExprSimplifier) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexBuilder (org.apache.calcite.rex.RexBuilder)7 RexSimplify (org.apache.calcite.rex.RexSimplify)7 RexExecutor (org.apache.calcite.rex.RexExecutor)6 RelOptPredicateList (org.apache.calcite.plan.RelOptPredicateList)5 RelNode (org.apache.calcite.rel.RelNode)4 RexNode (org.apache.calcite.rex.RexNode)4 ArrayList (java.util.ArrayList)3 RelOptCluster (org.apache.calcite.plan.RelOptCluster)3 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)3 ImmutableList (com.google.common.collect.ImmutableList)2 RelBuilder (org.apache.calcite.tools.RelBuilder)2 BiMap (com.google.common.collect.BiMap)1 HashBiMap (com.google.common.collect.HashBiMap)1 Type (java.lang.reflect.Type)1 HashMap (java.util.HashMap)1 List (java.util.List)1 JavaTypeFactory (org.apache.calcite.adapter.java.JavaTypeFactory)1 JavaTypeFactoryImpl (org.apache.calcite.jdbc.JavaTypeFactoryImpl)1 Enumerator (org.apache.calcite.linq4j.Enumerator)1 BlockBuilder (org.apache.calcite.linq4j.tree.BlockBuilder)1