*** a/doc/src/sgml/libpq.sgml
--- b/doc/src/sgml/libpq.sgml
***************
*** 7233,7238 **** int PQisthreadsafe();
--- 7233,7443 ----
   </sect1>
  
  
+  <sect1 id="libpq-altrowprocessor">
+   <title>Alternative row processor</title>
+ 
+   <indexterm zone="libpq-altrowprocessor">
+    <primary>PGresult</primary>
+    <secondary>PGconn</secondary>
+   </indexterm>
+ 
+   <para>
+    As the standard usage, rows are stored into <type>PQresult</type>
+    until full resultset is received.  Then such completely-filled
+    <type>PQresult</type> is passed to user.  This behaviour can be
+    changed by registering alternative row processor function,
+    that will see each row data as soon as it is received
+    from network.  It has the option of processing the data
+    immediately, or storing it into custom container.
+   </para>
+ 
+   <para>
+    Note - as row processor sees rows as they arrive, it cannot know
+    whether the SQL statement actually finishes successfully on server
+    or not.  So some care must be taken to get proper
+    transactionality.
+   </para>
+ 
+   <variablelist>
+    <varlistentry id="libpq-pqsetrowprocessor">
+     <term>
+      <function>PQsetRowProcessor</function>
+      <indexterm>
+       <primary>PQsetRowProcessor</primary>
+      </indexterm>
+     </term>
+ 
+     <listitem>
+      <para>
+        Sets a callback function to process each row.
+ <synopsis>
+ void PQsetRowProcessor(PGconn *conn, PQrowProcessor func, void *param);
+ </synopsis>
+      </para>
+      
+      <para>
+        <variablelist>
+ 	 <varlistentry>
+ 	   <term><parameter>conn</parameter></term>
+ 	   <listitem>
+ 	     <para>
+ 	       The connection object to set the row processor function.
+ 	     </para>
+ 	   </listitem>
+ 	 </varlistentry>
+ 	 <varlistentry>
+ 	   <term><parameter>func</parameter></term>
+ 	   <listitem>
+ 	     <para>
+ 	       Storage handler function to set. NULL means to use the
+ 	       default processor.
+ 	     </para>
+ 	   </listitem>
+ 	 </varlistentry>
+ 	 <varlistentry>
+ 	   <term><parameter>param</parameter></term>
+ 	   <listitem>
+ 	     <para>
+ 	       A pointer to contextual parameter passed
+ 	       to <parameter>func</parameter>.
+ 	     </para>
+ 	   </listitem>
+ 	 </varlistentry>
+        </variablelist>
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+ 
+   <variablelist>
+    <varlistentry id="libpq-pqrowprocessor">
+     <term>
+      <type>PQrowProcessor</type>
+      <indexterm>
+       <primary>PQrowProcessor</primary>
+      </indexterm>
+     </term>
+ 
+     <listitem>
+      <para>
+        The type for the row processor callback function.
+ <synopsis>
+ int (*PQrowProcessor)(PGresult *res, void *param, PGrowValue *columns);
+ 
+ typedef struct
+ {
+     int         len;            /* length in bytes of the value */
+     char       *value;          /* actual value, without null termination */
+ } PGrowValue;
+ </synopsis>
+      </para>
+ 
+      <para>
+       The <parameter>columns</parameter> array will have PQnfields()
+       elements, each one pointing to column value in network buffer.
+      </para>
+ 
+      <para>
+        This function must process or copy row values away from network
+        buffer before it returns, as next row might overwrite them.
+      </para>
+ 
+      <para>
+        This function must return 1 for success, and 0 for failure.
+        On failure this function should set the error message
+        with <function>PGsetRowProcessorErrMsg</function> if the cause
+        is other than out of memory.  This funcion must not throw any
+        exception.
+      </para>
+      <variablelist>
+        <varlistentry>
+ 
+ 	 <term><parameter>res</parameter></term>
+ 	 <listitem>
+ 	   <para>
+ 	     A pointer to the <type>PGresult</type> object.
+ 	   </para>
+ 	 </listitem>
+        </varlistentry>
+        <varlistentry>
+ 
+ 	 <term><parameter>param</parameter></term>
+ 	 <listitem>
+ 	   <para>
+ 	     Extra parameter that was given to <function>PQsetRowProcessor</function>.
+ 	   </para>
+ 	 </listitem>
+        </varlistentry>
+        <varlistentry>
+ 
+ 	 <term><parameter>columns</parameter></term>
+ 	 <listitem>
+ 	   <para>
+ 	     Column values of the row to process.  Column values
+ 	     are located in network buffer, the processor must
+ 	     copy them out from there.
+ 	   </para>
+ 	   <para>
+ 	     Column values are not null-terminated, so processor cannot
+ 	     use C string functions on them directly.
+ 	   </para>
+ 	 </listitem>
+        </varlistentry>
+      </variablelist>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+ 
+   <variablelist>
+    <varlistentry id="libpq-pqsetrowprocessorerrmsg">
+     <term>
+      <function>PQsetRowProcessorErrMsg</function>
+      <indexterm>
+       <primary>PQsetRowProcessorErrMsg</primary>
+      </indexterm>
+     </term>
+     <listitem>
+       <para>
+ 	Set the message for the error occurred
+ 	in <type>PQrowProcessor</type>.  If this message is not set, the
+ 	caller assumes the error to be out of memory.
+ <synopsis>
+ void PQsetRowProcessorErrMsg(PGresult *res, char *msg)
+ </synopsis>
+       </para>
+       <para>
+ 	<variablelist>
+ 	  <varlistentry>
+ 	    <term><parameter>res</parameter></term>
+ 	    <listitem>
+ 	      <para>
+ 		A pointer to the <type>PGresult</type> object
+ 		passed to <type>PQrowProcessor</type>.
+ 	      </para>
+ 	    </listitem>
+ 	  </varlistentry>
+ 	  <varlistentry>
+ 	    <term><parameter>mes</parameter></term>
+ 	    <listitem>
+ 	      <para>
+ 		Error message. This will be copied internally so there is
+ 		no need to care of the scope.
+ 	      </para>
+ 	      <para>
+ 		If <parameter>res</parameter> already has a message previously
+ 		set, it will be overritten. Set NULL to cancel the the costom
+ 		message.
+ 	      </para>
+ 	    </listitem>
+ 	  </varlistentry>
+ 	</variablelist>
+       </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </sect1>
+ 
+ 
   <sect1 id="libpq-build">
    <title>Building <application>libpq</application> Programs</title>
  
