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 int64_t lo_hton64 (int64_t host64)
 
static int64_t lo_ntoh64 (int64_t 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, int64_t 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)
 
int64_t lo_lseek64 (PGconn *conn, int fd, int64_t offset, int whence)
 
Oid lo_creat (PGconn *conn, int mode)
 
Oid lo_create (PGconn *conn, Oid lobjId)
 
int lo_tell (PGconn *conn, int fd)
 
int64_t 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.

Function Documentation

◆ lo_close()

int lo_close ( PGconn conn,
int  fd 
)

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

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;
110 &retval, &result_len, 1, argv, 1);
112 {
113 PQclear(res);
114 return retval;
115 }
116 else
117 {
118 PQclear(res);
119 return -1;
120 }
121}
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3411
void PQclear(PGresult *res)
Definition: fe-exec.c:721
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:2980
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:843
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:125
static int fd(const char *x, int i)
Definition: preproc-init.c:105
PGconn * conn
Definition: streamutil.c:52
int isint
Definition: libpq-fe.h:296
int integer
Definition: libpq-fe.h:300
union PQArgBlock::@189 u
Oid fn_lo_close
Definition: libpq-int.h:289
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:559

References conn, 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 dumpLOs(), EndRestoreLO(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), and pickout().

◆ lo_creat()

Oid lo_creat ( PGconn conn,
int  mode 
)

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

439{
440 PQArgBlock argv[1];
441 PGresult *res;
442 int retval;
443 int result_len;
444
445 if (lo_initialize(conn) < 0)
446 return InvalidOid;
447
448 argv[0].isint = 1;
449 argv[0].len = 4;
450 argv[0].u.integer = mode;
452 &retval, &result_len, 1, argv, 1);
454 {
455 PQclear(res);
456 return (Oid) retval;
457 }
458 else
459 {
460 PQclear(res);
461 return InvalidOid;
462 }
463}
static PgChecksumMode mode
Definition: pg_checksums.c:55
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
Oid fn_lo_creat
Definition: libpq-int.h:290

References conn, 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().

◆ lo_create()

Oid lo_create ( PGconn conn,
Oid  lobjId 
)

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

475{
476 PQArgBlock argv[1];
477 PGresult *res;
478 int retval;
479 int result_len;
480
481 if (lo_initialize(conn) < 0)
482 return InvalidOid;
483
484 /* Must check this on-the-fly because it's not there pre-8.1 */
485 if (conn->lobjfuncs->fn_lo_create == 0)
486 {
487 libpq_append_conn_error(conn, "cannot determine OID of function %s",
488 "lo_create");
489 return InvalidOid;
490 }
491
492 argv[0].isint = 1;
493 argv[0].len = 4;
494 argv[0].u.integer = lobjId;
496 &retval, &result_len, 1, argv, 1);
498 {
499 PQclear(res);
500 return (Oid) retval;
501 }
502 else
503 {
504 PQclear(res);
505 return InvalidOid;
506 }
507}
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1381
Oid fn_lo_create
Definition: libpq-int.h:291

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

Referenced by lo_import_internal(), and StartRestoreLO().

◆ lo_export()

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

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

