Search in sources :

Example 91 with SqlNodeList

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

the class SqlValidatorImpl method validateGroupClause.

/**
 * Validates the GROUP BY clause of a SELECT statement. This method is called even if no GROUP
 * BY clause is present.
 */
protected void validateGroupClause(SqlSelect select) {
    SqlNodeList groupList = select.getGroup();
    if (groupList == null) {
        return;
    }
    final String clause = "GROUP BY";
    validateNoAggs(aggOrOverFinder, groupList, clause);
    final SqlValidatorScope groupScope = getGroupScope(select);
    // expand the expression in group list.
    List<SqlNode> expandedList = new ArrayList<>();
    for (SqlNode groupItem : groupList) {
        SqlNode expandedItem = expandGroupByOrHavingExpr(groupItem, groupScope, select, false);
        expandedList.add(expandedItem);
    }
    groupList = new SqlNodeList(expandedList, groupList.getParserPosition());
    select.setGroupBy(groupList);
    inferUnknownTypes(unknownType, groupScope, groupList);
    for (SqlNode groupItem : expandedList) {
        validateGroupByItem(select, groupItem);
    }
    // expressions, because they do not have a type.
    for (SqlNode node : groupList) {
        switch(node.getKind()) {
            case GROUPING_SETS:
            case ROLLUP:
            case CUBE:
                node.validate(this, groupScope);
                break;
            default:
                node.validateExpr(this, groupScope);
        }
    }
    // Derive the type of each GROUP BY item. We don't need the type, but
    // it resolves functions, and that is necessary for deducing
    // monotonicity.
    final SqlValidatorScope selectScope = getSelectScope(select);
    AggregatingSelectScope aggregatingScope = null;
    if (selectScope instanceof AggregatingSelectScope) {
        aggregatingScope = (AggregatingSelectScope) selectScope;
    }
    for (SqlNode groupItem : groupList) {
        if (groupItem instanceof SqlNodeList && ((SqlNodeList) groupItem).size() == 0) {
            continue;
        }
        validateGroupItem(groupScope, aggregatingScope, groupItem);
    }
    SqlNode agg = aggFinder.findAgg(groupList);
    if (agg != null) {
        throw newValidationError(agg, RESOURCE.aggregateIllegalInClause(clause));
    }
}
Also used : ArrayList(java.util.ArrayList) SqlNodeList(org.apache.calcite.sql.SqlNodeList) BitString(org.apache.calcite.util.BitString) SqlNode(org.apache.calcite.sql.SqlNode)

Example 92 with SqlNodeList

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

the class SqlValidatorImpl method validateMeasure.

