Thread: Insert/Dump/Restore table with generated columns

Insert/Dump/Restore table with generated columns

From
zickzack@quantentunnel.de
Date:
Hi,

I have several tables with generated columns. If I restore the plain dumped data (insert statements from pg_dump) I'll
getthe error message "Column xyz is a generated column.". The exception is understandably, no question (and is well
documented).In case of the error no insert takes place.  
My problem now is that my simple backup/restore workflow is corrupted, cause those tables with generated column will be
empty.

## The question is:

Does some "simple" workaround exists to prevent this?
Is it somehow possible to dump only non-generated columns?
Is it somwhow possible to ignore the error and allow the other columns to be inserted?
Any other handy solutions? 

## simple example 

```sql
CREATE OR REPLACE FUNCTION generate_person_age(birth timestamptz) RETURNS double precision
LANGUAGE sql IMMUTABLE
AS $$
select EXTRACT(years FROM justify_interval(now() - birth));
$$; 
DROP TABLE IF EXISTS person;
CREATE TABLE person (
id serial primary key
,name text NOT NULL
,birth timestamptz NOT NULL
,age double precision GENERATED ALWAYS as (generate_person_age(birth)) STORED
); 
insert into person(name, birth) values
('Peter Pan', '1902-01-01'); 
-- leeds to exception
insert into person(id, name, birth, age) values
(1, 'Peter Pan', '1902-01-01 00:00:00+00', '121');
``` 

* exception
```
cannot insert into column "age"
Column "age" is a generated column.
``` 

## Solution ideas

* A colleague had the idea to change the generated columns into a normal one and to use a trigger on changes of the
sourcecolumns. Inserts should not be different than a default column. 
* Writing a before insert trigger, that removes the generated column values. But seems not that performant, cause this
willfire on every insert, not only in restores. 
* Excluding tables with generated columns during pg_dump. Exporting tables with generated columns with hand written
sql.Seems like a good source of many bugs and a maintainance problem.  
Greetings!



Re: Insert/Dump/Restore table with generated columns

From
David Rowley
Date:
On Thu, 1 Jul 2021 at 22:06, <zickzack@quantentunnel.de> wrote:
> I have several tables with generated columns. If I restore the plain dumped data (insert statements from pg_dump)
I'llget the error message "Column xyz is a generated column.". The exception is understandably, no question (and is
welldocumented). In case of the error no insert takes place. 
> My problem now is that my simple backup/restore workflow is corrupted, cause those tables with generated column will
beempty. 

As far as I can see, this shouldn't happen.  I tried to recreate and I can't.

create table ab (a int, b int generated always as (a / 2) stored);
insert into ab values(1);

Running:

pg_dump --table=ab --column-inserts postgres

I see the following in the pg_dump output.

INSERT INTO public.ab (a, b) VALUES (1, DEFAULT);

pg_dump --table=ab --inserts postgres

gives:

INSERT INTO public.ab VALUES (1, DEFAULT);

both of these commands work fine when I run them on the existing database.

I tested this on current master, but looking at the history [1], it
looks like the pg_dump support was added when the feature went in, so
that indicates that it was not missed then subsequently fixed later.

Just to keep us from having to guess, are you able to share the
version of PostgreSQL you're running? Also, the version of pg_dump?
pg_dump --version will tell you that.

David

[1] https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=fc22b6623b6b3bab3cb057ccd282c2bfad1a0b30



Re: Re: Insert/Dump/Restore table with generated columns

From
zickzack@quantentunnel.de
Date:
Hi David,

thanks for you're quick answer.
I'am using postgres 12 and also tested with 13. Both inside the official (debian based) docker hub hosted container.

After you're answer I did a few investigations. If I insert data with a single insert, everything is working like
expected

INSERT INTO public.ab VALUES (1, DEFAULT);

this changes if I do multiple inserts in one statement:

INSERT INTO public.ab VALUES (1, DEFAULT), (2, DEFAULT);
ERROR:  cannot insert into column "b"
DETAIL:  Column "b" is a generated column.

Is this a bug or a feature?

In my specific backup case I exported the data with the flags: --column-inserts, --inserts and --rows-per-insert=1000.
Dueto the latter I ran into the behaviour described obove.
 
If I export the data with the default copy statement, no problems occur.

Greetings



Re: Insert/Dump/Restore table with generated columns

From
Tom Lane
Date:
zickzack@quantentunnel.de writes:
> After you're answer I did a few investigations. If I insert data with a single insert, everything is working like
expected
> INSERT INTO public.ab VALUES (1, DEFAULT);
> this changes if I do multiple inserts in one statement:
> INSERT INTO public.ab VALUES (1, DEFAULT), (2, DEFAULT);
> ERROR:  cannot insert into column "b"
> DETAIL:  Column "b" is a generated column.

> Is this a bug or a feature?

It's a deficiency :-(.  It's fixed for v14 but the fix seemed too invasive
to back-patch.

https://git.postgresql.org/gitweb/?p=postgresql.git&a=commitdiff&h=17958972f

            regards, tom lane