34 bool unlockbuf,
bool unlockleftchild);
40 #define ROTATEDIST(d) do { \
41 SplitedPageLayout *tmp=(SplitedPageLayout*)palloc(sizeof(SplitedPageLayout)); \
42 memset(tmp,0,sizeof(SplitedPageLayout)); \
43 tmp->block.blkno = InvalidBlockNumber; \
44 tmp->buffer = InvalidBuffer; \
106 "GiST temporary context",
162 values, isnull,
true );
163 itup->
t_tid = *ht_ctid;
211 bool markfollowright)
230 elog(
ERROR,
"concurrent GiST page split was incomplete");
244 is_split =
gistnospace(page, itup, ntup, oldoffnum, freespace);
253 is_split =
gistnospace(page, itup, ntup, oldoffnum, freespace);
286 dist =
gistSplit(rel, page, itvec, tlen, giststate);
292 for (ptr = dist; ptr; ptr = ptr->
next)
298 elog(
ERROR,
"GiST page split into too many halves (%d, maximum %d)",
326 for (; ptr; ptr = ptr->next)
339 for (ptr = dist; ptr; ptr = ptr->
next)
361 for (ptr = dist; ptr; ptr = ptr->
next)
364 for (i = 0, ptr = dist; ptr; ptr = ptr->
next)
365 downlinks[i++] = ptr->itup;
379 for (ptr = dist; ptr; ptr = ptr->
next)
383 si->
buf = ptr->buffer;
385 *splitinfo =
lappend(*splitinfo, si);
393 for (ptr = dist; ptr; ptr = ptr->
next)
395 char *data = (
char *) (ptr->list);
397 for (i = 0; i < ptr->block.num; i++)
409 *newblkno = ptr->block.blkno;
417 ptr->next->block.blkno;
429 if (ptr->next && !is_rootsplit && markfollowright)
456 for (ptr = dist; ptr; ptr = ptr->
next)
471 dist, oldrlink, oldnsn, leftchildbuf,
476 for (ptr = dist; ptr; ptr = ptr->
next)
490 for (ptr = dist->
next; ptr; ptr = ptr->
next)
522 deloffs[0] = oldoffnum;
527 deloffs, ndeloffs, itup, ntup,
583 bool xlocked =
false;
594 state.
stack = stack = &firststack;
681 (
errmsg(
"index \"%s\" contains an inner tuple marked as invalid",
683 errdetail(
"This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1."),
684 errhint(
"Please REINDEX it.")));
744 item->
blkno = childblkno;
747 state.
stack = stack = item;
812 for (; stack; stack = stack->
parent)
875 elog(
ERROR,
"concurrent GiST page split was incomplete");
896 fifo =
lcons(ptr, fifo);
928 elog(
ERROR,
"failed to re-find parent of a page in index \"%s\", block %u",
1042 if (downlink ==
NULL)
1051 downlink = newdownlink;
1095 elog(
LOG,
"fixing incomplete split in index \"%s\", block %u",
1120 splitinfo =
lappend(splitinfo, si);
1185 bool unlockbuf,
bool unlockleftchild)
1255 foreach(lc, splitinfo)
1275 left->
buf, right->
buf,
false,
false))
1337 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1338 errmsg(
"index row size %zu exceeds maximum %zu for index \"%s\"",
1377 while (resptr->
next)
1378 resptr = resptr->
next;
1407 elog(
ERROR,
"numberOfAttributes %d > %d",
1412 "GiST scan context",
1518 deletable[ndeletable++] = offnum;
1544 deletable, ndeletable,
#define GistFollowRight(page)
ambeginscan_function ambeginscan
#define PG_RETURN_POINTER(x)
#define GistPageGetNSN(page)
ambulkdelete_function ambulkdelete
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)
amgettuple_function amgettuple
bool gistinsert(Relation r, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique)
FmgrInfo fetchFn[INDEX_MAX_KEYS]
IndexBulkDeleteResult * gistvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
#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]
IndexBulkDeleteResult * gistbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
Datum gisthandler(PG_FUNCTION_ARGS)
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()
bool gistgettuple(IndexScanDesc scan, ScanDirection dir)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define GistPageSetNSN(page, val)
GIST_SPLITVEC splitVector
#define START_CRIT_SECTION()
int errcode(int sqlerrcode)
#define GistTupleIsInvalid(itup)
#define GistPageHasGarbage(page)
void ReleaseBuffer(Buffer buffer)
aminsert_function aminsert
void gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
#define BUFFER_LOCK_EXCLUSIVE
bytea * gistoptions(Datum reloptions, bool validate)
#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)
amvalidate_function amvalidate
Datum spl_rattr[INDEX_MAX_KEYS]
XLogRecPtr gistGetFakeLSN(Relation rel)
#define ALLOCSET_DEFAULT_MINSIZE
Page PageGetTempPageCopySpecial(Page page)
IndexBuildResult * gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
IndexTuple * gistextractpage(Page page, int *len)
amgetbitmap_function amgetbitmap
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
amoptions_function amoptions
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
amcostestimate_function amcostestimate
void gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, ScanKey orderbys, int norderbys)
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)
amvacuumcleanup_function amvacuumcleanup
amendscan_function amendscan
#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)
amrescan_function amrescan
FmgrInfo decompressFn[INDEX_MAX_KEYS]
static void gistvacuumpage(Relation rel, Page page, Buffer buffer)
int64 gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
List * lappend(List *list, void *datum)
OffsetNumber gistchoose(Relation r, Page p, IndexTuple it, GISTSTATE *giststate)
void gistbuildempty(Relation index)
#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)
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)
bool gistcanreturn(Relation index, int attno)
#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)
void gistcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation)
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)
ammarkpos_function ammarkpos
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)
bool gistvalidate(Oid opclassoid)
#define MaxIndexTuplesPerPage
int errmsg(const char *fmt,...)
ambuildempty_function ambuildempty
#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
IndexScanDesc gistbeginscan(Relation r, int nkeys, int norderbys)
void gistendscan(IndexScanDesc scan)
#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
amcanreturn_function amcanreturn
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)
amrestrpos_function amrestrpos
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)