Search in sources :

Example 91 with RelDataType

use of org.apache.calcite.rel.type.RelDataType in project calcite by apache.

the class SqlValidatorImpl method validateWithItem.

public void validateWithItem(SqlWithItem withItem) {
    if (withItem.columnList != null) {
        final RelDataType rowType = getValidatedNodeType(withItem.query);
        final int fieldCount = rowType.getFieldCount();
        if (withItem.columnList.size() != fieldCount) {
            throw newValidationError(withItem.columnList, RESOURCE.columnCountMismatch());
        }
        SqlValidatorUtil.checkIdentifierListForDuplicates(withItem.columnList.getList(), validationErrorFunction);
    } else {
        // Luckily, field names have not been make unique yet.
        final List<String> fieldNames = getValidatedNodeType(withItem.query).getFieldNames();
        final int i = Util.firstDuplicate(fieldNames);
        if (i >= 0) {
            throw newValidationError(withItem.query, RESOURCE.duplicateColumnAndNoColumnList(fieldNames.get(i)));
        }
    }
}
Also used : RelDataType(org.apache.calcite.rel.type.RelDataType) BitString(org.apache.calcite.util.BitString)

Example 92 with RelDataType

use of org.apache.calcite.rel.type.RelDataType in project calcite by apache.

the class SqlValidatorImpl method validateValues.

/**
 * Validates a VALUES clause.
 *
 * @param node          Values clause
 * @param targetRowType Row type which expression must conform to
 * @param scope         Scope within which clause occurs
 */
protected void validateValues(SqlCall node, RelDataType targetRowType, final SqlValidatorScope scope) {
    assert node.getKind() == SqlKind.VALUES;
    final List<SqlNode> operands = node.getOperandList();
    for (SqlNode operand : operands) {
        if (!(operand.getKind() == SqlKind.ROW)) {
            throw Util.needToImplement("Values function where operands are scalars");
        }
        SqlCall rowConstructor = (SqlCall) operand;
        if (conformance.isInsertSubsetColumnsAllowed() && targetRowType.isStruct() && rowConstructor.operandCount() < targetRowType.getFieldCount()) {
            targetRowType = typeFactory.createStructType(targetRowType.getFieldList().subList(0, rowConstructor.operandCount()));
        } else if (targetRowType.isStruct() && rowConstructor.operandCount() != targetRowType.getFieldCount()) {
            return;
        }
        inferUnknownTypes(targetRowType, scope, rowConstructor);
        if (targetRowType.isStruct()) {
            for (Pair<SqlNode, RelDataTypeField> pair : Pair.zip(rowConstructor.getOperandList(), targetRowType.getFieldList())) {
                if (!pair.right.getType().isNullable() && SqlUtil.isNullLiteral(pair.left, false)) {
                    throw newValidationError(node, RESOURCE.columnNotNullable(pair.right.getName()));
                }
            }
        }
    }
    for (SqlNode operand : operands) {
        operand.validate(this, scope);
    }
    // validate that all row types have the same number of columns
    // and that expressions in each column are compatible.
    // A values expression is turned into something that looks like
    // ROW(type00, type01,...), ROW(type11,...),...
    final int rowCount = operands.size();
    if (rowCount >= 2) {
        SqlCall firstRow = (SqlCall) operands.get(0);
        final int columnCount = firstRow.operandCount();
        // 1. check that all rows have the same cols length
        for (SqlNode operand : operands) {
            SqlCall thisRow = (SqlCall) operand;
            if (columnCount != thisRow.operandCount()) {
                throw newValidationError(node, RESOURCE.incompatibleValueType(SqlStdOperatorTable.VALUES.getName()));
            }
        }
        // 2. check if types at i:th position in each row are compatible
        for (int col = 0; col < columnCount; col++) {
            final int c = col;
            final RelDataType type = typeFactory.leastRestrictive(new AbstractList<RelDataType>() {

                public RelDataType get(int row) {
                    SqlCall thisRow = (SqlCall) operands.get(row);
                    return deriveType(scope, thisRow.operand(c));
                }

                public int size() {
                    return rowCount;
                }
            });
            if (null == type) {
                throw newValidationError(node, RESOURCE.incompatibleValueType(SqlStdOperatorTable.VALUES.getName()));
            }
        }
    }
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) SqlCall(org.apache.calcite.sql.SqlCall) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlNode(org.apache.calcite.sql.SqlNode)

Example 93 with RelDataType

use of org.apache.calcite.rel.type.RelDataType in project calcite by apache.

the class SqlValidatorImpl method getLogicalTargetRowType.

protected RelDataType getLogicalTargetRowType(RelDataType targetRowType, SqlInsert insert) {
    if (insert.getTargetColumnList() == null && conformance.isInsertSubsetColumnsAllowed()) {
        // Target an implicit subset of columns.
        final SqlNode source = insert.getSource();
        final RelDataType sourceRowType = getNamespace(source).getRowType();
        final RelDataType logicalSourceRowType = getLogicalSourceRowType(sourceRowType, insert);
        final RelDataType implicitTargetRowType = typeFactory.createStructType(targetRowType.getFieldList().subList(0, logicalSourceRowType.getFieldCount()));
        final SqlValidatorNamespace targetNamespace = getNamespace(insert);
        validateNamespace(targetNamespace, implicitTargetRowType);
        return implicitTargetRowType;
    } else {
        // set of columns.
        return targetRowType;
    }
}
Also used : RelDataType(org.apache.calcite.rel.type.RelDataType) SqlNode(org.apache.calcite.sql.SqlNode)

