Subject: Documentation update for PQexecParams

From: Theo Kramer <[email-masked]>
Date: Wed, 08 Nov 2006 20:07:19 +0200

Hi

I have been using PQprepare() and PQexecPrepared(). This has led me to 
update libpq.sgml, in particular for PQexecParams().

The changes are to the formatting of the arguments for PQexecParams()
(as shared by PQexecPrepared()) which make it easier to read, as well as
creating a table giving a set of possible values for the various arguments with
the associated SQL types.

I would imagine the best place to submit the patch would be to
psql-patches, however, before I do this I am wondering if this is the right forum for
having the changes vetted before submitting the patch.

Please advise.
-- 
Regards
Theo

---

From: David Fetter <[email-masked]>
Date: Thu, 9 Nov 2006 06:43:48 -0800

> having the changes vetted before submitting the patch.

Send it to both lists, and thanks for doing this :)

Cheers,
D
-- 
David Fetter <[email-masked]> http://fetter.org/
phone: +1 415 235 3778        AIM: dfetter666
                              Skype: davidfetter

Remember to vote!

---

From: Theo Kramer <[email-masked]>
Date: Thu, 09 Nov 2006 17:04:47 +0200

> Send it to both lists, and thanks for doing this :)

Thanks - attached output of 'diff -c libpq.sgml libpq.sgml.org' where
libpq.sgml contains my proposed changes and libpq.sgml.org originates
from the 8.2 Beta 2 distribution for comment.
-- 
Regards
Theo
*** libpq.sgml	Tue Nov  7 22:06:37 2006
--- libpq.sgml.org	Mon Oct 23 20:10:31 2006
***************
*** 956,962 ****
  are connected to. The number is formed by converting the major, minor, and
  revision numbers into two-decimal-digit numbers and appending them
  together. For example, version 8.1.5 will be returned as 80105, and version
! 8.2 will be returned as 80200 (leading zeroes are not shown).  Zero is
  returned if the connection is bad.
  </para>
  </listitem>
--- 956,962 ----
  are connected to. The number is formed by converting the major, minor, and
  revision numbers into two-decimal-digit numbers and appending them
  together. For example, version 8.1.5 will be returned as 80105, and version
! 8.1 will be returned as 80100 (leading zeroes are not shown).  Zero is
  returned if the connection is bad.
  </para>
  </listitem>
***************
*** 1138,1237 ****
  </para>
  
  <para>
! 
! <variablelist>
!   <varlistentry>
!     <term><parameter>command</parameter></term>
!     <listitem>
!       <para>
!         The SQL command to be executed. If parameters are used, they are referred to in the command string
!         as <literal>$1</>, <literal>$2</>, etc.
!       </para>
!     </listitem>
!   </varlistentry>
! 
!   <varlistentry>
!     <term><parameter>nParams</parameter></term>
!     <listitem>
!       <para>
!         The number of parameters supplied; it is the length
!         of the arrays <parameter>paramTypes[]</>, <parameter>paramValues[]</>,
!         <parameter>paramLengths[]</>, and <parameter>paramFormats[]</>. (The array pointers
!         may be <symbol>NULL</symbol> when <parameter>nParams</> is zero.)
!       </para>
!     </listitem>
!   </varlistentry>
! 
!   <varlistentry>
!     <term><parameter>paramTypes[]</parameter></term>
!     <listitem>
!       <para>
!         Specifies, by OID, the data types to be assigned to
!         the parameter symbols.  If <parameter>paramTypes</> is <symbol>NULL</symbol>, or any particular
!         element in the array is zero, the server assigns a data type to the parameter
!         symbol in the same way it would do for an untyped literal string.
!       </para>
!     </listitem>
!   </varlistentry>
! 
!   <varlistentry>
!     <term><parameter>paramValues[]</parameter></term>
!     <listitem>
!       <para>
!         Specifies the actual values of the parameters.
!         A null pointer in this array means the corresponding parameter is null;
!         otherwise the pointer points to a zero-terminated text string (for text
!         format) or binary data in the format expected by the server (for binary
!         format).
!       </para>
!     </listitem>
!   </varlistentry>
! 
!   <varlistentry>
!     <term><parameter>paramLengths[]</parameter></term>
!     <listitem>
!       <para>
!         Specifies the actual data lengths of binary-format parameters.
!         It is ignored for null parameters and text-format parameters.
!         The array pointer may be null when there are no binary parameters.
!       </para>
!     </listitem>
!   </varlistentry>
! 
!   <varlistentry>
!     <term><parameter>paramFormats[]</parameter></term>
!     <listitem>
!       <para>
!         Specifies whether parameters are text (put a zero in the array for
!         the corresponding parameter) or binary (put a one in the array for
!         the corresponding parameter). If the array pointer is null then all
!         parameters are presumed to be zero terminated text strings.
!       </para>
!     </listitem>
!   </varlistentry>
! 
!   <varlistentry>
!     <term><parameter>resultFormat</parameter></term>
!     <listitem>
!       <para>
!         Specify zero to obtain results in text format, or one to
!         obtain results in binary format.  (There is not currently a provision to
!         obtain different result columns in different formats, although that is
!         possible in the underlying protocol.)
!       </para>
!     </listitem>
!   </varlistentry>
! 
! </variablelist>
  </para>
  
