Good question. A similar question came up during the hackathon.

The current code generation converts everything to strings. You can’t pass an 
object through — you need to generate java code that will create an identical 
object. That often means serializing the object to something like a JSON string 
and generating a call to de-serialize it.

It’s a bit painful, but it does mean that you can evaluate that code in another 
JVM (even on another machine).

Note that RelJsonWriter can serialize RelNodes to JSON, and RelJsonReader can 
read them back. Take a look at RelWriterTest and you will see that there is a 
way to convert RexNodes to JSON also. (It’s not very easy… you could contribute 
some library methods rexToJson and jsonToRex when you’ve figured out how 
RelJsonWriter and RelJsonReader do it.)

There is a back door which is DataContext. Generated code assumes that there is 
a variable “DataContext root”. That is the entry point for all objects (e.g. 
schemas and open connections) when the plan is running. Generated code can call 
DataContext.get(name) to get an object that has been stashed in the context. 
So, you could stash your RexCall in DataContext with a unique name, and 
generate code that calls something like

  (RexCall) root.get(“name$123”)

In summary, it’s not very easy but it’s possible. Let us know how you get on.

Julian


On Sep 17, 2014, at 9:14 AM, Abishek Baskaran <[email protected]> 
wrote:

> Hi,
> I need to push down the filter expression to my custom data source. I see
> that Optiq represents the filter expression as a RexCall and I wish to pass
> the RexCall object to my custom table. I am able to pass Strings and
> Arrays, but unable to figure out how to pass RexCall.
> 
> For example, in this codebase
> <https://github.com/julianhyde/optiq-csv/blob/master/src/main/java/net/hydromatic/optiq/impl/csv/CsvTableScan.java>
> ,
> We have the implement method that's called on successful push down rule.
> 
>  public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
>    PhysType physType =
>        PhysTypeImpl.of(
>            implementor.getTypeFactory(),
>            getRowType(),
>            pref.preferArray());
> 
>    if (table instanceof JsonTable) {
>      return implementor.result(
>          physType,
>          Blocks.toBlock(
>              Expressions.call(table.getExpression(JsonTable.class),
>                  "enumerable")));
>    }
>    return implementor.result(
>        physType,
>        Blocks.toBlock(
>            Expressions.call(table.getExpression(CsvTable.class), "project",
>                Expressions.constant(fields))));
>  }
> 
> Expressions.constant(fields) is good for Strings/Arrays. From Splunk
> adapter I also figured out how to pass Lists. My requirement is to pass a
> RexCall object, would appreciate any guidance here.
> 
> Thanks,
> Abishek

Reply via email to