749{
750 int result = 1;
751 int fd;
752 int nbytes,
753 tmp;
754 char buf[LO_BUFSIZE];
755 int lobj;
756 char sebuf[PG_STRERROR_R_BUFLEN];
757
758 /*
759 * open the large object.
760 */
761 lobj = lo_open(conn, lobjId, INV_READ);
762 if (lobj == -1)
763 {
764 /* we assume lo_open() already set a suitable error message */
765 return -1;
766 }
767
768 /*
769 * create the file to be written to
770 */
771 fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
772 if (fd < 0)
773 {
774 /* We must do lo_close before setting the errorMessage */
775 int save_errno = errno;
776
777 (void) lo_close(conn, lobj);
778 /* deliberately overwrite any error from lo_close */
780 libpq_append_conn_error(conn, "could not open file \"%s\": %s",
781 filename,
782 strerror_r(save_errno, sebuf, sizeof(sebuf)));
783 return -1;
784 }
785
786 /*
787 * read in from the large object and write to the file
788 */
789 while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0)
790 {
791 tmp = write(fd, buf, nbytes);
792 if (tmp != nbytes)
793 {
794 /* We must do lo_close before setting the errorMessage */
795 int save_errno = errno;
796
797 (void) lo_close(conn, lobj);
798 (void) close(fd);
799 /* deliberately overwrite any error from lo_close */
801 libpq_append_conn_error(conn, "could not write to file \"%s\": %s",
802 filename,
803 strerror_r(save_errno, sebuf, sizeof(sebuf)));
804 return -1;
805 }
806 }
807
808 /*
809 * If lo_read() failed, we are now in an aborted transaction so there's no
810 * need for lo_close(); furthermore, if we tried it we'd overwrite the
811 * useful error result with a useless one. So skip lo_close() if we got a
812 * failure result.
813 */
814 if (nbytes < 0 ||
815 lo_close(conn, lobj) != 0)
816 {
817 /* assume lo_read() or lo_close() left a suitable error message */
818 result = -1;
819 }
820
821 /* if we already failed, don't overwrite that msg with a close error */
822 if (close(fd) != 0 && result >= 0)
823 {
824 libpq_append_conn_error(conn, "could not write to file \"%s\": %s",
825 filename, strerror_r(errno, sebuf, sizeof(sebuf)));
826 result = -1;
827 }
828
829 return result;
830}
#define PG_BINARY
Definition: c.h:1244
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:96
#define LO_BUFSIZE
Definition: fe-lobj.c:42
int lo_read(PGconn *conn, int fd, char *buf, size_t len)
Definition: fe-lobj.c:245
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
#define INV_READ
Definition: libpq-fs.h:22
#define pqClearConnErrorState(conn)
Definition: libpq-int.h:907
static char * filename
Definition: pg_dumpall.c:124
static char * buf
Definition: pg_test_fsync.c:72
#define PG_STRERROR_R_BUFLEN
Definition: port.h:257
#define strerror_r
Definition: port.h:256

References buf, close, conn, fd(), filename, INV_READ, libpq_append_conn_error(), LO_BUFSIZE, lo_close(), lo_open(), lo_read(), PG_BINARY, PG_STRERROR_R_BUFLEN, pqClearConnErrorState, strerror_r, and write.

Referenced by do_lo_export(), and main().

◆ lo_hton64()

static int64_t lo_hton64 ( int64_t  host64)
static

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

1024{
1025 union
1026 {
1027 int64 i64;
1028 uint32 i32[2];
1029 } swap;
1030 uint32 t;
1031
1032 /* High order half first, since we're doing MSB-first */
1033 t = (uint32) (host64 >> 32);
1034 swap.i32[0] = pg_hton32(t);
1035
1036 /* Now the low order half */
1037 t = (uint32) host64;
1038 swap.i32[1] = pg_hton32(t);
1039
1040 return swap.i64;
1041}
int64_t int64
Definition: c.h:499
uint32_t uint32
Definition: c.h:502
#define pg_hton32(x)
Definition: pg_bswap.h:121

References pg_hton32.

Referenced by lo_lseek64(), and lo_truncate64().

◆ lo_import()

Oid lo_import ( PGconn conn,
const char *  filename 
)

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

627{
629}
static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid)
Definition: fe-lobj.c:647

References conn, filename, InvalidOid, and lo_import_internal().

Referenced by do_lo_import(), and main().

◆ lo_import_internal()

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

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

