- Check ntuples == 1 for various SELECT statements.

- Fix handling of --tables=* (multiple tables never worked properly, AFAICT)
- strdup() the current user in DB routines
- Check results of IO routines more carefully.
- Check results of PQ routines more carefully.

Have not fixed index output yet.
This commit is contained in:
Philip Warner 2001-01-12 04:32:07 +00:00
parent 565639cde0
commit 06ef1ef2ec
8 changed files with 257 additions and 71 deletions

View File

@ -27,6 +27,13 @@
* Modifications - 30-Oct-2000 - pjw@rhyme.com.au
* Added {Start,End}RestoreBlobs to allow extended TX during BLOB restore.
*
* Modifications - 04-Jan-2001 - pjw@rhyme.com.au
* - strdup() the current user just in case it's deallocated from it's TOC
* entry. Should *never* happen, but that's what they said about the
* Titanic...
*
* - Check results of IO routines more carefully.
*
*-------------------------------------------------------------------------
*/
@ -99,14 +106,18 @@ Archive* OpenArchive(const char* FileSpec, const ArchiveFormat fmt)
/* Public */
void CloseArchive(Archive* AHX)
{
int res = 0;
ArchiveHandle* AH = (ArchiveHandle*)AHX;
(*AH->ClosePtr)(AH);
/* Close the output */
if (AH->gzOut)
GZCLOSE(AH->OF);
res = GZCLOSE(AH->OF);
else if (AH->OF != stdout)
fclose(AH->OF);
res = fclose(AH->OF);
if (res != 0)
die_horribly(AH, "%s: could not close the output file in CloseArchive\n", progname);
}
/* Public */
@ -791,8 +802,8 @@ void SortTocFromFile(Archive* AHX, RestoreOptions *ropt)
/* Setup the file */
fh = fopen(ropt->tocFile, PG_BINARY_R);
if (!fh)
die_horribly(AH, "%s: could not open TOC file\n", progname);
if (!fh)
die_horribly(AH, "%s: could not open TOC file\n", progname);
while (fgets(buf, 1024, fh) != NULL)
{
@ -828,7 +839,8 @@ void SortTocFromFile(Archive* AHX, RestoreOptions *ropt)
tePrev = te;
}
fclose(fh);
if (fclose(fh) != 0)
die_horribly(AH, "%s: could not close TOC file\n", progname);
}
/**********************
@ -906,34 +918,42 @@ OutputContext SetOutput(ArchiveHandle* AH, char *filename, int compression)
#ifdef HAVE_LIBZ
if (compression != 0)
{
sprintf(fmode, "wb%d", compression);
if (fn) {
AH->OF = gzdopen(dup(fn), fmode); /* Don't use PG_BINARY_x since this is zlib */
} else {
AH->OF = gzopen(filename, fmode);
}
AH->gzOut = 1;
sprintf(fmode, "wb%d", compression);
if (fn) {
AH->OF = gzdopen(dup(fn), fmode); /* Don't use PG_BINARY_x since this is zlib */
} else {
AH->OF = gzopen(filename, fmode);
}
AH->gzOut = 1;
} else { /* Use fopen */
#endif
if (fn) {
AH->OF = fdopen(dup(fn), PG_BINARY_W);
} else {
AH->OF = fopen(filename, PG_BINARY_W);
}
AH->gzOut = 0;
if (fn) {
AH->OF = fdopen(dup(fn), PG_BINARY_W);
} else {
AH->OF = fopen(filename, PG_BINARY_W);
}
AH->gzOut = 0;
#ifdef HAVE_LIBZ
}
#endif
if (!AH->OF)
die_horribly(AH, "%s: could not set output\n", progname);
return sav;
}
void ResetOutput(ArchiveHandle* AH, OutputContext sav)
{
int res;
if (AH->gzOut)
GZCLOSE(AH->OF);
res = GZCLOSE(AH->OF);
else
fclose(AH->OF);
res = fclose(AH->OF);
if (res != 0)
die_horribly(AH, "%s: could not reset the output file\n", progname);
AH->gzOut = sav.gzOut;
AH->OF = sav.OF;
@ -1012,9 +1032,19 @@ int ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle* AH)
return res;
}
else if (AH->gzOut)
return GZWRITE((void*)ptr, size, nmemb, AH->OF);
{
res = GZWRITE((void*)ptr, size, nmemb, AH->OF);
if (res != (nmemb * size))
die_horribly(AH, "%s: could not write to archive\n", progname);
return res;
}
else if (AH->CustomOutPtr)
return AH->CustomOutPtr(AH, ptr, size * nmemb);
{
res = AH->CustomOutPtr(AH, ptr, size * nmemb);
if (res != (nmemb * size))
die_horribly(AH, "%s: could not write to custom output routine\n", progname);
return res;
}
else
{
/*
@ -1022,9 +1052,14 @@ int ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle* AH)
* then send it to the DB.
*/
if (RestoringToDB(AH))
return ExecuteSqlCommandBuf(AH, (void*)ptr, size*nmemb);
return ExecuteSqlCommandBuf(AH, (void*)ptr, size*nmemb); /* Always 1, currently */
else
return fwrite((void*)ptr, size, nmemb, AH->OF);
{
res = fwrite((void*)ptr, size, nmemb, AH->OF);
if (res != nmemb)
die_horribly(AH, "%s: could not write to output file (%d != %d)\n", progname, res, nmemb);
return res;
}
}
}
@ -1299,7 +1334,8 @@ _discoverArchiveFormat(ArchiveHandle* AH)
/* Close the file */
if (wantClose)
fclose(fh);
if (fclose(fh) != 0)
die_horribly(AH, "%s: could not close the input file after reading header\n", progname);
return AH->format;
}
@ -1342,7 +1378,7 @@ static ArchiveHandle* _allocAH(const char* FileSpec, const ArchiveFormat fmt,
AH->fSpec = NULL;
}
AH->currUser = "";
AH->currUser = strdup(""); /* So it's valid, but we can free() it later if necessary */
AH->toc = (TocEntry*)calloc(1, sizeof(TocEntry));
if (!AH->toc)
@ -1455,7 +1491,7 @@ void WriteToc(ArchiveHandle* AH)
if (AH->WriteExtraTocPtr) {
(*AH->WriteExtraTocPtr)(AH, te);
}
te = te->next;
te = te->next;
}
}
@ -1585,7 +1621,12 @@ static void _reconnectAsUser(ArchiveHandle* AH, const char *dbname, char *user)
{
ahprintf(AH, "\\connect %s %s\n", dbname, user);
}
AH->currUser = user;
if (AH->currUser)
{
free(AH->currUser);
}
AH->currUser = strdup(user);
}
}

View File

@ -44,7 +44,7 @@
#define GZREAD(p, s, n, fh) gzread(fh, p, n * s)
#else
#define GZCLOSE(fh) fclose(fh)
#define GZWRITE(p, s, n, fh) fwrite(p, s, n, fh)
#define GZWRITE(p, s, n, fh) (fwrite(p, s, n, fh) * s)
#define GZREAD(p, s, n, fh) fread(p, s, n, fh)
#define Z_DEFAULT_COMPRESSION -1
@ -62,7 +62,7 @@ typedef z_stream *z_streamp;
#define K_VERS_MAJOR 1
#define K_VERS_MINOR 4
#define K_VERS_REV 22
#define K_VERS_REV 23
/* Data block types */
#define BLK_DATA 1

View File

@ -24,6 +24,10 @@
*
* Initial version.
*
* Modifications - 04-Jan-2001 - pjw@rhyme.com.au
*
* - Check results of IO routines more carefully.
*
*-------------------------------------------------------------------------
*/
@ -164,7 +168,7 @@ void InitArchiveFmt_Custom(ArchiveHandle* AH)
AH->FH = stdout;
}
if (!AH)
if (!AH->FH)
die_horribly(AH, "%s: unable to open archive file %s",progname, AH->fSpec);
ctx->hasSeek = (fseek(AH->FH, 0, SEEK_CUR) == 0);
@ -176,7 +180,7 @@ void InitArchiveFmt_Custom(ArchiveHandle* AH)
} else {
AH->FH = stdin;
}
if (!AH)
if (!AH->FH)
die_horribly(AH, "%s: unable to open archive file %s",progname, AH->fSpec);
ctx->hasSeek = (fseek(AH->FH, 0, SEEK_CUR) == 0);
@ -666,6 +670,8 @@ static int _WriteByte(ArchiveHandle* AH, const int i)
res = fputc(i, AH->FH);
if (res != EOF) {
ctx->filePos += 1;
} else {
die_horribly(AH, "%s: could not write byte./n",progname);
}
return res;
}
@ -705,6 +711,10 @@ static int _WriteBuf(ArchiveHandle* AH, const void* buf, int len)
lclContext* ctx = (lclContext*)AH->formatData;
int res;
res = fwrite(buf, 1, len, AH->FH);
if (res != len)
die_horribly(AH, "%s: write error in _WriteBuf (%d != %d)\n", progname, res, len);
ctx->filePos += res;
return res;
}
@ -764,7 +774,9 @@ static void _CloseArchive(ArchiveHandle* AH)
}
}
fclose(AH->FH);
if (fclose(AH->FH) != 0)
die_horribly(AH, "%s: could not close archive file\n",progname);
AH->FH = NULL;
}
@ -873,7 +885,8 @@ static int _DoDeflate(ArchiveHandle* AH, lclContext* ctx, int flush)
if (zp->avail_out < zlibOutSize) {
/* printf("Wrote %d byte deflated chunk\n", zlibOutSize - zp->avail_out); */
WriteInt(AH, zlibOutSize - zp->avail_out);
fwrite(out, 1, zlibOutSize - zp->avail_out, AH->FH);
if (fwrite(out, 1, zlibOutSize - zp->avail_out, AH->FH) != (zlibOutSize - zp->avail_out))
die_horribly(AH, "%s: could write compressed chunk\n",progname);
ctx->filePos += zlibOutSize - zp->avail_out;
}
zp->next_out = out;
@ -884,7 +897,8 @@ static int _DoDeflate(ArchiveHandle* AH, lclContext* ctx, int flush)
if (zp->avail_in > 0)
{
WriteInt(AH, zp->avail_in);
fwrite(zp->next_in, 1, zp->avail_in, AH->FH);
if (fwrite(zp->next_in, 1, zp->avail_in, AH->FH) != zp->avail_in)
die_horribly(AH, "%s: could write uncompressed chunk\n", progname);
ctx->filePos += zp->avail_in;
zp->avail_in = 0;
} else {

View File

@ -1,5 +1,14 @@
/*-------------------------------------------------------------------------
*
* pg_backup_db.c
*
* Implements the basic DB functions used by the archiver.
*
* IDENTIFICATION
*
* Modifications - 04-Jan-2001 - pjw@rhyme.com.au
*
* - Check results of PQ routines more carefully.
*
*-------------------------------------------------------------------------
*/
@ -449,14 +458,17 @@ int ExecuteSqlCommandBuf(ArchiveHandle* AH, void *qryv, int bufLen)
/* fprintf(stderr, "Sending '%s' via COPY (at end = %d)\n\n", AH->pgCopyBuf->data, isEnd); */
PQputline(AH->connection, AH->pgCopyBuf->data);
if (PQputline(AH->connection, AH->pgCopyBuf->data) != 0)
die_horribly(AH, "%s: error returned by PQputline\n", progname);
resetPQExpBuffer(AH->pgCopyBuf);
/* fprintf(stderr, "Buffer is '%s'\n", AH->pgCopyBuf->data); */
if(isEnd) {
PQendcopy(AH->connection);
if (PQendcopy(AH->connection) != 0)
die_horribly(AH, "%s: error returned by PQendcopy\n", progname);
AH->pgCopyIn = 0;
break;
}

View File

@ -25,6 +25,10 @@
*
* Initial version.
*
* Modifications - 04-Jan-2001 - pjw@rhyme.com.au
*
* - Check results of IO routines more carefully.
*
*-------------------------------------------------------------------------
*/
@ -123,6 +127,10 @@ void InitArchiveFmt_Files(ArchiveHandle* AH)
} else {
AH->FH = stdout;
}
if (AH->FH == NULL)
die_horribly(NULL, "%s: Could not open output file\n", progname);
ctx->hasSeek = (fseek(AH->FH, 0, SEEK_CUR) == 0);
if (AH->compression < 0 || AH->compression > 9) {
@ -137,6 +145,10 @@ void InitArchiveFmt_Files(ArchiveHandle* AH)
} else {
AH->FH = stdin;
}
if (AH->FH == NULL)
die_horribly(NULL, "%s: Could not open input file\n", progname);
ctx->hasSeek = (fseek(AH->FH, 0, SEEK_CUR) == 0);
ReadHead(AH);
@ -221,6 +233,10 @@ static void _StartData(ArchiveHandle* AH, TocEntry* te)
#else
tctx->FH = fopen(tctx->filename, PG_BINARY_W);
#endif
if (tctx->FH == NULL)
die_horribly(AH, "%s: Could not open data file for output\n", progname);
}
static int _WriteData(ArchiveHandle* AH, const void* data, int dLen)
@ -258,6 +274,9 @@ static void _PrintFileData(ArchiveHandle* AH, char *filename, RestoreOptions *ro
AH->FH = fopen(filename,PG_BINARY_R);
#endif
if (AH->FH == NULL)
die_horribly(AH, "%s: Could not open data file for input\n", progname);
while ( (cnt = GZREAD(buf, 1, 4095, AH->FH)) > 0) {
buf[cnt] = '\0';
ahwrite(buf, 1, cnt, AH);
@ -322,6 +341,9 @@ static void _LoadBlobs(ArchiveHandle* AH, RestoreOptions *ropt)
ctx->blobToc = fopen("blobs.toc", PG_BINARY_R);
if (ctx->blobToc == NULL)
die_horribly(AH, "%s: Could not open BLOB TOC for input\n", progname);
_getBlobTocEntry(AH, &oid, fname);
while(oid != 0)
@ -341,13 +363,13 @@ static void _LoadBlobs(ArchiveHandle* AH, RestoreOptions *ropt)
static int _WriteByte(ArchiveHandle* AH, const int i)
{
lclContext* ctx = (lclContext*)AH->formatData;
int res;
res = fputc(i, AH->FH);
if (res != EOF) {
ctx->filePos += 1;
}
return res;
if (fputc(i, AH->FH) == EOF)
die_horribly(AH, "%s: could not write byte\n", progname);
ctx->filePos += 1;
return 1;
}
static int _ReadByte(ArchiveHandle* AH)
@ -367,6 +389,9 @@ static int _WriteBuf(ArchiveHandle* AH, const void* buf, int len)
lclContext* ctx = (lclContext*)AH->formatData;
int res;
res = fwrite(buf, 1, len, AH->FH);
if (res != len)
die_horribly(AH, "%s: write error in _WriteBuf (%d != %d)\n", progname, res, len);
ctx->filePos += res;
return res;
}
@ -416,7 +441,10 @@ static void _StartBlobs(ArchiveHandle* AH, TocEntry* te)
sprintf(fname, "blobs.toc");
ctx->blobToc = fopen(fname, PG_BINARY_W);
if (ctx->blobToc == NULL)
die_horribly(AH, "%s: could not open BLOB TOC for output\n", progname);
}
/*
@ -453,6 +481,8 @@ static void _StartBlob(ArchiveHandle* AH, TocEntry* te, int oid)
tctx->FH = fopen(fname, PG_BINARY_W);
#endif
if (tctx->FH == NULL)
die_horribly(AH, "%s: Could not open BLOB file\n", progname);
}
/*

View File

@ -22,6 +22,11 @@
*
* Initial version.
*
* Modifications - 04-Jan-2001 - pjw@rhyme.com.au
*
* - Check results of IO routines more carefully.
*
*
*-------------------------------------------------------------------------
*/

View File

@ -21,6 +21,10 @@
*
* Initial version.
*
* Modifications - 04-Jan-2001 - pjw@rhyme.com.au
*
* - Check results of IO routines more carefully.
*
*-------------------------------------------------------------------------
*/
@ -156,6 +160,10 @@ void InitArchiveFmt_Tar(ArchiveHandle* AH)
} else {
ctx->tarFH = stdout;
}
if (ctx->tarFH == NULL)
die_horribly(NULL, "%s: Could not open TOC file for output.\n", progname);
ctx->tarFHpos = 0;
/* Make unbuffered since we will dup() it, and the buffers screw each other */
@ -185,6 +193,9 @@ void InitArchiveFmt_Tar(ArchiveHandle* AH)
ctx->tarFH = stdin;
}
if (ctx->tarFH == NULL)
die_horribly(NULL, "%s: Could not open TOC file for input\n", progname);
/* Make unbuffered since we will dup() it, and the buffers screw each other */
/* setvbuf(ctx->tarFH, NULL, _IONBF, 0); */
@ -311,12 +322,18 @@ static TAR_MEMBER* tarOpen(ArchiveHandle *AH, const char *filename, char mode)
tm->tmpFH = tmpfile();
if (tm->tmpFH == NULL)
die_horribly(AH, "%s: could not generate temp file name.\n", progname);
#ifdef HAVE_LIBZ
if (AH->compression != 0)
{
sprintf(fmode, "wb%d", AH->compression);
tm->zFH = gzdopen(dup(fileno(tm->tmpFH)), fmode);
if (tm->zFH == NULL)
die_horribly(AH, "%s: could not gzdopen temp file.\n", progname);
} else
tm->nFH = tm->tmpFH;
@ -343,7 +360,8 @@ static void tarClose(ArchiveHandle *AH, TAR_MEMBER* th)
* Close the GZ file since we dup'd. This will flush the buffers.
*/
if (AH->compression != 0)
GZCLOSE(th->zFH);
if (GZCLOSE(th->zFH) != 0)
die_horribly(AH, "%s: could not close tar member\n", progname);
if (th->mode == 'w')
_tarAddFile(AH, th); /* This will close the temp file */
@ -477,6 +495,9 @@ static int tarWrite(const void *buf, int len, TAR_MEMBER *th)
else
res = fwrite(buf, 1, len, th->nFH);
if (res != len)
die_horribly(th->AH, "%s: could not write to tar member (%d != %d)\n", progname, res, len);
th->pos += res;
return res;
}
@ -485,9 +506,7 @@ static int _WriteData(ArchiveHandle* AH, const void* data, int dLen)
{
lclTocEntry* tctx = (lclTocEntry*)AH->currToc->formatData;
tarWrite((void*)data, dLen, tctx->TH);
/* GZWRITE((void*)data, 1, dLen, tctx->TH->FH); */
dLen = tarWrite((void*)data, dLen, tctx->TH);
return dLen;
}
@ -767,7 +786,8 @@ static void _CloseArchive(ArchiveHandle* AH)
/* Add a block of NULLs since it's de-rigeur. */
for(i=0; i<512; i++)
{
fputc(0, ctx->tarFH);
if (fputc(0, ctx->tarFH) == EOF)
die_horribly(AH, "%s: could not write null block at end of TAR archive.\n", progname);
}
}
@ -928,6 +948,7 @@ static void _tarAddFile(ArchiveHandle *AH, TAR_MEMBER* th)
char buf[32768];
int cnt;
int len = 0;
int res;
int i, pad;
/*
@ -941,19 +962,25 @@ static void _tarAddFile(ArchiveHandle *AH, TAR_MEMBER* th)
while ( (cnt = fread(&buf[0], 1, 32767, tmp)) > 0)
{
fwrite(&buf[0], 1, cnt, th->tarFH);
len += cnt;
res = fwrite(&buf[0], 1, cnt, th->tarFH);
if (res != cnt)
die_horribly(AH, "%s: write error appending to TAR archive (%d != %d).\n", progname, res, cnt);
len += res;
}
fclose(tmp); /* This *should* delete it... */
if (fclose(tmp) != 0) /* This *should* delete it... */
die_horribly(AH, "%s: Could not close tar member (fclose failed).\n", progname);
if (len != th->fileLen)
die_horribly(AH, "%s: Actual file length does not match expected (%d vs. %d)\n",
die_horribly(AH, "%s: Actual file length does not match expected (%d vs. %d).\n",
progname, len, th->pos);
pad = ((len + 511) & ~511) - len;
for (i=0 ; i < pad ; i++)
fputc('\0',th->tarFH);
{
if (fputc('\0',th->tarFH) == EOF)
die_horribly(AH, "%s: Could not output padding at end of tar member.\n", progname);
}
ctx->tarFHpos += len + pad;
}
@ -1131,5 +1158,8 @@ static void _tarWriteHeader(TAR_MEMBER* th)
lastSum = sum;
}
fwrite(h, 1, 512, th->tarFH);
if (fwrite(h, 1, 512, th->tarFH) != 512) {
die_horribly(th->AH, "%s: unable to write tar header\n", progname);
}
}

