It seems that "composite" operators crop up quite often. Having kept the operators separate in older adapters like the Mongo adapter, I took a different approach in Druid adapter, and I'm quite please with it.
DruidQuery contains a "stack" of internal relational operators. They are held in the field final ImmutableList<RelNode> rels; The initial DruidQuery contains just a TableScan. It grows as other operators (Filter, Project, Aggregate) are pushed down to Druid, one at a time. The internal RelNodes are not visible to the planner but are nevertheless set up pretty much as they would be if they were outside the DruidQuery. The row type of the query is the row type of the last RelNode in the stack. The "signature()" method helps figure out whether an operation can be pushed onto a DruidQuery. It returns a string that indicates the sequence of operations. For example, a TableScan followed by a Filter followed by a Project returns "sfp", and the rule to push an Aggregate into Druid knows that it can succeed because "sfpa" is in the list of valid signatures. Julian On Thu, May 11, 2017 at 4:16 AM, Γιώργος Θεοδωράκης <[email protected]> wrote: > I am trying to "separate" certain subsets of Operators in a query tree and > transform them to a more "general" RelNode implementation, that holds the > information required to rebuild them. I want to implement something more > general than CALC (for more types of operators), that works like this: > > Operator1 -> Operator2 -> Operator3 ===Enforcing Rules with certain > Conditions==> > > Operator1 -> (Operator2 -> Operator3) == Operator1 -> MergedOperators2,3 > (we can distinguish that this operator is build from Operators 2 and 3) > > Can anyone suggest a possible starting point?
