Re: [BUGS] BUG #14684: pg_dump omits columns in inherited tables / psql -d shows deleted columns - Mailing list pgsql-bugs

From Hans Buschmann
Subject Re: [BUGS] BUG #14684: pg_dump omits columns in inherited tables / psql -d shows deleted columns
Date
Msg-id D2B9F2A20670C84685EF7D183F2949E2373DC8@gigant.nidsa.net
Whole thread Raw
In response to [BUGS] BUG #14684: pg_dump omits columns in inherited tables / psql -d showsdeleted columns  (buschmann@nidsa.net)
Responses Re: [BUGS] BUG #14684: pg_dump omits columns in inherited tables / psql -d shows deleted columns  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs

Thanks for the quick answer.

My point on this topic is consistency:

1. I expect the command  add column xxx  to a table hierarchy followed by a drop column xxx to the same hierarchy to be logical a null operation.
add columns adds the columns to all inherited tables but drop column removes the column only in the parent table.

2. I expect the \d command to reflect the current logical status of the table

3. I expect all tools to see the same logical status of the tables, e.g. psql \d and pg_dump

In my original post I forgot to mention that the example was on the test machine after pg_dump/pg_restor from the production server.
To better show the problem I wrote a little test case:

---------------------------------------------------------------------------------

-- create database xxxdb template=template0 encoding 'UTF8' lc_collate='C';
-- \c xxxdb
-- create schema archiv;


select version();


ALTER DATABASE xxxdb SET search_path TO public,archiv;

SET search_path TO public,archiv;

drop table if exists of_test_archiv;
drop table if exists of_test;

CREATE TABLE of_test (
    id_of integer PRIMARY KEY,
    of_season smallint,
    of_p_deliver_etd date,
    of_p_deliver_eta date,
    of_style_cus character varying(35),
    CONSTRAINT ck_of_new CHECK ((of_season >= 22)) NO INHERIT
);


CREATE TABLE archiv.of_test_archiv (
    id_of integer PRIMARY KEY,
    of_season smallint,
    of_p_deliver_etd date,
    of_p_deliver_eta date,
    of_style_cus character varying(35),
    CONSTRAINT ck_of_old CHECK ((of_season < 22))
)
INHERITS (public.of_test);

\d of_test

\d of_test_archiv


alter table of_test
 add column of_id_off smallint
,add column of_id_for_group smallint
;

alter table of_test
drop column of_style_cus
;

\d of_test

\d of_test_archiv


-- pg_dump -U postgres -d xxxdb -f c:/xxxdb_struct.sql


----------------------------------------------------------------------------------

The log in psql:

                           version                          
-------------------------------------------------------------
 PostgreSQL 9.6.3, compiled by Visual C++ build 1800, 64-bit
(1 row)

ALTER DATABASE
SET
DROP TABLE
DROP TABLE
CREATE TABLE
CREATE TABLE
                Table "public.of_test"
      Column      |         Type          | Modifiers
------------------+-----------------------+-----------
 id_of            | integer               | not null
 of_season        | smallint              |
 of_p_deliver_etd | date                  |
 of_p_deliver_eta | date                  |
 of_style_cus     | character varying(35) |
Indexes:
    "of_test_pkey" PRIMARY KEY, btree (id_of)
Check constraints:
    "ck_of_new" CHECK (of_season >= 22) NO INHERIT
Number of child tables: 1 (Use \d+ to list them.)

            Table "archiv.of_test_archiv"
      Column      |         Type          | Modifiers
------------------+-----------------------+-----------
 id_of            | integer               | not null
 of_season        | smallint              |
 of_p_deliver_etd | date                  |
 of_p_deliver_eta | date                  |
 of_style_cus     | character varying(35) |
Indexes:
    "of_test_archiv_pkey" PRIMARY KEY, btree (id_of)
Check constraints:
    "ck_of_old" CHECK (of_season < 22)
Inherits: of_test

ALTER TABLE
ALTER TABLE
         Table "public.of_test"
      Column      |   Type   | Modifiers
------------------+----------+-----------
 id_of            | integer  | not null
 of_season        | smallint |
 of_p_deliver_etd | date     |
 of_p_deliver_eta | date     |
 of_id_off        | smallint |
 of_id_for_group  | smallint |
Indexes:
    "of_test_pkey" PRIMARY KEY, btree (id_of)
