Skip to content

Commit 587cda3

Browse files
committed
Fix things so that updatable views work with partitioned tables.
Previously, ExecInitModifyTable was missing handling for WITH CHECK OPTION, and view_query_is_auto_updatable was missing handling for RELKIND_PARTITIONED_TABLE. Amit Langote, reviewed by me.
1 parent 132488b commit 587cda3

File tree

4 files changed

+85
-1
lines changed

4 files changed

+85
-1
lines changed

src/backend/executor/nodeModifyTable.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,6 +1777,46 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
17771777
i++;
17781778
}
17791779

1780+
/*
1781+
* Build WITH CHECK OPTION constraints for each leaf partition rel.
1782+
* Note that we didn't build the withCheckOptionList for each partition
1783+
* within the planner, but simple translation of the varattnos for each
1784+
* partition will suffice. This only occurs for the INSERT case;
1785+
* UPDATE/DELETE cases are handled above.
1786+
*/
1787+
if (node->withCheckOptionLists != NIL && mtstate->mt_num_partitions > 0)
1788+
{
1789+
List *wcoList;
1790+
1791+
Assert(operation == CMD_INSERT);
1792+
resultRelInfo = mtstate->mt_partitions;
1793+
wcoList = linitial(node->withCheckOptionLists);
1794+
for (i = 0; i < mtstate->mt_num_partitions; i++)
1795+
{
1796+
Relation partrel = resultRelInfo->ri_RelationDesc;
1797+
List *mapped_wcoList;
1798+
List *wcoExprs = NIL;
1799+
ListCell *ll;
1800+
1801+
/* varno = node->nominalRelation */
1802+
mapped_wcoList = map_partition_varattnos(wcoList,
1803+
node->nominalRelation,
1804+
partrel, rel);
1805+
foreach(ll, mapped_wcoList)
1806+
{
1807+
WithCheckOption *wco = (WithCheckOption *) lfirst(ll);
1808+
ExprState *wcoExpr = ExecInitExpr((Expr *) wco->qual,
1809+
mtstate->mt_plans[i]);
1810+
1811+
wcoExprs = lappend(wcoExprs, wcoExpr);
1812+
}
1813+
1814+
resultRelInfo->ri_WithCheckOptions = mapped_wcoList;
1815+
resultRelInfo->ri_WithCheckOptionExprs = wcoExprs;
1816+
resultRelInfo++;
1817+
}
1818+
}
1819+
17801820
/*
17811821
* Initialize RETURNING projections if needed.
17821822
*/

src/backend/rewrite/rewriteHandler.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2249,7 +2249,8 @@ view_query_is_auto_updatable(Query *viewquery, bool check_cols)
22492249
if (base_rte->rtekind != RTE_RELATION ||
22502250
(base_rte->relkind != RELKIND_RELATION &&
22512251
base_rte->relkind != RELKIND_FOREIGN_TABLE &&
2252-
base_rte->relkind != RELKIND_VIEW))
2252+
base_rte->relkind != RELKIND_VIEW &&
2253+
base_rte->relkind != RELKIND_PARTITIONED_TABLE))
22532254
return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");
22542255

22552256
if (base_rte->tablesample)

src/test/regress/expected/updatable_views.out

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,3 +2367,27 @@ ERROR: new row violates check option for view "v1"
23672367
DETAIL: Failing row contains (-1, invalid).
23682368
DROP VIEW v1;
23692369
DROP TABLE t1;
2370+
-- check that an auto-updatable view on a partitioned table works correctly
2371+
create table p (a int, b int) partition by range (a, b);
2372+
create table p1 (b int not null, a int not null) partition by range (b);
2373+
create table p11 (like p1);
2374+
alter table p11 drop a;
2375+
alter table p11 add a int;
2376+
alter table p11 drop a;
2377+
alter table p11 add a int not null;
2378+
alter table p1 attach partition p11 for values from (2) to (5);
2379+
alter table p attach partition p1 for values from (1, 2) to (1, 10);
2380+
create view pv as select * from p;
2381+
insert into pv values (1, 2);
2382+
select tableoid::regclass, * from p;
2383+
tableoid | a | b
2384+
----------+---+---
2385+
p11 | 1 | 2
2386+
(1 row)
2387+
2388+
create view pv_wco as select * from p where a = 0 with check option;
2389+
insert into pv_wco values (1, 2);
2390+
ERROR: new row violates check option for view "pv_wco"
2391+
DETAIL: Failing row contains (2, 1).
2392+
drop view pv, pv_wco;
2393+
drop table p, p1, p11;

src/test/regress/sql/updatable_views.sql

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,3 +1112,22 @@ INSERT INTO v1 VALUES (-1, 'invalid'); -- should fail
11121112

11131113
DROP VIEW v1;
11141114
DROP TABLE t1;
1115+
1116+
-- check that an auto-updatable view on a partitioned table works correctly
1117+
create table p (a int, b int) partition by range (a, b);
1118+
create table p1 (b int not null, a int not null) partition by range (b);
1119+
create table p11 (like p1);
1120+
alter table p11 drop a;
1121+
alter table p11 add a int;
1122+
alter table p11 drop a;
1123+
alter table p11 add a int not null;
1124+
alter table p1 attach partition p11 for values from (2) to (5);
1125+
alter table p attach partition p1 for values from (1, 2) to (1, 10);
1126+
1127+
create view pv as select * from p;
1128+
insert into pv values (1, 2);
1129+
select tableoid::regclass, * from p;
1130+
create view pv_wco as select * from p where a = 0 with check option;
1131+
insert into pv_wco values (1, 2);
1132+
drop view pv, pv_wco;
1133+
drop table p, p1, p11;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy