]> granicus.if.org Git - postgresql/blob - src/include/access/tuptoaster.h
1ae44e0e695e72b0ad4f7971135992ec3a04b612
[postgresql] / src / include / access / tuptoaster.h
1 /*-------------------------------------------------------------------------
2  *
3  * tuptoaster.h
4  *        POSTGRES definitions for external and compressed storage
5  *        of variable size attributes.
6  *
7  * Copyright (c) 2000-2011, PostgreSQL Global Development Group
8  *
9  * src/include/access/tuptoaster.h
10  *
11  *-------------------------------------------------------------------------
12  */
13 #ifndef TUPTOASTER_H
14 #define TUPTOASTER_H
15
16 #include "access/htup.h"
17 #include "utils/relcache.h"
18
19 /*
20  * This enables de-toasting of index entries.  Needed until VACUUM is
21  * smart enough to rebuild indexes from scratch.
22  */
23 #define TOAST_INDEX_HACK
24
25
26 /*
27  * Find the maximum size of a tuple if there are to be N tuples per page.
28  */
29 #define MaximumBytesPerTuple(tuplesPerPage) \
30         MAXALIGN_DOWN((BLCKSZ - \
31                                    MAXALIGN(SizeOfPageHeaderData + (tuplesPerPage) * sizeof(ItemIdData))) \
32                                   / (tuplesPerPage))
33
34 /*
35  * These symbols control toaster activation.  If a tuple is larger than
36  * TOAST_TUPLE_THRESHOLD, we will try to toast it down to no more than
37  * TOAST_TUPLE_TARGET bytes through compressing compressible fields and
38  * moving EXTENDED and EXTERNAL data out-of-line.
39  *
40  * The numbers need not be the same, though they currently are.  It doesn't
41  * make sense for TARGET to exceed THRESHOLD, but it could be useful to make
42  * it be smaller.
43  *
44  * Currently we choose both values to match the largest tuple size for which
45  * TOAST_TUPLES_PER_PAGE tuples can fit on a heap page.
46  *
47  * XXX while these can be modified without initdb, some thought needs to be
48  * given to needs_toast_table() in toasting.c before unleashing random
49  * changes.  Also see LOBLKSIZE in large_object.h, which can *not* be
50  * changed without initdb.
51  */
52 #define TOAST_TUPLES_PER_PAGE   4
53
54 #define TOAST_TUPLE_THRESHOLD   MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE)
55
56 #define TOAST_TUPLE_TARGET              TOAST_TUPLE_THRESHOLD
57
58 /*
59  * The code will also consider moving MAIN data out-of-line, but only as a
60  * last resort if the previous steps haven't reached the target tuple size.
61  * In this phase we use a different target size, currently equal to the
62  * largest tuple that will fit on a heap page.  This is reasonable since
63  * the user has told us to keep the data in-line if at all possible.
64  */
65 #define TOAST_TUPLES_PER_PAGE_MAIN      1
66
67 #define TOAST_TUPLE_TARGET_MAIN MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE_MAIN)
68
69 /*
70  * If an index value is larger than TOAST_INDEX_TARGET, we will try to
71  * compress it (we can't move it out-of-line, however).  Note that this
72  * number is per-datum, not per-tuple, for simplicity in index_form_tuple().
73  */
74 #define TOAST_INDEX_TARGET              (MaxHeapTupleSize / 16)
75
76 /*
77  * When we store an oversize datum externally, we divide it into chunks
78  * containing at most TOAST_MAX_CHUNK_SIZE data bytes.  This number *must*
79  * be small enough that the completed toast-table tuple (including the
80  * ID and sequence fields and all overhead) will fit on a page.
81  * The coding here sets the size on the theory that we want to fit
82  * EXTERN_TUPLES_PER_PAGE tuples of maximum size onto a page.
83  *
84  * NB: Changing TOAST_MAX_CHUNK_SIZE requires an initdb.
85  */
86 #define EXTERN_TUPLES_PER_PAGE  4               /* tweak only this */
87
88 #define EXTERN_TUPLE_MAX_SIZE   MaximumBytesPerTuple(EXTERN_TUPLES_PER_PAGE)
89
90 #define TOAST_MAX_CHUNK_SIZE    \
91         (EXTERN_TUPLE_MAX_SIZE -                                                        \
92          MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) -      \
93          sizeof(Oid) -                                                                          \
94          sizeof(int32) -                                                                        \
95          VARHDRSZ)
96
97
98 /* ----------
99  * toast_insert_or_update -
100  *
101  *      Called by heap_insert() and heap_update().
102  * ----------
103  */
104 extern HeapTuple toast_insert_or_update(Relation rel,
105                                            HeapTuple newtup, HeapTuple oldtup,
106                                            int options);
107
108 /* ----------
109  * toast_delete -
110  *
111  *      Called by heap_delete().
112  * ----------
113  */
114 extern void toast_delete(Relation rel, HeapTuple oldtup);
115
116 /* ----------
117  * heap_tuple_fetch_attr() -
118  *
119  *              Fetches an external stored attribute from the toast
120  *              relation. Does NOT decompress it, if stored external
121  *              in compressed format.
122  * ----------
123  */
124 extern struct varlena *heap_tuple_fetch_attr(struct varlena * attr);
125
126 /* ----------
127  * heap_tuple_untoast_attr() -
128  *
129  *              Fully detoasts one attribute, fetching and/or decompressing
130  *              it as needed.
131  * ----------
132  */
133 extern struct varlena *heap_tuple_untoast_attr(struct varlena * attr);
134
135 /* ----------
136  * heap_tuple_untoast_attr_slice() -
137  *
138  *              Fetches only the specified portion of an attribute.
139  *              (Handles all cases for attribute storage)
140  * ----------
141  */
142 extern struct varlena *heap_tuple_untoast_attr_slice(struct varlena * attr,
143                                                           int32 sliceoffset,
144                                                           int32 slicelength);
145
146 /* ----------
147  * toast_flatten_tuple_attribute -
148  *
149  *      If a Datum is of composite type, "flatten" it to contain no toasted fields.
150  *      This must be invoked on any potentially-composite field that is to be
151  *      inserted into a tuple.  Doing this preserves the invariant that toasting
152  *      goes only one level deep in a tuple.
153  * ----------
154  */
155 extern Datum toast_flatten_tuple_attribute(Datum value,
156                                                           Oid typeId, int32 typeMod);
157
158 /* ----------
159  * toast_compress_datum -
160  *
161  *      Create a compressed version of a varlena datum, if possible
162  * ----------
163  */
164 extern Datum toast_compress_datum(Datum value);
165
166 /* ----------
167  * toast_raw_datum_size -
168  *
169  *      Return the raw (detoasted) size of a varlena datum
170  * ----------
171  */
172 extern Size toast_raw_datum_size(Datum value);
173
174 /* ----------
175  * toast_datum_size -
176  *
177  *      Return the storage size of a varlena datum
178  * ----------
179  */
180 extern Size toast_datum_size(Datum value);
181
182 #endif   /* TUPTOASTER_H */