Repository: incubator-gearpump Updated Branches: refs/heads/sql e04df0ddd -> 54686e0e2
http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/54686e0e/experiments/sql/src/test/java/org/apache/calcite/planner/CalciteTest.java ---------------------------------------------------------------------- diff --git a/experiments/sql/src/test/java/org/apache/calcite/planner/CalciteTest.java b/experiments/sql/src/test/java/org/apache/calcite/planner/CalciteTest.java deleted file mode 100644 index 4f0247a..0000000 --- a/experiments/sql/src/test/java/org/apache/calcite/planner/CalciteTest.java +++ /dev/null @@ -1,323 +0,0 @@ -/* - * 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.planner; - - -import com.google.common.collect.ImmutableList; -import org.apache.calcite.adapter.enumerable.EnumerableConvention; -import org.apache.calcite.adapter.java.JavaTypeFactory; -import org.apache.calcite.adapter.java.ReflectiveSchema; -import org.apache.calcite.config.CalciteConnectionConfig; -import org.apache.calcite.config.Lex; -import org.apache.calcite.jdbc.CalciteConnection; -import org.apache.calcite.jdbc.CalciteSchema; -import org.apache.calcite.plan.*; -import org.apache.calcite.plan.RelOptTable.ViewExpander; -import org.apache.calcite.plan.volcano.VolcanoPlanner; -import org.apache.calcite.prepare.CalciteCatalogReader; -import org.apache.calcite.rel.RelNode; -import org.apache.calcite.rel.RelRoot; -import org.apache.calcite.rel.rules.*; -import org.apache.calcite.rel.type.RelDataType; -import org.apache.calcite.rex.RexBuilder; -import org.apache.calcite.rex.RexExecutor; -import org.apache.calcite.schema.SchemaPlus; -import org.apache.calcite.sql.SqlNode; -import org.apache.calcite.sql.SqlOperatorTable; -import org.apache.calcite.sql.fun.SqlStdOperatorTable; -import org.apache.calcite.sql.parser.SqlParseException; -import org.apache.calcite.sql.parser.SqlParser; -import org.apache.calcite.sql.validate.SqlConformance; -import org.apache.calcite.sql.validate.SqlConformanceEnum; -import org.apache.calcite.sql.validate.SqlValidator; -import org.apache.calcite.sql.validate.SqlValidatorUtil; -import org.apache.calcite.sql2rel.RelDecorrelator; -import org.apache.calcite.sql2rel.SqlRexConvertletTable; -import org.apache.calcite.sql2rel.SqlToRelConverter; -import org.apache.calcite.tools.FrameworkConfig; -import org.apache.calcite.tools.Frameworks; -import org.apache.calcite.tools.Program; -import org.apache.calcite.tools.Programs; -import org.apache.calcite.util.Util; -import org.apache.calcite.utils.CalciteFrameworkConfiguration; -import org.apache.calcite.validator.CalciteSqlValidator; - -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.List; - -public class CalciteTest { - - private final SqlOperatorTable operatorTable; - private final FrameworkConfig config; - private final ImmutableList<RelTraitDef> traitDefs; - private final SqlParser.Config parserConfig; - private final SqlRexConvertletTable convertletTable; - private State state; - private SchemaPlus defaultSchema; - private JavaTypeFactory typeFactory; - private RelOptPlanner planner; - private RexExecutor executor; - private RelRoot root; - - public CalciteTest(FrameworkConfig config) { - this.config = config; - this.defaultSchema = config.getDefaultSchema(); - this.operatorTable = config.getOperatorTable(); - this.parserConfig = config.getParserConfig(); - this.state = State.STATE_0_CLOSED; - this.traitDefs = config.getTraitDefs(); - this.convertletTable = config.getConvertletTable(); - this.executor = config.getExecutor(); - reset(); - } - - private void ensure(State state) { - if (state == this.state) { - return; - } - if (state.ordinal() < this.state.ordinal()) { - throw new IllegalArgumentException("cannot move to " + state + " from " - + this.state); - } - state.from(this); - } - - public void close() { - typeFactory = null; - state = State.STATE_0_CLOSED; - } - - public void reset() { - ensure(State.STATE_0_CLOSED); - state = State.STATE_1_RESET; - } - - private void ready() { - switch (state) { - case STATE_0_CLOSED: - reset(); - } - ensure(State.STATE_1_RESET); - Frameworks.withPlanner( - new Frameworks.PlannerAction<Void>() { - public Void apply(RelOptCluster cluster, RelOptSchema relOptSchema, - SchemaPlus rootSchema) { - Util.discard(rootSchema); // use our own defaultSchema - typeFactory = (JavaTypeFactory) cluster.getTypeFactory(); - planner = cluster.getPlanner(); - planner.setExecutor(executor); - return null; - } - }, - config); - - state = State.STATE_2_READY; - - // If user specify own traitDef, instead of default default trait, - // first, clear the default trait def registered with planner - // then, register the trait def specified in traitDefs. - if (this.traitDefs != null) { - planner.clearRelTraitDefs(); - for (RelTraitDef def : this.traitDefs) { - planner.addRelTraitDef(def); - } - } - } - - private static SchemaPlus rootSchema(SchemaPlus schema) { - for (; ; ) { - if (schema.getParentSchema() == null) { - return schema; - } - schema = schema.getParentSchema(); - } - } - - private CalciteCatalogReader createCatalogReader() { - SchemaPlus rootSchema = rootSchema(defaultSchema); - return new CalciteCatalogReader( - CalciteSchema.from(rootSchema), - parserConfig.caseSensitive(), - CalciteSchema.from(defaultSchema).path(null), - typeFactory); - } - - private RexBuilder createRexBuilder() { - return new RexBuilder(typeFactory); - } - - private SqlConformance conformance() { - final Context context = config.getContext(); - if (context != null) { - final CalciteConnectionConfig connectionConfig = - context.unwrap(CalciteConnectionConfig.class); - if (connectionConfig != null) { - return connectionConfig.conformance(); - } - } - return SqlConformanceEnum.DEFAULT; - } - - /** - * Implements {@link org.apache.calcite.plan.RelOptTable.ViewExpander} - * interface for {@link org.apache.calcite.tools.Planner}. - */ - public class ViewExpanderImpl implements ViewExpander { - @Override - public RelRoot expandView(RelDataType rowType, String queryString, - List<String> schemaPath, List<String> viewPath) { - SqlParser parser = SqlParser.create(queryString, parserConfig); - SqlNode sqlNode; - try { - sqlNode = parser.parseQuery(); - } catch (SqlParseException e) { - throw new RuntimeException("parse failed", e); - } - - final SqlConformance conformance = conformance(); - final CalciteCatalogReader catalogReader = - createCatalogReader().withSchemaPath(schemaPath); - final SqlValidator validator = - new CalciteSqlValidator(operatorTable, catalogReader, typeFactory, - conformance); - validator.setIdentifierExpansion(true); - final SqlNode validatedSqlNode = validator.validate(sqlNode); - - final RexBuilder rexBuilder = createRexBuilder(); - final RelOptCluster cluster = RelOptCluster.create(planner, rexBuilder); - final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder() - .withTrimUnusedFields(false).withConvertTableAccess(false).build(); - final SqlToRelConverter sqlToRelConverter = - new SqlToRelConverter(new ViewExpanderImpl(), validator, - catalogReader, cluster, convertletTable, config); - - root = sqlToRelConverter.convertQuery(validatedSqlNode, true, false); - root = root.withRel(sqlToRelConverter.flattenTypes(root.rel, true)); - root = root.withRel(RelDecorrelator.decorrelateQuery(root.rel)); - - return CalciteTest.this.root; - } - } - - private enum State { - STATE_0_CLOSED { - @Override - void from(CalciteTest planner) { - planner.close(); - } - }, - STATE_1_RESET { - @Override - void from(CalciteTest planner) { - planner.ensure(STATE_0_CLOSED); - planner.reset(); - } - }, - STATE_2_READY { - @Override - void from(CalciteTest planner) { - STATE_1_RESET.from(planner); - planner.ready(); - } - }, - STATE_3_PARSED, - STATE_4_VALIDATED, - STATE_5_CONVERTED; - - /** - * Moves planner's state to this state. This must be a higher state. - */ - void from(CalciteTest planner) { - throw new IllegalArgumentException("cannot move from " + planner.state - + " to " + this); - } - } - - - void calTest() throws SqlParseException { - -// String sql = "select t.orders.id from t.orders"; -// -// String sql = "select t.products.id " -// + "from t.orders, t.products " -// + "where t.orders.id = t.products.id and quantity>2 "; - - String sql = "SELECT t.products.id AS product_id, t.products.name " - + "AS product_name, t.orders.id AS order_id " - + "FROM t.products JOIN t.orders ON t.products.id = t.orders.id WHERE quantity > 2"; - - final SqlParser.Config parserConfig = SqlParser.configBuilder().setLex(Lex.MYSQL).build(); - - // Parse the query - SqlParser parser = SqlParser.create(sql, parserConfig); - SqlNode sqlNode = parser.parseStmt(); - - // Validate the query - CalciteCatalogReader catalogReader = createCatalogReader(); - SqlValidator validator = SqlValidatorUtil.newValidator( - SqlStdOperatorTable.instance(), catalogReader, typeFactory, SqlConformance.DEFAULT); - SqlNode validatedSqlNode = validator.validate(sqlNode); - - // Convert SqlNode to RelNode - RexBuilder rexBuilder = createRexBuilder(); - RelOptCluster cluster = RelOptCluster.create(planner, rexBuilder); - SqlToRelConverter sqlToRelConverter = new SqlToRelConverter( - new ViewExpanderImpl(), - validator, - createCatalogReader(), - cluster, - convertletTable); - RelRoot root = sqlToRelConverter.convertQuery(validatedSqlNode, false, true); - System.out.println(RelOptUtil.toString(root.rel)); - - // Optimize the plan - RelOptPlanner planner = new VolcanoPlanner(); - - // Create a set of rules to apply - Program program = Programs.ofRules( - FilterProjectTransposeRule.INSTANCE, - ProjectMergeRule.INSTANCE, - FilterMergeRule.INSTANCE, - FilterJoinRule.JOIN, - LoptOptimizeJoinRule.INSTANCE); - - RelTraitSet traitSet = planner.emptyTraitSet().replace(EnumerableConvention.INSTANCE); - - // Execute the program - RelNode optimized = program.run(planner, root.rel, traitSet, ImmutableList.<RelOptMaterialization>of(), ImmutableList.<RelOptLattice>of()); - System.out.println(RelOptUtil.toString(optimized)); - - } - - public static void main(String[] args) throws ClassNotFoundException, SQLException, SqlParseException { - - Class.forName("org.apache.calcite.jdbc.Driver"); - java.sql.Connection connection = DriverManager.getConnection("jdbc:calcite:"); - CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class); - SchemaPlus rootSchema = calciteConnection.getRootSchema(); - rootSchema.add("t", new ReflectiveSchema(new StreamQueryPlanner.Transactions())); - - FrameworkConfig frameworkConfig = CalciteFrameworkConfiguration.getDefaultconfig(rootSchema); - CalciteTest ct = new CalciteTest(frameworkConfig); - ct.ready(); - ct.calTest(); - - } -} http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/54686e0e/experiments/sql/src/test/java/org/apache/calcite/planner/QueryTest.java ---------------------------------------------------------------------- diff --git a/experiments/sql/src/test/java/org/apache/calcite/planner/QueryTest.java b/experiments/sql/src/test/java/org/apache/calcite/planner/QueryTest.java deleted file mode 100644 index 1cc7102..0000000 --- a/experiments/sql/src/test/java/org/apache/calcite/planner/QueryTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.planner; - -import com.google.common.io.Resources; -import org.apache.calcite.jdbc.CalciteConnection; -import org.apache.calcite.model.ModelHandler; -import org.apache.calcite.plan.RelOptUtil; -import org.apache.calcite.rel.RelNode; -import org.apache.calcite.tools.RelConversionException; -import org.apache.calcite.tools.ValidationException; -import org.apache.log4j.Logger; -import org.junit.Test; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.sql.SQLException; - -public class QueryTest { - - private final static Logger logger = Logger.getLogger(QueryTest.class); - - @Test - public void testLogicalPlan() { - - try { - CalciteConnection connection = new Connection(); - String salesSchema = Resources.toString(Query.class.getResource("/model.json"), Charset.defaultCharset()); - new ModelHandler(connection, "inline:" + salesSchema); - - Query queryPlanner = new Query(connection.getRootSchema().getSubSchema(connection.getSchema())); - RelNode logicalPlan = queryPlanner.getLogicalPlan("SELECT item FROM transactions"); - - logger.info("Getting Logical Plan..."); - System.out.println(RelOptUtil.toString(logicalPlan)); - - } catch (IOException e) { - e.printStackTrace(); - } catch (RelConversionException e) { - e.printStackTrace(); - } catch (ValidationException e) { - e.printStackTrace(); - } catch (SQLException e) { - e.printStackTrace(); - } - - } -} http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/54686e0e/experiments/sql/src/test/java/org/apache/gearpump/sql/example/SqlWordCountTest.java ---------------------------------------------------------------------- diff --git a/experiments/sql/src/test/java/org/apache/gearpump/sql/example/SqlWordCountTest.java b/experiments/sql/src/test/java/org/apache/gearpump/sql/example/SqlWordCountTest.java new file mode 100644 index 0000000..64c5af7 --- /dev/null +++ b/experiments/sql/src/test/java/org/apache/gearpump/sql/example/SqlWordCountTest.java @@ -0,0 +1,125 @@ +/* + * 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.gearpump.sql.example; + +import org.apache.calcite.adapter.java.ReflectiveSchema; +import org.apache.calcite.jdbc.CalciteConnection; +import org.apache.calcite.plan.RelOptUtil; +import org.apache.calcite.plan.RelTraitDef; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.schema.SchemaPlus; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.parser.SqlParseException; +import org.apache.calcite.sql.parser.SqlParser; +import org.apache.calcite.tools.*; +import org.apache.gearpump.sql.rel.GearLogicalConvention; +import org.apache.gearpump.sql.rule.GearAggregationRule; +import org.apache.gearpump.sql.rule.GearFlatMapRule; +import org.apache.gearpump.sql.table.SampleString; +import org.apache.gearpump.sql.utils.GearConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.List; + +public class SqlWordCountTest { + + private static final Logger LOG = LoggerFactory.getLogger(SqlWordCountTest.class); + + private Planner getPlanner(List<RelTraitDef> traitDefs, Program... programs) { + try { + return getPlanner(traitDefs, SqlParser.Config.DEFAULT, programs); + } catch (ClassNotFoundException e) { + LOG.error(e.getMessage()); + } catch (SQLException e) { + LOG.error(e.getMessage()); + } + return null; + } + + private Planner getPlanner(List<RelTraitDef> traitDefs, + SqlParser.Config parserConfig, + Program... programs) throws ClassNotFoundException, SQLException { + + Class.forName("org.apache.calcite.jdbc.Driver"); + java.sql.Connection connection = DriverManager.getConnection("jdbc:calcite:"); + CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class); + SchemaPlus rootSchema = calciteConnection.getRootSchema(); + rootSchema.add("STR", new ReflectiveSchema(new SampleString.Stream())); + + final FrameworkConfig config = Frameworks.newConfigBuilder() + .parserConfig(parserConfig) + .defaultSchema(rootSchema) + .traitDefs(traitDefs) + .programs(programs) + .build(); + return Frameworks.getPlanner(config); + } + + void wordCountTest(GearConfiguration gearConfig) throws SqlParseException, + ValidationException, RelConversionException { + + RuleSet ruleSet = RuleSets.ofList( + GearFlatMapRule.INSTANCE, + GearAggregationRule.INSTANCE); + + Planner planner = getPlanner(null, Programs.of(ruleSet)); + + String sql = "SELECT COUNT(*) FROM str.kv GROUP BY str.kv.word"; + System.out.println("SQL Query:-\t" + sql + "\n"); + + SqlNode parse = planner.parse(sql); + System.out.println("SQL Parse Tree:- \n" + parse.toString() + "\n\n"); + + SqlNode validate = planner.validate(parse); + RelNode convert = planner.rel(validate).project(); + System.out.println("Relational Expression:- \n" + RelOptUtil.toString(convert) + "\n"); + + gearConfig.defaultConfiguration(); + gearConfig.ConfigJavaStreamApp(); + + RelTraitSet traitSet = convert.getTraitSet().replace(GearLogicalConvention.INSTANCE); + try { + RelNode transform = planner.transform(0, traitSet, convert); + System.out.println(RelOptUtil.toString(transform)); + } catch (Exception e) { + } + + } + + + public static void main(String[] args) throws ClassNotFoundException, + SQLException, SqlParseException { + + SqlWordCountTest gearSqlWordCount = new SqlWordCountTest(); + + try { + GearConfiguration gearConfig = new GearConfiguration(); + gearSqlWordCount.wordCountTest(gearConfig); + } catch (ValidationException e) { + LOG.error(e.getMessage()); + } catch (RelConversionException e) { + LOG.error(e.getMessage()); + } + + } +} http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/54686e0e/experiments/sql/src/test/java/org/apache/gearpump/sql/planner/CalciteTest.java ---------------------------------------------------------------------- diff --git a/experiments/sql/src/test/java/org/apache/gearpump/sql/planner/CalciteTest.java b/experiments/sql/src/test/java/org/apache/gearpump/sql/planner/CalciteTest.java new file mode 100644 index 0000000..2f21531 --- /dev/null +++ b/experiments/sql/src/test/java/org/apache/gearpump/sql/planner/CalciteTest.java @@ -0,0 +1,397 @@ +/* + * 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.gearpump.sql.planner; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.adapter.enumerable.EnumerableConvention; +import org.apache.calcite.adapter.enumerable.EnumerableRules; +import org.apache.calcite.adapter.java.JavaTypeFactory; +import org.apache.calcite.adapter.java.ReflectiveSchema; +import org.apache.calcite.config.CalciteConnectionConfig; +import org.apache.calcite.config.Lex; +import org.apache.calcite.jdbc.CalciteConnection; +import org.apache.calcite.jdbc.CalciteSchema; +import org.apache.calcite.plan.*; +import org.apache.calcite.plan.RelOptTable.ViewExpander; +import org.apache.calcite.plan.volcano.VolcanoPlanner; +import org.apache.calcite.prepare.CalciteCatalogReader; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.RelRoot; +import org.apache.calcite.rel.rules.LoptOptimizeJoinRule; +import org.apache.calcite.rel.rules.SortRemoveRule; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rex.RexBuilder; +import org.apache.calcite.rex.RexExecutor; +import org.apache.calcite.schema.SchemaPlus; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.SqlOperatorTable; +import org.apache.calcite.sql.fun.SqlStdOperatorTable; +import org.apache.calcite.sql.parser.SqlParseException; +import org.apache.calcite.sql.parser.SqlParser; +import org.apache.calcite.sql.validate.SqlConformance; +import org.apache.calcite.sql.validate.SqlConformanceEnum; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql.validate.SqlValidatorUtil; +import org.apache.calcite.sql2rel.RelDecorrelator; +import org.apache.calcite.sql2rel.SqlRexConvertletTable; +import org.apache.calcite.sql2rel.SqlToRelConverter; +import org.apache.calcite.tools.*; +import org.apache.calcite.util.Util; +import org.apache.gearpump.sql.rule.GearFilterRule; +import org.apache.gearpump.sql.table.SampleTransactions; +import org.apache.gearpump.sql.utils.CalciteFrameworkConfiguration; +import org.apache.gearpump.sql.validator.CalciteSqlValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.List; + +public class CalciteTest { + + private static final Logger LOG = LoggerFactory.getLogger(CalciteTest.class); + + private SqlOperatorTable operatorTable; + private FrameworkConfig config; + private ImmutableList<RelTraitDef> traitDefs; + private SqlParser.Config parserConfig; + private SqlRexConvertletTable convertletTable; + private State state; + private SchemaPlus defaultSchema; + private JavaTypeFactory typeFactory; + private RelOptPlanner planner; + private RexExecutor executor; + private RelRoot root; + + public CalciteTest(FrameworkConfig config) { + this.config = config; + this.defaultSchema = config.getDefaultSchema(); + this.operatorTable = config.getOperatorTable(); + this.parserConfig = config.getParserConfig(); + this.state = State.STATE_0_CLOSED; + this.traitDefs = config.getTraitDefs(); + this.convertletTable = config.getConvertletTable(); + this.executor = config.getExecutor(); + reset(); + } + + public CalciteTest() { + } + + private void ensure(State state) { + if (state == this.state) { + return; + } + if (state.ordinal() < this.state.ordinal()) { + throw new IllegalArgumentException("cannot move to " + state + " from " + + this.state); + } + state.from(this); + } + + public void close() { + typeFactory = null; + state = State.STATE_0_CLOSED; + } + + public void reset() { + ensure(State.STATE_0_CLOSED); + state = State.STATE_1_RESET; + } + + private void ready() { + switch (state) { + case STATE_0_CLOSED: + reset(); + } + ensure(State.STATE_1_RESET); + Frameworks.withPlanner( + new Frameworks.PlannerAction<Void>() { + public Void apply(RelOptCluster cluster, RelOptSchema relOptSchema, + SchemaPlus rootSchema) { + Util.discard(rootSchema); // use our own defaultSchema + typeFactory = (JavaTypeFactory) cluster.getTypeFactory(); + planner = cluster.getPlanner(); + planner.setExecutor(executor); + return null; + } + }, + config); + + state = State.STATE_2_READY; + + // If user specify own traitDef, instead of default default trait, + // first, clear the default trait def registered with planner + // then, register the trait def specified in traitDefs. + if (this.traitDefs != null) { + planner.clearRelTraitDefs(); + for (RelTraitDef def : this.traitDefs) { + planner.addRelTraitDef(def); + } + } + } + + private static SchemaPlus rootSchema(SchemaPlus schema) { + for (; ; ) { + if (schema.getParentSchema() == null) { + return schema; + } + schema = schema.getParentSchema(); + } + } + + private CalciteCatalogReader createCatalogReader() { + SchemaPlus rootSchema = rootSchema(defaultSchema); + return new CalciteCatalogReader( + CalciteSchema.from(rootSchema), + parserConfig.caseSensitive(), + CalciteSchema.from(defaultSchema).path(null), + typeFactory); + } + + private RexBuilder createRexBuilder() { + return new RexBuilder(typeFactory); + } + + private SqlConformance conformance() { + final Context context = config.getContext(); + if (context != null) { + final CalciteConnectionConfig connectionConfig = + context.unwrap(CalciteConnectionConfig.class); + if (connectionConfig != null) { + return connectionConfig.conformance(); + } + } + return SqlConformanceEnum.DEFAULT; + } + + /** + * Implements {@link org.apache.calcite.plan.RelOptTable.ViewExpander} + * interface for {@link org.apache.calcite.tools.Planner}. + */ + public class ViewExpanderImpl implements ViewExpander { + @Override + public RelRoot expandView(RelDataType rowType, String queryString, + List<String> schemaPath, List<String> viewPath) { + SqlParser parser = SqlParser.create(queryString, parserConfig); + SqlNode sqlNode; + try { + sqlNode = parser.parseQuery(); + } catch (SqlParseException e) { + throw new RuntimeException("parse failed", e); + } + + final SqlConformance conformance = conformance(); + final CalciteCatalogReader catalogReader = + createCatalogReader().withSchemaPath(schemaPath); + final SqlValidator validator = + new CalciteSqlValidator(operatorTable, catalogReader, typeFactory, + conformance); + validator.setIdentifierExpansion(true); + final SqlNode validatedSqlNode = validator.validate(sqlNode); + + final RexBuilder rexBuilder = createRexBuilder(); + final RelOptCluster cluster = RelOptCluster.create(planner, rexBuilder); + final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder() + .withTrimUnusedFields(false).withConvertTableAccess(false).build(); + final SqlToRelConverter sqlToRelConverter = + new SqlToRelConverter(new ViewExpanderImpl(), validator, + catalogReader, cluster, convertletTable, config); + + root = sqlToRelConverter.convertQuery(validatedSqlNode, true, false); + root = root.withRel(sqlToRelConverter.flattenTypes(root.rel, true)); + root = root.withRel(RelDecorrelator.decorrelateQuery(root.rel)); + + return CalciteTest.this.root; + } + } + + private enum State { + STATE_0_CLOSED { + @Override + void from(CalciteTest planner) { + planner.close(); + } + }, + STATE_1_RESET { + @Override + void from(CalciteTest planner) { + planner.ensure(STATE_0_CLOSED); + planner.reset(); + } + }, + STATE_2_READY { + @Override + void from(CalciteTest planner) { + STATE_1_RESET.from(planner); + planner.ready(); + } + }, + STATE_3_PARSED, + STATE_4_VALIDATED, + STATE_5_CONVERTED; + + /** + * Moves planner's state to this state. This must be a higher state. + */ + void from(CalciteTest planner) { + throw new IllegalArgumentException("cannot move from " + planner.state + + " to " + this); + } + } + + void calTest() throws SqlParseException { + +// String sql = "select t.orders.id from t.orders"; +// +// String sql = "select t.products.id " +// + "from t.orders, t.products " +// + "where t.orders.id = t.products.id and quantity>2 "; + + String sql = "SELECT t.products.id AS product_id, t.products.name " + + "AS product_name, t.orders.id AS order_id " + + "FROM t.products JOIN t.orders ON t.products.id = t.orders.id WHERE quantity > 2"; + + final SqlParser.Config parserConfig = SqlParser.configBuilder().setLex(Lex.MYSQL).build(); + + // Parse the query + SqlParser parser = SqlParser.create(sql, parserConfig); + SqlNode sqlNode = parser.parseStmt(); + + // Validate the query + CalciteCatalogReader catalogReader = createCatalogReader(); + SqlValidator validator = SqlValidatorUtil.newValidator( + SqlStdOperatorTable.instance(), catalogReader, typeFactory, SqlConformance.DEFAULT); + SqlNode validatedSqlNode = validator.validate(sqlNode); + + // Convert SqlNode to RelNode + RexBuilder rexBuilder = createRexBuilder(); + RelOptCluster cluster = RelOptCluster.create(planner, rexBuilder); + SqlToRelConverter sqlToRelConverter = new SqlToRelConverter( + new ViewExpanderImpl(), + validator, + createCatalogReader(), + cluster, + convertletTable); + RelRoot root = sqlToRelConverter.convertQuery(validatedSqlNode, false, true); + System.out.println(RelOptUtil.toString(root.rel)); + + // Optimize the plan + RelOptPlanner planner = new VolcanoPlanner(); + + // Create a set of rules to apply + Program program = Programs.ofRules( +// FilterProjectTransposeRule.INSTANCE, +// ProjectMergeRule.INSTANCE, +// FilterMergeRule.INSTANCE, +// FilterJoinRule.JOIN, + GearFilterRule.INSTANCE, + LoptOptimizeJoinRule.INSTANCE); + + RelTraitSet traitSet = planner.emptyTraitSet().replace(EnumerableConvention.INSTANCE); + + // Execute the program +// RelNode optimized = program.run(planner, root.rel, traitSet, +// ImmutableList.<RelOptMaterialization>of(), ImmutableList.<RelOptLattice>of()); +// logger.info(RelOptUtil.toString(optimized)); + + } + + // new test ------------------------- + private Planner getPlanner(List<RelTraitDef> traitDefs, Program... programs) { + try { + return getPlanner(traitDefs, SqlParser.Config.DEFAULT, programs); + } catch (ClassNotFoundException e) { + LOG.error(e.getMessage()); + } catch (SQLException e) { + LOG.error(e.getMessage()); + } + return null; + } + + private Planner getPlanner(List<RelTraitDef> traitDefs, + SqlParser.Config parserConfig, + Program... programs) throws ClassNotFoundException, SQLException { + + Class.forName("org.apache.calcite.jdbc.Driver"); + java.sql.Connection connection = DriverManager.getConnection("jdbc:calcite:"); + CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class); + SchemaPlus rootSchema = calciteConnection.getRootSchema(); + rootSchema.add("T", new ReflectiveSchema(new SampleTransactions.Transactions())); + + final FrameworkConfig config = Frameworks.newConfigBuilder() + .parserConfig(parserConfig) + .defaultSchema(rootSchema) + .traitDefs(traitDefs) + .programs(programs) + .build(); + return Frameworks.getPlanner(config); + } + + void calTest2() throws SqlParseException, ValidationException, RelConversionException { + + RuleSet ruleSet = RuleSets.ofList( + SortRemoveRule.INSTANCE, + EnumerableRules.ENUMERABLE_PROJECT_RULE, + EnumerableRules.ENUMERABLE_SORT_RULE); + + Planner planner = getPlanner(null, Programs.of(ruleSet)); + + String sql = "SELECT * FROM t.products ORDER BY t.products.id"; + + SqlNode parse = planner.parse(sql); + System.out.println("SQL Parse Tree:- \n" + parse.toString()); + + SqlNode validate = planner.validate(parse); + RelNode convert = planner.rel(validate).project(); + RelTraitSet traitSet = convert.getTraitSet().replace(EnumerableConvention.INSTANCE); + RelNode transform = planner.transform(0, traitSet, convert); + System.out.println("\n\nRelational Expression:- \n" + RelOptUtil.toString(transform)); + + } + + + public static void main(String[] args) throws ClassNotFoundException, + SQLException, SqlParseException { + + // calTest() +// Class.forName("org.apache.calcite.jdbc.Driver"); +// java.sql.Connection connection = DriverManager.getConnection("jdbc:calcite:"); +// CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class); +// SchemaPlus rootSchema = calciteConnection.getRootSchema(); +// rootSchema.add("t", new ReflectiveSchema(new StreamQueryPlanner.Transactions())); +// +// FrameworkConfig frameworkConfig = CalciteFrameworkConfiguration.getDefaultconfig(rootSchema); +// CalciteTest ct = new CalciteTest(frameworkConfig); +// ct.ready(); +// ct.calTest(); + + // calTest2() + CalciteTest calTest = new CalciteTest(); + try { + calTest.calTest2(); + } catch (ValidationException e) { + LOG.error(e.getMessage()); + } catch (RelConversionException e) { + LOG.error(e.getMessage()); + } + + } +} http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/54686e0e/experiments/sql/src/test/java/org/apache/gearpump/sql/planner/QueryTest.java ---------------------------------------------------------------------- diff --git a/experiments/sql/src/test/java/org/apache/gearpump/sql/planner/QueryTest.java b/experiments/sql/src/test/java/org/apache/gearpump/sql/planner/QueryTest.java new file mode 100644 index 0000000..551beff --- /dev/null +++ b/experiments/sql/src/test/java/org/apache/gearpump/sql/planner/QueryTest.java @@ -0,0 +1,65 @@ +/* + * 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.gearpump.sql.planner; + +import com.google.common.io.Resources; +import org.apache.calcite.jdbc.CalciteConnection; +import org.apache.calcite.model.ModelHandler; +import org.apache.calcite.plan.RelOptUtil; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.tools.RelConversionException; +import org.apache.calcite.tools.ValidationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.junit.Test; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.sql.SQLException; + +public class QueryTest { + + private static final Logger LOG = LoggerFactory.getLogger(QueryTest.class); + + @Test + public void testLogicalPlan() { + + try { + CalciteConnection connection = new Connection(); + String salesSchema = Resources.toString(Query.class.getResource("/model.json"), + Charset.defaultCharset()); + new ModelHandler(connection, "inline:" + salesSchema); + + Query queryPlanner = new Query(connection.getRootSchema().getSubSchema(connection.getSchema())); + RelNode logicalPlan = queryPlanner.getLogicalPlan("SELECT item FROM transactions"); + + System.out.println("Getting Logical Plan...\n" + RelOptUtil.toString(logicalPlan)); + + } catch (IOException e) { + LOG.error(e.getMessage()); + } catch (RelConversionException e) { + LOG.error(e.getMessage()); + } catch (ValidationException e) { + LOG.error(e.getMessage()); + } catch (SQLException e) { + LOG.error(e.getMessage()); + } + + } +} http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/54686e0e/experiments/sql/src/test/resources/model.json ---------------------------------------------------------------------- diff --git a/experiments/sql/src/test/resources/model.json b/experiments/sql/src/test/resources/model.json index 5dfbf53..bfb62ed 100644 --- a/experiments/sql/src/test/resources/model.json +++ b/experiments/sql/src/test/resources/model.json @@ -27,7 +27,7 @@ { "name": "Transactions", "type": "custom", - "factory": "org.apache.calcite.table.TransactionsTableFactory", + "factory": "org.apache.gearpump.sql.table.TransactionsTableFactory", "operand": { "file": "resources/sales/Transactions.csv", "flavor": "scannable"
