PostgreSQL Source Code  git master
fe-lobj.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/stat.h>
#include "libpq-fe.h"
#include "libpq-int.h"
#include "libpq/libpq-fs.h"
#include "port/pg_bswap.h"
Include dependency graph for fe-lobj.c:

Go to the source code of this file.

Macros

#define LO_BUFSIZE   8192
 

Functions

static int lo_initialize (PGconn *conn)
 
static Oid lo_import_internal (PGconn *conn, const char *filename, Oid oid)
 
static pg_int64 lo_hton64 (pg_int64 host64)
 
static pg_int64 lo_ntoh64 (pg_int64 net64)
 
int lo_open (PGconn *conn, Oid lobjId, int mode)
 
int lo_close (PGconn *conn, int fd)
 
int lo_truncate (PGconn *conn, int fd, size_t len)
 
int lo_truncate64 (PGconn *conn, int fd, pg_int64 len)
 
int lo_read (PGconn *conn, int fd, char *buf, size_t len)
 
int lo_write (PGconn *conn, int fd, const char *buf, size_t len)
 
int lo_lseek (PGconn *conn, int fd, int offset, int whence)
 
pg_int64 lo_lseek64 (PGconn *conn, int fd, pg_int64 offset, int whence)
 
Oid lo_creat (PGconn *conn, int mode)
 
Oid lo_create (PGconn *conn, Oid lobjId)
 
int lo_tell (PGconn *conn, int fd)
 
pg_int64 lo_tell64 (PGconn *conn, int fd)
 
int lo_unlink (PGconn *conn, Oid lobjId)
 
Oid lo_import (PGconn *conn, const char *filename)
 
Oid lo_import_with_oid (PGconn *conn, const char *filename, Oid lobjId)
 
int lo_export (PGconn *conn, Oid lobjId, const char *filename)
 

Macro Definition Documentation

◆ LO_BUFSIZE

#define LO_BUFSIZE   8192

Definition at line 42 of file fe-lobj.c.

Referenced by lo_export(), and lo_import_internal().

Function Documentation

◆ lo_close()

int lo_close ( PGconn conn,
int  fd 
)

Definition at line 99 of file fe-lobj.c.

References fd(), pgLobjfuncs::fn_lo_close, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

Referenced by dumpBlobs(), EndRestoreBlob(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), and pickout().

100 {
101  PQArgBlock argv[1];
102  PGresult *res;
103  int retval;
104  int result_len;
105 
106  if (conn == NULL || conn->lobjfuncs == NULL)
107  {
108  if (lo_initialize(conn) < 0)
109  return -1;
110  }
111 
112  argv[0].isint = 1;
113  argv[0].len = 4;
114  argv[0].u.integer = fd;
115  res = PQfn(conn, conn->lobjfuncs->fn_lo_close,
116  &retval, &result_len, 1, argv, 1);
117  if (PQresultStatus(res) == PGRES_COMMAND_OK)
118  {
119  PQclear(res);
120  return retval;
121  }
122  else
123  {
124  PQclear(res);
125  return -1;
126  }
127 }
union PQArgBlock::@139 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
void PQclear(PGresult *res)
Definition: fe-exec.c:671
Oid fn_lo_close
Definition: libpq-int.h:268
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_creat()

Oid lo_creat ( PGconn conn,
int  mode 
)

Definition at line 465 of file fe-lobj.c.

References pgLobjfuncs::fn_lo_creat, PQArgBlock::integer, InvalidOid, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

Referenced by importFile(), and lo_import_internal().

466 {
467  PQArgBlock argv[1];
468  PGresult *res;
469  int retval;
470  int result_len;
471 
472  if (conn == NULL || conn->lobjfuncs == NULL)
473  {
474  if (lo_initialize(conn) < 0)
475  return InvalidOid;
476  }
477 
478  argv[0].isint = 1;
479  argv[0].len = 4;
480  argv[0].u.integer = mode;
481  res = PQfn(conn, conn->lobjfuncs->fn_lo_creat,
482  &retval, &result_len, 1, argv, 1);
483  if (PQresultStatus(res) == PGRES_COMMAND_OK)
484  {
485  PQclear(res);
486  return (Oid) retval;
487  }
488  else
489  {
490  PQclear(res);
491  return InvalidOid;
492  }
493 }
union PQArgBlock::@139 u
unsigned int Oid
Definition: postgres_ext.h:31
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
#define InvalidOid
Definition: postgres_ext.h:36
void PQclear(PGresult *res)
Definition: fe-exec.c:671
Oid fn_lo_creat
Definition: libpq-int.h:269
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_create()

Oid lo_create ( PGconn conn,
Oid  lobjId 
)

Definition at line 504 of file fe-lobj.c.

References pg_conn::errorMessage, pgLobjfuncs::fn_lo_create, PQArgBlock::integer, InvalidOid, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

Referenced by lo_import_internal(), and StartRestoreBlob().

