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