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 96 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().

97 {
98  PQArgBlock argv[1];
99  PGresult *res;
100  int retval;
101  int result_len;
102 
103  if (lo_initialize(conn) < 0)
104  return -1;
105 
106  argv[0].isint = 1;
107  argv[0].len = 4;
108  argv[0].u.integer = fd;
109  res = PQfn(conn, conn->lobjfuncs->fn_lo_close,
110  &retval, &result_len, 1, argv, 1);
111  if (PQresultStatus(res) == PGRES_COMMAND_OK)
112  {
113  PQclear(res);
114  return retval;
115  }
116  else
117  {
118  PQclear(res);
119  return -1;
120  }
121 }
union PQArgBlock::@161 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:2783
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
void PQclear(PGresult *res)
Definition: fe-exec.c:680
Oid fn_lo_close
Definition: libpq-int.h:270
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_creat()

Oid lo_creat ( PGconn conn,
int  mode 
)

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

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

Referenced by importFile(), and lo_import_internal().

445 {
446  PQArgBlock argv[1];
447  PGresult *res;
448  int retval;
449  int result_len;
450 
451  if (lo_initialize(conn) < 0)
452  return InvalidOid;
453 
454  argv[0].isint = 1;
455  argv[0].len = 4;
456  argv[0].u.integer = mode;
457  res = PQfn(conn, conn->lobjfuncs->fn_lo_creat,
458  &retval, &result_len, 1, argv, 1);
459  if (PQresultStatus(res) == PGRES_COMMAND_OK)
460  {
461  PQclear(res);
462  return (Oid) retval;
463  }
464  else
465  {
466  PQclear(res);
467  return InvalidOid;
468  }
469 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
union PQArgBlock::@161 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:2783
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
#define InvalidOid
Definition: postgres_ext.h:36
void PQclear(PGresult *res)
Definition: fe-exec.c:680
Oid fn_lo_creat
Definition: libpq-int.h:271
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_create()

Oid lo_create ( PGconn conn,
Oid  lobjId 
)

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

References appendPQExpBuffer(), 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(), and PQArgBlock::u.

Referenced by lo_import_internal(), and StartRestoreBlob().

481 {
482  PQArgBlock argv[1];
483  PGresult *res;
484  int retval;
485  int result_len;
486 
487  if (lo_initialize(conn) < 0)
488  return InvalidOid;
489 
490  /* Must check this on-the-fly because it's not there pre-8.1 */
491  if (conn->lobjfuncs->fn_lo_create == 0)
492  {
494  libpq_gettext("cannot determine OID of function %s\n"),
495  "lo_create");
496  return InvalidOid;
497  }
498 
499  argv[0].isint = 1;
500  argv[0].len = 4;
501  argv[0].u.integer = lobjId;
502  res = PQfn(conn, conn->lobjfuncs->fn_lo_create,
503  &retval, &result_len, 1, argv, 1);
504  if (PQresultStatus(res) == PGRES_COMMAND_OK)
505  {
506  PQclear(res);
507  return (Oid) retval;
508  }
509  else
510  {
511  PQclear(res);
512  return InvalidOid;
513  }
514 }
union PQArgBlock::@161 u
Oid fn_lo_create
Definition: libpq-int.h:272
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:2783
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
PQExpBufferData errorMessage
Definition: libpq-int.h:569
#define InvalidOid
Definition: postgres_ext.h:36
void PQclear(PGresult *res)
Definition: fe-exec.c:680
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
#define libpq_gettext(x)
Definition: libpq-int.h:846
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_export()

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

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

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

Referenced by do_lo_export(), and main().

758 {
759  int result = 1;
760  int fd;
761  int nbytes,
762  tmp;
763  char buf[LO_BUFSIZE];
764  int lobj;
765  char sebuf[PG_STRERROR_R_BUFLEN];
766 
767  /*
768  * open the large object.
769  */
770  lobj = lo_open(conn, lobjId, INV_READ);
771  if (lobj == -1)
772  {
773  /* we assume lo_open() already set a suitable error message */
774  return -1;
775  }
776 
777  /*
778  * create the file to be written to
779  */
780  fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
781  if (fd < 0)
782  {
783  /* We must do lo_close before setting the errorMessage */
784  int save_errno = errno;
785 
786  (void) lo_close(conn, lobj);
787  /* deliberately overwrite any error from lo_close */
789  libpq_gettext("could not open file \"%s\": %s\n"),
790  filename,
791  strerror_r(save_errno, sebuf, sizeof(sebuf)));
792  return -1;
793  }
794 
795  /*
796  * read in from the large object and write to the file
797  */
798  while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0)
799  {
800  tmp = write(fd, buf, nbytes);
801  if (tmp != nbytes)
802  {
803  /* We must do lo_close before setting the errorMessage */
804  int save_errno = errno;
805 
806  (void) lo_close(conn, lobj);
807  (void) close(fd);
808  /* deliberately overwrite any error from lo_close */
810  libpq_gettext("could not write to file \"%s\": %s\n"),
811  filename,
812  strerror_r(save_errno, sebuf, sizeof(sebuf)));
813  return -1;
814  }
815  }
816 
817  /*
818  * If lo_read() failed, we are now in an aborted transaction so there's no
819  * need for lo_close(); furthermore, if we tried it we'd overwrite the
820  * useful error result with a useless one. So skip lo_close() if we got a
821  * failure result.
822  */
823  if (nbytes < 0 ||
824  lo_close(conn, lobj) != 0)
825  {
826  /* assume lo_read() or lo_close() left a suitable error message */
827  result = -1;
828  }
829 
830  /* if we already failed, don't overwrite that msg with a close error */
831  if (close(fd) != 0 && result >= 0)
832  {
834  libpq_gettext("could not write to file \"%s\": %s\n"),
835  filename, strerror_r(errno, sebuf, sizeof(sebuf)));
836  result = -1;
837  }
838 
839  return result;
840 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
#define write(a, b, c)
Definition: win32.h:14
#define PG_STRERROR_R_BUFLEN
Definition: port.h:234
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1271
#define INV_READ
Definition: libpq-fs.h:22
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:96
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
static char * buf
Definition: pg_test_fsync.c:68
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
PQExpBufferData errorMessage
Definition: libpq-int.h:569
#define LO_BUFSIZE
Definition: fe-lobj.c:42
#define strerror_r
Definition: port.h:233
static char * filename
Definition: pg_dumpall.c:91
int lo_read(PGconn *conn, int fd, char *buf, size_t len)
Definition: fe-lobj.c:248
#define close(a)
Definition: win32.h:12
#define libpq_gettext(x)
Definition: libpq-int.h:846

◆ lo_hton64()

static pg_int64 lo_hton64 ( pg_int64  host64)
static

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

References pg_hton32.

Referenced by lo_lseek64(), and lo_truncate64().

1044 {
1045  union
1046  {
1047  pg_int64 i64;
1048  uint32 i32[2];
1049  } swap;
1050  uint32 t;
1051 
1052  /* High order half first, since we're doing MSB-first */
1053  t = (uint32) (host64 >> 32);
1054  swap.i32[0] = pg_hton32(t);
1055 
1056  /* Now the low order half */
1057  t = (uint32) host64;
1058  swap.i32[1] = pg_hton32(t);
1059 
1060  return swap.i64;
1061 }
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:441

◆ lo_import()

Oid lo_import ( PGconn conn,
const char *  filename 
)

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

References InvalidOid, and lo_import_internal().

Referenced by do_lo_import(), and main().

635 {
636  return lo_import_internal(conn, filename, InvalidOid);
637 }
static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid)
Definition: fe-lobj.c:655
#define InvalidOid
Definition: postgres_ext.h:36
static char * filename
Definition: pg_dumpall.c:91

◆ lo_import_internal()

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

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

References appendPQExpBuffer(), 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, PG_STRERROR_R_BUFLEN, printfPQExpBuffer(), read, resetPQExpBuffer(), and strerror_r.

Referenced by lo_import(), and lo_import_with_oid().

656 {
657  int fd;
658  int nbytes,
659  tmp;
660  char buf[LO_BUFSIZE];
661  Oid lobjOid;
662  int lobj;
663  char sebuf[PG_STRERROR_R_BUFLEN];
664 
665  if (conn == NULL)
666  return InvalidOid;
667 
668  /* Since this is the beginning of a query cycle, reset the error buffer */
670 
671  /*
672  * open the file to be read in
673  */
674  fd = open(filename, O_RDONLY | PG_BINARY, 0666);
675  if (fd < 0)
676  { /* error */
678  libpq_gettext("could not open file \"%s\": %s\n"),
679  filename, strerror_r(errno, sebuf, sizeof(sebuf)));
680  return InvalidOid;
681  }
682 
683  /*
684  * create an inversion object
685  */
686  if (oid == InvalidOid)
687  lobjOid = lo_creat(conn, INV_READ | INV_WRITE);
688  else
689  lobjOid = lo_create(conn, oid);
690 
691  if (lobjOid == InvalidOid)
692  {
693  /* we assume lo_create() already set a suitable error message */
694  (void) close(fd);
695  return InvalidOid;
696  }
697 
698  lobj = lo_open(conn, lobjOid, INV_WRITE);
699  if (lobj == -1)
700  {
701  /* we assume lo_open() already set a suitable error message */
702  (void) close(fd);
703  return InvalidOid;
704  }
705 
706  /*
707  * read in from the file and write to the large object
708  */
709  while ((nbytes = read(fd, buf, LO_BUFSIZE)) > 0)
710  {
711  tmp = lo_write(conn, lobj, buf, nbytes);
712  if (tmp != nbytes)
713  {
714  /*
715  * If lo_write() failed, we are now in an aborted transaction so
716  * there's no need for lo_close(); furthermore, if we tried it
717  * we'd overwrite the useful error result with a useless one. So
718  * just nail the doors shut and get out of town.
719  */
720  (void) close(fd);
721  return InvalidOid;
722  }
723  }
724 
725  if (nbytes < 0)
726  {
727  /* We must do lo_close before setting the errorMessage */
728  int save_errno = errno;
729 
730  (void) lo_close(conn, lobj);
731  (void) close(fd);
732  /* deliberately overwrite any error from lo_close */
734  libpq_gettext("could not read from file \"%s\": %s\n"),
735  filename,
736  strerror_r(save_errno, sebuf, sizeof(sebuf)));
737  return InvalidOid;
738  }
739 
740  (void) close(fd);
741 
742  if (lo_close(conn, lobj) != 0)
743  {
744  /* we assume lo_close() already set a suitable error message */
745  return InvalidOid;
746  }
747 
748  return lobjOid;
749 }
int lo_write(PGconn *conn, int fd, const char *buf, size_t len)
Definition: fe-lobj.c:299
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
#define PG_STRERROR_R_BUFLEN
Definition: port.h:234
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:1271
#define INV_READ
Definition: libpq-fs.h:22
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:96
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
static char * buf
Definition: pg_test_fsync.c:68
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
PQExpBufferData errorMessage
Definition: libpq-int.h:569
#define InvalidOid
Definition: postgres_ext.h:36
Oid lo_create(PGconn *conn, Oid lobjId)
Definition: fe-lobj.c:480
#define LO_BUFSIZE
Definition: fe-lobj.c:42
#define strerror_r
Definition: port.h:233
#define INV_WRITE
Definition: libpq-fs.h:21
Oid lo_creat(PGconn *conn, int mode)
Definition: fe-lobj.c:444
static char * filename
Definition: pg_dumpall.c:91
#define close(a)
Definition: win32.h:12
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:148
#define read(a, b, c)
Definition: win32.h:13
#define libpq_gettext(x)
Definition: libpq-int.h:846

◆ lo_import_with_oid()

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

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

References lo_import_internal().

650 {
651  return lo_import_internal(conn, filename, lobjId);
652 }
static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid)
Definition: fe-lobj.c:655
static char * filename
Definition: pg_dumpall.c:91

◆ lo_initialize()

static int lo_initialize ( PGconn conn)
static

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

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

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().

