Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 51c5881

Browse files
committed
Dump comments for large objects.
1 parent 4714984 commit 51c5881

File tree

3 files changed

+162
-35
lines changed

3 files changed

+162
-35
lines changed

src/bin/pg_dump/pg_dump.c

+139-20
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* by PostgreSQL
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.410 2005/06/21 20:45:44 tgl Exp $
15+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.411 2005/06/30 03:02:56 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -163,7 +163,9 @@ static void selectSourceSchema(const char *schemaName);
163163
static char *getFormattedTypeName(Oid oid, OidOptions opts);
164164
static char *myFormatType(const char *typname, int32 typmod);
165165
static const char *fmtQualifiedId(const char *schema, const char *id);
166+
static bool hasBlobs(Archive *AH);
166167
static int dumpBlobs(Archive *AH, void *arg);
168+
static int dumpBlobComments(Archive *AH, void *arg);
167169
static void dumpDatabase(Archive *AH);
168170
static void dumpEncoding(Archive *AH);
169171
static const char *getAttrName(int attrnum, TableInfo *tblInfo);
@@ -344,6 +346,7 @@ main(int argc, char **argv)
344346

345347
case 's': /* dump schema only */
346348
schemaOnly = true;
349+
outputBlobs = false;
347350
break;
348351

349352
case 'S': /* Username for superuser in plain text
@@ -539,16 +542,22 @@ main(int argc, char **argv)
539542
if (!schemaOnly)
540543
getTableData(tblinfo, numTables, oids);
541544

542-
if (outputBlobs)
545+
if (outputBlobs && hasBlobs(g_fout))
543546
{
544-
/* This is just a placeholder to allow correct sorting of blobs */
547+
/* Add placeholders to allow correct sorting of blobs */
545548
DumpableObject *blobobj;
546549

547550
blobobj = (DumpableObject *) malloc(sizeof(DumpableObject));
548551
blobobj->objType = DO_BLOBS;
549552
blobobj->catId = nilCatalogId;
550553
AssignDumpId(blobobj);
551554
blobobj->name = strdup("BLOBS");
555+
556+
blobobj = (DumpableObject *) malloc(sizeof(DumpableObject));
557+
blobobj->objType = DO_BLOB_COMMENTS;
558+
blobobj->catId = nilCatalogId;
559+
AssignDumpId(blobobj);
560+
blobobj->name = strdup("BLOB COMMENTS");
552561
}
553562

