Search in sources :

Example 16 with SqlDynamicParam

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

the class SqlValidatorImpl method inferUnknownTypes.

protected void inferUnknownTypes(@Nonnull RelDataType inferredType, @Nonnull SqlValidatorScope scope, @Nonnull SqlNode node) {
    Objects.requireNonNull(inferredType);
    Objects.requireNonNull(scope);
    Objects.requireNonNull(node);
    final SqlValidatorScope newScope = scopes.get(node);
    if (newScope != null) {
        scope = newScope;
    }
    boolean isNullLiteral = SqlUtil.isNullLiteral(node, false);
    if ((node instanceof SqlDynamicParam) || isNullLiteral) {
        if (inferredType.equals(unknownType)) {
            if (isNullLiteral) {
                if (config.typeCoercionEnabled()) {
                    // derive type of null literal
                    deriveType(scope, node);
                    return;
                } else {
                    throw newValidationError(node, RESOURCE.nullIllegal());
                }
            } else {
                throw newValidationError(node, RESOURCE.dynamicParamIllegal());
            }
        }
        // REVIEW:  should dynamic parameter types always be nullable?
        RelDataType newInferredType = typeFactory.createTypeWithNullability(inferredType, true);
        if (SqlTypeUtil.inCharFamily(inferredType)) {
            newInferredType = typeFactory.createTypeWithCharsetAndCollation(newInferredType, inferredType.getCharset(), inferredType.getCollation());
        }
        setValidatedNodeType(node, newInferredType);
    } else if (node instanceof SqlNodeList) {
        SqlNodeList nodeList = (SqlNodeList) node;
        if (inferredType.isStruct()) {
            if (inferredType.getFieldCount() != nodeList.size()) {
                // bust out, and the error will be detected higher up
                return;
            }
        }
        int i = 0;
        for (SqlNode child : nodeList) {
            RelDataType type;
            if (inferredType.isStruct()) {
                type = inferredType.getFieldList().get(i).getType();
                ++i;
            } else {
                type = inferredType;
            }
            inferUnknownTypes(type, scope, child);
        }
    } else if (node instanceof SqlCase) {
        final SqlCase caseCall = (SqlCase) node;
        final RelDataType whenType = caseCall.getValueOperand() == null ? booleanType : unknownType;
        for (SqlNode sqlNode : caseCall.getWhenOperands().getList()) {
            inferUnknownTypes(whenType, scope, sqlNode);
        }
        RelDataType returnType = deriveType(scope, node);
        for (SqlNode sqlNode : caseCall.getThenOperands().getList()) {
            inferUnknownTypes(returnType, scope, sqlNode);
        }
        if (!SqlUtil.isNullLiteral(caseCall.getElseOperand(), false)) {
            inferUnknownTypes(returnType, scope, caseCall.getElseOperand());
        } else {
            setValidatedNodeType(caseCall.getElseOperand(), returnType);
        }
    } else if (node.getKind() == SqlKind.AS) {
        // For AS operator, only infer the operand not the alias
        inferUnknownTypes(inferredType, scope, ((SqlCall) node).operand(0));
    } else if (node instanceof SqlCall) {
        final SqlCall call = (SqlCall) node;
        final SqlOperandTypeInference operandTypeInference = call.getOperator().getOperandTypeInference();
        final SqlCallBinding callBinding = new SqlCallBinding(this, scope, call);
        final List<SqlNode> operands = callBinding.operands();
        final RelDataType[] operandTypes = new RelDataType[operands.size()];
        Arrays.fill(operandTypes, unknownType);
        // instead; for now just eat it
        if (operandTypeInference != null) {
            operandTypeInference.inferOperandTypes(callBinding, inferredType, operandTypes);
        }
        for (int i = 0; i < operands.size(); ++i) {
            final SqlNode operand = operands.get(i);
            if (operand != null) {
                inferUnknownTypes(operandTypes[i], scope, operand);
            }
        }
    }
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlOperandTypeInference(org.apache.calcite.sql.type.SqlOperandTypeInference) SqlDynamicParam(org.apache.calcite.sql.SqlDynamicParam) SqlCase(org.apache.calcite.sql.fun.SqlCase) SqlCallBinding(org.apache.calcite.sql.SqlCallBinding) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlNode(org.apache.calcite.sql.SqlNode)

Example 17 with SqlDynamicParam

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

the class SqlValidatorImpl method getParameterRowType.

public RelDataType getParameterRowType(SqlNode sqlQuery) {
    // NOTE: We assume that bind variables occur in depth-first tree
    // traversal in the same order that they occurred in the SQL text.
    final List<RelDataType> types = new ArrayList<>();
    // NOTE: but parameters on fetch/offset would be counted twice
    // as they are counted in the SqlOrderBy call and the inner SqlSelect call
    final Set<SqlNode> alreadyVisited = new HashSet<>();
    sqlQuery.accept(new SqlShuttle() {

        @Override
        public SqlNode visit(SqlDynamicParam param) {
            if (alreadyVisited.add(param)) {
                RelDataType type = getValidatedNodeType(param);
                types.add(type);
            }
            return param;
        }
    });
    return typeFactory.createStructType(types, new AbstractList<String>() {

        @Override
        public String get(int index) {
            return "?" + index;
        }

        @Override
        public int size() {
            return types.size();
        }
    });
}
Also used : SqlShuttle(org.apache.calcite.sql.util.SqlShuttle) SqlDynamicParam(org.apache.calcite.sql.SqlDynamicParam) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) BitString(org.apache.calcite.util.BitString) SqlNode(org.apache.calcite.sql.SqlNode) HashSet(java.util.HashSet)