854 {
855  PGresult *res;
856  PGlobjfuncs *lobjfuncs;
857  int n;
858  const char *query;
859  const char *fname;
860  Oid foid;
861 
862  /* Nothing we can do with no connection */
863  if (conn == NULL)
864  return -1;
865 
866  /* Since this is the beginning of a query cycle, reset the error buffer */
868 
869  /* Nothing else to do if we already collected info */
870  if (conn->lobjfuncs != NULL)
871  return 0;
872 
873  /*
874  * Allocate the structure to hold the function OIDs. We don't store it
875  * into the PGconn until it's successfully filled.
876  */
877  lobjfuncs = (PGlobjfuncs *) malloc(sizeof(PGlobjfuncs));
878  if (lobjfuncs == NULL)
879  {
881  libpq_gettext("out of memory\n"));
882  return -1;
883  }
884  MemSet((char *) lobjfuncs, 0, sizeof(PGlobjfuncs));
885 
886  /*
887  * Execute the query to get all the functions at once. (Not all of them
888  * may exist in older server versions.)
889  */
890  query = "select proname, oid from pg_catalog.pg_proc "
891  "where proname in ("
892  "'lo_open', "
893  "'lo_close', "
894  "'lo_creat', "
895  "'lo_create', "
896  "'lo_unlink', "
897  "'lo_lseek', "
898  "'lo_lseek64', "
899  "'lo_tell', "
900  "'lo_tell64', "
901  "'lo_truncate', "
902  "'lo_truncate64', "
903  "'loread', "
904  "'lowrite') "
905  "and pronamespace = (select oid from pg_catalog.pg_namespace "
906  "where nspname = 'pg_catalog')";
907 
908  res = PQexec(conn, query);
909  if (res == NULL)
910  {
911  free(lobjfuncs);
912  return -1;
913  }
914 
915  if (res->resultStatus != PGRES_TUPLES_OK)
916  {
917  free(lobjfuncs);
918  PQclear(res);
920  libpq_gettext("query to initialize large object functions did not return data\n"));
921  return -1;
922  }
923 
924  /*
925  * Examine the result and put the OID's into the struct
926  */
927  for (n = 0; n < PQntuples(res); n++)
928  {
929  fname = PQgetvalue(res, n, 0);
930  foid = (Oid) atoi(PQgetvalue(res, n, 1));
931  if (strcmp(fname, "lo_open") == 0)
932  lobjfuncs->fn_lo_open = foid;
933  else if (strcmp(fname, "lo_close") == 0)
934  lobjfuncs->fn_lo_close = foid;
935  else if (strcmp(fname, "lo_creat") == 0)
936  lobjfuncs->fn_lo_creat = foid;
937  else if (strcmp(fname, "lo_create") == 0)
938  lobjfuncs->fn_lo_create = foid;
939  else if (strcmp(fname, "lo_unlink") == 0)
940  lobjfuncs->fn_lo_unlink = foid;
941  else if (strcmp(fname, "lo_lseek") == 0)
942  lobjfuncs->fn_lo_lseek = foid;
943  else if (strcmp(fname, "lo_lseek64") == 0)
944  lobjfuncs->fn_lo_lseek64 = foid;
945  else if (strcmp(fname, "lo_tell") == 0)
946  lobjfuncs->fn_lo_tell = foid;
947  else if (strcmp(fname, "lo_tell64") == 0)
948  lobjfuncs->fn_lo_tell64 = foid;
949  else if (strcmp(fname, "lo_truncate") == 0)
950  lobjfuncs->fn_lo_truncate = foid;
951  else if (strcmp(fname, "lo_truncate64") == 0)
952  lobjfuncs->fn_lo_truncate64 = foid;
953  else if (strcmp(fname, "loread") == 0)
954  lobjfuncs->fn_lo_read = foid;
955  else if (strcmp(fname, "lowrite") == 0)
956  lobjfuncs->fn_lo_write = foid;
957  }
958 
959  PQclear(res);
960 
961  /*
962  * Finally check that we got all required large object interface functions
963  * (ones that have been added later than the stone age are instead checked
964  * only if used)
965  */
966  if (lobjfuncs->fn_lo_open == 0)
967  {
969  libpq_gettext("cannot determine OID of function %s\n"),
970  "lo_open");
971  free(lobjfuncs);
972  return -1;
973  }
974  if (lobjfuncs->fn_lo_close == 0)
975  {
977  libpq_gettext("cannot determine OID of function %s\n"),
978  "lo_close");
979  free(lobjfuncs);
980  return -1;
981  }
982  if (lobjfuncs->fn_lo_creat == 0)
983  {
985  libpq_gettext("cannot determine OID of function %s\n"),
986  "lo_creat");
987  free(lobjfuncs);
988  return -1;
989  }
990  if (lobjfuncs->fn_lo_unlink == 0)
991  {
993  libpq_gettext("cannot determine OID of function %s\n"),
994  "lo_unlink");
995  free(lobjfuncs);
996  return -1;
997  }
998  if (lobjfuncs->fn_lo_lseek == 0)
999  {
1001  libpq_gettext("cannot determine OID of function %s\n"),
1002  "lo_lseek");
1003  free(lobjfuncs);
1004  return -1;
1005  }
1006  if (lobjfuncs->fn_lo_tell == 0)
1007  {
1009  libpq_gettext("cannot determine OID of function %s\n"),
1010  "lo_tell");
1011  free(lobjfuncs);
1012  return -1;
1013  }
1014  if (lobjfuncs->fn_lo_read == 0)
1015  {
1017  libpq_gettext("cannot determine OID of function %s\n"),
1018  "loread");
1019  free(lobjfuncs);
1020  return -1;
1021  }
1022  if (lobjfuncs->fn_lo_write == 0)
1023  {
1025  libpq_gettext("cannot determine OID of function %s\n"),
1026  "lowrite");
1027  free(lobjfuncs);
1028  return -1;
1029  }
1030 
1031  /*
1032  * Put the structure into the connection control
1033  */
1034  conn->lobjfuncs = lobjfuncs;
1035  return 0;
1036 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3561
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
#define MemSet(start, val, len)
Definition: c.h:1008
unsigned int Oid
Definition: postgres_ext.h:31
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
#define malloc(a)
Definition: header.h:50
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
PQExpBufferData errorMessage
Definition: libpq-int.h:569
void PQclear(PGresult *res)
Definition: fe-exec.c:680
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2142
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:148
ExecStatusType resultStatus
Definition: libpq-int.h:177
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
#define libpq_gettext(x)
Definition: libpq-int.h:846

