Header And Logo

PostgreSQL
| The world's most advanced open source database.

tuptoaster.h

Go to the documentation of this file.
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 */