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.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 64c2673f9a5..b3ef201a3ae 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -45,6 +45,7 @@
#include "access/attnum.h"
#include "access/sysattr.h"
#include "access/transam.h"
+#include "catalog/pg_am.h"
#include "catalog/pg_cast.h"
#include "catalog/pg_class.h"
#include "catalog/pg_default_acl.h"
@@ -173,6 +174,7 @@ static void dumpFunc(Archive *fout, FuncInfo *finfo);
static void dumpCast(Archive *fout, CastInfo *cast);
static void dumpTransform(Archive *fout, TransformInfo *transform);
static void dumpOpr(Archive *fout, OprInfo *oprinfo);
+static void dumpAccessMethod(Archive *fout, AccessMethodInfo *oprinfo);
static void dumpOpclass(Archive *fout, OpclassInfo *opcinfo);
static void dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo);
static void dumpCollation(Archive *fout, CollInfo *convinfo);
@@ -1469,6 +1471,26 @@ selectDumpableProcLang(ProcLangInfo *plang, DumpOptions *dopt)
}
/*
+ * selectDumpableAccessMethod: policy-setting subroutine
+ * Mark an access method as to be dumped or not
+ *
+ * Access methods do not belong to any particular namespace. To identify
+ * built-in access methods, we must resort to checking whether the
+ * method's OID is in the range reserved for initdb.
+ */
+static void
+selectDumpableAccessMethod(AccessMethodInfo *method, DumpOptions *dopt)
+{
+ if (checkExtensionMembership(&method->dobj, dopt))
+ return; /* extension membership overrides all else */
+
+ if (method->dobj.catId.oid < (Oid) FirstNormalObjectId)
+ method->dobj.dump = false;
+ else
+ method->dobj.dump = dopt->include_everything;
+}
+
+/*
* selectDumpableExtension: policy-setting subroutine
* Mark an extension as to be dumped or not
*
@@ -4101,6 +4123,84 @@ getConversions(Archive *fout, int *numConversions)
}
/*
+ * getAccessMethods:
+ * read all user-defined access methods in the system catalogs and return
+ * them in the AccessMethodInfo* structure
+ *
+ * numAccessMethods is set to the number of access methods read in
+ */
+AccessMethodInfo *
+getAccessMethods(Archive *fout, int *numAccessMethods)
+{
+ DumpOptions *dopt = fout->dopt;
+ PGresult *res;
+ int ntups;
+ int i;
+ PQExpBuffer query;
+ AccessMethodInfo *aminfo;
+ int i_tableoid;
+ int i_oid;
+ int i_amname;
+ int i_amhandler;
+ int i_amtype;
+
+ /* Before 9.6, there are no user-defined access methods */
+ if (fout->remoteVersion < 90600)
+ {
+ *numAccessMethods = 0;
+ return NULL;
+ }
+
+ query = createPQExpBuffer();
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema(fout, "pg_catalog");
+
+ /*
+ * Select only user-defined access methods assuming all built-in access
+ * methods have oid < 10000.
+ */
+ appendPQExpBuffer(query, "SELECT tableoid, oid, amname, amtype, "
+ "amhandler::pg_catalog.regproc AS amhandler "
+ "FROM pg_am");
+
+ res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+
+ ntups = PQntuples(res);
+ *numAccessMethods = ntups;
+
+ aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
+
+ i_tableoid = PQfnumber(res, "tableoid");
+ i_oid = PQfnumber(res, "oid");
+ i_amname = PQfnumber(res, "amname");
+ i_amhandler = PQfnumber(res, "amhandler");
+ i_amtype = PQfnumber(res, "amtype");
+
+ for (i = 0; i < ntups; i++)
+ {
+ aminfo[i].dobj.objType = DO_ACCESS_METHOD;
+ aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
+ aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
+ AssignDumpId(&aminfo[i].dobj);
+ aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
+ aminfo[i].dobj.namespace = NULL;
+ aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
+ aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
+
+ /* Decide whether we want to dump it */
+ selectDumpableAccessMethod(&(aminfo[i]), dopt);
+ }
+
+ PQclear(res);
+
+ destroyPQExpBuffer(query);
+
+ return aminfo;
+}
+
+
+/*
* getOpclasses:
* read all opclasses in the system catalogs and return them in the
* OpclassInfo* structure
@@ -8408,6 +8508,9 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
case DO_OPERATOR:
dumpOpr(fout, (OprInfo *) dobj);
break;
+ case DO_ACCESS_METHOD:
+ dumpAccessMethod(fout, (AccessMethodInfo *) dobj);
+ break;
case DO_OPCLASS:
dumpOpclass(fout, (OpclassInfo *) dobj);
break;
@@ -11446,6 +11549,74 @@ convertTSFunction(Archive *fout, Oid funcOid)
return result;
}
+/*
+ * dumpAccessMethod
+ * write out a single access method definition
+ */
+static void
+dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
+{
+ DumpOptions *dopt = fout->dopt;
+ PQExpBuffer q;
+ PQExpBuffer delq;
+ PQExpBuffer labelq;
+ char *qamname;
+
+ /* Skip if not to be dumped */
+ if (!aminfo->dobj.dump || dopt->dataOnly)
+ return;
+
+ q = createPQExpBuffer();
+ delq = createPQExpBuffer();
+ labelq = createPQExpBuffer();
+
+ qamname = pg_strdup(fmtId(aminfo->dobj.name));
+
+ appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
+
+ switch (aminfo->amtype)
+ {
+ case AMTYPE_INDEX:
+ appendPQExpBuffer(q, "TYPE INDEX ");
+ break;
+ default:
+ write_msg(NULL, "WARNING: invalid type %c of access method %s\n",
+ aminfo->amtype, qamname);
+ destroyPQExpBuffer(q);
+ destroyPQExpBuffer(delq);
+ destroyPQExpBuffer(labelq);
+ return;
+ }
+
+ appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
+
+ appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
+ qamname);
+
+ appendPQExpBuffer(labelq, "ACCESS METHOD %s",
+ qamname);
+
+ ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
+ aminfo->dobj.name,
+ NULL,
+ NULL,
+ "",
+ false, "ACCESS METHOD", SECTION_PRE_DATA,
+ q->data, delq->data, NULL,
+ NULL, 0,
+ NULL, NULL);
+
+ /* Dump Access Method Comments */
+ dumpComment(fout, labelq->data,
+ NULL, "",
+ aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
+
+ free(qamname);
+
+ destroyPQExpBuffer(q);
+ destroyPQExpBuffer(delq);
+ destroyPQExpBuffer(labelq);
+}
/*
* dumpOpclass
@@ -16227,6 +16398,7 @@ addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
case DO_FUNC:
case DO_AGG:
case DO_OPERATOR:
+ case DO_ACCESS_METHOD:
case DO_OPCLASS:
case DO_OPFAMILY:
case DO_COLLATION: