@ -23,6 +23,7 @@ static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
static void check_for_user_defined_postfix_ops ( ClusterInfo * cluster ) ;
static void check_for_incompatible_polymorphics ( ClusterInfo * cluster ) ;
static void check_for_tables_with_oids ( ClusterInfo * cluster ) ;
static void check_for_not_null_inheritance ( ClusterInfo * cluster ) ;
static void check_for_pg_role_prefix ( ClusterInfo * cluster ) ;
static void check_for_new_tablespace_dir ( void ) ;
static void check_for_user_defined_encoding_conversions ( ClusterInfo * cluster ) ;
@ -671,6 +672,14 @@ check_and_dump_old_cluster(void)
if ( GET_MAJOR_VERSION ( old_cluster . major_version ) < = 1100 )
check_for_tables_with_oids ( & old_cluster ) ;
/*
* Pre - PG 18 allowed child tables to omit not - null constraints that their
* parents columns have , but schema restore fails for them . Verify there
* are none , iff applicable .
*/
if ( GET_MAJOR_VERSION ( old_cluster . major_version ) < = 1800 )
check_for_not_null_inheritance ( & old_cluster ) ;
/*
* Pre - PG 10 allowed tables with ' unknown ' type columns and non WAL logged
* hash indexes
@ -1623,6 +1632,93 @@ check_for_tables_with_oids(ClusterInfo *cluster)
check_ok ( ) ;
}
/*
* Callback function for processing results of query for
* check_for_not_null_inheritance .
*/
static void
process_inconsistent_notnull ( DbInfo * dbinfo , PGresult * res , void * arg )
{
UpgradeTaskReport * report = ( UpgradeTaskReport * ) arg ;
int ntups = PQntuples ( res ) ;
int i_nspname = PQfnumber ( res , " nspname " ) ;
int i_relname = PQfnumber ( res , " relname " ) ;
int i_attname = PQfnumber ( res , " attname " ) ;
AssertVariableIsOfType ( & process_inconsistent_notnull ,
UpgradeTaskProcessCB ) ;
if ( ntups = = 0 )
return ;
if ( report - > file = = NULL & &
( report - > file = fopen_priv ( report - > path , " w " ) ) = = NULL )
pg_fatal ( " could not open file \" %s \" : %m " , report - > path ) ;
fprintf ( report - > file , " In database: %s \n " , dbinfo - > db_name ) ;
for ( int rowno = 0 ; rowno < ntups ; rowno + + )
{
fprintf ( report - > file , " %s.%s.%s \n " ,
PQgetvalue ( res , rowno , i_nspname ) ,
PQgetvalue ( res , rowno , i_relname ) ,
PQgetvalue ( res , rowno , i_attname ) ) ;
}
}
/*
* check_for_not_null_inheritance ( )
*
* An attempt to create child tables lacking not - null constraints that are
* present in their parents errors out . This can no longer occur since 18 ,
* but previously there were various ways for that to happen . Check that
* the cluster to be upgraded doesn ' t have any of those problems .
*/
static void
check_for_not_null_inheritance ( ClusterInfo * cluster )
{
UpgradeTaskReport report ;
UpgradeTask * task ;
const char * query ;
prep_status ( " Checking for not-null constraint inconsistencies " ) ;
report . file = NULL ;
snprintf ( report . path , sizeof ( report . path ) , " %s/%s " ,
log_opts . basedir ,
" not_null_inconsistent_columns.txt " ) ;
query = " SELECT cc.relnamespace::pg_catalog.regnamespace AS nspname, "
" cc.relname, ac.attname "
" FROM pg_catalog.pg_inherits i, pg_catalog.pg_attribute ac, "
" pg_catalog.pg_attribute ap, pg_catalog.pg_class cc "
" WHERE cc.oid = ac.attrelid AND i.inhrelid = ac.attrelid "
" AND i.inhparent = ap.attrelid AND ac.attname = ap.attname "
" AND ap.attnum > 0 and ap.attnotnull AND NOT ac.attnotnull " ;
task = upgrade_task_create ( ) ;
upgrade_task_add_step ( task , query ,
process_inconsistent_notnull ,
true , & report ) ;
upgrade_task_run ( task , cluster ) ;
upgrade_task_free ( task ) ;
if ( report . file )
{
fclose ( report . file ) ;
pg_log ( PG_REPORT , " fatal " ) ;
pg_fatal ( " Your installation contains inconsistent NOT NULL constraints. \n "
" If the parent column(s) are NOT NULL, then the child column must \n "
" also be marked NOT NULL, or the upgrade will fail. \n "
" You can fix this by running \n "
" ALTER TABLE tablename ALTER column SET NOT NULL; \n "
" on each column listed in the file: \n "
" %s " , report . path ) ;
}
else
check_ok ( ) ;
}
/*
* check_for_pg_role_prefix ( )