[
https://issues.apache.org/jira/browse/DERBY-6363?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Knut Anders Hatlen updated DERBY-6363:
--------------------------------------
Attachment: d6363-1a.diff
The attached patch, d6363-1a.diff, disables the IN list transformation if the
OR node is not on conjunctive normal form. All the expressions that could be
used as qualifiers in a multi-probe scan will be on CNF at this point in the
code, and those expressions are the only ones that would benefit from such a
transformation, as far as I know, so skipping the transformation in those cases
should not hurt performance.
The current code, without the the patch, partially checks that the OR chain is
on CNF by checking that each left operand is either an equals operator or an IN
operator. (This is a stricter condition than CNF, which only requires that the
left operand is either an AND node on CNF or some node that is not an OR node.)
It does however not check that the right operand satisfies the CNF
requirements. Instead, it silently assumes that the right operand is either an
OR node or a BooleanConstantNode whose value is false.
The patch fixes this logic by verifying that the terminating right operand in
the chain indeed is Boolean false. If it is not, the conversion to an IN list
is skipped. In the examples above where the incorrect conversion happens, the
terminating right operand is a node representing {{(b = 'b')}}. Since the
original logic assumed that the chain would be terminated by a dummy {{FALSE}}
value, which could safely be dropped, it would ignore the {{(b = 'b')}} part of
the expression when it created the IN list. Now it will check explicitly that
the terminating node is safe to drop, and only do the rewrite if it is safe.
The patch also fixes a small bug in OrNode.verifyChangeToCNF() which prevented
it from detecting that the right side of the tree was not well-formed. This
code is only invoked in debug builds. The check in OrNode.verifyChangeToCNF()
now matches the check in AndNode.verifyChangeToCNF().
All regression tests passed with the patch.
> Incorrect evaluation of logical expressions in CASE
> ---------------------------------------------------
>
> Key: DERBY-6363
> URL: https://issues.apache.org/jira/browse/DERBY-6363
> Project: Derby
> Issue Type: Bug
> Components: SQL
> Affects Versions: 10.4.1.3, 10.8.3.0, 10.10.1.1
> Reporter: Grzegorz Żur
> Assignee: Knut Anders Hatlen
> Attachments: ac4d3680a5x0141x78ccx0cb1x000006c347101.java,
> d6363-1a.diff
>
>
> Logical expressions with AND and OR operators inside WHEN inside CASE
> expression nested in SELECT part of statement are wrongly evaluated.
> Evaluation results depends on position of OR subexpression. If OR is placed
> on left side of AND it is evaluated incorrectly.
> Following code shows the error.
> create table t ( a int, b char );
> insert into t values (1, 'a');
> insert into t values (2, 'b');
> insert into t values (3, 'a');
> insert into t values (4, 'b');
> insert into t values (5, 'a');
> insert into t values (6, 'b');
> select
> a,
> b,
> case
> when (( b = 'a' or b = 'b' ) and a < 4) then 'x'
> else '-'
> end,
> case
> when (a < 4 and ( b = 'a' or b = 'b' )) then 'y'
> else '-'
> end
> from t;
> Actual result:
> 1 a x y
> 2 b - y
> 3 a x y
> 4 b - -
> 5 a - -
> 6 b - -
> Expected result
> 1 a x y
> 2 b x y
> 3 a x y
> 4 b - -
> 5 a - -
> 6 b - -
--
This message was sent by Atlassian JIRA
(v6.1#6144)