1 /*------------------------------------------------------------------------- 2 * 3 * heaptoast.h 4 * Heap-specific definitions for external and compressed storage 5 * of variable size attributes. 6 * 7 * Copyright (c) 2000-2021, PostgreSQL Global Development Group 8 * 9 * src/include/access/heaptoast.h 10 * 11 *------------------------------------------------------------------------- 12 */ 13 #ifndef HEAPTOAST_H 14 #define HEAPTOAST_H 15 16 #include "access/htup_details.h" 17 #include "storage/lockdefs.h" 18 #include "utils/relcache.h" 19 20 /* 21 * Find the maximum size of a tuple if there are to be N tuples per page. 22 */ 23 #define MaximumBytesPerTuple(tuplesPerPage) \ 24 MAXALIGN_DOWN((BLCKSZ - \ 25 MAXALIGN(SizeOfPageHeaderData + (tuplesPerPage) * sizeof(ItemIdData))) \ 26 / (tuplesPerPage)) 27 28 /* 29 * These symbols control toaster activation. If a tuple is larger than 30 * TOAST_TUPLE_THRESHOLD, we will try to toast it down to no more than 31 * TOAST_TUPLE_TARGET bytes through compressing compressible fields and 32 * moving EXTENDED and EXTERNAL data out-of-line. 33 * 34 * The numbers need not be the same, though they currently are. It doesn't 35 * make sense for TARGET to exceed THRESHOLD, but it could be useful to make 36 * it be smaller. 37 * 38 * Currently we choose both values to match the largest tuple size for which 39 * TOAST_TUPLES_PER_PAGE tuples can fit on a heap page. 40 * 41 * XXX while these can be modified without initdb, some thought needs to be 42 * given to needs_toast_table() in toasting.c before unleashing random 43 * changes. Also see LOBLKSIZE in large_object.h, which can *not* be 44 * changed without initdb. 45 */ 46 #define TOAST_TUPLES_PER_PAGE 4 47 48 #define TOAST_TUPLE_THRESHOLD MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE) 49 50 #define TOAST_TUPLE_TARGET TOAST_TUPLE_THRESHOLD 51 52 /* 53 * The code will also consider moving MAIN data out-of-line, but only as a 54 * last resort if the previous steps haven't reached the target tuple size. 55 * In this phase we use a different target size, currently equal to the 56 * largest tuple that will fit on a heap page. This is reasonable since 57 * the user has told us to keep the data in-line if at all possible. 58 */ 59 #define TOAST_TUPLES_PER_PAGE_MAIN 1 60 61 #define TOAST_TUPLE_TARGET_MAIN MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE_MAIN) 62 63 /* 64 * If an index value is larger than TOAST_INDEX_TARGET, we will try to 65 * compress it (we can't move it out-of-line, however). Note that this 66 * number is per-datum, not per-tuple, for simplicity in index_form_tuple(). 67 */ 68 #define TOAST_INDEX_TARGET (MaxHeapTupleSize / 16) 69 70 /* 71 * When we store an oversize datum externally, we divide it into chunks 72 * containing at most TOAST_MAX_CHUNK_SIZE data bytes. This number *must* 73 * be small enough that the completed toast-table tuple (including the 74 * ID and sequence fields and all overhead) will fit on a page. 75 * The coding here sets the size on the theory that we want to fit 76 * EXTERN_TUPLES_PER_PAGE tuples of maximum size onto a page. 77 * 78 * NB: Changing TOAST_MAX_CHUNK_SIZE requires an initdb. 79 */ 80 #define EXTERN_TUPLES_PER_PAGE 4 /* tweak only this */ 81 82 #define EXTERN_TUPLE_MAX_SIZE MaximumBytesPerTuple(EXTERN_TUPLES_PER_PAGE) 83 84 #define TOAST_MAX_CHUNK_SIZE \ 85 (EXTERN_TUPLE_MAX_SIZE - \ 86 MAXALIGN(SizeofHeapTupleHeader) - \ 87 sizeof(Oid) - \ 88 sizeof(int32) - \ 89 VARHDRSZ) 90 91 /* ---------- 92 * heap_toast_insert_or_update - 93 * 94 * Called by heap_insert() and heap_update(). 95 * ---------- 96 */ 97 extern HeapTuple heap_toast_insert_or_update(Relation rel, HeapTuple newtup, 98 HeapTuple oldtup, int options); 99 100 /* ---------- 101 * heap_toast_delete - 102 * 103 * Called by heap_delete(). 104 * ---------- 105 */ 106 extern void heap_toast_delete(Relation rel, HeapTuple oldtup, 107 bool is_speculative); 108 109 /* ---------- 110 * toast_flatten_tuple - 111 * 112 * "Flatten" a tuple to contain no out-of-line toasted fields. 113 * (This does not eliminate compressed or short-header datums.) 114 * ---------- 115 */ 116 extern HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc); 117 118 /* ---------- 119 * toast_flatten_tuple_to_datum - 120 * 121 * "Flatten" a tuple containing out-of-line toasted fields into a Datum. 122 * ---------- 123 */ 124 extern Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, 125 uint32 tup_len, 126 TupleDesc tupleDesc); 127 128 /* ---------- 129 * toast_build_flattened_tuple - 130 * 131 * Build a tuple containing no out-of-line toasted fields. 132 * (This does not eliminate compressed or short-header datums.) 133 * ---------- 134 */ 135 extern HeapTuple toast_build_flattened_tuple(TupleDesc tupleDesc, 136 Datum *values, 137 bool *isnull); 138 139 /* ---------- 140 * heap_fetch_toast_slice 141 * 142 * Fetch a slice from a toast value stored in a heap table. 143 * ---------- 144 */ 145 extern void heap_fetch_toast_slice(Relation toastrel, Oid valueid, 146 int32 attrsize, int32 sliceoffset, 147 int32 slicelength, struct varlena *result); 148 149 #endif /* HEAPTOAST_H */ 150