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

From Tom Lane
Subject Re: ALTER TABLE RENAME fix
Date
Msg-id 14994.1005442918@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  (Brent Verner <brent@rcfile.org>)
List pgsql-patches
Brent Verner <brent@rcfile.org> writes:
> ... but we have to check both PK_RELNAME and FK_RELNAME,
> since we don't know which side of the constraint this relname is on.

But we do, because we know whether we're scanning by tgrelid or
tgconstrrelid.  This is not merely an efficiency hack, I believe it's
*necessary* to ensure correct functioning.  Think about (a) FK
constraints against a different rel that happens to have an att of the
same name as the one being renamed; (b) an FK constraint against the
*same* rel (quite legal).

Another thing in the back of my mind is that I think ALTER RENAME TABLE
has the same problem as ALTER RENAME COLUMN: the relnames in RI triggers
need to be fixed, and aren't getting fixed.  It seems to me that this
scan subroutine could be the workhorse for solving both problems, if
it's defined to do string substitution in a particular field of the
RI trigger args.  The scan subr should be something like

update_ri_trigger_args (Oid relid,
            bool scan_by_constrrelid,
            int tgargs_item_num,
            const char *oldname,
            const char *newname)

with the semantics that it examines all RI triggers with tgrelid=relid
if scan_by_constrrelid is FALSE, or all RI triggers with tgconstrrelid
= relid if scan_by_constrrelid is TRUE.  If the field numbered
tgargs_item_num contains the string oldname, replace it with newname;
else do nothing to that trigger.

Now, ALTER RENAME COLUMN does this:

update_ri_trigger_args(relid, false, RI_PK_ATTNAME_ARGNO,
               oldattname, newattname);
update_ri_trigger_args(relid, true, RI_FK_ATTNAME_ARGNO,
               oldattname, newattname);

and ALTER RENAME TABLE does this:

update_ri_trigger_args(relid, false, RI_PK_RELNAME_ARGNO,
               oldrelname, newrelname);
update_ri_trigger_args(relid, true, RI_FK_RELNAME_ARGNO,
               oldrelname, newrelname);

I might have the FK and PK roles backwards, but it seems like this
should work.

BTW, you probably need a CommandCounterIncrement between the two scans
in each case.  Otherwise the second scan doesn't see the tuples already
updated by the first, which is deadly if there are any self-referential
triggers.

            regards, tom lane

pgsql-patches by date:

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