Ruben,

Il giorno gio 17 set 2020 alle ore 14:57 Ruben Q L <rube...@gmail.com> ha
scritto:

> Enrico,
>
> I cannot understand how you can arrive at scenario C. Theoretically, if
> there are not enough rules to implement a certain plan, you should get a
> CannotPlanException from RelOptPlanner#findBest. I would expect this
> outcome if e.g. you do not have "rules that handle the LIMIT". Moreover,
> having "wrong plans computed for joins" seems like a bug. But it is not
> easy to assess the situation and evaluate what is going on without the
> actual query and rules that are applied.
>

I will send a demo when I have cycles.
Thanks for your response.

Enrico


>
> Best regards,
> Ruben
>
>
> Le mer. 16 sept. 2020 à 17:24, Enrico Olivelli <eolive...@gmail.com> a
> écrit :
>
> > Ruben,
> > thank you very much, using your snippet I got the planner working !
> >
> > In HerdDB we are currently using
> > Programs.ofRules(Programs.RULE_SET) +RelOptUtils#registerDefaultRules
> (that
> > add lots of rules) and we are able to handle several cases of very
> complex
> > generic SQL.
> >
> > But If I try to reduce the number of rules I see this behaviour:
> > a) if I am lucky I get some error from the planner that tells that it
> can't
> > find a way to compute the plan -> I can switch to the full planner
> ruleset
> > b) If I am less lucky I have a plan that works but it is less efficient
> ->
> > (this is expected, and this is what I want, that is to trade planner
> speed
> > vs efficiency of plans
> > c) If I am unlucky the planner returns a plan that leads to wrong
> results !
> >
> > For instance you can see c) if you do not add rules that handle "LIMIT"
> and
> > simply the plan sometimes won't pick the LIMIT and the database will
> return
> > unexpected results
> > but I saw worse cases, like wrong plans computed for joins.
> >
> > So my next question is:
> > is there a way to create a minimal set of rules that covers simple SQL
> > (think about basic JPA stuff....) and eventually fails the plan in case
> of
> > unhandled cases ?
> >
> > Best regards
> > Enrico
> >
> > Il giorno mer 16 set 2020 alle ore 09:57 Ruben Q L <rube...@gmail.com>
> ha
> > scritto:
> >
> > > 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 <eolive...@gmail.com> 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