Hello,

I'm trying to use Calcite as a query optimiser and familiarising myself with it.
I've created a simple program from some example programs and have
successfully made it work creating a logical plan.
But, I somehow get CannotPlanException error when creating an
optimised plan from the logical plan by using transform() method.

Does anyone have an idea why I am getting CannotPlanException ?

The followings are the code and error messages:

===============================
// import ...

public class SimpleQueryPlanner {
   public static void main(String[] args) throws
ClassNotFoundException, SQLException, ValidationException,
RelConversionException {
       Class.forName("org.apache.calcite.jdbc.Driver");
       Connection connection =
           DriverManager.getConnection("jdbc:calcite:");
       CalciteConnection calciteConnection =
           connection.unwrap(CalciteConnection.class);
       SchemaPlus rootSchema = calciteConnection.getRootSchema();
       rootSchema.add("os", new ReflectiveSchema(new Os()));

      final List<RelTraitDef> traitDefs = new ArrayList<RelTraitDef>();
      traitDefs.add(ConventionTraitDef.INSTANCE);
      traitDefs.add(RelCollationTraitDef.INSTANCE);

      FrameworkConfig calciteFrameworkConfig = Frameworks.newConfigBuilder()
            .parserConfig(SqlParser.configBuilder()
                  .setLex(Lex.MYSQL)
                  .build())
            .defaultSchema(rootSchema)
            .traitDefs(traitDefs)
            .context(Contexts.EMPTY_CONTEXT)
            .ruleSets(RuleSets.ofList())
            .costFactory(null)
            .typeSystem(RelDataTypeSystem.DEFAULT)
            .build();

      Planner planner = Frameworks.getPlanner(calciteFrameworkConfig);

      String query = "select * from os.orders";
      SqlNode sqlNode;
      try {
         sqlNode = planner.parse(query);
      } catch (SqlParseException e) {
         throw new RuntimeException("Query parsing error.", e);
      }
      SqlNode validatedSqlNode = planner.validate(sqlNode);
      RelNode plan = planner.rel(validatedSqlNode).project();
      RelTraitSet traitSet =
planner.getEmptyTraitSet().replace(EnumerableConvention.INSTANCE);
      plan = planner.transform(0, traitSet, plan); // <-- fails somehow

       System.out.println(RelOptUtil.toString(plan));
   }

   public static class Os {
       public final Order[] orders = {
         new Order(3,1,12),
         new Order(5,2,7),
         new Order(15, 3,4),
       };
   }

   public static class Order {
      public final int productid;
       public final int orderid;
       public final int units;


       public Order(int productid,int orderid, int units ) {
         this.productid=productid;
         this.orderid=orderid;
         this.units=units;
       }
   }
}
===============================

Error messages I get:
===============================
Exception in thread "main"
org.apache.calcite.plan.RelOptPlanner$CannotPlanException: Node
[rel#7:Subset#1.ENUMERABLE.[]] could not be implemented; planner
state:

Root: rel#7:Subset#1.ENUMERABLE.[]
Original rel:

Sets:
Set#0, type: RecordType(JavaType(int) productid, JavaType(int)
orderid, JavaType(int) units)
rel#4:Subset#0.ENUMERABLE.[], best=rel#2, importance=0.81
rel#2:EnumerableTableScan.ENUMERABLE.[](table=[os, orders]),
rowcount=100.0, cumulative cost={100.0 rows, 101.0 cpu, 0.0 io}
Set#1, type: RecordType(JavaType(int) productid, JavaType(int)
orderid, JavaType(int) units)
rel#6:Subset#1.NONE.[], best=null, importance=0.9
rel#5:LogicalProject.NONE.[](input=rel#4:Subset#0.ENUMERABLE.[],productid=$0,orderid=$1,units=$2),
rowcount=100.0, cumulative cost={inf}
rel#7:Subset#1.ENUMERABLE.[], best=null, importance=1.0
rel#8:AbstractConverter.ENUMERABLE.[](input=rel#6:Subset#1.NONE.[],convention=ENUMERABLE,sort=[]),
rowcount=100.0, cumulative cost={inf}


at 
org.apache.calcite.plan.volcano.RelSubset$CheapestPlanReplacer.visit(RelSubset.java:443)
at 
org.apache.calcite.plan.volcano.RelSubset.buildCheapestPlan(RelSubset.java:293)
at 
org.apache.calcite.plan.volcano.VolcanoPlanner.findBestExp(VolcanoPlanner.java:854)
at org.apache.calcite.tools.Programs$RuleSetProgram.run(Programs.java:334)
at org.apache.calcite.prepare.PlannerImpl.transform(PlannerImpl.java:309)
at examples.SimpleQueryPlanner.main(SimpleQueryPlanner.java:69)
===============================


Best regards,
Hiroyuki

Reply via email to