Обсуждение: Fwd: Bad Join moment - how is this happening?

Поиск
Список
Период
Сортировка

Fwd: Bad Join moment - how is this happening?

От
Jamie Lawrence
Дата:
I fully admit that I've been staring at this too long, and simply don't
understand what is wrong. Apologies aside, any kind sql hackers who care
to look this over will earn my undying gratitude, and a beer in the bar
of your choice, should we ever meet.


General issue: I'm getting cartesean products instead of left joins, and
I feel like a moron.


I have two tables (more actually, but the result will fix all of them):

dlm=# \d documents                                       Table "public.documents"   Column     |            Type
    |                         Modifiers                          
---------------+-----------------------------+-----------------------------------------------------------id
|integer                     | not null default nextval('public.documents_id_seq'::text)projects_id   | text
           | doc_num       | text                        | description   | text                        | date
|timestamp without time zone | createdate    | timestamp without time zone | default now()moddate       | timestamp
withouttime zone | people_id     | integer                     | parent        | integer                     |
document_type| integer                     | state         | integer                     | machines_id   | integer
              | phases_id     | integer                     |  
Indexes: documents_id_pkey primary key btree (id),        documents_parent_seq btree (parent),
documents_people_id_seqbtree (people_id),        documents_projects_id btree (projects_id) 
Foreign Key constraints: phases_exists FOREIGN KEY (phases_id) REFERENCES phases(id) ON UPDATE NO ACTION ON DELETE NO
ACTION,                       parent_exists FOREIGN KEY (parent) REFERENCES documents(id) ON UPDATE NO ACTION ON DELETE
NOACTION,                        machine_exists FOREIGN KEY (machines_id) REFERENCES machines(id) ON UPDATE NO ACTION
ONDELETE NO ACTION,                        people_exists FOREIGN KEY (people_id) REFERENCES people(id) ON UPDATE NO
ACTIONON DELETE NO ACTION,                        project_exists FOREIGN KEY (projects_id) REFERENCES projects(id) ON
UPDATENO ACTION ON DELETE NO ACTION 
Triggers: documents_timestamp_tr


dlm=# \d d_addenda                               Table "public.d_addenda"     Column       |  Type   |
      Modifiers                          
-------------------+---------+-----------------------------------------------------------id                | integer |
notnull default nextval('public.d_addenda_id_seq'::text)documents_id      | integer | item_num          | text    |
drawing_reference| text    |  
Indexes: d_addenda_id_pkey primary key btree (id),        d_addenda_documents_id_idx btree (documents_id)
Foreign Key constraints: documents_exists FOREIGN KEY (documents_id) REFERENCES documents(id) ON UPDATE NO ACTION ON
DELETENO ACTION 



I have a view:

create or replace view addenda as
select       documents.id,       documents.oid,       documents.projects_id,       documents.doc_num,
documents.description,      documents.date,       documents.createdate,       documents.moddate,
documents.people_id,      documents.parent,       documents.document_type,       documents.state,
documents.machines_id,      documents.phases_id, 
       d_addenda.item_num,       d_addenda.drawing_reference

from       d_addenda as a, documents as d               where a.documents_id =  d.id;


I appear to be getting a cartesean product when I select against the view
'addenda', when I want a left inner join. That is, I want documents
records matched to addenda records only when there is a record in
d_addenda  with a documents_id that matches the id field in documents.

An example:

dlm=# select * from documents;id | projects_id | doc_num |        description         |           date            |
   createdate         |          moddate           | people_id | parent | document_type | state | machines_id |
phases_id 

----+-------------+---------+----------------------------+---------------------------+----------------------------+----------------------------+-----------+--------+---------------+-------+-------------+-----------10
|1           |         | this is a test description |                           | 2003-07-30 12:22:48.094521 |
2003-07-3012:22:48.094521 |           |        |               |       |             |           2 | 1           |
foo123 | description text           | 2003-07-27 19:03:01.30362 | 2003-07-27 19:03:01.30362  | 2003-07-27
19:03:01.30362 |           |        |             1 |     1 |             |           
(2 rows)

dlm=# select * from d_addenda;id | documents_id | item_num | drawing_reference
----+--------------+----------+------------------- 7 |           10 | 2        | none 2 |            2 | 1        | foo
(2 rows)

dlm=# select * from addenda;id |  oid   | projects_id | doc_num |        description         |           date
|         createdate         |          moddate           | people_id | parent | document_type | state | machines_id |
phases_id| item_num | drawing_reference  

----+--------+-------------+---------+----------------------------+---------------------------+----------------------------+----------------------------+-----------+--------+---------------+-------+-------------+-----------+----------+-------------------10
|183371 | 1           |         | this is a test description |                           | 2003-07-30 12:22:48.094521 |
2003-07-3012:22:48.094521 |           |        |               |       |             |           | 2        | none10 |
183371| 1           |         | this is a test description |                           | 2003-07-30 12:22:48.094521 |
2003-07-3012:22:48.094521 |           |        |               |       |             |           | 1        | foo 2 |
180877| 1           | foo123  | description text           | 2003-07-27 19:03:01.30362 | 2003-07-27 19:03:01.30362  |
2003-07-2719:03:01.30362  |           |        |             1 |     1 |             |           | 2        | none 2 |
180877| 1           | foo123  | description text           | 2003-07-27 19:03:01.30362 | 2003-07-27 19:03:01.30362  |
2003-07-2719:03:01.30362  |           |        |             1 |     1 |             |           | 1        | foo10 |
183371| 1           |         | this is a test description |                           | 2003-07-30 12:22:48.094521 |
2003-07-3012:22:48.094521 |           |        |               |       |             |           | 2        | none10 |
183371| 1           |         | this is a test description |                           | 2003-07-30 12:22:48.094521 |
2003-07-3012:22:48.094521 |           |        |               |       |             |           | 1        | foo 2 |
180877| 1           | foo123  | description text           | 2003-07-27 19:03:01.30362 | 2003-07-27 19:03:01.30362  |
2003-07-2719:03:01.30362  |           |        |             1 |     1 |             |           | 2        | none 2 |
180877| 1           | foo123  | description text           | 2003-07-27 19:03:01.30362 | 2003-07-27 19:03:01.30362  |
2003-07-2719:03:01.30362  |           |        |             1 |     1 |             |           | 1        | foo 
(8 rows)


I'm sure I'm being an idiot, but does anyone have a fix?

Thanks.

-j

--
Jamie Lawrence                                        jal@jal.org
It it ain't broke, let me have a shot at it.



Re: Fwd: Bad Join moment - how is this happening?

От
Josh Berkus
Дата:
Jamie,

> General issue: I'm getting cartesean products instead of left joins, and
> I feel like a moron.

No, this is extremely bizarre.   I can't think of an explanation for the
results you're getting, except that the view definition isn't what you think
it is.  Can you do a \d addenda and post the results?

--
-Josh BerkusAglio Database SolutionsSan Francisco



Re: Fwd: Bad Join moment - how is this happening?

От
Richard Huxton
Дата:
On Wednesday 30 July 2003 21:07, Jamie Lawrence wrote:
> I fully admit that I've been staring at this too long, and simply don't
> understand what is wrong. Apologies aside, any kind sql hackers who care
> to look this over will earn my undying gratitude, and a beer in the bar
> of your choice, should we ever meet.

I'll take that beer (assuming I'm right)

> General issue: I'm getting cartesean products instead of left joins, and
> I feel like a moron.

Nope - it's a subtle one.

> I have a view:
>
> create or replace view addenda as
> select
>         documents.id,
>         documents.oid,
>         documents.projects_id,
>         documents.doc_num,
>         documents.description,
>         documents.date,
>         documents.createdate,
>         documents.moddate,
>         documents.people_id,
>         documents.parent,
>         documents.document_type,
>         documents.state,
>         documents.machines_id,
>         documents.phases_id,
>
>         d_addenda.item_num,
>         d_addenda.drawing_reference
>
> from
>         d_addenda as a, documents as d
>                 where a.documents_id =  d.id;
>
>
> I appear to be getting a cartesean product when I select against the view
> 'addenda', when I want a left inner join. That is, I want documents
> records matched to addenda records only when there is a record in
> d_addenda  with a documents_id that matches the id field in documents.

I think this is the "adding a table into the FROM" feature of PG. You're 
referring to documents.xxx in the select and d.id in the FROM. PG tries to 
help out by adding the table into the FROM for you - hence cartesian join.

I think you can turn this "feature" off in the config file in 7.3.x (haven't 
checked this though)

--  Richard Huxton Archonet Ltd


Re: Fwd: Bad Join moment - how is this happening?

От
Josh Berkus
Дата:
Richard,

> I think this is the "adding a table into the FROM" feature of PG. You're
> referring to documents.xxx in the select and d.id in the FROM. PG tries to
> help out by adding the table into the FROM for you - hence cartesian join.

Aha!  You're right.

> I think you can turn this "feature" off in the config file in 7.3.x (haven't
> checked this though)

