41 #define GIN_PAGE_FREESIZE \
42 ( BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(GinPageOpaqueData)) )
78 for (
i = 0;
i < ntuples;
i++)
82 memcpy(ptr, tuples[
i], this_size);
89 elog(
ERROR,
"failed to add item to index page in \"%s\"",
121 data.rightlink = rightlink;
122 data.ntuples = ntuples;
160 for (
i = 0;
i < ntuples;
i++)
168 res->nPendingPages++;
179 prevBuffer = curBuffer;
204 ntuples - startTuple,
206 res->nPendingPages++;
208 res->nPendingHeapTuples = 1;
228 bool separateList =
false;
229 bool needCleanup =
false;
382 elog(
ERROR,
"failed to add item to index page in \"%s\"",
385 memcpy(ptr, collector->
tuples[
i], tupsize);
488 &nentries, &categories);
495 elog(
ERROR,
"too many entries for GIN index");
500 if (collector->
tuples == NULL)
526 for (
i = 0;
i < nentries;
i++)
532 itup->
t_tid = *ht_ctid;
554 blknoToDelete = metadata->
head;
560 int64 nDeletedHeapTuples = 0;
568 freespace[
data.ndeleted] = blknoToDelete;
594 metadata->
head = blknoToDelete;
621 for (
i = 0;
i <
data.ndeleted;
i++)
635 for (
i = 0;
i <
data.ndeleted;
i++)
646 for (
i = 0;
i <
data.ndeleted;
i++)
653 for (
i = 0;
i <
data.ndeleted;
i++)
658 for (
i = 0; fill_fsm &&
i <
data.ndeleted;
i++)
661 }
while (blknoToDelete != newHead);
731 heapptr = itup->
t_tid;
735 curattnum == attrnum))
745 heapptr = itup->
t_tid;
775 bool fill_fsm,
bool forceCleanup,
790 bool cleanupFinish =
false;
791 bool fsm_vac =
false;
841 blknoFinish = metadata->
tail;
846 blkno = metadata->
head;
857 "GIN insert cleanup temporary context",
881 if (blkno == blknoFinish && full_clean ==
false)
882 cleanupFinish =
true;
922 &
attnum, &
key, &category, &nlist)) != NULL)
952 &
attnum, &
key, &category, &nlist)) != NULL)
1013 if (fsm_vac && fill_fsm)
1034 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1035 errmsg(
"recovery is in progress"),
1036 errhint(
"GIN pending list cannot be cleaned up during recovery.")));
1039 if (indexRel->
rd_rel->relkind != RELKIND_INDEX ||
1040 indexRel->
rd_rel->relam != GIN_AM_OID)
1042 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1043 errmsg(
"\"%s\" is not a GIN index",
1053 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1054 errmsg(
"cannot access temporary indexes of other sessions")));
1061 memset(&stats, 0,
sizeof(stats));
bool pg_class_ownercheck(Oid class_oid, Oid roleid)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
bool IsAutoVacuumWorkerProcess(void)
#define InvalidBlockNumber
BlockNumber BufferGetBlockNumber(Buffer buffer)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define BufferGetPage(buffer)
Size PageGetExactFreeSpace(Page page)
PageHeaderData * PageHeader
#define PageGetMaxOffsetNumber(page)
#define PageGetItemId(page, offsetNumber)
#define PageIsEmpty(page)
#define PageGetItem(page, itemId)
#define PageSetLSN(page, lsn)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
static void PGresult * res
elog(ERROR, "%s: %s", p2, msg)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PG_RETURN_INT64(x)
#define GinGetPendingListCleanupSize(relation)
#define GIN_METAPAGE_BLKNO
#define GinPageHasFullRow(page)
#define GinPageGetOpaque(page)
signed char GinNullCategory
#define GinPageGetMeta(p)
#define GinPageIsDeleted(page)
#define GinPageSetFullRow(page)
void ginBeginBAScan(BuildAccumulator *accum)
void ginInsertBAEntries(BuildAccumulator *accum, ItemPointer heapptr, OffsetNumber attnum, Datum *entries, GinNullCategory *categories, int32 nentries)
void ginInitBA(BuildAccumulator *accum)
ItemPointerData * ginGetBAEntry(BuildAccumulator *accum, OffsetNumber *attnum, Datum *key, GinNullCategory *category, uint32 *n)
IndexTuple GinFormTuple(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, Pointer data, Size dataSize, int nipd, bool errorTooBig)
#define GIN_PAGE_FREESIZE
Datum gin_clean_pending_list(PG_FUNCTION_ARGS)
void ginInsertCleanup(GinState *ginstate, bool full_clean, bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats)
void ginHeapTupleFastCollect(GinState *ginstate, GinTupleCollector *collector, OffsetNumber attnum, Datum value, bool isNull, ItemPointer ht_ctid)
static int32 writeListPage(Relation index, Buffer buffer, IndexTuple *tuples, int32 ntuples, BlockNumber rightlink)
int gin_pending_list_limit
static void processPendingPage(BuildAccumulator *accum, KeyArray *ka, Page page, OffsetNumber startoff)
static void initKeyArray(KeyArray *keys, int32 maxvalues)
static void makeSublist(Relation index, IndexTuple *tuples, int32 ntuples, GinMetaPageData *res)
static void shiftList(Relation index, Buffer metabuffer, BlockNumber newHead, bool fill_fsm, IndexBulkDeleteResult *stats)
static void addDatum(KeyArray *keys, Datum datum, GinNullCategory category)
void ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
void ginEntryInsert(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats)
Datum * ginExtractEntries(GinState *ginstate, OffsetNumber attnum, Datum value, bool isNull, int32 *nentries, GinNullCategory **categories)
OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple)
Buffer GinNewBuffer(Relation index)
void GinInitBuffer(Buffer b, uint32 f)
Datum gintuple_get_key(GinState *ginstate, IndexTuple tuple, GinNullCategory *category)
void initGinState(GinState *state, Relation index)
static MemoryContext opCtx
#define XLOG_GIN_UPDATE_META_PAGE
#define GIN_NDELETE_AT_ONCE
#define XLOG_GIN_INSERT_LISTPAGE
#define XLOG_GIN_DELETE_LISTPAGE
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void IndexFreeSpaceMapVacuum(Relation rel)
void RecordFreeIndexPage(Relation rel, BlockNumber freeBlock)
struct ItemIdData ItemIdData
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
#define ItemPointerIsValid(pointer)
#define ItemPointerSetInvalid(pointer)
IndexTupleData * IndexTuple
#define IndexTupleSize(itup)
Assert(fmt[strlen(fmt) - 1] !='\n')
bool ConditionalLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
void LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
void UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
void MemoryContextReset(MemoryContext context)
MemoryContext CurrentMemoryContext
void * repalloc(void *pointer, Size size)
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define START_CRIT_SECTION()
#define END_CRIT_SECTION()
#define InvalidOffsetNumber
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static uint32 pg_nextpower2_32(uint32 num)
void CheckForSerializableConflictIn(Relation relation, ItemPointer tid, BlockNumber blkno)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
#define RELATION_IS_OTHER_TEMP(relation)
BlockNumber nPendingPages
BlockNumber pages_deleted
GinNullCategory * categories
void vacuum_delay_point(void)
bool RecoveryInProgress(void)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBufData(uint8 block_id, char *data, int len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)
void XLogEnsureRecordSpace(int max_block_id, int ndatas)
void XLogRegisterData(char *data, int len)