diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index eafbaa777f50dae29e48080fcc53bfa950f26011..63fb3ab4192cc3ebc2bec496885aaf4a3dd3fb7d 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.195 2005/10/20 21:04:14 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.196 2005/10/20 23:57:51 tgl Exp $
 -->
 
  <chapter id="libpq">
@@ -1187,6 +1187,26 @@ than one nonempty command.)  This is a limitation of the underlying protocol,
 but has some usefulness as an extra defense against SQL-injection attacks.
 </para>
 
+<tip>
+<para>
+Specifying parameter types via OIDs is tedious, particularly if you prefer
+not to hard-wire particular OID values into your program.  However, you can
+avoid doing so even in cases where the server by itself cannot determine the
+type of the parameter, or chooses a different type than you want.  In the
+SQL command text, attach an explicit cast to the parameter symbol to show what
+data type you will send.  For example,
+<programlisting>
+select * from mytable where x = $1::bigint;
+</programlisting>
+This forces parameter <literal>$1</> to be treated as <type>bigint</>, whereas
+by default it would be assigned the same type as <literal>x</>.  Forcing the
+parameter type decision, either this way or by specifying a numeric type OID,
+is strongly recommended when sending parameter values in binary format, because
+binary format has less redundancy than text format and so there is less chance
+that the server will detect a type mismatch mistake for you.
+</para>
+</tip>
+
 <para>
 <variablelist>
 <varlistentry>
