Repository: calcite Updated Branches: refs/heads/master 614bc7b2b -> bd956458f
[CALCITE-2663] Add CREATE and DROP FUNCTION (ambition119) Syntax is similar to Apache Hive's function syntax. Close apache/calcite#908 Close apache/calcite#920 Close apache/calcite#913 Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/bd956458 Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/bd956458 Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/bd956458 Branch: refs/heads/master Commit: bd956458f9dd321c3cc90daaf5c13f194b8feb03 Parents: 614bc7b Author: ambition119 <1269223860> Authored: Thu Nov 8 20:28:12 2018 +0800 Committer: Julian Hyde <[email protected]> Committed: Fri Nov 16 20:10:33 2018 -0800 ---------------------------------------------------------------------- .../java/org/apache/calcite/sql/SqlKind.java | 6 ++ .../calcite/sql/validate/SqlValidatorUtil.java | 3 +- .../main/java/org/apache/calcite/util/Util.java | 11 +++ .../calcite/sql/parser/SqlParserTest.java | 17 ++-- .../calcite/sql/parser/SqlUnParserTest.java | 4 + .../java/org/apache/calcite/util/UtilTest.java | 13 ++- server/src/main/codegen/config.fmpp | 10 ++ .../src/main/codegen/includes/parserImpls.ftl | 59 ++++++++++++ .../calcite/sql/ddl/SqlCreateFunction.java | 97 ++++++++++++++++++++ .../org/apache/calcite/sql/ddl/SqlDdlNodes.java | 21 +++++ .../apache/calcite/sql/ddl/SqlDropFunction.java | 39 ++++++++ .../apache/calcite/sql/ddl/SqlDropObject.java | 1 + .../apache/calcite/test/ServerParserTest.java | 35 +++++++ .../apache/calcite/test/ServerUnParserTest.java | 40 ++++++++ site/_docs/reference.md | 16 ++++ 15 files changed, 363 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/core/src/main/java/org/apache/calcite/sql/SqlKind.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/SqlKind.java b/core/src/main/java/org/apache/calcite/sql/SqlKind.java index e56b066..fa8c2f0 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlKind.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlKind.java @@ -1059,6 +1059,12 @@ public enum SqlKind { /** {@code DROP TYPE} DDL statement. */ DROP_TYPE, + /** {@code CREATE FUNCTION} DDL statement. */ + CREATE_FUNCTION, + + /** {@code DROP FUNCTION} DDL statement. */ + DROP_FUNCTION, + /** DDL statement not handled above. * * <p><b>Note to other projects</b>: If you are extending Calcite's SQL parser http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java index 99aa23e..de3bcf6 100644 --- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java +++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java @@ -168,8 +168,7 @@ public class SqlValidatorUtil { SqlNodeList extendedColumns) { final List list = extendedColumns.getList(); //noinspection unchecked - return Pair.zip(Util.quotientList(list, 2, 0), - Util.quotientList(list, 2, 1)); + return Util.pairs(list); } /** http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/core/src/main/java/org/apache/calcite/util/Util.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/util/Util.java b/core/src/main/java/org/apache/calcite/util/Util.java index 1dcb567..1a5a429 100644 --- a/core/src/main/java/org/apache/calcite/util/Util.java +++ b/core/src/main/java/org/apache/calcite/util/Util.java @@ -1848,6 +1848,17 @@ public class Util { }; } + /** Given a list with N elements + * [e<sub>0</sub>, e<sub>1</sub>, ..., e<sub>N-1</sub>] + * (where N is even), returns a list of the N / 2 elements + * [ (e<sub>0</sub>, e<sub>1</sub>), + * (e<sub>2</sub>, e<sub>3</sub>), ... ]. */ + public static <E> List<Pair<E, E>> pairs(final List<E> list) { + //noinspection unchecked + return Pair.zip(quotientList(list, 2, 0), + quotientList(list, 2, 1)); + } + /** Returns the first value if it is not null, * otherwise the second value. * http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java index ad2856a..6d5d1dd 100644 --- a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java +++ b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java @@ -62,6 +62,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; +import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; /** @@ -1057,16 +1058,20 @@ public class SqlParserTest { final String whereRow2 = "select 1 from t2 where ^(x, y)^ < (a, b)"; conformance = SqlConformanceEnum.DEFAULT; sql(whereRow2).sansCarets().ok(whereExpected); - if (this instanceof SqlUnParserTest) { - // After this point, SqlUnparserTest has problems. - // We generate ROW in a dialect that does not allow ROW in all contexts. - // So bail out. - return; - } + + // After this point, SqlUnparserTest has problems. + // We generate ROW in a dialect that does not allow ROW in all contexts. + // So bail out. + assumeFalse(isUnparserTest()); conformance = SqlConformanceEnum.SQL_SERVER_2008; sql(whereRow2).sansCarets().ok(whereExpected); } + /** Whether this is a sub-class that tests un-parsing as well as parsing. */ + protected boolean isUnparserTest() { + return false; + } + @Test public void testPeriod() { // We don't have a PERIOD constructor currently; // ROW constructor is sufficient for now. http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/core/src/test/java/org/apache/calcite/sql/parser/SqlUnParserTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/sql/parser/SqlUnParserTest.java b/core/src/test/java/org/apache/calcite/sql/parser/SqlUnParserTest.java index a067e49..1126333 100644 --- a/core/src/test/java/org/apache/calcite/sql/parser/SqlUnParserTest.java +++ b/core/src/test/java/org/apache/calcite/sql/parser/SqlUnParserTest.java @@ -31,6 +31,10 @@ public class SqlUnParserTest extends SqlParserTest { @Override protected Tester getTester() { return new UnparsingTesterImpl(); } + + @Override protected boolean isUnparserTest() { + return true; + } } // End SqlUnParserTest.java http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/core/src/test/java/org/apache/calcite/util/UtilTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/util/UtilTest.java b/core/src/test/java/org/apache/calcite/util/UtilTest.java index f7a71ca..2063fe2 100644 --- a/core/src/test/java/org/apache/calcite/util/UtilTest.java +++ b/core/src/test/java/org/apache/calcite/util/UtilTest.java @@ -969,7 +969,8 @@ public class UtilTest { } /** - * Unit test for {@link Util#quotientList(java.util.List, int, int)}. + * Unit test for {@link Util#quotientList(java.util.List, int, int)} + * and {@link Util#pairs(List)}. */ @Test public void testQuotientList() { List<String> beatles = Arrays.asList("john", "paul", "george", "ringo"); @@ -1017,6 +1018,16 @@ public class UtilTest { final List list5 = Util.quotientList(beatles, 10, 5); assertEquals(0, list5.size()); + + final List<Pair<String, String>> list6 = Util.pairs(beatles); + assertThat(list6.size(), is(2)); + assertThat(list6.get(0).left, is("john")); + assertThat(list6.get(0).right, is("paul")); + assertThat(list6.get(1).left, is("george")); + assertThat(list6.get(1).right, is("ringo")); + + final List<Pair<String, String>> list7 = Util.pairs(empty); + assertThat(list7.size(), is(0)); } @Test public void testImmutableIntList() { http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/server/src/main/codegen/config.fmpp ---------------------------------------------------------------------- diff --git a/server/src/main/codegen/config.fmpp b/server/src/main/codegen/config.fmpp index c9f938f..30c3031 100644 --- a/server/src/main/codegen/config.fmpp +++ b/server/src/main/codegen/config.fmpp @@ -25,6 +25,8 @@ data: { "org.apache.calcite.sql.SqlCreate" "org.apache.calcite.sql.SqlDrop" "org.apache.calcite.sql.ddl.SqlDdlNodes" + "java.util.Map" + "java.util.HashMap" ] # List of keywords. @@ -33,6 +35,9 @@ data: { "MATERIALIZED" "STORED" "VIRTUAL" + "JAR" + "FILE" + "ARCHIVE" ] # List of keywords from "keywords" section that are not reserved. @@ -344,6 +349,9 @@ data: { "MATERIALIZED" "STORED" "VIRTUAL" + "JAR" + "FILE" + "ARCHIVE" ] # List of additional join types. Each is a method with no arguments. @@ -378,6 +386,7 @@ data: { "SqlCreateTable" "SqlCreateType" "SqlCreateView" + "SqlCreateFunction" ] # List of methods for parsing extensions to "DROP" calls. @@ -388,6 +397,7 @@ data: { "SqlDropTable" "SqlDropType" "SqlDropView" + "SqlDropFunction" ] # List of files in @includes directory that have parser method http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/server/src/main/codegen/includes/parserImpls.ftl ---------------------------------------------------------------------- diff --git a/server/src/main/codegen/includes/parserImpls.ftl b/server/src/main/codegen/includes/parserImpls.ftl index 82210a0..51ea3b4 100644 --- a/server/src/main/codegen/includes/parserImpls.ftl +++ b/server/src/main/codegen/includes/parserImpls.ftl @@ -303,6 +303,53 @@ SqlCreate SqlCreateMaterializedView(Span s, boolean replace) : } } +private void FunctionJarDef(SqlNodeList usingList) : +{ + final SqlDdlNodes.FileType fileType; + final SqlNode uri; +} +{ + ( + <ARCHIVE> { fileType = SqlDdlNodes.FileType.ARCHIVE; } + | + <FILE> { fileType = SqlDdlNodes.FileType.FILE; } + | + <JAR> { fileType = SqlDdlNodes.FileType.JAR; } + ) { + usingList.add(SqlLiteral.createSymbol(fileType, getPos())); + } + uri = StringLiteral() { + usingList.add(uri); + } +} + +SqlCreate SqlCreateFunction(Span s, boolean replace) : +{ + final boolean ifNotExists; + final SqlIdentifier id; + final SqlNode className; + SqlNodeList usingList = SqlNodeList.EMPTY; +} +{ + <FUNCTION> ifNotExists = IfNotExistsOpt() + id = CompoundIdentifier() + <AS> + className = StringLiteral() + [ + <USING> { + usingList = new SqlNodeList(getPos()); + } + FunctionJarDef(usingList) + ( + <COMMA> + FunctionJarDef(usingList) + )* + ] { + return SqlDdlNodes.createFunction(s.end(this), replace, ifNotExists, + id, className, usingList); + } +} + SqlDrop SqlDropSchema(Span s, boolean replace) : { final boolean ifExists; @@ -364,4 +411,16 @@ SqlDrop SqlDropMaterializedView(Span s, boolean replace) : } } +SqlDrop SqlDropFunction(Span s, boolean replace) : +{ + final boolean ifExists; + final SqlIdentifier id; +} +{ + <FUNCTION> ifExists = IfExistsOpt() + id = CompoundIdentifier() { + return SqlDdlNodes.dropFunction(s.end(this), ifExists, id); + } +} + // End parserImpls.ftl http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/server/src/main/java/org/apache/calcite/sql/ddl/SqlCreateFunction.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/calcite/sql/ddl/SqlCreateFunction.java b/server/src/main/java/org/apache/calcite/sql/ddl/SqlCreateFunction.java new file mode 100644 index 0000000..29ccc6b --- /dev/null +++ b/server/src/main/java/org/apache/calcite/sql/ddl/SqlCreateFunction.java @@ -0,0 +1,97 @@ +/* + * 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.sql.ddl; + +import org.apache.calcite.sql.SqlCreate; +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.SqlKind; +import org.apache.calcite.sql.SqlLiteral; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.SqlNodeList; +import org.apache.calcite.sql.SqlOperator; +import org.apache.calcite.sql.SqlSpecialOperator; +import org.apache.calcite.sql.SqlWriter; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.util.Pair; +import org.apache.calcite.util.Util; + +import com.google.common.base.Preconditions; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** + * Parse tree for {@code CREATE FUNCTION} statement. + */ +public class SqlCreateFunction extends SqlCreate { + private final SqlIdentifier name; + private final SqlNode className; + private final SqlNodeList usingList; + + private static final SqlSpecialOperator OPERATOR = + new SqlSpecialOperator("CREATE FUNCTION", SqlKind.CREATE_FUNCTION); + + /** Creates a SqlCreateFunction. */ + public SqlCreateFunction(SqlParserPos pos, boolean replace, + boolean ifNotExists, SqlIdentifier name, + SqlNode className, SqlNodeList usingList) { + super(OPERATOR, pos, replace, ifNotExists); + this.name = Objects.requireNonNull(name); + this.className = className; + this.usingList = Objects.requireNonNull(usingList); + Preconditions.checkArgument(usingList.size() % 2 == 0); + } + + @Override public void unparse(SqlWriter writer, int leftPrec, + int rightPrec) { + writer.keyword(getReplace() ? "CREATE OR REPLACE" : "CREATE"); + writer.keyword("FUNCTION"); + if (ifNotExists) { + writer.keyword("IF NOT EXISTS"); + } + name.unparse(writer, 0, 0); + writer.keyword("AS"); + className.unparse(writer, 0, 0); + if (usingList.size() > 0) { + writer.keyword("USING"); + final SqlWriter.Frame frame = + writer.startList(SqlWriter.FrameTypeEnum.SIMPLE); + for (Pair<SqlLiteral, SqlLiteral> using : pairs()) { + writer.sep(","); + using.left.unparse(writer, 0, 0); // FILE, URL or ARCHIVE + using.right.unparse(writer, 0, 0); // e.g. 'file:foo/bar.jar' + } + writer.endList(frame); + } + } + + @SuppressWarnings("unchecked") + private List<Pair<SqlLiteral, SqlLiteral>> pairs() { + return Util.pairs((List) usingList.getList()); + } + + @Override public SqlOperator getOperator() { + return OPERATOR; + } + + @Override public List<SqlNode> getOperandList() { + return Arrays.asList(name, className, usingList); + } +} + +// End SqlCreateFunction.java http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/server/src/main/java/org/apache/calcite/sql/ddl/SqlDdlNodes.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/calcite/sql/ddl/SqlDdlNodes.java b/server/src/main/java/org/apache/calcite/sql/ddl/SqlDdlNodes.java index d35e7cc..f370436 100644 --- a/server/src/main/java/org/apache/calcite/sql/ddl/SqlDdlNodes.java +++ b/server/src/main/java/org/apache/calcite/sql/ddl/SqlDdlNodes.java @@ -99,6 +99,14 @@ public class SqlDdlNodes { columnList, query); } + /** Creates a CREATE FUNCTION. */ + public static SqlCreateFunction createFunction( + SqlParserPos pos, boolean replace, boolean ifNotExists, + SqlIdentifier name, SqlNode className, SqlNodeList usingList) { + return new SqlCreateFunction(pos, replace, ifNotExists, name, + className, usingList); + } + /** Creates a DROP [ FOREIGN ] SCHEMA. */ public static SqlDropSchema dropSchema(SqlParserPos pos, boolean foreign, boolean ifExists, SqlIdentifier name) { @@ -129,6 +137,12 @@ public class SqlDdlNodes { return new SqlDropMaterializedView(pos, ifExists, name); } + /** Creates a DROP FUNCTION. */ + public static SqlDrop dropFunction(SqlParserPos pos, + boolean ifExists, SqlIdentifier name) { + return new SqlDropFunction(pos, ifExists, name); + } + /** Creates a column declaration. */ public static SqlNode column(SqlParserPos pos, SqlIdentifier name, SqlDataTypeSpec dataType, SqlNode expression, ColumnStrategy strategy) { @@ -236,6 +250,13 @@ public class SqlDdlNodes { throw new RuntimeException(e); } } + + /** File type for CREATE FUNCTION. */ + public enum FileType { + FILE, + JAR, + ARCHIVE + } } // End SqlDdlNodes.java http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/server/src/main/java/org/apache/calcite/sql/ddl/SqlDropFunction.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/calcite/sql/ddl/SqlDropFunction.java b/server/src/main/java/org/apache/calcite/sql/ddl/SqlDropFunction.java new file mode 100644 index 0000000..bd6c5bd --- /dev/null +++ b/server/src/main/java/org/apache/calcite/sql/ddl/SqlDropFunction.java @@ -0,0 +1,39 @@ +/* + * 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.sql.ddl; + +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.SqlKind; +import org.apache.calcite.sql.SqlOperator; +import org.apache.calcite.sql.SqlSpecialOperator; +import org.apache.calcite.sql.parser.SqlParserPos; + +/** + * Parse tree for {@code DROP FUNCTION} statement. + */ +public class SqlDropFunction extends SqlDropObject { + private static final SqlOperator OPERATOR = + new SqlSpecialOperator("DROP FUNCTION", SqlKind.DROP_FUNCTION); + + /** Creates a SqlDropFunction. */ + public SqlDropFunction(SqlParserPos pos, boolean ifExists, + SqlIdentifier name) { + super(OPERATOR, pos, ifExists, name); + } +} + +// End SqlDropFunction.java http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/server/src/main/java/org/apache/calcite/sql/ddl/SqlDropObject.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/calcite/sql/ddl/SqlDropObject.java b/server/src/main/java/org/apache/calcite/sql/ddl/SqlDropObject.java index dacc093..ed6e6d4 100644 --- a/server/src/main/java/org/apache/calcite/sql/ddl/SqlDropObject.java +++ b/server/src/main/java/org/apache/calcite/sql/ddl/SqlDropObject.java @@ -91,6 +91,7 @@ abstract class SqlDropObject extends SqlDrop RESOURCE.typeNotFound(name.getSimple())); } break; + case OTHER_DDL: default: throw new AssertionError(getKind()); } http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/server/src/test/java/org/apache/calcite/test/ServerParserTest.java ---------------------------------------------------------------------- diff --git a/server/src/test/java/org/apache/calcite/test/ServerParserTest.java b/server/src/test/java/org/apache/calcite/test/ServerParserTest.java index 3bb7c39..d9628d3 100644 --- a/server/src/test/java/org/apache/calcite/test/ServerParserTest.java +++ b/server/src/test/java/org/apache/calcite/test/ServerParserTest.java @@ -210,6 +210,29 @@ public class ServerParserTest extends SqlParserTest { sql(sql).ok(expected); } + @Test public void testCreateOrReplaceFunction() { + final String sql = "create or replace function if not exists x.udf\n" + + " as 'org.apache.calcite.udf.TableFun.demoUdf'\n" + + "using jar 'file:/path/udf/udf-0.0.1-SNAPSHOT.jar',\n" + + " jar 'file:/path/udf/udf2-0.0.1-SNAPSHOT.jar',\n" + + " file 'file:/path/udf/logback.xml'"; + final String expected = "CREATE OR REPLACE FUNCTION" + + " IF NOT EXISTS `X`.`UDF`" + + " AS 'org.apache.calcite.udf.TableFun.demoUdf'" + + " USING JAR 'file:/path/udf/udf-0.0.1-SNAPSHOT.jar'," + + " JAR 'file:/path/udf/udf2-0.0.1-SNAPSHOT.jar'," + + " FILE 'file:/path/udf/logback.xml'"; + sql(sql).ok(expected); + } + + @Test public void testCreateOrReplaceFunction2() { + final String sql = "create function \"my Udf\"\n" + + " as 'org.apache.calcite.udf.TableFun.demoUdf'"; + final String expected = "CREATE FUNCTION `my Udf`" + + " AS 'org.apache.calcite.udf.TableFun.demoUdf'"; + sql(sql).ok(expected); + } + @Test public void testDropSchema() { sql("drop schema x") .ok("DROP SCHEMA `X`"); @@ -270,6 +293,18 @@ public class ServerParserTest extends SqlParserTest { .ok("DROP MATERIALIZED VIEW IF EXISTS `X`"); } + @Test public void testDropFunction() { + final String sql = "drop function x.udf"; + final String expected = "DROP FUNCTION `X`.`UDF`"; + sql(sql).ok(expected); + } + + @Test public void testDropFunctionIfExists() { + final String sql = "drop function if exists \"my udf\""; + final String expected = "DROP FUNCTION IF EXISTS `my udf`"; + sql(sql).ok(expected); + } + } // End ServerParserTest.java http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/server/src/test/java/org/apache/calcite/test/ServerUnParserTest.java ---------------------------------------------------------------------- diff --git a/server/src/test/java/org/apache/calcite/test/ServerUnParserTest.java b/server/src/test/java/org/apache/calcite/test/ServerUnParserTest.java new file mode 100644 index 0000000..debf5c4 --- /dev/null +++ b/server/src/test/java/org/apache/calcite/test/ServerUnParserTest.java @@ -0,0 +1,40 @@ +/* + * 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.test; + +/** + * Extension to {@link ServerParserTest} that ensures that every expression can + * un-parse successfully. + */ +public class ServerUnParserTest extends ServerParserTest { + //~ Constructors ----------------------------------------------------------- + + public ServerUnParserTest() { + } + + //~ Methods ---------------------------------------------------------------- + + @Override protected Tester getTester() { + return new UnparsingTesterImpl(); + } + + @Override protected boolean isUnparserTest() { + return true; + } +} + +// End ServerUnParserTest.java http://git-wip-us.apache.org/repos/asf/calcite/blob/bd956458/site/_docs/reference.md ---------------------------------------------------------------------- diff --git a/site/_docs/reference.md b/site/_docs/reference.md index 261c1f1..e43e255 100644 --- a/site/_docs/reference.md +++ b/site/_docs/reference.md @@ -2196,12 +2196,14 @@ ddlStatement: | createViewStatement | createMaterializedViewStatement | createTypeStatement + | createFunctionStatement | dropSchemaStatement | dropForeignSchemaStatement | dropTableStatement | dropViewStatement | dropMaterializedViewStatement | dropTypeStatement + | dropFunctionStatement createSchemaStatement: CREATE [ OR REPLACE ] SCHEMA [ IF NOT EXISTS ] name @@ -2267,6 +2269,14 @@ createMaterializedViewStatement: [ '(' columnName [, columnName ]* ')' ] AS query +createFunctionStatement: + CREATE [ OR REPLACE ] FUNCTION [ IF NOT EXISTS ] name + AS classNameLiteral + [ USING usingFile [, usingFile ]* ] + +usingFile: + ( JAR | FILE | ARCHIVE ) filePathLiteral + dropSchemaStatement: DROP SCHEMA [ IF EXISTS ] name @@ -2284,6 +2294,9 @@ dropMaterializedViewStatement: dropTypeStatement: DROP TYPE [ IF EXISTS ] name + +dropFunctionStatement: + DROP FUNCTION [ IF EXISTS ] name {% endhighlight %} In *createTableStatement*, if you specify *AS query*, you may omit the list of @@ -2292,3 +2305,6 @@ case it just renames the underlying column. In *columnGenerator*, if you do not specify `VIRTUAL` or `STORED` for a generated column, `VIRTUAL` is the default. + +In *createFunctionStatement* and *usingFile*, *classNameLiteral* +and *filePathLiteral* are character literals.
