Modify pg_dump so that the preferred dump order is by name within

object types, rather than by OID.  This should help ensure consistent
dump output from databases that are logically the same but have different
histories, per recent discussion about 'diffing' databases.  The patch
is bulky because of renaming of fields, but not very complicated.
Also, do some tweaking to cause BLOB restoration to be done in a better
order, and clean up pg_restore's textual output to exactly match pg_dump.
This commit is contained in:
Tom Lane 2004-03-03 21:28:55 +00:00
parent 6819787c9b
commit 9e733eab69
10 changed files with 594 additions and 431 deletions

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.80 2003/12/08 16:39:05 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.81 2004/03/03 21:28:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -368,9 +368,9 @@ flagInhAttrs(TableInfo *tblinfo, int numTables,
pconstr = &(parent->checkexprs[l]);
if (strcmp(pconstr->condef, constr->condef) != 0)
continue;
if (strcmp(pconstr->conname, constr->conname) == 0 ||
(pconstr->conname[0] == '$' &&
constr->conname[0] == '$'))
if (strcmp(pconstr->dobj.name, constr->dobj.name) == 0 ||
(pconstr->dobj.name[0] == '$' &&
constr->dobj.name[0] == '$'))
{
constr->coninherited = true;
break;
@ -395,6 +395,8 @@ void
AssignDumpId(DumpableObject *dobj)
{
dobj->dumpId = ++lastDumpId;
dobj->name = NULL; /* must be set later */
dobj->namespace = NULL; /* may be set later */
dobj->dependencies = NULL;
dobj->nDeps = 0;
dobj->allocDeps = 0;
@ -725,7 +727,7 @@ findParentsByOid(TableInfo *self,
{
write_msg(NULL, "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n",
inhinfo[i].inhparent,
self->relname,
self->dobj.name,
oid);
exit_nicely();
}

View File

@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.83 2004/02/24 03:35:19 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.84 2004/03/03 21:28:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -49,6 +49,8 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
const int compression, ArchiveMode mode);
static int _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData);
static void fixPriorBlobRefs(ArchiveHandle *AH, TocEntry *blobte,
RestoreOptions *ropt);
static void _doSetFixedOutputState(ArchiveHandle *AH);
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
static void _reconnectToDB(ArchiveHandle *AH, const char *dbname, const char *user);
@ -279,7 +281,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
/*
* If we can output the data, then restore it.
*/
if (AH->PrintTocDataPtr !=NULL && (reqs & REQ_DATA) != 0)
if (AH->PrintTocDataPtr != NULL && (reqs & REQ_DATA) != 0)
{
#ifndef HAVE_LIBZ
if (AH->compression != 0)
@ -331,6 +333,24 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
(*AH->PrintTocDataPtr) (AH, te, ropt);
/*
* If we just restored blobs, fix references in
* previously-loaded tables; otherwise, if we
* previously restored blobs, fix references in
* this table. Note that in standard cases the BLOBS
* entry comes after all TABLE DATA entries, but
* we should cope with other orders in case the
* user demands reordering.
*/
if (strcmp(te->desc, "BLOBS") == 0)
fixPriorBlobRefs(AH, te, ropt);
else if (AH->createdBlobXref &&
strcmp(te->desc, "TABLE DATA") == 0)
{
ahlog(AH, 1, "fixing up large-object cross-reference for \"%s\"\n", te->tag);
FixupBlobRefs(AH, te);
}
_enableTriggersIfNecessary(AH, te, ropt);
}
}
@ -345,41 +365,6 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
te = te->next;
} /* end loop over TOC entries */
/*
* Now use blobs_xref (if used) to fixup any refs for tables that we
* loaded
*/
if (_canRestoreBlobs(AH) && AH->createdBlobXref)
{
/* NULL parameter means disable ALL user triggers */
_disableTriggersIfNecessary(AH, NULL, ropt);
te = AH->toc->next;
while (te != AH->toc)
{
/* Is it table data? */
if (strcmp(te->desc, "TABLE DATA") == 0)
{
ahlog(AH, 2, "checking whether we loaded \"%s\"\n", te->tag);
reqs = _tocEntryRequired(te, ropt);
if ((reqs & REQ_DATA) != 0) /* We loaded the data */
{
ahlog(AH, 1, "fixing up large-object cross-reference for \"%s\"\n", te->tag);
FixupBlobRefs(AH, te);
}
}
else
ahlog(AH, 2, "ignoring large-object cross-references for %s %s\n", te->desc, te->tag);
te = te->next;
}
/* NULL parameter means enable ALL user triggers */
_enableTriggersIfNecessary(AH, NULL, ropt);
}
/*
* Clean up & we're done.
*/
@ -399,6 +384,41 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
}
}
/*
* After restoring BLOBS, fix all blob references in previously-restored
* tables. (Normally, the BLOBS entry should appear after all TABLE DATA
* entries, so this will in fact handle all blob references.)
*/
static void
fixPriorBlobRefs(ArchiveHandle *AH, TocEntry *blobte, RestoreOptions *ropt)
{
TocEntry *te;
teReqs reqs;
if (AH->createdBlobXref)
{
/* NULL parameter means disable ALL user triggers */
_disableTriggersIfNecessary(AH, NULL, ropt);
for (te = AH->toc->next; te != blobte; te = te->next)
{
if (strcmp(te->desc, "TABLE DATA") == 0)
{
reqs = _tocEntryRequired(te, ropt);
if ((reqs & REQ_DATA) != 0) /* We loaded the data */
{
ahlog(AH, 1, "fixing up large-object cross-reference for \"%s\"\n", te->tag);
FixupBlobRefs(AH, te);
}
}
}
/* NULL parameter means enable ALL user triggers */
_enableTriggersIfNecessary(AH, NULL, ropt);
}
}
/*
* Allocate a new RestoreOptions block.
* This is mainly so we can initialize it, but also for future expansion,
@ -703,6 +723,9 @@ EndRestoreBlobs(ArchiveHandle *AH)
if (AH->blobTxActive)
CommitTransactionXref(AH);
if (AH->createdBlobXref)
CreateBlobXrefIndex(AH);
ahlog(AH, 1, "restored %d large objects\n", AH->blobCount);
}
@ -2148,7 +2171,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
pfx, te->tag, te->desc,
te->namespace ? te->namespace : "-",
te->owner);
if (AH->PrintExtraTocPtr !=NULL)
if (AH->PrintExtraTocPtr != NULL)
(*AH->PrintExtraTocPtr) (AH, te);
ahprintf(AH, "--\n\n");

View File

@ -19,7 +19,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.28 2003/12/06 03:00:11 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.29 2004/03/03 21:28:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -279,8 +279,9 @@ _PrintExtraToc(ArchiveHandle *AH, TocEntry *te)
{
lclTocEntry *ctx = (lclTocEntry *) te->formatData;
ahprintf(AH, "-- Data Pos: " INT64_FORMAT "\n",
(int64) ctx->dataPos);
if (AH->public.verbose)
ahprintf(AH, "-- Data Pos: " INT64_FORMAT "\n",
(int64) ctx->dataPos);
}
/*
@ -417,8 +418,8 @@ _EndBlobs(ArchiveHandle *AH, TocEntry *te)
}
/*
* Print data for a gievn TOC entry
*/
* Print data for a given TOC entry
*/
static void
_PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
{
@ -497,8 +498,6 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
blkType);
break;
}
ahprintf(AH, "\n\n");
}
/*

View File

@ -5,7 +5,7 @@
* Implements the basic DB functions used by the archiver.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.51 2003/11/29 19:52:05 pgsql Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.52 2004/03/03 21:28:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -674,13 +674,21 @@ CreateBlobXrefTable(ArchiveHandle *AH)
ahlog(AH, 1, "creating table for large object cross-references\n");
appendPQExpBuffer(qry, "Create Temporary Table %s(oldOid pg_catalog.oid, newOid pg_catalog.oid);", BLOB_XREF_TABLE);
appendPQExpBuffer(qry, "CREATE TEMPORARY TABLE %s(oldOid pg_catalog.oid, newOid pg_catalog.oid) WITHOUT OIDS", BLOB_XREF_TABLE);
ExecuteSqlCommand(AH, qry, "could not create large object cross-reference table", true);
resetPQExpBuffer(qry);
destroyPQExpBuffer(qry);
}
appendPQExpBuffer(qry, "Create Unique Index %s_ix on %s(oldOid)", BLOB_XREF_TABLE, BLOB_XREF_TABLE);
void
CreateBlobXrefIndex(ArchiveHandle *AH)
{
PQExpBuffer qry = createPQExpBuffer();
ahlog(AH, 1, "creating index for large object cross-references\n");
appendPQExpBuffer(qry, "CREATE UNIQUE INDEX %s_ix ON %s(oldOid)",
BLOB_XREF_TABLE, BLOB_XREF_TABLE);
ExecuteSqlCommand(AH, qry, "could not create index on large object cross-reference table", true);
destroyPQExpBuffer(qry);
@ -692,9 +700,8 @@ InsertBlobXref(ArchiveHandle *AH, Oid old, Oid new)
PQExpBuffer qry = createPQExpBuffer();
appendPQExpBuffer(qry,
"Insert Into %s(oldOid, newOid) Values ('%u', '%u');",
"INSERT INTO %s(oldOid, newOid) VALUES ('%u', '%u')",
BLOB_XREF_TABLE, old, new);
ExecuteSqlCommand(AH, qry, "could not create large object cross-reference entry", true);
destroyPQExpBuffer(qry);
@ -705,7 +712,7 @@ StartTransaction(ArchiveHandle *AH)
{
PQExpBuffer qry = createPQExpBuffer();
appendPQExpBuffer(qry, "Begin;");
appendPQExpBuffer(qry, "BEGIN");
ExecuteSqlCommand(AH, qry, "could not start database transaction", false);
AH->txActive = true;
@ -718,7 +725,7 @@ StartTransactionXref(ArchiveHandle *AH)
{
PQExpBuffer qry = createPQExpBuffer();
appendPQExpBuffer(qry, "Begin;");
appendPQExpBuffer(qry, "BEGIN");
ExecuteSqlCommand(AH, qry,
"could not start transaction for large object cross-references", true);
@ -732,7 +739,7 @@ CommitTransaction(ArchiveHandle *AH)
{
PQExpBuffer qry = createPQExpBuffer();
appendPQExpBuffer(qry, "Commit;");
appendPQExpBuffer(qry, "COMMIT");
ExecuteSqlCommand(AH, qry, "could not commit database transaction", false);
AH->txActive = false;
@ -745,7 +752,7 @@ CommitTransactionXref(ArchiveHandle *AH)
{
PQExpBuffer qry = createPQExpBuffer();
appendPQExpBuffer(qry, "Commit;");
appendPQExpBuffer(qry, "COMMIT");
ExecuteSqlCommand(AH, qry, "could not commit transaction for large object cross-references", true);
AH->blobTxActive = false;

View File

@ -2,7 +2,7 @@
* Definitions for pg_backup_db.c
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.h,v 1.9 2003/11/29 19:52:05 pgsql Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.h,v 1.10 2004/03/03 21:28:54 tgl Exp $
*/
#define BLOB_XREF_TABLE "pg_dump_blob_xref" /* MUST be lower case */
@ -12,6 +12,7 @@ extern int ExecuteSqlCommand(ArchiveHandle *AH, PQExpBuffer qry, char *desc, boo
extern int ExecuteSqlCommandBuf(ArchiveHandle *AH, void *qry, size_t bufLen);
extern void CreateBlobXrefTable(ArchiveHandle *AH);
extern void CreateBlobXrefIndex(ArchiveHandle *AH);
extern void InsertBlobXref(ArchiveHandle *AH, Oid old, Oid new);
extern void StartTransaction(ArchiveHandle *AH);
extern void StartTransactionXref(ArchiveHandle *AH);

View File

@ -20,7 +20,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_files.c,v 1.24 2003/12/06 03:00:11 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_files.c,v 1.25 2004/03/03 21:28:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -224,7 +224,8 @@ _PrintExtraToc(ArchiveHandle *AH, TocEntry *te)
{
lclTocEntry *ctx = (lclTocEntry *) te->formatData;
ahprintf(AH, "-- File: %s\n", ctx->filename);
if (AH->public.verbose)
ahprintf(AH, "-- File: %s\n", ctx->filename);
}
static void

View File

@ -16,7 +16,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.41 2003/12/08 16:39:05 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.42 2004/03/03 21:28:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -309,7 +309,7 @@ _PrintExtraToc(ArchiveHandle *AH, TocEntry *te)
{
lclTocEntry *ctx = (lclTocEntry *) te->formatData;
if (ctx->filename != NULL)
if (AH->public.verbose && ctx->filename != NULL)
ahprintf(AH, "-- File: %s\n", ctx->filename);
}

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.107 2003/12/06 03:00:16 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.108 2004/03/03 21:28:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -59,7 +59,7 @@ typedef int DumpId;
typedef enum
{
/* When modifying this enum, update priority table in pg_dump_sort.c! */
/* When modifying this enum, update priority tables in pg_dump_sort.c! */
DO_NAMESPACE,
DO_TYPE,
DO_FUNC,
@ -76,7 +76,9 @@ typedef enum
DO_FK_CONSTRAINT, /* see note for ConstraintInfo */
DO_PROCLANG,
DO_CAST,
DO_TABLE_DATA
DO_TABLE_DATA,
DO_TABLE_TYPE,
DO_BLOBS
} DumpableObjectType;
typedef struct _dumpableObject
@ -84,6 +86,8 @@ typedef struct _dumpableObject
DumpableObjectType objType;
CatalogId catId; /* zero if not a cataloged object */
DumpId dumpId; /* assigned by AssignDumpId() */
char *name; /* object name (should never be NULL) */
struct _namespaceInfo *namespace; /* containing namespace, or NULL */
DumpId *dependencies; /* dumpIds of objects this one depends on */
int nDeps; /* number of valid dependencies */
int allocDeps; /* allocated size of dependencies[] */
@ -92,7 +96,6 @@ typedef struct _dumpableObject
typedef struct _namespaceInfo
{
DumpableObject dobj;
char *nspname;
char *usename; /* name of owner, or empty string */
char *nspacl;
bool dump; /* true if need to dump definition */
@ -101,9 +104,10 @@ typedef struct _namespaceInfo
typedef struct _typeInfo
{
DumpableObject dobj;
char *typname; /* name as seen in catalog */
/* Note: format_type might produce something different than typname */
NamespaceInfo *typnamespace; /* link to containing namespace */
/*
* Note: dobj.name is the pg_type.typname entry. format_type() might
* produce something different than typname
*/
char *usename; /* name of owner, or empty string */
Oid typinput;
Oid typelem;
@ -120,8 +124,6 @@ typedef struct _typeInfo
typedef struct _funcInfo
{
DumpableObject dobj;
char *proname;
NamespaceInfo *pronamespace; /* link to containing namespace */
char *usename; /* name of owner, or empty string */
Oid lang;
int nargs;
@ -141,8 +143,6 @@ typedef struct _aggInfo
typedef struct _oprInfo
{
DumpableObject dobj;
char *oprname;
NamespaceInfo *oprnamespace; /* link to containing namespace */
char *usename;
Oid oprcode;
} OprInfo;
@ -150,16 +150,12 @@ typedef struct _oprInfo
typedef struct _opclassInfo
{
DumpableObject dobj;
char *opcname;
NamespaceInfo *opcnamespace; /* link to containing namespace */
char *usename;
} OpclassInfo;
typedef struct _convInfo
{
DumpableObject dobj;
char *conname;
NamespaceInfo *connamespace; /* link to containing namespace */
char *usename;
} ConvInfo;
@ -169,8 +165,6 @@ typedef struct _tableInfo
* These fields are collected for every table in the database.
*/
DumpableObject dobj;
char *relname;
NamespaceInfo *relnamespace; /* link to containing namespace */
char *usename; /* name of owner, or empty string */
char *relacl;
char relkind;
@ -240,7 +234,6 @@ typedef struct _tableDataInfo
typedef struct _indxInfo
{
DumpableObject dobj;
char *indexname;
TableInfo *indextable; /* link to table the index is for */
char *indexdef;
int indnkeys;
@ -253,7 +246,6 @@ typedef struct _indxInfo
typedef struct _ruleInfo
{
DumpableObject dobj;
char *rulename;
TableInfo *ruletable; /* link to table the rule is for */
char ev_type;
bool is_instead;
@ -263,7 +255,6 @@ typedef struct _triggerInfo
{
DumpableObject dobj;
TableInfo *tgtable; /* link to table the trigger is for */
char *tgname;
char *tgfname;
int tgtype;
int tgnargs;
@ -284,7 +275,6 @@ typedef struct _triggerInfo
typedef struct _constraintInfo
{
DumpableObject dobj;
char *conname;
TableInfo *contable; /* NULL if domain constraint */
TypeInfo *condomain; /* NULL if table constraint */
char contype;
@ -297,7 +287,6 @@ typedef struct _constraintInfo
typedef struct _procLangInfo
{
DumpableObject dobj;
char *lanname;
bool lanpltrusted;
Oid lanplcallfoid;
Oid lanvalidator;
@ -368,7 +357,8 @@ extern void exit_nicely(void);
extern void parseOidArray(const char *str, Oid *array, int arraysize);
extern void sortDumpableObjects(DumpableObject **objs, int numObjs);
extern void sortDumpableObjectsByType(DumpableObject **objs, int numObjs);
extern void sortDumpableObjectsByTypeName(DumpableObject **objs, int numObjs);
extern void sortDumpableObjectsByTypeOid(DumpableObject **objs, int numObjs);
/*
* version specific routines

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump_sort.c,v 1.3 2003/12/07 05:44:50 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump_sort.c,v 1.4 2004/03/03 21:28:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -20,12 +20,12 @@
static char *modulename = gettext_noop("sorter");
/*
* Sort priority for object types. Objects are sorted by priority,
* and within an equal priority level by OID. (This is a relatively
* crude hack to provide semi-reasonable behavior for old databases
* without full dependency info.)
* Sort priority for object types when dumping a pre-7.3 database.
* Objects are sorted by priority levels, and within an equal priority level
* by OID. (This is a relatively crude hack to provide semi-reasonable
* behavior for old databases without full dependency info.)
*/
static const int objectTypePriority[] =
static const int oldObjectTypePriority[] =
{
1, /* DO_NAMESPACE */
2, /* DO_TYPE */
@ -35,19 +35,49 @@ static const int objectTypePriority[] =
4, /* DO_OPCLASS */
5, /* DO_CONVERSION */
6, /* DO_TABLE */
7, /* DO_ATTRDEF */
10, /* DO_INDEX */
11, /* DO_RULE */
12, /* DO_TRIGGER */
9, /* DO_CONSTRAINT */
13, /* DO_FK_CONSTRAINT */
8, /* DO_ATTRDEF */
12, /* DO_INDEX */
13, /* DO_RULE */
14, /* DO_TRIGGER */
11, /* DO_CONSTRAINT */
15, /* DO_FK_CONSTRAINT */
2, /* DO_PROCLANG */
2, /* DO_CAST */
8 /* DO_TABLE_DATA */
9, /* DO_TABLE_DATA */
7, /* DO_TABLE_TYPE */
10 /* DO_BLOBS */
};
/*
* Sort priority for object types when dumping newer databases.
* Objects are sorted by type, and within a type by name.
*/
static const int newObjectTypePriority[] =
{
1, /* DO_NAMESPACE */
3, /* DO_TYPE */
4, /* DO_FUNC */
5, /* DO_AGG */
6, /* DO_OPERATOR */
7, /* DO_OPCLASS */
9, /* DO_CONVERSION */
10, /* DO_TABLE */
12, /* DO_ATTRDEF */
16, /* DO_INDEX */
17, /* DO_RULE */
18, /* DO_TRIGGER */
15, /* DO_CONSTRAINT */
19, /* DO_FK_CONSTRAINT */
2, /* DO_PROCLANG */
8, /* DO_CAST */
13, /* DO_TABLE_DATA */
11, /* DO_TABLE_TYPE */
14 /* DO_BLOBS */
};
static int DOTypeCompare(const void *p1, const void *p2);
static int DOTypeNameCompare(const void *p1, const void *p2);
static int DOTypeOidCompare(const void *p1, const void *p2);
static bool TopoSort(DumpableObject **objs,
int numObjs,
DumpableObject **ordering,
@ -67,27 +97,79 @@ static void describeDumpableObject(DumpableObject *obj,
/*
* Sort the given objects into a type/OID-based ordering
* Sort the given objects into a type/name-based ordering
*
* Normally this is just the starting point for the dependency-based
* ordering.
*/
void
sortDumpableObjectsByType(DumpableObject **objs, int numObjs)
sortDumpableObjectsByTypeName(DumpableObject **objs, int numObjs)
{
if (numObjs > 1)
qsort((void *) objs, numObjs, sizeof(DumpableObject *), DOTypeCompare);
qsort((void *) objs, numObjs, sizeof(DumpableObject *),
DOTypeNameCompare);
}
static int
DOTypeCompare(const void *p1, const void *p2)
DOTypeNameCompare(const void *p1, const void *p2)
{
DumpableObject *obj1 = *(DumpableObject **) p1;
DumpableObject *obj2 = *(DumpableObject **) p2;
int cmpval;
cmpval = objectTypePriority[obj1->objType] -
objectTypePriority[obj2->objType];
/* Sort by type */
cmpval = newObjectTypePriority[obj1->objType] -
newObjectTypePriority[obj2->objType];
if (cmpval != 0)
return cmpval;
/*
* Sort by namespace. Note that all objects of the same type should
* either have or not have a namespace link, so we needn't be fancy
* about cases where one link is null and the other not.
*/
if (obj1->namespace && obj2->namespace)
{
cmpval = strcmp(obj1->namespace->dobj.name,
obj2->namespace->dobj.name);
if (cmpval != 0)
return cmpval;
}
/* Sort by name */
cmpval = strcmp(obj1->name, obj2->name);
if (cmpval != 0)
return cmpval;
/* Probably shouldn't get here, but if we do, sort by OID */
return oidcmp(obj1->catId.oid, obj2->catId.oid);
}
/*
* Sort the given objects into a type/OID-based ordering
*
* This is used with pre-7.3 source databases as a crude substitute for the
* lack of dependency information.
*/
void
sortDumpableObjectsByTypeOid(DumpableObject **objs, int numObjs)
{
if (numObjs > 1)
qsort((void *) objs, numObjs, sizeof(DumpableObject *),
DOTypeOidCompare);
}
static int
DOTypeOidCompare(const void *p1, const void *p2)
{
DumpableObject *obj1 = *(DumpableObject **) p1;
DumpableObject *obj2 = *(DumpableObject **) p2;
int cmpval;
cmpval = oldObjectTypePriority[obj1->objType] -
oldObjectTypePriority[obj2->objType];
if (cmpval != 0)
return cmpval;
@ -839,93 +921,79 @@ describeDumpableObject(DumpableObject *obj, char *buf, int bufsize)
case DO_NAMESPACE:
snprintf(buf, bufsize,
"SCHEMA %s (ID %d OID %u)",
((NamespaceInfo *) obj)->nspname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_TYPE:
snprintf(buf, bufsize,
"TYPE %s (ID %d OID %u)",
((TypeInfo *) obj)->typname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_FUNC:
snprintf(buf, bufsize,
"FUNCTION %s (ID %d OID %u)",
((FuncInfo *) obj)->proname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_AGG:
snprintf(buf, bufsize,
"AGGREGATE %s (ID %d OID %u)",
((AggInfo *) obj)->aggfn.proname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_OPERATOR:
snprintf(buf, bufsize,
"OPERATOR %s (ID %d OID %u)",
((OprInfo *) obj)->oprname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_OPCLASS:
snprintf(buf, bufsize,
"OPERATOR CLASS %s (ID %d OID %u)",
((OpclassInfo *) obj)->opcname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_CONVERSION:
snprintf(buf, bufsize,
"CONVERSION %s (ID %d OID %u)",
((ConvInfo *) obj)->conname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_TABLE:
snprintf(buf, bufsize,
"TABLE %s (ID %d OID %u)",
((TableInfo *) obj)->relname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_ATTRDEF:
snprintf(buf, bufsize,
"ATTRDEF %s.%s (ID %d OID %u)",
((AttrDefInfo *) obj)->adtable->relname,
((AttrDefInfo *) obj)->adtable->dobj.name,
((AttrDefInfo *) obj)->adtable->attnames[((AttrDefInfo *) obj)->adnum - 1],
obj->dumpId, obj->catId.oid);
return;
case DO_INDEX:
snprintf(buf, bufsize,
"INDEX %s (ID %d OID %u)",
((IndxInfo *) obj)->indexname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_RULE:
snprintf(buf, bufsize,
"RULE %s (ID %d OID %u)",
((RuleInfo *) obj)->rulename,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_TRIGGER:
snprintf(buf, bufsize,
"TRIGGER %s (ID %d OID %u)",
((TriggerInfo *) obj)->tgname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_CONSTRAINT:
snprintf(buf, bufsize,
"CONSTRAINT %s (ID %d OID %u)",
((ConstraintInfo *) obj)->conname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_FK_CONSTRAINT:
snprintf(buf, bufsize,
"FK CONSTRAINT %s (ID %d OID %u)",
((ConstraintInfo *) obj)->conname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_PROCLANG:
snprintf(buf, bufsize,
"PROCEDURAL LANGUAGE %s (ID %d OID %u)",
((ProcLangInfo *) obj)->lanname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_CAST:
snprintf(buf, bufsize,
@ -937,8 +1005,17 @@ describeDumpableObject(DumpableObject *obj, char *buf, int bufsize)
case DO_TABLE_DATA:
snprintf(buf, bufsize,
"TABLE DATA %s (ID %d OID %u)",
((TableDataInfo *) obj)->tdtable->relname,
obj->dumpId, obj->catId.oid);
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_TABLE_TYPE:
snprintf(buf, bufsize,
"TABLE TYPE %s (ID %d OID %u)",
obj->name, obj->dumpId, obj->catId.oid);
return;
case DO_BLOBS:
snprintf(buf, bufsize,
"BLOBS (ID %d)",
obj->dumpId);
return;
}
/* shouldn't get here */