You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ha...@apache.org on 2012/12/10 17:42:02 UTC

svn commit: r1419577 - in /hive/trunk/ql/src: java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFReflect.java test/queries/clientpositive/udf_reflect.q test/results/clientpositive/udf_reflect.q.out

Author: hashutosh
Date: Mon Dec 10 16:42:01 2012
New Revision: 1419577

URL: http://svn.apache.org/viewvc?rev=1419577&view=rev
Log:
HIVE-3622 : reflect udf cannot find method which has arguments of primitive types and String, Binary, Timestamp types mixed (Navis via Ashutosh Chauhan)

Modified:
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFReflect.java
    hive/trunk/ql/src/test/queries/clientpositive/udf_reflect.q
    hive/trunk/ql/src/test/results/clientpositive/udf_reflect.q.out

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFReflect.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFReflect.java?rev=1419577&r1=1419576&r2=1419577&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFReflect.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFReflect.java Mon Dec 10 16:42:01 2012
@@ -50,8 +50,8 @@ public class GenericUDFReflect extends G
   StringObjectInspector classNameOI;
   StringObjectInspector methodNameOI;
   
-  Class<?>[] parameterJavaClasses; // Classes are Integer, Double, String
-  Class<?>[] parameterJavaTypes;   // Types are int, double, etc
+  PrimitiveTypeEntry[] parameterTypes;
+  Class[] parameterClasses;
   Object[] parameterJavaValues;
   
   @Override
@@ -77,8 +77,8 @@ public class GenericUDFReflect extends G
     methodNameOI = (StringObjectInspector)
         ObjectInspectorUtils.getStandardObjectInspector(arguments[1]);
     
-    parameterJavaClasses = new Class[arguments.length - 2];
-    parameterJavaTypes = new Class[arguments.length - 2];
+    parameterTypes = new PrimitiveTypeEntry[arguments.length - 2];
+    parameterClasses = new Class[arguments.length - 2];
     for (int i = 2; i < arguments.length; i++) {
       if (arguments[i].getCategory() != ObjectInspector.Category.PRIMITIVE) {
         throw new UDFArgumentTypeException(i,
@@ -87,10 +87,10 @@ public class GenericUDFReflect extends G
       }
       PrimitiveCategory category =
           ((PrimitiveObjectInspector)arguments[i]).getPrimitiveCategory();
-      PrimitiveTypeEntry t =
+      parameterTypes[i - 2] =
           PrimitiveObjectInspectorUtils.getTypeEntryFromPrimitiveCategory(category);
-      parameterJavaClasses[i - 2] = t.primitiveJavaClass;
-      parameterJavaTypes[i - 2] = t.primitiveJavaType;
+      parameterClasses[i - 2] = parameterTypes[i - 2].primitiveJavaType == null ?
+          parameterTypes[i - 2].primitiveJavaClass : parameterTypes[i - 2].primitiveJavaType;
     }
     
     parameterJavaValues = new Object[arguments.length - 2];
@@ -152,17 +152,9 @@ public class GenericUDFReflect extends G
       methodName = ObjectInspectorUtils.copyToStandardObject(newMethodName, newMethodNameOI);
       String methodNameString = methodNameOI.getPrimitiveJavaObject(methodName);
       try {
-        m = c.getMethod(methodNameString, parameterJavaClasses);
-      } catch (SecurityException e) {
+        m = findMethod(c, methodNameString, parameterTypes, parameterClasses);
+      } catch (Exception e) {
         throw new HiveException("UDFReflect getMethod ", e);
-      } catch (NoSuchMethodException e) {
-        try {
-          m = c.getMethod(methodNameString, parameterJavaTypes);
-        } catch (SecurityException ex) {
-          throw new HiveException("UDFReflect getMethod ", ex);
-        } catch (NoSuchMethodException ex) {
-          throw new HiveException("UDFReflect getMethod ", ex);
-        }
       }
     }
     
@@ -200,5 +192,32 @@ public class GenericUDFReflect extends G
     sb.append(')');
     return sb.toString();
   }
-  
+
+  // a(string,int,int) can be matched with methods like
+  // a(string,int,int), a(string,int,Integer), a(string,Integer,int) and a(string,Integer,Integer)
+  // and accepts the first one clazz.getMethods() returns
+  private Method findMethod(Class clazz, String name, PrimitiveTypeEntry[] parameterTypes,
+      Class[] parameterClasses) throws Exception {
+    for (Method method : clazz.getMethods()) {
+      if (!method.getName().equals(name) || method.getReturnType() != String.class ||
+          method.getParameterTypes().length != parameterTypes.length) {
+        continue;
+      }
+      // returns first one matches all of the params
+      boolean match = true;
+      Class<?>[] types = method.getParameterTypes();
+      for (int i = 0; i < parameterTypes.length; i++) {
+        if (types[i] != parameterTypes[i].primitiveJavaType &&
+            types[i] != parameterTypes[i].primitiveJavaClass) {
+          match = false;
+          break;
+        }
+      }
+      if (match) {
+        return method;
+      }
+    }
+    // tried all, back to original code (for error message)
+    return clazz.getMethod(name, parameterClasses);
+  }
 }