505 {
506  PQArgBlock argv[1];
507  PGresult *res;
508  int retval;
509  int result_len;
510 
511  if (conn == NULL || conn->lobjfuncs == NULL)
512  {
513  if (lo_initialize(conn) < 0)
514  return InvalidOid;
515  }
516 
517  /* Must check this on-the-fly because it's not there pre-8.1 */
518  if (conn->lobjfuncs->fn_lo_create == 0)
519  {
521  libpq_gettext("cannot determine OID of function lo_create\n"));
522  return InvalidOid;
523  }
524 
525  argv[0].isint = 1;
526  argv[0].len = 4;
527  argv[0].u.integer = lobjId;
528  res = PQfn(conn, conn->lobjfuncs->fn_lo_create,
529  &retval, &result_len, 1, argv, 1);
530  if (PQresultStatus(res) == PGRES_COMMAND_OK)
531  {
532  PQclear(res);
533  return (Oid) retval;
534  }
535  else
536  {
537  PQclear(res);
538  return InvalidOid;
539  }
540 }
union PQArgBlock::@139 u
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
Oid fn_lo_create
Definition: libpq-int.h:270
unsigned int Oid
Definition: postgres_ext.h:31
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
PQExpBufferData errorMessage
Definition: libpq-int.h:493
#define InvalidOid
Definition: postgres_ext.h:36
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
#define libpq_gettext(x)
Definition: libpq-int.h:685
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_export()

int lo_export ( PGconn conn,
Oid  lobjId,
const char *  filename 
)

Definition at line 784 of file fe-lobj.c.

References buf, close, pg_conn::errorMessage, fd(), INV_READ, libpq_gettext, LO_BUFSIZE, lo_close(), lo_open(), lo_read(), PG_BINARY, pqStrerror(), printfPQExpBuffer(), and write.

Referenced by do_lo_export(), and main().

785 {
786  int result = 1;
787  int fd;
788  int nbytes,
789  tmp;
790  char buf[LO_BUFSIZE];
791  int lobj;
792  char sebuf[256];
793 
794  /*
795  * open the large object.
796  */
797  lobj = lo_open(conn, lobjId, INV_READ);
798  if (lobj == -1)
799  {
800  /* we assume lo_open() already set a suitable error message */
801  return -1;
802  }
803 
804  /*
805  * create the file to be written to
806  */
807  fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
808  if (fd < 0)
809  {
810  /* We must do lo_close before setting the errorMessage */
811  int save_errno = errno;
812 
813  (void) lo_close(conn, lobj);
815  libpq_gettext("could not open file \"%s\": %s\n"),
816  filename,
817  pqStrerror(save_errno, sebuf, sizeof(sebuf)));
818  return -1;
819  }
820 
821  /*
822  * read in from the large object and write to the file
823  */
824  while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0)
825  {
826  tmp = write(fd, buf, nbytes);
827  if (tmp != nbytes)
828  {
829  /* We must do lo_close before setting the errorMessage */
830  int save_errno = errno;
831 
832  (void) lo_close(conn, lobj);
833  (void) close(fd);
835  libpq_gettext("could not write to file \"%s\": %s\n"),
836  filename,
837  pqStrerror(save_errno, sebuf, sizeof(sebuf)));
838  return -1;
839  }
840  }
841 
842  /*
843  * If lo_read() failed, we are now in an aborted transaction so there's no
844  * need for lo_close(); furthermore, if we tried it we'd overwrite the
845  * useful error result with a useless one. So skip lo_close() if we got a
846  * failure result.
847  */
848  if (nbytes < 0 ||
849  lo_close(conn, lobj) != 0)
850  {
851  /* assume lo_read() or lo_close() left a suitable error message */
852  result = -1;
853  }
854 
855  /* if we already failed, don't overwrite that msg with a close error */
856  if (close(fd) && result >= 0)
857  {
859  libpq_gettext("could not write to file \"%s\": %s\n"),
860  filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
861  result = -1;
862  }
863 
864  return result;
865 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define write(a, b, c)
Definition: win32.h:14
char * pqStrerror(int errnum, char *strerrbuf, size_t buflen)
Definition: thread.c:61
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1035
#define INV_READ
Definition: libpq-fs.h:22
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:99
static char * buf
Definition: pg_test_fsync.c:67
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
PQExpBufferData errorMessage
Definition: libpq-int.h:493
#define LO_BUFSIZE
Definition: fe-lobj.c:42
static char * filename
Definition: pg_dumpall.c:90
int lo_read(PGconn *conn, int fd, char *buf, size_t len)
Definition: fe-lobj.c:258
#define close(a)
Definition: win32.h:12
#define libpq_gettext(x)
Definition: libpq-int.h:685

◆ lo_hton64()

static pg_int64 lo_hton64 ( pg_int64  host64)
static

Definition at line 1061 of file fe-lobj.c.

References pg_hton32, and swap.

Referenced by lo_lseek64(), and lo_truncate64().

