Thread: BUG #13034: Inconsistent attrelid field in pg_attribute table after adding columns to table.
BUG #13034: Inconsistent attrelid field in pg_attribute table after adding columns to table.
From
alemagox@gmail.com
Date:
The following bug has been logged on the website: Bug reference: 13034 Logged by: Alejandro Email address: alemagox@gmail.com PostgreSQL version: 9.3.5 Operating system: Ubuntu 14.04 64 bits Description: Hello! At my work we are trying to automatically generate some tables based on already existing ones. For that reason, we need to check different system tables such as 'pg_attribute', 'pg_class' and 'pg_namespace' so we can retrieve the datatype of the existing columns. This error is easily reproducible from scratch by simply connecting the postgreSQL server as postgres user. Firstly, I will show the query we are trying to make work. Simply run the following queries to retrieve the type of 'id' field form a 'test' table inside a 'test' database: CREATE DATABASE test; \c test CREATE SCHEMA ab; CREATE TABLE ab.test ( id integer NOT NULL ); SELECT format_type(a.atttypid, a.atttypmod) FROM pg_attribute a JOIN pg_class b ON (a.attrelid = b.relfilenode) JOIN pg_namespace c ON (c.oid = b.relnamespace) WHERE b.relname = 'test' AND c.nspname = 'ab' AND a.attname = 'id'; After this last SELECT we receive the following output as expected: format_type ------------- integer The problem comes when we now try to add an extra column to 'test' table. We do it with the following query: ALTER TABLE ab.test ADD COLUMN time TIMESTAMP WITH TIME ZONE DEFAULT now(); Now, the query with 'format_type' returns empty set. I have run also a couple of extra queries and the issue seems to be that 'attrelid' field inside 'pg_attribute' table does not get update after the ALTER TABLE. For example, before running the ALTER TABLE we can run these queries: SELECT b.relfilenode FROM pg_class b, pg_namespace c WHERE c.oid = b.relnamespace AND b.relname='test' AND c.nspname='ab'; Here we receive as output that 'refilenode' has a value of '1861610'. If we now run the ALTER TABLE query and repeat the previous one we receive a value of '1861614'. If we try now the query below, we will receive empty set: SELECT a.* FROM pg_attribute a WHERE a.attrelid=1861614; But if we repeat the previous query using the number 1861610, we will receive all the fields of the table including the added 'time' column. If we change the attrelid field manually we can rerun the 'format_type' query and we will receive the integer output as expected: UPDATE pg_attribute SET attrelid=1861614 WHERE attrelid=1861610; SELECT format_type(a.atttypid, a.atttypmod) FROM pg_attribute a JOIN pg_class b ON (a.attrelid = b.relfilenode) JOIN pg_namespace c ON (c.oid = b.relnamespace) WHERE b.relname = 'test' AND c.nspname = 'ab' AND a.attname = 'id'; format_type ------------- integer As far as I understand, the field should be automatically updated as the user should not be touching these system tables. Thank you very much in advance for you attention. Best regards, Alejandro
Re: BUG #13034: Inconsistent attrelid field in pg_attribute table after adding columns to table.
From
Alvaro Herrera
Date:
alemagox@gmail.com wrote: > SELECT format_type(a.atttypid, a.atttypmod) > FROM pg_attribute a > JOIN pg_class b ON (a.attrelid = b.relfilenode) > JOIN pg_namespace c ON (c.oid = b.relnamespace) > WHERE b.relname = 'test' AND c.nspname = 'ab' AND a.attname = 'id'; pg_attribute.attrelid must be joined to pg_class.oid, not relfilenode. The relfilenode changes when the table is rewritten, which happens during some forms of ALTER TABLE and others. -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Re: BUG #13034: Inconsistent attrelid field in pg_attribute table after adding columns to table.
From
Alejandro Sánchez Medina
Date:
Thank you very much for the quick reply.
It indeed worked and I apologise for filling the issue as a bug.
Best regards,It indeed worked and I apologise for filling the issue as a bug.
2015-04-13 14:25 GMT+01:00 Alvaro Herrera <alvherre@2ndquadrant.com>:
alemagox@gmail.com wrote:
> SELECT format_type(a.atttypid, a.atttypmod)
> FROM pg_attribute a
> JOIN pg_class b ON (a.attrelid = b.relfilenode)
> JOIN pg_namespace c ON (c.oid = b.relnamespace)
> WHERE b.relname = 'test' AND c.nspname = 'ab' AND a.attname = 'id';
pg_attribute.attrelid must be joined to pg_class.oid, not relfilenode.
The relfilenode changes when the table is rewritten, which happens
during some forms of ALTER TABLE and others.
--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services