◆ lo_lseek()

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

Definition at line 349 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().

350 {
351  PQArgBlock argv[3];
352  PGresult *res;
353  int retval;
354  int result_len;
355 
356  if (lo_initialize(conn) < 0)
357  return -1;
358 
359  argv[0].isint = 1;
360  argv[0].len = 4;
361  argv[0].u.integer = fd;
362 
363  argv[1].isint = 1;
364  argv[1].len = 4;
365  argv[1].u.integer = offset;
366 
367  argv[2].isint = 1;
368  argv[2].len = 4;
369  argv[2].u.integer = whence;
370 
371  res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek,
372  &retval, &result_len, 1, argv, 3);
373  if (PQresultStatus(res) == PGRES_COMMAND_OK)
374  {
375  PQclear(res);
376  return retval;
377  }
378  else
379  {
380  PQclear(res);
381  return -1;
382  }
383 }
union PQArgBlock::@161 u
Oid fn_lo_lseek
Definition: libpq-int.h:274
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:2783
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
void PQclear(PGresult *res)
Definition: fe-exec.c:680
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_lseek64()

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

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

References appendPQExpBuffer(), 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(), PQArgBlock::ptr, and PQArgBlock::u.

Referenced by overwrite(), and pickout().

391 {
392  PQArgBlock argv[3];
393  PGresult *res;
394  pg_int64 retval;
395  int result_len;
396 
397  if (lo_initialize(conn) < 0)
398  return -1;
399 
400  if (conn->lobjfuncs->fn_lo_lseek64 == 0)
401  {
403  libpq_gettext("cannot determine OID of function %s\n"),
404  "lo_lseek64");
405  return -1;
406  }
407 
408  argv[0].isint = 1;
409  argv[0].len = 4;
410  argv[0].u.integer = fd;
411 
412  offset = lo_hton64(offset);
413  argv[1].isint = 0;
414  argv[1].len = 8;
415  argv[1].u.ptr = (int *) &offset;
416 
417  argv[2].isint = 1;
418  argv[2].len = 4;
419  argv[2].u.integer = whence;
420 
421  res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek64,
422  (void *) &retval, &result_len, 0, argv, 3);
423  if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
424  {
425  PQclear(res);
426  return lo_ntoh64(retval);
427  }
428  else
429  {
430  PQclear(res);
431  return -1;
432  }
433 }
union PQArgBlock::@161 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:2783
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
static pg_int64 lo_hton64(pg_int64 host64)
Definition: fe-lobj.c:1043
PQExpBufferData errorMessage
Definition: libpq-int.h:569
void PQclear(PGresult *res)
Definition: fe-exec.c:680
Oid fn_lo_lseek64
Definition: libpq-int.h:275
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
int * ptr
Definition: libpq-fe.h:241
#define libpq_gettext(x)
Definition: libpq-int.h:846
int integer
Definition: libpq-fe.h:242
static pg_int64 lo_ntoh64(pg_int64 net64)
Definition: fe-lobj.c:1068
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_ntoh64()