554563
/*
@@ -1313,52 +1322,82 @@ dumpEncoding(Archive *AH)
13131322
}
13141323

13151324

1325+
/*
1326+
* hasBlobs:
1327+
* Test whether database contains any large objects
1328+
*/
1329+
static bool
1330+
hasBlobs(Archive *AH)
1331+
{
1332+
bool result;
1333+
const char *blobQry;
1334+
PGresult *res;
1335+
1336+
/* Make sure we are in proper schema */
1337+
selectSourceSchema("pg_catalog");
1338+
1339+
/* Check for BLOB OIDs */
1340+
if (AH->remoteVersion >= 70100)
1341+
blobQry = "SELECT loid FROM pg_largeobject LIMIT 1";
1342+
else
1343+
blobQry = "SELECT oid FROM pg_class WHERE relkind = 'l' LIMIT 1";
1344+
1345+
res = PQexec(g_conn, blobQry);
1346+
check_sql_result(res, g_conn, blobQry, PGRES_TUPLES_OK);
1347+
1348+
result = PQntuples(res) > 0;
1349+
1350+
PQclear(res);
1351+
1352+
return result;
1353+
}
1354+
13161355
/*
13171356
* dumpBlobs:
13181357
* dump all blobs
1319-
*
13201358
*/
13211359
static int
13221360
dumpBlobs(Archive *AH, void *arg)
13231361
{
1324-
PQExpBuffer oidQry = createPQExpBuffer();
1325-
PQExpBuffer oidFetchQry = createPQExpBuffer();
1362+
const char *blobQry;
1363+
const char *blobFetchQry;
13261364
PGresult *res;
1327-
int i;
1328-
int loFd;
13291365
char buf[LOBBUFSIZE];
1366+
int i;
13301367
int cnt;
1331-
Oid blobOid;
13321368

13331369
if (g_verbose)
13341370
write_msg(NULL, "saving large objects\n");
13351371

13361372
/* Make sure we are in proper schema */
13371373
selectSourceSchema("pg_catalog");
13381374

1339-
/* Cursor to get all BLOB tables */
1375+
/* Cursor to get all BLOB OIDs */
13401376
if (AH->remoteVersion >= 70100)
1341-
appendPQExpBuffer(oidQry, "DECLARE bloboid CURSOR FOR SELECT DISTINCT loid FROM pg_largeobject");
1377+
blobQry = "DECLARE bloboid CURSOR FOR SELECT DISTINCT loid FROM pg_largeobject";
13421378
else
1343-
appendPQExpBuffer(oidQry, "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_class WHERE relkind = 'l'");
1379+
blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_class WHERE relkind = 'l'";
13441380

1345-
res = PQexec(g_conn, oidQry->data);
1346-
check_sql_result(res, g_conn, oidQry->data, PGRES_COMMAND_OK);
1381+
res = PQexec(g_conn, blobQry);
1382+
check_sql_result(res, g_conn, blobQry, PGRES_COMMAND_OK);
13471383

1348-
/* Fetch for cursor */
1349-
appendPQExpBuffer(oidFetchQry, "FETCH 1000 IN bloboid");
1384+
/* Command to fetch from cursor */
1385+
blobFetchQry = "FETCH 1000 IN bloboid";
13501386

13511387
do
13521388
{
13531389
PQclear(res);
13541390

13551391
/* Do a fetch */
1356-
res = PQexec(g_conn, oidFetchQry->data);
1357-
check_sql_result(res, g_conn, oidFetchQry->data, PGRES_TUPLES_OK);
1392+
res = PQexec(g_conn, blobFetchQry);
1393+
check_sql_result(res, g_conn, blobFetchQry, PGRES_TUPLES_OK);
13581394

13591395
/* Process the tuples, if any */
13601396
for (i = 0; i < PQntuples(res); i++)
13611397
{
1398+
Oid blobOid;
1399+
int loFd;
1400+
13621401
blobOid = atooid(PQgetvalue(res, i, 0));
13631402
/* Open the BLOB */
13641403
loFd = lo_open(g_conn, blobOid, INV_READ);
@@ -1393,8 +1432,81 @@ dumpBlobs(Archive *AH, void *arg)
13931432

13941433
PQclear(res);
13951434

1396-
destroyPQExpBuffer(oidQry);
1397-
destroyPQExpBuffer(oidFetchQry);
1435+
return 1;
1436+
}
1437+
1438+
/*
1439+
* dumpBlobComments
1440+
* dump all blob comments
1441+
*
1442+
* Since we don't provide any way to be selective about dumping blobs,
1443+
* there's no need to be selective about their comments either. We put
1444+
* all the comments into one big TOC entry.
1445+
*/
1446+
static int
1447+
dumpBlobComments(Archive *AH, void *arg)
1448+
{
1449+
const char *blobQry;
1450+
const char *blobFetchQry;
1451+
PQExpBuffer commentcmd = createPQExpBuffer();
1452+
PGresult *res;
1453+
int i;
1454+
1455+
if (g_verbose)
1456+
write_msg(NULL, "saving large object comments\n");
1457+
1458+
/* Make sure we are in proper schema */
1459+
selectSourceSchema("pg_catalog");
1460+
1461+
/* Cursor to get all BLOB comments */
1462+
if (AH->remoteVersion >= 70200)
1463+
blobQry = "DECLARE blobcmt CURSOR FOR SELECT DISTINCT loid, obj_description(loid, 'pg_largeobject') FROM pg_largeobject";
1464+
else if (AH->remoteVersion >= 70100)
1465+
blobQry = "DECLARE blobcmt CURSOR FOR SELECT DISTINCT loid, obj_description(loid) FROM pg_largeobject";
1466+
else
1467+
blobQry = "DECLARE blobcmt CURSOR FOR SELECT oid, (SELECT description FROM pg_description pd WHERE pd.objoid=pc.oid) FROM pg_class pc WHERE relkind = 'l'";
1468+
1469+
res = PQexec(g_conn, blobQry);
1470+
check_sql_result(res, g_conn, blobQry, PGRES_COMMAND_OK);
1471+
1472+
/* Command to fetch from cursor */
1473+
blobFetchQry = "FETCH 100 IN blobcmt";
1474+
1475+
do
1476+
{
1477+
PQclear(res);
1478+
1479+
/* Do a fetch */
1480+
res = PQexec(g_conn, blobFetchQry);
1481+
check_sql_result(res, g_conn, blobFetchQry, PGRES_TUPLES_OK);
1482+
1483+
/* Process the tuples, if any */
1484+
for (i = 0; i < PQntuples(res); i++)
1485+
{
1486+
Oid blobOid;
1487+
char *comment;
1488+
1489+
/* ignore blobs without comments */
1490+
if (PQgetisnull(res, i, 1))
1491+
continue;
1492+
1493+
blobOid = atooid(PQgetvalue(res, i, 0));
1494+
comment = PQgetvalue(res, i, 1);
1495+
1496+
printfPQExpBuffer(commentcmd, "COMMENT ON LARGE OBJECT %u IS ",
1497+
blobOid);
1498+
appendStringLiteral(commentcmd, comment, false);
1499+
appendPQExpBuffer(commentcmd, ";\n");
1500+
1501+
archputs(commentcmd->data, AH);
1502+
}
1503+
} while (PQntuples(res) > 0);
1504+
1505+
PQclear(res);
1506+
1507+
archputs("\n", AH);
1508+
1509+
destroyPQExpBuffer(commentcmd);
13981510

13991511
return 1;
14001512
}
@@ -4356,6 +4468,13 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
43564468
NULL, 0,
43574469
dumpBlobs, NULL);
43584470
break;
4471+
case DO_BLOB_COMMENTS:
4472+
ArchiveEntry(fout, dobj->catId, dobj->dumpId,
4473+
dobj->name, NULL, NULL, "",
4474+
false, "BLOB COMMENTS", "", "", NULL,
4475+
NULL, 0,
4476+
dumpBlobComments, NULL);
4477+
break;
43594478
}
43604479
}
43614480