1062 {
1063  union
1064  {
1065  pg_int64 i64;
1066  uint32 i32[2];
1067  } swap;
1068  uint32 t;
1069 
1070  /* High order half first, since we're doing MSB-first */
1071  t = (uint32) (host64 >> 32);
1072  swap.i32[0] = pg_hton32(t);
1073 
1074  /* Now the low order half */
1075  t = (uint32) host64;
1076  swap.i32[1] = pg_hton32(t);
1077 
1078  return swap.i64;
1079 }
#define swap(a, b)
Definition: qsort.c:94
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47
#define pg_hton32(x)
Definition: pg_bswap.h:121
unsigned int uint32
Definition: c.h:306

◆ lo_import()

Oid lo_import ( PGconn conn,
const char *  filename 
)

Definition at line 668 of file fe-lobj.c.

References InvalidOid, and lo_import_internal().

Referenced by do_lo_import(), and main().

669 {
670  return lo_import_internal(conn, filename, InvalidOid);
671 }
static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid)
Definition: fe-lobj.c:689
#define InvalidOid
Definition: postgres_ext.h:36
static char * filename
Definition: pg_dumpall.c:90

◆ lo_import_internal()

static Oid lo_import_internal ( PGconn conn,
const char *  filename,
Oid  oid 
)
static

Definition at line 689 of file fe-lobj.c.

References buf, close, pg_conn::errorMessage, fd(), INV_READ, INV_WRITE, InvalidOid, libpq_gettext, LO_BUFSIZE, lo_close(), lo_creat(), lo_create(), lo_open(), lo_write(), PG_BINARY, pqStrerror(), printfPQExpBuffer(), and read.

Referenced by lo_import(), and lo_import_with_oid().

690 {
691  int fd;
692  int nbytes,
693  tmp;
694  char buf[LO_BUFSIZE];
695  Oid lobjOid;
696  int lobj;
697  char sebuf[256];
698 
699  /*
700  * open the file to be read in
701  */
702  fd = open(filename, O_RDONLY | PG_BINARY, 0666);
703  if (fd < 0)
704  { /* error */
706  libpq_gettext("could not open file \"%s\": %s\n"),
707  filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
708  return InvalidOid;
709  }
710 
711  /*
712  * create an inversion object
713  */
714  if (oid == InvalidOid)
715  lobjOid = lo_creat(conn, INV_READ | INV_WRITE);
716  else
717  lobjOid = lo_create(conn, oid);
718 
719  if (lobjOid == InvalidOid)
720  {
721  /* we assume lo_create() already set a suitable error message */
722  (void) close(fd);
723  return InvalidOid;
724  }
725 
726  lobj = lo_open(conn, lobjOid, INV_WRITE);
727  if (lobj == -1)
728  {
729  /* we assume lo_open() already set a suitable error message */
730  (void) close(fd);
731  return InvalidOid;
732  }
733 
734  /*
735  * read in from the file and write to the large object
736  */
737  while ((nbytes = read(fd, buf, LO_BUFSIZE)) > 0)
738  {
739  tmp = lo_write(conn, lobj, buf, nbytes);
740  if (tmp != nbytes)
741  {
742  /*
743  * If lo_write() failed, we are now in an aborted transaction so
744  * there's no need for lo_close(); furthermore, if we tried it
745  * we'd overwrite the useful error result with a useless one. So
746  * just nail the doors shut and get out of town.
747  */
748  (void) close(fd);
749  return InvalidOid;
750  }
751  }
752 
753  if (nbytes < 0)
754  {
755  /* We must do lo_close before setting the errorMessage */
756  int save_errno = errno;
757 
758  (void) lo_close(conn, lobj);
759  (void) close(fd);
761  libpq_gettext("could not read from file \"%s\": %s\n"),
762  filename,
763  pqStrerror(save_errno, sebuf, sizeof(sebuf)));
764  return InvalidOid;
765  }
766 
767  (void) close(fd);
768 
769  if (lo_close(conn, lobj) != 0)
770  {
771  /* we assume lo_close() already set a suitable error message */
772  return InvalidOid;
773  }
774 
775  return lobjOid;
776 }
int lo_write(PGconn *conn, int fd, const char *buf, size_t len)
Definition: fe-lobj.c:312
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * pqStrerror(int errnum, char *strerrbuf, size_t buflen)
Definition: thread.c:61
unsigned int Oid
Definition: postgres_ext.h:31
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1035
#define INV_READ
Definition: libpq-fs.h:22
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:99
static char * buf
Definition: pg_test_fsync.c:67
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
PQExpBufferData errorMessage
Definition: libpq-int.h:493
#define InvalidOid
Definition: postgres_ext.h:36
Oid lo_create(PGconn *conn, Oid lobjId)
Definition: fe-lobj.c:504
#define LO_BUFSIZE
Definition: fe-lobj.c:42
#define INV_WRITE
Definition: libpq-fs.h:21
Oid lo_creat(PGconn *conn, int mode)
Definition: fe-lobj.c:465
static char * filename
Definition: pg_dumpall.c:90
#define close(a)
Definition: win32.h:12
#define read(a, b, c)
Definition: win32.h:13
#define libpq_gettext(x)
Definition: libpq-int.h:685

