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 2014/03/17 21:42:40 UTC
svn commit: r1578558 - in /hive/trunk/ql/src:
java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFPrintf.java
test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFPrintf.java
Author: xuefu
Date: Mon Mar 17 20:42:39 2014
New Revision: 1578558
URL: http://svn.apache.org/r1578558
Log:
HIVE-6620: UDF printf doesn't take either CHAR or VARCHAR as the first argument (reviewed by Jason)
Added:
hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFPrintf.java
Modified:
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFPrintf.java
Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFPrintf.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFPrintf.java?rev=1578558&r1=1578557&r2=1578558&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFPrintf.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFPrintf.java Mon Mar 17 20:42:39 2014
@@ -29,18 +29,13 @@ import org.apache.hadoop.hive.ql.exec.UD
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.serde.serdeConstants;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters.Converter;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
-import org.apache.hadoop.hive.serde2.objectinspector.primitive.BooleanObjectInspector;
-import org.apache.hadoop.hive.serde2.objectinspector.primitive.ByteObjectInspector;
-import org.apache.hadoop.hive.serde2.objectinspector.primitive.DoubleObjectInspector;
-import org.apache.hadoop.hive.serde2.objectinspector.primitive.FloatObjectInspector;
-import org.apache.hadoop.hive.serde2.objectinspector.primitive.IntObjectInspector;
-import org.apache.hadoop.hive.serde2.objectinspector.primitive.LongObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
-import org.apache.hadoop.hive.serde2.objectinspector.primitive.ShortObjectInspector;
-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.WritableHiveDecimalObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableStringObjectInspector;
import org.apache.hadoop.io.Text;
/**
@@ -58,6 +53,8 @@ import org.apache.hadoop.io.Text;
+ " \"Hello World 100 days\"")
public class GenericUDFPrintf extends GenericUDF {
private transient ObjectInspector[] argumentOIs;
+ protected transient Converter converterFormat;
+
private final Text resultText = new Text();
@Override
@@ -67,12 +64,25 @@ public class GenericUDFPrintf extends Ge
"The function PRINTF(String format, Obj... args) needs at least one arguments.");
}
- if (arguments[0].getTypeName() != serdeConstants.STRING_TYPE_NAME
- && arguments[0].getTypeName() != serdeConstants.VOID_TYPE_NAME) {
+ WritableStringObjectInspector resultOI = PrimitiveObjectInspectorFactory.writableStringObjectInspector;
+
+ if (arguments[0].getCategory() == ObjectInspector.Category.PRIMITIVE) {
+ PrimitiveObjectInspector poi = ((PrimitiveObjectInspector) arguments[0]);
+ if (poi.getPrimitiveCategory() == PrimitiveObjectInspector.PrimitiveCategory.STRING ||
+ poi.getPrimitiveCategory() == PrimitiveObjectInspector.PrimitiveCategory.CHAR ||
+ poi.getPrimitiveCategory() == PrimitiveObjectInspector.PrimitiveCategory.VARCHAR ||
+ poi.getPrimitiveCategory() == PrimitiveObjectInspector.PrimitiveCategory.VOID) {
+ converterFormat = ObjectInspectorConverters.getConverter(arguments[0], resultOI);
+ } else {
throw new UDFArgumentTypeException(0, "Argument 1"
- + " of function PRINTF must be \"" + serdeConstants.STRING_TYPE_NAME
- + "\", but \"" + arguments[0].getTypeName() + "\" was found.");
+ + " of function PRINTF must be \"" + serdeConstants.STRING_TYPE_NAME
+ + "\", but \"" + arguments[0].getTypeName() + "\" was found.");
}
+ } else {
+ throw new UDFArgumentTypeException(0, "Argument 1"
+ + " of function PRINTF must be \"" + serdeConstants.STRING_TYPE_NAME
+ + "\", but \"" + arguments[0].getTypeName() + "\" was found.");
+ }
for (int i = 1; i < arguments.length; i++) {
if (!arguments[i].getCategory().equals(Category.PRIMITIVE)){
@@ -83,58 +93,46 @@ public class GenericUDFPrintf extends Ge
}
argumentOIs = arguments;
- return PrimitiveObjectInspectorFactory.writableStringObjectInspector;
+ return resultOI;
}
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
+ // If the first argument is null, return null. (It's okay for other arguments to be null, in
+ // which case, "null" will be printed.)
+ if (arguments[0].get() == null) {
+ return null;
+ }
+
StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb, Locale.US);
- String pattern = ((StringObjectInspector) argumentOIs[0])
- .getPrimitiveJavaObject(arguments[0].get());
+ Text pattern = (Text)converterFormat.convert(arguments[0].get());
- ArrayList argumentList = new ArrayList();
+ ArrayList<Object> argumentList = new ArrayList<Object>();
for (int i = 1; i < arguments.length; i++) {
switch (((PrimitiveObjectInspector)argumentOIs[i]).getPrimitiveCategory()) {
case BOOLEAN:
- argumentList.add(((BooleanObjectInspector)argumentOIs[i]).get(arguments[i].get()));
- break;
case BYTE:
- argumentList.add(((ByteObjectInspector)argumentOIs[i]).get(arguments[i].get()));
- break;
case SHORT:
- argumentList.add(((ShortObjectInspector)argumentOIs[i]).get(arguments[i].get()));
- break;
case INT:
- argumentList.add(((IntObjectInspector)argumentOIs[i]).get(arguments[i].get()));
- break;
case LONG:
- argumentList.add(((LongObjectInspector)argumentOIs[i]).get(arguments[i].get()));
- break;
case FLOAT:
- argumentList.add(((FloatObjectInspector)argumentOIs[i]).get(arguments[i].get()));
- break;
case DOUBLE:
- argumentList.add(((DoubleObjectInspector)argumentOIs[i]).get(arguments[i].get()));
- break;
+ case CHAR:
+ case VARCHAR:
case STRING:
- argumentList.add(((StringObjectInspector)argumentOIs[i])
- .getPrimitiveJavaObject(arguments[i].get()));
- break;
case TIMESTAMP:
- argumentList.add(((TimestampObjectInspector)argumentOIs[i])
+ case DECIMAL:
+ argumentList.add(((PrimitiveObjectInspector)argumentOIs[i])
.getPrimitiveJavaObject(arguments[i].get()));
break;
- case BINARY:
- argumentList.add(arguments[i].get());
- break;
default:
argumentList.add(arguments[i].get());
break;
}
}
- formatter.format(pattern, argumentList.toArray());
+ formatter.format(pattern.toString(), argumentList.toArray());
resultText.set(sb.toString());
return resultText;
Added: hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFPrintf.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFPrintf.java?rev=1578558&view=auto
==============================================================================
--- hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFPrintf.java (added)
+++ hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFPrintf.java Mon Mar 17 20:42:39 2014
@@ -0,0 +1,140 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.udf.generic;
+
+import org.apache.hadoop.hive.common.type.HiveDecimal;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredJavaObject;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredObject;
+import org.apache.hadoop.hive.serde2.io.HiveCharWritable;
+import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable;
+import org.apache.hadoop.hive.serde2.io.HiveVarcharWritable;
+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.typeinfo.TypeInfoFactory;
+import org.apache.hadoop.io.Text;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestGenericUDFPrintf {
+
+ @Test
+ public void testCharVarcharArgs() throws HiveException {
+ GenericUDFPrintf udf = new GenericUDFPrintf();
+
+ ObjectInspector[] inputOIs = {
+ PrimitiveObjectInspectorFactory.writableStringObjectInspector,
+ PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(TypeInfoFactory.getCharTypeInfo(5)),
+ PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(TypeInfoFactory.getVarcharTypeInfo(7))
+ };
+
+ HiveCharWritable argChar = new HiveCharWritable();
+ argChar.set("hello");
+ HiveVarcharWritable argVarchar = new HiveVarcharWritable();
+ argVarchar.set("world");
+ DeferredObject[] args = {
+ new DeferredJavaObject(new Text("1st: %s, 2nd: %s")),
+ new DeferredJavaObject(argChar),
+ new DeferredJavaObject(argVarchar)
+ };
+
+ PrimitiveObjectInspector oi = (PrimitiveObjectInspector) udf.initialize(inputOIs);
+ Assert.assertEquals(PrimitiveObjectInspectorFactory.writableStringObjectInspector, oi);
+ Text res = (Text) udf.evaluate(args);
+ Assert.assertEquals("1st: hello, 2nd: world", res.toString());
+ }
+
+ @Test
+ public void testCharFormat() throws HiveException {
+ GenericUDFPrintf udf = new GenericUDFPrintf();
+
+ ObjectInspector[] inputOIs = {
+ PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(TypeInfoFactory.getCharTypeInfo(10)),
+ PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(TypeInfoFactory.getVarcharTypeInfo(7))
+ };
+
+ HiveCharWritable formatChar = new HiveCharWritable();
+ formatChar.set("arg1=%s");
+ HiveVarcharWritable argVarchar = new HiveVarcharWritable();
+ argVarchar.set("world");
+ DeferredObject[] args = {
+ new DeferredJavaObject(formatChar),
+ new DeferredJavaObject(argVarchar)
+ };
+
+ PrimitiveObjectInspector oi = (PrimitiveObjectInspector) udf.initialize(inputOIs);
+ Assert.assertEquals(PrimitiveObjectInspectorFactory.writableStringObjectInspector, oi);
+ Text res = (Text) udf.evaluate(args);
+ Assert.assertEquals("arg1=world", res.toString());
+ }
+
+ @Test
+ public void testVarcharFormat() throws HiveException {
+ GenericUDFPrintf udf = new GenericUDFPrintf();
+
+ ObjectInspector[] inputOIs = {
+ PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(TypeInfoFactory.getVarcharTypeInfo(7)),
+ PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(TypeInfoFactory.getCharTypeInfo(5))
+ };
+
+ HiveCharWritable argChar = new HiveCharWritable();
+ argChar.set("hello");
+ HiveVarcharWritable formatVarchar = new HiveVarcharWritable();
+ formatVarchar.set("arg1=%s");
+ DeferredObject[] args = {
+ new DeferredJavaObject(formatVarchar),
+ new DeferredJavaObject(argChar)
+ };
+
+ PrimitiveObjectInspector oi = (PrimitiveObjectInspector) udf.initialize(inputOIs);
+ Assert.assertEquals(PrimitiveObjectInspectorFactory.writableStringObjectInspector, oi);
+ Text res = (Text) udf.evaluate(args);
+ Assert.assertEquals("arg1=hello", res.toString());
+ }
+
+ @Test
+ public void testDecimalArgs() throws HiveException {
+ GenericUDFPrintf udf = new GenericUDFPrintf();
+
+ ObjectInspector[] inputOIs = {
+ PrimitiveObjectInspectorFactory.writableStringObjectInspector,
+ PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(TypeInfoFactory.getDecimalTypeInfo(5, 2)),
+ PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(TypeInfoFactory.getDecimalTypeInfo(3, 2))
+ };
+
+ HiveDecimalWritable argDec1 = new HiveDecimalWritable();
+ argDec1.set(HiveDecimal.create("234.789"));
+ HiveDecimalWritable argDec2 = new HiveDecimalWritable();
+ argDec2.set(HiveDecimal.create("3.5"));
+
+ DeferredObject[] args = {
+ new DeferredJavaObject(new Text("1st: %s, 2nd: %s")),
+ new DeferredJavaObject(argDec1),
+ new DeferredJavaObject(argDec2)
+ };
+
+ PrimitiveObjectInspector oi = (PrimitiveObjectInspector) udf.initialize(inputOIs);
+ Assert.assertEquals(PrimitiveObjectInspectorFactory.writableStringObjectInspector, oi);
+ Text res = (Text) udf.evaluate(args);
+ Assert.assertEquals("1st: 234.79, 2nd: 3.5", res.toString());
+ }
+
+}