Search in sources :

Example 16 with RexFieldAccess

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

the class RelDecorrelator 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(Correlate correlate, Project project, Filter 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<CorRef> corVarInFilter = Sets.newHashSet(cm.mapRefRelToCorRef.get(filter));
        for (RexFieldAccess correlatedJoinKey : correlatedJoinKeys) {
            corVarInFilter.remove(cm.mapFieldAccessToCorRef.get(correlatedJoinKey));
        }
        if (!corVarInFilter.isEmpty()) {
            return false;
        }
        // Check that the correlated variables referenced in these
        // comparisons do come from the Correlate.
        corVarInFilter.addAll(cm.mapRefRelToCorRef.get(filter));
        for (CorRef corVar : corVarInFilter) {
            if (cm.mapCorToCorRel.get(corVar.corr) != correlate) {
                return false;
            }
        }
    }
    // of the correlate.
    if ((project != null) && cm.mapRefRelToCorRef.containsKey(project)) {
        for (CorRef corVar : cm.mapRefRelToCorRef.get(project)) {
            if (cm.mapCorToCorRel.get(corVar.corr) != correlate) {
                return false;
            }
        }
    }
    return true;
}
Also used : RexFieldAccess(org.apache.calcite.rex.RexFieldAccess)

Example 17 with RexFieldAccess

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

the class PythonMapMergeRule method isFlattenCalc.

