Commit f7168bd4 authored by Bruce Momjian's avatar Bruce Momjian

They are two different problems; the TOC entry is important for any

multiline command  or to rerun the command easily later.

Whereas displaying the failed SQL command is a matter of fixing the
error
messages.

The latter is complicated by failed COPY commands which, with
die-on-errors
off, results in the data being processed as a command, so dumping the
command will dump all of the data.

In the case of long commands, should the whole command be dumped? eg.
(eg.
several pages of function definition).

In the case of the COPY command, I'm not sure what to do. Obviously, it
would be best to avoid sending the data, but the data and command are
combined (from memory). Also, the 'data' may be in the form of INSERT
statements.

Attached patch produces the first 125 chars of the command:

pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC Entry 26; 1255 16449270
FUNCTION
plpgsql_call_handler() pjw
pg_restore: [archiver (db)] could not execute query: ERROR:  function
"plpgsql_call_handler" already exists with same argument types
     Command was: CREATE FUNCTION plpgsql_call_handler() RETURNS
language_handler
     AS '/var/lib/pgsql-8.0b1/lib/plpgsql', 'plpgsql_call_han...
pg_restore: [archiver (db)] Error from TOC Entry 27; 1255 16449271
FUNCTION
plpgsql_validator(oid) pjw
pg_restore: [archiver (db)] could not execute query: ERROR:  function
"plpgsql_validator" already exists with same argument types
     Command was: CREATE FUNCTION plpgsql_validator(oid) RETURNS void
     AS '/var/lib/pgsql-8.0b1/lib/plpgsql', 'plpgsql_validator'
     LANGU...

Philip Warner
parent b43fd16e
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.93 2004/08/20 04:20:22 momjian Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.94 2004/08/20 20:00:34 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -137,6 +137,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) ...@@ -137,6 +137,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
bool defnDumped; bool defnDumped;
AH->ropt = ropt; AH->ropt = ropt;
AH->stage = STAGE_INITIALIZING;
/* /*
* Check for nonsensical option combinations. * Check for nonsensical option combinations.
...@@ -166,6 +167,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) ...@@ -166,6 +167,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
ConnectDatabase(AHX, ropt->dbname, ConnectDatabase(AHX, ropt->dbname,
ropt->pghost, ropt->pgport, ropt->username, ropt->pghost, ropt->pgport, ropt->username,
ropt->requirePassword, ropt->ignoreVersion); ropt->requirePassword, ropt->ignoreVersion);
/* If we're talking to the DB directly, don't send comments since they obscure SQL when displaying errors */
AH->noTocComments = 1;
} }
/* /*
...@@ -211,12 +214,16 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) ...@@ -211,12 +214,16 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
*/ */
_doSetFixedOutputState(AH); _doSetFixedOutputState(AH);
AH->stage = STAGE_PROCESSING;
/* /*
* Drop the items at the start, in reverse order * Drop the items at the start, in reverse order
*/ */
if (ropt->dropSchema) if (ropt->dropSchema)
{ {
te = AH->toc->prev; te = AH->toc->prev;
AH->currentTE = te;
while (te != AH->toc) while (te != AH->toc)
{ {
reqs = _tocEntryRequired(te, ropt, false); reqs = _tocEntryRequired(te, ropt, false);
...@@ -240,6 +247,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) ...@@ -240,6 +247,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
te = AH->toc->next; te = AH->toc->next;
while (te != AH->toc) while (te != AH->toc)
{ {
AH->currentTE = te;
/* Work out what, if anything, we want from this entry */ /* Work out what, if anything, we want from this entry */
reqs = _tocEntryRequired(te, ropt, false); reqs = _tocEntryRequired(te, ropt, false);
...@@ -375,6 +384,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) ...@@ -375,6 +384,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
te = AH->toc->next; te = AH->toc->next;
while (te != AH->toc) while (te != AH->toc)
{ {
AH->currentTE = te;
/* Work out what, if anything, we want from this entry */ /* Work out what, if anything, we want from this entry */
reqs = _tocEntryRequired(te, ropt, true); reqs = _tocEntryRequired(te, ropt, true);
...@@ -391,6 +402,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt) ...@@ -391,6 +402,8 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
/* /*
* Clean up & we're done. * Clean up & we're done.
*/ */
AH->stage = STAGE_FINALIZING;
if (ropt->filename || ropt->compression) if (ropt->filename || ropt->compression)
ResetOutput(AH, sav); ResetOutput(AH, sav);
...@@ -1227,6 +1240,39 @@ warn_or_die_horribly(ArchiveHandle *AH, ...@@ -1227,6 +1240,39 @@ warn_or_die_horribly(ArchiveHandle *AH,
const char *modulename, const char *fmt, ...) const char *modulename, const char *fmt, ...)
{ {
va_list ap; va_list ap;
switch(AH->stage) {
case STAGE_NONE:
/* Do nothing special */
break;
case STAGE_INITIALIZING:
if (AH->stage != AH->lastErrorStage) {
write_msg(modulename, "Error while INITIALIZING:\n");
}
break;
case STAGE_PROCESSING:
if (AH->stage != AH->lastErrorStage) {
write_msg(modulename, "Error while PROCESSING TOC:\n");
}
break;
case STAGE_FINALIZING:
if (AH->stage != AH->lastErrorStage) {
write_msg(modulename, "Error while FINALIZING:\n");
}
break;
}
if (AH->currentTE != NULL && AH->currentTE != AH->lastErrorTE) {
write_msg(modulename, "Error from TOC Entry %d; %u %u %s %s %s\n", AH->currentTE->dumpId,
AH->currentTE->catalogId.tableoid, AH->currentTE->catalogId.oid,
AH->currentTE->desc, AH->currentTE->tag, AH->currentTE->owner);
}
AH->lastErrorStage = AH->stage;
AH->lastErrorTE = AH->currentTE;
va_start(ap, fmt); va_start(ap, fmt);
if (AH->public.exit_on_error) if (AH->public.exit_on_error)
{ {
...@@ -2026,6 +2072,9 @@ _doSetFixedOutputState(ArchiveHandle *AH) ...@@ -2026,6 +2072,9 @@ _doSetFixedOutputState(ArchiveHandle *AH)
/* Make sure function checking is disabled */ /* Make sure function checking is disabled */
ahprintf(AH, "SET check_function_bodies = false;\n"); ahprintf(AH, "SET check_function_bodies = false;\n");
/* Avoid annoying notices etc */
ahprintf(AH, "SET client_min_messages = warning;\n");
ahprintf(AH, "\n"); ahprintf(AH, "\n");
} }
...@@ -2317,6 +2366,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat ...@@ -2317,6 +2366,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
return; return;
} }
if (AH->noTocComments)
return;
/* /*
* Avoid dumping the public schema, as it will already be created ... * Avoid dumping the public schema, as it will already be created ...
* unless we are using --clean mode, in which case it's been deleted * unless we are using --clean mode, in which case it's been deleted
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.59 2004/08/20 16:07:15 momjian Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.60 2004/08/20 20:00:34 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -152,6 +152,14 @@ typedef struct ...@@ -152,6 +152,14 @@ typedef struct
PQExpBuffer tagBuf; PQExpBuffer tagBuf;
} sqlparseInfo; } sqlparseInfo;
typedef enum
{
STAGE_NONE = 0,
STAGE_INITIALIZING,
STAGE_PROCESSING,
STAGE_FINALIZING
} ArchiverStage;
typedef struct _archiveHandle typedef struct _archiveHandle
{ {
Archive public; /* Public part of archive */ Archive public; /* Public part of archive */
...@@ -254,6 +262,12 @@ typedef struct _archiveHandle ...@@ -254,6 +262,12 @@ typedef struct _archiveHandle
void *lo_buf; void *lo_buf;
size_t lo_buf_used; size_t lo_buf_used;
size_t lo_buf_size; size_t lo_buf_size;
int noTocComments;
ArchiverStage stage;
ArchiverStage lastErrorStage;
struct _tocEntry *currentTE;
struct _tocEntry *lastErrorTE;
} ArchiveHandle; } ArchiveHandle;
typedef struct _tocEntry typedef struct _tocEntry
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Implements the basic DB functions used by the archiver. * Implements the basic DB functions used by the archiver.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.54 2004/08/20 16:07:15 momjian Exp $ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.55 2004/08/20 20:00:34 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -40,6 +40,8 @@ static char *_sendCopyLine(ArchiveHandle *AH, char *qry, char *eos); ...@@ -40,6 +40,8 @@ static char *_sendCopyLine(ArchiveHandle *AH, char *qry, char *eos);
static int _isIdentChar(char c); static int _isIdentChar(char c);
static int _isDQChar(char c, int atStart); static int _isDQChar(char c, int atStart);
#define DB_MAX_ERR_STMT 128
static int static int
_parse_version(ArchiveHandle *AH, const char *versionString) _parse_version(ArchiveHandle *AH, const char *versionString)
{ {
...@@ -302,6 +304,7 @@ static int ...@@ -302,6 +304,7 @@ static int
_executeSqlCommand(ArchiveHandle *AH, PGconn *conn, PQExpBuffer qry, char *desc) _executeSqlCommand(ArchiveHandle *AH, PGconn *conn, PQExpBuffer qry, char *desc)
{ {
PGresult *res; PGresult *res;
char errStmt[DB_MAX_ERR_STMT];
/* fprintf(stderr, "Executing: '%s'\n\n", qry->data); */ /* fprintf(stderr, "Executing: '%s'\n\n", qry->data); */
res = PQexec(conn, qry->data); res = PQexec(conn, qry->data);
...@@ -318,8 +321,18 @@ _executeSqlCommand(ArchiveHandle *AH, PGconn *conn, PQExpBuffer qry, char *desc) ...@@ -318,8 +321,18 @@ _executeSqlCommand(ArchiveHandle *AH, PGconn *conn, PQExpBuffer qry, char *desc)
AH->pgCopyIn = 1; AH->pgCopyIn = 1;
} }
else else
warn_or_die_horribly(AH, modulename, "%s: %s", {
desc, PQerrorMessage(AH->connection)); strncpy(errStmt, qry->data, DB_MAX_ERR_STMT);
if (errStmt[DB_MAX_ERR_STMT-1] != '\0') {
errStmt[DB_MAX_ERR_STMT-4] = '.';
errStmt[DB_MAX_ERR_STMT-3] = '.';
errStmt[DB_MAX_ERR_STMT-2] = '.';
errStmt[DB_MAX_ERR_STMT-1] = '\0';
}
warn_or_die_horribly(AH, modulename, "%s: %s Command was: %s\n",
desc, PQerrorMessage(AH->connection),
errStmt);
}
} }
PQclear(res); PQclear(res);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment