Search in sources :

Example 1 with HazelcastCallBinding

use of com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding in project hazelcast by hazelcast.

the class HazelcastSqlOperandMetadata method checkOperandTypes.

@Override
public final boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
    HazelcastCallBinding binding = prepareBinding(callBinding, operandTypeInference);
    boolean checkResult;
    if (ValidationUtil.hasAssignment(binding.getCall())) {
        OperandChecker[] checkers = parameters.stream().map(HazelcastTableFunctionParameter::checker).toArray(OperandChecker[]::new);
        checkResult = new NamedOperandCheckerProgram(checkers).check(binding, throwOnFailure);
    } else {
        OperandChecker[] checkers = parameters.stream().limit(binding.getOperandCount()).map(HazelcastTableFunctionParameter::checker).toArray(OperandChecker[]::new);
        checkResult = new OperandCheckerProgram(checkers).check(binding, throwOnFailure);
    }
    return checkResult && checkOperandTypes(binding, throwOnFailure);
}
Also used : NamedOperandCheckerProgram(com.hazelcast.jet.sql.impl.validate.operand.NamedOperandCheckerProgram) OperandChecker(com.hazelcast.jet.sql.impl.validate.operand.OperandChecker) OperandCheckerProgram(com.hazelcast.jet.sql.impl.validate.operand.OperandCheckerProgram) NamedOperandCheckerProgram(com.hazelcast.jet.sql.impl.validate.operand.NamedOperandCheckerProgram) HazelcastCallBinding(com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding)

Example 2 with HazelcastCallBinding

use of com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding in project hazelcast by hazelcast.

the class BinaryOperatorOperandTypeInference method inferOperandTypes.

