Search in sources :

Example 6 with SqlWindow

use of org.apache.calcite.sql.SqlWindow in project flink by apache.

the class SqlValidatorImpl method resolveWindow.

public SqlWindow resolveWindow(SqlNode windowOrRef, SqlValidatorScope scope) {
    SqlWindow window;
    if (windowOrRef instanceof SqlIdentifier) {
        window = getWindowByName((SqlIdentifier) windowOrRef, scope);
    } else {
        window = (SqlWindow) windowOrRef;
    }
    while (true) {
        final SqlIdentifier refId = window.getRefName();
        if (refId == null) {
            break;
        }
        final String refName = refId.getSimple();
        SqlWindow refWindow = scope.lookupWindow(refName);
        if (refWindow == null) {
            throw newValidationError(refId, RESOURCE.windowNotFound(refName));
        }
        window = window.overlay(refWindow, this);
    }
    return window;
}
Also used : SqlWindow(org.apache.calcite.sql.SqlWindow) BitString(org.apache.calcite.util.BitString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier)

Example 7 with SqlWindow

use of org.apache.calcite.sql.SqlWindow in project flink by apache.

the class SqlValidatorImpl method validateWindow.

public void validateWindow(SqlNode windowOrId, SqlValidatorScope scope, SqlCall call) {
    // Enable nested aggregates with window aggregates (OVER operator)
    inWindow = true;
    final SqlWindow targetWindow;
    switch(windowOrId.getKind()) {
        case IDENTIFIER:
            // Just verify the window exists in this query.  It will validate
            // when the definition is processed
            targetWindow = getWindowByName((SqlIdentifier) windowOrId, scope);
            break;
        case WINDOW:
            targetWindow = (SqlWindow) windowOrId;
            break;
        default:
            throw Util.unexpected(windowOrId.getKind());
    }
    assert targetWindow.getWindowCall() == null;
    targetWindow.setWindowCall(call);
    targetWindow.validate(this, scope);
    targetWindow.setWindowCall(null);
    call.validate(this, scope);
    validateAggregateParams(call, null, null, scope);
    // Disable nested aggregates post validation
    inWindow = false;
}
Also used : SqlWindow(org.apache.calcite.sql.SqlWindow) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier)

Example 8 with SqlWindow

use of org.apache.calcite.sql.SqlWindow in project drill by axbaretto.

the class UnsupportedOperatorsVisitor method visit.