648{
649 int fd;
650 int nbytes,
651 tmp;
652 char buf[LO_BUFSIZE];
653 Oid lobjOid;
654 int lobj;
655 char sebuf[PG_STRERROR_R_BUFLEN];
656
657 if (conn == NULL)
658 return InvalidOid;
659
660 /* Since this is the beginning of a query cycle, reset the error state */
662
663 /*
664 * open the file to be read in
665 */
666 fd = open(filename, O_RDONLY | PG_BINARY, 0666);
667 if (fd < 0)
668 { /* error */
669 libpq_append_conn_error(conn, "could not open file \"%s\": %s",
670 filename, strerror_r(errno, sebuf, sizeof(sebuf)));
671 return InvalidOid;
672 }
673
674 /*
675 * create an inversion object
676 */
677 if (oid == InvalidOid)
678 lobjOid = lo_creat(conn, INV_READ | INV_WRITE);
679 else
680 lobjOid = lo_create(conn, oid);
681
682 if (lobjOid == InvalidOid)
683 {
684 /* we assume lo_create() already set a suitable error message */
685 (void) close(fd);
686 return InvalidOid;
687 }
688
689 lobj = lo_open(conn, lobjOid, INV_WRITE);
690 if (lobj == -1)
691 {
692 /* we assume lo_open() already set a suitable error message */
693 (void) close(fd);
694 return InvalidOid;
695 }
696
697 /*
698 * read in from the file and write to the large object
699 */
700 while ((nbytes = read(fd, buf, LO_BUFSIZE)) > 0)
701 {
702 tmp = lo_write(conn, lobj, buf, nbytes);
703 if (tmp != nbytes)
704 {
705 /*
706 * If lo_write() failed, we are now in an aborted transaction so
707 * there's no need for lo_close(); furthermore, if we tried it
708 * we'd overwrite the useful error result with a useless one. So
709 * just nail the doors shut and get out of town.
710 */
711 (void) close(fd);
712 return InvalidOid;
713 }
714 }
715
716 if (nbytes < 0)
717 {
718 /* We must do lo_close before setting the errorMessage */
719 int save_errno = errno;
720
721 (void) lo_close(conn, lobj);
722 (void) close(fd);
723 /* deliberately overwrite any error from lo_close */
725 libpq_append_conn_error(conn, "could not read from file \"%s\": %s",
726 filename,
727 strerror_r(save_errno, sebuf, sizeof(sebuf)));
728 return InvalidOid;
729 }
730
731 (void) close(fd);
732
733 if (lo_close(conn, lobj) != 0)
734 {
735 /* we assume lo_close() already set a suitable error message */
736 return InvalidOid;
737 }
738
739 return lobjOid;
740}
Oid lo_creat(PGconn *conn, int mode)
Definition: fe-lobj.c:438
int lo_write(PGconn *conn, int fd, const char *buf, size_t len)
Definition: fe-lobj.c:295
Oid lo_create(PGconn *conn, Oid lobjId)
Definition: fe-lobj.c:474
#define read(a, b, c)
Definition: win32.h:13
#define INV_WRITE
Definition: libpq-fs.h:21

References buf, close, conn, fd(), filename, INV_READ, INV_WRITE, InvalidOid, libpq_append_conn_error(), LO_BUFSIZE, lo_close(), lo_creat(), lo_create(), lo_open(), lo_write(), PG_BINARY, PG_STRERROR_R_BUFLEN, pqClearConnErrorState, read, and strerror_r.

Referenced by lo_import(), and lo_import_with_oid().

◆ lo_import_with_oid()

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

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

642{
643 return lo_import_internal(conn, filename, lobjId);
644}

References conn, filename, and lo_import_internal().

◆ lo_initialize()

static int lo_initialize ( PGconn conn)
static

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

