If you intend to run a query then you should follow the tutorial and try to 
change the csv adapter.  You can add the table to the schema at runtime using 
something like:
---------------------------------------------------------------------

Class.forName("org.apache.calcite.jdbc.Driver");
Properties info = new Properties();
info.setProperty("lex", "MYSQL_ANSI");

final Connection connection = DriverManager.getConnection("jdbc:calcite:", 
info);
CalciteConnection conn = connection.unwrap(CalciteConnection.class);
SchemaPlus root = conn.getRootSchema();
root.add("MYTABLE", new TableImpl());
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery("SELECT * FROM MYTABLE");
---------------------------------------------------------------------

But if you only want to parse, validate and optimize the query plan, you can 
use something like:
---------------------------------------------------------------------
    Table table = new TableImpl();
    final SchemaPlus rootSchema = Frameworks.createRootSchema(true);
    SchemaPlus schema = rootSchema.add("x", new AbstractSchema());
    schema.add("MYTABLE", table);
    List<RelTraitDef> traitDefs = new ArrayList<>();
    traitDefs.add(ConventionTraitDef.INSTANCE);
    traitDefs.add(RelCollationTraitDef.INSTANCE);
    SqlParser.Config parserConfig = 
       SqlParser.configBuilder(SqlParser.Config.DEFAULT)
      .setCaseSensitive(false)
      .build();
      
    final FrameworkConfig config = Frameworks.newConfigBuilder()
        .parserConfig(parserConfig)
        .defaultSchema(schema)
        .traitDefs(traitDefs)
        // define the rules you want to apply

        .programs(Programs.ofRules(Programs.RULE_SET))
        .build();
    Planner planner = Frameworks.getPlanner(config);
    SqlNode n = planner.parse(" SELECT * FROM MYTABLE WHERE ID < 10");
    n = planner.validate(n);
    RelNode root = planner.rel(n).project();
    System.out.println(RelOptUtil.dumpPlan("-- Logical Plan", root, 
SqlExplainFormat.TEXT, 
        SqlExplainLevel.DIGEST_ATTRIBUTES));
    RelOptCluster cluster = root.getCluster();
    final RelOptPlanner optPlanner = cluster.getPlanner();
    RelTraitSet desiredTraits =
        cluster.traitSet().replace(EnumerableConvention.INSTANCE);
    final RelNode newRoot = optPlanner.changeTraits(root, desiredTraits);
    optPlanner.setRoot(newRoot);
    RelNode bestExp = optPlanner.findBestExp();        
System.out.println(RelOptUtil.dumpPlan("-- Best Plan", bestExp, 
SqlExplainFormat.TEXT, 
        SqlExplainLevel.DIGEST_ATTRIBUTES));
 ---------------------------------------------------------------------

The main problem was that you were not setting the desired trait to use 
EnumerableConvention.
You can see that instead of implementing all the interfaces you should use the 
available builders and classes.
Also for implementing Table I think you should extend AbstractTable instead of 
implementing Table interface and you can use Statistics.of instead of 
implementing Statistic interface if it is simple:
---------------------------------------------------------------------

  private static class TableImpl extends AbstractTable {
    public TableImpl() {}
    @Override    public RelDataType getRowType(RelDataTypeFactory typeFactory) {
      Builder builder = new RelDataTypeFactory.Builder(typeFactory);
      return builder.add("id", typeFactory.createSqlType(SqlTypeName.INTEGER))
          .add("name", typeFactory.createSqlType(SqlTypeName.VARCHAR)).build();
    }
    @Override
    public Statistic getStatistic() {
       return Statistics.of(15D, ImmutableList.<ImmutableBitSet>of(), 
          ImmutableList.of(RelCollations.of(0), RelCollations.of(1)));
    }

  }
---------------------------------------------------------------------


    Em quarta-feira, 8 de novembro de 2017 12:15:34 BRST, Enrico Olivelli 
<[email protected]> escreveu:  
 
 Hi,
I am playing with the planner but I can't get it work for a very simple
query.
Th table is
 MYTABLE(id integer, name varchar)            definition is given in code
snippet
the query is "SELECT * FROM MYTABLE"

