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-2016, 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: in current usage, flag bit IFS_RDLOCK is *always* set, and we don't 31 * bother to test for it. Permission checks are made at first read or write 32 * attempt, not during inv_open(), so we have other bits to remember that. 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 #define IFS_RD_PERM_OK (1 << 2) /* read permission has been verified */ 51 #define IFS_WR_PERM_OK (1 << 3) /* write permission has been verified */ 52 53 } LargeObjectDesc; 54 55 56 /* 57 * Each "page" (tuple) of a large object can hold this much data 58 * 59 * We could set this as high as BLCKSZ less some overhead, but it seems 60 * better to make it a smaller value, so that not as much space is used 61 * up when a page-tuple is updated. Note that the value is deliberately 62 * chosen large enough to trigger the tuple toaster, so that we will 63 * attempt to compress page tuples in-line. (But they won't be moved off 64 * unless the user creates a toast-table for pg_largeobject...) 65 * 66 * Also, it seems to be a smart move to make the page size be a power of 2, 67 * since clients will often be written to send data in power-of-2 blocks. 68 * This avoids unnecessary tuple updates caused by partial-page writes. 69 * 70 * NB: Changing LOBLKSIZE requires an initdb. 71 */ 72 #define LOBLKSIZE (BLCKSZ / 4) 73 74 /* 75 * Maximum length in bytes for a large object. To make this larger, we'd 76 * have to widen pg_largeobject.pageno as well as various internal variables. 77 */ 78 #define MAX_LARGE_OBJECT_SIZE ((int64) INT_MAX * LOBLKSIZE) 79 80 81 /* 82 * Function definitions... 83 */ 84 85 /* inversion stuff in inv_api.c */ 86 extern void close_lo_relation(bool isCommit); 87 extern Oid inv_create(Oid lobjId); 88 extern LargeObjectDesc *inv_open(Oid lobjId, int flags, MemoryContext mcxt); 89 extern void inv_close(LargeObjectDesc *obj_desc); 90 extern int inv_drop(Oid lobjId); 91 extern int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence); 92 extern int64 inv_tell(LargeObjectDesc *obj_desc); 93 extern int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes); 94 extern int inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes); 95 extern void inv_truncate(LargeObjectDesc *obj_desc, int64 len); 96 97 #endif /* LARGE_OBJECT_H */ 98