Only dump non-default sequence access methods
authorCraig Ringer <craig@2ndquadrant.com>
Tue, 26 May 2015 02:18:10 +0000 (10:18 +0800)
committerCraig Ringer <craig@2ndquadrant.com>
Tue, 26 May 2015 02:22:56 +0000 (10:22 +0800)
To prevent issues with UDR and with restoring BDR dumps to non-BDR
databases, don't emit a USING clause unless the pg_seqam catalog is
present and the dumped sequence uses a non-default sequence access
method.

The dump should be restored with default_seqam = 'local' to ensure
that local sequences aren't transformed into 'bdr' sequences during
restore.

src/bin/pg_dump/pg_dump.c

index 8d07387c2046da787666a088f7dcd6619a5593a0..01154754e1a16f18aaa8dc083461bda6828b92d6 100644 (file)
@@ -14202,6 +14202,46 @@ findLastBuiltinOid_V70(Archive *fout)
    return last_oid;
 }
 
+/*
+ * If pg_seqam exists, return the sequence AM name for the specified
+ * sequence. If there's no pg_seqam, return null.
+ *
+ * The string returned, if any, must be free'd by the caller.
+ */
+static char*
+find_sequence_seqam(Archive *fout, Oid seq_oid)
+{
+   PGresult   *res;
+   const char *amname = NULL;
+   PQExpBuffer query = createPQExpBuffer();
+
+   res = ExecuteSqlQuery(fout, "SELECT EXISTS(SELECT 1 "
+                               "FROM pg_catalog.pg_class c, "
+                               "pg_catalog.pg_namespace n "
+                               "WHERE n.oid = c.relnamespace "
+                               "AND c.relname = 'pg_seqam' "
+                               "AND c.relkind = 'r');",
+                         PGRES_TUPLES_OK);
+   if (strcmp(PQgetvalue(res, 0, 0), "t") == 0)
+   {
+       PQclear(res);
+
+       printfPQExpBuffer(query, "SELECT a.seqamname\n"
+                                "FROM pg_catalog.pg_seqam a, pg_catalog.pg_class c\n"
+                                "WHERE c.relam = a.oid AND c.oid = %u",
+                         seq_oid);
+
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+
+       amname = pg_strdup(PQgetvalue(res, 0, 0));
+   }
+
+   PQclear(res);
+
+   destroyPQExpBuffer(query);
+   return amname;
+}
+
 /*
  * dumpSequence
  *   write the declaration (not data) of one user-defined sequence
@@ -14215,7 +14255,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
               *maxv = NULL,
               *minv = NULL,
               *cache,
-              *amname = "local";
+              *amname;
    char        bufm[100],
                bufx[100];
    bool        cycled;
@@ -14296,28 +14336,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 
    PQclear(res);
 
-   res = ExecuteSqlQuery(fout, "SELECT EXISTS(SELECT 1 "
-                               "FROM pg_catalog.pg_class c, "
-                               "pg_catalog.pg_namespace n "
-                               "WHERE n.oid = c.relnamespace "
-                               "AND c.relname = 'pg_seqam' "
-                               "AND c.relkind = 'r');",
-                         PGRES_TUPLES_OK);
-   if (strcmp(PQgetvalue(res, 0, 0), "t") == 0)
-   {
-       PQclear(res);
-
-       printfPQExpBuffer(query, "SELECT a.seqamname\n"
-                                "FROM pg_catalog.pg_seqam a, pg_catalog.pg_class c\n"
-                                "WHERE c.relam = a.oid AND c.oid = %u",
-                         tbinfo->dobj.catId.oid);
-
-       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
-
-       amname = pg_strdup(PQgetvalue(res, 0, 0));
-   }
-
-   PQclear(res);
+   amname = find_sequence_seqam(fout, tbinfo->dobj.catId.oid);
 
    /*
     * DROP must be fully qualified in case same name appears in pg_catalog
@@ -14360,11 +14379,24 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
                      "    CACHE %s%s",
                      cache, (cycled ? "\n    CYCLE" : ""));
 
-   appendPQExpBuffer(query, "\n    USING %s", fmtId(amname));
+   /*
+    * Only dump the sequence access method if it's not a PostgreSQL
+    * built-in sequence.
+    *
+    * FIXME: For 'bdr' sequences we should really delay them
+    * until the data from the 'bdr' extension schema has been
+    * restored.
+    */
+   if (amname != NULL && strcmp(amname, "local") != 0)
+       appendPQExpBuffer(query, "\n    USING %s", fmtId(amname));
+
+   free(amname);
+
    appendPQExpBufferStr(query, ";\n");
 
    appendPQExpBuffer(labelq, "SEQUENCE %s", fmtId(tbinfo->dobj.name));
 
+
    /* binary_upgrade:  no need to clear TOAST table oid */
 
    if (binary_upgrade)