844{
845 PGresult *res;
846 PGlobjfuncs *lobjfuncs;
847 int n;
848 const char *query;
849 const char *fname;
850 Oid foid;
851
852 /* Nothing we can do with no connection */
853 if (conn == NULL)
854 return -1;
855
856 /* Since this is the beginning of a query cycle, reset the error state */
858
859 /* Nothing else to do if we already collected info */
860 if (conn->lobjfuncs != NULL)
861 return 0;
862
863 /*
864 * Allocate the structure to hold the function OIDs. We don't store it
865 * into the PGconn until it's successfully filled.
866 */
867 lobjfuncs = (PGlobjfuncs *) malloc(sizeof(PGlobjfuncs));
868 if (lobjfuncs == NULL)
869 {
870 libpq_append_conn_error(conn, "out of memory");
871 return -1;
872 }
873 MemSet(lobjfuncs, 0, sizeof(PGlobjfuncs));
874
875 /*
876 * Execute the query to get all the functions at once. (Not all of them
877 * may exist in older server versions.)
878 */
879 query = "select proname, oid from pg_catalog.pg_proc "
880 "where proname in ("
881 "'lo_open', "
882 "'lo_close', "
883 "'lo_creat', "
884 "'lo_create', "
885 "'lo_unlink', "
886 "'lo_lseek', "
887 "'lo_lseek64', "
888 "'lo_tell', "
889 "'lo_tell64', "
890 "'lo_truncate', "
891 "'lo_truncate64', "
892 "'loread', "
893 "'lowrite') "
894 "and pronamespace = (select oid from pg_catalog.pg_namespace "
895 "where nspname = 'pg_catalog')";
896
897 res = PQexec(conn, query);
898 if (res == NULL)
899 {
900 free(lobjfuncs);
901 return -1;
902 }
903
904 if (res->resultStatus != PGRES_TUPLES_OK)
905 {
906 free(lobjfuncs);
907 PQclear(res);
908 libpq_append_conn_error(conn, "query to initialize large object functions did not return data");
909 return -1;
910 }
911
912 /*
913 * Examine the result and put the OID's into the struct
914 */
915 for (n = 0; n < PQntuples(res); n++)
916 {
917 fname = PQgetvalue(res, n, 0);
918 foid = (Oid) atoi(PQgetvalue(res, n, 1));
919 if (strcmp(fname, "lo_open") == 0)
920 lobjfuncs->fn_lo_open = foid;
921 else if (strcmp(fname, "lo_close") == 0)
922 lobjfuncs->fn_lo_close = foid;
923 else if (strcmp(fname, "lo_creat") == 0)
924 lobjfuncs->fn_lo_creat = foid;
925 else if (strcmp(fname, "lo_create") == 0)
926 lobjfuncs->fn_lo_create = foid;
927 else if (strcmp(fname, "lo_unlink") == 0)
928 lobjfuncs->fn_lo_unlink = foid;
929 else if (strcmp(fname, "lo_lseek") == 0)
930 lobjfuncs->fn_lo_lseek = foid;
931 else if (strcmp(fname, "lo_lseek64") == 0)
932 lobjfuncs->fn_lo_lseek64 = foid;
933 else if (strcmp(fname, "lo_tell") == 0)
934 lobjfuncs->fn_lo_tell = foid;
935 else if (strcmp(fname, "lo_tell64") == 0)
936 lobjfuncs->fn_lo_tell64 = foid;
937 else if (strcmp(fname, "lo_truncate") == 0)
938 lobjfuncs->fn_lo_truncate = foid;
939 else if (strcmp(fname, "lo_truncate64") == 0)
940 lobjfuncs->fn_lo_truncate64 = foid;
941 else if (strcmp(fname, "loread") == 0)
942 lobjfuncs->fn_lo_read = foid;
943 else if (strcmp(fname, "lowrite") == 0)
944 lobjfuncs->fn_lo_write = foid;
945 }
946
947 PQclear(res);
948
949 /*
950 * Finally check that we got all required large object interface functions
951 * (ones that have been added later than the stone age are instead checked
952 * only if used)
953 */
954 if (lobjfuncs->fn_lo_open == 0)
955 {
956 libpq_append_conn_error(conn, "cannot determine OID of function %s",
957 "lo_open");
958 free(lobjfuncs);
959 return -1;
960 }
961 if (lobjfuncs->fn_lo_close == 0)
962 {
963 libpq_append_conn_error(conn, "cannot determine OID of function %s",
964 "lo_close");
965 free(lobjfuncs);
966 return -1;
967 }
968 if (lobjfuncs->fn_lo_creat == 0)
969 {
970 libpq_append_conn_error(conn, "cannot determine OID of function %s",
971 "lo_creat");
972 free(lobjfuncs);
973 return -1;
974 }
975 if (lobjfuncs->fn_lo_unlink == 0)
976 {
977 libpq_append_conn_error(conn, "cannot determine OID of function %s",
978 "lo_unlink");
979 free(lobjfuncs);
980 return -1;
981 }
982 if (lobjfuncs->fn_lo_lseek == 0)
983 {
984 libpq_append_conn_error(conn, "cannot determine OID of function %s",
985 "lo_lseek");
986 free(lobjfuncs);
987 return -1;
988 }
989 if (lobjfuncs->fn_lo_tell == 0)
990 {
991 libpq_append_conn_error(conn, "cannot determine OID of function %s",
992 "lo_tell");
993 free(lobjfuncs);
994 return -1;
995 }
996 if (lobjfuncs->fn_lo_read == 0)
997 {
998 libpq_append_conn_error(conn, "cannot determine OID of function %s",
999 "loread");
1000 free(lobjfuncs);
1001 return -1;
1002 }
1003 if (lobjfuncs->fn_lo_write == 0)
1004 {
1005 libpq_append_conn_error(conn, "cannot determine OID of function %s",
1006 "lowrite");
1007 free(lobjfuncs);
1008 return -1;
1009 }
1010
1011 /*
1012 * Put the structure into the connection control
1013 */
1014 conn->lobjfuncs = lobjfuncs;
1015 return 0;
1016}
#define MemSet(start, val, len)
Definition: c.h:991
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2262
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:78
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:128
Oid fn_lo_tell64
Definition: libpq-int.h:296
Oid fn_lo_write
Definition: libpq-int.h:300
Oid fn_lo_unlink
Definition: libpq-int.h:292
Oid fn_lo_open
Definition: libpq-int.h:288
Oid fn_lo_truncate64
Definition: libpq-int.h:298
Oid fn_lo_truncate
Definition: libpq-int.h:297
Oid fn_lo_lseek
Definition: libpq-int.h:293
Oid fn_lo_tell
Definition: libpq-int.h:295
Oid fn_lo_lseek64
Definition: libpq-int.h:294
Oid fn_lo_read
Definition: libpq-int.h:299
ExecStatusType resultStatus
Definition: libpq-int.h:182

