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
>