On Thu, Jun 04, 2026 at 11:39:02AM +0100, Dagfinn Ilmari Mannsåker wrote:
> Nathan Bossart <[email protected]> writes:
> 
>> - <sect1 id="libpq-fastpath">
>> -  <title>The Fast-Path Interface</title>
>> -
>> -  <indexterm zone="libpq-fastpath">
>> -   <primary>fast path</primary>
>> -  </indexterm>
> 
> Should we move this to the "Obsolete or Renamed Features" appendix
> (e.g. appendix-obsolete-libpq-fastpath.sgml) with a description of why
> it was removed?

Yes, I think we should.  Done in the attached.

-- 
nathan
>From 63486371b3531be66bb8e0c62ef1b8cc7e95abb5 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <[email protected]>
Date: Mon, 1 Jun 2026 16:55:00 -0500
Subject: [PATCH v4 1/3] remove PQfn

---
 .../appendix-obsolete-libpq-fastpath.sgml     |  24 ++++
 doc/src/sgml/appendix-obsolete.sgml           |   1 +
 doc/src/sgml/filelist.sgml                    |   1 +
 doc/src/sgml/libpq.sgml                       | 117 +-----------------
 src/backend/tcop/fastpath.c                   |   4 +-
 src/include/tcop/dest.h                       |   4 +-
 src/interfaces/libpq/fe-exec.c                |  42 +++++--
 src/interfaces/libpq/fe-lobj.c                |  38 +++---
 8 files changed, 86 insertions(+), 145 deletions(-)
 create mode 100644 doc/src/sgml/appendix-obsolete-libpq-fastpath.sgml

diff --git a/doc/src/sgml/appendix-obsolete-libpq-fastpath.sgml 
b/doc/src/sgml/appendix-obsolete-libpq-fastpath.sgml
new file mode 100644
index 00000000000..e42c2ece487
--- /dev/null
+++ b/doc/src/sgml/appendix-obsolete-libpq-fastpath.sgml
@@ -0,0 +1,24 @@
+<!-- doc/src/sgml/appendix-obsolete-libpq-fastpath.sgml -->
+<!--
+  See doc/src/sgml/appendix-obsolete.sgml for why this file exists. Do not 
change the id attribute.
+-->
+
+<sect1 id="libpq-fastpath">
+  <title><application>libpq</application> Fast-Path Interface Removed</title>
+
+   <indexterm zone="libpq-fastpath">
+    <primary>fast path</primary>
+   </indexterm>
+
+   <para>
+    In <productname>PostgreSQL</productname> 19 and below,
+    <application>libpq</application> supported a fast-path interface to send
+    simple function calls to the server.  This interface was unsafe and
+    obsolete, and thus was removed in <productname>PostgreSQL</productname> 20.
+    One can achieve similar performance and greater functionality by setting up
+    a prepared statement to define the function call.  Then, executing the
+    statement with binary transmission of parameters and results substitutes
+    for a fast-path function call.
+   </para>
+
+</sect1>
diff --git a/doc/src/sgml/appendix-obsolete.sgml 
b/doc/src/sgml/appendix-obsolete.sgml
index cc002653052..11a033112ef 100644
--- a/doc/src/sgml/appendix-obsolete.sgml
+++ b/doc/src/sgml/appendix-obsolete.sgml
@@ -39,5 +39,6 @@
  &obsolete-pgresetxlog;
  &obsolete-pgreceivexlog;
  &obsolete-auth-radius;
+ &obsolete-libpq-fastpath;
 
 </appendix>
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
index 25a85082759..7dbe741d729 100644
--- a/doc/src/sgml/filelist.sgml
+++ b/doc/src/sgml/filelist.sgml
@@ -209,3 +209,4 @@
 <!ENTITY obsolete-pgresetxlog SYSTEM "appendix-obsolete-pgresetxlog.sgml">
 <!ENTITY obsolete-pgreceivexlog SYSTEM "appendix-obsolete-pgreceivexlog.sgml">
 <!ENTITY obsolete-auth-radius SYSTEM "appendix-obsolete-auth-radius.sgml">
