Search in sources :

Example 71 with RexNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode in project calcite by apache.

the class RexToLixTranslator method translateConstructor.

public Expression translateConstructor(List<RexNode> operandList, SqlKind kind) {
    switch(kind) {
        case MAP_VALUE_CONSTRUCTOR:
            Expression map = list.append("map", Expressions.new_(LinkedHashMap.class), false);
            for (int i = 0; i < operandList.size(); i++) {
                RexNode key = operandList.get(i++);
                RexNode value = operandList.get(i);
                list.add(Expressions.statement(Expressions.call(map, BuiltInMethod.MAP_PUT.method, Expressions.box(translate(key)), Expressions.box(translate(value)))));
            }
            return map;
        case ARRAY_VALUE_CONSTRUCTOR:
            Expression lyst = list.append("list", Expressions.new_(ArrayList.class), false);
            for (RexNode value : operandList) {
                list.add(Expressions.statement(Expressions.call(lyst, BuiltInMethod.COLLECTION_ADD.method, Expressions.box(translate(value)))));
            }
            return lyst;
        default:
            throw new AssertionError("unexpected: " + kind);
    }
}
Also used : Expression(org.apache.calcite.linq4j.tree.Expression) UnaryExpression(org.apache.calcite.linq4j.tree.UnaryExpression) ConstantExpression(org.apache.calcite.linq4j.tree.ConstantExpression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) RexNode(org.apache.calcite.rex.RexNode)

Example 72 with RexNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode in project calcite by apache.

the class EnumerableWindow method translateBound.

private Expression translateBound(RexToLixTranslator translator, ParameterExpression i_, Expression row_, Expression min_, Expression max_, Expression rows_, Group group, boolean lower, PhysType physType, Expression rowComparator, Expression keySelector, Expression keyComparator) {
    RexWindowBound bound = lower ? group.lowerBound : group.upperBound;
    if (bound.isUnbounded()) {
        return bound.isPreceding() ? min_ : max_;
    }
    if (group.isRows) {
        if (bound.isCurrentRow()) {
            return i_;
        }
        RexNode node = bound.getOffset();
        Expression offs = translator.translate(node);
        // Floating offset does not make sense since we refer to array index.
        // Nulls do not make sense as well.
        offs = RexToLixTranslator.convert(offs, int.class);
        Expression b = i_;
        if (bound.isFollowing()) {
            b = Expressions.add(b, offs);
        } else {
            b = Expressions.subtract(b, offs);
        }
        return b;
    }
    Expression searchLower = min_;
    Expression searchUpper = max_;
    if (bound.isCurrentRow()) {
        if (lower) {
            searchUpper = i_;
        } else {
            searchLower = i_;
        }
    }
    List<RelFieldCollation> fieldCollations = group.collation().getFieldCollations();
    if (bound.isCurrentRow() && fieldCollations.size() != 1) {
        return Expressions.call((lower ? BuiltInMethod.BINARY_SEARCH5_LOWER : BuiltInMethod.BINARY_SEARCH5_UPPER).method, rows_, row_, searchLower, searchUpper, keySelector, keyComparator);
    }
    assert fieldCollations.size() == 1 : "When using range window specification, ORDER BY should have" + " exactly one expression." + " Actual collation is " + group.collation();
    // isRange
    int orderKey = fieldCollations.get(0).getFieldIndex();
    RelDataType keyType = physType.getRowType().getFieldList().get(orderKey).getType();
    Type desiredKeyType = translator.typeFactory.getJavaClass(keyType);
    if (bound.getOffset() == null) {
        desiredKeyType = Primitive.box(desiredKeyType);
    }
    Expression val = translator.translate(new RexInputRef(orderKey, keyType), desiredKeyType);
    if (!bound.isCurrentRow()) {
        RexNode node = bound.getOffset();
        Expression offs = translator.translate(node);
        // TODO: support date + interval somehow
        if (bound.isFollowing()) {
            val = Expressions.add(val, offs);
        } else {
            val = Expressions.subtract(val, offs);
        }
    }
    return Expressions.call((lower ? BuiltInMethod.BINARY_SEARCH6_LOWER : BuiltInMethod.BINARY_SEARCH6_UPPER).method, rows_, val, searchLower, searchUpper, keySelector, keyComparator);
}
Also used : RelDataType(org.apache.calcite.rel.type.RelDataType) Type(java.lang.reflect.Type) BinaryExpression(org.apache.calcite.linq4j.tree.BinaryExpression) Expression(org.apache.calcite.linq4j.tree.Expression) ParameterExpression(org.apache.calcite.linq4j.tree.ParameterExpression) RexWindowBound(org.apache.calcite.rex.RexWindowBound) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexInputRef(org.apache.calcite.rex.RexInputRef) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 73 with RexNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode in project calcite by apache.

