Search in sources :

Example 6 with SqlValidatorNamespace

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

the class SqlTesterImpl method checkMonotonic.

public void checkMonotonic(String query, SqlMonotonicity expectedMonotonicity) {
    SqlValidator validator = getValidator();
    SqlNode n = parseAndValidate(validator, query);
    final RelDataType rowType = validator.getValidatedNodeType(n);
    final SqlValidatorNamespace selectNamespace = validator.getNamespace(n);
    final String field0 = rowType.getFieldList().get(0).getName();
    final SqlMonotonicity monotonicity = selectNamespace.getMonotonicity(field0);
    assertThat(monotonicity, equalTo(expectedMonotonicity));
}
Also used : SqlValidator(org.apache.calcite.sql.validate.SqlValidator) SqlMonotonicity(org.apache.calcite.sql.validate.SqlMonotonicity) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlValidatorNamespace(org.apache.calcite.sql.validate.SqlValidatorNamespace) SqlNode(org.apache.calcite.sql.SqlNode)

Example 7 with SqlValidatorNamespace

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

the class SqlCallBinding method getOperandType.

@Override
public RelDataType getOperandType(int ordinal) {
    final SqlNode operand = call.operand(ordinal);
    final RelDataType type = validator.deriveType(scope, operand);
    final SqlValidatorNamespace namespace = validator.getNamespace(operand);
    if (namespace != null) {
        return namespace.getType();
    }
    return type;
}
Also used : RelDataType(org.apache.calcite.rel.type.RelDataType) SqlValidatorNamespace(org.apache.calcite.sql.validate.SqlValidatorNamespace)

Example 8 with SqlValidatorNamespace

use of org.apache.calcite.sql.validate.SqlValidatorNamespace in project flink by apache.

the class TypeInferenceOperandChecker method updateInferredType.

/**
 * Adopted from {@link org.apache.calcite.sql.validate.implicit.AbstractTypeCoercion}.
 */
private void updateInferredType(SqlValidator validator, SqlNode node, RelDataType type) {
    validator.setValidatedNodeType(node, type);
    final SqlValidatorNamespace namespace = validator.getNamespace(node);
    if (namespace != null) {
        namespace.setType(type);
    }
}
Also used : SqlValidatorNamespace(org.apache.calcite.sql.validate.SqlValidatorNamespace)

Example 9 with SqlValidatorNamespace

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

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

the class SqlToRelConverter method createAggImpl.

