Search in sources :

Example 1 with ListScope

use of org.apache.calcite.sql.validate.ListScope 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)

Example 2 with ListScope

use of org.apache.calcite.sql.validate.ListScope in project calcite by apache.

the class SqlToRelConverter method convertMultisets.

private RelNode convertMultisets(final List<SqlNode> operands, Blackboard bb) {
    // NOTE: Wael 2/04/05: this implementation is not the most efficient in
    // terms of planning since it generates XOs that can be reduced.
    final List<Object> joinList = new ArrayList<>();
    List<SqlNode> lastList = new ArrayList<>();
    for (int i = 0; i < operands.size(); i++) {
        SqlNode operand = operands.get(i);
        if (!(operand instanceof SqlCall)) {
            lastList.add(operand);
            continue;
        }
        final SqlCall call = (SqlCall) operand;
        final RelNode input;
        switch(call.getKind()) {
            case MULTISET_VALUE_CONSTRUCTOR:
            case ARRAY_VALUE_CONSTRUCTOR:
                final SqlNodeList list = new SqlNodeList(call.getOperandList(), call.getParserPosition());
                CollectNamespace nss = (CollectNamespace) validator.getNamespace(call);
                Blackboard usedBb;
                if (null != nss) {
                    usedBb = createBlackboard(nss.getScope(), null, false);
                } else {
                    usedBb = createBlackboard(new ListScope(bb.scope) {

                        public SqlNode getNode() {
                            return call;
                        }
                    }, null, false);
                }
                RelDataType multisetType = validator.getValidatedNodeType(call);
                ((SqlValidatorImpl) validator).setValidatedNodeType(list, multisetType.getComponentType());
                input = convertQueryOrInList(usedBb, list, null);
                break;
            case MULTISET_QUERY_CONSTRUCTOR:
            case ARRAY_QUERY_CONSTRUCTOR:
                final RelRoot root = convertQuery(call.operand(0), false, true);
                input = root.rel;
                break;
            default:
                lastList.add(operand);
                continue;
        }
        if (lastList.size() > 0) {
            joinList.add(lastList);
        }
        lastList = new ArrayList<>();
        Collect collect = new Collect(cluster, cluster.traitSetOf(Convention.NONE), input, validator.deriveAlias(call, i));
        joinList.add(collect);
    }
    if (joinList.size() == 0) {
        joinList.add(lastList);
    }
    for (int i = 0; i < joinList.size(); i++) {
        Object o = joinList.get(i);
        if (o instanceof List) {
            @SuppressWarnings("unchecked") List<SqlNode> projectList = (List<SqlNode>) o;
            final List<RexNode> selectList = new ArrayList<>();
            final List<String> fieldNameList = new ArrayList<>();
            for (int j = 0; j < projectList.size(); j++) {
                SqlNode operand = projectList.get(j);
                selectList.add(bb.convertExpression(operand));
                // REVIEW angel 5-June-2005: Use deriveAliasFromOrdinal
                // instead of deriveAlias to match field names from
                // SqlRowOperator. Otherwise, get error   Type
                // 'RecordType(INTEGER EMPNO)' has no field 'EXPR$0' when
                // doing   select * from unnest(     select multiset[empno]
                // from sales.emps);
                fieldNameList.add(SqlUtil.deriveAliasFromOrdinal(j));
            }
            relBuilder.push(LogicalValues.createOneRow(cluster)).projectNamed(selectList, fieldNameList, true);
            joinList.set(i, relBuilder.build());
        }
    }
    RelNode ret = (RelNode) joinList.get(0);
    for (int i = 1; i < joinList.size(); i++) {
        RelNode relNode = (RelNode) joinList.get(i);
        ret = RelFactories.DEFAULT_JOIN_FACTORY.createJoin(ret, relNode, rexBuilder.makeLiteral(true), ImmutableSet.<CorrelationId>of(), JoinRelType.INNER, false);
    }
    return ret;
}
Also used : Collect(org.apache.calcite.rel.core.Collect) SqlCall(org.apache.calcite.sql.SqlCall) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) RelRoot(org.apache.calcite.rel.RelRoot) NlsString(org.apache.calcite.util.NlsString) SqlValidatorImpl(org.apache.calcite.sql.validate.SqlValidatorImpl) RelNode(org.apache.calcite.rel.RelNode) SqlNodeList(org.apache.calcite.sql.SqlNodeList) ArrayList(java.util.ArrayList) AbstractList(java.util.AbstractList) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) SqlNodeList(org.apache.calcite.sql.SqlNodeList) CorrelationId(org.apache.calcite.rel.core.CorrelationId) CollectNamespace(org.apache.calcite.sql.validate.CollectNamespace) ListScope(org.apache.calcite.sql.validate.ListScope) SqlNode(org.apache.calcite.sql.SqlNode) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RelNode (org.apache.calcite.rel.RelNode)2 CorrelationId (org.apache.calcite.rel.core.CorrelationId)2 RelDataType (org.apache.calcite.rel.type.RelDataType)2 ListScope (org.apache.calcite.sql.validate.ListScope)2 NlsString (org.apache.calcite.util.NlsString)2 ImmutableList (com.google.common.collect.ImmutableList)1 AbstractList (java.util.AbstractList)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 RelRoot (org.apache.calcite.rel.RelRoot)1 Collect (org.apache.calcite.rel.core.Collect)1 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)1 RexFieldAccess (org.apache.calcite.rex.RexFieldAccess)1 RexNode (org.apache.calcite.rex.RexNode)1 SqlCall (org.apache.calcite.sql.SqlCall)1 SqlNode (org.apache.calcite.sql.SqlNode)1 SqlNodeList (org.apache.calcite.sql.SqlNodeList)1 CollectNamespace (org.apache.calcite.sql.validate.CollectNamespace)1 SqlNameMatcher (org.apache.calcite.sql.validate.SqlNameMatcher)1 SqlValidatorImpl (org.apache.calcite.sql.validate.SqlValidatorImpl)1