Interface TypeCoercion

  • All Known Implementing Classes:
    AbstractTypeCoercion, TypeCoercionImpl

    public interface TypeCoercion
    Default Strategies to coerce differing types that participate in operations into compatible ones.

    Notes about type widening / tightest common types: Broadly, there are two cases that need to widen data types (i.e. set operations, binary comparison):

    • Case1: Look for a common data type for two or more data types, and no loss of precision is allowed. Including type inference for returned/operands type (i.e. what's the column's common data type if one row is an integer while the other row is a long?).
    • Case2: Look for a widen data type with some acceptable loss of precision (i.e. there is no common type for double and decimal because double's range is larger than decimal(with default max precision), and yet decimal is more precise than double, but in union we would cast the decimal to double).


    • Method Detail

      • getTightestCommonType

        RelDataType getTightestCommonType​(RelDataType type1,
                                          RelDataType type2)
        Case1: type widening with no precision loss. Find the tightest common type of two types that might be used in binary expression.
        common type
      • getWiderTypeForDecimal

        RelDataType getWiderTypeForDecimal​(RelDataType type1,
                                           RelDataType type2)
        Finds a wider type when one or both types are decimal type.

        If the wider decimal type's precision/scale exceeds system limitation, this rule will truncate the decimal type to the max precision/scale. For decimal and fractional types, returns a decimal type which has the higher precision of the two.

        The default implementation depends on the max precision/scale of the type system, you can override it based on the specific system requirement in RelDataTypeSystem.

      • commonTypeForBinaryComparison

        RelDataType commonTypeForBinaryComparison​(RelDataType type1,
                                                  RelDataType type2)
        Determines common type for a comparison operator whose operands are String type and the other (non String) type.
      • rowTypeCoercion

        boolean rowTypeCoercion​(SqlValidatorScope scope,
                                SqlNode query,
                                int columnIndex,
                                RelDataType targetType)
        Widen a SqlNode ith column type to target type, mainly used for set operations like UNION, INTERSECT and EXCEPT.
        scope - scope to query
        query - SqlNode which have children nodes as columns
        columnIndex - target column index
        targetType - target type to cast to
        true if we add any cast in successfully.
      • inOperationCoercion

        boolean inOperationCoercion​(SqlCallBinding binding)
        Handles type coercion for IN operation with or without sub-query.

        See TypeCoercionImpl for default strategies.

      • binaryArithmeticCoercion

        boolean binaryArithmeticCoercion​(SqlCallBinding binding)
        Coerce operand of binary arithmetic expressions to Numeric type.
      • caseWhenCoercion

        boolean caseWhenCoercion​(SqlCallBinding binding)
        Coerce CASE WHEN statement branches to one common type.

        Rules: Find common type for all the then operands and else operands, then try to coerce the then/else operands to the type if needed.

      • builtinFunctionCoercion

        boolean builtinFunctionCoercion​(SqlCallBinding binding,
                                        java.util.List<RelDataType> operandTypes,
                                        java.util.List<SqlTypeFamily> expectedFamilies)
        Type coercion with inferred type from passed in arguments and the SqlTypeFamily defined in the checkers, e.g. the FamilyOperandTypeChecker.

        Caution that we do not cast from numeric if desired type family is also SqlTypeFamily.NUMERIC.

        If the FamilyOperandTypeCheckers are subsumed in a CompositeOperandTypeChecker, check them based on their combination order. i.e. If we allows a (numeric, numeric) OR (string, numeric) family but with arguments (op1, op2) of types (varchar(20), boolean), try to coerce op1 to numeric and op2 to numeric if the type coercion rules allow it, or else try to coerce op2 to numeric and keep op1 the type as it is.

        This is also very interrelated to the composition predicate for the checkers: if the predicate is AND, we would fail fast if the first family type coercion fails.

        binding - Call binding
        operandTypes - Types of the operands passed in
        expectedFamilies - Expected SqlTypeFamily list by user specified
        true if we successfully do any implicit cast
      • userDefinedFunctionCoercion

        boolean userDefinedFunctionCoercion​(SqlValidatorScope scope,
                                            SqlCall call,
                                            SqlFunction function)
        Non built-in functions (UDFs) type coercion, compare the types of arguments with rules:
        1. named param: find the desired type by the passed in operand's name
        2. non-named param: find the desired type by formal parameter ordinal

        Try to make type coercion only of the desired type is found.

        true if any operands is coerced