Repository: hive
Updated Branches:
  refs/heads/master 2b882d5b1 -> 0d0721fa4


HIVE-20940: Bridge cases in which Calcite's type resolution is more stricter 
than Hive. (Zoltan Haindrich reviewed by Ashutosh Chauhan)

Signed-off-by: Zoltan Haindrich <k...@rxd.hu>


Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/0d0721fa
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/0d0721fa
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/0d0721fa

Branch: refs/heads/master
Commit: 0d0721fa4dacde4c505aa727a27f958e916e8a2d
Parents: 2b882d5
Author: Zoltan Haindrich <k...@rxd.hu>
Authored: Wed Nov 21 07:47:25 2018 +0100
Committer: Zoltan Haindrich <k...@rxd.hu>
Committed: Wed Nov 21 07:47:25 2018 +0100

----------------------------------------------------------------------
 .../calcite/translator/RexNodeConverter.java    | 32 ++++++++++++++++++++
 .../llap/vector_case_when_conversion.q.out      |  8 ++---
 2 files changed, 36 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/0d0721fa/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/RexNodeConverter.java
----------------------------------------------------------------------
diff --git 
a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/RexNodeConverter.java
 
b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/RexNodeConverter.java
index f6a6ff2..fef28dd 100644
--- 
a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/RexNodeConverter.java
+++ 
b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/RexNodeConverter.java
@@ -337,6 +337,8 @@ public class RexNodeConverter {
       if (calciteOp.getKind() == SqlKind.CASE) {
         // If it is a case operator, we need to rewrite it
         childRexNodeLst = rewriteCaseChildren(func, childRexNodeLst);
+        // Adjust branch types by inserting explicit casts if the actual is 
ambigous
+        childRexNodeLst = adjustCaseBranchTypes(childRexNodeLst, retType);
       } else if (HiveExtractDate.ALL_FUNCTIONS.contains(calciteOp)) {
         // If it is a extract operator, we need to rewrite it
         childRexNodeLst = rewriteExtractDateChildren(calciteOp, 
childRexNodeLst);
@@ -362,6 +364,8 @@ public class RexNodeConverter {
         // This allows to be further reduced to OR, if possible
         calciteOp = SqlStdOperatorTable.CASE;
         childRexNodeLst = rewriteCoalesceChildren(func, childRexNodeLst);
+        // Adjust branch types by inserting explicit casts if the actual is 
ambigous
+        childRexNodeLst = adjustCaseBranchTypes(childRexNodeLst, retType);
       } else if (calciteOp == HiveToDateSqlOperator.INSTANCE) {
         childRexNodeLst = rewriteToDateChildren(childRexNodeLst);
       }
@@ -471,6 +475,34 @@ public class RexNodeConverter {
     return newChildRexNodeLst;
   }
 
+  /**
+   * Adds explicit casts if Calcite's type system could not resolve the CASE 
branches to a common type.
+   *
+   * Calcite is more stricter than hive w.r.t type conversions.
+   * If a CASE has branches with string/int/boolean branch types; there is no 
common type.
+   */
+  private List<RexNode> adjustCaseBranchTypes(List<RexNode> nodes, RelDataType 
retType) {
+    List<RelDataType> branchTypes = new ArrayList<>();
+    for (int i = 1; i < nodes.size(); i += 2) {
+      branchTypes.add(nodes.get(i).getType());
+    }
+    RelDataType commonType = 
cluster.getTypeFactory().leastRestrictive(branchTypes);
+    if (commonType != null) {
+      // conversion is possible; not changes are neccessary
+      return nodes;
+    }
+    List<RexNode> newNodes = new ArrayList<>();
+    for (int i = 0; i < nodes.size(); i++) {
+      RexNode node = nodes.get(i);
+      if (i % 2 == 1) {
+        newNodes.add(cluster.getRexBuilder().makeCast(retType, node));
+      } else {
+        newNodes.add(node);
+      }
+    }
+    return newNodes;
+  }
+
   private List<RexNode> rewriteExtractDateChildren(SqlOperator op, 
List<RexNode> childRexNodeLst)
       throws SemanticException {
     List<RexNode> newChildRexNodeLst = new ArrayList<>(2);

http://git-wip-us.apache.org/repos/asf/hive/blob/0d0721fa/ql/src/test/results/clientpositive/llap/vector_case_when_conversion.q.out
----------------------------------------------------------------------
diff --git 
a/ql/src/test/results/clientpositive/llap/vector_case_when_conversion.q.out 
b/ql/src/test/results/clientpositive/llap/vector_case_when_conversion.q.out
index 8e07710..4da58e0 100644
--- a/ql/src/test/results/clientpositive/llap/vector_case_when_conversion.q.out
+++ b/ql/src/test/results/clientpositive/llap/vector_case_when_conversion.q.out
@@ -209,8 +209,8 @@ STAGE PLANS:
                       Select Vectorization:
                           className: VectorSelectOperator
                           native: true
-                          projectedOutputColumnNums: [6, 2, 4, 1, 18]
-                          selectExpressions: VectorUDFAdaptor(CASE WHEN 
(cstring1 is not null) THEN (cstring1) WHEN (cint is not null) THEN (cint) WHEN 
(cfloat is not null) THEN (cfloat) WHEN (csmallint is not null) THEN 
(csmallint) ELSE ('none') END)(children: VectorUDFAdaptor(cstring1 is not null) 
-> 14:boolean, VectorUDFAdaptor(cint is not null) -> 15:boolean, 
VectorUDFAdaptor(cfloat is not null) -> 16:boolean, VectorUDFAdaptor(csmallint 
is not null) -> 17:boolean) -> 18:string
+                          projectedOutputColumnNums: [6, 2, 4, 1, 21]
+                          selectExpressions: VectorUDFAdaptor(CASE WHEN 
(cstring1 is not null) THEN (cstring1) WHEN (cint is not null) THEN (CAST( cint 
AS STRING)) WHEN (cfloat is not null) THEN (CAST( cfloat AS STRING)) WHEN 
(csmallint is not null) THEN (CAST( csmallint AS STRING)) ELSE ('none') 
END)(children: VectorUDFAdaptor(cstring1 is not null) -> 14:boolean, 
VectorUDFAdaptor(cint is not null) -> 15:boolean, VectorUDFAdaptor(CAST( cint 
AS STRING)) -> 16:string, VectorUDFAdaptor(cfloat is not null) -> 17:boolean, 
VectorUDFAdaptor(CAST( cfloat AS STRING)) -> 18:string, 
VectorUDFAdaptor(csmallint is not null) -> 19:boolean, VectorUDFAdaptor(CAST( 
csmallint AS STRING)) -> 20:string) -> 21:string
                         Reduce Sink Vectorization:
                             className: VectorReduceSinkObjectHashOperator
                             native: true
@@ -517,8 +517,8 @@ STAGE PLANS:
                       Select Vectorization:
                           className: VectorSelectOperator
                           native: true
-                          projectedOutputColumnNums: [6, 2, 4, 1, 18]
-                          selectExpressions: VectorUDFAdaptor(CASE WHEN 
(cstring1 is not null) THEN (cstring1) WHEN (cint is not null) THEN (cint) WHEN 
(cfloat is not null) THEN (cfloat) WHEN (csmallint is not null) THEN 
(csmallint) ELSE (null) END)(children: VectorUDFAdaptor(cstring1 is not null) 
-> 14:boolean, VectorUDFAdaptor(cint is not null) -> 15:boolean, 
VectorUDFAdaptor(cfloat is not null) -> 16:boolean, VectorUDFAdaptor(csmallint 
is not null) -> 17:boolean) -> 18:string
+                          projectedOutputColumnNums: [6, 2, 4, 1, 21]
+                          selectExpressions: VectorUDFAdaptor(CASE WHEN 
(cstring1 is not null) THEN (cstring1) WHEN (cint is not null) THEN (CAST( cint 
AS STRING)) WHEN (cfloat is not null) THEN (CAST( cfloat AS STRING)) WHEN 
(csmallint is not null) THEN (CAST( csmallint AS STRING)) ELSE (null) 
END)(children: VectorUDFAdaptor(cstring1 is not null) -> 14:boolean, 
VectorUDFAdaptor(cint is not null) -> 15:boolean, VectorUDFAdaptor(CAST( cint 
AS STRING)) -> 16:string, VectorUDFAdaptor(cfloat is not null) -> 17:boolean, 
VectorUDFAdaptor(CAST( cfloat AS STRING)) -> 18:string, 
VectorUDFAdaptor(csmallint is not null) -> 19:boolean, VectorUDFAdaptor(CAST( 
csmallint AS STRING)) -> 20:string) -> 21:string
                         Reduce Sink Vectorization:
                             className: VectorReduceSinkObjectHashOperator
                             native: true

Reply via email to