00001 /*------------------------------------------------------------------------- 00002 * 00003 * tuptoaster.h 00004 * POSTGRES definitions for external and compressed storage 00005 * of variable size attributes. 00006 * 00007 * Copyright (c) 2000-2013, PostgreSQL Global Development Group 00008 * 00009 * src/include/access/tuptoaster.h 00010 * 00011 *------------------------------------------------------------------------- 00012 */ 00013 #ifndef TUPTOASTER_H 00014 #define TUPTOASTER_H 00015 00016 #include "access/htup_details.h" 00017 #include "utils/relcache.h" 00018 00019 /* 00020 * This enables de-toasting of index entries. Needed until VACUUM is 00021 * smart enough to rebuild indexes from scratch. 00022 */ 00023 #define TOAST_INDEX_HACK 00024 00025 00026 /* 00027 * Find the maximum size of a tuple if there are to be N tuples per page. 00028 */ 00029 #define MaximumBytesPerTuple(tuplesPerPage) \ 00030 MAXALIGN_DOWN((BLCKSZ - \ 00031 MAXALIGN(SizeOfPageHeaderData + (tuplesPerPage) * sizeof(ItemIdData))) \ 00032 / (tuplesPerPage)) 00033 00034 /* 00035 * These symbols control toaster activation. If a tuple is larger than 00036 * TOAST_TUPLE_THRESHOLD, we will try to toast it down to no more than 00037 * TOAST_TUPLE_TARGET bytes through compressing compressible fields and 00038 * moving EXTENDED and EXTERNAL data out-of-line. 00039 * 00040 * The numbers need not be the same, though they currently are. It doesn't 00041 * make sense for TARGET to exceed THRESHOLD, but it could be useful to make 00042 * it be smaller. 00043 * 00044 * Currently we choose both values to match the largest tuple size for which 00045 * TOAST_TUPLES_PER_PAGE tuples can fit on a heap page. 00046 * 00047 * XXX while these can be modified without initdb, some thought needs to be 00048 * given to needs_toast_table() in toasting.c before unleashing random 00049 * changes. Also see LOBLKSIZE in large_object.h, which can *not* be 00050 * changed without initdb. 00051 */ 00052 #define TOAST_TUPLES_PER_PAGE 4 00053 00054 #define TOAST_TUPLE_THRESHOLD MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE) 00055 00056 #define TOAST_TUPLE_TARGET TOAST_TUPLE_THRESHOLD 00057 00058 /* 00059 * The code will also consider moving MAIN data out-of-line, but only as a 00060 * last resort if the previous steps haven't reached the target tuple size. 00061 * In this phase we use a different target size, currently equal to the 00062 * largest tuple that will fit on a heap page. This is reasonable since 00063 * the user has told us to keep the data in-line if at all possible. 00064 */ 00065 #define TOAST_TUPLES_PER_PAGE_MAIN 1 00066 00067 #define TOAST_TUPLE_TARGET_MAIN MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE_MAIN) 00068 00069 /* 00070 * If an index value is larger than TOAST_INDEX_TARGET, we will try to 00071 * compress it (we can't move it out-of-line, however). Note that this 00072 * number is per-datum, not per-tuple, for simplicity in index_form_tuple(). 00073 */ 00074 #define TOAST_INDEX_TARGET (MaxHeapTupleSize / 16) 00075 00076 /* 00077 * When we store an oversize datum externally, we divide it into chunks 00078 * containing at most TOAST_MAX_CHUNK_SIZE data bytes. This number *must* 00079 * be small enough that the completed toast-table tuple (including the 00080 * ID and sequence fields and all overhead) will fit on a page. 00081 * The coding here sets the size on the theory that we want to fit 00082 * EXTERN_TUPLES_PER_PAGE tuples of maximum size onto a page. 00083 * 00084 * NB: Changing TOAST_MAX_CHUNK_SIZE requires an initdb. 00085 */ 00086 #define EXTERN_TUPLES_PER_PAGE 4 /* tweak only this */ 00087 00088 #define EXTERN_TUPLE_MAX_SIZE MaximumBytesPerTuple(EXTERN_TUPLES_PER_PAGE) 00089 00090 #define TOAST_MAX_CHUNK_SIZE \ 00091 (EXTERN_TUPLE_MAX_SIZE - \ 00092 MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) - \ 00093 sizeof(Oid) - \ 00094 sizeof(int32) - \ 00095 VARHDRSZ) 00096 00097 00098 /* ---------- 00099 * toast_insert_or_update - 00100 * 00101 * Called by heap_insert() and heap_update(). 00102 * ---------- 00103 */ 00104 extern HeapTuple toast_insert_or_update(Relation rel, 00105 HeapTuple newtup, HeapTuple oldtup, 00106 int options); 00107 00108 /* ---------- 00109 * toast_delete - 00110 * 00111 * Called by heap_delete(). 00112 * ---------- 00113 */ 00114 extern void toast_delete(Relation rel, HeapTuple oldtup); 00115 00116 /* ---------- 00117 * heap_tuple_fetch_attr() - 00118 * 00119 * Fetches an external stored attribute from the toast 00120 * relation. Does NOT decompress it, if stored external 00121 * in compressed format. 00122 * ---------- 00123 */ 00124 extern struct varlena *heap_tuple_fetch_attr(struct varlena * attr); 00125 00126 /* ---------- 00127 * heap_tuple_untoast_attr() - 00128 * 00129 * Fully detoasts one attribute, fetching and/or decompressing 00130 * it as needed. 00131 * ---------- 00132 */ 00133 extern struct varlena *heap_tuple_untoast_attr(struct varlena * attr); 00134 00135 /* ---------- 00136 * heap_tuple_untoast_attr_slice() - 00137 * 00138 * Fetches only the specified portion of an attribute. 00139 * (Handles all cases for attribute storage) 00140 * ---------- 00141 */ 00142 extern struct varlena *heap_tuple_untoast_attr_slice(struct varlena * attr, 00143 int32 sliceoffset, 00144 int32 slicelength); 00145 00146 /* ---------- 00147 * toast_flatten_tuple - 00148 * 00149 * "Flatten" a tuple to contain no out-of-line toasted fields. 00150 * (This does not eliminate compressed or short-header datums.) 00151 * ---------- 00152 */ 00153 extern HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc); 00154 00155 /* ---------- 00156 * toast_flatten_tuple_attribute - 00157 * 00158 * If a Datum is of composite type, "flatten" it to contain no toasted fields. 00159 * This must be invoked on any potentially-composite field that is to be 00160 * inserted into a tuple. Doing this preserves the invariant that toasting 00161 * goes only one level deep in a tuple. 00162 * ---------- 00163 */ 00164 extern Datum toast_flatten_tuple_attribute(Datum value, 00165 Oid typeId, int32 typeMod); 00166 00167 /* ---------- 00168 * toast_compress_datum - 00169 * 00170 * Create a compressed version of a varlena datum, if possible 00171 * ---------- 00172 */ 00173 extern Datum toast_compress_datum(Datum value); 00174 00175 /* ---------- 00176 * toast_raw_datum_size - 00177 * 00178 * Return the raw (detoasted) size of a varlena datum 00179 * ---------- 00180 */ 00181 extern Size toast_raw_datum_size(Datum value); 00182 00183 /* ---------- 00184 * toast_datum_size - 00185 * 00186 * Return the storage size of a varlena datum 00187 * ---------- 00188 */ 00189 extern Size toast_datum_size(Datum value); 00190 00191 #endif /* TUPTOASTER_H */