44 * server checks and output routines
55 *
66 * Copyright (c) 2010, PostgreSQL Global Development Group
7- * $PostgreSQL: pgsql/contrib/pg_upgrade/check.c,v 1.12 2010/07/13 15:56:53 momjian Exp $
7+ * $PostgreSQL: pgsql/contrib/pg_upgrade/check.c,v 1.13 2010/07/25 03:28:32 momjian Exp $
88 */
99
1010#include "pg_upgrade.h"
@@ -14,6 +14,7 @@ static void set_locale_and_encoding(migratorContext *ctx, Cluster whichCluster);
1414static void check_new_db_is_empty (migratorContext * ctx );
1515static void check_locale_and_encoding (migratorContext * ctx , ControlData * oldctrl ,
1616 ControlData * newctrl );
17+ static void check_for_reg_data_type_usage (migratorContext * ctx , Cluster whichCluster );
1718
1819
1920void
@@ -61,11 +62,12 @@ check_old_cluster(migratorContext *ctx, bool live_check,
6162 * Check for various failure cases
6263 */
6364
64- old_8_3_check_for_isn_and_int8_passing_mismatch (ctx , CLUSTER_OLD );
65+ check_for_reg_data_type_usage (ctx , CLUSTER_OLD );
6566
6667 /* old = PG 8.3 checks? */
6768 if (GET_MAJOR_VERSION (ctx -> old .major_version ) <= 803 )
6869 {
70+ old_8_3_check_for_isn_and_int8_passing_mismatch (ctx , CLUSTER_OLD );
6971 old_8_3_check_for_name_data_type_usage (ctx , CLUSTER_OLD );
7072 old_8_3_check_for_tsquery_usage (ctx , CLUSTER_OLD );
7173 if (ctx -> check )
@@ -439,3 +441,104 @@ create_script_for_old_cluster_deletion(migratorContext *ctx,
439441
440442 check_ok (ctx );
441443}
444+
445+
446+ /*
447+ * check_for_reg_data_type_usage()
448+ * pg_upgrade only preserves these system values:
449+ * pg_class.relfilenode
450+ * pg_type.oid
451+ * pg_enum.oid
452+ *
453+ * Most of the reg* data types reference system catalog info that is
454+ * not preserved, and hence these data types cannot be used in user
455+ * tables upgraded by pg_upgrade.
456+ */
457+ void
458+ check_for_reg_data_type_usage (migratorContext * ctx , Cluster whichCluster )
459+ {
460+ ClusterInfo * active_cluster = (whichCluster == CLUSTER_OLD ) ?
461+ & ctx -> old : & ctx -> new ;
462+ int dbnum ;
463+ FILE * script = NULL ;
464+ bool found = false;
465+ char output_path [MAXPGPATH ];
466+
467+ prep_status (ctx , "Checking for reg* system oid user data types" );
468+
469+ snprintf (output_path , sizeof (output_path ), "%s/tables_using_reg.txt" ,
470+ ctx -> cwd );
471+
472+ for (dbnum = 0 ; dbnum < active_cluster -> dbarr .ndbs ; dbnum ++ )
473+ {
474+ PGresult * res ;
475+ bool db_used = false;
476+ int ntups ;
477+ int rowno ;
478+ int i_nspname ,
479+ i_relname ,
480+ i_attname ;
481+ DbInfo * active_db = & active_cluster -> dbarr .dbs [dbnum ];
482+ PGconn * conn = connectToServer (ctx , active_db -> db_name , whichCluster );
483+
484+ res = executeQueryOrDie (ctx , conn ,
485+ "SELECT n.nspname, c.relname, a.attname "
486+ "FROM pg_catalog.pg_class c, "
487+ " pg_catalog.pg_namespace n, "
488+ " pg_catalog.pg_attribute a "
489+ "WHERE c.oid = a.attrelid AND "
490+ " NOT a.attisdropped AND "
491+ " a.atttypid IN ( "
492+ " 'pg_catalog.regproc'::pg_catalog.regtype, "
493+ " 'pg_catalog.regprocedure'::pg_catalog.regtype, "
494+ " 'pg_catalog.regoper'::pg_catalog.regtype, "
495+ " 'pg_catalog.regoperator'::pg_catalog.regtype, "
496+ " 'pg_catalog.regclass'::pg_catalog.regtype, "
497+ /* regtype.oid is preserved, so 'regtype' is OK */
498+ " 'pg_catalog.regconfig'::pg_catalog.regtype, "
499+ " 'pg_catalog.regdictionary'::pg_catalog.regtype) AND "
500+ " c.relnamespace = n.oid AND "
501+ " n.nspname != 'pg_catalog' AND "
502+ " n.nspname != 'information_schema'" );
503+
504+ ntups = PQntuples (res );
505+ i_nspname = PQfnumber (res , "nspname" );
506+ i_relname = PQfnumber (res , "relname" );
507+ i_attname = PQfnumber (res , "attname" );
508+ for (rowno = 0 ; rowno < ntups ; rowno ++ )
509+ {
510+ found = true;
511+ if (script == NULL && (script = fopen (output_path , "w" )) == NULL )
512+ pg_log (ctx , PG_FATAL , "Could not create necessary file: %s\n" , output_path );
513+ if (!db_used )
514+ {
515+ fprintf (script , "Database: %s\n" , active_db -> db_name );
516+ db_used = true;
517+ }
518+ fprintf (script , " %s.%s.%s\n" ,
519+ PQgetvalue (res , rowno , i_nspname ),
520+ PQgetvalue (res , rowno , i_relname ),
521+ PQgetvalue (res , rowno , i_attname ));
522+ }
523+
524+ PQclear (res );
525+
526+ PQfinish (conn );
527+ }
528+
529+ if (found )
530+ {
531+ fclose (script );
532+ pg_log (ctx , PG_REPORT , "fatal\n" );
533+ pg_log (ctx , PG_FATAL ,
534+ "| Your installation contains one of the reg* data types in\n"
535+ "| user tables. These data types reference system oids that\n"
536+ "| are not preserved by pg_upgrade, so this cluster cannot\n"
537+ "| currently be upgraded. You can remove the problem tables\n"
538+ "| and restart the migration. A list of the problem columns\n"
539+ "| is in the file:\n"
540+ "| \t%s\n\n" , output_path );
541+ }
542+ else
543+ check_ok (ctx );
544+ }
0 commit comments