◆ lo_import_with_oid()

Oid lo_import_with_oid ( PGconn conn,
const char *  filename,
Oid  lobjId 
)

Definition at line 683 of file fe-lobj.c.

References lo_import_internal().

684 {
685  return lo_import_internal(conn, filename, lobjId);
686 }
static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid)
Definition: fe-lobj.c:689
static char * filename
Definition: pg_dumpall.c:90

◆ lo_initialize()

static int lo_initialize ( PGconn conn)
static

Definition at line 876 of file fe-lobj.c.

References pg_conn::errorMessage, free, libpq_gettext, pg_conn::lobjfuncs, malloc, MemSet, PGRES_TUPLES_OK, PQclear(), PQexec(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), pg_result::resultStatus, and pg_conn::sversion.

Referenced by lo_close(), lo_creat(), lo_create(), lo_lseek(), lo_lseek64(), lo_open(), lo_read(), lo_tell(), lo_tell64(), lo_truncate(), lo_truncate64(), lo_unlink(), and lo_write().

877 {
878  PGresult *res;
879  PGlobjfuncs *lobjfuncs;
880  int n;
881  const char *query;
882  const char *fname;
883  Oid foid;
884 
885  if (!conn)
886  return -1;
887 
888  /*
889  * Allocate the structure to hold the functions OID's
890  */
891  lobjfuncs = (PGlobjfuncs *) malloc(sizeof(PGlobjfuncs));
892  if (lobjfuncs == NULL)
893  {
895  libpq_gettext("out of memory\n"));
896  return -1;
897  }
898  MemSet((char *) lobjfuncs, 0, sizeof(PGlobjfuncs));
899 
900  /*
901  * Execute the query to get all the functions at once. In 7.3 and later
902  * we need to be schema-safe. lo_create only exists in 8.1 and up.
903  * lo_truncate only exists in 8.3 and up.
904  */
905  if (conn->sversion >= 70300)
906  query = "select proname, oid from pg_catalog.pg_proc "
907  "where proname in ("
908  "'lo_open', "
909  "'lo_close', "
910  "'lo_creat', "
911  "'lo_create', "
912  "'lo_unlink', "
913  "'lo_lseek', "
914  "'lo_lseek64', "
915  "'lo_tell', "
916  "'lo_tell64', "
917  "'lo_truncate', "
918  "'lo_truncate64', "
919  "'loread', "
920  "'lowrite') "
921  "and pronamespace = (select oid from pg_catalog.pg_namespace "
922  "where nspname = 'pg_catalog')";
923  else
924  query = "select proname, oid from pg_proc "
925  "where proname = 'lo_open' "
926  "or proname = 'lo_close' "
927  "or proname = 'lo_creat' "
928  "or proname = 'lo_unlink' "
929  "or proname = 'lo_lseek' "
930  "or proname = 'lo_tell' "
931  "or proname = 'loread' "
932  "or proname = 'lowrite'";
933 
934  res = PQexec(conn, query);
935  if (res == NULL)
936  {
937  free(lobjfuncs);
938  return -1;
939  }
940 
941  if (res->resultStatus != PGRES_TUPLES_OK)
942  {
943  free(lobjfuncs);
944  PQclear(res);
946  libpq_gettext("query to initialize large object functions did not return data\n"));
947  return -1;
948  }
949 
950  /*
951  * Examine the result and put the OID's into the struct
952  */
953  for (n = 0; n < PQntuples(res); n++)
954  {
955  fname = PQgetvalue(res, n, 0);
956  foid = (Oid) atoi(PQgetvalue(res, n, 1));
957  if (strcmp(fname, "lo_open") == 0)
958  lobjfuncs->fn_lo_open = foid;
959  else if (strcmp(fname, "lo_close") == 0)
960  lobjfuncs->fn_lo_close = foid;
961  else if (strcmp(fname, "lo_creat") == 0)
962  lobjfuncs->fn_lo_creat = foid;
963  else if (strcmp(fname, "lo_create") == 0)
964  lobjfuncs->fn_lo_create = foid;
965  else if (strcmp(fname, "lo_unlink") == 0)
966  lobjfuncs->fn_lo_unlink = foid;
967  else if (strcmp(fname, "lo_lseek") == 0)
968  lobjfuncs->fn_lo_lseek = foid;
969  else if (strcmp(fname, "lo_lseek64") == 0)
970  lobjfuncs->fn_lo_lseek64 = foid;
971  else if (strcmp(fname, "lo_tell") == 0)
972  lobjfuncs->fn_lo_tell = foid;
973  else if (strcmp(fname, "lo_tell64") == 0)
974  lobjfuncs->fn_lo_tell64 = foid;
975  else if (strcmp(fname, "lo_truncate") == 0)
976  lobjfuncs->fn_lo_truncate = foid;
977  else if (strcmp(fname, "lo_truncate64") == 0)
978  lobjfuncs->fn_lo_truncate64 = foid;
979  else if (strcmp(fname, "loread") == 0)
980  lobjfuncs->fn_lo_read = foid;
981  else if (strcmp(fname, "lowrite") == 0)
982  lobjfuncs->fn_lo_write = foid;
983  }
984 
985  PQclear(res);
986 
987  /*
988  * Finally check that we got all required large object interface functions
989  * (ones that have been added later than the stone age are instead checked
990  * only if used)
991  */
992  if (lobjfuncs->fn_lo_open == 0)
993  {
995  libpq_gettext("cannot determine OID of function lo_open\n"));
996  free(lobjfuncs);
997  return -1;
998  }
999  if (lobjfuncs->fn_lo_close == 0)
1000  {
1002  libpq_gettext("cannot determine OID of function lo_close\n"));
1003  free(lobjfuncs);
1004  return -1;
1005  }
1006  if (lobjfuncs->fn_lo_creat == 0)
1007  {
1009  libpq_gettext("cannot determine OID of function lo_creat\n"));
1010  free(lobjfuncs);
1011  return -1;
1012  }
1013  if (lobjfuncs->fn_lo_unlink == 0)
1014  {
1016  libpq_gettext("cannot determine OID of function lo_unlink\n"));
1017  free(lobjfuncs);
1018  return -1;
1019  }
1020  if (lobjfuncs->fn_lo_lseek == 0)
1021  {
1023  libpq_gettext("cannot determine OID of function lo_lseek\n"));
1024  free(lobjfuncs);
1025  return -1;
1026  }
1027  if (lobjfuncs->fn_lo_tell == 0)
1028  {
1030  libpq_gettext("cannot determine OID of function lo_tell\n"));
1031  free(lobjfuncs);
1032  return -1;
1033  }
1034  if (lobjfuncs->fn_lo_read == 0)
1035  {
1037  libpq_gettext("cannot determine OID of function loread\n"));
1038  free(lobjfuncs);
1039  return -1;
1040  }
1041  if (lobjfuncs->fn_lo_write == 0)
1042  {
1044  libpq_gettext("cannot determine OID of function lowrite\n"));
1045  free(lobjfuncs);
1046  return -1;
1047  }
1048 
1049  /*
1050  * Put the structure into the connection control
1051  */
1052  conn->lobjfuncs = lobjfuncs;
1053  return 0;
1054 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3118
#define MemSet(start, val, len)
Definition: c.h:863
unsigned int Oid
Definition: postgres_ext.h:31
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2724
#define malloc(a)
Definition: header.h:50
int sversion
Definition: libpq-int.h:405
PQExpBufferData errorMessage
Definition: libpq-int.h:493
void PQclear(PGresult *res)
Definition: fe-exec.c:671
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
ExecStatusType resultStatus
Definition: libpq-int.h:177
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
#define libpq_gettext(x)
Definition: libpq-int.h:685

