Search in sources :

Example 21 with SqlCall

use of org.apache.calcite.sql.SqlCall in project calcite by apache.

the class SqlToRelConverter method convertInToOr.

/**
 * Converts "x IN (1, 2, ...)" to "x=1 OR x=2 OR ...".
 *
 * @param leftKeys   LHS
 * @param valuesList RHS
 * @param op         The operator (IN, NOT IN, > SOME, ...)
 * @return converted expression
 */
private RexNode convertInToOr(final Blackboard bb, final List<RexNode> leftKeys, SqlNodeList valuesList, SqlInOperator op) {
    final List<RexNode> comparisons = new ArrayList<>();
    for (SqlNode rightVals : valuesList) {
        RexNode rexComparison;
        final SqlOperator comparisonOp;
        if (op instanceof SqlQuantifyOperator) {
            comparisonOp = RelOptUtil.op(((SqlQuantifyOperator) op).comparisonKind, SqlStdOperatorTable.EQUALS);
        } else {
            comparisonOp = SqlStdOperatorTable.EQUALS;
        }
        if (leftKeys.size() == 1) {
            rexComparison = rexBuilder.makeCall(comparisonOp, leftKeys.get(0), ensureSqlType(leftKeys.get(0).getType(), bb.convertExpression(rightVals)));
        } else {
            assert rightVals instanceof SqlCall;
            final SqlBasicCall call = (SqlBasicCall) rightVals;
            assert (call.getOperator() instanceof SqlRowOperator) && call.operandCount() == leftKeys.size();
            rexComparison = RexUtil.composeConjunction(rexBuilder, Iterables.transform(Pair.zip(leftKeys, call.getOperandList()), new Function<Pair<RexNode, SqlNode>, RexNode>() {

                public RexNode apply(Pair<RexNode, SqlNode> pair) {
                    return rexBuilder.makeCall(comparisonOp, pair.left, ensureSqlType(pair.left.getType(), bb.convertExpression(pair.right)));
                }
            }), false);
        }
        comparisons.add(rexComparison);
    }
    switch(op.kind) {
        case ALL:
            return RexUtil.composeConjunction(rexBuilder, comparisons, true);
        case NOT_IN:
            return rexBuilder.makeCall(SqlStdOperatorTable.NOT, RexUtil.composeDisjunction(rexBuilder, comparisons, true));
        case IN:
        case SOME:
            return RexUtil.composeDisjunction(rexBuilder, comparisons, true);
        default:
            throw new AssertionError();
    }
}
Also used : SqlOperator(org.apache.calcite.sql.SqlOperator) SqlCall(org.apache.calcite.sql.SqlCall) ArrayList(java.util.ArrayList) SqlRowOperator(org.apache.calcite.sql.fun.SqlRowOperator) SqlBasicCall(org.apache.calcite.sql.SqlBasicCall) SqlQuantifyOperator(org.apache.calcite.sql.fun.SqlQuantifyOperator) RexNode(org.apache.calcite.rex.RexNode) SqlNode(org.apache.calcite.sql.SqlNode) Pair(org.apache.calcite.util.Pair)

Example 22 with SqlCall

use of org.apache.calcite.sql.SqlCall in project calcite by apache.

the class SqlToRelConverter method convertNonCorrelatedSubQuery.

/**
 * Determines if a sub-query is non-correlated and if so, converts it to a
 * constant.
 *
 * @param subQuery  the call that references the sub-query
 * @param bb        blackboard used to convert the sub-query
 * @param converted RelNode tree corresponding to the sub-query
 * @param isExists  true if the sub-query is part of an EXISTS expression
 * @return Whether the sub-query can be converted to a constant
 */
private boolean convertNonCorrelatedSubQuery(SubQuery subQuery, Blackboard bb, RelNode converted, boolean isExists) {
    SqlCall call = (SqlBasicCall) subQuery.node;
    if (subQueryConverter.canConvertSubQuery() && isSubQueryNonCorrelated(converted, bb)) {
        // First check if the sub-query has already been converted
        // because it's a nested sub-query.  If so, don't re-evaluate
        // it again.
        RexNode constExpr = mapConvertedNonCorrSubqs.get(call);
        if (constExpr == null) {
            constExpr = subQueryConverter.convertSubQuery(call, this, isExists, config.isExplain());
        }
        if (constExpr != null) {
            subQuery.expr = constExpr;
            mapConvertedNonCorrSubqs.put(call, constExpr);
            return true;
        }
    }
    return false;
}
Also used : SqlBasicCall(org.apache.calcite.sql.SqlBasicCall) SqlCall(org.apache.calcite.sql.SqlCall) RexNode(org.apache.calcite.rex.RexNode)

