Search in sources :

Example 1 with RexCorrelVariable

use of org.apache.calcite.rex.RexCorrelVariable 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)

Example 2 with RexCorrelVariable

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

the class SqlToRelConverter method convertIdentifier.

/**
 * Converts an identifier into an expression in a given scope. For example,
 * the "empno" in "select empno from emp join dept" becomes "emp.empno".
 */
private RexNode convertIdentifier(Blackboard bb, SqlIdentifier identifier) {
    // first check for reserved identifiers like CURRENT_USER
    final SqlCall call = SqlUtil.makeCall(opTab, identifier);
    if (call != null) {
        return bb.convertExpression(call);
    }
    String pv = null;
    if (bb.isPatternVarRef && identifier.names.size() > 1) {
        pv = identifier.names.get(0);
    }
    final SqlQualified qualified;
    if (bb.scope != null) {
        qualified = bb.scope.fullyQualify(identifier);
    } else {
        qualified = SqlQualified.create(null, 1, null, identifier);
    }
    final Pair<RexNode, Map<String, Integer>> e0 = bb.lookupExp(qualified);
    RexNode e = e0.left;
    for (String name : qualified.suffix()) {
        if (e == e0.left && e0.right != null) {
            int i = e0.right.get(name);
            e = rexBuilder.makeFieldAccess(e, i);
        } else {
            // name already fully-qualified
            final boolean caseSensitive = true;
            if (identifier.isStar() && bb.scope instanceof MatchRecognizeScope) {
                e = rexBuilder.makeFieldAccess(e, 0);
            } else {
                e = rexBuilder.makeFieldAccess(e, name, caseSensitive);
            }
        }
    }
    if (e instanceof RexInputRef) {
        // adjust the type to account for nulls introduced by outer joins
        e = adjustInputRef(bb, (RexInputRef) e);
        if (pv != null) {
            e = RexPatternFieldRef.of(pv, (RexInputRef) e);
        }
    }
    if (e0.left instanceof RexCorrelVariable) {
        assert e instanceof RexFieldAccess;
        final RexNode prev = bb.mapCorrelateToRex.put(((RexCorrelVariable) e0.left).id, (RexFieldAccess) e);
        assert prev == null;
    }
    return e;
}
Also used : RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) SqlCall(org.apache.calcite.sql.SqlCall) SqlQualified(org.apache.calcite.sql.validate.SqlQualified) RexInputRef(org.apache.calcite.rex.RexInputRef) NlsString(org.apache.calcite.util.NlsString) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode) MatchRecognizeScope(org.apache.calcite.sql.validate.MatchRecognizeScope)

Example 3 with RexCorrelVariable

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

the class RelFieldTrimmer method trimChild.

/**
 * Trims the fields of an input relational expression.
 *
 * @param rel        Relational expression
 * @param input      Input relational expression, whose fields to trim
 * @param fieldsUsed Bitmap of fields needed by the consumer
 * @return New relational expression and its field mapping
 */
protected TrimResult trimChild(RelNode rel, RelNode input, final ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final ImmutableBitSet.Builder fieldsUsedBuilder = fieldsUsed.rebuild();
    // Fields that define the collation cannot be discarded.
    final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
    final ImmutableList<RelCollation> collations = mq.collations(input);
    for (RelCollation collation : collations) {
        for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
            fieldsUsedBuilder.set(fieldCollation.getFieldIndex());
        }
    }
    // fields.
    for (final CorrelationId correlation : rel.getVariablesSet()) {
        rel.accept(new CorrelationReferenceFinder() {

            protected RexNode handle(RexFieldAccess fieldAccess) {
                final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
                if (v.id.equals(correlation)) {
                    fieldsUsedBuilder.set(fieldAccess.getField().getIndex());
                }
                return fieldAccess;
            }
        });
    }
    return dispatchTrimFields(input, fieldsUsedBuilder.build(), extraFields);
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) RelCollation(org.apache.calcite.rel.RelCollation) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

Example 4 with RexCorrelVariable

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

the class SubQueryDecorrelator method analyzeCorConditions.

