36 bool unlockbuf,
bool unlockleftchild);
42 #define ROTATEDIST(d) do { \
43 SplitedPageLayout *tmp=(SplitedPageLayout*)palloc(sizeof(SplitedPageLayout)); \
44 memset(tmp,0,sizeof(SplitedPageLayout)); \
45 tmp->block.blkno = InvalidBlockNumber; \
46 tmp->buffer = InvalidBuffer; \
64 "GiST temporary context",
130 values, isnull,
true );
131 itup->
t_tid = *ht_ctid;
179 bool markfollowright)
198 elog(
ERROR,
"concurrent GiST page split was incomplete");
212 is_split =
gistnospace(page, itup, ntup, oldoffnum, freespace);
221 is_split =
gistnospace(page, itup, ntup, oldoffnum, freespace);
254 dist =
gistSplit(rel, page, itvec, tlen, giststate);
260 for (ptr = dist; ptr; ptr = ptr->
next)
266 elog(
ERROR,
"GiST page split into too many halves (%d, maximum %d)",
294 for (; ptr; ptr = ptr->next)
307 for (ptr = dist; ptr; ptr = ptr->
next)
329 for (ptr = dist; ptr; ptr = ptr->
next)
332 for (i = 0, ptr = dist; ptr; ptr = ptr->
next)
333 downlinks[i++] = ptr->itup;
347 for (ptr = dist; ptr; ptr = ptr->
next)
351 si->
buf = ptr->buffer;
353 *splitinfo =
lappend(*splitinfo, si);
361 for (ptr = dist; ptr; ptr = ptr->
next)
363 char *data = (
char *) (ptr->list);
365 for (i = 0; i < ptr->block.num; i++)
377 *newblkno = ptr->block.blkno;
385 ptr->next->block.blkno;
397 if (ptr->next && !is_rootsplit && markfollowright)
424 for (ptr = dist; ptr; ptr = ptr->
next)
439 dist, oldrlink, oldnsn, leftchildbuf,
444 for (ptr = dist; ptr; ptr = ptr->
next)
458 for (ptr = dist->
next; ptr; ptr = ptr->
next)
490 deloffs[0] = oldoffnum;
495 deloffs, ndeloffs, itup, ntup,
551 bool xlocked =
false;
562 state.
stack = stack = &firststack;
649 (
errmsg(
"index \"%s\" contains an inner tuple marked as invalid",
651 errdetail(
"This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1."),
652 errhint(
"Please REINDEX it.")));
712 item->
blkno = childblkno;
715 state.
stack = stack = item;
780 for (; stack; stack = stack->
parent)
843 elog(
ERROR,
"concurrent GiST page split was incomplete");
864 fifo =
lcons(ptr, fifo);
896 elog(
ERROR,
"failed to re-find parent of a page in index \"%s\", block %u",
1010 if (downlink ==
NULL)
1019 downlink = newdownlink;
1063 elog(
LOG,
"fixing incomplete split in index \"%s\", block %u",
1088 splitinfo =
lappend(splitinfo, si);
1153 bool unlockbuf,
bool unlockleftchild)
1223 foreach(lc, splitinfo)
1243 left->
buf, right->
buf,
false,
false))
1305 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1306 errmsg(
"index row size %zu exceeds maximum %zu for index \"%s\"",
1345 while (resptr->
next)
1346 resptr = resptr->
next;
1375 elog(
ERROR,
"numberOfAttributes %d > %d",
1380 "GiST scan context",
1486 deletable[ndeletable++] = offnum;
1512 deletable, ndeletable,
#define GistFollowRight(page)
#define GistPageGetNSN(page)
#define PG_GETARG_INT32(n)
static bool gistinserttuple(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, IndexTuple tuple, OffsetNumber oldoffnum)
void MemoryContextDelete(MemoryContext context)
int errhint(const char *fmt,...)
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
Datum spl_lattr[INDEX_MAX_KEYS]
void PageRestoreTempPage(Page tempPage, Page oldPage)
static void gistfixsplit(GISTInsertState *state, GISTSTATE *giststate)
OffsetNumber PageAddItem(Page page, Item item, Size size, OffsetNumber offsetNumber, bool overwrite, bool is_heap)
FmgrInfo fetchFn[INDEX_MAX_KEYS]
#define GistClearPageHasGarbage(page)
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
void MarkBufferDirty(Buffer buffer)
MemoryContext createTempGistContext(void)
Oid supportCollation[INDEX_MAX_KEYS]
FmgrInfo compressFn[INDEX_MAX_KEYS]
FmgrInfo equalFn[INDEX_MAX_KEYS]
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
void gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off)
#define END_CRIT_SECTION()
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define GistPageSetNSN(page, val)
GIST_SPLITVEC splitVector
#define START_CRIT_SECTION()
int errcode(int sqlerrcode)
#define GistTupleIsInvalid(itup)
#define PG_GETARG_POINTER(n)
#define GistPageHasGarbage(page)
void ReleaseBuffer(Buffer buffer)
void gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
#define BUFFER_LOCK_EXCLUSIVE
#define ItemIdIsDead(itemId)
#define OidIsValid(objectId)
#define PageGetMaxOffsetNumber(page)
static void gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, List *splitinfo, bool releasebuf)
IndexTuple gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *giststate)
void gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate, GistSplitVector *v, int attno)
Datum spl_rattr[INDEX_MAX_KEYS]
Datum gistbuildempty(PG_FUNCTION_ARGS)
XLogRecPtr gistGetFakeLSN(Relation rel)
#define ALLOCSET_DEFAULT_MINSIZE
ItemPointerData * ItemPointer
Page PageGetTempPageCopySpecial(Page page)
Datum gistinsert(PG_FUNCTION_ARGS)
IndexTuple * gistextractpage(Page page, int *len)
struct RelationData * Relation
FmgrInfo consistentFn[INDEX_MAX_KEYS]
#define GIST_PICKSPLIT_PROC
void UnlockReleaseBuffer(Buffer buffer)
static IndexTuple gistformdownlink(Relation rel, Buffer buf, GISTSTATE *giststate, GISTInsertStack *stack)
#define GIST_COMPRESS_PROC
#define GIST_MAX_SPLIT_PAGES
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, Buffer buffer, IndexTuple *itup, int ntup, OffsetNumber oldoffnum, BlockNumber *newblkno, Buffer leftchildbuf, List **splitinfo, bool markfollowright)
IndexTuple CopyIndexTuple(IndexTuple source)
#define DEFAULT_COLLATION_OID
void check_stack_depth(void)
#define FirstOffsetNumber
IndexTupleData * IndexTuple
int errdetail(const char *fmt,...)
FmgrInfo picksplitFn[INDEX_MAX_KEYS]
bool gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace)
#define RelationGetRelationName(relation)
FmgrInfo penaltyFn[INDEX_MAX_KEYS]
MemoryContext CurrentMemoryContext
struct SplitedPageLayout * next
#define BufferGetPage(buffer)
void freeGISTstate(GISTSTATE *giststate)
#define ereport(elevel, rest)
FmgrInfo decompressFn[INDEX_MAX_KEYS]
static void gistvacuumpage(Relation rel, Page page, Buffer buffer)
List * lappend(List *list, void *datum)
OffsetNumber gistchoose(Relation r, Page p, IndexTuple it, GISTSTATE *giststate)
#define GistPageIsLeaf(page)
#define GistTupleSetValid(itup)
#define XLogRecPtrIsInvalid(r)
OffsetNumber downlinkoffnum
#define PageGetItemId(page, offsetNumber)
static void gistFindCorrectParent(Relation r, GISTInsertStack *child)
#define GistClearFollowRight(page)
IndexTuple * gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)
static bool gistinserttuples(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, IndexTuple *tuples, int ntup, OffsetNumber oldoffnum, Buffer leftchild, Buffer rightchild, bool unlockbuf, bool unlockleftchild)
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
void * palloc0(Size size)
#define PG_RETURN_BOOL(x)
void LockBuffer(Buffer buffer, int mode)
GISTSTATE * initGISTstate(Relation index)
struct DataPageDeleteStack * child
SplitedPageLayout * gistSplit(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate)
#define InvalidOffsetNumber
static GISTInsertStack * gistFindPath(Relation r, BlockNumber child, OffsetNumber *downlinkoffnum)
#define GIST_CONSISTENT_PROC
bool gistfitpage(IndexTuple *itvec, int len)
#define GistPageGetOpaque(page)
List * lcons(void *datum, List *list)
#define Assert(condition)
struct DataPageDeleteStack * parent
void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
void gistcheckpage(Relation rel, Buffer buf)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define OffsetNumberNext(offsetNumber)
IndexTupleData * gistfillitupvec(IndexTuple *vec, int veclen, int *memlen)
#define GIST_PENALTY_PROC
#define InvalidBlockNumber
static int list_length(const List *l)
void XLogEnsureRecordSpace(int max_block_id, int ndatas)
#define GIST_DISTANCE_PROC
#define BufferIsValid(bufnum)
FmgrInfo distanceFn[INDEX_MAX_KEYS]
#define ItemPointerSetBlockNumber(pointer, blockNumber)
#define GistMarkFollowRight(page)
#define RelationNeedsWAL(relation)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
static Datum values[MAXATTR]
bool spl_risnull[INDEX_MAX_KEYS]
BlockNumber BufferGetBlockNumber(Buffer buffer)
#define MaxIndexTuplesPerPage
int errmsg(const char *fmt,...)
#define ALLOCSET_DEFAULT_INITSIZE
#define OffsetNumberIsValid(offsetNumber)
void GISTInitBuffer(Buffer b, uint32 f)
IndexTuple gistFormTuple(GISTSTATE *giststate, Relation r, Datum attdata[], bool isnull[], bool isleaf)
#define ALLOCSET_DEFAULT_MAXSIZE
#define GIST_DECOMPRESS_PROC
#define ItemPointerGetBlockNumber(pointer)
XLogRecPtr gistXLogUpdate(RelFileNode node, Buffer buffer, OffsetNumber *todelete, int ntodelete, IndexTuple *itup, int ituplen, Buffer leftchildbuf)
bool spl_lisnull[INDEX_MAX_KEYS]
FmgrInfo unionFn[INDEX_MAX_KEYS]
#define PageSetLSN(page, lsn)
struct GISTInsertStack * parent
Buffer gistNewBuffer(Relation r)
#define PageGetItem(page, itemId)
#define IndexTupleSize(itup)
List * list_delete_first(List *list)
XLogRecPtr gistXLogSplit(RelFileNode node, BlockNumber blkno, bool page_is_leaf, SplitedPageLayout *dist, BlockNumber origrlink, GistNSN orignsn, Buffer leftchildbuf, bool markfollowright)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)