private List<Map.Entry<String, RelDataType>> validateMeasure(SqlMatchRecognize mr, MatchRecognizeScope scope, boolean allRows) {
    final List<String> aliases = new ArrayList<>();
    final List<SqlNode> sqlNodes = new ArrayList<>();
    final SqlNodeList measures = mr.getMeasureList();
    final List<Map.Entry<String, RelDataType>> fields = new ArrayList<>();
    for (SqlNode measure : measures) {
        assert measure instanceof SqlCall;
        final String alias = deriveAlias(measure, aliases.size());
        aliases.add(alias);
        SqlNode expand = expand(measure, scope);
        expand = navigationInMeasure(expand, allRows);
        setOriginal(expand, measure);
        inferUnknownTypes(unknownType, scope, expand);
        final RelDataType type = deriveType(scope, expand);
        setValidatedNodeType(measure, type);
        fields.add(Pair.of(alias, type));
        sqlNodes.add(SqlStdOperatorTable.AS.createCall(SqlParserPos.ZERO, expand, new SqlIdentifier(alias, SqlParserPos.ZERO)));
    }
    SqlNodeList list = new SqlNodeList(sqlNodes, measures.getParserPosition());
    inferUnknownTypes(unknownType, scope, list);
    for (SqlNode node : list) {
        validateExpr(node, scope);
    }
    mr.setOperand(SqlMatchRecognize.OPERAND_MEASURES, list);
    return fields;
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) ArrayList(java.util.ArrayList) SqlNodeList(org.apache.calcite.sql.SqlNodeList) RelDataType(org.apache.calcite.rel.type.RelDataType) BitString(org.apache.calcite.util.BitString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlNode(org.apache.calcite.sql.SqlNode)

Example 93 with SqlNodeList

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

the class SqlValidatorImpl method validateSelect.

/**
 * Validates a SELECT statement.
 *
 * @param select Select statement
 * @param targetRowType Desired row type, must not be null, may be the data type 'unknown'.
 */
protected void validateSelect(SqlSelect select, RelDataType targetRowType) {
    assert targetRowType != null;
    // Namespace is either a select namespace or a wrapper around one.
    final SelectNamespace ns = getNamespace(select).unwrap(SelectNamespace.class);
    // account.
    assert ns.rowType == null;
    if (select.isDistinct()) {
        validateFeature(RESOURCE.sQLFeature_E051_01(), select.getModifierNode(SqlSelectKeyword.DISTINCT).getParserPosition());
    }
    final SqlNodeList selectItems = select.getSelectList();
    RelDataType fromType = unknownType;
    if (selectItems.size() == 1) {
        final SqlNode selectItem = selectItems.get(0);
        if (selectItem instanceof SqlIdentifier) {
            SqlIdentifier id = (SqlIdentifier) selectItem;
            if (id.isStar() && (id.names.size() == 1)) {
                // Special case: for INSERT ... VALUES(?,?), the SQL
                // standard says we're supposed to propagate the target
                // types down.  So iff the select list is an unqualified
                // star (as it will be after an INSERT ... VALUES has been
                // expanded), then propagate.
                fromType = targetRowType;
            }
        }
    }
    // Make sure that items in FROM clause have distinct aliases.
    final SelectScope fromScope = (SelectScope) getFromScope(select);
    List<String> names = fromScope.getChildNames();
    if (!catalogReader.nameMatcher().isCaseSensitive()) {
        names = names.stream().map(s -> s.toUpperCase(Locale.ROOT)).collect(Collectors.toList());
    }
    final int duplicateAliasOrdinal = Util.firstDuplicate(names);
    if (duplicateAliasOrdinal >= 0) {
        final ScopeChild child = fromScope.children.get(duplicateAliasOrdinal);
        throw newValidationError(child.namespace.getEnclosingNode(), RESOURCE.fromAliasDuplicate(child.name));
    }
    if (select.getFrom() == null) {
        if (this.config.sqlConformance().isFromRequired()) {
            throw newValidationError(select, RESOURCE.selectMissingFrom());
        }
    } else {
        validateFrom(select.getFrom(), fromType, fromScope);
    }
    validateWhereClause(select);
    validateGroupClause(select);
    validateHavingClause(select);
    validateWindowClause(select);
    handleOffsetFetch(select.getOffset(), select.getFetch());
    // Validate the SELECT clause late, because a select item might
    // depend on the GROUP BY list, or the window function might reference
    // window name in the WINDOW clause etc.
    final RelDataType rowType = validateSelectList(selectItems, select, targetRowType);
    ns.setType(rowType);
    // Validate ORDER BY after we have set ns.rowType because in some
    // dialects you can refer to columns of the select list, e.g.
    // "SELECT empno AS x FROM emp ORDER BY x"
    validateOrderList(select);
    if (shouldCheckForRollUp(select.getFrom())) {
        checkRollUpInSelectList(select);
        checkRollUp(null, select, select.getWhere(), getWhereScope(select));
        checkRollUp(null, select, select.getHaving(), getHavingScope(select));
        checkRollUpInWindowDecl(select);
        checkRollUpInGroupBy(select);
        checkRollUpInOrderBy(select);
    }
}
Also used : SqlNodeList(org.apache.calcite.sql.SqlNodeList) RelDataType(org.apache.calcite.rel.type.RelDataType) BitString(org.apache.calcite.util.BitString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlNode(org.apache.calcite.sql.SqlNode)

Example 94 with SqlNodeList

use of org.apache.calcite.sql.SqlNodeList 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)

Example 95 with SqlNodeList

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

the class SqlValidatorImpl method checkTypeAssignment.

/**
 * Checks the type assignment of an INSERT or UPDATE query.
 *
 * <p>Skip the virtual columns(can not insert into) type assignment check if the source fields
 * count equals with the real target table fields count, see how #checkFieldCount was used.
 *
 * @param sourceScope Scope of query source which is used to infer node type
 * @param table Target table
 * @param sourceRowType Source row type
 * @param targetRowType Target row type, it should either contain all the virtual columns (can
 *     not insert into) or exclude all the virtual columns
 * @param query The query
 */
protected void checkTypeAssignment(SqlValidatorScope sourceScope, SqlValidatorTable table, RelDataType sourceRowType, RelDataType targetRowType, final SqlNode query) {
    // NOTE jvs 23-Feb-2006: subclasses may allow for extra targets
    // representing system-maintained columns, so stop after all sources
    // matched
    boolean isUpdateModifiableViewTable = false;
    if (query instanceof SqlUpdate) {
        final SqlNodeList targetColumnList = ((SqlUpdate) query).getTargetColumnList();
        if (targetColumnList != null) {
            final int targetColumnCnt = targetColumnList.size();
            targetRowType = SqlTypeUtil.extractLastNFields(typeFactory, targetRowType, targetColumnCnt);
            sourceRowType = SqlTypeUtil.extractLastNFields(typeFactory, sourceRowType, targetColumnCnt);
        }
        isUpdateModifiableViewTable = table.unwrap(ModifiableViewTable.class) != null;
    }
    if (SqlTypeUtil.equalAsStructSansNullability(typeFactory, sourceRowType, targetRowType, null)) {
        // Returns early if source and target row type equals sans nullability.
        return;
    }
    if (config.typeCoercionEnabled() && !isUpdateModifiableViewTable) {
        // Try type coercion first if implicit type coercion is allowed.
        boolean coerced = typeCoercion.querySourceCoercion(sourceScope, sourceRowType, targetRowType, query);
        if (coerced) {
            return;
        }
    }
    // Fall back to default behavior: compare the type families.
    List<RelDataTypeField> sourceFields = sourceRowType.getFieldList();
    List<RelDataTypeField> targetFields = targetRowType.getFieldList();
    final int sourceCount = sourceFields.size();
    for (int i = 0; i < sourceCount; ++i) {
        RelDataType sourceType = sourceFields.get(i).getType();
        RelDataType targetType = targetFields.get(i).getType();
        if (!SqlTypeUtil.canAssignFrom(targetType, sourceType)) {
            SqlNode node = getNthExpr(query, i, sourceCount);
            if (node instanceof SqlDynamicParam) {
                continue;
            }
            String targetTypeString;
            String sourceTypeString;
            if (SqlTypeUtil.areCharacterSetsMismatched(sourceType, targetType)) {
                sourceTypeString = sourceType.getFullTypeString();
                targetTypeString = targetType.getFullTypeString();
            } else {
                sourceTypeString = sourceType.toString();
                targetTypeString = targetType.toString();
            }
            throw newValidationError(node, RESOURCE.typeNotAssignable(targetFields.get(i).getName(), targetTypeString, sourceFields.get(i).getName(), sourceTypeString));
        }
    }
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) SqlDynamicParam(org.apache.calcite.sql.SqlDynamicParam) SqlNodeList(org.apache.calcite.sql.SqlNodeList) RelDataType(org.apache.calcite.rel.type.RelDataType) BitString(org.apache.calcite.util.BitString) SqlUpdate(org.apache.calcite.sql.SqlUpdate) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

SqlNodeList (org.apache.calcite.sql.SqlNodeList)123 SqlNode (org.apache.calcite.sql.SqlNode)97 ArrayList (java.util.ArrayList)45 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)43 RelDataType (org.apache.calcite.rel.type.RelDataType)39 SqlCall (org.apache.calcite.sql.SqlCall)30 SqlSelect (org.apache.calcite.sql.SqlSelect)29 BitString (org.apache.calcite.util.BitString)23 RexNode (org.apache.calcite.rex.RexNode)13 SqlLiteral (org.apache.calcite.sql.SqlLiteral)11 ImmutableList (com.google.common.collect.ImmutableList)10 List (java.util.List)10 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)10 NlsString (org.apache.calcite.util.NlsString)9 RelNode (org.apache.calcite.rel.RelNode)8 SqlUpdate (org.apache.calcite.sql.SqlUpdate)8 SqlBasicCall (org.apache.calcite.sql.SqlBasicCall)7 SqlWriter (org.apache.calcite.sql.SqlWriter)7 SqlParserPos (org.apache.calcite.sql.parser.SqlParserPos)7 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)6