libpq_rowproc_doc_20120223.patch

text/x-patch

Filename: libpq_rowproc_doc_20120223.patch
Type: text/x-patch
Part: 1
Message: Re: Speed dblink using alternate libpq tuple storage

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
doc/src/sgml/libpq.sgml 324 0
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 72c9384..0087b43 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -7233,6 +7233,330 @@ int PQisthreadsafe();
  </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 behavior 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, PGrowValue *columns, void *param);
+
+typedef struct
+{
+    int         len;            /* length in bytes of the value, -1 if NULL */
+    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.
+      The <parameter>len</parameter> field will contain number of
+      bytes in value.  If the field value is NULL then
+      <parameter>len</parameter> will be -1 and value will point
+      to position where the value would have been in buffer.
+      This allows estimating row size by pointer arithmetic.
+     </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.  When non-blocking API is in use,
+       it can also return 2 for early exit
+       from <function>PQisBusy</function> function.  The
+       supplied <parameter>res</parameter>
+       and <parameter>columns</parameter> values will stay valid so
+       row can be processed outside of callback.  Caller is
+       responsible for tracking whether
+       the <parameter>PQisBusy</parameter> returned early from
+       callback or for other reasons.  Usually this should happen via
+       setting cached values to NULL before
+       calling <function>PQisBusy</function>.
+     </para>
+
+     <para>
+       The function is allowed to exit via exception (setjmp/longjmp).
+       The connection and row are guaranteed to be in valid state.
+       The connection can later be closed via <function>PQfinish</function>.
+       Processing can also be continued without closing the connection,
+       call <function>getResult</function> on syncronous mode,
+       <function>PQisBusy</function> on asynchronous connection.  Then
+       processing will continue with new row, previous row that got
+       exception will be skipped. Or you can discard all remaining
+       rows by calling <function>PQskipResult</function> without
+       closing connection.
+     </para>
+
+     <variablelist>
+       <varlistentry>
+
+	 <term><parameter>res</parameter></term>
+	 <listitem>
+	   <para>
+	     A pointer to the <type>PGresult</type> object.
+	   </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>
+       <varlistentry>
+
+	 <term><parameter>param</parameter></term>
+	 <listitem>
+	   <para>
+	     Extra parameter that was given to <function>PQsetRowProcessor</function>.
+	   </para>
+	 </listitem>
+       </varlistentry>
+     </variablelist>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+
+  <variablelist>
+   <varlistentry id="libpq-pqskipresult">
+    <term>
+     <function>PQskipResult</function>
+     <indexterm>
+      <primary>PQskipResult</primary>
+     </indexterm>
+    </term>
+    <listitem>
+      <para>
+		Discard all the remaining row data
+		after <function>PQexec</function>
+		or <function>PQgetResult</function> exits by the exception raised
+		in <type>RowProcessor</type> without closing connection.
+<synopsis>
+void PQskipResult(PGconn *conn, int skipAll)
+</synopsis>
+      </para>
+      <para>
+	<variablelist>
+	 <varlistentry>
+	   <term><parameter>conn</parameter></term>
+	   <listitem>
+	     <para>
+	       The connection object.
+	     </para>
+	   </listitem>
+	 </varlistentry>
+
+	 <varlistentry>
+	   <term><parameter>skipAll</parameter></term>
+	   <listitem>
+	     <para>
+	       Skip remaining rows in current result
+	       if <parameter>skipAll</parameter> is false(0). Skip
+	       remaining rows in current result and all rows in
+	       succeeding results if true(non-zero).
+	     </para>
+	   </listitem>
+	 </varlistentry>
+
+	</variablelist>
+      </para>
+    </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, const 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>msg</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 overwritten. Set NULL to cancel the the custom
+		message.
+	      </para>
+	    </listitem>
+	  </varlistentry>
+	</variablelist>
+      </para>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+
+  <variablelist>
+   <varlistentry id="libpq-pqgetrowprcessor">
+    <term>
+     <function>PQgetRowProcessor</function>
+     <indexterm>
+      <primary>PQgetRowProcessor</primary>
+     </indexterm>
+    </term>
+    <listitem>
+      <para>
+       Get row processor and its context parameter currently set to
+       the connection.
+<synopsis>
+PQrowProcessor PQgetRowProcessor(PGconn *conn, void **param)
+</synopsis>
+      </para>
+      <para>
+	<variablelist>
+	 <varlistentry>
+	   <term><parameter>conn</parameter></term>
+	   <listitem>
+	     <para>
+	       The connection object.
+	     </para>
+	   </listitem>
+	 </varlistentry>
+
+	 <varlistentry>
+	   <term><parameter>param</parameter></term>
+	   <listitem>
+	     <para>
+              Set the current row processor parameter of the
+              connection here if not NULL.
+	     </para>
+	   </listitem>
+	 </varlistentry>
+
+	</variablelist>
+      </para>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+
+ </sect1>
+
+
  <sect1 id="libpq-build">
   <title>Building <application>libpq</application> Programs</title>