Modified: hive/trunk/ql/src/test/queries/clientpositive/udf_reflect.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/udf_reflect.q?rev=1419577&r1=1419576&r2=1419577&view=diff
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/udf_reflect.q (original)
+++ hive/trunk/ql/src/test/queries/clientpositive/udf_reflect.q Mon Dec 10 16:42:01 2012
@@ -8,7 +8,8 @@ SELECT reflect("java.lang.String", "valu
        reflect("java.lang.Math", "min", 2, 3),
        reflect("java.lang.Math", "round", 2.5),
        reflect("java.lang.Math", "exp", 1.0),
-       reflect("java.lang.Math", "floor", 1.9)
+       reflect("java.lang.Math", "floor", 1.9),
+       reflect("java.lang.Integer", "valueOf", key, 16)
 FROM src LIMIT 1;
 
 
@@ -18,5 +19,6 @@ SELECT reflect("java.lang.String", "valu
        reflect("java.lang.Math", "min", 2, 3),
        reflect("java.lang.Math", "round", 2.5),
        reflect("java.lang.Math", "exp", 1.0),
-       reflect("java.lang.Math", "floor", 1.9)
+       reflect("java.lang.Math", "floor", 1.9),
+       reflect("java.lang.Integer", "valueOf", key, 16)
 FROM src LIMIT 1;

Modified: hive/trunk/ql/src/test/results/clientpositive/udf_reflect.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientpositive/udf_reflect.q.out?rev=1419577&r1=1419576&r2=1419577&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/clientpositive/udf_reflect.q.out (original)
+++ hive/trunk/ql/src/test/results/clientpositive/udf_reflect.q.out Mon Dec 10 16:42:01 2012
@@ -18,7 +18,8 @@ SELECT reflect("java.lang.String", "valu
        reflect("java.lang.Math", "min", 2, 3),
        reflect("java.lang.Math", "round", 2.5),
        reflect("java.lang.Math", "exp", 1.0),
-       reflect("java.lang.Math", "floor", 1.9)
+       reflect("java.lang.Math", "floor", 1.9),
+       reflect("java.lang.Integer", "valueOf", key, 16)
 FROM src LIMIT 1
 PREHOOK: type: QUERY
 POSTHOOK: query: EXPLAIN EXTENDED
@@ -28,11 +29,12 @@ SELECT reflect("java.lang.String", "valu
        reflect("java.lang.Math", "min", 2, 3),
        reflect("java.lang.Math", "round", 2.5),
        reflect("java.lang.Math", "exp", 1.0),
-       reflect("java.lang.Math", "floor", 1.9)
+       reflect("java.lang.Math", "floor", 1.9),
+       reflect("java.lang.Integer", "valueOf", key, 16)
 FROM src LIMIT 1
 POSTHOOK: type: QUERY
 ABSTRACT SYNTAX TREE:
-  (TOK_QUERY (TOK_FROM (TOK_TABREF (TOK_TABNAME src))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.String" "valueOf" 1)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.String" "isEmpty")) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Math" "max" 2 3)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Math" "min" 2 3)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Math" "round" 2.5)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Math" "exp" 1.0)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Math" "floor" 1.9))) (TOK_LIMIT 1)))
+  (TOK_QUERY (TOK_FROM (TOK_TABREF (TOK_TABNAME src))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.String" "valueOf" 1)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.String" "isEmpty")) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Math" "max" 2 3)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Math" "min" 2 3)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Math" "round" 2.5)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Math" "exp" 1.0)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Math" "floor" 1.9)) (TOK_SELEXPR (TOK_FUNCTION reflect "java.lang.Integer" "valueOf" (TOK_TABLE_OR_COL key) 16))) (TOK_LIMIT 1)))
 
 STAGE DEPENDENCIES:
   Stage-1 is a root stage
@@ -62,7 +64,9 @@ STAGE PLANS:
                     type: string
                     expr: reflect('java.lang.Math','floor',1.9)
                     type: string
-              outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6
+                    expr: reflect('java.lang.Integer','valueOf',key,16)
+                    type: string
+              outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7
               Limit
                 File Output Operator
                   compressed: false
@@ -74,8 +78,8 @@ STAGE PLANS:
                       input format: org.apache.hadoop.mapred.TextInputFormat
                       output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
                       properties:
-                        columns _col0,_col1,_col2,_col3,_col4,_col5,_col6
-                        columns.types string:string:string:string:string:string:string
+                        columns _col0,_col1,_col2,_col3,_col4,_col5,_col6,_col7
+                        columns.types string:string:string:string:string:string:string:string
                         escape.delim \
                         serialization.format 1
                   TotalFiles: 1
@@ -141,7 +145,8 @@ PREHOOK: query: SELECT reflect("java.lan
        reflect("java.lang.Math", "min", 2, 3),
        reflect("java.lang.Math", "round", 2.5),
        reflect("java.lang.Math", "exp", 1.0),
-       reflect("java.lang.Math", "floor", 1.9)
+       reflect("java.lang.Math", "floor", 1.9),
+       reflect("java.lang.Integer", "valueOf", key, 16)
 FROM src LIMIT 1
 PREHOOK: type: QUERY
 PREHOOK: Input: default@src
@@ -152,9 +157,10 @@ POSTHOOK: query: SELECT reflect("java.la
        reflect("java.lang.Math", "min", 2, 3),
        reflect("java.lang.Math", "round", 2.5),
        reflect("java.lang.Math", "exp", 1.0),
-       reflect("java.lang.Math", "floor", 1.9)
+       reflect("java.lang.Math", "floor", 1.9),
+       reflect("java.lang.Integer", "valueOf", key, 16)
 FROM src LIMIT 1
 POSTHOOK: type: QUERY
 POSTHOOK: Input: default@src
 #### A masked pattern was here ####
-1	true	3	2	3	2.7182818284590455	1.0
+1	true	3	2	3	2.7182818284590455	1.0	568