diff --git ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCase.java ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCase.java index e10a2eb..a470370 100644 --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCase.java +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCase.java @@ -22,6 +22,7 @@ import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils; /** @@ -71,11 +72,15 @@ public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumen } } - return returnOIResolver.get(); + ObjectInspector resolved = returnOIResolver.get(); + return resolved == null ? PrimitiveObjectInspectorFactory.javaVoidObjectInspector : resolved; } @Override public Object evaluate(DeferredObject[] arguments) throws HiveException { + if (returnOIResolver.get() == null) { + return null; + } Object exprValue = arguments[0].get(); for (int i = 1; i + 1 < arguments.length; i += 2) { Object caseKey = arguments[i].get(); diff --git ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFWhen.java ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFWhen.java index 6ffdbd8..b861f70 100644 --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFWhen.java +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFWhen.java @@ -23,6 +23,7 @@ import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.BooleanObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; /** * GenericUDF Class for SQL construct @@ -66,11 +67,15 @@ public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumen } } - return returnOIResolver.get(); + ObjectInspector resolved = returnOIResolver.get(); + return resolved == null ? PrimitiveObjectInspectorFactory.javaVoidObjectInspector : resolved; } @Override public Object evaluate(DeferredObject[] arguments) throws HiveException { + if (returnOIResolver.get() == null) { + return null; + } for (int i = 0; i + 1 < arguments.length; i += 2) { Object caseKey = arguments[i].get(); if (caseKey != null diff --git ql/src/test/queries/clientpositive/udf_case.q ql/src/test/queries/clientpositive/udf_case.q index 43573bf..7582200 100644 --- ql/src/test/queries/clientpositive/udf_case.q +++ ql/src/test/queries/clientpositive/udf_case.q @@ -80,3 +80,5 @@ SELECT CASE 1 ELSE cast('ijkl' as char(4)) END FROM src tablesample (1 rows); + +select case 1 when 1 then null when 2 then null end from src tablesample (1 rows); diff --git ql/src/test/queries/clientpositive/udf_when.q ql/src/test/queries/clientpositive/udf_when.q index 4eb7f69..04b18cf 100644 --- ql/src/test/queries/clientpositive/udf_when.q +++ ql/src/test/queries/clientpositive/udf_when.q @@ -74,3 +74,5 @@ SELECT CASE ELSE cast('ijkl' as char(4)) END FROM src tablesample (1 rows); + +select case when 1=1 then null when 1=2 then null end from src tablesample (1 rows); diff --git ql/src/test/results/clientpositive/udf_case.q.out ql/src/test/results/clientpositive/udf_case.q.out index fe11fce..849b5d8 100644 --- ql/src/test/results/clientpositive/udf_case.q.out +++ ql/src/test/results/clientpositive/udf_case.q.out @@ -197,3 +197,12 @@ POSTHOOK: type: QUERY POSTHOOK: Input: default@src #### A masked pattern was here #### 123 123.0 abcd +PREHOOK: query: select case 1 when 1 then null when 2 then null end from src tablesample (1 rows) +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: select case 1 when 1 then null when 2 then null end from src tablesample (1 rows) +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +NULL diff --git ql/src/test/results/clientpositive/udf_when.q.out ql/src/test/results/clientpositive/udf_when.q.out index 42736f4..77dd5c0 100644 --- ql/src/test/results/clientpositive/udf_when.q.out +++ ql/src/test/results/clientpositive/udf_when.q.out @@ -180,3 +180,12 @@ POSTHOOK: type: QUERY POSTHOOK: Input: default@src #### A masked pattern was here #### 123 123.0 abcd +PREHOOK: query: select case when 1=1 then null when 1=2 then null end from src tablesample (1 rows) +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: select case when 1=1 then null when 1=2 then null end from src tablesample (1 rows) +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +NULL diff --git serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java index 1baf359..8b11c6d 100644 --- serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java +++ serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java @@ -69,9 +69,7 @@ import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.TimestampObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableStringObjectInspector; -import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils; -import org.apache.hadoop.hive.shims.ShimLoader; import org.apache.hadoop.io.BytesWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.util.StringUtils; @@ -108,7 +106,7 @@ public static ObjectInspector getWritableObjectInspector(ObjectInspector oi) { PrimitiveObjectInspector poi = (PrimitiveObjectInspector) oi; if (!(poi instanceof AbstractPrimitiveWritableObjectInspector)) { return PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector( - (PrimitiveTypeInfo)poi.getTypeInfo()); + poi.getTypeInfo()); } } return oi; @@ -1005,6 +1003,9 @@ public static boolean compareTypes(ObjectInspector o1, ObjectInspector o2) { } public static ConstantObjectInspector getConstantObjectInspector(ObjectInspector oi, Object value) { + if (oi instanceof ConstantObjectInspector) { + return (ConstantObjectInspector) oi; + } ObjectInspector writableOI = getStandardObjectInspector(oi, ObjectInspectorCopyOption.WRITABLE); Object writableValue = ObjectInspectorConverters.getConverter(oi, writableOI).convert(value); diff --git serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/JavaVoidObjectInspector.java serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/JavaVoidObjectInspector.java index 4ea3651..07ffb17 100644 --- serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/JavaVoidObjectInspector.java +++ serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/JavaVoidObjectInspector.java @@ -17,14 +17,14 @@ */ package org.apache.hadoop.hive.serde2.objectinspector.primitive; +import org.apache.hadoop.hive.serde2.objectinspector.ConstantObjectInspector; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory; -import org.apache.hadoop.io.NullWritable; /** * A JavaVoidObjectInspector inspects a Java Void Object. */ public class JavaVoidObjectInspector extends - AbstractPrimitiveJavaObjectInspector implements VoidObjectInspector { + AbstractPrimitiveJavaObjectInspector implements VoidObjectInspector, ConstantObjectInspector { JavaVoidObjectInspector() { super(TypeInfoFactory.voidTypeInfo); @@ -32,7 +32,11 @@ @Override public Object getPrimitiveWritableObject(Object o) { - return NullWritable.get(); + return null; } + @Override + public Object getWritableConstantValue() { + return null; + } } diff --git serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/WritableVoidObjectInspector.java serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/WritableVoidObjectInspector.java index 02b672a..ec4cdf9 100644 --- serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/WritableVoidObjectInspector.java +++ serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/WritableVoidObjectInspector.java @@ -19,6 +19,7 @@ import org.apache.hadoop.hive.serde2.objectinspector.ConstantObjectInspector; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory; +import org.apache.hadoop.io.NullWritable; /** * A WritableVoidObjectInspector inspects a NullWritable Object. @@ -44,6 +45,6 @@ public Object getWritableConstantValue() { @Override public Object getPrimitiveJavaObject(Object o) { - throw new RuntimeException("Internal error: cannot create Void object."); + return null; } }