Hi Stamatis, This approach worth trying, but I am afraid that it may produce too many permutations. For example, this is the logical plan of one of TPC-H benchmarks, and I am not very keen expanding it much further :-)
901:ProjectLogicalRel(ps_partkey=[$0], val=[$1]) 899:FilterLogicalRel(subset=[rel#900:Subset#66.LOGICAL.ANY.[]], condition=[>($1, $2)]) 897:JoinLogicalRel(subset=[rel#898:Subset#65.LOGICAL.ANY.[]], condition=[true], joinType=[left]) 882:AggregateLogicalRel(subset=[rel#883:Subset#57.LOGICAL.ANY.[]], group=[{0}], val=[SUM($1)]) 880:ProjectLogicalRel(subset=[rel#881:Subset#56.LOGICAL.ANY.[]], ps_partkey=[$1], $f1=[*($2, $3)]) 878:JoinLogicalRel(subset=[rel#879:Subset#55.LOGICAL.ANY.[]], condition=[=($5, $6)], joinType=[inner]) 875:JoinLogicalRel(subset=[rel#876:Subset#53.LOGICAL.ANY.[]], condition=[=($0, $4)], joinType=[inner]) 634:MapScanLogicalRel(subset=[rel#873:Subset#51.LOGICAL.ANY.[]], table=[[partsupp]], projects=[[0, 1, 2, 3]]) 632:MapScanLogicalRel(subset=[rel#874:Subset#52.LOGICAL.ANY.[]], table=[[supplier]], projects=[[0, 1]]) 630:MapScanLogicalRel(subset=[rel#877:Subset#54.LOGICAL.ANY.[]], table=[[nation]], projects=[[0, 1]], filter=[=($1, '[NATION]')]) 895:AggregateLogicalRel(subset=[rel#896:Subset#64.LOGICAL.ANY.[]], group=[{}], agg#0=[SINGLE_VALUE($0)]) 893:ProjectLogicalRel(subset=[rel#894:Subset#63.LOGICAL.ANY.[]], EXPR$0=[*($0, 0.9:DECIMAL(2, 1))]) 891:AggregateLogicalRel(subset=[rel#892:Subset#62.LOGICAL.ANY.[]], group=[{}], agg#0=[SUM($0)]) 889:ProjectLogicalRel(subset=[rel#890:Subset#61.LOGICAL.ANY.[]], $f0=[*($1, $2)]) 887:JoinLogicalRel(subset=[rel#888:Subset#60.LOGICAL.ANY.[]], condition=[=($4, $5)], joinType=[inner]) 885:JoinLogicalRel(subset=[rel#886:Subset#59.LOGICAL.ANY.[]], condition=[=($0, $3)], joinType=[inner]) 680:MapScanLogicalRel(subset=[rel#884:Subset#58.LOGICAL.ANY.[]], table=[[partsupp]], projects=[[0, 2, 3]]) 632:MapScanLogicalRel(subset=[rel#874:Subset#52.LOGICAL.ANY.[]], table=[[supplier]], projects=[[0, 1]]) 630:MapScanLogicalRel(subset=[rel#877:Subset#54.LOGICAL.ANY.[]], table=[[nation]], projects=[[0, 1]], filter=[=($1, '[NATION]')]) I have two working solutions at the moment, which do not require cross-convention converters: 1) Create separate rules for logical-physical node conversion, and for physical-physical optimization 2) A kind of hack: add fake AbstractConverter with logical traits after the physical node is created I hope one of them will work good enough for the production case. Most likely it would be p.1. Regards, Vladimir. пт, 15 нояб. 2019 г. в 11:04, Stamatis Zampetakis <zabe...@gmail.com>: > Hi again Vladimir, > > In my previous email, I mentioned three rules for performing logical to > physical conversions. > It's normal that if you add more operators we will end up with more rules. > Now that the example has a filter we have the following rule list: > > Rule 1: RootLogicalRel -> RootPhysicalRel > Rule 2: ProjectLogicalRel -> ProjectPhysicalRel > Rule 3: FilterLogicalRel -> FilterPhysicalRel > Rule 4: MapScanLogicalRel -> MapScanPhysicalRel > > If I understand well, your concern is that in order to get the optimal plan > you would have to introduce many additional rules for the Exchange operator > (e.g., ExchangeProjectTransposeRule, ExchangeFilterTransposeRue, etc.). > I was thinking that it is not necessary to introduce these kind of rules. > You could have only one rule, i.e., PhysicaExchangeRule, for enforcing a > distribution that would be applied when there is a requirement for > particular distribution. > > So for the initial plan > LogicalRoot [distribution=SINGLETON] > -> LogicalProject > -> LogicalFilter > -> LogicalScan > > The ruleset above should generate the following alternatives where the > PhysicalExchangeRule is applied 3 times. > > Alt1: > PhysicalRoot > -> SingletonExchange > -> PhysicalProject > -> PhysicalFilter > -> PhysicalScan > > Alt2: > PhysicalRoot > -> PhysicalProject > -> SingletonExchange > -> PhysicalFilter > -> PhysicalScan > > Alt3: > PhysicalRoot > -> PhysicalProject > -> PhysicalFilter > -> SingletonExchange > -> PhysicalScan > > This is still in the same spirit of the previous example where the physical > property (distribution) is either satisfied immediately or passed down to > the next level. > > Best, > Stamatis > > On Thu, Nov 14, 2019 at 11:14 AM Vladimir Ozerov <ppoze...@gmail.com> > wrote: > > > search place* = search space > > > > чт, 14 нояб. 2019 г. в 13:10, Vladimir Ozerov <ppoze...@gmail.com>: > > > > > Hi Haisheng, > > > > > > I double-checked the code. My original version returned false for some > > > cases, but it didn't affect number of rules calls anyway, so I changed > it > > > to always return true. Please note that if I change the code as you > > > suggested, the test started failing, because bottom-up propagation of > > rule > > > calls no longer work: when the child is converted to physical form, the > > > parent logical node is not notified. This is the very problem I address > > > with that weird physical-to-logical conversions: they do not make > sense, > > > and converter expansion does not produce any new rels, but their > > existence > > > allow for logical rule re-trigger which ultimately allow the plan to > > > compile. > > > > > > Regarding two conventions - I agree that it may look strange, but I do > > not > > > see any problems from the correctness perspective. Separation of > logical > > > and physical planning helps me avoid excessive expansion of the search > > > place: I do not want my physical rules to produce new rels from not > > > optimized logical rels. Do you see any problems with that approach? > > > > > > Regards, > > > Vladimir > > > > > > ср, 6 нояб. 2019 г. в 03:52, Haisheng Yuan <h.y...@alibaba-inc.com>: > > > > > >> Hi Vladimir, > > >> > > >> The code in PHYSICAL convention L44 looks weird, I think it always > > >> returns true. > > >> > > >> > > > https://github.com/devozerov/calcite-optimizer/blob/master/src/main/java/devozerov/HazelcastConventions.java#L44 > > >> > > >> Try this: > > >> > > >> fromTraits.containsIfApplicable(Convention.PHYSICAL) > > >> && toTraits.containsIfApplicable(Convention.PHYSICAL); > > >> > > >> > > >> Adding a AbstractConverter on logical operators is meaningless. > Calcite > > >> is mixing the concept of logical and physical together, which is sad. > > >> > > >> BTW, using 2 conventions is not appropriate and wrong. > > >> > > >> - Haisheng > > >> > > >> ------------------------------------------------------------------ > > >> 发件人:Vladimir Ozerov<ppoze...@gmail.com> > > >> 日 期:2019年11月05日 18:02:15 > > >> 收件人:Haisheng Yuan<h.y...@alibaba-inc.com> > > >> 抄 送:dev@calcite.apache.org (dev@calcite.apache.org)< > > >> dev@calcite.apache.org> > > >> 主 题:Re: Re: Problem with converters and possibly rule matching > > >> > > >> Hi Haisheng, > > >> > > >> think I already tried something very similar to what you explained, > but > > >> it gave not an optimal plan. Please let me describe what I did. I > would > > >> appreciate your feedback. > > >> > > >> 1) We start with a simple operator tree Root <- Project <- Scan, where > > >> the root is a final aggregator in the distributed query engine: > > >> -> LogicalRoot > > >> -> LogicalProject > > >> -> LogicalScan > > >> > > >> 2) First, we convert the Root and enforce SINGLETON distribution on a > > >> child: > > >> *-> PhysicalRoot[SINGLETON]* > > >> * -> Enforcer#1[SINGLETON]* > > >> -> LogicalProject > > >> -> LogicalScan > > >> > > >> 3) Then the project's rule is invoked. It doesn't know the > distribution > > >> of the input, so it requests ANY distribution. Note that we have to > set > > ANY > > >> to the project as well since we do not know the distribution of the > > input: > > >> -> PhysicalRoot[SINGLETON] > > >> -> Enforcer#1[SINGLETON] > > >> * -> PhysicalProject[ANY]* > > >> * -> Enforcer#2[ANY]* > > >> -> LogicalScan > > >> > > >> 4) Finally, the physical scan is created and its distribution is > > >> resolved. Suppose that it is REPLICATED, i.e. the whole result set is > > >> located on all nodes. > > >> -> PhysicalRoot[SINGLETON] > > >> -> Enforcer#1[SINGLETON] > > >> -> PhysicalProject[ANY] > > >> -> Enforcer#2[ANY] > > >> * -> PhysicalScan[REPLICATED]* > > >> > > >> 5) Now as all logical nodes are converted, we start resolving > enforcers. > > >> The second one is no-op, since REPLICATED satisfies ANY: > > >> -> PhysicalRoot[SINGLETON] > > >> -> Enforcer#1[SINGLETON] > > >> -> PhysicalProject[ANY] > > >> -> PhysicalScan[REPLICATED] > > >> > > >> 6) But the first enforcer now requires an Exchange, since ANY doesn't > > >> satisfy SINGLETON! > > >> -> PhysicalRoot[SINGLETON] > > >> * -> SingletonExchange[SINGLETON]* > > >> -> PhysicalProject[ANY] // <= unresolved! > > >> -> PhysicalScan[REPLICATED] > > >> > > >> The resulting plan requires data movement only because we didn't know > > >> precise distribution of the PhysicalProject when it was created. But > > should > > >> I enable Convention.Impl.canConvertConvention, bottom-up propagation > > >> kicks in, and the correct plan is produced because now LogicalProject > > >> has a chance to be converted to PhysicalProject with the concrete > > >> distribution. The optimized plan looks like this (since REPLICATED > > >> satisfies SINGLETON): > > >> -> PhysicalRoot[SINGLETON] > > >> -> PhysicalProject[REPLICATED] > > >> -> PhysicalScan[REPLICATED] > > >> > > >> You may see this in action in my reproducer: > > >> 1) Test producing "bad" plan: > > >> > > > https://github.com/devozerov/calcite-optimizer/blob/master/src/test/java/devozerov/OptimizerTest.java#L45 > > >> 2) Root enforces SINGLETON on Project: > > >> > > > https://github.com/devozerov/calcite-optimizer/blob/master/src/main/java/devozerov/physical/RootPhysicalRule.java#L45 > > >> 3) Project enforces default (ANY) distribution on Scan: > > >> > > > https://github.com/devozerov/calcite-optimizer/blob/master/src/main/java/devozerov/physical/ProjectPhysicalRule.java#L49 > > >> > > >> Please let me know if this flow is similar to what you meant. > > >> > > >> Regards, > > >> Vladimir. > > >> > > >> пн, 4 нояб. 2019 г. в 10:33, Haisheng Yuan <h.y...@alibaba-inc.com>: > > >> > > >>> Hi Vladimir, > > >>> > > >>> This is still can be done through top-down request approach. > > >>> > > >>> PhysicalFilter operator should request ANY distribution from child > > >>> operator, unless there is outer reference in the filter condition, in > > which > > >>> case, PhysicalFilter should request SINGLETON or BROADCAST > > distribution. So > > >>> in your case, PhysicalFilter request ANY, its required distribution > > will be > > >>> enforced on filter's output. > > >>> > > >>> Regarding index usage, you should have a FIlterTableScan2IndexGet > > >>> logical transformation rule, and a IndexGet2IndexScan physical > > >>> implementation rule. Note that IndexGet is a logical operator and > > IndexScan > > >>> is a physical operator, which are also used by SQL Server. > > >>> > > >>> - Haisheng > > >>> > > >>> ------------------------------------------------------------------ > > >>> 发件人:Vladimir Ozerov<ppoze...@gmail.com> > > >>> 日 期:2019年11月01日 17:30:26 > > >>> 收件人:<dev@calcite.apache.org> > > >>> 主 题:Re: Problem with converters and possibly rule matching > > >>> > > >>> Hi Stamatis, > > >>> > > >>> Thank you for your reply. I also thought that we may set the > > distribution > > >>> trait during logical planning because it is known in advance. And the > > >>> example I gave will work! :-) But unfortunately, it will work only > > >>> because > > >>> the tree is very simple, and the Project is adjacent to the Scan. > This > > is > > >>> how my reproducer will work in that case: > > >>> 1) Root: enforce "SINGLETON" on Project > > >>> 2) Project: check the logical Scan, infer already resolved > > distribution, > > >>> then convert to [PhyiscalProject <- PhysicalScan] > > >>> 3) Resolve Root enforcer, adding and Exchange if needed. > > >>> > > >>> But this stops working as soon as a plan becomes more complex so that > > it > > >>> is > > >>> impossible to infer the distribution from the child immediately. > E.g.: > > >>> LogicalRoot [distribution=SINGLETON] > > >>> -> LogicalProject // We are here new and cannot produce the physical > > >>> project > > >>> -> LogicalFilter[distribution=?] > > >>> -> LogicalScan[distribution=REPLICATED] > > >>> > > >>> This is where your suggestion with cascading enforcement may kick in. > > But > > >>> now consider that instead of having REPLICATED distribution, which > > >>> satisfies SINGLETON, we have a PARTITIONED distribution, It doesn't > > >>> satisfy > > >>> SINGLETON, so we have to insert the exchange. > > >>> > > >>> Before: > > >>> PhysicalRoot [SINGLETON] > > >>> -> PhysicalProject [SINGLETON] > > >>> -> PhysicalFilter [SINGLETON] > > >>> -> LogicalScan [PARTITIONED] // SINGLETON is enforced here > > >>> > > >>> After: > > >>> PhysicalRoot [SINGLETON] > > >>> -> PhysicalProject [SINGLETON] > > >>> -> PhysicalFilter [SINGLETON] > > >>> -> SingletonExchange [SINGLETON] > > >>> -> PhysicalScan [PARTITIONED] > > >>> > > >>> But unfortunately, this plan is not optimal. Since we perform Project > > and > > >>> Filter after the exchange, we now have to reshuffle the whole table. > > The > > >>> optimal plan would be to pushdown Project and Filter past exchange: > > >>> PhysicalRoot [SINGLETON] > > >>> -> SingletonExchange [SINGLETON] > > >>> -> PhysicalProject [PARTITIONED] > > >>> -> PhysicalFilter [PARTITIONED] > > >>> -> PhysicalScan [PARTITIONED] > > >>> > > >>> But in order to achieve that, now I need to introduce new rules which > > >>> will > > >>> attempt to transpose dozens of different operators past exchange, so > > most > > >>> likely the planning will never finish :-) > > >>> > > >>> This is why it seems that the bottom-up approach seems to be more > > natural > > >>> for such cases. Another example is index support. A table may have a > > >>> number > > >>> of access methods in addition to plain scan, and every such method > may > > >>> produce a physical scan with different collations. It is not > practical > > to > > >>> try to enforce something from the top. Instead, we'd better produce > > >>> alternatives from the bottom. > > >>> > > >>> Basically, Drill tries to mix two approaches. First, it tries to > derive > > >>> traits from the child. If it fails and no transformations were > created, > > >>> it > > >>> just stops trait propagation. As a result, an exchange is created on > > top > > >>> of > > >>> the operator where we stopped, which again leads to not optimal > plans. > > >>> You > > >>> may observe this in action if you run my reproducer. "testPass" > > produces > > >>> an > > >>> optimal plan with help of abstract converters. "testDrill" produces > not > > >>> optimal plan with the unnecessary exchange. > > >>> > > >>> All in all, I cannot get how we can employ distribution metadata and > > >>> index > > >>> metadata for optimal planning without using a pure bottom-up > approach. > > >>> > > >>> Regards, > > >>> Vladimir. > > >>> > > >>> пт, 1 нояб. 2019 г. в 11:42, Stamatis Zampetakis <zabe...@gmail.com > >: > > >>> > > >>> > The discussion is interesting thanks for the nice examples. > > >>> > I am replying in this thread since it has all the examples and the > > >>> history > > >>> > of the conversation. > > >>> > > > >>> > *Part I: Distribution physical or logical property* > > >>> > > > >>> > The Volcano paper writes the following regarding properties: > > >>> > > > >>> > "Logical properties can be derived from the logical algebra > > expression > > >>> and > > >>> > include schema, expected size, etc., while physical properties > depend > > >>> on > > >>> > algorithms, e.g., sort order, partitioning, etc." > > >>> > > > >>> > We could say that partitioning is not only a property which depends > > on > > >>> an > > >>> > algorithm but a property which depends on the schema. When you > have a > > >>> table > > >>> > you know in advance that the particular table is replicated. > > >>> > > > >>> > Basically, this means that the starting "logical" plan in your case > > >>> could > > >>> > be the following: > > >>> > RootLogicalRel[convention=LOGICAL, distribution=ANY] > > >>> > -> ProjectLogicalRel[convention=LOGICAL, distribution=ANY] > > >>> > -> MapScanLogicalRel[convention=LOGICAL, distribution=REPLICATED] > > >>> > > > >>> > When you are about to create your physical projection it is not > > >>> necessary > > >>> > to create three equivalent paths but the most promising by asking > the > > >>> input > > >>> > what can it offer as traits. Again this partially overlaps with the > > >>> > discussion about "On demand traitset" [1] where as I wrote there is > > >>> already > > >>> > a mechanism to derive traits from children (collation, > distribution, > > >>> etc.). > > >>> > > > >>> > Note that I am not saying that there is nothing more to be done to > > >>> improve > > >>> > the Calcite optimizer; I am just trying to provide a viable > > alternative > > >>> > given the current situation of the project. > > >>> > > > >>> > *Part II: Example with the original Volcano optimizer* > > >>> > > > >>> > Now let me try to show how the original (from the paper) Volcano > > >>> optimizer > > >>> > could handle your query. > > >>> > > > >>> > The optimization starts and we request two properties convention > and > > >>> > distribution. > > >>> > > > >>> > RootLogicalRel[convention=PHYSICAL, distribution=SINGLETON] > > >>> > -> ProjectLogicalRel > > >>> > -> MapScanLogicalRel > > >>> > > > >>> > Rule 1: RootLogicalRel -> RootPhysicalRel applies the algorithm but > > >>> cannot > > >>> > satisfy the SINGLETON property so it propagates the demand > > >>> > > > >>> > RootPhysicalRel > > >>> > -> ProjectLogicalRel [convention=PHYSICAL, distribution=SINGLETON] > > >>> > -> MapScanLogicalRel > > >>> > > > >>> > Rule 2: ProjectLogicalRel -> ProjectPhysicalRel applies the > algorithm > > >>> but > > >>> > cannot satisfy the SINGLETON property so it propagates the demand > > >>> > > > >>> > RootPhysicalRel > > >>> > -> ProjectPhysicalRel > > >>> > -> MapScanLogicalRel [convention=PHYSICAL, distribution=SINGLETON] > > >>> > > > >>> > Rule 3: MapScanLogicalRel -> MapScanPhysicalRel applies the > algorithm > > >>> and > > >>> > given that the table is replicated it satisfies the distribution > > >>> property. > > >>> > > > >>> > RootPhysicalRel > > >>> > -> ProjectPhysicalRel > > >>> > -> MapScanPhysicalRel > > >>> > > > >>> > So we end up with a complete plan that satisfies all properties and > > >>> does > > >>> > not have redundant exchange operators. > > >>> > Moreover we didn't require all possible distributions when we > applied > > >>> Rule > > >>> > 2 since we just want to satisfy the SINGLETON property requested by > > the > > >>> > parent. > > >>> > The example above does not demonstrate the additional optimization > > >>> paths > > >>> > which would be apply an enforcer (an Exchange operator to satisfy > the > > >>> > SINGLETON property) at a higher level than the scan. > > >>> > > > >>> > Would this be an acceptable approach? Does it still suffer from a > big > > >>> > search space? > > >>> > > > >>> > To make the analog with the actual Volcano optimizer in Calcite the > > >>> thing > > >>> > that may be missing is to be able to know what trait was requested > by > > >>> the > > >>> > parent during the application of Rule 2. > > >>> > > > >>> > Best, > > >>> > Stamatis > > >>> > > > >>> > [1] > > >>> > > > >>> > > > >>> > > > https://lists.apache.org/thread.html/79dac47ea50b5dfbd3f234e368ed61d247fb0eb989f87fe01aedaf25@%3Cdev.calcite.apache.org%3E > > >>> > > > >>> > On Wed, Oct 30, 2019 at 7:24 PM Vladimir Ozerov < > ppoze...@gmail.com> > > >>> > wrote: > > >>> > > > >>> > > Hi Stamatis, > > >>> > > > > >>> > > The problem that the presented reproducer is a very simplified > > >>> version of > > >>> > > what is actually needed. In reality, there are several > distribution > > >>> > types - > > >>> > > PARTITIONED, REPLICATED, SINGLETON. To make things worse, > > >>> PARTITIONED may > > >>> > > or may not have concrete distribution fields. In theory, I can > > >>> create one > > >>> > > transformation per distribution type, but that would increase > plan > > >>> space > > >>> > > significantly. In my sample "Root <- Project <- Scan" plan, there > > is > > >>> no > > >>> > > room for optimization at all, we only need to convert the nodes > and > > >>> > > propagate traits. But if I follow the proposed approach, the > > planner > > >>> > would > > >>> > > create three equivalent paths. For complex queries, this may > > increase > > >>> > > optimization time significantly. > > >>> > > > > >>> > > What I need instead is to gradually convert and optimize nodes > > >>> > *bottom-up*, > > >>> > > instead of top-bottom. That is, create a physical scan first, > then > > >>> > create a > > >>> > > physical project on top of it, etc. But at the same time, some > > rules > > >>> > still > > >>> > > require the top-bottom approach. So essentially I need the > > optimizer > > >>> to > > >>> > do > > >>> > > both. Abstract converters help me establish bottom-up preparation > > >>> but do > > >>> > > this at the cost of considering too many trait pairs, and as a > > >>> result, > > >>> > also > > >>> > > pollute the search space. > > >>> > > > > >>> > > To the contrast, precise command "I transformed the node A to > node > > B, > > >>> > > please re-trigger the rules for A's parents" would allow us to > > >>> re-trigger > > >>> > > only required rules, without adding more nodes. > > >>> > > > > >>> > > Does it make sense? > > >>> > > > > >>> > > Regards, > > >>> > > Vladimir. > > >>> > > > > >>> > > ср, 30 окт. 2019 г. в 21:02, Stamatis Zampetakis < > > zabe...@gmail.com > > >>> >: > > >>> > > > > >>> > > > I admit that I didn't thoroughly read the exchanges so far but > > >>> forcing > > >>> > > the > > >>> > > > rules trigger does not seem the right approach. > > >>> > > > > > >>> > > > Other than that I would like to backtrack a bit to point 4.3 > > >>> raised by > > >>> > > > Vladimir. > > >>> > > > > > >>> > > > "ProjectPhysicalRule [6] - transforms logical project to > physical > > >>> > > > project *ONLY* if there is an underlying physical input with > > >>> REPLICATED > > >>> > > or > > >>> > > > SINGLETON distribution" > > >>> > > > > > >>> > > > The rule could be modified to do the following two > > transformations: > > >>> > > > 1. Create a physical project and require the input to be > > >>> REPLICATED. > > >>> > > > 2. Create a physical project and require > > >>> > > > the input to be SINGLETON. > > >>> > > > > > >>> > > > I would assume that afterwards when your scan rule fires it > > should > > >>> go > > >>> > to > > >>> > > > the appropriate subset and give you back the desired plan. Is > > >>> there a > > >>> > > > problem with this approach? > > >>> > > > > > >>> > > > Best, > > >>> > > > Stamatis > > >>> > > > > > >>> > > > On Wed, Oct 30, 2019, 5:52 PM Seliverstov Igor < > > >>> gvvinbl...@gmail.com> > > >>> > > > wrote: > > >>> > > > > > >>> > > > > Unfortunately it requires package-private API usage. > > >>> > > > > > > >>> > > > > Best solution there if Calcite provide it for end users. > > >>> > > > > > > >>> > > > > ср, 30 окт. 2019 г., 18:48 Vladimir Ozerov < > ppoze...@gmail.com > > >: > > >>> > > > > > > >>> > > > > > “e pension” == “expand conversion” :) > > >>> > > > > > > > >>> > > > > > ср, 30 окт. 2019 г. в 18:46, Vladimir Ozerov < > > >>> ppoze...@gmail.com>: > > >>> > > > > > > > >>> > > > > > > Yes, that may work. Even if e pension rule is used, for > the > > >>> most > > >>> > > > cases > > >>> > > > > it > > >>> > > > > > > will not trigger any real conversions, since we are > moving > > >>> from > > >>> > > > > abstract > > >>> > > > > > > convention to physical, and created converters will have > > the > > >>> > > opposite > > >>> > > > > > trait > > >>> > > > > > > direction (from physical to abstract). > > >>> > > > > > > > > >>> > > > > > > But again - ideally we only need to re-trigger the rules > > for > > >>> a > > >>> > > > specific > > >>> > > > > > > node, no more than that. So API support like > > >>> > > > > > > “VolcanoPlanner.forceRules(RelNode)” would be very > > >>> convenient. > > >>> > > > > > > > > >>> > > > > > > What do you think? > > >>> > > > > > > > > >>> > > > > > > ср, 30 окт. 2019 г. в 17:56, Seliverstov Igor < > > >>> > > gvvinbl...@gmail.com > > >>> > > > >: > > >>> > > > > > > > > >>> > > > > > >> I considered manual rules calling too, for now we use > > >>> abstract > > >>> > > > > > converters > > >>> > > > > > >> + > > >>> > > > > > >> ExpandConversionRule for exchanges producing. > > >>> > > > > > >> > > >>> > > > > > >> You may create such converters manually (checking > > >>> appropriate > > >>> > > > subset) > > >>> > > > > > this > > >>> > > > > > >> case you may reduce created converters count, also, a > > >>> converter > > >>> > > is a > > >>> > > > > > quite > > >>> > > > > > >> special node, that does almost nothing (without > > >>> corresponding > > >>> > > rule) > > >>> > > > it > > >>> > > > > > may > > >>> > > > > > >> be used just as a rule trigger. > > >>> > > > > > >> > > >>> > > > > > >> Regards, > > >>> > > > > > >> Igor > > >>> > > > > > >> > > >>> > > > > > >> ср, 30 окт. 2019 г., 17:31 Vladimir Ozerov < > > >>> ppoze...@gmail.com > > >>> > >: > > >>> > > > > > >> > > >>> > > > > > >> > One funny hack which helped me is manual registration > > of a > > >>> > fake > > >>> > > > > > RelNode > > >>> > > > > > >> > with desired traits through VolcanoPlanner.register() > > >>> method. > > >>> > > But > > >>> > > > > > again, > > >>> > > > > > >> > this leads to trashing. What could really help is a > call > > >>> to > > >>> > > > > > >> > VolcanoPlanner.fireRules() with desired rel. But this > > >>> doesn't > > >>> > > work > > >>> > > > > out > > >>> > > > > > >> of > > >>> > > > > > >> > the box since some internals of the rule queue needs > to > > be > > >>> > > > adjusted. > > >>> > > > > > >> > > > >>> > > > > > >> > What does the community think about adding a method > > which > > >>> will > > >>> > > > > re-add > > >>> > > > > > >> rules > > >>> > > > > > >> > applicable to the specific RelNode to the rule queue? > > >>> > > > > > >> > > > >>> > > > > > >> > ср, 30 окт. 2019 г. в 17:00, Vladimir Ozerov < > > >>> > > ppoze...@gmail.com > > >>> > > > >: > > >>> > > > > > >> > > > >>> > > > > > >> > > Hi Igor, > > >>> > > > > > >> > > > > >>> > > > > > >> > > Yes, I came to the same conclusion, thank you. This > is > > >>> how > > >>> > it > > >>> > > > > > >> basically > > >>> > > > > > >> > > happens when converters are disabled: > > >>> > > > > > >> > > 1) We start with initial tree: [LogicalProject] <- > > >>> > > [LogicalScan] > > >>> > > > > > >> > > 2) Then we convert LogicalScan to PhysicalScan, so > it > > is > > >>> > added > > >>> > > > to > > >>> > > > > > the > > >>> > > > > > >> > > set: [LogicalProject] <- [LogicalScan, PhysicalScan] > > >>> > > > > > >> > > 3) Finally, when it is time to fire a rule for > > >>> PhysicalScan, > > >>> > > we > > >>> > > > > try > > >>> > > > > > to > > >>> > > > > > >> > get > > >>> > > > > > >> > > parents of that scan set with traits of the > > >>> PhysicalScan. > > >>> > > Since > > >>> > > > > > there > > >>> > > > > > >> are > > >>> > > > > > >> > > no such parents (we skipped it intentionally), the > > rule > > >>> is > > >>> > not > > >>> > > > > > queued. > > >>> > > > > > >> > > > > >>> > > > > > >> > > But when converters are enabled, a converter rel is > > >>> created: > > >>> > > > > > >> > [LogicalProject] > > >>> > > > > > >> > > <- [LogicalScan, PhysicalScan, > > >>> > > ConverterFromPhysicalToLogical]. > > >>> > > > No > > >>> > > > > > >> rules > > >>> > > > > > >> > > are fired for PhysicalScan again, but they are fired > > for > > >>> > > > converter > > >>> > > > > > >> since > > >>> > > > > > >> > > it has the necessary LOGICAL trait. > > >>> > > > > > >> > > > > >>> > > > > > >> > > It makes sense, that converters essentially allow > > >>> forcing > > >>> > rule > > >>> > > > > > >> invocation > > >>> > > > > > >> > > on parents, even if the child was created with > > different > > >>> > > traits. > > >>> > > > > But > > >>> > > > > > >> it > > >>> > > > > > >> > > seems that this mechanism may be too heavy for > complex > > >>> > queries > > >>> > > > > > >> because it > > >>> > > > > > >> > > literally creates hundreds of new converter rels and > > >>> > triggers > > >>> > > > > rules > > >>> > > > > > >> over > > >>> > > > > > >> > > and over again. > > >>> > > > > > >> > > > > >>> > > > > > >> > > We need some fine-grained alternative. Basically, > what > > >>> would > > >>> > > be > > >>> > > > > > enough > > >>> > > > > > >> > for > > >>> > > > > > >> > > me is to let the planner know somehow: "I created > that > > >>> rel, > > >>> > > and > > >>> > > > I > > >>> > > > > > want > > >>> > > > > > >> > you > > >>> > > > > > >> > > to execute parent rules not only using its trait but > > >>> also on > > >>> > > > this > > >>> > > > > > and > > >>> > > > > > >> > those > > >>> > > > > > >> > > traits." > > >>> > > > > > >> > > Is there any API in Calcite which allows doing this > > >>> without > > >>> > > > > > creating a > > >>> > > > > > >> > new > > >>> > > > > > >> > > rel node? > > >>> > > > > > >> > > > > >>> > > > > > >> > > Regards, > > >>> > > > > > >> > > Vladimir. > > >>> > > > > > >> > > > > >>> > > > > > >> > > > > >>> > > > > > >> > > ср, 30 окт. 2019 г. в 09:25, Seliverstov Igor < > > >>> > > > > gvvinbl...@gmail.com > > >>> > > > > > >: > > >>> > > > > > >> > > > > >>> > > > > > >> > >> Vladimir, > > >>> > > > > > >> > >> > > >>> > > > > > >> > >> Probably it'll help you: > > >>> > > > > > >> > >> > > >>> > > > > > >> > >> Seems the cause of issue in > RelSubset.getParentRels() > > >>> The > > >>> > > > check > > >>> > > > > > used > > >>> > > > > > >> > when > > >>> > > > > > >> > >> the planner schedules newly matched rules after > > >>> successful > > >>> > > > > > >> > transformation > > >>> > > > > > >> > >> (see VolcanoRuleCall.matchRecurse), it prevents the > > >>> parent > > >>> > > rule > > >>> > > > > be > > >>> > > > > > >> > applied > > >>> > > > > > >> > >> once again (here your logical project with an input > > >>> having > > >>> > > ANY > > >>> > > > > > >> > >> distribution > > >>> > > > > > >> > >> doesn't satisfy a transformed input traits). > > >>> > > > > > >> > >> > > >>> > > > > > >> > >> In our case we use another workaround, so there are > > >>> also > > >>> > much > > >>> > > > > more > > >>> > > > > > >> > >> transformations than we wanted, so the desired rule > > is > > >>> > > > triggered. > > >>> > > > > > >> > >> > > >>> > > > > > >> > >> > > >>> > > > > > >> > >> вт, 29 окт. 2019 г., 14:46 Vladimir Ozerov < > > >>> > > ppoze...@gmail.com > > >>> > > > >: > > >>> > > > > > >> > >> > > >>> > > > > > >> > >> > Hi Vladimir, > > >>> > > > > > >> > >> > > > >>> > > > > > >> > >> > I am sorry. Pushed, it works now. > > >>> > > > > > >> > >> > > > >>> > > > > > >> > >> > вт, 29 окт. 2019 г. в 14:41, Vladimir Sitnikov < > > >>> > > > > > >> > >> > sitnikov.vladi...@gmail.com > > >>> > > > > > >> > >> > >: > > >>> > > > > > >> > >> > > > >>> > > > > > >> > >> > > > mvn clean test > > >>> > > > > > >> > >> > > > > >>> > > > > > >> > >> > > [ERROR] The goal you specified requires a > project > > >>> to > > >>> > > > execute > > >>> > > > > > but > > >>> > > > > > >> > >> there is > > >>> > > > > > >> > >> > > no POM in this directory > > >>> > > > > > >> > >> > > > > >>> > > > > > >> > >> > > Vladimir, please push missing files > > >>> > > > > > >> > >> > > > > >>> > > > > > >> > >> > > Vladimir > > >>> > > > > > >> > >> > > > > >>> > > > > > >> > >> > > > >>> > > > > > >> > >> > > >>> > > > > > >> > > > > >>> > > > > > >> > > > >>> > > > > > >> > > >>> > > > > > > > > >>> > > > > > > > >>> > > > > > > >>> > > > > > >>> > > > > >>> > > > >>> > > >>> > > >> > > >