@Override
public void inferOperandTypes(SqlCallBinding binding, RelDataType returnType, RelDataType[] operandTypes) {
    assert operandTypes.length == 2;
    assert binding.getOperandCount() == 2;
    boolean hasParameters = HazelcastTypeUtils.hasParameters(binding);
    int knownTypeOperandIndex = -1;
    RelDataType knownType = null;
    for (int i = 0; i < binding.getOperandCount(); i++) {
        operandTypes[i] = binding.getOperandType(i);
        if (!operandTypes[i].equals(binding.getValidator().getUnknownType())) {
            if (hasParameters && toHazelcastType(operandTypes[i]).getTypeFamily().isNumericInteger()) {
                // If we are here, the operands are a parameter and a numeric expression.
                // We widen the type of the numeric expression to BIGINT, so that an expression `1 > ?` is resolved to
                // `(BIGINT)1 > (BIGINT)?` rather than `(TINYINT)1 > (TINYINT)?`
                RelDataType newOperandType = createType(binding.getTypeFactory(), SqlTypeName.BIGINT, operandTypes[i].isNullable());
                operandTypes[i] = newOperandType;
            }
            if (knownType == null || knownType.getSqlTypeName() == SqlTypeName.NULL) {
                knownType = operandTypes[i];
                knownTypeOperandIndex = i;
            }
        }
    }
    // since we cannot deduce the return type
    if (knownType == null || knownType.getSqlTypeName() == SqlTypeName.NULL && hasParameters) {
        throw new HazelcastCallBinding(binding).newValidationSignatureError();
    }
    if (SqlTypeName.INTERVAL_TYPES.contains(knownType.getSqlTypeName()) && operandTypes[1 - knownTypeOperandIndex].getSqlTypeName() == SqlTypeName.NULL) {
        // If there is an interval on the one side and NULL on the other, assume that the other side is a TIMESTAMP,
        // because this is the only viable overload.
        operandTypes[1 - knownTypeOperandIndex] = createType(binding.getTypeFactory(), SqlTypeName.TIMESTAMP, true);
    } else {
        operandTypes[1 - knownTypeOperandIndex] = knownType;
    }
}
Also used : HazelcastCallBinding(com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 3 with HazelcastCallBinding

use of com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding in project hazelcast by hazelcast.

the class ComparisonOperatorOperandTypeInference method inferOperandTypes.

@Override
public void inferOperandTypes(SqlCallBinding binding, RelDataType returnType, RelDataType[] operandTypes) {
    assert operandTypes.length == 2;
    assert binding.getOperandCount() == 2;
    boolean hasParameters = HazelcastTypeUtils.hasParameters(binding);
    int knownTypeOperandIndex = -1;
    RelDataType knownType = null;
    for (int i = 0; i < binding.getOperandCount(); i++) {
        operandTypes[i] = binding.getOperandType(i);
        if (!operandTypes[i].equals(binding.getValidator().getUnknownType())) {
            if (knownType == null || knownType.getSqlTypeName() == SqlTypeName.NULL) {
                knownType = operandTypes[i];
                knownTypeOperandIndex = i;
            }
        }
    }
    // since we cannot deduce the return type
    if (knownType == null || knownType.getSqlTypeName() == SqlTypeName.NULL && hasParameters) {
        throw new HazelcastCallBinding(binding).newValidationSignatureError();
    }
    if (SqlTypeName.INTERVAL_TYPES.contains(knownType.getSqlTypeName()) && operandTypes[1 - knownTypeOperandIndex].getSqlTypeName() == SqlTypeName.NULL) {
        // If there is an interval on the one side and NULL on the other, assume that the other side is a TIMESTAMP,
        // because this is the only viable overload.
        operandTypes[1 - knownTypeOperandIndex] = createType(binding.getTypeFactory(), SqlTypeName.TIMESTAMP, true);
    } else {
        operandTypes[1 - knownTypeOperandIndex] = knownType;
    }
}
Also used : HazelcastCallBinding(com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 4 with HazelcastCallBinding

use of com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding in project hazelcast by hazelcast.

the class HazelcastInOperator method deriveType.

@Override
public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) {
    final List<SqlNode> operands = call.getOperandList();
    assert operands.size() == 2;
    final SqlNode left = operands.get(0);
    final SqlNode right = operands.get(1);
    final RelDataTypeFactory typeFactory = validator.getTypeFactory();
    RelDataType leftType = validator.deriveType(scope, left);
    RelDataType rightType;
    // Derive type for RHS.
    if (right instanceof SqlNodeList) {
        // Handle the 'IN (expr, ...)' form.
        List<RelDataType> rightTypeList = new ArrayList<>();
        SqlNodeList nodeList = (SqlNodeList) right;
        for (SqlNode node : nodeList) {
            if (node instanceof SqlLiteral) {
                SqlLiteral lit = (SqlLiteral) node;
                // We are not supporting raw NULL literals within IN right-hand side list.
                if (lit.getValue() == null) {
                    throw validator.newValidationError(right, HZRESOURCE.noRawNullsAllowed());
                }
            }
            RelDataType nodeType = validator.deriveType(scope, node);
            rightTypeList.add(nodeType);
        }
        rightType = typeFactory.leastRestrictive(rightTypeList);
        // Same rules as the VALUES operator (per SQL:2003 Part 2 Section 8.4, <in predicate>).
        if (null == rightType && validator.config().typeCoercionEnabled()) {
            // Do implicit type cast if it is allowed to.
            rightType = validator.getTypeCoercion().getWiderTypeFor(rightTypeList, false);
        }
        if (null == rightType) {
            throw validator.newValidationError(right, RESOURCE.incompatibleTypesInList());
        }
        // Record the RHS type for use by SqlToRelConverter.
        validator.setValidatedNodeType(nodeList, rightType);
    } else {
        // We do not support sub-querying for IN operator.
        throw validator.newValidationError(call, HZRESOURCE.noSubQueryAllowed());
    }
    HazelcastCallBinding hazelcastCallBinding = prepareBinding(new SqlCallBinding(validator, scope, call));
    // Coerce type first.
    if (hazelcastCallBinding.isTypeCoercionEnabled()) {
        boolean coerced = hazelcastCallBinding.getValidator().getTypeCoercion().inOperationCoercion(hazelcastCallBinding);
        if (coerced) {
            // Update the node data type if we coerced any type.
            leftType = validator.deriveType(scope, call.operand(0));
            rightType = validator.deriveType(scope, call.operand(1));
        }
    }
    // Now check that the left expression is compatible with the
    // type of the list. Same strategy as the '=' operator.
    // Normalize the types on both sides to be row types
    // for the purposes of compatibility-checking.
    RelDataType leftRowType = SqlTypeUtil.promoteToRowType(typeFactory, leftType, null);
    RelDataType rightRowType = SqlTypeUtil.promoteToRowType(typeFactory, rightType, null);
    final ComparableOperandTypeChecker checker = (ComparableOperandTypeChecker) OperandTypes.COMPARABLE_UNORDERED_COMPARABLE_UNORDERED;
    if (!checker.checkOperandTypes(new ExplicitOperatorBinding(hazelcastCallBinding, ImmutableList.of(leftRowType, rightRowType)), hazelcastCallBinding)) {
        throw validator.newValidationError(call, RESOURCE.incompatibleValueType(SqlStdOperatorTable.IN.getName()));
    }
    return typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.BOOLEAN), anyNullable(leftRowType.getFieldList()) || anyNullable(rightRowType.getFieldList()));
}
Also used : ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) ExplicitOperatorBinding(org.apache.calcite.sql.ExplicitOperatorBinding) ComparableOperandTypeChecker(org.apache.calcite.sql.type.ComparableOperandTypeChecker) HazelcastCallBinding(com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) SqlCallBinding(org.apache.calcite.sql.SqlCallBinding) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlLiteral(org.apache.calcite.sql.SqlLiteral) SqlNode(org.apache.calcite.sql.SqlNode)

