Home Explore Blog CI



postgresql

80th chunk of `doc/src/sgml/libpq.sgml`
9c7c8e373bef4bb41460a35c67d069eeb18b7d57c1e8d5950000000100000fb5
 such as <function>PQfn</function>,
    <function>PQexec</function>,
    <function>PQexecParams</function>,
    <function>PQprepare</function>,
    <function>PQexecPrepared</function>,
    <function>PQdescribePrepared</function>,
    <function>PQdescribePortal</function>,
    <function>PQclosePrepared</function>,
    <function>PQclosePortal</function>,
    is an error condition.
    <function>PQsendQuery</function> is
    also disallowed, because it uses the simple query protocol.
    Once all dispatched commands have had their results processed, and
    the end pipeline result has been consumed, the application may return
    to non-pipelined mode with <xref linkend="libpq-PQexitPipelineMode"/>.
   </para>

   <note>
    <para>
     It is best to use pipeline mode with <application>libpq</application> in
     <link linkend="libpq-PQsetnonblocking">non-blocking mode</link>. If used
     in blocking mode it is possible for a client/server deadlock to occur.
      <footnote>
       <para>
        The client will block trying to send queries to the server, but the
        server will block trying to send results to the client from queries
        it has already processed. This only occurs when the client sends
        enough queries to fill both its output buffer and the server's receive
        buffer before it switches to processing input from the server,
        but it's hard to predict exactly when that will happen.
       </para>
      </footnote>
    </para>
   </note>

   <sect3 id="libpq-pipeline-sending">
    <title>Issuing Queries</title>

    <para>
     After entering pipeline mode, the application dispatches requests using
     <xref linkend="libpq-PQsendQueryParams"/>
     or its prepared-query sibling
     <xref linkend="libpq-PQsendQueryPrepared"/>.
     These requests are queued on the client-side until flushed to the server;
     this occurs when <xref linkend="libpq-PQpipelineSync"/> is used to
     establish a synchronization point in the pipeline,
     or when <xref linkend="libpq-PQflush"/> is called.
     The functions <xref linkend="libpq-PQsendPrepare"/>,
     <xref linkend="libpq-PQsendDescribePrepared"/>,
     <xref linkend="libpq-PQsendDescribePortal"/>,
     <xref linkend="libpq-PQsendClosePrepared"/>, and
     <xref linkend="libpq-PQsendClosePortal"/> also work in pipeline mode.
     Result processing is described below.
    </para>

    <para>
     The server executes statements, and returns results, in the order the
     client sends them.  The server will begin executing the commands in the
     pipeline immediately, not waiting for the end of the pipeline.
     Note that results are buffered on the server side; the server flushes
     that buffer when a synchronization point is established with either
     <function>PQpipelineSync</function> or
     <function>PQsendPipelineSync</function>, or when
     <function>PQsendFlushRequest</function> is called.
     If any statement encounters an error, the server aborts the current
     transaction and does not execute any subsequent command in the queue
     until the next synchronization point;
     a <literal>PGRES_PIPELINE_ABORTED</literal> result is produced for
     each such command.
     (This remains true even if the commands in the pipeline would rollback
     the transaction.)
     Query processing resumes after the synchronization point.
    </para>

    <para>
     It's fine for one operation to depend on the results of a
     prior one; for example, one query may define a table that the next
     query in the same pipeline uses. Similarly, an application may
     create a named prepared statement and execute it with later
     statements in the same pipeline.
    </para>
   </sect3>

   <sect3 id="libpq-pipeline-results">
    <title>Processing Results</title>

    <para>
     To process the result of one query in a pipeline, the application calls
     <function>PQgetResult</function> repeatedly and handles each result
     until <function>PQgetResult</function>

Title: Pipeline Mode Usage: Sending Queries, Handling Results, and Avoiding Deadlocks
Summary
This section details how to use pipeline mode in libpq. It emphasizes the importance of using non-blocking mode to avoid client/server deadlocks, which can occur when the client's output buffer and the server's receive buffer are full. To dispatch requests, applications use `PQsendQueryParams` or `PQsendQueryPrepared`. These requests are queued until flushed via `PQpipelineSync` or `PQflush`. The server executes statements in order, buffering results until a synchronization point established with `PQpipelineSync`, `PQsendPipelineSync`, or `PQsendFlushRequest`. Errors cause the server to abort the transaction until the next synchronization point, producing a `PGRES_PIPELINE_ABORTED` result for each subsequent command. Query processing resumes after synchronization. Operations can depend on prior results within the same pipeline. Result processing involves calling `PQgetResult` repeatedly and handling each result until it returns NULL, indicating the end of the result set.