Search in sources :

Example 21 with CorrelationId

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.CorrelationId in project calcite by apache.

the class RelJson method toRex.

RexNode toRex(RelInput relInput, Object o) {
    final RelOptCluster cluster = relInput.getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    if (o == null) {
        return null;
    } else if (o instanceof Map) {
        Map map = (Map) o;
        final String op = (String) map.get("op");
        final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
        if (op != null) {
            final List operands = (List) map.get("operands");
            final Object jsonType = map.get("type");
            final SqlOperator operator = toOp(op, map);
            final List<RexNode> rexOperands = toRexList(relInput, operands);
            RelDataType type;
            if (jsonType != null) {
                type = toType(typeFactory, jsonType);
            } else {
                type = rexBuilder.deriveReturnType(operator, rexOperands);
            }
            return rexBuilder.makeCall(type, operator, rexOperands);
        }
        final Integer input = (Integer) map.get("input");
        if (input != null) {
            List<RelNode> inputNodes = relInput.getInputs();
            int i = input;
            for (RelNode inputNode : inputNodes) {
                final RelDataType rowType = inputNode.getRowType();
                if (i < rowType.getFieldCount()) {
                    final RelDataTypeField field = rowType.getFieldList().get(i);
                    return rexBuilder.makeInputRef(field.getType(), input);
                }
                i -= rowType.getFieldCount();
            }
            throw new RuntimeException("input field " + input + " is out of range");
        }
        final String field = (String) map.get("field");
        if (field != null) {
            final Object jsonExpr = map.get("expr");
            final RexNode expr = toRex(relInput, jsonExpr);
            return rexBuilder.makeFieldAccess(expr, field, true);
        }
        final String correl = (String) map.get("correl");
        if (correl != null) {
            final Object jsonType = map.get("type");
            RelDataType type = toType(typeFactory, jsonType);
            return rexBuilder.makeCorrel(type, new CorrelationId(correl));
        }
        if (map.containsKey("literal")) {
            final Object literal = map.get("literal");
            final SqlTypeName sqlTypeName = Util.enumVal(SqlTypeName.class, (String) map.get("type"));
            if (literal == null) {
                return rexBuilder.makeNullLiteral(typeFactory.createSqlType(sqlTypeName));
            }
            return toRex(relInput, literal);
        }
        throw new UnsupportedOperationException("cannot convert to rex " + o);
    } else if (o instanceof Boolean) {
        return rexBuilder.makeLiteral((Boolean) o);
    } else if (o instanceof String) {
        return rexBuilder.makeLiteral((String) o);
    } else if (o instanceof Number) {
        final Number number = (Number) o;
        if (number instanceof Double || number instanceof Float) {
            return rexBuilder.makeApproxLiteral(BigDecimal.valueOf(number.doubleValue()));
        } else {
            return rexBuilder.makeExactLiteral(BigDecimal.valueOf(number.longValue()));
        }
    } else {
        throw new UnsupportedOperationException("cannot convert to rex " + o);
    }
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) SqlOperator(org.apache.calcite.sql.SqlOperator) RelDataType(org.apache.calcite.rel.type.RelDataType) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexBuilder(org.apache.calcite.rex.RexBuilder) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) CorrelationId(org.apache.calcite.rel.core.CorrelationId) HashMap(java.util.HashMap) Map(java.util.Map) RexNode(org.apache.calcite.rex.RexNode)

Example 22 with CorrelationId

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.CorrelationId 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 23 with CorrelationId

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.CorrelationId 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)

Example 24 with CorrelationId

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.CorrelationId in project calcite by apache.

the class SqlToRelConverter method isSubQueryNonCorrelated.

/**
 * Determines whether a sub-query is non-correlated. Note that a
 * non-correlated sub-query can contain correlated references, provided those
 * references do not reference select statements that are parents of the
 * sub-query.
 *
 * @param subq the sub-query
 * @param bb   blackboard used while converting the sub-query, i.e., the
 *             blackboard of the parent query of this sub-query
 * @return true if the sub-query is non-correlated
 */
