PostgreSQL Source Code git master
Data Structures | Macros | Typedefs | Functions
itup.h File Reference
#include "access/tupdesc.h"
#include "access/tupmacs.h"
#include "storage/bufpage.h"
#include "storage/itemptr.h"
Include dependency graph for itup.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct   IndexTupleData
 
 

Macros

#define  INDEX_SIZE_MASK   0x1FFF
 
 
#define  INDEX_VAR_MASK   0x4000
 
#define  INDEX_NULL_MASK   0x8000
 
 

Typedefs

typedef struct IndexTupleData  IndexTupleData
 
 
 
 

Functions

static Size  IndexTupleSize (const IndexTupleData *itup)
 
static bool  IndexTupleHasNulls (const IndexTupleData *itup)
 
static bool  IndexTupleHasVarwidths (const IndexTupleData *itup)
 
IndexTuple  index_form_tuple (TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
 
IndexTuple  index_form_tuple_context (TupleDesc tupleDescriptor, const Datum *values, const bool *isnull, MemoryContext context)
 
 
void  index_deform_tuple (IndexTuple tup, TupleDesc tupleDescriptor, Datum *values, bool *isnull)
 
void  index_deform_tuple_internal (TupleDesc tupleDescriptor, Datum *values, bool *isnull, char *tp, bits8 *bp, int hasnulls)
 
 
IndexTuple  index_truncate_tuple (TupleDesc sourceDescriptor, IndexTuple source, int leavenatts)
 
static Size  IndexInfoFindDataOffset (unsigned short t_info)
 
static Datum  index_getattr (IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
 

Macro Definition Documentation

INDEX_AM_RESERVED_BIT

#define INDEX_AM_RESERVED_BIT
Value:
0x2000 /* reserved for index-AM specific
* usage */

Definition at line 66 of file itup.h.

INDEX_NULL_MASK

#define INDEX_NULL_MASK   0x8000

Definition at line 68 of file itup.h.

INDEX_SIZE_MASK

#define INDEX_SIZE_MASK   0x1FFF

Definition at line 65 of file itup.h.

INDEX_VAR_MASK

#define INDEX_VAR_MASK   0x4000

Definition at line 67 of file itup.h.

MaxIndexTuplesPerPage

#define MaxIndexTuplesPerPage
Value:
((int) ((BLCKSZ - SizeOfPageHeaderData) / \
(MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
#define SizeOfPageHeaderData
Definition: bufpage.h:217
#define MAXALIGN(LEN)
Definition: c.h:810
struct ItemIdData ItemIdData

Definition at line 181 of file itup.h.

Typedef Documentation

IndexAttributeBitMap

Definition at line 60 of file itup.h.

IndexAttributeBitMapData

IndexTuple

Definition at line 53 of file itup.h.

IndexTupleData

Function Documentation

CopyIndexTuple()

IndexTuple CopyIndexTuple ( IndexTuple  source )

Definition at line 547 of file indextuple.c.

548{
549 IndexTuple result;
550 Size size;
551
552 size = IndexTupleSize(source);
553 result = (IndexTuple) palloc(size);
554 memcpy(result, source, size);
555 return result;
556}
size_t Size
Definition: c.h:610
IndexTupleData * IndexTuple
Definition: itup.h:53
static Size IndexTupleSize(const IndexTupleData *itup)
Definition: itup.h:71
void * palloc(Size size)
Definition: mcxt.c:1365
static rewind_source * source
Definition: pg_rewind.c:89

References IndexTupleSize(), palloc(), and source.

Referenced by _bt_buildadd(), _bt_insert_parent(), _bt_insertonpg(), _bt_load(), _bt_newlevel(), _bt_pagedel(), _bt_swap_posting(), _hash_splitbucket(), _hash_squeezebucket(), btree_xlog_insert(), btree_xlog_split(), gin_check_parent_keys_consistency(), gin_refind_parent(), gistformdownlink(), and index_truncate_tuple().

index_deform_tuple()

void index_deform_tuple ( IndexTuple  tup,
TupleDesc  tupleDescriptor,
Datumvalues,
bool *  isnull 
)

Definition at line 456 of file indextuple.c.

458{
459 char *tp; /* ptr to tuple data */
460 bits8 *bp; /* ptr to null bitmap in tuple */
461
462 /* XXX "knows" t_bits are just after fixed tuple header! */
463 bp = (bits8 *) ((char *) tup + sizeof(IndexTupleData));
464
465 tp = (char *) tup + IndexInfoFindDataOffset(tup->t_info);
466
467 index_deform_tuple_internal(tupleDescriptor, values, isnull,
468 tp, bp, IndexTupleHasNulls(tup));
469}
static Datum values[MAXATTR]
Definition: bootstrap.c:153
uint8 bits8
Definition: c.h:545
void index_deform_tuple_internal(TupleDesc tupleDescriptor, Datum *values, bool *isnull, char *tp, bits8 *bp, int hasnulls)
Definition: indextuple.c:479
static bool IndexTupleHasNulls(const IndexTupleData *itup)
Definition: itup.h:77
struct IndexTupleData IndexTupleData
static Size IndexInfoFindDataOffset(unsigned short t_info)
Definition: itup.h:112
unsigned short t_info
Definition: itup.h:49

References index_deform_tuple_internal(), IndexInfoFindDataOffset(), IndexTupleHasNulls(), IndexTupleData::t_info, and values.

Referenced by _bt_check_unique(), comparetup_index_btree_tiebreak(), get_actual_variable_endpoint(), gist_page_items(), index_truncate_tuple(), and StoreIndexTuple().

index_deform_tuple_internal()

void index_deform_tuple_internal ( TupleDesc  tupleDescriptor,
Datumvalues,
bool *  isnull,
char *  tp,
bits8bp,
int  hasnulls 
)

Definition at line 479 of file indextuple.c.

482{
483 int natts = tupleDescriptor->natts; /* number of atts to extract */
484 int attnum;
485 int off = 0; /* offset in tuple data */
486 bool slow = false; /* can we use/set attcacheoff? */
487
488 /* Assert to protect callers who allocate fixed-size arrays */
489 Assert(natts <= INDEX_MAX_KEYS);
490
491 for (attnum = 0; attnum < natts; attnum++)
492 {
493 CompactAttribute *thisatt = TupleDescCompactAttr(tupleDescriptor, attnum);
494
495 if (hasnulls && att_isnull(attnum, bp))
496 {
497 values[attnum] = (Datum) 0;
498 isnull[attnum] = true;
499 slow = true; /* can't use attcacheoff anymore */
500 continue;
501 }
502
503 isnull[attnum] = false;
504
505 if (!slow && thisatt->attcacheoff >= 0)
506 off = thisatt->attcacheoff;
507 else if (thisatt->attlen == -1)
508 {
509 /*
510 * We can only cache the offset for a varlena attribute if the
511 * offset is already suitably aligned, so that there would be no
512 * pad bytes in any case: then the offset will be valid for either
513 * an aligned or unaligned value.
514 */
515 if (!slow &&
516 off == att_nominal_alignby(off, thisatt->attalignby))
517 thisatt->attcacheoff = off;
518 else
519 {
520 off = att_pointer_alignby(off, thisatt->attalignby, -1,
521 tp + off);
522 slow = true;
523 }
524 }
525 else
526 {
527 /* not varlena, so safe to use att_nominal_alignby */
528 off = att_nominal_alignby(off, thisatt->attalignby);
529
530 if (!slow)
531 thisatt->attcacheoff = off;
532 }
533
534 values[attnum] = fetchatt(thisatt, tp + off);
535
536 off = att_addlength_pointer(off, thisatt->attlen, tp + off);
537
538 if (thisatt->attlen <= 0)
539 slow = true; /* can't use attcacheoff anymore */
540 }
541}
Assert(PointerIsAligned(start, uint64))
int16 attnum
Definition: pg_attribute.h:74
#define INDEX_MAX_KEYS
uint64_t Datum
Definition: postgres.h:70
uint8 attalignby
Definition: tupdesc.h:80
int16 attlen
Definition: tupdesc.h:71
int32 attcacheoff
Definition: tupdesc.h:70
int natts
Definition: tupdesc.h:137
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:175
#define att_nominal_alignby(cur_offset, attalignby)
Definition: tupmacs.h:160
static bool att_isnull(int ATT, const bits8 *BITS)
Definition: tupmacs.h:26
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:180
#define att_pointer_alignby(cur_offset, attalignby, attlen, attptr)
Definition: tupmacs.h:124
#define fetchatt(A, T)
Definition: tupmacs.h:44

References Assert(), att_addlength_pointer, att_isnull(), att_nominal_alignby, att_pointer_alignby, CompactAttribute::attalignby, CompactAttribute::attcacheoff, CompactAttribute::attlen, attnum, fetchatt, INDEX_MAX_KEYS, TupleDescData::natts, TupleDescCompactAttr(), and values.

Referenced by index_deform_tuple(), and spgDeformLeafTuple().

index_form_tuple()

IndexTuple index_form_tuple ( TupleDesc  tupleDescriptor,
const Datumvalues,
const bool *  isnull 
)

Definition at line 44 of file indextuple.c.

47{
48 return index_form_tuple_context(tupleDescriptor, values, isnull,
50}
IndexTuple index_form_tuple_context(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull, MemoryContext context)
Definition: indextuple.c:65
MemoryContext CurrentMemoryContext
Definition: mcxt.c:160

References CurrentMemoryContext, index_form_tuple_context(), and values.

Referenced by bt_normalize_tuple(), bt_tuple_present_callback(), btinsert(), GinFormTuple(), gistFormTuple(), hashbuildCallback(), hashinsert(), and index_truncate_tuple().

index_form_tuple_context()

IndexTuple index_form_tuple_context ( TupleDesc  tupleDescriptor,
const Datumvalues,
const bool *  isnull,
MemoryContext  context 
)

Definition at line 65 of file indextuple.c.

69{
70 char *tp; /* tuple pointer */
71 IndexTuple tuple; /* return tuple */
72 Size size,
73 data_size,
74 hoff;
75 int i;
76 unsigned short infomask = 0;
77 bool hasnull = false;
78 uint16 tupmask = 0;
79 int numberOfAttributes = tupleDescriptor->natts;
80
81#ifdef TOAST_INDEX_HACK
82 Datum untoasted_values[INDEX_MAX_KEYS] = {0};
83 bool untoasted_free[INDEX_MAX_KEYS] = {0};
84#endif
85
86 if (numberOfAttributes > INDEX_MAX_KEYS)
88 (errcode(ERRCODE_TOO_MANY_COLUMNS),
89 errmsg("number of index columns (%d) exceeds limit (%d)",
90 numberOfAttributes, INDEX_MAX_KEYS)));
91
92#ifdef TOAST_INDEX_HACK
93 for (i = 0; i < numberOfAttributes; i++)
94 {
95 Form_pg_attribute att = TupleDescAttr(tupleDescriptor, i);
96
97 untoasted_values[i] = values[i];
98 untoasted_free[i] = false;
99
100 /* Do nothing if value is NULL or not of varlena type */
101 if (isnull[i] || att->attlen != -1)
102 continue;
103
104 /*
105 * If value is stored EXTERNAL, must fetch it so we are not depending
106 * on outside storage. This should be improved someday.
107 */
109 {
110 untoasted_values[i] =
113 untoasted_free[i] = true;
114 }
115
116 /*
117 * If value is above size target, and is of a compressible datatype,
118 * try to compress it in-line.
119 */
120 if (!VARATT_IS_EXTENDED(DatumGetPointer(untoasted_values[i])) &&
121 VARSIZE(DatumGetPointer(untoasted_values[i])) > TOAST_INDEX_TARGET &&
122 (att->attstorage == TYPSTORAGE_EXTENDED ||
123 att->attstorage == TYPSTORAGE_MAIN))
124 {
125 Datum cvalue;
126
127 cvalue = toast_compress_datum(untoasted_values[i],
128 att->attcompression);
129
130 if (DatumGetPointer(cvalue) != NULL)
131 {
132 /* successful compression */
133 if (untoasted_free[i])
134 pfree(DatumGetPointer(untoasted_values[i]));
135 untoasted_values[i] = cvalue;
136 untoasted_free[i] = true;
137 }
138 }
139 }
140#endif
141
142 for (i = 0; i < numberOfAttributes; i++)
143 {
144 if (isnull[i])
145 {
146 hasnull = true;
147 break;
148 }
149 }
150
151 if (hasnull)
152 infomask |= INDEX_NULL_MASK;
153
154 hoff = IndexInfoFindDataOffset(infomask);
155#ifdef TOAST_INDEX_HACK
156 data_size = heap_compute_data_size(tupleDescriptor,
157 untoasted_values, isnull);
158#else
159 data_size = heap_compute_data_size(tupleDescriptor,
160 values, isnull);
161#endif
162 size = hoff + data_size;
163 size = MAXALIGN(size); /* be conservative */
164
165 tp = (char *) MemoryContextAllocZero(context, size);
166 tuple = (IndexTuple) tp;
167
168 heap_fill_tuple(tupleDescriptor,
169#ifdef TOAST_INDEX_HACK
170 untoasted_values,
171#else
172 values,
173#endif
174 isnull,
175 (char *) tp + hoff,
176 data_size,
177 &tupmask,
178 (hasnull ? (bits8 *) tp + sizeof(IndexTupleData) : NULL));
179
180#ifdef TOAST_INDEX_HACK
181 for (i = 0; i < numberOfAttributes; i++)
182 {
183 if (untoasted_free[i])
184 pfree(DatumGetPointer(untoasted_values[i]));
185 }
186#endif
187
188 /*
189 * We do this because heap_fill_tuple wants to initialize a "tupmask"
190 * which is used for HeapTuples, but we want an indextuple infomask. The
191 * only relevant info is the "has variable attributes" field. We have
192 * already set the hasnull bit above.
193 */
194 if (tupmask & HEAP_HASVARWIDTH)
195 infomask |= INDEX_VAR_MASK;
196
197 /* Also assert we got rid of external attributes */
198#ifdef TOAST_INDEX_HACK
199 Assert((tupmask & HEAP_HASEXTERNAL) == 0);
200#endif
201
202 /*
203 * Here we make sure that the size will fit in the field reserved for it
204 * in t_info.
205 */
206 if ((size & INDEX_SIZE_MASK) != size)
208 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
209 errmsg("index row requires %zu bytes, maximum size is %zu",
210 size, (Size) INDEX_SIZE_MASK)));
211
212 infomask |= size;
213
214 /*
215 * initialize metadata
216 */
217 tuple->t_info = infomask;
218 return tuple;
219}
uint16_t uint16
Definition: c.h:537
struct varlena * detoast_external_attr(struct varlena *attr)
Definition: detoast.c:45
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
#define TOAST_INDEX_TARGET
Definition: heaptoast.h:68
Size heap_compute_data_size(TupleDesc tupleDesc, const Datum *values, const bool *isnull)
Definition: heaptuple.c:219
void heap_fill_tuple(TupleDesc tupleDesc, const Datum *values, const bool *isnull, char *data, Size data_size, uint16 *infomask, bits8 *bit)
Definition: heaptuple.c:401
#define HEAP_HASVARWIDTH
Definition: htup_details.h:191
#define HEAP_HASEXTERNAL
Definition: htup_details.h:192
#define TOAST_INDEX_HACK
Definition: indextuple.c:29
i
int i
Definition: isn.c:77
#define INDEX_VAR_MASK
Definition: itup.h:67
#define INDEX_NULL_MASK
Definition: itup.h:68
#define INDEX_SIZE_MASK
Definition: itup.h:65
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1263
void pfree(void *pointer)
Definition: mcxt.c:1594
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:322
Definition: c.h:692
Datum toast_compress_datum(Datum value, char cmethod)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160
static bool VARATT_IS_EXTENDED(const void *PTR)
Definition: varatt.h:410
static bool VARATT_IS_EXTERNAL(const void *PTR)
Definition: varatt.h:354
static Size VARSIZE(const void *PTR)
Definition: varatt.h:298

References Assert(), DatumGetPointer(), detoast_external_attr(), ereport, errcode(), errmsg(), ERROR, heap_compute_data_size(), heap_fill_tuple(), HEAP_HASEXTERNAL, HEAP_HASVARWIDTH, i, INDEX_MAX_KEYS, INDEX_NULL_MASK, INDEX_SIZE_MASK, INDEX_VAR_MASK, IndexInfoFindDataOffset(), MAXALIGN, MemoryContextAllocZero(), TupleDescData::natts, pfree(), PointerGetDatum(), IndexTupleData::t_info, toast_compress_datum(), TOAST_INDEX_HACK, TOAST_INDEX_TARGET, TupleDescAttr(), values, VARATT_IS_EXTENDED(), VARATT_IS_EXTERNAL(), and VARSIZE().

Referenced by index_form_tuple(), and tuplesort_putindextuplevalues().

index_getattr()

static Datum index_getattr ( IndexTuple  tup,
int  attnum,
TupleDesc  tupleDesc,
bool *  isnull 
)
inlinestatic

Definition at line 131 of file itup.h.

133{
134 Assert(isnull);
135 Assert(attnum > 0);
136
137 *isnull = false;
138
139 if (!IndexTupleHasNulls(tup))
140 {
141 CompactAttribute *attr = TupleDescCompactAttr(tupleDesc, attnum - 1);
142
143 if (attr->attcacheoff >= 0)
144 {
145 return fetchatt(attr,
146 (char *) tup + IndexInfoFindDataOffset(tup->t_info) +
147 attr->attcacheoff);
148 }
149 else
150 return nocache_index_getattr(tup, attnum, tupleDesc);
151 }
152 else
153 {
154 if (att_isnull(attnum - 1, (bits8 *) tup + sizeof(IndexTupleData)))
155 {
156 *isnull = true;
157 return (Datum) 0;
158 }
159 else
160 return nocache_index_getattr(tup, attnum, tupleDesc);
161 }
Datum nocache_index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc)
Definition: indextuple.c:241

References Assert(), att_isnull(), CompactAttribute::attcacheoff, attnum, fetchatt, IndexInfoFindDataOffset(), IndexTupleHasNulls(), nocache_index_getattr(), IndexTupleData::t_info, and TupleDescCompactAttr().

Referenced by _bt_advance_array_keys(), _bt_check_compare(), _bt_check_rowcompare(), _bt_compare(), _bt_keep_natts(), _bt_keep_natts_fast(), _bt_load(), _bt_mkscankey(), _bt_set_startikey(), _bt_tuple_before_array_skeys(), _hash_checkqual(), bt_normalize_tuple(), comparetup_index_btree_tiebreak(), gintuple_get_attrnum(), gintuple_get_key(), gistchoose(), gistDeCompressAtt(), gistFetchTuple(), gistindex_keytest(), gistMakeUnionItVec(), gistSplitByKey(), readtup_index(), removeabbrev_index(), and tuplesort_putindextuplevalues().

index_truncate_tuple()

IndexTuple index_truncate_tuple ( TupleDesc  sourceDescriptor,
IndexTuple  source,
int  leavenatts 
)

Definition at line 576 of file indextuple.c.

578{
579 TupleDesc truncdesc;
581 bool isnull[INDEX_MAX_KEYS];
582 IndexTuple truncated;
583
584 Assert(leavenatts <= sourceDescriptor->natts);
585
586 /* Easy case: no truncation actually required */
587 if (leavenatts == sourceDescriptor->natts)
588 return CopyIndexTuple(source);
589
590 /* Create temporary truncated tuple descriptor */
591 truncdesc = CreateTupleDescTruncatedCopy(sourceDescriptor, leavenatts);
592
593 /* Deform, form copy of tuple with fewer attributes */
594 index_deform_tuple(source, truncdesc, values, isnull);
595 truncated = index_form_tuple(truncdesc, values, isnull);
596 truncated->t_tid = source->t_tid;
598
599 /*
600 * Cannot leak memory here, TupleDescCopy() doesn't allocate any inner
601 * structure, so, plain pfree() should clean all allocated memory
602 */
603 pfree(truncdesc);
604
605 return truncated;
606}
void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: indextuple.c:456
IndexTuple CopyIndexTuple(IndexTuple source)
Definition: indextuple.c:547
IndexTuple index_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: indextuple.c:44
ItemPointerData t_tid
Definition: itup.h:37
TupleDesc CreateTupleDescTruncatedCopy(TupleDesc tupdesc, int natts)
Definition: tupdesc.c:296

References Assert(), CopyIndexTuple(), CreateTupleDescTruncatedCopy(), index_deform_tuple(), index_form_tuple(), INDEX_MAX_KEYS, IndexTupleSize(), TupleDescData::natts, pfree(), source, IndexTupleData::t_tid, and values.

Referenced by _bt_truncate().

IndexInfoFindDataOffset()

static Size IndexInfoFindDataOffset ( unsigned short  t_info )
inlinestatic

Definition at line 112 of file itup.h.

114{
115 if (!(t_info & INDEX_NULL_MASK))
116 return MAXALIGN(sizeof(IndexTupleData));
117 else
118 return MAXALIGN(sizeof(IndexTupleData) + sizeof(IndexAttributeBitMapData));

References INDEX_NULL_MASK, and MAXALIGN.

Referenced by _hash_get_indextuple_hashkey(), bt_page_print_tuples(), index_deform_tuple(), index_form_tuple_context(), index_getattr(), and nocache_index_getattr().

IndexTupleHasNulls()

static bool IndexTupleHasNulls ( const IndexTupleDataitup )
inlinestatic

Definition at line 77 of file itup.h.

79{
80 return itup->t_info & INDEX_NULL_MASK;

References INDEX_NULL_MASK, and IndexTupleData::t_info.

Referenced by bt_page_print_tuples(), GinFormTuple(), index_deform_tuple(), index_getattr(), nocache_index_getattr(), and spgExtractNodeLabels().

IndexTupleHasVarwidths()

static bool IndexTupleHasVarwidths ( const IndexTupleDataitup )
inlinestatic

Definition at line 83 of file itup.h.

85{
86 return itup->t_info & INDEX_VAR_MASK;

References INDEX_VAR_MASK, and IndexTupleData::t_info.

Referenced by bt_normalize_tuple(), bt_page_print_tuples(), and nocache_index_getattr().

IndexTupleSize()

static Size IndexTupleSize ( const IndexTupleDataitup )
inlinestatic

Definition at line 71 of file itup.h.

73{
74 return (itup->t_info & INDEX_SIZE_MASK);

References INDEX_SIZE_MASK, and IndexTupleData::t_info.

Referenced by _bt_buildadd(), _bt_check_third_page(), _bt_dedup_finish_pending(), _bt_dedup_save_htid(), _bt_dedup_start_pending(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_doinsert(), _bt_form_posting(), _bt_insert_parent(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_recsplitloc(), _bt_restore_page(), _bt_saveitem(), _bt_sort_dedup_finish_pending(), _bt_split(), _bt_truncate(), _hash_doinsert(), _hash_pgaddmultitup(), _hash_splitbucket(), _hash_squeezebucket(), bt_check_level_from_leftmost(), bt_page_print_tuples(), bt_pivot_tuple_identical(), bt_rootdescend(), bt_target_page_check(), bt_tuple_present_callback(), btree_xlog_insert(), btree_xlog_split(), btree_xlog_updates(), BTreeTupleGetHeapTID(), CopyIndexTuple(), decodePageSplitRecord(), entryExecPlaceToPage(), entryIsEnoughSpace(), entrySplitPage(), GetBTPageStatistics(), gin_check_parent_keys_consistency(), ginEntryFillRoot(), GinFormInteriorTuple(), GinFormTuple(), ginHeapTupleFastCollect(), ginHeapTupleFastInsert(), ginRedoInsertEntry(), ginRedoInsertListPage(), ginRedoUpdateMetapage(), ginVacuumEntryPage(), gist_indexsortbuild_levelstate_add(), gist_indexsortbuild_levelstate_flush(), gist_page_items(), gist_page_items_bytea(), gistBuildCallback(), gistfillbuffer(), gistfillitupvec(), gistfitpage(), gistGetItupFromPage(), gistnospace(), gistPlaceItupToPage(), gistplacetopage(), gistRedoPageUpdateRecord(), gistSplit(), gistXLogUpdate(), hash_xlog_move_page_contents(), hash_xlog_squeeze_page(), index_truncate_tuple(), makeSublist(), spgFormInnerTuple(), writeListPage(), and writetup_index().

nocache_index_getattr()

Datum nocache_index_getattr ( IndexTuple  tup,
int  attnum,
TupleDesc  tupleDesc 
)

Definition at line 241 of file indextuple.c.

244{
245 char *tp; /* ptr to data part of tuple */
246 bits8 *bp = NULL; /* ptr to null bitmap in tuple */
247 bool slow = false; /* do we have to walk attrs? */
248 int data_off; /* tuple data offset */
249 int off; /* current offset within data */
250
251 /* ----------------
252 * Three cases:
253 *
254 * 1: No nulls and no variable-width attributes.
255 * 2: Has a null or a var-width AFTER att.
256 * 3: Has nulls or var-widths BEFORE att.
257 * ----------------
258 */
259
260 data_off = IndexInfoFindDataOffset(tup->t_info);
261
262 attnum--;
263
264 if (IndexTupleHasNulls(tup))
265 {
266 /*
267 * there's a null somewhere in the tuple
268 *
269 * check to see if desired att is null
270 */
271
272 /* XXX "knows" t_bits are just after fixed tuple header! */
273 bp = (bits8 *) ((char *) tup + sizeof(IndexTupleData));
274
275 /*
276 * Now check to see if any preceding bits are null...
277 */
278 {
279 int byte = attnum >> 3;
280 int finalbit = attnum & 0x07;
281
282 /* check for nulls "before" final bit of last byte */
283 if ((~bp[byte]) & ((1 << finalbit) - 1))
284 slow = true;
285 else
286 {
287 /* check for nulls in any "earlier" bytes */
288 int i;
289
290 for (i = 0; i < byte; i++)
291 {
292 if (bp[i] != 0xFF)
293 {
294 slow = true;
295 break;
296 }
297 }
298 }
299 }
300 }
301
302 tp = (char *) tup + data_off;
303
304 if (!slow)
305 {
306 CompactAttribute *att;
307
308 /*
309 * If we get here, there are no nulls up to and including the target
310 * attribute. If we have a cached offset, we can use it.
311 */
312 att = TupleDescCompactAttr(tupleDesc, attnum);
313 if (att->attcacheoff >= 0)
314 return fetchatt(att, tp + att->attcacheoff);
315
316 /*
317 * Otherwise, check for non-fixed-length attrs up to and including
318 * target. If there aren't any, it's safe to cheaply initialize the
319 * cached offsets for these attrs.
320 */
321 if (IndexTupleHasVarwidths(tup))
322 {
323 int j;
324
325 for (j = 0; j <= attnum; j++)
326 {
327 if (TupleDescCompactAttr(tupleDesc, j)->attlen <= 0)
328 {
329 slow = true;
330 break;
331 }
332 }
333 }
334 }
335
336 if (!slow)
337 {
338 int natts = tupleDesc->natts;
339 int j = 1;
340
341 /*
342 * If we get here, we have a tuple with no nulls or var-widths up to
343 * and including the target attribute, so we can use the cached offset
344 * ... only we don't have it yet, or we'd not have got here. Since
345 * it's cheap to compute offsets for fixed-width columns, we take the
346 * opportunity to initialize the cached offsets for *all* the leading
347 * fixed-width columns, in hope of avoiding future visits to this
348 * routine.
349 */
350 TupleDescCompactAttr(tupleDesc, 0)->attcacheoff = 0;
351
352 /* we might have set some offsets in the slow path previously */
353 while (j < natts && TupleDescCompactAttr(tupleDesc, j)->attcacheoff > 0)
354 j++;
355
356 off = TupleDescCompactAttr(tupleDesc, j - 1)->attcacheoff +
357 TupleDescCompactAttr(tupleDesc, j - 1)->attlen;
358
359 for (; j < natts; j++)
360 {
361 CompactAttribute *att = TupleDescCompactAttr(tupleDesc, j);
362
363 if (att->attlen <= 0)
364 break;
365
366 off = att_nominal_alignby(off, att->attalignby);
367
368 att->attcacheoff = off;
369
370 off += att->attlen;
371 }
372
373 Assert(j > attnum);
374
375 off = TupleDescCompactAttr(tupleDesc, attnum)->attcacheoff;
376 }
377 else
378 {
379 bool usecache = true;
380 int i;
381
382 /*
383 * Now we know that we have to walk the tuple CAREFULLY. But we still
384 * might be able to cache some offsets for next time.
385 *
386 * Note - This loop is a little tricky. For each non-null attribute,
387 * we have to first account for alignment padding before the attr,
388 * then advance over the attr based on its length. Nulls have no
389 * storage and no alignment padding either. We can use/set
390 * attcacheoff until we reach either a null or a var-width attribute.
391 */
392 off = 0;
393 for (i = 0;; i++) /* loop exit is at "break" */
394 {
395 CompactAttribute *att = TupleDescCompactAttr(tupleDesc, i);
396
397 if (IndexTupleHasNulls(tup) && att_isnull(i, bp))
398 {
399 usecache = false;
400 continue; /* this cannot be the target att */
401 }
402
403 /* If we know the next offset, we can skip the rest */
404 if (usecache && att->attcacheoff >= 0)
405 off = att->attcacheoff;
406 else if (att->attlen == -1)
407 {
408 /*
409 * We can only cache the offset for a varlena attribute if the
410 * offset is already suitably aligned, so that there would be
411 * no pad bytes in any case: then the offset will be valid for
412 * either an aligned or unaligned value.
413 */
414 if (usecache &&
415 off == att_nominal_alignby(off, att->attalignby))
416 att->attcacheoff = off;
417 else
418 {
419 off = att_pointer_alignby(off, att->attalignby, -1,
420 tp + off);
421 usecache = false;
422 }
423 }
424 else
425 {
426 /* not varlena, so safe to use att_nominal_alignby */
427 off = att_nominal_alignby(off, att->attalignby);
428
429 if (usecache)
430 att->attcacheoff = off;
431 }
432
433 if (i == attnum)
434 break;
435
436 off = att_addlength_pointer(off, att->attlen, tp + off);
437
438 if (usecache && att->attlen <= 0)
439 usecache = false;
440 }
441 }
442
443 return fetchatt(TupleDescCompactAttr(tupleDesc, attnum), tp + off);
444}
j
int j
Definition: isn.c:78
static bool IndexTupleHasVarwidths(const IndexTupleData *itup)
Definition: itup.h:83
int16 attlen
Definition: pg_attribute.h:59

References Assert(), att_addlength_pointer, att_isnull(), att_nominal_alignby, att_pointer_alignby, CompactAttribute::attalignby, CompactAttribute::attcacheoff, CompactAttribute::attlen, attlen, attnum, fetchatt, i, IndexInfoFindDataOffset(), IndexTupleHasNulls(), IndexTupleHasVarwidths(), j, TupleDescData::natts, IndexTupleData::t_info, and TupleDescCompactAttr().

Referenced by index_getattr().

AltStyle によって変換されたページ (->オリジナル) /