@Override
public SqlNode visit(SqlCall sqlCall) {
    // Inspect the window functions
    if (sqlCall instanceof SqlSelect) {
        SqlSelect sqlSelect = (SqlSelect) sqlCall;
        checkGrouping((sqlSelect));
        checkRollupCubeGrpSets(sqlSelect);
        for (SqlNode nodeInSelectList : sqlSelect.getSelectList()) {
            // enter the first operand of AS operator
            if (nodeInSelectList.getKind() == SqlKind.AS && (((SqlCall) nodeInSelectList).getOperandList().get(0).getKind() == SqlKind.OVER)) {
                nodeInSelectList = ((SqlCall) nodeInSelectList).getOperandList().get(0);
            }
            if (nodeInSelectList.getKind() == SqlKind.OVER) {
                // Throw exceptions if window functions are disabled
                if (!context.getOptions().getOption(ExecConstants.ENABLE_WINDOW_FUNCTIONS).bool_val) {
                    unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Window functions are disabled\n" + "See Apache Drill JIRA: DRILL-2559");
                    throw new UnsupportedOperationException();
                }
                // DRILL-3182, DRILL-3195
                SqlCall over = (SqlCall) nodeInSelectList;
                if (over.getOperandList().get(0) instanceof SqlCall) {
                    SqlCall function = (SqlCall) over.getOperandList().get(0);
                    // Window function with DISTINCT qualifier is temporarily disabled
                    if (function.getFunctionQuantifier() != null && function.getFunctionQuantifier().getValue() == SqlSelectKeyword.DISTINCT) {
                        unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "DISTINCT for window aggregate functions is not currently supported\n" + "See Apache Drill JIRA: DRILL-3182");
                        throw new UnsupportedOperationException();
                    }
                    // DRILL-3596: we only allow (<column-name>) or (<column-name>, 1)
                    final String functionName = function.getOperator().getName().toUpperCase();
                    if ("LEAD".equals(functionName) || "LAG".equals(functionName)) {
                        boolean supported = true;
                        if (function.operandCount() > 2) {
                            // we don't support more than 2 arguments
                            supported = false;
                        } else if (function.operandCount() == 2) {
                            SqlNode operand = function.operand(1);
                            if (operand instanceof SqlNumericLiteral) {
                                SqlNumericLiteral offsetLiteral = (SqlNumericLiteral) operand;
                                try {
                                    if (offsetLiteral.intValue(true) != 1) {
                                        // we don't support offset != 1
                                        supported = false;
                                    }
                                } catch (AssertionError e) {
                                    // we only support offset as an integer
                                    supported = false;
                                }
                            } else {
                                // we only support offset as a numeric literal
                                supported = false;
                            }
                        }
                        if (!supported) {
                            unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Function " + functionName + " only supports (<value expression>) or (<value expression>, 1)\n" + "See Apache DRILL JIRA: DRILL-3596");
                            throw new UnsupportedOperationException();
                        }
                    }
                }
            }
        }
    }
    // (i.e., BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
    if (sqlCall instanceof SqlWindow) {
        SqlWindow window = (SqlWindow) sqlCall;
        SqlNode lowerBound = window.getLowerBound();
        SqlNode upperBound = window.getUpperBound();
        // If no frame is specified
        // it is a default frame
        boolean isSupported = (lowerBound == null && upperBound == null);
        // RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        if (window.getOrderList().size() != 0 && !window.isRows() && SqlWindow.isUnboundedPreceding(lowerBound) && (upperBound == null || SqlWindow.isCurrentRow(upperBound) || SqlWindow.isUnboundedFollowing(upperBound))) {
            isSupported = true;
        }
        // is supported with and without the ORDER BY clause
        if (window.isRows() && SqlWindow.isUnboundedPreceding(lowerBound) && (upperBound == null || SqlWindow.isCurrentRow(upperBound))) {
            isSupported = true;
        }
        // is supported with and without an ORDER BY clause
        if (!window.isRows() && SqlWindow.isCurrentRow(lowerBound) && SqlWindow.isCurrentRow(upperBound)) {
            isSupported = true;
        }
        // ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        if (window.getOrderList().size() == 0 && SqlWindow.isUnboundedPreceding(lowerBound) && SqlWindow.isUnboundedFollowing(upperBound)) {
            isSupported = true;
        }
        if (!isSupported) {
            unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "This type of window frame is currently not supported \n" + "See Apache Drill JIRA: DRILL-3188");
            throw new UnsupportedOperationException();
        }
        // DRILL-3189: Disable DISALLOW PARTIAL
        if (!window.isAllowPartial()) {
            unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Disallowing partial windows is currently not supported \n" + "See Apache Drill JIRA: DRILL-3189");
            throw new UnsupportedOperationException();
        }
    }
    // Disable unsupported Intersect, Except
    if (sqlCall.getKind() == SqlKind.INTERSECT || sqlCall.getKind() == SqlKind.EXCEPT) {
        unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.RELATIONAL, sqlCall.getOperator().getName() + " is not supported\n" + "See Apache Drill JIRA: DRILL-1921");
        throw new UnsupportedOperationException();
    }
    // Disable unsupported JOINs
    if (sqlCall.getKind() == SqlKind.JOIN) {
        SqlJoin join = (SqlJoin) sqlCall;
        // Block Natural Join
        if (join.isNatural()) {
            unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.RELATIONAL, "NATURAL JOIN is not supported\n" + "See Apache Drill JIRA: DRILL-1986");
            throw new UnsupportedOperationException();
        }
        // Block Cross Join
        if (join.getJoinType() == JoinType.CROSS) {
            unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.RELATIONAL, "CROSS JOIN is not supported\n" + "See Apache Drill JIRA: DRILL-1921");
            throw new UnsupportedOperationException();
        }
    }
    // Disable Function
    for (String strOperator : disabledOperators) {
        if (sqlCall.getOperator().isName(strOperator)) {
            unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, sqlCall.getOperator().getName() + " is not supported\n" + "See Apache Drill JIRA: DRILL-2115");
            throw new UnsupportedOperationException();
        }
    }
    // Disable complex functions incorrect placement
    if (sqlCall instanceof SqlSelect) {
        SqlSelect sqlSelect = (SqlSelect) sqlCall;
        for (SqlNode nodeInSelectList : sqlSelect.getSelectList()) {
            if (checkDirExplorers(nodeInSelectList)) {
                unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions are not supported in Select List\n" + "See Apache Drill JIRA: DRILL-3944");
                throw new UnsupportedOperationException();
            }
        }
        if (sqlSelect.hasWhere()) {
            if (checkDirExplorers(sqlSelect.getWhere()) && !context.getPlannerSettings().isConstantFoldingEnabled()) {
                unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions can not be used " + "when " + PlannerSettings.CONSTANT_FOLDING.getOptionName() + " option is set to false\n" + "See Apache Drill JIRA: DRILL-3944");
                throw new UnsupportedOperationException();
            }
        }
        if (sqlSelect.hasOrderBy()) {
            for (SqlNode sqlNode : sqlSelect.getOrderList()) {
                if (containsFlatten(sqlNode)) {
                    unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Order By\n" + "See Apache Drill JIRA: DRILL-2181");
                    throw new UnsupportedOperationException();
                } else if (checkDirExplorers(sqlNode)) {
                    unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions are not supported in Order By\n" + "See Apache Drill JIRA: DRILL-3944");
                    throw new UnsupportedOperationException();
                }
            }
        }
        if (sqlSelect.getGroup() != null) {
            for (SqlNode sqlNode : sqlSelect.getGroup()) {
                if (containsFlatten(sqlNode)) {
                    unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Group By\n" + "See Apache Drill JIRA: DRILL-2181");
                    throw new UnsupportedOperationException();
                } else if (checkDirExplorers(sqlNode)) {
                    unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions are not supported in Group By\n" + "See Apache Drill JIRA: DRILL-3944");
                    throw new UnsupportedOperationException();
                }
            }
        }
        if (sqlSelect.isDistinct()) {
            for (SqlNode column : sqlSelect.getSelectList()) {
                if (column.getKind() == SqlKind.AS) {
                    if (containsFlatten(((SqlCall) column).getOperandList().get(0))) {
                        unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Distinct\n" + "See Apache Drill JIRA: DRILL-2181");
                        throw new UnsupportedOperationException();
                    }
                } else {
                    if (containsFlatten(column)) {
                        unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Distinct\n" + "See Apache Drill JIRA: DRILL-2181");
                        throw new UnsupportedOperationException();
                    }
                }
            }
        }
    }
    if (DrillCalciteWrapperUtility.extractSqlOperatorFromWrapper(sqlCall.getOperator()) instanceof SqlCountAggFunction) {
        for (SqlNode sqlNode : sqlCall.getOperandList()) {
            if (containsFlatten(sqlNode)) {
                unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function in aggregate functions is not supported\n" + "See Apache Drill JIRA: DRILL-2181");
                throw new UnsupportedOperationException();
            }
        }
    }
    return sqlCall.getOperator().acceptCall(this, sqlCall);
}
Also used : SqlSelect(org.apache.calcite.sql.SqlSelect) SqlCall(org.apache.calcite.sql.SqlCall) SqlJoin(org.apache.calcite.sql.SqlJoin) SqlWindow(org.apache.calcite.sql.SqlWindow) SqlNumericLiteral(org.apache.calcite.sql.SqlNumericLiteral) SqlCountAggFunction(org.apache.calcite.sql.fun.SqlCountAggFunction) SqlNode(org.apache.calcite.sql.SqlNode)

