You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by xu...@apache.org on 2013/11/17 05:52:36 UTC

svn commit: r1542646 - in /hive/trunk/ql/src: java/org/apache/hadoop/hive/ql/udf/generic/ test/queries/clientnegative/ test/queries/clientpositive/ test/results/clientnegative/ test/results/clientpositive/

Author: xuefu
Date: Sun Nov 17 04:52:35 2013
New Revision: 1542646

URL: http://svn.apache.org/r1542646
Log:
HIVE-5825: Case statement type checking too restrictive for parameterized types (Jason via Xuefu)

Removed:
    hive/trunk/ql/src/test/queries/clientnegative/udf_case_type_wrong.q
    hive/trunk/ql/src/test/queries/clientnegative/udf_case_type_wrong2.q
    hive/trunk/ql/src/test/queries/clientnegative/udf_case_type_wrong3.q
    hive/trunk/ql/src/test/queries/clientnegative/udf_when_type_wrong2.q
    hive/trunk/ql/src/test/queries/clientnegative/udf_when_type_wrong3.q
    hive/trunk/ql/src/test/results/clientnegative/udf_case_type_wrong.q.out
    hive/trunk/ql/src/test/results/clientnegative/udf_case_type_wrong2.q.out
    hive/trunk/ql/src/test/results/clientnegative/udf_case_type_wrong3.q.out
    hive/trunk/ql/src/test/results/clientnegative/udf_when_type_wrong2.q.out
    hive/trunk/ql/src/test/results/clientnegative/udf_when_type_wrong3.q.out
Modified:
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCase.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFWhen.java
    hive/trunk/ql/src/test/queries/clientpositive/udf_case.q
    hive/trunk/ql/src/test/queries/clientpositive/udf_when.q
    hive/trunk/ql/src/test/results/clientpositive/udf_case.q.out
    hive/trunk/ql/src/test/results/clientpositive/udf_when.q.out

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCase.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCase.java?rev=1542646&r1=1542645&r2=1542646&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCase.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCase.java Sun Nov 17 04:52:35 2013
@@ -25,11 +25,11 @@ import org.apache.hadoop.hive.serde2.obj
 import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
 
 /**
- * GenericUDF Class for SQL construct
- * "CASE WHEN a THEN b WHEN c THEN d [ELSE f] END".
+ * GenericUDF Class for SQL construct "CASE a WHEN b THEN c [ELSE f] END".
  * 
- * NOTES: 1. a and c should be boolean, or an exception will be thrown. 2. b, d
- * and f should have the same TypeInfo, or an exception will be thrown.
+ * NOTES: 1. a and b should be compatible, or an exception will be
+ * thrown. 2. c and f should be compatible types, or an exception will be
+ * thrown.
  */
 public class GenericUDFCase extends GenericUDF {
   private transient ObjectInspector[] argumentOIs;
@@ -40,8 +40,8 @@ public class GenericUDFCase extends Gene
   public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentTypeException {
 
     argumentOIs = arguments;
-    caseOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver();
-    returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver();
+    caseOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver(true);
+    returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver(true);
 
     boolean r = caseOIResolver.update(arguments[0]);
     assert (r);
@@ -79,12 +79,13 @@ public class GenericUDFCase extends Gene
     Object exprValue = arguments[0].get();
     for (int i = 1; i + 1 < arguments.length; i += 2) {
       Object caseKey = arguments[i].get();
-      if (PrimitiveObjectInspectorUtils.comparePrimitiveObjects(exprValue,
-          (PrimitiveObjectInspector) argumentOIs[0], caseKey,
-          (PrimitiveObjectInspector) argumentOIs[i])) {
+      // May need to convert to common type to compare
+      PrimitiveObjectInspector caseOI = (PrimitiveObjectInspector) caseOIResolver.get();
+      if (PrimitiveObjectInspectorUtils.comparePrimitiveObjects(
+            caseOIResolver.convertIfNecessary(exprValue, argumentOIs[0]), caseOI,
+            caseOIResolver.convertIfNecessary(caseKey, argumentOIs[i]), caseOI)) {
         Object caseValue = arguments[i + 1].get();
-        return returnOIResolver.convertIfNecessary(caseValue,
-            argumentOIs[i + 1]);
+        return returnOIResolver.convertIfNecessary(caseValue, argumentOIs[i + 1]);
       }
     }
     // Process else statement

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFWhen.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFWhen.java?rev=1542646&r1=1542645&r2=1542646&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFWhen.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFWhen.java Sun Nov 17 04:52:35 2013
@@ -25,11 +25,11 @@ import org.apache.hadoop.hive.serde2.obj
 import org.apache.hadoop.hive.serde2.objectinspector.primitive.BooleanObjectInspector;
 
 /**
- * GenericUDF Class for SQL construct "CASE a WHEN b THEN c [ELSE f] END".
+ * GenericUDF Class for SQL construct
+ * "CASE WHEN a THEN b WHEN c THEN d [ELSE f] END".
  * 
- * NOTES: 1. a and b should have the same TypeInfo, or an exception will be
- * thrown. 2. c and f should have the same TypeInfo, or an exception will be
- * thrown.
+ * NOTES: 1. a and c should be boolean, or an exception will be thrown. 2. b, d
+ * and f should be common types, or an exception will be thrown.
  */
 public class GenericUDFWhen extends GenericUDF {
   private transient ObjectInspector[] argumentOIs;
@@ -39,7 +39,7 @@ public class GenericUDFWhen extends Gene
   public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentTypeException {
 
     argumentOIs = arguments;
-    returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver();
+    returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver(true);
 
     for (int i = 0; i + 1 < arguments.length; i += 2) {
       if (!arguments[i].getTypeName().equals(serdeConstants.BOOLEAN_TYPE_NAME)) {

Modified: hive/trunk/ql/src/test/queries/clientpositive/udf_case.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/udf_case.q?rev=1542646&r1=1542645&r2=1542646&view=diff
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/udf_case.q (original)
+++ hive/trunk/ql/src/test/queries/clientpositive/udf_case.q Sun Nov 17 04:52:35 2013
@@ -63,3 +63,20 @@ FROM src tablesample (1 rows);
 SELECT CASE 1 WHEN 1 THEN 'yo'
 ELSE reflect('java.lang.String', 'bogus', 1) END
 FROM src tablesample (1 rows);
+
+-- Allow compatible types in when/return type
+SELECT CASE 1
+        WHEN 1 THEN 123.0BD
+        ELSE 0.0BD
+       END,
+       CASE 1
+        WHEN 1.0 THEN 123
+        WHEN 2 THEN 1.0
+        ELSE 0.0BD
+       END,
+       CASE 'abc'
+        WHEN cast('abc' as varchar(3)) THEN 'abcd'
+        WHEN 'efg' THEN cast('efgh' as varchar(10))
+        ELSE cast('ijkl' as char(4))
+       END
+FROM src tablesample (1 rows);

Modified: hive/trunk/ql/src/test/queries/clientpositive/udf_when.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/udf_when.q?rev=1542646&r1=1542645&r2=1542646&view=diff
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/udf_when.q (original)
+++ hive/trunk/ql/src/test/queries/clientpositive/udf_when.q Sun Nov 17 04:52:35 2013
@@ -57,3 +57,20 @@ SELECT CASE
         WHEN 28=28 THEN NULL
        END
 FROM src tablesample (1 rows);
+
+-- Allow compatible types to be used in return value
+SELECT CASE
+        WHEN 1=1 THEN 123.0BD
+        ELSE 0.0BD
+       END,
+       CASE
+        WHEN 1=1 THEN 123
+        WHEN 1=2 THEN 1.0
+        ELSE 0.0BD
+       END,
+       CASE
+        WHEN 1=1 THEN 'abcd'
+        WHEN 1=2 THEN cast('efgh' as varchar(10))
+        ELSE cast('ijkl' as char(4))
+       END
+FROM src tablesample (1 rows);

Modified: hive/trunk/ql/src/test/results/clientpositive/udf_case.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientpositive/udf_case.q.out?rev=1542646&r1=1542645&r2=1542646&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/clientpositive/udf_case.q.out (original)
+++ hive/trunk/ql/src/test/results/clientpositive/udf_case.q.out Sun Nov 17 04:52:35 2013
@@ -172,3 +172,42 @@ POSTHOOK: type: QUERY
 POSTHOOK: Input: default@src
 #### A masked pattern was here ####
 yo
+PREHOOK: query: -- Allow compatible types in when/return type
+SELECT CASE 1
+        WHEN 1 THEN 123.0BD
+        ELSE 0.0BD
+       END,
+       CASE 1
+        WHEN 1.0 THEN 123
+        WHEN 2 THEN 1.0
+        ELSE 0.0BD
+       END,
+       CASE 'abc'
+        WHEN cast('abc' as varchar(3)) THEN 'abcd'
+        WHEN 'efg' THEN cast('efgh' as varchar(10))
+        ELSE cast('ijkl' as char(4))
+       END
+FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: -- Allow compatible types in when/return type
+SELECT CASE 1
+        WHEN 1 THEN 123.0BD
+        ELSE 0.0BD
+       END,
+       CASE 1
+        WHEN 1.0 THEN 123
+        WHEN 2 THEN 1.0
+        ELSE 0.0BD
+       END,
+       CASE 'abc'
+        WHEN cast('abc' as varchar(3)) THEN 'abcd'
+        WHEN 'efg' THEN cast('efgh' as varchar(10))
+        ELSE cast('ijkl' as char(4))
+       END
+FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+123	123	abcd

Modified: hive/trunk/ql/src/test/results/clientpositive/udf_when.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientpositive/udf_when.q.out?rev=1542646&r1=1542645&r2=1542646&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/clientpositive/udf_when.q.out (original)
+++ hive/trunk/ql/src/test/results/clientpositive/udf_when.q.out Sun Nov 17 04:52:35 2013
@@ -155,3 +155,42 @@ POSTHOOK: type: QUERY
 POSTHOOK: Input: default@src
 #### A masked pattern was here ####
 2	9	14	NULL	24	NULL
+PREHOOK: query: -- Allow compatible types to be used in return value
+SELECT CASE
+        WHEN 1=1 THEN 123.0BD
+        ELSE 0.0BD
+       END,
+       CASE
+        WHEN 1=1 THEN 123
+        WHEN 1=2 THEN 1.0
+        ELSE 0.0BD
+       END,
+       CASE
+        WHEN 1=1 THEN 'abcd'
+        WHEN 1=2 THEN cast('efgh' as varchar(10))
+        ELSE cast('ijkl' as char(4))
+       END
+FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: -- Allow compatible types to be used in return value
+SELECT CASE
+        WHEN 1=1 THEN 123.0BD
+        ELSE 0.0BD
+       END,
+       CASE
+        WHEN 1=1 THEN 123
+        WHEN 1=2 THEN 1.0
+        ELSE 0.0BD
+       END,
+       CASE
+        WHEN 1=1 THEN 'abcd'
+        WHEN 1=2 THEN cast('efgh' as varchar(10))
+        ELSE cast('ijkl' as char(4))
+       END
+FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+123	123	abcd