+<!ENTITY obsolete-libpq-fastpath SYSTEM 
"appendix-obsolete-libpq-fastpath.sgml">
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 7d3c3bb66d8..123e7f03902 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -5887,7 +5887,7 @@ int PQflush(PGconn *conn);
     are permitted, command strings containing multiple SQL commands are
     disallowed, and so is <literal>COPY</literal>.
     Using synchronous command execution functions
-    such as <function>PQfn</function>,
+    such as
     <function>PQexec</function>,
     <function>PQexecParams</function>,
     <function>PQprepare</function>,
@@ -7046,121 +7046,6 @@ int PQrequestCancel(PGconn *conn);
   </sect2>
  </sect1>
 
- <sect1 id="libpq-fastpath">
-  <title>The Fast-Path Interface</title>
-
-  <indexterm zone="libpq-fastpath">
-   <primary>fast path</primary>
-  </indexterm>
-
-  <para>
-   <productname>PostgreSQL</productname> provides a fast-path interface
-   to send simple function calls to the server.
-  </para>
-
-  <warning>
-   <para>
-    This interface is unsafe and should not be used.  When
-    <parameter>result_is_int</parameter> is set to <literal>0</literal>,
-    <function>PQfn</function> may write data beyond the end of
-    <parameter>result_buf</parameter>, regardless of whether the buffer has
-    enough space for the requested number of bytes.  Furthermore, it is
-    obsolete, as one can achieve similar
-    performance and greater functionality by setting up a prepared
-    statement to define the function call.  Then, executing the statement
-    with binary transmission of parameters and results substitutes for a
-    fast-path function call.
-   </para>
-  </warning>
-
-  <para>
-   The function <function 
id="libpq-PQfn">PQfn</function><indexterm><primary>PQfn</primary></indexterm>
-   requests execution of a server function via the fast-path interface:
-<synopsis>
-PGresult *PQfn(PGconn *conn,
-               int fnid,
-               int *result_buf,
-               int *result_len,
-               int result_is_int,
-               const PQArgBlock *args,
-               int nargs);
-
-typedef struct
-{
-    int len;
-    int isint;
-    union
-    {
-        int *ptr;
-        int integer;
-    } u;
-} PQArgBlock;
-</synopsis>
-  </para>
-
-  <para>
-   The <parameter>fnid</parameter> argument is the OID of the function to be
-   executed.  <parameter>args</parameter> and <parameter>nargs</parameter> 
define the
-   parameters to be passed to the function; they must match the declared
-   function argument list.  When the <parameter>isint</parameter> field of a
-   parameter structure is true, the <parameter>u.integer</parameter> value is 
sent
-   to the server as an integer of the indicated length (this must be
-   2 or 4 bytes); proper byte-swapping occurs.  When 
<parameter>isint</parameter>
-   is false, the indicated number of bytes at <parameter>*u.ptr</parameter> are
-   sent with no processing; the data must be in the format expected by
-   the server for binary transmission of the function's argument data
-   type.  (The declaration of <parameter>u.ptr</parameter> as being of
-   type <type>int *</type> is historical; it would be better to consider
-   it <type>void *</type>.)
-   <parameter>result_buf</parameter> points to the buffer in which to place
-   the function's return value.  The caller must have allocated sufficient
-   space to store the return value.  (There is no check!) The actual result
-   length in bytes will be returned in the integer pointed to by
-   <parameter>result_len</parameter>.  If a 2- or 4-byte integer result
-   is expected, set <parameter>result_is_int</parameter> to 1, otherwise
-   set it to 0.  Setting <parameter>result_is_int</parameter> to 1 causes
-   <application>libpq</application> to byte-swap the value if necessary, so 
that it
-   is delivered as a proper <type>int</type> value for the client machine;
-   note that a 4-byte integer is delivered into 
<parameter>*result_buf</parameter>
-   for either allowed result size.
-   When <parameter>result_is_int</parameter> is 0, the binary-format byte 
string
-   sent by the server is returned unmodified. (In this case it's better
-   to consider <parameter>result_buf</parameter> as being of
-   type <type>void *</type>.)
-  </para>
-
-  <para>
-   <function>PQfn</function> always returns a valid
-   <structname>PGresult</structname> pointer, with
-   status <literal>PGRES_COMMAND_OK</literal> for success
-   or <literal>PGRES_FATAL_ERROR</literal> if some problem was encountered.
-   The result status should be
-   checked before the result is used.   The caller is responsible for
-   freeing  the  <structname>PGresult</structname>  with
-   <xref linkend="libpq-PQclear"/> when it is no longer needed.
-  </para>
-
-  <para>
-   To pass a NULL argument to the function, set
-   the <parameter>len</parameter> field of that parameter structure
-   to <literal>-1</literal>; the <parameter>isint</parameter>
-   and <parameter>u</parameter> fields are then irrelevant.
-  </para>
-
-  <para>
-   If the function returns NULL, <parameter>*result_len</parameter> is set
-   to <literal>-1</literal>, and <parameter>*result_buf</parameter> is not
-   modified.
-  </para>
-
-  <para>
-   Note that it is not possible to handle set-valued results when using
-   this interface.  Also, the function must be a plain function, not an
-   aggregate, window function, or procedure.
-  </para>
-
- </sect1>
-
  <sect1 id="libpq-notify">
   <title>Asynchronous Notification</title>
 
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index 52772bc90a8..5379e4ad9f5 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -11,7 +11,9 @@
  *       src/backend/tcop/fastpath.c
  *
  * NOTES
