@ -163,6 +163,13 @@ static int nseclabels = 0;
*/
*/
# define DUMP_DEFAULT_ROWS_PER_INSERT 1
# define DUMP_DEFAULT_ROWS_PER_INSERT 1
/*
* Maximum number of large objects to group into a single ArchiveEntry .
* At some point we might want to make this user - controllable , but for now
* a hard - wired setting will suffice .
*/
# define MAX_BLOBS_PER_ARCHIVE_ENTRY 1000
/*
/*
* Macro for producing quoted , schema - qualified name of a dumpable object .
* Macro for producing quoted , schema - qualified name of a dumpable object .
*/
*/
@ -267,7 +274,7 @@ static void dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo);
static DumpId dumpACL ( Archive * fout , DumpId objDumpId , DumpId altDumpId ,
static DumpId dumpACL ( Archive * fout , DumpId objDumpId , DumpId altDumpId ,
const char * type , const char * name , const char * subname ,
const char * type , const char * name , const char * subname ,
const char * nspname , const char * owner ,
const char * nspname , const char * tag , const char * owner ,
const DumpableAcl * dacl ) ;
const DumpableAcl * dacl ) ;
static void getDependencies ( Archive * fout ) ;
static void getDependencies ( Archive * fout ) ;
@ -3291,7 +3298,7 @@ dumpDatabase(Archive *fout)
dumpACL ( fout , dbDumpId , InvalidDumpId , " DATABASE " ,
dumpACL ( fout , dbDumpId , InvalidDumpId , " DATABASE " ,
qdatname , NULL , NULL ,
qdatname , NULL , NULL ,
dba , & dbdacl ) ;
NULL , dba , & dbdacl ) ;
/*
/*
* Now construct a DATABASE PROPERTIES archive entry to restore any
* Now construct a DATABASE PROPERTIES archive entry to restore any
@ -3612,11 +3619,10 @@ getLOs(Archive *fout)
{
{
DumpOptions * dopt = fout - > dopt ;
DumpOptions * dopt = fout - > dopt ;
PQExpBuffer loQry = createPQExpBuffer ( ) ;
PQExpBuffer loQry = createPQExpBuffer ( ) ;
LoInfo * loinfo ;
DumpableObject * lodata ;
PGresult * res ;
PGresult * res ;
int ntups ;
int ntups ;
int i ;
int i ;
int n ;
int i_oid ;
int i_oid ;
int i_lomowner ;
int i_lomowner ;
int i_lomacl ;
int i_lomacl ;
@ -3624,11 +3630,15 @@ getLOs(Archive *fout)
pg_log_info ( " reading large objects " ) ;
pg_log_info ( " reading large objects " ) ;
/* Fetch LO OIDs, and owner/ACL data */
/*
* Fetch LO OIDs and owner / ACL data . Order the data so that all the blobs
* with the same owner / ACL appear together .
*/
appendPQExpBufferStr ( loQry ,
appendPQExpBufferStr ( loQry ,
" SELECT oid, lomowner, lomacl, "
" SELECT oid, lomowner, lomacl, "
" acldefault('L', lomowner) AS acldefault "
" acldefault('L', lomowner) AS acldefault "
" FROM pg_largeobject_metadata " ) ;
" FROM pg_largeobject_metadata "
" ORDER BY lomowner, lomacl::pg_catalog.text, oid " ) ;
res = ExecuteSqlQuery ( fout , loQry - > data , PGRES_TUPLES_OK ) ;
res = ExecuteSqlQuery ( fout , loQry - > data , PGRES_TUPLES_OK ) ;
@ -3640,30 +3650,72 @@ getLOs(Archive *fout)
ntups = PQntuples ( res ) ;
ntups = PQntuples ( res ) ;
/*
/*
* Each large object has its own " BLOB " archive entry .
* Group the blobs into suitably - sized groups that have the same owner and
* ACL setting , and build a metadata and a data DumpableObject for each
* group . ( If we supported initprivs for blobs , we ' d have to insist that
* groups also share initprivs settings , since the DumpableObject only has
* room for one . ) i is the index of the first tuple in the current group ,
* and n is the number of tuples we include in the group .
*/
*/
loinfo = ( LoInfo * ) pg_malloc ( ntups * sizeof ( LoInfo ) ) ;
for ( i = 0 ; i < ntups ; i + = n )
{
Oid thisoid = atooid ( PQgetvalue ( res , i , i_oid ) ) ;
char * thisowner = PQgetvalue ( res , i , i_lomowner ) ;
char * thisacl = PQgetvalue ( res , i , i_lomacl ) ;
LoInfo * loinfo ;
DumpableObject * lodata ;
char namebuf [ 64 ] ;
for ( i = 0 ; i < ntups ; i + + )
/* Scan to find first tuple not to be included in group */
n = 1 ;
while ( n < MAX_BLOBS_PER_ARCHIVE_ENTRY & & i + n < ntups )
{
if ( strcmp ( thisowner , PQgetvalue ( res , i + n , i_lomowner ) ) ! = 0 | |
strcmp ( thisacl , PQgetvalue ( res , i + n , i_lomacl ) ) ! = 0 )
break ;
n + + ;
}
/* Build the metadata DumpableObject */
loinfo = ( LoInfo * ) pg_malloc ( offsetof ( LoInfo , looids ) + n * sizeof ( Oid ) ) ;
loinfo - > dobj . objType = DO_LARGE_OBJECT ;
loinfo - > dobj . catId . tableoid = LargeObjectRelationId ;
loinfo - > dobj . catId . oid = thisoid ;
AssignDumpId ( & loinfo - > dobj ) ;
if ( n > 1 )
snprintf ( namebuf , sizeof ( namebuf ) , " %u..%u " , thisoid ,
atooid ( PQgetvalue ( res , i + n - 1 , i_oid ) ) ) ;
else
snprintf ( namebuf , sizeof ( namebuf ) , " %u " , thisoid ) ;
loinfo - > dobj . name = pg_strdup ( namebuf ) ;
loinfo - > dacl . acl = pg_strdup ( thisacl ) ;
loinfo - > dacl . acldefault = pg_strdup ( PQgetvalue ( res , i , i_acldefault ) ) ;
loinfo - > dacl . privtype = 0 ;
loinfo - > dacl . initprivs = NULL ;
loinfo - > rolname = getRoleName ( thisowner ) ;
loinfo - > numlos = n ;
loinfo - > looids [ 0 ] = thisoid ;
/* Collect OIDs of the remaining blobs in this group */
for ( int k = 1 ; k < n ; k + + )
{
{
loinfo [ i ] . dobj . objType = DO_LARGE_OBJECT ;
CatalogId extraID ;
loinfo [ i ] . dobj . catId . tableoid = LargeObjectRelationId ;
loinfo [ i ] . dobj . catId . oid = atooid ( PQgetvalue ( res , i , i_oid ) ) ;
AssignDumpId ( & loinfo [ i ] . dobj ) ;
loinfo [ i ] . dobj . name = pg_strdup ( PQgetvalue ( res , i , i_oid ) ) ;
loinfo - > looids [ k ] = atooid ( PQgetvalue ( res , i + k , i_oid ) ) ;
loinfo [ i ] . dacl . acl = pg_strdup ( PQgetvalue ( res , i , i_lomacl ) ) ;
loinfo [ i ] . dacl . acldefault = pg_strdup ( PQgetvalue ( res , i , i_acldefault ) ) ;
/* Make sure we can look up loinfo by any of the blobs' OIDs */
loinfo [ i ] . dacl . privtype = 0 ;
extraID . tableoid = LargeObjectRelationId ;
loinfo [ i ] . dacl . initprivs = NULL ;
extraID . oid = loinfo - > looids [ k ] ;
loinfo [ i ] . rolname = getRoleName ( PQgetvalue ( res , i , i_lomowner ) ) ;
recordAdditionalCatalogID ( extraID , & loinfo - > dobj ) ;
}
/* LOs have data */
/* LOs have data */
loinfo [ i ] . dobj . components | = DUMP_COMPONENT_DATA ;
loinfo - > dobj . components | = DUMP_COMPONENT_DATA ;
/* Mark whether LO has an ACL */
/* Mark whether LO group has a non-empty ACL */
if ( ! PQgetisnull ( res , i , i_lomacl ) )
if ( ! PQgetisnull ( res , i , i_lomacl ) )
loinfo [ i ] . dobj . components | = DUMP_COMPONENT_ACL ;
loinfo - > dobj . components | = DUMP_COMPONENT_ACL ;
/*
/*
* In binary - upgrade mode for LOs , we do * not * dump out the LO data ,
* In binary - upgrade mode for LOs , we do * not * dump out the LO data ,
@ -3673,21 +3725,22 @@ getLOs(Archive *fout)
* pg_largeobject_metadata , after the dump is restored .
* pg_largeobject_metadata , after the dump is restored .
*/
*/
if ( dopt - > binary_upgrade )
if ( dopt - > binary_upgrade )
loinfo [ i ] . dobj . dump & = ~ DUMP_COMPONENT_DATA ;
loinfo - > dobj . dump & = ~ DUMP_COMPONENT_DATA ;
}
/*
/*
* If we have any large objects , a " BLOBS " archive entry is needed . This
* Create a " BLOBS " data item for the group , too . This is just a
* is just a placeholder for sorting ; it carries no data now .
* placeholder for sorting ; it carries no data now .
*/
*/
if ( ntups > 0 )
{
lodata = ( DumpableObject * ) pg_malloc ( sizeof ( DumpableObject ) ) ;
lodata = ( DumpableObject * ) pg_malloc ( sizeof ( DumpableObject ) ) ;
lodata - > objType = DO_LARGE_OBJECT_DATA ;
lodata - > objType = DO_LARGE_OBJECT_DATA ;
lodata - > catId = nilCatalogId ;
lodata - > catId = nilCatalogId ;
AssignDumpId ( lodata ) ;
AssignDumpId ( lodata ) ;
lodata - > name = pg_strdup ( " BLOBS " ) ;
lodata - > name = pg_strdup ( namebuf ) ;
lodata - > components | = DUMP_COMPONENT_DATA ;
lodata - > components | = DUMP_COMPONENT_DATA ;
/* Set up explicit dependency from data to metadata */
lodata - > dependencies = ( DumpId * ) pg_malloc ( sizeof ( DumpId ) ) ;
lodata - > dependencies [ 0 ] = loinfo - > dobj . dumpId ;
lodata - > nDeps = lodata - > allocDeps = 1 ;
}
}
PQclear ( res ) ;
PQclear ( res ) ;
@ -3697,97 +3750,113 @@ getLOs(Archive *fout)
/*
/*
* dumpLO
* dumpLO
*
*
* dump the definition ( metadata ) of the given large object
* dump the definition ( metadata ) of the given large object group
*/
*/
static void
static void
dumpLO ( Archive * fout , const LoInfo * loinfo )
dumpLO ( Archive * fout , const LoInfo * loinfo )
{
{
PQExpBuffer cquery = createPQExpBuffer ( ) ;
PQExpBuffer cquery = createPQExpBuffer ( ) ;
PQExpBuffer dquery = createPQExpBuffer ( ) ;
appendPQExpBuffer ( cquery ,
/*
" SELECT pg_catalog.lo_create('%s'); \n " ,
* The " definition " is just a newline - separated list of OIDs . We need to
loinfo - > dobj . name ) ;
* put something into the dropStmt too , but it can just be a comment .
*/
appendPQExpBuffer ( dquery ,
for ( int i = 0 ; i < loinfo - > numlos ; i + + )
" SELECT pg_catalog.lo_unlink('%s'); \n " ,
appendPQExpBuffer ( cquery , " %u \n " , loinfo - > looids [ i ] ) ;
loinfo - > dobj . name ) ;
if ( loinfo - > dobj . dump & DUMP_COMPONENT_DEFINITION )
if ( loinfo - > dobj . dump & DUMP_COMPONENT_DEFINITION )
ArchiveEntry ( fout , loinfo - > dobj . catId , loinfo - > dobj . dumpId ,
ArchiveEntry ( fout , loinfo - > dobj . catId , loinfo - > dobj . dumpId ,
ARCHIVE_OPTS ( . tag = loinfo - > dobj . name ,
ARCHIVE_OPTS ( . tag = loinfo - > dobj . name ,
. owner = loinfo - > rolname ,
. owner = loinfo - > rolname ,
. description = " BLOB " ,
. description = " BLOB METADATA " ,
. section = SECTION_PRE_ DATA ,
. section = SECTION_DATA ,
. createStmt = cquery - > data ,
. createStmt = cquery - > data ,
. dropStmt = dquery - > data ) ) ;
. dropStmt = " -- dummy " ) ) ;
/*
* Dump per - blob comments and seclabels if any . We assume these are rare
* enough that it ' s okay to generate retail TOC entries for them .
*/
if ( loinfo - > dobj . dump & ( DUMP_COMPONENT_COMMENT |
DUMP_COMPONENT_SECLABEL ) )
{
for ( int i = 0 ; i < loinfo - > numlos ; i + + )
{
CatalogId catId ;
char namebuf [ 32 ] ;
/* Build identifying info for this blob */
catId . tableoid = loinfo - > dobj . catId . tableoid ;
catId . oid = loinfo - > looids [ i ] ;
snprintf ( namebuf , sizeof ( namebuf ) , " %u " , loinfo - > looids [ i ] ) ;
/* Dump comment if any */
if ( loinfo - > dobj . dump & DUMP_COMPONENT_COMMENT )
if ( loinfo - > dobj . dump & DUMP_COMPONENT_COMMENT )
dumpComment ( fout , " LARGE OBJECT " , loinfo - > dobj . name ,
dumpComment ( fout , " LARGE OBJECT " , namebuf ,
NULL , loinfo - > rolname ,
NULL , loinfo - > rolname ,
loinfo - > dobj . catId , 0 , loinfo - > dobj . dumpId ) ;
catId , 0 , loinfo - > dobj . dumpId ) ;
/* Dump security label if any */
if ( loinfo - > dobj . dump & DUMP_COMPONENT_SECLABEL )
if ( loinfo - > dobj . dump & DUMP_COMPONENT_SECLABEL )
dumpSecLabel ( fout , " LARGE OBJECT " , loinfo - > dobj . name ,
dumpSecLabel ( fout , " LARGE OBJECT " , namebuf ,
NULL , loinfo - > rolname ,
NULL , loinfo - > rolname ,
loinfo - > dobj . catId , 0 , loinfo - > dobj . dumpId ) ;
catId , 0 , loinfo - > dobj . dumpId ) ;
}
}
/* Dump ACL if any */
/*
* Dump the ACLs if any ( remember that all blobs in the group will have
* the same ACL ) . If there ' s just one blob , dump a simple ACL entry ; if
* there ' s more , make a " LARGE OBJECTS " entry that really contains only
* the ACL for the first blob . _printTocEntry ( ) will be cued by the tag
* string to emit a mutated version for each blob .
*/
if ( loinfo - > dobj . dump & DUMP_COMPONENT_ACL )
if ( loinfo - > dobj . dump & DUMP_COMPONENT_ACL )
dumpACL ( fout , loinfo - > dobj . dumpId , InvalidDumpId , " LARGE OBJECT " ,
{
loinfo - > dobj . name , NULL ,
char namebuf [ 32 ] ;
/* Build identifying info for the first blob */
snprintf ( namebuf , sizeof ( namebuf ) , " %u " , loinfo - > looids [ 0 ] ) ;
if ( loinfo - > numlos > 1 )
{
char tagbuf [ 64 ] ;
snprintf ( tagbuf , sizeof ( tagbuf ) , " LARGE OBJECTS %u..%u " ,
loinfo - > looids [ 0 ] , loinfo - > looids [ loinfo - > numlos - 1 ] ) ;
dumpACL ( fout , loinfo - > dobj . dumpId , InvalidDumpId ,
" LARGE OBJECT " , namebuf , NULL , NULL ,
tagbuf , loinfo - > rolname , & loinfo - > dacl ) ;
}
else
{
dumpACL ( fout , loinfo - > dobj . dumpId , InvalidDumpId ,
" LARGE OBJECT " , namebuf , NULL , NULL ,
NULL , loinfo - > rolname , & loinfo - > dacl ) ;
NULL , loinfo - > rolname , & loinfo - > dacl ) ;
}
}
destroyPQExpBuffer ( cquery ) ;
destroyPQExpBuffer ( cquery ) ;
destroyPQExpBuffer ( dquery ) ;
}
}
/*
/*
* dumpLOs :
* dumpLOs :
* dump the data contents of all large objects
* dump the data contents of the large objects in the given group
*/
*/
static int
static int
dumpLOs ( Archive * fout , const void * arg )
dumpLOs ( Archive * fout , const void * arg )
{
{
const char * loQry ;
const LoInfo * loinfo = ( const LoInfo * ) arg ;
const char * loFetchQry ;
PGconn * conn = GetConnection ( fout ) ;
PGconn * conn = GetConnection ( fout ) ;
PGresult * res ;
char buf [ LOBBUFSIZE ] ;
char buf [ LOBBUFSIZE ] ;
int ntups ;
int i ;
int cnt ;
pg_log_info ( " saving large objects " ) ;
/*
* Currently , we re - fetch all LO OIDs using a cursor . Consider scanning
* the already - in - memory dumpable objects instead . . .
*/
loQry =
" DECLARE looid CURSOR FOR "
" SELECT oid FROM pg_largeobject_metadata ORDER BY 1 " ;
ExecuteSqlStatement ( fout , loQry ) ;
/* Command to fetch from cursor */
pg_log_info ( " saving large objects \" %s \" " , loinfo - > dobj . name ) ;
loFetchQry = " FETCH 1000 IN looid " ;
do
{
/* Do a fetch */
res = ExecuteSqlQuery ( fout , loFetchQry , PGRES_TUPLES_OK ) ;
/* Process the tuples, if any */
for ( int i = 0 ; i < loinfo - > numlos ; i + + )
ntups = PQntuples ( res ) ;
for ( i = 0 ; i < ntups ; i + + )
{
{
Oid loOid ;
Oid loOid = loinfo - > looids [ i ] ;
int loFd ;
int loFd ;
int cnt ;
loOid = atooid ( PQgetvalue ( res , i , 0 ) ) ;
/* Open the LO */
/* Open the LO */
loFd = lo_open ( conn , loOid , INV_READ ) ;
loFd = lo_open ( conn , loOid , INV_READ ) ;
if ( loFd = = - 1 )
if ( loFd = = - 1 )
@ -3812,9 +3881,6 @@ dumpLOs(Archive *fout, const void *arg)
EndLO ( fout , loOid ) ;
EndLO ( fout , loOid ) ;
}
}
PQclear ( res ) ;
} while ( ntups > 0 ) ;
return 1 ;
return 1 ;
}
}
@ -10646,28 +10712,34 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
case DO_LARGE_OBJECT_DATA :
case DO_LARGE_OBJECT_DATA :
if ( dobj - > dump & DUMP_COMPONENT_DATA )
if ( dobj - > dump & DUMP_COMPONENT_DATA )
{
{
LoInfo * loinfo ;
TocEntry * te ;
TocEntry * te ;
loinfo = ( LoInfo * ) findObjectByDumpId ( dobj - > dependencies [ 0 ] ) ;
if ( loinfo = = NULL )
pg_fatal ( " missing metadata for large objects \" %s \" " ,
dobj - > name ) ;
te = ArchiveEntry ( fout , dobj - > catId , dobj - > dumpId ,
te = ArchiveEntry ( fout , dobj - > catId , dobj - > dumpId ,
ARCHIVE_OPTS ( . tag = dobj - > name ,
ARCHIVE_OPTS ( . tag = dobj - > name ,
. owner = loinfo - > rolname ,
. description = " BLOBS " ,
. description = " BLOBS " ,
. section = SECTION_DATA ,
. section = SECTION_DATA ,
. dumpFn = dumpLOs ) ) ;
. deps = dobj - > dependencies ,
. nDeps = dobj - > nDeps ,
. dumpFn = dumpLOs ,
. dumpArg = loinfo ) ) ;
/*
/*
* Set the TocEntry ' s dataLength in case we are doing a
* Set the TocEntry ' s dataLength in case we are doing a
* parallel dump and want to order dump jobs by table size .
* parallel dump and want to order dump jobs by table size .
* ( We need some size estimate for every TocEntry with a
* ( We need some size estimate for every TocEntry with a
* DataDumper function . ) We don ' t currently have any cheap
* DataDumper function . ) We don ' t currently have any cheap
* way to estimate the size of LOs , but it doesn ' t matter ;
* way to estimate the size of LOs , but fortunately it doesn ' t
* let ' s just set the size to a large value so parallel dumps
* matter too much as long as we get large batches of LOs
* will launch this job first . If there ' s lots of LOs , we
* processed reasonably early . Assume 8 K per blob .
* win , and if there aren ' t , we don ' t lose much . ( If you want
* to improve on this , really what you should be thinking
* about is allowing LO dumping to be parallelized , not just
* getting a smarter estimate for the single TOC entry . )
*/
*/
te - > dataLength = INT_MAX ;
te - > dataLength = loinfo - > numlos * ( pgoff_t ) 8192 ;
}
}
break ;
break ;
case DO_POLICY :
case DO_POLICY :
@ -10765,7 +10837,7 @@ dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
if ( nspinfo - > dobj . dump & DUMP_COMPONENT_ACL )
if ( nspinfo - > dobj . dump & DUMP_COMPONENT_ACL )
dumpACL ( fout , nspinfo - > dobj . dumpId , InvalidDumpId , " SCHEMA " ,
dumpACL ( fout , nspinfo - > dobj . dumpId , InvalidDumpId , " SCHEMA " ,
qnspname , NULL , NULL ,
qnspname , NULL , NULL ,
nspinfo - > rolname , & nspinfo - > dacl ) ;
NULL , nspinfo - > rolname , & nspinfo - > dacl ) ;
free ( qnspname ) ;
free ( qnspname ) ;
@ -11062,7 +11134,7 @@ dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
qtypname , NULL ,
qtypname , NULL ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > rolname , & tyinfo - > dacl ) ;
NULL , tyinfo - > rolname , & tyinfo - > dacl ) ;
PQclear ( res ) ;
PQclear ( res ) ;
destroyPQExpBuffer ( q ) ;
destroyPQExpBuffer ( q ) ;
@ -11215,7 +11287,7 @@ dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
qtypname , NULL ,
qtypname , NULL ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > rolname , & tyinfo - > dacl ) ;
NULL , tyinfo - > rolname , & tyinfo - > dacl ) ;
PQclear ( res ) ;
PQclear ( res ) ;
destroyPQExpBuffer ( q ) ;
destroyPQExpBuffer ( q ) ;
@ -11286,7 +11358,7 @@ dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
qtypname , NULL ,
qtypname , NULL ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > rolname , & tyinfo - > dacl ) ;
NULL , tyinfo - > rolname , & tyinfo - > dacl ) ;
destroyPQExpBuffer ( q ) ;
destroyPQExpBuffer ( q ) ;
destroyPQExpBuffer ( delq ) ;
destroyPQExpBuffer ( delq ) ;
@ -11533,7 +11605,7 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
qtypname , NULL ,
qtypname , NULL ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > rolname , & tyinfo - > dacl ) ;
NULL , tyinfo - > rolname , & tyinfo - > dacl ) ;
PQclear ( res ) ;
PQclear ( res ) ;
destroyPQExpBuffer ( q ) ;
destroyPQExpBuffer ( q ) ;
@ -11688,7 +11760,7 @@ dumpDomain(Archive *fout, const TypeInfo *tyinfo)
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
qtypname , NULL ,
qtypname , NULL ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > rolname , & tyinfo - > dacl ) ;
NULL , tyinfo - > rolname , & tyinfo - > dacl ) ;
/* Dump any per-constraint comments */
/* Dump any per-constraint comments */
for ( i = 0 ; i < tyinfo - > nDomChecks ; i + + )
for ( i = 0 ; i < tyinfo - > nDomChecks ; i + + )
@ -11902,7 +11974,7 @@ dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
dumpACL ( fout , tyinfo - > dobj . dumpId , InvalidDumpId , " TYPE " ,
qtypname , NULL ,
qtypname , NULL ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > dobj . namespace - > dobj . name ,
tyinfo - > rolname , & tyinfo - > dacl ) ;
NULL , tyinfo - > rolname , & tyinfo - > dacl ) ;
/* Dump any per-column comments */
/* Dump any per-column comments */
if ( tyinfo - > dobj . dump & DUMP_COMPONENT_COMMENT )
if ( tyinfo - > dobj . dump & DUMP_COMPONENT_COMMENT )
@ -12178,7 +12250,7 @@ dumpProcLang(Archive *fout, const ProcLangInfo *plang)
if ( plang - > lanpltrusted & & plang - > dobj . dump & DUMP_COMPONENT_ACL )
if ( plang - > lanpltrusted & & plang - > dobj . dump & DUMP_COMPONENT_ACL )
dumpACL ( fout , plang - > dobj . dumpId , InvalidDumpId , " LANGUAGE " ,
dumpACL ( fout , plang - > dobj . dumpId , InvalidDumpId , " LANGUAGE " ,
qlanname , NULL , NULL ,
qlanname , NULL , NULL ,
plang - > lanowner , & plang - > dacl ) ;
NULL , plang - > lanowner , & plang - > dacl ) ;
free ( qlanname ) ;
free ( qlanname ) ;
@ -12642,7 +12714,7 @@ dumpFunc(Archive *fout, const FuncInfo *finfo)
dumpACL ( fout , finfo - > dobj . dumpId , InvalidDumpId , keyword ,
dumpACL ( fout , finfo - > dobj . dumpId , InvalidDumpId , keyword ,
funcsig , NULL ,
funcsig , NULL ,
finfo - > dobj . namespace - > dobj . name ,
finfo - > dobj . namespace - > dobj . name ,
finfo - > rolname , & finfo - > dacl ) ;
NULL , finfo - > rolname , & finfo - > dacl ) ;
PQclear ( res ) ;
PQclear ( res ) ;
@ -14502,7 +14574,7 @@ dumpAgg(Archive *fout, const AggInfo *agginfo)
dumpACL ( fout , agginfo - > aggfn . dobj . dumpId , InvalidDumpId ,
dumpACL ( fout , agginfo - > aggfn . dobj . dumpId , InvalidDumpId ,
" FUNCTION " , aggsig , NULL ,
" FUNCTION " , aggsig , NULL ,
agginfo - > aggfn . dobj . namespace - > dobj . name ,
agginfo - > aggfn . dobj . namespace - > dobj . name ,
agginfo - > aggfn . rolname , & agginfo - > aggfn . dacl ) ;
NULL , agginfo - > aggfn . rolname , & agginfo - > aggfn . dacl ) ;
free ( aggsig ) ;
free ( aggsig ) ;
free ( aggfullsig ) ;
free ( aggfullsig ) ;
@ -14899,7 +14971,7 @@ dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
/* Handle the ACL */
/* Handle the ACL */
if ( fdwinfo - > dobj . dump & DUMP_COMPONENT_ACL )
if ( fdwinfo - > dobj . dump & DUMP_COMPONENT_ACL )
dumpACL ( fout , fdwinfo - > dobj . dumpId , InvalidDumpId ,
dumpACL ( fout , fdwinfo - > dobj . dumpId , InvalidDumpId ,
" FOREIGN DATA WRAPPER " , qfdwname , NULL ,
" FOREIGN DATA WRAPPER " , qfdwname , NULL , NULL ,
NULL , fdwinfo - > rolname , & fdwinfo - > dacl ) ;
NULL , fdwinfo - > rolname , & fdwinfo - > dacl ) ;
free ( qfdwname ) ;
free ( qfdwname ) ;
@ -14986,7 +15058,7 @@ dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
/* Handle the ACL */
/* Handle the ACL */
if ( srvinfo - > dobj . dump & DUMP_COMPONENT_ACL )
if ( srvinfo - > dobj . dump & DUMP_COMPONENT_ACL )
dumpACL ( fout , srvinfo - > dobj . dumpId , InvalidDumpId ,
dumpACL ( fout , srvinfo - > dobj . dumpId , InvalidDumpId ,
" FOREIGN SERVER " , qsrvname , NULL ,
" FOREIGN SERVER " , qsrvname , NULL , NULL ,
NULL , srvinfo - > rolname , & srvinfo - > dacl ) ;
NULL , srvinfo - > rolname , & srvinfo - > dacl ) ;
/* Dump user mappings */
/* Dump user mappings */
@ -15186,6 +15258,8 @@ dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
* ' subname ' is the formatted name of the sub - object , if any . Must be quoted .
* ' subname ' is the formatted name of the sub - object , if any . Must be quoted .
* ( Currently we assume that subname is only provided for table columns . )
* ( Currently we assume that subname is only provided for table columns . )
* ' nspname ' is the namespace the object is in ( NULL if none ) .
* ' nspname ' is the namespace the object is in ( NULL if none ) .
* ' tag ' is the tag to use for the ACL TOC entry ; typically , this is NULL
* to use the default for the object type .
* ' owner ' is the owner , NULL if there is no owner ( for languages ) .
* ' owner ' is the owner , NULL if there is no owner ( for languages ) .
* ' dacl ' is the DumpableAcl struct for the object .
* ' dacl ' is the DumpableAcl struct for the object .
*
*
@ -15196,7 +15270,7 @@ dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
static DumpId
static DumpId
dumpACL ( Archive * fout , DumpId objDumpId , DumpId altDumpId ,
dumpACL ( Archive * fout , DumpId objDumpId , DumpId altDumpId ,
const char * type , const char * name , const char * subname ,
const char * type , const char * name , const char * subname ,
const char * nspname , const char * owner ,
const char * nspname , const char * tag , const char * owner ,
const DumpableAcl * dacl )
const DumpableAcl * dacl )
{
{
DumpId aclDumpId = InvalidDumpId ;
DumpId aclDumpId = InvalidDumpId ;
@ -15268,14 +15342,16 @@ dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId,
if ( sql - > len > 0 )
if ( sql - > len > 0 )
{
{
PQExpBuffer tag = createPQExpBuffer ( ) ;
PQExpBuffer tagbuf = createPQExpBuffer ( ) ;
DumpId aclDeps [ 2 ] ;
DumpId aclDeps [ 2 ] ;
int nDeps = 0 ;
int nDeps = 0 ;
if ( subname )
if ( tag )
appendPQExpBuffer ( tag , " COLUMN %s.%s " , name , subname ) ;
appendPQExpBufferStr ( tagbuf , tag ) ;
else if ( subname )
appendPQExpBuffer ( tagbuf , " COLUMN %s.%s " , name , subname ) ;
else
else
appendPQExpBuffer ( tag , " %s %s " , type , name ) ;
appendPQExpBuffer ( tagbuf , " %s %s " , type , name ) ;
aclDeps [ nDeps + + ] = objDumpId ;
aclDeps [ nDeps + + ] = objDumpId ;
if ( altDumpId ! = InvalidDumpId )
if ( altDumpId ! = InvalidDumpId )
@ -15284,7 +15360,7 @@ dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId,
aclDumpId = createDumpId ( ) ;
aclDumpId = createDumpId ( ) ;
ArchiveEntry ( fout , nilCatalogId , aclDumpId ,
ArchiveEntry ( fout , nilCatalogId , aclDumpId ,
ARCHIVE_OPTS ( . tag = tag - > data ,
ARCHIVE_OPTS ( . tag = tagbuf - > data ,
. namespace = nspname ,
. namespace = nspname ,
. owner = owner ,
. owner = owner ,
. description = " ACL " ,
. description = " ACL " ,
@ -15293,7 +15369,7 @@ dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId,
. deps = aclDeps ,
. deps = aclDeps ,
. nDeps = nDeps ) ) ;
. nDeps = nDeps ) ) ;
destroyPQExpBuffer ( tag ) ;
destroyPQExpBuffer ( tagbuf ) ;
}
}
destroyPQExpBuffer ( sql ) ;
destroyPQExpBuffer ( sql ) ;
@ -15675,8 +15751,8 @@ dumpTable(Archive *fout, const TableInfo *tbinfo)
tableAclDumpId =
tableAclDumpId =
dumpACL ( fout , tbinfo - > dobj . dumpId , InvalidDumpId ,
dumpACL ( fout , tbinfo - > dobj . dumpId , InvalidDumpId ,
objtype , namecopy , NULL ,
objtype , namecopy , NULL ,
tbinfo - > dobj . namespace - > dobj . name , tbinfo - > rolname ,
tbinfo - > dobj . namespace - > dobj . name ,
& tbinfo - > dacl ) ;
NULL , tbinfo - > rolname , & tbinfo - > dacl ) ;
}
}
/*
/*
@ -15769,8 +15845,8 @@ dumpTable(Archive *fout, const TableInfo *tbinfo)
*/
*/
dumpACL ( fout , tbinfo - > dobj . dumpId , tableAclDumpId ,
dumpACL ( fout , tbinfo - > dobj . dumpId , tableAclDumpId ,
" TABLE " , namecopy , attnamecopy ,
" TABLE " , namecopy , attnamecopy ,
tbinfo - > dobj . namespace - > dobj . name , tbinfo - > rolname ,
tbinfo - > dobj . namespace - > dobj . name ,
& coldacl ) ;
NULL , tbinfo - > rolname , & coldacl ) ;
free ( attnamecopy ) ;
free ( attnamecopy ) ;
}
}
PQclear ( res ) ;
PQclear ( res ) ;
@ -18641,12 +18717,12 @@ addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
case DO_FDW :
case DO_FDW :
case DO_FOREIGN_SERVER :
case DO_FOREIGN_SERVER :
case DO_TRANSFORM :
case DO_TRANSFORM :
case DO_LARGE_OBJECT :
/* Pre-data objects: must come before the pre-data boundary */
/* Pre-data objects: must come before the pre-data boundary */
addObjectDependency ( preDataBound , dobj - > dumpId ) ;
addObjectDependency ( preDataBound , dobj - > dumpId ) ;
break ;
break ;
case DO_TABLE_DATA :
case DO_TABLE_DATA :
case DO_SEQUENCE_SET :
case DO_SEQUENCE_SET :
case DO_LARGE_OBJECT :
case DO_LARGE_OBJECT_DATA :
case DO_LARGE_OBJECT_DATA :
/* Data objects: must come between the boundaries */
/* Data objects: must come between the boundaries */
addObjectDependency ( dobj , preDataBound - > dumpId ) ;
addObjectDependency ( dobj , preDataBound - > dumpId ) ;