Skip to content

Commit 2cce0fe

Browse files
committed
psql: Allow queries terminated by semicolons while in pipeline mode
Currently, the only way to pipe queries in an ongoing pipeline (in a \startpipeline block) is to leverage the meta-commands able to create extended queries such as \bind, \parse or \bind_named. While this is good enough for testing the backend with pipelines, it has been mentioned that it can also be very useful to allow queries terminated by semicolons to be appended to a pipeline. For example, it would be possible to migrate existing psql scripts to use pipelines by just adding a set of \startpipeline and \endpipeline meta-commands, making such scripts more efficient. Doing such a change is proving to be simple in psql: queries terminated by semicolons can be executed through PQsendQueryParams() without any parameters set when the pipeline mode is active, instead of PQsendQuery(), the default, like pgbench. \watch is still forbidden while in a pipeline, as it expects its results to be processed synchronously. The large portion of this commit consists in providing more test coverage, with mixes of extended queries appended in a pipeline by \bind and friends, and queries terminated by semicolons. This improvement has been suggested by Daniel Vérité. Author: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com> Discussion: https://postgr.es/m/d67b9c19-d009-4a50-8020-1a0ea92366a1@manitou-mail.org
1 parent 0b53c08 commit 2cce0fe

File tree

5 files changed

+359
-47
lines changed

5 files changed

+359
-47
lines changed

doc/src/sgml/ref/psql-ref.sgml

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3698,14 +3698,15 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
36983698
</para>
36993699

37003700
<para>
3701-
Pipeline mode requires the use of the extended query protocol. All
3702-
queries need to be sent using the meta-commands
3703-
<literal>\bind</literal>, <literal>\bind_named</literal>,
3704-
<literal>\close</literal> or <literal>\parse</literal>. While a
3705-
pipeline is ongoing, <literal>\sendpipeline</literal> will append the
3706-
current query buffer to the pipeline. Other meta-commands like
3707-
<literal>\g</literal>, <literal>\gx</literal> or <literal>\gdesc</literal>
3708-
are not allowed in pipeline mode.
3701+
All queries executed while a pipeline is ongoing use the extended
3702+
query protocol. Queries are appended to the pipeline when ending with
3703+
a semicolon. The meta-commands <literal>\bind</literal>,
3704+
<literal>\bind_named</literal>, <literal>\close</literal> or
3705+
<literal>\parse</literal> can be used in an ongoing pipeline. While
3706+
a pipeline is ongoing, <literal>\sendpipeline</literal> will append
3707+
the current query buffer to the pipeline. Other meta-commands like
3708+
<literal>\g</literal>, <literal>\gx</literal> or
3709+
<literal>\gdesc</literal> are not allowed in pipeline mode.
37093710
</para>
37103711

37113712
<para>
@@ -3723,10 +3724,7 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
37233724
If provided, only the first
37243725
<replaceable class="parameter">number_results</replaceable> pending
37253726
results will be read. If not provided or <literal>0</literal>, all
3726-
pending results are read. The commands <literal>\bind</literal>,
3727-
<literal>\bind_named</literal>, <literal>\close</literal>,
3728-
<literal>\parse</literal> and <literal>\syncpipeline</literal>
3729-
generate one result to get.
3727+
pending results are read.
37303728
</para>
37313729

37323730
<para>
@@ -3739,6 +3737,7 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
37393737
Example:
37403738
<programlisting>
37413739
\startpipeline
3740+
SELECT * FROM pg_class;
37423741
SELECT 1 \bind \sendpipeline
37433742
\flushrequest
37443743
\getresults
@@ -4513,9 +4512,7 @@ bar
45134512
<term><varname>PIPELINE_COMMAND_COUNT</varname></term>
45144513
<listitem>
45154514
<para>
4516-
The number of commands generated by <literal>\bind</literal>,
4517-
<literal>\bind_named</literal>, <literal>\close</literal> or
4518-
<literal>\parse</literal> queued in an ongoing pipeline.
4515+
The number of commands queued in an ongoing pipeline.
45194516
</para>
45204517
</listitem>
45214518
</varlistentry>

src/bin/psql/command.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3282,6 +3282,13 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch,
32823282
int iter = 0;
32833283
int min_rows = 0;
32843284

3285+
if (PQpipelineStatus(pset.db) != PQ_PIPELINE_OFF)
3286+
{
3287+
pg_log_error("\\watch not allowed in pipeline mode");
3288+
clean_extended_state();
3289+
success = false;
3290+
}
3291+
32853292
/*
32863293
* Parse arguments. We allow either an unlabeled interval or
32873294
* "name=value", where name is from the set ('i', 'interval', 'c',

src/bin/psql/common.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1668,7 +1668,15 @@ ExecQueryAndProcessResults(const char *query,
16681668
}
16691669
break;
16701670
case PSQL_SEND_QUERY:
1671-
success = PQsendQuery(pset.db, query);
1671+
if (PQpipelineStatus(pset.db) != PQ_PIPELINE_OFF)
1672+
{
1673+
success = PQsendQueryParams(pset.db, query,
1674+
0, NULL, NULL, NULL, NULL, 0);
1675+
if (success)
1676+
pset.piped_commands++;
1677+
}
1678+
else
1679+
success = PQsendQuery(pset.db, query);
16721680
break;
16731681
}
16741682

0 commit comments

Comments
 (0)