Skip to content

Commit

Permalink
[CALCITE-1384] Extension point for ALTER statements (Gabriel Reid)
Browse files Browse the repository at this point in the history
Add a parser extension point for parsing of ALTER statements.

The main content of this commit is the addition of an initial
test setup to allow testing parsing extension points within
Calcite itself. This involves the addition of test-specific
parser templates and building of a test-specific parser.

Close apache#322
  • Loading branch information
Gabriel Reid authored and julianhyde committed Nov 8, 2016
1 parent 76fef36 commit 6958ac8
Show file tree
Hide file tree
Showing 13 changed files with 450 additions and 39 deletions.
50 changes: 46 additions & 4 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,20 @@ limitations under the License.

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<!--
<excludes>
<exclude>${project.build.directory}/generated-test-sources/javacc</exclude>
</excludes>
-->
<generatedTestSourcesDirectory>${project.build.directory}/generated-test-sources/javacc</generatedTestSourcesDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
Expand Down Expand Up @@ -195,6 +209,22 @@ limitations under the License.
<isStatic>false</isStatic>
</configuration>
</execution>
<execution>
<id>javacc-test</id>
<phase>generate-test-sources</phase>
<goals>
<goal>javacc</goal>
</goals>
<configuration>
<sourceDirectory>${project.build.directory}/generated-test-sources/fmpp</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-test-sources/javacc</outputDirectory>
<includes>
<include>**/Parser.jj</include>
</includes>
<lookAhead>2</lookAhead>
<isStatic>false</isStatic>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
Expand Down Expand Up @@ -444,18 +474,30 @@ limitations under the License.
<plugin>
<groupId>com.googlecode.fmpp-maven-plugin</groupId>
<artifactId>fmpp-maven-plugin</artifactId>
<configuration>
<cfgFile>src/main/codegen/config.fmpp</cfgFile>
<templateDirectory>src/main/codegen/templates</templateDirectory>
</configuration>
<executions>
<execution>
<configuration>
<cfgFile>src/main/codegen/config.fmpp</cfgFile>
<templateDirectory>src/main/codegen/templates</templateDirectory>
</configuration>
<id>generate-fmpp-sources</id>
<phase>validate</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
<execution>
<configuration>
<cfgFile>src/test/codegen/config.fmpp</cfgFile>
<templateDirectory>src/main/codegen/templates</templateDirectory>
<outputDirectory>${project.build.directory}/generated-test-sources/fmpp</outputDirectory>
</configuration>
<id>generate-fmpp-test-sources</id>
<phase>validate</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/codegen/config.fmpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ data: {
dataTypeParserMethods: [
]

# List of methods for parsing extensions to ALTER SYSTEM calls.
# Each must accept arguments "(SqlParserPos pos, String scope)".
# Example: "SqlUploadJarNode"
alterStatementParserMethods: [
]

# 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
Expand Down
55 changes: 42 additions & 13 deletions core/src/main/codegen/templates/Parser.jj
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.runtime.CalciteContextException;
import org.apache.calcite.sql.JoinConditionType;
import org.apache.calcite.sql.JoinType;
import org.apache.calcite.sql.SqlAlter;
import org.apache.calcite.sql.SqlBinaryOperator;
import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlCharStringLiteral;
Expand Down Expand Up @@ -923,7 +924,9 @@ SqlNode SqlStmt() :
}
{
(
stmt = SqlSetOption()
stmt = SqlSetOption(null, null)
|
stmt = SqlAlter()
|
stmt = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
|
Expand Down Expand Up @@ -2965,21 +2968,15 @@ SqlCall SequenceExpression() :
}

/**
* Parses an expression for setting or resetting an option in SQL, such as QUOTED_IDENTIFIERS,
* or explain plan level (physical/logical).
* Parses "SET <NAME> = VALUE" or "RESET <NAME>", without a leading
* "ALTER <SCOPE>".
*/
SqlSetOption SqlSetOption() :
SqlSetOption SqlSetOption(SqlParserPos pos, String scope) :
{
SqlParserPos pos = null;
String scope = null;
SqlIdentifier name;
SqlNode val = null;
final SqlNode val;
}
{
(
<ALTER> { pos = getPos(); }
scope = Scope()
)?
(
<SET> {
pos = pos == null ? getPos() : pos;
Expand All @@ -2996,20 +2993,52 @@ SqlSetOption SqlSetOption() :
val = new SqlIdentifier(token.image.toUpperCase(), getPos());
}
)
{
return new SqlSetOption(pos.plus(getPos()), scope, name, val);
}
|
<RESET> {
pos = pos == null ? getPos() : pos;
}
(
name = CompoundIdentifier()
|
|
<ALL> {
name = new SqlIdentifier(token.image.toUpperCase(), getPos());
}
)
{
return new SqlSetOption(pos.plus(getPos()), scope, name, null);
}
)
}

