aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_dump/pg_dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/pg_dump/pg_dump.c')
-rw-r--r--src/bin/pg_dump/pg_dump.c187
1 files changed, 182 insertions, 5 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 34ebc27168d..d1715eccce8 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.548 2009/09/22 23:43:38 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.549 2009/10/05 19:24:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,6 +34,7 @@
#include "access/sysattr.h"
#include "catalog/pg_cast.h"
#include "catalog/pg_class.h"
+#include "catalog/pg_default_acl.h"
#include "catalog/pg_largeobject.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_trigger.h"
@@ -162,6 +163,7 @@ static void dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo);
static void dumpUserMappings(Archive *fout, const char *target,
const char *servername, const char *namespace,
const char *owner, CatalogId catalogId, DumpId dumpId);
+static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
const char *type, const char *name, const char *subname,
@@ -1050,6 +1052,23 @@ selectDumpableType(TypeInfo *tinfo)
}
/*
+ * selectDumpableDefaultACL: policy-setting subroutine
+ * Mark a default ACL as to be dumped or not
+ *
+ * For per-schema default ACLs, dump if the schema is to be dumped.
+ * Otherwise dump if we are dumping "everything". Note that dataOnly
+ * and aclsSkip are checked separately.
+ */
+static void
+selectDumpableDefaultACL(DefaultACLInfo *dinfo)
+{
+ if (dinfo->dobj.namespace)
+ dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump;
+ else
+ dinfo->dobj.dump = include_everything;
+}
+
+/*
* selectDumpableObject: policy-setting subroutine
* Mark a generic dumpable object as to be dumped or not
*
@@ -1779,7 +1798,7 @@ dumpDatabase(Archive *AH)
PQExpBuffer loFrozenQry = createPQExpBuffer();
PQExpBuffer loOutQry = createPQExpBuffer();
int i_relfrozenxid;
-
+
appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid\n"
"FROM pg_catalog.pg_class\n"
"WHERE oid = %d;\n",
@@ -1808,7 +1827,7 @@ dumpDatabase(Archive *AH)
loOutQry->data, "", NULL,
NULL, 0,
NULL, NULL);
-
+
PQclear(lo_res);
destroyPQExpBuffer(loFrozenQry);
destroyPQExpBuffer(loOutQry);
@@ -5646,6 +5665,94 @@ getForeignServers(int *numForeignServers)
}
/*
+ * getDefaultACLs:
+ * read all default ACL information in the system catalogs and return
+ * them in the DefaultACLInfo structure
+ *
+ * numDefaultACLs is set to the number of ACLs read in
+ */
+DefaultACLInfo *
+getDefaultACLs(int *numDefaultACLs)
+{
+ DefaultACLInfo *daclinfo;
+ PQExpBuffer query;
+ PGresult *res;
+ int i_oid;
+ int i_tableoid;
+ int i_defaclrole;
+ int i_defaclnamespace;
+ int i_defaclobjtype;
+ int i_defaclacl;
+ int i,
+ ntups;
+
+ if (g_fout->remoteVersion < 80500)
+ {
+ *numDefaultACLs = 0;
+ return NULL;
+ }
+
+ query = createPQExpBuffer();
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema("pg_catalog");
+
+ appendPQExpBuffer(query, "SELECT oid, tableoid, "
+ "(%s defaclrole) AS defaclrole, "
+ "defaclnamespace, "
+ "defaclobjtype, "
+ "defaclacl "
+ "FROM pg_default_acl",
+ username_subquery);
+
+ res = PQexec(g_conn, query->data);
+ check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+
+ ntups = PQntuples(res);
+ *numDefaultACLs = ntups;
+
+ daclinfo = (DefaultACLInfo *) malloc(ntups * sizeof(DefaultACLInfo));
+
+ i_oid = PQfnumber(res, "oid");
+ i_tableoid = PQfnumber(res, "tableoid");
+ i_defaclrole = PQfnumber(res, "defaclrole");
+ i_defaclnamespace = PQfnumber(res, "defaclnamespace");
+ i_defaclobjtype = PQfnumber(res, "defaclobjtype");
+ i_defaclacl = PQfnumber(res, "defaclacl");
+
+ for (i = 0; i < ntups; i++)
+ {
+ Oid nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
+
+ daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
+ daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
+ daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
+ AssignDumpId(&daclinfo[i].dobj);
+ /* cheesy ... is it worth coming up with a better object name? */
+ daclinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_defaclobjtype));
+
+ if (nspid != InvalidOid)
+ daclinfo[i].dobj.namespace = findNamespace(nspid,
+ daclinfo[i].dobj.catId.oid);
+ else
+ daclinfo[i].dobj.namespace = NULL;
+
+ daclinfo[i].defaclrole = strdup(PQgetvalue(res, i, i_defaclrole));
+ daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
+ daclinfo[i].defaclacl = strdup(PQgetvalue(res, i, i_defaclacl));
+
+ /* Decide whether we want to dump it */
+ selectDumpableDefaultACL(&(daclinfo[i]));
+ }
+
+ PQclear(res);
+
+ destroyPQExpBuffer(query);
+
+ return daclinfo;
+}
+
+/*
* dumpComment --
*
* This routine is used to dump any comments associated with the
@@ -6058,6 +6165,9 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
case DO_FOREIGN_SERVER:
dumpForeignServer(fout, (ForeignServerInfo *) dobj);
break;
+ case DO_DEFAULT_ACL:
+ dumpDefaultACL(fout, (DefaultACLInfo *) dobj);
+ break;
case DO_BLOBS:
ArchiveEntry(fout, dobj->catId, dobj->dumpId,
dobj->name, NULL, NULL, "",
@@ -9791,6 +9901,72 @@ dumpUserMappings(Archive *fout, const char *target,
destroyPQExpBuffer(q);
}
+/*
+ * Write out default privileges information
+ */
+static void
+dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
+{
+ PQExpBuffer q;
+ PQExpBuffer tag;
+ const char *type;
+
+ /* Skip if not to be dumped */
+ if (!daclinfo->dobj.dump || dataOnly || aclsSkip)
+ return;
+
+ q = createPQExpBuffer();
+ tag = createPQExpBuffer();
+
+ switch (daclinfo->defaclobjtype)
+ {
+ case DEFACLOBJ_RELATION:
+ type = "TABLE";
+ break;
+ case DEFACLOBJ_SEQUENCE:
+ type = "SEQUENCE";
+ break;
+ case DEFACLOBJ_FUNCTION:
+ type = "FUNCTION";
+ break;
+ default:
+ /* shouldn't get here */
+ write_msg(NULL, "unknown object type (%d) in default privileges\n",
+ (int) daclinfo->defaclobjtype);
+ exit_nicely();
+ type = ""; /* keep compiler quiet */
+ }
+
+ appendPQExpBuffer(tag, "DEFAULT %s PRIVILEGES", type);
+
+ /* build the actual command(s) for this tuple */
+ if (!buildDefaultACLCommands(type,
+ daclinfo->dobj.namespace != NULL ?
+ daclinfo->dobj.namespace->dobj.name : NULL,
+ daclinfo->defaclacl,
+ daclinfo->defaclrole,
+ fout->remoteVersion,
+ q))
+ {
+ write_msg(NULL, "could not parse default ACL list (%s)\n",
+ daclinfo->defaclacl);
+ exit_nicely();
+ }
+
+ ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
+ tag->data,
+ daclinfo->dobj.namespace ? daclinfo->dobj.namespace->dobj.name : NULL,
+ NULL,
+ daclinfo->defaclrole,
+ false, "DEFAULT ACL", SECTION_NONE,
+ q->data, "", NULL,
+ daclinfo->dobj.dependencies, daclinfo->dobj.nDeps,
+ NULL, NULL);
+
+ destroyPQExpBuffer(tag);
+ destroyPQExpBuffer(q);
+}
+
/*----------
* Write out grant/revoke information
*
@@ -9820,7 +9996,8 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
sql = createPQExpBuffer();
- if (!buildACLCommands(name, subname, type, acls, owner, fout->remoteVersion, sql))
+ if (!buildACLCommands(name, subname, type, acls, owner,
+ "", fout->remoteVersion, sql))
{
write_msg(NULL, "could not parse ACL list (%s) for object \"%s\" (%s)\n",
acls, name, type);
@@ -10263,7 +10440,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
fmtId(tbinfo->dobj.name));
appendPQExpBuffer(q, "ALTER COLUMN %s ",
fmtId(tbinfo->attnames[j]));
- appendPQExpBuffer(q, "SET STATISTICS DISTINCT %g;\n",
+ appendPQExpBuffer(q, "SET STATISTICS DISTINCT %g;\n",
tbinfo->attdistinct[j]);
}