Example 18 with SqlDynamicParam

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

Example 19 with SqlDynamicParam

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

the class AbstractTypeCoercion method coerceColumnType.

/**
 * Cast column at index {@code index} to target type.
 *
 * @param scope      Validator scope for the node list
 * @param nodeList   Column node list
 * @param index      Index of column
 * @param targetType Target type to cast to
 */
protected boolean coerceColumnType(@Nullable SqlValidatorScope scope, SqlNodeList nodeList, int index, RelDataType targetType) {
    // does not support deriving JavaType yet.
    if (RelDataTypeFactoryImpl.isJavaType(targetType)) {
        targetType = ((JavaTypeFactory) factory).toSql(targetType);
    }
    // See SqlToRelConverter#convertSelectList for details.
    if (index >= nodeList.size()) {
        // just return true.
        return true;
    }
    final SqlNode node = nodeList.get(index);
    if (node instanceof SqlDynamicParam) {
        // Do not support implicit type coercion for dynamic param.
        return false;
    }
    if (node instanceof SqlIdentifier) {
        // Do not expand a star/dynamic table col.
        SqlIdentifier node1 = (SqlIdentifier) node;
        if (node1.isStar()) {
            return true;
        } else if (DynamicRecordType.isDynamicStarColName(Util.last(node1.names))) {
            // Should support implicit cast for dynamic table.
            return false;
        }
    }
    requireNonNull(scope, "scope is needed for needToCast(scope, operand, targetType)");
    if (node instanceof SqlCall) {
        SqlCall node2 = (SqlCall) node;
        if (node2.getOperator().kind == SqlKind.AS) {
            final SqlNode operand = node2.operand(0);
            if (!needToCast(scope, operand, targetType)) {
                return false;
            }
            RelDataType targetType2 = syncAttributes(validator.deriveType(scope, operand), targetType);
            final SqlNode casted = castTo(operand, targetType2);
            node2.setOperand(0, casted);
            updateInferredType(casted, targetType2);
            return true;
        }
    }
    if (!needToCast(scope, node, targetType)) {
        return false;
    }
    RelDataType targetType3 = syncAttributes(validator.deriveType(scope, node), targetType);
    final SqlNode node3 = castTo(node, targetType3);
    nodeList.set(index, node3);
    updateInferredType(node3, targetType3);
    return true;
}
Also used : SqlDynamicParam(org.apache.calcite.sql.SqlDynamicParam) SqlCall(org.apache.calcite.sql.SqlCall) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlNode(org.apache.calcite.sql.SqlNode)

Example 20 with SqlDynamicParam

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

the class AbstractTypeCoercion method coerceOperandType.

// ~ Methods ----------------------------------------------------------------
/**
 * Cast operand at index {@code index} to target type.
 * we do this base on the fact that validate happens before type coercion.
 */
protected boolean coerceOperandType(@Nullable SqlValidatorScope scope, SqlCall call, int index, RelDataType targetType) {
    // does not support deriving JavaType yet.
    if (RelDataTypeFactoryImpl.isJavaType(targetType)) {
        targetType = ((JavaTypeFactory) factory).toSql(targetType);
    }
    SqlNode operand = call.getOperandList().get(index);
    if (operand instanceof SqlDynamicParam) {
        // Do not support implicit type coercion for dynamic param.
        return false;
    }
    requireNonNull(scope, "scope");
    // Check it early.
    if (!needToCast(scope, operand, targetType)) {
        return false;
    }
    // Fix up nullable attr.
    RelDataType targetType1 = syncAttributes(validator.deriveType(scope, operand), targetType);
    SqlNode desired = castTo(operand, targetType1);
    call.setOperand(index, desired);
    updateInferredType(desired, targetType1);
    return true;
}
Also used : SqlDynamicParam(org.apache.calcite.sql.SqlDynamicParam) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

SqlDynamicParam (org.apache.calcite.sql.SqlDynamicParam)21 SqlNode (org.apache.calcite.sql.SqlNode)19 RelDataType (org.apache.calcite.rel.type.RelDataType)16 ParameterConverter (com.hazelcast.sql.impl.ParameterConverter)4 SqlCallBinding (org.apache.calcite.sql.SqlCallBinding)4 SqlNodeList (org.apache.calcite.sql.SqlNodeList)4 BitString (org.apache.calcite.util.BitString)4 SqlCall (org.apache.calcite.sql.SqlCall)3 HazelcastSqlValidator (com.hazelcast.jet.sql.impl.validate.HazelcastSqlValidator)2 AnyToVarcharParameterConverter (com.hazelcast.jet.sql.impl.validate.param.AnyToVarcharParameterConverter)2 NumericPrecedenceParameterConverter (com.hazelcast.jet.sql.impl.validate.param.NumericPrecedenceParameterConverter)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)2 SqlUpdate (org.apache.calcite.sql.SqlUpdate)2 SqlCase (org.apache.calcite.sql.fun.SqlCase)2 SqlOperandTypeInference (org.apache.calcite.sql.type.SqlOperandTypeInference)2 SqlShuttle (org.apache.calcite.sql.util.SqlShuttle)2 SqlValidatorImpl (org.apache.calcite.sql.validate.SqlValidatorImpl)2 SqlColumnType (com.hazelcast.sql.SqlColumnType)1