private static void analyzeCorConditions(final Set<CorrelationId> variableSet, final RexNode condition, final RexBuilder rexBuilder, final int maxCnfNodeCount, final List<RexNode> corConditions, final List<RexNode> nonCorConditions, final List<RexNode> unsupportedCorConditions) {
    // converts the expanded expression to conjunctive normal form,
    // like "(a AND b) OR c" will be converted to "(a OR c) AND (b OR c)"
    final RexNode cnf = FlinkRexUtil.toCnf(rexBuilder, maxCnfNodeCount, condition);
    // converts the cnf condition to a list of AND conditions
    final List<RexNode> conjunctions = RelOptUtil.conjunctions(cnf);
    // `true` for RexNode is supported correlation condition,
    // `false` for RexNode is unsupported correlation condition,
    // `null` for RexNode is not a correlation condition.
    final RexVisitorImpl<Boolean> visitor = new RexVisitorImpl<Boolean>(true) {

        @Override
        public Boolean visitFieldAccess(RexFieldAccess fieldAccess) {
            final RexNode ref = fieldAccess.getReferenceExpr();
            if (ref instanceof RexCorrelVariable) {
                return visitCorrelVariable((RexCorrelVariable) ref);
            } else {
                return super.visitFieldAccess(fieldAccess);
            }
        }

        @Override
        public Boolean visitCorrelVariable(RexCorrelVariable correlVariable) {
            return variableSet.contains(correlVariable.id);
        }

        @Override
        public Boolean visitSubQuery(RexSubQuery subQuery) {
            final List<Boolean> result = new ArrayList<>();
            for (RexNode operand : subQuery.operands) {
                result.add(operand.accept(this));
            }
            // in (select t3.d from t3)
            if (result.contains(true) || result.contains(false)) {
                return false;
            } else {
                return null;
            }
        }

        @Override
        public Boolean visitCall(RexCall call) {
            final List<Boolean> result = new ArrayList<>();
            for (RexNode operand : call.operands) {
                result.add(operand.accept(this));
            }
            if (result.contains(false)) {
                return false;
            } else if (result.contains(true)) {
                // return call.op.getKind() != SqlKind.OR || !result.contains(null);
                return call.op.getKind() != SqlKind.OR;
            } else {
                return null;
            }
        }
    };
    for (RexNode c : conjunctions) {
        Boolean r = c.accept(visitor);
        if (r == null) {
            nonCorConditions.add(c);
        } else if (r) {
            corConditions.add(c);
        } else {
            unsupportedCorConditions.add(c);
        }
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) ArrayList(java.util.ArrayList) RexVisitorImpl(org.apache.calcite.rex.RexVisitorImpl) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexSubQuery(org.apache.calcite.rex.RexSubQuery) RexNode(org.apache.calcite.rex.RexNode)

Example 5 with RexCorrelVariable

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

the class RelFieldTrimmer method trimChild.

/**
 * Trims the fields of an input relational expression.
 *
 * @param rel        Relational expression
 * @param input      Input relational expression, whose fields to trim
 * @param fieldsUsed Bitmap of fields needed by the consumer
 * @return New relational expression and its field mapping
 */
protected TrimResult trimChild(RelNode rel, RelNode input, final ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final ImmutableBitSet.Builder fieldsUsedBuilder = fieldsUsed.rebuild();
    // Fields that define the collation cannot be discarded.
    final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
    final ImmutableList<RelCollation> collations = mq.collations(input);
    if (collations != null) {
        for (RelCollation collation : collations) {
            for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
                fieldsUsedBuilder.set(fieldCollation.getFieldIndex());
            }
        }
    }
    // fields.
    for (final CorrelationId correlation : rel.getVariablesSet()) {
        rel.accept(new CorrelationReferenceFinder() {

            protected RexNode handle(RexFieldAccess fieldAccess) {
                final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
                if (v.id.equals(correlation)) {
                    fieldsUsedBuilder.set(fieldAccess.getField().getIndex());
                }
                return fieldAccess;
            }
        });
    }
    return dispatchTrimFields(input, fieldsUsedBuilder.build(), extraFields);
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) RelCollation(org.apache.calcite.rel.RelCollation) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) CorrelationReferenceFinder(org.apache.calcite.sql2rel.CorrelationReferenceFinder) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexCorrelVariable (org.apache.calcite.rex.RexCorrelVariable)12 RexFieldAccess (org.apache.calcite.rex.RexFieldAccess)9 RexNode (org.apache.calcite.rex.RexNode)9 CorrelationId (org.apache.calcite.rel.core.CorrelationId)5 RexCall (org.apache.calcite.rex.RexCall)4 RexInputRef (org.apache.calcite.rex.RexInputRef)4 RelNode (org.apache.calcite.rel.RelNode)3 RexBuilder (org.apache.calcite.rex.RexBuilder)3 RelBuilder (org.apache.calcite.tools.RelBuilder)3 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 RelCollation (org.apache.calcite.rel.RelCollation)2 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)2 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)2 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)2 CorrelationReferenceFinder (org.apache.calcite.sql2rel.CorrelationReferenceFinder)2 Test (org.junit.Test)2