private boolean isFlattenCalc(List<RexNode> middleProjects, int inputRowFieldCount) {
    if (inputRowFieldCount != middleProjects.size()) {
        return false;
    }
    for (int i = 0; i < inputRowFieldCount; i++) {
        RexNode middleProject = middleProjects.get(i);
        if (middleProject instanceof RexFieldAccess) {
            RexFieldAccess rexField = ((RexFieldAccess) middleProject);
            if (rexField.getField().getIndex() != i) {
                return false;
            }
            RexNode expr = rexField.getReferenceExpr();
            if (expr instanceof RexInputRef) {
                if (((RexInputRef) expr).getIndex() != 0) {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    return true;
}
Also used : RexInputRef(org.apache.calcite.rex.RexInputRef) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

Example 18 with RexFieldAccess

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

the class PythonCorrelateSplitRule method createNewFieldNames.

private List<String> createNewFieldNames(RelDataType rowType, RexBuilder rexBuilder, int primitiveFieldCount, ArrayBuffer<RexNode> extractedRexNodes, List<RexNode> calcProjects) {
    for (int i = 0; i < primitiveFieldCount; i++) {
        calcProjects.add(RexInputRef.of(i, rowType));
    }
    // change RexCorrelVariable to RexInputRef.
    RexDefaultVisitor<RexNode> visitor = new RexDefaultVisitor<RexNode>() {

        @Override
        public RexNode visitFieldAccess(RexFieldAccess fieldAccess) {
            RexNode expr = fieldAccess.getReferenceExpr();
            if (expr instanceof RexCorrelVariable) {
                RelDataTypeField field = fieldAccess.getField();
                return new RexInputRef(field.getIndex(), field.getType());
            } else {
                return rexBuilder.makeFieldAccess(expr.accept(this), fieldAccess.getField().getIndex());
            }
        }

        @Override
        public RexNode visitNode(RexNode rexNode) {
            return rexNode;
        }
    };
    // add the fields of the extracted rex calls.
    Iterator<RexNode> iterator = extractedRexNodes.iterator();
    while (iterator.hasNext()) {
        RexNode rexNode = iterator.next();
        if (rexNode instanceof RexCall) {
            RexCall rexCall = (RexCall) rexNode;
            List<RexNode> newProjects = rexCall.getOperands().stream().map(x -> x.accept(visitor)).collect(Collectors.toList());
            RexCall newRexCall = rexCall.clone(rexCall.getType(), newProjects);
            calcProjects.add(newRexCall);
        } else {
            calcProjects.add(rexNode);
        }
    }
    List<String> nameList = new LinkedList<>();
    for (int i = 0; i < primitiveFieldCount; i++) {
        nameList.add(rowType.getFieldNames().get(i));
    }
    Iterator<Object> indicesIterator = extractedRexNodes.indices().iterator();
    while (indicesIterator.hasNext()) {
        nameList.add("f" + indicesIterator.next());
    }
    return SqlValidatorUtil.uniquify(nameList, rexBuilder.getTypeFactory().getTypeSystem().isSchemaCaseSensitive());
}
Also used : RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexProgram(org.apache.calcite.rex.RexProgram) RexUtil(org.apache.calcite.rex.RexUtil) SqlValidatorUtil(org.apache.calcite.sql.validate.SqlValidatorUtil) RexNode(org.apache.calcite.rex.RexNode) LinkedList(java.util.LinkedList) ArrayBuffer(scala.collection.mutable.ArrayBuffer) PythonUtil(org.apache.flink.table.planner.plan.utils.PythonUtil) RelDataType(org.apache.calcite.rel.type.RelDataType) RexDefaultVisitor(org.apache.flink.table.planner.plan.utils.RexDefaultVisitor) RexBuilder(org.apache.calcite.rex.RexBuilder) Iterator(scala.collection.Iterator) FlinkLogicalTableFunctionScan(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalTableFunctionScan) FlinkLogicalCalc(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCalc) RelNode(org.apache.calcite.rel.RelNode) Collectors(java.util.stream.Collectors) RelOptRuleCall(org.apache.calcite.plan.RelOptRuleCall) RexInputRef(org.apache.calcite.rex.RexInputRef) RelOptRule(org.apache.calcite.plan.RelOptRule) RexProgramBuilder(org.apache.calcite.rex.RexProgramBuilder) List(java.util.List) StreamPhysicalCorrelateRule(org.apache.flink.table.planner.plan.rules.physical.stream.StreamPhysicalCorrelateRule) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) HepRelVertex(org.apache.calcite.plan.hep.HepRelVertex) FlinkLogicalCorrelate(org.apache.flink.table.planner.plan.nodes.logical.FlinkLogicalCorrelate) RexCall(org.apache.calcite.rex.RexCall) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) RexDefaultVisitor(org.apache.flink.table.planner.plan.utils.RexDefaultVisitor) LinkedList(java.util.LinkedList) RexCall(org.apache.calcite.rex.RexCall) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RexInputRef(org.apache.calcite.rex.RexInputRef) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

Example 19 with RexFieldAccess

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

the class RelJson method toJson.

private Object toJson(RexNode node) {
    final Map<String, Object> map;
    switch(node.getKind()) {
        case FIELD_ACCESS:
            map = jsonBuilder.map();
            final RexFieldAccess fieldAccess = (RexFieldAccess) node;
            map.put("field", fieldAccess.getField().getName());
            map.put("expr", toJson(fieldAccess.getReferenceExpr()));
            return map;
        case LITERAL:
            final RexLiteral literal = (RexLiteral) node;
            final Object value2 = literal.getValue2();
            if (value2 == null) {
                // Special treatment for null literal because (1) we wouldn't want
                // 'null' to be confused as an empty expression and (2) for null
                // literals we need an explicit type.
                map = jsonBuilder.map();
                map.put("literal", null);
                map.put("type", literal.getTypeName().name());
                return map;
            }
            return value2;
        case INPUT_REF:
        case LOCAL_REF:
            map = jsonBuilder.map();
            map.put("input", ((RexSlot) node).getIndex());
            map.put("name", ((RexSlot) node).getName());
            return map;
        case CORREL_VARIABLE:
            map = jsonBuilder.map();
            map.put("correl", ((RexCorrelVariable) node).getName());
            map.put("type", toJson(node.getType()));
            return map;
        default:
            if (node instanceof RexCall) {
                final RexCall call = (RexCall) node;
                map = jsonBuilder.map();
                map.put("op", toJson(call.getOperator()));
                final List<Object> list = jsonBuilder.list();
                for (RexNode operand : call.getOperands()) {
                    list.add(toJson(operand));
                }
                map.put("operands", list);
                switch(node.getKind()) {
                    case CAST:
                        map.put("type", toJson(node.getType()));
                }
                if (call.getOperator() instanceof SqlFunction) {
                    if (((SqlFunction) call.getOperator()).getFunctionType().isUserDefined()) {
                        map.put("class", call.getOperator().getClass().getName());
                    }
                }
                return map;
            }
            throw new UnsupportedOperationException("unknown rex " + node);
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexLiteral(org.apache.calcite.rex.RexLiteral) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode) SqlFunction(org.apache.calcite.sql.SqlFunction)

Example 20 with RexFieldAccess

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

the class SqlToRelConverter method getCorrelationUse.

private CorrelationUse getCorrelationUse(Blackboard bb, final RelNode r0) {
    final Set<CorrelationId> correlatedVariables = RelOptUtil.getVariablesUsed(r0);
    if (correlatedVariables.isEmpty()) {
        return null;
    }
    final ImmutableBitSet.Builder requiredColumns = ImmutableBitSet.builder();
    final List<CorrelationId> correlNames = Lists.newArrayList();
    // All correlations must refer the same namespace since correlation
    // produces exactly one correlation source.
    // The same source might be referenced by different variables since
    // DeferredLookups are not de-duplicated at create time.
    SqlValidatorNamespace prevNs = null;
    for (CorrelationId correlName : correlatedVariables) {
        DeferredLookup lookup = mapCorrelToDeferred.get(correlName);
        RexFieldAccess fieldAccess = lookup.getFieldAccess(correlName);
        String originalRelName = lookup.getOriginalRelName();
        String originalFieldName = fieldAccess.getField().getName();
        final SqlNameMatcher nameMatcher = lookup.bb.scope.getValidator().getCatalogReader().nameMatcher();
        final SqlValidatorScope.ResolvedImpl resolved = new SqlValidatorScope.ResolvedImpl();
        lookup.bb.scope.resolve(ImmutableList.of(originalRelName), nameMatcher, false, resolved);
        assert resolved.count() == 1;
        final SqlValidatorScope.Resolve resolve = resolved.only();
        final SqlValidatorNamespace foundNs = resolve.namespace;
        final RelDataType rowType = resolve.rowType();
        final int childNamespaceIndex = resolve.path.steps().get(0).i;
        final SqlValidatorScope ancestorScope = resolve.scope;
        boolean correlInCurrentScope = ancestorScope == bb.scope;
        if (!correlInCurrentScope) {
            continue;
        }
        if (prevNs == null) {
            prevNs = foundNs;
        } else {
            assert prevNs == foundNs : "All correlation variables should resolve" + " to the same namespace." + " Prev ns=" + prevNs + ", new ns=" + foundNs;
        }
        int namespaceOffset = 0;
        if (childNamespaceIndex > 0) {
            // of output types from all the preceding namespaces
            assert ancestorScope instanceof ListScope;
            List<SqlValidatorNamespace> children = ((ListScope) ancestorScope).getChildren();
            for (int i = 0; i < childNamespaceIndex; i++) {
                SqlValidatorNamespace child = children.get(i);
                namespaceOffset += child.getRowType().getFieldCount();
            }
        }
        RexFieldAccess topLevelFieldAccess = fieldAccess;
        while (topLevelFieldAccess.getReferenceExpr() instanceof RexFieldAccess) {
            topLevelFieldAccess = (RexFieldAccess) topLevelFieldAccess.getReferenceExpr();
        }
        final RelDataTypeField field = rowType.getFieldList().get(topLevelFieldAccess.getField().getIndex() - namespaceOffset);
        int pos = namespaceOffset + field.getIndex();
        assert field.getType() == topLevelFieldAccess.getField().getType();
        assert pos != -1;
        if (bb.mapRootRelToFieldProjection.containsKey(bb.root)) {
            // bb.root is an aggregate and only projects group by
            // keys.
            Map<Integer, Integer> exprProjection = bb.mapRootRelToFieldProjection.get(bb.root);
            // the root of the outer relation.
            if (exprProjection.containsKey(pos)) {
                pos = exprProjection.get(pos);
            } else {
                // correl not grouped
                throw new AssertionError("Identifier '" + originalRelName + "." + originalFieldName + "' is not a group expr");
            }
        }
        requiredColumns.set(pos);
        correlNames.add(correlName);
    }
    if (correlNames.isEmpty()) {
        // None of the correlating variables originated in this scope.
        return null;
    }
    RelNode r = r0;
    if (correlNames.size() > 1) {
        // The same table was referenced more than once.
        // So we deduplicate.
        r = DeduplicateCorrelateVariables.go(rexBuilder, correlNames.get(0), Util.skip(correlNames), r0);
        // Add new node to leaves.
        leaves.add(r);
    }
    return new CorrelationUse(correlNames.get(0), requiredColumns.build(), r);
}
Also used : SqlValidatorScope(org.apache.calcite.sql.validate.SqlValidatorScope) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelDataType(org.apache.calcite.rel.type.RelDataType) NlsString(org.apache.calcite.util.NlsString) SqlNameMatcher(org.apache.calcite.sql.validate.SqlNameMatcher) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) SqlValidatorNamespace(org.apache.calcite.sql.validate.SqlValidatorNamespace) ListScope(org.apache.calcite.sql.validate.ListScope)

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