Search in sources :

Example 21 with RexInputRef

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

the class RelMdAllPredicates method getAllPredicates.

/**
 * Add the Join condition to the list obtained from the input.
 */
public RelOptPredicateList getAllPredicates(Join join, RelMetadataQuery mq) {
    if (join.getJoinType() != JoinRelType.INNER) {
        // We cannot map origin of this expression.
        return null;
    }
    final RexBuilder rexBuilder = join.getCluster().getRexBuilder();
    final RexNode pred = join.getCondition();
    final Multimap<List<String>, RelTableRef> qualifiedNamesToRefs = HashMultimap.create();
    RelOptPredicateList newPreds = RelOptPredicateList.EMPTY;
    for (RelNode input : join.getInputs()) {
        final RelOptPredicateList inputPreds = mq.getAllPredicates(input);
        if (inputPreds == null) {
            // Bail out
            return null;
        }
        // Gather table references
        final Set<RelTableRef> tableRefs = mq.getTableReferences(input);
        if (input == join.getLeft()) {
            // Left input references remain unchanged
            for (RelTableRef leftRef : tableRefs) {
                qualifiedNamesToRefs.put(leftRef.getQualifiedName(), leftRef);
            }
            newPreds = newPreds.union(rexBuilder, inputPreds);
        } else {
            // Right input references might need to be updated if there are table name
            // clashes with left input
            final Map<RelTableRef, RelTableRef> currentTablesMapping = new HashMap<>();
            for (RelTableRef rightRef : tableRefs) {
                int shift = 0;
                Collection<RelTableRef> lRefs = qualifiedNamesToRefs.get(rightRef.getQualifiedName());
                if (lRefs != null) {
                    shift = lRefs.size();
                }
                currentTablesMapping.put(rightRef, RelTableRef.of(rightRef.getTable(), shift + rightRef.getEntityNumber()));
            }
            final List<RexNode> updatedPreds = Lists.newArrayList(Iterables.transform(inputPreds.pulledUpPredicates, new Function<RexNode, RexNode>() {

                @Override
                public RexNode apply(RexNode e) {
                    return RexUtil.swapTableReferences(rexBuilder, e, currentTablesMapping);
                }
            }));
            newPreds = newPreds.union(rexBuilder, RelOptPredicateList.of(rexBuilder, updatedPreds));
        }
    }
    // Extract input fields referenced by Join condition
    final Set<RelDataTypeField> inputExtraFields = new LinkedHashSet<>();
    final RelOptUtil.InputFinder inputFinder = new RelOptUtil.InputFinder(inputExtraFields);
    pred.accept(inputFinder);
    final ImmutableBitSet inputFieldsUsed = inputFinder.inputBitSet.build();
    // Infer column origin expressions for given references
    final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
    for (int idx : inputFieldsUsed) {
        final RexInputRef inputRef = RexInputRef.of(idx, join.getRowType().getFieldList());
        final Set<RexNode> originalExprs = mq.getExpressionLineage(join, inputRef);
        if (originalExprs == null) {
            // Bail out
            return null;
        }
        final RexInputRef ref = RexInputRef.of(idx, join.getRowType().getFieldList());
        mapping.put(ref, originalExprs);
    }
    // Replace with new expressions and return union of predicates
    return newPreds.union(rexBuilder, RelOptPredicateList.of(rexBuilder, RelMdExpressionLineage.createAllPossibleExpressions(rexBuilder, pred, mapping)));
}
Also used : LinkedHashSet(java.util.LinkedHashSet) LinkedHashSet(java.util.LinkedHashSet) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Set(java.util.Set) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) LinkedHashMap(java.util.LinkedHashMap) Function(com.google.common.base.Function) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) RexBuilder(org.apache.calcite.rex.RexBuilder) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) List(java.util.List) RelOptUtil(org.apache.calcite.plan.RelOptUtil) RelTableRef(org.apache.calcite.rex.RexTableInputRef.RelTableRef) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 22 with RexInputRef

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

the class RelMdAllPredicates method getAllPredicates.

/**
 * Add the Filter condition to the list obtained from the input.
 */
public RelOptPredicateList getAllPredicates(Filter filter, RelMetadataQuery mq) {
    final RelNode input = filter.getInput();
    final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
    final RexNode pred = filter.getCondition();
    final RelOptPredicateList predsBelow = mq.getAllPredicates(input);
    if (predsBelow == null) {
        // Safety check
        return null;
    }
    // Extract input fields referenced by Filter condition
    final Set<RelDataTypeField> inputExtraFields = new LinkedHashSet<>();
    final RelOptUtil.InputFinder inputFinder = new RelOptUtil.InputFinder(inputExtraFields);
    pred.accept(inputFinder);
    final ImmutableBitSet inputFieldsUsed = inputFinder.inputBitSet.build();
    // Infer column origin expressions for given references
    final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
    for (int idx : inputFieldsUsed) {
        final RexInputRef ref = RexInputRef.of(idx, filter.getRowType().getFieldList());
        final Set<RexNode> originalExprs = mq.getExpressionLineage(filter, ref);
        if (originalExprs == null) {
            // Bail out
            return null;
        }
        mapping.put(ref, originalExprs);
    }
    // Replace with new expressions and return union of predicates
    return predsBelow.union(rexBuilder, RelOptPredicateList.of(rexBuilder, RelMdExpressionLineage.createAllPossibleExpressions(rexBuilder, pred, mapping)));
}
Also used : LinkedHashSet(java.util.LinkedHashSet) LinkedHashSet(java.util.LinkedHashSet) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Set(java.util.Set) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelOptUtil(org.apache.calcite.plan.RelOptUtil) LinkedHashMap(java.util.LinkedHashMap) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 23 with RexInputRef

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

the class RelBuilderTest method testBadFieldName.

@Test
public void testBadFieldName() {
    final RelBuilder builder = RelBuilder.create(config().build());
    try {
        RexInputRef ref = builder.scan("EMP").field("deptno");
        fail("expected error, got " + ref);
    } catch (IllegalArgumentException e) {
        assertThat(e.getMessage(), is("field [deptno] not found; input fields are: [EMPNO, ENAME, JOB, " + "MGR, HIREDATE, SAL, COMM, DEPTNO]"));
    }
}
Also used : RelBuilder(org.apache.calcite.tools.RelBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) Test(org.junit.Test)

Example 24 with RexInputRef

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

the class RelBuilderTest method testBadFieldOrdinal.

@Test
public void testBadFieldOrdinal() {
    final RelBuilder builder = RelBuilder.create(config().build());
    try {
        RexInputRef ref = builder.scan("DEPT").field(20);
        fail("expected error, got " + ref);
    } catch (IllegalArgumentException e) {
        assertThat(e.getMessage(), is("field ordinal [20] out of range; " + "input fields are: [DEPTNO, DNAME, LOC]"));
    }
}
Also used : RelBuilder(org.apache.calcite.tools.RelBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) Test(org.junit.Test)

Example 25 with RexInputRef

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

the class RexToLixTranslator method translate0.

/**
 * Translates an expression that is not in the cache.
 *
 * @param expr Expression
 * @param nullAs If false, if expression is definitely not null at
 *   runtime. Therefore we can optimize. For example, we can cast to int
 *   using x.intValue().
 * @return Translated expression
 */
private Expression translate0(RexNode expr, RexImpTable.NullAs nullAs, Type storageType) {
    if (nullAs == RexImpTable.NullAs.NULL && !expr.getType().isNullable()) {
        nullAs = RexImpTable.NullAs.NOT_POSSIBLE;
    }
    switch(expr.getKind()) {
        case INPUT_REF:
            final int index = ((RexInputRef) expr).getIndex();
            Expression x = inputGetter.field(list, index, storageType);
            // safe to share
            Expression input = list.append("inp" + index + "_", x);
            if (nullAs == RexImpTable.NullAs.NOT_POSSIBLE && input.type.equals(storageType)) {
                // unboxing via nullAs.handle below.
                return input;
            }
            return handleNull(input, nullAs);
        case LOCAL_REF:
            return translate(deref(expr), nullAs, storageType);
        case LITERAL:
            return translateLiteral((RexLiteral) expr, nullifyType(expr.getType(), isNullable(expr) && nullAs != RexImpTable.NullAs.NOT_POSSIBLE), typeFactory, nullAs);
        case DYNAMIC_PARAM:
            return translateParameter((RexDynamicParam) expr, nullAs, storageType);
        case CORREL_VARIABLE:
            throw new RuntimeException("Cannot translate " + expr + ". Correlated" + " variables should always be referenced by field access");
        case FIELD_ACCESS:
            RexFieldAccess fieldAccess = (RexFieldAccess) expr;
            RexNode target = deref(fieldAccess.getReferenceExpr());
            // only $cor.field access is supported
            if (!(target instanceof RexCorrelVariable)) {
                throw new RuntimeException("cannot translate expression " + expr);
            }
            if (correlates == null) {
                throw new RuntimeException("Cannot translate " + expr + " since " + "correlate variables resolver is not defined");
            }
            InputGetter getter = correlates.apply(((RexCorrelVariable) target).getName());
            return getter.field(list, fieldAccess.getField().getIndex(), storageType);
        default:
            if (expr instanceof RexCall) {
                return translateCall((RexCall) expr, nullAs);
            }
            throw new RuntimeException("cannot translate expression " + expr);
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) 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) RexInputRef(org.apache.calcite.rex.RexInputRef) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

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