@@ -4226,7 +4246,7 @@ testlibpq.o(.text+0xa4): undefined reference to `PQerrorMessage'
 /*
  * testlibpq.c
  *
- *              Test the C version of LIBPQ, the POSTGRES frontend library.
+ *      Test the C version of libpq, the PostgreSQL frontend library.
  */
 #include &lt;stdio.h&gt;
 #include &lt;stdlib.h&gt;
@@ -4235,112 +4255,111 @@ testlibpq.o(.text+0xa4): undefined reference to `PQerrorMessage'
 static void
 exit_nicely(PGconn *conn)
 {
-        PQfinish(conn);
-        exit(1);
+    PQfinish(conn);
+    exit(1);
 }
 
 int
 main(int argc, char **argv)
 {
-        const char *conninfo;
-        PGconn     *conn;
-        PGresult   *res;
-        int                     nFields;
-        int                     i,
-                                j;
-
-        /*
-         * If the user supplies a parameter on the command line, use it as
-         * the conninfo string; otherwise default to setting dbname=postgres
-         * and using environment variables or defaults for all other connection
-         * parameters.
-         */
-        if (argc &gt; 1)
-                conninfo = argv[1];
-        else
-                conninfo = "dbname = postgres";
-
-        /* Make a connection to the database */
-        conn = PQconnectdb(conninfo);
-
-        /* Check to see that the backend connection was successfully made */
-        if (PQstatus(conn) != CONNECTION_OK)
-        {
-                fprintf(stderr, "Connection to database failed: %s",
-                        PQerrorMessage(conn));
-                exit_nicely(conn);
-        }
-
-        /*
-         * Our test case here involves using a cursor, for which we must be
-         * inside a transaction block.  We could do the whole thing with a
-         * single PQexec() of "select * from pg_database", but that's too
-         * trivial to make a good example.
-         */
-
-        /* Start a transaction block */
-        res = PQexec(conn, "BEGIN");
-        if (PQresultStatus(res) != PGRES_COMMAND_OK)
-        {
-                fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
-                PQclear(res);
-                exit_nicely(conn);
-        }
-
-        /*
-         * Should PQclear PGresult whenever it is no longer needed to avoid
-         * memory leaks
-         */
+    const char *conninfo;
+    PGconn     *conn;
+    PGresult   *res;
+    int         nFields;
+    int         i,
+                j;
+
+    /*
+     * If the user supplies a parameter on the command line, use it as the
+     * conninfo string; otherwise default to setting dbname=postgres and using
+     * environment variables or defaults for all other connection parameters.
+     */
+    if (argc &gt; 1)
+        conninfo = argv[1];
+    else
+        conninfo = "dbname = postgres";
+
+    /* Make a connection to the database */
+    conn = PQconnectdb(conninfo);
+
+    /* Check to see that the backend connection was successfully made */
+    if (PQstatus(conn) != CONNECTION_OK)
+    {
+        fprintf(stderr, "Connection to database failed: %s",
+                PQerrorMessage(conn));
+        exit_nicely(conn);
+    }
+
+    /*
+     * Our test case here involves using a cursor, for which we must be inside
+     * a transaction block.  We could do the whole thing with a single
+     * PQexec() of "select * from pg_database", but that's too trivial to make
+     * a good example.
+     */
+
+    /* Start a transaction block */
+    res = PQexec(conn, "BEGIN");
+    if (PQresultStatus(res) != PGRES_COMMAND_OK)
+    {
+        fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
         PQclear(res);
-
-        /*
-         * Fetch rows from pg_database, the system catalog of databases
-         */
-        res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
-        if (PQresultStatus(res) != PGRES_COMMAND_OK)
-        {
-                fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
-                PQclear(res);
-                exit_nicely(conn);
-        }
+        exit_nicely(conn);
+    }
+
+    /*
+     * Should PQclear PGresult whenever it is no longer needed to avoid memory
+     * leaks
+     */
+    PQclear(res);
+
+    /*
+     * Fetch rows from pg_database, the system catalog of databases
+     */
+    res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
+    if (PQresultStatus(res) != PGRES_COMMAND_OK)
+    {
+        fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
         PQclear(res);
+        exit_nicely(conn);
+    }
+    PQclear(res);
+
+    res = PQexec(conn, "FETCH ALL in myportal");
+    if (PQresultStatus(res) != PGRES_TUPLES_OK)
+    {
+        fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
+        PQclear(res);
+        exit_nicely(conn);
+    }
 
-        res = PQexec(conn, "FETCH ALL in myportal");
-        if (PQresultStatus(res) != PGRES_TUPLES_OK)
-        {
-                fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
-                PQclear(res);
-                exit_nicely(conn);
-        }
+    /* first, print out the attribute names */
+    nFields = PQnfields(res);
+    for (i = 0; i &lt; nFields; i++)
+        printf("%-15s", PQfname(res, i));
+    printf("\n\n");
 
-        /* first, print out the attribute names */
-        nFields = PQnfields(res);
-        for (i = 0; i &lt; nFields; i++)
-                printf("%-15s", PQfname(res, i));
-        printf("\n\n");
+    /* next, print out the rows */
+    for (i = 0; i &lt; PQntuples(res); i++)
+    {
+        for (j = 0; j &lt; nFields; j++)
+            printf("%-15s", PQgetvalue(res, i, j));
+        printf("\n");
+    }
 
-        /* next, print out the rows */
-        for (i = 0; i &lt; PQntuples(res); i++)
-        {
-                for (j = 0; j &lt; nFields; j++)
-                        printf("%-15s", PQgetvalue(res, i, j));
-                printf("\n");
-        }
-
-        PQclear(res);
+    PQclear(res);
 
-        /* close the portal ... we don't bother to check for errors ... */
-        res = PQexec(conn, "CLOSE myportal");
-        PQclear(res);
+    /* close the portal ... we don't bother to check for errors ... */
+    res = PQexec(conn, "CLOSE myportal");
+    PQclear(res);
 
-        /* end the transaction */
-        res = PQexec(conn, "END");
-        PQclear(res);
+    /* end the transaction */
+    res = PQexec(conn, "END");
+    PQclear(res);
 
-        /* close the connection to the database and cleanup */
-        PQfinish(conn);
+    /* close the connection to the database and cleanup */
+    PQfinish(conn);
 
-        return 0;
+    return 0;
 }
 </programlisting>
   </example>
