You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by jo...@apache.org on 2023/07/14 19:04:05 UTC

[impala] 01/02: IMPALA-12285: Use targetType in string-to-numeric literal conversion

This is an automated email from the ASF dual-hosted git repository.

joemcdonnell pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit b41339c22d94a26b8cd707ddc8a97698785389de
Author: Peter Rozsa <pr...@cloudera.com>
AuthorDate: Fri Jul 14 11:14:07 2023 +0200

    IMPALA-12285: Use targetType in string-to-numeric literal conversion
    
    This change fixes mismatched type problems when an implicitly casted
    string literal gets converted to a numeric type. Example:
    
    'INSERT INTO example(float_col) VALUES ("0"), (15629);'
    
    After this change, StringLiteral's 'convertToNumber' method will
    consider the targetType parameter when creates a new NumericLiteral.
    
    Test:
     - test case added to insert-unsafe.test
    
    Change-Id: I2141e7ab164af55a7fa66dda05fe6dcbd7379b69
    Reviewed-on: http://gerrit.cloudera.org:8080/20197
    Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 fe/src/main/java/org/apache/impala/analysis/StringLiteral.java | 10 +++++-----
 .../functional-query/queries/QueryTest/insert-unsafe.test      |  3 +++
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/fe/src/main/java/org/apache/impala/analysis/StringLiteral.java b/fe/src/main/java/org/apache/impala/analysis/StringLiteral.java
index d0b93ef8e..eb1f331fe 100644
--- a/fe/src/main/java/org/apache/impala/analysis/StringLiteral.java
+++ b/fe/src/main/java/org/apache/impala/analysis/StringLiteral.java
@@ -156,7 +156,7 @@ public class StringLiteral extends LiteralExpr {
     } else if (targetType.isStringType()) {
       type_ = targetType;
     } else if (targetType.isNumericType()) {
-      return convertToNumber();
+      return convertToNumber(targetType);
     } else if (targetType.isDateOrTimeType()) {
       // Let the BE do the cast
       // - it is in Boost format in case target type is TIMESTAMP
@@ -169,14 +169,14 @@ public class StringLiteral extends LiteralExpr {
   /**
    * Convert this string literal to numeric literal.
    *
+   * @param targetType sets the target type of the newly created literal
    * @return new converted literal (not null)
    *         the type of the literal is determined by the lexical scanner
    * @throws AnalysisException
    *           if NumberFormatException occurs,
    *           or if floating point value is NaN or infinite
    */
-  public LiteralExpr convertToNumber()
-      throws AnalysisException {
+  public LiteralExpr convertToNumber(Type targetType) throws AnalysisException {
     StringReader reader = new StringReader(value_);
     SqlScanner scanner = new SqlScanner(reader);
     // For distinguishing positive and negative numbers.
@@ -201,12 +201,12 @@ public class StringLiteral extends LiteralExpr {
     if (sym.sym == SqlParserSymbols.INTEGER_LITERAL) {
       BigDecimal val = (BigDecimal) sym.value;
       if (negative) val = val.negate();
-      return new NumericLiteral(val);
+      return new NumericLiteral(val, targetType);
     }
     if (sym.sym == SqlParserSymbols.DECIMAL_LITERAL) {
       BigDecimal val = (BigDecimal) sym.value;
       if (negative) val = val.negate();
-      return new NumericLiteral(val);
+      return new NumericLiteral(val, targetType);
     }
     // Symbol is not an integer or floating point literal.
     throw new AnalysisException("Failed to convert string literal '"
diff --git a/testdata/workloads/functional-query/queries/QueryTest/insert-unsafe.test b/testdata/workloads/functional-query/queries/QueryTest/insert-unsafe.test
index 05e588632..d21eeacd5 100644
--- a/testdata/workloads/functional-query/queries/QueryTest/insert-unsafe.test
+++ b/testdata/workloads/functional-query/queries/QueryTest/insert-unsafe.test
@@ -152,6 +152,9 @@ INSERT INTO unsafe_insert(char_col) values (cast("100" as STRING));
 INSERT INTO unsafe_insert(varchar_col) values (cast("100" as STRING));
 ====
 ---- QUERY
+INSERT INTO unsafe_insert(float_col) values ("100"), (15629);
+====
+---- QUERY
 INSERT INTO unsafe_insert(bigint_col) select string_col from unsafe_insert;
 ---- CATCH
 AnalysisException: Unsafe implicit cast is prohibited for non-const expression: string_col