Add pg_dump --binary-upgrade flag to be used by binary upgrade
authorBruce Momjian
Tue, 17 Feb 2009 15:41:50 +0000 (15:41 +0000)
committerBruce Momjian
Tue, 17 Feb 2009 15:41:50 +0000 (15:41 +0000)
utilities.

The new code allows transfer of dropped column information to the
upgraded server.

doc/src/sgml/ref/pg_dump.sgml
doc/src/sgml/ref/pg_dumpall.sgml
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
src/bin/pg_dump/pg_dumpall.c

index 8ba20ade3ff21735e55a3e65113a93b86c4b3114..0a9d0dc26ef9ad33c7e2aac42cc39bbc067159db 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -827,6 +827,11 @@ CREATE DATABASE foo WITH TEMPLATE template0;
    editing of the dump file might be required.
   
 
+  
+   pg_dump also supports a
+   --binary-upgrade option for upgrade utility usage.
+  
+
  
 
  
index dfb8d0dc6f7f4440041d4a41e93531510a4b24df..6e6ef46c6789cd14173cb8e899ce52e1f7fe1a63 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -489,6 +489,11 @@ PostgreSQL documentation
    locations.
   
 
+  
+   pg_dump also supports a
+   --binary-upgrade option for upgrade utility usage.
+  
+
  
 
 
index 51301cd48c180547f7317b650ee2a01a9ce502a9..c1fc678d6186ebdc351db5cb6fefa0dacda75912 100644 (file)
@@ -12,7 +12,7 @@
  * by PostgreSQL
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.521 2009/02/16 23:06:55 momjian Exp $
+ *   $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.522 2009/02/17 15:41:50 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -99,6 +99,8 @@ static SimpleOidList table_exclude_oids = {NULL, NULL};
 /* default, if no "inclusion" switches appear, is to dump everything */
 static bool include_everything = true;
 
+static int binary_upgrade = 0;
+
 char       g_opaque_type[10];  /* name for the opaque type */
 
 /* placeholders for the delimiters for comments */
@@ -236,7 +238,8 @@ main(int argc, char **argv)
    static int  outputNoTablespaces = 0;
    static int  use_setsessauth = 0;
 
-   static struct option long_options[] = {
+   struct option long_options[] = {
+       {"binary-upgrade", no_argument, &binary_upgrade, 1},    /* not documented */
        {"data-only", no_argument, NULL, 'a'},
        {"blobs", no_argument, NULL, 'b'},
        {"clean", no_argument, NULL, 'c'},
@@ -4611,6 +4614,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
    int         i_attnotnull;
    int         i_atthasdef;
    int         i_attisdropped;
+   int         i_attlen;
+   int         i_attalign;
    int         i_attislocal;
    PGresult   *res;
    int         ntups;
@@ -4655,7 +4660,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
            appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
                                 "a.attstattarget, a.attstorage, t.typstorage, "
                                 "a.attnotnull, a.atthasdef, a.attisdropped, "
-                                "a.attislocal, "
+                                "a.attlen, a.attalign, a.attislocal, "
                   "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname "
             "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
                              "ON a.atttypid = t.oid "
@@ -4674,7 +4679,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
            appendPQExpBuffer(q, "SELECT a.attnum, a.attname, "
                              "a.atttypmod, -1 AS attstattarget, a.attstorage, "
                              "t.typstorage, a.attnotnull, a.atthasdef, "
-                             "false AS attisdropped, false AS attislocal, "
+                             "false AS attisdropped, 0 AS attlen, "
+                             "' ' AS attalign, false AS attislocal, "
                              "format_type(t.oid,a.atttypmod) AS atttypname "
                              "FROM pg_attribute a LEFT JOIN pg_type t "
                              "ON a.atttypid = t.oid "
@@ -4690,7 +4696,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                              "-1 AS attstattarget, attstorage, "
                              "attstorage AS typstorage, "
                              "attnotnull, atthasdef, false AS attisdropped, "
-                             "false AS attislocal, "
+                             "0 AS attlen, ' ' AS attalign, "
+                             "false AS attislocal, "
                              "(SELECT typname FROM pg_type WHERE oid = atttypid) AS atttypname "
                              "FROM pg_attribute a "
                              "WHERE attrelid = '%u'::oid "
@@ -4714,6 +4721,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
        i_attnotnull = PQfnumber(res, "attnotnull");
        i_atthasdef = PQfnumber(res, "atthasdef");
        i_attisdropped = PQfnumber(res, "attisdropped");
+       i_attlen = PQfnumber(res, "attlen");
+       i_attalign = PQfnumber(res, "attalign");
        i_attislocal = PQfnumber(res, "attislocal");
 
        tbinfo->numatts = ntups;
@@ -4724,6 +4733,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
        tbinfo->attstorage = (char *) malloc(ntups * sizeof(char));
        tbinfo->typstorage = (char *) malloc(ntups * sizeof(char));
        tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool));
+       tbinfo->attlen = (int *) malloc(ntups * sizeof(int));
+       tbinfo->attalign = (char *) malloc(ntups * sizeof(char));
        tbinfo->attislocal = (bool *) malloc(ntups * sizeof(bool));
        tbinfo->notnull = (bool *) malloc(ntups * sizeof(bool));
        tbinfo->attrdefs = (AttrDefInfo **) malloc(ntups * sizeof(AttrDefInfo *));
@@ -4747,6 +4758,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
            tbinfo->attstorage[j] = *(PQgetvalue(res, j, i_attstorage));
            tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage));
            tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't');
