($INBOX_DIR/description missing)  
help / color / mirror / Atom feed
[PATCH 2/2] doc review
26+ messages / 3 participants
[nested] [flat]

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* [PATCH 2/2] doc review
@ 2021-03-03 22:36  Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Justin Pryzby @ 2021-03-03 22:36 UTC (permalink / raw)

---
 doc/src/sgml/libpq.sgml                | 67 +++++++++++++-------------
 src/interfaces/libpq/fe-exec.c         |  2 +-
 src/test/modules/test_libpq/pipeline.c |  6 +--
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a34ecbb144..e2865a218b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -3130,8 +3130,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_SYNC</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a point in a
-            pipeline where a synchronization point has been established.
+            The <structname>PGresult</structname> represents a
+            synchronization point in pipeline mode, requested by 
+            <xref linkend="libpq-PQsendPipeline"/>.
             This status occurs only when pipeline mode has been selected.
            </para>
           </listitem>
@@ -3141,9 +3142,9 @@ ExecStatusType PQresultStatus(const PGresult *res);
           <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
           <listitem>
            <para>
-            The <structname>PGresult</structname> represents a pipeline that's
+            The <structname>PGresult</structname> represents a pipeline that has
             received an error from the server.  <function>PQgetResult</function>
-            must be called repeatedly, and it will return this status code,
+            must be called repeatedly, and each time it will return this status code
             until the end of the current pipeline, at which point it will return
             <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
             resume.
@@ -4953,7 +4954,7 @@ int PQflush(PGconn *conn);
    <title>Using Pipeline Mode</title>
 
    <para>
-    To issue pipelines the application must switch a connection into pipeline mode.
+    To issue pipelines, the application must switch a connection into pipeline mode.
     Enter pipeline mode with <xref linkend="libpq-PQenterPipelineMode"/>
     or test whether pipeline mode is active with
     <xref linkend="libpq-PQpipelineStatus"/>.
@@ -4975,7 +4976,7 @@ int PQflush(PGconn *conn);
         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 switching to processing input from the server,
+        buffer before it switches to processing input from the server,
         but it's hard to predict exactly when that will happen.
        </para>
       </footnote>
@@ -5025,7 +5026,7 @@ int PQflush(PGconn *conn);
     <title>Processing Results</title>
 
     <para>
-     To process the result of one pipeline query, the application calls
+     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> returns null.
      The result from the next query in the pipeline may then be retrieved using
@@ -5057,10 +5058,10 @@ int PQflush(PGconn *conn);
      <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
      and <literal>PGRES_PIPELINE_ABORTED</literal>.
      <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
-     <function>PQsendPipeline</function> call at the corresponding point in
-     the result stream.
+     <function>PQsendPipeline</function> after retrieving results for all
+     queries in the pipeline.
      <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
-     result stream result for the first error and all subsequent results
+     stream result for the first error and all subsequent results
      except <literal>PGRES_PIPELINE_SYNC</literal> and null;
      see <xref linkend="libpq-pipeline-errors"/>.
     </para>
@@ -5075,7 +5076,8 @@ int PQflush(PGconn *conn);
      application about the query currently being processed (except that
      <function>PQgetResult</function> returns null to indicate that we start
      returning the results of next query). The application must keep track
-     of the order in which it sent queries and the expected results.
+     of the order in which it sent queries, to associate them with their
+     corresponding results.
      Applications will typically use a state machine or a FIFO queue for this.
     </para>
 
@@ -5091,10 +5093,10 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     From the client perspective, after the client gets a
-     <literal>PGRES_FATAL_ERROR</literal> return from
-     <function>PQresultStatus</function> the pipeline is flagged as aborted.
-     <application>libpq</application> will report
+     From the client perspective, after <function>PQresultStatus</function>
+     returns <literal>PGRES_FATAL_ERROR</literal>,
+     the pipeline is flagged as aborted.
+     <function>PQresultStatus</function>, will report a
      <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
      operation in an aborted pipeline. The result for
      <function>PQsendPipeline</function> is reported as
@@ -5108,8 +5110,8 @@ int PQflush(PGconn *conn);
     </para>
 
     <para>
-     If the pipeline used an implicit transaction then operations that have
-     already executed are rolled back and operations that were queued for after
+     If the pipeline used an implicit transaction, then operations that have
+     already executed are rolled back and operations that were queued to follow
      the failed operation are skipped entirely. The same behaviour holds if the
      pipeline starts and commits a single explicit transaction (i.e. the first
      statement is <literal>BEGIN</literal> and the last is
@@ -5145,11 +5147,11 @@ int PQflush(PGconn *conn);
 
     <para>
      The client application should generally maintain a queue of work
-     still to be dispatched and a queue of work that has been dispatched
+     remaining to be dispatched and a queue of work that has been dispatched
      but not yet had its results processed. When the socket is writable
      it should dispatch more work. When the socket is readable it should
      read results and process them, matching them up to the next entry in
-     its expected results queue.  Based on available memory, results from
+     its expected results queue.  Based on available memory, results from the
      socket should be read frequently: there's no need to wait until the
      pipeline end to read the results.  Pipelines should be scoped to logical
      units of work, usually (but not necessarily) one transaction per pipeline.
@@ -5191,8 +5193,8 @@ int PQflush(PGconn *conn);
 
      <listitem>
       <para>
-      Returns current pipeline mode status of the <application>libpq</application>
-      connection.
+      Returns the current pipeline mode status of the
+      <application>libpq</application> connection.
 <synopsis>
 PGpipelineStatus PQpipelineStatus(const PGconn *conn);
 </synopsis>
@@ -5233,11 +5235,10 @@ PGpipelineStatus PQpipelineStatus(const PGconn *conn);
          <listitem>
           <para>
            The <application>libpq</application> connection is in pipeline
-           mode and an error has occurred while processing the current
-           pipeline.
-           The aborted flag is cleared as soon as the result
-           of the <function>PQsendPipeline</function> at the end of the aborted
-           pipeline is processed. Clients don't usually need this function to
+           mode and an error occurred while processing the current pipeline.
+           The aborted flag is cleared when <function>PQresultStatus</function>
+           returns PGRES_PIPELINE_SYNC at the end of the pipeline.
+           Clients don't usually need this function to
            verify aborted status, as they can tell that the pipeline is aborted
            from the <literal>PGRES_PIPELINE_ABORTED</literal> result code.
           </para>
@@ -5328,7 +5329,7 @@ int PQsendPipeline(PGconn *conn);
        Returns 1 for success. Returns 0 if the connection is not in
        pipeline mode or sending a
        <link linkend="protocol-flow-ext-query">sync message</link>
-       is failed.
+       failed.
       </para>
      </listitem>
     </varlistentry>
@@ -5349,7 +5350,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is most useful when the server is distant, i.e., network latency
     (<quote>ping time</quote>) is high, and also when many small operations
-    are being performed in rapid sequence.  There is usually less benefit
+    are being performed in rapid succession.  There is usually less benefit
     in using pipelined commands when each query takes many multiples of the client/server
     round-trip time to execute.  A 100-statement operation run on a server
     300ms round-trip-time away would take 30 seconds in network latency alone
@@ -5367,7 +5368,7 @@ int PQsendPipeline(PGconn *conn);
    <para>
     Pipeline mode is not useful when information from one operation is required by
     the client to produce the next operation. In such cases, the client
-    must introduce a synchronization point and wait for a full client/server
+    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:
@@ -5392,10 +5393,10 @@ UPDATE mytable SET x = x + 1 WHERE id = 42;
 
    <note>
     <para>
-     The pipeline API was introduced in PostgreSQL 14, but clients using
-     the PostgreSQL 14 version of <application>libpq</application> can use
-     pipelines on server versions 7.4 and newer. Pipeline mode works on any server
-     that supports the v3 extended query protocol.
+     The pipeline API was introduced in <productname>PostgreSQL</productname> 14.
+     Pipeline mode is a client-side feature which doesn't require server
+     support, and works on any server that supports the v3 extended query
+     protocol.
     </para>
    </note>
   </sect2>
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7ae7c14948..d7b036a35c 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -3803,7 +3803,7 @@ pqPipelineFlush(PGconn *conn)
 {
 	if ((conn->pipelineStatus == PQ_PIPELINE_OFF) ||
 		(conn->outCount >= OUTBUFFER_THRESHOLD))
-		return (pqFlush(conn));
+		return pqFlush(conn);
 	return 0;
 }
 
diff --git a/src/test/modules/test_libpq/pipeline.c b/src/test/modules/test_libpq/pipeline.c
index f4a2bdec57..01d5a9a8ff 100644
--- a/src/test/modules/test_libpq/pipeline.c
+++ b/src/test/modules/test_libpq/pipeline.c
@@ -126,7 +126,7 @@ test_simple_pipeline(PGconn *conn)
 	 * process the results of as they come in.
 	 *
 	 * For a simple case we should be able to do this without interim
-	 * processing of results since our out buffer will give us enough slush to
+	 * processing of results since our output buffer will give us enough slush to
 	 * work with and we won't block on sending. So blocking mode is fine.
 	 */
 	if (PQisnonblocking(conn))
@@ -603,7 +603,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 
 	/*
 	 * Now we start inserting. We'll be sending enough data that we could fill
-	 * our out buffer, so to avoid deadlocking we need to enter nonblocking
+	 * our output buffer, so to avoid deadlocking we need to enter nonblocking
 	 * mode and consume input while we send more output. As results of each
 	 * query are processed we should pop them to allow processing of the next
 	 * query. There's no need to finish the pipeline before processing
@@ -635,7 +635,7 @@ test_pipelined_insert(PGconn *conn, int n_rows)
 		}
 
 		/*
-		 * Process any results, so we keep the server's out buffer free
+		 * Process any results, so we keep the server's output buffer free
 		 * flowing and it can continue to process input
 		 */
 		if (FD_ISSET(sock, &input_mask))
-- 
2.17.0


--oC1+HKm2/end4ao3--





^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* Re: Deduplicate min restart_lsn calculation code
@ 2022-01-06 18:24  Alvaro Herrera <[email protected]>
  0 siblings, 1 reply; 26+ messages in thread

From: Alvaro Herrera @ 2022-01-06 18:24 UTC (permalink / raw)
  To: Bharath Rupireddy <[email protected]>; +Cc: PostgreSQL Hackers <[email protected]>

On 2022-Jan-06, Bharath Rupireddy wrote:

> Hi,
> 
> It seems like the two functions ReplicationSlotsComputeRequiredLSN and
> ReplicationSlotsComputeLogicalRestartLSN more or less does the same
> thing which makes me optimize (saving 40 LOC) it as attached. I'm
> pretty much okay if it gets rejected on the grounds that it creates a
> lot of diff with the older versions and the new API may not look
> nicer, still I want to give it a try.
> 
> Thoughts?

Hmm, it seems sensible to me.  But I would not have the second boolean
argument in the new function, and instead have the caller save the
return value in a local variable to do the XLogSetReplicationSlotMinimumLSN
step separately.  Then the new function API is not so strange.

-- 
Álvaro Herrera           39°49'30"S 73°17'W  —  https://www.EnterpriseDB.com/
"Linux transformó mi computadora, de una `máquina para hacer cosas',
en un aparato realmente entretenido, sobre el cual cada día aprendo
algo nuevo" (Jaime Salinas)






^ permalink  raw  reply  [nested|flat] 26+ messages in thread

* Re: Deduplicate min restart_lsn calculation code
@ 2022-01-07 03:37  Bharath Rupireddy <[email protected]>
  parent: Alvaro Herrera <[email protected]>
  0 siblings, 0 replies; 26+ messages in thread

From: Bharath Rupireddy @ 2022-01-07 03:37 UTC (permalink / raw)
  To: Alvaro Herrera <[email protected]>; +Cc: PostgreSQL Hackers <[email protected]>

On Thu, Jan 6, 2022 at 11:54 PM Alvaro Herrera <[email protected]> wrote:
>
> On 2022-Jan-06, Bharath Rupireddy wrote:
>
> > Hi,
> >
> > It seems like the two functions ReplicationSlotsComputeRequiredLSN and
> > ReplicationSlotsComputeLogicalRestartLSN more or less does the same
> > thing which makes me optimize (saving 40 LOC) it as attached. I'm
> > pretty much okay if it gets rejected on the grounds that it creates a
> > lot of diff with the older versions and the new API may not look
> > nicer, still I want to give it a try.
> >
> > Thoughts?
>
> Hmm, it seems sensible to me.  But I would not have the second boolean
> argument in the new function, and instead have the caller save the
> return value in a local variable to do the XLogSetReplicationSlotMinimumLSN
> step separately.  Then the new function API is not so strange.

Thanks for taking a look at it. Here's the v2 patch, please review.

Regards,
Bharath Rupireddy.


Attachments:

  [application/octet-stream] v2-0001-deduplicate-min-restart_lsn-calculation-code.patch (10.4K, ../../CALj2ACUqex0S8wYxrm5_Qz4NYnsqs6s8JMYeeg2qO35kS7hUAA@mail.gmail.com/2-v2-0001-deduplicate-min-restart_lsn-calculation-code.patch)
  download | inline diff:
From 02ea832d505ee05b701c2e255a9f084a0b765624 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <[email protected]>
Date: Fri, 7 Jan 2022 03:16:51 +0000
Subject: [PATCH v2] deduplicate min restart_lsn calculation code

---
 src/backend/access/heap/rewriteheap.c       |  2 +-
 src/backend/replication/logical/logical.c   |  5 +-
 src/backend/replication/logical/snapbuild.c |  2 +-
 src/backend/replication/slot.c              | 89 ++++++---------------
 src/backend/replication/slotfuncs.c         |  8 +-
 src/backend/replication/walsender.c         |  5 +-
 src/include/replication/slot.h              |  3 +-
 7 files changed, 43 insertions(+), 71 deletions(-)

diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 986a776bbd..7265ac0652 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -1204,7 +1204,7 @@ CheckPointLogicalRewriteHeap(void)
 	redo = GetRedoRecPtr();
 
 	/* now check for the restart ptrs from existing slots */
-	cutoff = ReplicationSlotsComputeLogicalRestartLSN();
+	cutoff = ReplicationSlotsComputeRequiredLSN(true);
 
 	/* don't start earlier than the restart lsn */
 	if (cutoff != InvalidXLogRecPtr && redo < cutoff)
diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c
index 10cbdea124..f61378fa2f 100644
--- a/src/backend/replication/logical/logical.c
+++ b/src/backend/replication/logical/logical.c
@@ -1771,12 +1771,15 @@ LogicalConfirmReceivedLocation(XLogRecPtr lsn)
 		 */
 		if (updated_xmin)
 		{
+			XLogRecPtr	min_required;
+
 			SpinLockAcquire(&MyReplicationSlot->mutex);
 			MyReplicationSlot->effective_catalog_xmin = MyReplicationSlot->data.catalog_xmin;
 			SpinLockRelease(&MyReplicationSlot->mutex);
 
 			ReplicationSlotsComputeRequiredXmin(false);
-			ReplicationSlotsComputeRequiredLSN();
+			min_required = ReplicationSlotsComputeRequiredLSN(false);
+			XLogSetReplicationSlotMinimumLSN(min_required);
 		}
 	}
 	else
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index dbdc172a2b..a0cb09836e 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1935,7 +1935,7 @@ CheckPointSnapBuild(void)
 	redo = GetRedoRecPtr();
 
 	/* now check for the restart ptrs from existing slots */
-	cutoff = ReplicationSlotsComputeLogicalRestartLSN();
+	cutoff = ReplicationSlotsComputeRequiredLSN(true);
 
 	/* don't start earlier than the restart lsn */
 	if (redo < cutoff)
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 90ba9b417d..d299bbf347 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -594,6 +594,7 @@ ReplicationSlotDropPtr(ReplicationSlot *slot)
 {
 	char		path[MAXPGPATH];
 	char		tmppath[MAXPGPATH];
+	XLogRecPtr	min_required;
 
 	/*
 	 * If some other backend ran this code concurrently with us, we might try
@@ -665,7 +666,8 @@ ReplicationSlotDropPtr(ReplicationSlot *slot)
 	 * limits.
 	 */
 	ReplicationSlotsComputeRequiredXmin(false);
-	ReplicationSlotsComputeRequiredLSN();
+	min_required = ReplicationSlotsComputeRequiredLSN(false);
+	XLogSetReplicationSlotMinimumLSN(min_required);
 
 	/*
 	 * If removing the directory fails, the worst thing that will happen is
@@ -807,82 +809,37 @@ ReplicationSlotsComputeRequiredXmin(bool already_locked)
 }
 
 /*
- * Compute the oldest restart LSN across all slots and inform xlog module.
+ * Compute the oldest restart LSN of replication slots
+ *
+ * When only_logical is true, compute for logical decoding slots only.
  *
  * Note: while max_slot_wal_keep_size is theoretically relevant for this
  * purpose, we don't try to account for that, because this module doesn't
  * know what to compare against.
  */
-void
-ReplicationSlotsComputeRequiredLSN(void)
-{
-	int			i;
-	XLogRecPtr	min_required = InvalidXLogRecPtr;
-
-	Assert(ReplicationSlotCtl != NULL);
-
-	LWLockAcquire(ReplicationSlotControlLock, LW_SHARED);
-	for (i = 0; i < max_replication_slots; i++)
-	{
-		ReplicationSlot *s = &ReplicationSlotCtl->replication_slots[i];
-		XLogRecPtr	restart_lsn;
-
-		if (!s->in_use)
-			continue;
-
-		SpinLockAcquire(&s->mutex);
-		restart_lsn = s->data.restart_lsn;
-		SpinLockRelease(&s->mutex);
-
-		if (restart_lsn != InvalidXLogRecPtr &&
-			(min_required == InvalidXLogRecPtr ||
-			 restart_lsn < min_required))
-			min_required = restart_lsn;
-	}
-	LWLockRelease(ReplicationSlotControlLock);
-
-	XLogSetReplicationSlotMinimumLSN(min_required);
-}
-
-/*
- * Compute the oldest WAL LSN required by *logical* decoding slots..
- *
- * Returns InvalidXLogRecPtr if logical decoding is disabled or no logical
- * slots exist.
- *
- * NB: this returns a value >= ReplicationSlotsComputeRequiredLSN(), since it
- * ignores physical replication slots.
- *
- * The results aren't required frequently, so we don't maintain a precomputed
- * value like we do for ComputeRequiredLSN() and ComputeRequiredXmin().
- */
 XLogRecPtr
-ReplicationSlotsComputeLogicalRestartLSN(void)
+ReplicationSlotsComputeRequiredLSN(bool only_logical)
 {
-	XLogRecPtr	result = InvalidXLogRecPtr;
 	int			i;
+	XLogRecPtr	min_required = InvalidXLogRecPtr;
 
 	if (max_replication_slots <= 0)
 		return InvalidXLogRecPtr;
 
-	LWLockAcquire(ReplicationSlotControlLock, LW_SHARED);
+	Assert(ReplicationSlotCtl != NULL);
 
+	LWLockAcquire(ReplicationSlotControlLock, LW_SHARED);
 	for (i = 0; i < max_replication_slots; i++)
 	{
-		ReplicationSlot *s;
+		ReplicationSlot *s = &ReplicationSlotCtl->replication_slots[i];
 		XLogRecPtr	restart_lsn;
 
-		s = &ReplicationSlotCtl->replication_slots[i];
-
-		/* cannot change while ReplicationSlotCtlLock is held */
 		if (!s->in_use)
 			continue;
 
-		/* we're only interested in logical slots */
-		if (!SlotIsLogical(s))
+		if (only_logical && !SlotIsLogical(s))
 			continue;
 
-		/* read once, it's ok if it increases while we're checking */
 		SpinLockAcquire(&s->mutex);
 		restart_lsn = s->data.restart_lsn;
 		SpinLockRelease(&s->mutex);
@@ -890,14 +847,13 @@ ReplicationSlotsComputeLogicalRestartLSN(void)
 		if (restart_lsn == InvalidXLogRecPtr)
 			continue;
 
-		if (result == InvalidXLogRecPtr ||
-			restart_lsn < result)
-			result = restart_lsn;
+		if (min_required == InvalidXLogRecPtr ||
+			restart_lsn < min_required)
+			min_required = restart_lsn;
 	}
-
 	LWLockRelease(ReplicationSlotControlLock);
 
-	return result;
+	return min_required;
 }
 
 /*
@@ -1096,6 +1052,7 @@ ReplicationSlotReserveWal(void)
 	{
 		XLogSegNo	segno;
 		XLogRecPtr	restart_lsn;
+		XLogRecPtr	min_required;
 
 		/*
 		 * For logical slots log a standby snapshot and start logical decoding
@@ -1133,7 +1090,8 @@ ReplicationSlotReserveWal(void)
 		}
 
 		/* prevent WAL removal as fast as possible */
-		ReplicationSlotsComputeRequiredLSN();
+		min_required = ReplicationSlotsComputeRequiredLSN(false);
+		XLogSetReplicationSlotMinimumLSN(min_required);
 
 		/*
 		 * If all required WAL is still there, great, otherwise retry. The
@@ -1343,8 +1301,11 @@ restart:
 	 */
 	if (invalidated)
 	{
+		XLogRecPtr	min_required;
+
 		ReplicationSlotsComputeRequiredXmin(false);
-		ReplicationSlotsComputeRequiredLSN();
+		min_required = ReplicationSlotsComputeRequiredLSN(false);
+		XLogSetReplicationSlotMinimumLSN(min_required);
 	}
 
 	return invalidated;
@@ -1396,6 +1357,7 @@ StartupReplicationSlots(void)
 {
 	DIR		   *replication_dir;
 	struct dirent *replication_de;
+	XLogRecPtr	min_required;
 
 	elog(DEBUG1, "starting up replication slots");
 
@@ -1441,7 +1403,8 @@ StartupReplicationSlots(void)
 
 	/* Now that we have recovered all the data, compute replication xmin */
 	ReplicationSlotsComputeRequiredXmin(false);
-	ReplicationSlotsComputeRequiredLSN();
+	min_required = ReplicationSlotsComputeRequiredLSN(false);
+	XLogSetReplicationSlotMinimumLSN(min_required);
 }
 
 /* ----
diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index d11daeb1fc..5def594640 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -608,6 +608,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 	bool		nulls[2];
 	HeapTuple	tuple;
 	Datum		result;
+	XLogRecPtr	min_required;
 
 	Assert(!MyReplicationSlot);
 
@@ -672,7 +673,8 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 	 * advancing potentially done.
 	 */
 	ReplicationSlotsComputeRequiredXmin(false);
-	ReplicationSlotsComputeRequiredLSN();
+	min_required = ReplicationSlotsComputeRequiredLSN(false);
+	XLogSetReplicationSlotMinimumLSN(min_required);
 
 	ReplicationSlotRelease();
 
@@ -816,6 +818,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 		XLogRecPtr	copy_confirmed_flush;
 		bool		copy_islogical;
 		char	   *copy_name;
+		XLogRecPtr	min_required;
 
 		/* Copy data of source slot again */
 		SpinLockAcquire(&src->mutex);
@@ -873,7 +876,8 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 
 		ReplicationSlotMarkDirty();
 		ReplicationSlotsComputeRequiredXmin(false);
-		ReplicationSlotsComputeRequiredLSN();
+		min_required = ReplicationSlotsComputeRequiredLSN(false);
+		XLogSetReplicationSlotMinimumLSN(min_required);
 		ReplicationSlotSave();
 
 #ifdef USE_ASSERT_CHECKING
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 84915ed95b..cf0a65d975 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -1977,8 +1977,11 @@ PhysicalConfirmReceivedLocation(XLogRecPtr lsn)
 
 	if (changed)
 	{
+		XLogRecPtr	min_required;
+
 		ReplicationSlotMarkDirty();
-		ReplicationSlotsComputeRequiredLSN();
+		min_required = ReplicationSlotsComputeRequiredLSN(false);
+		XLogSetReplicationSlotMinimumLSN(min_required);
 	}
 
 	/*
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index 53d773ccff..53ae2b3607 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -209,8 +209,7 @@ extern void ReplicationSlotMarkDirty(void);
 extern bool ReplicationSlotValidateName(const char *name, int elevel);
 extern void ReplicationSlotReserveWal(void);
 extern void ReplicationSlotsComputeRequiredXmin(bool already_locked);
-extern void ReplicationSlotsComputeRequiredLSN(void);
-extern XLogRecPtr ReplicationSlotsComputeLogicalRestartLSN(void);
+extern XLogRecPtr ReplicationSlotsComputeRequiredLSN(bool only_logical);
 extern bool ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive);
 extern void ReplicationSlotsDropDBSlots(Oid dboid);
 extern bool InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno);
-- 
2.25.1



^ permalink  raw  reply  [nested|flat] 26+ messages in thread


end of thread, other threads:[~2022-01-07 03:37 UTC | newest]

Thread overview: 26+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2021-03-03 22:36 [PATCH 2/2] doc review Justin Pryzby <[email protected]>
2022-01-06 18:24 Re: Deduplicate min restart_lsn calculation code Alvaro Herrera <[email protected]>
2022-01-07 03:37 ` Re: Deduplicate min restart_lsn calculation code Bharath Rupireddy <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox