Small updates to Hive UDF: fixes for aggregate and constant checker to add 
errors to error collector.  Register hive udfs without descriptions using fully 
qualified name with underscores instead of periods.


Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/693bd353
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/693bd353
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/693bd353

Branch: refs/heads/master
Commit: 693bd35391b9106df4f2795bdf0ee5a73adb27af
Parents: f8fbb5d
Author: Jacques Nadeau <[email protected]>
Authored: Sat Mar 22 09:02:04 2014 -0700
Committer: Jacques Nadeau <[email protected]>
Committed: Sat Mar 22 09:02:04 2014 -0700

----------------------------------------------------------------------
 .../common/expression/ErrorCollectorImpl.java   |   1 +
 .../common/expression/ExpressionFunction.java   |   1 +
 .../expression/ExpressionValidationError.java   |  31 ----
 .../ExpressionValidationException.java          |  38 -----
 .../common/expression/ExpressionValidator.java  | 125 -----------------
 .../expression/visitors/ConstantChecker.java    |  68 +++++----
 .../visitors/ExpressionValidationError.java     |  31 ++++
 .../visitors/ExpressionValidationException.java |  38 +++++
 .../visitors/ExpressionValidator.java           | 140 +++++++++++++++++++
 .../apache/drill/common/util/PathScanner.java   |   1 +
 .../exec/expr/ExpressionTreeMaterializer.java   |   2 +-
 .../fn/DrillFunctionImplementationRegistry.java |   3 +-
 .../fn/HiveFunctionImplementationRegistry.java  |  32 ++---
 13 files changed, 267 insertions(+), 244 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/common/src/main/java/org/apache/drill/common/expression/ErrorCollectorImpl.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/ErrorCollectorImpl.java
 
b/common/src/main/java/org/apache/drill/common/expression/ErrorCollectorImpl.java
index 9e5747b..bd67be3 100644
--- 
a/common/src/main/java/org/apache/drill/common/expression/ErrorCollectorImpl.java
+++ 
b/common/src/main/java/org/apache/drill/common/expression/ErrorCollectorImpl.java
@@ -20,6 +20,7 @@ package org.apache.drill.common.expression;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.drill.common.expression.visitors.ExpressionValidationError;
 import org.apache.drill.common.types.TypeProtos.MajorType;
 
 import com.google.common.base.Joiner;

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/common/src/main/java/org/apache/drill/common/expression/ExpressionFunction.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/ExpressionFunction.java
 
b/common/src/main/java/org/apache/drill/common/expression/ExpressionFunction.java
index 0a514fd..3fe0d4c 100644
--- 
a/common/src/main/java/org/apache/drill/common/expression/ExpressionFunction.java
+++ 
b/common/src/main/java/org/apache/drill/common/expression/ExpressionFunction.java
@@ -21,6 +21,7 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Type;
 import java.util.List;
 
+import 
org.apache.drill.common.expression.visitors.ExpressionValidationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/common/src/main/java/org/apache/drill/common/expression/ExpressionValidationError.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/ExpressionValidationError.java
 
b/common/src/main/java/org/apache/drill/common/expression/ExpressionValidationError.java
deleted file mode 100644
index 01bc6be..0000000
--- 
a/common/src/main/java/org/apache/drill/common/expression/ExpressionValidationError.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * 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.drill.common.expression;
-
-public class ExpressionValidationError {
-    String message;
-
-    public ExpressionValidationError(String message) {
-        this.message = message;
-    }
-
-    @Override
-    public String toString() {
-        return message;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/common/src/main/java/org/apache/drill/common/expression/ExpressionValidationException.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/ExpressionValidationException.java
 
b/common/src/main/java/org/apache/drill/common/expression/ExpressionValidationException.java
deleted file mode 100644
index 32e70df..0000000
--- 
a/common/src/main/java/org/apache/drill/common/expression/ExpressionValidationException.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * 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.drill.common.expression;
-
-public class ExpressionValidationException extends RuntimeException {
-
-  public ExpressionValidationException() {
-    super();
-  }
-
-  public ExpressionValidationException(String arg0, Throwable arg1) {
-    super(arg0, arg1);
-  }
-
-  public ExpressionValidationException(String arg0) {
-    super(arg0);
-  }
-
-  public ExpressionValidationException(Throwable arg0) {
-    super(arg0);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/common/src/main/java/org/apache/drill/common/expression/ExpressionValidator.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/ExpressionValidator.java
 
b/common/src/main/java/org/apache/drill/common/expression/ExpressionValidator.java
deleted file mode 100644
index 3c7e132..0000000
--- 
a/common/src/main/java/org/apache/drill/common/expression/ExpressionValidator.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * 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.drill.common.expression;
-
-import org.apache.drill.common.expression.IfExpression.IfCondition;
-import org.apache.drill.common.expression.ValueExpressions.BooleanExpression;
-import org.apache.drill.common.expression.ValueExpressions.DoubleExpression;
-import org.apache.drill.common.expression.ValueExpressions.LongExpression;
-import org.apache.drill.common.expression.ValueExpressions.QuotedString;
-import org.apache.drill.common.expression.visitors.AggregateChecker;
-import org.apache.drill.common.expression.visitors.ConstantChecker;
-import org.apache.drill.common.expression.visitors.ExprVisitor;
-import org.apache.drill.common.types.TypeProtos.DataMode;
-import org.apache.drill.common.types.TypeProtos.MajorType;
-import org.apache.drill.common.types.TypeProtos.MinorType;
-
-public class ExpressionValidator implements ExprVisitor<Void, ErrorCollector, 
RuntimeException> {
-  static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(ExpressionValidator.class);
-
-  @Override
-  public Void visitFunctionCall(FunctionCall call, ErrorCollector errors) 
throws RuntimeException {
-    throw new UnsupportedOperationException("FunctionCall is not expected 
here. "+
-      "It should have been converted to FunctionHolderExpression in 
materialization");
-  }
-
-  @Override
-  public Void visitFunctionHolderExpression(FunctionHolderExpression holder, 
ErrorCollector errors) throws RuntimeException {
-    // make sure aggregate functions are not nested inside aggregate functions
-    AggregateChecker.isAggregating(holder);
-
-    // make sure arguments are constant if the function implementation expects 
constants for any arguments
-    ConstantChecker.onlyIncludesConstants(holder);
-
-    return null;
-  }
-
-  @Override
-  public Void visitIfExpression(IfExpression ifExpr, ErrorCollector errors) 
throws RuntimeException {
-    // confirm that all conditions are required boolean values.
-    int i = 0;
-    for (IfCondition c : ifExpr.conditions) {
-      MajorType mt = c.condition.getMajorType();
-      if (mt.getMode() != DataMode.REQUIRED || mt.getMinorType() != 
MinorType.BIT){
-        errors.addGeneralError(c.condition.getPosition(),String.format(
-                        "Failure composing If Expression.  All conditions must 
return a required value and be of type boolean.  Condition %d was DatMode %s 
and Type %s.",
-                        i, mt.getMode(), mt.getMinorType()));
-      }
-      i++;
-    }
-
-    // confirm that all outcomes are the same type.
-    final MajorType mt = ifExpr.elseExpression.getMajorType();
-    i = 0;
-    for (IfCondition c : ifExpr.conditions) {
-      MajorType innerT = c.expression.getMajorType();
-      if (
-          (innerT.getMode() == DataMode.REPEATED && mt.getMode() != 
DataMode.REPEATED) || //
-          (innerT.getMinorType() != mt.getMinorType())
-          ) {
-        errors.addGeneralError(c.condition.getPosition(),String.format(
-            "Failure composing If Expression.  All expressions must return the 
same MajorType as the else expression.  The %d if condition returned type type 
%s but the else expression was of type %s",
-            i, innerT, mt));
-      }
-      i++;
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitSchemaPath(SchemaPath path, ErrorCollector errors) throws 
RuntimeException {
-    return null;
-  }
-
-  @Override
-  public Void visitIntConstant(ValueExpressions.IntExpression intExpr, 
ErrorCollector value) throws RuntimeException {
-    return null;
-  }
-
-  @Override
-  public Void visitFloatConstant(ValueExpressions.FloatExpression fExpr, 
ErrorCollector value) throws RuntimeException {
-    return null;
-  }
-
-  @Override
-  public Void visitLongConstant(LongExpression intExpr, ErrorCollector errors) 
throws RuntimeException {
-    return null;
-  }
-
-  @Override
-  public Void visitDoubleConstant(DoubleExpression dExpr, ErrorCollector 
errors) throws RuntimeException {
-    return null;
-  }
-
-  @Override
-  public Void visitBooleanConstant(BooleanExpression e, ErrorCollector errors) 
throws RuntimeException {
-    return null;
-  }
-
-  @Override
-  public Void visitQuotedStringConstant(QuotedString e, ErrorCollector errors) 
throws RuntimeException {
-    return null;
-  }
-
-  @Override
-  public Void visitUnknown(LogicalExpression e, ErrorCollector value) throws 
RuntimeException {
-    return null;
-  }
-
-  
-}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/common/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
index fcb2489..1391c84 100644
--- 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
+++ 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ConstantChecker.java
@@ -17,6 +17,7 @@
  */
 package org.apache.drill.common.expression.visitors;
 
+import org.apache.drill.common.expression.ErrorCollector;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.FunctionHolderExpression;
 import org.apache.drill.common.expression.IfExpression;
@@ -25,88 +26,93 @@ import org.apache.drill.common.expression.LogicalExpression;
 import org.apache.drill.common.expression.SchemaPath;
 import org.apache.drill.common.expression.ValueExpressions.BooleanExpression;
 import org.apache.drill.common.expression.ValueExpressions.DoubleExpression;
-import org.apache.drill.common.expression.ValueExpressions.LongExpression;
-import org.apache.drill.common.expression.ValueExpressions.IntExpression;
 import org.apache.drill.common.expression.ValueExpressions.FloatExpression;
+import org.apache.drill.common.expression.ValueExpressions.IntExpression;
+import org.apache.drill.common.expression.ValueExpressions.LongExpression;
 import org.apache.drill.common.expression.ValueExpressions.QuotedString;
 
-public final class ConstantChecker extends SimpleExprVisitor<Boolean>{
-       
+final class ConstantChecker implements ExprVisitor<Boolean, ErrorCollector, 
RuntimeException> {
+
+
   private final static ConstantChecker INSTANCE = new ConstantChecker();
   
   private ConstantChecker(){}
   
-  public static boolean onlyIncludesConstants(LogicalExpression e){
-    return e.accept(INSTANCE, null);
+  public static void checkConstants(LogicalExpression e, ErrorCollector 
errors){
+    e.accept(INSTANCE, errors);
   }
 
   @Override
-  public Boolean visitFunctionCall(FunctionCall call) {
-    throw new UnsupportedOperationException("FunctionCall is not expected 
here. "+
-      "It should have been converted to FunctionHolderExpression in 
materialization");
+  public Boolean visitFunctionCall(FunctionCall call, ErrorCollector errors) {
+    throw new UnsupportedOperationException("FunctionCall is not expected 
here. "
+        + "It should have been converted to FunctionHolderExpression in 
materialization");
   }
 
   @Override
-  public Boolean visitFunctionHolderExpression(FunctionHolderExpression 
holder) {
-    for(int i=0; i<holder.args.size(); i++) {
-      if (holder.argConstantOnly(i) && !holder.args.get(i).accept(this, null)) 
{
-        StringBuilder sb = new StringBuilder();
-        sb.append("Function '").append(holder.getName())
-          .append("' expects constant input for argument number ").append(i);
-        throw new UnsupportedOperationException(sb.toString());
+  public Boolean visitFunctionHolderExpression(FunctionHolderExpression 
holder, ErrorCollector errors) {
+    boolean allArgsAreConstant = true;
+    for (int i = 0; i < holder.args.size(); i++) {
+      boolean thisArgIsConstant = holder.args.get(i).accept(this, errors);
+      if(!thisArgIsConstant){
+        allArgsAreConstant = false;
+        if (holder.argConstantOnly(i)) {
+          errors.addGeneralError( //
+              holder.args.get(i).getPosition(), //
+              String.format("Function %s expects constant input for argument 
number %d", holder.getName(), i));
+        }
       }
     }
-    return true;
+    return allArgsAreConstant;
   }
 
   @Override
-  public Boolean visitIfExpression(IfExpression ifExpr) {
-    for(IfCondition c : ifExpr.conditions){
-      if(!c.condition.accept(this, null) || !c.expression.accept(this, null)) 
return false;
+  public Boolean visitIfExpression(IfExpression ifExpr, ErrorCollector errors) 
{
+    for (IfCondition c : ifExpr.conditions) {
+      if (!c.condition.accept(this, errors) || !c.expression.accept(this, 
errors))
+        return false;
     }
-    if(!ifExpr.elseExpression.accept(this, null)) return false;
+    if (!ifExpr.elseExpression.accept(this, errors)) return false;
     return true;
   }
 
   @Override
-  public Boolean visitSchemaPath(SchemaPath path) {
+  public Boolean visitSchemaPath(SchemaPath path, ErrorCollector errors) {
     return false;
   }
 
   @Override
-  public Boolean visitIntConstant(IntExpression intExpr) {
+  public Boolean visitIntConstant(IntExpression intExpr, ErrorCollector 
errors) {
     return true;
   }
 
   @Override
-  public Boolean visitFloatConstant(FloatExpression fExpr) {
+  public Boolean visitFloatConstant(FloatExpression fExpr, ErrorCollector 
errors) {
     return true;
   }
 
   @Override
-  public Boolean visitLongConstant(LongExpression intExpr) {
+  public Boolean visitLongConstant(LongExpression intExpr, ErrorCollector 
errors) {
     return true;
   }
 
   @Override
-  public Boolean visitDoubleConstant(DoubleExpression dExpr) {
+  public Boolean visitDoubleConstant(DoubleExpression dExpr, ErrorCollector 
errors) {
     return true;
   }
 
   @Override
-  public Boolean visitBooleanConstant(BooleanExpression e) {
+  public Boolean visitBooleanConstant(BooleanExpression e, ErrorCollector 
errors) {
     return true;
   }
 
   @Override
-  public Boolean visitQuotedStringConstant(QuotedString e) {
+  public Boolean visitQuotedStringConstant(QuotedString e, ErrorCollector 
errors) {
     return true;
   }
 
   @Override
-  public Boolean visitUnknown(LogicalExpression e, Void value) throws 
RuntimeException {
+  public Boolean visitUnknown(LogicalExpression e, ErrorCollector errors){
     return false;
   }
-       
-  
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationError.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationError.java
 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationError.java
new file mode 100644
index 0000000..e905638
--- /dev/null
+++ 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationError.java
@@ -0,0 +1,31 @@
+/**
+ * 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.drill.common.expression.visitors;
+
+public class ExpressionValidationError {
+    String message;
+
+    public ExpressionValidationError(String message) {
+        this.message = message;
+    }
+
+    @Override
+    public String toString() {
+        return message;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationException.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationException.java
 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationException.java
new file mode 100644
index 0000000..3d944da
--- /dev/null
+++ 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidationException.java
@@ -0,0 +1,38 @@
+/**
+ * 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.drill.common.expression.visitors;
+
+public class ExpressionValidationException extends RuntimeException {
+
+  public ExpressionValidationException() {
+    super();
+  }
+
+  public ExpressionValidationException(String arg0, Throwable arg1) {
+    super(arg0, arg1);
+  }
+
+  public ExpressionValidationException(String arg0) {
+    super(arg0);
+  }
+
+  public ExpressionValidationException(Throwable arg0) {
+    super(arg0);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidator.java
----------------------------------------------------------------------
diff --git 
a/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidator.java
 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidator.java
new file mode 100644
index 0000000..396517a
--- /dev/null
+++ 
b/common/src/main/java/org/apache/drill/common/expression/visitors/ExpressionValidator.java
@@ -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.drill.common.expression.visitors;
+
+import org.apache.drill.common.expression.ErrorCollector;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.FunctionHolderExpression;
+import org.apache.drill.common.expression.IfExpression;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.expression.ValueExpressions;
+import org.apache.drill.common.expression.IfExpression.IfCondition;
+import org.apache.drill.common.expression.ValueExpressions.BooleanExpression;
+import org.apache.drill.common.expression.ValueExpressions.DoubleExpression;
+import org.apache.drill.common.expression.ValueExpressions.FloatExpression;
+import org.apache.drill.common.expression.ValueExpressions.IntExpression;
+import org.apache.drill.common.expression.ValueExpressions.LongExpression;
+import org.apache.drill.common.expression.ValueExpressions.QuotedString;
+import org.apache.drill.common.types.TypeProtos.DataMode;
+import org.apache.drill.common.types.TypeProtos.MajorType;
+import org.apache.drill.common.types.TypeProtos.MinorType;
+
+public class ExpressionValidator implements ExprVisitor<Void, ErrorCollector, 
RuntimeException> {
+  static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(ExpressionValidator.class);
+
+  @Override
+  public Void visitFunctionCall(FunctionCall call, ErrorCollector errors) 
throws RuntimeException {
+    // we throw an exception here because this is a fundamental operator 
programming problem as opposed to an expression
+    // problem. At this point in an expression's lifecycle, all function calls 
should have been converted into
+    // FunctionHolders.
+    throw new UnsupportedOperationException("FunctionCall is not expected 
here. "
+        + "It should have been converted to FunctionHolderExpression in 
materialization");
+  }
+
+  @Override
+  public Void visitFunctionHolderExpression(FunctionHolderExpression holder, 
ErrorCollector errors)
+      throws RuntimeException {
+    // make sure aggregate functions are not nested inside aggregate functions
+    AggregateChecker.isAggregating(holder);
+
+    // make sure arguments are constant if the function implementation expects 
constants for any arguments
+    ConstantChecker.checkConstants(holder, errors);
+
+    return null;
+  }
+
+  @Override
+  public Void visitIfExpression(IfExpression ifExpr, ErrorCollector errors) 
throws RuntimeException {
+    // confirm that all conditions are required boolean values.
+    int i = 0;
+    for (IfCondition c : ifExpr.conditions) {
+      MajorType mt = c.condition.getMajorType();
+      if (mt.getMode() != DataMode.REQUIRED || mt.getMinorType() != 
MinorType.BIT) {
+        errors
+            .addGeneralError(
+                c.condition.getPosition(),
+                String
+                    .format(
+                        "Failure composing If Expression.  All conditions must 
return a required value and be of type boolean.  Condition %d was DatMode %s 
and Type %s.",
+                        i, mt.getMode(), mt.getMinorType()));
+      }
+      i++;
+    }
+
+    // confirm that all outcomes are the same type.
+    final MajorType mt = ifExpr.elseExpression.getMajorType();
+    i = 0;
+    for (IfCondition c : ifExpr.conditions) {
+      MajorType innerT = c.expression.getMajorType();
+      if ((innerT.getMode() == DataMode.REPEATED && mt.getMode() != 
DataMode.REPEATED) || //
+          (innerT.getMinorType() != mt.getMinorType())) {
+        errors
+            .addGeneralError(
+                c.condition.getPosition(),
+                String
+                    .format(
+                        "Failure composing If Expression.  All expressions 
must return the same MajorType as the else expression.  The %d if condition 
returned type type %s but the else expression was of type %s",
+                        i, innerT, mt));
+      }
+      i++;
+    }
+    return null;
+  }
+
+  @Override
+  public Void visitSchemaPath(SchemaPath path, ErrorCollector errors) throws 
RuntimeException {
+    return null;
+  }
+
+  @Override
+  public Void visitIntConstant(ValueExpressions.IntExpression intExpr, 
ErrorCollector value) throws RuntimeException {
+    return null;
+  }
+
+  @Override
+  public Void visitFloatConstant(ValueExpressions.FloatExpression fExpr, 
ErrorCollector value) throws RuntimeException {
+    return null;
+  }
+
+  @Override
+  public Void visitLongConstant(LongExpression intExpr, ErrorCollector errors) 
throws RuntimeException {
+    return null;
+  }
+
+  @Override
+  public Void visitDoubleConstant(DoubleExpression dExpr, ErrorCollector 
errors) throws RuntimeException {
+    return null;
+  }
+
+  @Override
+  public Void visitBooleanConstant(BooleanExpression e, ErrorCollector errors) 
throws RuntimeException {
+    return null;
+  }
+
+  @Override
+  public Void visitQuotedStringConstant(QuotedString e, ErrorCollector errors) 
throws RuntimeException {
+    return null;
+  }
+
+  @Override
+  public Void visitUnknown(LogicalExpression e, ErrorCollector value) throws 
RuntimeException {
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/common/src/main/java/org/apache/drill/common/util/PathScanner.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/drill/common/util/PathScanner.java 
b/common/src/main/java/org/apache/drill/common/util/PathScanner.java
index 21aaf48..65dcf23 100644
--- a/common/src/main/java/org/apache/drill/common/util/PathScanner.java
+++ b/common/src/main/java/org/apache/drill/common/util/PathScanner.java
@@ -79,6 +79,7 @@ public class PathScanner {
       Set<Class<? extends T>> classes = 
getReflections().getSubTypesOf(baseClass);
       for(Iterator<Class<? extends T>> i = classes.iterator(); i.hasNext();){
         Class<? extends T> c = i.next();
+        assert baseClass.isAssignableFrom(c);
         if(Modifier.isAbstract(c.getModifiers())) i.remove();
       }
       return classes;

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
index 82f45c0..def54d9 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
@@ -21,7 +21,6 @@ import java.util.List;
 
 import org.apache.drill.common.expression.ErrorCollector;
 import org.apache.drill.common.expression.ExpressionPosition;
-import org.apache.drill.common.expression.ExpressionValidator;
 import org.apache.drill.common.expression.FunctionCall;
 import org.apache.drill.common.expression.FunctionHolderExpression;
 import org.apache.drill.common.expression.IfExpression;
@@ -36,6 +35,7 @@ import 
org.apache.drill.common.expression.ValueExpressions.IntExpression;
 import org.apache.drill.common.expression.ValueExpressions.QuotedString;
 import org.apache.drill.common.expression.fn.CastFunctions;
 import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.drill.common.expression.visitors.ExpressionValidator;
 import org.apache.drill.common.types.TypeProtos;
 import org.apache.drill.common.types.TypeProtos.MinorType;
 import org.apache.drill.common.types.Types;

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFunctionImplementationRegistry.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFunctionImplementationRegistry.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFunctionImplementationRegistry.java
index c78895e..64ceef5 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFunctionImplementationRegistry.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFunctionImplementationRegistry.java
@@ -40,8 +40,7 @@ public class DrillFunctionImplementationRegistry {
       if(holder != null){
         // register handle for each name the function can be referred to
         String[] names = holder.getRegisteredNames();
-        for(String name : names)
-          methods.put(name, holder);
+        for(String name : names) methods.put(name, holder);
       }else{
         logger.warn("Unable to initialize function for class {}", 
clazz.getName());
       }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/693bd353/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/HiveFunctionImplementationRegistry.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/HiveFunctionImplementationRegistry.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/HiveFunctionImplementationRegistry.java
index 0c19a08..634b24f 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/HiveFunctionImplementationRegistry.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/HiveFunctionImplementationRegistry.java
@@ -38,11 +38,11 @@ import 
org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
 import com.google.common.collect.ArrayListMultimap;
 
 public class HiveFunctionImplementationRegistry {
-  static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(DrillFunctionImplementationRegistry.class);
+  static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(HiveFunctionImplementationRegistry.class);
 
   private ArrayListMultimap<String, Class<? extends GenericUDF>> 
methodsGenericUDF = ArrayListMultimap.create();
   private ArrayListMultimap<String, Class<? extends UDF>> methodsUDF = 
ArrayListMultimap.create();
-  private HashSet<Class> nonDeterministicUDFs = new HashSet<>();
+  private HashSet<Class<?>> nonDeterministicUDFs = new HashSet<>();
 
   /**
    * Scan the classpath for implementation of GenericUDF/UDF interfaces,
@@ -62,20 +62,20 @@ public class HiveFunctionImplementationRegistry {
 
   private <C,I> void register(Class<? extends I> clazz, 
ArrayListMultimap<String,Class<? extends I>> methods) {
     Description desc = clazz.getAnnotation(Description.class);
-    if (desc != null) {
-      // if the function is non-deterministic add it to the list
-      UDFType type = clazz.getAnnotation(UDFType.class);
-      if (type != null && type.deterministic())
-        nonDeterministicUDFs.add(clazz);
-
-      String[] names = desc.name().split(",");
-      for(int i=0; i<names.length; i++)
-        names[i] = names[i].trim();
-
-      for(int i=0; i<names.length;i++)
-        methods.put(names[i], clazz);
-    } else {
-      logger.warn("Unable to initialize function for class {}", 
clazz.getName());
+    String[] names;
+    if(desc != null){
+      names = desc.name().split(",");
+      for(int i=0; i<names.length; i++) names[i] = names[i].trim();
+    }else{
+      names = new String[]{clazz.getName().replace('.', '_')};
+    }
+    
+    UDFType type = clazz.getAnnotation(UDFType.class);
+    if (type != null && type.deterministic()) nonDeterministicUDFs.add(clazz);
+
+
+    for(int i=0; i<names.length;i++){
+      methods.put(names[i], clazz);
     }
   }
 

Reply via email to