public interface TypeCoercion
Notes about type widening / tightest common types: Broadly, there are two cases that need to widen data types (i.e. set operations, binary comparison):
REFERENCE: SQL-SERVER HIVE
| Modifier and Type | Method and Description |
|---|---|
boolean |
binaryArithmeticCoercion(SqlCallBinding binding)
Coerces operand of binary arithmetic expressions to Numeric type.
|
boolean |
binaryComparisonCoercion(SqlCallBinding binding)
Coerces operands in binary comparison expressions.
|
boolean |
builtinFunctionCoercion(SqlCallBinding binding,
List<RelDataType> operandTypes,
List<SqlTypeFamily> expectedFamilies)
Type coercion with inferred type from passed in arguments and the
SqlTypeFamily defined in the checkers, e.g. |
boolean |
caseWhenCoercion(SqlCallBinding binding)
Coerces CASE WHEN statement branches to one common type.
|
@Nullable RelDataType |
commonTypeForBinaryComparison(@Nullable RelDataType type1,
@Nullable RelDataType type2)
Determines common type for a comparison operator whose operands are STRING
type and the other (non STRING) type.
|
@Nullable RelDataType |
getTightestCommonType(@Nullable RelDataType type1,
@Nullable RelDataType type2)
Case1: type widening with no precision loss.
|
@Nullable RelDataType |
getWiderTypeFor(List<RelDataType> typeList,
boolean stringPromotion)
Similar to
getWiderTypeForTwo(org.apache.calcite.rel.type.RelDataType, org.apache.calcite.rel.type.RelDataType, boolean), but can handle
sequence types. |
@Nullable RelDataType |
getWiderTypeForDecimal(@Nullable RelDataType type1,
@Nullable RelDataType type2)
Finds a wider type when one or both types are DECIMAL type.
|
@Nullable RelDataType |
getWiderTypeForTwo(@Nullable RelDataType type1,
@Nullable RelDataType type2,
boolean stringPromotion)
Case2: type widening.
|
boolean |
inOperationCoercion(SqlCallBinding binding)
Handles type coercion for IN operation with or without sub-query.
|
boolean |
querySourceCoercion(@Nullable SqlValidatorScope scope,
RelDataType sourceRowType,
RelDataType targetRowType,
SqlNode query)
Coerces the source row expression to target type in an INSERT or UPDATE query.
|
boolean |
rowTypeCoercion(@Nullable 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.
|
boolean |
userDefinedFunctionCoercion(SqlValidatorScope scope,
SqlCall call,
SqlFunction function)
Non built-in functions (UDFs) type coercion, compare the types of arguments
with rules:
Named param: find the desired type by the passed in operand's name
Non-named param: find the desired type by formal parameter ordinal
|
@Nullable RelDataType getTightestCommonType(@Nullable RelDataType type1, @Nullable RelDataType type2)
@Nullable RelDataType getWiderTypeForTwo(@Nullable RelDataType type1, @Nullable RelDataType type2, boolean stringPromotion)
getTightestCommonType(org.apache.calcite.rel.type.RelDataType, org.apache.calcite.rel.type.RelDataType) is that we allow
some precision loss when widening decimal to fractional, or promote to string type.@Nullable RelDataType getWiderTypeFor(List<RelDataType> typeList, boolean stringPromotion)
getWiderTypeForTwo(org.apache.calcite.rel.type.RelDataType, org.apache.calcite.rel.type.RelDataType, boolean), but can handle
sequence types. getWiderTypeForTwo(org.apache.calcite.rel.type.RelDataType, org.apache.calcite.rel.type.RelDataType, boolean) doesn't satisfy the associative law,
i.e. (a op b) op c may not equal to a op (b op c). This is only a problem for STRING or
nested STRING in collection type like ARRAY. Excluding these types,
getWiderTypeForTwo(org.apache.calcite.rel.type.RelDataType, org.apache.calcite.rel.type.RelDataType, boolean) satisfies the associative law. For instance,
(DATE, INTEGER, VARCHAR) should have VARCHAR as the wider common type.@Nullable RelDataType getWiderTypeForDecimal(@Nullable RelDataType type1, @Nullable RelDataType type2)
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 DECIMAL type that 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.
@Nullable RelDataType commonTypeForBinaryComparison(@Nullable RelDataType type1, @Nullable RelDataType type2)
boolean rowTypeCoercion(@Nullable SqlValidatorScope scope, SqlNode query, int columnIndex, RelDataType targetType)
scope - Scope to queryquery - SqlNode which have children nodes as columnscolumnIndex - Target column indextargetType - Target type to cast toboolean inOperationCoercion(SqlCallBinding binding)
See TypeCoercionImpl for default strategies.
boolean binaryArithmeticCoercion(SqlCallBinding binding)
boolean binaryComparisonCoercion(SqlCallBinding binding)
boolean caseWhenCoercion(SqlCallBinding binding)
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.
boolean builtinFunctionCoercion(SqlCallBinding binding, List<RelDataType> operandTypes, List<SqlTypeFamily> expectedFamilies)
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 allow a NUMERIC_NUMERIC OR
STRING_NUMERIC family combination and are with arguments (op1: VARCHAR(20), op2: BOOLEAN),
try to coerce both op1 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 bindingoperandTypes - Types of the operands passed inexpectedFamilies - Expected SqlTypeFamily list by user specifiedboolean userDefinedFunctionCoercion(SqlValidatorScope scope, SqlCall call, SqlFunction function)
Try to make type coercion only if the desired type is found.
boolean querySourceCoercion(@Nullable SqlValidatorScope scope, RelDataType sourceRowType, RelDataType targetRowType, SqlNode query)
If the source and target fields in the same ordinal do not equal sans nullability, try to coerce the source field to target field type.
scope - Source scopesourceRowType - Source row typetargetRowType - Target row typequery - The query, either an INSERT or UPDATECopyright © 2012-2022 Apache Software Foundation. All Rights Reserved.