Re: Creating filter expressions with java predicates
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:
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.
> On Jun 21, 2018, at 2:06 AM, Stamatis Zampetakis <zabetak@xxxxxxxxx> 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
> 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.