Example 5 with HazelcastCallBinding

use of com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding in project hazelcast by hazelcast.

the class HazelcastOperandTypeCheckerAware method prepareBinding.

default HazelcastCallBinding prepareBinding(SqlCallBinding binding, SqlOperandTypeInference operandTypeInference) {
    HazelcastSqlValidator validator = (HazelcastSqlValidator) binding.getValidator();
    boolean resolveOperands = false;
    for (int i = 0; i < binding.getOperandCount(); i++) {
        RelDataType operandType = binding.getOperandType(i);
        if (operandType.getSqlTypeName() == SqlTypeName.NULL) {
            resolveOperands = true;
            break;
        }
    }
    if (resolveOperands) {
        RelDataType unknownType = binding.getValidator().getUnknownType();
        RelDataType[] operandTypes = new RelDataType[binding.getOperandCount()];
        Arrays.fill(operandTypes, unknownType);
        operandTypeInference.inferOperandTypes(binding, binding.getValidator().getUnknownType(), operandTypes);
        for (int i = 0; i < binding.getOperandCount(); i++) {
            validator.setValidatedNodeType(binding.getCall().operand(i), operandTypes[i]);
        }
    }
    // Provide custom binding
    return new HazelcastCallBinding(binding);
}
Also used : HazelcastCallBinding(com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding) HazelcastSqlValidator(com.hazelcast.jet.sql.impl.validate.HazelcastSqlValidator) RelDataType(org.apache.calcite.rel.type.RelDataType)

Aggregations

HazelcastCallBinding (com.hazelcast.jet.sql.impl.validate.HazelcastCallBinding)6 RelDataType (org.apache.calcite.rel.type.RelDataType)5 ArrayList (java.util.ArrayList)2 HazelcastSqlValidator (com.hazelcast.jet.sql.impl.validate.HazelcastSqlValidator)1 NamedOperandCheckerProgram (com.hazelcast.jet.sql.impl.validate.operand.NamedOperandCheckerProgram)1 OperandChecker (com.hazelcast.jet.sql.impl.validate.operand.OperandChecker)1 OperandCheckerProgram (com.hazelcast.jet.sql.impl.validate.operand.OperandCheckerProgram)1 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)1 ExplicitOperatorBinding (org.apache.calcite.sql.ExplicitOperatorBinding)1 SqlCallBinding (org.apache.calcite.sql.SqlCallBinding)1 SqlLiteral (org.apache.calcite.sql.SqlLiteral)1 SqlNode (org.apache.calcite.sql.SqlNode)1 SqlNodeList (org.apache.calcite.sql.SqlNodeList)1 ComparableOperandTypeChecker (org.apache.calcite.sql.type.ComparableOperandTypeChecker)1