You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@calcite.apache.org by Christian Beikov <ch...@gmail.com> on 2020/02/14 00:29:27 UTC

RelNode rewrite

Hello,

I'm trying to generate SQL for a trigger that requires a little rewrite 
of a RelNode structure and I wanted to know if anyone could help me 
figure out how to do a few things

  * I need to swap left and right of a LogicalJoin. Doing that messes up
    predicates and projections though. Is there a utility I could use or
    how would I do that?
  * I need to introduce an "alias" like "NEW" into a RelNode for which I
    want to create a RexNode "NEW.key1" for. I want to add a WHERE
    condition based on the NEW alias. Not sure how I would do that
    though. On SqlNode level only maybe?
  * Can I somehow determine what columns of a table are unique or part
    of the primary key? I want to create a predicate like (NEW.key1,
    NEW.key2) = (existing.key1, existing.key2)

Thanks in advance!

Regards,

Christian


Re: RelNode rewrite

Posted by Christian Beikov <ch...@gmail.com>.
Hey Jess!

Am 14.02.2020 um 02:16 schrieb Jess Balint:
> Hey Christian,
>
> On Thu, Feb 13, 2020 at 6:30 PM Christian Beikov <ch...@gmail.com>
> wrote:
>
>> Hello,
>>
>> I'm trying to generate SQL for a trigger that requires a little rewrite
>> of a RelNode structure and I wanted to know if anyone could help me
>> figure out how to do a few things
>>
>>    * I need to swap left and right of a LogicalJoin. Doing that messes up
>>      predicates and projections though. Is there a utility I could use or
>>      how would I do that?
>>
> You can use JoinCommuteRule, or check it's code for your needs.
Thanks for the hint. I just hope the re-projection isn't confusing for 
the DBMS optimizer. Would be cool if a RelNode could be rewritten from 
bottom up to avoid this. Or is there some kind of Rule I can apply to 
optimize the re-projection away?
>>    * I need to introduce an "alias" like "NEW" into a RelNode for which I
>>      want to create a RexNode "NEW.key1" for. I want to add a WHERE
>>      condition based on the NEW alias. Not sure how I would do that
>>      though. On SqlNode level only maybe?
>>
> I don't understand what you're after here. The WHERE condition will be a
> filter node. Can you just add it with attaching something to the rel node?

So in a SQL trigger, there is the alias "NEW" and "OLD" available which 
I want to reference in a correlation predicate. I essentially want to 
correlate the RelNode of the changed table with the "NEW" alias and I 
try to do that through the primary key. Let's consider the example query 
"select * from table1 t". So for a trigger for "table1" I essentially 
want to create the query "select * from table1 t where (t.id) = (NEW.id)".

This is what I have so far, maybe you could point me to the right 
direction? The uniqueKeys are unfortunately null although the node is a 
JdbcTableScan.

private RexNodecreateNewCorrelatedJoinCondition(LogicalJoin join, RelNode node) {
     Set<ImmutableBitSet> uniqueKeys = node.getCluster().getMetadataQuery().getUniqueKeys(node); ImmutableBitSet uniqueFieldBitSet = uniqueKeys.iterator().next(); List<RelDataTypeField> fieldList = node.getRowType().getFieldList(); RelBuilder relBuilder = RelBuilder.create(config); RexNode condition = join.getCondition(); List<RexNode> conjuncts =new ArrayList<>(uniqueFieldBitSet.size() +1); conjuncts.add(condition); for (Integer index : uniqueFieldBitSet) {
         conjuncts.add(
             relBuilder.equals(
                 relBuilder.field("NEW", fieldList.get(index).getName()), relBuilder.field(fieldList.get(index).getIndex())
             )
         ); }
     return RexUtil.composeConjunction(rexBuilder, conjuncts); }

Thanks,

Christian


Re: RelNode rewrite

Posted by Jess Balint <jb...@gmail.com>.
Hey Christian,

On Thu, Feb 13, 2020 at 6:30 PM Christian Beikov <ch...@gmail.com>
wrote:

> Hello,
>
> I'm trying to generate SQL for a trigger that requires a little rewrite
> of a RelNode structure and I wanted to know if anyone could help me
> figure out how to do a few things
>
>   * I need to swap left and right of a LogicalJoin. Doing that messes up
>     predicates and projections though. Is there a utility I could use or
>     how would I do that?
>

You can use JoinCommuteRule, or check it's code for your needs.


>   * I need to introduce an "alias" like "NEW" into a RelNode for which I
>     want to create a RexNode "NEW.key1" for. I want to add a WHERE
>     condition based on the NEW alias. Not sure how I would do that
>     though. On SqlNode level only maybe?
>

I don't understand what you're after here. The WHERE condition will be a
filter node. Can you just add it with attaching something to the rel node?


>   * Can I somehow determine what columns of a table are unique or part
>     of the primary key? I want to create a predicate like (NEW.key1,
>     NEW.key2) = (existing.key1, existing.key2)
>

You can use RelMetadataQuery.

Best,

Jess


>
> Thanks in advance!
>
> Regards,
>
> Christian
>
>