tajo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hyun...@apache.org
Subject [1/3] TAJO-1092: Improve the function system to allow other function implementation types.
Date Wed, 15 Oct 2014 17:41:38 GMT
Repository: tajo
Updated Branches:
  refs/heads/block_iteration 5eb7ee1fd -> 05ca386c4


http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/main/java/org/apache/tajo/master/TajoMaster.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMaster.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMaster.java
index 7fec037..f267921 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMaster.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMaster.java
@@ -37,13 +37,9 @@ import org.apache.hadoop.yarn.util.Clock;
 import org.apache.hadoop.yarn.util.RackResolver;
 import org.apache.hadoop.yarn.util.SystemClock;
 import org.apache.tajo.catalog.*;
-import org.apache.tajo.catalog.function.Function;
-import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.engine.function.FunctionLoader;
 import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.conf.TajoConf.ConfVars;
-import org.apache.tajo.engine.function.annotation.Description;
-import org.apache.tajo.engine.function.annotation.ParamOptionTypes;
-import org.apache.tajo.engine.function.annotation.ParamTypes;
 import org.apache.tajo.master.ha.HAService;
 import org.apache.tajo.master.ha.HAServiceHDFSImpl;
 import org.apache.tajo.master.metrics.CatalogMetricsGaugeSet;
@@ -65,11 +61,9 @@ import java.lang.management.ManagementFactory;
 import java.lang.management.ThreadInfo;
 import java.lang.management.ThreadMXBean;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
 import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 
 import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
 import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
@@ -168,7 +162,7 @@ public class TajoMaster extends CompositeService {
       checkAndInitializeSystemDirectories();
       this.storeManager = StorageManagerFactory.getStorageManager(systemConf);
 
-      catalogServer = new CatalogServer(initBuiltinFunctions());
+      catalogServer = new CatalogServer(FunctionLoader.load());
       addIfService(catalogServer);
       catalog = new LocalCatalogWrapper(catalogServer, systemConf);
 
@@ -279,81 +273,6 @@ public class TajoMaster extends CompositeService {
     }
   }
 