private boolean isSubQueryNonCorrelated(RelNode subq, Blackboard bb) {
    Set<CorrelationId> correlatedVariables = RelOptUtil.getVariablesUsed(subq);
    for (CorrelationId correlName : correlatedVariables) {
        DeferredLookup lookup = mapCorrelToDeferred.get(correlName);
        String originalRelName = lookup.getOriginalRelName();
        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);
        SqlValidatorScope ancestorScope = resolved.only().scope;
        // If the correlated reference is in a scope that's "above" the
        // sub-query, then this is a correlated sub-query.
        SqlValidatorScope parentScope = bb.scope;
        do {
            if (ancestorScope == parentScope) {
                return false;
            }
            if (parentScope instanceof DelegatingScope) {
                parentScope = ((DelegatingScope) parentScope).getParent();
            } else {
                break;
            }
        } while (parentScope != null);
    }
    return true;
}
Also used : SqlValidatorScope(org.apache.calcite.sql.validate.SqlValidatorScope) SqlNameMatcher(org.apache.calcite.sql.validate.SqlNameMatcher) CorrelationId(org.apache.calcite.rel.core.CorrelationId) NlsString(org.apache.calcite.util.NlsString) DelegatingScope(org.apache.calcite.sql.validate.DelegatingScope)

Example 25 with CorrelationId

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.CorrelationId in project calcite by apache.

the class SqlToRelConverter method createJoin.

protected RelNode createJoin(Blackboard bb, RelNode leftRel, RelNode rightRel, RexNode joinCond, JoinRelType joinType) {
    assert joinCond != null;
    final CorrelationUse p = getCorrelationUse(bb, rightRel);
    if (p != null) {
        LogicalCorrelate corr = LogicalCorrelate.create(leftRel, p.r, p.id, p.requiredColumns, SemiJoinType.of(joinType));
        if (!joinCond.isAlwaysTrue()) {
            final RelFactories.FilterFactory factory = RelFactories.DEFAULT_FILTER_FACTORY;
            return factory.createFilter(corr, joinCond);
        }
        return corr;
    }
    final Join originalJoin = (Join) RelFactories.DEFAULT_JOIN_FACTORY.createJoin(leftRel, rightRel, joinCond, ImmutableSet.<CorrelationId>of(), joinType, false);
    return RelOptUtil.pushDownJoinConditions(originalJoin, relBuilder);
}
Also used : Join(org.apache.calcite.rel.core.Join) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) SqlJoin(org.apache.calcite.sql.SqlJoin) LogicalCorrelate(org.apache.calcite.rel.logical.LogicalCorrelate) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RelFactories(org.apache.calcite.rel.core.RelFactories)

Aggregations

CorrelationId (org.apache.calcite.rel.core.CorrelationId)29 RelNode (org.apache.calcite.rel.RelNode)18 RexNode (org.apache.calcite.rex.RexNode)15 ArrayList (java.util.ArrayList)11 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)10 RelDataType (org.apache.calcite.rel.type.RelDataType)7 RexBuilder (org.apache.calcite.rex.RexBuilder)7 LogicalCorrelate (org.apache.calcite.rel.logical.LogicalCorrelate)6 RexFieldAccess (org.apache.calcite.rex.RexFieldAccess)6 ImmutableList (com.google.common.collect.ImmutableList)5 HashMap (java.util.HashMap)5 List (java.util.List)5 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)5 RexCorrelVariable (org.apache.calcite.rex.RexCorrelVariable)5 RelOptCluster (org.apache.calcite.plan.RelOptCluster)4 RelBuilder (org.apache.calcite.tools.RelBuilder)4 Function2 (org.apache.calcite.linq4j.function.Function2)3 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)3 NlsString (org.apache.calcite.util.NlsString)3 Map (java.util.Map)2