Example 9 with SqlWindow

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

the class AggChecker method visit.

public Void visit(SqlCall call) {
    final SqlValidatorScope scope = scopes.peek();
    if (call.getOperator().isAggregator()) {
        if (distinct) {
            if (scope instanceof AggregatingSelectScope) {
                SqlNodeList selectList = ((SqlSelect) scope.getNode()).getSelectList();
                // Check if this aggregation function is just an element in the select
                for (SqlNode sqlNode : selectList) {
                    if (sqlNode.getKind() == SqlKind.AS) {
                        sqlNode = ((SqlCall) sqlNode).operand(0);
                    }
                    if (validator.expand(sqlNode, scope).equalsDeep(call, Litmus.IGNORE)) {
                        return null;
                    }
                }
            }
            // Cannot use agg fun in ORDER BY clause if have SELECT DISTINCT.
            SqlNode originalExpr = validator.getOriginal(call);
            final String exprString = originalExpr.toString();
            throw validator.newValidationError(call, RESOURCE.notSelectDistinctExpr(exprString));
        }
        // BY deptno'
        return null;
    }
    if (call.getKind() == SqlKind.FILTER) {
        call.operand(0).accept(this);
        return null;
    }
    // Visit the operand in window function
    if (call.getKind() == SqlKind.OVER) {
        for (SqlNode operand : call.<SqlCall>operand(0).getOperandList()) {
            operand.accept(this);
        }
        // Check the OVER clause
        final SqlNode over = call.operand(1);
        if (over instanceof SqlCall) {
            over.accept(this);
        } else if (over instanceof SqlIdentifier) {
            // Check the corresponding SqlWindow in WINDOW clause
            final SqlWindow window = scope.lookupWindow(((SqlIdentifier) over).getSimple());
            window.getPartitionList().accept(this);
            window.getOrderList().accept(this);
        }
    }
    if (isGroupExpr(call)) {
        // This call matches an expression in the GROUP BY clause.
        return null;
    }
    final SqlCall groupCall = SqlStdOperatorTable.convertAuxiliaryToGroupCall(call);
    if (groupCall != null) {
        if (isGroupExpr(groupCall)) {
            // TUMBLE(rowtime, INTERVAL '1' HOUR')
            return null;
        }
        throw validator.newValidationError(groupCall, RESOURCE.auxiliaryWithoutMatchingGroupCall(call.getOperator().getName(), groupCall.getOperator().getName()));
    }
    if (call.isA(SqlKind.QUERY)) {
        // references to forbidden columns.
        return null;
    }
    // Switch to new scope.
    SqlValidatorScope newScope = scope.getOperandScope(call);
    scopes.push(newScope);
    // Visit the operands (only expressions).
    call.getOperator().acceptCall(this, call, true, ArgHandlerImpl.<Void>instance());
    // Restore scope.
    scopes.pop();
    return null;
}
Also used : SqlSelect(org.apache.calcite.sql.SqlSelect) SqlCall(org.apache.calcite.sql.SqlCall) SqlWindow(org.apache.calcite.sql.SqlWindow) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlNode(org.apache.calcite.sql.SqlNode)