@@ -4351,7 +4370,7 @@ main(int argc, char **argv)
 <programlisting>
 /*
  * testlibpq2.c
- *              Test of the asynchronous notification interface
+ *      Test of the asynchronous notification interface
  *
  * Start this program, then from psql in another window do
  *   NOTIFY TBL2;
@@ -4382,102 +4401,101 @@ main(int argc, char **argv)
 static void
 exit_nicely(PGconn *conn)
 {
-        PQfinish(conn);
-        exit(1);
+    PQfinish(conn);
+    exit(1);
 }
 
 int
 main(int argc, char **argv)
 {
-        const char *conninfo;
-        PGconn     *conn;
-        PGresult   *res;
-        PGnotify   *notify;
-        int                     nnotifies;
-
+    const char *conninfo;
+    PGconn     *conn;
+    PGresult   *res;
+    PGnotify   *notify;
+    int         nnotifies;
+
+    /*
+     * If the user supplies a parameter on the command line, use it as the
+     * conninfo string; otherwise default to setting dbname=postgres and using
+     * environment variables or defaults for all other connection parameters.
+     */
+    if (argc &gt; 1)
+        conninfo = argv[1];
+    else
+        conninfo = "dbname = postgres";
+
+    /* Make a connection to the database */
+    conn = PQconnectdb(conninfo);
+
+    /* Check to see that the backend connection was successfully made */
+    if (PQstatus(conn) != CONNECTION_OK)
+    {
+        fprintf(stderr, "Connection to database failed: %s",
+                PQerrorMessage(conn));
+        exit_nicely(conn);
+    }
+
+    /*
+     * Issue LISTEN command to enable notifications from the rule's NOTIFY.
+     */
+    res = PQexec(conn, "LISTEN TBL2");
+    if (PQresultStatus(res) != PGRES_COMMAND_OK)
+    {
+        fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
+        PQclear(res);
+        exit_nicely(conn);
+    }
+
+    /*
+     * should PQclear PGresult whenever it is no longer needed to avoid memory
+     * leaks
+     */
+    PQclear(res);
+
+    /* Quit after four notifies are received. */
+    nnotifies = 0;
+    while (nnotifies &lt; 4)
+    {
         /*
-         * If the user supplies a parameter on the command line, use it as
-         * the conninfo string; otherwise default to setting dbname=postgres
-         * and using environment variables or defaults for all other connection
-         * parameters.
+         * Sleep until something happens on the connection.  We use select(2)
+         * to wait for input, but you could also use poll() or similar
+         * facilities.
          */
-        if (argc &gt; 1)
-                conninfo = argv[1];
-        else
-                conninfo = "dbname = postgres";
+        int         sock;
+        fd_set      input_mask;
 
-        /* Make a connection to the database */
-        conn = PQconnectdb(conninfo);
+        sock = PQsocket(conn);
 
-        /* Check to see that the backend connection was successfully made */
-        if (PQstatus(conn) != CONNECTION_OK)
-        {
-                fprintf(stderr, "Connection to database failed: %s",
-                        PQerrorMessage(conn));
-                exit_nicely(conn);
-        }
+        if (sock &lt; 0)
+            break;              /* shouldn't happen */
 
-        /*
-         * Issue LISTEN command to enable notifications from the rule's NOTIFY.
-         */
-        res = PQexec(conn, "LISTEN TBL2");
-        if (PQresultStatus(res) != PGRES_COMMAND_OK)
+        FD_ZERO(&amp;input_mask);
+        FD_SET(sock, &amp;input_mask);
+
+        if (select(sock + 1, &amp;input_mask, NULL, NULL, NULL) &lt; 0)
         {
-                fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
-                PQclear(res);
-                exit_nicely(conn);
+            fprintf(stderr, "select() failed: %s\n", strerror(errno));
+            exit_nicely(conn);
         }
 
-        /*
-         * should PQclear PGresult whenever it is no longer needed to avoid
-         * memory leaks
-         */
-        PQclear(res);
-
-        /* Quit after four notifies are received. */
-        nnotifies = 0;
-        while (nnotifies &lt; 4)
+        /* Now check for input */
+        PQconsumeInput(conn);
+        while ((notify = PQnotifies(conn)) != NULL)
         {
-                /*
-                 * Sleep until something happens on the connection.  We use select(2)
-                 * to wait for input, but you could also use poll() or similar
-                 * facilities.
-                 */
-                int                     sock;
-                fd_set          input_mask;
-
-                sock = PQsocket(conn);
-
-                if (sock &lt; 0)
-                        break;                          /* shouldn't happen */
-
-                FD_ZERO(&amp;input_mask);
-                FD_SET(sock, &amp;input_mask);
-
-                if (select(sock + 1, &amp;input_mask, NULL, NULL, NULL) &lt; 0)
-                {
-                        fprintf(stderr, "select() failed: %s\n", strerror(errno));
-                        exit_nicely(conn);
-                }
-
-                /* Now check for input */
-                PQconsumeInput(conn);
-                while ((notify = PQnotifies(conn)) != NULL)
-                {
-                        fprintf(stderr,
-                                        "ASYNC NOTIFY of '%s' received from backend pid %d\n",
-                                        notify-&gt;relname, notify-&gt;be_pid);
-                        PQfreemem(notify);
-                        nnotifies++;
-                }
+            fprintf(stderr,
+                    "ASYNC NOTIFY of '%s' received from backend pid %d\n",
+                    notify-&gt;relname, notify-&gt;be_pid);
+            PQfreemem(notify);
+            nnotifies++;
         }
+    }
 