static pg_int64 lo_ntoh64 ( pg_int64  net64)
static

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

References pg_ntoh32.

Referenced by lo_lseek64(), and lo_tell64().

1069 {
1070  union
1071  {
1072  pg_int64 i64;
1073  uint32 i32[2];
1074  } swap;
1075  pg_int64 result;
1076 
1077  swap.i64 = net64;
1078 
1079  result = (uint32) pg_ntoh32(swap.i32[0]);
1080  result <<= 32;
1081  result |= (uint32) pg_ntoh32(swap.i32[1]);
1082 
1083  return result;
1084 }
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:441

◆ 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, mode, 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 (lo_initialize(conn) < 0)
65  return -1;
66 
67  argv[0].isint = 1;
68  argv[0].len = 4;
69  argv[0].u.integer = lobjId;
70 
71  argv[1].isint = 1;
72  argv[1].len = 4;
73  argv[1].u.integer = mode;
74 
75  res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2);
76  if (PQresultStatus(res) == PGRES_COMMAND_OK)
77  {
78  PQclear(res);
79  return fd;
80  }
81  else
82  {
83  PQclear(res);
84  return -1;
85  }
86 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
union PQArgBlock::@161 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:2783
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
Oid fn_lo_open
Definition: libpq-int.h:269
void PQclear(PGresult *res)
Definition: fe-exec.c:680
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_read()

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

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

References appendPQExpBufferStr(), 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(), and PQArgBlock::u.

Referenced by lo_export().

249 {
250  PQArgBlock argv[2];
251  PGresult *res;
252  int result_len;
253 
254  if (lo_initialize(conn) < 0)
255  return -1;
256 
257  /*
258  * Long ago, somebody thought it'd be a good idea to declare this function
259  * as taking size_t ... but the underlying backend function only accepts a
260  * signed int32 length. So throw error if the given value overflows
261  * int32.
262  */
263  if (len > (size_t) INT_MAX)
264  {
266  libpq_gettext("argument of lo_read exceeds integer range\n"));
267  return -1;
268  }
269 
270  argv[0].isint = 1;
271  argv[0].len = 4;
272  argv[0].u.integer = fd;
273 
274  argv[1].isint = 1;
275  argv[1].len = 4;
276  argv[1].u.integer = (int) len;
277 
278  res = PQfn(conn, conn->lobjfuncs->fn_lo_read,
279  (void *) buf, &result_len, 0, argv, 2);
280  if (PQresultStatus(res) == PGRES_COMMAND_OK)
281  {
282  PQclear(res);
283  return result_len;
284  }
285  else
286  {
287  PQclear(res);
288  return -1;
289  }
290 }
union PQArgBlock::@161 u
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
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:2783
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
Oid fn_lo_read
Definition: libpq-int.h:280
static char * buf
Definition: pg_test_fsync.c:68
PQExpBufferData errorMessage
Definition: libpq-int.h:569
void PQclear(PGresult *res)
Definition: fe-exec.c:680
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
#define libpq_gettext(x)
Definition: libpq-int.h:846
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_tell()

int lo_tell ( PGconn conn,
int  fd 
)

Definition at line 522 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.

523 {
524  int retval;
525  PQArgBlock argv[1];
526  PGresult *res;
527  int result_len;
528 
529  if (lo_initialize(conn) < 0)
530  return -1;
531 
532  argv[0].isint = 1;
533  argv[0].len = 4;
534  argv[0].u.integer = fd;
535 
536  res = PQfn(conn, conn->lobjfuncs->fn_lo_tell,
537  &retval, &result_len, 1, argv, 1);
538  if (PQresultStatus(res) == PGRES_COMMAND_OK)
539  {
540  PQclear(res);
541  return retval;
542  }
543  else
544  {
545  PQclear(res);
546  return -1;
547  }
548 }
union PQArgBlock::@161 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:2783
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
Oid fn_lo_tell
Definition: libpq-int.h:276
void PQclear(PGresult *res)
Definition: fe-exec.c:680
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_tell64()

