diff --git a/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java b/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java index 863da6524007..6c2cc943a95d 100644 --- a/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java +++ b/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java @@ -711,12 +711,12 @@ public static SqlCall stripSeparator(SqlCall call) { *

This method serves as a dispatcher that routes to the appropriate handler * based on the type of operator binding. It handles both SQL parse tree bindings * (SqlCallBinding) and relational expression bindings (RexCallBinding), with a - * fallback for other binding types.

+ * fallback for other binding types. * *

The method is crucial for decimal multiplication type inference because it * needs to analyze the actual operand values (not just their declared types) to * determine if integer literals should be converted to decimal types for proper - * decimal arithmetic.

+ * decimal arithmetic. * * @param opBinding the operator binding containing operand information and types * @param typeFactory the type factory used to create new data types if needed @@ -742,7 +742,7 @@ private static Pair getDecimalMultiplyBindingType( * *

This method handles relational expression bindings (RexCallBinding) where operands * are represented as RexNode objects. It analyzes both the declared types and actual - * values to determine if type conversions are needed for proper decimal arithmetic.

+ * values to determine if type conversions are needed for proper decimal arithmetic. * *

The method implements a comprehensive type inference strategy that considers: *

- *

* *

Key scenarios handled: *

- *

* * @param opBinding the RexCallBinding containing RexNode operands * @param typeFactory the type factory for creating new data types @@ -811,7 +809,7 @@ private static Pair getRelDataTypeRelDataTypePair( *

This method is responsible for type conversion in relational expression scenarios * where integer literals need to be promoted to decimal types for proper decimal arithmetic. * The conversion is essential when multiplying integers with decimals to maintain - * precision and avoid unintended integer arithmetic.

+ * precision and avoid unintended integer arithmetic. * *

Conversion logic: *

- *

* *

The precision calculation for converted integers uses the number of digits * in the integer value. For example: @@ -829,7 +826,6 @@ private static Pair getRelDataTypeRelDataTypePair( *

  • 45 → DECIMAL(2, 0) (2 digits)
  • *
  • 0 → DECIMAL(1, 0) (special case)
  • * - *

    * * @param typeFactory the type factory for creating new DECIMAL types * @param opBinding the RexCallBinding containing the operands @@ -881,12 +877,12 @@ private static RelDataType createDecimalTypeOrDefault(RelDataTypeFactory typeFac * *

    This method handles SQL parse tree bindings (SqlCallBinding) where operands * are represented as SqlNode objects. It analyzes both the declared types and actual - * values to determine if type conversions are needed for proper decimal arithmetic.

    + * values to determine if type conversions are needed for proper decimal arithmetic. * *

    Similar to the RexCallBinding version, this method implements comprehensive * type inference but operates on SqlNode objects instead of RexNode objects. * The key difference is that during SQL parsing, integer literals are automatically - * converted to DECIMAL type, which affects the conversion logic.

    + * converted to DECIMAL type, which affects the conversion logic. * *

    Key scenarios handled: *

    - *

    * * @param opBinding the SqlCallBinding containing SqlNode operands * @param typeFactory the type factory for creating new data types @@ -947,7 +942,7 @@ private static Pair getRelDataTypeRelDataTypePair( *

    This method handles type conversion in SQL parse tree scenarios where numeric literals * need to be processed for decimal arithmetic. Unlike the RexCallBinding version, this method * operates on SqlNode objects where integer literals have already been converted to DECIMAL - * type during SQL parsing.

    + * type during SQL parsing. * *

    Key difference from RexCallBinding version: *

      @@ -955,7 +950,6 @@ private static Pair getRelDataTypeRelDataTypePair( *
    • This method primarily ensures proper precision and scale are preserved
    • *
    • No need to manually calculate precision from integer values
    • *
    - *

    * *

    Conversion logic: *

      @@ -963,7 +957,6 @@ private static Pair getRelDataTypeRelDataTypePair( *
    • Use the literal's existing precision and scale information
    • *
    • For non-literals, return the default type unchanged
    • *
    - *

    * * @param typeFactory the type factory for creating new DECIMAL types * @param opBinding the SqlCallBinding containing SqlNode operands @@ -1216,13 +1209,13 @@ private static RelDataType createDecimalTypeOrDefault(RelDataTypeFactory typeFac * For example, * *

    concat(cast('a' as varchar(2)), cast('b' as varchar(3)),cast('c' as varchar(2))) - * returns varchar(7).

    + * returns varchar(7). * *

    concat(cast('a' as varchar), cast('b' as varchar(2), cast('c' as varchar(2)))) - * returns varchar.

    + * returns varchar. * *

    concat(cast('a' as varchar(65535)), cast('b' as varchar(2)), cast('c' as varchar(2))) - * returns varchar.

    + * returns varchar. */ public static final SqlReturnTypeInference MULTIVALENT_STRING_SUM_PRECISION = opBinding -> { diff --git a/core/src/main/java/org/apache/calcite/util/SqlNodeUtils.java b/core/src/main/java/org/apache/calcite/util/SqlNodeUtils.java index bbf8d015ec71..e6fbdb9565ba 100644 --- a/core/src/main/java/org/apache/calcite/util/SqlNodeUtils.java +++ b/core/src/main/java/org/apache/calcite/util/SqlNodeUtils.java @@ -37,11 +37,11 @@ *

    This class provides various static methods to analyze and validate SQL nodes, * particularly focusing on numeric and decimal constant detection. It includes methods * to check if nodes represent decimal constants, numeric literals, or complex expressions - * containing numeric values.

    + * containing numeric values. * *

    The utility supports both {@link SqlNode} (parse tree representation) and * {@link RexNode} (relational expression representation) objects, providing consistent - * behavior across different stages of SQL processing.

    + * behavior across different stages of SQL processing. */ public class SqlNodeUtils { @@ -57,7 +57,7 @@ private SqlNodeUtils() { * *

    A decimal constant is defined as a {@link SqlNumericLiteral} with DECIMAL type * that is not an integer literal. This method specifically excludes integer values - * even if they are stored as DECIMAL type.

    + * even if they are stored as DECIMAL type. * * @param node the SQL node to check, may be null * @return true if the node is a decimal constant (non-integer DECIMAL), false otherwise @@ -82,7 +82,7 @@ public static boolean isDecimalConstant(SqlNode node) { *

    Unlike {@link #isDecimalConstant(SqlNode)}, this method includes both decimal * and integer values. During SQL parsing, integers are converted to DECIMAL type, * so this method checks for DECIMAL type regardless of whether it's an integer - * or decimal value.

    + * or decimal value. * * @param node the SQL node to check, may be null * @return true if the node is a DECIMAL type numeric literal (including integers), false @@ -107,7 +107,7 @@ public static boolean isDecimalOrIntegerConstant(SqlNode node) { * *

    This method checks if the node is a {@link RexLiteral} with DECIMAL type * or any approximate numeric type (like FLOAT, DOUBLE). Unlike the SqlNode - * version, this includes approximate numeric types as well.

    + * version, this includes approximate numeric types as well. * * @param node the Rex node to check, may be null * @return true if the node is a decimal or approximate numeric constant, false otherwise @@ -126,7 +126,7 @@ public static boolean isDecimalConstant(RexNode node) { * Checks if the given {@link SqlNode} is a numeric literal. * *

    This is a simple type check that returns true if the node is an instance - * of {@link SqlNumericLiteral}, regardless of the specific numeric type.

    + * of {@link SqlNumericLiteral}, regardless of the specific numeric type. * * @param node the SQL node to check, may be null * @return true if the node is a numeric literal, false otherwise @@ -140,7 +140,7 @@ public static boolean isNumericLiteral(SqlNode node) { * *

    This method checks if the node is a {@link RexLiteral} with a numeric type. * It uses {@link SqlTypeUtil#isNumeric(RelDataType)} to determine if the type - * is numeric, which includes all numeric types like INTEGER, DECIMAL, FLOAT, etc.

    + * is numeric, which includes all numeric types like INTEGER, DECIMAL, FLOAT, etc. * * @param node the Rex node to check, may be null * @return true if the node is a numeric literal, false otherwise @@ -159,7 +159,7 @@ public static boolean isNumericLiteral(RexNode node) { * is a numeric literal. * *

    This method verifies that the operand is both a literal and has a numeric type. - * It's commonly used in operator validation to ensure operands are numeric literals.

    + * It's commonly used in operator validation to ensure operands are numeric literals. * * @param binding the operator binding containing the operands * @param ordinal the zero-based index of the operand to check @@ -175,7 +175,7 @@ public static boolean isNumericLiteral(SqlOperatorBinding binding, int ordinal) * *

    This method performs a deep analysis of the expression tree to determine if * it contains only numeric literals and at least one decimal constant. It traverses - * binary arithmetic operations (like +, -, *, /) and checks all operands.

    + * binary arithmetic operations (like +, -, *, /) and checks all operands. * *

    The method returns true only if: *

      @@ -183,7 +183,7 @@ public static boolean isNumericLiteral(SqlOperatorBinding binding, int ordinal) *
    • At least one leaf node is a decimal constant
    • *
    • All intermediate nodes are binary arithmetic operations
    • *
    - *

    + * * *

    For example, this would return true for expressions like: *

      @@ -195,7 +195,6 @@ public static boolean isNumericLiteral(SqlOperatorBinding binding, int ordinal) *
    • 1 + 2 (no decimal constants)
    • *
    • 1.5 + column_name (contains non-literal)
    • *
    - *

    * * @param node the Rex node to check, may be null * @return true if the expression contains only numeric literals and at least one decimal constant @@ -257,10 +256,10 @@ public static boolean isDecimalConstantRexNode(RexNode node) { * *

    This method performs a deep analysis of the expression tree to determine if * it contains only numeric literals. It traverses binary arithmetic operations - * and checks all operands to ensure they are all numeric literals.

    + * and checks all operands to ensure they are all numeric literals. * *

    Unlike {@link #isDecimalConstantRexNode(RexNode)}, this method doesn't require - * at least one decimal constant - it accepts expressions with only integer literals as well.

    + * at least one decimal constant - it accepts expressions with only integer literals as well. * *

    For example, this would return true for expressions like: *

      @@ -273,7 +272,6 @@ public static boolean isDecimalConstantRexNode(RexNode node) { *
    • 1 + column_name (contains non-literal)
    • *
    • function_call(5) (contains function call)
    • *
    - *

    * * @param node the Rex node to check, may be null * @return true if the expression contains only numeric literals, false otherwise @@ -316,14 +314,14 @@ public static boolean isNumericLiteralRexNode(RexNode node) { * *

    This method is the SqlNode equivalent of {@link #isDecimalConstantRexNode(RexNode)}. * It performs a deep analysis of the SQL expression tree to determine if - * it contains only numeric literals and at least one decimal constant.

    + * it contains only numeric literals and at least one decimal constant. * *

    The method traverses binary arithmetic operations and checks all operands. * It returns true only if all leaf nodes are numeric literals and at least one - * is a decimal constant.

    + * is a decimal constant. * *

    This method is typically used during SQL parsing and validation stages, - * before the SQL is converted to relational expressions.

    + * before the SQL is converted to relational expressions. * * @param node the SQL node to check, may be null * @return true if the expression contains only numeric literals and at least one decimal constant @@ -384,14 +382,14 @@ public static boolean isDecimalConstantSqlNode(SqlNode node) { * *

    This method is the SqlNode equivalent of {@link #isNumericLiteralRexNode(RexNode)}. * It performs a deep analysis of the SQL expression tree to determine if - * it contains only numeric literals.

    + * it contains only numeric literals. * *

    The method traverses binary arithmetic operations and checks all operands * to ensure they are all numeric literals. It accepts expressions with both - * integer and decimal literals.

    + * integer and decimal literals. * *

    This method is typically used during SQL parsing and validation to identify - * constant expressions that can be evaluated at compile time.

    + * constant expressions that can be evaluated at compile time. * * @param node the SQL node to check, may be null * @return true if the expression contains only numeric literals, false otherwise