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 ,
1616ControlData * 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? */
6768if (GET_MAJOR_VERSION (ctx -> old .major_version ) <=803 )
6869{
70+ old_8_3_check_for_isn_and_int8_passing_mismatch (ctx ,CLUSTER_OLD );
6971old_8_3_check_for_name_data_type_usage (ctx ,CLUSTER_OLD );
7072old_8_3_check_for_tsquery_usage (ctx ,CLUSTER_OLD );
7173if (ctx -> check )
@@ -439,3 +441,104 @@ create_script_for_old_cluster_deletion(migratorContext *ctx,
439441
440442check_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+ "FROMpg_catalog.pg_class c, "
487+ "pg_catalog.pg_namespace n, "
488+ "pg_catalog.pg_attribute a "
489+ "WHEREc.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+ }