IMPALA-4099: Fix the error message while loading UDFs with no JARs

Currently we throw a generic exception due to a missing check in
the code for cases where the UDF has no resources associated with
it. This is not super useful from supportability point of view.
This commit fixes that. This also cleans up the code a little
by moving these checks out of the extractFunctions() method.

Change-Id: I167426ea96b0a41374227ef238b6f60e4184a9d7
Reviewed-on: http://gerrit.cloudera.org:8080/4365
Reviewed-by: Alex Behm <[email protected]>
Reviewed-by: Marcel Kornacker <[email protected]>
Tested-by: Internal Jenkins


Project: http://git-wip-us.apache.org/repos/asf/incubator-impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-impala/commit/94fc6a3d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-impala/tree/94fc6a3d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-impala/diff/94fc6a3d

Branch: refs/heads/master
Commit: 94fc6a3d07aaf19591b832d4fc88eee831db9f99
Parents: f9bcb91
Author: Bharath Vissapragada <[email protected]>
Authored: Fri Sep 9 17:22:28 2016 -0700
Committer: Internal Jenkins <[email protected]>
Committed: Tue Sep 13 03:40:02 2016 +0000

----------------------------------------------------------------------
 .../impala/catalog/CatalogServiceCatalog.java   | 70 +++++++++++++-------
 1 file changed, 45 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/94fc6a3d/fe/src/main/java/com/cloudera/impala/catalog/CatalogServiceCatalog.java
----------------------------------------------------------------------
diff --git 
a/fe/src/main/java/com/cloudera/impala/catalog/CatalogServiceCatalog.java 
b/fe/src/main/java/com/cloudera/impala/catalog/CatalogServiceCatalog.java
index e8f5577..f43938b 100644
--- a/fe/src/main/java/com/cloudera/impala/catalog/CatalogServiceCatalog.java
+++ b/fe/src/main/java/com/cloudera/impala/catalog/CatalogServiceCatalog.java
@@ -391,6 +391,49 @@ public class CatalogServiceCatalog extends Catalog {
   }
 
   /**
+   * Checks if the Hive function 'fn' is Impala compatible. A function is 
Impala
+   * compatible iff
+   *
+   * 1. The function is JAVA based,
+   * 2. Has exactly one binary resource associated (We don't support loading
+   *    dependencies yet) and
+   * 3. The binary is of type JAR.
+   *
+   * Returns true if compatible and false otherwise. In case of incompatible
+   * functions 'incompatMsg' has the reason for the incompatibility.
+   * */
+   public static boolean isFunctionCompatible(
+       org.apache.hadoop.hive.metastore.api.Function fn, StringBuilder 
incompatMsg) {
+    boolean isCompatible = true;
+    if (fn.getFunctionType() != FunctionType.JAVA) {
+      isCompatible = false;
+      incompatMsg.append("Function type: " + fn.getFunctionType().name()
+          + " is not supported. Only " + FunctionType.JAVA.name() + " 
functions "
+          + "are supported.");
+    } else if (fn.getResourceUrisSize() == 0) {
+      isCompatible = false;
+      incompatMsg.append("No executable binary resource (like a JAR file) is " 
+
+          "associated with this function. To fix this, recreate the function 
by " +
+          "specifying a 'location' in the function create statement.");
+    } else if (fn.getResourceUrisSize() != 1) {
+      isCompatible = false;
+      List<String> resourceUris = Lists.newArrayList();
+      for (ResourceUri resource: fn.getResourceUris()) {
+        resourceUris.add(resource.getUri());
+      }
+      incompatMsg.append("Impala does not support multiple Jars for 
dependencies."
+          + "(" + Joiner.on(",").join(resourceUris) + ") ");
+    } else if (fn.getResourceUris().get(0).getResourceType() != 
ResourceType.JAR) {
+      isCompatible = false;
+      incompatMsg.append("Function binary type: " +
+        fn.getResourceUris().get(0).getResourceType().name()
+        + " is not supported. Only " + ResourceType.JAR.name()
+        + " type is supported.");
+    }
+    return isCompatible;
+  }
+
+  /**
    * Returns a list of Impala Functions, one per compatible "evaluate" method 
in the UDF
    * class referred to by the given Java function. This method copies the UDF 
Jar
    * referenced by "function" to a temporary file in "LOCAL_LIBRARY_PATH" and 
loads it
@@ -404,32 +447,9 @@ public class CatalogServiceCatalog extends Catalog {
       throws ImpalaRuntimeException{
     List<Function> result = Lists.newArrayList();
     List<String> addedSignatures = Lists.newArrayList();
-    boolean compatible = true;
     StringBuilder warnMessage = new StringBuilder();
-    if (function.getFunctionType() != FunctionType.JAVA) {
-      compatible = false;
-      warnMessage.append("Function type: " + function.getFunctionType().name()
-          + " is not supported. Only " + FunctionType.JAVA.name() + " 
functions "
-          + "are supported.");
-    }
-    if (function.getResourceUrisSize() != 1) {
-      compatible = false;
-      List<String> resourceUris = Lists.newArrayList();
-      for (ResourceUri resource: function.getResourceUris()) {
-        resourceUris.add(resource.getUri());
-      }
-      warnMessage.append("Impala does not support multiple Jars for 
dependencies."
-          + "(" + Joiner.on(",").join(resourceUris) + ") ");
-    }
-    if (function.getResourceUris().get(0).getResourceType() != 
ResourceType.JAR) {
-      compatible = false;
-      warnMessage.append("Function binary type: " +
-        function.getResourceUris().get(0).getResourceType().name()
-        + " is not supported. Only " + ResourceType.JAR.name()
-        + " type is supported.");
-    }
-    if (!compatible) {
-      LOG.warn("Skipping load of incompatible Java function: " +
+    if (!isFunctionCompatible(function, warnMessage)) {
+      LOG.warn("Skipping load of incompatible function: " +
           function.getFunctionName() + ". " + warnMessage.toString());
       return result;
     }

Reply via email to