I see that if you have a hint on, say, the root node then it would be nice for its child or grand-child to be able to see that hint.
How about giving each hint an inherit path? Thus given Filter Hint1 +- Join +- Scan +- Project Hint2 +- Scan Filter would have hints {Hint1[]} Join would have hints {Hint1[0]} Scan would have hints {Hint1[0, 0]} Project would have hints {Hint1[0,1], Hint2} Scan2 would have hints {[Hint1[0, 0, 1, 0], Hint2[0]} You could populate the hints and inherit paths with a single visitor pass after sql-to-rel conversion. By the way, I still like the idea of having kinds as a kind of RelMetadata, but I realize that a given RelNode might have more than one hint. So I think that the getHints(RelNode) method would return a List<Hint>, with Hint as follows: class Hint { public final List<Integer> inheritPath; // immutable, not null public final String type; // not null public final Object operand; // immutable, may be null, must be JSON data } operand must be JSON-style data (null, boolean, number, String, immutable List of JSON data, or immutable order-preserving Map from String to JSON data). > On Apr 23, 2019, at 1:25 AM, Yuzhao Chen <yuzhao....@gmail.com> wrote: > > Thx, Andrew > > I don’t want to have a custom RelNode class, I hope all the work about hints > would be contributed to the community. I want to find an acceptable way to > keep and propagate the hints if we use the MetadataHandler to cache and query > the hints. > > I don’t think the hints should be mixed into the cost model, that would make > the cost computation very complex and hard to maintain, we only need the > hints in our planning phrase to give suggestions, hints is more like another > guideline for me and transparent to the planner. > > Best, > Danny Chan > 在 2019年4月23日 +0800 PM2:24,Андрей Цвелодуб <a.tsvelo...@gmail.com>,写道: >> Hi Danny, >> >> I would also agree with Julian on his position. I've tried to get around >> this limitation in several different ways, but none of it ended well :) >> >> For your idea with hints, if you have custom RelNode classes, you can add >> hint as an additional field of the class and you can write a simple rule >> that propagates the hint downwards, step by step. And also include the hint >> in your cost estimation, so that nodes with hints would be more attractive >> to the planner. I'm not sure this would be the most correct way to use the >> cost mechanism, but at least it is straightforward and it works. >> >> Best Regards, >> Andrew Tsvelodub >> >> On Tue, 23 Apr 2019 at 08:44, Yuzhao Chen <yuzhao....@gmail.com> wrote: >> >>> Julian, >>> >>> I want to add hint support for Calcite, the initial idea was to tag a >>> RelNode(transformed from a SqlNode with hint) with a hit attribute(or >>> trait), then I hope that the children (inputs) of it can see this hint, so >>> to make some decisions if it should consume or propagate the hint. >>> >>> The problem I got here is the trait propagate from inputs from, which is >>> the opposite as what I need, can you give some suggestions ? If I use >>> MetadataHandler to cache and propagate the hints, how to propagate from >>> parents to children ? >>> >>> Best, >>> Danny Chan >>> 在 2019年4月23日 +0800 AM3:14,Julian Hyde <jh...@apache.org>,写道: >>>> TL;DR: RelNodes don’t really have parents. Be careful if you are relying >>> on the parent concept too much. Rely on rules instead. >>>> >>>> In the Volcano model, a RelNode doesn’t really have a parent. It might >>> be used in several places. (RelSet has a field ‘List<RelNode> parents’ that >>> is kept up to date as planing progresses. But it’s really for Volcano’s >>> internal use.) >>>> >>>> Even if you are not using Volcano, there are reasons to want the RelNode >>> graph to be a dag, so again, a RelNode doesn’t have a unique parent. >>>> >>>> RelShuttleImpl has a stack. You can use that to find the parent. But the >>> “parent” is just “where we came from as we traversed the RelNode graph”. >>> There may be other “parents” that you do not know about. >>>> >>>> If you have a Project and want to find all parents that are Filters, >>> don’t even think about “iterating over the parents” of the Project. Just >>> write a rule that matches a Filter on a Project, and trust Volcano to do >>> its job. >>>> >>>> Julian >>>> >>>> >>>> >>>> >>>>> On Apr 22, 2019, at 6:15 AM, Yuzhao Chen <yuzhao....@gmail.com> wrote: >>>>> >>>>> Thx, Stamatis, that somehow make sense, if i pass around the parent >>> node every time I visit a RelNode and keep the parents in the cache, but it >>> is still not that intuitive. Actually I what a to add a new RelTrait which >>> bind to a specific scope, for example: >>>>> >>>>> join-rel(trait1) >>>>> / \ >>>>> join2 join3 >>>>> >>>>> Join-rel has a trait trait1, and I want all the children of join-rel >>> can see this trait, with Calcite’s default metadata handler, I can only see >>> the trait from children nodes(traits propagate from the inputs), and I have >>> no idea how to propagate a trait reversely? >>>>> >>>>> >>>>> Best, >>>>> Danny Chan >>>>> 在 2019年4月22日 +0800 PM8:44,Stamatis Zampetakis <zabe...@gmail.com>,写道: >>>>>> Hi Danny, >>>>>> >>>>>> Apart from RelShuttle there is also RelVisitor which has a visit >>> method >>>>>> that provides the parent [1]. Not sure, if it suits your needs. >>>>>> >>>>>> Best, >>>>>> Stamatis >>>>>> >>>>>> [1] >>>>>> >>> https://github.com/apache/calcite/blob/ee83efd360793ef4201f4cdfc2af8d837b76ca69/core/src/main/java/org/apache/calcite/rel/RelVisitor.java#L43 >>>>>> >>>>>> >>>>>> On Mon, Apr 22, 2019 at 2:14 PM Yuzhao Chen <yuzhao....@gmail.com> >>> wrote: >>>>>> >>>>>>> Now for RelNode, we have method getInput()[1] to fetch the input >>>>>>> RelNodes, but how we fetch the parent ? >>>>>>> >>>>>>> For example, we have plan: >>>>>>> >>>>>>> join-rel >>>>>>> / \ >>>>>>> scan1 scan2 >>>>>>> >>>>>>> >>>>>>> We can get scan1 and scan2 in join-rel directly with method >>> getInput, but >>>>>>> how can we get the join rel in scan1 and scan 2 ? >>>>>>> >>>>>>> I know that there is a RelShuttle that can visit every RelNode and >>> if I >>>>>>> make a cache for the inputs mapping, finally I can get the >>> ‘parents’ from >>>>>>> the cache, but this is boring code and not that intuitive. >>>>>>> >>>>>>> Do you guys have any good ideas ? >>>>>>> >>>>>>> [1] >>>>>>> >>> https://github.com/apache/calcite/blob/ee83efd360793ef4201f4cdfc2af8d837b76ca69/core/src/main/java/org/apache/calcite/rel/RelNode.java#L132 >>>>>>> >>>>>>> >>>>>>> Best, >>>>>>> Danny Chan >>>>>>> >>>> >>>