From b6263cd851ef245a5dc38119448e029ca1592da4 Mon Sep 17 00:00:00 2001 From: Dean Rasheed Date: Tue, 13 Jun 2017 17:30:36 +0100 Subject: [PATCH] Teach relation_is_updatable() about partitioned tables. Table partitioning, introduced in commit f0e44751d7, added a new relkind - RELKIND_PARTITIONED_TABLE. Update relation_is_updatable() to handle it. Specifically, partitioned tables and simple views built on top of them are updatable. This affects the SQL-callable functions pg_relation_is_updatable() and pg_column_is_updatable(), and the views information_schema.views and information_schema.columns. Dean Rasheed, reviewed by Ashutosh Bapat. Discussion: https://postgr.es/m/CAEZATCXnbiFkMXgF4Ez1pmM2c-tS1z33bSq7OGbw7QQhHov%2B6Q%40mail.gmail.com --- src/backend/rewrite/rewriteHandler.c | 6 ++-- src/test/regress/expected/updatable_views.out | 36 +++++++++++++++++++ src/test/regress/sql/updatable_views.sql | 10 ++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 6cd73c1386..399380735c 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -2454,7 +2454,8 @@ relation_is_updatable(Oid reloid, return 0; /* If the relation is a table, it is always updatable */ - if (rel->rd_rel->relkind == RELKIND_RELATION) + if (rel->rd_rel->relkind == RELKIND_RELATION || + rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { relation_close(rel, AccessShareLock); return ALL_EVENTS; @@ -2568,7 +2569,8 @@ relation_is_updatable(Oid reloid, base_rte = rt_fetch(rtr->rtindex, viewquery->rtable); Assert(base_rte->rtekind == RTE_RELATION); - if (base_rte->relkind != RELKIND_RELATION) + if (base_rte->relkind != RELKIND_RELATION && + base_rte->relkind != RELKIND_PARTITIONED_TABLE) { baseoid = base_rte->relid; include_cols = adjust_view_column_set(updatable_cols, diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out index f6b51a54c3..971dddd01c 100644 --- a/src/test/regress/expected/updatable_views.out +++ b/src/test/regress/expected/updatable_views.out @@ -2378,6 +2378,42 @@ alter table pt11 add a int not null; alter table pt1 attach partition pt11 for values from (2) to (5); alter table pt attach partition pt1 for values from (1, 2) to (1, 10); create view ptv as select * from pt; +select events & 4 != 0 AS upd, + events & 8 != 0 AS ins, + events & 16 != 0 AS del + from pg_catalog.pg_relation_is_updatable('pt'::regclass, false) t(events); + upd | ins | del +-----+-----+----- + t | t | t +(1 row) + +select pg_catalog.pg_column_is_updatable('pt'::regclass, 1::smallint, false); + pg_column_is_updatable +------------------------ + t +(1 row) + +select pg_catalog.pg_column_is_updatable('pt'::regclass, 2::smallint, false); + pg_column_is_updatable +------------------------ + t +(1 row) + +select table_name, is_updatable, is_insertable_into + from information_schema.views where table_name = 'ptv'; + table_name | is_updatable | is_insertable_into +------------+--------------+-------------------- + ptv | YES | YES +(1 row) + +select table_name, column_name, is_updatable + from information_schema.columns where table_name = 'ptv' order by column_name; + table_name | column_name | is_updatable +------------+-------------+-------------- + ptv | a | YES + ptv | b | YES +(2 rows) + insert into ptv values (1, 2); select tableoid::regclass, * from pt; tableoid | a | b diff --git a/src/test/regress/sql/updatable_views.sql b/src/test/regress/sql/updatable_views.sql index d89062c3b1..6a9958d38b 100644 --- a/src/test/regress/sql/updatable_views.sql +++ b/src/test/regress/sql/updatable_views.sql @@ -1125,6 +1125,16 @@ alter table pt1 attach partition pt11 for values from (2) to (5); alter table pt attach partition pt1 for values from (1, 2) to (1, 10); create view ptv as select * from pt; +select events & 4 != 0 AS upd, + events & 8 != 0 AS ins, + events & 16 != 0 AS del + from pg_catalog.pg_relation_is_updatable('pt'::regclass, false) t(events); +select pg_catalog.pg_column_is_updatable('pt'::regclass, 1::smallint, false); +select pg_catalog.pg_column_is_updatable('pt'::regclass, 2::smallint, false); +select table_name, is_updatable, is_insertable_into + from information_schema.views where table_name = 'ptv'; +select table_name, column_name, is_updatable + from information_schema.columns where table_name = 'ptv' order by column_name; insert into ptv values (1, 2); select tableoid::regclass, * from pt; create view ptv_wco as select * from pt where a = 0 with check option; -- 2.40.0