Thread: pg_upgrade patches applied

pg_upgrade patches applied

From
Bruce Momjian
Date:
I have applied the attached four patches which simplify pg_upgrade
processing --- less code means fewer bugs.  The commit message is at the
top of each patch.

The last patch fixes a problem where I was not migrating
pg_largeobject_metadata and its index for 9.0+ migrations, which of
course would only affect migrations to 9.1 and 9.0 to 9.0 migrations, so
I backpatched that to 9.0.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +
commit 6e6bee987ff4b6d650eec9f20fd477269d95e295
Author: Bruce Momjian <bruce@momjian.us>
Date:   Sat Jan 1 12:06:36 2011 -0500

    In pg_upgrade, remove use of whichCluster, and just pass old/new cluster
    pointers, which simplifies the code.  This was not possible in 9.0 because
    everything was in a single nested struct, but is possible now.

    Per suggestion from Tom.

diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
index 6d5111c..839a3c9 100644
*** /tmp/jfuWAe_check.c    Wed Jan  5 09:04:02 2011
--- /tmp/RmpcZc_check.c    Wed Jan  5 09:04:02 2011
***************
*** 10,22 ****
  #include "pg_upgrade.h"


! static void set_locale_and_encoding(Cluster whichCluster);
  static void check_new_db_is_empty(void);
  static void check_locale_and_encoding(ControlData *oldctrl,
                            ControlData *newctrl);
! static void check_for_isn_and_int8_passing_mismatch(
!                                         Cluster whichCluster);
! static void check_for_reg_data_type_usage(Cluster whichCluster);


  void
--- 10,21 ----
  #include "pg_upgrade.h"


! static void set_locale_and_encoding(ClusterInfo *cluster);
  static void check_new_db_is_empty(void);
  static void check_locale_and_encoding(ControlData *oldctrl,
                            ControlData *newctrl);
! static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
! static void check_for_reg_data_type_usage(ClusterInfo *cluster);


  void
*************** check_old_cluster(bool live_check,
*** 46,59 ****
      /* -- OLD -- */

      if (!live_check)
!         start_postmaster(CLUSTER_OLD, false);

!     set_locale_and_encoding(CLUSTER_OLD);

!     get_pg_database_relfilenode(CLUSTER_OLD);

      /* Extract a list of databases and tables from the old cluster */
!     get_db_and_rel_infos(&old_cluster.dbarr, CLUSTER_OLD);

      init_tablespaces();

--- 45,58 ----
      /* -- OLD -- */

      if (!live_check)
!         start_postmaster(&old_cluster, false);

!     set_locale_and_encoding(&old_cluster);

!     get_pg_database_relfilenode(&old_cluster);

      /* Extract a list of databases and tables from the old cluster */
!     get_db_and_rel_infos(&old_cluster);

      init_tablespaces();

*************** check_old_cluster(bool live_check,
*** 64,82 ****
       * Check for various failure cases
       */

!     check_for_reg_data_type_usage(CLUSTER_OLD);
!     check_for_isn_and_int8_passing_mismatch(CLUSTER_OLD);

      /* old = PG 8.3 checks? */
      if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
      {
!         old_8_3_check_for_name_data_type_usage(CLUSTER_OLD);
!         old_8_3_check_for_tsquery_usage(CLUSTER_OLD);
          if (user_opts.check)
          {
!             old_8_3_rebuild_tsvector_tables(true, CLUSTER_OLD);
!             old_8_3_invalidate_hash_gin_indexes(true, CLUSTER_OLD);
!             old_8_3_invalidate_bpchar_pattern_ops_indexes(true, CLUSTER_OLD);
          }
          else

--- 63,81 ----
       * Check for various failure cases
       */

!     check_for_reg_data_type_usage(&old_cluster);
!     check_for_isn_and_int8_passing_mismatch(&old_cluster);

      /* old = PG 8.3 checks? */
      if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
      {
!         old_8_3_check_for_name_data_type_usage(&old_cluster);
!         old_8_3_check_for_tsquery_usage(&old_cluster);
          if (user_opts.check)
          {
!             old_8_3_rebuild_tsvector_tables(&old_cluster, true);
!             old_8_3_invalidate_hash_gin_indexes(&old_cluster, true);
!             old_8_3_invalidate_bpchar_pattern_ops_indexes(&old_cluster, true);
          }
          else

*************** check_old_cluster(bool live_check,
*** 86,97 ****
               * end.
               */
              *sequence_script_file_name =
!                 old_8_3_create_sequence_script(CLUSTER_OLD);
      }

      /* Pre-PG 9.0 had no large object permissions */
      if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
!         new_9_0_populate_pg_largeobject_metadata(true, CLUSTER_OLD);

      /*
       * While not a check option, we do this now because this is the only time
--- 85,96 ----
               * end.
               */
              *sequence_script_file_name =
!                 old_8_3_create_sequence_script(&old_cluster);
      }

      /* Pre-PG 9.0 had no large object permissions */
      if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
!         new_9_0_populate_pg_largeobject_metadata(&old_cluster, true);

      /*
       * While not a check option, we do this now because this is the only time
*************** check_old_cluster(bool live_check,
*** 111,117 ****
  void
  check_new_cluster(void)
  {
!     set_locale_and_encoding(CLUSTER_NEW);

      check_new_db_is_empty();

--- 110,116 ----
  void
  check_new_cluster(void)
  {
!     set_locale_and_encoding(&new_cluster);

      check_new_db_is_empty();

*************** issue_warnings(char *sequence_script_fil
*** 149,155 ****
      /* old = PG 8.3 warnings? */
      if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
      {
!         start_postmaster(CLUSTER_NEW, true);

          /* restore proper sequence values using file created from old server */
          if (sequence_script_file_name)
--- 148,154 ----
      /* old = PG 8.3 warnings? */
      if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
      {
!         start_postmaster(&new_cluster, true);

          /* restore proper sequence values using file created from old server */
          if (sequence_script_file_name)
*************** issue_warnings(char *sequence_script_fil
*** 165,181 ****
              check_ok();
          }

!         old_8_3_rebuild_tsvector_tables(false, CLUSTER_NEW);
!         old_8_3_invalidate_hash_gin_indexes(false, CLUSTER_NEW);
!         old_8_3_invalidate_bpchar_pattern_ops_indexes(false, CLUSTER_NEW);
          stop_postmaster(false, true);
      }

      /* Create dummy large object permissions for old < PG 9.0? */
      if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
      {
!         start_postmaster(CLUSTER_NEW, true);
!         new_9_0_populate_pg_largeobject_metadata(false, CLUSTER_NEW);
          stop_postmaster(false, true);
      }
  }
--- 164,180 ----
              check_ok();
          }

!         old_8_3_rebuild_tsvector_tables(&new_cluster, false);
!         old_8_3_invalidate_hash_gin_indexes(&new_cluster, false);
!         old_8_3_invalidate_bpchar_pattern_ops_indexes(&new_cluster, false);
          stop_postmaster(false, true);
      }

      /* Create dummy large object permissions for old < PG 9.0? */
      if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
      {
!         start_postmaster(&new_cluster, true);
!         new_9_0_populate_pg_largeobject_metadata(&new_cluster, false);
          stop_postmaster(false, true);
      }
  }
*************** void
*** 210,217 ****
  check_cluster_versions(void)
  {
      /* get old and new cluster versions */
!     old_cluster.major_version = get_major_server_version(&old_cluster.major_version_str, CLUSTER_OLD);
!     new_cluster.major_version = get_major_server_version(&new_cluster.major_version_str, CLUSTER_NEW);

      /* We allow upgrades from/to the same major version for alpha/beta upgrades */

--- 209,216 ----
  check_cluster_versions(void)
  {
      /* get old and new cluster versions */
!     old_cluster.major_version = get_major_server_version(&old_cluster, &old_cluster.major_version_str);
!     new_cluster.major_version = get_major_server_version(&new_cluster, &new_cluster.major_version_str);

      /* We allow upgrades from/to the same major version for alpha/beta upgrades */

*************** check_cluster_compatibility(bool live_ch
*** 270,285 ****
   * query the database to get the template0 locale
   */
  static void
! set_locale_and_encoding(Cluster whichCluster)
  {
!     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
!     ControlData *ctrl = &active_cluster->controldata;
      PGconn       *conn;
      PGresult   *res;
      int            i_encoding;
!     int            cluster_version = active_cluster->major_version;

!     conn = connectToServer("template1", whichCluster);

      /* for pg < 80400, we got the values from pg_controldata */
      if (cluster_version >= 80400)
--- 269,283 ----
   * query the database to get the template0 locale
   */
  static void
! set_locale_and_encoding(ClusterInfo *cluster)
  {
!     ControlData *ctrl = &cluster->controldata;
      PGconn       *conn;
      PGresult   *res;
      int            i_encoding;
!     int            cluster_version = cluster->major_version;

!     conn = connectToServer(cluster, "template1");

      /* for pg < 80400, we got the values from pg_controldata */
      if (cluster_version >= 80400)
*************** check_new_db_is_empty(void)
*** 345,351 ****
      int            dbnum;
      bool        found = false;

!     get_db_and_rel_infos(&new_cluster.dbarr, CLUSTER_NEW);

      for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
      {
--- 343,349 ----
      int            dbnum;
      bool        found = false;

!     get_db_and_rel_infos(&new_cluster);

      for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
      {
*************** create_script_for_old_cluster_deletion(
*** 457,465 ****
   *    it must match for the old and new servers.
   */
  void
! check_for_isn_and_int8_passing_mismatch(Cluster whichCluster)
  {
-     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
--- 455,462 ----
   *    it must match for the old and new servers.
   */
  void
! check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
  {
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
*************** check_for_isn_and_int8_passing_mismatch(
*** 478,484 ****
      snprintf(output_path, sizeof(output_path), "%s/contrib_isn_and_int8_pass_by_value.txt",
               os_info.cwd);

!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
--- 475,481 ----
      snprintf(output_path, sizeof(output_path), "%s/contrib_isn_and_int8_pass_by_value.txt",
               os_info.cwd);

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
*************** check_for_isn_and_int8_passing_mismatch(
*** 486,493 ****
          int            rowno;
          int            i_nspname,
                      i_proname;
!         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(active_db->db_name, whichCluster);

          /* Find any functions coming from contrib/isn */
          res = executeQueryOrDie(conn,
--- 483,490 ----
          int            rowno;
          int            i_nspname,
                      i_proname;
!         DbInfo       *active_db = &cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(cluster, active_db->db_name);

          /* Find any functions coming from contrib/isn */
          res = executeQueryOrDie(conn,
*************** check_for_isn_and_int8_passing_mismatch(
*** 552,560 ****
   *    tables upgraded by pg_upgrade.
   */
  void
! check_for_reg_data_type_usage(Cluster whichCluster)
  {
-     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
--- 549,556 ----
   *    tables upgraded by pg_upgrade.
   */
  void
! check_for_reg_data_type_usage(ClusterInfo *cluster)
  {
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
*************** check_for_reg_data_type_usage(Cluster wh
*** 565,571 ****
      snprintf(output_path, sizeof(output_path), "%s/tables_using_reg.txt",
               os_info.cwd);

!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
--- 561,567 ----
      snprintf(output_path, sizeof(output_path), "%s/tables_using_reg.txt",
               os_info.cwd);

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
*************** check_for_reg_data_type_usage(Cluster wh
*** 574,581 ****
          int            i_nspname,
                      i_relname,
                      i_attname;
!         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(active_db->db_name, whichCluster);

          res = executeQueryOrDie(conn,
                                  "SELECT n.nspname, c.relname, a.attname "
--- 570,577 ----
          int            i_nspname,
                      i_relname,
                      i_attname;
!         DbInfo       *active_db = &cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(cluster, active_db->db_name);

          res = executeQueryOrDie(conn,
                                  "SELECT n.nspname, c.relname, a.attname "
diff --git a/contrib/pg_upgrade/exec.c b/contrib/pg_upgrade/exec.c
index af0fcf9..1959b8a 100644
*** /tmp/c4HFhd_exec.c    Wed Jan  5 09:04:03 2011
--- /tmp/SVwHBd_exec.c    Wed Jan  5 09:04:03 2011
***************
*** 14,20 ****


  static void check_data_dir(const char *pg_data);
! static void check_bin_dir(ClusterInfo *cluster, Cluster whichCluster);
  static int    check_exec(const char *dir, const char *cmdName);
  static const char *validate_exec(const char *path);

--- 14,20 ----


  static void check_data_dir(const char *pg_data);
! static void check_bin_dir(ClusterInfo *cluster);
  static int    check_exec(const char *dir, const char *cmdName);
  static const char *validate_exec(const char *path);

*************** verify_directories(void)
*** 99,105 ****
      check_ok();

      prep_status("Checking old bin directory (%s)", old_cluster.bindir);
!     check_bin_dir(&old_cluster, CLUSTER_OLD);
      check_ok();

      prep_status("Checking new data directory (%s)", new_cluster.pgdata);
--- 99,105 ----
      check_ok();

      prep_status("Checking old bin directory (%s)", old_cluster.bindir);
!     check_bin_dir(&old_cluster);
      check_ok();

      prep_status("Checking new data directory (%s)", new_cluster.pgdata);
*************** verify_directories(void)
*** 107,113 ****
      check_ok();

      prep_status("Checking new bin directory (%s)", new_cluster.bindir);
!     check_bin_dir(&new_cluster, CLUSTER_NEW);
      check_ok();
  }

--- 107,113 ----
      check_ok();

      prep_status("Checking new bin directory (%s)", new_cluster.bindir);
!     check_bin_dir(&new_cluster);
      check_ok();
  }

*************** check_data_dir(const char *pg_data)
*** 158,169 ****
   *    exit().
   */
  static void
! check_bin_dir(ClusterInfo *cluster, Cluster whichCluster)
  {
      check_exec(cluster->bindir, "postgres");
      check_exec(cluster->bindir, "pg_ctl");
      check_exec(cluster->bindir, "pg_resetxlog");
!     if (whichCluster == CLUSTER_NEW)
      {
          /* these are only needed in the new cluster */
          check_exec(cluster->bindir, "pg_config");
--- 158,169 ----
   *    exit().
   */
  static void
! check_bin_dir(ClusterInfo *cluster)
  {
      check_exec(cluster->bindir, "postgres");
      check_exec(cluster->bindir, "pg_ctl");
      check_exec(cluster->bindir, "pg_resetxlog");
!     if (cluster == &new_cluster)
      {
          /* these are only needed in the new cluster */
          check_exec(cluster->bindir, "pg_config");
diff --git a/contrib/pg_upgrade/function.c b/contrib/pg_upgrade/function.c
index c76aaeb..877b004 100644
*** /tmp/kQEsXa_function.c    Wed Jan  5 09:04:03 2011
--- /tmp/gaM4hb_function.c    Wed Jan  5 09:04:03 2011
*************** install_support_functions(void)
*** 28,34 ****
      for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
      {
          DbInfo       *newdb = &new_cluster.dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(newdb->db_name, CLUSTER_NEW);

          /* suppress NOTICE of dropped objects */
          PQclear(executeQueryOrDie(conn,
--- 28,34 ----
      for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
      {
          DbInfo       *newdb = &new_cluster.dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(&new_cluster, newdb->db_name);

          /* suppress NOTICE of dropped objects */
          PQclear(executeQueryOrDie(conn,
*************** uninstall_support_functions(void)
*** 99,105 ****
      for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
      {
          DbInfo       *newdb = &new_cluster.dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(newdb->db_name, CLUSTER_NEW);

          /* suppress NOTICE of dropped objects */
          PQclear(executeQueryOrDie(conn,
--- 99,105 ----
      for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
      {
          DbInfo       *newdb = &new_cluster.dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(&new_cluster, newdb->db_name);

          /* suppress NOTICE of dropped objects */
          PQclear(executeQueryOrDie(conn,
*************** uninstall_support_functions(void)
*** 123,142 ****
  void
  get_loadable_libraries(void)
  {
-     ClusterInfo *active_cluster = &old_cluster;
      PGresult  **ress;
      int            totaltups;
      int            dbnum;

      ress = (PGresult **)
!         pg_malloc(active_cluster->dbarr.ndbs * sizeof(PGresult *));
      totaltups = 0;

      /* Fetch all library names, removing duplicates within each DB */
!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
!         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(active_db->db_name, CLUSTER_OLD);

          /* Fetch all libraries referenced in this DB */
          ress[dbnum] = executeQueryOrDie(conn,
--- 123,141 ----
  void
  get_loadable_libraries(void)
  {
      PGresult  **ress;
      int            totaltups;
      int            dbnum;

      ress = (PGresult **)
!         pg_malloc(old_cluster.dbarr.ndbs * sizeof(PGresult *));
      totaltups = 0;

      /* Fetch all library names, removing duplicates within each DB */
!     for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
      {
!         DbInfo       *active_db = &old_cluster.dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(&old_cluster, active_db->db_name);

          /* Fetch all libraries referenced in this DB */
          ress[dbnum] = executeQueryOrDie(conn,
*************** get_loadable_libraries(void)
*** 163,169 ****
       */
      totaltups = 0;

!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res = ress[dbnum];
          int            ntups;
--- 162,168 ----
       */
      totaltups = 0;

!     for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
      {
          PGresult   *res = ress[dbnum];
          int            ntups;
*************** get_loadable_libraries(void)
*** 207,213 ****
  void
  check_loadable_libraries(void)
  {
!     PGconn       *conn = connectToServer("template1", CLUSTER_NEW);
      int            libnum;
      FILE       *script = NULL;
      bool        found = false;
--- 206,212 ----
  void
  check_loadable_libraries(void)
  {
!     PGconn       *conn = connectToServer(&new_cluster, "template1");
      int            libnum;
      FILE       *script = NULL;
      bool        found = false;
diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c
index 99a1548..e44798a 100644
*** /tmp/eLhpRb_info.c    Wed Jan  5 09:04:03 2011
--- /tmp/uNYs5b_info.c    Wed Jan  5 09:04:03 2011
***************
*** 12,24 ****
  #include "access/transam.h"


! static void get_db_infos(DbInfoArr *dbinfos,
!              Cluster whichCluster);
! static void dbarr_print(DbInfoArr *arr,
!             Cluster whichCluster);
  static void relarr_print(RelInfoArr *arr);
! static void get_rel_infos(const DbInfo *dbinfo,
!               RelInfoArr *relarr, Cluster whichCluster);
  static void relarr_free(RelInfoArr *rel_arr);
  static void map_rel(const RelInfo *oldrel,
          const RelInfo *newrel, const DbInfo *old_db,
--- 12,22 ----
  #include "access/transam.h"


! static void get_db_infos(ClusterInfo *cluster);
! static void dbarr_print(ClusterInfo *cluster);
  static void relarr_print(RelInfoArr *arr);
! static void get_rel_infos(ClusterInfo *cluster, const DbInfo *dbinfo,
!               RelInfoArr *relarr);
  static void relarr_free(RelInfoArr *rel_arr);
  static void map_rel(const RelInfo *oldrel,
          const RelInfo *newrel, const DbInfo *old_db,
*************** static void map_rel_by_id(Oid oldid, Oid
*** 30,40 ****
                const char *old_tablespace, const DbInfo *old_db,
                const DbInfo *new_db, const char *olddata,
                const char *newdata, FileNameMap *map);
! static RelInfo *relarr_lookup_reloid(RelInfoArr *rel_arr,
!                 Oid oid, Cluster whichCluster);
! static RelInfo *relarr_lookup_rel(RelInfoArr *rel_arr,
!                   const char *nspname, const char *relname,
!                   Cluster whichCluster);


  /*
--- 28,37 ----
                const char *old_tablespace, const DbInfo *old_db,
                const DbInfo *new_db, const char *olddata,
                const char *newdata, FileNameMap *map);
! static RelInfo *relarr_lookup_reloid(ClusterInfo *cluster, RelInfoArr *rel_arr,
!                 Oid oid);
! static RelInfo *relarr_lookup_rel(ClusterInfo *cluster, RelInfoArr *rel_arr,
!                   const char *nspname, const char *relname);


  /*
*************** gen_db_file_maps(DbInfo *old_db, DbInfo
*** 66,73 ****
          if (strcmp(newrel->nspname, "pg_toast") == 0)
              continue;

!         oldrel = relarr_lookup_rel(&old_db->rel_arr, newrel->nspname,
!                                    newrel->relname, CLUSTER_OLD);

          map_rel(oldrel, newrel, old_db, new_db, old_pgdata, new_pgdata,
                  maps + num_maps);
--- 63,70 ----
          if (strcmp(newrel->nspname, "pg_toast") == 0)
              continue;

!         oldrel = relarr_lookup_rel(&old_cluster, &old_db->rel_arr,
!                                    newrel->nspname, newrel->relname);

          map_rel(oldrel, newrel, old_db, new_db, old_pgdata, new_pgdata,
                  maps + num_maps);
*************** gen_db_file_maps(DbInfo *old_db, DbInfo
*** 91,100 ****
                       newrel->reloid);

              /* look them up in their respective arrays */
!             old_toast = relarr_lookup_reloid(&old_db->rel_arr,
!                                              oldrel->toastrelid, CLUSTER_OLD);
!             new_toast = relarr_lookup_rel(&new_db->rel_arr,
!                                           "pg_toast", new_name, CLUSTER_NEW);

              /* finally create a mapping for them */
              map_rel(old_toast, new_toast, old_db, new_db, old_pgdata, new_pgdata,
--- 88,97 ----
                       newrel->reloid);

              /* look them up in their respective arrays */
!             old_toast = relarr_lookup_reloid(&old_cluster, &old_db->rel_arr,
!                                              oldrel->toastrelid);
!             new_toast = relarr_lookup_rel(&new_cluster, &new_db->rel_arr,
!                                           "pg_toast", new_name);

              /* finally create a mapping for them */
              map_rel(old_toast, new_toast, old_db, new_db, old_pgdata, new_pgdata,
*************** gen_db_file_maps(DbInfo *old_db, DbInfo
*** 118,127 ****

              /* look them up in their respective arrays */
              /* we lose our cache location here */
!             old_toast = relarr_lookup_rel(&old_db->rel_arr,
!                                           "pg_toast", old_name, CLUSTER_OLD);
!             new_toast = relarr_lookup_rel(&new_db->rel_arr,
!                                           "pg_toast", new_name, CLUSTER_NEW);

              /* finally create a mapping for them */
              map_rel(old_toast, new_toast, old_db, new_db, old_pgdata,
--- 115,124 ----

              /* look them up in their respective arrays */
              /* we lose our cache location here */
!             old_toast = relarr_lookup_rel(&old_cluster, &old_db->rel_arr,
!                                           "pg_toast", old_name);
!             new_toast = relarr_lookup_rel(&new_cluster, &new_db->rel_arr,
!                                           "pg_toast", new_name);

              /* finally create a mapping for them */
              map_rel(old_toast, new_toast, old_db, new_db, old_pgdata,
*************** print_maps(FileNameMap *maps, int n, con
*** 214,226 ****
  /*
   * get_db_infos()
   *
!  * Scans pg_database system catalog and returns (in dbinfs_arr) all user
   * databases.
   */
  static void
! get_db_infos(DbInfoArr *dbinfs_arr, Cluster whichCluster)
  {
!     PGconn       *conn = connectToServer("template1", whichCluster);
      PGresult   *res;
      int            ntups;
      int            tupnum;
--- 211,223 ----
  /*
   * get_db_infos()
   *
!  * Scans pg_database system catalog and populates all user
   * databases.
   */
  static void
! get_db_infos(ClusterInfo *cluster)
  {
!     PGconn       *conn = connectToServer(cluster, "template1");
      PGresult   *res;
      int            ntups;
      int            tupnum;
*************** get_db_infos(DbInfoArr *dbinfs_arr, Clus
*** 256,263 ****

      PQfinish(conn);

!     dbinfs_arr->dbs = dbinfos;
!     dbinfs_arr->ndbs = ntups;
  }


--- 253,260 ----

      PQfinish(conn);

!     cluster->dbarr.dbs = dbinfos;
!     cluster->dbarr.ndbs = ntups;
  }


*************** get_db_infos(DbInfoArr *dbinfs_arr, Clus
*** 268,285 ****
   * on the given "port". Assumes that server is already running.
   */
  void
! get_db_and_rel_infos(DbInfoArr *db_arr, Cluster whichCluster)
  {
      int            dbnum;

!     get_db_infos(db_arr, whichCluster);

!     for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++)
!         get_rel_infos(&db_arr->dbs[dbnum],
!                       &db_arr->dbs[dbnum].rel_arr, whichCluster);

      if (log_opts.debug)
!         dbarr_print(db_arr, whichCluster);
  }


--- 265,282 ----
   * on the given "port". Assumes that server is already running.
   */
  void
! get_db_and_rel_infos(ClusterInfo *cluster)
  {
      int            dbnum;

!     get_db_infos(cluster);

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
!         get_rel_infos(cluster, &cluster->dbarr.dbs[dbnum],
!                       &cluster->dbarr.dbs[dbnum].rel_arr);

      if (log_opts.debug)
!         dbarr_print(cluster);
  }


*************** get_db_and_rel_infos(DbInfoArr *db_arr,
*** 293,301 ****
   * FirstNormalObjectId belongs to the user
   */
  static void
! get_rel_infos(const DbInfo *dbinfo, RelInfoArr *relarr, Cluster whichCluster)
  {
!     PGconn       *conn = connectToServer(dbinfo->db_name, whichCluster);
      PGresult   *res;
      RelInfo    *relinfos;
      int            ntups;
--- 290,298 ----
   * FirstNormalObjectId belongs to the user
   */
  static void
! get_rel_infos(ClusterInfo *cluster, const DbInfo *dbinfo, RelInfoArr *relarr)
  {
!     PGconn       *conn = connectToServer(cluster, dbinfo->db_name);
      PGresult   *res;
      RelInfo    *relinfos;
      int            ntups;
*************** dbarr_lookup_db(DbInfoArr *db_arr, const
*** 417,424 ****
   * RelInfo structure.
   */
  static RelInfo *
! relarr_lookup_rel(RelInfoArr *rel_arr, const char *nspname,
!                     const char *relname, Cluster whichCluster)
  {
      int            relnum;

--- 414,421 ----
   * RelInfo structure.
   */
  static RelInfo *
! relarr_lookup_rel(ClusterInfo *cluster, RelInfoArr *rel_arr,
!                     const char *nspname, const char *relname)
  {
      int            relnum;

*************** relarr_lookup_rel(RelInfoArr *rel_arr, c
*** 441,447 ****
          }
      }
      pg_log(PG_FATAL, "Could not find %s.%s in %s cluster\n",
!            nspname, relname, CLUSTER_NAME(whichCluster));
      return NULL;
  }

--- 438,444 ----
          }
      }
      pg_log(PG_FATAL, "Could not find %s.%s in %s cluster\n",
!            nspname, relname, CLUSTER_NAME(cluster));
      return NULL;
  }

*************** relarr_lookup_rel(RelInfoArr *rel_arr, c
*** 454,461 ****
   *    found.
   */
  static RelInfo *
! relarr_lookup_reloid(RelInfoArr *rel_arr, Oid oid,
!                      Cluster whichCluster)
  {
      int            relnum;

--- 451,457 ----
   *    found.
   */
  static RelInfo *
! relarr_lookup_reloid(ClusterInfo *cluster, RelInfoArr *rel_arr, Oid oid)
  {
      int            relnum;

*************** relarr_lookup_reloid(RelInfoArr *rel_arr
*** 465,471 ****
              return &rel_arr->rels[relnum];
      }
      pg_log(PG_FATAL, "Could not find %d in %s cluster\n",
!            oid, CLUSTER_NAME(whichCluster));
      return NULL;
  }

--- 461,467 ----
              return &rel_arr->rels[relnum];
      }
      pg_log(PG_FATAL, "Could not find %d in %s cluster\n",
!            oid, CLUSTER_NAME(cluster));
      return NULL;
  }

*************** dbarr_free(DbInfoArr *db_arr)
*** 491,506 ****


  static void
! dbarr_print(DbInfoArr *arr, Cluster whichCluster)
  {
      int            dbnum;

!     pg_log(PG_DEBUG, "%s databases\n", CLUSTER_NAME(whichCluster));

!     for (dbnum = 0; dbnum < arr->ndbs; dbnum++)
      {
!         pg_log(PG_DEBUG, "Database: %s\n", arr->dbs[dbnum].db_name);
!         relarr_print(&arr->dbs[dbnum].rel_arr);
          pg_log(PG_DEBUG, "\n\n");
      }
  }
--- 487,502 ----


  static void
! dbarr_print(ClusterInfo *cluster)
  {
      int            dbnum;

!     pg_log(PG_DEBUG, "%s databases\n", CLUSTER_NAME(cluster));

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
!         pg_log(PG_DEBUG, "Database: %s\n", cluster->dbarr.dbs[dbnum].db_name);
!         relarr_print(&cluster->dbarr.dbs[dbnum].rel_arr);
          pg_log(PG_DEBUG, "\n\n");
      }
  }
diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c
index bfd2def..d2ca08b 100644
*** /tmp/6Uc1Td_pg_upgrade.c    Wed Jan  5 09:04:03 2011
--- /tmp/e9RP2d_pg_upgrade.c    Wed Jan  5 09:04:03 2011
*************** static void set_frozenxids(void);
*** 22,29 ****
  static void setup(char *argv0, bool live_check);
  static void cleanup(void);

! ClusterInfo old_cluster,
!             new_cluster;
  OSInfo        os_info;

  int
--- 22,28 ----
  static void setup(char *argv0, bool live_check);
  static void cleanup(void);

! ClusterInfo old_cluster, new_cluster;
  OSInfo        os_info;

  int
*************** main(int argc, char **argv)
*** 46,52 ****


      /* -- NEW -- */
!     start_postmaster(CLUSTER_NEW, false);

      check_new_cluster();
      report_clusters_compatible();
--- 45,51 ----


      /* -- NEW -- */
!     start_postmaster(&new_cluster, false);

      check_new_cluster();
      report_clusters_compatible();
*************** prepare_new_cluster(void)
*** 178,184 ****
             new_cluster.bindir, new_cluster.port, os_info.user, log_opts.filename);
      check_ok();

!     get_pg_database_relfilenode(CLUSTER_NEW);
  }


--- 177,183 ----
             new_cluster.bindir, new_cluster.port, os_info.user, log_opts.filename);
      check_ok();

!     get_pg_database_relfilenode(&new_cluster);
  }


*************** static void
*** 186,192 ****
  prepare_new_databases(void)
  {
      /* -- NEW -- */
!     start_postmaster(CLUSTER_NEW, false);

      /*
       * We set autovacuum_freeze_max_age to its maximum value so autovacuum
--- 185,191 ----
  prepare_new_databases(void)
  {
      /* -- NEW -- */
!     start_postmaster(&new_cluster, false);

      /*
       * We set autovacuum_freeze_max_age to its maximum value so autovacuum
*************** prepare_new_databases(void)
*** 210,216 ****
                GLOBALS_DUMP_FILE, log_opts.filename);
      check_ok();

!     get_db_and_rel_infos(&new_cluster.dbarr, CLUSTER_NEW);

      stop_postmaster(false, false);
  }
--- 209,215 ----
                GLOBALS_DUMP_FILE, log_opts.filename);
      check_ok();

!     get_db_and_rel_infos(&new_cluster);

      stop_postmaster(false, false);
  }
*************** static void
*** 220,226 ****
  create_new_objects(void)
  {
      /* -- NEW -- */
!     start_postmaster(CLUSTER_NEW, false);

      install_support_functions();

--- 219,225 ----
  create_new_objects(void)
  {
      /* -- NEW -- */
!     start_postmaster(&new_cluster, false);

      install_support_functions();

*************** create_new_objects(void)
*** 235,241 ****

      /* regenerate now that we have db schemas */
      dbarr_free(&new_cluster.dbarr);
!     get_db_and_rel_infos(&new_cluster.dbarr, CLUSTER_NEW);

      uninstall_support_functions();

--- 234,240 ----

      /* regenerate now that we have db schemas */
      dbarr_free(&new_cluster.dbarr);
!     get_db_and_rel_infos(&new_cluster);

      uninstall_support_functions();

*************** set_frozenxids(void)
*** 309,315 ****

      prep_status("Setting frozenxid counters in new cluster");

!     conn_template1 = connectToServer("template1", CLUSTER_NEW);

      /* set pg_database.datfrozenxid */
      PQclear(executeQueryOrDie(conn_template1,
--- 308,314 ----

      prep_status("Setting frozenxid counters in new cluster");

!     conn_template1 = connectToServer(&new_cluster, "template1");

      /* set pg_database.datfrozenxid */
      PQclear(executeQueryOrDie(conn_template1,
*************** set_frozenxids(void)
*** 344,350 ****
                                        "SET    datallowconn = true "
                                        "WHERE datname = '%s'", datname));

!         conn = connectToServer(datname, CLUSTER_NEW);

          /* set pg_class.relfrozenxid */
          PQclear(executeQueryOrDie(conn,
--- 343,349 ----
                                        "SET    datallowconn = true "
                                        "WHERE datname = '%s'", datname));

!         conn = connectToServer(&new_cluster, datname);

          /* set pg_class.relfrozenxid */
          PQclear(executeQueryOrDie(conn,
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
index c53f935..b6ce965 100644
*** /tmp/oOiOpd_pg_upgrade.h    Wed Jan  5 09:04:03 2011
--- /tmp/cMi7nb_pg_upgrade.h    Wed Jan  5 09:04:03 2011
***************
*** 52,60 ****
  #define EXE_EXT                ".exe"
  #endif

! #define CLUSTER_NAME(cluster)    ((cluster) == CLUSTER_OLD ? "old" : "new")
! #define ACTIVE_CLUSTER(cluster) (((cluster) == CLUSTER_OLD) ? \
!                                     &old_cluster : &new_cluster)

  #define atooid(x)  ((Oid) strtoul((x), NULL, 10))

--- 52,59 ----
  #define EXE_EXT                ".exe"
  #endif

! #define CLUSTER_NAME(cluster)    ((cluster) == &old_cluster ? "old" : \
!                                  (cluster) == &new_cluster ? "new" : "none")

  #define atooid(x)  ((Oid) strtoul((x), NULL, 10))

*************** typedef enum
*** 163,177 ****
      PG_DEBUG
  } eLogType;

- /*
-  * Enumeration to distinguish between old cluster and new cluster
-  */
- typedef enum
- {
-     NONE = 0,                    /* used for no running servers */
-     CLUSTER_OLD,
-     CLUSTER_NEW
- } Cluster;

  typedef long pgpid_t;

--- 162,167 ----
*************** typedef struct
*** 234,240 ****
      char      **libraries;        /* loadable libraries */
      int            num_libraries;
      pgpid_t        postmasterPID;    /* PID of currently running postmaster */
!     Cluster        running_cluster;
  } OSInfo;


--- 224,230 ----
      char      **libraries;        /* loadable libraries */
      int            num_libraries;
      pgpid_t        postmasterPID;    /* PID of currently running postmaster */
!     ClusterInfo *running_cluster;
  } OSInfo;


*************** typedef struct
*** 243,250 ****
   */
  extern LogOpts    log_opts;
  extern UserOpts user_opts;
! extern ClusterInfo old_cluster,
!             new_cluster;
  extern OSInfo os_info;
  extern char scandir_file_pattern[];

--- 233,239 ----
   */
  extern LogOpts    log_opts;
  extern UserOpts user_opts;
! extern ClusterInfo old_cluster, new_cluster;
  extern OSInfo os_info;
  extern char scandir_file_pattern[];

*************** void        check_loadable_libraries(void);
*** 339,346 ****
  FileNameMap *gen_db_file_maps(DbInfo *old_db,
                   DbInfo *new_db, int *nmaps, const char *old_pgdata,
                   const char *new_pgdata);
! void get_db_and_rel_infos(DbInfoArr *db_arr,
!                      Cluster whichCluster);
  DbInfo       *dbarr_lookup_db(DbInfoArr *db_arr, const char *db_name);
  void        dbarr_free(DbInfoArr *db_arr);
  void print_maps(FileNameMap *maps, int n,
--- 328,334 ----
  FileNameMap *gen_db_file_maps(DbInfo *old_db,
                   DbInfo *new_db, int *nmaps, const char *old_pgdata,
                   const char *new_pgdata);
! void get_db_and_rel_infos(ClusterInfo *cluster);
  DbInfo       *dbarr_lookup_db(DbInfoArr *db_arr, const char *db_name);
  void        dbarr_free(DbInfoArr *db_arr);
  void print_maps(FileNameMap *maps, int n,
*************** void        parseCommandLine(int argc, char *a
*** 352,358 ****

  /* relfilenode.c */

! void        get_pg_database_relfilenode(Cluster whichCluster);
  const char *transfer_all_new_dbs(DbInfoArr *olddb_arr,
                     DbInfoArr *newdb_arr, char *old_pgdata, char *new_pgdata);

--- 340,346 ----

  /* relfilenode.c */

! void        get_pg_database_relfilenode(ClusterInfo *cluster);
  const char *transfer_all_new_dbs(DbInfoArr *olddb_arr,
                     DbInfoArr *newdb_arr, char *old_pgdata, char *new_pgdata);

*************** void        init_tablespaces(void);
*** 364,377 ****

  /* server.c */

! PGconn *connectToServer(const char *db_name,
!                 Cluster whichCluster);
! PGresult *executeQueryOrDie(PGconn *conn,
!                   const char *fmt,...);

! void        start_postmaster(Cluster whichCluster, bool quiet);
  void        stop_postmaster(bool fast, bool quiet);
! uint32 get_major_server_version(char **verstr, Cluster whichCluster);
  void        check_for_libpq_envvars(void);


--- 352,363 ----

  /* server.c */

! PGconn *connectToServer(ClusterInfo *cluster, const char *db_name);
! PGresult *executeQueryOrDie(PGconn *conn, const char *fmt,...);

! void        start_postmaster(ClusterInfo *cluster, bool quiet);
  void        stop_postmaster(bool fast, bool quiet);
! uint32 get_major_server_version(ClusterInfo *cluster, char **verstr);
  void        check_for_libpq_envvars(void);


*************** unsigned int str2uint(const char *str);
*** 394,410 ****

  /* version.c */

! void new_9_0_populate_pg_largeobject_metadata(
!                                       bool check_mode, Cluster whichCluster);

  /* version_old_8_3.c */

! void        old_8_3_check_for_name_data_type_usage(Cluster whichCluster);
! void        old_8_3_check_for_tsquery_usage(Cluster whichCluster);
! void old_8_3_rebuild_tsvector_tables(bool check_mode,
!                                 Cluster whichCluster);
! void old_8_3_invalidate_hash_gin_indexes(bool check_mode,
!                                     Cluster whichCluster);
! void old_8_3_invalidate_bpchar_pattern_ops_indexes(bool check_mode,
!                                               Cluster whichCluster);
! char       *old_8_3_create_sequence_script(Cluster whichCluster);
--- 380,394 ----

  /* version.c */

! void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster,
!                                               bool check_mode);

  /* version_old_8_3.c */

! void        old_8_3_check_for_name_data_type_usage(ClusterInfo *cluster);
! void        old_8_3_check_for_tsquery_usage(ClusterInfo *cluster);
! void old_8_3_rebuild_tsvector_tables(ClusterInfo *cluster, bool check_mode);
! void old_8_3_invalidate_hash_gin_indexes(ClusterInfo *cluster, bool check_mode);
! void old_8_3_invalidate_bpchar_pattern_ops_indexes(ClusterInfo *cluster,
!                                                    bool check_mode);
! char       *old_8_3_create_sequence_script(ClusterInfo *cluster);
diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c
index da7531e..b23ce2f 100644
*** /tmp/ODaojb_relfilenode.c    Wed Jan  5 09:04:03 2011
--- /tmp/iRj1Qd_relfilenode.c    Wed Jan  5 09:04:03 2011
*************** transfer_all_new_dbs(DbInfoArr *olddb_ar
*** 77,86 ****
   *    relfilenodes later in the upgrade process.
   */
  void
! get_pg_database_relfilenode(Cluster whichCluster)
  {
!     PGconn       *conn = connectToServer("template1", whichCluster);
!     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      PGresult   *res;
      int            i_relfile;

--- 77,85 ----
   *    relfilenodes later in the upgrade process.
   */
  void
! get_pg_database_relfilenode(ClusterInfo *cluster)
  {
!     PGconn       *conn = connectToServer(cluster, "template1");
      PGresult   *res;
      int            i_relfile;

*************** get_pg_database_relfilenode(Cluster whic
*** 94,100 ****
                              "ORDER BY c.relname");

      i_relfile = PQfnumber(res, "relfilenode");
!     active_cluster->pg_database_oid = atooid(PQgetvalue(res, 0, i_relfile));

      PQclear(res);
      PQfinish(conn);
--- 93,99 ----
                              "ORDER BY c.relname");

      i_relfile = PQfnumber(res, "relfilenode");
!     cluster->pg_database_oid = atooid(PQgetvalue(res, 0, i_relfile));

      PQclear(res);
      PQfinish(conn);
diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c
index 127f9c4..56dcb10 100644
*** /tmp/WhnLOc_server.c    Wed Jan  5 09:04:03 2011
--- /tmp/AAEUcd_server.c    Wed Jan  5 09:04:03 2011
***************
*** 15,22 ****


  static pgpid_t get_postmaster_pid(const char *datadir);
! static bool test_server_conn(int timeout,
!                  Cluster whichCluster);


  /*
--- 15,21 ----


  static pgpid_t get_postmaster_pid(const char *datadir);
! static bool test_server_conn(ClusterInfo *cluster, int timeout);


  /*
*************** static bool test_server_conn(int timeout
*** 27,37 ****
   *    message and calls exit_nicely() to kill the program.
   */
  PGconn *
! connectToServer(const char *db_name,
!                 Cluster whichCluster)
  {
!     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
!     unsigned short port = active_cluster->port;
      char        connectString[MAXPGPATH];
      PGconn       *conn;

--- 26,34 ----
   *    message and calls exit_nicely() to kill the program.
   */
  PGconn *
! connectToServer(ClusterInfo *cluster, const char *db_name)
  {
!     unsigned short port = cluster->port;
      char        connectString[MAXPGPATH];
      PGconn       *conn;

*************** get_postmaster_pid(const char *datadir)
*** 132,141 ****
   * is retrieved by reading the PG_VERSION file.
   */
  uint32
! get_major_server_version(char **verstr, Cluster whichCluster)
  {
!     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
!     const char *datadir = active_cluster->pgdata;
      FILE       *version_fd;
      char        ver_file[MAXPGPATH];
      int            integer_version = 0;
--- 129,137 ----
   * is retrieved by reading the PG_VERSION file.
   */
  uint32
! get_major_server_version(ClusterInfo *cluster, char **verstr)
  {
!     const char *datadir = cluster->pgdata;
      FILE       *version_fd;
      char        ver_file[MAXPGPATH];
      int            integer_version = 0;
*************** get_major_server_version(char **verstr,
*** 160,176 ****


  void
! start_postmaster(Cluster whichCluster, bool quiet)
  {
-     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      char        cmd[MAXPGPATH];
      const char *bindir;
      const char *datadir;
      unsigned short port;

!     bindir = active_cluster->bindir;
!     datadir = active_cluster->pgdata;
!     port = active_cluster->port;

      /*
       * On Win32, we can't send both pg_upgrade output and pg_ctl output to the
--- 156,171 ----


  void
! start_postmaster(ClusterInfo *cluster, bool quiet)
  {
      char        cmd[MAXPGPATH];
      const char *bindir;
      const char *datadir;
      unsigned short port;

!     bindir = cluster->bindir;
!     datadir = cluster->pgdata;
!     port = cluster->port;

      /*
       * On Win32, we can't send both pg_upgrade output and pg_ctl output to the
*************** start_postmaster(Cluster whichCluster, b
*** 193,205 ****

      /* wait for the server to start properly */

!     if (test_server_conn(POSTMASTER_UPTIME, whichCluster) == false)
          pg_log(PG_FATAL, " Unable to start %s postmaster with the command: %s\nPerhaps pg_hba.conf was not set to
\"trust\".",
!                CLUSTER_NAME(whichCluster), cmd);

      if ((os_info.postmasterPID = get_postmaster_pid(datadir)) == 0)
          pg_log(PG_FATAL, " Unable to get postmaster pid\n");
!     os_info.running_cluster = whichCluster;
  }


--- 188,200 ----

      /* wait for the server to start properly */

!     if (test_server_conn(cluster, POSTMASTER_UPTIME) == false)
          pg_log(PG_FATAL, " Unable to start %s postmaster with the command: %s\nPerhaps pg_hba.conf was not set to
\"trust\".",
!                CLUSTER_NAME(cluster), cmd);

      if ((os_info.postmasterPID = get_postmaster_pid(datadir)) == 0)
          pg_log(PG_FATAL, " Unable to get postmaster pid\n");
!     os_info.running_cluster = cluster;
  }


*************** stop_postmaster(bool fast, bool quiet)
*** 210,221 ****
      const char *bindir;
      const char *datadir;

!     if (os_info.running_cluster == CLUSTER_OLD)
      {
          bindir = old_cluster.bindir;
          datadir = old_cluster.pgdata;
      }
!     else if (os_info.running_cluster == CLUSTER_NEW)
      {
          bindir = new_cluster.bindir;
          datadir = new_cluster.pgdata;
--- 205,216 ----
      const char *bindir;
      const char *datadir;

!     if (os_info.running_cluster == &old_cluster)
      {
          bindir = old_cluster.bindir;
          datadir = old_cluster.pgdata;
      }
!     else if (os_info.running_cluster == &new_cluster)
      {
          bindir = new_cluster.bindir;
          datadir = new_cluster.pgdata;
*************** stop_postmaster(bool fast, bool quiet)
*** 236,242 ****
      exec_prog(fast ? false : true, "%s", cmd);

      os_info.postmasterPID = 0;
!     os_info.running_cluster = NONE;
  }


--- 231,237 ----
      exec_prog(fast ? false : true, "%s", cmd);

      os_info.postmasterPID = 0;
!     os_info.running_cluster = NULL;
  }


*************** stop_postmaster(bool fast, bool quiet)
*** 250,259 ****
   * Returns true if the connection attempt was successfull, false otherwise.
   */
  static bool
! test_server_conn(int timeout, Cluster whichCluster)
  {
!     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
!     unsigned short port = active_cluster->port;
      PGconn       *conn = NULL;
      char        con_opts[MAX_STRING];
      int            tries;
--- 245,253 ----
   * Returns true if the connection attempt was successfull, false otherwise.
   */
  static bool
! test_server_conn(ClusterInfo *cluster, int timeout)
  {
!     unsigned short port = cluster->port;
      PGconn       *conn = NULL;
      char        con_opts[MAX_STRING];
      int            tries;
*************** test_server_conn(int timeout, Cluster wh
*** 275,281 ****

          if (tries == STARTUP_WARNING_TRIES)
              prep_status("Trying to start %s server ",
!                         CLUSTER_NAME(whichCluster));
          else if (tries > STARTUP_WARNING_TRIES)
              pg_log(PG_REPORT, ".");
      }
--- 269,275 ----

          if (tries == STARTUP_WARNING_TRIES)
              prep_status("Trying to start %s server ",
!                         CLUSTER_NAME(cluster));
          else if (tries > STARTUP_WARNING_TRIES)
              pg_log(PG_REPORT, ".");
      }
diff --git a/contrib/pg_upgrade/tablespace.c b/contrib/pg_upgrade/tablespace.c
index 4930d5d..70fe057 100644
*** /tmp/u5hK1a_tablespace.c    Wed Jan  5 09:04:03 2011
--- /tmp/Qgyybb_tablespace.c    Wed Jan  5 09:04:03 2011
***************
*** 10,17 ****
  #include "pg_upgrade.h"

  static void get_tablespace_paths(void);
! static void set_tablespace_directory_suffix(
!                                 Cluster whichCluster);


  void
--- 10,16 ----
  #include "pg_upgrade.h"

  static void get_tablespace_paths(void);
! static void set_tablespace_directory_suffix(ClusterInfo *cluster);


  void
*************** init_tablespaces(void)
*** 19,26 ****
  {
      get_tablespace_paths();

!     set_tablespace_directory_suffix(CLUSTER_OLD);
!     set_tablespace_directory_suffix(CLUSTER_NEW);

      if (os_info.num_tablespaces > 0 &&
      strcmp(old_cluster.tablespace_suffix, new_cluster.tablespace_suffix) == 0)
--- 18,25 ----
  {
      get_tablespace_paths();

!     set_tablespace_directory_suffix(&old_cluster);
!     set_tablespace_directory_suffix(&new_cluster);

      if (os_info.num_tablespaces > 0 &&
      strcmp(old_cluster.tablespace_suffix, new_cluster.tablespace_suffix) == 0)
*************** init_tablespaces(void)
*** 39,45 ****
  static void
  get_tablespace_paths(void)
  {
!     PGconn       *conn = connectToServer("template1", CLUSTER_OLD);
      PGresult   *res;
      int            tblnum;
      int            i_spclocation;
--- 38,44 ----
  static void
  get_tablespace_paths(void)
  {
!     PGconn       *conn = connectToServer(&old_cluster, "template1");
      PGresult   *res;
      int            tblnum;
      int            i_spclocation;
*************** get_tablespace_paths(void)
*** 71,91 ****


  static void
! set_tablespace_directory_suffix(Cluster whichCluster)
  {
!     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
!
!     if (GET_MAJOR_VERSION(active_cluster->major_version) <= 804)
!         active_cluster->tablespace_suffix = pg_strdup("");
      else
      {
          /* This cluster has a version-specific subdirectory */
!         active_cluster->tablespace_suffix = pg_malloc(4 +
!                                   strlen(active_cluster->major_version_str) +
                                                        10 /* OIDCHARS */ + 1);

          /* The leading slash is needed to start a new directory. */
!         sprintf(active_cluster->tablespace_suffix, "/PG_%s_%d", active_cluster->major_version_str,
!                 active_cluster->controldata.cat_ver);
      }
  }
--- 70,88 ----


  static void
! set_tablespace_directory_suffix(ClusterInfo *cluster)
  {
!     if (GET_MAJOR_VERSION(cluster->major_version) <= 804)
!         cluster->tablespace_suffix = pg_strdup("");
      else
      {
          /* This cluster has a version-specific subdirectory */
!         cluster->tablespace_suffix = pg_malloc(4 +
!                                   strlen(cluster->major_version_str) +
                                                        10 /* OIDCHARS */ + 1);

          /* The leading slash is needed to start a new directory. */
!         sprintf(cluster->tablespace_suffix, "/PG_%s_%d", cluster->major_version_str,
!                 cluster->controldata.cat_ver);
      }
  }
diff --git a/contrib/pg_upgrade/version.c b/contrib/pg_upgrade/version.c
index b85b814..cdda741 100644
*** /tmp/kw6RCe_version.c    Wed Jan  5 09:04:03 2011
--- /tmp/0Xvpyc_version.c    Wed Jan  5 09:04:03 2011
***************
*** 18,27 ****
   *    9.0 has a new pg_largeobject permission table
   */
  void
! new_9_0_populate_pg_largeobject_metadata(bool check_mode,
!                                          Cluster whichCluster)
  {
-     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
--- 18,25 ----
   *    9.0 has a new pg_largeobject permission table
   */
  void
! new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
  {
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
*************** new_9_0_populate_pg_largeobject_metadata
*** 32,43 ****
      snprintf(output_path, sizeof(output_path), "%s/pg_largeobject.sql",
               os_info.cwd);

!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          int            i_count;
!         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(active_db->db_name, whichCluster);

          /* find if there are any large objects */
          res = executeQueryOrDie(conn,
--- 30,41 ----
      snprintf(output_path, sizeof(output_path), "%s/pg_largeobject.sql",
               os_info.cwd);

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          int            i_count;
!         DbInfo       *active_db = &cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(cluster, active_db->db_name);

          /* find if there are any large objects */
          res = executeQueryOrDie(conn,
diff --git a/contrib/pg_upgrade/version_old_8_3.c b/contrib/pg_upgrade/version_old_8_3.c
index 5a396de..c342cd9 100644
*** /tmp/M08uca_version_old_8_3.c    Wed Jan  5 09:04:03 2011
--- /tmp/68bpUa_version_old_8_3.c    Wed Jan  5 09:04:03 2011
***************
*** 19,27 ****
   *    checks tables and indexes.
   */
  void
! old_8_3_check_for_name_data_type_usage(Cluster whichCluster)
  {
-     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
--- 19,26 ----
   *    checks tables and indexes.
   */
  void
! old_8_3_check_for_name_data_type_usage(ClusterInfo *cluster)
  {
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
*************** old_8_3_check_for_name_data_type_usage(C
*** 32,38 ****
      snprintf(output_path, sizeof(output_path), "%s/tables_using_name.txt",
               os_info.cwd);

!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
--- 31,37 ----
      snprintf(output_path, sizeof(output_path), "%s/tables_using_name.txt",
               os_info.cwd);

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
*************** old_8_3_check_for_name_data_type_usage(C
*** 41,48 ****
          int            i_nspname,
                      i_relname,
                      i_attname;
!         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(active_db->db_name, whichCluster);

          /*
           * With a smaller alignment in 8.4, 'name' cannot be used in a
--- 40,47 ----
          int            i_nspname,
                      i_relname,
                      i_attname;
!         DbInfo       *active_db = &cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(cluster, active_db->db_name);

          /*
           * With a smaller alignment in 8.4, 'name' cannot be used in a
*************** old_8_3_check_for_name_data_type_usage(C
*** 113,121 ****
   *    so upgrading of such fields is impossible.
   */
  void
! old_8_3_check_for_tsquery_usage(Cluster whichCluster)
  {
-     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
--- 112,119 ----
   *    so upgrading of such fields is impossible.
   */
  void
! old_8_3_check_for_tsquery_usage(ClusterInfo *cluster)
  {
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
*************** old_8_3_check_for_tsquery_usage(Cluster
*** 126,132 ****
      snprintf(output_path, sizeof(output_path), "%s/tables_using_tsquery.txt",
               os_info.cwd);

!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
--- 124,130 ----
      snprintf(output_path, sizeof(output_path), "%s/tables_using_tsquery.txt",
               os_info.cwd);

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
*************** old_8_3_check_for_tsquery_usage(Cluster
*** 135,142 ****
          int            i_nspname,
                      i_relname,
                      i_attname;
!         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(active_db->db_name, whichCluster);

          /* Find any user-defined tsquery columns */
          res = executeQueryOrDie(conn,
--- 133,140 ----
          int            i_nspname,
                      i_relname,
                      i_attname;
!         DbInfo       *active_db = &cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(cluster, active_db->db_name);

          /* Find any user-defined tsquery columns */
          res = executeQueryOrDie(conn,
*************** old_8_3_check_for_tsquery_usage(Cluster
*** 208,217 ****
   *    'c' 'bb' 'aaa'           -- 8.3
   */
  void
! old_8_3_rebuild_tsvector_tables(bool check_mode,
!                                 Cluster whichCluster)
  {
-     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
--- 206,213 ----
   *    'c' 'bb' 'aaa'           -- 8.3
   */
  void
! old_8_3_rebuild_tsvector_tables(ClusterInfo *cluster, bool check_mode)
  {
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
*************** old_8_3_rebuild_tsvector_tables(bool che
*** 222,228 ****
      snprintf(output_path, sizeof(output_path), "%s/rebuild_tsvector_tables.sql",
               os_info.cwd);

!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
--- 218,224 ----
      snprintf(output_path, sizeof(output_path), "%s/rebuild_tsvector_tables.sql",
               os_info.cwd);

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
*************** old_8_3_rebuild_tsvector_tables(bool che
*** 233,240 ****
          int            i_nspname,
                      i_relname,
                      i_attname;
!         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(active_db->db_name, whichCluster);

          /* Find any user-defined tsvector columns */
          res = executeQueryOrDie(conn,
--- 229,236 ----
          int            i_nspname,
                      i_relname,
                      i_attname;
!         DbInfo       *active_db = &cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(cluster, active_db->db_name);

          /* Find any user-defined tsvector columns */
          res = executeQueryOrDie(conn,
*************** old_8_3_rebuild_tsvector_tables(bool che
*** 352,361 ****
   *    Hash, Gin, and GiST index binary format has changes from 8.3->8.4
   */
  void
! old_8_3_invalidate_hash_gin_indexes(bool check_mode,
!                                     Cluster whichCluster)
  {
-     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
--- 348,355 ----
   *    Hash, Gin, and GiST index binary format has changes from 8.3->8.4
   */
  void
! old_8_3_invalidate_hash_gin_indexes(ClusterInfo *cluster, bool check_mode)
  {
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
*************** old_8_3_invalidate_hash_gin_indexes(bool
*** 366,372 ****
      snprintf(output_path, sizeof(output_path), "%s/reindex_hash_and_gin.sql",
               os_info.cwd);

!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
--- 360,366 ----
      snprintf(output_path, sizeof(output_path), "%s/reindex_hash_and_gin.sql",
               os_info.cwd);

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
*************** old_8_3_invalidate_hash_gin_indexes(bool
*** 374,381 ****
          int            rowno;
          int            i_nspname,
                      i_relname;
!         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(active_db->db_name, whichCluster);

          /* find hash and gin indexes */
          res = executeQueryOrDie(conn,
--- 368,375 ----
          int            rowno;
          int            i_nspname,
                      i_relname;
!         DbInfo       *active_db = &cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(cluster, active_db->db_name);

          /* find hash and gin indexes */
          res = executeQueryOrDie(conn,
*************** old_8_3_invalidate_hash_gin_indexes(bool
*** 467,476 ****
   *    8.4 bpchar_pattern_ops no longer sorts based on trailing spaces
   */
  void
! old_8_3_invalidate_bpchar_pattern_ops_indexes(bool check_mode,
!                                               Cluster whichCluster)
  {
-     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
--- 461,469 ----
   *    8.4 bpchar_pattern_ops no longer sorts based on trailing spaces
   */
  void
! old_8_3_invalidate_bpchar_pattern_ops_indexes(ClusterInfo *cluster,
!                                               bool check_mode)
  {
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
*************** old_8_3_invalidate_bpchar_pattern_ops_in
*** 481,487 ****
      snprintf(output_path, sizeof(output_path), "%s/reindex_bpchar_ops.sql",
               os_info.cwd);

!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
--- 474,480 ----
      snprintf(output_path, sizeof(output_path), "%s/reindex_bpchar_ops.sql",
               os_info.cwd);

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
*************** old_8_3_invalidate_bpchar_pattern_ops_in
*** 489,496 ****
          int            rowno;
          int            i_nspname,
                      i_relname;
!         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(active_db->db_name, whichCluster);

          /* find bpchar_pattern_ops indexes */

--- 482,489 ----
          int            rowno;
          int            i_nspname,
                      i_relname;
!         DbInfo       *active_db = &cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(cluster, active_db->db_name);

          /* find bpchar_pattern_ops indexes */

*************** old_8_3_invalidate_bpchar_pattern_ops_in
*** 602,610 ****
   *    server, even in link mode.
   */
  char *
! old_8_3_create_sequence_script(Cluster whichCluster)
  {
-     ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
--- 595,602 ----
   *    server, even in link mode.
   */
  char *
! old_8_3_create_sequence_script(ClusterInfo *cluster)
  {
      int            dbnum;
      FILE       *script = NULL;
      bool        found = false;
*************** old_8_3_create_sequence_script(Cluster w
*** 614,620 ****

      prep_status("Creating script to adjust sequences");

!     for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
--- 606,612 ----

      prep_status("Creating script to adjust sequences");

!     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          PGresult   *res;
          bool        db_used = false;
*************** old_8_3_create_sequence_script(Cluster w
*** 622,629 ****
          int            rowno;
          int            i_nspname,
                      i_relname;
!         DbInfo       *active_db = &active_cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(active_db->db_name, whichCluster);

          /* Find any sequences */
          res = executeQueryOrDie(conn,
--- 614,621 ----
          int            rowno;
          int            i_nspname,
                      i_relname;
!         DbInfo       *active_db = &cluster->dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(cluster, active_db->db_name);

          /* Find any sequences */
          res = executeQueryOrDie(conn,
commit 67c9e4442f2521ff2ad62aa4d409269ea684ac0a
Author: Bruce Momjian <bruce@momjian.us>
Date:   Sat Jan 1 12:28:48 2011 -0500

    Furter pg_upgrade optimizations to reduce function call argument count.

diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
index 839a3c9..5708e2f 100644
*** /tmp/ky16ee_check.c    Wed Jan  5 09:04:30 2011
--- /tmp/uJkDve_check.c    Wed Jan  5 09:04:30 2011
*************** void
*** 209,216 ****
  check_cluster_versions(void)
  {
      /* get old and new cluster versions */
!     old_cluster.major_version = get_major_server_version(&old_cluster, &old_cluster.major_version_str);
!     new_cluster.major_version = get_major_server_version(&new_cluster, &new_cluster.major_version_str);

      /* We allow upgrades from/to the same major version for alpha/beta upgrades */

--- 209,216 ----
  check_cluster_versions(void)
  {
      /* get old and new cluster versions */
!     old_cluster.major_version = get_major_server_version(&old_cluster);
!     new_cluster.major_version = get_major_server_version(&new_cluster);

      /* We allow upgrades from/to the same major version for alpha/beta upgrades */

diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c
index e44798a..7651096 100644
*** /tmp/Q6ensd_info.c    Wed Jan  5 09:04:30 2011
--- /tmp/a3Vosb_info.c    Wed Jan  5 09:04:30 2011
***************
*** 15,22 ****
  static void get_db_infos(ClusterInfo *cluster);
  static void dbarr_print(ClusterInfo *cluster);
  static void relarr_print(RelInfoArr *arr);
! static void get_rel_infos(ClusterInfo *cluster, const DbInfo *dbinfo,
!               RelInfoArr *relarr);
  static void relarr_free(RelInfoArr *rel_arr);
  static void map_rel(const RelInfo *oldrel,
          const RelInfo *newrel, const DbInfo *old_db,
--- 15,21 ----
  static void get_db_infos(ClusterInfo *cluster);
  static void dbarr_print(ClusterInfo *cluster);
  static void relarr_print(RelInfoArr *arr);
! static void get_rel_infos(ClusterInfo *cluster, const int dbnum);
  static void relarr_free(RelInfoArr *rel_arr);
  static void map_rel(const RelInfo *oldrel,
          const RelInfo *newrel, const DbInfo *old_db,
*************** get_db_and_rel_infos(ClusterInfo *cluste
*** 272,279 ****
      get_db_infos(cluster);

      for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
!         get_rel_infos(cluster, &cluster->dbarr.dbs[dbnum],
!                       &cluster->dbarr.dbs[dbnum].rel_arr);

      if (log_opts.debug)
          dbarr_print(cluster);
--- 271,277 ----
      get_db_infos(cluster);

      for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
!         get_rel_infos(cluster, dbnum);

      if (log_opts.debug)
          dbarr_print(cluster);
*************** get_db_and_rel_infos(ClusterInfo *cluste
*** 290,298 ****
   * FirstNormalObjectId belongs to the user
   */
  static void
! get_rel_infos(ClusterInfo *cluster, const DbInfo *dbinfo, RelInfoArr *relarr)
  {
!     PGconn       *conn = connectToServer(cluster, dbinfo->db_name);
      PGresult   *res;
      RelInfo    *relinfos;
      int            ntups;
--- 288,297 ----
   * FirstNormalObjectId belongs to the user
   */
  static void
! get_rel_infos(ClusterInfo *cluster, const int dbnum)
  {
!     PGconn       *conn = connectToServer(cluster,
!                                        cluster->dbarr.dbs[dbnum].db_name);
      PGresult   *res;
      RelInfo    *relinfos;
      int            ntups;
*************** get_rel_infos(ClusterInfo *cluster, cons
*** 374,389 ****
          tblspace = PQgetvalue(res, relnum, i_spclocation);
          /* if no table tablespace, use the database tablespace */
          if (strlen(tblspace) == 0)
!             tblspace = dbinfo->db_tblspace;
          strlcpy(curr->tablespace, tblspace, sizeof(curr->tablespace));
      }
      PQclear(res);

      PQfinish(conn);

!     relarr->rels = relinfos;
!     relarr->nrels = num_rels;
!     relarr->last_relname_lookup = 0;
  }


--- 373,388 ----
          tblspace = PQgetvalue(res, relnum, i_spclocation);
          /* if no table tablespace, use the database tablespace */
          if (strlen(tblspace) == 0)
!             tblspace = cluster->dbarr.dbs[dbnum].db_tblspace;
          strlcpy(curr->tablespace, tblspace, sizeof(curr->tablespace));
      }
      PQclear(res);

      PQfinish(conn);

!     cluster->dbarr.dbs[dbnum].rel_arr.rels = relinfos;
!     cluster->dbarr.dbs[dbnum].rel_arr.nrels = num_rels;
!     cluster->dbarr.dbs[dbnum].rel_arr.last_relname_lookup = 0;
  }


diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c
index d2ca08b..5b8bf72 100644
*** /tmp/Ch0sza_pg_upgrade.c    Wed Jan  5 09:04:30 2011
--- /tmp/KJwJSa_pg_upgrade.c    Wed Jan  5 09:04:30 2011
*************** cleanup(void)
*** 384,391 ****
      dbarr_free(&new_cluster.dbarr);
      pg_free(log_opts.filename);
      pg_free(os_info.user);
-     pg_free(old_cluster.major_version_str);
-     pg_free(new_cluster.major_version_str);
      pg_free(old_cluster.controldata.lc_collate);
      pg_free(new_cluster.controldata.lc_collate);
      pg_free(old_cluster.controldata.lc_ctype);
--- 384,389 ----
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
index b6ce965..5405209 100644
*** /tmp/uDtZHc_pg_upgrade.h    Wed Jan  5 09:04:30 2011
--- /tmp/mf7mXc_pg_upgrade.h    Wed Jan  5 09:04:30 2011
*************** typedef struct
*** 179,185 ****
      char       *bindir;            /* pathname for cluster's executable directory */
      unsigned short port;        /* port number where postmaster is waiting */
      uint32        major_version;    /* PG_VERSION of cluster */
!     char       *major_version_str;        /* string PG_VERSION of cluster */
      Oid            pg_database_oid;    /* OID of pg_database relation */
      char       *libpath;        /* pathname for cluster's pkglibdir */
      char       *tablespace_suffix;        /* directory specification */
--- 179,185 ----
      char       *bindir;            /* pathname for cluster's executable directory */
      unsigned short port;        /* port number where postmaster is waiting */
      uint32        major_version;    /* PG_VERSION of cluster */
!     char       major_version_str[64];        /* string PG_VERSION of cluster */
      Oid            pg_database_oid;    /* OID of pg_database relation */
      char       *libpath;        /* pathname for cluster's pkglibdir */
      char       *tablespace_suffix;        /* directory specification */
*************** PGresult *executeQueryOrDie(PGconn *conn
*** 357,363 ****

  void        start_postmaster(ClusterInfo *cluster, bool quiet);
  void        stop_postmaster(bool fast, bool quiet);
! uint32 get_major_server_version(ClusterInfo *cluster, char **verstr);
  void        check_for_libpq_envvars(void);


--- 357,363 ----

  void        start_postmaster(ClusterInfo *cluster, bool quiet);
  void        stop_postmaster(bool fast, bool quiet);
! uint32 get_major_server_version(ClusterInfo *cluster);
  void        check_for_libpq_envvars(void);


diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c
index 56dcb10..785e2ee 100644
*** /tmp/MgF32b_server.c    Wed Jan  5 09:04:30 2011
--- /tmp/wuqipc_server.c    Wed Jan  5 09:04:30 2011
*************** get_postmaster_pid(const char *datadir)
*** 129,150 ****
   * is retrieved by reading the PG_VERSION file.
   */
  uint32
! get_major_server_version(ClusterInfo *cluster, char **verstr)
  {
      const char *datadir = cluster->pgdata;
      FILE       *version_fd;
!     char        ver_file[MAXPGPATH];
      int            integer_version = 0;
      int            fractional_version = 0;

!     *verstr = pg_malloc(64);
!
!     snprintf(ver_file, sizeof(ver_file), "%s/PG_VERSION", datadir);
!     if ((version_fd = fopen(ver_file, "r")) == NULL)
          return 0;

!     if (fscanf(version_fd, "%63s", *verstr) == 0 ||
!         sscanf(*verstr, "%d.%d", &integer_version, &fractional_version) != 2)
      {
          pg_log(PG_FATAL, "could not get version from %s\n", datadir);
          fclose(version_fd);
--- 129,149 ----
   * is retrieved by reading the PG_VERSION file.
   */
  uint32
! get_major_server_version(ClusterInfo *cluster)
  {
      const char *datadir = cluster->pgdata;
      FILE       *version_fd;
!     char        ver_filename[MAXPGPATH];
      int            integer_version = 0;
      int            fractional_version = 0;

!     snprintf(ver_filename, sizeof(ver_filename), "%s/PG_VERSION", datadir);
!     if ((version_fd = fopen(ver_filename, "r")) == NULL)
          return 0;

!     if (fscanf(version_fd, "%63s", cluster->major_version_str) == 0 ||
!         sscanf(cluster->major_version_str, "%d.%d", &integer_version,
!                &fractional_version) != 2)
      {
          pg_log(PG_FATAL, "could not get version from %s\n", datadir);
          fclose(version_fd);
commit 25cc7424e3b4d3bd76fa54bfc6907f294b4b99d1
Author: Bruce Momjian <bruce@momjian.us>
Date:   Tue Jan 4 19:11:00 2011 -0500

    Simplify functions and parameters used by pg_upgrade.

diff --git a/contrib/pg_upgrade/dump.c b/contrib/pg_upgrade/dump.c
index a192cbb..52ab481 100644
*** /tmp/tIZ55c_dump.c    Wed Jan  5 09:04:50 2011
--- /tmp/HVwJqb_dump.c    Wed Jan  5 09:04:50 2011
***************
*** 10,16 ****
  #include "pg_upgrade.h"


-
  void
  generate_old_dump(void)
  {
--- 10,15 ----
diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c
index a83248c..9e69ecd 100644
*** /tmp/HVyUPd_info.c    Wed Jan  5 09:04:50 2011
--- /tmp/dK2i7d_info.c    Wed Jan  5 09:04:50 2011
***************
*** 13,36 ****


  static void get_db_infos(ClusterInfo *cluster);
! static void dbarr_print(ClusterInfo *cluster);
! static void relarr_print(RelInfoArr *arr);
! static void get_rel_infos(ClusterInfo *cluster, const int dbnum);
! static void relarr_free(RelInfoArr *rel_arr);
! static void map_rel(const RelInfo *oldrel,
!         const RelInfo *newrel, const DbInfo *old_db,
!         const DbInfo *new_db, const char *olddata,
!         const char *newdata, FileNameMap *map);
! static void map_rel_by_id(Oid oldid, Oid newid,
!               const char *old_nspname, const char *old_relname,
!               const char *new_nspname, const char *new_relname,
!               const char *old_tablespace, const DbInfo *old_db,
!               const DbInfo *new_db, const char *olddata,
!               const char *newdata, FileNameMap *map);
! static RelInfo *relarr_lookup_reloid(ClusterInfo *cluster, RelInfoArr *rel_arr,
!                 Oid oid);
! static RelInfo *relarr_lookup_rel(ClusterInfo *cluster, RelInfoArr *rel_arr,
                    const char *nspname, const char *relname);


  /*
--- 13,30 ----


  static void get_db_infos(ClusterInfo *cluster);
! static void print_db_arr(ClusterInfo *cluster);
! static void print_rel_arr(RelInfoArr *arr);
! static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo);
! static void free_rel_arr(RelInfoArr *rel_arr);
! static void create_rel_filename_map(const char *old_data, const char *new_data,
!               const DbInfo *old_db, const DbInfo *new_db,
!               const RelInfo *old_rel, const RelInfo *new_rel,
!               FileNameMap *map);
! static RelInfo *relarr_lookup_rel_name(ClusterInfo *cluster, RelInfoArr *rel_arr,
                    const char *nspname, const char *relname);
+ static RelInfo *relarr_lookup_rel_oid(ClusterInfo *cluster, RelInfoArr *rel_arr,
+                 Oid oid);


  /*
*************** gen_db_file_maps(DbInfo *old_db, DbInfo
*** 62,72 ****
          if (strcmp(newrel->nspname, "pg_toast") == 0)
              continue;

!         oldrel = relarr_lookup_rel(&old_cluster, &old_db->rel_arr,
                                     newrel->nspname, newrel->relname);

!         map_rel(oldrel, newrel, old_db, new_db, old_pgdata, new_pgdata,
!                 maps + num_maps);
          num_maps++;

          /*
--- 56,66 ----
          if (strcmp(newrel->nspname, "pg_toast") == 0)
              continue;

!         oldrel = relarr_lookup_rel_name(&old_cluster, &old_db->rel_arr,
                                     newrel->nspname, newrel->relname);

!         create_rel_filename_map(old_pgdata, new_pgdata, old_db, new_db,
!                 oldrel, newrel, maps + num_maps);
          num_maps++;

          /*
*************** gen_db_file_maps(DbInfo *old_db, DbInfo
*** 81,100 ****
              char        old_name[MAXPGPATH];

              /* construct the new and old relnames for the toast relation */
!             snprintf(old_name, sizeof(old_name), "pg_toast_%u",
!                      oldrel->reloid);
!             snprintf(new_name, sizeof(new_name), "pg_toast_%u",
!                      newrel->reloid);

              /* look them up in their respective arrays */
!             old_toast = relarr_lookup_reloid(&old_cluster, &old_db->rel_arr,
                                               oldrel->toastrelid);
!             new_toast = relarr_lookup_rel(&new_cluster, &new_db->rel_arr,
                                            "pg_toast", new_name);

              /* finally create a mapping for them */
!             map_rel(old_toast, new_toast, old_db, new_db, old_pgdata, new_pgdata,
!                     maps + num_maps);
              num_maps++;

              /*
--- 75,92 ----
              char        old_name[MAXPGPATH];

              /* construct the new and old relnames for the toast relation */
!             snprintf(old_name, sizeof(old_name), "pg_toast_%u", oldrel->reloid);
!             snprintf(new_name, sizeof(new_name), "pg_toast_%u", newrel->reloid);

              /* look them up in their respective arrays */
!             old_toast = relarr_lookup_rel_oid(&old_cluster, &old_db->rel_arr,
                                               oldrel->toastrelid);
!             new_toast = relarr_lookup_rel_name(&new_cluster, &new_db->rel_arr,
                                            "pg_toast", new_name);

              /* finally create a mapping for them */
!             create_rel_filename_map(old_pgdata, new_pgdata, old_db, new_db,
!                     old_toast, new_toast, maps + num_maps);
              num_maps++;

              /*
*************** gen_db_file_maps(DbInfo *old_db, DbInfo
*** 113,127 ****
                       newrel->reloid);

              /* look them up in their respective arrays */
!             /* we lose our cache location here */
!             old_toast = relarr_lookup_rel(&old_cluster, &old_db->rel_arr,
                                            "pg_toast", old_name);
!             new_toast = relarr_lookup_rel(&new_cluster, &new_db->rel_arr,
                                            "pg_toast", new_name);

              /* finally create a mapping for them */
!             map_rel(old_toast, new_toast, old_db, new_db, old_pgdata,
!                     new_pgdata, maps + num_maps);
              num_maps++;
          }
      }
--- 105,118 ----
                       newrel->reloid);

              /* look them up in their respective arrays */
!             old_toast = relarr_lookup_rel_name(&old_cluster, &old_db->rel_arr,
                                            "pg_toast", old_name);
!             new_toast = relarr_lookup_rel_name(&new_cluster, &new_db->rel_arr,
                                            "pg_toast", new_name);

              /* finally create a mapping for them */
!             create_rel_filename_map(old_pgdata, new_pgdata, old_db,
!                     new_db, old_toast, new_toast, maps + num_maps);
              num_maps++;
          }
      }
*************** gen_db_file_maps(DbInfo *old_db, DbInfo
*** 131,186 ****
  }


- static void
- map_rel(const RelInfo *oldrel, const RelInfo *newrel,
-         const DbInfo *old_db, const DbInfo *new_db, const char *olddata,
-         const char *newdata, FileNameMap *map)
- {
-     map_rel_by_id(oldrel->relfilenode, newrel->relfilenode, oldrel->nspname,
-                   oldrel->relname, newrel->nspname, newrel->relname, oldrel->tablespace, old_db,
-                   new_db, olddata, newdata, map);
- }
-
-
  /*
!  * map_rel_by_id()
   *
   * fills a file node map structure and returns it in "map".
   */
  static void
! map_rel_by_id(Oid oldid, Oid newid,
!               const char *old_nspname, const char *old_relname,
!               const char *new_nspname, const char *new_relname,
!               const char *old_tablespace, const DbInfo *old_db,
!               const DbInfo *new_db, const char *olddata,
!               const char *newdata, FileNameMap *map)
  {
!     map->old_relfilenode = oldid;
!     map->new_relfilenode = newid;

!     snprintf(map->old_nspname, sizeof(map->old_nspname), "%s", old_nspname);
!     snprintf(map->old_relname, sizeof(map->old_relname), "%s", old_relname);
!     snprintf(map->new_nspname, sizeof(map->new_nspname), "%s", new_nspname);
!     snprintf(map->new_relname, sizeof(map->new_relname), "%s", new_relname);

!     if (strlen(old_tablespace) == 0)
      {
          /*
!          * relation belongs to the default tablespace, hence relfiles would
           * exist in the data directories.
           */
!         snprintf(map->old_dir, sizeof(map->old_dir), "%s/base/%u", olddata, old_db->db_oid);
!         snprintf(map->new_dir, sizeof(map->new_dir), "%s/base/%u", newdata, new_db->db_oid);
      }
      else
      {
          /*
!          * relation belongs to some tablespace, hence copy its physical
!          * location
           */
!         snprintf(map->old_dir, sizeof(map->old_dir), "%s%s/%u", old_tablespace,
                   old_cluster.tablespace_suffix, old_db->db_oid);
!         snprintf(map->new_dir, sizeof(map->new_dir), "%s%s/%u", old_tablespace,
                   new_cluster.tablespace_suffix, new_db->db_oid);
      }
  }
--- 122,166 ----
  }


  /*
!  * create_rel_filename_map()
   *
   * fills a file node map structure and returns it in "map".
   */
  static void
! create_rel_filename_map(const char *old_data, const char *new_data,
!               const DbInfo *old_db, const DbInfo *new_db,
!               const RelInfo *old_rel, const RelInfo *new_rel,
!               FileNameMap *map)
  {
!     map->old_relfilenode = old_rel->relfilenode;
!     map->new_relfilenode = new_rel->relfilenode;

!     snprintf(map->old_nspname, sizeof(map->old_nspname), "%s", old_rel->nspname);
!     snprintf(map->new_nspname, sizeof(map->new_nspname), "%s", new_rel->nspname);

!     snprintf(map->old_relname, sizeof(map->old_relname), "%s", old_rel->relname);
!     snprintf(map->new_relname, sizeof(map->new_relname), "%s", new_rel->relname);
!
!     if (strlen(old_rel->tablespace) == 0)
      {
          /*
!          * relation belongs to the default tablespace, hence relfiles should
           * exist in the data directories.
           */
!         snprintf(map->old_dir, sizeof(map->old_dir), "%s/base/%u", old_data,
!                  old_db->db_oid);
!         snprintf(map->new_dir, sizeof(map->new_dir), "%s/base/%u", new_data,
!                  new_db->db_oid);
      }
      else
      {
          /*
!          * relation belongs to some tablespace, so use the tablespace location
           */
!         snprintf(map->old_dir, sizeof(map->old_dir), "%s%s/%u", old_rel->tablespace,
                   old_cluster.tablespace_suffix, old_db->db_oid);
!         snprintf(map->new_dir, sizeof(map->new_dir), "%s%s/%u", new_rel->tablespace,
                   new_cluster.tablespace_suffix, new_db->db_oid);
      }
  }
*************** get_db_and_rel_infos(ClusterInfo *cluste
*** 271,280 ****
      get_db_infos(cluster);

      for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
!         get_rel_infos(cluster, dbnum);

      if (log_opts.debug)
!         dbarr_print(cluster);
  }


--- 251,260 ----
      get_db_infos(cluster);

      for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
!         get_rel_infos(cluster, &cluster->dbarr.dbs[dbnum]);

      if (log_opts.debug)
!         print_db_arr(cluster);
  }


*************** get_db_and_rel_infos(ClusterInfo *cluste
*** 288,297 ****
   * FirstNormalObjectId belongs to the user
   */
  static void
! get_rel_infos(ClusterInfo *cluster, const int dbnum)
  {
      PGconn       *conn = connectToServer(cluster,
!                                        cluster->dbarr.dbs[dbnum].db_name);
      PGresult   *res;
      RelInfo    *relinfos;
      int            ntups;
--- 268,277 ----
   * FirstNormalObjectId belongs to the user
   */
  static void
! get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
  {
      PGconn       *conn = connectToServer(cluster,
!                                        dbinfo->db_name);
      PGresult   *res;
      RelInfo    *relinfos;
      int            ntups;
*************** get_rel_infos(ClusterInfo *cluster, cons
*** 373,388 ****
          tblspace = PQgetvalue(res, relnum, i_spclocation);
          /* if no table tablespace, use the database tablespace */
          if (strlen(tblspace) == 0)
!             tblspace = cluster->dbarr.dbs[dbnum].db_tblspace;
          strlcpy(curr->tablespace, tblspace, sizeof(curr->tablespace));
      }
      PQclear(res);

      PQfinish(conn);

!     cluster->dbarr.dbs[dbnum].rel_arr.rels = relinfos;
!     cluster->dbarr.dbs[dbnum].rel_arr.nrels = num_rels;
!     cluster->dbarr.dbs[dbnum].rel_arr.last_relname_lookup = 0;
  }


--- 353,368 ----
          tblspace = PQgetvalue(res, relnum, i_spclocation);
          /* if no table tablespace, use the database tablespace */
          if (strlen(tblspace) == 0)
!             tblspace = dbinfo->db_tblspace;
          strlcpy(curr->tablespace, tblspace, sizeof(curr->tablespace));
      }
      PQclear(res);

      PQfinish(conn);

!     dbinfo->rel_arr.rels = relinfos;
!     dbinfo->rel_arr.nrels = num_rels;
!     dbinfo->rel_arr.last_relname_lookup = 0;
  }


*************** dbarr_lookup_db(DbInfoArr *db_arr, const
*** 407,419 ****


  /*
!  * relarr_lookup_rel()
   *
   * Searches "relname" in rel_arr. Returns the *real* pointer to the
   * RelInfo structure.
   */
  static RelInfo *
! relarr_lookup_rel(ClusterInfo *cluster, RelInfoArr *rel_arr,
                      const char *nspname, const char *relname)
  {
      int            relnum;
--- 387,399 ----


  /*
!  * relarr_lookup_rel_name()
   *
   * Searches "relname" in rel_arr. Returns the *real* pointer to the
   * RelInfo structure.
   */
  static RelInfo *
! relarr_lookup_rel_name(ClusterInfo *cluster, RelInfoArr *rel_arr,
                      const char *nspname, const char *relname)
  {
      int            relnum;
*************** relarr_lookup_rel(ClusterInfo *cluster,
*** 443,456 ****


  /*
!  * relarr_lookup_reloid()
   *
   *    Returns a pointer to the RelInfo structure for the
   *    given oid or NULL if the desired entry cannot be
   *    found.
   */
  static RelInfo *
! relarr_lookup_reloid(ClusterInfo *cluster, RelInfoArr *rel_arr, Oid oid)
  {
      int            relnum;

--- 423,436 ----


  /*
!  * relarr_lookup_rel_oid()
   *
   *    Returns a pointer to the RelInfo structure for the
   *    given oid or NULL if the desired entry cannot be
   *    found.
   */
  static RelInfo *
! relarr_lookup_rel_oid(ClusterInfo *cluster, RelInfoArr *rel_arr, Oid oid)
  {
      int            relnum;

*************** relarr_lookup_reloid(ClusterInfo *cluste
*** 466,472 ****


  static void
! relarr_free(RelInfoArr *rel_arr)
  {
      pg_free(rel_arr->rels);
      rel_arr->nrels = 0;
--- 446,452 ----


  static void
! free_rel_arr(RelInfoArr *rel_arr)
  {
      pg_free(rel_arr->rels);
      rel_arr->nrels = 0;
*************** dbarr_free(DbInfoArr *db_arr)
*** 480,492 ****
      int            dbnum;

      for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++)
!         relarr_free(&db_arr->dbs[dbnum].rel_arr);
      db_arr->ndbs = 0;
  }


  static void
! dbarr_print(ClusterInfo *cluster)
  {
      int            dbnum;

--- 460,472 ----
      int            dbnum;

      for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++)
!         free_rel_arr(&db_arr->dbs[dbnum].rel_arr);
      db_arr->ndbs = 0;
  }


  static void
! print_db_arr(ClusterInfo *cluster)
  {
      int            dbnum;

*************** dbarr_print(ClusterInfo *cluster)
*** 495,508 ****
      for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          pg_log(PG_DEBUG, "Database: %s\n", cluster->dbarr.dbs[dbnum].db_name);
!         relarr_print(&cluster->dbarr.dbs[dbnum].rel_arr);
          pg_log(PG_DEBUG, "\n\n");
      }
  }


  static void
! relarr_print(RelInfoArr *arr)
  {
      int            relnum;

--- 475,488 ----
      for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      {
          pg_log(PG_DEBUG, "Database: %s\n", cluster->dbarr.dbs[dbnum].db_name);
!         print_rel_arr(&cluster->dbarr.dbs[dbnum].rel_arr);
          pg_log(PG_DEBUG, "\n\n");
      }
  }


  static void
! print_rel_arr(RelInfoArr *arr)
  {
      int            relnum;

commit 3302334b48e2be6eb2c01dcf500363dbd4f22e59
Author: Bruce Momjian <bruce@momjian.us>
Date:   Tue Jan 4 23:35:49 2011 -0500

    In pg_upgrade, copy pg_largeobject_metadata and its index for 9.0+
    servers because, like pg_largeobject, it is a system table whose
    contents are not dumped by pg_dump --schema-only.

diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c
index 9e69ecd..8d566c0 100644
*** /tmp/I8SAQe_info.c    Wed Jan  5 09:05:05 2011
--- /tmp/IOoIFc_info.c    Wed Jan  5 09:05:05 2011
*************** get_rel_infos(ClusterInfo *cluster, DbIn
*** 310,322 ****
               "    ) OR ( "
               "    n.nspname = 'pg_catalog' "
               "    AND relname IN "
!              "        ('pg_largeobject', 'pg_largeobject_loid_pn_index') )) "
               "    AND relkind IN ('r','t', 'i'%s)"
               "GROUP BY  c.oid, n.nspname, c.relname, c.relfilenode,"
               "            c.reltoastrelid, t.spclocation, "
               "            n.nspname "
               "ORDER BY t.spclocation, n.nspname, c.relname;",
               FirstNormalObjectId,
      /* see the comment at the top of old_8_3_create_sequence_script() */
               (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) ?
               "" : ", 'S'");
--- 310,325 ----
               "    ) OR ( "
               "    n.nspname = 'pg_catalog' "
               "    AND relname IN "
!              "        ('pg_largeobject', 'pg_largeobject_loid_pn_index'%s) )) "
               "    AND relkind IN ('r','t', 'i'%s)"
               "GROUP BY  c.oid, n.nspname, c.relname, c.relfilenode,"
               "            c.reltoastrelid, t.spclocation, "
               "            n.nspname "
               "ORDER BY t.spclocation, n.nspname, c.relname;",
               FirstNormalObjectId,
+     /* does pg_largeobject_metadata need to be migrated? */
+              (GET_MAJOR_VERSION(old_cluster.major_version) <= 804) ?
+              "" : ", 'pg_largeobject_metadata', 'pg_largeobject_metadata_oid_index'",
      /* see the comment at the top of old_8_3_create_sequence_script() */
               (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) ?
               "" : ", 'S'");

Re: pg_upgrade patches applied

From
Tom Lane
Date:
Bruce Momjian <bruce@momjian.us> writes:
> The last patch fixes a problem where I was not migrating
> pg_largeobject_metadata and its index for 9.0+ migrations, which of
> course would only affect migrations to 9.1 and 9.0 to 9.0 migrations, so
> I backpatched that to 9.0.

That isn't going to work.  At least not unless you start trying to force
roles to have the same OIDs in the new installation.
        regards, tom lane


Re: pg_upgrade patches applied

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <bruce@momjian.us> writes:
> > The last patch fixes a problem where I was not migrating
> > pg_largeobject_metadata and its index for 9.0+ migrations, which of
> > course would only affect migrations to 9.1 and 9.0 to 9.0 migrations, so
> > I backpatched that to 9.0.
> 
> That isn't going to work.  At least not unless you start trying to force
> roles to have the same OIDs in the new installation.

Uh, don't we store the pg_shadow.usesysid in pg_largeobject_metadata? 
If so I can use the CREATE ROLE ... SYSID clause when doing a binary
upgrade.

--  Bruce Momjian  <bruce@momjian.us>        http://momjian.us EnterpriseDB
http://enterprisedb.com
 + It's impossible for everything to be true. +


Re: pg_upgrade patches applied

From
Tom Lane
Date:
Bruce Momjian <bruce@momjian.us> writes:
> Tom Lane wrote:
>> That isn't going to work.  At least not unless you start trying to force
>> roles to have the same OIDs in the new installation.

> If so I can use the CREATE ROLE ... SYSID clause when doing a binary
> upgrade.

Oh, I had forgotten we still had that wart in the grammar.
It doesn't actually work:
    else if (strcmp(defel->defname, "sysid") == 0)    {        ereport(NOTICE,                (errmsg("SYSID can no
longerbe specified")));    }
 

Not sure if it's better to try to make that work again than to add
another hack in pg_upgrade_support.  On the whole that's a keyword
I'd rather see us drop someday soon.
        regards, tom lane


Re: pg_upgrade patches applied

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <bruce@momjian.us> writes:
> > Tom Lane wrote:
> >> That isn't going to work.  At least not unless you start trying to force
> >> roles to have the same OIDs in the new installation.
> 
> > If so I can use the CREATE ROLE ... SYSID clause when doing a binary
> > upgrade.
> 
> Oh, I had forgotten we still had that wart in the grammar.
> It doesn't actually work:
> 
>         else if (strcmp(defel->defname, "sysid") == 0)
>         {
>             ereport(NOTICE,
>                     (errmsg("SYSID can no longer be specified")));
>         }
> 
> Not sure if it's better to try to make that work again than to add
> another hack in pg_upgrade_support.  On the whole that's a keyword
> I'd rather see us drop someday soon.

OK, let me work on adding it to pg_upgrade_support.  Glad you saw this.

--  Bruce Momjian  <bruce@momjian.us>        http://momjian.us EnterpriseDB
http://enterprisedb.com
 + It's impossible for everything to be true. +


Fix for pg_upgrade migrating pg_largeobject_metadata

From
Bruce Momjian
Date:
Bruce Momjian wrote:
> Tom Lane wrote:
> > Bruce Momjian <bruce@momjian.us> writes:
> > > Tom Lane wrote:
> > >> That isn't going to work.  At least not unless you start trying to force
> > >> roles to have the same OIDs in the new installation.
> >
> > > If so I can use the CREATE ROLE ... SYSID clause when doing a binary
> > > upgrade.
> >
> > Oh, I had forgotten we still had that wart in the grammar.
> > It doesn't actually work:
> >
> >         else if (strcmp(defel->defname, "sysid") == 0)
> >         {
> >             ereport(NOTICE,
> >                     (errmsg("SYSID can no longer be specified")));
> >         }
> >
> > Not sure if it's better to try to make that work again than to add
> > another hack in pg_upgrade_support.  On the whole that's a keyword
> > I'd rather see us drop someday soon.
>
> OK, let me work on adding it to pg_upgrade_support.  Glad you saw this.

I have fixed the bug by using pg_upgrade_support.  It was a little
complicated because you need to install the pg_upgrade_support functions
in the super-user database so it is available when you create the users
in the first step of restoring the pg_dumpall file.

I am afraid we have to batckpatch this to fix to 9.0 for 9.0 to 9.0
upgrades.  It does not apply when coming from pre-9.0 because there was
no pg_largeobject_metadata.

For testing I did this:

    CREATE DATABASE lo;
    \c lo
    SELECT lo_import('/etc/motd');
    \set loid `psql -qt -c 'select loid from pg_largeobject' lo`
    CREATE ROLE user1;
    CREATE ROLE user2;
    -- force user2 to have a different user id on restore
    DROP ROLE user1;
    GRANT ALL ON LARGE OBJECT :loid TO user2;

The fixed version shows:

    lo=> select * from pg_largeobject_metadata;
     lomowner |                  lomacl
    ----------+------------------------------------------
           10 | {postgres=rw/postgres,user2=rw/postgres}
    (1 row)

In the broken version, 'user2' was a raw oid, obviously wrong.

Fortunately this was found during my testing and not reported as a bug
by a pg_upgrade user.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +
diff --git a/contrib/pg_upgrade/dump.c b/contrib/pg_upgrade/dump.c
index 52ab481..aba95f4 100644
*** /tmp/pgdiff.20347/YPWaqb_dump.c    Wed Jan  5 20:52:07 2011
--- contrib/pg_upgrade/dump.c    Wed Jan  5 20:43:29 2011
*************** generate_old_dump(void)
*** 33,39 ****
   *
   *    This function splits pg_dumpall output into global values and
   *    database creation, and per-db schemas.    This allows us to create
!  *    the toast place holders between restoring these two parts of the
   *    dump.  We split on the first "\connect " after a CREATE ROLE
   *    username match;  this is where the per-db restore starts.
   *
--- 33,39 ----
   *
   *    This function splits pg_dumpall output into global values and
   *    database creation, and per-db schemas.    This allows us to create
!  *    the support functions between restoring these two parts of the
   *    dump.  We split on the first "\connect " after a CREATE ROLE
   *    username match;  this is where the per-db restore starts.
   *
diff --git a/contrib/pg_upgrade/function.c b/contrib/pg_upgrade/function.c
index 2ab8e4f..5675551 100644
*** /tmp/pgdiff.20347/QpVBHa_function.c    Wed Jan  5 20:52:07 2011
--- contrib/pg_upgrade/function.c    Wed Jan  5 20:26:33 2011
***************
*** 13,35 ****


  /*
!  * install_support_functions()
   *
   * pg_upgrade requires some support functions that enable it to modify
   * backend behavior.
   */
  void
! install_support_functions(void)
  {
!     int            dbnum;
!
!     prep_status("Adding support functions to new cluster");
!
!     for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
!     {
!         DbInfo       *new_db = &new_cluster.dbarr.dbs[dbnum];
!         PGconn       *conn = connectToServer(&new_cluster, new_db->db_name);
!
          /* suppress NOTICE of dropped objects */
          PQclear(executeQueryOrDie(conn,
                                    "SET client_min_messages = warning;"));
--- 13,28 ----


  /*
!  * install_db_support_functions()
   *
   * pg_upgrade requires some support functions that enable it to modify
   * backend behavior.
   */
  void
! install_db_support_functions(const char *db_name)
  {
!         PGconn *conn = connectToServer(&new_cluster, db_name);
!
          /* suppress NOTICE of dropped objects */
          PQclear(executeQueryOrDie(conn,
                                    "SET client_min_messages = warning;"));
*************** install_support_functions(void)
*** 83,91 ****
                                    "RETURNS VOID "
                                    "AS '$libdir/pg_upgrade_support' "
                                    "LANGUAGE C STRICT;"));
          PQfinish(conn);
-     }
-     check_ok();
  }


--- 76,88 ----
                                    "RETURNS VOID "
                                    "AS '$libdir/pg_upgrade_support' "
                                    "LANGUAGE C STRICT;"));
+         PQclear(executeQueryOrDie(conn,
+                                   "CREATE OR REPLACE FUNCTION "
+              "        binary_upgrade.set_next_pg_authid_oid(OID) "
+                                   "RETURNS VOID "
+                                   "AS '$libdir/pg_upgrade_support' "
+                                   "LANGUAGE C STRICT;"));
          PQfinish(conn);
  }


diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c
index 578bdb9..339849d 100644
*** /tmp/pgdiff.20347/6HSV7d_info.c    Wed Jan  5 20:52:07 2011
--- contrib/pg_upgrade/info.c    Wed Jan  5 20:17:46 2011
*************** get_rel_infos(ClusterInfo *cluster, DbIn
*** 282,288 ****
               "    ON c.relnamespace = n.oid "
               "   LEFT OUTER JOIN pg_catalog.pg_tablespace t "
               "    ON c.reltablespace = t.oid "
!              "WHERE (( n.nspname NOT IN ('pg_catalog', 'information_schema') "
               "    AND c.oid >= %u "
               "    ) OR ( "
               "    n.nspname = 'pg_catalog' "
--- 282,288 ----
               "    ON c.relnamespace = n.oid "
               "   LEFT OUTER JOIN pg_catalog.pg_tablespace t "
               "    ON c.reltablespace = t.oid "
!              "WHERE (( n.nspname NOT IN ('pg_catalog', 'information_schema', 'binary_upgrade') "
               "    AND c.oid >= %u "
               "    ) OR ( "
               "    n.nspname = 'pg_catalog' "
diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c
index 64fb8f8..fe7b3db 100644
*** /tmp/pgdiff.20347/2pEOVc_pg_upgrade.c    Wed Jan  5 20:52:07 2011
--- contrib/pg_upgrade/pg_upgrade.c    Wed Jan  5 20:49:07 2011
*************** prepare_new_databases(void)
*** 195,205 ****

      set_frozenxids();

      /*
!      * We have to create the databases first so we can create the toast table
!      * placeholder relfiles.
       */
-     prep_status("Creating databases in the new cluster");
      exec_prog(true,
                SYSTEMQUOTE "\"%s/psql\" --set ON_ERROR_STOP=on "
      /* --no-psqlrc prevents AUTOCOMMIT=off */
--- 195,209 ----

      set_frozenxids();

+     prep_status("Creating databases in the new cluster");
+
+     /* install support functions in the database used by GLOBALS_DUMP_FILE */
+     install_db_support_functions(os_info.user);
+
      /*
!      * We have to create the databases first so we can install support
!      * functions in all the other databases.
       */
      exec_prog(true,
                SYSTEMQUOTE "\"%s/psql\" --set ON_ERROR_STOP=on "
      /* --no-psqlrc prevents AUTOCOMMIT=off */
*************** prepare_new_databases(void)
*** 218,227 ****
  static void
  create_new_objects(void)
  {
      /* -- NEW -- */
      start_postmaster(&new_cluster, false);

!     install_support_functions();

      prep_status("Restoring database schema to new cluster");
      exec_prog(true,
--- 222,241 ----
  static void
  create_new_objects(void)
  {
+     int            dbnum;
+
      /* -- NEW -- */
      start_postmaster(&new_cluster, false);

!     prep_status("Adding support functions to new cluster");
!
!     for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
!     {
!         DbInfo       *new_db = &new_cluster.dbarr.dbs[dbnum];
!
!         install_db_support_functions(new_db->db_name);
!     }
!     check_ok();

      prep_status("Restoring database schema to new cluster");
      exec_prog(true,
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
index d863155..ef2cdff 100644
*** /tmp/pgdiff.20347/gzDtFb_pg_upgrade.h    Wed Jan  5 20:52:07 2011
--- contrib/pg_upgrade/pg_upgrade.h    Wed Jan  5 20:32:45 2011
*************** void        check_hard_link(void);
*** 324,330 ****

  /* function.c */

! void        install_support_functions(void);
  void        uninstall_support_functions(void);
  void        get_loadable_libraries(void);
  void        check_loadable_libraries(void);
--- 324,330 ----

  /* function.c */

! void        install_db_support_functions(const char *db_name);
  void        uninstall_support_functions(void);
  void        get_loadable_libraries(void);
  void        check_loadable_libraries(void);
diff --git a/contrib/pg_upgrade_support/pg_upgrade_support.c b/contrib/pg_upgrade_support/pg_upgrade_support.c
index e55e139..31c2b4e 100644
*** /tmp/pgdiff.20347/szwF0a_pg_upgrade_support.c    Wed Jan  5 20:52:07 2011
--- contrib/pg_upgrade_support/pg_upgrade_support.c    Wed Jan  5 20:17:46 2011
*************** extern PGDLLIMPORT Oid binary_upgrade_ne
*** 27,32 ****
--- 27,33 ----
  extern PGDLLIMPORT Oid binary_upgrade_next_toast_relfilenode;
  extern PGDLLIMPORT Oid binary_upgrade_next_index_relfilenode;
  extern PGDLLIMPORT Oid binary_upgrade_next_pg_enum_oid;
+ extern PGDLLIMPORT Oid binary_upgrade_next_pg_authid_oid;

  Datum        set_next_pg_type_oid(PG_FUNCTION_ARGS);
  Datum        set_next_pg_type_array_oid(PG_FUNCTION_ARGS);
*************** Datum        set_next_heap_relfilenode(PG_FUNC
*** 35,40 ****
--- 36,42 ----
  Datum        set_next_toast_relfilenode(PG_FUNCTION_ARGS);
  Datum        set_next_index_relfilenode(PG_FUNCTION_ARGS);
  Datum        set_next_pg_enum_oid(PG_FUNCTION_ARGS);
+ Datum        set_next_pg_authid_oid(PG_FUNCTION_ARGS);

  PG_FUNCTION_INFO_V1(set_next_pg_type_oid);
  PG_FUNCTION_INFO_V1(set_next_pg_type_array_oid);
*************** PG_FUNCTION_INFO_V1(set_next_heap_relfil
*** 43,48 ****
--- 45,51 ----
  PG_FUNCTION_INFO_V1(set_next_toast_relfilenode);
  PG_FUNCTION_INFO_V1(set_next_index_relfilenode);
  PG_FUNCTION_INFO_V1(set_next_pg_enum_oid);
+ PG_FUNCTION_INFO_V1(set_next_pg_authid_oid);

  Datum
  set_next_pg_type_oid(PG_FUNCTION_ARGS)
*************** set_next_pg_enum_oid(PG_FUNCTION_ARGS)
*** 113,115 ****
--- 116,128 ----

      PG_RETURN_VOID();
  }
+
+ Datum
+ set_next_pg_authid_oid(PG_FUNCTION_ARGS)
+ {
+     Oid            authoid = PG_GETARG_OID(0);
+
+     binary_upgrade_next_pg_authid_oid = authoid;
+     PG_RETURN_VOID();
+ }
+
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index be049cb..93bfd40 100644
*** /tmp/pgdiff.20347/AvSkle_user.c    Wed Jan  5 20:52:07 2011
--- src/backend/commands/user.c    Wed Jan  5 20:17:46 2011
***************
*** 35,40 ****
--- 35,43 ----
  #include "utils/syscache.h"
  #include "utils/tqual.h"

+ /* Kluge for upgrade-in-place support */
+ Oid            binary_upgrade_next_pg_authid_oid = InvalidOid;
+

  /* GUC parameter */
  extern bool Password_encryption;
*************** CreateRole(CreateRoleStmt *stmt)
*** 393,398 ****
--- 396,408 ----

      tuple = heap_form_tuple(pg_authid_dsc, new_record, new_record_nulls);

+     /* Use binary-upgrade override if applicable */
+     if (OidIsValid(binary_upgrade_next_pg_authid_oid))
+     {
+         HeapTupleSetOid(tuple, binary_upgrade_next_pg_authid_oid);
+         binary_upgrade_next_pg_authid_oid = InvalidOid;
+     }
+
      /*
       * Insert new record in the pg_authid table
       */
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 17a73b8..2928232 100644
*** /tmp/pgdiff.20347/aQpZrb_pg_dumpall.c    Wed Jan  5 20:52:07 2011
--- src/bin/pg_dump/pg_dumpall.c    Wed Jan  5 20:17:46 2011
*************** dumpRoles(PGconn *conn)
*** 650,656 ****
  {
      PQExpBuffer buf = createPQExpBuffer();
      PGresult   *res;
!     int            i_rolname,
                  i_rolsuper,
                  i_rolinherit,
                  i_rolcreaterole,
--- 650,657 ----
  {
      PQExpBuffer buf = createPQExpBuffer();
      PGresult   *res;
!     int            i_oid,
!                 i_rolname,
                  i_rolsuper,
                  i_rolinherit,
                  i_rolcreaterole,
*************** dumpRoles(PGconn *conn)
*** 667,700 ****
      /* note: rolconfig is dumped later */
      if (server_version >= 90100)
          printfPQExpBuffer(buf,
!                           "SELECT rolname, rolsuper, rolinherit, "
                            "rolcreaterole, rolcreatedb, rolcatupdate, "
                            "rolcanlogin, rolconnlimit, rolpassword, "
                            "rolvaliduntil, rolreplication, "
                "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment "
                            "FROM pg_authid "
!                           "ORDER BY 1");
      else if (server_version >= 80200)
          printfPQExpBuffer(buf,
!                           "SELECT rolname, rolsuper, rolinherit, "
                            "rolcreaterole, rolcreatedb, rolcatupdate, "
                            "rolcanlogin, rolconnlimit, rolpassword, "
                            "rolvaliduntil, false as rolreplication, "
                "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment "
                            "FROM pg_authid "
!                           "ORDER BY 1");
      else if (server_version >= 80100)
          printfPQExpBuffer(buf,
!                           "SELECT rolname, rolsuper, rolinherit, "
                            "rolcreaterole, rolcreatedb, rolcatupdate, "
                            "rolcanlogin, rolconnlimit, rolpassword, "
                            "rolvaliduntil, false as rolreplication, "
                            "null as rolcomment "
                            "FROM pg_authid "
!                           "ORDER BY 1");
      else
          printfPQExpBuffer(buf,
!                           "SELECT usename as rolname, "
                            "usesuper as rolsuper, "
                            "true as rolinherit, "
                            "usesuper as rolcreaterole, "
--- 668,701 ----
      /* note: rolconfig is dumped later */
      if (server_version >= 90100)
          printfPQExpBuffer(buf,
!                           "SELECT oid, rolname, rolsuper, rolinherit, "
                            "rolcreaterole, rolcreatedb, rolcatupdate, "
                            "rolcanlogin, rolconnlimit, rolpassword, "
                            "rolvaliduntil, rolreplication, "
                "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment "
                            "FROM pg_authid "
!                           "ORDER BY 2");
      else if (server_version >= 80200)
          printfPQExpBuffer(buf,
!                           "SELECT oid, rolname, rolsuper, rolinherit, "
                            "rolcreaterole, rolcreatedb, rolcatupdate, "
                            "rolcanlogin, rolconnlimit, rolpassword, "
                            "rolvaliduntil, false as rolreplication, "
                "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment "
                            "FROM pg_authid "
!                           "ORDER BY 2");
      else if (server_version >= 80100)
          printfPQExpBuffer(buf,
!                           "SELECT oid, rolname, rolsuper, rolinherit, "
                            "rolcreaterole, rolcreatedb, rolcatupdate, "
                            "rolcanlogin, rolconnlimit, rolpassword, "
                            "rolvaliduntil, false as rolreplication, "
                            "null as rolcomment "
                            "FROM pg_authid "
!                           "ORDER BY 2");
      else
          printfPQExpBuffer(buf,
!                           "SELECT 0, usename as rolname, "
                            "usesuper as rolsuper, "
                            "true as rolinherit, "
                            "usesuper as rolcreaterole, "
*************** dumpRoles(PGconn *conn)
*** 708,714 ****
                            "null as rolcomment "
                            "FROM pg_shadow "
                            "UNION ALL "
!                           "SELECT groname as rolname, "
                            "false as rolsuper, "
                            "true as rolinherit, "
                            "false as rolcreaterole, "
--- 709,715 ----
                            "null as rolcomment "
                            "FROM pg_shadow "
                            "UNION ALL "
!                           "SELECT 0, groname as rolname, "
                            "false as rolsuper, "
                            "true as rolinherit, "
                            "false as rolcreaterole, "
*************** dumpRoles(PGconn *conn)
*** 723,732 ****
                            "FROM pg_group "
                            "WHERE NOT EXISTS (SELECT 1 FROM pg_shadow "
                            " WHERE usename = groname) "
!                           "ORDER BY 1");

      res = executeQuery(conn, buf->data);

      i_rolname = PQfnumber(res, "rolname");
      i_rolsuper = PQfnumber(res, "rolsuper");
      i_rolinherit = PQfnumber(res, "rolinherit");
--- 724,734 ----
                            "FROM pg_group "
                            "WHERE NOT EXISTS (SELECT 1 FROM pg_shadow "
                            " WHERE usename = groname) "
!                           "ORDER BY 2");

      res = executeQuery(conn, buf->data);

+     i_oid = PQfnumber(res, "oid");
      i_rolname = PQfnumber(res, "rolname");
      i_rolsuper = PQfnumber(res, "rolsuper");
      i_rolinherit = PQfnumber(res, "rolinherit");
*************** dumpRoles(PGconn *conn)
*** 751,756 ****
--- 753,768 ----

          resetPQExpBuffer(buf);

+         if (binary_upgrade)
+         {
+             Oid            auth_oid = atooid(PQgetvalue(res, i, i_oid));
+
+             appendPQExpBuffer(buf, "\n-- For binary upgrade, must preserve pg_authid.oid\n");
+             appendPQExpBuffer(buf,
+              "SELECT binary_upgrade.set_next_pg_authid_oid('%u'::pg_catalog.oid);\n\n",
+                               auth_oid);
+         }
+
          /*
           * We dump CREATE ROLE followed by ALTER ROLE to ensure that the role
           * will acquire the right properties even if it already exists (ie, it

Re: Fix for pg_upgrade migrating pg_largeobject_metadata

From
Bruce Momjian
Date:
Patch applied.

I did not backpatch to 9.0 because you can't migrate from 9.0 to 9.0
with the same catversion (because of tablespace conflict), and a pre-9.0
migration to 9.0 has not large object permissions to migrate.  In
summary, it didn't seem worth the risk, and was hard to test.

---------------------------------------------------------------------------

Bruce Momjian wrote:
> Bruce Momjian wrote:
> > Tom Lane wrote:
> > > Bruce Momjian <bruce@momjian.us> writes:
> > > > Tom Lane wrote:
> > > >> That isn't going to work.  At least not unless you start trying to force
> > > >> roles to have the same OIDs in the new installation.
> > > 
> > > > If so I can use the CREATE ROLE ... SYSID clause when doing a binary
> > > > upgrade.
> > > 
> > > Oh, I had forgotten we still had that wart in the grammar.
> > > It doesn't actually work:
> > > 
> > >         else if (strcmp(defel->defname, "sysid") == 0)
> > >         {
> > >             ereport(NOTICE,
> > >                     (errmsg("SYSID can no longer be specified")));
> > >         }
> > > 
> > > Not sure if it's better to try to make that work again than to add
> > > another hack in pg_upgrade_support.  On the whole that's a keyword
> > > I'd rather see us drop someday soon.
> > 
> > OK, let me work on adding it to pg_upgrade_support.  Glad you saw this.
> 
> I have fixed the bug by using pg_upgrade_support.  It was a little
> complicated because you need to install the pg_upgrade_support functions
> in the super-user database so it is available when you create the users
> in the first step of restoring the pg_dumpall file.
> 
> I am afraid we have to batckpatch this to fix to 9.0 for 9.0 to 9.0
> upgrades.  It does not apply when coming from pre-9.0 because there was
> no pg_largeobject_metadata.
> 
> For testing I did this:
> 
>     CREATE DATABASE lo;
>     \c lo
>     SELECT lo_import('/etc/motd');
>     \set loid `psql -qt -c 'select loid from pg_largeobject' lo`
>     CREATE ROLE user1;
>     CREATE ROLE user2;
>     -- force user2 to have a different user id on restore
>     DROP ROLE user1;
>     GRANT ALL ON LARGE OBJECT :loid TO user2;
> 
> The fixed version shows:
> 
>     lo=> select * from pg_largeobject_metadata;
>      lomowner |                  lomacl
>     ----------+------------------------------------------
>            10 | {postgres=rw/postgres,user2=rw/postgres}
>     (1 row)
> 
> In the broken version, 'user2' was a raw oid, obviously wrong.
> 
> Fortunately this was found during my testing and not reported as a bug
> by a pg_upgrade user.

--  Bruce Momjian  <bruce@momjian.us>        http://momjian.us EnterpriseDB
http://enterprisedb.com
 + It's impossible for everything to be true. +