Skip to content

Commit

Permalink
CALCITE-1384 Extension point for ALTER statements
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.
  • Loading branch information
Gabriel Reid committed Nov 4, 2016
1 parent 435b6d4 commit ccd5797
Show file tree
Hide file tree
Showing 12 changed files with 445 additions and 34 deletions.
46 changes: 42 additions & 4 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@ 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>${project.build.directory}/generated-test-sources/javacc</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 +205,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 +470,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
4 changes: 4 additions & 0 deletions core/src/main/codegen/config.fmpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ data: {
dataTypeParserMethods: [
]

# List of methods for parsing extensions to ALTER SYSTEM calls
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
53 changes: 45 additions & 8 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 @@ -925,6 +926,8 @@ SqlNode SqlStmt() :
(
stmt = SqlSetOption()
|
stmt = SqlAlter()
|
stmt = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
|
stmt = SqlExplain()
Expand Down Expand Up @@ -2965,21 +2968,17 @@ 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() :
{
SqlParserPos pos = null;
String scope = null;
SqlIdentifier name;
SqlNode val = null;
SqlSetOption setOption = null;
}
{
(
<ALTER> { pos = getPos(); }
scope = Scope()
)?
(
<SET> {
pos = pos == null ? getPos() : pos;
Expand All @@ -2996,6 +2995,9 @@ SqlSetOption SqlSetOption() :
val = new SqlIdentifier(token.image.toUpperCase(), getPos());
}
)
{
setOption = new SqlSetOption(pos.plus(getPos()), null, name, val);
}
|
<RESET> {
pos = pos == null ? getPos() : pos;
Expand All @@ -3007,9 +3009,44 @@ SqlSetOption SqlSetOption() :
name = new SqlIdentifier(token.image.toUpperCase(), getPos());
}
)
{
setOption = new SqlSetOption(pos.plus(getPos()), null, name, val);
}
)
{
return setOption;
}
}

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

<#-- additional literal parser methods are included here -->
<#list parser.alterStatementParserMethods as method>
|
alterNode = ${method}
</#list>
)
{
return new SqlSetOption(pos.plus(getPos()), scope, name, val);
alterNode.setScope(scope);
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
71 changes: 71 additions & 0 deletions core/src/test/codegen/config.fmpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# 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
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 ccd5797

Please sign in to comment.