1 /*-------------------------------------------------------------------------
4 * POSTGRES definitions for external and compressed storage
5 * of variable size attributes.
7 * Copyright (c) 2000-2008, PostgreSQL Global Development Group
11 *-------------------------------------------------------------------------
16 #include "access/htup.h"
17 #include "storage/bufpage.h"
18 #include "utils/relcache.h"
21 * This enables de-toasting of index entries. Needed until VACUUM is
22 * smart enough to rebuild indexes from scratch.
24 #define TOAST_INDEX_HACK
28 * These symbols control toaster activation. If a tuple is larger than
29 * TOAST_TUPLE_THRESHOLD, we will try to toast it down to no more than
30 * TOAST_TUPLE_TARGET bytes. Both numbers include all tuple header overhead
31 * and between-fields alignment padding, but we do *not* consider any
32 * end-of-tuple alignment padding; hence the values can be compared directly
33 * to a tuple's t_len field.
35 * The numbers need not be the same, though they currently are. It doesn't
36 * make sense for TARGET to exceed THRESHOLD, but it could be useful to make
39 * Currently we choose both values to match the largest tuple size for which
40 * TOAST_TUPLES_PER_PAGE tuples can fit on a disk page.
42 * XXX while these can be modified without initdb, some thought needs to be
43 * given to needs_toast_table() in toasting.c before unleashing random
44 * changes. Also see LOBLKSIZE in large_object.h, which can *not* be
45 * changed without initdb.
47 #define TOAST_TUPLES_PER_PAGE 4
49 #define TOAST_TUPLE_THRESHOLD \
50 MAXALIGN_DOWN((BLCKSZ - \
51 MAXALIGN(SizeOfPageHeaderData + TOAST_TUPLES_PER_PAGE * sizeof(ItemIdData))) \
52 / TOAST_TUPLES_PER_PAGE)
54 #define TOAST_TUPLE_TARGET TOAST_TUPLE_THRESHOLD
57 * If an index value is larger than TOAST_INDEX_TARGET, we will try to
58 * compress it (we can't move it out-of-line, however). Note that this
59 * number is per-datum, not per-tuple, for simplicity in index_form_tuple().
61 #define TOAST_INDEX_TARGET (MaxHeapTupleSize / 16)
64 * When we store an oversize datum externally, we divide it into chunks
65 * containing at most TOAST_MAX_CHUNK_SIZE data bytes. This number *must*
66 * be small enough that the completed toast-table tuple (including the
67 * ID and sequence fields and all overhead) will fit on a page.
68 * The coding here sets the size on the theory that we want to fit
69 * EXTERN_TUPLES_PER_PAGE tuples of maximum size onto a page.
71 * NB: Changing TOAST_MAX_CHUNK_SIZE requires an initdb.
73 #define EXTERN_TUPLES_PER_PAGE 4 /* tweak only this */
75 #define EXTERN_TUPLE_MAX_SIZE \
76 MAXALIGN_DOWN((BLCKSZ - \
77 MAXALIGN(SizeOfPageHeaderData + EXTERN_TUPLES_PER_PAGE * sizeof(ItemIdData))) \
78 / EXTERN_TUPLES_PER_PAGE)
80 #define TOAST_MAX_CHUNK_SIZE \
81 (EXTERN_TUPLE_MAX_SIZE - \
82 MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) - \
89 * toast_insert_or_update -
91 * Called by heap_insert() and heap_update().
94 extern HeapTuple
toast_insert_or_update(Relation rel
,
95 HeapTuple newtup
, HeapTuple oldtup
,
96 bool use_wal
, bool use_fsm
);
101 * Called by heap_delete().
104 extern void toast_delete(Relation rel
, HeapTuple oldtup
);
107 * heap_tuple_fetch_attr() -
109 * Fetches an external stored attribute from the toast
110 * relation. Does NOT decompress it, if stored external
111 * in compressed format.
114 extern struct varlena
*heap_tuple_fetch_attr(struct varlena
* attr
);
117 * heap_tuple_untoast_attr() -
119 * Fully detoasts one attribute, fetching and/or decompressing
123 extern struct varlena
*heap_tuple_untoast_attr(struct varlena
* attr
);
126 * heap_tuple_untoast_attr_slice() -
128 * Fetches only the specified portion of an attribute.
129 * (Handles all cases for attribute storage)
132 extern struct varlena
*heap_tuple_untoast_attr_slice(struct varlena
* attr
,
137 * toast_flatten_tuple_attribute -
139 * If a Datum is of composite type, "flatten" it to contain no toasted fields.
140 * This must be invoked on any potentially-composite field that is to be
141 * inserted into a tuple. Doing this preserves the invariant that toasting
142 * goes only one level deep in a tuple.
145 extern Datum
toast_flatten_tuple_attribute(Datum value
,
146 Oid typeId
, int32 typeMod
);
149 * toast_compress_datum -
151 * Create a compressed version of a varlena datum, if possible
154 extern Datum
toast_compress_datum(Datum value
);
157 * toast_raw_datum_size -
159 * Return the raw (detoasted) size of a varlena datum
162 extern Size
toast_raw_datum_size(Datum value
);
167 * Return the storage size of a varlena datum
170 extern Size
toast_datum_size(Datum value
);
172 #endif /* TUPTOASTER_H */