[
https://issues.apache.org/jira/browse/CALCITE-2615?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16644046#comment-16644046
]
Zoltan Haindrich commented on CALCITE-2615:
-------------------------------------------
The concept on which it builds is somewhat the following:
Given an OR expression: {{(c1 || c2 || .. || cn)}} ; considering that {{c1}} is
true or not the expression can be rewritten to {{(c1 || ( !c1 && (c2 || ... ||
cn)))}}
And the above is perfectly fine in 2 valued logic; however in 3 valued logic:
when c1 is null after this rewrite {{( !c1 && (c2 || ... || cn))}} can be null
or false ; but never true as long a c1 is null.
It remained hidden because during simplification simplifyPredicates instead of
true; wraps the operand into an IS_NOT_NULL cover.
The test of this jira have exploited that {{(b>true}} is effectively an
unsatisfiable expression; and simplifyUsingPredicates was able to came up with
an empty range - which was returning false directly; however in case of a
nullable variable it might not be right - although: I always think that a
predicate of {{a=1}} also implies that {{a is not null}} so returning false
seems appropriate...
Beyond the above case we seem to be in luck; since the symmetrical
simplification of IS is missing - and right now I don't see any other way to
trigger it - to be successful with this 1 operand of the OR should became true;
to be able to nullify all the other operands..
Right now I think the old logic could be fixed by restricting it to only
consider nonNullable expressions as predicates to guarantee correctness - I
think the alternate solution will work in most cases just as well; however it
will not be able to untangle nested things...
> When simplifying NOT-AND-OR, RexSimplify incorrectly applies predicates
> deduced for operands to the same operands
> -----------------------------------------------------------------------------------------------------------------
>
> Key: CALCITE-2615
> URL: https://issues.apache.org/jira/browse/CALCITE-2615
> Project: Calcite
> Issue Type: Task
> Reporter: Julian Hyde
> Assignee: Zoltan Haindrich
> Priority: Major
> Labels: newbie
>
> When simplifying NOT-AND-OR, RexSimplify incorrectly applies predicates
> deduced for operands to the same operands.
> Here is the test case (add it to RexProgramTest):
> {code:java}
> @Test public void testSimplifyNotAnd() {
> final RexNode e = not(
> and(
> gt(and(vBool(1), literal(true)),
> or(literal(true), literal(true), literal(false))),
> gt(isNotNull(vBool(0)), eq(literal(false), vBool(1))),
> or(ne(literal(true), literal(false)),
> ge(vInt(0), literal((Integer) null)))));
> final String expected = "TODO";
> checkSimplify(e, expected);
> }
> {code}
> When you run it, verify will find a combination of assignments such that the
> simplified expression returns a different result than the original.
> The test case is not minimal; sorry. Maybe it reproduces with NOT-OR.
> The bug is in
> [RexSimplify.simplifyAndTerms|https://github.com/apache/calcite/blob/6b3844c0634792263a5073b8ea93565fb3415f41/core/src/main/java/org/apache/calcite/rex/RexSimplify.java#L412].
> Put a breakpoint at that line to see the problem. It passes through the
> operands once, building a list of predicates. Then it passes through the
> operands again, simplifying each operand. Thus operand1 is simplified using a
> list of predicates that includes the predicate 'not operand1'. Clearly wrong.
> [~kgyrtkirk], I warned that this was possible in our discussions.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)