/**
* Parses an expression for setting or resetting an option in SQL, such as QUOTED_IDENTIFIERS,
* or explain plan level (physical/logical).
*/
SqlAlter SqlAlter() :
{
final SqlParserPos pos;
final String scope;
final SqlAlter alterNode;
}
{
(
<ALTER> { pos = getPos(); }
scope = Scope()
)
(
alterNode = SqlSetOption(pos, scope)

<#-- additional literal parser methods are included here -->
<#list parser.alterStatementParserMethods as method>
|
alterNode = ${method}(pos, scope)
</#list>
)
{
return new SqlSetOption(pos.plus(getPos()), scope, name, val);
return alterNode;
}
}

Expand Down
60 changes: 60 additions & 0 deletions core/src/main/java/org/apache/calcite/sql/SqlAlter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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;

import org.apache.calcite.sql.parser.SqlParserPos;

/**
* Base class for an ALTER statements parse tree nodes. The portion of the
* statement covered by this class is "ALTER &lt;SCOPE&gt;. Subclasses handle
* whatever comes after the scope.
*/
public abstract class SqlAlter extends SqlCall {

/** Scope of the operation. Values "SYSTEM" and "SESSION" are typical. */
String scope;

public SqlAlter(SqlParserPos pos) {
this(pos, null);
}

public SqlAlter(SqlParserPos pos, String scope) {
super(pos);
this.scope = scope;
}

@Override public final void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
if (scope != null) {
writer.keyword("ALTER");
writer.keyword(scope);
}
unparseAlterOperation(writer, leftPrec, rightPrec);
}

protected abstract void unparseAlterOperation(SqlWriter writer, int leftPrec, int rightPrec);

public String getScope() {
return scope;
}

public void setScope(String scope) {
this.scope = scope;
}

}

// End SqlAlter.java
21 changes: 3 additions & 18 deletions core/src/main/java/org/apache/calcite/sql/SqlSetOption.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
* <li><code>ALTER SESSION RESET ALL</code></li>
* </ul>
*/
public class SqlSetOption extends SqlCall {
public class SqlSetOption extends SqlAlter {
public static final SqlSpecialOperator OPERATOR =
new SqlSpecialOperator("SET_OPTION", SqlKind.SET_OPTION) {
@Override public SqlCall createCall(SqlLiteral functionQualifier,
Expand All @@ -70,9 +70,6 @@ public class SqlSetOption extends SqlCall {
}
};

/** Scope of the assignment. Values "SYSTEM" and "SESSION" are typical. */
String scope;

/** Name of the option as an {@link org.apache.calcite.sql.SqlIdentifier}
* with one or more parts.*/
SqlIdentifier name;
Expand All @@ -94,7 +91,7 @@ public class SqlSetOption extends SqlCall {
*/
public SqlSetOption(SqlParserPos pos, String scope, SqlIdentifier name,
SqlNode value) {
super(pos);
super(pos, scope);
this.scope = scope;
this.name = name;
this.value = value;
Expand Down Expand Up @@ -141,11 +138,7 @@ public SqlSetOption(SqlParserPos pos, String scope, SqlIdentifier name,
}
}

@Override public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
if (scope != null) {
writer.keyword("ALTER");
writer.keyword(scope);
}
@Override protected void unparseAlterOperation(SqlWriter writer, int leftPrec, int rightPrec) {
if (value != null) {
writer.keyword("SET");
} else {
Expand Down Expand Up @@ -174,14 +167,6 @@ public void setName(SqlIdentifier name) {
this.name = name;
}

public String getScope() {
return scope;
}

public void setScope(String scope) {
this.scope = scope;
}

public SqlNode getValue() {
return value;
}
Expand Down
72 changes: 72 additions & 0 deletions core/src/test/codegen/config.fmpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# 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.extension",
class: "ExtensionSqlParserImpl",

# List of import statements.
imports: [
"org.apache.calcite.sql.parser.extension.SqlUploadJarNode"
]

# List of keywords.
keywords: [
"UPLOAD"
"JAR"
]

# List of keywords from "keywords" section that are not reserved.
nonReservedKeywords: [
]

# 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 SYSTEM calls.
# Each must accept arguments "(SqlParserPos pos, String scope)".
alterStatementParserMethods: [
"SqlUploadJarNode"
]

# List of files in @includes directory that have parser method
# implementations for 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/
}
Loading

0 comments on commit 6958ac8

Please sign in to comment.