- <para>
  The primary advantage of <function>PQexecParams</> over <function>PQexec</>
  is that parameter values may be separated from the command string, thus
  avoiding the need for tedious and error-prone quoting and escaping.
- </para>
  
- <para>
  Unlike <function>PQexec</>, <function>PQexecParams</> allows at most one SQL
  command in the given string.  (There can be semicolons in it, but not more
  than one nonempty command.)  This is a limitation of the underlying protocol,
--- 1138,1178 ----
  </para>
  
  <para>
! If parameters are used, they are referred to in the command string
! as <literal>$1</>, <literal>$2</>, etc.
! <parameter>nParams</> is the number of parameters supplied; it is the length
! of the arrays <parameter>paramTypes[]</>, <parameter>paramValues[]</>,
! <parameter>paramLengths[]</>, and <parameter>paramFormats[]</>.  (The
! array pointers may be <symbol>NULL</symbol> when <parameter>nParams</> is zero.)
! <parameter>paramTypes[]</> specifies, by OID, the data types to be assigned to
! the parameter symbols.  If <parameter>paramTypes</> is <symbol>NULL</symbol>, or any particular
! element in the array is zero, the server assigns a data type to the parameter
! symbol in the same way it would do for an untyped literal string.
! <parameter>paramValues[]</> specifies the actual values of the parameters.
! A null pointer in this array means the corresponding parameter is null;
! otherwise the pointer points to a zero-terminated text string (for text
! format) or binary data in the format expected by the server (for binary
! format).
! <parameter>paramLengths[]</> specifies the actual data lengths of
! binary-format parameters.  It is ignored for null parameters and text-format
! parameters.  The array pointer may be null when there are no binary
! parameters.
! <parameter>paramFormats[]</> specifies whether parameters are text (put a zero
! in the array) or binary (put a one in the array).  If the array pointer is
! null then all parameters are presumed to be text.
! <parameter>resultFormat</> is zero to obtain results in text format, or one to
! obtain results in binary format.  (There is not currently a provision to
! obtain different result columns in different formats, although that is
! possible in the underlying protocol.)
  </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
  
  The primary advantage of <function>PQexecParams</> over <function>PQexec</>
  is that parameter values may be separated from the command string, thus
  avoiding the need for tedious and error-prone quoting and escaping.
  
  Unlike <function>PQexec</>, <function>PQexecParams</> allows at most one SQL
  command in the given string.  (There can be semicolons in it, but not more
  than one nonempty command.)  This is a limitation of the underlying protocol,
***************
*** 1259,1416 ****
  </tip>
  
  <para>
