Search in sources :

Example 1 with RexInputRef

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

the class HivePreFilteringRule method extractCommonOperands.

private static List<RexNode> extractCommonOperands(RexBuilder rexBuilder, RexNode condition, int maxCNFNodeCount) {
    assert condition.getKind() == SqlKind.OR;
    Multimap<String, RexNode> reductionCondition = LinkedHashMultimap.create();
    // Data structure to control whether a certain reference is present in every
    // operand
    Set<String> refsInAllOperands = null;
    // 1. We extract the information necessary to create the predicate for the
    // new filter; currently we support comparison functions, in and between
    ImmutableList<RexNode> operands = RexUtil.flattenOr(((RexCall) condition).getOperands());
    for (int i = 0; i < operands.size(); i++) {
        final RexNode operand = operands.get(i);
        final RexNode operandCNF = RexUtil.toCnf(rexBuilder, maxCNFNodeCount, operand);
        final List<RexNode> conjunctions = RelOptUtil.conjunctions(operandCNF);
        Set<String> refsInCurrentOperand = Sets.newHashSet();
        for (RexNode conjunction : conjunctions) {
            // We do not know what it is, we bail out for safety
            if (!(conjunction instanceof RexCall) || !HiveCalciteUtil.isDeterministic(conjunction)) {
                return new ArrayList<>();
            }
            RexCall conjCall = (RexCall) conjunction;
            RexNode ref = null;
            if (COMPARISON.contains(conjCall.getOperator().getKind())) {
                if (conjCall.operands.get(0) instanceof RexInputRef && conjCall.operands.get(1) instanceof RexLiteral) {
                    ref = conjCall.operands.get(0);
                } else if (conjCall.operands.get(1) instanceof RexInputRef && conjCall.operands.get(0) instanceof RexLiteral) {
                    ref = conjCall.operands.get(1);
                } else {
                    // We do not know what it is, we bail out for safety
                    return new ArrayList<>();
                }
            } else if (conjCall.getOperator().getKind().equals(SqlKind.IN)) {
                ref = conjCall.operands.get(0);
            } else if (conjCall.getOperator().getKind().equals(SqlKind.BETWEEN)) {
                ref = conjCall.operands.get(1);
            } else {
                // We do not know what it is, we bail out for safety
                return new ArrayList<>();
            }
            String stringRef = ref.toString();
            reductionCondition.put(stringRef, conjCall);
            refsInCurrentOperand.add(stringRef);
        }
        // Updates the references that are present in every operand up till now
        if (i == 0) {
            refsInAllOperands = refsInCurrentOperand;
        } else {
            refsInAllOperands = Sets.intersection(refsInAllOperands, refsInCurrentOperand);
        }
        // bail out
        if (refsInAllOperands.isEmpty()) {
            return new ArrayList<>();
        }
    }
    // 2. We gather the common factors and return them
    List<RexNode> commonOperands = new ArrayList<>();
    for (String ref : refsInAllOperands) {
        commonOperands.add(RexUtil.composeDisjunction(rexBuilder, reductionCondition.get(ref), false));
    }
    return commonOperands;
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexLiteral(org.apache.calcite.rex.RexLiteral) ArrayList(java.util.ArrayList) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 2 with RexInputRef

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

the class HiveOpConverter method createColInfos.

private static Pair<ArrayList<ColumnInfo>, Set<Integer>> createColInfos(List<RexNode> calciteExprs, List<ExprNodeDesc> hiveExprs, List<String> projNames, OpAttr inpOpAf) {
    if (hiveExprs.size() != projNames.size()) {
        throw new RuntimeException("Column expressions list doesn't match Column Names list");
    }
    RexNode rexN;
    ExprNodeDesc pe;
    ArrayList<ColumnInfo> colInfos = new ArrayList<ColumnInfo>();
    boolean vc;
    Set<Integer> newVColSet = new HashSet<Integer>();
    for (int i = 0; i < hiveExprs.size(); i++) {
        pe = hiveExprs.get(i);
        rexN = calciteExprs.get(i);
        vc = false;
        if (rexN instanceof RexInputRef) {
            if (inpOpAf.vcolsInCalcite.contains(((RexInputRef) rexN).getIndex())) {
                newVColSet.add(i);
                vc = true;
            }
        }
        colInfos.add(new ColumnInfo(projNames.get(i), pe.getTypeInfo(), inpOpAf.tabAlias, vc));
    }
    return new Pair<ArrayList<ColumnInfo>, Set<Integer>>(colInfos, newVColSet);
}
Also used : ArrayList(java.util.ArrayList) ColumnInfo(org.apache.hadoop.hive.ql.exec.ColumnInfo) RexInputRef(org.apache.calcite.rex.RexInputRef) ExprNodeDesc(org.apache.hadoop.hive.ql.plan.ExprNodeDesc) RexNode(org.apache.calcite.rex.RexNode) HashSet(java.util.HashSet) Pair(org.apache.calcite.util.Pair)

Example 3 with RexInputRef

use of org.apache.calcite.rex.RexInputRef in project flink by apache.

the class FlinkAggregateExpandDistinctAggregatesRule method createSelectDistinct.

/**
	 * Given an {@link org.apache.calcite.rel.logical.LogicalAggregate}
	 * and the ordinals of the arguments to a
	 * particular call to an aggregate function, creates a 'select distinct'
	 * relational expression which projects the group columns and those
	 * arguments but nothing else.
	 *
	 * <p>For example, given
	 *
	 * <blockquote>
	 * <pre>select f0, count(distinct f1), count(distinct f2)
	 * from t group by f0</pre>
	 * </blockquote>
	 *
	 * and the argument list
	 *
	 * <blockquote>{2}</blockquote>
	 *
	 * returns
	 *
	 * <blockquote>
	 * <pre>select distinct f0, f2 from t</pre>
	 * </blockquote>
	 *
	 * '
	 *
	 * <p>The <code>sourceOf</code> map is populated with the source of each
	 * column; in this case sourceOf.get(0) = 0, and sourceOf.get(1) = 2.</p>
	 *
	 * @param relBuilder Relational expression builder
	 * @param aggregate Aggregate relational expression
	 * @param argList   Ordinals of columns to make distinct
	 * @param filterArg Ordinal of column to filter on, or -1
	 * @param sourceOf  Out parameter, is populated with a map of where each
	 *				  output field came from
	 * @return Aggregate relational expression which projects the required
	 * columns
	 */
private RelBuilder createSelectDistinct(RelBuilder relBuilder, Aggregate aggregate, List<Integer> argList, int filterArg, Map<Integer, Integer> sourceOf) {
    relBuilder.push(aggregate.getInput());
    final List<Pair<RexNode, String>> projects = new ArrayList<>();
    final List<RelDataTypeField> childFields = relBuilder.peek().getRowType().getFieldList();
    for (int i : aggregate.getGroupSet()) {
        sourceOf.put(i, projects.size());
        projects.add(RexInputRef.of2(i, childFields));
    }
    for (Integer arg : argList) {
        if (filterArg >= 0) {
            // Implement
            //   agg(DISTINCT arg) FILTER $f
            // by generating
            //   SELECT DISTINCT ... CASE WHEN $f THEN arg ELSE NULL END AS arg
            // and then applying
            //   agg(arg)
            // as usual.
            //
            // It works except for (rare) agg functions that need to see null
            // values.
            final RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder();
            final RexInputRef filterRef = RexInputRef.of(filterArg, childFields);
            final Pair<RexNode, String> argRef = RexInputRef.of2(arg, childFields);
            RexNode condition = rexBuilder.makeCall(SqlStdOperatorTable.CASE, filterRef, argRef.left, rexBuilder.ensureType(argRef.left.getType(), rexBuilder.constantNull(), true));
            sourceOf.put(arg, projects.size());
            projects.add(Pair.of(condition, "i$" + argRef.right));
            continue;
        }
        if (sourceOf.get(arg) != null) {
            continue;
        }
        sourceOf.put(arg, projects.size());
        projects.add(RexInputRef.of2(arg, childFields));
    }
    relBuilder.project(Pair.left(projects), Pair.right(projects));
    // Get the distinct values of the GROUP BY fields and the arguments
    // to the agg functions.
    relBuilder.push(aggregate.copy(aggregate.getTraitSet(), relBuilder.build(), false, ImmutableBitSet.range(projects.size()), null, ImmutableList.<AggregateCall>of()));
    return relBuilder;
}
Also used : ArrayList(java.util.ArrayList) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) Pair(org.apache.calcite.util.Pair) RexNode(org.apache.calcite.rex.RexNode)