pg_int64 lo_tell64 ( PGconn conn,
int  fd 
)

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

References appendPQExpBuffer(), 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(), and PQArgBlock::u.

Referenced by pickout().

556 {
557  pg_int64 retval;
558  PQArgBlock argv[1];
559  PGresult *res;
560  int result_len;
561 
562  if (lo_initialize(conn) < 0)
563  return -1;
564 
565  if (conn->lobjfuncs->fn_lo_tell64 == 0)
566  {
568  libpq_gettext("cannot determine OID of function %s\n"),
569  "lo_tell64");
570  return -1;
571  }
572 
573  argv[0].isint = 1;
574  argv[0].len = 4;
575  argv[0].u.integer = fd;
576 
577  res = PQfn(conn, conn->lobjfuncs->fn_lo_tell64,
578  (void *) &retval, &result_len, 0, argv, 1);
579  if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
580  {
581  PQclear(res);
582  return lo_ntoh64(retval);
583  }
584  else
585  {
586  PQclear(res);
587  return -1;
588  }
589 }
union PQArgBlock::@161 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:2783
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
Oid fn_lo_tell64
Definition: libpq-int.h:277
PQExpBufferData errorMessage
Definition: libpq-int.h:569
void PQclear(PGresult *res)
Definition: fe-exec.c:680
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
#define libpq_gettext(x)
Definition: libpq-int.h:846
int integer
Definition: libpq-fe.h:242
static pg_int64 lo_ntoh64(pg_int64 net64)
Definition: fe-lobj.c:1068
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_truncate()

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

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

References appendPQExpBuffer(), appendPQExpBufferStr(), 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(), and PQArgBlock::u.

132 {
133  PQArgBlock argv[2];
134  PGresult *res;
135  int retval;
136  int result_len;
137 
138  if (lo_initialize(conn) < 0)
139  return -1;
140 
141  /* Must check this on-the-fly because it's not there pre-8.3 */
142  if (conn->lobjfuncs->fn_lo_truncate == 0)
143  {
145  libpq_gettext("cannot determine OID of function %s\n"),
146  "lo_truncate");
147  return -1;
148  }
149 
150  /*
151  * Long ago, somebody thought it'd be a good idea to declare this function
152  * as taking size_t ... but the underlying backend function only accepts a
153  * signed int32 length. So throw error if the given value overflows
154  * int32. (A possible alternative is to automatically redirect the call
155  * to lo_truncate64; but if the caller wanted to rely on that backend
156  * function being available, he could have called lo_truncate64 for
157  * himself.)
158  */
159  if (len > (size_t) INT_MAX)
160  {
162  libpq_gettext("argument of lo_truncate exceeds integer range\n"));
163  return -1;
164  }
165 
166  argv[0].isint = 1;
167  argv[0].len = 4;
168  argv[0].u.integer = fd;
169 
170  argv[1].isint = 1;
171  argv[1].len = 4;
172  argv[1].u.integer = (int) len;
173 
174  res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate,
175  &retval, &result_len, 1, argv, 2);
176 
177  if (PQresultStatus(res) == PGRES_COMMAND_OK)
178  {
179  PQclear(res);
180  return retval;
181  }
182  else
183  {
184  PQclear(res);
185  return -1;
186  }
187 }
union PQArgBlock::@161 u
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
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:2783
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
Oid fn_lo_truncate
Definition: libpq-int.h:278
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
PQExpBufferData errorMessage
Definition: libpq-int.h:569
void PQclear(PGresult *res)
Definition: fe-exec.c:680
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
#define libpq_gettext(x)
Definition: libpq-int.h:846
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_truncate64()

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

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

References appendPQExpBuffer(), 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(), PQArgBlock::ptr, and PQArgBlock::u.

Referenced by my_truncate().

198 {
199  PQArgBlock argv[2];
200  PGresult *res;
201  int retval;
202  int result_len;
203 
204  if (lo_initialize(conn) < 0)
205  return -1;
206 
207  if (conn->lobjfuncs->fn_lo_truncate64 == 0)
208  {
210  libpq_gettext("cannot determine OID of function %s\n"),
211  "lo_truncate64");
212  return -1;
213  }
214 
215  argv[0].isint = 1;
216  argv[0].len = 4;
217  argv[0].u.integer = fd;
218 
219  len = lo_hton64(len);
220  argv[1].isint = 0;
221  argv[1].len = 8;
222  argv[1].u.ptr = (int *) &len;
223 
224  res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate64,
225  &retval, &result_len, 1, argv, 2);
226 
227  if (PQresultStatus(res) == PGRES_COMMAND_OK)
228  {
229  PQclear(res);
230  return retval;
231  }
232  else
233  {
234  PQclear(res);
235  return -1;
236  }
237 }
union PQArgBlock::@161 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:2783
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
static pg_int64 lo_hton64(pg_int64 host64)
Definition: fe-lobj.c:1043
Oid fn_lo_truncate64
Definition: libpq-int.h:279
PQExpBufferData errorMessage
Definition: libpq-int.h:569
void PQclear(PGresult *res)
Definition: fe-exec.c:680
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
int * ptr
Definition: libpq-fe.h:241
#define libpq_gettext(x)
Definition: libpq-int.h:846
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_unlink()

int lo_unlink ( PGconn conn,
Oid  lobjId 
)

Definition at line 597 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().

598 {
599  PQArgBlock argv[1];
600  PGresult *res;
601  int result_len;
602  int retval;
603 
604  if (lo_initialize(conn) < 0)
605  return -1;
606 
607  argv[0].isint = 1;
608  argv[0].len = 4;
609  argv[0].u.integer = lobjId;
610 
611  res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink,
612  &retval, &result_len, 1, argv, 1);
613  if (PQresultStatus(res) == PGRES_COMMAND_OK)
614  {
615  PQclear(res);
616  return retval;
617  }
618  else
619  {
620  PQclear(res);
621  return -1;
622  }
623 }
union PQArgBlock::@161 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:2783
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
void PQclear(PGresult *res)
Definition: fe-exec.c:680
Oid fn_lo_unlink
Definition: libpq-int.h:273
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853

◆ lo_write()

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

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

References appendPQExpBufferStr(), 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(), PQArgBlock::ptr, PQArgBlock::u, and unconstify.

Referenced by lo_import_internal().

300 {
301  PQArgBlock argv[2];
302  PGresult *res;
303  int result_len;
304  int retval;
305 
306  if (lo_initialize(conn) < 0)
307  return -1;
308 
309  /*
310  * Long ago, somebody thought it'd be a good idea to declare this function
311  * as taking size_t ... but the underlying backend function only accepts a
312  * signed int32 length. So throw error if the given value overflows
313  * int32.
314  */
315  if (len > (size_t) INT_MAX)
316  {
318  libpq_gettext("argument of lo_write exceeds integer range\n"));
319  return -1;
320  }
321 
322  argv[0].isint = 1;
323  argv[0].len = 4;
324  argv[0].u.integer = fd;
325 
326  argv[1].isint = 0;
327  argv[1].len = (int) len;
328  argv[1].u.ptr = (int *) unconstify(char *, buf);
329 
330  res = PQfn(conn, conn->lobjfuncs->fn_lo_write,
331  &retval, &result_len, 1, argv, 2);
332  if (PQresultStatus(res) == PGRES_COMMAND_OK)
333  {
334  PQclear(res);
335  return retval;
336  }
337  else
338  {
339  PQclear(res);
340  return -1;
341  }
342 }
union PQArgBlock::@161 u
Oid fn_lo_write
Definition: libpq-int.h:281
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
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:2783
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
static char * buf
Definition: pg_test_fsync.c:68
#define unconstify(underlying_type, expr)
Definition: c.h:1243
PQExpBufferData errorMessage
Definition: libpq-int.h:569
void PQclear(PGresult *res)
Definition: fe-exec.c:680
int isint
Definition: libpq-fe.h:238
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:475
int * ptr
Definition: libpq-fe.h:241
#define libpq_gettext(x)
Definition: libpq-int.h:846
int integer
Definition: libpq-fe.h:242
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:853