Search in sources :

Example 16 with SqlValidatorScope

use of org.apache.calcite.sql.validate.SqlValidatorScope 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 17 with SqlValidatorScope

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

the class SqlToRelConverter method convertUpdate.

private RelNode convertUpdate(SqlUpdate call) {
    final SqlValidatorScope scope = validator.getWhereScope(call.getSourceSelect());
    Blackboard bb = createBlackboard(scope, null, false);
    Builder<RexNode> rexNodeSourceExpressionListBuilder = ImmutableList.builder();
    for (SqlNode n : call.getSourceExpressionList()) {
        RexNode rn = bb.convertExpression(n);
        rexNodeSourceExpressionListBuilder.add(rn);
    }
    RelOptTable targetTable = getTargetTable(call);
    // convert update column list from SqlIdentifier to String
    final List<String> targetColumnNameList = new ArrayList<>();
    final RelDataType targetRowType = targetTable.getRowType();
    for (SqlNode node : call.getTargetColumnList()) {
        SqlIdentifier id = (SqlIdentifier) node;
        RelDataTypeField field = SqlValidatorUtil.getTargetField(targetRowType, typeFactory, id, catalogReader, targetTable);
        assert field != null : "column " + id.toString() + " not found";
        targetColumnNameList.add(field.getName());
    }
    RelNode sourceRel = convertSelect(call.getSourceSelect(), false);
    return LogicalTableModify.create(targetTable, catalogReader, sourceRel, LogicalTableModify.Operation.UPDATE, targetColumnNameList, rexNodeSourceExpressionListBuilder.build(), false);
}
Also used : SqlValidatorScope(org.apache.calcite.sql.validate.SqlValidatorScope) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) NlsString(org.apache.calcite.util.NlsString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RelOptTable(org.apache.calcite.plan.RelOptTable) RexNode(org.apache.calcite.rex.RexNode) SqlNode(org.apache.calcite.sql.SqlNode)

Example 18 with SqlValidatorScope

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

the class SqlToRelConverter method convertValues.

/**
 * Converts a SELECT statement's parse tree into a relational expression.
 */
public RelNode convertValues(SqlCall values, RelDataType targetRowType) {
    final SqlValidatorScope scope = validator.getOverScope(values);
    assert scope != null;
    final Blackboard bb = createBlackboard(scope, null, false);
    convertValuesImpl(bb, values, targetRowType);
    return bb.root;
}
Also used : SqlValidatorScope(org.apache.calcite.sql.validate.SqlValidatorScope)

Example 19 with SqlValidatorScope

use of org.apache.calcite.sql.validate.SqlValidatorScope 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 20 with SqlValidatorScope

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

the class SqlToRelConverter method convertFrom.

/**
 * Converts a FROM clause into a relational expression.
 *
 * @param bb   Scope within which to resolve identifiers
 * @param from FROM clause of a query. Examples include:
 *
 *             <ul>
 *             <li>a single table ("SALES.EMP"),
 *             <li>an aliased table ("EMP AS E"),
 *             <li>a list of tables ("EMP, DEPT"),
 *             <li>an ANSI Join expression ("EMP JOIN DEPT ON EMP.DEPTNO =
 *             DEPT.DEPTNO"),
 *             <li>a VALUES clause ("VALUES ('Fred', 20)"),
 *             <li>a query ("(SELECT * FROM EMP WHERE GENDER = 'F')"),
 *             <li>or any combination of the above.
 *             </ul>
 */
protected void convertFrom(Blackboard bb, SqlNode from) {
    if (from == null) {
        bb.setRoot(LogicalValues.createOneRow(cluster), false);
        return;
    }
    final SqlCall call;
    final SqlNode[] operands;
    switch(from.getKind()) {
        case MATCH_RECOGNIZE:
            convertMatchRecognize(bb, (SqlCall) from);
            return;
        case AS:
            call = (SqlCall) from;
            convertFrom(bb, call.operand(0));
            if (call.operandCount() > 2 && bb.root instanceof Values) {
                final List<String> fieldNames = new ArrayList<>();
                for (SqlNode node : Util.skip(call.getOperandList(), 2)) {
                    fieldNames.add(((SqlIdentifier) node).getSimple());
                }
                bb.setRoot(relBuilder.push(bb.root).rename(fieldNames).build(), true);
            }
            return;
        case WITH_ITEM:
            convertFrom(bb, ((SqlWithItem) from).query);
            return;
        case WITH:
            convertFrom(bb, ((SqlWith) from).body);
            return;
        case TABLESAMPLE:
            operands = ((SqlBasicCall) from).getOperands();
            SqlSampleSpec sampleSpec = SqlLiteral.sampleValue(operands[1]);
            if (sampleSpec instanceof SqlSampleSpec.SqlSubstitutionSampleSpec) {
                String sampleName = ((SqlSampleSpec.SqlSubstitutionSampleSpec) sampleSpec).getName();
                datasetStack.push(sampleName);
                convertFrom(bb, operands[0]);
                datasetStack.pop();
            } else if (sampleSpec instanceof SqlSampleSpec.SqlTableSampleSpec) {
                SqlSampleSpec.SqlTableSampleSpec tableSampleSpec = (SqlSampleSpec.SqlTableSampleSpec) sampleSpec;
                convertFrom(bb, operands[0]);
                RelOptSamplingParameters params = new RelOptSamplingParameters(tableSampleSpec.isBernoulli(), tableSampleSpec.getSamplePercentage(), tableSampleSpec.isRepeatable(), tableSampleSpec.getRepeatableSeed());
                bb.setRoot(new Sample(cluster, bb.root, params), false);
            } else {
                throw new AssertionError("unknown TABLESAMPLE type: " + sampleSpec);
            }
            return;
        case IDENTIFIER:
            convertIdentifier(bb, (SqlIdentifier) from, null);
            return;
        case EXTEND:
            call = (SqlCall) from;
            SqlIdentifier id = (SqlIdentifier) call.getOperandList().get(0);
            SqlNodeList extendedColumns = (SqlNodeList) call.getOperandList().get(1);
            convertIdentifier(bb, id, extendedColumns);
            return;
        case JOIN:
            final SqlJoin join = (SqlJoin) from;
            final SqlValidatorScope scope = validator.getJoinScope(from);
            final Blackboard fromBlackboard = createBlackboard(scope, null, false);
            SqlNode left = join.getLeft();
            SqlNode right = join.getRight();
            final boolean isNatural = join.isNatural();
            final JoinType joinType = join.getJoinType();
            final SqlValidatorScope leftScope = Util.first(validator.getJoinScope(left), ((DelegatingScope) bb.scope).getParent());
            final Blackboard leftBlackboard = createBlackboard(leftScope, null, false);
            final SqlValidatorScope rightScope = Util.first(validator.getJoinScope(right), ((DelegatingScope) bb.scope).getParent());
            final Blackboard rightBlackboard = createBlackboard(rightScope, null, false);
            convertFrom(leftBlackboard, left);
            RelNode leftRel = leftBlackboard.root;
            convertFrom(rightBlackboard, right);
            RelNode rightRel = rightBlackboard.root;
            JoinRelType convertedJoinType = convertJoinType(joinType);
            RexNode conditionExp;
            final SqlValidatorNamespace leftNamespace = validator.getNamespace(left);
            final SqlValidatorNamespace rightNamespace = validator.getNamespace(right);
            if (isNatural) {
                final RelDataType leftRowType = leftNamespace.getRowType();
                final RelDataType rightRowType = rightNamespace.getRowType();
                final List<String> columnList = SqlValidatorUtil.deriveNaturalJoinColumnList(leftRowType, rightRowType);
                conditionExp = convertUsing(leftNamespace, rightNamespace, columnList);
            } else {
                conditionExp = convertJoinCondition(fromBlackboard, leftNamespace, rightNamespace, join.getCondition(), join.getConditionType(), leftRel, rightRel);
            }
            final RelNode joinRel = createJoin(fromBlackboard, leftRel, rightRel, conditionExp, convertedJoinType);
            bb.setRoot(joinRel, false);
            return;
        case SELECT:
        case INTERSECT:
        case EXCEPT:
        case UNION:
            final RelNode rel = convertQueryRecursive(from, false, null).project();
            bb.setRoot(rel, true);
            return;
        case VALUES:
            convertValuesImpl(bb, (SqlCall) from, null);
            return;
        case UNNEST:
            call = (SqlCall) from;
            final List<SqlNode> nodes = call.getOperandList();
            final SqlUnnestOperator operator = (SqlUnnestOperator) call.getOperator();
            for (SqlNode node : nodes) {
                replaceSubQueries(bb, node, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
            }
            final List<RexNode> exprs = new ArrayList<>();
            final List<String> fieldNames = new ArrayList<>();
            for (Ord<SqlNode> node : Ord.zip(nodes)) {
                exprs.add(bb.convertExpression(node.e));
                fieldNames.add(validator.deriveAlias(node.e, node.i));
            }
            RelNode child = (null != bb.root) ? bb.root : LogicalValues.createOneRow(cluster);
            relBuilder.push(child).projectNamed(exprs, fieldNames, false);
            Uncollect uncollect = new Uncollect(cluster, cluster.traitSetOf(Convention.NONE), relBuilder.build(), operator.withOrdinality);
            bb.setRoot(uncollect, true);
            return;
        case COLLECTION_TABLE:
            call = (SqlCall) from;
            // Dig out real call; TABLE() wrapper is just syntactic.
            assert call.getOperandList().size() == 1;
            final SqlCall call2 = call.operand(0);
            convertCollectionTable(bb, call2);
            return;
        default:
            throw new AssertionError("not a join operator " + from);
    }
}
Also used : SqlValidatorScope(org.apache.calcite.sql.validate.SqlValidatorScope) Uncollect(org.apache.calcite.rel.core.Uncollect) Values(org.apache.calcite.rel.core.Values) LogicalValues(org.apache.calcite.rel.logical.LogicalValues) ArrayList(java.util.ArrayList) SqlUnnestOperator(org.apache.calcite.sql.SqlUnnestOperator) RelDataType(org.apache.calcite.rel.type.RelDataType) NlsString(org.apache.calcite.util.NlsString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) RelOptSamplingParameters(org.apache.calcite.plan.RelOptSamplingParameters) SqlNode(org.apache.calcite.sql.SqlNode) SqlCall(org.apache.calcite.sql.SqlCall) Sample(org.apache.calcite.rel.core.Sample) SqlSampleSpec(org.apache.calcite.sql.SqlSampleSpec) JoinType(org.apache.calcite.sql.JoinType) SemiJoinType(org.apache.calcite.sql.SemiJoinType) JoinRelType(org.apache.calcite.rel.core.JoinRelType) RelNode(org.apache.calcite.rel.RelNode) SqlJoin(org.apache.calcite.sql.SqlJoin) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlValidatorNamespace(org.apache.calcite.sql.validate.SqlValidatorNamespace) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

SqlValidatorScope (org.apache.calcite.sql.validate.SqlValidatorScope)20 RelDataType (org.apache.calcite.rel.type.RelDataType)12 SqlNode (org.apache.calcite.sql.SqlNode)10 ArrayList (java.util.ArrayList)7 SqlNodeList (org.apache.calcite.sql.SqlNodeList)6 SqlValidator (org.apache.calcite.sql.validate.SqlValidator)6 RelNode (org.apache.calcite.rel.RelNode)5 SqlCall (org.apache.calcite.sql.SqlCall)5 List (java.util.List)4 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)4 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)4 NlsString (org.apache.calcite.util.NlsString)4 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)3 RexNode (org.apache.calcite.rex.RexNode)3 SqlOperator (org.apache.calcite.sql.SqlOperator)3 SqlSelect (org.apache.calcite.sql.SqlSelect)3 ImmutableList (com.google.common.collect.ImmutableList)2 HazelcastSqlValidator (com.hazelcast.jet.sql.impl.validate.HazelcastSqlValidator)2 QueryDataTypeFamily (com.hazelcast.sql.impl.type.QueryDataTypeFamily)2 Consumer (java.util.function.Consumer)2