-        fprintf(stderr, "Done.\n");
+    fprintf(stderr, "Done.\n");
 
-        /* close the connection to the database and cleanup */
-        PQfinish(conn);
+    /* close the connection to the database and cleanup */
+    PQfinish(conn);
 
-        return 0;
+    return 0;
 }
 </programlisting>
   </example>
@@ -4488,7 +4506,7 @@ main(int argc, char **argv)
 <programlisting>
 /*
  * testlibpq3.c
- *              Test out-of-line parameters and binary I/O.
+ *      Test out-of-line parameters and binary I/O.
  *
  * Before running this, populate a database with the following commands
  * (provided in src/test/examples/testlibpq3.sql):
@@ -4505,6 +4523,10 @@ main(int argc, char **argv)
  *  t = (11 bytes) 'joe's place'
  *  b = (5 bytes) \000\001\002\003\004
  *
+ * tuple 0: got
+ *  i = (4 bytes) 2
+ *  t = (8 bytes) 'ho there'
+ *  b = (5 bytes) \004\003\002\001\000
  */
 #include &lt;stdio.h&gt;
 #include &lt;stdlib.h&gt;
@@ -4520,125 +4542,178 @@ main(int argc, char **argv)
 static void
 exit_nicely(PGconn *conn)
 {
-        PQfinish(conn);
-        exit(1);
+    PQfinish(conn);
+    exit(1);
 }
 