Example 10 with SqlWindow

use of org.apache.calcite.sql.SqlWindow in project flink by apache.

the class SqlValidatorImpl method validateWindowClause.

protected void validateWindowClause(SqlSelect select) {
    final SqlNodeList windowList = select.getWindowList();
    @SuppressWarnings("unchecked") final List<SqlWindow> windows = (List) windowList.getList();
    if (windows.isEmpty()) {
        return;
    }
    final SelectScope windowScope = (SelectScope) getFromScope(select);
    assert windowScope != null;
    // 2. ensure they are unique within this scope
    for (SqlWindow window : windows) {
        SqlIdentifier declName = window.getDeclName();
        if (!declName.isSimple()) {
            throw newValidationError(declName, RESOURCE.windowNameMustBeSimple());
        }
        if (windowScope.existingWindowName(declName.toString())) {
            throw newValidationError(declName, RESOURCE.duplicateWindowName());
        } else {
            windowScope.addWindowName(declName.toString());
        }
    }
    // Check for pairs of windows which are equivalent.
    for (int i = 0; i < windows.size(); i++) {
        SqlNode window1 = windows.get(i);
        for (int j = i + 1; j < windows.size(); j++) {
            SqlNode window2 = windows.get(j);
            if (window1.equalsDeep(window2, Litmus.IGNORE)) {
                throw newValidationError(window2, RESOURCE.dupWindowSpec());
            }
        }
    }
    for (SqlWindow window : windows) {
        final SqlNodeList expandedOrderList = (SqlNodeList) expand(window.getOrderList(), windowScope);
        window.setOrderList(expandedOrderList);
        expandedOrderList.validate(this, windowScope);
        final SqlNodeList expandedPartitionList = (SqlNodeList) expand(window.getPartitionList(), windowScope);
        window.setPartitionList(expandedPartitionList);
        expandedPartitionList.validate(this, windowScope);
    }
    // Hand off to validate window spec components
    windowList.validate(this, windowScope);
}
Also used : SqlWindow(org.apache.calcite.sql.SqlWindow) SqlNodeList(org.apache.calcite.sql.SqlNodeList) ArrayList(java.util.ArrayList) AbstractList(java.util.AbstractList) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) ImmutableNullableList(org.apache.calcite.util.ImmutableNullableList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

SqlWindow (org.apache.calcite.sql.SqlWindow)13 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)8 SqlNode (org.apache.calcite.sql.SqlNode)6 SqlNodeList (org.apache.calcite.sql.SqlNodeList)5 SqlCall (org.apache.calcite.sql.SqlCall)4 BitString (org.apache.calcite.util.BitString)4 ImmutableList (com.google.common.collect.ImmutableList)3 SqlSelect (org.apache.calcite.sql.SqlSelect)3 AbstractList (java.util.AbstractList)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 SqlJoin (org.apache.calcite.sql.SqlJoin)2 SqlNumericLiteral (org.apache.calcite.sql.SqlNumericLiteral)2 SqlCountAggFunction (org.apache.calcite.sql.fun.SqlCountAggFunction)2 ImmutableNullableList (org.apache.calcite.util.ImmutableNullableList)2 RexFieldCollation (org.apache.calcite.rex.RexFieldCollation)1 RexNode (org.apache.calcite.rex.RexNode)1 RexShuttle (org.apache.calcite.rex.RexShuttle)1 SqlKind (org.apache.calcite.sql.SqlKind)1 SqlLiteral (org.apache.calcite.sql.SqlLiteral)1