Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 69cf1d5

Browse files
committed
Add PQsendFlushRequest to libpq
This new libpq function allows the application to send an 'H' message, which instructs the server to flush its outgoing buffer. This hasn't been needed so far because the Sync message already requests a buffer; and I failed to realize that this was needed in pipeline mode because PQpipelineSync also causes the buffer to be flushed. However, sometimes it is useful to request a flush without establishing a synchronization point. Backpatch to 14, where pipeline mode was introduced in libpq. Reported-by: Boris Kolpackov <boris@codesynthesis.com> Author: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/202106252350.t76x73nt643j@alvherre.pgsql
1 parent f8b5146 commit 69cf1d5

File tree

4 files changed

+70
-3
lines changed

4 files changed

+70
-3
lines changed

doc/src/sgml/libpq.sgml

+31-2
Original file line numberDiff line numberDiff line change
@@ -5102,10 +5102,13 @@ int PQflush(PGconn *conn);
51025102
The server executes statements, and returns results, in the order the
51035103
client sends them. The server will begin executing the commands in the
51045104
pipeline immediately, not waiting for the end of the pipeline.
5105+
Note that results are buffered on the server side; the server flushes
5106+
that buffer when a synchronization point is established with
5107+
<function>PQpipelineSync</function>, or when
5108+
<function>PQsendFlushRequest</function> is called.
51055109
If any statement encounters an error, the server aborts the current
51065110
transaction and does not execute any subsequent command in the queue
5107-
until the next synchronization point established by
5108-
<function>PQpipelineSync</function>;
5111+
until the next synchronization point;
51095112
a <literal>PGRES_PIPELINE_ABORTED</literal> result is produced for
51105113
each such command.
51115114
(This remains true even if the commands in the pipeline would rollback
@@ -5399,6 +5402,32 @@ int PQpipelineSync(PGconn *conn);
53995402
</para>
54005403
</listitem>
54015404
</varlistentry>
5405+
5406+
<varlistentry id="libpq-PQsendFlushRequest">
5407+
<term><function>PQsendFlushRequest</function><indexterm><primary>PQsendFlushRequest</primary></indexterm></term>
5408+
5409+
<listitem>
5410+
<para>
5411+
Sends a request for the server to flush its output buffer.
5412+
<synopsis>
5413+
int PQsendFlushRequest(PGconn *conn);
5414+
</synopsis>
5415+
</para>
5416+
5417+
<para>
5418+
Returns 1 for success. Returns 0 on any failure.
5419+
</para>
5420+
<para>
5421+
The server flushes its output buffer automatically as a result of
5422+
<function>PQpipelineSync</function> being called, or
5423+
on any request when not in pipeline mode; this function is useful
5424+
to cause the server to flush its output buffer in pipeline mode
5425+
without establishing a synchronization point.
5426+
Note that the request is not itself flushed to the server automatically;
5427+
use <function>PQflush</function> if necessary.
5428+
</para>
5429+
</listitem>
5430+
</varlistentry>
54025431
</variablelist>
54035432
</sect2>
54045433

src/interfaces/libpq/exports.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,5 @@ PQexitPipelineMode 181
184184
PQpipelineSync 182
185185
PQpipelineStatus 183
186186
PQsetTraceFlags 184
187-
PQmblenBounded 185
187+
PQmblenBounded 185
188+
PQsendFlushRequest 186

src/interfaces/libpq/fe-exec.c

+36
Original file line numberDiff line numberDiff line change
@@ -3099,6 +3099,42 @@ PQpipelineSync(PGconn *conn)
30993099
return 0;
31003100
}
31013101

3102+
/*
3103+
* PQsendFlushRequest
3104+
* Send request for server to flush its buffer. Useful in pipeline
3105+
* mode when a sync point is not desired.
3106+
*/
3107+
int
3108+
PQsendFlushRequest(PGconn *conn)
3109+
{
3110+
if (!conn)
3111+
return 0;
3112+
3113+
/* Don't try to send if we know there's no live connection. */
3114+
if (conn->status != CONNECTION_OK)
3115+
{
3116+
appendPQExpBufferStr(&conn->errorMessage,
3117+
libpq_gettext("no connection to the server\n"));
3118+
return 0;
3119+
}
3120+
3121+
/* Can't send while already busy, either, unless enqueuing for later */
3122+
if (conn->asyncStatus != PGASYNC_IDLE &&
3123+
conn->pipelineStatus == PQ_PIPELINE_OFF)
3124+
{
3125+
appendPQExpBufferStr(&conn->errorMessage,
3126+
libpq_gettext("another command is already in progress\n"));
3127+
return false;
3128+
}
3129+
3130+
if (pqPutMsgStart('H', conn) < 0 ||
3131+
pqPutMsgEnd(conn) < 0)
3132+
{
3133+
return 0;
3134+
}
3135+
3136+
return 1;
3137+
}
31023138

31033139
/* ====== accessor funcs for PGresult ======== */
31043140

src/interfaces/libpq/libpq-fe.h

+1
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ extern int PQconsumeInput(PGconn *conn);
470470
extern int PQenterPipelineMode(PGconn *conn);
471471
extern int PQexitPipelineMode(PGconn *conn);
472472
extern int PQpipelineSync(PGconn *conn);
473+
extern int PQsendFlushRequest(PGconn *conn);
473474

474475
/* LISTEN/NOTIFY support */
475476
extern PGnotify *PQnotifies(PGconn *conn);

0 commit comments

Comments
 (0)