-   <xref linkend="libpq-param-table"> shows a range of typical values for
-   <parameter>paramTypes[]</parameter> in column <acronym>PG Type</acronym>, as determined from 
-   <filename>pg_type.h</>, as well as the corresponding SQL attribute names, ODBC and C types, and lengths.
- </para>
- 
-    <table id="libpq-param-table">
-     <title>Parameter Types</title>
-     <tgroup cols="7">
-      <thead>
-       <row>
-        <entry>Name</entry>
-        <entry>PG Type</entry>
-        <entry>ODBC Type</entry>
-        <entry>C Type</entry>
-        <entry>Length Text Format</entry>
-        <entry>Length Binary Format</entry>
-        <entry>Description</entry>
-       </row>
-      </thead>
- 
-      <tbody>
-       <row>
-        <entry><type>character(n)</type></entry>
-        <entry><type>BPCHAROID</type></entry>
-        <entry><type>SQL_CHAR</type></entry>
-        <entry><type>char[n + 1]</type></entry>
-        <entry>0</entry>
-        <entry>n</entry>
-        <entry>Blanks are automatically padded for the length of the string.</entry>
-       </row>
- 
-       <row>
-        <entry><type>varchar(n)</type></entry>
-        <entry><type>VARCHAROID</type></entry>
-        <entry><type>SQL_VARCHAR</type></entry>
-        <entry><type>char[n + 1]</type></entry>
-        <entry>0</entry>
-        <entry>n</entry>
-        <entry>Not blank padded.</entry>
-       </row>
- 
-       <row>
-        <entry><type>text</type></entry>
-        <entry><type>TEXTOID</type></entry>
-        <entry><type>SQL_LONGVARCHAR</type></entry>
-        <entry><type>char *</type></entry>
-        <entry>0</entry>
-        <entry>n</entry>
-        <entry>String with appropriate size must be allocated. Care must be taken not to overflow allocated string.</entry>
-       </row>
- 
-       <row>
-        <entry><type>smallint</type></entry>
-        <entry><type>INT2OID</type></entry>
-        <entry><type>SQL_SHORT</type></entry>
-        <entry><type>short</type></entry>
-        <entry>0</entry>
-        <entry>2</entry>
-        <entry>2 byte short integer</entry>
-       </row>
- 
-       <row>
-        <entry><type>integer</type></entry>
-        <entry><type>INT4OID</type></entry>
-        <entry><type>SQL_INTEGER</type></entry>
-        <entry><type>int</type></entry>
-        <entry>0</entry>
-        <entry>4</entry>
-        <entry>4 byte integer</entry>
-       </row>
- 
-       <row>
-        <entry><type>real</type></entry>
-        <entry><type>FLOAT4OID</type></entry>
-        <entry><type>SQL_REAL</type></entry>
-        <entry><type>float</type></entry>
-        <entry>0</entry>
-        <entry>4</entry>
-        <entry>4 byte floating point</entry>
-       </row>
- 
-       <row>
-        <entry><type>double precision</type></entry>
-        <entry><type>FLOAT8OID</type></entry>
-        <entry><type>SQL_DOUBLE</type></entry>
-        <entry><type>double</type></entry>
-        <entry>0</entry>
-        <entry>8</entry>
-        <entry>8 byte floating point</entry>
-       </row>
- 
-       <row>
-        <entry><type>numeric[(p,s)]</type></entry>
-        <entry><type>NUMERICOID</type></entry>
-        <entry><type>SQL_NUMERIC</type></entry>
-        <entry><type>structure</type></entry>
-        <entry>0</entry>
-        <entry>variable</entry>
-        <entry>Cast to and from double if no bcd library and use 8 as binary length. Equivalent to decimal[(p,s)]</entry>
-       </row>
- 
-       <row>
-        <entry><type>timestamp</type></entry>
-        <entry><type>TIMESTAMPOID</type></entry>
-        <entry><type>SQL_TYPE_TIMESTAMP</type></entry>
-        <entry><type>long long</type></entry>
-        <entry>0</entry>
-        <entry>8</entry>
-        <entry></entry>
-       </row>
- 
-      </tbody>
-     </tgroup>
-    </table>
- 
-    <note>
-    <title>Column Details</title>
-    <para>
-    </para>
-    <para>
-      <quote>Name</quote> The SQL attribute type.
-    </para>
-    <para>
-      <quote>PG Type</quote> The equivalent <productname>PostgreSQL</> type from
-      <filename>pg_types.h</> for <parameter>paramTypes[]</>.
-    </para>
-    <para>
-      <quote>ODBC Type</quote> The equivalent ODBC type.
-    </para>
-    <para>
-      <quote>C Type</quote> The equivalent C language type.
-    </para>
-    <para>
-      <quote>Length Text Format</quote> indicates value for <parameter>paramLengths[]</>
-      for text format.
-    </para>
-    <para>
-      <quote>Length Binary Format</quote> indicates value for <parameter>paramLengths[]</>
-      for binary format.
-    </para>
-    </note>
-    <para>
-      Refer to table <xref linkend="datatype-table"> for further details on data types supported.
-    </para>
- 
- </listitem>
- </varlistentry>
- </variablelist>
- 
- </para>
- 
- <para>
  <variablelist>
  <varlistentry>
  <term><function>PQprepare</function><indexterm><primary>PQprepare</></></term>
