updatable view set default interact with base rel generated stored columns

Started by jian heover 1 year ago2 messages
#1jian he
jian.universality@gmail.com

hi.
While reviewing virtual generated columns,
I find some issues with the updatable view interacting with stored
generated columns.

-----------------------
drop table if exists base_tbl cascade;
CREATE TABLE base_tbl (a int, b int GENERATED ALWAYS AS (22) stored, d
int default 22);
create view rw_view1 as select * from base_tbl;
insert into rw_view1(a) values (12) returning *;

alter view rw_view1 alter column b set default 11.1;
insert into rw_view1(a,b,d) values ( 12, default,33) returning *;
insert into rw_view1(a,d) values (12,33) returning *;
insert into rw_view1 default values returning *;

SELECT events & 4 != 0 AS can_upd,
events & 8 != 0 AS can_ins,
events & 16 != 0 AS can_del
FROM pg_catalog.pg_relation_is_updatable('rw_view1'::regclass, false) t(events);
-----------------------

"alter view rw_view1 alter column b set default 11.1;"
because rw_view1 view relation in ATExecColumnDefault
TupleDesc->attgenerated == '\0',
otherwise it can error out in ATExecColumnDefault.
Now after we set default, we cannot insert any value to rw_view1,
which makes it not updatable.

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: jian he (#1)
Re: updatable view set default interact with base rel generated stored columns

jian he <jian.universality@gmail.com> writes:

-----------------------
drop table if exists base_tbl cascade;
CREATE TABLE base_tbl (a int, b int GENERATED ALWAYS AS (22) stored, d
int default 22);
create view rw_view1 as select * from base_tbl;
insert into rw_view1(a) values (12) returning *;

alter view rw_view1 alter column b set default 11.1;
insert into rw_view1(a,b,d) values ( 12, default,33) returning *;
insert into rw_view1(a,d) values (12,33) returning *;
insert into rw_view1 default values returning *;

SELECT events & 4 != 0 AS can_upd,
events & 8 != 0 AS can_ins,
events & 16 != 0 AS can_del
FROM pg_catalog.pg_relation_is_updatable('rw_view1'::regclass, false) t(events);
-----------------------

I don't really see anything wrong here. Yeah, you broke insertions
into the view yet it still claims to be updatable. But there is
nothing about the view that makes it not-updatable; it's something
that happens at runtime in the base table that is problematic.
If we try to detect all such cases we'll be solving the halting
problem. That is, I don't see any functional difference between
this example and, say, a default value attached to the view that
violates a CHECK constraint of the base table.

regards, tom lane