+           tbinfo->attlen[j] = atoi(PQgetvalue(res, j, i_attlen));
+           tbinfo->attalign[j] = *(PQgetvalue(res, j, i_attalign));
            tbinfo->attislocal[j] = (PQgetvalue(res, j, i_attislocal)[0] == 't');
            tbinfo->notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't');
            tbinfo->attrdefs[j] = NULL; /* fix below */
@@ -4760,6 +4773,21 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 
        PQclear(res);
 
+
+       /*
+        *  ALTER TABLE DROP COLUMN clears pg_attribute.atttypid, so we
+        *  set the column data type to 'TEXT;  we will later drop the
+        *  column.
+        */
+       if (binary_upgrade)
+       {
+           for (j = 0; j < ntups; j++)
+           {
+               if (tbinfo->attisdropped[j])
+                   tbinfo->atttypnames[j] = strdup("TEXT");
+           }
+       }
+           
        /*
         * Get info about column defaults
         */
@@ -9680,7 +9708,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
        for (j = 0; j < tbinfo->numatts; j++)
        {
            /* Is this one of the table's own attrs, and not dropped ? */
-           if (!tbinfo->inhAttrs[j] && !tbinfo->attisdropped[j])
+           if (!tbinfo->inhAttrs[j] &&
+               (!tbinfo->attisdropped[j] || binary_upgrade))
            {
                /* Format properly if not first attr */
                if (actual_atts > 0)
@@ -9786,6 +9815,53 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
        appendPQExpBuffer(q, ";\n");
 
+       /*
+        * For binary-compatible heap files, we create dropped columns
+        * above and drop them here.
+        */
+       if (binary_upgrade)
+       {
+           for (j = 0; j < tbinfo->numatts; j++)
+           {
+               if (tbinfo->attisdropped[j])
+               {
+                   appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+                                     fmtId(tbinfo->dobj.name));
+                   appendPQExpBuffer(q, "DROP COLUMN %s;\n",
+                                     fmtId(tbinfo->attnames[j]));
+
+                   /*
+                    *  ALTER TABLE DROP COLUMN clears pg_attribute.atttypid,
+                    *  so we have to set pg_attribute.attlen and
+                    *  pg_attribute.attalign values because that is what
+                    *  is used to skip over dropped columns in the heap tuples.
+                    *  We have atttypmod, but it seems impossible to know the
+                    *  correct data type that will yield pg_attribute values
+                    *  that match the old installation.
+                    *  See comment in backend/catalog/heap.c::RemoveAttributeById()
+                    */
+                   appendPQExpBuffer(q, "\n-- For binary upgrade, recreate dropped column's length and alignment.\n");
+                   appendPQExpBuffer(q, "UPDATE pg_attribute\n"
+                                        "SET attlen = %d, "
+                                        "attalign = '%c'\n"
+                                        "WHERE attname = '%s'\n"
+                                        "  AND attrelid = \n"
+                                        "  (\n"
+                                        "      SELECT oid\n"
+                                        "      FROM pg_class\n"
+                                        "      WHERE   relnamespace = "
+                                        "(SELECT oid FROM pg_namespace "
+                                        "WHERE nspname = CURRENT_SCHEMA)\n"
+                                        "          AND relname = '%s'\n"
+                                        "  );",
+                                        tbinfo->attlen[j],
+                                        tbinfo->attalign[j],
+                                        tbinfo->attnames[j],
+                                        tbinfo->dobj.name);
+               }
+           }
+       }
+   
        /* Loop dumping statistics and storage statements */
        for (j = 0; j < tbinfo->numatts; j++)
        {
index f18703ca85c3c31847a9094cc611bdbd47d8cecd..ffa3c2ea9eff11c4f0f259eddc356c989b238845 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.150 2009/02/02 19:31:39 alvherre Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.151 2009/02/17 15:41:50 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -245,6 +245,8 @@ typedef struct _tableInfo
    char       *attstorage;     /* attribute storage scheme */
    char       *typstorage;     /* type storage scheme */
    bool       *attisdropped;   /* true if attr is dropped; don't dump it */
+   int        *attlen;         /* attribute length, used by binary_upgrade */
+   char       *attalign;       /* attribute align, used by binary_upgrade */
    bool       *attislocal;     /* true if attr has local definition */
 
    /*
index f5a08eb834f9e47bcd00aba55ed1c4776528a90c..edc20b6f4465b12f100f5b43e3db67b8c53d56f4 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.113 2009/01/22 20:16:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.114 2009/02/17 15:41:50 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -90,8 +90,10 @@ main(int argc, char *argv[])
    const char *std_strings;
    int         c,
                ret;
+   int         binary_upgrade = 0;
 
-   static struct option long_options[] = {
+   struct option long_options[] = {
+       {"binary-upgrade", no_argument, &binary_upgrade, 1},    /* not documented */
        {"data-only", no_argument, NULL, 'a'},
        {"clean", no_argument, NULL, 'c'},
        {"inserts", no_argument, NULL, 'd'},
@@ -310,6 +312,8 @@ main(int argc, char *argv[])
    }
 
    /* Add long options to the pg_dump argument list */
+   if (binary_upgrade)
+       appendPQExpBuffer(pgdumpopts, " --binary-upgrade");
    if (disable_dollar_quoting)
        appendPQExpBuffer(pgdumpopts, " --disable-dollar-quoting");
    if (disable_triggers)