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,
