OSDN Git Service

376d25a09a8825a5d22a8a9b314558b3523d0cc5
[pg-rex/syncrep.git] / contrib / pg_upgrade / check.c
1 /*
2  *      check.c
3  *
4  *      server checks and output routines
5  *
6  *      Copyright (c) 2010-2011, PostgreSQL Global Development Group
7  *      contrib/pg_upgrade/check.c
8  */
9
10 #include "pg_upgrade.h"
11
12
13 static void set_locale_and_encoding(ClusterInfo *cluster);
14 static void check_new_cluster_is_empty(void);
15 static void check_old_cluster_has_new_cluster_dbs(void);
16 static void check_locale_and_encoding(ControlData *oldctrl,
17                                                   ControlData *newctrl);
18 static void check_is_super_user(ClusterInfo *cluster);
19 static void check_for_prepared_transactions(ClusterInfo *cluster);
20 static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
21 static void check_for_reg_data_type_usage(ClusterInfo *cluster);
22
23
24 void
25 output_check_banner(bool *live_check)
26 {
27         if (user_opts.check && is_server_running(old_cluster.pgdata))
28         {
29                 *live_check = true;
30                 if (old_cluster.port == new_cluster.port)
31                         pg_log(PG_FATAL, "When checking a live server, "
32                                    "the old and new port numbers must be different.\n");
33                 pg_log(PG_REPORT, "PerForming Consistency Checks on Old Live Server\n");
34                 pg_log(PG_REPORT, "------------------------------------------------\n");
35         }
36         else
37         {
38                 pg_log(PG_REPORT, "Performing Consistency Checks\n");
39                 pg_log(PG_REPORT, "-----------------------------\n");
40         }
41 }
42
43
44 void
45 check_old_cluster(bool live_check,
46                                   char **sequence_script_file_name)
47 {
48         /* -- OLD -- */
49
50         if (!live_check)
51                 start_postmaster(&old_cluster);
52
53         set_locale_and_encoding(&old_cluster);
54
55         get_pg_database_relfilenode(&old_cluster);
56
57         /* Extract a list of databases and tables from the old cluster */
58         get_db_and_rel_infos(&old_cluster);
59
60         init_tablespaces();
61
62         get_loadable_libraries();
63
64
65         /*
66          * Check for various failure cases
67          */
68         check_is_super_user(&old_cluster);
69         check_for_prepared_transactions(&old_cluster);
70         check_for_reg_data_type_usage(&old_cluster);
71         check_for_isn_and_int8_passing_mismatch(&old_cluster);
72
73         /* old = PG 8.3 checks? */
74         if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
75         {
76                 old_8_3_check_for_name_data_type_usage(&old_cluster);
77                 old_8_3_check_for_tsquery_usage(&old_cluster);
78                 if (user_opts.check)
79                 {
80                         old_8_3_rebuild_tsvector_tables(&old_cluster, true);
81                         old_8_3_invalidate_hash_gin_indexes(&old_cluster, true);
82                         old_8_3_invalidate_bpchar_pattern_ops_indexes(&old_cluster, true);
83                 }
84                 else
85
86                         /*
87                          * While we have the old server running, create the script to
88                          * properly restore its sequence values but we report this at the
89                          * end.
90                          */
91                         *sequence_script_file_name =
92                                 old_8_3_create_sequence_script(&old_cluster);
93         }
94
95         /* Pre-PG 9.0 had no large object permissions */
96         if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
97                 new_9_0_populate_pg_largeobject_metadata(&old_cluster, true);
98
99         /*
100          * While not a check option, we do this now because this is the only time
101          * the old server is running.
102          */
103         if (!user_opts.check)
104         {
105                 generate_old_dump();
106                 split_old_dump();
107         }
108
109         if (!live_check)
110                 stop_postmaster(false);
111 }
112
113
114 void
115 check_new_cluster(void)
116 {
117         set_locale_and_encoding(&new_cluster);
118
119         get_db_and_rel_infos(&new_cluster);
120
121         check_new_cluster_is_empty();
122         check_for_prepared_transactions(&new_cluster);
123         check_old_cluster_has_new_cluster_dbs();
124
125         check_loadable_libraries();
126
127         check_locale_and_encoding(&old_cluster.controldata, &new_cluster.controldata);
128
129         if (user_opts.transfer_mode == TRANSFER_MODE_LINK)
130                 check_hard_link();
131 }
132
133
134 void
135 report_clusters_compatible(void)
136 {
137         if (user_opts.check)
138         {
139                 pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
140                 /* stops new cluster */
141                 stop_postmaster(false);
142                 exit(0);
143         }
144
145         pg_log(PG_REPORT, "\n"
146                    "| If pg_upgrade fails after this point, you must\n"
147                    "| re-initdb the new cluster before continuing.\n"
148                    "| You will also need to remove the \".old\" suffix\n"
149                    "| from %s/global/pg_control.old.\n", old_cluster.pgdata);
150 }
151
152
153 void
154 issue_warnings(char *sequence_script_file_name)
155 {
156         /* old = PG 8.3 warnings? */
157         if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
158         {
159                 start_postmaster(&new_cluster);
160
161                 /* restore proper sequence values using file created from old server */
162                 if (sequence_script_file_name)
163                 {
164                         prep_status("Adjusting sequences");
165                         exec_prog(true,
166                                           SYSTEMQUOTE "\"%s/psql\" --set ON_ERROR_STOP=on "
167                                           "--no-psqlrc --port %d --username \"%s\" "
168                                           "-f \"%s\" --dbname template1 >> \"%s\"" SYSTEMQUOTE,
169                                           new_cluster.bindir, new_cluster.port, os_info.user,
170                                           sequence_script_file_name, log_opts.filename);
171                         unlink(sequence_script_file_name);
172                         check_ok();
173                 }
174
175                 old_8_3_rebuild_tsvector_tables(&new_cluster, false);
176                 old_8_3_invalidate_hash_gin_indexes(&new_cluster, false);
177                 old_8_3_invalidate_bpchar_pattern_ops_indexes(&new_cluster, false);
178                 stop_postmaster(false);
179         }
180
181         /* Create dummy large object permissions for old < PG 9.0? */
182         if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
183         {
184                 start_postmaster(&new_cluster);
185                 new_9_0_populate_pg_largeobject_metadata(&new_cluster, false);
186                 stop_postmaster(false);
187         }
188 }
189
190
191 void
192 output_completion_banner(char *deletion_script_file_name)
193 {
194         /* Did we copy the free space files? */
195         if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804)
196                 pg_log(PG_REPORT,
197                            "| Optimizer statistics are not transferred by pg_upgrade\n"
198                            "| so consider running:\n"
199                            "| \tvacuumdb --all --analyze-only\n"
200                            "| on the newly-upgraded cluster.\n\n");
201         else
202                 pg_log(PG_REPORT,
203                            "| Optimizer statistics and free space information\n"
204                            "| are not transferred by pg_upgrade so consider\n"
205                            "| running:\n"
206                            "| \tvacuumdb --all --analyze\n"
207                            "| on the newly-upgraded cluster.\n\n");
208
209         pg_log(PG_REPORT,
210                    "| Running this script will delete the old cluster's data files:\n"
211                    "| \t%s\n",
212                    deletion_script_file_name);
213 }
214
215
216 void
217 check_cluster_versions(void)
218 {
219         /* get old and new cluster versions */
220         old_cluster.major_version = get_major_server_version(&old_cluster);
221         new_cluster.major_version = get_major_server_version(&new_cluster);
222
223         /*
224          * We allow upgrades from/to the same major version for alpha/beta
225          * upgrades
226          */
227
228         if (GET_MAJOR_VERSION(old_cluster.major_version) < 803)
229                 pg_log(PG_FATAL, "This utility can only upgrade from PostgreSQL version 8.3 and later.\n");
230
231         /* Only current PG version is supported as a target */
232         if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM))
233                 pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version %s.\n",
234                            PG_MAJORVERSION);
235
236         /*
237          * We can't allow downgrading because we use the target pg_dumpall, and
238          * pg_dumpall cannot operate on new datbase versions, only older versions.
239          */
240         if (old_cluster.major_version > new_cluster.major_version)
241                 pg_log(PG_FATAL, "This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
242 }
243
244
245 void
246 check_cluster_compatibility(bool live_check)
247 {
248         char            libfile[MAXPGPATH];
249         FILE       *lib_test;
250
251         /*
252          * Test pg_upgrade_support.so is in the proper place.    We cannot copy it
253          * ourselves because install directories are typically root-owned.
254          */
255         snprintf(libfile, sizeof(libfile), "%s/pg_upgrade_support%s", new_cluster.libpath,
256                          DLSUFFIX);
257
258         if ((lib_test = fopen(libfile, "r")) == NULL)
259                 pg_log(PG_FATAL,
260                            "pg_upgrade_support%s must be created and installed in %s\n", DLSUFFIX, libfile);
261         else
262                 fclose(lib_test);
263
264         /* get/check pg_control data of servers */
265         get_control_data(&old_cluster, live_check);
266         get_control_data(&new_cluster, false);
267         check_control_data(&old_cluster.controldata, &new_cluster.controldata);
268
269         /* Is it 9.0 but without tablespace directories? */
270         if (GET_MAJOR_VERSION(new_cluster.major_version) == 900 &&
271                 new_cluster.controldata.cat_ver < TABLE_SPACE_SUBDIRS_CAT_VER)
272                 pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n"
273                            "because of backend API changes made during development.\n");
274 }
275
276
277 /*
278  * set_locale_and_encoding()
279  *
280  * query the database to get the template0 locale
281  */
282 static void
283 set_locale_and_encoding(ClusterInfo *cluster)
284 {
285         ControlData *ctrl = &cluster->controldata;
286         PGconn     *conn;
287         PGresult   *res;
288         int                     i_encoding;
289         int                     cluster_version = cluster->major_version;
290
291         conn = connectToServer(cluster, "template1");
292
293         /* for pg < 80400, we got the values from pg_controldata */
294         if (cluster_version >= 80400)
295         {
296                 int                     i_datcollate;
297                 int                     i_datctype;
298
299                 res = executeQueryOrDie(conn,
300                                                                 "SELECT datcollate, datctype "
301                                                                 "FROM   pg_catalog.pg_database "
302                                                                 "WHERE  datname = 'template0' ");
303                 assert(PQntuples(res) == 1);
304
305                 i_datcollate = PQfnumber(res, "datcollate");
306                 i_datctype = PQfnumber(res, "datctype");
307
308                 ctrl->lc_collate = pg_strdup(PQgetvalue(res, 0, i_datcollate));
309                 ctrl->lc_ctype = pg_strdup(PQgetvalue(res, 0, i_datctype));
310
311                 PQclear(res);
312         }
313
314         res = executeQueryOrDie(conn,
315                                                         "SELECT pg_catalog.pg_encoding_to_char(encoding) "
316                                                         "FROM   pg_catalog.pg_database "
317                                                         "WHERE  datname = 'template0' ");
318         assert(PQntuples(res) == 1);
319
320         i_encoding = PQfnumber(res, "pg_encoding_to_char");
321         ctrl->encoding = pg_strdup(PQgetvalue(res, 0, i_encoding));
322
323         PQclear(res);
324
325         PQfinish(conn);
326 }
327
328
329 /*
330  * check_locale_and_encoding()
331  *
332  *      locale is not in pg_controldata in 8.4 and later so
333  *      we probably had to get via a database query.
334  */
335 static void
336 check_locale_and_encoding(ControlData *oldctrl,
337                                                   ControlData *newctrl)
338 {
339         /* These are often defined with inconsistent case, so use pg_strcasecmp(). */
340         if (pg_strcasecmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
341                 pg_log(PG_FATAL,
342                            "old and new cluster lc_collate values do not match\n");
343         if (pg_strcasecmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
344                 pg_log(PG_FATAL,
345                            "old and new cluster lc_ctype values do not match\n");
346         if (pg_strcasecmp(oldctrl->encoding, newctrl->encoding) != 0)
347                 pg_log(PG_FATAL,
348                            "old and new cluster encoding values do not match\n");
349 }
350
351
352 static void
353 check_new_cluster_is_empty(void)
354 {
355         int                     dbnum;
356
357         for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
358         {
359                 int                     relnum;
360                 RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
361
362                 for (relnum = 0; relnum < rel_arr->nrels;
363                          relnum++)
364                 {
365                         /* pg_largeobject and its index should be skipped */
366                         if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
367                                 pg_log(PG_FATAL, "New cluster database \"%s\" is not empty\n",
368                                            new_cluster.dbarr.dbs[dbnum].db_name);
369                 }
370         }
371
372 }
373
374
375 /*
376  *      If someone removes the 'postgres' database from the old cluster and
377  *      the new cluster has a 'postgres' database, the number of databases
378  *      will not match.  We actually could upgrade such a setup, but it would
379  *      violate the 1-to-1 mapping of database counts, so we throw an error
380  *      instead.  We would detect this as a database count mismatch during
381  *      upgrade, but we want to detect it during the check phase and report
382  *      the database name.
383  */
384 static void
385 check_old_cluster_has_new_cluster_dbs(void)
386 {
387         int                     old_dbnum,
388                                 new_dbnum;
389
390         for (new_dbnum = 0; new_dbnum < new_cluster.dbarr.ndbs; new_dbnum++)
391         {
392                 for (old_dbnum = 0; old_dbnum < old_cluster.dbarr.ndbs; old_dbnum++)
393                         if (strcmp(old_cluster.dbarr.dbs[old_dbnum].db_name,
394                                            new_cluster.dbarr.dbs[new_dbnum].db_name) == 0)
395                                 break;
396                 if (old_dbnum == old_cluster.dbarr.ndbs)
397                         pg_log(PG_FATAL, "New cluster database \"%s\" does not exist in the old cluster\n",
398                                    new_cluster.dbarr.dbs[new_dbnum].db_name);
399         }
400 }
401
402
403 /*
404  * create_script_for_old_cluster_deletion()
405  *
406  *      This is particularly useful for tablespace deletion.
407  */
408 void
409 create_script_for_old_cluster_deletion(
410                                                                            char **deletion_script_file_name)
411 {
412         FILE       *script = NULL;
413         int                     tblnum;
414
415         *deletion_script_file_name = pg_malloc(MAXPGPATH);
416
417         prep_status("Creating script to delete old cluster");
418
419         snprintf(*deletion_script_file_name, MAXPGPATH, "%s/delete_old_cluster.%s",
420                          os_info.cwd, SCRIPT_EXT);
421
422         if ((script = fopen(*deletion_script_file_name, "w")) == NULL)
423                 pg_log(PG_FATAL, "Could not create necessary file:  %s\n",
424                            *deletion_script_file_name);
425
426 #ifndef WIN32
427         /* add shebang header */
428         fprintf(script, "#!/bin/sh\n\n");
429 #endif
430
431         /* delete old cluster's default tablespace */
432         fprintf(script, RMDIR_CMD " %s\n", old_cluster.pgdata);
433
434         /* delete old cluster's alternate tablespaces */
435         for (tblnum = 0; tblnum < os_info.num_tablespaces; tblnum++)
436         {
437                 /*
438                  * Do the old cluster's per-database directories share a directory
439                  * with a new version-specific tablespace?
440                  */
441                 if (strlen(old_cluster.tablespace_suffix) == 0)
442                 {
443                         /* delete per-database directories */
444                         int                     dbnum;
445
446                         fprintf(script, "\n");
447                         /* remove PG_VERSION? */
448                         if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
449                                 fprintf(script, RM_CMD " %s%s/PG_VERSION\n",
450                                  os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
451
452                         for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
453                         {
454                                 fprintf(script, RMDIR_CMD " %s%s/%d\n",
455                                   os_info.tablespaces[tblnum], old_cluster.tablespace_suffix,
456                                                 old_cluster.dbarr.dbs[dbnum].db_oid);
457                         }
458                 }
459                 else
460
461                         /*
462                          * Simply delete the tablespace directory, which might be ".old"
463                          * or a version-specific subdirectory.
464                          */
465                         fprintf(script, RMDIR_CMD " %s%s\n",
466                                  os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
467         }
468
469         fclose(script);
470
471 #ifndef WIN32
472         if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
473                 pg_log(PG_FATAL, "Could not add execute permission to file:  %s\n",
474                            *deletion_script_file_name);
475 #endif
476
477         check_ok();
478 }
479
480
481 /*
482  *      check_is_super_user()
483  *
484  *      Make sure we are the super-user.
485  */
486 static void
487 check_is_super_user(ClusterInfo *cluster)
488 {
489         PGresult   *res;
490         PGconn     *conn = connectToServer(cluster, "template1");
491
492         prep_status("Checking database user is a superuser");
493
494         /* Can't use pg_authid because only superusers can view it. */
495         res = executeQueryOrDie(conn,
496                                                         "SELECT rolsuper "
497                                                         "FROM pg_catalog.pg_roles "
498                                                         "WHERE rolname = current_user");
499
500         if (PQntuples(res) != 1 || strcmp(PQgetvalue(res, 0, 0), "t") != 0)
501                 pg_log(PG_FATAL, "database user \"%s\" is not a superuser\n",
502                            os_info.user);
503
504         PQclear(res);
505
506         PQfinish(conn);
507
508         check_ok();
509 }
510
511
512 /*
513  *      check_for_prepared_transactions()
514  *
515  *      Make sure there are no prepared transactions because the storage format
516  *      might have changed.
517  */
518 static void
519 check_for_prepared_transactions(ClusterInfo *cluster)
520 {
521         PGresult   *res;
522         PGconn     *conn = connectToServer(cluster, "template1");
523
524         prep_status("Checking for prepared transactions");
525
526         res = executeQueryOrDie(conn,
527                                                         "SELECT * "
528                                                         "FROM pg_catalog.pg_prepared_xact()");
529
530         if (PQntuples(res) != 0)
531                 pg_log(PG_FATAL, "The %s cluster contains prepared transactions\n",
532                            CLUSTER_NAME(cluster));
533
534         PQclear(res);
535
536         PQfinish(conn);
537
538         check_ok();
539 }
540
541
542 /*
543  *      check_for_isn_and_int8_passing_mismatch()
544  *
545  *      contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
546  *      by value.  The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
547  *      it must match for the old and new servers.
548  */
549 static void
550 check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
551 {
552         int                     dbnum;
553         FILE       *script = NULL;
554         bool            found = false;
555         char            output_path[MAXPGPATH];
556
557         prep_status("Checking for contrib/isn with bigint-passing mismatch");
558
559         if (old_cluster.controldata.float8_pass_by_value ==
560                 new_cluster.controldata.float8_pass_by_value)
561         {
562                 /* no mismatch */
563                 check_ok();
564                 return;
565         }
566
567         snprintf(output_path, sizeof(output_path), "%s/contrib_isn_and_int8_pass_by_value.txt",
568                          os_info.cwd);
569
570         for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
571         {
572                 PGresult   *res;
573                 bool            db_used = false;
574                 int                     ntups;
575                 int                     rowno;
576                 int                     i_nspname,
577                                         i_proname;
578                 DbInfo     *active_db = &cluster->dbarr.dbs[dbnum];
579                 PGconn     *conn = connectToServer(cluster, active_db->db_name);
580
581                 /* Find any functions coming from contrib/isn */
582                 res = executeQueryOrDie(conn,
583                                                                 "SELECT n.nspname, p.proname "
584                                                                 "FROM   pg_catalog.pg_proc p, "
585                                                                 "               pg_catalog.pg_namespace n "
586                                                                 "WHERE  p.pronamespace = n.oid AND "
587                                                                 "               p.probin = '$libdir/isn'");
588
589                 ntups = PQntuples(res);
590                 i_nspname = PQfnumber(res, "nspname");
591                 i_proname = PQfnumber(res, "proname");
592                 for (rowno = 0; rowno < ntups; rowno++)
593                 {
594                         found = true;
595                         if (script == NULL && (script = fopen(output_path, "w")) == NULL)
596                                 pg_log(PG_FATAL, "Could not create necessary file:  %s\n", output_path);
597                         if (!db_used)
598                         {
599                                 fprintf(script, "Database:  %s\n", active_db->db_name);
600                                 db_used = true;
601                         }
602                         fprintf(script, "  %s.%s\n",
603                                         PQgetvalue(res, rowno, i_nspname),
604                                         PQgetvalue(res, rowno, i_proname));
605                 }
606
607                 PQclear(res);
608
609                 PQfinish(conn);
610         }
611
612         if (script)
613                 fclose(script);
614
615         if (found)
616         {
617                 pg_log(PG_REPORT, "fatal\n");
618                 pg_log(PG_FATAL,
619                            "| Your installation contains \"contrib/isn\" functions\n"
620                            "| which rely on the bigint data type.  Your old and\n"
621                            "| new clusters pass bigint values differently so this\n"
622                            "| cluster cannot currently be upgraded.  You can\n"
623                            "| manually upgrade data that use \"contrib/isn\"\n"
624                            "| facilities and remove \"contrib/isn\" from the\n"
625                            "| old cluster and restart the upgrade.  A list\n"
626                            "| of the problem functions is in the file:\n"
627                            "| \t%s\n\n", output_path);
628         }
629         else
630                 check_ok();
631 }
632
633
634 /*
635  * check_for_reg_data_type_usage()
636  *      pg_upgrade only preserves these system values:
637  *              pg_class.relfilenode
638  *              pg_type.oid
639  *              pg_enum.oid
640  *
641  *      Most of the reg* data types reference system catalog info that is
642  *      not preserved, and hence these data types cannot be used in user
643  *      tables upgraded by pg_upgrade.
644  */
645 static void
646 check_for_reg_data_type_usage(ClusterInfo *cluster)
647 {
648         int                     dbnum;
649         FILE       *script = NULL;
650         bool            found = false;
651         char            output_path[MAXPGPATH];
652
653         prep_status("Checking for reg* system oid user data types");
654
655         snprintf(output_path, sizeof(output_path), "%s/tables_using_reg.txt",
656                          os_info.cwd);
657
658         for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
659         {
660                 PGresult   *res;
661                 bool            db_used = false;
662                 int                     ntups;
663                 int                     rowno;
664                 int                     i_nspname,
665                                         i_relname,
666                                         i_attname;
667                 DbInfo     *active_db = &cluster->dbarr.dbs[dbnum];
668                 PGconn     *conn = connectToServer(cluster, active_db->db_name);
669
670                 res = executeQueryOrDie(conn,
671                                                                 "SELECT n.nspname, c.relname, a.attname "
672                                                                 "FROM   pg_catalog.pg_class c, "
673                                                                 "               pg_catalog.pg_namespace n, "
674                                                                 "               pg_catalog.pg_attribute a "
675                                                                 "WHERE  c.oid = a.attrelid AND "
676                                                                 "               NOT a.attisdropped AND "
677                                                                 "               a.atttypid IN ( "
678                   "                     'pg_catalog.regproc'::pg_catalog.regtype, "
679                                                                 "                       'pg_catalog.regprocedure'::pg_catalog.regtype, "
680                   "                     'pg_catalog.regoper'::pg_catalog.regtype, "
681                                                                 "                       'pg_catalog.regoperator'::pg_catalog.regtype, "
682                  "                      'pg_catalog.regclass'::pg_catalog.regtype, "
683                 /* regtype.oid is preserved, so 'regtype' is OK */
684                 "                       'pg_catalog.regconfig'::pg_catalog.regtype, "
685                                                                 "                       'pg_catalog.regdictionary'::pg_catalog.regtype) AND "
686                                                                 "               c.relnamespace = n.oid AND "
687                                                           "             n.nspname != 'pg_catalog' AND "
688                                                  "              n.nspname != 'information_schema'");
689
690                 ntups = PQntuples(res);
691                 i_nspname = PQfnumber(res, "nspname");
692                 i_relname = PQfnumber(res, "relname");
693                 i_attname = PQfnumber(res, "attname");
694                 for (rowno = 0; rowno < ntups; rowno++)
695                 {
696                         found = true;
697                         if (script == NULL && (script = fopen(output_path, "w")) == NULL)
698                                 pg_log(PG_FATAL, "Could not create necessary file:  %s\n", output_path);
699                         if (!db_used)
700                         {
701                                 fprintf(script, "Database:  %s\n", active_db->db_name);
702                                 db_used = true;
703                         }
704                         fprintf(script, "  %s.%s.%s\n",
705                                         PQgetvalue(res, rowno, i_nspname),
706                                         PQgetvalue(res, rowno, i_relname),
707                                         PQgetvalue(res, rowno, i_attname));
708                 }
709
710                 PQclear(res);
711
712                 PQfinish(conn);
713         }
714
715         if (script)
716                 fclose(script);
717
718         if (found)
719         {
720                 pg_log(PG_REPORT, "fatal\n");
721                 pg_log(PG_FATAL,
722                            "| Your installation contains one of the reg* data types in\n"
723                            "| user tables.  These data types reference system oids that\n"
724                            "| are not preserved by pg_upgrade, so this cluster cannot\n"
725                            "| currently be upgraded.  You can remove the problem tables\n"
726                            "| and restart the upgrade.  A list of the problem columns\n"
727                            "| is in the file:\n"
728                            "| \t%s\n\n", output_path);
729         }
730         else
731                 check_ok();
732 }