#include "postgres.h"
#include "access/gin_private.h"
#include "utils/rel.h"
Go to the source code of this file.
static OffsetNumber entryFindChildPtr | ( | GinBtree | btree, | |
Page | page, | |||
BlockNumber | blkno, | |||
OffsetNumber | storedOff | |||
) | [static] |
Definition at line 374 of file ginentrypage.c.
References Assert, FirstOffsetNumber, GinGetDownlink, GinPageIsData, GinPageIsLeaf, i, PageGetItem, PageGetItemId, and PageGetMaxOffsetNumber.
{ OffsetNumber i, maxoff = PageGetMaxOffsetNumber(page); IndexTuple itup; Assert(!GinPageIsLeaf(page)); Assert(!GinPageIsData(page)); /* if page isn't changed, we returns storedOff */ if (storedOff >= FirstOffsetNumber && storedOff <= maxoff) { itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, storedOff)); if (GinGetDownlink(itup) == blkno) return storedOff; /* * we hope, that needed pointer goes to right. It's true if there * wasn't a deletion */ for (i = storedOff + 1; i <= maxoff; i++) { itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, i)); if (GinGetDownlink(itup) == blkno) return i; } maxoff = storedOff - 1; } /* last chance */ for (i = FirstOffsetNumber; i <= maxoff; i++) { itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, i)); if (GinGetDownlink(itup) == blkno) return i; } return InvalidOffsetNumber; }
static BlockNumber entryGetLeftMostPage | ( | GinBtree | btree, | |
Page | page | |||
) | [static] |
Definition at line 415 of file ginentrypage.c.
References Assert, FirstOffsetNumber, GinGetDownlink, GinPageIsData, GinPageIsLeaf, PageGetItem, PageGetItemId, and PageGetMaxOffsetNumber.
{ IndexTuple itup; Assert(!GinPageIsLeaf(page)); Assert(!GinPageIsData(page)); Assert(PageGetMaxOffsetNumber(page) >= FirstOffsetNumber); itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, FirstOffsetNumber)); return GinGetDownlink(itup); }
static bool entryIsEnoughSpace | ( | GinBtree | btree, | |
Buffer | buf, | |||
OffsetNumber | off | |||
) | [static] |
Definition at line 428 of file ginentrypage.c.
References Assert, BufferGetPage, GinBtreeData::entry, GinPageIsData, IndexTupleSize, GinBtreeData::isDelete, MAXALIGN, PageGetFreeSpace(), PageGetItem, and PageGetItemId.
{ Size itupsz = 0; Page page = BufferGetPage(buf); Assert(btree->entry); Assert(!GinPageIsData(page)); if (btree->isDelete) { IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off)); itupsz = MAXALIGN(IndexTupleSize(itup)) + sizeof(ItemIdData); } if (PageGetFreeSpace(page) + itupsz >= MAXALIGN(IndexTupleSize(btree->entry)) + sizeof(ItemIdData)) return true; return false; }
Definition at line 212 of file ginentrypage.c.
References GinBtreeData::entryAttnum, GinBtreeData::entryCategory, GinBtreeData::entryKey, getRightMostTuple(), ginCompareAttEntries(), GinPageRightMost, GinBtreeData::ginstate, gintuple_get_attrnum(), and gintuple_get_key().
{ IndexTuple itup; OffsetNumber attnum; Datum key; GinNullCategory category; if (GinPageRightMost(page)) return FALSE; itup = getRightMostTuple(page); attnum = gintuple_get_attrnum(btree->ginstate, itup); key = gintuple_get_key(btree->ginstate, itup, &category); if (ginCompareAttEntries(btree->ginstate, btree->entryAttnum, btree->entryKey, btree->entryCategory, attnum, key, category) > 0) return TRUE; return FALSE; }
static BlockNumber entryLocateEntry | ( | GinBtree | btree, | |
GinBtreeStack * | stack | |||
) | [static] |
Definition at line 239 of file ginentrypage.c.
References Assert, GinBtreeStack::buffer, BufferGetPage, GinBtreeData::entryAttnum, GinBtreeData::entryCategory, GinBtreeData::entryKey, FirstOffsetNumber, GinBtreeData::fullScan, GinBtreeData::getLeftMostPage, GIN_ROOT_BLKNO, ginCompareAttEntries(), GinGetDownlink, GinPageIsData, GinPageIsLeaf, GinPageRightMost, GinBtreeData::ginstate, gintuple_get_attrnum(), gintuple_get_key(), GinBtreeStack::off, PageGetItem, PageGetItemId, PageGetMaxOffsetNumber, and GinBtreeStack::predictNumber.
{ OffsetNumber low, high, maxoff; IndexTuple itup = NULL; int result; Page page = BufferGetPage(stack->buffer); Assert(!GinPageIsLeaf(page)); Assert(!GinPageIsData(page)); if (btree->fullScan) { stack->off = FirstOffsetNumber; stack->predictNumber *= PageGetMaxOffsetNumber(page); return btree->getLeftMostPage(btree, page); } low = FirstOffsetNumber; maxoff = high = PageGetMaxOffsetNumber(page); Assert(high >= low); high++; while (high > low) { OffsetNumber mid = low + ((high - low) / 2); if (mid == maxoff && GinPageRightMost(page)) { /* Right infinity */ result = -1; } else { OffsetNumber attnum; Datum key; GinNullCategory category; itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, mid)); attnum = gintuple_get_attrnum(btree->ginstate, itup); key = gintuple_get_key(btree->ginstate, itup, &category); result = ginCompareAttEntries(btree->ginstate, btree->entryAttnum, btree->entryKey, btree->entryCategory, attnum, key, category); } if (result == 0) { stack->off = mid; Assert(GinGetDownlink(itup) != GIN_ROOT_BLKNO); return GinGetDownlink(itup); } else if (result > 0) low = mid + 1; else high = mid; } Assert(high >= FirstOffsetNumber && high <= maxoff); stack->off = high; itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, high)); Assert(GinGetDownlink(itup) != GIN_ROOT_BLKNO); return GinGetDownlink(itup); }
static bool entryLocateLeafEntry | ( | GinBtree | btree, | |
GinBtreeStack * | stack | |||
) | [static] |
Definition at line 315 of file ginentrypage.c.
References Assert, GinBtreeStack::buffer, BufferGetPage, GinBtreeData::entryAttnum, GinBtreeData::entryCategory, GinBtreeData::entryKey, GinBtreeData::fullScan, ginCompareAttEntries(), GinPageIsData, GinPageIsLeaf, GinBtreeData::ginstate, gintuple_get_attrnum(), gintuple_get_key(), GinBtreeStack::off, PageGetItem, PageGetItemId, and PageGetMaxOffsetNumber.
{ Page page = BufferGetPage(stack->buffer); OffsetNumber low, high; Assert(GinPageIsLeaf(page)); Assert(!GinPageIsData(page)); if (btree->fullScan) { stack->off = FirstOffsetNumber; return TRUE; } low = FirstOffsetNumber; high = PageGetMaxOffsetNumber(page); if (high < low) { stack->off = FirstOffsetNumber; return false; } high++; while (high > low) { OffsetNumber mid = low + ((high - low) / 2); IndexTuple itup; OffsetNumber attnum; Datum key; GinNullCategory category; int result; itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, mid)); attnum = gintuple_get_attrnum(btree->ginstate, itup); key = gintuple_get_key(btree->ginstate, itup, &category); result = ginCompareAttEntries(btree->ginstate, btree->entryAttnum, btree->entryKey, btree->entryCategory, attnum, key, category); if (result == 0) { stack->off = mid; return true; } else if (result > 0) low = mid + 1; else high = mid; } stack->off = high; return false; }
static void entryPlaceToPage | ( | GinBtree | btree, | |
Buffer | buf, | |||
OffsetNumber | off, | |||
XLogRecData ** | prdata | |||
) | [static] |
Definition at line 485 of file ginentrypage.c.
References ginxlogInsert::blkno, XLogRecData::buffer, XLogRecData::buffer_std, BufferGetBlockNumber(), BufferGetPage, XLogRecData::data, elog, GinBtreeData::entry, entryPreparePage(), ERROR, GinPageIsLeaf, GinBtreeData::index, IndexTupleSize, InvalidBlockNumber, ginxlogInsert::isData, GinBtreeData::isDelete, ginxlogInsert::isDelete, ginxlogInsert::isLeaf, XLogRecData::len, XLogRecData::next, ginxlogInsert::nitem, ginxlogInsert::node, ginxlogInsert::offset, PageAddItem(), RelationData::rd_node, RelationGetRelationName, TRUE, and ginxlogInsert::updateBlkno.
{ Page page = BufferGetPage(buf); OffsetNumber placed; int cnt = 0; /* these must be static so they can be returned to caller */ static XLogRecData rdata[3]; static ginxlogInsert data; *prdata = rdata; data.updateBlkno = entryPreparePage(btree, page, off); placed = PageAddItem(page, (Item) btree->entry, IndexTupleSize(btree->entry), off, false, false); if (placed != off) elog(ERROR, "failed to add item to index page in \"%s\"", RelationGetRelationName(btree->index)); data.node = btree->index->rd_node; data.blkno = BufferGetBlockNumber(buf); data.offset = off; data.nitem = 1; data.isDelete = btree->isDelete; data.isData = false; data.isLeaf = GinPageIsLeaf(page) ? TRUE : FALSE; /* * Prevent full page write if child's split occurs. That is needed to * remove incomplete splits while replaying WAL * * data.updateBlkno contains new block number (of newly created right * page) for recently splited page. */ if (data.updateBlkno == InvalidBlockNumber) { rdata[0].buffer = buf; rdata[0].buffer_std = TRUE; rdata[0].data = NULL; rdata[0].len = 0; rdata[0].next = &rdata[1]; cnt++; } rdata[cnt].buffer = InvalidBuffer; rdata[cnt].data = (char *) &data; rdata[cnt].len = sizeof(ginxlogInsert); rdata[cnt].next = &rdata[cnt + 1]; cnt++; rdata[cnt].buffer = InvalidBuffer; rdata[cnt].data = (char *) btree->entry; rdata[cnt].len = IndexTupleSize(btree->entry); rdata[cnt].next = NULL; btree->entry = NULL; }
static BlockNumber entryPreparePage | ( | GinBtree | btree, | |
Page | page, | |||
OffsetNumber | off | |||
) | [static] |
Definition at line 455 of file ginentrypage.c.
References Assert, GinBtreeData::entry, GinPageIsData, GinPageIsLeaf, GinSetDownlink, InvalidBlockNumber, GinBtreeData::isDelete, PageGetItem, PageGetItemId, PageIndexTupleDelete(), and GinBtreeData::rightblkno.
Referenced by entryPlaceToPage(), and entrySplitPage().
{ BlockNumber ret = InvalidBlockNumber; Assert(btree->entry); Assert(!GinPageIsData(page)); if (btree->isDelete) { Assert(GinPageIsLeaf(page)); PageIndexTupleDelete(page, off); } if (!GinPageIsLeaf(page) && btree->rightblkno != InvalidBlockNumber) { IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off)); GinSetDownlink(itup, btree->rightblkno); ret = btree->rightblkno; } btree->rightblkno = InvalidBlockNumber; return ret; }
static Page entrySplitPage | ( | GinBtree | btree, | |
Buffer | lbuf, | |||
Buffer | rbuf, | |||
OffsetNumber | off, | |||
XLogRecData ** | prdata | |||
) | [static] |
Definition at line 549 of file ginentrypage.c.
References XLogRecData::buffer, BufferGetBlockNumber(), BufferGetPage, XLogRecData::data, elog, GinBtreeData::entry, entryPreparePage(), ERROR, FirstOffsetNumber, GinFormInteriorTuple(), GinGetDownlink, GinInitPage(), GinPageGetOpaque, GinPageIsLeaf, i, GinBtreeData::index, IndexTupleSize, InvalidOffsetNumber, ginxlogSplit::isData, ginxlogSplit::isLeaf, ginxlogSplit::isRootSplit, ginxlogSplit::lblkno, ginxlogSplit::leftChildBlkno, XLogRecData::len, MAXALIGN, XLogRecData::next, ginxlogSplit::nitem, ginxlogSplit::node, PageAddItem(), PageGetItem, PageGetItemId, PageGetMaxOffsetNumber, PageGetPageSize, PageGetTempPageCopy(), ginxlogSplit::rblkno, RelationData::rd_node, RelationGetRelationName, GinBtreeData::rightblkno, ginxlogSplit::rootBlkno, ginxlogSplit::separator, totalsize, TRUE, and ginxlogSplit::updateBlkno.
{ OffsetNumber i, maxoff, separator = InvalidOffsetNumber; Size totalsize = 0; Size lsize = 0, size; char *ptr; IndexTuple itup, leftrightmost = NULL; Page page; Page lpage = PageGetTempPageCopy(BufferGetPage(lbuf)); Page rpage = BufferGetPage(rbuf); Size pageSize = PageGetPageSize(lpage); /* these must be static so they can be returned to caller */ static XLogRecData rdata[2]; static ginxlogSplit data; static char tupstore[2 * BLCKSZ]; *prdata = rdata; data.leftChildBlkno = (GinPageIsLeaf(lpage)) ? InvalidOffsetNumber : GinGetDownlink(btree->entry); data.updateBlkno = entryPreparePage(btree, lpage, off); maxoff = PageGetMaxOffsetNumber(lpage); ptr = tupstore; for (i = FirstOffsetNumber; i <= maxoff; i++) { if (i == off) { size = MAXALIGN(IndexTupleSize(btree->entry)); memcpy(ptr, btree->entry, size); ptr += size; totalsize += size + sizeof(ItemIdData); } itup = (IndexTuple) PageGetItem(lpage, PageGetItemId(lpage, i)); size = MAXALIGN(IndexTupleSize(itup)); memcpy(ptr, itup, size); ptr += size; totalsize += size + sizeof(ItemIdData); } if (off == maxoff + 1) { size = MAXALIGN(IndexTupleSize(btree->entry)); memcpy(ptr, btree->entry, size); ptr += size; totalsize += size + sizeof(ItemIdData); } GinInitPage(rpage, GinPageGetOpaque(lpage)->flags, pageSize); GinInitPage(lpage, GinPageGetOpaque(rpage)->flags, pageSize); ptr = tupstore; maxoff++; lsize = 0; page = lpage; for (i = FirstOffsetNumber; i <= maxoff; i++) { itup = (IndexTuple) ptr; if (lsize > totalsize / 2) { if (separator == InvalidOffsetNumber) separator = i - 1; page = rpage; } else { leftrightmost = itup; lsize += MAXALIGN(IndexTupleSize(itup)) + sizeof(ItemIdData); } if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber) elog(ERROR, "failed to add item to index page in \"%s\"", RelationGetRelationName(btree->index)); ptr += MAXALIGN(IndexTupleSize(itup)); } btree->entry = GinFormInteriorTuple(leftrightmost, lpage, BufferGetBlockNumber(lbuf)); btree->rightblkno = BufferGetBlockNumber(rbuf); data.node = btree->index->rd_node; data.rootBlkno = InvalidBlockNumber; data.lblkno = BufferGetBlockNumber(lbuf); data.rblkno = BufferGetBlockNumber(rbuf); data.separator = separator; data.nitem = maxoff; data.isData = FALSE; data.isLeaf = GinPageIsLeaf(lpage) ? TRUE : FALSE; data.isRootSplit = FALSE; rdata[0].buffer = InvalidBuffer; rdata[0].data = (char *) &data; rdata[0].len = sizeof(ginxlogSplit); rdata[0].next = &rdata[1]; rdata[1].buffer = InvalidBuffer; rdata[1].data = tupstore; rdata[1].len = MAXALIGN(totalsize); rdata[1].next = NULL; return lpage; }
static IndexTuple getRightMostTuple | ( | Page | page | ) | [static] |
Definition at line 204 of file ginentrypage.c.
References PageGetItem, PageGetItemId, and PageGetMaxOffsetNumber.
Referenced by entryIsMoveRight(), and ginPageGetLinkItup().
{ OffsetNumber maxoff = PageGetMaxOffsetNumber(page); return (IndexTuple) PageGetItem(page, PageGetItemId(page, maxoff)); }
Definition at line 682 of file ginentrypage.c.
References BufferGetPage, elog, ERROR, ginPageGetLinkItup(), IndexTupleSize, InvalidOffsetNumber, PageAddItem(), and pfree().
Referenced by ginRedoSplit().
{ Page page; IndexTuple itup; page = BufferGetPage(root); itup = ginPageGetLinkItup(lbuf); if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber) elog(ERROR, "failed to add item to index root page"); pfree(itup); itup = ginPageGetLinkItup(rbuf); if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber) elog(ERROR, "failed to add item to index root page"); pfree(itup); }
static IndexTuple GinFormInteriorTuple | ( | IndexTuple | itup, | |
Page | page, | |||
BlockNumber | childblk | |||
) | [static] |
Definition at line 170 of file ginentrypage.c.
References GinGetPostingOffset, GinIsPostingTree, GinPageIsLeaf, GinSetDownlink, IndexTupleSize, MAXALIGN, palloc(), and IndexTupleData::t_info.
Referenced by entrySplitPage(), and ginPageGetLinkItup().
{ IndexTuple nitup; if (GinPageIsLeaf(page) && !GinIsPostingTree(itup)) { /* Tuple contains a posting list, just copy stuff before that */ uint32 origsize = GinGetPostingOffset(itup); origsize = MAXALIGN(origsize); nitup = (IndexTuple) palloc(origsize); memcpy(nitup, itup, origsize); /* ... be sure to fix the size header field ... */ nitup->t_info &= ~INDEX_SIZE_MASK; nitup->t_info |= origsize; } else { /* Copy the tuple as-is */ nitup = (IndexTuple) palloc(IndexTupleSize(itup)); memcpy(nitup, itup, IndexTupleSize(itup)); } /* Now insert the correct downlink */ GinSetDownlink(nitup, childblk); return nitup; }
IndexTuple GinFormTuple | ( | GinState * | ginstate, | |
OffsetNumber | attnum, | |||
Datum | key, | |||
GinNullCategory | category, | |||
ItemPointerData * | ipd, | |||
uint32 | nipd, | |||
bool | errorTooBig | |||
) |
Definition at line 36 of file ginentrypage.c.
References Assert, ereport, errcode(), errmsg(), ERROR, GIN_CAT_NORM_KEY, GinCategoryOffset, GinGetPosting, GinMaxItemSize, GinSetNPosting, GinSetNullCategory, GinSetPostingOffset, GinState::index, index_form_tuple(), INDEX_SIZE_MASK, IndexTupleHasNulls, IndexTupleSize, Max, MAXALIGN, Min, GinState::oneCol, pfree(), RelationGetRelationName, repalloc(), SHORTALIGN, IndexTupleData::t_info, GinState::tupdesc, and UInt16GetDatum.
Referenced by addItemPointersToLeafTuple(), buildFreshLeafTuple(), ginHeapTupleFastCollect(), and ginVacuumEntryPage().
{ Datum datums[2]; bool isnull[2]; IndexTuple itup; uint32 newsize; /* Build the basic tuple: optional column number, plus key datum */ if (ginstate->oneCol) { datums[0] = key; isnull[0] = (category != GIN_CAT_NORM_KEY); } else { datums[0] = UInt16GetDatum(attnum); isnull[0] = false; datums[1] = key; isnull[1] = (category != GIN_CAT_NORM_KEY); } itup = index_form_tuple(ginstate->tupdesc[attnum - 1], datums, isnull); /* * Determine and store offset to the posting list, making sure there is * room for the category byte if needed. * * Note: because index_form_tuple MAXALIGNs the tuple size, there may well * be some wasted pad space. Is it worth recomputing the data length to * prevent that? That would also allow us to Assert that the real data * doesn't overlap the GinNullCategory byte, which this code currently * takes on faith. */ newsize = IndexTupleSize(itup); if (IndexTupleHasNulls(itup)) { uint32 minsize; Assert(category != GIN_CAT_NORM_KEY); minsize = GinCategoryOffset(itup, ginstate) + sizeof(GinNullCategory); newsize = Max(newsize, minsize); } newsize = SHORTALIGN(newsize); GinSetPostingOffset(itup, newsize); GinSetNPosting(itup, nipd); /* * Add space needed for posting list, if any. Then check that the tuple * won't be too big to store. */ newsize += sizeof(ItemPointerData) * nipd; newsize = MAXALIGN(newsize); if (newsize > Min(INDEX_SIZE_MASK, GinMaxItemSize)) { if (errorTooBig) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("index row size %lu exceeds maximum %lu for index \"%s\"", (unsigned long) newsize, (unsigned long) Min(INDEX_SIZE_MASK, GinMaxItemSize), RelationGetRelationName(ginstate->index)))); pfree(itup); return NULL; } /* * Resize tuple if needed */ if (newsize != IndexTupleSize(itup)) { itup = repalloc(itup, newsize); /* set new size in tuple header */ itup->t_info &= ~INDEX_SIZE_MASK; itup->t_info |= newsize; } /* * Insert category byte, if needed */ if (category != GIN_CAT_NORM_KEY) { Assert(IndexTupleHasNulls(itup)); GinSetNullCategory(itup, ginstate, category); } /* * Copy in the posting list, if provided */ if (ipd) memcpy(GinGetPosting(itup), ipd, sizeof(ItemPointerData) * nipd); return itup; }
IndexTuple ginPageGetLinkItup | ( | Buffer | buf | ) |
Definition at line 665 of file ginentrypage.c.
References BufferGetBlockNumber(), BufferGetPage, getRightMostTuple(), and GinFormInteriorTuple().
Referenced by ginContinueSplit(), and ginEntryFillRoot().
{ IndexTuple itup, nitup; Page page = BufferGetPage(buf); itup = getRightMostTuple(page); nitup = GinFormInteriorTuple(itup, page, BufferGetBlockNumber(buf)); return nitup; }
void ginPrepareEntryScan | ( | GinBtree | btree, | |
OffsetNumber | attnum, | |||
Datum | key, | |||
GinNullCategory | category, | |||
GinState * | ginstate | |||
) |
Definition at line 707 of file ginentrypage.c.
References GinBtreeData::entryAttnum, GinBtreeData::entryCategory, GinBtreeData::entryKey, GinBtreeData::fillRoot, GinBtreeData::findChildPage, GinBtreeData::findChildPtr, GinBtreeData::findItem, GinBtreeData::fullScan, GinBtreeData::getLeftMostPage, GinBtreeData::ginstate, GinState::index, GinBtreeData::index, GinBtreeData::isBuild, GinBtreeData::isData, GinBtreeData::isDelete, GinBtreeData::isEnoughSpace, GinBtreeData::isMoveRight, GinBtreeData::placeToPage, GinBtreeData::searchMode, and GinBtreeData::splitPage.
Referenced by ginContinueSplit(), ginEntryInsert(), and startScanEntry().
{ memset(btree, 0, sizeof(GinBtreeData)); btree->index = ginstate->index; btree->ginstate = ginstate; btree->findChildPage = entryLocateEntry; btree->isMoveRight = entryIsMoveRight; btree->findItem = entryLocateLeafEntry; btree->findChildPtr = entryFindChildPtr; btree->getLeftMostPage = entryGetLeftMostPage; btree->isEnoughSpace = entryIsEnoughSpace; btree->placeToPage = entryPlaceToPage; btree->splitPage = entrySplitPage; btree->fillRoot = ginEntryFillRoot; btree->isData = FALSE; btree->searchMode = FALSE; btree->fullScan = FALSE; btree->isBuild = FALSE; btree->entryAttnum = attnum; btree->entryKey = key; btree->entryCategory = category; btree->isDelete = FALSE; }
void GinShortenTuple | ( | IndexTuple | itup, | |
uint32 | nipd | |||
) |
Definition at line 145 of file ginentrypage.c.
References Assert, GinGetNPosting, GinGetPostingOffset, GinSetNPosting, INDEX_SIZE_MASK, MAXALIGN, and IndexTupleData::t_info.
Referenced by addItemPointersToLeafTuple().
{ uint32 newsize; Assert(nipd <= GinGetNPosting(itup)); newsize = GinGetPostingOffset(itup) + sizeof(ItemPointerData) * nipd; newsize = MAXALIGN(newsize); Assert(newsize <= (itup->t_info & INDEX_SIZE_MASK)); itup->t_info &= ~INDEX_SIZE_MASK; itup->t_info |= newsize; GinSetNPosting(itup, nipd); }