OSDN Git Service

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