-int
-main(int argc, char **argv)
+/*
+ * This function prints a query result that is a binary-format fetch from
+ * a table defined as in the comment above.  We split it out because the
+ * main() function uses it twice.
+ */
+static void
+show_binary_results(PGresult *res)
 {
-        const char *conninfo;
-        PGconn     *conn;
-        PGresult   *res;
-        const char *paramValues[1];
-        int                     i,
-                                j;
-        int                     i_fnum,
-                                t_fnum,
-                                b_fnum;
+    int         i,
+                j;
+    int         i_fnum,
+                t_fnum,
+                b_fnum;
+
+    /* Use PQfnumber to avoid assumptions about field order in result */
+    i_fnum = PQfnumber(res, "i");
+    t_fnum = PQfnumber(res, "t");
+    b_fnum = PQfnumber(res, "b");
+
+    for (i = 0; i &lt; PQntuples(res); i++)
+    {
+        char       *iptr;
+        char       *tptr;
+        char       *bptr;
+        int         blen;
+        int         ival;
+
+        /* Get the field values (we ignore possibility they are null!) */
+        iptr = PQgetvalue(res, i, i_fnum);
+        tptr = PQgetvalue(res, i, t_fnum);
+        bptr = PQgetvalue(res, i, b_fnum);
 
         /*
-         * If the user supplies a parameter on the command line, use it as
-         * the conninfo string; otherwise default to setting dbname=postgres
-         * and using environment variables or defaults for all other connection
-         * parameters.
+         * The binary representation of INT4 is in network byte order, which
+         * we'd better coerce to the local byte order.
          */
-        if (argc &gt; 1)
-                conninfo = argv[1];
-        else
-                conninfo = "dbname = postgres";
-
-        /* Make a connection to the database */
-        conn = PQconnectdb(conninfo);
-
-        /* Check to see that the backend connection was successfully made */
-        if (PQstatus(conn) != CONNECTION_OK)
-        {
-                fprintf(stderr, "Connection to database failed: %s",
-                        PQerrorMessage(conn));
-                exit_nicely(conn);
-        }
+        ival = ntohl(*((uint32_t *) iptr));
 
         /*
-         * The point of this program is to illustrate use of PQexecParams()
-         * with out-of-line parameters, as well as binary transmission of
-         * results.  By using out-of-line parameters we can avoid a lot of
-         * tedious mucking about with quoting and escaping.  Notice how we
-         * don't have to do anything special with the quote mark in the
-         * parameter value.
+         * The binary representation of TEXT is, well, text, and since libpq
+         * was nice enough to append a zero byte to it, it'll work just fine
+         * as a C string.
+         *
+         * The binary representation of BYTEA is a bunch of bytes, which could
+         * include embedded nulls so we have to pay attention to field length.
          */
+        blen = PQgetlength(res, i, b_fnum);
+
+        printf("tuple %d: got\n", i);
+        printf(" i = (%d bytes) %d\n",
+               PQgetlength(res, i, i_fnum), ival);
+        printf(" t = (%d bytes) '%s'\n",
+               PQgetlength(res, i, t_fnum), tptr);
+        printf(" b = (%d bytes) ", blen);
+        for (j = 0; j &lt; blen; j++)
+            printf("\\%03o", bptr[j]);
+        printf("\n\n");
+    }
+}
 