-  @SuppressWarnings("unchecked")
-  public static List<FunctionDesc> initBuiltinFunctions() throws ServiceException {
-    List<FunctionDesc> sqlFuncs = new ArrayList<FunctionDesc>();
-
-    Set<Class> functionClasses = ClassUtil.findClasses(org.apache.tajo.catalog.function.Function.class,
-          "org.apache.tajo.engine.function");
-
-    for (Class eachClass : functionClasses) {
-      if(eachClass.isInterface() || Modifier.isAbstract(eachClass.getModifiers())) {
-        continue;
-      }
-      Function function = null;
-      try {
-        function = (Function)eachClass.newInstance();
-      } catch (Exception e) {
-        LOG.warn(eachClass + " cannot instantiate Function class because of " + e.getMessage());
-        continue;
-      }
-      String functionName = function.getClass().getAnnotation(Description.class).functionName();
-      String[] synonyms = function.getClass().getAnnotation(Description.class).synonyms();
-      String description = function.getClass().getAnnotation(Description.class).description();
-      String detail = function.getClass().getAnnotation(Description.class).detail();
-      String example = function.getClass().getAnnotation(Description.class).example();
-      Type returnType = function.getClass().getAnnotation(Description.class).returnType();
-      ParamTypes[] paramArray = function.getClass().getAnnotation(Description.class).paramTypes();
-
-      String[] allFunctionNames = null;
-      if(synonyms != null && synonyms.length > 0) {
-        allFunctionNames = new String[1 + synonyms.length];
-        allFunctionNames[0] = functionName;
-        System.arraycopy(synonyms, 0, allFunctionNames, 1, synonyms.length);
-      } else {
-        allFunctionNames = new String[]{functionName};
-      }
-
-      for(String eachFunctionName: allFunctionNames) {
-        for (ParamTypes params : paramArray) {
-          ParamOptionTypes[] paramOptionArray;
-          if(params.paramOptionTypes() == null ||
-              params.paramOptionTypes().getClass().getAnnotation(ParamTypes.class) == null)
{
-            paramOptionArray = new ParamOptionTypes[0];
-          } else {
-            paramOptionArray = params.paramOptionTypes().getClass().getAnnotation(ParamTypes.class).paramOptionTypes();
-          }
-
-          Type[] paramTypes = params.paramTypes();
-          if (paramOptionArray.length > 0)
-            paramTypes = params.paramTypes().clone();
-
-          for (int i=0; i < paramOptionArray.length + 1; i++) {
-            FunctionDesc functionDesc = new FunctionDesc(eachFunctionName,
-                function.getClass(), function.getFunctionType(),
-                CatalogUtil.newSimpleDataType(returnType),
-                paramTypes.length == 0 ? CatalogUtil.newSimpleDataTypeArray() : CatalogUtil.newSimpleDataTypeArray(paramTypes));
-
-            functionDesc.setDescription(description);
-            functionDesc.setExample(example);
-            functionDesc.setDetail(detail);
-            sqlFuncs.add(functionDesc);
-
-            if (i != paramOptionArray.length) {
-              paramTypes = new Type[paramTypes.length +
-                  paramOptionArray[i].paramOptionTypes().length];
-              System.arraycopy(params.paramTypes(), 0, paramTypes, 0, paramTypes.length);
-              System.arraycopy(paramOptionArray[i].paramOptionTypes(), 0, paramTypes, paramTypes.length,
-                  paramOptionArray[i].paramOptionTypes().length);
-            }
-          }
-        }
-      }
-    }
-
-    return sqlFuncs;
-  }
-
   private void startJvmPauseMonitor(){
     pauseMonitor = new JvmPauseMonitor(systemConf);
     pauseMonitor.start();

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
index 65bde27..a4688d9 100644
--- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
+++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java
@@ -57,7 +57,6 @@ import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.StringProto;
 import org.apache.tajo.util.KeyValueSet;
 import org.apache.tajo.util.NetUtils;
 import org.apache.tajo.util.ProtoUtil;
-import org.apache.tajo.util.StringUtils;
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
@@ -814,7 +813,7 @@ public class TajoMasterClientService extends AbstractService {
           if (functionName == null || functionName.isEmpty()) {
             functionProtos.add(eachFunction.getProto());
           } else {
-            if(functionName.equals(eachFunction.getSignature())) {
+            if(functionName.equals(eachFunction.getFunctionName())) {
               functionProtos.add(eachFunction.getProto());
             }
           }

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/main/java/org/apache/tajo/util/ClassUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/util/ClassUtil.java b/tajo-core/src/main/java/org/apache/tajo/util/ClassUtil.java
deleted file mode 100644
index f59ec3f..0000000
--- a/tajo-core/src/main/java/org/apache/tajo/util/ClassUtil.java
+++ /dev/null
@@ -1,156 +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.tajo.util;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.io.File;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-public abstract class ClassUtil {
-  private static final Log LOG = LogFactory.getLog(ClassUtil.class);
-
-  public static Set<Class> findClasses(Class type, String packageFilter) {
-    Set<Class> classSet = new HashSet<Class>();
-
-    String classpath = System.getProperty("java.class.path");
-    String[] paths = classpath.split(System.getProperty("path.separator"));
-
-    for (String path : paths) {
-      File file = new File(path);
-      if (file.exists()) {
-        findClasses(classSet, file, file, true, type, packageFilter);
-      }
-    }
-
-    return classSet;
-  }
-
-  private static void findClasses(Set<Class> matchedClassSet, File root, File file,
boolean includeJars, Class type,
-                                  String packageFilter) {
-    if (file.isDirectory()) {
-      for (File child : file.listFiles()) {
-        findClasses(matchedClassSet, root, child, includeJars, type, packageFilter);
-      }
-    } else {
-      if (file.getName().toLowerCase().endsWith(".jar") && includeJars) {
-        JarFile jar = null;
-        try {
-          jar = new JarFile(file);
-        } catch (Exception ex) {
-          LOG.error(ex.getMessage(), ex);
-          return;
-        }
-        Enumeration<JarEntry> entries = jar.entries();
-        while (entries.hasMoreElements()) {
-          JarEntry entry = entries.nextElement();
-          String name = entry.getName();
-          int extIndex = name.lastIndexOf(".class");
-          if (extIndex > 0) {
-            String qualifiedClassName = name.substring(0, extIndex).replace("/", ".");
-            if (qualifiedClassName.indexOf(packageFilter) >= 0 && !isTestClass(qualifiedClassName))
{
-              try {
-                Class clazz = Class.forName(qualifiedClassName);
-
-                if (!clazz.isInterface() && isMatch(type, clazz)) {
-                  matchedClassSet.add(clazz);
-                }
-              } catch (ClassNotFoundException e) {
-                LOG.error(e.getMessage(), e);
-              }
-            }
-          }
-        }
-      } else if (file.getName().toLowerCase().endsWith(".class")) {
-        String qualifiedClassName = createClassName(root, file);
-        if (qualifiedClassName.indexOf(packageFilter) >= 0 && !isTestClass(qualifiedClassName))
{
-          try {
-            Class clazz = Class.forName(qualifiedClassName);
-            if (!clazz.isInterface() && isMatch(type, clazz)) {
-              matchedClassSet.add(clazz);
-            }
-          } catch (ClassNotFoundException e) {
-            LOG.error(e.getMessage(), e);
-          }
-        }
-      }
-    }
-  }
-
-  private static boolean isTestClass(String qualifiedClassName) {
-    String className = getSimpleClassName(qualifiedClassName);
-    if(className == null) {
-      return false;
-    }
-
-    return className.startsWith("Test");
-  }
-
-  private static boolean isMatch(Class targetClass, Class loadedClass) {
-    if (targetClass.equals(loadedClass)) {
-      return true;
-    }
-
-    Class[] classInterfaces = loadedClass.getInterfaces();
-    if (classInterfaces != null) {
-      for (Class eachInterfaceClass : classInterfaces) {
-        if (eachInterfaceClass.equals(targetClass)) {
-          return true;
-        }
-
-        if (isMatch(targetClass, eachInterfaceClass)) {
-          return true;
-        }
-      }
-    }
-
-    Class superClass = loadedClass.getSuperclass();
-    if (superClass != null) {
-      if (isMatch(targetClass, superClass)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private static String getSimpleClassName(String qualifiedClassName) {
-    String[] tokens = qualifiedClassName.split("\\.");
-    if (tokens.length == 0) {
-      return qualifiedClassName;
-    }
-    return tokens[tokens.length - 1];
-  }
-
-  private static String createClassName(File root, File file) {
-    StringBuffer sb = new StringBuffer();
-    String fileName = file.getName();
-    sb.append(fileName.substring(0, fileName.lastIndexOf(".class")));
-    file = file.getParentFile();
-    while (file != null && !file.equals(root)) {
-      sb.insert(0, '.').insert(0, file.getName());
-      file = file.getParentFile();
-    }
-    return sb.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/main/java/org/apache/tajo/util/JSPUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/java/org/apache/tajo/util/JSPUtil.java b/tajo-core/src/main/java/org/apache/tajo/util/JSPUtil.java
index fb7ba26..9d0dcaa 100644
--- a/tajo-core/src/main/java/org/apache/tajo/util/JSPUtil.java
+++ b/tajo-core/src/main/java/org/apache/tajo/util/JSPUtil.java
@@ -208,7 +208,7 @@ public class JSPUtil {
     Collections.sort(functions, new java.util.Comparator<FunctionDesc>() {
       @Override
       public int compare(FunctionDesc f1, FunctionDesc f2) {
-        int nameCompared = f1.getSignature().compareTo(f2.getSignature());
+        int nameCompared = f1.getFunctionName().compareTo(f2.getFunctionName());
         if(nameCompared != 0) {
           return nameCompared;
         } else {

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/main/resources/webapps/admin/functions.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/functions.jsp b/tajo-core/src/main/resources/webapps/admin/functions.jsp
index 68e127b..c805aaa 100644
--- a/tajo-core/src/main/resources/webapps/admin/functions.jsp
+++ b/tajo-core/src/main/resources/webapps/admin/functions.jsp
@@ -62,7 +62,7 @@
         }
 %>
         <tr>
-            <td><%=eachFunction.getSignature()%></td>
+            <td><%=eachFunction.getFunctionName()%></td>
             <td><%=eachFunction.getHelpSignature()%></td>
             <td><%=eachFunction.getFuncType()%></td>
             <td><%=HtmlQuoting.quoteHtmlChars(fullDecription).replace("\n", "<br/>")%></td>

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java b/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java
index 4d9ca67..805fe06 100644
--- a/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java
+++ b/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java
@@ -18,9 +18,11 @@
 
 package org.apache.tajo;
 
+import com.google.common.base.Preconditions;
 import com.google.protobuf.ServiceException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.security.UserGroupInformation;
@@ -34,10 +36,13 @@ import org.apache.tajo.engine.planner.global.MasterPlan;
 import org.apache.tajo.engine.query.QueryContext;
 import org.apache.tajo.master.session.Session;
 import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.util.FileUtil;
 import org.apache.tajo.util.KeyValueSet;
 import org.apache.tajo.util.TajoIdUtils;
 
+import java.io.File;
 import java.io.IOException;
+import java.net.URL;
 import java.sql.ResultSet;
 import java.util.UUID;
 
@@ -143,4 +148,20 @@ public class LocalTajoTestingUtility {
       util.shutdownMiniCluster();
     }
   }
+
+  public static Path getResourcePath(String path, String suffix) {
+    URL resultBaseURL = ClassLoader.getSystemResource(path);
+    return new Path(resultBaseURL.toString(), suffix);
+  }
+
+  public static Path getResultPath(Class clazz, String fileName) {
+    return new Path (getResourcePath("results", clazz.getSimpleName()), fileName);
+  }
+
+  public static String getResultText(Class clazz, String fileName) throws IOException {
+    FileSystem localFS = FileSystem.getLocal(new Configuration());
+    Path path = getResultPath(clazz, fileName);
+    Preconditions.checkState(localFS.exists(path) && localFS.isFile(path));
+    return FileUtil.readTextFile(new File(path.toUri()));
+  }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java
index 2e69666..4ede88e 100644
--- a/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java
+++ b/tajo-core/src/test/java/org/apache/tajo/client/TestTajoClient.java
@@ -585,7 +585,7 @@ public class TestTajoClient {
     String functionName = "sum";
     int numFunctions = 0;
     for(FunctionDesc eachFunction: catalogFunctions) {
-      if(functionName.equals(eachFunction.getSignature())) {
+      if(functionName.equals(eachFunction.getFunctionName())) {
         numFunctions++;
       }
     }

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
index 92cd218..0805cb9 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/ExprTestBase.java
@@ -34,6 +34,7 @@ import org.apache.tajo.datum.*;
 import org.apache.tajo.engine.codegen.EvalCodeGenerator;
 import org.apache.tajo.engine.codegen.EvalNodeCompiler;
 import org.apache.tajo.engine.codegen.TajoClassLoader;
+import org.apache.tajo.engine.function.FunctionLoader;
 import org.apache.tajo.engine.json.CoreGsonHelper;
 import org.apache.tajo.engine.parser.SQLAnalyzer;
 import org.apache.tajo.engine.plan.EvalTreeProtoDeserializer;
@@ -85,7 +86,7 @@ public class ExprTestBase {
     cat = util.getMiniCatalogCluster().getCatalog();
     cat.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");
     cat.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
-    for (FunctionDesc funcDesc : TajoMaster.initBuiltinFunctions()) {
+    for (FunctionDesc funcDesc : FunctionLoader.load()) {
       cat.createFunction(funcDesc);
     }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
index 50fd66d..222b8e1 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/eval/TestEvalTreeUtil.java
@@ -31,6 +31,7 @@ import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
 import org.apache.tajo.common.TajoDataTypes;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.engine.function.FunctionLoader;
 import org.apache.tajo.engine.function.GeneralFunction;
 import org.apache.tajo.engine.optimizer.eval.EvalTreeOptimizer;
 import org.apache.tajo.engine.parser.SQLAnalyzer;
@@ -93,7 +94,7 @@ public class TestEvalTreeUtil {
     util = new TajoTestingCluster();
     util.startCatalogCluster();
     catalog = util.getMiniCatalogCluster().getCatalog();
-    for (FunctionDesc funcDesc : TajoMaster.initBuiltinFunctions()) {
+    for (FunctionDesc funcDesc : FunctionLoader.findLegacyFunctions()) {
       catalog.createFunction(funcDesc);
     }
     catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/engine/function/TestFunctionLoader.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestFunctionLoader.java
b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestFunctionLoader.java
new file mode 100644
index 0000000..32b98dd
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestFunctionLoader.java
@@ -0,0 +1,46 @@
+/***
+ * 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.tajo.engine.function;
+
+import com.google.common.collect.Lists;
+import org.apache.tajo.catalog.FunctionDesc;
+import org.apache.tajo.function.FunctionSignature;
+import org.apache.tajo.util.TUtil;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import static org.apache.tajo.LocalTajoTestingUtility.getResultText;
+import static org.junit.Assert.assertEquals;
+
+
+public class TestFunctionLoader {
+
+  @Test
+  public void testFindScalarFunctions() throws IOException {
+    List<FunctionDesc> collections = Lists.newArrayList(FunctionLoader.findScalarFunctions());
+    Collections.sort(collections);
+    String functionList = TUtil.collectionToString(collections, "\n");
+
+    String result = getResultText(TestFunctionLoader.class, "testFindScalarFunctions.result");
+    assertEquals(result.trim(), functionList.trim());
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
index e54c40c..49ef7e0 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
@@ -397,6 +397,8 @@ public class TestMathFunctions extends ExprTestBase {
     testSimpleEval("select pow(9,3) as col1 ", new String[]{String.valueOf(Math.pow(9,3))});
     testSimpleEval("select pow(1.0,3) as col1 ", new String[]{String.valueOf(Math.pow(1.0,3))});
     testSimpleEval("select pow(20.1,3.1) as col1 ", new String[]{String.valueOf(Math.pow(20.1,3.1))});
+    testSimpleEval("select pow(null,3.1) as col1 ", new String[]{""});
+    testSimpleEval("select pow(20.1,null) as col1 ", new String[]{""});
 
     Schema schema = new Schema();
     schema.addColumn("col1", FLOAT4);

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestExprAnnotator.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestExprAnnotator.java
b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestExprAnnotator.java
index 682a366..bd88cd6 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestExprAnnotator.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestExprAnnotator.java
@@ -28,19 +28,19 @@ public class TestExprAnnotator {
   @Test
   public void testGetWidestType() throws Exception {
     assertEquals(Type.INT1,
-        ExprAnnotator.getWidestType(CatalogUtil.newSimpleDataType(Type.INT1)).getType());
+        CatalogUtil.getWidestType(CatalogUtil.newSimpleDataType(Type.INT1)).getType());
     assertEquals(Type.INT2,
-        ExprAnnotator.getWidestType(CatalogUtil.newSimpleDataTypeArray(Type.INT1, Type.INT2)).getType());
+        CatalogUtil.getWidestType(CatalogUtil.newSimpleDataTypeArray(Type.INT1, Type.INT2)).getType());
     assertEquals(Type.INT4,
-        ExprAnnotator.getWidestType(CatalogUtil.newSimpleDataTypeArray(Type.INT1, Type.INT2,
Type.INT4)).getType());
+        CatalogUtil.getWidestType(CatalogUtil.newSimpleDataTypeArray(Type.INT1, Type.INT2,
Type.INT4)).getType());
     assertEquals(Type.INT8,
-        ExprAnnotator.getWidestType(CatalogUtil.newSimpleDataTypeArray(Type.INT1, Type.INT2,
Type.INT4,
+        CatalogUtil.getWidestType(CatalogUtil.newSimpleDataTypeArray(Type.INT1, Type.INT2,
Type.INT4,
             Type.INT8)).getType());
     assertEquals(Type.FLOAT4,
-        ExprAnnotator.getWidestType(CatalogUtil.newSimpleDataTypeArray(Type.FLOAT4, Type.INT2,
Type.INT4,
+        CatalogUtil.getWidestType(CatalogUtil.newSimpleDataTypeArray(Type.FLOAT4, Type.INT2,
Type.INT4,
             Type.INT8)).getType());
     assertEquals(Type.FLOAT8,
-        ExprAnnotator.getWidestType(CatalogUtil.newSimpleDataTypeArray(Type.FLOAT4, Type.FLOAT8,
Type.INT4,
+        CatalogUtil.getWidestType(CatalogUtil.newSimpleDataTypeArray(Type.FLOAT4, Type.FLOAT8,
Type.INT4,
             Type.INT8)).getType());
   }
 }

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalOptimizer.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalOptimizer.java
b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalOptimizer.java
index 82e7f21..0e4a9ce 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalOptimizer.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalOptimizer.java
@@ -26,6 +26,7 @@ import org.apache.tajo.catalog.*;
 import org.apache.tajo.catalog.proto.CatalogProtos.FunctionType;
 import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
 import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.engine.function.FunctionLoader;
 import org.apache.tajo.engine.function.builtin.SumInt;
 import org.apache.tajo.engine.parser.SQLAnalyzer;
 import org.apache.tajo.engine.planner.logical.*;
@@ -57,7 +58,7 @@ public class TestLogicalOptimizer {
     catalog = util.getMiniCatalogCluster().getCatalog();
     catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");
     catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
-    for (FunctionDesc funcDesc : TajoMaster.initBuiltinFunctions()) {
+    for (FunctionDesc funcDesc : FunctionLoader.findLegacyFunctions()) {
       catalog.createFunction(funcDesc);
     }
     

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
index 73f72be..57e0e50 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java
@@ -33,6 +33,7 @@ import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
 import org.apache.tajo.common.TajoDataTypes.Type;
 import org.apache.tajo.datum.TextDatum;
 import org.apache.tajo.engine.eval.*;
+import org.apache.tajo.engine.function.FunctionLoader;
 import org.apache.tajo.engine.function.builtin.SumInt;
 import org.apache.tajo.engine.json.CoreGsonHelper;
 import org.apache.tajo.engine.parser.SQLAnalyzer;
@@ -73,7 +74,7 @@ public class TestLogicalPlanner {
     catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234");
     catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
 
-    for (FunctionDesc funcDesc : TajoMaster.initBuiltinFunctions()) {
+    for (FunctionDesc funcDesc : FunctionLoader.findLegacyFunctions()) {
       catalog.createFunction(funcDesc);
     }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/engine/planner/global/TestBroadcastJoinPlan.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/planner/global/TestBroadcastJoinPlan.java
b/tajo-core/src/test/java/org/apache/tajo/engine/planner/global/TestBroadcastJoinPlan.java
index 4beb5c5..f1122ce 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/planner/global/TestBroadcastJoinPlan.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/planner/global/TestBroadcastJoinPlan.java
@@ -34,6 +34,7 @@ import org.apache.tajo.conf.TajoConf;
 import org.apache.tajo.datum.Datum;
 import org.apache.tajo.datum.DatumFactory;
 import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.engine.function.FunctionLoader;
 import org.apache.tajo.engine.parser.SQLAnalyzer;
 import org.apache.tajo.engine.planner.LogicalOptimizer;
 import org.apache.tajo.engine.planner.LogicalPlan;
@@ -87,7 +88,7 @@ public class TestBroadcastJoinPlan {
     catalog = util.startCatalogCluster().getCatalog();
     catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
     catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
-    util.getMiniCatalogCluster().getCatalogServer().reloadBuiltinFunctions(TajoMaster.initBuiltinFunctions());
+    util.getMiniCatalogCluster().getCatalogServer().reloadBuiltinFunctions(FunctionLoader.findLegacyFunctions());
 
     Schema smallTable1Schema = new Schema();
     smallTable1Schema.addColumn("small1_id", TajoDataTypes.Type.INT4);

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
b/tajo-core/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
index 7a350ce..915cd65 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/planner/physical/TestPhysicalPlanner.java
@@ -37,6 +37,7 @@ import org.apache.tajo.datum.Datum;
 import org.apache.tajo.datum.DatumFactory;
 import org.apache.tajo.datum.NullDatum;
 import org.apache.tajo.engine.eval.AggregationFunctionCallEval;
+import org.apache.tajo.engine.function.FunctionLoader;
 import org.apache.tajo.engine.parser.SQLAnalyzer;
 import org.apache.tajo.engine.planner.*;
 import org.apache.tajo.engine.planner.enforce.Enforcer;
@@ -105,7 +106,7 @@ public class TestPhysicalPlanner {
     catalog = util.getMiniCatalogCluster().getCatalog();
     catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
     catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
-    for (FunctionDesc funcDesc : TajoMaster.initBuiltinFunctions()) {
+    for (FunctionDesc funcDesc : FunctionLoader.findLegacyFunctions()) {
       catalog.createFunction(funcDesc);
     }
 

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/java/org/apache/tajo/master/TestGlobalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/master/TestGlobalPlanner.java b/tajo-core/src/test/java/org/apache/tajo/master/TestGlobalPlanner.java
index a92b751..167c1f6 100644
--- a/tajo-core/src/test/java/org/apache/tajo/master/TestGlobalPlanner.java
+++ b/tajo-core/src/test/java/org/apache/tajo/master/TestGlobalPlanner.java
@@ -32,6 +32,7 @@ import org.apache.tajo.common.TajoDataTypes;
 import org.apache.tajo.engine.eval.BinaryEval;
 import org.apache.tajo.engine.eval.EvalType;
 import org.apache.tajo.engine.eval.FieldEval;
+import org.apache.tajo.engine.function.FunctionLoader;
 import org.apache.tajo.engine.parser.SQLAnalyzer;
 import org.apache.tajo.engine.planner.*;
 import org.apache.tajo.engine.planner.global.DataChannel;
@@ -72,7 +73,7 @@ public class TestGlobalPlanner {
     util = new TajoTestingCluster();
     util.startCatalogCluster();
     catalog = util.getMiniCatalogCluster().getCatalog();
-    for (FunctionDesc funcDesc : TajoMaster.initBuiltinFunctions()) {
+    for (FunctionDesc funcDesc : FunctionLoader.findLegacyFunctions()) {
       catalog.createFunction(funcDesc);
     }
     catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:1234/warehouse");

http://git-wip-us.apache.org/repos/asf/tajo/blob/05ca386c/tajo-core/src/test/resources/results/TestFunctionLoader/testFindScalarFunctions.result
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/resources/results/TestFunctionLoader/testFindScalarFunctions.result
b/tajo-core/src/test/resources/results/TestFunctionLoader/testFindScalarFunctions.result
new file mode 100644
index 0000000..ac2408d
--- /dev/null
+++ b/tajo-core/src/test/resources/results/TestFunctionLoader/testFindScalarFunctions.result
@@ -0,0 +1,2 @@
+float8 pi()
+float8 pow(float8,float8)
\ No newline at end of file


Mime
View raw message