The error is:
org.apache.calcite.plan.RelOptPlanner$CannotPlanException: Node
[rel#7:Subset#0.NONE.[0, 1].any] could not be implemented; planner state:

Root: rel#7:Subset#0.NONE.[0, 1].any
Original rel:
LogicalProject(subset=[rel#6:Subset#1.NONE.[0, 1].any], id=[$0],
name=[$1]): rowcount = 15.0, cumulative cost = {15.0 rows, 30.0 cpu, 0.0
io}, id = 5
  EnumerableTableScan(subset=[rel#4:Subset#0.ENUMERABLE.[0, 1].any],
table=[[default, MYTABLE]]): rowcount = 15.0, cumulative cost = {15.0 rows,
16.0 cpu, 0.0 io}, id = 2

Sets:
Set#0, type: RecordType(INTEGER id, VARCHAR name)
    rel#4:Subset#0.ENUMERABLE.[0, 1].any, best=rel#2, importance=0.9
        rel#2:EnumerableTableScan.ENUMERABLE.[[0, 1]].any(table=[default,
MYTABLE]), rowcount=15.0, cumulative cost={15.0 rows, 16.0 cpu, 0.0 io}
        rel#9:EnumerableProject.ENUMERABLE.[[0,
1]].any(input=rel#4:Subset#0.ENUMERABLE.[0, 1].any,id=$0,name=$1),
rowcount=15.0, cumulative cost={30.0 rows, 46.0 cpu, 0.0 io}
    rel#7:Subset#0.NONE.[0, 1].any, best=null, importance=1.0
        rel#5:LogicalProject.NONE.[[0,
1]].any(input=rel#4:Subset#0.ENUMERABLE.[0, 1].any,id=$0,name=$1),
rowcount=15.0, cumulative cost={inf}
        rel#8:AbstractConverter.NONE.[0,
1].any(input=rel#4:Subset#0.ENUMERABLE.[0, 1].any,convention=NONE,sort=[0,
1],dist=any), rowcount=15.0, cumulative cost={inf}

Does anybody has an hint for me ?
I am using currert master of Calcite (1.15-SNAPSHOT)

Thank you

Enrico


