Skip to content

Commit 1ace786

Browse files
committed
Fix dumping of security_barrier views with circular dependencies.
If a view has circular dependencies, pg_dump splits it into a CREATE TABLE and a CREATE RULE command to break the dependency loop. However, if the view has reloptions, those options cannot be applied in the CREATE TABLE command, because views and tables have different allowed reloptions so CREATE TABLE would reject them. Instead apply the reloptions after the CREATE RULE, using ALTER VIEW SET.
1 parent e0badf6 commit 1ace786

File tree

3 files changed

+34
-6
lines changed

3 files changed

+34
-6
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5062,6 +5062,16 @@ getRules(Archive *fout, int *numRules)
50625062
}
50635063
else
50645064
ruleinfo[i].separate = true;
5065+
5066+
/*
5067+
* If we're forced to break a dependency loop by dumping a view as a
5068+
* table and separate _RETURN rule, we'll move the view's reloptions
5069+
* to the rule. (This is necessary because tables and views have
5070+
* different valid reloptions, so we can't apply the options until the
5071+
* backend knows it's a view.) Otherwise the rule's reloptions stay
5072+
* NULL.
5073+
*/
5074+
ruleinfo[i].reloptions = NULL;
50655075
}
50665076

50675077
PQclear(res);
@@ -13724,10 +13734,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
1372413734
*/
1372513735
if (rinfo->ev_enabled != 'O')
1372613736
{
13727-
appendPQExpBuffer(cmd, "ALTER TABLE %s.",
13728-
fmtId(tbinfo->dobj.namespace->dobj.name));
13729-
appendPQExpBuffer(cmd, "%s ",
13730-
fmtId(tbinfo->dobj.name));
13737+
appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtId(tbinfo->dobj.name));
1373113738
switch (rinfo->ev_enabled)
1373213739
{
1373313740
case 'A':
@@ -13745,6 +13752,16 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
1374513752
}
1374613753
}
1374713754

13755+
/*
13756+
* Apply view's reloptions when its ON SELECT rule is separate.
13757+
*/
13758+
if (rinfo->reloptions)
13759+
{
13760+
appendPQExpBuffer(cmd, "ALTER VIEW %s SET (%s);\n",
13761+
fmtId(tbinfo->dobj.name),
13762+
rinfo->reloptions);
13763+
}
13764+
1374813765
/*
1374913766
* DROP must be fully qualified in case same name appears in pg_catalog
1375013767
*/

src/bin/pg_dump/pg_dump.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ typedef struct _ruleInfo
332332
char ev_enabled;
333333
bool separate; /* TRUE if must dump as separate item */
334334
/* separate is always true for non-ON SELECT rules */
335+
char *reloptions; /* options specified by WITH (...) */
336+
/* reloptions is only set if we need to dump the options with the rule */
335337
} RuleInfo;
336338

337339
typedef struct _triggerInfo

src/bin/pg_dump/pg_dump_sort.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,12 +722,21 @@ static void
722722
repairViewRuleMultiLoop(DumpableObject *viewobj,
723723
DumpableObject *ruleobj)
724724
{
725+
TableInfo *viewinfo = (TableInfo *) viewobj;
726+
RuleInfo *ruleinfo = (RuleInfo *) ruleobj;
727+
725728
/* remove view's dependency on rule */
726729
removeObjectDependency(viewobj, ruleobj->dumpId);
727730
/* pretend view is a plain table and dump it that way */
728-
((TableInfo *) viewobj)->relkind = 'r'; /* RELKIND_RELATION */
731+
viewinfo->relkind = 'r'; /* RELKIND_RELATION */
729732
/* mark rule as needing its own dump */
730-
((RuleInfo *) ruleobj)->separate = true;
733+
ruleinfo->separate = true;
734+
/* move any reloptions from view to rule */
735+
if (viewinfo->reloptions)
736+
{
737+
ruleinfo->reloptions = viewinfo->reloptions;
738+
viewinfo->reloptions = NULL;
739+
}
731740
/* put back rule's dependency on view */
732741
addObjectDependency(ruleobj, viewobj->dumpId);
733742
/* now that rule is separate, it must be post-data */

0 commit comments

Comments
 (0)