◆ lo_lseek()

int lo_lseek ( PGconn conn,
int  fd,
int  offset,
int  whence 
)

Definition at line 365 of file fe-lobj.c.

References fd(), pgLobjfuncs::fn_lo_lseek, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

Referenced by overwrite(), and pickout().

366 {
367  PQArgBlock argv[3];
368  PGresult *res;
369  int retval;
370  int result_len;
371 
372  if (conn == NULL || conn->lobjfuncs == NULL)
373  {
374  if (lo_initialize(conn) < 0)
375  return -1;
376  }
377 
378  argv[0].isint = 1;
379  argv[0].len = 4;
380  argv[0].u.integer = fd;
381 
382  argv[1].isint = 1;
383  argv[1].len = 4;
384  argv[1].u.integer = offset;
385 
386  argv[2].isint = 1;
387  argv[2].len = 4;
388  argv[2].u.integer = whence;
389 
390  res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek,
391  &retval, &result_len, 1, argv, 3);
392  if (PQresultStatus(res) == PGRES_COMMAND_OK)
393  {
394  PQclear(res);
395  return retval;
396  }
397  else
398  {
399  PQclear(res);
400  return -1;
401  }
402 }
union PQArgBlock::@139 u
Oid fn_lo_lseek
Definition: libpq-int.h:272
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_lseek64()

pg_int64 lo_lseek64 ( PGconn conn,
int  fd,
pg_int64  offset,
int  whence 
)

Definition at line 409 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_lseek64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_hton64(), lo_initialize(), lo_ntoh64(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), PQArgBlock::ptr, and PQArgBlock::u.

Referenced by overwrite(), and pickout().

