You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by mm...@apache.org on 2018/07/20 17:41:37 UTC
[24/53] [abbrv] calcite git commit: [CALCITE-2280] Babel SQL parser
[CALCITE-2280] Babel SQL parser
Add BABEL conformance value and SqlConformance.isLiberal() method.
CalciteAssert.withSchema automatically sets the schema as default.
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/3e50a532
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/3e50a532
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/3e50a532
Branch: refs/heads/site
Commit: 3e50a5325357720d109e5fa300dad7a918087139
Parents: c749f25
Author: Julian Hyde <jh...@apache.org>
Authored: Wed May 2 00:03:14 2018 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Sun Jul 8 22:41:08 2018 -0700
----------------------------------------------------------------------
babel/pom.xml | 241 +++++++++++++++++++
babel/src/main/codegen/config.fmpp | 80 ++++++
babel/src/main/codegen/includes/parserImpls.ftl | 18 ++
.../org/apache/calcite/sql/babel/Babel.java | 26 ++
.../apache/calcite/sql/babel/package-info.java | 26 ++
.../apache/calcite/test/BabelParserTest.java | 47 ++++
.../apache/calcite/test/BabelQuidemTest.java | 193 +++++++++++++++
.../java/org/apache/calcite/test/BabelTest.java | 56 +++++
babel/src/test/resources/sql/dummy.iq | 27 +++
babel/src/test/resources/sql/select.iq | 54 +++++
.../apache/calcite/runtime/CalciteResource.java | 3 +
.../sql/validate/SqlAbstractConformance.java | 4 +
.../calcite/sql/validate/SqlConformance.java | 20 ++
.../sql/validate/SqlConformanceEnum.java | 30 ++-
.../calcite/runtime/CalciteResource.properties | 1 +
.../org/apache/calcite/test/CalciteAssert.java | 131 +++++-----
.../calcite/test/JdbcFrontJdbcBackTest.java | 1 -
.../org/apache/calcite/test/QuidemTest.java | 19 +-
pom.xml | 21 +-
.../src/test/resources/sql/materialized_view.iq | 4 +-
server/src/test/resources/sql/schema.iq | 2 +-
21 files changed, 935 insertions(+), 69 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/babel/pom.xml
----------------------------------------------------------------------
diff --git a/babel/pom.xml b/babel/pom.xml
new file mode 100644
index 0000000..20550d7
--- /dev/null
+++ b/babel/pom.xml
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.calcite</groupId>
+ <artifactId>calcite</artifactId>
+ <version>1.17.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>calcite-babel</artifactId>
+ <packaging>jar</packaging>
+ <version>1.17.0-SNAPSHOT</version>
+ <name>Calcite Babel</name>
+ <description>Calcite Babel</description>
+
+ <properties>
+ <top.dir>${project.basedir}/..</top.dir>
+ </properties>
+
+ <dependencies>
+ <!-- Sorted by groupId, artifactId; calcite dependencies first. Put versions
+ in dependencyManagement in the root POM, not here. -->
+ <dependency>
+ <groupId>org.apache.calcite.avatica</groupId>
+ <artifactId>avatica-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.calcite</groupId>
+ <artifactId>calcite-core</artifactId>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.calcite</groupId>
+ <artifactId>calcite-core</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>net.hydromatic</groupId>
+ <artifactId>quidem</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.hydromatic</groupId>
+ <artifactId>scott-data-hsqldb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.incava</groupId>
+ <artifactId>java-diff</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <!-- Sorted by groupId, artifactId. Put versions in
+ pluginManagement in the root POM, not here. -->
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>${maven-dependency-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>analyze</id>
+ <goals>
+ <goal>analyze-only</goal>
+ </goals>
+ <configuration>
+ <failOnWarning>true</failOnWarning>
+ <!-- ignore "unused but declared" warnings -->
+ <ignoredUnusedDeclaredDependencies>
+ <ignoredUnusedDeclaredDependency>net.hydromatic:scott-data-hsqldb</ignoredUnusedDeclaredDependency>
+ <ignoredUnusedDeclaredDependency>org.hsqldb:hsqldb</ignoredUnusedDeclaredDependency>
+ <ignoredUnusedDeclaredDependency>org.incava:java-diff</ignoredUnusedDeclaredDependency>
+ <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-api</ignoredUnusedDeclaredDependency>
+ <ignoredUnusedDeclaredDependency>org.slf4j:slf4j-log4j12</ignoredUnusedDeclaredDependency>
+ </ignoredUnusedDeclaredDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-fmpp-resources</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/codegen</outputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/codegen</directory>
+ <filtering>false</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ </plugin>
+ <!-- Parent module has the same plugin and does the work of
+ generating -sources.jar for each project. But without the
+ plugin declared here, IDEs don't know the sources are
+ available. -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>jar-no-fork</goal>
+ <goal>test-jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>javacc-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>javacc</id>
+ <goals>
+ <goal>javacc</goal>
+ </goals>
+ <configuration>
+ <sourceDirectory>${project.build.directory}/generated-sources/fmpp</sourceDirectory>
+ <outputDirectory>${project.build.directory}/generated-sources/javacc</outputDirectory>
+ <includes>
+ <include>**/Parser.jj</include>
+ </includes>
+ <lookAhead>2</lookAhead>
+ <isStatic>false</isStatic>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <!-- CALCITE-538: workaround for https://github.com/freemarker/fmpp/issues/11
+ FMPP always overwrites destination file, however we do not want
+ recompile the whole module every time.
+ -->
+ <id>generate-parser</id>
+ <activation>
+ <property>
+ <name>!skipGenerate</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>com.googlecode.fmpp-maven-plugin</groupId>
+ <artifactId>fmpp-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <configuration>
+ <cfgFile>src/main/codegen/config.fmpp</cfgFile>
+ <outputDirectory>${project.build.directory}/generated-sources/fmpp</outputDirectory>
+ <templateDirectory>${top.dir}/core/src/main/codegen/templates</templateDirectory>
+ </configuration>
+ <id>generate-fmpp-sources</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/babel/src/main/codegen/config.fmpp
----------------------------------------------------------------------
diff --git a/babel/src/main/codegen/config.fmpp b/babel/src/main/codegen/config.fmpp
new file mode 100644
index 0000000..57bbe86
--- /dev/null
+++ b/babel/src/main/codegen/config.fmpp
@@ -0,0 +1,80 @@
+# 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.
+
+data: {
+ parser: {
+ # Generated parser implementation class package and name
+ package: "org.apache.calcite.sql.parser.babel",
+ class: "SqlBabelParserImpl",
+
+ # List of import statements.
+ imports: [
+ ]
+
+ # List of keywords.
+ keywords: [
+ "SEMI"
+ ]
+
+ # List of keywords from "keywords" section that are not reserved.
+ nonReservedKeywords: [
+ "SEMI"
+ ]
+
+ # List of methods for parsing custom SQL statements.
+ statementParserMethods: [
+ ]
+
+ # List of methods for parsing custom literals.
+ # Example: ParseJsonLiteral().
+ literalParserMethods: [
+ ]
+
+ # List of methods for parsing custom data types.
+ dataTypeParserMethods: [
+ ]
+
+ # List of methods for parsing extensions to "ALTER <scope>" calls.
+ # Each must accept arguments "(SqlParserPos pos, String scope)".
+ alterStatementParserMethods: [
+ ]
+
+ # List of methods for parsing extensions to "CREATE [OR REPLACE]" calls.
+ # Each must accept arguments "(SqlParserPos pos, boolean replace)".
+ createStatementParserMethods: [
+ ]
+
+ # List of methods for parsing extensions to "DROP" calls.
+ # Each must accept arguments "(SqlParserPos pos)".
+ dropStatementParserMethods: [
+ ]
+
+ # List of files in @includes directory that have parser method
+ # implementations for parsing custom SQL statements, literals or types
+ # given as part of "statementParserMethods", "literalParserMethods" or
+ # "dataTypeParserMethods".
+ implementationFiles: [
+ "parserImpls.ftl"
+ ]
+
+ includeCompoundIdentifier: true
+ includeBraces: true
+ includeAdditionalDeclarations: false
+
+ }
+}
+freemarkerLinks: {
+ includes: includes/
+}
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/babel/src/main/codegen/includes/parserImpls.ftl
----------------------------------------------------------------------
diff --git a/babel/src/main/codegen/includes/parserImpls.ftl b/babel/src/main/codegen/includes/parserImpls.ftl
new file mode 100644
index 0000000..627a634
--- /dev/null
+++ b/babel/src/main/codegen/includes/parserImpls.ftl
@@ -0,0 +1,18 @@
+<#--
+// 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.
+-->
+
+// End parserImpls.ftl
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/babel/src/main/java/org/apache/calcite/sql/babel/Babel.java
----------------------------------------------------------------------
diff --git a/babel/src/main/java/org/apache/calcite/sql/babel/Babel.java b/babel/src/main/java/org/apache/calcite/sql/babel/Babel.java
new file mode 100644
index 0000000..167a136
--- /dev/null
+++ b/babel/src/main/java/org/apache/calcite/sql/babel/Babel.java
@@ -0,0 +1,26 @@
+/*
+ * 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.babel;
+
+/** SQL parser that accepts a wide variety of dialects. */
+@SuppressWarnings("unused")
+public class Babel {
+ // This class is currently a place-holder. Javadoc gets upset
+ // if there are no classes in babel/java/main.
+}
+
+// End Babel.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/babel/src/main/java/org/apache/calcite/sql/babel/package-info.java
----------------------------------------------------------------------
diff --git a/babel/src/main/java/org/apache/calcite/sql/babel/package-info.java b/babel/src/main/java/org/apache/calcite/sql/babel/package-info.java
new file mode 100644
index 0000000..498513a
--- /dev/null
+++ b/babel/src/main/java/org/apache/calcite/sql/babel/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * Parse tree for SQL extensions used by the Babel parser.
+ */
+@PackageMarker
+package org.apache.calcite.sql.babel;
+
+import org.apache.calcite.avatica.util.PackageMarker;
+
+// End package-info.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java
----------------------------------------------------------------------
diff --git a/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java b/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java
new file mode 100644
index 0000000..521266d
--- /dev/null
+++ b/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import org.apache.calcite.sql.parser.SqlParserImplFactory;
+import org.apache.calcite.sql.parser.SqlParserTest;
+import org.apache.calcite.sql.parser.babel.SqlBabelParserImpl;
+
+import org.junit.Test;
+
+/**
+ * Tests the "Babel" SQL parser, that understands all dialects of SQL.
+ */
+public class BabelParserTest extends SqlParserTest {
+
+ @Override protected SqlParserImplFactory parserImplFactory() {
+ return SqlBabelParserImpl.FACTORY;
+ }
+
+ @Override public void testGenerateKeyWords() {
+ // by design, method only works in base class; no-ops in this sub-class
+ }
+
+ @Test public void testSelect() {
+ final String sql = "select 1 from t";
+ final String expected = "SELECT 1\n"
+ + "FROM `T`";
+ sql(sql).ok(expected);
+ }
+
+}
+
+// End BabelParserTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/babel/src/test/java/org/apache/calcite/test/BabelQuidemTest.java
----------------------------------------------------------------------
diff --git a/babel/src/test/java/org/apache/calcite/test/BabelQuidemTest.java b/babel/src/test/java/org/apache/calcite/test/BabelQuidemTest.java
new file mode 100644
index 0000000..4c2e304
--- /dev/null
+++ b/babel/src/test/java/org/apache/calcite/test/BabelQuidemTest.java
@@ -0,0 +1,193 @@
+/*
+ * 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;
+
+import org.apache.calcite.config.CalciteConnectionConfig;
+import org.apache.calcite.config.CalciteConnectionConfigImpl;
+import org.apache.calcite.config.CalciteConnectionProperty;
+import org.apache.calcite.jdbc.CalciteConnection;
+import org.apache.calcite.materialize.MaterializationService;
+import org.apache.calcite.plan.Contexts;
+import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlWriter;
+import org.apache.calcite.sql.dialect.CalciteSqlDialect;
+import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.parser.babel.SqlBabelParserImpl;
+import org.apache.calcite.sql.pretty.SqlPrettyWriter;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
+import org.apache.calcite.tools.Frameworks;
+import org.apache.calcite.tools.Planner;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import net.hydromatic.quidem.AbstractCommand;
+import net.hydromatic.quidem.Command;
+import net.hydromatic.quidem.CommandHandler;
+import net.hydromatic.quidem.Quidem;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.sql.Connection;
+import java.util.Collection;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Unit tests for the Babel SQL parser.
+ */
+@RunWith(Parameterized.class)
+@Ignore
+public class BabelQuidemTest extends QuidemTest {
+ /** Creates a BabelQuidemTest. Public per {@link Parameterized}. */
+ @SuppressWarnings("WeakerAccess")
+ public BabelQuidemTest(String path) {
+ super(path);
+ }
+
+ /** Runs a test from the command line.
+ *
+ * <p>For example:
+ *
+ * <blockquote>
+ * <code>java BabelQuidemTest sql/table.iq</code>
+ * </blockquote> */
+ public static void main(String[] args) throws Exception {
+ for (String arg : args) {
+ new BabelQuidemTest(arg).test();
+ }
+ }
+
+ @Override @Test public void test() throws Exception {
+ MaterializationService.setThreadLocal();
+ super.test();
+ }
+
+ /** For {@link Parameterized} runner. */
+ @Parameterized.Parameters(name = "{index}: quidem({0})")
+ public static Collection<Object[]> data() {
+ // Start with a test file we know exists, then find the directory and list
+ // its files.
+ final String first = "sql/select.iq";
+ return data(first);
+ }
+
+ @Override protected Quidem.ConnectionFactory createConnectionFactory() {
+ return new QuidemConnectionFactory() {
+ @Override public Connection connect(String name, boolean reference)
+ throws Exception {
+ switch (name) {
+ case "babel":
+ return BabelTest.connect();
+ }
+ return super.connect(name, reference);
+ }
+ };
+ }
+
+ @Override protected CommandHandler createCommandHandler() {
+ return new BabelCommandHandler();
+ }
+
+ /** Command that prints the validated parse tree of a SQL statement. */
+ static class ExplainValidatedCommand extends AbstractCommand {
+ private final ImmutableList<String> lines;
+ private final ImmutableList<String> content;
+ private final Set<String> productSet;
+
+ ExplainValidatedCommand(List<String> lines, List<String> content,
+ Set<String> productSet) {
+ this.lines = ImmutableList.copyOf(lines);
+ this.content = ImmutableList.copyOf(content);
+ this.productSet = ImmutableSet.copyOf(productSet);
+ }
+
+ @Override public void execute(Context x, boolean execute) throws Exception {
+ if (execute) {
+ // use Babel parser
+ final SqlParser.ConfigBuilder parserConfig =
+ SqlParser.configBuilder()
+ .setParserFactory(SqlBabelParserImpl.FACTORY);
+
+ // use Babel conformance for validation
+ final Properties properties = new Properties();
+ properties.setProperty(CalciteConnectionProperty.CONFORMANCE.name(),
+ SqlConformanceEnum.BABEL.name());
+ final CalciteConnectionConfig connectionConfig =
+ new CalciteConnectionConfigImpl(properties);
+
+ // extract named schema from connection and use it in planner
+ final CalciteConnection calciteConnection =
+ x.connection().unwrap(CalciteConnection.class);
+ final String schemaName = calciteConnection.getSchema();
+ final SchemaPlus schema =
+ schemaName != null
+ ? calciteConnection.getRootSchema().getSubSchema(schemaName)
+ : calciteConnection.getRootSchema();
+ final Frameworks.ConfigBuilder config =
+ Frameworks.newConfigBuilder()
+ .defaultSchema(schema)
+ .parserConfig(parserConfig.build())
+ .context(Contexts.of(connectionConfig));
+
+ // parse, validate and un-parse
+ final Quidem.SqlCommand sqlCommand = x.previousSqlCommand();
+ final Planner planner = Frameworks.getPlanner(config.build());
+ final SqlNode node = planner.parse(sqlCommand.sql);
+ final SqlNode validateNode = planner.validate(node);
+ final SqlWriter sqlWriter =
+ new SqlPrettyWriter(CalciteSqlDialect.DEFAULT);
+ validateNode.unparse(sqlWriter, 0, 0);
+ x.echo(ImmutableList.of(sqlWriter.toSqlString().getSql()));
+ } else {
+ x.echo(content);
+ }
+ x.echo(lines);
+ }
+ }
+
+ /** Command handler that adds a "!explain-validated-on dialect..." command
+ * (see {@link ExplainValidatedCommand}). */
+ private static class BabelCommandHandler implements CommandHandler {
+ @Override public Command parseCommand(List<String> lines,
+ List<String> content, String line) {
+ final String prefix = "explain-validated-on";
+ if (line.startsWith(prefix)) {
+ final Pattern pattern =
+ Pattern.compile("explain-validated-on( [-_+a-zA-Z0-9]+)*?");
+ final Matcher matcher = pattern.matcher(line);
+ if (matcher.matches()) {
+ final ImmutableSet.Builder<String> set = ImmutableSet.builder();
+ for (int i = 0; i < matcher.groupCount(); i++) {
+ set.add(matcher.group(i + 1));
+ }
+ return new ExplainValidatedCommand(lines, content, set.build());
+ }
+ }
+ return null;
+ }
+ }
+}
+
+// End BabelQuidemTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/babel/src/test/java/org/apache/calcite/test/BabelTest.java
----------------------------------------------------------------------
diff --git a/babel/src/test/java/org/apache/calcite/test/BabelTest.java b/babel/src/test/java/org/apache/calcite/test/BabelTest.java
new file mode 100644
index 0000000..5a21749
--- /dev/null
+++ b/babel/src/test/java/org/apache/calcite/test/BabelTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+import org.apache.calcite.config.CalciteConnectionProperty;
+import org.apache.calcite.sql.parser.babel.SqlBabelParserImpl;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for Babel framework.
+ */
+public class BabelTest {
+
+ static final String URL = "jdbc:calcite:";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ static Connection connect() throws SQLException {
+ return DriverManager.getConnection(URL,
+ CalciteAssert.propBuilder()
+ .set(CalciteConnectionProperty.PARSER_FACTORY,
+ SqlBabelParserImpl.class.getName() + "#FACTORY")
+ .build());
+ }
+
+ @Test public void testFoo() {
+ assertThat(1 + 1, is(2));
+ }
+}
+
+// End BabelTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/babel/src/test/resources/sql/dummy.iq
----------------------------------------------------------------------
diff --git a/babel/src/test/resources/sql/dummy.iq b/babel/src/test/resources/sql/dummy.iq
new file mode 100755
index 0000000..e5aa269
--- /dev/null
+++ b/babel/src/test/resources/sql/dummy.iq
@@ -0,0 +1,27 @@
+# dummy.iq
+#
+# 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.
+#
+!use scott
+!set outputformat mysql
+
+# VALUES as top-level (not Oracle)
+VALUES 1 + 2;
+
+VALUES ROW(1 + 2)
+!explain-validated-on calcite postgres
+
+# End dummy.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/babel/src/test/resources/sql/select.iq
----------------------------------------------------------------------
diff --git a/babel/src/test/resources/sql/select.iq b/babel/src/test/resources/sql/select.iq
new file mode 100755
index 0000000..ef692dc
--- /dev/null
+++ b/babel/src/test/resources/sql/select.iq
@@ -0,0 +1,54 @@
+# select.iq - Babel test for non-standard clauses in SELECT
+#
+# 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.
+#
+!use scott
+!set outputformat mysql
+
+# ORDER BY column not in SELECT clause
+SELECT ename
+FROM emp, dept
+ORDER BY emp.deptno;
+
+SELECT "EMP"."ENAME"
+FROM "scott"."EMP" AS "EMP",
+ "scott"."DEPT" AS "DEPT"
+ORDER BY "EMP"."DEPTNO"
+!explain-validated-on all
+
+# Test CONNECT BY (Oracle only)
+!if (false) {
+SELECT *
+FROM emp
+START WITH mgr IS NULL
+CONNECT BY empno = PRIOR mgr;
+select(...)
+!explain-validated-on oracle
+!}
+
+# WITH RECURSIVE (Oracle, MySQL 8 onwards)
+!if (false) {
+WITH RECURSIVE t(n) AS (
+ VALUES (1)
+ UNION ALL
+ SELECT n+1 FROM t WHERE n < 100
+)
+SELECT sum(n) FROM t;
+select(...)
+!explain-validated-on mysql8+ oracle
+!}
+
+# End select.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
index 48079eb..122b39e 100644
--- a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
+++ b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
@@ -754,6 +754,9 @@ public interface CalciteResource {
@BaseMessage("Type ''{0}'' not found")
ExInst<SqlValidatorException> typeNotFound(String name);
+
+ @BaseMessage("Dialect does not support feature: ''{0}''")
+ ExInst<SqlValidatorException> dialectDoesNotSupportFeature(String featureName);
}
// End CalciteResource.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java
index c4d0f2d..059127b 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java
@@ -23,6 +23,10 @@ package org.apache.calcite.sql.validate;
* and behaves the same as in {@link SqlConformanceEnum#DEFAULT}.
*/
public abstract class SqlAbstractConformance implements SqlConformance {
+ public boolean isLiberal() {
+ return SqlConformanceEnum.DEFAULT.isLiberal();
+ }
+
public boolean isGroupByAlias() {
return SqlConformanceEnum.DEFAULT.isGroupByAlias();
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
index 84eee35..9fa0f5e 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
@@ -62,10 +62,17 @@ public interface SqlConformance {
SqlConformanceEnum PRAGMATIC_2003 = SqlConformanceEnum.PRAGMATIC_2003;
/**
+ * Whether this dialect supports features from a wide variety of
+ * dialects. This is enabled for the Babel parser, disabled otherwise.
+ */
+ boolean isLiberal();
+
+ /**
* Whether to allow aliases from the {@code SELECT} clause to be used as
* column names in the {@code GROUP BY} clause.
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#MYSQL_5};
* false otherwise.
@@ -77,6 +84,7 @@ public interface SqlConformance {
* in the select list'.
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#MYSQL_5};
* false otherwise.
@@ -88,6 +96,7 @@ public interface SqlConformance {
* column names in the {@code HAVING} clause.
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#MYSQL_5};
* false otherwise.
@@ -100,6 +109,7 @@ public interface SqlConformance {
*
* <p>Among the built-in conformance levels, true in
* {@link SqlConformanceEnum#DEFAULT},
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#MYSQL_5},
* {@link SqlConformanceEnum#ORACLE_10},
@@ -118,6 +128,7 @@ public interface SqlConformance {
*
* <p>Among the built-in conformance levels, true in
* {@link SqlConformanceEnum#DEFAULT},
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#MYSQL_5},
* {@link SqlConformanceEnum#ORACLE_10},
@@ -156,6 +167,7 @@ public interface SqlConformance {
* the parser.
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#MYSQL_5},
* {@link SqlConformanceEnum#ORACLE_10};
@@ -169,6 +181,7 @@ public interface SqlConformance {
* {@code mod} function.
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#MYSQL_5};
* false otherwise.
@@ -180,6 +193,7 @@ public interface SqlConformance {
* the parser.
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#ORACLE_10};
* {@link SqlConformanceEnum#ORACLE_12};
@@ -207,6 +221,7 @@ public interface SqlConformance {
* </ul>
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#SQL_SERVER_2008};
* {@link SqlConformanceEnum#ORACLE_12};
@@ -228,6 +243,7 @@ public interface SqlConformance {
* column is not declared {@code NOT NULL}.
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#PRAGMATIC_99},
* {@link SqlConformanceEnum#PRAGMATIC_2003};
@@ -254,6 +270,7 @@ public interface SqlConformance {
* not.
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#MYSQL_5};
* false otherwise.
@@ -293,6 +310,7 @@ public interface SqlConformance {
* </blockquote>
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT};
* false otherwise.
*/
@@ -308,6 +326,7 @@ public interface SqlConformance {
* <p>MySQL and CUBRID allow this behavior.
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#MYSQL_5};
* false otherwise.
@@ -318,6 +337,7 @@ public interface SqlConformance {
* Whether to allow geo-spatial extensions, including the GEOMETRY type.
*
* <p>Among the built-in conformance levels, true in
+ * {@link SqlConformanceEnum#BABEL},
* {@link SqlConformanceEnum#LENIENT},
* {@link SqlConformanceEnum#MYSQL_5},
* {@link SqlConformanceEnum#SQL_SERVER_2008};
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
index c52d39c..192e58b 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
@@ -23,9 +23,14 @@ public enum SqlConformanceEnum implements SqlConformance {
/** Calcite's default SQL behavior. */
DEFAULT,
- /** Conformance value that allows just about everything. */
+ /** Conformance value that allows just about everything supported by
+ * Calcite. */
LENIENT,
+ /** Conformance value that allows anything supported by any dialect.
+ * Even more liberal than {@link #LENIENT}. */
+ BABEL,
+
/** Conformance value that instructs Calcite to use SQL semantics strictly
* consistent with the SQL:92 standard. */
STRICT_92,
@@ -66,8 +71,18 @@ public enum SqlConformanceEnum implements SqlConformance {
* consistent with Microsoft SQL Server version 2008. */
SQL_SERVER_2008;
+ public boolean isLiberal() {
+ switch (this) {
+ case BABEL:
+ return true;
+ default:
+ return false;
+ }
+ }
+
public boolean isGroupByAlias() {
switch (this) {
+ case BABEL:
case LENIENT:
case MYSQL_5:
return true;
@@ -78,6 +93,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean isGroupByOrdinal() {
switch (this) {
+ case BABEL:
case LENIENT:
case MYSQL_5:
return true;
@@ -88,6 +104,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean isHavingAlias() {
switch (this) {
+ case BABEL:
case LENIENT:
case MYSQL_5:
return true;
@@ -99,6 +116,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean isSortByOrdinal() {
switch (this) {
case DEFAULT:
+ case BABEL:
case LENIENT:
case MYSQL_5:
case ORACLE_10:
@@ -116,6 +134,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean isSortByAlias() {
switch (this) {
case DEFAULT:
+ case BABEL:
case LENIENT:
case MYSQL_5:
case ORACLE_10:
@@ -148,6 +167,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean isBangEqualAllowed() {
switch (this) {
case LENIENT:
+ case BABEL:
case MYSQL_5:
case ORACLE_10:
case ORACLE_12:
@@ -159,6 +179,7 @@ public enum SqlConformanceEnum implements SqlConformance {
@Override public boolean isMinusAllowed() {
switch (this) {
+ case BABEL:
case LENIENT:
case ORACLE_10:
case ORACLE_12:
@@ -170,6 +191,7 @@ public enum SqlConformanceEnum implements SqlConformance {
@Override public boolean isPercentRemainderAllowed() {
switch (this) {
+ case BABEL:
case LENIENT:
case MYSQL_5:
return true;
@@ -180,6 +202,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean isApplyAllowed() {
switch (this) {
+ case BABEL:
case LENIENT:
case SQL_SERVER_2008:
case ORACLE_12:
@@ -191,6 +214,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean isInsertSubsetColumnsAllowed() {
switch (this) {
+ case BABEL:
case LENIENT:
case PRAGMATIC_99:
case PRAGMATIC_2003:
@@ -202,6 +226,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean allowNiladicParentheses() {
switch (this) {
+ case BABEL:
case LENIENT:
case MYSQL_5:
return true;
@@ -222,6 +247,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean allowExtend() {
switch (this) {
+ case BABEL:
case LENIENT:
return true;
default:
@@ -231,6 +257,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean isLimitStartCountAllowed() {
switch (this) {
+ case BABEL:
case LENIENT:
case MYSQL_5:
return true;
@@ -241,6 +268,7 @@ public enum SqlConformanceEnum implements SqlConformance {
public boolean allowGeometry() {
switch (this) {
+ case BABEL:
case LENIENT:
case MYSQL_5:
case SQL_SERVER_2008:
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties b/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
index d1ea199..bf83769 100644
--- a/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
+++ b/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
@@ -245,4 +245,5 @@ ViewExists=View ''{0}'' already exists and REPLACE not specified
SchemaNotFound=Schema ''{0}'' not found
ViewNotFound=View ''{0}'' not found
TypeNotFound=Type ''{0}'' not found
+DialectDoesNotSupportFeature=Dialect does not support feature: ''{0}''
# End CalciteResource.properties
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
index 9056ecc..171fed4 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
@@ -670,35 +670,31 @@ public class CalciteAssert {
}
public static SchemaPlus addSchema(SchemaPlus rootSchema, SchemaSpec schema) {
- SchemaPlus foodmart;
- SchemaPlus jdbcScott;
+ final SchemaPlus foodmart;
+ final SchemaPlus jdbcScott;
final ConnectionSpec cs;
final DataSource dataSource;
switch (schema) {
case REFLECTIVE_FOODMART:
- return rootSchema.add("foodmart",
+ return rootSchema.add(schema.schemaName,
new ReflectiveSchema(new JdbcTest.FoodmartSchema()));
case JDBC_SCOTT:
cs = DatabaseInstance.HSQLDB.scott;
dataSource = JdbcSchema.dataSource(cs.url, cs.driver, cs.username,
cs.password);
- return rootSchema.add("JDBC_SCOTT",
- JdbcSchema.create(rootSchema, "JDBC_SCOTT", dataSource, cs.catalog,
- cs.schema));
+ return rootSchema.add(schema.schemaName,
+ JdbcSchema.create(rootSchema, schema.schemaName, dataSource,
+ cs.catalog, cs.schema));
case JDBC_FOODMART:
cs = DB.foodmart;
dataSource =
JdbcSchema.dataSource(cs.url, cs.driver, cs.username, cs.password);
- return rootSchema.add("foodmart",
- JdbcSchema.create(rootSchema, "foodmart", dataSource, cs.catalog,
- cs.schema));
+ return rootSchema.add(schema.schemaName,
+ JdbcSchema.create(rootSchema, schema.schemaName, dataSource,
+ cs.catalog, cs.schema));
case JDBC_FOODMART_WITH_LATTICE:
- foodmart = rootSchema.getSubSchema("foodmart");
- if (foodmart == null) {
- foodmart =
- CalciteAssert.addSchema(rootSchema, SchemaSpec.JDBC_FOODMART);
- }
- foodmart.add("lattice",
+ foodmart = addSchemaIfNotExists(rootSchema, SchemaSpec.JDBC_FOODMART);
+ foodmart.add(schema.schemaName,
Lattice.create(foodmart.unwrap(CalciteSchema.class),
"select 1 from \"foodmart\".\"sales_fact_1997\" as s\n"
+ "join \"foodmart\".\"time_by_day\" as t using (\"time_id\")\n"
@@ -708,23 +704,16 @@ public class CalciteAssert {
true));
return foodmart;
case SCOTT:
- jdbcScott = rootSchema.getSubSchema("jdbc_scott");
- if (jdbcScott == null) {
- jdbcScott =
- CalciteAssert.addSchema(rootSchema, SchemaSpec.JDBC_SCOTT);
- }
- return rootSchema.add("scott", new CloneSchema(jdbcScott));
+ jdbcScott = addSchemaIfNotExists(rootSchema, SchemaSpec.JDBC_SCOTT);
+ return rootSchema.add(schema.schemaName, new CloneSchema(jdbcScott));
case CLONE_FOODMART:
- foodmart = rootSchema.getSubSchema("foodmart");
- if (foodmart == null) {
- foodmart =
- CalciteAssert.addSchema(rootSchema, SchemaSpec.JDBC_FOODMART);
- }
+ foodmart = addSchemaIfNotExists(rootSchema, SchemaSpec.JDBC_FOODMART);
return rootSchema.add("foodmart2", new CloneSchema(foodmart));
case GEO:
ModelHandler.addFunctions(rootSchema, null, ImmutableList.of(),
GeoFunctions.class.getName(), "*", true);
- final SchemaPlus s = rootSchema.add("GEO", new AbstractSchema());
+ final SchemaPlus s =
+ rootSchema.add(schema.schemaName, new AbstractSchema());
ModelHandler.addFunctions(s, "countries", ImmutableList.of(),
CountriesTableFunction.class.getName(), null, false);
final String sql = "select * from table(\"countries\"(true))";
@@ -733,21 +722,23 @@ public class CalciteAssert {
s.add("countries", viewMacro);
return s;
case HR:
- return rootSchema.add("hr",
+ return rootSchema.add(schema.schemaName,
new ReflectiveSchema(new JdbcTest.HrSchema()));
case LINGUAL:
- return rootSchema.add("SALES",
+ return rootSchema.add(schema.schemaName,
new ReflectiveSchema(new JdbcTest.LingualSchema()));
case BLANK:
- return rootSchema.add("BLANK", new AbstractSchema());
+ return rootSchema.add(schema.schemaName, new AbstractSchema());
case ORINOCO:
- final SchemaPlus orinoco = rootSchema.add("ORINOCO", new AbstractSchema());
+ final SchemaPlus orinoco =
+ rootSchema.add(schema.schemaName, new AbstractSchema());
orinoco.add("ORDERS",
new StreamTest.OrdersHistoryTable(
StreamTest.OrdersStreamTableFactory.getRowList()));
return orinoco;
case POST:
- final SchemaPlus post = rootSchema.add("POST", new AbstractSchema());
+ final SchemaPlus post =
+ rootSchema.add(schema.schemaName, new AbstractSchema());
post.add("EMP",
ViewTable.viewMacro(post,
"select * from (values\n"
@@ -789,6 +780,15 @@ public class CalciteAssert {
}
}
+ private static SchemaPlus addSchemaIfNotExists(SchemaPlus rootSchema,
+ SchemaSpec schemaSpec) {
+ final SchemaPlus schema = rootSchema.getSubSchema(schemaSpec.schemaName);
+ if (schema != null) {
+ return schema;
+ }
+ return addSchema(rootSchema, schemaSpec);
+ }
+
/**
* Asserts that two objects are equal. If they are not, an
* {@link AssertionError} is thrown with the given message. If
@@ -909,6 +909,12 @@ public class CalciteAssert {
connectionFactory.with(new AddSchemaPostProcessor(name, schema)));
}
+ /** Sets the default schema of the connection. Schema name may be null. */
+ public AssertThat withDefaultSchema(String schema) {
+ return new AssertThat(
+ connectionFactory.with(new DefaultSchemaPostProcessor(schema)));
+ }
+
public AssertThat with(ConnectionPostProcessor postProcessor) {
return new AssertThat(connectionFactory.with(postProcessor));
}
@@ -1032,12 +1038,6 @@ public class CalciteAssert {
}
}
- public AssertThat withDefaultSchema(String schema) {
- return new AssertThat(
- connectionFactory.with(
- new AddSchemaPostProcessor(schema, null)));
- }
-
/** Use sparingly. Does not close the connection. */
public Connection connect() throws SQLException {
return connectionFactory.createConnection();
@@ -1100,8 +1100,8 @@ public class CalciteAssert {
private final Schema schema;
public AddSchemaPostProcessor(String name, Schema schema) {
- this.name = name;
- this.schema = schema;
+ this.name = Objects.requireNonNull(name);
+ this.schema = Objects.requireNonNull(schema);
}
public Connection apply(Connection connection) throws SQLException {
@@ -1115,6 +1115,21 @@ public class CalciteAssert {
}
}
+ /** Sets a default schema name. */
+ public static class DefaultSchemaPostProcessor
+ implements ConnectionPostProcessor {
+ private final String name;
+
+ public DefaultSchemaPostProcessor(String name) {
+ this.name = name;
+ }
+
+ public Connection apply(Connection connection) throws SQLException {
+ connection.setSchema(name);
+ return connection;
+ }
+ }
+
/** Adds {@link SchemaSpec} (set of schemes) to a connection. */
public static class AddSchemaSpecPostProcessor
implements ConnectionPostProcessor {
@@ -1135,9 +1150,7 @@ public class CalciteAssert {
default:
addSchema(rootSchema, schemaSpec);
}
- if (schemaSpec == SchemaSpec.CLONE_FOODMART) {
- con.setSchema("foodmart2");
- }
+ con.setSchema(schemaSpec.schemaName);
return connection;
}
}
@@ -1755,18 +1768,26 @@ public class CalciteAssert {
/** Specification for common test schemas. */
public enum SchemaSpec {
- REFLECTIVE_FOODMART,
- JDBC_FOODMART,
- CLONE_FOODMART,
- JDBC_FOODMART_WITH_LATTICE,
- GEO,
- HR,
- JDBC_SCOTT,
- SCOTT,
- BLANK,
- LINGUAL,
- POST,
- ORINOCO
+ REFLECTIVE_FOODMART("foodmart"),
+ JDBC_FOODMART("foodmart"),
+ CLONE_FOODMART("foodmart2"),
+ JDBC_FOODMART_WITH_LATTICE("lattice"),
+ GEO("GEO"),
+ HR("hr"),
+ JDBC_SCOTT("JDBC_SCOTT"),
+ SCOTT("scott"),
+ BLANK("BLANK"),
+ LINGUAL("SALES"),
+ POST("POST"),
+ ORINOCO("ORINOCO");
+
+ /** The name of the schema that is usually created from this specification.
+ * (Names are not unique, and you can use another name if you wish.) */
+ public final String schemaName;
+
+ SchemaSpec(String schemaName) {
+ this.schemaName = schemaName;
+ }
}
/** Converts a {@link ResultSet} to string. */
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/core/src/test/java/org/apache/calcite/test/JdbcFrontJdbcBackTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcFrontJdbcBackTest.java b/core/src/test/java/org/apache/calcite/test/JdbcFrontJdbcBackTest.java
index a0a753c..3f9ec26 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcFrontJdbcBackTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcFrontJdbcBackTest.java
@@ -137,7 +137,6 @@ public class JdbcFrontJdbcBackTest {
@Test public void testCase() {
that()
.with(CalciteAssert.Config.JDBC_FOODMART)
- .withDefaultSchema("foodmart")
.query("select\n"
+ " case when \"sales_fact_1997\".\"promotion_id\" = 1 then 0\n"
+ " else \"sales_fact_1997\".\"store_sales\" end as \"c0\"\n"
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/core/src/test/java/org/apache/calcite/test/QuidemTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/QuidemTest.java b/core/src/test/java/org/apache/calcite/test/QuidemTest.java
index e70c7e9..6bf727f 100644
--- a/core/src/test/java/org/apache/calcite/test/QuidemTest.java
+++ b/core/src/test/java/org/apache/calcite/test/QuidemTest.java
@@ -35,6 +35,7 @@ import org.apache.calcite.util.Util;
import com.google.common.collect.Lists;
import com.google.common.io.PatternFilenameFilter;
+import net.hydromatic.quidem.CommandHandler;
import net.hydromatic.quidem.Quidem;
import org.junit.Test;
@@ -152,7 +153,11 @@ public abstract class QuidemTest {
try (final Reader reader = Util.reader(inFile);
final Writer writer = Util.printWriter(outFile);
final Closer closer = new Closer()) {
- new Quidem(reader, writer, QuidemTest::getEnv, createConnectionFactory())
+ final Quidem.Config config = Quidem.configBuilder()
+ .withReader(reader)
+ .withWriter(writer)
+ .withConnectionFactory(createConnectionFactory())
+ .withCommandHandler(createCommandHandler())
.withPropertyHandler((propertyName, value) -> {
if (propertyName.equals("bindable")) {
final boolean b = value instanceof Boolean
@@ -165,7 +170,9 @@ public abstract class QuidemTest {
closer.add(Prepare.THREAD_EXPAND.push(b));
}
})
- .execute();
+ .withEnv(QuidemTest::getEnv)
+ .build();
+ new Quidem(config).execute();
}
final String diff = DiffTestCase.diff(inFile, outFile);
if (!diff.isEmpty()) {
@@ -174,6 +181,11 @@ public abstract class QuidemTest {
}
}
+ /** Creates a command handler. */
+ protected CommandHandler createCommandHandler() {
+ return Quidem.EMPTY_COMMAND_HANDLER;
+ }
+
/** Creates a connection factory. */
protected Quidem.ConnectionFactory createConnectionFactory() {
return new QuidemConnectionFactory();
@@ -246,7 +258,6 @@ public abstract class QuidemTest {
return CalciteAssert.that()
.with(CalciteAssert.Config.REGULAR)
.with(CalciteAssert.SchemaSpec.POST)
- .withDefaultSchema("POST")
.connect();
case "catchall":
return CalciteAssert.that()
@@ -257,7 +268,6 @@ public abstract class QuidemTest {
case "orinoco":
return CalciteAssert.that()
.with(CalciteAssert.SchemaSpec.ORINOCO)
- .withDefaultSchema("ORINOCO")
.connect();
case "blank":
return CalciteAssert.that()
@@ -265,7 +275,6 @@ public abstract class QuidemTest {
"org.apache.calcite.sql.parser.parserextensiontesting"
+ ".ExtensionSqlParserImpl#FACTORY")
.with(CalciteAssert.SchemaSpec.BLANK)
- .withDefaultSchema("BLANK")
.connect();
case "seq":
final Connection connection = CalciteAssert.that()
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 8ac7193..bea1327 100644
--- a/pom.xml
+++ b/pom.xml
@@ -136,6 +136,18 @@ limitations under the License.
<xerces.version>2.9.1</xerces.version>
<sketches.version>0.9.0</sketches.version>
<fmpp.version>0.9.14</fmpp.version>
+
+ <!-- Other properties (not version numbers) -->
+ <maven-javadoc-plugin.excludePackageNames>
+ org.apache.calcite.benchmarks.generated,
+ org.apache.calcite.sql.parser.babel,
+ org.apache.calcite.sql.parser.ddl,
+ org.apache.calcite.sql.parser.impl,
+ org.apache.calcite.sql.parser.parserextensiontesting,
+ org.apache.calcite.piglet.parser,
+ org.openjdk.jmh,org.apache.calcite.adapter.elasticsearch2
+ </maven-javadoc-plugin.excludePackageNames>
+ <maven-javadoc-plugin.link>https://docs.oracle.com/javase/9/docs/api/</maven-javadoc-plugin.link>
</properties>
<issueManagement>
@@ -151,6 +163,7 @@ limitations under the License.
</scm>
<modules>
+ <module>babel</module>
<module>cassandra</module>
<module>core</module>
<module>druid</module>
@@ -720,9 +733,9 @@ limitations under the License.
<configuration>
<additionalparam>-html5</additionalparam>
<links>
- <link>https://docs.oracle.com/javase/9/docs/api/</link>
+ <link>${maven-javadoc-plugin.link}</link>
</links>
- <excludePackageNames>org.apache.calcite.benchmarks.generated,org.apache.calcite.sql.parser.ddl,org.apache.calcite.sql.parser.impl,org.apache.calcite.sql.parser.parserextensiontesting,org.apache.calcite.piglet.parser,org.openjdk.jmh,org.apache.calcite.adapter.elasticsearch2</excludePackageNames>
+ <excludePackageNames>${maven-javadoc-plugin.excludePackageNames}</excludePackageNames>
<show>private</show>
</configuration>
</plugin>
@@ -960,9 +973,9 @@ limitations under the License.
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<links>
- <link>https://docs.oracle.com/javase/8/docs/api/</link>
+ <link>${maven-javadoc-plugin.link}</link>
</links>
- <excludePackageNames>org.apache.calcite.benchmarks.generated,org.apache.calcite.sql.parser.ddl,org.apache.calcite.sql.parser.impl,org.apache.calcite.sql.parser.parserextensiontesting,org.apache.calcite.piglet.parser,org.openjdk.jmh,org.apache.calcite.adapter.elasticsearch2</excludePackageNames>
+ <excludePackageNames>${maven-javadoc-plugin.excludePackageNames}</excludePackageNames>
<notimestamp>true</notimestamp>
<windowtitle>Apache Calcite API</windowtitle>
</configuration>
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/server/src/test/resources/sql/materialized_view.iq
----------------------------------------------------------------------
diff --git a/server/src/test/resources/sql/materialized_view.iq b/server/src/test/resources/sql/materialized_view.iq
index e587313..0e02a18 100644
--- a/server/src/test/resources/sql/materialized_view.iq
+++ b/server/src/test/resources/sql/materialized_view.iq
@@ -93,12 +93,12 @@ drop materialized view if exists v;
# Create materialized view without AS - fails
create materialized view d;
-Encountered "<EOF>" at line 1, column 27.
+Encountered "<EOF>" at line 1, column 26.
!error
# Create materialized view without AS - fails
create materialized view d (x, y);
-Encountered "<EOF>" at line 1, column 34.
+Encountered "<EOF>" at line 1, column 33.
!error
# Create materialized view without AS - fails
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e50a532/server/src/test/resources/sql/schema.iq
----------------------------------------------------------------------
diff --git a/server/src/test/resources/sql/schema.iq b/server/src/test/resources/sql/schema.iq
index 65c6396..82ad470 100755
--- a/server/src/test/resources/sql/schema.iq
+++ b/server/src/test/resources/sql/schema.iq
@@ -91,7 +91,7 @@ Encountered "library" at line 1, column 18.
!error
create foreign schema fs;
-Encountered "<EOF>" at line 1, column 25.
+Encountered "<EOF>" at line 1, column 24.
Was expecting one of:
"TYPE" ...
"LIBRARY" ...