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
@@ -3728,6 +3728,12 @@ testdb=> \setenv LESS -imx4F
generate one result to get.
+
+ When pipeline mode is active, a dedicated prompt variable is available
+ to report the pipeline status.
+ See for more details
+
+
Example:
@@ -4502,6 +4508,39 @@ bar
+
+ PIPELINE_COMMAND_COUNT
+
+
+ The number of commands generated by \bind,
+ \bind_named, \close or
+ \parse queued in an ongoing pipeline.
+
+
+
+
+
+ PIPELINE_RESULT_COUNT
+
+
+ The number of commands of an ongoing pipeline that were followed
+ by either a \flushrequest or a
+ \syncpipeline, forcing the server to send the
+ results. These results can be retrieved with
+ \getresults.
+
+
+
+
+
+ PIPELINE_SYNC_COUNT
+
+
+ The number of sync messages queued in an ongoing pipeline.
+
+
+
+
PORT
@@ -4901,6 +4940,17 @@ testdb=> INSERT INTO my_table VALUES (:'content');
+
+ %P
+
+
+ Pipeline status: off when not in a pipeline,
+ on when in an ongoing pipeline or
+ abort when in an aborted pipeline.
+
+
+
+
%R
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
@@ -524,6 +524,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
*
@@ -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.