410 {
411  PQArgBlock argv[3];
412  PGresult *res;
413  pg_int64 retval;
414  int result_len;
415 
416  if (conn == NULL || conn->lobjfuncs == NULL)
417  {
418  if (lo_initialize(conn) < 0)
419  return -1;
420  }
421 
422  if (conn->lobjfuncs->fn_lo_lseek64 == 0)
423  {
425  libpq_gettext("cannot determine OID of function lo_lseek64\n"));
426  return -1;
427  }
428 
429  argv[0].isint = 1;
430  argv[0].len = 4;
431  argv[0].u.integer = fd;
432 
433  offset = lo_hton64(offset);
434  argv[1].isint = 0;
435  argv[1].len = 8;
436  argv[1].u.ptr = (int *) &offset;
437 
438  argv[2].isint = 1;
439  argv[2].len = 4;
440  argv[2].u.integer = whence;
441 
442  res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek64,
443  (void *) &retval, &result_len, 0, argv, 3);
444  if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
445  {
446  PQclear(res);
447  return lo_ntoh64(retval);
448  }
449  else
450  {
451  PQclear(res);
452  return -1;
453  }
454 }
union PQArgBlock::@139 u
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47
static pg_int64 lo_hton64(pg_int64 host64)
Definition: fe-lobj.c:1061
PQExpBufferData errorMessage
Definition: libpq-int.h:493
void PQclear(PGresult *res)
Definition: fe-exec.c:671
Oid fn_lo_lseek64
Definition: libpq-int.h:273
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
int * ptr
Definition: libpq-fe.h:226
#define libpq_gettext(x)
Definition: libpq-int.h:685
int integer
Definition: libpq-fe.h:227
static pg_int64 lo_ntoh64(pg_int64 net64)
Definition: fe-lobj.c:1086
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_ntoh64()

static pg_int64 lo_ntoh64 ( pg_int64  net64)
static

Definition at line 1086 of file fe-lobj.c.

References pg_ntoh32, and swap.

Referenced by lo_lseek64(), and lo_tell64().

1087 {
1088  union
1089  {
1090  pg_int64 i64;
1091  uint32 i32[2];
1092  } swap;
1093  pg_int64 result;
1094 
1095  swap.i64 = net64;
1096 
1097  result = (uint32) pg_ntoh32(swap.i32[0]);
1098  result <<= 32;
1099  result |= (uint32) pg_ntoh32(swap.i32[1]);
1100 
1101  return result;
1102 }
#define swap(a, b)
Definition: qsort.c:94
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47
#define pg_ntoh32(x)
Definition: pg_bswap.h:125
unsigned int uint32
Definition: c.h:306

◆ lo_open()

int lo_open ( PGconn conn,
Oid  lobjId,
int  mode 
)

Definition at line 57 of file fe-lobj.c.

References fd(), pgLobjfuncs::fn_lo_open, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

Referenced by dumpBlobs(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), pickout(), and StartRestoreBlob().

58 {
59  int fd;
60  int result_len;
61  PQArgBlock argv[2];
62  PGresult *res;
63 
64  if (conn == NULL || conn->lobjfuncs == NULL)
65  {
66  if (lo_initialize(conn) < 0)
67  return -1;
68  }
69 
70  argv[0].isint = 1;
71  argv[0].len = 4;
72  argv[0].u.integer = lobjId;
73 
74  argv[1].isint = 1;
75  argv[1].len = 4;
76  argv[1].u.integer = mode;
77 
78  res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2);
79  if (PQresultStatus(res) == PGRES_COMMAND_OK)
80  {
81  PQclear(res);
82  return fd;
83  }
84  else
85  {
86  PQclear(res);
87  return -1;
88  }
89 }
union PQArgBlock::@139 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
Oid fn_lo_open
Definition: libpq-int.h:267
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_read()

int lo_read ( PGconn conn,
int  fd,
char *  buf,
size_t  len 
)

Definition at line 258 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_read, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

Referenced by lo_export().

259 {
260  PQArgBlock argv[2];
261  PGresult *res;
262  int result_len;
263 
264  if (conn == NULL || conn->lobjfuncs == NULL)
265  {
266  if (lo_initialize(conn) < 0)
267  return -1;
268  }
269 
270  /*
271  * Long ago, somebody thought it'd be a good idea to declare this function
272  * as taking size_t ... but the underlying backend function only accepts a
273  * signed int32 length. So throw error if the given value overflows
274  * int32.
275  */
276  if (len > (size_t) INT_MAX)
277  {
279  libpq_gettext("argument of lo_read exceeds integer range\n"));
280  return -1;
281  }
282 
283  argv[0].isint = 1;
284  argv[0].len = 4;
285  argv[0].u.integer = fd;
286 
287  argv[1].isint = 1;
288  argv[1].len = 4;
289  argv[1].u.integer = (int) len;
290 
291  res = PQfn(conn, conn->lobjfuncs->fn_lo_read,
292  (void *) buf, &result_len, 0, argv, 2);
293  if (PQresultStatus(res) == PGRES_COMMAND_OK)
294  {
295  PQclear(res);
296  return result_len;
297  }
298  else
299  {
300  PQclear(res);
301  return -1;
302  }
303 }
union PQArgBlock::@139 u
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
Oid fn_lo_read
Definition: libpq-int.h:278
static char * buf
Definition: pg_test_fsync.c:67
PQExpBufferData errorMessage
Definition: libpq-int.h:493
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
#define libpq_gettext(x)
Definition: libpq-int.h:685
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_tell()

int lo_tell ( PGconn conn,
int  fd 
)

Definition at line 548 of file fe-lobj.c.

References fd(), pgLobjfuncs::fn_lo_tell, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

549 {
550  int retval;
551  PQArgBlock argv[1];
552  PGresult *res;
553  int result_len;
554 
555  if (conn == NULL || conn->lobjfuncs == NULL)
556  {
557  if (lo_initialize(conn) < 0)
558  return -1;
559  }
560 
561  argv[0].isint = 1;
562  argv[0].len = 4;
563  argv[0].u.integer = fd;
564 
565  res = PQfn(conn, conn->lobjfuncs->fn_lo_tell,
566  &retval, &result_len, 1, argv, 1);
567  if (PQresultStatus(res) == PGRES_COMMAND_OK)
568  {
569  PQclear(res);
570  return retval;
571  }
572  else
573  {
574  PQclear(res);
575  return -1;
576  }
577 }
union PQArgBlock::@139 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
Oid fn_lo_tell
Definition: libpq-int.h:274
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_tell64()

pg_int64 lo_tell64 ( PGconn conn,
int  fd 
)

Definition at line 584 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_tell64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), lo_ntoh64(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

Referenced by pickout().

585 {
586  pg_int64 retval;
587  PQArgBlock argv[1];
588  PGresult *res;
589  int result_len;
590 
591  if (conn == NULL || conn->lobjfuncs == NULL)
592  {
593  if (lo_initialize(conn) < 0)
594  return -1;
595  }
596 
597  if (conn->lobjfuncs->fn_lo_tell64 == 0)
598  {
600  libpq_gettext("cannot determine OID of function lo_tell64\n"));
601  return -1;
602  }
603 
604  argv[0].isint = 1;
605  argv[0].len = 4;
606  argv[0].u.integer = fd;
607 
608  res = PQfn(conn, conn->lobjfuncs->fn_lo_tell64,
609  (void *) &retval, &result_len, 0, argv, 1);
610  if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
611  {
612  PQclear(res);
613  return lo_ntoh64(retval);
614  }
615  else
616  {
617  PQclear(res);
618  return -1;
619  }
620 }
union PQArgBlock::@139 u
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47
Oid fn_lo_tell64
Definition: libpq-int.h:275
PQExpBufferData errorMessage
Definition: libpq-int.h:493
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
#define libpq_gettext(x)
Definition: libpq-int.h:685
int integer
Definition: libpq-fe.h:227
static pg_int64 lo_ntoh64(pg_int64 net64)
Definition: fe-lobj.c:1086
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_truncate()

int lo_truncate ( PGconn conn,
int  fd,
size_t  len 
)

Definition at line 137 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_truncate, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), and PQArgBlock::u.

138 {
139  PQArgBlock argv[2];
140  PGresult *res;
141  int retval;
142  int result_len;
143 
144  if (conn == NULL || conn->lobjfuncs == NULL)
145  {
146  if (lo_initialize(conn) < 0)
147  return -1;
148  }
149 
150  /* Must check this on-the-fly because it's not there pre-8.3 */
151  if (conn->lobjfuncs->fn_lo_truncate == 0)
152  {
154  libpq_gettext("cannot determine OID of function lo_truncate\n"));
155  return -1;
156  }
157 
158  /*
159  * Long ago, somebody thought it'd be a good idea to declare this function
160  * as taking size_t ... but the underlying backend function only accepts a
161  * signed int32 length. So throw error if the given value overflows
162  * int32. (A possible alternative is to automatically redirect the call
163  * to lo_truncate64; but if the caller wanted to rely on that backend
164  * function being available, he could have called lo_truncate64 for
165  * himself.)
166  */
167  if (len > (size_t) INT_MAX)
168  {
170  libpq_gettext("argument of lo_truncate exceeds integer range\n"));
171  return -1;
172  }
173 
174  argv[0].isint = 1;
175  argv[0].len = 4;
176  argv[0].u.integer = fd;
177 
178  argv[1].isint = 1;
179  argv[1].len = 4;
180  argv[1].u.integer = (int) len;
181 
182  res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate,
183  &retval, &result_len, 1, argv, 2);
184 
185  if (PQresultStatus(res) == PGRES_COMMAND_OK)
186  {
187  PQclear(res);
188  return retval;
189  }
190  else
191  {
192  PQclear(res);
193  return -1;
194  }
195 }
union PQArgBlock::@139 u
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
Oid fn_lo_truncate
Definition: libpq-int.h:276
PQExpBufferData errorMessage
Definition: libpq-int.h:493
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
#define libpq_gettext(x)
Definition: libpq-int.h:685
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_truncate64()

int lo_truncate64 ( PGconn conn,
int  fd,
pg_int64  len 
)

Definition at line 205 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_truncate64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_hton64(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), PQArgBlock::ptr, and PQArgBlock::u.

Referenced by my_truncate().

206 {
207  PQArgBlock argv[2];
208  PGresult *res;
209  int retval;
210  int result_len;
211 
212  if (conn == NULL || conn->lobjfuncs == NULL)
213  {
214  if (lo_initialize(conn) < 0)
215  return -1;
216  }
217 
218  if (conn->lobjfuncs->fn_lo_truncate64 == 0)
219  {
221  libpq_gettext("cannot determine OID of function lo_truncate64\n"));
222  return -1;
223  }
224 
225  argv[0].isint = 1;
226  argv[0].len = 4;
227  argv[0].u.integer = fd;
228 
229  len = lo_hton64(len);
230  argv[1].isint = 0;
231  argv[1].len = 8;
232  argv[1].u.ptr = (int *) &len;
233 
234  res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate64,
235  &retval, &result_len, 1, argv, 2);
236 
237  if (PQresultStatus(res) == PGRES_COMMAND_OK)
238  {
239  PQclear(res);
240  return retval;
241  }
242  else
243  {
244  PQclear(res);
245  return -1;
246  }
247 }
union PQArgBlock::@139 u
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
static pg_int64 lo_hton64(pg_int64 host64)
Definition: fe-lobj.c:1061
Oid fn_lo_truncate64
Definition: libpq-int.h:277
PQExpBufferData errorMessage
Definition: libpq-int.h:493
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
int * ptr
Definition: libpq-fe.h:226
#define libpq_gettext(x)
Definition: libpq-int.h:685
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_unlink()

int lo_unlink ( PGconn conn,
Oid  lobjId 
)

Definition at line 628 of file fe-lobj.c.

References pgLobjfuncs::fn_lo_unlink, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), and PQArgBlock::u.

Referenced by do_lo_unlink(), and vacuumlo().

629 {
630  PQArgBlock argv[1];
631  PGresult *res;
632  int result_len;
633  int retval;
634 
635  if (conn == NULL || conn->lobjfuncs == NULL)
636  {
637  if (lo_initialize(conn) < 0)
638  return -1;
639  }
640 
641  argv[0].isint = 1;
642  argv[0].len = 4;
643  argv[0].u.integer = lobjId;
644 
645  res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink,
646  &retval, &result_len, 1, argv, 1);
647  if (PQresultStatus(res) == PGRES_COMMAND_OK)
648  {
649  PQclear(res);
650  return retval;
651  }
652  else
653  {
654  PQclear(res);
655  return -1;
656  }
657 }
union PQArgBlock::@139 u
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
void PQclear(PGresult *res)
Definition: fe-exec.c:671
Oid fn_lo_unlink
Definition: libpq-int.h:271
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876

◆ lo_write()

int lo_write ( PGconn conn,
int  fd,
const char *  buf,
size_t  len 
)

Definition at line 312 of file fe-lobj.c.

References pg_conn::errorMessage, fd(), pgLobjfuncs::fn_lo_write, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_gettext, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), printfPQExpBuffer(), PQArgBlock::ptr, and PQArgBlock::u.

Referenced by lo_import_internal().

313 {
314  PQArgBlock argv[2];
315  PGresult *res;
316  int result_len;
317  int retval;
318 
319  if (conn == NULL || conn->lobjfuncs == NULL)
320  {
321  if (lo_initialize(conn) < 0)
322  return -1;
323  }
324 
325  /*
326  * Long ago, somebody thought it'd be a good idea to declare this function
327  * as taking size_t ... but the underlying backend function only accepts a
328  * signed int32 length. So throw error if the given value overflows
329  * int32.
330  */
331  if (len > (size_t) INT_MAX)
332  {
334  libpq_gettext("argument of lo_write exceeds integer range\n"));
335  return -1;
336  }
337 
338  argv[0].isint = 1;
339  argv[0].len = 4;
340  argv[0].u.integer = fd;
341 
342  argv[1].isint = 0;
343  argv[1].len = (int) len;
344  argv[1].u.ptr = (int *) buf;
345 
346  res = PQfn(conn, conn->lobjfuncs->fn_lo_write,
347  &retval, &result_len, 1, argv, 2);
348  if (PQresultStatus(res) == PGRES_COMMAND_OK)
349  {
350  PQclear(res);
351  return retval;
352  }
353  else
354  {
355  PQclear(res);
356  return -1;
357  }
358 }
union PQArgBlock::@139 u
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
Oid fn_lo_write
Definition: libpq-int.h:279
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2607
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
static char * buf
Definition: pg_test_fsync.c:67
PQExpBufferData errorMessage
Definition: libpq-int.h:493
void PQclear(PGresult *res)
Definition: fe-exec.c:671
int isint
Definition: libpq-fe.h:223
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:426
int * ptr
Definition: libpq-fe.h:226
#define libpq_gettext(x)
Definition: libpq-int.h:685
int integer
Definition: libpq-fe.h:227
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:876