Example 23 with SqlCall

use of org.apache.calcite.sql.SqlCall in project calcite by apache.

the class SqlToRelConverter method convertIdentifier.

/**
 * Converts an identifier into an expression in a given scope. For example,
 * the "empno" in "select empno from emp join dept" becomes "emp.empno".
 */
private RexNode convertIdentifier(Blackboard bb, SqlIdentifier identifier) {
    // first check for reserved identifiers like CURRENT_USER
    final SqlCall call = SqlUtil.makeCall(opTab, identifier);
    if (call != null) {
        return bb.convertExpression(call);
    }
    String pv = null;
    if (bb.isPatternVarRef && identifier.names.size() > 1) {
        pv = identifier.names.get(0);
    }
    final SqlQualified qualified;
    if (bb.scope != null) {
        qualified = bb.scope.fullyQualify(identifier);
    } else {
        qualified = SqlQualified.create(null, 1, null, identifier);
    }
    final Pair<RexNode, Map<String, Integer>> e0 = bb.lookupExp(qualified);
    RexNode e = e0.left;
    for (String name : qualified.suffix()) {
        if (e == e0.left && e0.right != null) {
            int i = e0.right.get(name);
            e = rexBuilder.makeFieldAccess(e, i);
        } else {
            // name already fully-qualified
            final boolean caseSensitive = true;
            if (identifier.isStar() && bb.scope instanceof MatchRecognizeScope) {
                e = rexBuilder.makeFieldAccess(e, 0);
            } else {
                e = rexBuilder.makeFieldAccess(e, name, caseSensitive);
            }
        }
    }
    if (e instanceof RexInputRef) {
        // adjust the type to account for nulls introduced by outer joins
        e = adjustInputRef(bb, (RexInputRef) e);
        if (pv != null) {
            e = RexPatternFieldRef.of(pv, (RexInputRef) e);
        }
    }
    if (e0.left instanceof RexCorrelVariable) {
        assert e instanceof RexFieldAccess;
        final RexNode prev = bb.mapCorrelateToRex.put(((RexCorrelVariable) e0.left).id, (RexFieldAccess) e);
        assert prev == null;
    }
    return e;
}
Also used : RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) SqlCall(org.apache.calcite.sql.SqlCall) SqlQualified(org.apache.calcite.sql.validate.SqlQualified) RexInputRef(org.apache.calcite.rex.RexInputRef) NlsString(org.apache.calcite.util.NlsString) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode) MatchRecognizeScope(org.apache.calcite.sql.validate.MatchRecognizeScope)

Example 24 with SqlCall

use of org.apache.calcite.sql.SqlCall in project calcite by apache.

the class SqlValidatorUtil method convertGroupSet.

/**
 * Analyzes a GROUPING SETS item in a GROUP BY clause.
 */
private static void convertGroupSet(SqlValidatorScope scope, GroupAnalyzer groupAnalyzer, ImmutableList.Builder<ImmutableBitSet> builder, SqlNode groupExpr) {
    switch(groupExpr.getKind()) {
        case GROUPING_SETS:
            final SqlCall call = (SqlCall) groupExpr;
            for (SqlNode node : call.getOperandList()) {
                convertGroupSet(scope, groupAnalyzer, builder, node);
            }
            return;
        case ROW:
            final List<ImmutableBitSet> bitSets = analyzeGroupTuple(scope, groupAnalyzer, ((SqlCall) groupExpr).getOperandList());
            builder.add(ImmutableBitSet.union(bitSets));
            return;
        case ROLLUP:
        case CUBE:
            {
                // GROUPING SETS ( (a), ROLLUP(c,b), CUBE(d,e) )
                // is EQUIVALENT to
                // GROUPING SETS ( (a), (c,b), (b) ,(), (d,e), (d), (e) ).
                // Expand all ROLLUP/CUBE nodes
                List<ImmutableBitSet> operandBitSet = analyzeGroupTuple(scope, groupAnalyzer, ((SqlCall) groupExpr).getOperandList());
                switch(groupExpr.getKind()) {
                    case ROLLUP:
                        builder.addAll(rollup(operandBitSet));
                        return;
                    default:
                        builder.addAll(cube(operandBitSet));
                        return;
                }
            }
        default:
            builder.add(analyzeGroupExpr(scope, groupAnalyzer, groupExpr));
            return;
    }
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) SqlCall(org.apache.calcite.sql.SqlCall) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlNode(org.apache.calcite.sql.SqlNode)

Example 25 with SqlCall

use of org.apache.calcite.sql.SqlCall in project calcite by apache.

the class SqlValidatorUtil method analyzeGroupExpr.

/**
 * Analyzes a component of a tuple in a GROUPING SETS clause.
 */
private static ImmutableBitSet analyzeGroupExpr(SqlValidatorScope scope, GroupAnalyzer groupAnalyzer, SqlNode groupExpr) {
    final SqlNode expandedGroupExpr = scope.getValidator().expand(groupExpr, scope);
    switch(expandedGroupExpr.getKind()) {
        case ROW:
            return ImmutableBitSet.union(analyzeGroupTuple(scope, groupAnalyzer, ((SqlCall) expandedGroupExpr).getOperandList()));
        case OTHER:
            if (expandedGroupExpr instanceof SqlNodeList && ((SqlNodeList) expandedGroupExpr).size() == 0) {
                return ImmutableBitSet.of();
            }
    }
    final int ref = lookupGroupExpr(groupAnalyzer, groupExpr);
    if (expandedGroupExpr instanceof SqlIdentifier) {
        // SQL 2003 does not allow expressions of column references
        SqlIdentifier expr = (SqlIdentifier) expandedGroupExpr;
        // column references should be fully qualified.
        assert expr.names.size() == 2;
        String originalRelName = expr.names.get(0);
        String originalFieldName = expr.names.get(1);
        final SqlNameMatcher nameMatcher = scope.getValidator().getCatalogReader().nameMatcher();
        final SqlValidatorScope.ResolvedImpl resolved = new SqlValidatorScope.ResolvedImpl();
        scope.resolve(ImmutableList.of(originalRelName), nameMatcher, false, resolved);
        assert resolved.count() == 1;
        final SqlValidatorScope.Resolve resolve = resolved.only();
        final RelDataType rowType = resolve.rowType();
        final int childNamespaceIndex = resolve.path.steps().get(0).i;
        int namespaceOffset = 0;
        if (childNamespaceIndex > 0) {
            // If not the first child, need to figure out the width of
            // output types from all the preceding namespaces
            final SqlValidatorScope ancestorScope = resolve.scope;
            assert ancestorScope instanceof ListScope;
            List<SqlValidatorNamespace> children = ((ListScope) ancestorScope).getChildren();
            for (int j = 0; j < childNamespaceIndex; j++) {
                namespaceOffset += children.get(j).getRowType().getFieldCount();
            }
        }
        RelDataTypeField field = nameMatcher.field(rowType, originalFieldName);
        int origPos = namespaceOffset + field.getIndex();
        groupAnalyzer.groupExprProjection.put(origPos, ref);
    }
    return ImmutableBitSet.of(ref);
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

SqlCall (org.apache.calcite.sql.SqlCall)108 SqlNode (org.apache.calcite.sql.SqlNode)81 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)32 SqlNodeList (org.apache.calcite.sql.SqlNodeList)32 RelDataType (org.apache.calcite.rel.type.RelDataType)30 SqlOperator (org.apache.calcite.sql.SqlOperator)26 BitString (org.apache.calcite.util.BitString)19 ArrayList (java.util.ArrayList)18 SqlSelect (org.apache.calcite.sql.SqlSelect)17 RexNode (org.apache.calcite.rex.RexNode)13 SqlBasicCall (org.apache.calcite.sql.SqlBasicCall)12 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)11 SqlLiteral (org.apache.calcite.sql.SqlLiteral)11 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)9 SqlKind (org.apache.calcite.sql.SqlKind)9 SqlParserPos (org.apache.calcite.sql.parser.SqlParserPos)9 List (java.util.List)8 SqlCallBinding (org.apache.calcite.sql.SqlCallBinding)8 Pair (org.apache.calcite.util.Pair)8 RelNode (org.apache.calcite.rel.RelNode)7