operation. In such cases, the client
would have to introduce a synchronization point and wait for a full client/server
round-trip to get the results it needs. However, it's often possible to
adjust the client design to exchange the required information server-side.
Read-modify-write cycles are especially good candidates; for example:
<programlisting>
BEGIN;
SELECT x FROM mytable WHERE id = 42 FOR UPDATE;
-- result: x=2
-- client adds 1 to x:
UPDATE mytable SET x = 3 WHERE id = 42;
COMMIT;
</programlisting>
could be much more efficiently done with:
<programlisting>
UPDATE mytable SET x = x + 1 WHERE id = 42;
</programlisting>
</para>
<para>
Pipelining is less useful, and more complex, when a single pipeline contains
multiple transactions (see <xref linkend="libpq-pipeline-errors"/>).
</para>
</sect2>
</sect1>
<!-- keep this not-too-apropos sect1 ID for stability of doc URLs -->
<sect1 id="libpq-single-row-mode">
<title>Retrieving Query Results in Chunks</title>
<indexterm zone="libpq-single-row-mode">
<primary>libpq</primary>
<secondary>single-row mode</secondary>
</indexterm>
<indexterm zone="libpq-single-row-mode">
<primary>libpq</primary>
<secondary>chunked mode</secondary>
</indexterm>
<para>
Ordinarily, <application>libpq</application> collects an SQL command's
entire result and returns it to the application as a single
<structname>PGresult</structname>. This can be unworkable for commands
that return a large number of rows. For such cases, applications can use
<xref linkend="libpq-PQsendQuery"/> and <xref linkend="libpq-PQgetResult"/> in
<firstterm>single-row mode</firstterm> or <firstterm>chunked
mode</firstterm>. In these modes, result row(s) are returned to the
application as they are received from the server, one at a time for
single-row mode or in groups for chunked mode.
</para>
<para>
To enter one of these modes, call <xref linkend="libpq-PQsetSingleRowMode"/>
or <xref linkend="libpq-PQsetChunkedRowsMode"/>
immediately after a successful call of <xref linkend="libpq-PQsendQuery"/>
(or a sibling function). This mode selection is effective only for the
currently executing query. Then call <xref linkend="libpq-PQgetResult"/>
repeatedly, until it returns null, as documented in <xref
linkend="libpq-async"/>. If the query returns any rows, they are returned
as one or more <structname>PGresult</structname> objects, which look like
normal query results except for having status code
<literal>PGRES_SINGLE_TUPLE</literal> for single-row mode or
<literal>PGRES_TUPLES_CHUNK</literal> for chunked mode, instead of
<literal>PGRES_TUPLES_OK</literal>. There is exactly one result row in
each <literal>PGRES_SINGLE_TUPLE</literal> object, while
a <literal>PGRES_TUPLES_CHUNK</literal> object contains at least one
row but not more than the specified number of rows per chunk.
After the last row, or immediately if
the query returns zero rows, a zero-row object with status
<literal>PGRES_TUPLES_OK</literal> is returned; this is the signal that no
more rows will arrive. (But note that it is still necessary to continue
calling <xref linkend="libpq-PQgetResult"/> until it returns null.) All of
these <structname>PGresult</structname> objects will contain the same row
description data (column names, types, etc.) that an ordinary
<structname>PGresult</structname> object for the query would have.
Each object should be freed with <xref linkend="libpq-PQclear"/> as usual.
</para>
<para>
When using pipeline mode, single-row or chunked mode needs to be
activated for each query in the pipeline before retrieving results for
that query with <function>PQgetResult</function>.
See <xref linkend="libpq-pipeline-mode"/> for more information.
</para>
<para>
<variablelist>
<varlistentry id="libpq-PQsetSingleRowMode">
<term><function>PQsetSingleRowMode</function><indexterm><primary>PQsetSingleRowMode</primary></indexterm></term>