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.