[
https://issues.apache.org/jira/browse/CALCITE-7722?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ruben Q L updated CALCITE-7722:
-------------------------------
Description:
RexSimplify.simplifyIsNotNull / simplifyIsNull currently bail out of the whole
simplification when the input RexCall is not fully safe (i.e.
isSafeExpression(a) == false). This is stricter than necessary for operators
with Strong.Policy.ANY, where IS [NOT] NULL(f(a, b, ...)) is semantically
equivalent to IS [NOT] NULL(a) OR/AND IS [NOT] NULL(b) OR/AND ... — the
operator itself does not need to be evaluated to compute the result.
Example (regression for downstream projects such as Hive):
{code}
Before (≤ 1.34):
IS NOT NULL(CAST(key AS DOUBLE) + 1.0) → IS NOT NULL(CAST(key AS DOUBLE))
After (≥ 1.35):
IS NOT NULL(CAST(key AS DOUBLE) + 1.0) → (unchanged)
{code}
The rewrite is dropped because CAST(key AS DOUBLE) + 1.0 is a non-lossless cast
wrapped in a +, so isSafeExpression returns false, even though + is Strong.ANY
and the distribution is a valid rewrite regardless of the outer call's safety.
was:
Example: consider the expression {{{}(CAST(col AS INT)*2) IS NULL{}}}. If the
operation uses integer overflows, then it does not affect the nullability. So
the expression can be simplified to {{{}CAST(col as INT) IS NULL{}}}.
If the operation just returns NULL or throws an exception, then this
simplification would change the semantics. Calcite's built-in multiplication
[uses integer
overflows|https://github.com/apache/calcite/blob/437398834e49c8086a64870427214fec428684fc/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java#L844],
so it should carry out that simplification.
However, currently the following RexProgramTest assertion fails:
{code:java}
checkSimplify(isNull(mul(vInt(), literal(2))), "IS NULL(?0.int0)"); {code}
If the sub-expression may throw an exception, then the multiplication can still
be removed:
{code:java}
checkSimplify(isNull(mul(cast(vVarchar(), tInt(false)), literal(2))),
"IS NULL(CAST(?0.varchar0):INTEGER NOT NULL)"); {code}
> RexSimplify IS [NOT] NULL over a Strong.ANY call is no longer simplified when
> the call itself is unsafe
> -------------------------------------------------------------------------------------------------------
>
> Key: CALCITE-7722
> URL: https://issues.apache.org/jira/browse/CALCITE-7722
> Project: Calcite
> Issue Type: Improvement
> Reporter: Thomas Rebele
> Assignee: Ruben Q L
> Priority: Major
> Labels: pull-request-available
>
> RexSimplify.simplifyIsNotNull / simplifyIsNull currently bail out of the
> whole simplification when the input RexCall is not fully safe (i.e.
> isSafeExpression(a) == false). This is stricter than necessary for operators
> with Strong.Policy.ANY, where IS [NOT] NULL(f(a, b, ...)) is semantically
> equivalent to IS [NOT] NULL(a) OR/AND IS [NOT] NULL(b) OR/AND ... — the
> operator itself does not need to be evaluated to compute the result.
> Example (regression for downstream projects such as Hive):
> {code}
> Before (≤ 1.34):
> IS NOT NULL(CAST(key AS DOUBLE) + 1.0) → IS NOT NULL(CAST(key AS DOUBLE))
> After (≥ 1.35):
> IS NOT NULL(CAST(key AS DOUBLE) + 1.0) → (unchanged)
> {code}
> The rewrite is dropped because CAST(key AS DOUBLE) + 1.0 is a non-lossless
> cast wrapped in a +, so isSafeExpression returns false, even though + is
> Strong.ANY and the distribution is a valid rewrite regardless of the outer
> call's safety.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)