Repository: calcite
Updated Branches:
  refs/heads/master a2d7165f3 -> 94051eaed


[CALCITE-991] Create separate SqlFunctionCategory values for table functions 
and macros (Julien Le Dem, Minji Kim)

Add a simple test for CalciteCatalogReader (Minji Kim).

Fix up (Julian Hyde).

Close apache/calcite#168


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/0599cdde
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/0599cdde
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/0599cdde

Branch: refs/heads/master
Commit: 0599cdde009d6e08f0cb973f914b526f9518dc47
Parents: a2d7165
Author: Julien Le Dem <[email protected]>
Authored: Sun Mar 13 22:06:30 2016 -0700
Committer: Julian Hyde <[email protected]>
Committed: Tue Jun 14 18:02:58 2016 -0700

----------------------------------------------------------------------
 core/src/main/codegen/templates/Parser.jj       |   4 +-
 .../calcite/prepare/CalciteCatalogReader.java   |  23 ++-
 .../apache/calcite/rel/externalize/RelJson.java |   6 +-
 .../org/apache/calcite/sql/SqlFunction.java     |   7 +-
 .../apache/calcite/sql/SqlFunctionCategory.java |  66 ++++++-
 .../java/org/apache/calcite/sql/SqlUtil.java    |   3 +-
 .../sql/parser/SqlAbstractParserImpl.java       |   2 +-
 .../calcite/sql/util/ListSqlOperatorTable.java  |  19 +-
 .../apache/calcite/sql/validate/AggFinder.java  |  24 +--
 .../sql/validate/SqlUserDefinedFunction.java    |  15 +-
 .../validate/SqlUserDefinedTableFunction.java   |   3 +-
 .../sql/validate/SqlUserDefinedTableMacro.java  |   2 +-
 .../sql2rel/RelStructuredTypeFlattener.java     |  11 +-
 .../prepare/LookupOperatorOverloadsTest.java    | 174 +++++++++++++++++++
 .../org/apache/calcite/test/CalciteSuite.java   |   2 +
 15 files changed, 308 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/codegen/templates/Parser.jj
----------------------------------------------------------------------
diff --git a/core/src/main/codegen/templates/Parser.jj 
b/core/src/main/codegen/templates/Parser.jj
index bad32b0..d7415cc 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -1928,13 +1928,13 @@ void ColumnType(List<SqlNode> list) :
 SqlNode TableFunctionCall(SqlParserPos pos) :
 {
     SqlNode call;
-    SqlFunctionCategory funcType = SqlFunctionCategory.USER_DEFINED_FUNCTION;
+    SqlFunctionCategory funcType = 
SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION;
 }
 {
     [
         <SPECIFIC>
         {
-            funcType = SqlFunctionCategory.USER_DEFINED_SPECIFIC_FUNCTION;
+            funcType = 
SqlFunctionCategory.USER_DEFINED_TABLE_SPECIFIC_FUNCTION;
         }
     ]
     {

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java 
b/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java
index 68b297e..40299e9 100644
--- a/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java
+++ b/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java
@@ -53,6 +53,7 @@ import org.apache.calcite.sql.validate.SqlValidatorUtil;
 import org.apache.calcite.util.Util;
 
 import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
@@ -232,7 +233,27 @@ public class CalciteCatalogReader implements 
Prepare.CatalogReader {
     if (syntax != SqlSyntax.FUNCTION) {
       return;
     }
-    final Collection<Function> functions = getFunctionsFrom(opName.names);
+
+    final Predicate<Function> predicate;
+    if (category == null) {
+      predicate = Predicates.alwaysTrue();
+    } else if (category.isTableFunction()) {
+      predicate = new Predicate<Function>() {
+        public boolean apply(Function function) {
+          return function instanceof TableMacro
+              || function instanceof TableFunction;
+        }
+      };
+    } else {
+      predicate = new Predicate<Function>() {
+        public boolean apply(Function function) {
+          return !(function instanceof TableMacro
+              || function instanceof TableFunction);
+        }
+      };
+    }
+    final Collection<Function> functions =
+        Collections2.filter(getFunctionsFrom(opName.names), predicate);
     if (functions.isEmpty()) {
       return;
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java 
b/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
index b7ef54a..1b24811 100644
--- a/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
+++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
@@ -339,11 +339,7 @@ public class RelJson {
           map.put("type", toJson(node.getType()));
         }
         if (call.getOperator() instanceof SqlFunction) {
-          switch (((SqlFunction) call.getOperator()).getFunctionType()) {
-          case USER_DEFINED_CONSTRUCTOR:
-          case USER_DEFINED_FUNCTION:
-          case USER_DEFINED_PROCEDURE:
-          case USER_DEFINED_SPECIFIC_FUNCTION:
+          if (((SqlFunction) 
call.getOperator()).getFunctionType().isUserDefined()) {
             map.put("class", call.getOperator().getClass().getName());
           }
         }

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/sql/SqlFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlFunction.java 
b/core/src/main/java/org/apache/calcite/sql/SqlFunction.java
index 3bdc91c..7f9b0f3 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlFunction.java
@@ -26,9 +26,11 @@ import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql.validate.SqlValidatorScope;
 import org.apache.calcite.util.Util;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 import java.util.List;
+import javax.annotation.Nonnull;
 
 import static org.apache.calcite.util.Static.RESOURCE;
 
@@ -121,10 +123,9 @@ public class SqlFunction extends SqlOperator {
         operandTypeChecker);
 
     this.sqlIdentifier = sqlIdentifier;
-    this.category = category;
+    this.category = Preconditions.checkNotNull(category);
     this.paramTypes =
         paramTypes == null ? null : ImmutableList.copyOf(paramTypes);
-    assert category != null;
   }
 
   //~ Methods ----------------------------------------------------------------
@@ -174,7 +175,7 @@ public class SqlFunction extends SqlOperator {
   /**
    * @return function category
    */
-  public SqlFunctionCategory getFunctionType() {
+  @Nonnull public SqlFunctionCategory getFunctionType() {
     return this.category;
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/sql/SqlFunctionCategory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlFunctionCategory.java 
b/core/src/main/java/org/apache/calcite/sql/SqlFunctionCategory.java
index 8c836da..02cd381 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlFunctionCategory.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlFunctionCategory.java
@@ -18,24 +18,72 @@ package org.apache.calcite.sql;
 
 import org.apache.calcite.util.Util;
 
+import static org.apache.calcite.sql.SqlFunctionCategory.Property.FUNCTION;
+import static org.apache.calcite.sql.SqlFunctionCategory.Property.SPECIFIC;
+import static 
org.apache.calcite.sql.SqlFunctionCategory.Property.TABLE_FUNCTION;
+import static org.apache.calcite.sql.SqlFunctionCategory.Property.USER_DEFINED;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+
 /**
  * Enumeration of the categories of
  * SQL-invoked routines.
  */
 public enum SqlFunctionCategory {
-  STRING("STRING", "String function"),
-  NUMERIC("NUMERIC", "Numeric function"),
-  TIMEDATE("TIMEDATE", "Time and date function"),
-  SYSTEM("SYSTEM", "System function"),
-  USER_DEFINED_FUNCTION("UDF", "User-defined function"),
-  USER_DEFINED_PROCEDURE("UDP", "User-defined procedure"),
-  USER_DEFINED_CONSTRUCTOR("UDC", "User-defined constructor"),
+  STRING("STRING", "String function", FUNCTION),
+  NUMERIC("NUMERIC", "Numeric function", FUNCTION),
+  TIMEDATE("TIMEDATE", "Time and date function", FUNCTION),
+  SYSTEM("SYSTEM", "System function", FUNCTION),
+  USER_DEFINED_FUNCTION("UDF", "User-defined function", USER_DEFINED,
+      FUNCTION),
+  USER_DEFINED_PROCEDURE("UDP", "User-defined procedure", USER_DEFINED),
+  USER_DEFINED_CONSTRUCTOR("UDC", "User-defined constructor", USER_DEFINED),
   USER_DEFINED_SPECIFIC_FUNCTION("UDF_SPECIFIC",
-      "User-defined function with SPECIFIC name");
+      "User-defined function with SPECIFIC name", USER_DEFINED, SPECIFIC,
+      FUNCTION),
+  USER_DEFINED_TABLE_FUNCTION("TABLE_UDF", "User-defined table function",
+      USER_DEFINED, TABLE_FUNCTION),
+  USER_DEFINED_TABLE_SPECIFIC_FUNCTION("TABLE_UDF_SPECIFIC",
+      "User-defined table function with SPECIFIC name", USER_DEFINED,
+      TABLE_FUNCTION, SPECIFIC);
 
-  SqlFunctionCategory(String abbrev, String description) {
+  private final EnumSet<Property> properties;
+
+  SqlFunctionCategory(String abbrev, String description,
+      Property... properties) {
     Util.discard(abbrev);
     Util.discard(description);
+    this.properties = EnumSet.copyOf(Arrays.asList(properties));
+  }
+
+  public boolean isUserDefined() {
+    return properties.contains(USER_DEFINED);
+  }
+
+  public boolean isTableFunction() {
+    return properties.contains(TABLE_FUNCTION);
+  }
+
+  public boolean isFunction() {
+    return properties.contains(FUNCTION);
+  }
+
+  public boolean isSpecific() {
+    return properties.contains(SPECIFIC);
+  }
+
+  public boolean isUserDefinedNotSpecificFunction() {
+    return isUserDefined()
+        && (isFunction() || isTableFunction())
+        && !isSpecific();
+  }
+
+  /**
+   * Property of a SqlFunctionCategory.
+   */
+  enum Property {
+    USER_DEFINED, TABLE_FUNCTION, SPECIFIC, FUNCTION
   }
 }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlUtil.java 
b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
index a620f2a..ca8fb27 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java
@@ -263,8 +263,7 @@ public abstract class SqlUtil {
     if (operator instanceof SqlFunction) {
       SqlFunction function = (SqlFunction) operator;
 
-      switch (function.getFunctionType()) {
-      case USER_DEFINED_SPECIFIC_FUNCTION:
+      if (function.getFunctionType().isSpecific()) {
         writer.keyword("SPECIFIC");
       }
       SqlIdentifier id = function.getSqlIdentifier();

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java 
b/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java
index bef5da7..2e0008d 100644
--- 
a/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java
+++ 
b/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java
@@ -363,7 +363,7 @@ public abstract class SqlAbstractParserImpl {
     /// name when regenerating SQL).
     if (funName.isSimple()) {
       final List<SqlOperator> list = Lists.newArrayList();
-      opTab.lookupOperatorOverloads(funName, null, SqlSyntax.FUNCTION, list);
+      opTab.lookupOperatorOverloads(funName, funcType, SqlSyntax.FUNCTION, 
list);
       if (list.size() == 1) {
         fun = list.get(0);
       }

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/sql/util/ListSqlOperatorTable.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/sql/util/ListSqlOperatorTable.java 
b/core/src/main/java/org/apache/calcite/sql/util/ListSqlOperatorTable.java
index b018177..fe0aea0 100644
--- a/core/src/main/java/org/apache/calcite/sql/util/ListSqlOperatorTable.java
+++ b/core/src/main/java/org/apache/calcite/sql/util/ListSqlOperatorTable.java
@@ -63,20 +63,23 @@ public class ListSqlOperatorTable implements 
SqlOperatorTable {
           || !operator.isName(opName.getSimple())) {
         continue;
       }
-      SqlFunctionCategory functionCategory;
-      if (operator instanceof SqlFunction) {
-        functionCategory = ((SqlFunction) operator).getFunctionType();
-      } else {
-        functionCategory = SqlFunctionCategory.SYSTEM;
-      }
-      if (category != functionCategory
-          && category != SqlFunctionCategory.USER_DEFINED_FUNCTION) {
+      if (category != null
+          && category != category(operator)
+          && !category.isUserDefinedNotSpecificFunction()) {
         continue;
       }
       operatorList.add(operator);
     }
   }
 
+  protected static SqlFunctionCategory category(SqlOperator operator) {
+    if (operator instanceof SqlFunction) {
+      return ((SqlFunction) operator).getFunctionType();
+    } else {
+      return SqlFunctionCategory.SYSTEM;
+    }
+  }
+
   public List<SqlOperator> getOperatorList() {
     return operatorList;
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/sql/validate/AggFinder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/AggFinder.java 
b/core/src/main/java/org/apache/calcite/sql/validate/AggFinder.java
index a363fca..29226b0 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/AggFinder.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/AggFinder.java
@@ -18,7 +18,6 @@ package org.apache.calcite.sql.validate;
 
 import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlFunction;
-import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.SqlOperator;
@@ -110,17 +109,18 @@ class AggFinder extends SqlBasicVisitor<Void> {
       }
     }
     // User-defined function may not be resolved yet.
-    if (operator instanceof SqlFunction
-        && ((SqlFunction) operator).getFunctionType()
-        == SqlFunctionCategory.USER_DEFINED_FUNCTION) {
-      final List<SqlOperator> list = Lists.newArrayList();
-      opTab.lookupOperatorOverloads(((SqlFunction) 
operator).getSqlIdentifier(),
-          SqlFunctionCategory.USER_DEFINED_FUNCTION, SqlSyntax.FUNCTION, list);
-      for (SqlOperator sqlOperator : list) {
-        if (sqlOperator.isAggregator()) {
-          // If nested aggregates disallowed or found aggregate at invalid 
level
-          if (aggregate) {
-            throw new Util.FoundOne(call);
+    if (operator instanceof SqlFunction) {
+      final SqlFunction sqlFunction = (SqlFunction) operator;
+      if (sqlFunction.getFunctionType().isUserDefinedNotSpecificFunction()) {
+        final List<SqlOperator> list = Lists.newArrayList();
+        opTab.lookupOperatorOverloads(sqlFunction.getSqlIdentifier(),
+            sqlFunction.getFunctionType(), SqlSyntax.FUNCTION, list);
+        for (SqlOperator sqlOperator : list) {
+          if (sqlOperator.isAggregator()) {
+            // If nested aggregates disallowed or found aggregate at invalid 
level
+            if (aggregate) {
+              throw new Util.FoundOne(call);
+            }
           }
         }
       }

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedFunction.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedFunction.java
 
b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedFunction.java
index 163687e..cc3ed3f 100644
--- 
a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedFunction.java
+++ 
b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedFunction.java
@@ -41,15 +41,28 @@ import java.util.List;
 public class SqlUserDefinedFunction extends SqlFunction {
   public final Function function;
 
+  /** Creates a {@link SqlUserDefinedFunction}. */
   public SqlUserDefinedFunction(SqlIdentifier opName,
       SqlReturnTypeInference returnTypeInference,
       SqlOperandTypeInference operandTypeInference,
       SqlOperandTypeChecker operandTypeChecker,
       List<RelDataType> paramTypes,
       Function function) {
+    this(opName, returnTypeInference, operandTypeInference, operandTypeChecker,
+        paramTypes, function, SqlFunctionCategory.USER_DEFINED_FUNCTION);
+  }
+
+  /** Constructor used internally and by derived classes. */
+  protected SqlUserDefinedFunction(SqlIdentifier opName,
+      SqlReturnTypeInference returnTypeInference,
+      SqlOperandTypeInference operandTypeInference,
+      SqlOperandTypeChecker operandTypeChecker,
+      List<RelDataType> paramTypes,
+      Function function,
+      SqlFunctionCategory category) {
     super(Util.last(opName.names), opName, SqlKind.OTHER_FUNCTION,
         returnTypeInference, operandTypeInference, operandTypeChecker,
-        paramTypes, SqlFunctionCategory.USER_DEFINED_FUNCTION);
+        paramTypes, category);
     this.function = function;
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableFunction.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableFunction.java
 
b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableFunction.java
index 338a1ed..1e6f300 100644
--- 
a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableFunction.java
+++ 
b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableFunction.java
@@ -19,6 +19,7 @@ package org.apache.calcite.sql.validate;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.schema.TableFunction;
+import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.type.SqlOperandTypeChecker;
@@ -42,7 +43,7 @@ public class SqlUserDefinedTableFunction extends 
SqlUserDefinedFunction {
       List<RelDataType> paramTypes,
       TableFunction function) {
     super(opName, returnTypeInference, operandTypeInference, 
operandTypeChecker,
-        paramTypes, function);
+        paramTypes, function, SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableMacro.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableMacro.java
 
b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableMacro.java
index e20eed0..9ef6cc2 100644
--- 
a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableMacro.java
+++ 
b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableMacro.java
@@ -70,7 +70,7 @@ public class SqlUserDefinedTableMacro extends SqlFunction {
     super(Util.last(opName.names), opName, SqlKind.OTHER_FUNCTION,
         returnTypeInference, operandTypeInference, operandTypeChecker,
         Preconditions.checkNotNull(paramTypes),
-        SqlFunctionCategory.USER_DEFINED_FUNCTION);
+        SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION);
     this.tableMacro = tableMacro;
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java 
b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
index e7278d6..82b1f4e 100644
--- 
a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
+++ 
b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
@@ -702,8 +702,7 @@ public class RelStructuredTypeFlattener implements 
ReflectiveVisitor {
             RelStructuredTypeFlattener.class,
             RelNode.class);
 
-    // implement RelVisitor
-    public void visit(RelNode p, int ordinal, RelNode parent) {
+    @Override public void visit(RelNode p, int ordinal, RelNode parent) {
       // rewrite children first
       super.visit(p, ordinal, parent);
 
@@ -720,13 +719,11 @@ public class RelStructuredTypeFlattener implements 
ReflectiveVisitor {
           // for leaves, it's usually safe to assume that
           // no transformation is required
           rewriteGeneric(p);
+        } else {
+          throw new AssertionError("no '" + visitMethodName
+              + "' method found for class " + p.getClass().getName());
         }
       }
-      if (!found) {
-        throw Util.newInternal(
-            "no '" + visitMethodName + "' method found for class "
-            + p.getClass().getName());
-      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/test/java/org/apache/calcite/prepare/LookupOperatorOverloadsTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/calcite/prepare/LookupOperatorOverloadsTest.java
 
b/core/src/test/java/org/apache/calcite/prepare/LookupOperatorOverloadsTest.java
new file mode 100644
index 0000000..e760cd0
--- /dev/null
+++ 
b/core/src/test/java/org/apache/calcite/prepare/LookupOperatorOverloadsTest.java
@@ -0,0 +1,174 @@
+/*
+ * 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.calcite.prepare;
+
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.jdbc.CalciteConnection;
+import org.apache.calcite.jdbc.CalcitePrepare;
+import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.schema.TableFunction;
+import org.apache.calcite.schema.impl.AbstractSchema;
+import org.apache.calcite.schema.impl.TableFunctionImpl;
+import org.apache.calcite.server.CalciteServerStatement;
+import org.apache.calcite.sql.SqlFunctionCategory;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlSyntax;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.validate.SqlUserDefinedTableFunction;
+import org.apache.calcite.util.Smalls;
+
+import com.google.common.collect.Lists;
+
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static 
org.apache.calcite.sql.SqlFunctionCategory.USER_DEFINED_CONSTRUCTOR;
+import static org.apache.calcite.sql.SqlFunctionCategory.USER_DEFINED_FUNCTION;
+import static 
org.apache.calcite.sql.SqlFunctionCategory.USER_DEFINED_PROCEDURE;
+import static 
org.apache.calcite.sql.SqlFunctionCategory.USER_DEFINED_SPECIFIC_FUNCTION;
+import static 
org.apache.calcite.sql.SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION;
+import static 
org.apache.calcite.sql.SqlFunctionCategory.USER_DEFINED_TABLE_SPECIFIC_FUNCTION;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Test for lookupOperatorOverloads() in {@link CalciteCatalogReader}.
+ */
+public class LookupOperatorOverloadsTest {
+
+  private void checkFunctionType(int size, String name,
+      List<SqlOperator> operatorList) {
+    assertThat(size, is(operatorList.size()));
+
+    for (SqlOperator op : operatorList) {
+      assertThat(op, instanceOf(SqlUserDefinedTableFunction.class));
+      assertThat(name, is(op.getName()));
+    }
+  }
+
+  private static void check(List<SqlFunctionCategory> actuals,
+      SqlFunctionCategory... expecteds) {
+    assertThat(actuals, is(Arrays.asList(expecteds)));
+  }
+
+  @Test public void testIsUserDefined() throws SQLException {
+    List<SqlFunctionCategory> cats = new ArrayList<>();
+    for (SqlFunctionCategory c : SqlFunctionCategory.values()) {
+      if (c.isUserDefined()) {
+        cats.add(c);
+      }
+    }
+    check(cats, USER_DEFINED_FUNCTION, USER_DEFINED_PROCEDURE,
+        USER_DEFINED_CONSTRUCTOR, USER_DEFINED_SPECIFIC_FUNCTION,
+        USER_DEFINED_TABLE_FUNCTION, USER_DEFINED_TABLE_SPECIFIC_FUNCTION);
+  }
+
+  @Test public void testIsTableFunction() throws SQLException {
+    List<SqlFunctionCategory> cats = new ArrayList<>();
+    for (SqlFunctionCategory c : SqlFunctionCategory.values()) {
+      if (c.isTableFunction()) {
+        cats.add(c);
+      }
+    }
+    check(cats, USER_DEFINED_TABLE_FUNCTION,
+        USER_DEFINED_TABLE_SPECIFIC_FUNCTION);
+  }
+
+  @Test public void testIsSpecific() throws SQLException {
+    List<SqlFunctionCategory> cats = new ArrayList<>();
+    for (SqlFunctionCategory c : SqlFunctionCategory.values()) {
+      if (c.isSpecific()) {
+        cats.add(c);
+      }
+    }
+    check(cats, USER_DEFINED_SPECIFIC_FUNCTION,
+        USER_DEFINED_TABLE_SPECIFIC_FUNCTION);
+  }
+
+  @Test public void testIsUserDefinedNotSpecificFunction() throws SQLException 
{
+    List<SqlFunctionCategory> cats = new ArrayList<>();
+    for (SqlFunctionCategory sqlFunctionCategory : 
SqlFunctionCategory.values()) {
+      if (sqlFunctionCategory.isUserDefinedNotSpecificFunction()) {
+        cats.add(sqlFunctionCategory);
+      }
+    }
+    check(cats, USER_DEFINED_FUNCTION, USER_DEFINED_TABLE_FUNCTION);
+  }
+
+  @Test public void test() throws SQLException {
+    final String schemaName = "MySchema";
+    final String funcName = "MyFUNC";
+    final String anotherName = "AnotherFunc";
+
+    try (Connection connection = DriverManager.getConnection("jdbc:calcite:")) 
{
+      CalciteConnection calciteConnection =
+          connection.unwrap(CalciteConnection.class);
+      SchemaPlus rootSchema = calciteConnection.getRootSchema();
+      SchemaPlus schema = rootSchema.add(schemaName, new AbstractSchema());
+      final TableFunction table = TableFunctionImpl.create(Smalls.MAZE_METHOD);
+      schema.add(funcName, table);
+      schema.add(anotherName, table);
+      final TableFunction table2 =
+          TableFunctionImpl.create(Smalls.MAZE3_METHOD);
+      schema.add(funcName, table2);
+
+      final CalciteServerStatement statement =
+          connection.createStatement().unwrap(CalciteServerStatement.class);
+      final CalcitePrepare.Context prepareContext =
+          statement.createPrepareContext();
+      final JavaTypeFactory typeFactory = prepareContext.getTypeFactory();
+      CalciteCatalogReader reader =
+          new CalciteCatalogReader(prepareContext.getRootSchema(), false, null,
+              typeFactory);
+
+      final List<SqlOperator> operatorList = new ArrayList<>();
+      SqlIdentifier myFuncIdentifier =
+          new SqlIdentifier(Lists.newArrayList(schemaName, funcName), null,
+              SqlParserPos.ZERO, null);
+      reader.lookupOperatorOverloads(myFuncIdentifier,
+          SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION, SqlSyntax.FUNCTION,
+          operatorList);
+      checkFunctionType(2, funcName, operatorList);
+
+      operatorList.clear();
+      reader.lookupOperatorOverloads(myFuncIdentifier,
+          SqlFunctionCategory.USER_DEFINED_FUNCTION, SqlSyntax.FUNCTION,
+          operatorList);
+      checkFunctionType(0, null, operatorList);
+
+      operatorList.clear();
+      SqlIdentifier anotherFuncIdentifier =
+          new SqlIdentifier(Lists.newArrayList(schemaName, anotherName), null,
+              SqlParserPos.ZERO, null);
+      reader.lookupOperatorOverloads(anotherFuncIdentifier,
+          SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION, SqlSyntax.FUNCTION,
+          operatorList);
+      checkFunctionType(1, anotherName, operatorList);
+    }
+  }
+}
+
+// End LookupOperatorOverloadsTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/0599cdde/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteSuite.java 
b/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
index 3dfb659..9bab603 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
@@ -24,6 +24,7 @@ import org.apache.calcite.plan.RelWriterTest;
 import org.apache.calcite.plan.volcano.TraitPropagationTest;
 import org.apache.calcite.plan.volcano.VolcanoPlannerTest;
 import org.apache.calcite.plan.volcano.VolcanoPlannerTraitTest;
+import org.apache.calcite.prepare.LookupOperatorOverloadsTest;
 import org.apache.calcite.rel.RelCollationTest;
 import org.apache.calcite.rel.rel2sql.RelToSqlConverterTest;
 import org.apache.calcite.rex.RexBuilderTest;
@@ -119,6 +120,7 @@ import org.junit.runners.Suite;
     ChunkListTest.class,
     FrameworksTest.class,
     EnumerableCorrelateTest.class,
+    LookupOperatorOverloadsTest.class,
 
     // slow tests (above 1s)
     UdfTest.class,

Reply via email to