I have a case open with Oracle and they say they can't reproduce this. Running the following in 11.2.0.1 or lower produces two rows from both of these queries, but in 11.2.0.2 the second query returns three rows unless the case statement is removed. Can anyone confirm this behavior?
create table t1 as (select rownum+1 id1 from dual connect by rownum<=3);
create table t2 as (select rownum+1 id2 from dual connect by rownum<=2);
--Correct version that returns two rows.
SELECT t1.id1 id1, t2.id2 id2, t3.id3 id3
, DECODE(1,1,'a','b') "Case/Decode"
FROM t1
LEFT JOIN t2 ON t1.id1 = t2.id2
LEFT JOIN (SELECT 1 id3 FROM dual) t3 ON t3.id3 = t1.id1
WHERE (t2.id2 IS NOT NULL or t3.id3 IS NOT NULL);
--Incorrect version that returns three rows when it should return two.
SELECT t1.id1 id1, t2.id2 id2, t3.id3 id3
, case when 1=1 then 'a' else 'b' end "Case/Decode"
FROM t1
LEFT JOIN t2 ON t1.id1 = t2.id2
LEFT JOIN (SELECT 1 id3 FROM dual) t3 ON t3.id3 = t1.id1
WHERE (t2.id2 IS NOT NULL or t3.id3 IS NOT NULL);
The same issue seems to be effecting the following, which returns the wrong data even though the number of rows is the same.
create table t1 as (select rownum id1 from dual connect by rownum<=3);
--Correct version.
SELECT t1.id1, NVL(t2.id2,'NULL') id2, 'No' Case_Present, t2.Constant_Value
FROM t1
LEFT JOIN (select null id2, 'Should Be NULL' Constant_Value from dual) t2
ON t1.id1 = t2.id2;
--Incorrect version shows values for Constant_Value when it shouldn't.
SELECT t1.id1, NVL(t2.id2,'NULL') id2
, case
when 1=1 then ('Yes')
else ' '
end as Case_Present
, t2.Constant_Value
FROM t1
LEFT JOIN (select null id2, 'Should Be NULL' Constant_Value from dual) t2
ON t1.id1 = t2.id2;