@ -15670,6 +15670,7 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
DumpOptions * dopt = fout - > dopt ;
PQExpBuffer q = createPQExpBuffer ( ) ;
PQExpBuffer delq = createPQExpBuffer ( ) ;
PQExpBuffer extra = createPQExpBuffer ( ) ;
char * qrelname ;
char * qualrelname ;
int numParents ;
@ -15736,7 +15737,7 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
char * partkeydef = NULL ;
char * ftoptions = NULL ;
char * srvname = NULL ;
char * foreign = " " ;
const char * foreign = " " ;
/*
* Set reltypename , and collect any relkind - specific data that we
@ -16094,51 +16095,98 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
tbinfo - > relkind = = RELKIND_FOREIGN_TABLE | |
tbinfo - > relkind = = RELKIND_PARTITIONED_TABLE ) )
{
bool firstitem ;
/*
* Drop any dropped columns . Merge the pg_attribute manipulations
* into a single SQL command , so that we don ' t cause repeated
* relcache flushes on the target table . Otherwise we risk O ( N ^ 2 )
* relcache bloat while dropping N columns .
*/
resetPQExpBuffer ( extra ) ;
firstitem = true ;
for ( j = 0 ; j < tbinfo - > numatts ; j + + )
{
if ( tbinfo - > attisdropped [ j ] )
{
appendPQExpBufferStr ( q , " \n -- For binary upgrade, recreate dropped column. \n " ) ;
appendPQExpBuffer ( q , " UPDATE pg_catalog.pg_attribute \n "
" SET attlen = %d, "
" attalign = '%c', attbyval = false \n "
" WHERE attname = " ,
if ( firstitem )
{
appendPQExpBufferStr ( q , " \n -- For binary upgrade, recreate dropped columns. \n "
" UPDATE pg_catalog.pg_attribute \n "
" SET attlen = v.dlen, "
" attalign = v.dalign, "
" attbyval = false \n "
" FROM (VALUES " ) ;
firstitem = false ;
}
else
appendPQExpBufferStr ( q , " , \n " ) ;
appendPQExpBufferChar ( q , ' ( ' ) ;
appendStringLiteralAH ( q , tbinfo - > attnames [ j ] , fout ) ;
appendPQExpBuffer ( q , " , %d, '%c') " ,
tbinfo - > attlen [ j ] ,
tbinfo - > attalign [ j ] ) ;
appendStringLiteralAH ( q , tbinfo - > attnames [ j ] , fout ) ;
appendPQExpBufferStr ( q , " \n AND attrelid = " ) ;
appendStringLiteralAH ( q , qualrelname , fout ) ;
appendPQExpBufferStr ( q , " ::pg_catalog.regclass; \n " ) ;
if ( tbinfo - > relkind = = RELKIND_RELATION | |
tbinfo - > relkind = = RELKIND_PARTITIONED_TABLE )
appendPQExpBuffer ( q , " ALTER TABLE ONLY %s " ,
qualrelname ) ;
else
appendPQExpBuffer ( q , " ALTER FOREIGN TABLE ONLY %s " ,
qualrelname ) ;
appendPQExpBuffer ( q , " DROP COLUMN %s; \n " ,
/* The ALTER ... DROP COLUMN commands must come after */
appendPQExpBuffer ( extra , " ALTER %sTABLE ONLY %s " ,
foreign , qualrelname ) ;
appendPQExpBuffer ( extra , " DROP COLUMN %s; \n " ,
fmtId ( tbinfo - > attnames [ j ] ) ) ;
}
else if ( ! tbinfo - > attislocal [ j ] )
}
if ( ! firstitem )
{
appendPQExpBufferStr ( q , " ) v(dname, dlen, dalign) \n "
" WHERE attrelid = " ) ;
appendStringLiteralAH ( q , qualrelname , fout ) ;
appendPQExpBufferStr ( q , " ::pg_catalog.regclass \n "
" AND attname = v.dname; \n " ) ;
/* Now we can issue the actual DROP COLUMN commands */
appendBinaryPQExpBuffer ( q , extra - > data , extra - > len ) ;
}
/*
* Fix up inherited columns . As above , do the pg_attribute
* manipulations in a single SQL command .
*/
firstitem = true ;
for ( j = 0 ; j < tbinfo - > numatts ; j + + )
{
if ( ! tbinfo - > attisdropped [ j ] & &
! tbinfo - > attislocal [ j ] )
{
appendPQExpBufferStr ( q , " \n -- For binary upgrade, recreate inherited column. \n " ) ;
appendPQExpBufferStr ( q , " UPDATE pg_catalog.pg_attribute \n "
" SET attislocal = false \n "
" WHERE attname = " ) ;
if ( firstitem )
{
appendPQExpBufferStr ( q , " \n -- For binary upgrade, recreate inherited columns. \n " ) ;
appendPQExpBufferStr ( q , " UPDATE pg_catalog.pg_attribute \n "
" SET attislocal = false \n "
" WHERE attrelid = " ) ;
appendStringLiteralAH ( q , qualrelname , fout ) ;
appendPQExpBufferStr ( q , " ::pg_catalog.regclass \n "
" AND attname IN ( " ) ;
firstitem = false ;
}
else
appendPQExpBufferStr ( q , " , " ) ;
appendStringLiteralAH ( q , tbinfo - > attnames [ j ] , fout ) ;
appendPQExpBufferStr ( q , " \n AND attrelid = " ) ;
appendStringLiteralAH ( q , qualrelname , fout ) ;
appendPQExpBufferStr ( q , " ::pg_catalog.regclass; \n " ) ;
}
}
if ( ! firstitem )
appendPQExpBufferStr ( q , " ); \n " ) ;
/*
* Add inherited CHECK constraints , if any .
*
* For partitions , they were already dumped , and conislocal
* doesn ' t need fixing .
*
* As above , issue only one direct manipulation of pg_constraint .
* Although it is tempting to merge the ALTER ADD CONSTRAINT
* commands into one as well , refrain for now due to concern about
* possible backend memory bloat if there are many such
* constraints .
*/
resetPQExpBuffer ( extra ) ;
firstitem = true ;
for ( k = 0 ; k < tbinfo - > ncheck ; k + + )
{
ConstraintInfo * constr = & ( tbinfo - > checkexprs [ k ] ) ;
@ -16146,18 +16194,31 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
if ( constr - > separate | | constr - > conislocal | | tbinfo - > ispartition )
continue ;
appendPQExpBufferStr ( q , " \n -- For binary upgrade, set up inherited constraint. \n " ) ;
if ( firstitem )
appendPQExpBufferStr ( q , " \n -- For binary upgrade, set up inherited constraints. \n " ) ;
appendPQExpBuffer ( q , " ALTER %sTABLE ONLY %s ADD CONSTRAINT %s %s; \n " ,
foreign , qualrelname ,
fmtId ( constr - > dobj . name ) ,
constr - > condef ) ;
appendPQExpBufferStr ( q , " UPDATE pg_catalog.pg_constraint \n "
" SET conislocal = false \n "
" WHERE contype = 'c' AND conname = " ) ;
appendStringLiteralAH ( q , constr - > dobj . name , fout ) ;
appendPQExpBufferStr ( q , " \n AND conrelid = " ) ;
appendStringLiteralAH ( q , qualrelname , fout ) ;
appendPQExpBufferStr ( q , " ::pg_catalog.regclass; \n " ) ;
/* Update pg_constraint after all the ALTER TABLEs */
if ( firstitem )
{
appendPQExpBufferStr ( extra , " UPDATE pg_catalog.pg_constraint \n "
" SET conislocal = false \n "
" WHERE contype = 'c' AND conrelid = " ) ;
appendStringLiteralAH ( extra , qualrelname , fout ) ;
appendPQExpBufferStr ( extra , " ::pg_catalog.regclass \n " ) ;
appendPQExpBufferStr ( extra , " AND conname IN ( " ) ;
firstitem = false ;
}
else
appendPQExpBufferStr ( extra , " , " ) ;
appendStringLiteralAH ( extra , constr - > dobj . name , fout ) ;
}
if ( ! firstitem )
{
appendPQExpBufferStr ( extra , " ); \n " ) ;
appendBinaryPQExpBuffer ( q , extra - > data , extra - > len ) ;
}
if ( numParents > 0 & & ! tbinfo - > ispartition )
@ -16344,7 +16405,7 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
if ( tbinfo - > relkind = = RELKIND_FOREIGN_TABLE & &
tbinfo - > attfdwoptions [ j ] [ 0 ] ! = ' \0 ' )
appendPQExpBuffer ( q ,
" ALTER FOREIGN TABLE %s ALTER COLUMN %s OPTIONS ( \n "
" ALTER FOREIGN TABLE ONLY %s ALTER COLUMN %s OPTIONS ( \n "
" %s \n "
" ); \n " ,
qualrelname ,
@ -16445,6 +16506,7 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
destroyPQExpBuffer ( q ) ;
destroyPQExpBuffer ( delq ) ;
destroyPQExpBuffer ( extra ) ;
free ( qrelname ) ;
free ( qualrelname ) ;
}