Hi Enrico,

not sure if this can be applied to your case, but I also have a use case
with HepPlanner and VolcanoPlanner.
In my case I have an initial phase of rules applied with HepPlanner. These
are rules that optimize the logical plan and are always a "quickwin" (they
always generate a better version of the plan, so it makes sense to apply
them with a Hep).
Then, I have a "main" phase, applied with VolcanoPlanner, that takes care
of converting the plan into the most optimized Enumerable result.
A simplified code snippet would be:

private static final Program PHASE_1 =
Programs.of(HepProgram.builder().addRuleCollection(
 Arrays.asList(
  CoreRules.FILTER_INTO_JOIN,
  CoreRules.SORT_PROJECT_TRANSPOSE,
  CoreRules.SORT_JOIN_TRANSPOSE,
  CoreRules.FILTER_REDUCE_EXPRESSIONS,
  ...
  )).build(), false, MyRelMetadataProvider.INSTANCE);

private static final List<RelOptRule> PHASE_2_RULES = Arrays.asList(
 EnumerableRules.ENUMERABLE_VALUES_RULE,
 EnumerableRules.ENUMERABLE_UNION_RULE,
 EnumerableRules.ENUMERABLE_FILTER_TO_CALC_RULE,
 EnumerableRules.ENUMERABLE_PROJECT_TO_CALC_RULE,
 EnumerableRules.ENUMERABLE_COLLECT_RULE,
 EnumerableRules.ENUMERABLE_UNCOLLECT_RULE,
 ...);
private static final Program PHASE_2 =
Programs.of(RuleSets.ofList(PHASE_2_RULES));


EnumerableRel optimizeLogicalPlan(RelNode query)
{
 Program optPhases = Programs.sequence(PHASE_1, PHASE_2);
 RelTraitSet desiredTraitSet = query.getTraitSet()
  .replace(EnumerableConvention.INSTANCE)
  .simplify();
 EnumerableRel result = (EnumerableRel) optPhases.run(
  query.getCluster().getPlanner(), // this is a VolcanoPlanner
  query,
  desiredTraitSet,
  Collections.emptyList(),
  Collections.emptyList());
 return result;
}


I hope it helps.

Best regards,
Ruben


Le mar. 15 sept. 2020 à 17:43, Enrico Olivelli <[email protected]> a
écrit :

> Hi,
>
> I am trying to create a two stage planner using HepPlanner and then
> VolcanoPlanner
>
> Which is the correct sequence of steps to pass from SQL to Enumerable ?
> My goal is to use Hep for very simple queries like simple INSERTs, SELECT *
> FROM TABLE, SELECT * FROM TABLE WHERE pk=?....
> Volcano is overkill for such stuff.
>
> This is my idea:
> 1) get a Planner (that's Volcano)
> Planner planner = Frameworks.getPlanner(config);
>
> 2) Get the logical plan
>  SqlNode n = planner.parse(query);
>             n = planner.validate(n);
>             RelNode logicalPlan = planner.rel(n).project();
> 3) Create HepPlanner
> HepProgram hepProgram =
>                     HepProgram.
>                             builder()
>                             . ?? which Rules ?
>                             .build();
>
>             HepPlanner hepPlanner = new HepPlanner(hepProgram);
>             hepPlanner.addRelTraitDef(ConventionTraitDef.INSTANCE);
>
>             hepPlanner.setRoot(logicalPlan);
>
> 4) Run HepPlanner
> RelNode bestForHep = hepPlanner.findBestExp();
>
> 5) Pick Volcano
>
> final RelOptPlanner optPlanner = cluster.getPlanner();
>
> 6) Convert to Enumerable
>
> final RelOptPlanner optPlanner = cluster.getPlanner();
>
>             optPlanner.addRule(CoreRules.FILTER_REDUCE_EXPRESSIONS);
>             RelTraitSet desiredTraits =
>                     cluster.traitSet()
>                             .replace(EnumerableConvention.INSTANCE);
>             final RelCollation collation =
>                     logicalPlan instanceof Sort
>                             ? ((Sort) logicalPlan).collation
>                             : null;
>             if (collation != null) {
>                 desiredTraits = desiredTraits.replace(collation);
>             }
>             final RelNode newRoot = optPlanner.changeTraits(logicalPlan,
> desiredTraits);
>             optPlanner.setRoot(newRoot);
>             RelNode bestExp = optPlanner.findBestExp();
>
> Any hint/pointer is very appreciated
>
> The alternative is to detect such simple queries and use a little set of
> Rules and not Programs.ofRules(Programs.RULE_SET)
>
> Best regards
> Enrico
>

Reply via email to