1 /*------------------------------------------------------------------------- 2 * 3 * large_object.h 4 * Declarations for PostgreSQL large objects. POSTGRES 4.2 supported 5 * zillions of large objects (internal, external, jaquith, inversion). 6 * Now we only support inversion. 7 * 8 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group 9 * Portions Copyright (c) 1994, Regents of the University of California 10 * 11 * src/include/storage/large_object.h 12 * 13 *------------------------------------------------------------------------- 14 */ 15 #ifndef LARGE_OBJECT_H 16 #define LARGE_OBJECT_H 17 18 #include "utils/snapshot.h" 19 20 21 /*---------- 22 * Data about a currently-open large object. 23 * 24 * id is the logical OID of the large object 25 * snapshot is the snapshot to use for read/write operations 26 * subid is the subtransaction that opened the desc (or currently owns it) 27 * offset is the current seek offset within the LO 28 * flags contains some flag bits 29 * 30 * NOTE: as of v11, permission checks are made when the large object is 31 * opened; therefore IFS_RDLOCK/IFS_WRLOCK indicate that read or write mode 32 * has been requested *and* the corresponding permission has been checked. 33 * 34 * NOTE: before 7.1, we also had to store references to the separate table 35 * and index of a specific large object. Now they all live in pg_largeobject 36 * and are accessed via a common relation descriptor. 37 *---------- 38 */ 39 typedef struct LargeObjectDesc 40 { 41 Oid id; /* LO's identifier */ 42 Snapshot snapshot; /* snapshot to use */ 43 SubTransactionId subid; /* owning subtransaction ID */ 44 uint64 offset; /* current seek pointer */ 45 int flags; /* see flag bits below */ 46 47 /* bits in flags: */ 48 #define IFS_RDLOCK (1 << 0) /* LO was opened for reading */ 49 #define IFS_WRLOCK (1 << 1) /* LO was opened for writing */ 50 51 } LargeObjectDesc; 52 53 54 /* 55 * Each "page" (tuple) of a large object can hold this much data 56 * 57 * We could set this as high as BLCKSZ less some overhead, but it seems 58 * better to make it a smaller value, so that not as much space is used 59 * up when a page-tuple is updated. Note that the value is deliberately 60 * chosen large enough to trigger the tuple toaster, so that we will 61 * attempt to compress page tuples in-line. (But they won't be moved off 62 * unless the user creates a toast-table for pg_largeobject...) 63 * 64 * Also, it seems to be a smart move to make the page size be a power of 2, 65 * since clients will often be written to send data in power-of-2 blocks. 66 * This avoids unnecessary tuple updates caused by partial-page writes. 67 * 68 * NB: Changing LOBLKSIZE requires an initdb. 69 */ 70 #define LOBLKSIZE (BLCKSZ / 4) 71 72 /* 73 * Maximum length in bytes for a large object. To make this larger, we'd 74 * have to widen pg_largeobject.pageno as well as various internal variables. 75 */ 76 #define MAX_LARGE_OBJECT_SIZE ((int64) INT_MAX * LOBLKSIZE) 77 78 79 /* 80 * GUC: backwards-compatibility flag to suppress LO permission checks 81 */ 82 extern bool lo_compat_privileges; 83 84 /* 85 * Function definitions... 86 */ 87 88 /* inversion stuff in inv_api.c */ 89 extern void close_lo_relation(bool isCommit); 90 extern Oid inv_create(Oid lobjId); 91 extern LargeObjectDesc *inv_open(Oid lobjId, int flags, MemoryContext mcxt); 92 extern void inv_close(LargeObjectDesc *obj_desc); 93 extern int inv_drop(Oid lobjId); 94 extern int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence); 95 extern int64 inv_tell(LargeObjectDesc *obj_desc); 96 extern int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes); 97 extern int inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes); 98 extern void inv_truncate(LargeObjectDesc *obj_desc, int64 len); 99 100 #endif /* LARGE_OBJECT_H */ 101