References conn, pgLobjfuncs::fn_lo_close, pgLobjfuncs::fn_lo_creat, pgLobjfuncs::fn_lo_create, pgLobjfuncs::fn_lo_lseek, pgLobjfuncs::fn_lo_lseek64, pgLobjfuncs::fn_lo_open, pgLobjfuncs::fn_lo_read, pgLobjfuncs::fn_lo_tell, pgLobjfuncs::fn_lo_tell64, pgLobjfuncs::fn_lo_truncate, pgLobjfuncs::fn_lo_truncate64, pgLobjfuncs::fn_lo_unlink, pgLobjfuncs::fn_lo_write, free, if(), libpq_append_conn_error(), pg_conn::lobjfuncs, malloc, MemSet, PGRES_TUPLES_OK, PQclear(), pqClearConnErrorState, PQexec(), PQgetvalue(), PQntuples(), 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().

◆ lo_lseek()

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

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

345{
346 PQArgBlock argv[3];
347 PGresult *res;
348 int retval;
349 int result_len;
350
351 if (lo_initialize(conn) < 0)
352 return -1;
353
354 argv[0].isint = 1;
355 argv[0].len = 4;
356 argv[0].u.integer = fd;
357
358 argv[1].isint = 1;
359 argv[1].len = 4;
360 argv[1].u.integer = offset;
361
362 argv[2].isint = 1;
363 argv[2].len = 4;
364 argv[2].u.integer = whence;
365
367 &retval, &result_len, 1, argv, 3);
369 {
370 PQclear(res);
371 return retval;
372 }
373 else
374 {
375 PQclear(res);
376 return -1;
377 }
378}

References conn, 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().

◆ lo_lseek64()

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

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

386{
387 PQArgBlock argv[3];
388 PGresult *res;
389 int64 retval;
390 int result_len;
391
392 if (lo_initialize(conn) < 0)
393 return -1;
394
395 if (conn->lobjfuncs->fn_lo_lseek64 == 0)
396 {
397 libpq_append_conn_error(conn, "cannot determine OID of function %s",
398 "lo_lseek64");
399 return -1;
400 }
401
402 argv[0].isint = 1;
403 argv[0].len = 4;
404 argv[0].u.integer = fd;
405
406 offset = lo_hton64(offset);
407 argv[1].isint = 0;
408 argv[1].len = 8;
409 argv[1].u.ptr = (int *) &offset;
410
411 argv[2].isint = 1;
412 argv[2].len = 4;
413 argv[2].u.integer = whence;
414
416 (void *) &retval, &result_len, 0, argv, 3);
417 if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
418 {
419 PQclear(res);
420 return lo_ntoh64(retval);
421 }
422 else
423 {
424 PQclear(res);
425 return -1;
426 }
427}
static int64_t lo_ntoh64(int64_t net64)
Definition: fe-lobj.c:1048
static int64_t lo_hton64(int64_t host64)
Definition: fe-lobj.c:1023
int * ptr
Definition: libpq-fe.h:299

