pg_upgrade patches applied - Mailing list pgsql-hackers

From Bruce Momjian
Subject pg_upgrade patches applied
Date
Msg-id 201101051408.p05E8nu19834@momjian.us
Whole thread Raw
Responses Re: pg_upgrade patches applied  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
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'");

pgsql-hackers by date:

Previous
From: Robert Haas
Date:
Subject: Re: WIP: Range Types
Next
From: Pavel Stehule
Date:
Subject: Re: Support for negative index values in array fetching