aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/ref/psql-ref.sgml50
-rw-r--r--src/bin/psql/common.c27
-rw-r--r--src/bin/psql/prompt.c14
-rw-r--r--src/bin/psql/startup.c5
-rw-r--r--src/test/regress/expected/psql_pipeline.out22
-rw-r--r--src/test/regress/sql/psql_pipeline.sql11
6 files changed, 128 insertions, 1 deletions
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 3edbd65e46c..cedccc14129 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -3729,6 +3729,12 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
</para>
<para>
+ When pipeline mode is active, a dedicated prompt variable is available
+ to report the pipeline status.
+ See <xref linkend="app-psql-prompting-p-uc"/> for more details
+ </para>
+
+ <para>
Example:
<programlisting>
\startpipeline
@@ -4502,6 +4508,39 @@ bar
</listitem>
</varlistentry>
+ <varlistentry id="app-psql-variables-pipeline-command-count">
+ <term><varname>PIPELINE_COMMAND_COUNT</varname></term>
+ <listitem>
+ <para>
+ The number of commands generated by <literal>\bind</literal>,
+ <literal>\bind_named</literal>, <literal>\close</literal> or
+ <literal>\parse</literal> queued in an ongoing pipeline.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="app-psql-variables-pipeline-result-count">
+ <term><varname>PIPELINE_RESULT_COUNT</varname></term>
+ <listitem>
+ <para>
+ The number of commands of an ongoing pipeline that were followed
+ by either a <command>\flushrequest</command> or a
+ <command>\syncpipeline</command>, forcing the server to send the
+ results. These results can be retrieved with
+ <command>\getresults</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="app-psql-variables-pipeline-sync-count">
+ <term><varname>PIPELINE_SYNC_COUNT</varname></term>
+ <listitem>
+ <para>
+ The number of sync messages queued in an ongoing pipeline.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="app-psql-variables-port">
<term><varname>PORT</varname></term>
<listitem>
@@ -4901,6 +4940,17 @@ testdb=&gt; <userinput>INSERT INTO my_table VALUES (:'content');</userinput>
</listitem>
</varlistentry>
+ <varlistentry id="app-psql-prompting-p-uc">
+ <term><literal>%P</literal></term>
+ <listitem>
+ <para>
+ Pipeline status: <literal>off</literal> when not in a pipeline,
+ <literal>on</literal> when in an ongoing pipeline or
+ <literal>abort</literal> when in an aborted pipeline.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="app-psql-prompting-r">
<term><literal>%R</literal></term>
<listitem>
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index bc8c40898f7..ed340a466f9 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -525,6 +525,26 @@ SetShellResultVariables(int wait_result)
/*
+ * Set special pipeline variables
+ * - PIPELINE_SYNC_COUNT: The number of piped syncs
+ * - PIPELINE_COMMAND_COUNT: The number of piped commands
+ * - PIPELINE_RESULT_COUNT: The number of results available to read
+ */
+static void
+SetPipelineVariables(void)
+{
+ char buf[32];
+
+ snprintf(buf, sizeof(buf), "%d", pset.piped_syncs);
+ SetVariable(pset.vars, "PIPELINE_SYNC_COUNT", buf);
+ snprintf(buf, sizeof(buf), "%d", pset.piped_commands);
+ SetVariable(pset.vars, "PIPELINE_COMMAND_COUNT", buf);
+ snprintf(buf, sizeof(buf), "%d", pset.available_results);
+ SetVariable(pset.vars, "PIPELINE_RESULT_COUNT", buf);
+}
+
+
+/*
* ClearOrSaveResult
*
* If the result represents an error, remember it for possible display by
@@ -1661,6 +1681,8 @@ ExecQueryAndProcessResults(const char *query,
CheckConnection();
+ SetPipelineVariables();
+
return -1;
}
@@ -1669,8 +1691,10 @@ ExecQueryAndProcessResults(const char *query,
{
/*
* We are in a pipeline and have not reached the pipeline end, or
- * there was no request to read pipeline results, exit.
+ * there was no request to read pipeline results. Update the psql
+ * variables tracking the pipeline activity and exit.
*/
+ SetPipelineVariables();
return 1;
}
@@ -2105,6 +2129,7 @@ ExecQueryAndProcessResults(const char *query,
Assert(pset.available_results == 0);
}
Assert(pset.requested_results == 0);
+ SetPipelineVariables();
/* may need this to recover from conn loss during COPY */
if (!CheckConnection())
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 08a14feb3c3..3aa7d2d06c8 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -31,6 +31,7 @@
* sockets, "[local:/dir/name]" if not default
* %m - like %M, but hostname only (before first dot), or always "[local]"
* %p - backend pid
+ * %P - pipeline status: on, off or abort
* %> - database server port number
* %n - database user name
* %s - service
@@ -181,6 +182,19 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
snprintf(buf, sizeof(buf), "%d", pid);
}
break;
+ /* pipeline status */
+ case 'P':
+ {
+ PGpipelineStatus status = PQpipelineStatus(pset.db);
+
+ if (status == PQ_PIPELINE_ON)
+ strlcpy(buf, "on", sizeof(buf));
+ else if (status == PQ_PIPELINE_ABORTED)
+ strlcpy(buf, "abort", sizeof(buf));
+ else
+ strlcpy(buf, "off", sizeof(buf));
+ break;
+ }
case '0':
case '1':
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 703f3f582c1..5018eedf1e5 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -205,6 +205,11 @@ main(int argc, char *argv[])
SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
SetVariableBool(pset.vars, "SHOW_ALL_RESULTS");
+ /* Initialize pipeline variables */
+ SetVariable(pset.vars, "PIPELINE_SYNC_COUNT", "0");
+ SetVariable(pset.vars, "PIPELINE_COMMAND_COUNT", "0");
+ SetVariable(pset.vars, "PIPELINE_RESULT_COUNT", "0");
+
parse_psql_options(argc, argv, &options);
/*
diff --git a/src/test/regress/expected/psql_pipeline.out b/src/test/regress/expected/psql_pipeline.out
index f4603d2b66a..3df2415a840 100644
--- a/src/test/regress/expected/psql_pipeline.out
+++ b/src/test/regress/expected/psql_pipeline.out
@@ -57,12 +57,24 @@ SELECT $1, $2 \bind 'val2' 'val3' \g
-- Send multiple syncs
\startpipeline
+\echo :PIPELINE_COMMAND_COUNT
+0
+\echo :PIPELINE_SYNC_COUNT
+0
+\echo :PIPELINE_RESULT_COUNT
+0
SELECT $1 \bind 'val1' \g
\syncpipeline
\syncpipeline
SELECT $1, $2 \bind 'val2' 'val3' \g
\syncpipeline
SELECT $1, $2 \bind 'val4' 'val5' \g
+\echo :PIPELINE_COMMAND_COUNT
+1
+\echo :PIPELINE_SYNC_COUNT
+3
+\echo :PIPELINE_RESULT_COUNT
+2
\endpipeline
?column?
----------
@@ -303,13 +315,21 @@ SELECT $1 \bind 2 \g
SELECT $1 \bind 1 \g
SELECT $1 \bind 2 \g
SELECT $1 \bind 3 \g
+\echo :PIPELINE_SYNC_COUNT
+0
\syncpipeline
+\echo :PIPELINE_SYNC_COUNT
+1
+\echo :PIPELINE_RESULT_COUNT
+3
\getresults 1
?column?
----------
1
(1 row)
+\echo :PIPELINE_RESULT_COUNT
+2
SELECT $1 \bind 4 \g
\getresults 3
?column?
@@ -322,6 +342,8 @@ SELECT $1 \bind 4 \g
3
(1 row)
+\echo :PIPELINE_RESULT_COUNT
+0
\endpipeline
?column?
----------
diff --git a/src/test/regress/sql/psql_pipeline.sql b/src/test/regress/sql/psql_pipeline.sql
index ec62e6c5f24..6517ebb71f8 100644
--- a/src/test/regress/sql/psql_pipeline.sql
+++ b/src/test/regress/sql/psql_pipeline.sql
@@ -27,12 +27,18 @@ SELECT $1, $2 \bind 'val2' 'val3' \g
-- Send multiple syncs
\startpipeline
+\echo :PIPELINE_COMMAND_COUNT
+\echo :PIPELINE_SYNC_COUNT
+\echo :PIPELINE_RESULT_COUNT
SELECT $1 \bind 'val1' \g
\syncpipeline
\syncpipeline
SELECT $1, $2 \bind 'val2' 'val3' \g
\syncpipeline
SELECT $1, $2 \bind 'val4' 'val5' \g
+\echo :PIPELINE_COMMAND_COUNT
+\echo :PIPELINE_SYNC_COUNT
+\echo :PIPELINE_RESULT_COUNT
\endpipeline
-- \startpipeline should not have any effect if already in a pipeline.
@@ -174,10 +180,15 @@ SELECT $1 \bind 2 \g
SELECT $1 \bind 1 \g
SELECT $1 \bind 2 \g
SELECT $1 \bind 3 \g
+\echo :PIPELINE_SYNC_COUNT
\syncpipeline
+\echo :PIPELINE_SYNC_COUNT
+\echo :PIPELINE_RESULT_COUNT
\getresults 1
+\echo :PIPELINE_RESULT_COUNT
SELECT $1 \bind 4 \g
\getresults 3
+\echo :PIPELINE_RESULT_COUNT
\endpipeline
-- \syncpipeline count as one command to fetch for \getresults.