My code is:
  @Test
    public void test() throws Exception {
        Table table = new TableImpl();
        CalciteSchema schema = CalciteSchema.createRootSchema(true, true,
"default");
        schema.add("MYTABLE", table);
        SchemaPlus rootSchema = schema.plus();
        SqlRexConvertletTable convertletTable =
StandardConvertletTable.INSTANCE;
        SqlToRelConverter.Config config = SqlToRelConverter.Config.DEFAULT;
        FrameworkConfig frameworkConfig = new FrameworkConfigImpl(config,
rootSchema, convertletTable);
        Planner imp = Frameworks.getPlanner(frameworkConfig);
        SqlNode sqlNode = imp.parse("SELECT * FROM MYTABLE");
        sqlNode = imp.validate(sqlNode);
        RelRoot relRoot = imp.rel(sqlNode);
        RelNode project = relRoot.project();
        RelOptPlanner planner = project.getCluster().getPlanner();
        planner.setRoot(project);
        RelNode findBestExp = planner.findBestExp();
        System.out.println("best:" + findBestExp);
    }

    private class FrameworkConfigImpl implements FrameworkConfig {

        private final SqlToRelConverter.Config config;
        private final SchemaPlus rootSchema;
        private final SqlRexConvertletTable convertletTable;

        public FrameworkConfigImpl(SqlToRelConverter.Config config,
SchemaPlus rootSchema, SqlRexConvertletTable convertletTable) {
            this.config = config;
            this.rootSchema = rootSchema;
            this.convertletTable = convertletTable;
        }

        @Override
        public SqlParser.Config getParserConfig() {
            return SqlParser.Config.DEFAULT;
        }

        @Override
        public SqlToRelConverter.Config getSqlToRelConverterConfig() {
            return config;
        }

        @Override
        public SchemaPlus getDefaultSchema() {
            return rootSchema;
        }

        @Override
        public RexExecutor getExecutor() {
            return new RexExecutorImpl(new DataContextImpl());
        }

        @Override
        public ImmutableList<Program> getPrograms() {
            return ImmutableList.of(Programs.standard());
        }

        @Override
        public SqlOperatorTable getOperatorTable() {
            return new SqlStdOperatorTable();
        }

        @Override
        public RelOptCostFactory getCostFactory() {
            return null;
        }

        @Override
        public ImmutableList<RelTraitDef> getTraitDefs() {

            return ImmutableList.of(ConventionTraitDef.INSTANCE,
                    RelCollationTraitDef.INSTANCE,
                    RelDistributionTraitDef.INSTANCE
            );
        }

        @Override
        public SqlRexConvertletTable getConvertletTable() {
            return convertletTable;
        }

        @Override
        public Context getContext() {
            return new ContextImpl();
        }

        @Override
        public RelDataTypeSystem getTypeSystem() {
            return RelDataTypeSystem.DEFAULT;
        }

        class DataContextImpl implements DataContext {

            public DataContextImpl() {
            }

            @Override
            public SchemaPlus getRootSchema() {
                return rootSchema;
            }

            @Override
            public JavaTypeFactory getTypeFactory() {
                throw new UnsupportedOperationException("Not supported
yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public QueryProvider getQueryProvider() {
                throw new UnsupportedOperationException("Not supported
yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public Object get(String name) {
                throw new UnsupportedOperationException("Not supported
yet."); //To change body of generated methods, choose Tools | Templates.
            }

        }

        private class ContextImpl implements Context {

            public ContextImpl() {
            }

            @Override
            public <C> C unwrap(Class<C> aClass) {
                return null;
            }
        }
    }

    private static class TableImpl implements Table {

        public TableImpl() {
        }

        @Override
        public RelDataType getRowType(RelDataTypeFactory typeFactory) {
            return typeFactory
                    .builder()
                    .add("id",
typeFactory.createSqlType(SqlTypeName.INTEGER))
                    .add("name",
typeFactory.createSqlType(SqlTypeName.VARCHAR))
                    .build();
        }

        @Override
        public Statistic getStatistic() {
            return new StatisticImpl();
        }

        @Override
        public Schema.TableType getJdbcTableType() {
            throw new UnsupportedOperationException("Not supported yet.");
//To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public boolean isRolledUp(String column) {
            return true;
        }

        @Override
        public boolean rolledUpColumnValidInsideAgg(String column, SqlCall
call, SqlNode parent, CalciteConnectionConfig config) {
            return false;
        }

        class StatisticImpl implements Statistic {

            public StatisticImpl() {
            }

            @Override
            public Double getRowCount() {
                return 15d;
            }

            @Override
            public boolean isKey(ImmutableBitSet columns) {
                return false;
            }

            @Override
            public List<RelReferentialConstraint>
getReferentialConstraints() {
                return Collections.emptyList();
            }

            @Override
            public List<RelCollation> getCollations() {
                RelCollation c = new RelCollationImpl(
                        ImmutableList.of(
                                new RelFieldCollation(0,
RelFieldCollation.Direction.ASCENDING),
                                new RelFieldCollation(1,
RelFieldCollation.Direction.ASCENDING)
                        )) {
                };
                return Arrays.asList(c);
            }

            @Override
            public RelDistribution getDistribution() {
                return RelDistributions.ANY;
            }
        }
    }




2017-11-06 19:48 GMT+01:00 Julian Hyde <[email protected]>:

> Yes that is definitely possible. I am too busy to write a code snippet but
> you should take a look at PlannerTest.
>
> > On Nov 6, 2017, at 3:05 AM, Stéphane Campinas <
> [email protected]> wrote:
> >
> > Hi,
> >
> > I am trying to use the Volcano planner in order to optimise queries based
> > on statistics but I am having some issues understanding how to achieve
> > this, even after looking at the Github repository for tests.
> > A first goal I would like to achieve would be to choose a join
> > implementation based on its cost.
> >
> > For example, a query tree can have several joins, and depending on the
> > position of the join in the tree, an certain implementation would be more
> > efficient than another.
> > Would that be possible ? If so, could you share a code snippet ?
> >
> > Thanks
> >
> > --
> > Campinas Stéphane
>
>  

Reply via email to