[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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 <>) but you can create one manually:

  RelBuilder relBuilder;
  List<RelNode> inputs = ImmutableList.of(;
  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
>   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.