-        /* Here is our out-of-line parameter value */
-        paramValues[0] = "joe's place";
-
-        res = PQexecParams(conn,
-                                           "SELECT * FROM test1 WHERE t = $1",
-                                           1,           /* one param */
-                                           NULL,        /* let the backend deduce param type */
-                                           paramValues,
-                                           NULL,        /* don't need param lengths since text */
-                                           NULL,        /* default to all text params */
-                                           1);          /* ask for binary results */
-
-        if (PQresultStatus(res) != PGRES_TUPLES_OK)
-        {
-                fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
-                PQclear(res);
-                exit_nicely(conn);
-        }
-
-        /* Use PQfnumber to avoid assumptions about field order in result */
-        i_fnum = PQfnumber(res, "i");
-        t_fnum = PQfnumber(res, "t");
-        b_fnum = PQfnumber(res, "b");
+int
+main(int argc, char **argv)
+{
+    const char *conninfo;
+    PGconn     *conn;
+    PGresult   *res;
+    const char *paramValues[1];
+    int         paramLengths[1];
+    int         paramFormats[1];
+    uint32_t    binaryIntVal;
+
+    /*
+     * If the user supplies a parameter on the command line, use it as the
+     * conninfo string; otherwise default to setting dbname=postgres and using
+     * environment variables or defaults for all other connection parameters.
+     */
+    if (argc &gt; 1)
+        conninfo = argv[1];
+    else
+        conninfo = "dbname = postgres";
+
+    /* Make a connection to the database */
+    conn = PQconnectdb(conninfo);
+
+    /* Check to see that the backend connection was successfully made */
+    if (PQstatus(conn) != CONNECTION_OK)
+    {
+        fprintf(stderr, "Connection to database failed: %s",
+                PQerrorMessage(conn));
+        exit_nicely(conn);
+    }
+
+    /*
+     * The point of this program is to illustrate use of PQexecParams() with
+     * out-of-line parameters, as well as binary transmission of data.
+     *
+     * This first example transmits the parameters as text, but receives the
+     * results in binary format.  By using out-of-line parameters we can
+     * avoid a lot of tedious mucking about with quoting and escaping, even
+     * though the data is text.  Notice how we don't have to do anything
+     * special with the quote mark in the parameter value.
+     */
+
+    /* Here is our out-of-line parameter value */
+    paramValues[0] = "joe's place";
+
+    res = PQexecParams(conn,
+                       "SELECT * FROM test1 WHERE t = $1",
+                       1,       /* one param */
+                       NULL,    /* let the backend deduce param type */
+                       paramValues,
+                       NULL,    /* don't need param lengths since text */
+                       NULL,    /* default to all text params */
+                       1);      /* ask for binary results */
+
+    if (PQresultStatus(res) != PGRES_TUPLES_OK)
+    {
+        fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
+        PQclear(res);
+        exit_nicely(conn);
+    }
+
+    show_binary_results(res);
+
+    PQclear(res);
+
+    /*
+     * In this second example we transmit an integer parameter in binary
+     * form, and again retrieve the results in binary form.
+     *
+     * Although we tell PQexecParams we are letting the backend deduce
+     * parameter type, we really force the decision by casting the parameter
+     * symbol in the query text.  This is a good safety measure when sending
+     * binary parameters.
+     */
+
+    /* Convert integer value "2" to network byte order */
+    binaryIntVal = htonl((uint32_t) 2);
+
+    /* Set up parameter arrays for PQexecParams */
+    paramValues[0] = (char *) &amp;binaryIntVal;
+    paramLengths[0] = sizeof(binaryIntVal);
+    paramFormats[0] = 1;        /* binary */
+
+    res = PQexecParams(conn,
+                       "SELECT * FROM test1 WHERE i = $1::int4",
+                       1,       /* one param */
+                       NULL,    /* let the backend deduce param type */
+                       paramValues,
+                       paramLengths,
+                       paramFormats,
+                       1);      /* ask for binary results */
+
+    if (PQresultStatus(res) != PGRES_TUPLES_OK)
+    {
+        fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
+        PQclear(res);
+        exit_nicely(conn);
+    }
 
-        for (i = 0; i &lt; PQntuples(res); i++)
-        {
-                char       *iptr;
-                char       *tptr;
-                char       *bptr;
-                int                     blen;
-                int                     ival;
-
-                /* Get the field values (we ignore possibility they are null!) */
-                iptr = PQgetvalue(res, i, i_fnum);
-                tptr = PQgetvalue(res, i, t_fnum);
-                bptr = PQgetvalue(res, i, b_fnum);
-
-                /*
-                 * The binary representation of INT4 is in network byte order,
-                 * which we'd better coerce to the local byte order.
-                 */
-                ival = ntohl(*((uint32_t *) iptr));
-
-                /*
-                 * The binary representation of TEXT is, well, text, and since
-                 * libpq was nice enough to append a zero byte to it, it'll work
-                 * just fine as a C string.
-                 *
-                 * The binary representation of BYTEA is a bunch of bytes, which
-                 * could include embedded nulls so we have to pay attention to
-                 * field length.
-                 */
-                blen = PQgetlength(res, i, b_fnum);
-
-                printf("tuple %d: got\n", i);
-                printf(" i = (%d bytes) %d\n",
-                           PQgetlength(res, i, i_fnum), ival);
-                printf(" t = (%d bytes) '%s'\n",
-                           PQgetlength(res, i, t_fnum), tptr);
-                printf(" b = (%d bytes) ", blen);
-                for (j = 0; j &lt; blen; j++)
-                        printf("\\%03o", bptr[j]);
-                printf("\n\n");
-        }
+    show_binary_results(res);
 
-        PQclear(res);
+    PQclear(res);
 
-        /* close the connection to the database and cleanup */
-        PQfinish(conn);
+    /* close the connection to the database and cleanup */
+    PQfinish(conn);
 
-        return 0;
+    return 0;
 }
 </programlisting>
   </example>
