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