Re: ALTER TABLE RENAME fix - Mailing list pgsql-patches

From Tom Lane
Subject Re: ALTER TABLE RENAME fix
Date
Msg-id 17937.1005446483@sss.pgh.pa.us
Whole thread Raw
In response to Re: ALTER TABLE RENAME fix  (Brent Verner <brent@rcfile.org>)
Responses Re: ALTER TABLE RENAME fix
List pgsql-patches
Brent Verner <brent@rcfile.org> writes:
> | But we do, because we know whether we're scanning by tgrelid or
> | tgconstrrelid.

> My brain is not stretching far enough to see this.  Yes, we know
> what we are scanning on, but that stilll doesn't tell us which
> side of the FK/PK relation this relname is on.

Doesn't it?  Maybe I'm the one who's confused.  The RI trigger functions
certainly know which field is which without any searching.

I did:

regression=# CREATE TABLE p_rel (p_id int UNIQUE);
NOTICE:  CREATE TABLE / UNIQUE will create implicit index 'p_rel_p_id_key' for table 'p_rel'
CREATE
regression=# CREATE TABLE f_rel (f_id int REFERENCES p_rel(p_id) ON UPDATE CASCADE);
NOTICE:  CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
CREATE
regression=# select tgfoid::regproc,tgargs from pg_trigger where tgrelid =
regression-# (select oid from pg_class where relname = 'p_rel');
        tgfoid        |                             tgargs
----------------------+----------------------------------------------------------------
 RI_FKey_noaction_del | <unnamed>\000f_rel\000p_rel\000UNSPECIFIED\000f_id\000p_id\000
 RI_FKey_cascade_upd  | <unnamed>\000f_rel\000p_rel\000UNSPECIFIED\000f_id\000p_id\000
(2 rows)

regression=# select tgfoid::regproc,tgargs from pg_trigger where tgconstrrelid =
regression-# (select oid from pg_class where relname = 'p_rel');
      tgfoid       |                             tgargs
-------------------+----------------------------------------------------------------
 RI_FKey_check_ins | <unnamed>\000f_rel\000p_rel\000UNSPECIFIED\000f_id\000p_id\000
(1 row)

regression=# select tgfoid::regproc,tgargs from pg_trigger where tgrelid =
regression-# (select oid from pg_class where relname = 'f_rel');
      tgfoid       |                             tgargs
-------------------+----------------------------------------------------------------
 RI_FKey_check_ins | <unnamed>\000f_rel\000p_rel\000UNSPECIFIED\000f_id\000p_id\000
(1 row)

regression=# select tgfoid::regproc,tgargs from pg_trigger where tgconstrrelid =
regression-# (select oid from pg_class where relname = 'f_rel');
        tgfoid        |                             tgargs
----------------------+----------------------------------------------------------------
 RI_FKey_noaction_del | <unnamed>\000f_rel\000p_rel\000UNSPECIFIED\000f_id\000p_id\000
 RI_FKey_cascade_upd  | <unnamed>\000f_rel\000p_rel\000UNSPECIFIED\000f_id\000p_id\000
(2 rows)

Hmm, so the same tgargs vector is passed to all the triggers regardless
of which side of the relationship they're on, and it's up to the trigger
itself to know which relname/attname applies to its own table.

I think what this means is that a boolean "is_ri_trigger" classification
isn't good enough.  You need to make the knowledge function have a
three-way return: not an RI trigger, RI trigger for PK relation, or
RI trigger for FK relation.  Then the scan subroutine has to take two
item-number parameters, one telling it which tgarg item to look at for a
PK relation and a different one to look at for an FK relation.

Or maybe some slightly different structure would be cleaner.  But the
point is that you have to be able to decide which item to look at
by some means that doesn't involve checking the relname item.  Else it
doesn't work for self-referential RI constraints (same relname on
both sides).

> AFAICS, given a relname, the only way we can know if it is the PK or
> FK is the number of tuples a known scan returns.

The number of tuples is an implementation artifact and might change;
I don't think we should trust that.  (For example, RI_FKey_noaction_del
and RI_FKey_cascade_upd could theoretically be merged into a single
trigger that pays attention to the event it was called for.)

            regards, tom lane

pgsql-patches by date:

Previous
From: Brent Verner
Date:
Subject: Re: ALTER TABLE RENAME fix
Next
From: Tom Lane
Date:
Subject: Re: ALTER TABLE RENAME fix