References conn, fd(), pgLobjfuncs::fn_lo_lseek64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_append_conn_error(), 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().

◆ lo_ntoh64()

static int64_t lo_ntoh64 ( int64_t  net64)
static

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

1049{
1050 union
1051 {
1052 int64 i64;
1053 uint32 i32[2];
1054 } swap;
1055 int64 result;
1056
1057 swap.i64 = net64;
1058
1059 result = (uint32) pg_ntoh32(swap.i32[0]);
1060 result <<= 32;
1061 result |= (uint32) pg_ntoh32(swap.i32[1]);
1062
1063 return result;
1064}
#define pg_ntoh32(x)
Definition: pg_bswap.h:125

References pg_ntoh32.

Referenced by lo_lseek64(), and lo_tell64().

◆ lo_open()

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

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

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);
77 {
78 PQclear(res);
79 return fd;
80 }
81 else
82 {
83 PQclear(res);
84 return -1;
85 }
86}

References conn, 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 dumpLOs(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), pickout(), and StartRestoreLO().

◆ lo_read()

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

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

246{
247 PQArgBlock argv[2];
248 PGresult *res;
249 int result_len;
250
251 if (lo_initialize(conn) < 0)
252 return -1;
253
254 /*
255 * Long ago, somebody thought it'd be a good idea to declare this function
256 * as taking size_t ... but the underlying backend function only accepts a
257 * signed int32 length. So throw error if the given value overflows
258 * int32.
259 */
260 if (len > (size_t) INT_MAX)
261 {
262 libpq_append_conn_error(conn, "argument of lo_read exceeds integer range");
263 return -1;
264 }
265
266 argv[0].isint = 1;
267 argv[0].len = 4;
268 argv[0].u.integer = fd;
269
270 argv[1].isint = 1;
271 argv[1].len = 4;
272 argv[1].u.integer = (int) len;
273
275 (void *) buf, &result_len, 0, argv, 2);
277 {
278 PQclear(res);
279 return result_len;
280 }
281 else
282 {
283 PQclear(res);
284 return -1;
285 }
286}
const void size_t len

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

Referenced by lo_export().

◆ lo_tell()

int lo_tell ( PGconn conn,
int  fd 
)

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

516{
517 int retval;
518 PQArgBlock argv[1];
519 PGresult *res;
520 int result_len;
521
522 if (lo_initialize(conn) < 0)
523 return -1;
524
525 argv[0].isint = 1;
526 argv[0].len = 4;
527 argv[0].u.integer = fd;
528
530 &retval, &result_len, 1, argv, 1);
532 {
533 PQclear(res);
534 return retval;
535 }
536 else
537 {
538 PQclear(res);
539 return -1;
540 }
541}

References conn, 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.

◆ lo_tell64()

int64_t lo_tell64 ( PGconn conn,
int  fd 
)

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

549{
550 int64 retval;
551 PQArgBlock argv[1];
552 PGresult *res;
553 int result_len;
554
555 if (lo_initialize(conn) < 0)
556 return -1;
557
558 if (conn->lobjfuncs->fn_lo_tell64 == 0)
559 {
560 libpq_append_conn_error(conn, "cannot determine OID of function %s",
561 "lo_tell64");
562 return -1;
563 }
564
565 argv[0].isint = 1;
566 argv[0].len = 4;
567 argv[0].u.integer = fd;
568
570 (void *) &retval, &result_len, 0, argv, 1);
571 if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
572 {
573 PQclear(res);
574 return lo_ntoh64(retval);
575 }
576 else
577 {
578 PQclear(res);
579 return -1;
580 }
581}

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