diff --git a/src/test/examples/testlibpq3.c b/src/test/examples/testlibpq3.c
index 918d142c7b6a677d71a15a0ba77edb4051750d73..c7e4e097322659d8ffcbd84bd2f335f1f87cb6ba 100644
--- a/src/test/examples/testlibpq3.c
+++ b/src/test/examples/testlibpq3.c
@@ -17,6 +17,10 @@
  *	t = (11 bytes) 'joe's place'
  *	b = (5 bytes) \000\001\002\003\004
  *
+ * tuple 0: got
+ *  i = (4 bytes) 2
+ *  t = (8 bytes) 'ho there'
+ *  b = (5 bytes) \004\003\002\001\000
  */
 #include <stdio.h>
 #include <stdlib.h>
@@ -36,6 +40,66 @@ exit_nicely(PGconn *conn)
 	exit(1);
 }
 
+/*
+ * This function prints a query result that is a binary-format fetch from
+ * a table defined as in the comment above.  We split it out because the
+ * main() function uses it twice.
+ */
+static void
+show_binary_results(PGresult *res)
+{
+	int			i,
+				j;
+	int			i_fnum,
+				t_fnum,
+				b_fnum;
+
+	/* Use PQfnumber to avoid assumptions about field order in result */
+	i_fnum = PQfnumber(res, "i");
+	t_fnum = PQfnumber(res, "t");
+	b_fnum = PQfnumber(res, "b");
+
+	for (i = 0; i < PQntuples(res); i++)
+	{
+		char	   *iptr;
+		char	   *tptr;
+		char	   *bptr;
+		int			blen;
+		int			ival;
+
+		/* Get the field values (we ignore possibility they are null!) */
+		iptr = PQgetvalue(res, i, i_fnum);
+		tptr = PQgetvalue(res, i, t_fnum);
+		bptr = PQgetvalue(res, i, b_fnum);
+
+		/*
+		 * The binary representation of INT4 is in network byte order, which
+		 * we'd better coerce to the local byte order.
+		 */
+		ival = ntohl(*((uint32_t *) iptr));
+
+		/*
+		 * The binary representation of TEXT is, well, text, and since libpq
+		 * was nice enough to append a zero byte to it, it'll work just fine
+		 * as a C string.
+		 *
+		 * The binary representation of BYTEA is a bunch of bytes, which could
+		 * include embedded nulls so we have to pay attention to field length.
+		 */
+		blen = PQgetlength(res, i, b_fnum);
+
+		printf("tuple %d: got\n", i);
+		printf(" i = (%d bytes) %d\n",
+			   PQgetlength(res, i, i_fnum), ival);
+		printf(" t = (%d bytes) '%s'\n",
+			   PQgetlength(res, i, t_fnum), tptr);
+		printf(" b = (%d bytes) ", blen);
+		for (j = 0; j < blen; j++)
+			printf("\\%03o", bptr[j]);
+		printf("\n\n");
+	}
+}
+
 int
 main(int argc, char **argv)
 {
@@ -43,11 +107,9 @@ main(int argc, char **argv)
 	PGconn	   *conn;
 	PGresult   *res;
 	const char *paramValues[1];
-	int			i,
-				j;
-	int			i_fnum,
-				t_fnum,
-				b_fnum;
+	int			paramLengths[1];
+	int			paramFormats[1];
+	uint32_t	binaryIntVal;
 
 	/*
 	 * If the user supplies a parameter on the command line, use it as the
@@ -72,10 +134,13 @@ main(int argc, char **argv)
 
 	/*
 	 * The point of this program is to illustrate use of PQexecParams() with
-	 * out-of-line parameters, as well as binary transmission of results.  By
-	 * using out-of-line parameters we can avoid a lot of tedious mucking
-	 * about with quoting and escaping.  Notice how we don't have to do
-	 * anything special with the quote mark in the parameter value.
+	 * out-of-line parameters, as well as binary transmission of data.
+	 *
+	 * This first example transmits the parameters as text, but receives the
+	 * results in binary format.  By using out-of-line parameters we can
+	 * avoid a lot of tedious mucking about with quoting and escaping, even
+	 * though the data is text.  Notice how we don't have to do anything
+	 * special with the quote mark in the parameter value.
 	 */
 
 	/* Here is our out-of-line parameter value */
@@ -97,51 +162,46 @@ main(int argc, char **argv)
 		exit_nicely(conn);
 	}
 
