Regardless of how you create it, it’s difficult to pass arbitrary objects into a plan. It you can ensure that each predicate has a public no-arguments constructor, you could pass the predicate’s class name. Then your custom operator can instantiate the predicate.
One option is to create a user-defined table function. One of its arguments will be a cursor (the input relational expression) and other arguments will be the names of the predicate classes. Its output is a cursor. There is currently no method in RelBuilder to add a table function scan (see https://issues.apache.org/jira/browse/CALCITE-1515 <https://issues.apache.org/jira/browse/CALCITE-1515>) but you can create one manually: RelBuilder relBuilder; … List<RelNode> inputs = ImmutableList.of(relBuilder.build()); relBuilder.push(new TableFunctionScan(…, inputs, …)); Because of RelBuilder’s stack model, you can easily mix RelNodes that it creates with RelNodes you create manually. Julian > On Jun 21, 2018, at 2:06 AM, Stamatis Zampetakis <[email protected]> wrote: > > Hi all, > > I am trying to replace pieces of an old query execution framework with > Calcite. Consider for example the following very simplified representation > of such Query in this framework. > > class Query > { > private final String pathToTableData; > private final Predicate<Record> pred1; > private final Predicate<Record> pred2; > } > > Basically, it corresponds to a TableScan with Filter(s) so I would like to > map it as such to Calcite. > > *Approach A* > The first thing that came to my mind is to use the RelBuilder and > RexBuilder classes to do so. Then when I am about to create a filter, I am > not sure how to create the respective row expression that is able to > describe the above predicates. At the moment, I have the following ideas: > > 1. One possibility would be to create RexCall expression with a custom > SqlOperator that takes the java predicate among its parameters. > 2. Another possibility would be to create RexCall expression with a > SqlUserDefinedFunction that already accepts as an input a Function object > and there I could pass a custom Function object that contains the java > Predicate. > > Then during query planning, it is necessary to add an appropriate rule that > goes over the condition of the filter examine the SqlOperator and introduce > a CustomFilter expression for handling this call. > > *Approach B* > The second alternative would be to not to use at all the RelBuilder and > build the plan manually with custom relational expressions (subclasses of > RelNode). As such the CustomFilter expression could take as an argument a > java predicate and there is no need to introduce further changes or rules. > The latter implies that the CustomFilter does not have a RexNode condition, > which further means that it cannot inherit from the existing Filter class. > > I was wondering if any of the above approaches seems reasonable enough and > if there are other better alternatives that I am missing. Suggestions and > comments are very welcomed.
