Search in sources :

Example 1 with RexFieldAccess

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

the class FlinkRelDecorrelator method checkCorVars.

/**
	 * Checks whether the correlations in projRel and filter are related to
	 * the correlated variables provided by corRel.
	 *
	 * @param correlate          Correlate
	 * @param project            The original Project as the RHS input of the join
	 * @param filter             Filter
	 * @param correlatedJoinKeys Correlated join keys
	 * @return true if filter and proj only references corVar provided by corRel
	 */
private boolean checkCorVars(LogicalCorrelate correlate, LogicalProject project, LogicalFilter filter, List<RexFieldAccess> correlatedJoinKeys) {
    if (filter != null) {
        assert correlatedJoinKeys != null;
        // check that all correlated refs in the filter condition are
        // used in the join(as field access).
        Set<Correlation> corVarInFilter = Sets.newHashSet(cm.mapRefRelToCorVar.get(filter));
        for (RexFieldAccess correlatedJoinKey : correlatedJoinKeys) {
            corVarInFilter.remove(cm.mapFieldAccessToCorVar.get(correlatedJoinKey));
        }
        if (!corVarInFilter.isEmpty()) {
            return false;
        }
        // Check that the correlated variables referenced in these
        // comparisons do come from the correlatorRel.
        corVarInFilter.addAll(cm.mapRefRelToCorVar.get(filter));
        for (Correlation corVar : corVarInFilter) {
            if (cm.mapCorVarToCorRel.get(corVar.corr) != correlate) {
                return false;
            }
        }
    }
    // of the correlate.
    if ((project != null) && cm.mapRefRelToCorVar.containsKey(project)) {
        for (Correlation corVar : cm.mapRefRelToCorVar.get(project)) {
            if (cm.mapCorVarToCorRel.get(corVar.corr) != correlate) {
                return false;
            }
        }
    }
    return true;
}
Also used : RexFieldAccess(org.apache.calcite.rex.RexFieldAccess)

Example 2 with RexFieldAccess

use of org.apache.calcite.rex.RexFieldAccess 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 3 with RexFieldAccess

use of org.apache.calcite.rex.RexFieldAccess 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 4 with RexFieldAccess

use of org.apache.calcite.rex.RexFieldAccess 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 5 with RexFieldAccess

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

the class RelOptUtil method splitCorrelatedFilterCondition.

private static void splitCorrelatedFilterCondition(LogicalFilter filter, RexNode condition, List<RexNode> joinKeys, List<RexNode> correlatedJoinKeys, List<RexNode> nonEquiList, boolean extractCorrelatedFieldAccess) {
    if (condition instanceof RexCall) {
        RexCall call = (RexCall) condition;
        if (call.getOperator().getKind() == SqlKind.AND) {
            for (RexNode operand : call.getOperands()) {
                splitCorrelatedFilterCondition(filter, operand, joinKeys, correlatedJoinKeys, nonEquiList, extractCorrelatedFieldAccess);
            }
            return;
        }
        if (call.getOperator().getKind() == SqlKind.EQUALS) {
            final List<RexNode> operands = call.getOperands();
            RexNode op0 = operands.get(0);
            RexNode op1 = operands.get(1);
            if (extractCorrelatedFieldAccess) {
                if (!RexUtil.containsFieldAccess(op0) && (op1 instanceof RexFieldAccess)) {
                    joinKeys.add(op0);
                    correlatedJoinKeys.add(op1);
                    return;
                } else if ((op0 instanceof RexFieldAccess) && !RexUtil.containsFieldAccess(op1)) {
                    correlatedJoinKeys.add(op0);
                    joinKeys.add(op1);
                    return;
                }
            } else {
                if (!(RexUtil.containsInputRef(op0)) && (op1 instanceof RexInputRef)) {
                    correlatedJoinKeys.add(op0);
                    joinKeys.add(op1);
                    return;
                } else if ((op0 instanceof RexInputRef) && !(RexUtil.containsInputRef(op1))) {
                    joinKeys.add(op0);
                    correlatedJoinKeys.add(op1);
                    return;
                }
            }
        }
    }
    // The operator is not of RexCall type
    // So we fail. Fall through.
    // Add this condition to the list of non-equi-join conditions.
    nonEquiList.add(condition);
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexInputRef(org.apache.calcite.rex.RexInputRef) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexFieldAccess (org.apache.calcite.rex.RexFieldAccess)21 RexNode (org.apache.calcite.rex.RexNode)15 RexCorrelVariable (org.apache.calcite.rex.RexCorrelVariable)9 RexInputRef (org.apache.calcite.rex.RexInputRef)8 RexCall (org.apache.calcite.rex.RexCall)7 CorrelationId (org.apache.calcite.rel.core.CorrelationId)5 ArrayList (java.util.ArrayList)4 RexBuilder (org.apache.calcite.rex.RexBuilder)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 RelNode (org.apache.calcite.rel.RelNode)3 NlsString (org.apache.calcite.util.NlsString)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 List (java.util.List)2 RelSubset (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.volcano.RelSubset)2 RelNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode)2 LogicalCorrelate (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalCorrelate)2 LogicalProject (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject)2 RexFieldAccess (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexFieldAccess)2 RexNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)2