Thread: BUG #4413: LEFT JOIN not working as expected

BUG #4413: LEFT JOIN not working as expected

From
"David Jaquay"
Date:
The following bug has been logged online:

Bug reference:      4413
Logged by:          David Jaquay
Email address:      djaquay@gmail.com
PostgreSQL version: 8.3.3
Operating system:   Ubuntu Heron
Description:        LEFT JOIN not working as expected
Details:

I'm seeing a problem with a LEFT JOIN.  The sql below demonstrates the
issue.

What I expect to see is no rows in the output, i.e. the LEFT JOIN should
pair the two rows together, and the WHERE clause should decide that the
joined row doesn't match, and should yield no output.

What happens is that the planner appears to apply the WHERE clause early,
the left table doesn't yield any rows, and the row from the right table is
output by itself.  This only appears to happen when both sides of the OR are
present, and the idx_beta_datereceived index is present.  Remove any one,
and it works like I expect.

Dave



create table alpha (
  alphaid  bigint not null,
  betaid   bigint null,
  itemcode char(1) not null
);

ALTER TABLE ONLY alpha
    ADD CONSTRAINT pk_alpha PRIMARY KEY (alphaid);


create table beta (
  betaid  bigint not null,
  datereceived date null
);

ALTER TABLE ONLY beta
    ADD CONSTRAINT pk_beta PRIMARY KEY (betaid);

create index idx_alpha_betaid on alpha(betaid);

insert into alpha values (22044, 92359002, 'U');
insert into beta  values (92359002, '2008-08-11');
CREATE INDEX idx_beta_datereceived ON beta USING btree (datereceived);
analyze alpha;
analyze beta;

explain select  alpha.alphaid as aid
      , alpha.betaid   as alphabetaid
      , beta.betaid     as betaid
      , beta.datereceived
      , alpha.itemcode
from   alpha
                left join beta on beta.betaid = alpha.betaid
where  alpha.alphaid = 22044
and (    beta.datereceived IS NULL
       OR
              (     beta.betaid IS NULL
            AND alpha.itemcode='U'
              )
         );

                                              QUERY PLAN
----------------------------------------------------------------------------
---------------------------
 Nested Loop Left Join  (cost=0.00..2.04 rows=1 width=30)
   Join Filter: (beta.betaid = alpha.betaid)
   Filter: ((beta.datereceived IS NULL) OR ((beta.betaid IS NULL) AND
(alpha.itemcode = 'U'::bpchar)))
   ->  Seq Scan on alpha  (cost=0.00..1.01 rows=1 width=18)
         Filter: (alphaid = 22044)
   ->  Seq Scan on beta  (cost=0.00..1.01 rows=1 width=12)
         Filter: ((beta.datereceived IS NULL) OR (beta.betaid IS NULL))
(7 rows)

Re: BUG #4413: LEFT JOIN not working as expected

From
"Jaime Casanova"
Date:
On Tue, Sep 9, 2008 at 3:28 PM, David Jaquay <djaquay@gmail.com> wrote:
>
> Description:        LEFT JOIN not working as expected
> Details:
>
> I'm seeing a problem with a LEFT JOIN.  The sql below demonstrates the
> issue.
>
> What I expect to see is no rows in the output, i.e. the LEFT JOIN should
> pair the two rows together, and the WHERE clause should decide that the
> joined row doesn't match, and should yield no output.
>
> What happens is that the planner appears to apply the WHERE clause early,
> the left table doesn't yield any rows, and the row from the right table is
> output by itself.  This only appears to happen when both sides of the OR =
are
> present, and the idx_beta_datereceived index is present.  Remove any one,
> and it works like I expect.
>

This has been reported and fixed already:
http://archives.postgresql.org/pgsql-bugs/2008-06/msg00175.php

if you can compile postgres from sources you can apply the fix Tom
shows. If not you have to wait for 8.3.4.

Is not time for a new minor release?

--=20
regards,
Jaime Casanova
Soporte y capacitaci=F3n de PostgreSQL
Asesor=EDa y desarrollo de sistemas
Guayaquil - Ecuador
Cel. (593) 87171157

Re: BUG #4413: LEFT JOIN not working as expected

From
Tom Lane
Date:
"David Jaquay" <djaquay@gmail.com> writes:
> I'm seeing a problem with a LEFT JOIN.  The sql below demonstrates the
> issue.

Yeah, this is a known bug:
http://archives.postgresql.org/pgsql-bugs/2008-06/msg00175.php

It's fixed in CVS but we haven't made a new release since then.
If you don't mind patching your copy it's practically a one-liner:
http://archives.postgresql.org/pgsql-committers/2008-06/msg00336.php

            regards, tom lane