Example 4 with RexInputRef

use of org.apache.calcite.rex.RexInputRef in project flink by apache.

the class FlinkAggregateJoinTransposeRule method populateEquivalences.

private static void populateEquivalences(Map<Integer, BitSet> equivalence, RexNode predicate) {
    switch(predicate.getKind()) {
        case EQUALS:
            RexCall call = (RexCall) predicate;
            final List<RexNode> operands = call.getOperands();
            if (operands.get(0) instanceof RexInputRef) {
                final RexInputRef ref0 = (RexInputRef) operands.get(0);
                if (operands.get(1) instanceof RexInputRef) {
                    final RexInputRef ref1 = (RexInputRef) operands.get(1);
                    populateEquivalence(equivalence, ref0.getIndex(), ref1.getIndex());
                    populateEquivalence(equivalence, ref1.getIndex(), ref0.getIndex());
                }
            }
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 5 with RexInputRef

use of org.apache.calcite.rex.RexInputRef in project flink by apache.

the class FlinkRelDecorrelator method getNewForOldInputRef.

private RexInputRef getNewForOldInputRef(RexInputRef oldInputRef) {
    assert currentRel != null;
    int oldOrdinal = oldInputRef.getIndex();
    int newOrdinal = 0;
    // determine which input rel oldOrdinal references, and adjust
    // oldOrdinal to be relative to that input rel
    RelNode oldInput = null;
    for (RelNode oldInput0 : currentRel.getInputs()) {
        RelDataType oldInputType = oldInput0.getRowType();
        int n = oldInputType.getFieldCount();
        if (oldOrdinal < n) {
            oldInput = oldInput0;
            break;
        }
        RelNode newInput = map.get(oldInput0).r;
        newOrdinal += newInput.getRowType().getFieldCount();
        oldOrdinal -= n;
    }
    assert oldInput != null;
    final Frame frame = map.get(oldInput);
    assert frame != null;
    // now oldOrdinal is relative to oldInput
    int oldLocalOrdinal = oldOrdinal;
    // figure out the newLocalOrdinal, relative to the newInput.
    int newLocalOrdinal = oldLocalOrdinal;
    if (!frame.oldToNewOutputPos.isEmpty()) {
        newLocalOrdinal = frame.oldToNewOutputPos.get(oldLocalOrdinal);
    }
    newOrdinal += newLocalOrdinal;
    return new RexInputRef(newOrdinal, frame.r.getRowType().getFieldList().get(newLocalOrdinal).getType());
}
Also used : RelNode(org.apache.calcite.rel.RelNode) RexInputRef(org.apache.calcite.rex.RexInputRef) RelDataType(org.apache.calcite.rel.type.RelDataType)

Aggregations

RexInputRef (org.apache.calcite.rex.RexInputRef)241 RexNode (org.apache.calcite.rex.RexNode)200 ArrayList (java.util.ArrayList)103 RelNode (org.apache.calcite.rel.RelNode)85 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)80 RexCall (org.apache.calcite.rex.RexCall)67 RelDataType (org.apache.calcite.rel.type.RelDataType)63 RexBuilder (org.apache.calcite.rex.RexBuilder)54 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)52 HashMap (java.util.HashMap)47 AggregateCall (org.apache.calcite.rel.core.AggregateCall)36 List (java.util.List)35 HashSet (java.util.HashSet)32 Pair (org.apache.calcite.util.Pair)32 RexLiteral (org.apache.calcite.rex.RexLiteral)29 Map (java.util.Map)24 RelOptUtil (org.apache.calcite.plan.RelOptUtil)24 Set (java.util.Set)20 ImmutableList (com.google.common.collect.ImmutableList)19 LinkedHashMap (java.util.LinkedHashMap)19