diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 255e8cac14..bbe5935019 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -72,6 +72,18 @@ PostgreSQL documentation
+
+
+
+
+
+ Print failed SQL commands to standard error output. This is
+ equivalent to setting the variable ECHO to
+ errors.
+
+
+
+
@@ -2812,7 +2824,9 @@ bar
queries,
psql merely prints all queries as
they are sent to the server. The switch for this is
- .
+ . If set to errors then only
+ failed queries are displayed on standard error output. The switch
+ for this is .
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index c08c81366d..676e2680af 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -995,6 +995,9 @@ SendQuery(const char *query)
results = NULL; /* PQclear(NULL) does nothing */
}
+ if (!OK && pset.echo == PSQL_ECHO_ERRORS)
+ psql_error("STATEMENT: %s\n", query);
+
/* If we made a temporary savepoint, possibly release/rollback */
if (on_error_rollback_savepoint)
{
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 3aa3c169c2..f8f000fb50 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -87,6 +87,7 @@ usage(void)
printf(_("\nInput and output options:\n"));
printf(_(" -a, --echo-all echo all input from script\n"));
+ printf(_(" -b, --echo-errors echo failed commands\n"));
printf(_(" -e, --echo-queries echo commands sent to server\n"));
printf(_(" -E, --echo-hidden display queries that internal commands generate\n"));
printf(_(" -L, --log-file=FILENAME send session log to file\n"));
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
index 0a60e6817b..453d6c889d 100644
--- a/src/bin/psql/settings.h
+++ b/src/bin/psql/settings.h
@@ -31,6 +31,7 @@ typedef enum
{
PSQL_ECHO_NONE,
PSQL_ECHO_QUERIES,
+ PSQL_ECHO_ERRORS,
PSQL_ECHO_ALL
} PSQL_ECHO;
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 45653a15a8..5a397e8d55 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -354,6 +354,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
{"command", required_argument, NULL, 'c'},
{"dbname", required_argument, NULL, 'd'},
{"echo-queries", no_argument, NULL, 'e'},
+ {"echo-errors", no_argument, NULL, 'b'},
{"echo-hidden", no_argument, NULL, 'E'},
{"file", required_argument, NULL, 'f'},
{"field-separator", required_argument, NULL, 'F'},
@@ -391,7 +392,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
memset(options, 0, sizeof *options);
- while ((c = getopt_long(argc, argv, "aAc:d:eEf:F:h:HlL:no:p:P:qR:sStT:U:v:VwWxXz?01",
+ while ((c = getopt_long(argc, argv, "aAbc:d:eEf:F:h:HlL:no:p:P:qR:sStT:U:v:VwWxXz?01",
long_options, &optindex)) != -1)
{
switch (c)
@@ -402,6 +403,9 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
case 'A':
pset.popt.topt.format = PRINT_UNALIGNED;
break;
+ case 'b':
+ SetVariable(pset.vars, "ECHO", "errors");
+ break;
case 'c':
options->action_string = pg_strdup(optarg);
if (optarg[0] == '\\')
@@ -720,6 +724,8 @@ echo_hook(const char *newval)
pset.echo = PSQL_ECHO_NONE;
else if (strcmp(newval, "queries") == 0)
pset.echo = PSQL_ECHO_QUERIES;
+ else if (strcmp(newval, "errors") == 0)
+ pset.echo = PSQL_ECHO_ERRORS;
else if (strcmp(newval, "all") == 0)
pset.echo = PSQL_ECHO_ALL;
else