Header And Logo

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

itup.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * itup.h
00004  *    POSTGRES index tuple definitions.
00005  *
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  * src/include/access/itup.h
00011  *
00012  *-------------------------------------------------------------------------
00013  */
00014 #ifndef ITUP_H
00015 #define ITUP_H
00016 
00017 #include "access/tupdesc.h"
00018 #include "access/tupmacs.h"
00019 #include "storage/bufpage.h"
00020 #include "storage/itemptr.h"
00021 
00022 /*
00023  * Index tuple header structure
00024  *
00025  * All index tuples start with IndexTupleData.  If the HasNulls bit is set,
00026  * this is followed by an IndexAttributeBitMapData.  The index attribute
00027  * values follow, beginning at a MAXALIGN boundary.
00028  *
00029  * Note that the space allocated for the bitmap does not vary with the number
00030  * of attributes; that is because we don't have room to store the number of
00031  * attributes in the header.  Given the MAXALIGN constraint there's no space
00032  * savings to be had anyway, for usual values of INDEX_MAX_KEYS.
00033  */
00034 
00035 typedef struct IndexTupleData
00036 {
00037     ItemPointerData t_tid;      /* reference TID to heap tuple */
00038 
00039     /* ---------------
00040      * t_info is laid out in the following fashion:
00041      *
00042      * 15th (high) bit: has nulls
00043      * 14th bit: has var-width attributes
00044      * 13th bit: unused
00045      * 12-0 bit: size of tuple
00046      * ---------------
00047      */
00048 
00049     unsigned short t_info;      /* various info about tuple */
00050 
00051 } IndexTupleData;               /* MORE DATA FOLLOWS AT END OF STRUCT */
00052 
00053 typedef IndexTupleData *IndexTuple;
00054 
00055 typedef struct IndexAttributeBitMapData
00056 {
00057     bits8       bits[(INDEX_MAX_KEYS + 8 - 1) / 8];
00058 }   IndexAttributeBitMapData;
00059 
00060 typedef IndexAttributeBitMapData *IndexAttributeBitMap;
00061 
00062 /*
00063  * t_info manipulation macros
00064  */
00065 #define INDEX_SIZE_MASK 0x1FFF
00066 /* bit 0x2000 is not used at present */
00067 #define INDEX_VAR_MASK  0x4000
00068 #define INDEX_NULL_MASK 0x8000
00069 
00070 #define IndexTupleSize(itup)        ((Size) (((IndexTuple) (itup))->t_info & INDEX_SIZE_MASK))
00071 #define IndexTupleDSize(itup)       ((Size) ((itup).t_info & INDEX_SIZE_MASK))
00072 #define IndexTupleHasNulls(itup)    ((((IndexTuple) (itup))->t_info & INDEX_NULL_MASK))
00073 #define IndexTupleHasVarwidths(itup) ((((IndexTuple) (itup))->t_info & INDEX_VAR_MASK))
00074 
00075 
00076 /*
00077  * Takes an infomask as argument (primarily because this needs to be usable
00078  * at index_form_tuple time so enough space is allocated).
00079  */
00080 #define IndexInfoFindDataOffset(t_info) \
00081 ( \
00082     (!((t_info) & INDEX_NULL_MASK)) ? \
00083     ( \
00084         (Size)MAXALIGN(sizeof(IndexTupleData)) \
00085     ) \
00086     : \
00087     ( \
00088         (Size)MAXALIGN(sizeof(IndexTupleData) + sizeof(IndexAttributeBitMapData)) \
00089     ) \
00090 )
00091 
00092 /* ----------------
00093  *      index_getattr
00094  *
00095  *      This gets called many times, so we macro the cacheable and NULL
00096  *      lookups, and call nocache_index_getattr() for the rest.
00097  *
00098  * ----------------
00099  */
00100 #define index_getattr(tup, attnum, tupleDesc, isnull) \
00101 ( \
00102     AssertMacro(PointerIsValid(isnull) && (attnum) > 0), \
00103     *(isnull) = false, \
00104     !IndexTupleHasNulls(tup) ? \
00105     ( \
00106         (tupleDesc)->attrs[(attnum)-1]->attcacheoff >= 0 ? \
00107         ( \
00108             fetchatt((tupleDesc)->attrs[(attnum)-1], \
00109             (char *) (tup) + IndexInfoFindDataOffset((tup)->t_info) \
00110             + (tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
00111         ) \
00112         : \
00113             nocache_index_getattr((tup), (attnum), (tupleDesc)) \
00114     ) \
00115     : \
00116     ( \
00117         (att_isnull((attnum)-1, (char *)(tup) + sizeof(IndexTupleData))) ? \
00118         ( \
00119             *(isnull) = true, \
00120             (Datum)NULL \
00121         ) \
00122         : \
00123         ( \
00124             nocache_index_getattr((tup), (attnum), (tupleDesc)) \
00125         ) \
00126     ) \
00127 )
00128 
00129 /*
00130  * MaxIndexTuplesPerPage is an upper bound on the number of tuples that can
00131  * fit on one index page.  An index tuple must have either data or a null
00132  * bitmap, so we can safely assume it's at least 1 byte bigger than a bare
00133  * IndexTupleData struct.  We arrive at the divisor because each tuple
00134  * must be maxaligned, and it must have an associated item pointer.
00135  */
00136 #define MaxIndexTuplesPerPage   \
00137     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
00138             (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
00139 
00140 
00141 /* routines in indextuple.c */
00142 extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
00143                  Datum *values, bool *isnull);
00144 extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
00145                       TupleDesc tupleDesc);
00146 extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,
00147                    Datum *values, bool *isnull);
00148 extern IndexTuple CopyIndexTuple(IndexTuple source);
00149 
00150 #endif   /* ITUP_H */