diff options
| author | Tom Lane | 2015-09-05 15:58:20 +0000 |
|---|---|---|
| committer | Tom Lane | 2015-09-05 15:58:33 +0000 |
| commit | 0426f349effb6bde2061f3398a71db7180c97dd9 (patch) | |
| tree | 741fcee27d57266182690fefd31721b8d6546b1e /src/interfaces | |
| parent | c80b5f66c6faff085e312492be0aa50754e99eb9 (diff) | |
Rearrange the handling of error context reports.
Remove the code in plpgsql that suppressed the innermost line of CONTEXT
for messages emitted by RAISE commands. That was never more than a quick
backwards-compatibility hack, and it's pretty silly in cases where the
RAISE is nested in several levels of function. What's more, it violated
our design theory that verbosity of error reports should be controlled
on the client side not the server side.
To alleviate the resulting noise increase, introduce a feature in libpq
and psql whereby the CONTEXT field of messages can be suppressed, either
always or only for non-error messages. Printing CONTEXT for errors only
is now their default behavior.
The actual code changes here are pretty small, but the effects on the
regression test outputs are widespread. I had to edit some of the
alternative expected outputs by hand; hopefully the buildfarm will soon
find anything I fat-fingered.
In passing, fix up (again) the output line counts in psql's various
help displays. Add some commentary about how to verify them.
Pavel Stehule, reviewed by Petr JelĂnek, Jeevan Chalke, and others
Diffstat (limited to 'src/interfaces')
| -rw-r--r-- | src/interfaces/libpq/exports.txt | 1 | ||||
| -rw-r--r-- | src/interfaces/libpq/fe-connect.c | 13 | ||||
| -rw-r--r-- | src/interfaces/libpq/fe-protocol3.c | 15 | ||||
| -rw-r--r-- | src/interfaces/libpq/libpq-fe.h | 11 | ||||
| -rw-r--r-- | src/interfaces/libpq/libpq-int.h | 1 |
5 files changed, 36 insertions, 5 deletions
diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt index 4a21bf1d2c..0bbcae51bb 100644 --- a/src/interfaces/libpq/exports.txt +++ b/src/interfaces/libpq/exports.txt @@ -169,3 +169,4 @@ PQsslInUse 166 PQsslStruct 167 PQsslAttributes 168 PQsslAttribute 169 +PQsetErrorContextVisibility 170 diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index a45f4cba34..f3030fb2c7 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -2782,6 +2782,7 @@ makeEmptyPGconn(void) conn->client_encoding = PG_SQL_ASCII; conn->std_strings = false; /* unless server says differently */ conn->verbosity = PQERRORS_DEFAULT; + conn->show_context = PQSHOW_CONTEXT_ERRORS; conn->sock = PGINVALID_SOCKET; conn->auth_req_received = false; conn->password_needed = false; @@ -5553,6 +5554,18 @@ PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity) return old; } +PGContextVisibility +PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context) +{ + PGContextVisibility old; + + if (!conn) + return PQSHOW_CONTEXT_ERRORS; + old = conn->show_context; + conn->show_context = show_context; + return old; +} + void PQtrace(PGconn *conn, FILE *debug_port) { diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c index dbc0d89a4e..641804cb06 100644 --- a/src/interfaces/libpq/fe-protocol3.c +++ b/src/interfaces/libpq/fe-protocol3.c @@ -250,7 +250,7 @@ pqParseInput3(PGconn *conn) if (!conn->result) { printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("out of memory")); + libpq_gettext("out of memory")); pqSaveErrorResult(conn); } } @@ -321,7 +321,7 @@ pqParseInput3(PGconn *conn) if (!conn->result) { printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("out of memory")); + libpq_gettext("out of memory")); pqSaveErrorResult(conn); } } @@ -934,9 +934,14 @@ pqGetErrorNotice3(PGconn *conn, bool isError) val = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY); if (val) appendPQExpBuffer(&workBuf, libpq_gettext("QUERY: %s\n"), val); - val = PQresultErrorField(res, PG_DIAG_CONTEXT); - if (val) - appendPQExpBuffer(&workBuf, libpq_gettext("CONTEXT: %s\n"), val); + if (conn->show_context == PQSHOW_CONTEXT_ALWAYS || + (conn->show_context == PQSHOW_CONTEXT_ERRORS && isError)) + { + val = PQresultErrorField(res, PG_DIAG_CONTEXT); + if (val) + appendPQExpBuffer(&workBuf, libpq_gettext("CONTEXT: %s\n"), + val); + } } if (conn->verbosity == PQERRORS_VERBOSE) { diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index a73eae2087..828c533c1a 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -110,6 +110,13 @@ typedef enum PQERRORS_VERBOSE /* all the facts, ma'am */ } PGVerbosity; +typedef enum +{ + PQSHOW_CONTEXT_NEVER, /* never show CONTEXT field */ + PQSHOW_CONTEXT_ERRORS, /* show CONTEXT for errors only (default) */ + PQSHOW_CONTEXT_ALWAYS /* always show CONTEXT field */ +} PGContextVisibility; + /* * PGPing - The ordering of this enum should not be altered because the * values are exposed externally via pg_isready. @@ -337,6 +344,10 @@ extern void PQinitOpenSSL(int do_ssl, int do_crypto); /* Set verbosity for PQerrorMessage and PQresultErrorMessage */ extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity); +/* Set CONTEXT visibility for PQerrorMessage and PQresultErrorMessage */ +extern PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, + PGContextVisibility show_context); + /* Enable/disable tracing */ extern void PQtrace(PGconn *conn, FILE *debug_port); extern void PQuntrace(PGconn *conn); diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index 21759578f3..04d056e6a6 100644 --- a/src/interfaces/libpq/libpq-int.h +++ b/src/interfaces/libpq/libpq-int.h @@ -394,6 +394,7 @@ struct pg_conn int client_encoding; /* encoding id */ bool std_strings; /* standard_conforming_strings */ PGVerbosity verbosity; /* error/notice message verbosity */ + PGContextVisibility show_context; /* whether to show CONTEXT field */ PGlobjfuncs *lobjfuncs; /* private state for large-object access fns */ /* Buffer for data received from backend and not yet processed */ |
