psql-estream.patch
text/x-patch
Filename: psql-estream.patch
Type: text/x-patch
Part: 0
Message:
User control over psql error stream
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| doc/src/sgml/ref/psql-ref.sgml | 40 | 15 |
| src/bin/psql/command.c | 26 | 0 |
| src/bin/psql/common.c | 12 | 3 |
| src/bin/psql/settings.h | 8 | 0 |
| src/bin/psql/startup.c | 1 | 0 |
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index c41593c..695739e 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -1800,11 +1800,16 @@ lo_import 152801
specified, the query output will be reset to the standard output.
</para>
- <para><quote>Query results</quote> includes all tables, command
- responses, and notices obtained from the database server, as
- well as output of various backslash commands that query the
- database (such as <command>\d</command>), but not error
- messages.
+ <para><quote>Query results</quote> includes all tables, sql
+ command responses and status information, notifications from
+ <command>LISTEN</command>, and output of various backslash
+ commands that query the database (such as
+ <command>\d</command>). <quote>Query results</quote> do not
+ include errors from <application>psql</application>or notice
+ messages or errors from the database server unless
+ <command>\pset estream</command> is used. Nor do they include
+ output of backslash commands which do not query the database
+ (such as <command>\h</command>).
</para>
<tip>
@@ -1863,16 +1868,18 @@ lo_import 152801
<listitem>
<para>
- This command sets options affecting the output of query result tables.
- <replaceable class="parameter">option</replaceable>
- indicates which option is to be set. The semantics of
- <replaceable class="parameter">value</replaceable> vary depending
- on the selected option. For some options, omitting <replaceable
- class="parameter">value</replaceable> causes the option to be toggled
- or unset, as described under the particular option. If no such
- behavior is mentioned, then omitting
- <replaceable class="parameter">value</replaceable> just results in
- the current setting being displayed.
+ This command sets options affecting the output of errors and
+ query results. There are extensive options regarding table
+ formatting. <replaceable
+ class="parameter">option</replaceable> indicates which option
+ is to be set. The semantics of <replaceable
+ class="parameter">value</replaceable> vary depending on the
+ selected option. For some options, omitting <replaceable
+ class="parameter">value</replaceable> causes the option to be
+ toggled or unset, as described under the particular option.
+ If no such behavior is mentioned, then omitting <replaceable
+ class="parameter">value</replaceable> just results in the
+ current setting being displayed.
</para>
<para>
@@ -1914,6 +1921,24 @@ lo_import 152801
</varlistentry>
<varlistentry>
+ <term><literal>estream</literal></term>
+ <listitem>
+ <para>
+ Controls the output stream(s) used to report error messages.
+ <replaceable class="parameter">Value</replaceable> must be
+ one of: <literal>stderr</literal> (the default), which sends
+ errors to the standard error stream;
+ <literal>query</literal>, which injects error messages into
+ the query result output stream; or <literal>both</literal>,
+ which sends errors to both output streams. <quote>Error
+ messages</quote> are comprised of errors from
+ <application>psql</application> and notice messages and
+ errors from the database server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><literal>expanded</literal> (or <literal>x</literal>)</term>
<listitem>
<para>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 8ccd00d..454a4b9 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -2448,6 +2448,32 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
printf(_("Target width is %d.\n"), popt->topt.columns);
}
+ /* set error output stream */
+ else if (strcmp(param, "estream") == 0)
+ {
+ if (!value)
+ ;
+ else if (pg_strncasecmp("stderr", value, vallen) == 0)
+ pset.estream = PSQL_ESTREAM_STDERR;
+ else if (pg_strncasecmp("query", value, vallen) == 0)
+ pset.estream = PSQL_ESTREAM_QUERY;
+ else if (pg_strncasecmp("both", value, vallen) == 0)
+ pset.estream = PSQL_ESTREAM_BOTH;
+ else
+ {
+ psql_error("\\pset: allowed estream values are stderr, query, both\n");
+ return false;
+ }
+
+ if (!quiet)
+ if (pset.estream == PSQL_ESTREAM_STDERR)
+ puts(_("Errors sent to stderr."));
+ else if (pset.estream == PSQL_ESTREAM_QUERY)
+ puts(_("Errors injected into query output."));
+ else
+ puts(_("Errors sent to stderr and injected into query output."));
+ }
+
else
{
psql_error("\\pset: unknown option: %s\n", param);
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index 179c162..6183064 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -153,10 +153,19 @@ psql_error(const char *fmt,...)
if (pset.queryFout && pset.queryFout != stdout)
fflush(pset.queryFout);
- if (pset.inputfile)
- fprintf(stderr, "%s:%s:" UINT64_FORMAT ": ", pset.progname, pset.inputfile, pset.lineno);
+ if (pset.inputfile) {
+ if (pset.estream != PSQL_ESTREAM_QUERY)
+ fprintf(stderr, "%s:%s:" UINT64_FORMAT ": ",
+ pset.progname, pset.inputfile, pset.lineno);
+ if (pset.estream != PSQL_ESTREAM_STDERR)
+ fprintf(pset.queryFout, "%s:%s:" UINT64_FORMAT ": ",
+ pset.progname, pset.inputfile, pset.lineno);
+ }
va_start(ap, fmt);
- vfprintf(stderr, _(fmt), ap);
+ if (pset.estream != PSQL_ESTREAM_QUERY)
+ vfprintf(stderr, _(fmt), ap);
+ if (pset.estream != PSQL_ESTREAM_STDERR)
+ vfprintf(pset.queryFout, _(fmt), ap);
va_end(ap);
}
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
index c907fa0..5efb782 100644
--- a/src/bin/psql/settings.h
+++ b/src/bin/psql/settings.h
@@ -63,12 +63,20 @@ enum trivalue
TRI_YES
};
+typedef enum
+{
+ PSQL_ESTREAM_STDERR,
+ PSQL_ESTREAM_QUERY,
+ PSQL_ESTREAM_BOTH
+} PSQL_ESTREAM;
+
typedef struct _psqlSettings
{
PGconn *db; /* connection to backend */
int encoding; /* client_encoding */
FILE *queryFout; /* where to send the query results */
bool queryFoutPipe; /* queryFout is from a popen() */
+ PSQL_ESTREAM estream; /* where to send errors */
printQueryOpt popt;
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 1fcc47f..bd91025 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -120,6 +120,7 @@ main(int argc, char *argv[])
pset.encoding = PQenv2encoding();
pset.queryFout = stdout;
pset.queryFoutPipe = false;
+ pset.estream = PSQL_ESTREAM_STDERR;
pset.cur_cmd_source = stdin;
pset.cur_cmd_interactive = false;