- *       This cruft is the server side of PQfn.
+ *       This cruft is the server side of PQfn.  libpq's PQfn() was retired in
+ *       v20 and now always errors, but the server code is retained for the
+ *       benefit of older clients.
  *
  *-------------------------------------------------------------------------
  */
diff --git a/src/include/tcop/dest.h b/src/include/tcop/dest.h
index 103f27fc3cb..507414421ec 100644
--- a/src/include/tcop/dest.h
+++ b/src/include/tcop/dest.h
@@ -12,8 +12,8 @@
  *
  *       - a remote process is the destination when we are
  *             running a backend with a frontend and the frontend executes
- *             PQexec() or PQfn().  In this case, the results are sent
- *             to the frontend via the functions in backend/libpq.
+ *             PQexec().  In this case, the results are sent to the frontend 
via
+ *             the functions in backend/libpq.
  *
  *       - DestNone is the destination when the system executes
  *             a query internally.  The results are discarded.
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7b8edacbfde..2f034d70e65 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -2986,10 +2986,10 @@ PQendcopy(PGconn *conn)
  *             nargs                   : # of arguments in args array.
  *
  * RETURNS
- *             PGresult with status = PGRES_COMMAND_OK if successful.
- *                     *result_len is > 0 if there is a return value, 0 if not.
- *             PGresult with status = PGRES_FATAL_ERROR if backend returns an 
error.
- *             NULL on communications failure.  conn->errorMessage will be set.
+ *             This function was unsafe and is no longer supported, so it now 
always
+ *             sets *result_len to 0 and returns a PGresult with status set to
+ *             PGRES_FATAL_ERROR (unless the connection is in the wrong state, 
in
+ *             which case it returns NULL).
  * ----------------
  */
 
