Thank you all.
Once I have understood the basic mechanism I am working very well with
Calcite planner.
I will report on the issue my troubles in understanding the first step.
I think that the most important starting point would be a glossary of main
terms, like Convention and Traits then a good example.
The fact that we use marker interfaces for Tables was not very intuitive.
I am going at spees now, in less that a wel of manwork I am going to
replace fully the planner of my opensource product, HerdDB.

Thanks
Enrico

Il lun 13 nov 2017, 16:21 Michael Mior <[email protected]> ha scritto:

> Enrico,
>
> The documentation on the planner definitely could be improved. There's
> already been an issue created for this which can be followed here:
> https://issues.apache.org/jira/browse/CALCITE-2048
>
> --
> Michael Mior
> [email protected]
>
> 2017-11-11 10:29 GMT-05:00 Enrico Olivelli <[email protected]>:
>
> > Got it by myself, the Table must implement ModifiableTable.
> > As far as I am learning the planner is driven by the properties of the
> > Table, expressed using intefaces
> >
> > I wonder if there is some summary of the behavior of the planner or some
> > basic Glossary
> >
> > Cheers
> > Enrico
> >
> > 2017-11-11 11:27 GMT+01:00 Enrico Olivelli <[email protected]>:
> >
> > > Sorry I cannot make it work for INSERT/DELETE/UPDATE
> > >
> > >
> > > This is the error for a DELETE
> > > Qury: DELETE FROM MYTABLE where id=1
> > > -- Logical Plan
> > > LogicalTableModify(table=[[x, MYTABLE]], operation=[DELETE],
> > > flattened=[true])
> > >   LogicalProject(id=[$0], name=[$1])
> > >     LogicalFilter(condition=[=($0, 1)])
> > >       LogicalTableScan(table=[[x, MYTABLE]])
> > >
> > > Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 3.167
> sec
> > > <<< FAILURE!
> > > test(PlannerExampleTest)  Time elapsed: 3.034 sec  <<< ERROR!
> > > org.apache.calcite.plan.RelOptPlanner$CannotPlanException: Node
> > > [rel#15:Subset#3.ENUMERABLE.[].any] could not be implemented; planner
> > > state:
> > >
> > > Root: rel#15:Subset#3.ENUMERABLE.[].any
> > > Original rel:
> > > LogicalTableModify(subset=[rel#15:Subset#3.ENUMERABLE.[].any],
> > table=[[x,
> > > MYTABLE]], operation=[DELETE], flattened=[true]): rowcount = 2.25,
> > > cumulative cost = {2.25 rows, 0.0 cpu, 0.0 io}, id = 13
> > >   LogicalProject(subset=[rel#12:Subset#2.NONE.[].any], id=[$0],
> > > name=[$1]): rowcount = 2.25, cumulative cost = {2.25 rows, 4.5 cpu, 0.0
> > > io}, id = 11
> > >     LogicalFilter(subset=[rel#10:Subset#1.NONE.[].any],
> condition=[=($0,
> > > 1)]): rowcount = 2.25, cumulative cost = {2.25 rows, 15.0 cpu, 0.0 io},
> > id
> > > = 9
> > >       LogicalTableScan(subset=[rel#8:Subset#0.NONE.[].any], table=[[x,
> > > MYTABLE]]): rowcount = 15.0, cumulative cost = {15.0 rows, 16.0 cpu,
> 0.0
> > > io}, id = 4
> > >
> > > Sets:
> > > Set#0, type: RecordType(INTEGER id, INTEGER name)
> > >     rel#8:Subset#0.NONE.[].any, best=null,
> importance=0.7290000000000001
> > >         rel#4:LogicalTableScan.NONE.[].any(table=[x, MYTABLE]),
> > > rowcount=15.0, cumulative cost={inf}
> > >     rel#21:Subset#0.ENUMERABLE.[].any, best=rel#26,
> > > importance=0.36450000000000005
> > >         rel#26:EnumerableInterpreter.ENUMERABLE.[].any(input=rel#
> > 25:Subset#0.BINDABLE.[].any),
> > > rowcount=15.0, cumulative cost={7.65 rows, 7.66 cpu, 0.0 io}
> > >     rel#25:Subset#0.BINDABLE.[].any, best=rel#24,
> > > importance=0.36450000000000005
> > >         rel#24:BindableTableScan.BINDABLE.[].any(table=[x, MYTABLE]),
> > > rowcount=15.0, cumulative cost={0.15 rows, 0.16 cpu, 0.0 io}
> > > Set#1, type: RecordType(INTEGER id, INTEGER name)
> > >     rel#10:Subset#1.NONE.[].any, best=null, importance=0.81
> > >         rel#9:LogicalFilter.NONE.[].any(input=rel#8:Subset#0.NONE.
> > [].any,condition==($0,
> > > 1)), rowcount=2.25, cumulative cost={inf}
> > >         rel#11:LogicalProject.NONE.[].any(input=rel#10:Subset#1.
> > NONE.[].any,id=$0,name=$1),
> > > rowcount=2.25, cumulative cost={inf}
> > >     rel#17:Subset#1.ENUMERABLE.[].any, best=rel#29,
> > > importance=0.4510687500000001
> > >         rel#18:EnumerableProject.ENUMERABLE.[].any(input=rel#
> > > 17:Subset#1.ENUMERABLE.[].any,id=$0,name=$1), rowcount=15.0, cumulative
> > > cost={22.65 rows, 37.66 cpu, 0.0 io}
> > >         rel#22:EnumerableFilter.ENUMERABLE.[].any(input=rel#
> > > 21:Subset#0.ENUMERABLE.[].any,condition==($0, 1)), rowcount=2.25,
> > > cumulative cost={9.9 rows, 22.66 cpu, 0.0 io}
> > >         rel#29:EnumerableInterpreter.ENUMERABLE.[].any(input=rel#
> > 20:Subset#1.BINDABLE.[].any),
> > > rowcount=15.0, cumulative cost={7.65 rows, 7.66 cpu, 0.0 io}
> > >     rel#20:Subset#1.BINDABLE.[].any, best=rel#19, importance=0.405
> > >         rel#19:BindableTableScan.BINDABLE.[].any(table=[x,
> > > MYTABLE],filters=[=($0, 1)]), rowcount=15.0, cumulative cost={0.15
> rows,
> > > 0.16 cpu, 0.0 io}
> > > Set#3, type: RecordType(BIGINT ROWCOUNT)
> > >     rel#14:Subset#3.NONE.[].any, best=null, importance=0.9
> > >         rel#13:LogicalTableModify.NONE.[].any(input=rel#10:
> > Subset#1.NONE.[].any,table=[x,
> > > MYTABLE],operation=DELETE,flattened=true), rowcount=2.25, cumulative
> > > cost={inf}
> > >     rel#15:Subset#3.ENUMERABLE.[].any, best=null, importance=1.0
> > >         rel#16:AbstractConverter.ENUMERABLE.[].any(input=rel#
> > > 14:Subset#3.NONE.[].any,convention=ENUMERABLE,sort=[],dist=any),
> > > rowcount=2.25, cumulative cost={inf}
> > >
> > >
> > >     at org.apache.calcite.plan.volcano.RelSubset$
> > > CheapestPlanReplacer.visit(RelSubset.java:441)
> > >     at org.apache.calcite.plan.volcano.RelSubset.
> > > buildCheapestPlan(RelSubset.java:291)
> > >     at org.apache.calcite.plan.volcano.VolcanoPlanner.
> > > findBestExp(VolcanoPlanner.java:666)
> > >
> > >
> > >
> > >
> > > This is for an Insert
> > > Qury: INSERT INTO MYTABLE(id,name) values(1,2)
> > > -- Logical Plan
> > > LogicalTableModify(table=[[x, MYTABLE]], operation=[INSERT],
> > > flattened=[true])
> > >   LogicalValues(type=[RecordType(INTEGER id, INTEGER name)], tuples=[[{
> > > 1, 2 }]])
> > >
> > > Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.377
> sec
> > > <<< FAILURE!
> > > test(PlannerExampleTest)  Time elapsed: 2.214 sec  <<< ERROR!
> > > org.apache.calcite.plan.RelOptPlanner$CannotPlanException: Node
> > > [rel#7:Subset#1.ENUMERABLE.[].any] could not be implemented; planner
> > > state:
> > >
> > > Root: rel#7:Subset#1.ENUMERABLE.[].any
> > > Original rel:
> > > LogicalTableModify(subset=[rel#7:Subset#1.ENUMERABLE.[].any],
> table=[[x,
> > > MYTABLE]], operation=[INSERT], flattened=[true]): rowcount = 1.0,
> > > cumulative cost = {1.0 rows, 0.0 cpu, 0.0 io}, id = 5
> > >   LogicalValues(subset=[rel#4:Subset#0.NONE.[].any], tuples=[[{ 1, 2
> > > }]]): rowcount = 1.0, cumulative cost = {1.0 rows, 1.0 cpu, 0.0 io}, id
> > = 2
> > >
> > > Sets:
> > > Set#0, type: RecordType(INTEGER id, INTEGER name)
> > >     rel#4:Subset#0.NONE.[].any, best=null, importance=0.81
> > >         rel#2:LogicalValues.NONE.[[0, 1], [1]].any(type=RecordType(
> > INTEGER
> > > id, INTEGER name),tuples=[{ 1, 2 }]), rowcount=1.0, cumulative
> cost={inf}
> > >     rel#10:Subset#0.ENUMERABLE.[].broadcast, best=rel#9,
> > importance=0.405
> > >         rel#9:EnumerableValues.ENUMERABLE.[[0, 1], [1]].broadcast(type=
> > RecordType(INTEGER
> > > id, INTEGER name),tuples=[{ 1, 2 }]), rowcount=1.0, cumulative
> cost={1.0
> > > rows, 1.0 cpu, 0.0 io}
> > > Set#1, type: RecordType(BIGINT ROWCOUNT)
> > >     rel#6:Subset#1.NONE.[].any, best=null, importance=0.9
> > >         rel#5:LogicalTableModify.NONE.[].any(input=rel#4:Subset#0.
> > NONE.[].any,table=[x,
> > > MYTABLE],operation=INSERT,flattened=true), rowcount=1.0, cumulative
> > > cost={inf}
> > >     rel#7:Subset#1.ENUMERABLE.[].any, best=null, importance=1.0
> > >         rel#8:AbstractConverter.ENUMERABLE.[].any(input=rel#6:
> > > Subset#1.NONE.[].any,convention=ENUMERABLE,sort=[],dist=any),
> > > rowcount=1.0, cumulative cost={inf}
> > >
> > >
> > >     at org.apache.calcite.plan.volcano.RelSubset$
> > > CheapestPlanReplacer.visit(RelSubset.java:441)
> > >     at org.apache.calcite.plan.volcano.RelSubset.
> > > buildCheapestPlan(RelSubset.java:291)
> > >     at org.apache.calcite.plan.volcano.VolcanoPlanner.
> > > findBestExp(VolcanoPlanner.java:666)
> > >
> > >
> > >
> > > I really appreciate your help
> > > Enrico
> > >
> > > 2017-11-09 9:43 GMT+01:00 Enrico Olivelli <[email protected]>:
> > >
> > >> The example from Luis works like a charm.
> > >> I have some questions,I will start separate threads
> > >>
> > >> Thank you
> > >> Enrico
> > >>
> > >> 2017-11-08 21:51 GMT+01:00 Enrico Olivelli <[email protected]>:
> > >>
> > >>> Luis thank you,
> > >>> my case is the second one. I want to use Calcite planner internally
> on
> > a
> > >>> database system. I will try with your suggestion
> > >>>
> > >>> Enrico
> > >>>
> > >>> Il mer 8 nov 2017, 20:14 Luis Fernando Kauer
> > >>> <[email protected]> ha scritto:
> > >>>
> > >>>>  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(SqlT
> > >>>> ypeName.INTEGER))
> > >>>>           .add("name", typeFactory.createSqlType(SqlT
> > >>>> ypeName.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.DEFAU
> > >>>> LT;
> > >>>>         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
> > >>>> >
> > >>>> >
> > >>>
> > >>> --
> > >>>
> > >>>
> > >>> -- Enrico Olivelli
> > >>>
> > >>
> > >>
> > >
> >
>
-- 


-- Enrico Olivelli

Reply via email to