]> granicus.if.org Git - postgresql/commitdiff
Teach relation_is_updatable() about partitioned tables.
authorDean Rasheed <dean.a.rasheed@gmail.com>
Tue, 13 Jun 2017 16:30:36 +0000 (17:30 +0100)
committerDean Rasheed <dean.a.rasheed@gmail.com>
Tue, 13 Jun 2017 16:30:36 +0000 (17:30 +0100)
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
src/test/regress/expected/updatable_views.out
src/test/regress/sql/updatable_views.sql

index 6cd73c13868110a510059fa26e50c4424ab9a95b..399380735c57cdb4092a975ac138c8b23a08506f 100644 (file)
@@ -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,
index f6b51a54c31fd32ea9cbe1f4ab553f4113c810a9..971dddd01c5b03ae47786164a6113738391c6005 100644 (file)
@@ -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 
index d89062c3b13b07fca3083ae0581bb33edb5a3f27..6a9958d38b9b51d5df43efdb576175107943d7c0 100644 (file)
@@ -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;