From: | "Joel Jacobson" <joel(at)compiler(dot)org> |
---|---|
To: | pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | pg_attribute.attname inconsistency when renaming primary key columns |
Date: | 2021-02-22 17:21:23 |
Message-ID: | 5860814f-c91d-4ab0-b771-ded90d7b9c55@www.fastmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi,
When renaming a column that is part of a primary key,
the primary key index's pg_attribute.attname value
isn't updated accordingly, the old value remains.
This causes problems when trying to measure if the
effects of a migration script caused the same end result
as if installing the same version of the schema from scratch.
The schema diffing tool reports a diff, and there is one,
but not actually diff that causes any problems,
since the primary key index's attname doesn't appear
to be used for anything, since the attnum is probably
used instead, which is correct.
Below in an example to illustrate the problem:
CREATE TABLE foo (
foo_id integer NOT NULL,
CONSTRAINT foo_pk PRIMARY KEY (foo_id)
);
\d foo
Table "public.foo"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
foo_id | integer | | not null |
Indexes:
"foo_pk" PRIMARY KEY, btree (foo_id)
SELECT c.relname, a.attnum, c.relkind, a.attname
FROM pg_class AS c
JOIN pg_attribute AS a ON a.attrelid = c.oid
JOIN pg_namespace AS n ON n.oid = c.relnamespace
WHERE n.nspname = 'public'
ORDER BY 1,2;
relname | attnum | relkind | attname
---------+--------+---------+----------
foo | -6 | r | tableoid
foo | -5 | r | cmax
foo | -4 | r | xmax
foo | -3 | r | cmin
foo | -2 | r | xmin
foo | -1 | r | ctid
foo | 1 | r | foo_id
foo_pk | 1 | i | foo_id
(8 rows)
ALTER TABLE foo RENAME COLUMN foo_id TO bar_id;
ALTER TABLE foo RENAME CONSTRAINT "foo_pk" TO "bar_pk";
ALTER TABLE foo RENAME TO bar;
\d bar
Table "public.bar"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
bar_id | integer | | not null |
Indexes:
"bar_pk" PRIMARY KEY, btree (bar_id)
Looks good! But...
SELECT c.relname, a.attnum, c.relkind, a.attname
FROM pg_class AS c
JOIN pg_attribute AS a ON a.attrelid = c.oid
JOIN pg_namespace AS n ON n.oid = c.relnamespace
WHERE n.nspname = 'public'
ORDER BY 1,2;
relname | attnum | relkind | attname
---------+--------+---------+----------
bar | -6 | r | tableoid
bar | -5 | r | cmax
bar | -4 | r | xmax
bar | -3 | r | cmin
bar | -2 | r | xmin
bar | -1 | r | ctid
bar | 1 | r | bar_id
bar_pk | 1 | i | foo_id
(8 rows)
On the last row, we can see that the
attname for the PRIMARY KEY index
still says "foo_id".
While I could ignore PRIMARY KEY index
attname values, it is ugly and I hope there
is a way to avoid it.
/Joel
From | Date | Subject | |
---|---|---|---|
Next Message | Markus Wanner | 2021-02-22 17:34:13 | Re: [HACKERS] logical decoding of two-phase transactions |
Previous Message | Justin Pryzby | 2021-02-22 17:15:25 | Re: [PATCH]: Allow errors in parameter values to be reported during the BIND phase itself.. |