the class AbstractMaterializedViewRule method computeCompensationPredicates.

/**
 * We check whether the predicates in the source are contained in the predicates
 * in the target. The method treats separately the equi-column predicates, the
 * range predicates, and the rest of predicates.
 *
 * <p>If the containment is confirmed, we produce compensation predicates that
 * need to be added to the target to produce the results in the source. Thus,
 * if source and target expressions are equivalent, those predicates will be the
 * true constant.
 *
 * <p>In turn, if containment cannot be confirmed, the method returns null.
 */
private static Triple<RexNode, RexNode, RexNode> computeCompensationPredicates(RexBuilder rexBuilder, RexSimplify simplify, EquivalenceClasses sourceEC, Triple<RexNode, RexNode, RexNode> sourcePreds, EquivalenceClasses targetEC, Triple<RexNode, RexNode, RexNode> targetPreds, BiMap<RelTableRef, RelTableRef> sourceToTargetTableMapping) {
    final RexNode compensationColumnsEquiPred;
    final RexNode compensationRangePred;
    final RexNode compensationResidualPred;
    // 1. Establish relationship between source and target equivalence classes.
    // If every target equivalence class is not a subset of a source
    // equivalence class, we bail out.
    compensationColumnsEquiPred = generateEquivalenceClasses(rexBuilder, sourceEC, targetEC);
    if (compensationColumnsEquiPred == null) {
        // Cannot rewrite
        return null;
    }
    // 2. We check that range intervals for the source are contained in the target.
    // Compute compensating predicates.
    final RexNode queryRangePred = RexUtil.swapColumnReferences(rexBuilder, sourcePreds.getMiddle(), sourceEC.getEquivalenceClassesMap());
    final RexNode viewRangePred = RexUtil.swapTableColumnReferences(rexBuilder, targetPreds.getMiddle(), sourceToTargetTableMapping.inverse(), sourceEC.getEquivalenceClassesMap());
    compensationRangePred = SubstitutionVisitor.splitFilter(simplify, queryRangePred, viewRangePred);
    if (compensationRangePred == null) {
        // Cannot rewrite
        return null;
    }
    // 3. Finally, we check that residual predicates of the source are satisfied
    // within the target.
    // Compute compensating predicates.
    final RexNode queryResidualPred = RexUtil.swapColumnReferences(rexBuilder, sourcePreds.getRight(), sourceEC.getEquivalenceClassesMap());
    final RexNode viewResidualPred = RexUtil.swapTableColumnReferences(rexBuilder, targetPreds.getRight(), sourceToTargetTableMapping.inverse(), sourceEC.getEquivalenceClassesMap());
    compensationResidualPred = SubstitutionVisitor.splitFilter(simplify, queryResidualPred, viewResidualPred);
    if (compensationResidualPred == null) {
        // Cannot rewrite
        return null;
    }
    return ImmutableTriple.<RexNode, RexNode, RexNode>of(compensationColumnsEquiPred, compensationRangePred, compensationResidualPred);
}
Also used : RexNode(org.apache.calcite.rex.RexNode)

Example 74 with RexNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode in project calcite by apache.

the class AbstractMaterializedViewRule method generateEquivalenceClasses.

/**
 * Given the equi-column predicates of the source and the target and the
 * computed equivalence classes, it extracts possible mappings between
 * the equivalence classes.
 *
 * <p>If there is no mapping, it returns null. If there is a exact match,
 * it will return a compensation predicate that evaluates to true.
 * Finally, if a compensation predicate needs to be enforced on top of
 * the target to make the equivalences classes match, it returns that
 * compensation predicate.
 */
