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

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


The following commit(s) were added to refs/heads/master by this push:
     new 5cb1b10e9f6 HIVE-26745: HPL unable to handle Decimal or null values in 
hplsql mode (#3769) (Adam Szita, reviewed by Attila Magyar and Denys Kuzmenko)
5cb1b10e9f6 is described below

commit 5cb1b10e9f696a0b514a5ddb816d60fa61b7aca7
Author: Adam Szita <40628386+sz...@users.noreply.github.com>
AuthorDate: Thu Nov 17 11:38:49 2022 +0100

    HIVE-26745: HPL unable to handle Decimal or null values in hplsql mode 
(#3769) (Adam Szita, reviewed by Attila Magyar and Denys Kuzmenko)
---
 .../src/main/java/org/apache/hive/hplsql/Var.java  |  4 +-
 .../apache/hive/beeline/TestBeeLineWithArgs.java   |  4 +-
 .../apache/hive/beeline/TestHplSqlViaBeeLine.java  | 52 +++++++++++++++-------
 .../cli/operation/hplsql/HplSqlQueryExecutor.java  | 11 +++++
 4 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/hplsql/src/main/java/org/apache/hive/hplsql/Var.java 
b/hplsql/src/main/java/org/apache/hive/hplsql/Var.java
index bd60b06f7d8..198a4d0b09a 100644
--- a/hplsql/src/main/java/org/apache/hive/hplsql/Var.java
+++ b/hplsql/src/main/java/org/apache/hive/hplsql/Var.java
@@ -255,11 +255,11 @@ public class Var {
       cast(new Var(queryResult.column(idx, String.class)));
     } else if (type == java.sql.Types.INTEGER || type == java.sql.Types.BIGINT 
||
             type == java.sql.Types.SMALLINT || type == java.sql.Types.TINYINT) 
{
-      cast(new Var(Long.valueOf(queryResult.column(idx, Long.class))));
+      cast(new Var(queryResult.column(idx, Long.class)));
     } else if (type == java.sql.Types.DECIMAL || type == 
java.sql.Types.NUMERIC) {
       cast(new Var(queryResult.column(idx, BigDecimal.class)));
     } else if (type == java.sql.Types.FLOAT || type == java.sql.Types.DOUBLE) {
-      cast(new Var(Double.valueOf(queryResult.column(idx, Double.class))));
+      cast(new Var(queryResult.column(idx, Double.class)));
     }
     return this;
   }
diff --git 
a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java
 
b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java
index 902ab2a2cd7..e8ebf251297 100644
--- 
a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java
+++ 
b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java
@@ -63,7 +63,7 @@ import org.junit.Test;
  *
  */
   public class TestBeeLineWithArgs {
-  private enum OutStream {
+  enum OutStream {
     ERR, OUT
   }
 
@@ -158,7 +158,7 @@ import org.junit.Test;
    * @return The stderr and stdout from running the script
    * @throws Throwable
    */
-  private static String testCommandLineScript(List<String> argList, 
InputStream inputStream,
+  static String testCommandLineScript(List<String> argList, InputStream 
inputStream,
       OutStream streamType)
       throws Throwable {
     BeeLine beeLine = new BeeLine();
diff --git 
a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestHplSqlViaBeeLine.java
 
b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestHplSqlViaBeeLine.java
index 269d499a067..f8dcaed6c36 100644
--- 
a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestHplSqlViaBeeLine.java
+++ 
b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestHplSqlViaBeeLine.java
@@ -20,12 +20,12 @@
 
 package org.apache.hive.beeline;
 
+import static org.apache.hive.beeline.TestBeeLineWithArgs.OutStream;
+import static 
org.apache.hive.beeline.TestBeeLineWithArgs.testCommandLineScript;
 import static org.junit.Assert.fail;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.InputStream;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -368,27 +368,47 @@ public class TestHplSqlViaBeeLine {
     testScriptFile(SCRIPT_TEXT, args(), "e1=1 e2=2 e3=3 e4=4 e5=5 e6=6");
   }
 
+  @Test
+  public void testDecimalCast() throws Throwable {
+    String SCRIPT_TEXT =
+        "DECLARE\n" +
+        "a DECIMAL(10,2);\n" +
+        "BEGIN\n" +
+        "SELECT CAST('10.5' AS DECIMAL(10,2)) as t INTO a;\n" +
+        "print (a);\n" +
+        "END;\n" +
+        "/";
+    testScriptFile(SCRIPT_TEXT, args(), "10.50", OutStream.ERR);
+  }
+
+  @Test
+  public void testNullCast() throws Throwable {
+    String SCRIPT_TEXT =
+        "BEGIN\n" +
+        "DECLARE a BIGINT;\n" +
+        "print('started');\n" +
+        "SELECT cast (null as BIGINT) as t INTO a\n" +
+        "print (a);\n" +
+        "print ('here');\n" +
+        "end;\n" +
+        "/";
+    // Inverted match, output should not have NPE
+    testScriptFile(SCRIPT_TEXT, args(), "^(.(?!(NullPointerException)))*$", 
OutStream.ERR);
+  }
+
   private static List<String> args() {
     return Arrays.asList("-d", BeeLine.BEELINE_DEFAULT_JDBC_DRIVER,
             "-u", miniHS2.getBaseJdbcURL() + ";mode=hplsql", "-n", userName);
   }
 
-  private static String testCommandLineScript(List<String> argList, 
InputStream inputStream)
-          throws Throwable {
-    BeeLine beeLine = new BeeLine();
-    ByteArrayOutputStream os = new ByteArrayOutputStream();
-    PrintStream beelineOutputStream = new PrintStream(os);
-    beeLine.setOutputStream(beelineOutputStream);
-    String[] args = argList.toArray(new String[argList.size()]);
-    beeLine.begin(args, inputStream);
-    beeLine.close();
-    beelineOutputStream.close();
-    String output = os.toString("UTF8");
-    return output;
-  }
 
   private void testScriptFile(String scriptText, List<String> argList, String 
expectedPattern)
           throws Throwable {
+    testScriptFile(scriptText, argList, expectedPattern, OutStream.OUT);
+  }
+
+  private void testScriptFile(String scriptText, List<String> argList, String 
expectedPattern,
+          TestBeeLineWithArgs.OutStream outStream) throws Throwable {
     File scriptFile = File.createTempFile(this.getClass().getSimpleName(), 
"temp");
     scriptFile.deleteOnExit();
     try (PrintStream os = new PrintStream(new FileOutputStream(scriptFile))) {
@@ -397,7 +417,7 @@ public class TestHplSqlViaBeeLine {
     List<String> copy = new ArrayList<>(argList);
     copy.add("-f");
     copy.add(scriptFile.getAbsolutePath());
-    String output = testCommandLineScript(copy, null);
+    String output = testCommandLineScript(copy, null, outStream);
     if (!Pattern.compile(".*" + expectedPattern + ".*", 
Pattern.DOTALL).matcher(output).matches()) {
       fail("Output: '" + output + "' should match " + expectedPattern);
     }
diff --git 
a/service/src/java/org/apache/hive/service/cli/operation/hplsql/HplSqlQueryExecutor.java
 
b/service/src/java/org/apache/hive/service/cli/operation/hplsql/HplSqlQueryExecutor.java
index a1305eb12a5..9aa25d39c69 100644
--- 
a/service/src/java/org/apache/hive/service/cli/operation/hplsql/HplSqlQueryExecutor.java
+++ 
b/service/src/java/org/apache/hive/service/cli/operation/hplsql/HplSqlQueryExecutor.java
@@ -20,6 +20,7 @@
 
 package org.apache.hive.service.cli.operation.hplsql;
 
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -29,6 +30,7 @@ import java.util.Map;
 
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.serde.serdeConstants;
 import org.apache.hive.hplsql.executor.ColumnMeta;
 import org.apache.hive.hplsql.executor.Metadata;
 import org.apache.hive.hplsql.executor.QueryException;
@@ -120,6 +122,9 @@ public class HplSqlQueryExecutor implements QueryExecutor {
 
     @Override
     public <T> T get(int columnIndex, Class<T> type) {
+      if (current[columnIndex] == null) {
+        return null;
+      }
       if (type.isInstance(current[columnIndex])) {
         return (T) current[columnIndex];
       } else {
@@ -133,6 +138,12 @@ public class HplSqlQueryExecutor implements QueryExecutor {
           if (type == Byte.class)
               return type.cast(((Number) current[columnIndex]).byteValue());
         }
+        // RowSet can never return the HiveDecimal instances created on Hive 
side, nor its BigDecimal representation.
+        // Instead, it gets converted into String object in 
ColumnBasedSet.addRow()...
+        if (type == BigDecimal.class &&
+            
serdeConstants.DECIMAL_TYPE_NAME.equalsIgnoreCase(metadata(handle).columnTypeName(columnIndex)))
 {
+          return (T) new BigDecimal((String) current[columnIndex]);
+        }
         throw new ClassCastException(current[columnIndex].getClass() + " 
cannot be casted to " + type);
       }
     }

Reply via email to