Referenced by pickout().

◆ lo_truncate()

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

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

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 {
144 libpq_append_conn_error(conn, "cannot determine OID of function %s",
145 "lo_truncate");
146 return -1;
147 }
148
149 /*
150 * Long ago, somebody thought it'd be a good idea to declare this function
151 * as taking size_t ... but the underlying backend function only accepts a
152 * signed int32 length. So throw error if the given value overflows
153 * int32. (A possible alternative is to automatically redirect the call
154 * to lo_truncate64; but if the caller wanted to rely on that backend
155 * function being available, he could have called lo_truncate64 for
156 * himself.)
157 */
158 if (len > (size_t) INT_MAX)
159 {
160 libpq_append_conn_error(conn, "argument of lo_truncate exceeds integer range");
161 return -1;
162 }
163
164 argv[0].isint = 1;
165 argv[0].len = 4;
166 argv[0].u.integer = fd;
167
168 argv[1].isint = 1;
169 argv[1].len = 4;
170 argv[1].u.integer = (int) len;
171
173 &retval, &result_len, 1, argv, 2);
174
176 {
177 PQclear(res);
178 return retval;
179 }
180 else
181 {
182 PQclear(res);
183 return -1;
184 }
185}

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

◆ lo_truncate64()

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

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

196{
197 PQArgBlock argv[2];
198 PGresult *res;
199 int retval;
200 int result_len;
201
202 if (lo_initialize(conn) < 0)
203 return -1;
204
206 {
207 libpq_append_conn_error(conn, "cannot determine OID of function %s",
208 "lo_truncate64");
209 return -1;
210 }
211
212 argv[0].isint = 1;
213 argv[0].len = 4;
214 argv[0].u.integer = fd;
215
216 len = lo_hton64(len);
217 argv[1].isint = 0;
218 argv[1].len = 8;
219 argv[1].u.ptr = (int *) &len;
220
222 &retval, &result_len, 1, argv, 2);
223
225 {
226 PQclear(res);
227 return retval;
228 }
229 else
230 {
231 PQclear(res);
232 return -1;
233 }
234}

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

Referenced by my_truncate().

◆ lo_unlink()

int lo_unlink ( PGconn conn,
Oid  lobjId 
)

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

590{
591 PQArgBlock argv[1];
592 PGresult *res;
593 int result_len;
594 int retval;
595
596 if (lo_initialize(conn) < 0)
597 return -1;
598
599 argv[0].isint = 1;
600 argv[0].len = 4;
601 argv[0].u.integer = lobjId;
602
604 &retval, &result_len, 1, argv, 1);
606 {
607 PQclear(res);
608 return retval;
609 }
610 else
611 {
612 PQclear(res);
613 return -1;
614 }
615}

References conn, 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().

◆ lo_write()

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

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

296{
297 PQArgBlock argv[2];
298 PGresult *res;
299 int result_len;
300 int retval;
301
302 if (lo_initialize(conn) < 0)
303 return -1;
304
305 /*
306 * Long ago, somebody thought it'd be a good idea to declare this function
307 * as taking size_t ... but the underlying backend function only accepts a
308 * signed int32 length. So throw error if the given value overflows
309 * int32.
310 */
311 if (len > (size_t) INT_MAX)
312 {
313 libpq_append_conn_error(conn, "argument of lo_write exceeds integer range");
314 return -1;
315 }
316
317 argv[0].isint = 1;
318 argv[0].len = 4;
319 argv[0].u.integer = fd;
320
321 argv[1].isint = 0;
322 argv[1].len = (int) len;
323 argv[1].u.ptr = (int *) unconstify(char *, buf);
324
326 &retval, &result_len, 1, argv, 2);
328 {
329 PQclear(res);
330 return retval;
331 }
332 else
333 {
334 PQclear(res);
335 return -1;
336 }
337}
#define unconstify(underlying_type, expr)
Definition: c.h:1216

References buf, conn, fd(), pgLobjfuncs::fn_lo_write, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, len, libpq_append_conn_error(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), PQArgBlock::ptr, PQArgBlock::u, and unconstify.

Referenced by lo_import_internal().