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
> >>>
> >>
> >>
> >
>

Reply via email to