protected final void createAggImpl(Blackboard bb, final AggConverter aggConverter, SqlNodeList selectList, SqlNodeList groupList, SqlNode having, List<SqlNode> orderExprList) {
    // Find aggregate functions in SELECT and HAVING clause
    final AggregateFinder aggregateFinder = new AggregateFinder();
    selectList.accept(aggregateFinder);
    if (having != null) {
        having.accept(aggregateFinder);
    }
    // first replace the sub-queries inside the aggregates
    // because they will provide input rows to the aggregates.
    replaceSubQueries(bb, aggregateFinder.list, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
    // also replace sub-queries inside filters in the aggregates
    replaceSubQueries(bb, aggregateFinder.filterList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
    // If group-by clause is missing, pretend that it has zero elements.
    if (groupList == null) {
        groupList = SqlNodeList.EMPTY;
    }
    replaceSubQueries(bb, groupList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
    // register the group exprs
    // build a map to remember the projections from the top scope to the
    // output of the current root.
    // 
    // Calcite allows expressions, not just column references in
    // group by list. This is not SQL 2003 compliant, but hey.
    final AggregatingSelectScope scope = aggConverter.aggregatingSelectScope;
    final AggregatingSelectScope.Resolved r = scope.resolved.get();
    for (SqlNode groupExpr : r.groupExprList) {
        aggConverter.addGroupExpr(groupExpr);
    }
    final RexNode havingExpr;
    final List<Pair<RexNode, String>> projects = Lists.newArrayList();
    try {
        Preconditions.checkArgument(bb.agg == null, "already in agg mode");
        bb.agg = aggConverter;
        // convert the select and having expressions, so that the
        // agg converter knows which aggregations are required
        selectList.accept(aggConverter);
        // Assert we don't have dangling items left in the stack
        assert !aggConverter.inOver;
        for (SqlNode expr : orderExprList) {
            expr.accept(aggConverter);
            assert !aggConverter.inOver;
        }
        if (having != null) {
            having.accept(aggConverter);
            assert !aggConverter.inOver;
        }
        // compute inputs to the aggregator
        List<Pair<RexNode, String>> preExprs = aggConverter.getPreExprs();
        if (preExprs.size() == 0) {
            // Special case for COUNT(*), where we can end up with no inputs
            // at all.  The rest of the system doesn't like 0-tuples, so we
            // select a dummy constant here.
            final RexNode zero = rexBuilder.makeExactLiteral(BigDecimal.ZERO);
            preExprs = ImmutableList.of(Pair.of(zero, (String) null));
        }
        final RelNode inputRel = bb.root;
        // Project the expressions required by agg and having.
        bb.setRoot(relBuilder.push(inputRel).projectNamed(Pair.left(preExprs), Pair.right(preExprs), false).build(), false);
        bb.mapRootRelToFieldProjection.put(bb.root, r.groupExprProjection);
        // REVIEW jvs 31-Oct-2007:  doesn't the declaration of
        // monotonicity here assume sort-based aggregation at
        // the physical level?
        // Tell bb which of group columns are sorted.
        bb.columnMonotonicities.clear();
        for (SqlNode groupItem : groupList) {
            bb.columnMonotonicities.add(bb.scope.getMonotonicity(groupItem));
        }
        // Add the aggregator
        bb.setRoot(createAggregate(bb, r.groupSet, r.groupSets, aggConverter.getAggCalls()), false);
        bb.mapRootRelToFieldProjection.put(bb.root, r.groupExprProjection);
        // the replaced expressions
        if (having != null) {
            SqlNode newHaving = pushDownNotForIn(bb.scope, having);
            replaceSubQueries(bb, newHaving, RelOptUtil.Logic.UNKNOWN_AS_FALSE);
            havingExpr = bb.convertExpression(newHaving);
        } else {
            havingExpr = relBuilder.literal(true);
        }
        // Now convert the other sub-queries in the select list.
        // This needs to be done separately from the sub-query inside
        // any aggregate in the select list, and after the aggregate rel
        // is allocated.
        replaceSubQueries(bb, selectList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
        // Now sub-queries in the entire select list have been converted.
        // Convert the select expressions to get the final list to be
        // projected.
        int k = 0;
        // For select expressions, use the field names previously assigned
        // by the validator. If we derive afresh, we might generate names
        // like "EXPR$2" that don't match the names generated by the
        // validator. This is especially the case when there are system
        // fields; system fields appear in the relnode's rowtype but do not
        // (yet) appear in the validator type.
        final SelectScope selectScope = SqlValidatorUtil.getEnclosingSelectScope(bb.scope);
        assert selectScope != null;
        final SqlValidatorNamespace selectNamespace = validator.getNamespace(selectScope.getNode());
        final List<String> names = selectNamespace.getRowType().getFieldNames();
        int sysFieldCount = selectList.size() - names.size();
        for (SqlNode expr : selectList) {
            projects.add(Pair.of(bb.convertExpression(expr), k < sysFieldCount ? validator.deriveAlias(expr, k++) : names.get(k++ - sysFieldCount)));
        }
        for (SqlNode expr : orderExprList) {
            projects.add(Pair.of(bb.convertExpression(expr), validator.deriveAlias(expr, k++)));
        }
    } finally {
        bb.agg = null;
    }
    // implement HAVING (we have already checked that it is non-trivial)
    relBuilder.push(bb.root);
    if (havingExpr != null) {
        relBuilder.filter(havingExpr);
    }
    // implement the SELECT list
    relBuilder.project(Pair.left(projects), Pair.right(projects)).rename(Pair.right(projects));
    bb.setRoot(relBuilder.build(), false);
    // Tell bb which of group columns are sorted.
    bb.columnMonotonicities.clear();
    for (SqlNode selectItem : selectList) {
        bb.columnMonotonicities.add(bb.scope.getMonotonicity(selectItem));
    }
}
Also used : SelectScope(org.apache.calcite.sql.validate.SelectScope) AggregatingSelectScope(org.apache.calcite.sql.validate.AggregatingSelectScope) NlsString(org.apache.calcite.util.NlsString) RelNode(org.apache.calcite.rel.RelNode) SqlValidatorNamespace(org.apache.calcite.sql.validate.SqlValidatorNamespace) AggregatingSelectScope(org.apache.calcite.sql.validate.AggregatingSelectScope) SqlNode(org.apache.calcite.sql.SqlNode) RexNode(org.apache.calcite.rex.RexNode) Pair(org.apache.calcite.util.Pair)

Aggregations

SqlValidatorNamespace (org.apache.calcite.sql.validate.SqlValidatorNamespace)12 RelDataType (org.apache.calcite.rel.type.RelDataType)6 NlsString (org.apache.calcite.util.NlsString)6 RelNode (org.apache.calcite.rel.RelNode)5 RexNode (org.apache.calcite.rex.RexNode)4 SqlNode (org.apache.calcite.sql.SqlNode)4 ArrayList (java.util.ArrayList)3 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)3 SqlValidatorScope (org.apache.calcite.sql.validate.SqlValidatorScope)3 SqlCall (org.apache.calcite.sql.SqlCall)2 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)2 SqlNodeList (org.apache.calcite.sql.SqlNodeList)2 SqlNameMatcher (org.apache.calcite.sql.validate.SqlNameMatcher)2 SqlValidatorTable (org.apache.calcite.sql.validate.SqlValidatorTable)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 TreeSet (java.util.TreeSet)1 RelOptSamplingParameters (org.apache.calcite.plan.RelOptSamplingParameters)1 RelOptTable (org.apache.calcite.plan.RelOptTable)1