Attached a POC adding a new variable ECHO_ERROR \set ECHO_ERROR text|none|psqlstate
On Mon, Dec 3, 2018 at 2:47 AM Andrew Gierth <and...@tao11.riddles.org.uk> wrote: > > >>>>> "Tom" == Tom Lane <t...@sss.pgh.pa.us> writes: > > Tom> I don't buy that argument. We use psql's normal display in all the > Tom> regular regression tests, and it's not a big maintenance problem. > > The regular regression tests have the advantage that they don't need to > work across pg versions. > > It is more of a problem for extensions; I just ran into this myself in > fact, with a test failing because "invalid input syntax for integer" got > changed to "invalid input syntax for type integer". > > -- > Andrew (irc:RhodiumToad)
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 62c2928e6b..049d43086f 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -536,10 +536,22 @@ AcceptResult(const PGresult *result) if (!OK) { - const char *error = PQerrorMessage(pset.db); + const char *error = ""; + const char *err_fmt = "%s"; + switch (pset.echo_error) { + case PSQL_ECHO_ERROR_NONE: + break; + case PSQL_ECHO_ERROR_PSQLSTATE: + err_fmt = "%s\n"; + error = PQresultErrorField(result, PG_DIAG_SQLSTATE); + break; + default: + error = PQerrorMessage(pset.db); + break; + } if (strlen(error)) - psql_error("%s", error); + psql_error(err_fmt, error); CheckConnection(); } diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 2e9fe760eb..b653e37526 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -339,7 +339,7 @@ helpVariables(unsigned short int pager) * Windows builds currently print one more line than non-Windows builds. * Using the larger number is fine. */ - output = PageOutput(156, pager ? &(pset.popt.topt) : NULL); + output = PageOutput(159, pager ? &(pset.popt.topt) : NULL); fprintf(output, _("List of specially treated variables\n\n")); @@ -360,6 +360,9 @@ helpVariables(unsigned short int pager) fprintf(output, _(" ECHO_HIDDEN\n" " if set, display internal queries executed by backslash commands;\n" " if set to \"noexec\", just show them without execution\n")); + fprintf(output, _(" ECHO_ERROR\n" + " controls what error msg is written to standard error\n" + " [text, sqlstate, none]\n")); fprintf(output, _(" ENCODING\n" " current client character set encoding\n")); fprintf(output, _(" ERROR\n" @@ -411,7 +414,7 @@ helpVariables(unsigned short int pager) fprintf(output, _(" USER\n" " the currently connected database user\n")); fprintf(output, _(" VERBOSITY\n" - " controls verbosity of error reports [default, verbose, terse]\n")); + " controls verbosity of server error reports [default, verbose, terse]\n")); fprintf(output, _(" VERSION\n" " VERSION_NAME\n" " VERSION_NUM\n" diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h index 176c85afd0..dd1f5f2c55 100644 --- a/src/bin/psql/settings.h +++ b/src/bin/psql/settings.h @@ -48,6 +48,13 @@ typedef enum PSQL_ECHO_HIDDEN_NOEXEC } PSQL_ECHO_HIDDEN; +typedef enum +{ + PSQL_ECHO_ERROR_NONE, + PSQL_ECHO_ERROR_TEXT, + PSQL_ECHO_ERROR_PSQLSTATE +} PSQL_ECHO_ERROR; + typedef enum { PSQL_ERROR_ROLLBACK_OFF, @@ -132,6 +139,7 @@ typedef struct _psqlSettings int ignoreeof; PSQL_ECHO echo; PSQL_ECHO_HIDDEN echo_hidden; + PSQL_ECHO_ERROR echo_error; PSQL_ERROR_ROLLBACK on_error_rollback; PSQL_COMP_CASE comp_case; HistControl histcontrol; diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index e7536a8a06..156b4665ac 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -949,6 +949,33 @@ echo_hook(const char *newval) return true; } +static char * +echo_error_substitute_hook(char *newval) +{ + if (newval == NULL) + newval = pg_strdup("text"); + return newval; +} + +static bool +echo_error_hook(const char *newval) +{ + Assert(newval != NULL); /* else substitute hook messed up */ + if (pg_strcasecmp(newval, "text") == 0) + pset.echo_error = PSQL_ECHO_ERROR_TEXT; + else if (pg_strcasecmp(newval, "none") == 0) + pset.echo_error = PSQL_ECHO_ERROR_NONE; + else if (pg_strcasecmp(newval, "psqlstate") == 0) + pset.echo_error = PSQL_ECHO_ERROR_PSQLSTATE; + else + { + PsqlVarEnumError("ECHO_ERROR", newval, "none, psqlstate, text"); + return false; + } + return true; +} + + static bool echo_hidden_hook(const char *newval) { @@ -1167,6 +1194,9 @@ EstablishVariableSpace(void) SetVariableHooks(pset.vars, "ECHO_HIDDEN", bool_substitute_hook, echo_hidden_hook); + SetVariableHooks(pset.vars, "ECHO_ERROR", + echo_error_substitute_hook, + echo_error_hook); SetVariableHooks(pset.vars, "ON_ERROR_ROLLBACK", bool_substitute_hook, on_error_rollback_hook); diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index fa44b2820b..bf23c1f4bb 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3561,6 +3561,8 @@ psql_completion(const char *text, int start, int end) "preserve-lower", "preserve-upper"); else if (TailMatchesCS("ECHO")) COMPLETE_WITH_CS("errors", "queries", "all", "none"); + else if (TailMatchesCS("ECHO_ERROR")) + COMPLETE_WITH_CS("text", "sqlstate", "none"); else if (TailMatchesCS("ECHO_HIDDEN")) COMPLETE_WITH_CS("noexec", "off", "on"); else if (TailMatchesCS("HISTCONTROL"))