LCOV - differential code coverage report
Current view: top level - src/bin/pg_upgrade - check.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 40.0 % 453 181 58 21 146 47 31 116 3 31 167 96 27 33
Current Date: 2023-04-08 15:15:32 Functions: 72.0 % 25 18 1 6 18 7 15 3
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a