Nope, it's a 7.4 feature to turn it off in .conf.  Look under the
"compatibility" section (the last section) in 7.4's postgresql.conf.

--
-Josh BerkusAglio Database SolutionsSan Francisco



Re: Fwd: Bad Join moment - how is this happening?

От
Stephan Szabo
Дата:
On Wed, 30 Jul 2003, Jamie Lawrence wrote:

> I have a view:
>
> create or replace view addenda as
> select
>         documents.id,
>         documents.oid,
>         documents.projects_id,
>         documents.doc_num,
>         documents.description,
>         documents.date,
>         documents.createdate,
>         documents.moddate,
>         documents.people_id,
>         documents.parent,
>         documents.document_type,
>         documents.state,
>         documents.machines_id,
>         documents.phases_id,
>
>         d_addenda.item_num,
>         d_addenda.drawing_reference
>
> from
>         d_addenda as a, documents as d
>                 where a.documents_id =  d.id;

I think you're being bitten by from clause
addition.  You're referencing documents in the
select list rather than d so it's probably
adding an unconstrained join to documents.



Re: Fwd: Bad Join moment - how is this happening?

От
Christoph Haller
Дата:
> I have a view:
>
> create or replace view addenda as
> select
>         documents.id,
>         documents.oid,
>         documents.projects_id,
>         documents.doc_num,
>         documents.description,
>         documents.date,
>         documents.createdate,
>         documents.moddate,
>         documents.people_id,
>         documents.parent,
>         documents.document_type,
>         documents.state,
>         documents.machines_id,
>         documents.phases_id,
>
>         d_addenda.item_num,
>         d_addenda.drawing_reference
>
> from
>         d_addenda as a, documents as d
>                 where a.documents_id =  d.id;
>
Doing this you should have got
NOTICE:  Adding missing FROM-clause entry for table "d_addenda"
NOTICE:  Adding missing FROM-clause entry for table "documents"
So it's pretty useful to write psql's output to a file when creating
relations
and check for NOTICE messages.

exec 3>/tmp/psql.out;$PGSQLD/bin/psql <your options here>  1>&3 2>&3

NOTICE messages appear to be sent to stderr.

As the previous posters already made clear
create or replace view addenda as
select       documents.id,       documents.oid,       documents.projects_id,       documents.doc_num,
documents.description,      documents.date,       documents.createdate,       documents.moddate,
documents.people_id,      documents.parent,       documents.document_type,       documents.state,
documents.machines_id,      documents.phases_id,
 
       d_addenda.item_num,       d_addenda.drawing_reference

from       d_addenda , documents               where d_addenda.documents_id =  documents.id;
resp.
create or replace view addenda as
select       d.id,       d.oid,       d.projects_id,       d.doc_num,       d.description,       d.date,
d.createdate,      d.moddate,       d.people_id,       d.parent,       d.document_type,       d.state,
d.machines_id,      d.phases_id,
 
       a.item_num,       a.drawing_reference

from       d_addenda as a, documents as d               where a.documents_id =  d.id;
should match your intentions.

Regards, Christoph




Re: Fwd: Bad Join moment - how is this happening?

От
Jamie Lawrence
Дата:

Sorry to be slow on responses... Thanks to everyone who replies.

On Wed, 30 Jul 2003, Richard Huxton wrote:

> On Wednesday 30 July 2003 21:07, Jamie Lawrence wrote:
> > I fully admit that I've been staring at this too long, and simply don't
> > understand what is wrong. Apologies aside, any kind sql hackers who care
> > to look this over will earn my undying gratitude, and a beer in the bar
> > of your choice, should we ever meet.
> 
> I'll take that beer (assuming I'm right)

I think you nailed it first. You appear to be in London, which I haven't
made it to in ~15 years, and mailing it is probably a bad idea. Ever
make it to the NYC area?
> > I appear to be getting a cartesean product when I select against the view
> > 'addenda', when I want a left inner join. That is, I want documents
> > records matched to addenda records only when there is a record in
> > d_addenda  with a documents_id that matches the id field in documents.
> 
> I think this is the "adding a table into the FROM" feature of PG. You're 
> referring to documents.xxx in the select and d.id in the FROM. PG tries to 
> help out by adding the table into the FROM for you - hence cartesian join.
> 
> I think you can turn this "feature" off in the config file in 7.3.x (haven't 
> checked this though)

This was exactly it. Thanks for the help, this was really making me
crazy.

-j

-- 
Jamie Lawrence                                        jal@jal.org
anger, bargaining, depression, and, finally, acceptance