LCOV - code coverage report
Current view: top level - src/bin/pg_upgrade - check.c (source / functions) Hit Total Coverage
Test: PostgreSQL 15devel Lines: 192 452 42.5 %
Date: 2021-12-09 03:08:47 Functions: 21 27 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  check.c
       3             :  *
       4             :  *  server checks and output routines
       5             :  *
       6             :  *  Copyright (c) 2010-2021, PostgreSQL Global Development Group
       7             :  *  src/bin/pg_upgrade/check.c
       8             :  */
       9             : 
      10             : #include "postgres_fe.h"
      11             : 
      12             : #include "catalog/pg_authid_d.h"
      13             : #include "fe_utils/string_utils.h"
      14             : #include "mb/pg_wchar.h"
      15             : #include "pg_upgrade.h"
      16             : 
      17             : static void check_new_cluster_is_empty(void);
      18             : static void check_databases_are_compatible(void);
      19             : static void check_locale_and_encoding(DbInfo *olddb, DbInfo *newdb);
      20             : static bool equivalent_locale(int category, const char *loca, const char *locb);
      21             : static void check_is_install_user(ClusterInfo *cluster);
      22             : static void check_proper_datallowconn(ClusterInfo *cluster);
      23             : static void check_for_prepared_transactions(ClusterInfo *cluster);
      24             : static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
      25             : static void check_for_user_defined_postfix_ops(ClusterInfo *cluster);
      26             : static void check_for_tables_with_oids(ClusterInfo *cluster);
      27             : static void check_for_composite_data_type_usage(ClusterInfo *cluster);
      28             : static void check_for_reg_data_type_usage(ClusterInfo *cluster);
      29             : static void check_for_jsonb_9_4_usage(ClusterInfo *cluster);
      30             : static void check_for_pg_role_prefix(ClusterInfo *cluster);
      31             : static void check_for_new_tablespace_dir(ClusterInfo *new_cluster);
      32             : static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster);
      33             : static char *get_canonical_locale_name(int category, const char *locale);
      34             : 
      35             : 
      36             : /*
      37             :  * fix_path_separator
      38             :  * For non-Windows, just return the argument.
      39             :  * For Windows convert any forward slash to a backslash
      40             :  * such as is suitable for arguments to builtin commands
      41             :  * like RMDIR and DEL.
      42             :  */
      43             : static char *
      44           2 : fix_path_separator(char *path)
      45             : {
      46             : #ifdef WIN32
      47             : 
      48             :     char       *result;
      49             :     char       *c;
      50             : 
      51             :     result = pg_strdup(path);
      52             : 
      53             :     for (c = result; *c != '\0'; c++)
      54             :         if (*c == '/')
      55             :             *c = '\\';
      56             : 
      57             :     return result;
      58             : #else
      59             : 
      60           2 :     return path;
      61             : #endif
      62             : }
      63             : 
      64             : void
      65           2 : output_check_banner(bool live_check)
      66             : {
      67           2 :     if (user_opts.check && live_check)
      68             :     {
      69           0 :         pg_log(PG_REPORT,
      70             :                "Performing Consistency Checks on Old Live Server\n"
      71             :                "------------------------------------------------\n");
      72             :     }
      73             :     else
      74             :     {
      75           2 :         pg_log(PG_REPORT,
      76             :                "Performing Consistency Checks\n"
      77             :                "-----------------------------\n");
      78             :     }
      79           2 : }
      80             : 
      81             : 
      82             : void
      83           2 : check_and_dump_old_cluster(bool live_check)
      84             : {
      85             :     /* -- OLD -- */
      86             : 
      87           2 :     if (!live_check)
      88           2 :         start_postmaster(&old_cluster, true);
      89             : 
      90             :     /* Extract a list of databases and tables from the old cluster */
      91           2 :     get_db_and_rel_infos(&old_cluster);
      92             : 
      93           2 :     init_tablespaces();
      94             : 
      95           2 :     get_loadable_libraries();
      96             : 
      97             : 
      98             :     /*
      99             :      * Check for various failure cases
     100             :      */
     101           2 :     check_is_install_user(&old_cluster);
     102           2 :     check_proper_datallowconn(&old_cluster);
     103           2 :     check_for_prepared_transactions(&old_cluster);
     104           2 :     check_for_composite_data_type_usage(&old_cluster);
     105           2 :     check_for_reg_data_type_usage(&old_cluster);
     106           2 :     check_for_isn_and_int8_passing_mismatch(&old_cluster);
     107             : 
     108             :     /*
     109             :      * PG 14 changed the function signature of encoding conversion functions.
     110             :      * Conversions from older versions cannot be upgraded automatically
     111             :      * because the user-defined functions used by the encoding conversions
     112             :      * need to be changed to match the new signature.
     113             :      */
     114           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1300)
     115           0 :         check_for_user_defined_encoding_conversions(&old_cluster);
     116             : 
     117             :     /*
     118             :      * Pre-PG 14 allowed user defined postfix operators, which are not
     119             :      * supported anymore.  Verify there are none, iff applicable.
     120             :      */
     121           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1300)
     122           0 :         check_for_user_defined_postfix_ops(&old_cluster);
     123             : 
     124             :     /*
     125             :      * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
     126             :      * supported anymore. Verify there are none, iff applicable.
     127             :      */
     128           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1100)
     129           0 :         check_for_tables_with_oids(&old_cluster);
     130             : 
     131             :     /*
     132             :      * PG 12 changed the 'sql_identifier' type storage to be based on name,
     133             :      * not varchar, which breaks on-disk format for existing data. So we need
     134             :      * to prevent upgrade when used in user objects (tables, indexes, ...).
     135             :      */
     136           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1100)
     137           0 :         old_11_check_for_sql_identifier_data_type_usage(&old_cluster);
     138             : 
     139             :     /*
     140             :      * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
     141             :      * hash indexes
     142             :      */
     143           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) <= 906)
     144             :     {
     145           0 :         old_9_6_check_for_unknown_data_type_usage(&old_cluster);
     146           0 :         if (user_opts.check)
     147           0 :             old_9_6_invalidate_hash_indexes(&old_cluster, true);
     148             :     }
     149             : 
     150             :     /* 9.5 and below should not have roles starting with pg_ */
     151           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) <= 905)
     152           0 :         check_for_pg_role_prefix(&old_cluster);
     153             : 
     154           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) == 904 &&
     155           0 :         old_cluster.controldata.cat_ver < JSONB_FORMAT_CHANGE_CAT_VER)
     156           0 :         check_for_jsonb_9_4_usage(&old_cluster);
     157             : 
     158             :     /* Pre-PG 9.4 had a different 'line' data type internal format */
     159           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) <= 903)
     160           0 :         old_9_3_check_for_line_data_type_usage(&old_cluster);
     161             : 
     162             :     /* Pre-PG 9.0 had no large object permissions */
     163           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
     164           0 :         new_9_0_populate_pg_largeobject_metadata(&old_cluster, true);
     165             : 
     166             :     /*
     167             :      * While not a check option, we do this now because this is the only time
     168             :      * the old server is running.
     169             :      */
     170           2 :     if (!user_opts.check)
     171           2 :         generate_old_dump();
     172             : 
     173           2 :     if (!live_check)
     174           2 :         stop_postmaster(false);
     175           2 : }
     176             : 
     177             : 
     178             : void
     179           2 : check_new_cluster(void)
     180             : {
     181           2 :     get_db_and_rel_infos(&new_cluster);
     182             : 
     183           2 :     check_new_cluster_is_empty();
     184           2 :     check_databases_are_compatible();
     185             : 
     186           2 :     check_loadable_libraries();
     187             : 
     188           2 :     switch (user_opts.transfer_mode)
     189             :     {
     190           0 :         case TRANSFER_MODE_CLONE:
     191           0 :             check_file_clone();
     192           0 :             break;
     193           2 :         case TRANSFER_MODE_COPY:
     194           2 :             break;
     195           0 :         case TRANSFER_MODE_LINK:
     196           0 :             check_hard_link();
     197           0 :             break;
     198             :     }
     199             : 
     200           2 :     check_is_install_user(&new_cluster);
     201             : 
     202           2 :     check_for_prepared_transactions(&new_cluster);
     203             : 
     204           2 :     check_for_new_tablespace_dir(&new_cluster);
     205           2 : }
     206             : 
     207             : 
     208             : void
     209           2 : report_clusters_compatible(void)
     210             : {
     211           2 :     if (user_opts.check)
     212             :     {
     213           0 :         pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
     214             :         /* stops new cluster */
     215           0 :         stop_postmaster(false);
     216           0 :         exit(0);
     217             :     }
     218             : 
     219           2 :     pg_log(PG_REPORT, "\n"
     220             :            "If pg_upgrade fails after this point, you must re-initdb the\n"
     221             :            "new cluster before continuing.\n");
     222           2 : }
     223             : 
     224             : 
     225             : void
     226           2 : issue_warnings_and_set_wal_level(void)
     227             : {
     228             :     /*
     229             :      * We unconditionally start/stop the new server because pg_resetwal -o set
     230             :      * wal_level to 'minimum'.  If the user is upgrading standby servers using
     231             :      * the rsync instructions, they will need pg_upgrade to write its final
     232             :      * WAL record showing wal_level as 'replica'.
     233             :      */
     234           2 :     start_postmaster(&new_cluster, true);
     235             : 
     236             :     /* Create dummy large object permissions for old < PG 9.0? */
     237           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
     238           0 :         new_9_0_populate_pg_largeobject_metadata(&new_cluster, false);
     239             : 
     240             :     /* Reindex hash indexes for old < 10.0 */
     241           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) <= 906)
     242           0 :         old_9_6_invalidate_hash_indexes(&new_cluster, false);
     243             : 
     244           2 :     report_extension_updates(&new_cluster);
     245             : 
     246           2 :     stop_postmaster(false);
     247           2 : }
     248             : 
     249             : 
     250             : void
     251           2 : output_completion_banner(char *deletion_script_file_name)
     252             : {
     253             :     PQExpBufferData user_specification;
     254             : 
     255           2 :     initPQExpBuffer(&user_specification);
     256           2 :     if (os_info.user_specified)
     257             :     {
     258           0 :         appendPQExpBufferStr(&user_specification, "-U ");
     259           0 :         appendShellString(&user_specification, os_info.user);
     260           0 :         appendPQExpBufferChar(&user_specification, ' ');
     261             :     }
     262             : 
     263           2 :     pg_log(PG_REPORT,
     264             :            "Optimizer statistics are not transferred by pg_upgrade.\n"
     265             :            "Once you start the new server, consider running:\n"
     266             :            "    %s/vacuumdb %s--all --analyze-in-stages\n\n", new_cluster.bindir, user_specification.data);
     267             : 
     268           2 :     if (deletion_script_file_name)
     269           2 :         pg_log(PG_REPORT,
     270             :                "Running this script will delete the old cluster's data files:\n"
     271             :                "    %s\n",
     272             :                deletion_script_file_name);
     273             :     else
     274           0 :         pg_log(PG_REPORT,
     275             :                "Could not create a script to delete the old cluster's data files\n"
     276             :                "because user-defined tablespaces or the new cluster's data directory\n"
     277             :                "exist in the old cluster directory.  The old cluster's contents must\n"
     278             :                "be deleted manually.\n");
     279             : 
     280           2 :     termPQExpBuffer(&user_specification);
     281           2 : }
     282             : 
     283             : 
     284             : void
     285           2 : check_cluster_versions(void)
     286             : {
     287           2 :     prep_status("Checking cluster versions");
     288             : 
     289             :     /* cluster versions should already have been obtained */
     290             :     Assert(old_cluster.major_version != 0);
     291             :     Assert(new_cluster.major_version != 0);
     292             : 
     293             :     /*
     294             :      * We allow upgrades from/to the same major version for alpha/beta
     295             :      * upgrades
     296             :      */
     297             : 
     298           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) < 804)
     299           0 :         pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n");
     300             : 
     301             :     /* Only current PG version is supported as a target */
     302           2 :     if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM))
     303           0 :         pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
     304             :                  PG_MAJORVERSION);
     305             : 
     306             :     /*
     307             :      * We can't allow downgrading because we use the target pg_dump, and
     308             :      * pg_dump cannot operate on newer database versions, only current and
     309             :      * older versions.
     310             :      */
     311           2 :     if (old_cluster.major_version > new_cluster.major_version)
     312           0 :         pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
     313             : 
     314             :     /* Ensure binaries match the designated data directories */
     315           2 :     if (GET_MAJOR_VERSION(old_cluster.major_version) !=
     316           2 :         GET_MAJOR_VERSION(old_cluster.bin_version))
     317           0 :         pg_fatal("Old cluster data and binary directories are from different major versions.\n");
     318           2 :     if (GET_MAJOR_VERSION(new_cluster.major_version) !=
     319           2 :         GET_MAJOR_VERSION(new_cluster.bin_version))
     320           0 :         pg_fatal("New cluster data and binary directories are from different major versions.\n");
     321             : 
     322           2 :     check_ok();
     323           2 : }
     324             : 
     325             : 
     326             : void
     327           2 : check_cluster_compatibility(bool live_check)
     328             : {
     329             :     /* get/check pg_control data of servers */
     330           2 :     get_control_data(&old_cluster, live_check);
     331           2 :     get_control_data(&new_cluster, false);
     332           2 :     check_control_data(&old_cluster.controldata, &new_cluster.controldata);
     333             : 
     334             :     /* We read the real port number for PG >= 9.1 */
     335           2 :     if (live_check && GET_MAJOR_VERSION(old_cluster.major_version) <= 900 &&
     336           0 :         old_cluster.port == DEF_PGUPORT)
     337           0 :         pg_fatal("When checking a pre-PG 9.1 live old server, "
     338             :                  "you must specify the old server's port number.\n");
     339             : 
     340           2 :     if (live_check && old_cluster.port == new_cluster.port)
     341           0 :         pg_fatal("When checking a live server, "
     342             :                  "the old and new port numbers must be different.\n");
     343           2 : }
     344             : 
     345             : 
     346             : /*
     347             :  * check_locale_and_encoding()
     348             :  *
     349             :  * Check that locale and encoding of a database in the old and new clusters
     350             :  * are compatible.
     351             :  */
     352             : static void
     353           4 : check_locale_and_encoding(DbInfo *olddb, DbInfo *newdb)
     354             : {
     355           4 :     if (olddb->db_encoding != newdb->db_encoding)
     356           0 :         pg_fatal("encodings for database \"%s\" do not match:  old \"%s\", new \"%s\"\n",
     357             :                  olddb->db_name,
     358             :                  pg_encoding_to_char(olddb->db_encoding),
     359             :                  pg_encoding_to_char(newdb->db_encoding));
     360           4 :     if (!equivalent_locale(LC_COLLATE, olddb->db_collate, newdb->db_collate))
     361           0 :         pg_fatal("lc_collate values for database \"%s\" do not match:  old \"%s\", new \"%s\"\n",
     362             :                  olddb->db_name, olddb->db_collate, newdb->db_collate);
     363           4 :     if (!equivalent_locale(LC_CTYPE, olddb->db_ctype, newdb->db_ctype))
     364           0 :         pg_fatal("lc_ctype values for database \"%s\" do not match:  old \"%s\", new \"%s\"\n",
     365             :                  olddb->db_name, olddb->db_ctype, newdb->db_ctype);
     366           4 : }
     367             : 
     368             : /*
     369             :  * equivalent_locale()
     370             :  *
     371             :  * Best effort locale-name comparison.  Return false if we are not 100% sure
     372             :  * the locales are equivalent.
     373             :  *
     374             :  * Note: The encoding parts of the names are ignored. This function is
     375             :  * currently used to compare locale names stored in pg_database, and
     376             :  * pg_database contains a separate encoding field. That's compared directly
     377             :  * in check_locale_and_encoding().
     378             :  */
     379             : static bool
     380           8 : equivalent_locale(int category, const char *loca, const char *locb)
     381             : {
     382             :     const char *chara;
     383             :     const char *charb;
     384             :     char       *canona;
     385             :     char       *canonb;
     386             :     int         lena;
     387             :     int         lenb;
     388             : 
     389             :     /*
     390             :      * If the names are equal, the locales are equivalent. Checking this first
     391             :      * avoids calling setlocale() in the common case that the names are equal.
     392             :      * That's a good thing, if setlocale() is buggy, for example.
     393             :      */
     394           8 :     if (pg_strcasecmp(loca, locb) == 0)
     395           8 :         return true;
     396             : 
     397             :     /*
     398             :      * Not identical. Canonicalize both names, remove the encoding parts, and
     399             :      * try again.
     400             :      */
     401           0 :     canona = get_canonical_locale_name(category, loca);
     402           0 :     chara = strrchr(canona, '.');
     403           0 :     lena = chara ? (chara - canona) : strlen(canona);
     404             : 
     405           0 :     canonb = get_canonical_locale_name(category, locb);
     406           0 :     charb = strrchr(canonb, '.');
     407           0 :     lenb = charb ? (charb - canonb) : strlen(canonb);
     408             : 
     409           0 :     if (lena == lenb && pg_strncasecmp(canona, canonb, lena) == 0)
     410             :     {
     411           0 :         pg_free(canona);
     412           0 :         pg_free(canonb);
     413           0 :         return true;
     414             :     }
     415             : 
     416           0 :     pg_free(canona);
     417           0 :     pg_free(canonb);
     418           0 :     return false;
     419             : }
     420             : 
     421             : 
     422             : static void
     423           2 : check_new_cluster_is_empty(void)
     424             : {
     425             :     int         dbnum;
     426             : 
     427           6 :     for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
     428             :     {
     429             :         int         relnum;
     430           4 :         RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
     431             : 
     432          12 :         for (relnum = 0; relnum < rel_arr->nrels;
     433           8 :              relnum++)
     434             :         {
     435             :             /* pg_largeobject and its index should be skipped */
     436           8 :             if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
     437           0 :                 pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n",
     438           0 :                          new_cluster.dbarr.dbs[dbnum].db_name,
     439           0 :                          rel_arr->rels[relnum].nspname,
     440           0 :                          rel_arr->rels[relnum].relname);
     441             :         }
     442             :     }
     443           2 : }
     444             : 
     445             : /*
     446             :  * Check that every database that already exists in the new cluster is
     447             :  * compatible with the corresponding database in the old one.
     448             :  */
     449             : static void
     450           2 : check_databases_are_compatible(void)
     451             : {
     452             :     int         newdbnum;
     453             :     int         olddbnum;
     454             :     DbInfo     *newdbinfo;
     455             :     DbInfo     *olddbinfo;
     456             : 
     457           6 :     for (newdbnum = 0; newdbnum < new_cluster.dbarr.ndbs; newdbnum++)
     458             :     {
     459           4 :         newdbinfo = &new_cluster.dbarr.dbs[newdbnum];
     460             : 
     461             :         /* Find the corresponding database in the old cluster */
     462          14 :         for (olddbnum = 0; olddbnum < old_cluster.dbarr.ndbs; olddbnum++)
     463             :         {
     464          14 :             olddbinfo = &old_cluster.dbarr.dbs[olddbnum];
     465          14 :             if (strcmp(newdbinfo->db_name, olddbinfo->db_name) == 0)
     466             :             {
     467           4 :                 check_locale_and_encoding(olddbinfo, newdbinfo);
     468           4 :                 break;
     469             :             }
     470             :         }
     471             :     }
     472           2 : }
     473             : 
     474             : /*
     475             :  * A previous run of pg_upgrade might have failed and the new cluster
     476             :  * directory recreated, but they might have forgotten to remove
     477             :  * the new cluster's tablespace directories.  Therefore, check that
     478             :  * new cluster tablespace directories do not already exist.  If
     479             :  * they do, it would cause an error while restoring global objects.
     480             :  * This allows the failure to be detected at check time, rather than
     481             :  * during schema restore.
     482             :  *
     483             :  * Note, v8.4 has no tablespace_suffix, which is fine so long as the
     484             :  * version being upgraded *to* has a suffix, since it's not allowed
     485             :  * to pg_upgrade from a version to the same version if tablespaces are
     486             :  * in use.
     487             :  */
     488             : static void
     489           2 : check_for_new_tablespace_dir(ClusterInfo *new_cluster)
     490             : {
     491             :     int         tblnum;
     492             :     char        new_tablespace_dir[MAXPGPATH];
     493             : 
     494           2 :     prep_status("Checking for new cluster tablespace directories");
     495             : 
     496           2 :     for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
     497             :     {
     498             :         struct stat statbuf;
     499             : 
     500           0 :         snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
     501           0 :                  os_info.old_tablespaces[tblnum],
     502             :                  new_cluster->tablespace_suffix);
     503             : 
     504           0 :         if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
     505           0 :             pg_fatal("new cluster tablespace directory already exists: \"%s\"\n",
     506             :                      new_tablespace_dir);
     507             :     }
     508             : 
     509           2 :     check_ok();
     510           2 : }
     511             : 
     512             : /*
     513             :  * create_script_for_old_cluster_deletion()
     514             :  *
     515             :  *  This is particularly useful for tablespace deletion.
     516             :  */
     517             : void
     518           2 : create_script_for_old_cluster_deletion(char **deletion_script_file_name)
     519             : {
     520           2 :     FILE       *script = NULL;
     521             :     int         tblnum;
     522             :     char        old_cluster_pgdata[MAXPGPATH],
     523             :                 new_cluster_pgdata[MAXPGPATH];
     524             : 
     525           2 :     *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
     526             :                                           SCRIPT_PREFIX, SCRIPT_EXT);
     527             : 
     528           2 :     strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
     529           2 :     canonicalize_path(old_cluster_pgdata);
     530             : 
     531           2 :     strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
     532           2 :     canonicalize_path(new_cluster_pgdata);
     533             : 
     534             :     /* Some people put the new data directory inside the old one. */
     535           2 :     if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
     536             :     {
     537           0 :         pg_log(PG_WARNING,
     538             :                "\nWARNING:  new data directory should not be inside the old data directory, e.g. %s\n", old_cluster_pgdata);
     539             : 
     540             :         /* Unlink file in case it is left over from a previous run. */
     541           0 :         unlink(*deletion_script_file_name);
     542           0 :         pg_free(*deletion_script_file_name);
     543           0 :         *deletion_script_file_name = NULL;
     544           0 :         return;
     545             :     }
     546             : 
     547             :     /*
     548             :      * Some users (oddly) create tablespaces inside the cluster data
     549             :      * directory.  We can't create a proper old cluster delete script in that
     550             :      * case.
     551             :      */
     552           2 :     for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
     553             :     {
     554             :         char        old_tablespace_dir[MAXPGPATH];
     555             : 
     556           0 :         strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
     557           0 :         canonicalize_path(old_tablespace_dir);
     558           0 :         if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
     559             :         {
     560             :             /* reproduce warning from CREATE TABLESPACE that is in the log */
     561           0 :             pg_log(PG_WARNING,
     562             :                    "\nWARNING:  user-defined tablespace locations should not be inside the data directory, e.g. %s\n", old_tablespace_dir);
     563             : 
     564             :             /* Unlink file in case it is left over from a previous run. */
     565           0 :             unlink(*deletion_script_file_name);
     566           0 :             pg_free(*deletion_script_file_name);
     567           0 :             *deletion_script_file_name = NULL;
     568           0 :             return;
     569             :         }
     570             :     }
     571             : 
     572           2 :     prep_status("Creating script to delete old cluster");
     573             : 
     574           2 :     if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
     575           0 :         pg_fatal("could not open file \"%s\": %s\n",
     576           0 :                  *deletion_script_file_name, strerror(errno));
     577             : 
     578             : #ifndef WIN32
     579             :     /* add shebang header */
     580           2 :     fprintf(script, "#!/bin/sh\n\n");
     581             : #endif
     582             : 
     583             :     /* delete old cluster's default tablespace */
     584           2 :     fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
     585             :             fix_path_separator(old_cluster.pgdata), PATH_QUOTE);
     586             : 
     587             :     /* delete old cluster's alternate tablespaces */
     588           2 :     for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
     589             :     {
     590             :         /*
     591             :          * Do the old cluster's per-database directories share a directory
     592             :          * with a new version-specific tablespace?
     593             :          */
     594           0 :         if (strlen(old_cluster.tablespace_suffix) == 0)
     595             :         {
     596             :             /* delete per-database directories */
     597             :             int         dbnum;
     598             : 
     599           0 :             fprintf(script, "\n");
     600             :             /* remove PG_VERSION? */
     601           0 :             if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
     602           0 :                 fprintf(script, RM_CMD " %s%cPG_VERSION\n",
     603           0 :                         fix_path_separator(os_info.old_tablespaces[tblnum]),
     604             :                         PATH_SEPARATOR);
     605             : 
     606           0 :             for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
     607           0 :                 fprintf(script, RMDIR_CMD " %c%s%c%u%c\n", PATH_QUOTE,
     608           0 :                         fix_path_separator(os_info.old_tablespaces[tblnum]),
     609           0 :                         PATH_SEPARATOR, old_cluster.dbarr.dbs[dbnum].db_oid,
     610             :                         PATH_QUOTE);
     611             :         }
     612             :         else
     613             :         {
     614           0 :             char       *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
     615             : 
     616             :             /*
     617             :              * Simply delete the tablespace directory, which might be ".old"
     618             :              * or a version-specific subdirectory.
     619             :              */
     620           0 :             fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
     621           0 :                     fix_path_separator(os_info.old_tablespaces[tblnum]),
     622             :                     fix_path_separator(suffix_path), PATH_QUOTE);
     623           0 :             pfree(suffix_path);
     624             :         }
     625             :     }
     626             : 
     627           2 :     fclose(script);
     628             : 
     629             : #ifndef WIN32
     630           2 :     if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
     631           0 :         pg_fatal("could not add execute permission to file \"%s\": %s\n",
     632           0 :                  *deletion_script_file_name, strerror(errno));
     633             : #endif
     634             : 
     635           2 :     check_ok();
     636             : }
     637             : 
     638             : 
     639             : /*
     640             :  *  check_is_install_user()
     641             :  *
     642             :  *  Check we are the install user, and that the new cluster
     643             :  *  has no other users.
     644             :  */
     645             : static void
     646           4 : check_is_install_user(ClusterInfo *cluster)
     647             : {
     648             :     PGresult   *res;
     649           4 :     PGconn     *conn = connectToServer(cluster, "template1");
     650             : 
     651           4 :     prep_status("Checking database user is the install user");
     652             : 
     653             :     /* Can't use pg_authid because only superusers can view it. */
     654           4 :     res = executeQueryOrDie(conn,
     655             :                             "SELECT rolsuper, oid "
     656             :                             "FROM pg_catalog.pg_roles "
     657             :                             "WHERE rolname = current_user "
     658             :                             "AND rolname !~ '^pg_'");
     659             : 
     660             :     /*
     661             :      * We only allow the install user in the new cluster (see comment below)
     662             :      * and we preserve pg_authid.oid, so this must be the install user in the
     663             :      * old cluster too.
     664             :      */
     665           4 :     if (PQntuples(res) != 1 ||
     666           4 :         atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
     667           0 :         pg_fatal("database user \"%s\" is not the install user\n",
     668             :                  os_info.user);
     669             : 
     670           4 :     PQclear(res);
     671             : 
     672           4 :     res = executeQueryOrDie(conn,
     673             :                             "SELECT COUNT(*) "
     674             :                             "FROM pg_catalog.pg_roles "
     675             :                             "WHERE rolname !~ '^pg_'");
     676             : 
     677           4 :     if (PQntuples(res) != 1)
     678           0 :         pg_fatal("could not determine the number of users\n");
     679             : 
     680             :     /*
     681             :      * We only allow the install user in the new cluster because other defined
     682             :      * users might match users defined in the old cluster and generate an
     683             :      * error during pg_dump restore.
     684             :      */
     685           4 :     if (cluster == &new_cluster && atooid(PQgetvalue(res, 0, 0)) != 1)
     686           0 :         pg_fatal("Only the install user can be defined in the new cluster.\n");
     687             : 
     688           4 :     PQclear(res);
     689             : 
     690           4 :     PQfinish(conn);
     691             : 
     692           4 :     check_ok();
     693           4 : }
     694             : 
     695             : 
     696             : static void
     697           2 : check_proper_datallowconn(ClusterInfo *cluster)
     698             : {
     699             :     int         dbnum;
     700             :     PGconn     *conn_template1;
     701             :     PGresult   *dbres;
     702             :     int         ntups;
     703             :     int         i_datname;
     704             :     int         i_datallowconn;
     705             : 
     706           2 :     prep_status("Checking database connection settings");
     707             : 
     708           2 :     conn_template1 = connectToServer(cluster, "template1");
     709             : 
     710             :     /* get database names */
     711           2 :     dbres = executeQueryOrDie(conn_template1,
     712             :                               "SELECT  datname, datallowconn "
     713             :                               "FROM    pg_catalog.pg_database");
     714             : 
     715           2 :     i_datname = PQfnumber(dbres, "datname");
     716           2 :     i_datallowconn = PQfnumber(dbres, "datallowconn");
     717             : 
     718           2 :     ntups = PQntuples(dbres);
     719          16 :     for (dbnum = 0; dbnum < ntups; dbnum++)
     720             :     {
     721          14 :         char       *datname = PQgetvalue(dbres, dbnum, i_datname);
     722          14 :         char       *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
     723             : 
     724          14 :         if (strcmp(datname, "template0") == 0)
     725             :         {
     726             :             /* avoid restore failure when pg_dumpall tries to create template0 */
     727           2 :             if (strcmp(datallowconn, "t") == 0)
     728           0 :                 pg_fatal("template0 must not allow connections, "
     729             :                          "i.e. its pg_database.datallowconn must be false\n");
     730             :         }
     731             :         else
     732             :         {
     733             :             /*
     734             :              * avoid datallowconn == false databases from being skipped on
     735             :              * restore
     736             :              */
     737          12 :             if (strcmp(datallowconn, "f") == 0)
     738           0 :                 pg_fatal("All non-template0 databases must allow connections, "
     739             :                          "i.e. their pg_database.datallowconn must be true\n");
     740             :         }
     741             :     }
     742             : 
     743           2 :     PQclear(dbres);
     744             : 
     745           2 :     PQfinish(conn_template1);
     746             : 
     747           2 :     check_ok();
     748           2 : }
     749             : 
     750             : 
     751             : /*
     752             :  *  check_for_prepared_transactions()
     753             :  *
     754             :  *  Make sure there are no prepared transactions because the storage format
     755             :  *  might have changed.
     756             :  */
     757             : static void
     758           4 : check_for_prepared_transactions(ClusterInfo *cluster)
     759             : {
     760             :     PGresult   *res;
     761           4 :     PGconn     *conn = connectToServer(cluster, "template1");
     762             : 
     763           4 :     prep_status("Checking for prepared transactions");
     764             : 
     765           4 :     res = executeQueryOrDie(conn,
     766             :                             "SELECT * "
     767             :                             "FROM pg_catalog.pg_prepared_xacts");
     768             : 
     769           4 :     if (PQntuples(res) != 0)
     770             :     {
     771           0 :         if (cluster == &old_cluster)
     772           0 :             pg_fatal("The source cluster contains prepared transactions\n");
     773             :         else
     774           0 :             pg_fatal("The target cluster contains prepared transactions\n");
     775             :     }
     776             : 
     777           4 :     PQclear(res);
     778             : 
     779           4 :     PQfinish(conn);
     780             : 
     781           4 :     check_ok();
     782           4 : }
     783             : 
     784             : 
     785             : /*
     786             :  *  check_for_isn_and_int8_passing_mismatch()
     787             :  *
     788             :  *  contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
     789             :  *  by value.  The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
     790             :  *  it must match for the old and new servers.
     791             :  */
     792             : static void
     793           2 : check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
     794             : {
     795             :     int         dbnum;
     796           2 :     FILE       *script = NULL;
     797           2 :     bool        found = false;
     798             :     char        output_path[MAXPGPATH];
     799             : 
     800           2 :     prep_status("Checking for contrib/isn with bigint-passing mismatch");
     801             : 
     802           2 :     if (old_cluster.controldata.float8_pass_by_value ==
     803           2 :         new_cluster.controldata.float8_pass_by_value)
     804             :     {
     805             :         /* no mismatch */
     806           2 :         check_ok();
     807           2 :         return;
     808             :     }
     809             : 
     810           0 :     snprintf(output_path, sizeof(output_path),
     811             :              "contrib_isn_and_int8_pass_by_value.txt");
     812             : 
     813           0 :     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
     814             :     {
     815             :         PGresult   *res;
     816           0 :         bool        db_used = false;
     817             :         int         ntups;
     818             :         int         rowno;
     819             :         int         i_nspname,
     820             :                     i_proname;
     821           0 :         DbInfo     *active_db = &cluster->dbarr.dbs[dbnum];
     822           0 :         PGconn     *conn = connectToServer(cluster, active_db->db_name);
     823             : 
     824             :         /* Find any functions coming from contrib/isn */
     825           0 :         res = executeQueryOrDie(conn,
     826             :                                 "SELECT n.nspname, p.proname "
     827             :                                 "FROM  pg_catalog.pg_proc p, "
     828             :                                 "      pg_catalog.pg_namespace n "
     829             :                                 "WHERE p.pronamespace = n.oid AND "
     830             :                                 "      p.probin = '$libdir/isn'");
     831             : 
     832           0 :         ntups = PQntuples(res);
     833           0 :         i_nspname = PQfnumber(res, "nspname");
     834           0 :         i_proname = PQfnumber(res, "proname");
     835           0 :         for (rowno = 0; rowno < ntups; rowno++)
     836             :         {
     837           0 :             found = true;
     838           0 :             if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
     839           0 :                 pg_fatal("could not open file \"%s\": %s\n",
     840           0 :                          output_path, strerror(errno));
     841           0 :             if (!db_used)
     842             :             {
     843           0 :                 fprintf(script, "In database: %s\n", active_db->db_name);
     844           0 :                 db_used = true;
     845             :             }
     846           0 :             fprintf(script, "  %s.%s\n",
     847             :                     PQgetvalue(res, rowno, i_nspname),
     848             :                     PQgetvalue(res, rowno, i_proname));
     849             :         }
     850             : 
     851           0 :         PQclear(res);
     852             : 
     853           0 :         PQfinish(conn);
     854             :     }
     855             : 
     856           0 :     if (script)
     857           0 :         fclose(script);
     858             : 
     859           0 :     if (found)
     860             :     {
     861           0 :         pg_log(PG_REPORT, "fatal\n");
     862           0 :         pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
     863             :                  "bigint data type.  Your old and new clusters pass bigint values\n"
     864             :                  "differently so this cluster cannot currently be upgraded.  You can\n"
     865             :                  "manually dump databases in the old cluster that use \"contrib/isn\"\n"
     866             :                  "facilities, drop them, perform the upgrade, and then restore them.  A\n"
     867             :                  "list of the problem functions is in the file:\n"
     868             :                  "    %s\n\n", output_path);
     869             :     }
     870             :     else
     871           0 :         check_ok();
     872             : }
     873             : 
     874             : /*
     875             :  * Verify that no user defined postfix operators exist.
     876             :  */
     877             : static void
     878           0 : check_for_user_defined_postfix_ops(ClusterInfo *cluster)
     879             : {
     880             :     int         dbnum;
     881           0 :     FILE       *script = NULL;
     882           0 :     bool        found = false;
     883             :     char        output_path[MAXPGPATH];
     884             : 
     885           0 :     prep_status("Checking for user-defined postfix operators");
     886             : 
     887           0 :     snprintf(output_path, sizeof(output_path),
     888             :              "postfix_ops.txt");
     889             : 
     890             :     /* Find any user defined postfix operators */
     891           0 :     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
     892             :     {
     893             :         PGresult   *res;
     894           0 :         bool        db_used = false;
     895             :         int         ntups;
     896             :         int         rowno;
     897             :         int         i_oproid,
     898             :                     i_oprnsp,
     899             :                     i_oprname,
     900             :                     i_typnsp,
     901             :                     i_typname;
     902           0 :         DbInfo     *active_db = &cluster->dbarr.dbs[dbnum];
     903           0 :         PGconn     *conn = connectToServer(cluster, active_db->db_name);
     904             : 
     905             :         /*
     906             :          * The query below hardcodes FirstNormalObjectId as 16384 rather than
     907             :          * interpolating that C #define into the query because, if that
     908             :          * #define is ever changed, the cutoff we want to use is the value
     909             :          * used by pre-version 14 servers, not that of some future version.
     910             :          */
     911           0 :         res = executeQueryOrDie(conn,
     912             :                                 "SELECT o.oid AS oproid, "
     913             :                                 "       n.nspname AS oprnsp, "
     914             :                                 "       o.oprname, "
     915             :                                 "       tn.nspname AS typnsp, "
     916             :                                 "       t.typname "
     917             :                                 "FROM pg_catalog.pg_operator o, "
     918             :                                 "     pg_catalog.pg_namespace n, "
     919             :                                 "     pg_catalog.pg_type t, "
     920             :                                 "     pg_catalog.pg_namespace tn "
     921             :                                 "WHERE o.oprnamespace = n.oid AND "
     922             :                                 "      o.oprleft = t.oid AND "
     923             :                                 "      t.typnamespace = tn.oid AND "
     924             :                                 "      o.oprright = 0 AND "
     925             :                                 "      o.oid >= 16384");
     926           0 :         ntups = PQntuples(res);
     927           0 :         i_oproid = PQfnumber(res, "oproid");
     928           0 :         i_oprnsp = PQfnumber(res, "oprnsp");
     929           0 :         i_oprname = PQfnumber(res, "oprname");
     930           0 :         i_typnsp = PQfnumber(res, "typnsp");
     931           0 :         i_typname = PQfnumber(res, "typname");
     932           0 :         for (rowno = 0; rowno < ntups; rowno++)
     933             :         {
     934           0 :             found = true;
     935           0 :             if (script == NULL &&
     936           0 :                 (script = fopen_priv(output_path, "w")) == NULL)
     937           0 :                 pg_fatal("could not open file \"%s\": %s\n",
     938           0 :                          output_path, strerror(errno));
     939           0 :             if (!db_used)
     940             :             {
     941           0 :                 fprintf(script, "In database: %s\n", active_db->db_name);
     942           0 :                 db_used = true;
     943             :             }
     944           0 :             fprintf(script, "  (oid=%s) %s.%s (%s.%s, NONE)\n",
     945             :                     PQgetvalue(res, rowno, i_oproid),
     946             :                     PQgetvalue(res, rowno, i_oprnsp),
     947             :                     PQgetvalue(res, rowno, i_oprname),
     948             :                     PQgetvalue(res, rowno, i_typnsp),
     949             :                     PQgetvalue(res, rowno, i_typname));
     950             :         }
     951             : 
     952           0 :         PQclear(res);
     953             : 
     954           0 :         PQfinish(conn);
     955             :     }
     956             : 
     957           0 :     if (script)
     958           0 :         fclose(script);
     959             : 
     960           0 :     if (found)
     961             :     {
     962           0 :         pg_log(PG_REPORT, "fatal\n");
     963           0 :         pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
     964             :                  "supported anymore.  Consider dropping the postfix operators and replacing\n"
     965             :                  "them with prefix operators or function calls.\n"
     966             :                  "A list of user-defined postfix operators is in the file:\n"
     967             :                  "    %s\n\n", output_path);
     968             :     }
     969             :     else
     970           0 :         check_ok();
     971           0 : }
     972             : 
     973             : /*
     974             :  * Verify that no tables are declared WITH OIDS.
     975             :  */
     976             : static void
     977           0 : check_for_tables_with_oids(ClusterInfo *cluster)
     978             : {
     979             :     int         dbnum;
     980           0 :     FILE       *script = NULL;
     981           0 :     bool        found = false;
     982             :     char        output_path[MAXPGPATH];
     983             : 
     984           0 :     prep_status("Checking for tables WITH OIDS");
     985             : 
     986           0 :     snprintf(output_path, sizeof(output_path),
     987             :              "tables_with_oids.txt");
     988             : 
     989             :     /* Find any tables declared WITH OIDS */
     990           0 :     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
     991             :     {
     992             :         PGresult   *res;
     993           0 :         bool        db_used = false;
     994             :         int         ntups;
     995             :         int         rowno;
     996             :         int         i_nspname,
     997             :                     i_relname;
     998           0 :         DbInfo     *active_db = &cluster->dbarr.dbs[dbnum];
     999           0 :         PGconn     *conn = connectToServer(cluster, active_db->db_name);
    1000             : 
    1001           0 :         res = executeQueryOrDie(conn,
    1002             :                                 "SELECT n.nspname, c.relname "
    1003             :                                 "FROM  pg_catalog.pg_class c, "
    1004             :                                 "      pg_catalog.pg_namespace n "
    1005             :                                 "WHERE c.relnamespace = n.oid AND "
    1006             :                                 "      c.relhasoids AND"
    1007             :                                 "       n.nspname NOT IN ('pg_catalog')");
    1008             : 
    1009           0 :         ntups = PQntuples(res);
    1010           0 :         i_nspname = PQfnumber(res, "nspname");
    1011           0 :         i_relname = PQfnumber(res, "relname");
    1012           0 :         for (rowno = 0; rowno < ntups; rowno++)
    1013             :         {
    1014           0 :             found = true;
    1015           0 :             if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
    1016           0 :                 pg_fatal("could not open file \"%s\": %s\n",
    1017           0 :                          output_path, strerror(errno));
    1018           0 :             if (!db_used)
    1019             :             {
    1020           0 :                 fprintf(script, "In database: %s\n", active_db->db_name);
    1021           0 :                 db_used = true;
    1022             :             }
    1023           0 :             fprintf(script, "  %s.%s\n",
    1024             :                     PQgetvalue(res, rowno, i_nspname),
    1025             :                     PQgetvalue(res, rowno, i_relname));
    1026             :         }
    1027             : 
    1028           0 :         PQclear(res);
    1029             : 
    1030           0 :         PQfinish(conn);
    1031             :     }
    1032             : 
    1033           0 :     if (script)
    1034           0 :         fclose(script);
    1035             : 
    1036           0 :     if (found)
    1037             :     {
    1038           0 :         pg_log(PG_REPORT, "fatal\n");
    1039           0 :         pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
    1040             :                  "supported anymore.  Consider removing the oid column using\n"
    1041             :                  "    ALTER TABLE ... SET WITHOUT OIDS;\n"
    1042             :                  "A list of tables with the problem is in the file:\n"
    1043             :                  "    %s\n\n", output_path);
    1044             :     }
    1045             :     else
    1046           0 :         check_ok();
    1047           0 : }
    1048             : 
    1049             : 
    1050             : /*
    1051             :  * check_for_composite_data_type_usage()
    1052             :  *  Check for system-defined composite types used in user tables.
    1053             :  *
    1054             :  *  The OIDs of rowtypes of system catalogs and information_schema views
    1055             :  *  can change across major versions; unlike user-defined types, we have
    1056             :  *  no mechanism for forcing them to be the same in the new cluster.
    1057             :  *  Hence, if any user table uses one, that's problematic for pg_upgrade.
    1058             :  */
    1059             : static void
    1060           2 : check_for_composite_data_type_usage(ClusterInfo *cluster)
    1061             : {
    1062             :     bool        found;
    1063             :     Oid         firstUserOid;
    1064             :     char        output_path[MAXPGPATH];
    1065             :     char       *base_query;
    1066             : 
    1067           2 :     prep_status("Checking for system-defined composite types in user tables");
    1068             : 
    1069           2 :     snprintf(output_path, sizeof(output_path), "tables_using_composite.txt");
    1070             : 
    1071             :     /*
    1072             :      * Look for composite types that were made during initdb *or* belong to
    1073             :      * information_schema; that's important in case information_schema was
    1074             :      * dropped and reloaded.
    1075             :      *
    1076             :      * The cutoff OID here should match the source cluster's value of
    1077             :      * FirstNormalObjectId.  We hardcode it rather than using that C #define
    1078             :      * because, if that #define is ever changed, our own version's value is
    1079             :      * NOT what to use.  Eventually we may need a test on the source cluster's
    1080             :      * version to select the correct value.
    1081             :      */
    1082           2 :     firstUserOid = 16384;
    1083             : 
    1084           2 :     base_query = psprintf("SELECT t.oid FROM pg_catalog.pg_type t "
    1085             :                           "LEFT JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid "
    1086             :                           " WHERE typtype = 'c' AND (t.oid < %u OR nspname = 'information_schema')",
    1087             :                           firstUserOid);
    1088             : 
    1089           2 :     found = check_for_data_types_usage(cluster, base_query, output_path);
    1090             : 
    1091           2 :     free(base_query);
    1092             : 
    1093           2 :     if (found)
    1094             :     {
    1095           0 :         pg_log(PG_REPORT, "fatal\n");
    1096           0 :         pg_fatal("Your installation contains system-defined composite type(s) in user tables.\n"
    1097             :                  "These type OIDs are not stable across PostgreSQL versions,\n"
    1098             :                  "so this cluster cannot currently be upgraded.  You can\n"
    1099             :                  "drop the problem columns and restart the upgrade.\n"
    1100             :                  "A list of the problem columns is in the file:\n"
    1101             :                  "    %s\n\n", output_path);
    1102             :     }
    1103             :     else
    1104           2 :         check_ok();
    1105           2 : }
    1106             : 
    1107             : /*
    1108             :  * check_for_reg_data_type_usage()
    1109             :  *  pg_upgrade only preserves these system values:
    1110             :  *      pg_class.oid
    1111             :  *      pg_type.oid
    1112             :  *      pg_enum.oid
    1113             :  *
    1114             :  *  Many of the reg* data types reference system catalog info that is
    1115             :  *  not preserved, and hence these data types cannot be used in user
    1116             :  *  tables upgraded by pg_upgrade.
    1117             :  */
    1118             : static void
    1119           2 : check_for_reg_data_type_usage(ClusterInfo *cluster)
    1120             : {
    1121             :     bool        found;
    1122             :     char        output_path[MAXPGPATH];
    1123             : 
    1124           2 :     prep_status("Checking for reg* data types in user tables");
    1125             : 
    1126           2 :     snprintf(output_path, sizeof(output_path), "tables_using_reg.txt");
    1127             : 
    1128             :     /*
    1129             :      * Note: older servers will not have all of these reg* types, so we have
    1130             :      * to write the query like this rather than depending on casts to regtype.
    1131             :      */
    1132           2 :     found = check_for_data_types_usage(cluster,
    1133             :                                        "SELECT oid FROM pg_catalog.pg_type t "
    1134             :                                        "WHERE t.typnamespace = "
    1135             :                                        "        (SELECT oid FROM pg_catalog.pg_namespace "
    1136             :                                        "         WHERE nspname = 'pg_catalog') "
    1137             :                                        "  AND t.typname IN ( "
    1138             :     /* pg_class.oid is preserved, so 'regclass' is OK */
    1139             :                                        "           'regcollation', "
    1140             :                                        "           'regconfig', "
    1141             :                                        "           'regdictionary', "
    1142             :                                        "           'regnamespace', "
    1143             :                                        "           'regoper', "
    1144             :                                        "           'regoperator', "
    1145             :                                        "           'regproc', "
    1146             :                                        "           'regprocedure' "
    1147             :     /* pg_authid.oid is preserved, so 'regrole' is OK */
    1148             :     /* pg_type.oid is (mostly) preserved, so 'regtype' is OK */
    1149             :                                        "         )",
    1150             :                                        output_path);
    1151             : 
    1152           2 :     if (found)
    1153             :     {
    1154           0 :         pg_log(PG_REPORT, "fatal\n");
    1155           0 :         pg_fatal("Your installation contains one of the reg* data types in user tables.\n"
    1156             :                  "These data types reference system OIDs that are not preserved by\n"
    1157             :                  "pg_upgrade, so this cluster cannot currently be upgraded.  You can\n"
    1158             :                  "drop the problem columns and restart the upgrade.\n"
    1159             :                  "A list of the problem columns is in the file:\n"
    1160             :                  "    %s\n\n", output_path);
    1161             :     }
    1162             :     else
    1163           2 :         check_ok();
    1164           2 : }
    1165             : 
    1166             : 
    1167             : /*
    1168             :  * check_for_jsonb_9_4_usage()
    1169             :  *
    1170             :  *  JSONB changed its storage format during 9.4 beta, so check for it.
    1171             :  */
    1172             : static void
    1173           0 : check_for_jsonb_9_4_usage(ClusterInfo *cluster)
    1174             : {
    1175             :     char        output_path[MAXPGPATH];
    1176             : 
    1177           0 :     prep_status("Checking for incompatible \"jsonb\" data type");
    1178             : 
    1179           0 :     snprintf(output_path, sizeof(output_path), "tables_using_jsonb.txt");
    1180             : 
    1181           0 :     if (check_for_data_type_usage(cluster, "pg_catalog.jsonb", output_path))
    1182             :     {
    1183           0 :         pg_log(PG_REPORT, "fatal\n");
    1184           0 :         pg_fatal("Your installation contains the \"jsonb\" data type in user tables.\n"
    1185             :                  "The internal format of \"jsonb\" changed during 9.4 beta so this\n"
    1186             :                  "cluster cannot currently be upgraded.  You can\n"
    1187             :                  "drop the problem columns and restart the upgrade.\n"
    1188             :                  "A list of the problem columns is in the file:\n"
    1189             :                  "    %s\n\n", output_path);
    1190             :     }
    1191             :     else
    1192           0 :         check_ok();
    1193           0 : }
    1194             : 
    1195             : /*
    1196             :  * check_for_pg_role_prefix()
    1197             :  *
    1198             :  *  Versions older than 9.6 should not have any pg_* roles
    1199             :  */
    1200             : static void
    1201           0 : check_for_pg_role_prefix(ClusterInfo *cluster)
    1202             : {
    1203             :     PGresult   *res;
    1204           0 :     PGconn     *conn = connectToServer(cluster, "template1");
    1205             : 
    1206           0 :     prep_status("Checking for roles starting with \"pg_\"");
    1207             : 
    1208           0 :     res = executeQueryOrDie(conn,
    1209             :                             "SELECT * "
    1210             :                             "FROM pg_catalog.pg_roles "
    1211             :                             "WHERE rolname ~ '^pg_'");
    1212             : 
    1213           0 :     if (PQntuples(res) != 0)
    1214             :     {
    1215           0 :         if (cluster == &old_cluster)
    1216           0 :             pg_fatal("The source cluster contains roles starting with \"pg_\"\n");
    1217             :         else
    1218           0 :             pg_fatal("The target cluster contains roles starting with \"pg_\"\n");
    1219             :     }
    1220             : 
    1221           0 :     PQclear(res);
    1222             : 
    1223           0 :     PQfinish(conn);
    1224             : 
    1225           0 :     check_ok();
    1226           0 : }
    1227             : 
    1228             : /*
    1229             :  * Verify that no user-defined encoding conversions exist.
    1230             :  */
    1231             : static void
    1232           0 : check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
    1233             : {
    1234             :     int         dbnum;
    1235           0 :     FILE       *script = NULL;
    1236           0 :     bool        found = false;
    1237             :     char        output_path[MAXPGPATH];
    1238             : 
    1239           0 :     prep_status("Checking for user-defined encoding conversions");
    1240             : 
    1241           0 :     snprintf(output_path, sizeof(output_path),
    1242             :              "encoding_conversions.txt");
    1243             : 
    1244             :     /* Find any user defined encoding conversions */
    1245           0 :     for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
    1246             :     {
    1247             :         PGresult   *res;
    1248           0 :         bool        db_used = false;
    1249             :         int         ntups;
    1250             :         int         rowno;
    1251             :         int         i_conoid,
    1252             :                     i_conname,
    1253             :                     i_nspname;
    1254           0 :         DbInfo     *active_db = &cluster->dbarr.dbs[dbnum];
    1255           0 :         PGconn     *conn = connectToServer(cluster, active_db->db_name);
    1256             : 
    1257             :         /*
    1258             :          * The query below hardcodes FirstNormalObjectId as 16384 rather than
    1259             :          * interpolating that C #define into the query because, if that
    1260             :          * #define is ever changed, the cutoff we want to use is the value
    1261             :          * used by pre-version 14 servers, not that of some future version.
    1262             :          */
    1263           0 :         res = executeQueryOrDie(conn,
    1264             :                                 "SELECT c.oid as conoid, c.conname, n.nspname "
    1265             :                                 "FROM pg_catalog.pg_conversion c, "
    1266             :                                 "     pg_catalog.pg_namespace n "
    1267             :                                 "WHERE c.connamespace = n.oid AND "
    1268             :                                 "      c.oid >= 16384");
    1269           0 :         ntups = PQntuples(res);
    1270           0 :         i_conoid = PQfnumber(res, "conoid");
    1271           0 :         i_conname = PQfnumber(res, "conname");
    1272           0 :         i_nspname = PQfnumber(res, "nspname");
    1273           0 :         for (rowno = 0; rowno < ntups; rowno++)
    1274             :         {
    1275           0 :             found = true;
    1276           0 :             if (script == NULL &&
    1277           0 :                 (script = fopen_priv(output_path, "w")) == NULL)
    1278           0 :                 pg_fatal("could not open file \"%s\": %s\n",
    1279           0 :                          output_path, strerror(errno));
    1280           0 :             if (!db_used)
    1281             :             {
    1282           0 :                 fprintf(script, "In database: %s\n", active_db->db_name);
    1283           0 :                 db_used = true;
    1284             :             }
    1285           0 :             fprintf(script, "  (oid=%s) %s.%s\n",
    1286             :                     PQgetvalue(res, rowno, i_conoid),
    1287             :                     PQgetvalue(res, rowno, i_nspname),
    1288             :                     PQgetvalue(res, rowno, i_conname));
    1289             :         }
    1290             : 
    1291           0 :         PQclear(res);
    1292             : 
    1293           0 :         PQfinish(conn);
    1294             :     }
    1295             : 
    1296           0 :     if (script)
    1297           0 :         fclose(script);
    1298             : 
    1299           0 :     if (found)
    1300             :     {
    1301           0 :         pg_log(PG_REPORT, "fatal\n");
    1302           0 :         pg_fatal("Your installation contains user-defined encoding conversions.\n"
    1303             :                  "The conversion function parameters changed in PostgreSQL version 14\n"
    1304             :                  "so this cluster cannot currently be upgraded.  You can remove the\n"
    1305             :                  "encoding conversions in the old cluster and restart the upgrade.\n"
    1306             :                  "A list of user-defined encoding conversions is in the file:\n"
    1307             :                  "    %s\n\n", output_path);
    1308             :     }
    1309             :     else
    1310           0 :         check_ok();
    1311           0 : }
    1312             : 
    1313             : 
    1314             : /*
    1315             :  * get_canonical_locale_name
    1316             :  *
    1317             :  * Send the locale name to the system, and hope we get back a canonical
    1318             :  * version.  This should match the backend's check_locale() function.
    1319             :  */
    1320             : static char *
    1321           0 : get_canonical_locale_name(int category, const char *locale)
    1322             : {
    1323             :     char       *save;
    1324             :     char       *res;
    1325             : 
    1326             :     /* get the current setting, so we can restore it. */
    1327           0 :     save = setlocale(category, NULL);
    1328           0 :     if (!save)
    1329           0 :         pg_fatal("failed to get the current locale\n");
    1330             : 
    1331             :     /* 'save' may be pointing at a modifiable scratch variable, so copy it. */
    1332           0 :     save = pg_strdup(save);
    1333             : 
    1334             :     /* set the locale with setlocale, to see if it accepts it. */
    1335           0 :     res = setlocale(category, locale);
    1336             : 
    1337           0 :     if (!res)
    1338           0 :         pg_fatal("failed to get system locale name for \"%s\"\n", locale);
    1339             : 
    1340           0 :     res = pg_strdup(res);
    1341             : 
    1342             :     /* restore old value. */
    1343           0 :     if (!setlocale(category, save))
    1344           0 :         pg_fatal("failed to restore old locale \"%s\"\n", save);
    1345             : 
    1346           0 :     pg_free(save);
    1347             : 
    1348           0 :     return res;
    1349             : }

Generated by: LCOV version 1.14