From 402cdd273f0926fa2a500645ebac297036658579 Mon Sep 17 00:00:00 2001 From: Julian Hyde Date: Tue, 21 Apr 2015 21:43:12 -0700 Subject: [PATCH 1/3] PHOENIX-1706 Create skeleton for parsing DDL --- phoenix-core/pom.xml | 91 ++++++++++++ .../apache/phoenix/calcite/CalciteTest.java | 140 ++++++++++++------ phoenix-core/src/main/codegen/config.fmpp | 22 +++ phoenix-core/src/main/codegen/data/Parser.tdd | 58 ++++++++ .../src/main/codegen/includes/license.ftl | 18 +++ .../src/main/codegen/includes/parserImpls.ftl | 36 +++++ .../calcite/jdbc/PhoenixPrepareImpl.java | 8 + .../phoenix/calcite/parse/SqlCommit.java | 44 ++++++ 8 files changed, 369 insertions(+), 48 deletions(-) create mode 100644 phoenix-core/src/main/codegen/config.fmpp create mode 100644 phoenix-core/src/main/codegen/data/Parser.tdd create mode 100644 phoenix-core/src/main/codegen/includes/license.ftl create mode 100644 phoenix-core/src/main/codegen/includes/parserImpls.ftl create mode 100644 phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCommit.java diff --git a/phoenix-core/pom.xml b/phoenix-core/pom.xml index b5d3cbf2d8c..0bf2f3df223 100644 --- a/phoenix-core/pom.xml +++ b/phoenix-core/pom.xml @@ -89,6 +89,53 @@ + + maven-resources-plugin + + + copy-fmpp-resources + initialize + + copy-resources + + + ${project.build.directory}/codegen + + + src/main/codegen + false + + + + + + + + com.googlecode.fmpp-maven-plugin + fmpp-maven-plugin + 1.0 + + + org.freemarker + freemarker + 2.3.19 + + + + + generate-fmpp-sources + generate-sources + + generate + + + ${project.build.directory}/codegen/config.fmpp + target/generated-sources + ${project.build.directory}/codegen/templates + + + + org.codehaus.mojo build-helper-maven-plugin @@ -108,6 +155,29 @@ + + org.codehaus.mojo + javacc-maven-plugin + 2.4 + + + generate-sources + javacc + + javacc + + + ${project.build.directory}/generated-sources/ + + **/Parser.jj + + 2 + false + ${project.build.directory}/generated-sources/ + + + + org.antlr @@ -208,6 +278,27 @@ maven-dependency-plugin + + + unpack-parser-template + initialize + + unpack + + + + + org.apache.calcite + calcite-core + jar + true + ${project.build.directory}/ + **/Parser.jj + + + + create-phoenix-generated-classpath diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java index b96c2a20db2..8e012417bd6 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java @@ -1,3 +1,20 @@ +/* + * 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.phoenix.calcite; import com.google.common.collect.Lists; @@ -10,6 +27,7 @@ import org.apache.phoenix.schema.TableAlreadyExistsException; import org.apache.phoenix.util.PropertiesUtil; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import java.io.File; @@ -120,6 +138,18 @@ public Sql explainIs(String expected) { return this; } + + public boolean execute() { + try { + final Statement statement = start.getConnection().createStatement(); + final boolean execute = statement.execute(sql); + statement.close(); + return execute; + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + public List getResult(String sql) { try { final Statement statement = start.getConnection().createStatement(); @@ -423,25 +453,29 @@ protected void createIndices(String... indexDDL) throws Exception { {"invalid001", "INVALID-1", null, null}}) .close(); - start().sql("select t1.entity_id, t2.a_string, t1.organization_id from aTable t1 join aTable t2 on t1.organization_id = t2.organization_id and t1.entity_id = t2.entity_id") + start().sql("select t1.entity_id, t2.a_string, t1.organization_id from aTable t1 join aTable t2 on t1.organization_id = t2.organization_id and t1.entity_id = t2.entity_id") .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixClientProject(ENTITY_ID=[$1], A_STRING=[$4], ORGANIZATION_ID=[$0])\n" + - " PhoenixClientJoin(condition=[AND(=($0, $2), =($1, $3))], joinType=[inner])\n" + - " PhoenixToClientConverter\n" + - " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + - " PhoenixToClientConverter\n" + - " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") + " PhoenixClientProject(ENTITY_ID=[$1], A_STRING=[$4], ORGANIZATION_ID=[$0])\n" + + + " PhoenixClientJoin(condition=[AND(=($0, $2), =($1, $3))], joinType=[inner])\n" + + + " PhoenixToClientConverter\n" + + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1])\n" + + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + + " PhoenixToClientConverter\n" + + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") .resultIs(new Object[][] { - {"00A123122312312", "a", "00D300000000XHP"}, - {"00A223122312312", "a", "00D300000000XHP"}, - {"00A323122312312", "a", "00D300000000XHP"}, - {"00A423122312312", "a", "00D300000000XHP"}, - {"00B523122312312", "b", "00D300000000XHP"}, - {"00B623122312312", "b", "00D300000000XHP"}, - {"00B723122312312", "b", "00D300000000XHP"}, - {"00B823122312312", "b", "00D300000000XHP"}, + {"00A123122312312", "a", "00D300000000XHP"}, + {"00A223122312312", "a", "00D300000000XHP"}, + {"00A323122312312", "a", "00D300000000XHP"}, + {"00A423122312312", "a", "00D300000000XHP"}, + {"00B523122312312", "b", "00D300000000XHP"}, + {"00B623122312312", "b", "00D300000000XHP"}, + {"00B723122312312", "b", "00D300000000XHP"}, + {"00B823122312312", "b", "00D300000000XHP"}, {"00C923122312312", "c", "00D300000000XHP"}}) .close(); } @@ -494,26 +528,30 @@ protected void createIndices(String... indexDDL) throws Exception { {"00A423122312312", "a", "00D300000000XHP"}}) .close(); - start().sql("select t1.entity_id, t2.a_string, t3.organization_id from aTable t1 join aTable t2 on t1.entity_id = t2.entity_id and t1.organization_id = t2.organization_id join atable t3 on t1.entity_id = t3.entity_id and t1.organization_id = t3.organization_id") + start().sql("select t1.entity_id, t2.a_string, t3.organization_id from aTable t1 join aTable t2 on t1.entity_id = t2.entity_id and t1.organization_id = t2.organization_id join atable t3 on t1.entity_id = t3.entity_id and t1.organization_id = t3.organization_id") .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixClientProject(ENTITY_ID=[$19], A_STRING=[$2], ORGANIZATION_ID=[$36])\n" + - " PhoenixToClientConverter\n" + - " PhoenixServerJoin(condition=[AND(=($19, $1), =($18, $0))], joinType=[inner])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + - " PhoenixToClientConverter\n" + - " PhoenixServerJoin(condition=[AND(=($1, $19), =($0, $18))], joinType=[inner])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + - " PhoenixToClientConverter\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") + " PhoenixClientProject(ENTITY_ID=[$19], A_STRING=[$2], ORGANIZATION_ID=[$36])\n" + + + " PhoenixToClientConverter\n" + + " PhoenixServerJoin(condition=[AND(=($19, $1), =($18, $0))], joinType=[inner])\n" + + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + + " PhoenixToClientConverter\n" + + " PhoenixServerJoin(condition=[AND(=($1, $19), =($0, $18))], joinType=[inner])\n" + + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + + + " PhoenixToClientConverter\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") .resultIs(new Object[][] { - {"00A123122312312", "a", "00D300000000XHP"}, - {"00A223122312312", "a", "00D300000000XHP"}, - {"00A323122312312", "a", "00D300000000XHP"}, - {"00A423122312312", "a", "00D300000000XHP"}, - {"00B523122312312", "b", "00D300000000XHP"}, - {"00B623122312312", "b", "00D300000000XHP"}, - {"00B723122312312", "b", "00D300000000XHP"}, - {"00B823122312312", "b", "00D300000000XHP"}, + {"00A123122312312", "a", "00D300000000XHP"}, + {"00A223122312312", "a", "00D300000000XHP"}, + {"00A323122312312", "a", "00D300000000XHP"}, + {"00A423122312312", "a", "00D300000000XHP"}, + {"00B523122312312", "b", "00D300000000XHP"}, + {"00B623122312312", "b", "00D300000000XHP"}, + {"00B723122312312", "b", "00D300000000XHP"}, + {"00B823122312312", "b", "00D300000000XHP"}, {"00C923122312312", "c", "00D300000000XHP"}}) .close(); } @@ -816,7 +854,7 @@ protected void createIndices(String... indexDDL) throws Exception { {"000000000000005", 5000}}) .close(); } - + @Test public void testScalarSubquery() { start().sql("select \"item_id\", name, (select max(quantity) sq \n" + "from " + JOIN_ORDER_TABLE_FULL_NAME + " o where o.\"item_id\" = i.\"item_id\")\n" @@ -833,12 +871,12 @@ protected void createIndices(String... indexDDL) throws Exception { " PhoenixServerProject(item_id=[$0])\n" + " PhoenixTableScan(table=[[phoenix, Join, ItemTable]])\n") .resultIs(new Object[][] { - new Object[] {"0000000001", "T1", 1000}, - new Object[] {"0000000002", "T2", 3000}, - new Object[] {"0000000003", "T3", 5000}, - new Object[] {"0000000004", "T4", null}, - new Object[] {"0000000005", "T5", null}, - new Object[] {"0000000006", "T6", 4000}, + new Object[] {"0000000001", "T1", 1000}, + new Object[] {"0000000002", "T2", 3000}, + new Object[] {"0000000003", "T3", 5000}, + new Object[] {"0000000004", "T4", null}, + new Object[] {"0000000005", "T5", null}, + new Object[] {"0000000006", "T6", 4000}, new Object[] {"invalid001", "INVALID-1", null}}) .close(); @@ -857,10 +895,10 @@ protected void createIndices(String... indexDDL) throws Exception { " PhoenixServerAggregate(group=[{0}])\n" + " PhoenixTableScan(table=[[phoenix, Join, ItemTable]], filter=[<($0, '0000000006')])\n") .resultIs(new Object[][] { - new Object[] {"0000000001", "T1", 1000}, - new Object[] {"0000000002", "T2", 3000}, - new Object[] {"0000000003", "T3", 5000}, - new Object[] {"0000000004", "T4", null}, + new Object[] {"0000000001", "T1", 1000}, + new Object[] {"0000000002", "T2", 3000}, + new Object[] {"0000000003", "T3", 5000}, + new Object[] {"0000000004", "T4", null}, new Object[] {"0000000005", "T5", null}}) .close();; } @@ -961,10 +999,16 @@ protected void createIndices(String... indexDDL) throws Exception { .resultIs(new Object[][] { {"00C923122312312", "c"}, {"00A423122312312", "a"}, - {"00A323122312312", "a"}}) + {"00A323122312312", "a"}}) .close(); } - + + /** Tests a simple command that is defined in Phoenix's extended SQL parser. */ + @Ignore + @Test public void testCommit() { + start().sql("commit").execute(); + } + @Test public void testConnectJoinHsqldb() { final Start start = new Start(new Properties(), false) { @Override diff --git a/phoenix-core/src/main/codegen/config.fmpp b/phoenix-core/src/main/codegen/config.fmpp new file mode 100644 index 00000000000..283a824fa53 --- /dev/null +++ b/phoenix-core/src/main/codegen/config.fmpp @@ -0,0 +1,22 @@ +# 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: tdd(../data/Parser.tdd) +} +freemarkerLinks: { + includes: includes/ +} diff --git a/phoenix-core/src/main/codegen/data/Parser.tdd b/phoenix-core/src/main/codegen/data/Parser.tdd new file mode 100644 index 00000000000..90d592f354e --- /dev/null +++ b/phoenix-core/src/main/codegen/data/Parser.tdd @@ -0,0 +1,58 @@ +# 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. + +{ + # Generated parser implementation class package and name + package: "org.apache.phoenix.calcite.parser", + class: "PhoenixParserImpl", + + # List of import statements. + imports: [ + "org.apache.phoenix.calcite.parse.*", + "java.util.*" + ] + + # List of keywords. + keywords: [ + ] + + # List of methods for parsing custom SQL statements. + statementParserMethods: [ + "SqlCommit()" + ] + + # List of methods for parsing custom literals. + # Example: ParseJsonLiteral(). + literalParserMethods: [ + ] + + # List of methods for parsing custom data types. + dataTypeParserMethods: [ + ] + + # 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 + +} diff --git a/phoenix-core/src/main/codegen/includes/license.ftl b/phoenix-core/src/main/codegen/includes/license.ftl new file mode 100644 index 00000000000..0455fd87ddc --- /dev/null +++ b/phoenix-core/src/main/codegen/includes/license.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. + ******************************************************************************/ \ No newline at end of file diff --git a/phoenix-core/src/main/codegen/includes/parserImpls.ftl b/phoenix-core/src/main/codegen/includes/parserImpls.ftl new file mode 100644 index 00000000000..42aa48c39ea --- /dev/null +++ b/phoenix-core/src/main/codegen/includes/parserImpls.ftl @@ -0,0 +1,36 @@ +<#-- +// 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. +--> + +<#-- + Add implementations of additional parser statements here. + Each implementation should return an object of SqlNode type. +--> + +/** + * Parses statement + * COMMIT + */ +SqlNode SqlCommit() : +{ + SqlParserPos pos; +} +{ + { pos = getPos(); } + { + return new SqlCommit(pos); + } +} diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java index 0c3ced9541c..22d5d041bca 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java @@ -7,7 +7,9 @@ import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.prepare.CalcitePrepareImpl; import org.apache.calcite.rel.rules.JoinCommuteRule; +import org.apache.calcite.sql.parser.SqlParser; import org.apache.phoenix.calcite.PhoenixSchema; +import org.apache.phoenix.calcite.parser.PhoenixParserImpl; import org.apache.phoenix.calcite.rules.PhoenixAddScanLimitRule; import org.apache.phoenix.calcite.rules.PhoenixCompactClientSortRule; import org.apache.phoenix.calcite.rules.PhoenixFilterScanMergeRule; @@ -22,6 +24,12 @@ public PhoenixPrepareImpl(RelOptRule[] defaultConverterRules) { this.defaultConverterRules = defaultConverterRules; } + @Override + protected SqlParser.ConfigBuilder createParserConfig() { + return super.createParserConfig() + .setParserFactory(PhoenixParserImpl.FACTORY); + } + @Override protected RelOptPlanner createPlanner( final CalcitePrepare.Context prepareContext, diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCommit.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCommit.java new file mode 100644 index 00000000000..a7d206e21cc --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCommit.java @@ -0,0 +1,44 @@ +/* + * 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.phoenix.calcite.parse; + +import com.google.common.collect.ImmutableList; + +import org.apache.calcite.sql.SqlCall; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.SqlOperator; +import org.apache.calcite.sql.parser.SqlParserPos; + +import java.util.List; + +/** + * Parse tree node for SQL {@code COMMIT} command. + */ +public class SqlCommit extends SqlCall { + public SqlCommit(SqlParserPos pos) { + super(pos); + } + + public SqlOperator getOperator() { + throw new UnsupportedOperationException(); + } + + public List getOperandList() { + return ImmutableList.of(); + } +} From b58ad870811b0b074250671992c8185c349b0297 Mon Sep 17 00:00:00 2001 From: Julian Hyde Date: Thu, 20 Aug 2015 13:18:28 -0700 Subject: [PATCH 2/3] work in progress --- .../apache/phoenix/calcite/CalciteTest.java | 4 ++ phoenix-core/src/main/codegen/data/Parser.tdd | 3 +- .../src/main/codegen/includes/parserImpls.ftl | 30 +++++++++ .../calcite/jdbc/PhoenixPrepareImpl.java | 9 +++ .../phoenix/calcite/parse/SqlCreateView.java | 64 +++++++++++++++++++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCreateView.java diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java index 8e012417bd6..bc236382a10 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java @@ -1009,6 +1009,10 @@ protected void createIndices(String... indexDDL) throws Exception { start().sql("commit").execute(); } + @Test public void testCreateView() { + start().sql("create view v as select * from (values (1, 'a'), (2, 'b')) as t(x, y)").execute(); + } + @Test public void testConnectJoinHsqldb() { final Start start = new Start(new Properties(), false) { @Override diff --git a/phoenix-core/src/main/codegen/data/Parser.tdd b/phoenix-core/src/main/codegen/data/Parser.tdd index 90d592f354e..9406eda718d 100644 --- a/phoenix-core/src/main/codegen/data/Parser.tdd +++ b/phoenix-core/src/main/codegen/data/Parser.tdd @@ -31,7 +31,8 @@ # List of methods for parsing custom SQL statements. statementParserMethods: [ - "SqlCommit()" + "SqlCommit()", + "SqlCreateView()" ] # List of methods for parsing custom literals. diff --git a/phoenix-core/src/main/codegen/includes/parserImpls.ftl b/phoenix-core/src/main/codegen/includes/parserImpls.ftl index 42aa48c39ea..bc1640eac6c 100644 --- a/phoenix-core/src/main/codegen/includes/parserImpls.ftl +++ b/phoenix-core/src/main/codegen/includes/parserImpls.ftl @@ -34,3 +34,33 @@ SqlNode SqlCommit() : return new SqlCommit(pos); } } + +// Remove when +// [CALCITE-851] Add original SQL string as a field in the parser +// is fixed. +JAVACODE +public String originalSql() { + return org.apache.phoenix.calcite.jdbc.PhoenixPrepareImpl.THREAD_SQL_STRING.get(); +} + +SqlNode SqlCreateView() : +{ + SqlParserPos pos; + SqlIdentifier name; + SqlNode query; +} +{ + { pos = getPos(); } name = CompoundIdentifier() + + query = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY) + { + String sql = originalSql(); + SqlParserPos pos2 = query.getParserPosition(); + SqlParserPos pos3 = getPos(); + int start = SqlParserUtil.lineColToIndex(sql, pos2.getLineNum(), pos2.getColumnNum()); + int end = SqlParserUtil.lineColToIndex(sql, pos3.getEndLineNum(), pos3.getEndColumnNum()); + String queryString = sql.substring(start, end + 1); + System.out.println("[" + queryString + "]"); + return new SqlCreateView(pos.plus(pos3), name, query, queryString); + } +} diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java index 22d5d041bca..b4c34b26675 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java @@ -17,6 +17,9 @@ import org.apache.phoenix.calcite.rules.PhoenixJoinSingleValueAggregateMergeRule; public class PhoenixPrepareImpl extends CalcitePrepareImpl { + public static final ThreadLocal THREAD_SQL_STRING = + new ThreadLocal<>(); + protected final RelOptRule[] defaultConverterRules; public PhoenixPrepareImpl(RelOptRule[] defaultConverterRules) { @@ -30,6 +33,12 @@ protected SqlParser.ConfigBuilder createParserConfig() { .setParserFactory(PhoenixParserImpl.FACTORY); } + protected SqlParser createParser(String sql, + SqlParser.ConfigBuilder parserConfig) { + THREAD_SQL_STRING.set(sql); + return SqlParser.create(sql, parserConfig.build()); + } + @Override protected RelOptPlanner createPlanner( final CalcitePrepare.Context prepareContext, diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCreateView.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCreateView.java new file mode 100644 index 00000000000..cd074811d48 --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCreateView.java @@ -0,0 +1,64 @@ +/* + * 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.phoenix.calcite.parse; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.sql.SqlCall; +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.SqlKind; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.SqlOperator; +import org.apache.calcite.sql.SqlSpecialOperator; +import org.apache.calcite.sql.SqlSyntax; +import org.apache.calcite.sql.SqlWriter; +import org.apache.calcite.sql.parser.SqlParserPos; + +import java.util.List; + +/** + * Parse tree node for SQL {@code CREATE VIEW} command. + */ +public class SqlCreateView extends SqlCall { + public final SqlIdentifier name; + public final SqlNode query; + public final String queryString; + + /** Creates a CREATE VIEW. */ + public SqlCreateView(SqlParserPos pos, SqlIdentifier name, SqlNode query, String queryString) { + super(pos); + this.name = name; + this.query = query; + this.queryString = queryString; + } + + public SqlOperator getOperator() { + return new SqlSpecialOperator("CREATE VIEW", SqlKind.OTHER) { + @Override + public void unparse(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) { + writer.sep("CREATE VIEW"); + name.unparse(writer, 0, 0); + writer.sep(" "); + query.unparse(writer, 0, 0); + } + }; + } + + public List getOperandList() { + return ImmutableList.of(name, query); + } +} From 4bc3e4105d3d471c35e10e0023f558ab6cdada54 Mon Sep 17 00:00:00 2001 From: Julian Hyde Date: Thu, 20 Aug 2015 16:00:46 -0700 Subject: [PATCH 3/3] create view now works depends on calcite changes in https://github.com/julianhyde/incubator-calcite/tree/852-ddl --- .../calcite/jdbc/PhoenixPrepareImpl.java | 14 ++++++++++++ .../phoenix/calcite/parse/SqlCreateView.java | 22 +++++++++---------- .../phoenix/calcite/parse/SqlDdlOperator.java | 20 +++++++++++++++++ pom.xml | 8 +++---- 4 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlDdlOperator.java diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java index b4c34b26675..226cf7026ec 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java @@ -7,8 +7,10 @@ import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.prepare.CalcitePrepareImpl; import org.apache.calcite.rel.rules.JoinCommuteRule; +import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.parser.SqlParser; import org.apache.phoenix.calcite.PhoenixSchema; +import org.apache.phoenix.calcite.parse.SqlCreateView; import org.apache.phoenix.calcite.parser.PhoenixParserImpl; import org.apache.phoenix.calcite.rules.PhoenixAddScanLimitRule; import org.apache.phoenix.calcite.rules.PhoenixCompactClientSortRule; @@ -70,4 +72,16 @@ protected RelOptPlanner createPlanner( return planner; } + + @Override + public void executeDdl(Context context, SqlNode node) { + switch (node.getKind()) { + case CREATE_VIEW: + final SqlCreateView cv = (SqlCreateView) node; + System.out.println("Create view: " + cv.name); + break; + default: + throw new AssertionError("unknown DDL type " + node.getKind() + " " + node.getClass()); + } + } } diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCreateView.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCreateView.java index cd074811d48..8d5af1a6cce 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCreateView.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlCreateView.java @@ -23,8 +23,6 @@ import org.apache.calcite.sql.SqlKind; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlOperator; -import org.apache.calcite.sql.SqlSpecialOperator; -import org.apache.calcite.sql.SqlSyntax; import org.apache.calcite.sql.SqlWriter; import org.apache.calcite.sql.parser.SqlParserPos; @@ -34,6 +32,8 @@ * Parse tree node for SQL {@code CREATE VIEW} command. */ public class SqlCreateView extends SqlCall { + public static final SqlOperator OPERATOR = new SqlDdlOperator("CREATE VIEW", SqlKind.CREATE_VIEW); + public final SqlIdentifier name; public final SqlNode query; public final String queryString; @@ -47,18 +47,18 @@ public SqlCreateView(SqlParserPos pos, SqlIdentifier name, SqlNode query, String } public SqlOperator getOperator() { - return new SqlSpecialOperator("CREATE VIEW", SqlKind.OTHER) { - @Override - public void unparse(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) { - writer.sep("CREATE VIEW"); - name.unparse(writer, 0, 0); - writer.sep(" "); - query.unparse(writer, 0, 0); - } - }; + return OPERATOR; } public List getOperandList() { return ImmutableList.of(name, query); } + + @Override + public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { + writer.keyword("CREATE VIEW"); + name.unparse(writer, 0, 0); + writer.keyword(" "); + query.unparse(writer, 0, 0); + } } diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlDdlOperator.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlDdlOperator.java new file mode 100644 index 00000000000..9c7a18b3c11 --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/parse/SqlDdlOperator.java @@ -0,0 +1,20 @@ +package org.apache.phoenix.calcite.parse; + +import org.apache.calcite.sql.SqlCall; +import org.apache.calcite.sql.SqlKind; +import org.apache.calcite.sql.SqlSpecialOperator; +import org.apache.calcite.sql.SqlWriter; + +/** + * Operator for a DDL statement. + */ +class SqlDdlOperator extends SqlSpecialOperator { + public SqlDdlOperator(String name, SqlKind kind) { + super(name, kind); + } + + @Override + public void unparse(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) { + call.unparse(writer, leftPrec, rightPrec); + } +} diff --git a/pom.xml b/pom.xml index fbdf9de0134..2566d1248ec 100644 --- a/pom.xml +++ b/pom.xml @@ -57,10 +57,10 @@ true - - apache calcite - https://repository.apache.org/content/repositories/orgapachecalcite-1008 - + + + +