src/bin/pg_dump/pg_dump.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.115 2004/12/31 22:03:08 pgsql Exp $
9+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.116 2005/06/30 03:03:02 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -78,7 +78,8 @@ typedef enum
7878
DO_CAST,
7979
DO_TABLE_DATA,
8080
DO_TABLE_TYPE,
81-
DO_BLOBS
81+
DO_BLOBS,
82+
DO_BLOB_COMMENTS
8283
} DumpableObjectType;
8384

8485
typedef struct _dumpableObject

src/bin/pg_dump/pg_dump_sort.c

+20-13
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump_sort.c,v 1.9 2005/02/03 23:38:58 tgl Exp $
12+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump_sort.c,v 1.10 2005/06/30 03:03:04 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -36,16 +36,17 @@ static const int oldObjectTypePriority[] =
3636
5, /* DO_CONVERSION */
3737
6, /* DO_TABLE */
3838
8, /* DO_ATTRDEF */
39-
12, /* DO_INDEX */
40-
13, /* DO_RULE */
41-
14, /* DO_TRIGGER */
42-
11, /* DO_CONSTRAINT */
43-
15, /* DO_FK_CONSTRAINT */
39+
13, /* DO_INDEX */
40+
14, /* DO_RULE */
41+
15, /* DO_TRIGGER */
42+
12, /* DO_CONSTRAINT */
43+
16, /* DO_FK_CONSTRAINT */
4444
2, /* DO_PROCLANG */
4545
2, /* DO_CAST */
4646
9, /* DO_TABLE_DATA */
4747
7, /* DO_TABLE_TYPE */
48-
10 /* DO_BLOBS */
48+
10, /* DO_BLOBS */
49+
11 /* DO_BLOB_COMMENTS */
4950
};
5051

5152
/*
@@ -63,16 +64,17 @@ static const int newObjectTypePriority[] =
6364
9, /* DO_CONVERSION */
6465
10, /* DO_TABLE */
6566
12, /* DO_ATTRDEF */
66-
16, /* DO_INDEX */
67-
17, /* DO_RULE */
68-
18, /* DO_TRIGGER */
69-
15, /* DO_CONSTRAINT */
70-
19, /* DO_FK_CONSTRAINT */
67+
17, /* DO_INDEX */
68+
18, /* DO_RULE */
69+
19, /* DO_TRIGGER */
70+
16, /* DO_CONSTRAINT */
71+
20, /* DO_FK_CONSTRAINT */
7172
2, /* DO_PROCLANG */
7273
8, /* DO_CAST */
7374
13, /* DO_TABLE_DATA */
7475
11, /* DO_TABLE_TYPE */
75-
14 /* DO_BLOBS */
76+
14, /* DO_BLOBS */
77+
15 /* DO_BLOB_COMMENTS */
7678
};
7779

7880

@@ -1072,6 +1074,11 @@ describeDumpableObject(DumpableObject *obj, char *buf, int bufsize)
10721074
"BLOBS (ID %d)",
10731075
obj->dumpId);
10741076
return;
1077+
case DO_BLOB_COMMENTS:
1078+
snprintf(buf, bufsize,
1079+
"BLOB COMMENTS (ID %d)",
1080+
obj->dumpId);
1081+
return;
10751082
}
10761083
/* shouldn't get here */
10771084
snprintf(buf, bufsize,

0 commit comments

Comments
 (0)