-	/* Use PQfnumber to avoid assumptions about field order in result */
-	i_fnum = PQfnumber(res, "i");
-	t_fnum = PQfnumber(res, "t");
-	b_fnum = PQfnumber(res, "b");
+	show_binary_results(res);
 
-	for (i = 0; i < PQntuples(res); i++)
-	{
-		char	   *iptr;
-		char	   *tptr;
-		char	   *bptr;
-		int			blen;
-		int			ival;
+	PQclear(res);
 
-		/* Get the field values (we ignore possibility they are null!) */
-		iptr = PQgetvalue(res, i, i_fnum);
-		tptr = PQgetvalue(res, i, t_fnum);
-		bptr = PQgetvalue(res, i, b_fnum);
+	/*
+	 * In this second example we transmit an integer parameter in binary
+	 * form, and again retrieve the results in binary form.
+	 *
+	 * Although we tell PQexecParams we are letting the backend deduce
+	 * parameter type, we really force the decision by casting the parameter
+	 * symbol in the query text.  This is a good safety measure when sending
+	 * binary parameters.
+	 */
 
-		/*
-		 * The binary representation of INT4 is in network byte order, which
-		 * we'd better coerce to the local byte order.
-		 */
-		ival = ntohl(*((uint32_t *) iptr));
+	/* Convert integer value "2" to network byte order */
+	binaryIntVal = htonl((uint32_t) 2);
 
-		/*
-		 * The binary representation of TEXT is, well, text, and since libpq
-		 * was nice enough to append a zero byte to it, it'll work just fine
-		 * as a C string.
-		 *
-		 * The binary representation of BYTEA is a bunch of bytes, which could
-		 * include embedded nulls so we have to pay attention to field length.
-		 */
-		blen = PQgetlength(res, i, b_fnum);
+	/* Set up parameter arrays for PQexecParams */
+	paramValues[0] = (char *) &binaryIntVal;
+	paramLengths[0] = sizeof(binaryIntVal);
+	paramFormats[0] = 1;		/* binary */
 
-		printf("tuple %d: got\n", i);
-		printf(" i = (%d bytes) %d\n",
-			   PQgetlength(res, i, i_fnum), ival);
-		printf(" t = (%d bytes) '%s'\n",
-			   PQgetlength(res, i, t_fnum), tptr);
-		printf(" b = (%d bytes) ", blen);
-		for (j = 0; j < blen; j++)
-			printf("\\%03o", bptr[j]);
-		printf("\n\n");
+	res = PQexecParams(conn,
+					   "SELECT * FROM test1 WHERE i = $1::int4",
+					   1,		/* one param */
+					   NULL,	/* let the backend deduce param type */
+					   paramValues,
+					   paramLengths,
+					   paramFormats,
+					   1);		/* ask for binary results */
+
+	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
+		PQclear(res);
+		exit_nicely(conn);
 	}
 
+	show_binary_results(res);
+
 	PQclear(res);
 
 	/* close the connection to the database and cleanup */