aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-08-21 15:18:36 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-08-21 15:18:36 -0400
commit0f524ea0cf388a149f362e48a33c01662eeddc04 (patch)
tree306092fe85e6cffbc515b26c688654487a531c46 /src
parent4b373e42d1efd24f871193ce8178c41f199c5df3 (diff)
downloadpostgresql-0f524ea0cf388a149f362e48a33c01662eeddc04.tar.gz
postgresql-0f524ea0cf388a149f362e48a33c01662eeddc04.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_dump.c25
-rw-r--r--src/bin/pg_dump/pg_dump.h2
-rw-r--r--src/bin/pg_dump/pg_dump_sort.c13
3 files changed, 34 insertions, 6 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 09ca6ddbeb8..cdbed209083 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -5064,6 +5064,16 @@ getRules(Archive *fout, int *numRules)
}
else
ruleinfo[i].separate = true;
+
+ /*
+ * If we're forced to break a dependency loop by dumping a view as a
+ * table and separate _RETURN rule, we'll move the view's reloptions
+ * to the rule. (This is necessary because tables and views have
+ * different valid reloptions, so we can't apply the options until the
+ * backend knows it's a view.) Otherwise the rule's reloptions stay
+ * NULL.
+ */
+ ruleinfo[i].reloptions = NULL;
}
PQclear(res);
@@ -13873,10 +13883,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
*/
if (rinfo->ev_enabled != 'O')
{
- appendPQExpBuffer(cmd, "ALTER TABLE %s.",
- fmtId(tbinfo->dobj.namespace->dobj.name));
- appendPQExpBuffer(cmd, "%s ",
- fmtId(tbinfo->dobj.name));
+ appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtId(tbinfo->dobj.name));
switch (rinfo->ev_enabled)
{
case 'A':
@@ -13895,6 +13902,16 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
}
/*
+ * Apply view's reloptions when its ON SELECT rule is separate.
+ */
+ if (rinfo->reloptions)
+ {
+ appendPQExpBuffer(cmd, "ALTER VIEW %s SET (%s);\n",
+ fmtId(tbinfo->dobj.name),
+ rinfo->reloptions);
+ }
+
+ /*
* DROP must be fully qualified in case same name appears in pg_catalog
*/
appendPQExpBuffer(delcmd, "DROP RULE %s ",
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 5793bca0c4f..2aa206038de 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -333,6 +333,8 @@ typedef struct _ruleInfo
char ev_enabled;
bool separate; /* TRUE if must dump as separate item */
/* separate is always true for non-ON SELECT rules */
+ char *reloptions; /* options specified by WITH (...) */
+ /* reloptions is only set if we need to dump the options with the rule */
} RuleInfo;
typedef struct _triggerInfo
diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index cccc1e0646e..ddbe8305b13 100644
--- a/src/bin/pg_dump/pg_dump_sort.c
+++ b/src/bin/pg_dump/pg_dump_sort.c
@@ -725,12 +725,21 @@ static void
repairViewRuleMultiLoop(DumpableObject *viewobj,
DumpableObject *ruleobj)
{
+ TableInfo *viewinfo = (TableInfo *) viewobj;
+ RuleInfo *ruleinfo = (RuleInfo *) ruleobj;
+
/* remove view's dependency on rule */
removeObjectDependency(viewobj, ruleobj->dumpId);
/* pretend view is a plain table and dump it that way */
- ((TableInfo *) viewobj)->relkind = 'r'; /* RELKIND_RELATION */
+ viewinfo->relkind = 'r'; /* RELKIND_RELATION */
/* mark rule as needing its own dump */
- ((RuleInfo *) ruleobj)->separate = true;
+ ruleinfo->separate = true;
+ /* move any reloptions from view to rule */
+ if (viewinfo->reloptions)
+ {
+ ruleinfo->reloptions = viewinfo->reloptions;
+ viewinfo->reloptions = NULL;
+ }
/* put back rule's dependency on view */
addObjectDependency(ruleobj, viewobj->dumpId);
/* now that rule is separate, it must be post-data */