--- 1200,1205 ----

---

From: Peter Eisentraut <[email-masked]>
Date: Fri, 10 Nov 2006 10:50:42 +0100

> from the 8.2 Beta 2 distribution for comment.

The patch is backwards.

-- 
Peter Eisentraut
http://developer.postgresql.org/~petere/

---

From: Theo Kramer <[email-masked]>
Date: Fri, 10 Nov 2006 12:02:53 +0200

> > from the 8.2 Beta 2 distribution for comment.

Thanks - re-done and re-attached

-- 
Regards
Theo
*** libpq.sgml.org	Mon Oct 23 20:10:31 2006
--- libpq.sgml	Tue Nov  7 22:06:37 2006
***************
*** 956,962 ****
  are connected to. The number is formed by converting the major, minor, and
  revision numbers into two-decimal-digit numbers and appending them
  together. For example, version 8.1.5 will be returned as 80105, and version
! 8.1 will be returned as 80100 (leading zeroes are not shown).  Zero is
  returned if the connection is bad.
  </para>
  </listitem>
--- 956,962 ----
  are connected to. The number is formed by converting the major, minor, and
  revision numbers into two-decimal-digit numbers and appending them
  together. For example, version 8.1.5 will be returned as 80105, and version
! 8.2 will be returned as 80200 (leading zeroes are not shown).  Zero is
  returned if the connection is bad.
  </para>
  </listitem>
***************
*** 1138,1178 ****
  </para>
  
  <para>
  </variablelist>

--- 1138,1237 ----
  </para>
  
  <para>
! 
! <variablelist>
!   <varlistentry>
  </variablelist>
+ </para>
  
+ <para>
+ </para>
  
+ <para>
*** 1200,1205 ****
--- 1259,1416 ----
  </tip>
  
  <para>
