39 bool unlockbuf,
bool unlockleftchild);
46 #define ROTATEDIST(d) do { \
47 SplitedPageLayout *tmp=(SplitedPageLayout*)palloc0(sizeof(SplitedPageLayout)); \
48 tmp->block.blkno = InvalidBlockNumber; \
49 tmp->buffer = InvalidBuffer; \
124 "GiST temporary context",
169 if (giststate == NULL)
182 itup->t_tid = *ht_ctid;
230 bool markfollowright,
250 elog(
ERROR,
"concurrent GiST page split was incomplete");
267 is_split =
gistnospace(page, itup, ntup, oldoffnum, freespace);
276 is_split =
gistnospace(page, itup, ntup, oldoffnum, freespace);
306 memmove(itvec + pos, itvec + pos + 1,
sizeof(
IndexTuple) * (tlen - pos));
309 dist =
gistSplit(rel, page, itvec, tlen, giststate);
315 for (ptr = dist; ptr; ptr = ptr->
next)
321 elog(
ERROR,
"GiST page split into too many halves (%d, maximum %d)",
349 for (; ptr; ptr = ptr->next)
365 for (ptr = dist; ptr; ptr = ptr->
next)
387 for (ptr = dist; ptr; ptr = ptr->
next)
390 for (
i = 0, ptr = dist; ptr; ptr = ptr->
next)
391 downlinks[
i++] = ptr->itup;
405 for (ptr = dist; ptr; ptr = ptr->
next)
409 si->
buf = ptr->buffer;
411 *splitinfo =
lappend(*splitinfo, si);
419 for (ptr = dist; ptr; ptr = ptr->
next)
421 char *
data = (
char *) (ptr->list);
423 for (
int i = 0;
i < ptr->block.num;
i++)
435 *newblkno = ptr->block.blkno;
443 ptr->next->block.blkno;
455 if (ptr->next && !is_rootsplit && markfollowright)
482 for (ptr = dist; ptr; ptr = ptr->
next)
510 dist, oldrlink, oldnsn, leftchildbuf,
516 for (ptr = dist; ptr; ptr = ptr->
next)
528 for (ptr = dist->
next; ptr; ptr = ptr->
next)
550 elog(
ERROR,
"failed to add item to index page in \"%s\"",
582 deloffs[0] = oldoffnum;
587 deloffs, ndeloffs, itup, ntup,
641 bool xlocked =
false;
644 state.freespace = freespace;
646 state.heapRel = heapRel;
647 state.is_build = is_build;
655 state.stack = stack = &firststack;
694 stack->
lsn = xlocked ?
759 (
errmsg(
"index \"%s\" contains an inner tuple marked as invalid",
761 errdetail(
"This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1."),
762 errhint(
"Please REINDEX it.")));
822 item->
blkno = childblkno;
825 state.stack = stack = item;
891 for (; stack; stack = stack->
parent)
957 elog(
ERROR,
"concurrent GiST page split was incomplete");
978 fifo =
lcons(ptr, fifo);
1010 elog(
ERROR,
"failed to re-find parent of a page in index \"%s\", block %u",
1141 if (downlink == NULL)
1150 downlink = newdownlink;
1195 (
errmsg(
"fixing incomplete split in index \"%s\", block %u",
1220 splitinfo =
lappend(splitinfo, si);
1285 bool unlockbuf,
bool unlockleftchild)
1364 for (
int pos =
list_length(splitinfo) - 1; pos > 1; pos--)
1373 left->
buf, right->
buf,
false,
false))
1461 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1462 errmsg(
"index row size %zu exceeds maximum %zu for index \"%s\"",
1503 while (resptr->
next)
1504 resptr = resptr->
next;
1533 elog(
ERROR,
"numberOfAttributes %d > %d",
1538 "GiST scan context",
1632 for (;
i <
index->rd_att->natts;
i++)
1684 deletable[ndeletable++] = offnum;
1692 snapshotConflictHorizon =
1694 deletable, ndeletable);
1717 deletable, ndeletable,
1718 snapshotConflictHorizon,
#define InvalidBlockNumber
static Datum values[MAXATTR]
BlockNumber BufferGetBlockNumber(Buffer buffer)
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
void ReleaseBuffer(Buffer buffer)
XLogRecPtr BufferGetLSNAtomic(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
static Page BufferGetPage(Buffer buffer)
static bool BufferIsValid(Buffer bufnum)
void PageRestoreTempPage(Page tempPage, Page oldPage)
void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
Page PageGetTempPageCopySpecial(Page page)
bool PageIndexTupleOverwrite(Page page, OffsetNumber offnum, Item newtup, Size newsize)
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
static Item PageGetItem(Page page, ItemId itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static XLogRecPtr PageGetLSN(Page page)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
#define OidIsValid(objectId)
static void PGresult * res
elog(ERROR, "%s: %s", p2, msg)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
#define PG_RETURN_POINTER(x)
TransactionId index_compute_xid_horizon_for_tuples(Relation irel, Relation hrel, Buffer ibuf, OffsetNumber *itemnos, int nitems)
void gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate, Relation heapRel, bool is_build)
static void gistfixsplit(GISTInsertState *state, GISTSTATE *giststate)
static void gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel)
bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, Buffer buffer, IndexTuple *itup, int ntup, OffsetNumber oldoffnum, BlockNumber *newblkno, Buffer leftchildbuf, List **splitinfo, bool markfollowright, Relation heapRel, bool is_build)
bool gistinsert(Relation r, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)
SplitedPageLayout * gistSplit(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate)
GISTSTATE * initGISTstate(Relation index)
void gistbuildempty(Relation index)
static GISTInsertStack * gistFindPath(Relation r, BlockNumber child, OffsetNumber *downlinkoffnum)
static bool gistinserttuples(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, IndexTuple *tuples, int ntup, OffsetNumber oldoffnum, Buffer leftchild, Buffer rightchild, bool unlockbuf, bool unlockleftchild)
MemoryContext createTempGistContext(void)
void freeGISTstate(GISTSTATE *giststate)
static bool gistinserttuple(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, IndexTuple tuple, OffsetNumber oldoffnum)
static void gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, List *splitinfo, bool unlockbuf)
static void gistFindCorrectParent(Relation r, GISTInsertStack *child, bool is_build)
static IndexTuple gistformdownlink(Relation rel, Buffer buf, GISTSTATE *giststate, GISTInsertStack *stack, bool is_build)
Datum gisthandler(PG_FUNCTION_ARGS)
#define GIST_DECOMPRESS_PROC
#define GIST_PICKSPLIT_PROC
#define GistMarkFollowRight(page)
#define GIST_CONSISTENT_PROC
#define GistClearFollowRight(page)
#define GIST_COMPRESS_PROC
#define GistClearPageHasGarbage(page)
#define GIST_PENALTY_PROC
#define GistPageIsLeaf(page)
#define GistFollowRight(page)
#define GIST_OPTIONS_PROC
#define GIST_DISTANCE_PROC
#define GistPageSetNSN(page, val)
#define GistPageIsDeleted(page)
#define GistPageGetOpaque(page)
#define GistPageHasGarbage(page)
#define GistPageGetNSN(page)
#define GIST_MAX_SPLIT_PAGES
#define GistTupleSetValid(itup)
#define GistTupleIsInvalid(itup)
IndexBuildResult * gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
bool gistgettuple(IndexScanDesc scan, ScanDirection dir)
int64 gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
bool gistcanreturn(Relation index, int attno)
IndexScanDesc gistbeginscan(Relation r, int nkeys, int norderbys)
void gistendscan(IndexScanDesc scan)
void gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, ScanKey orderbys, int norderbys)
void gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate, GistSplitVector *v, int attno)
IndexTuple gistFormTuple(GISTSTATE *giststate, Relation r, Datum *attdata, bool *isnull, bool isleaf)
Buffer gistNewBuffer(Relation r, Relation heaprel)
bool gistproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull)
bool gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace)
void gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off)
IndexTuple * gistextractpage(Page page, int *len)
bool gistfitpage(IndexTuple *itvec, int len)
IndexTuple gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *giststate)
OffsetNumber gistchoose(Relation r, Page p, IndexTuple it, GISTSTATE *giststate)
XLogRecPtr gistGetFakeLSN(Relation rel)
IndexTuple * gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)
bytea * gistoptions(Datum reloptions, bool validate)
void GISTInitBuffer(Buffer b, uint32 f)
IndexTupleData * gistfillitupvec(IndexTuple *vec, int veclen, int *memlen)
void gistcheckpage(Relation rel, Buffer buf)
IndexBulkDeleteResult * gistbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
IndexBulkDeleteResult * gistvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
void gistadjustmembers(Oid opfamilyoid, Oid opclassoid, List *operators, List *functions)
bool gistvalidate(Oid opclassoid)
XLogRecPtr gistXLogDelete(Buffer buffer, OffsetNumber *todelete, int ntodelete, TransactionId snapshotConflictHorizon, Relation heaprel)
XLogRecPtr gistXLogUpdate(Buffer buffer, OffsetNumber *todelete, int ntodelete, IndexTuple *itup, int ituplen, Buffer leftchildbuf)
XLogRecPtr gistXLogSplit(bool page_is_leaf, SplitedPageLayout *dist, BlockNumber origrlink, GistNSN orignsn, Buffer leftchildbuf, bool markfollowright)
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
IndexTuple CopyIndexTuple(IndexTuple source)
if(TABLE==NULL||TABLE_index==NULL)
#define ItemIdIsDead(itemId)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
static void ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
IndexTupleData * IndexTuple
#define IndexTupleSize(itup)
#define MaxIndexTuplesPerPage
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
List * list_delete_first(List *list)
List * lcons(void *datum, List *list)
void MemoryContextReset(MemoryContext context)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define START_CRIT_SECTION()
#define END_CRIT_SECTION()
#define InvalidOffsetNumber
#define OffsetNumberIsValid(offsetNumber)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static int list_length(const List *l)
static void * list_nth(const List *list, int n)
void check_stack_depth(void)
void PredicateLockPageSplit(Relation relation, BlockNumber oldblkno, BlockNumber newblkno)
void CheckForSerializableConflictIn(Relation relation, ItemPointer tid, BlockNumber blkno)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
void gistcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
OffsetNumber downlinkoffnum
struct GISTInsertStack * parent
FmgrInfo fetchFn[INDEX_MAX_KEYS]
FmgrInfo penaltyFn[INDEX_MAX_KEYS]
Oid supportCollation[INDEX_MAX_KEYS]
FmgrInfo distanceFn[INDEX_MAX_KEYS]
FmgrInfo consistentFn[INDEX_MAX_KEYS]
FmgrInfo decompressFn[INDEX_MAX_KEYS]
FmgrInfo compressFn[INDEX_MAX_KEYS]
FmgrInfo equalFn[INDEX_MAX_KEYS]
FmgrInfo unionFn[INDEX_MAX_KEYS]
FmgrInfo picksplitFn[INDEX_MAX_KEYS]
GIST_SPLITVEC splitVector
Datum spl_lattr[INDEX_MAX_KEYS]
bool spl_lisnull[INDEX_MAX_KEYS]
Datum spl_rattr[INDEX_MAX_KEYS]
bool spl_risnull[INDEX_MAX_KEYS]
ambuildphasename_function ambuildphasename
ambuildempty_function ambuildempty
amvacuumcleanup_function amvacuumcleanup
amoptions_function amoptions
amestimateparallelscan_function amestimateparallelscan
amrestrpos_function amrestrpos
aminsert_function aminsert
amendscan_function amendscan
amparallelrescan_function amparallelrescan
amcostestimate_function amcostestimate
amadjustmembers_function amadjustmembers
amgettuple_function amgettuple
amcanreturn_function amcanreturn
amgetbitmap_function amgetbitmap
amproperty_function amproperty
ambulkdelete_function ambulkdelete
amvalidate_function amvalidate
ammarkpos_function ammarkpos
bool amusemaintenanceworkmem
ambeginscan_function ambeginscan
amrescan_function amrescan
aminitparallelscan_function aminitparallelscan
uint8 amparallelvacuumoptions
struct SplitedPageLayout * next
#define InvalidTransactionId
TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc)
#define VACUUM_OPTION_PARALLEL_BULKDEL
#define VACUUM_OPTION_PARALLEL_COND_CLEANUP
#define XLogStandbyInfoActive()
#define XLogRecPtrIsInvalid(r)
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)
void XLogEnsureRecordSpace(int max_block_id, int ndatas)