Example 94 with RelDataType

use of org.apache.calcite.rel.type.RelDataType in project calcite by apache.

the class SqlValidatorImpl method validateJoin.

protected void validateJoin(SqlJoin join, SqlValidatorScope scope) {
    SqlNode left = join.getLeft();
    SqlNode right = join.getRight();
    SqlNode condition = join.getCondition();
    boolean natural = join.isNatural();
    final JoinType joinType = join.getJoinType();
    final JoinConditionType conditionType = join.getConditionType();
    final SqlValidatorScope joinScope = scopes.get(join);
    validateFrom(left, unknownType, joinScope);
    validateFrom(right, unknownType, joinScope);
    // Validate condition.
    switch(conditionType) {
        case NONE:
            Preconditions.checkArgument(condition == null);
            break;
        case ON:
            Preconditions.checkArgument(condition != null);
            SqlNode expandedCondition = expand(condition, joinScope);
            join.setOperand(5, expandedCondition);
            condition = join.getCondition();
            validateWhereOrOn(joinScope, condition, "ON");
            checkRollUp(null, join, condition, joinScope, "ON");
            break;
        case USING:
            SqlNodeList list = (SqlNodeList) condition;
            // Parser ensures that using clause is not empty.
            Preconditions.checkArgument(list.size() > 0, "Empty USING clause");
            for (int i = 0; i < list.size(); i++) {
                SqlIdentifier id = (SqlIdentifier) list.get(i);
                final RelDataType leftColType = validateUsingCol(id, left);
                final RelDataType rightColType = validateUsingCol(id, right);
                if (!SqlTypeUtil.isComparable(leftColType, rightColType)) {
                    throw newValidationError(id, RESOURCE.naturalOrUsingColumnNotCompatible(id.getSimple(), leftColType.toString(), rightColType.toString()));
                }
                checkRollUpInUsing(id, left);
                checkRollUpInUsing(id, right);
            }
            break;
        default:
            throw Util.unexpected(conditionType);
    }
    // Validate NATURAL.
    if (natural) {
        if (condition != null) {
            throw newValidationError(condition, RESOURCE.naturalDisallowsOnOrUsing());
        }
        // Join on fields that occur exactly once on each side. Ignore
        // fields that occur more than once on either side.
        final RelDataType leftRowType = getNamespace(left).getRowType();
        final RelDataType rightRowType = getNamespace(right).getRowType();
        List<String> naturalColumnNames = SqlValidatorUtil.deriveNaturalJoinColumnList(leftRowType, rightRowType);
        // Check compatibility of the chosen columns.
        final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
        for (String name : naturalColumnNames) {
            final RelDataType leftColType = nameMatcher.field(leftRowType, name).getType();
            final RelDataType rightColType = nameMatcher.field(rightRowType, name).getType();
            if (!SqlTypeUtil.isComparable(leftColType, rightColType)) {
                throw newValidationError(join, RESOURCE.naturalOrUsingColumnNotCompatible(name, leftColType.toString(), rightColType.toString()));
            }
        }
    }
    // a NATURAL keyword?
    switch(joinType) {
        case INNER:
        case LEFT:
        case RIGHT:
        case FULL:
            if ((condition == null) && !natural) {
                throw newValidationError(join, RESOURCE.joinRequiresCondition());
            }
            break;
        case COMMA:
        case CROSS:
            if (condition != null) {
                throw newValidationError(join.getConditionTypeNode(), RESOURCE.crossJoinDisallowsCondition());
            }
            if (natural) {
                throw newValidationError(join.getConditionTypeNode(), RESOURCE.crossJoinDisallowsCondition());
            }
            break;
        default:
            throw Util.unexpected(joinType);
    }
}
Also used : JoinConditionType(org.apache.calcite.sql.JoinConditionType) JoinType(org.apache.calcite.sql.JoinType) 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 95 with RelDataType

use of org.apache.calcite.rel.type.RelDataType in project calcite by apache.

the class SqlValidatorImpl method deriveTypeImpl.

/**
 * Derives the type of a node, never null.
 */
RelDataType deriveTypeImpl(SqlValidatorScope scope, SqlNode operand) {
    DeriveTypeVisitor v = new DeriveTypeVisitor(scope);
    final RelDataType type = operand.accept(v);
    // After Guava 17, use Verify.verifyNotNull for Preconditions.checkNotNull
    Bug.upgrade("guava-17");
    return Preconditions.checkNotNull(scope.nullifyType(operand, type));
}
Also used : RelDataType(org.apache.calcite.rel.type.RelDataType)

Aggregations

RelDataType (org.apache.calcite.rel.type.RelDataType)834 RexNode (org.apache.calcite.rex.RexNode)268 ArrayList (java.util.ArrayList)213 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)209 RelNode (org.apache.calcite.rel.RelNode)153 SqlNode (org.apache.calcite.sql.SqlNode)143 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)123 RexBuilder (org.apache.calcite.rex.RexBuilder)118 Test (org.junit.Test)62 ImmutableList (com.google.common.collect.ImmutableList)58 RexInputRef (org.apache.calcite.rex.RexInputRef)57 List (java.util.List)51 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)45 RexLiteral (org.apache.calcite.rex.RexLiteral)44 SqlNodeList (org.apache.calcite.sql.SqlNodeList)42 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)40 AggregateCall (org.apache.calcite.rel.core.AggregateCall)39 BitString (org.apache.calcite.util.BitString)38 BigDecimal (java.math.BigDecimal)35 RelBuilder (org.apache.calcite.tools.RelBuilder)34