+   <xref linkend="libpq-param-table"> shows a range of typical values for
+   <parameter>paramTypes[]</parameter> in column <acronym>PG Type</acronym>, as determined from 
+   <filename>pg_type.h</>, as well as the corresponding SQL attribute names, ODBC and C types, and lengths.
+ </para>
+ 
+    <table id="libpq-param-table">
+     <title>Parameter Types</title>
+     <tgroup cols="7">
+      <thead>
+       <row>
+        <entry>Name</entry>
+        <entry>PG Type</entry>
+        <entry>ODBC Type</entry>
+        <entry>C Type</entry>
+        <entry>Length Text Format</entry>
+        <entry>Length Binary Format</entry>
+        <entry>Description</entry>
+       </row>
+      </thead>
+ 
+      <tbody>
+       <row>
+        <entry><type>character(n)</type></entry>
+        <entry><type>BPCHAROID</type></entry>
+        <entry><type>SQL_CHAR</type></entry>
+        <entry><type>char[n + 1]</type></entry>
+        <entry>0</entry>
+        <entry>n</entry>
+        <entry>Blanks are automatically padded for the length of the string.</entry>
+       </row>
+ 
+       <row>
+        <entry><type>varchar(n)</type></entry>
+        <entry><type>VARCHAROID</type></entry>
+        <entry><type>SQL_VARCHAR</type></entry>
+        <entry><type>char[n + 1]</type></entry>
+        <entry>0</entry>
+        <entry>n</entry>
+        <entry>Not blank padded.</entry>
+       </row>
+ 
+       <row>
+        <entry><type>text</type></entry>
+        <entry><type>TEXTOID</type></entry>
+        <entry><type>SQL_LONGVARCHAR</type></entry>
+        <entry><type>char *</type></entry>
+        <entry>0</entry>
+        <entry>n</entry>
+        <entry>String with appropriate size must be allocated. Care must be taken not to overflow allocated string.</entry>
+       </row>
+ 
+       <row>
+        <entry><type>smallint</type></entry>
+        <entry><type>INT2OID</type></entry>
+        <entry><type>SQL_SHORT</type></entry>
+        <entry><type>short</type></entry>
+        <entry>0</entry>
+        <entry>2</entry>
+        <entry>2 byte short integer</entry>
+       </row>
+ 
+       <row>
+        <entry><type>integer</type></entry>
+        <entry><type>INT4OID</type></entry>
+        <entry><type>SQL_INTEGER</type></entry>
+        <entry><type>int</type></entry>
+        <entry>0</entry>
+        <entry>4</entry>
+        <entry>4 byte integer</entry>
+       </row>
+ 
+       <row>
+        <entry><type>real</type></entry>
+        <entry><type>FLOAT4OID</type></entry>
+        <entry><type>SQL_REAL</type></entry>
+        <entry><type>float</type></entry>
+        <entry>0</entry>
+        <entry>4</entry>
+        <entry>4 byte floating point</entry>
+       </row>
+ 
+       <row>
+        <entry><type>double precision</type></entry>
+        <entry><type>FLOAT8OID</type></entry>
+        <entry><type>SQL_DOUBLE</type></entry>
+        <entry><type>double</type></entry>
+        <entry>0</entry>
+        <entry>8</entry>
+        <entry>8 byte floating point</entry>
+       </row>
+ 
+       <row>
+        <entry><type>numeric[(p,s)]</type></entry>
+        <entry><type>NUMERICOID</type></entry>
+        <entry><type>SQL_NUMERIC</type></entry>
+        <entry><type>structure</type></entry>
+        <entry>0</entry>
+        <entry>variable</entry>
+        <entry>Cast to and from double if no bcd library and use 8 as binary length. Equivalent to decimal[(p,s)]</entry>
+       </row>
+ 
+       <row>
+        <entry><type>timestamp</type></entry>
+        <entry><type>TIMESTAMPOID</type></entry>
+        <entry><type>SQL_TYPE_TIMESTAMP</type></entry>
+        <entry><type>long long</type></entry>
+        <entry>0</entry>
+        <entry>8</entry>
+        <entry></entry>
+       </row>
+ 
+      </tbody>
+     </tgroup>
+    </table>
+ 
+    <note>
+    <title>Column Details</title>
+    <para>
+    </para>
+    <para>
+      <quote>Name</quote> The SQL attribute type.
+    </para>
+    <para>
+      <quote>PG Type</quote> The equivalent <productname>PostgreSQL</> type from
+      <filename>pg_types.h</> for <parameter>paramTypes[]</>.
+    </para>
+    <para>
+      <quote>ODBC Type</quote> The equivalent ODBC type.
+    </para>
+    <para>
+      <quote>C Type</quote> The equivalent C language type.
+    </para>
+    <para>
+      <quote>Length Text Format</quote> indicates value for <parameter>paramLengths[]</>
+      for text format.
+    </para>
+    <para>
+      <quote>Length Binary Format</quote> indicates value for <parameter>paramLengths[]</>
+      for binary format.
+    </para>
+    </note>
+    <para>
+      Refer to table <xref linkend="datatype-table"> for further details on data types supported.
+    </para>
+ 
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ 
+ </para>
+ 
+ <para>
  <variablelist>
  <varlistentry>
  <term><function>PQprepare</function><indexterm><primary>PQprepare</></></term>

---

From: Tom Lane <[email-masked]>
Date: Fri, 10 Nov 2006 17:24:10 -0500

> Thanks - re-done and re-attached

I applied the part of this that reformats the PQexecParams argument
descriptions --- I agree that makes it more readable.  I did not like
the proposed table of datatypes though.  It strikes me as incomplete,
unhelpful, and in places downright misleading.  For instance, I don't
see the point of listing ODBC type codes; they are irrelevant to libpq,
and the only likely outcome of listing them is that someone might think
he could use them for paramTypes[] entries.  The description of the
binary formats was not helpful either, as it avoided any of the useful
details (endianness etc), as well as portability issues like whether
timestamps are int or float.

			regards, tom lane

---

From: Theo Kramer <[email-masked]>
Date: Sat, 11 Nov 2006 05:50:20 +0200

> timestamps are int or float.

Thanks for the input - I agree that the table is incomplete.

My intention with the table is for it to be a start to something that is
more useful than the incomplete examples regarding these functions. I
suggest I redo it taking into consideration your input, unless you have
other suggestions for improving the docs on the use with typical values
for the arguments.

On the ODBC types - I found these useful as my interface is based on
that. I imagine that others who have used ODBC and who would like to use
the libpq functions may also find it useful, but also agree that it may
be misleading.

Perhaps, with a couple of iterations, we can get to something that will
make the documentation on these functions more useful.

-- 
Regards
Theo

---

From: Mark Kirkwood <[email-masked]>
Date: Sat, 11 Nov 2006 17:19:23 +1300

> make the documentation on these functions more useful.

Maybe add a new chapter discussing ODBC (even if it is *very* short), 
and include the datatype info in it?