You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@calcite.apache.org by Julian Feinauer <j....@pragmaticminds.de> on 2019/03/31 16:45:41 UTC

Problem with Code Generation

Hi all,

I have some problems with the code generation from Linq4j which I'm unable to resolve myself.
Basically, I want to translate a condition from Rex to a Linq4j expression to use it in generated code.
In my example the Condition is from Match Recognize and in SQL is: `up."commission" > prev(up."commission")`.

```
RexBuilder rexBuilder = new RexBuilder(implementor.getTypeFactory());
RexProgramBuilder rexProgramBuilder = new RexProgramBuilder(physType.getRowType(), rexBuilder);

rexProgramBuilder.addCondition(entry.getValue());

final Expression condition = RexToLixTranslator.translateCondition(rexProgramBuilder.getProgram(),
          (JavaTypeFactory) getCluster().getTypeFactory(),
          builder2,
          inputGetter1,
          implementor.allCorrelateVariables,
          implementor.getConformance());


builder2.add(Expressions.return_(null, condition));
```

Here, the condition seems okay, it is: ">(PREV(UP.$4, 0), PREV(UP.$4, 1))",  so it should be a comparison of two variables (I rewrite the PREV with a custom Input Getter".
But, the generated code (for Janino) is:

```
Object p1 = row_.get($L4J$C$0_1);
org.apache.calcite.test.JdbcTest.Employee p0 = (org.apache.calcite.test.JdbcTest.Employee) p1;
Object p3 = row_.get($L4J$C$1_1);
org.apache.calcite.test.JdbcTest.Employee p2 = (org.apache.calcite.test.JdbcTest.Employee) p3;
Object p5 = row_.get($L4J$C$0_1);
org.apache.calcite.test.JdbcTest.Employee p4 = (org.apache.calcite.test.JdbcTest.Employee) p5;
Object p7 = row_.get($L4J$C$1_1);
org.apache.calcite.test.JdbcTest.Employee p6 = (org.apache.calcite.test.JdbcTest.Employee) p7;
return p0.commission && p2.commission && p4.commission > p6.commission;
```

This confuses me a lot as I do not know where the check for p0.commission and p2.commission comes from.
It seems that Linq4j adds them as it expects these variables to be nullable, but I have no idea on how to avoid this.
These fields are Numeric so I always get a compilation exception.

Can someone help me with this issue?

Thanks!
Julian


AW: Problem with Code Generation

Posted by Julian Feinauer <j....@pragmaticminds.de>.
Hi, Yuzhou,

Thank you very much!
Please, tell me if you need any informations or snippets.

Julian



Von meinem Mobiltelefon gesendet


-------- Ursprüngliche Nachricht --------
Betreff: Re: Problem with Code Generation
Von: Yuzhao Chen
An: dev@calcite.apache.org
Cc:

Julian Feinauer, i have fire a JIRA and prepare to fix it.

[1] https://issues.apache.org/jira/browse/CALCITE-2966

Best,
Danny Chan
在 2019年4月1日 +0800 AM12:45,dev@calcite.apache.org,写道:
>
> Hi all,
>
> I have some problems with the code generation from Linq4j which I'm unable to resolve myself.
> Basically, I want to translate a condition from Rex to a Linq4j expression to use it in generated code.
> In my example the Condition is from Match Recognize and in SQL is: `up."commission" > prev(up."commission")`.
>
> ```
> RexBuilder rexBuilder = new RexBuilder(implementor.getTypeFactory());
> RexProgramBuilder rexProgramBuilder = new RexProgramBuilder(physType.getRowType(), rexBuilder);
>
> rexProgramBuilder.addCondition(entry.getValue());
>
> final Expression condition = RexToLixTranslator.translateCondition(rexProgramBuilder.getProgram(),
> (JavaTypeFactory) getCluster().getTypeFactory(),
> builder2,
> inputGetter1,
> implementor.allCorrelateVariables,
> implementor.getConformance());
>
> builder2.add(Expressions.return_(null, condition));
> ```
>
> Here, the condition seems okay, it is: ">(PREV(UP.$4, 0), PREV(UP.$4, 1))", so it should be a comparison of two variables (I rewrite the PREV with a custom Input Getter".
> But, the generated code (for Janino) is:
>
> ```
> Object p1 = row_.get($L4J$C$0_1);
> org.apache.calcite.test.JdbcTest.Employee p0 = (org.apache.calcite.test.JdbcTest.Employee) p1;
> Object p3 = row_.get($L4J$C$1_1);
> org.apache.calcite.test.JdbcTest.Employee p2 = (org.apache.calcite.test.JdbcTest.Employee) p3;
> Object p5 = row_.get($L4J$C$0_1);
> org.apache.calcite.test.JdbcTest.Employee p4 = (org.apache.calcite.test.JdbcTest.Employee) p5;
> Object p7 = row_.get($L4J$C$1_1);
> org.apache.calcite.test.JdbcTest.Employee p6 = (org.apache.calcite.test.JdbcTest.Employee) p7;
> return p0.commission && p2.commission && p4.commission > p6.commission;
> ```
>
> This confuses me a lot as I do not know where the check for p0.commission and p2.commission comes from.
> It seems that Linq4j adds them as it expects these variables to be nullable, but I have no idea on how to avoid this.
> These fields are Numeric so I always get a compilation exception.
>
> Can someone help me with this issue?

Re: Problem with Code Generation

Posted by Yuzhao Chen <yu...@gmail.com>.
Julian Feinauer, i have fire a JIRA and prepare to fix it.

[1] https://issues.apache.org/jira/browse/CALCITE-2966

Best,
Danny Chan
在 2019年4月1日 +0800 AM12:45,dev@calcite.apache.org,写道:
>
> Hi all,
>
> I have some problems with the code generation from Linq4j which I'm unable to resolve myself.
> Basically, I want to translate a condition from Rex to a Linq4j expression to use it in generated code.
> In my example the Condition is from Match Recognize and in SQL is: `up."commission" > prev(up."commission")`.
>
> ```
> RexBuilder rexBuilder = new RexBuilder(implementor.getTypeFactory());
> RexProgramBuilder rexProgramBuilder = new RexProgramBuilder(physType.getRowType(), rexBuilder);
>
> rexProgramBuilder.addCondition(entry.getValue());
>
> final Expression condition = RexToLixTranslator.translateCondition(rexProgramBuilder.getProgram(),
> (JavaTypeFactory) getCluster().getTypeFactory(),
> builder2,
> inputGetter1,
> implementor.allCorrelateVariables,
> implementor.getConformance());
>
> builder2.add(Expressions.return_(null, condition));
> ```
>
> Here, the condition seems okay, it is: ">(PREV(UP.$4, 0), PREV(UP.$4, 1))", so it should be a comparison of two variables (I rewrite the PREV with a custom Input Getter".
> But, the generated code (for Janino) is:
>
> ```
> Object p1 = row_.get($L4J$C$0_1);
> org.apache.calcite.test.JdbcTest.Employee p0 = (org.apache.calcite.test.JdbcTest.Employee) p1;
> Object p3 = row_.get($L4J$C$1_1);
> org.apache.calcite.test.JdbcTest.Employee p2 = (org.apache.calcite.test.JdbcTest.Employee) p3;
> Object p5 = row_.get($L4J$C$0_1);
> org.apache.calcite.test.JdbcTest.Employee p4 = (org.apache.calcite.test.JdbcTest.Employee) p5;
> Object p7 = row_.get($L4J$C$1_1);
> org.apache.calcite.test.JdbcTest.Employee p6 = (org.apache.calcite.test.JdbcTest.Employee) p7;
> return p0.commission && p2.commission && p4.commission > p6.commission;
> ```
>
> This confuses me a lot as I do not know where the check for p0.commission and p2.commission comes from.
> It seems that Linq4j adds them as it expects these variables to be nullable, but I have no idea on how to avoid this.
> These fields are Numeric so I always get a compilation exception.
>
> Can someone help me with this issue?

Re: Problem with Code Generation

Posted by Julian Hyde <jh...@apache.org>.
It looks as if you’ve made progress translating PREV. So, well done. That was a hard problem that I hadn’t managed to make progress on.

Regarding "p0.commission && p2.commission && p4.commission > p6.commission”. Those first two terms look a lot like “is null” checks that Linq4j inserts sometimes. So, I surmise that the converter is suffering an off-by-one (or off-by-N) error and using the wrong expressions.

Julian
 

> On Mar 31, 2019, at 9:45 AM, Julian Feinauer <j....@pragmaticminds.de> wrote:
> 
> Hi all,
> 
> I have some problems with the code generation from Linq4j which I'm unable to resolve myself.
> Basically, I want to translate a condition from Rex to a Linq4j expression to use it in generated code.
> In my example the Condition is from Match Recognize and in SQL is: `up."commission" > prev(up."commission")`.
> 
> ```
> RexBuilder rexBuilder = new RexBuilder(implementor.getTypeFactory());
> RexProgramBuilder rexProgramBuilder = new RexProgramBuilder(physType.getRowType(), rexBuilder);
> 
> rexProgramBuilder.addCondition(entry.getValue());
> 
> final Expression condition = RexToLixTranslator.translateCondition(rexProgramBuilder.getProgram(),
>          (JavaTypeFactory) getCluster().getTypeFactory(),
>          builder2,
>          inputGetter1,
>          implementor.allCorrelateVariables,
>          implementor.getConformance());
> 
> 
> builder2.add(Expressions.return_(null, condition));
> ```
> 
> Here, the condition seems okay, it is: ">(PREV(UP.$4, 0), PREV(UP.$4, 1))",  so it should be a comparison of two variables (I rewrite the PREV with a custom Input Getter".
> But, the generated code (for Janino) is:
> 
> ```
> Object p1 = row_.get($L4J$C$0_1);
> org.apache.calcite.test.JdbcTest.Employee p0 = (org.apache.calcite.test.JdbcTest.Employee) p1;
> Object p3 = row_.get($L4J$C$1_1);
> org.apache.calcite.test.JdbcTest.Employee p2 = (org.apache.calcite.test.JdbcTest.Employee) p3;
> Object p5 = row_.get($L4J$C$0_1);
> org.apache.calcite.test.JdbcTest.Employee p4 = (org.apache.calcite.test.JdbcTest.Employee) p5;
> Object p7 = row_.get($L4J$C$1_1);
> org.apache.calcite.test.JdbcTest.Employee p6 = (org.apache.calcite.test.JdbcTest.Employee) p7;
> return p0.commission && p2.commission && p4.commission > p6.commission;
> ```
> 
> This confuses me a lot as I do not know where the check for p0.commission and p2.commission comes from.
> It seems that Linq4j adds them as it expects these variables to be nullable, but I have no idea on how to avoid this.
> These fields are Numeric so I always get a compilation exception.
> 
> Can someone help me with this issue?
> 
> Thanks!
> Julian
>