View File

@ -22,7 +22,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.185 2001/01/06 20:57:26 petere Exp $
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.186 2001/01/12 04:32:07 pjw Exp $
*
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
*
@ -96,6 +96,11 @@
* table with the currently implementation, and (b) it's not clear how to restore
* a partial BLOB backup (given the current OID-based BLOB implementation).
*
* Modifications - 04-Jan-2000 - pjw@rhyme.com.au
*
* - Check ntuples == 1 for various SELECT statements.
* - Fix handling of --tables=* (multiple tables never worked properly, AFAICT)
*
*-------------------------------------------------------------------------
*/
@ -213,7 +218,7 @@ help(const char *progname)
" -s, --schema-only dump out only the schema, no data\n"
" -S, --superuser=NAME specify the superuser user name to use in plain\n"
" text format\n"
" -t, --table=TABLE dump for this table only\n"
" -t, --table=TABLE dump for this table only (* for all)\n"
" -u, --password use password authentication\n"
" -v, --verbose verbose\n"
" -x, --no-acl do not dump ACL's (grant/revoke)\n"
@ -242,7 +247,7 @@ help(const char *progname)
" -s dump out only the schema, no data\n"
" -S NAME specify the superuser user name to use in plain\n"
" text format\n"
" -t TABLE dump for this table only\n"
" -t TABLE dump for this table only (* for all)\n"
" -u use password authentication\n"
" -v verbose\n"
" -x do not dump ACL's (grant/revoke)\n"
@ -562,7 +567,7 @@ dumpClasses(const TableInfo *tblinfo, const int numTables, Archive *fout,
char copyBuf[512];
char *copyStmt;
if (onlytable == NULL)
if (onlytable == NULL || (strlen(onlytable) == 0) )
all_only = "all";
else
all_only = "only";
@ -576,8 +581,9 @@ dumpClasses(const TableInfo *tblinfo, const int numTables, Archive *fout,
if (g_verbose)
fprintf(stderr, "%s preparing to dump out the contents of %s %d table%s/sequence%s %s\n",
g_comment_start, all_only,
(onlytable == NULL) ? numTables : 1,
(onlytable == NULL) ? "s" : "", (onlytable == NULL) ? "s" : "",
(onlytable == NULL || (strlen(onlytable) == 0)) ? numTables : 1,
(onlytable == NULL || (strlen(onlytable) == 0)) ? "s" : "",
(onlytable == NULL || (strlen(onlytable) == 0)) ? "s" : "",
g_comment_end);
/* Dump SEQUENCEs first (if dataOnly) */
@ -587,7 +593,7 @@ dumpClasses(const TableInfo *tblinfo, const int numTables, Archive *fout,
{
if (!(tblinfo[i].sequence))
continue;
if (!onlytable || (!strcmp(tblinfo[i].relname, onlytable)))
if (!onlytable || (strcmp(tblinfo[i].relname, onlytable) == 0) || (strlen(onlytable) == 0) )
{
if (g_verbose)
fprintf(stderr, "%s dumping out schema of sequence '%s' %s\n",
@ -609,7 +615,7 @@ dumpClasses(const TableInfo *tblinfo, const int numTables, Archive *fout,
if (tblinfo[i].sequence)/* already dumped */
continue;
if (!onlytable || (!strcmp(classname, onlytable)))
if (!onlytable || (strcmp(classname, onlytable) == 0) || (strlen(onlytable) == 0))
{
if (g_verbose)
fprintf(stderr, "%s preparing to dump out the contents of Table '%s' %s\n",
@ -847,6 +853,11 @@ main(int argc, char **argv)
for (i = 0; tablename[i]; i++)
if (isupper((unsigned char) tablename[i]))
tablename[i] = tolower((unsigned char) tablename[i]);
/* '*' is a special case meaning ALL tables, but only if unquoted */
if (strcmp(tablename,"*") == 0)
tablename[0] = '\0';
}
}
break;
@ -901,10 +912,10 @@ main(int argc, char **argv)
exit(1);
}
if (outputBlobs && (tablename != NULL) )
if (outputBlobs && tablename != NULL && strlen(tablename) > 0 )
{
fprintf(stderr,
"%s: BLOB output is not supported for a single table. Use a full dump instead.\n",
"%s: BLOB output is not supported for a single table. Use all tables or a full dump instead.\n",
progname);
exit(1);
}
@ -2301,6 +2312,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
if (findx == numFuncs)
{
PGresult *r;
int numFuncs;
/*
* the funcname is an oid which we use to find the
@ -2318,9 +2330,19 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
r = PQexec(g_conn, query->data);
if (!r || PQresultStatus(r) != PGRES_TUPLES_OK)
{
fprintf(stderr, "getTables(): SELECT (funcname) failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
fprintf(stderr, "getTables(): SELECT (funcname) failed for trigger %s. Explanation from backend: '%s'.\n",
PQgetvalue(res2, i2, i_tgname), PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
/* Sanity: Check we got only one tuple */
numFuncs = PQntuples(r);
if (numFuncs != 1) {
fprintf(stderr, "getTables(): SELECT (funcname) for trigger %s returned %d tuples. Expected 1.\n",
PQgetvalue(res2, i2, i_tgname), numFuncs);
exit_nicely(g_conn);
}
tgfunc = strdup(PQgetvalue(r, 0, PQfnumber(r, "proname")));
PQclear(r);
}
@ -2607,6 +2629,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
{
PGresult *res2;
int numAttr;
if (g_verbose)
fprintf(stderr, "%s finding DEFAULT expression for attr: '%s' %s\n",
@ -2626,6 +2649,15 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
"Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
/* Sanity: Check we got only one tuple */
numAttr = PQntuples(res2);
if (numAttr != 1) {
fprintf(stderr, "getTableAttrs(): SELECT (for DEFAULT) for attr %s returned %d tuples. Expected 1.\n",
tblinfo[i].attnames[j], numAttr);
exit_nicely(g_conn);
}
tblinfo[i].adef_expr[j] = strdup(PQgetvalue(res2, 0, PQfnumber(res2, "adsrc")));
PQclear(res2);
}
@ -3539,7 +3571,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
char *reltypename;
/* First - dump SEQUENCEs */
if (tablename)
if (tablename && strlen(tablename) > 0)
{
serialSeq = malloc(strlen(tablename) + strlen(serialSeqSuffix) + 1);
strcpy(serialSeq, tablename);
@ -3566,7 +3598,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
if (tblinfo[i].sequence)/* already dumped */
continue;
if (!tablename || (!strcmp(tblinfo[i].relname, tablename)))
if (!tablename || (!strcmp(tblinfo[i].relname, tablename)) || (strlen(tablename) == 0))
{
resetPQExpBuffer(delq);
@ -3727,6 +3759,7 @@ dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
funcname = NULL;
else
{
int numFuncs;
/*
* the funcname is an oid which we use to find the name of the
@ -3746,6 +3779,15 @@ dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
"Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
/* Sanity: Check we got only one tuple */
numFuncs = PQntuples(res);
if (numFuncs != 1) {
fprintf(stderr, "dumpIndices(): SELECT (funcname) for index %s returned %d tuples. Expected 1.\n",
indinfo[i].indrelname, numFuncs);
exit_nicely(g_conn);
}
funcname = strdup(PQgetvalue(res, 0, PQfnumber(res, "proname")));
PQclear(res);
}
@ -3753,6 +3795,8 @@ dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
/* convert opclass oid(s) into names */
for (nclass = 0; nclass < INDEX_MAX_KEYS; nclass++)
{
int numRows;
indclass = atoi(indinfo[i].indclass[nclass]);
if (indclass == 0)
break;
@ -3768,6 +3812,15 @@ dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
"Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
exit_nicely(g_conn);
}
/* Sanity: Check we got only one tuple */
numRows = PQntuples(res);
if (numRows != 1) {
fprintf(stderr, "dumpIndices(): SELECT (classname) for index %s returned %d tuples. Expected 1.\n",
indinfo[i].indrelname, numRows);
exit_nicely(g_conn);
}
classname[nclass] = strdup(PQgetvalue(res, 0, PQfnumber(res, "opcname")));
PQclear(res);
}
@ -3815,7 +3868,7 @@ dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
}
}
if (!tablename || (!strcmp(indinfo[i].indrelname, tablename)))
if (!tablename || (strcmp(indinfo[i].indrelname, tablename) == 0) || (strlen(tablename) == 0) )
{
/*
@ -4140,8 +4193,9 @@ dumpTriggers(Archive *fout, const char *tablename,
for (i = 0; i < numTables; i++)
{
if (tablename && strcmp(tblinfo[i].relname, tablename))
if (tablename && (strcmp(tblinfo[i].relname, tablename) != 0) && (strlen(tablename) > 0) )
continue;
for (j = 0; j < tblinfo[i].ntrig; j++)
{
ArchiveEntry(fout, tblinfo[i].triggers[j].oid, tblinfo[i].triggers[j].tgname,
@ -4177,7 +4231,7 @@ dumpRules(Archive *fout, const char *tablename,
*/
for (t = 0; t < numTables; t++)
{
if (tablename && strcmp(tblinfo[t].relname, tablename))
if (tablename && (strcmp(tblinfo[t].relname, tablename) != 0) && (strlen(tablename) > 0) )
continue;
/*