private static RexNode generateEquivalenceClasses(RexBuilder rexBuilder, EquivalenceClasses sourceEC, EquivalenceClasses targetEC) {
    if (sourceEC.getEquivalenceClasses().isEmpty() && targetEC.getEquivalenceClasses().isEmpty()) {
        // Empty mapping and compensation predicate
        return rexBuilder.makeLiteral(true);
    }
    if (sourceEC.getEquivalenceClasses().isEmpty() && !targetEC.getEquivalenceClasses().isEmpty()) {
        // No column equality predicates in source, but column equality predicates in target
        return null;
    }
    final List<Set<RexTableInputRef>> sourceEquivalenceClasses = sourceEC.getEquivalenceClasses();
    final List<Set<RexTableInputRef>> targetEquivalenceClasses = targetEC.getEquivalenceClasses();
    final Multimap<Integer, Integer> mapping = extractPossibleMapping(sourceEquivalenceClasses, targetEquivalenceClasses);
    if (mapping == null) {
        // bail out
        return null;
    }
    // Create the compensation predicate
    RexNode compensationPredicate = rexBuilder.makeLiteral(true);
    for (int i = 0; i < sourceEquivalenceClasses.size(); i++) {
        if (!mapping.containsKey(i)) {
            // Add all predicates
            Iterator<RexTableInputRef> it = sourceEquivalenceClasses.get(i).iterator();
            RexTableInputRef e0 = it.next();
            while (it.hasNext()) {
                RexNode equals = rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, e0, it.next());
                compensationPredicate = rexBuilder.makeCall(SqlStdOperatorTable.AND, compensationPredicate, equals);
            }
        } else {
            // Add only predicates that are not there
            for (int j : mapping.get(i)) {
                Set<RexTableInputRef> difference = new HashSet<>(sourceEquivalenceClasses.get(i));
                difference.removeAll(targetEquivalenceClasses.get(j));
                for (RexTableInputRef e : difference) {
                    RexNode equals = rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, e, targetEquivalenceClasses.get(j).iterator().next());
                    compensationPredicate = rexBuilder.makeCall(SqlStdOperatorTable.AND, compensationPredicate, equals);
                }
            }
        }
    }
    return compensationPredicate;
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) RexTableInputRef(org.apache.calcite.rex.RexTableInputRef) RelReferentialConstraint(org.apache.calcite.rel.RelReferentialConstraint) RexNode(org.apache.calcite.rex.RexNode) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 75 with RexNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode in project calcite by apache.

the class AbstractMaterializedViewRule method generateSwapTableColumnReferencesLineage.

/**
 * It swaps the table references and then the column references of the input
 * expressions using the table mapping and the equivalence classes.
 */
private static NodeLineage generateSwapTableColumnReferencesLineage(RexBuilder rexBuilder, RelMetadataQuery mq, RelNode node, BiMap<RelTableRef, RelTableRef> tableMapping, EquivalenceClasses ec, List<RexNode> nodeExprs) {
    Map<String, Integer> exprsLineage = new HashMap<>();
    Map<String, Integer> exprsLineageLosslessCasts = new HashMap<>();
    for (int i = 0; i < nodeExprs.size(); i++) {
        final Set<RexNode> s = mq.getExpressionLineage(node, nodeExprs.get(i));
        if (s == null) {
            // Next expression
            continue;
        }
        // a single expression
        assert s.size() == 1;
        // Rewrite expr. First we swap the table references following the table
        // mapping, then we take first element from the corresponding equivalence class
        final RexNode e = RexUtil.swapTableColumnReferences(rexBuilder, s.iterator().next(), tableMapping, ec.getEquivalenceClassesMap());
        exprsLineage.put(e.toString(), i);
        if (RexUtil.isLosslessCast(e)) {
            exprsLineageLosslessCasts.put(((RexCall) e).getOperands().get(0).toString(), i);
        }
    }
    return NodeLineage.of(exprsLineage, exprsLineageLosslessCasts);
}
Also used : HashMap(java.util.HashMap) RelReferentialConstraint(org.apache.calcite.rel.RelReferentialConstraint) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexNode (org.apache.calcite.rex.RexNode)1167 ArrayList (java.util.ArrayList)423 RelNode (org.apache.calcite.rel.RelNode)363 RelDataType (org.apache.calcite.rel.type.RelDataType)289 RexBuilder (org.apache.calcite.rex.RexBuilder)262 RexInputRef (org.apache.calcite.rex.RexInputRef)207 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)198 RexCall (org.apache.calcite.rex.RexCall)185 Test (org.junit.Test)138 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)136 RexLiteral (org.apache.calcite.rex.RexLiteral)104 HashMap (java.util.HashMap)102 List (java.util.List)97 AggregateCall (org.apache.calcite.rel.core.AggregateCall)83 Pair (org.apache.calcite.util.Pair)79 Project (org.apache.calcite.rel.core.Project)77 RelBuilder (org.apache.calcite.tools.RelBuilder)77 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)66 ImmutableList (com.google.common.collect.ImmutableList)64 Map (java.util.Map)63