> You say that
>    …
> isn't valid SQL. What's wrong with it? It looks valid and correct to
> me.

Right, this was phrased poorly. I assume this is valid ANSI SQL, but it is not 
for the versions of Oracle and SQL Server I’m currently working with. To this 
point I haven’t run into any issues with the generated SQL that I haven’t been 
able to readily work around.

It’s unclear to me what the approach is to handling this sort of situation. Do 
I simply remove that rule when targeting these specific data sources? Can the 
rule be configured in some manner to produce the SQL valid for those targets?

Thanks

On 2024/05/21 18:32:42 Julian Hyde wrote:
> You say that
>
> SELECT code, CASE WHEN code = 'test_val' THEN ABS(val) ELSE NULL END AS absval
> FROM TEST
> WHERE CASE WHEN code = 'test_val' THEN ABS(val) > 0 ELSE FALSE END
>
> isn't valid SQL. What's wrong with it? It looks valid and correct to
> me. (I acknowledge that it's neither pretty nor optimal.)
>
> To make the query more pretty and optimal, it would be nice if Calcite
> did a couple of simplifications:
>
> 1. Simplify CASE to AND. "CASE WHEN code = 'test_val' THEN ABS(val) >
> 0 ELSE FALSE END" --> "code = 'test_val' AND ABS(val) > 0". This
> rewrite is valid only if the expressions are pure, can't throw, and
> NULL values don't matter, all true in this case.
>
> 2. Reduce constants. "CASE WHEN code = 'test_val' THEN ABS(val) ELSE
> NULL END AS absval" becomes "ABS(val) AS absval" because the WHERE
> clause has ensured that "code = 'test_val'" is always true.
>
> I believe there's a rule for 2 but not for 1.
>
> Julian
>
> On Tue, May 21, 2024 at 11:18 AM <je...@gmail.com> wrote:
> >
> > I'm having an issue with CoreFilters.FILTER_REDUCE_EXPRESSIONS. I'm 
> > wondering if this is a problem with the rule, or with how I've set up my 
> > logical tree.
> >
> > Conceptually I am trying to use the equivalent of a computed column in a 
> > WHERE. Since this isn't legal:
> >
> > SELECT code, CASE WHEN code = 'test_val' THEN ABS(val) ELSE NULL END AS 
> > absval
> > FROM TEST
> > WHERE absval > 0
> >
> > I need to move that same CASE logic into the WHERE clause, so:
> >
> > SELECT code, CASE WHEN code = 'test_val' THEN ABS(val) ELSE NULL END AS 
> > absval
> > FROM TEST
> > WHERE CASE WHEN code = 'test_val' THEN ABS(val) ELSE NULL END > 0
> >
> > I'm able to set up my logical RelNode tree and generate exactly this SQL 
> > directly from the logical tree. The builder logic has:
> >
> > RelNode relNode = builder
> > .projectPlus(builder.alias(caseNode, "ABSVAL"))
> > .filter(builder.greaterThan(caseNode, builder.literal(0)))
> > .build();
> >
> > However, when I try to generate a physical tree from this, I can see the 
> > FILTER_REDUCE_EXPRESSIONS rule coerses the CASE statement in the filter 
> > into a BOOLEAN expression, and it produces:
> >
> > SELECT code, CASE WHEN code = 'test_val' THEN ABS(val) ELSE NULL END AS 
> > absval
> > FROM TEST
> > WHERE CASE WHEN code = 'test_val' THEN ABS(val) > 0 ELSE FALSE END
> >
> > Which isn't even valid SQL. If I remove that rule from the planner 
> > altogether:
> >
> > planner.removeRule(FILTER_REDUCE_EXPRESSIONS)
> >
> > The SQL looks correct (effectively the same as that translated directly 
> > from the logical tree above.)
>

Reply via email to