“IN” with a list of scalar values is just syntactic sugar. If you use 
RelBuilder there is no equivalent to ‘x in (1, 2)’; you need to write ‘x = 1 or 
x = 2’ long-hand.

If you want to, you can instead use RelBuilder to build the equivalent of ‘x in 
(values (1), (2))’ — that is, a sub-query. You use a RexSubQuery node for that. 
That formulation is semantically equivalent to the OR but structurally quite 
different, and will tend to be optimized differently.

Julian


> On Jan 23, 2017, at 8:36 AM, Jess Balint <[email protected]> wrote:
> 
> Hi,
> 
> I'm trying to use RelBuilder.call() with SqlStdOperatorTable.IN. I want to
> use IN with the scalar expr list form, not a subquery. How should this be
> represented by a RexNode? I tried using SqlToRelConverter and it parses as
> "x = 1 OR x = 2 ....". When I used the expr list form through RelBuilder
> (flat list of arguments with LHS first) and passed it to RelToSqlConverter,
> I get "x IN 1 IN 2" due to this code in SqlImplementor:
> 
>        if (op instanceof SqlBinaryOperator && nodeList.size() > 2) {
>          // In RexNode trees, OR and AND have any number of children;
>          // SqlCall requires exactly 2. So, convert to a left-deep binary
> tree.
>          return createLeftCall(op, nodeList);
>        }
> 
> I am wondering if one of the following is true:
> * IN w/expr list is not intended to be represented in RexNode form, hence
> the conversion by SqlToRelConverter creates an OR tree
> * I am representing the arguments incorrectly w/something like call(IN,
> field("x"), literal(1), literal(2)) and need to use a specialized RexNode
> structure
> * RelToSqlConverter is lacking the proper handling of the IN operator
> 
> Any hints/thoughts appreciated.
> 
> Thanks.
> Jess

Reply via email to