Check constraints:
    "ck_of_new" CHECK (of_season >= 22) NO INHERIT
Number of child tables: 1 (Use \d+ to list them.)

            Table "archiv.of_test_archiv"
      Column      |         Type          | Modifiers
------------------+-----------------------+-----------
 id_of            | integer               | not null
 of_season        | smallint              |
 of_p_deliver_etd | date                  |
 of_p_deliver_eta | date                  |
 of_style_cus     | character varying(35) |
 of_id_off        | smallint              |
 of_id_for_group  | smallint              |
Indexes:
    "of_test_archiv_pkey" PRIMARY KEY, btree (id_of)
Check constraints:
    "ck_of_old" CHECK (of_season < 22)
Inherits: of_test

---------------------------------------------------------------------------------------

Please note the ordering of the columns in of_test_archiv !!!

The dump output shows (in parts):

...

CREATE TABLE of_test (
    id_of integer NOT NULL,
    of_season smallint,
    of_p_deliver_etd date,
    of_p_deliver_eta date,
    of_id_off smallint,
    of_id_for_group smallint,
    CONSTRAINT ck_of_new CHECK ((of_season >= 22)) NO INHERIT
);


ALTER TABLE of_test OWNER TO postgres;

SET search_path = archiv, pg_catalog;

--
-- Name: of_test_archiv; Type: TABLE; Schema: archiv; Owner: postgres
--

CREATE TABLE of_test_archiv (
    id_of integer,
    of_season smallint,
    of_p_deliver_etd date,
    of_p_deliver_eta date,
    of_style_cus character varying(35),
    CONSTRAINT ck_of_old CHECK ((of_season < 22))
)
INHERITS (public.of_test);


ALTER TABLE of_test_archiv OWNER TO postgres;

...
-----------------------------------------------------------------------------------

Here the table creation of of_test_archiv misses the newly added columns and still has the dropped column.

When you later restore the dump on a different machine (e.g. as backup), the definition of the of_test_archiv table changes in psql \d:

xxxdb=# \d of_test_archiv
            Table "archiv.of_test_archiv"
      Column      |         Type          | Modifiers
------------------+-----------------------+-----------
 id_of            | integer               | not null
 of_season        | smallint              |
 of_p_deliver_etd | date                  |
 of_p_deliver_eta | date                  |
 of_id_off        | smallint              |
 of_id_for_group  | smallint              |
 of_style_cus     | character varying(35) |
Indexes:
    "of_test_archiv_pkey" PRIMARY KEY, btree (id_of)
Check constraints:
    "ck_of_old" CHECK (of_season < 22)
Inherits: of_test


xxxdb=# alter table of_test_archiv no inherit of_test;
ALTER TABLE
xxxdb=# \d of_test_archiv
            Table "archiv.of_test_archiv"
      Column      |         Type          | Modifiers
------------------+-----------------------+-----------
 id_of            | integer               | not null
 of_season        | smallint              |
 of_p_deliver_etd | date                  |
 of_p_deliver_eta | date                  |
 of_id_off        | smallint              |
 of_id_for_group  | smallint              |
 of_style_cus     | character varying(35) |
Indexes:
    "of_test_archiv_pkey" PRIMARY KEY, btree (id_of)
Check constraints:
    "ck_of_old" CHECK (of_season < 22)

Now table of_test_archiv has of_style_cus as a column, even when in the original database this column was not more part of the table definition (see above)

The dump/restore operation is no longer logical invariant to the table structure.


Because I have many of these inherited tables and I am still in the process of restructuring the data, about a year ago I got an error of restoring the production database to the dev machine bcause of inheritence error (I cant remember exactly and could not nail it down at the time: it seemed to be a type error because of column ordering).

So it is possible that you get more serious data problems by changing columns in inherited tables.

I would expect that pg_dump recognizes the same table struct as psql \d at any time.


BTW: the bloat output (e.g. NOTICE:  merging column "id_of" with inherited definition) appears in psql window even when output is redirected with \o

pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: [BUGS] BUG #14686: OpenSSL 1.1.0+ breaks PostgreSQL's sslcompression assumption, defaults to SSL_OP_NO_COMPRESSION
Next
From: Tom Lane
Date:
Subject: Re: [BUGS] BUG #14684: pg_dump omits columns in inherited tables / psql -d shows deleted columns