@@ -3002,15 +3002,43 @@ PQfn(PGconn *conn,
         const PQArgBlock *args,
         int nargs)
 {
-       return PQnfn(conn, fnid, result_buf, -1, result_len,
-                                result_is_int, args, nargs);
+       *result_len = 0;
+
+       if (!conn)
+               return NULL;
+
+       /*
+        * Since this is the beginning of a query cycle, reset the error state.
+        * However, in pipeline mode with something already queued, the error
+        * buffer belongs to that command and we shouldn't clear it.
+        */
+       if (conn->cmd_queue_head == NULL)
+               pqClearConnErrorState(conn);
+
+       if (conn->pipelineStatus != PQ_PIPELINE_OFF)
+       {
+               libpq_append_conn_error(conn, "%s not allowed in pipeline 
mode", "PQfn");
+               return NULL;
+       }
+
+       if (conn->sock == PGINVALID_SOCKET || conn->asyncStatus != PGASYNC_IDLE 
||
+               pgHavePendingResult(conn))
+       {
+               libpq_append_conn_error(conn, "connection in wrong state");
+               return NULL;
+       }
+
+       libpq_append_conn_error(conn, "PQfn() is no longer supported; use a 
prepared statement or PQexecParams() with binary results instead");
+       pqSaveErrorResult(conn);
+       return pqPrepareAsyncResult(conn);
 }
 
 /*
  * PQnfn
  *             Private version of PQfn() with verification that returned data 
fits in
  *             result_buf when result_is_int == 0.  Setting buf_size to -1 
disables
- *             this verification.
+ *             this verification.  This is currently only used by the frontend 
LO
+ *             interface and will hopefully be removed down the road.
  */
 PGresult *
 PQnfn(PGconn *conn, int fnid, int *result_buf, int buf_size, int *result_len,
diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index 12a32fcbaf3..1660c969f58 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -72,7 +72,7 @@ lo_open(PGconn *conn, Oid lobjId, int mode)
        argv[1].len = 4;
        argv[1].u.integer = mode;
 
-       res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, 
argv, 2);
+       res = PQnfn(conn, conn->lobjfuncs->fn_lo_open, &fd, -1, &result_len, 1, 
argv, 2);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
        {
                PQclear(res);
@@ -106,8 +106,8 @@ lo_close(PGconn *conn, int fd)
        argv[0].isint = 1;
        argv[0].len = 4;
        argv[0].u.integer = fd;
-       res = PQfn(conn, conn->lobjfuncs->fn_lo_close,
-                          &retval, &result_len, 1, argv, 1);
+       res = PQnfn(conn, conn->lobjfuncs->fn_lo_close,
+                               &retval, -1, &result_len, 1, argv, 1);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
        {
                PQclear(res);
@@ -169,8 +169,8 @@ lo_truncate(PGconn *conn, int fd, size_t len)
        argv[1].len = 4;
        argv[1].u.integer = (int) len;
 
-       res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate,
-                          &retval, &result_len, 1, argv, 2);
+       res = PQnfn(conn, conn->lobjfuncs->fn_lo_truncate,
+                               &retval, -1, &result_len, 1, argv, 2);
 
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
        {
@@ -218,8 +218,8 @@ lo_truncate64(PGconn *conn, int fd, int64_t len)
        argv[1].len = 8;
        argv[1].u.ptr = (int *) &len;
 
-       res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate64,
-                          &retval, &result_len, 1, argv, 2);
+       res = PQnfn(conn, conn->lobjfuncs->fn_lo_truncate64,
+                               &retval, -1, &result_len, 1, argv, 2);
 
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
        {
@@ -322,8 +322,8 @@ lo_write(PGconn *conn, int fd, const char *buf, size_t len)
        argv[1].len = (int) len;
        argv[1].u.ptr = (int *) unconstify(char *, buf);
 
-       res = PQfn(conn, conn->lobjfuncs->fn_lo_write,
-                          &retval, &result_len, 1, argv, 2);
+       res = PQnfn(conn, conn->lobjfuncs->fn_lo_write,
+                               &retval, -1, &result_len, 1, argv, 2);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
        {
                PQclear(res);
@@ -363,8 +363,8 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
        argv[2].len = 4;
        argv[2].u.integer = whence;
 
-       res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek,
-                          &retval, &result_len, 1, argv, 3);
+       res = PQnfn(conn, conn->lobjfuncs->fn_lo_lseek,
+                               &retval, -1, &result_len, 1, argv, 3);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
        {
                PQclear(res);
@@ -448,8 +448,8 @@ lo_creat(PGconn *conn, int mode)
        argv[0].isint = 1;
        argv[0].len = 4;
        argv[0].u.integer = mode;
-       res = PQfn(conn, conn->lobjfuncs->fn_lo_creat,
-                          &retval, &result_len, 1, argv, 1);
+       res = PQnfn(conn, conn->lobjfuncs->fn_lo_creat,
+                               &retval, -1, &result_len, 1, argv, 1);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
        {
                PQclear(res);
@@ -492,8 +492,8 @@ lo_create(PGconn *conn, Oid lobjId)
        argv[0].isint = 1;
        argv[0].len = 4;
        argv[0].u.integer = lobjId;
-       res = PQfn(conn, conn->lobjfuncs->fn_lo_create,
-                          &retval, &result_len, 1, argv, 1);
+       res = PQnfn(conn, conn->lobjfuncs->fn_lo_create,
+                               &retval, -1, &result_len, 1, argv, 1);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
        {
                PQclear(res);
@@ -526,8 +526,8 @@ lo_tell(PGconn *conn, int fd)
        argv[0].len = 4;
        argv[0].u.integer = fd;
 
-       res = PQfn(conn, conn->lobjfuncs->fn_lo_tell,
-                          &retval, &result_len, 1, argv, 1);
+       res = PQnfn(conn, conn->lobjfuncs->fn_lo_tell,
+                               &retval, -1, &result_len, 1, argv, 1);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
        {
                PQclear(res);
@@ -600,8 +600,8 @@ lo_unlink(PGconn *conn, Oid lobjId)
        argv[0].len = 4;
        argv[0].u.integer = lobjId;
 
-       res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink,
-                          &retval, &result_len, 1, argv, 1);
+       res = PQnfn(conn, conn->lobjfuncs->fn_lo_unlink,
+                               &retval, -1, &result_len, 1, argv, 1);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
        {
                PQclear(res);
-- 
2.50.1 (Apple Git-155)

>From 181028cbf820700f104f48dfc0e94d0c7f5e42e0 Mon Sep 17 00:00:00 2001
From: Reviewer <[email protected]>
Date: Tue, 2 Jun 2026 17:22:48 +0000
Subject: [PATCH v4 2/3] remove lo_hton64() and lo_ntoh64()

---
 src/interfaces/libpq/fe-lobj.c | 58 +++-------------------------------
 1 file changed, 4 insertions(+), 54 deletions(-)

diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index 1660c969f58..42b2a36bda9 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -43,8 +43,6 @@
 
 static int     lo_initialize(PGconn *conn);
 static Oid     lo_import_internal(PGconn *conn, const char *filename, Oid oid);
-static int64_t lo_hton64(int64_t host64);
-static int64_t lo_ntoh64(int64_t net64);
 
 /*
  * lo_open
@@ -213,7 +211,7 @@ lo_truncate64(PGconn *conn, int fd, int64_t len)
        argv[0].len = 4;
        argv[0].u.integer = fd;
 
-       len = lo_hton64(len);
+       len = pg_hton64(len);
        argv[1].isint = 0;
        argv[1].len = 8;
        argv[1].u.ptr = (int *) &len;
@@ -403,7 +401,7 @@ lo_lseek64(PGconn *conn, int fd, int64_t offset, int whence)
        argv[0].len = 4;
        argv[0].u.integer = fd;
 
-       offset = lo_hton64(offset);
+       offset = pg_hton64(offset);
        argv[1].isint = 0;
        argv[1].len = 8;
        argv[1].u.ptr = (int *) &offset;
@@ -417,7 +415,7 @@ lo_lseek64(PGconn *conn, int fd, int64_t offset, int whence)
        if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
        {
                PQclear(res);
-               return lo_ntoh64(retval);
+               return pg_ntoh64(retval);
        }
        else
        {
@@ -571,7 +569,7 @@ lo_tell64(PGconn *conn, int fd)
        if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
        {
                PQclear(res);
-               return lo_ntoh64(retval);
+               return pg_ntoh64(retval);
        }
        else
        {
@@ -1014,51 +1012,3 @@ lo_initialize(PGconn *conn)
        conn->lobjfuncs = lobjfuncs;
        return 0;
 }
-
-/*
- * lo_hton64
- *       converts a 64-bit integer from host byte order to network byte order
- */
-static int64_t
-lo_hton64(int64_t host64)
-{
-       union
-       {
-               int64           i64;
-               uint32          i32[2];
-       }                       swap;
-       uint32          t;
-
-       /* High order half first, since we're doing MSB-first */
-       t = (uint32) (host64 >> 32);
-       swap.i32[0] = pg_hton32(t);
-
-       /* Now the low order half */
-       t = (uint32) host64;
-       swap.i32[1] = pg_hton32(t);
-
-       return swap.i64;
-}
-
-/*
- * lo_ntoh64
- *       converts a 64-bit integer from network byte order to host byte order
- */
-static int64_t
-lo_ntoh64(int64_t net64)
-{
-       union
-       {
-               int64           i64;
-               uint32          i32[2];
-       }                       swap;
-       int64           result;
-
-       swap.i64 = net64;
-
-       result = (uint32) pg_ntoh32(swap.i32[0]);
-       result <<= 32;
-       result |= (uint32) pg_ntoh32(swap.i32[1]);
-
-       return result;
-}
-- 
2.50.1 (Apple Git-155)

>From 8e5a937d5e302a56ff2118ce3ea4f69e7db5ae9f Mon Sep 17 00:00:00 2001
From: Reviewer <[email protected]>
Date: Tue, 2 Jun 2026 18:24:30 +0000
Subject: [PATCH v4 3/3] add helper functions for fast-path arg setup

---
 src/interfaces/libpq/fe-lobj.c | 110 ++++++++++++---------------------
 1 file changed, 38 insertions(+), 72 deletions(-)

diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index 42b2a36bda9..e8f6d958e84 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -44,6 +44,22 @@
 static int     lo_initialize(PGconn *conn);
 static Oid     lo_import_internal(PGconn *conn, const char *filename, Oid oid);
 
+static inline void
+lo_set_int_arg(PQArgBlock *arg, int value)
+{
+       arg->isint = 1;
+       arg->len = 4;
+       arg->u.integer = value;
+}
+
+static inline void
+lo_set_ptr_arg(PQArgBlock *arg, const void *ptr, int len)
+{
+       arg->isint = 0;
+       arg->len = len;
+       arg->u.ptr = (int *) unconstify(void *, ptr);
+}
+
 /*
  * lo_open
  *       opens an existing large object
@@ -62,13 +78,8 @@ lo_open(PGconn *conn, Oid lobjId, int mode)
        if (lo_initialize(conn) < 0)
                return -1;
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = lobjId;
-
-       argv[1].isint = 1;
-       argv[1].len = 4;
-       argv[1].u.integer = mode;
+       lo_set_int_arg(&argv[0], lobjId);
+       lo_set_int_arg(&argv[1], mode);
 
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_open, &fd, -1, &result_len, 1, 
argv, 2);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -101,9 +112,7 @@ lo_close(PGconn *conn, int fd)
        if (lo_initialize(conn) < 0)
                return -1;
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = fd;
+       lo_set_int_arg(&argv[0], fd);
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_close,
                                &retval, -1, &result_len, 1, argv, 1);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -159,13 +168,8 @@ lo_truncate(PGconn *conn, int fd, size_t len)
                return -1;
        }
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = fd;
-
-       argv[1].isint = 1;
-       argv[1].len = 4;
-       argv[1].u.integer = (int) len;
+       lo_set_int_arg(&argv[0], fd);
+       lo_set_int_arg(&argv[1], (int) len);
 
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_truncate,
                                &retval, -1, &result_len, 1, argv, 2);
@@ -207,14 +211,10 @@ lo_truncate64(PGconn *conn, int fd, int64_t len)
                return -1;
        }
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = fd;
+       lo_set_int_arg(&argv[0], fd);
 
        len = pg_hton64(len);
-       argv[1].isint = 0;
-       argv[1].len = 8;
-       argv[1].u.ptr = (int *) &len;
+       lo_set_ptr_arg(&argv[1], &len, 8);
 
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_truncate64,
                                &retval, -1, &result_len, 1, argv, 2);
@@ -261,13 +261,8 @@ lo_read(PGconn *conn, int fd, char *buf, size_t len)
                return -1;
        }
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = fd;
-
-       argv[1].isint = 1;
-       argv[1].len = 4;
-       argv[1].u.integer = (int) len;
+       lo_set_int_arg(&argv[0], fd);
+       lo_set_int_arg(&argv[1], (int) len);
 
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_read,
                                (void *) buf, len, &result_len, 0, argv, 2);
@@ -312,13 +307,8 @@ lo_write(PGconn *conn, int fd, const char *buf, size_t len)
                return -1;
        }
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = fd;
-
-       argv[1].isint = 0;
-       argv[1].len = (int) len;
-       argv[1].u.ptr = (int *) unconstify(char *, buf);
+       lo_set_int_arg(&argv[0], fd);
+       lo_set_ptr_arg(&argv[1], buf, (int) len);
 
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_write,
                                &retval, -1, &result_len, 1, argv, 2);
@@ -349,17 +339,9 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
        if (lo_initialize(conn) < 0)
                return -1;
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = fd;
-
-       argv[1].isint = 1;
-       argv[1].len = 4;
-       argv[1].u.integer = offset;
-
-       argv[2].isint = 1;
-       argv[2].len = 4;
-       argv[2].u.integer = whence;
+       lo_set_int_arg(&argv[0], fd);
+       lo_set_int_arg(&argv[1], offset);
+       lo_set_int_arg(&argv[2], whence);
 
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_lseek,
                                &retval, -1, &result_len, 1, argv, 3);
@@ -397,18 +379,12 @@ lo_lseek64(PGconn *conn, int fd, int64_t offset, int 
whence)
                return -1;
        }
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = fd;
+       lo_set_int_arg(&argv[0], fd);
 
        offset = pg_hton64(offset);
-       argv[1].isint = 0;
-       argv[1].len = 8;
-       argv[1].u.ptr = (int *) &offset;
+       lo_set_ptr_arg(&argv[1], &offset, 8);
 
-       argv[2].isint = 1;
-       argv[2].len = 4;
-       argv[2].u.integer = whence;
+       lo_set_int_arg(&argv[2], whence);
 
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_lseek64,
                                (void *) &retval, sizeof(retval), &result_len, 
0, argv, 3);
@@ -443,9 +419,7 @@ lo_creat(PGconn *conn, int mode)
        if (lo_initialize(conn) < 0)
                return InvalidOid;
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = mode;
+       lo_set_int_arg(&argv[0], mode);
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_creat,
                                &retval, -1, &result_len, 1, argv, 1);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -487,9 +461,7 @@ lo_create(PGconn *conn, Oid lobjId)
                return InvalidOid;
        }
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = lobjId;
+       lo_set_int_arg(&argv[0], lobjId);
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_create,
                                &retval, -1, &result_len, 1, argv, 1);
        if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -520,9 +492,7 @@ lo_tell(PGconn *conn, int fd)
        if (lo_initialize(conn) < 0)
                return -1;
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = fd;
+       lo_set_int_arg(&argv[0], fd);
 
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_tell,
                                &retval, -1, &result_len, 1, argv, 1);
@@ -560,9 +530,7 @@ lo_tell64(PGconn *conn, int fd)
                return -1;
        }
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = fd;
+       lo_set_int_arg(&argv[0], fd);
 
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_tell64,
                                (void *) &retval, sizeof(retval), &result_len, 
0, argv, 1);
@@ -594,9 +562,7 @@ lo_unlink(PGconn *conn, Oid lobjId)
        if (lo_initialize(conn) < 0)
                return -1;
 
-       argv[0].isint = 1;
-       argv[0].len = 4;
-       argv[0].u.integer = lobjId;
+       lo_set_int_arg(&argv[0], lobjId);
 
        res = PQnfn(conn, conn->lobjfuncs->fn_lo_unlink,
                                &retval, -1, &result_len, 1, argv, 1);
-- 
2.50.1 (Apple Git-155)

Reply via email to