39#define PARALLEL_KEY_GIN_SHARED UINT64CONST(0xB000000000000001)
40#define PARALLEL_KEY_TUPLESORT UINT64CONST(0xB000000000000002)
41#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xB000000000000003)
42#define PARALLEL_KEY_WAL_USAGE UINT64CONST(0xB000000000000004)
43#define PARALLEL_KEY_BUFFER_USAGE UINT64CONST(0xB000000000000005)
104#define ParallelTableScanFromGinBuildShared(shared) \
105 (ParallelTableScanDesc) ((char *) (shared) + BUFFERALIGN(sizeof(GinBuildShared)))
180 bool isconcurrent,
int request);
233 oldItems, oldNPosting,
244 (
char *) compressedList,
248 pfree(compressedList);
302 (
char *) compressedList,
305 pfree(compressedList);
353 btree.
isBuild = (buildStats != NULL);
404 insertdata.
entry = itup;
428 &nentries, &categories);
432 entries, categories, nentries);
441 bool *isnull,
bool tupleIsAlive,
void *
state)
464 &
attnum, &
key, &category, &nlist)) != NULL)
495 &
attnum, &
key, &category, &nlist)) != NULL)
508 key, attr->attlen, attr->attbyval,
509 list, nlist, &tuplen);
534 bool *isnull,
bool tupleIsAlive,
void *
state)
563 buildstate->
tid = *tid;
597 elog(
ERROR,
"index \"%s\" already contains data",
635 "Gin build temporary context",
643 "Gin build temporary context for user-defined function",
675 if (
state->bs_leader)
682 state->bs_leader->nparticipanttuplesorts;
707 state->bs_sortstate =
730 &
attnum, &
key, &category, &nlist)) != NULL)
816 &nentries, &categories);
818 for (
i = 0;
i < nentries;
i++)
836 if (ginstate == NULL)
846 "Gin insert temporary context",
897 bool isconcurrent,
int request)
900 int scantuplesortstates;
909 bool leaderparticipates =
true;
912#ifdef DISABLE_LEADER_PARTICIPATION
913 leaderparticipates =
false;
924 scantuplesortstates = leaderparticipates ? request + 1 : request;
977 if (pcxt->
seg == NULL)
1040 ginleader->
pcxt = pcxt;
1042 if (leaderparticipates)
1061 if (leaderparticipates)
1109 int nparticipanttuplesorts;
1111 nparticipanttuplesorts =
state->bs_leader->nparticipanttuplesorts;
1127 WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN);
1132 return state->bs_reltuples;
1175#ifdef USE_ASSERT_CHECKING
1180 for (
int i = 0;
i < buffer->
nitems;
i++)
1202#ifdef USE_ASSERT_CHECKING
1251 for (
i = 0;
i < nKeys;
i++)
1282 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
1283 errmsg(
"could not identify a comparison function for type %s",
1299 return (buffer->
nitems == 0);
1456 if ((buffer->
nitems > 0) &&
1494 if (buffer->
items == NULL)
1617 double reltuples = 0;
1621 double numtuples = 0;
1646 const int progress_index[] = {
1652 const int64 progress_vals[] = {
1654 state->bs_numtuples,
1832 state->bs_numtuples = 0;
1869 state->bs_numtuples++;
1930 state->bs_numtuples++;
2002 state->work_mem = (sortmem / 2);
2039 state->bs_reltuples += reltuples;
2118 "Gin build temporary context",
2126 "Gin build temporary context for user-defined function",
2148 heapRel, indexRel, sortmem,
false);
2220 keylen =
sizeof(
Datum);
2221 else if (typlen > 0)
2223 else if (typlen == -1)
2225 else if (typlen == -2)
2228 elog(
ERROR,
"unexpected typlen value (%d)", typlen);
2236 while (ncompressed <
nitems)
2290 else if (typlen > 0)
2294 else if (typlen == -1)
2298 else if (typlen == -2)
2346 memcpy(&
key,
a->data,
a->keylen);
2370 Assert(ndecoded ==
a->nitems);
2396 if (
a->attrnum <
b->attrnum)
2399 if (
a->attrnum >
b->attrnum)
2402 if (
a->category <
b->category)
2405 if (
a->category >
b->category)
2415 &ssup[
a->attrnum - 1]);
void InitializeParallelDSM(ParallelContext *pcxt)
void WaitForParallelWorkersToFinish(ParallelContext *pcxt)
void LaunchParallelWorkers(ParallelContext *pcxt)
void DestroyParallelContext(ParallelContext *pcxt)
ParallelContext * CreateParallelContext(const char *library_name, const char *function_name, int nworkers)
void WaitForParallelWorkersToAttach(ParallelContext *pcxt)
void pgstat_progress_update_param(int index, int64 val)
void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)
void pgstat_report_activity(BackendState state, const char *cmd_str)
static Datum values[MAXATTR]
BlockNumber BufferGetBlockNumber(Buffer buffer)
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
#define OidIsValid(objectId)
bool ConditionVariableCancelSleep(void)
void ConditionVariableInit(ConditionVariable *cv)
void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
void ConditionVariableSignal(ConditionVariable *cv)
Datum datumCopy(Datum value, bool typByVal, int typLen)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PROGRESS_GIN_PHASE_PERFORMSORT_2
#define PROGRESS_GIN_PHASE_MERGE_1
#define PROGRESS_GIN_PHASE_PERFORMSORT_1
#define PROGRESS_GIN_PHASE_MERGE_2
#define PROGRESS_GIN_PHASE_INDEXBUILD_TABLESCAN
#define GinGetUseFastUpdate(relation)
static ItemPointer GinTupleGetFirst(GinTuple *tup)
#define GinIsPostingTree(itup)
#define SizeOfGinPostingList(plist)
#define GinGetPostingTree(itup)
signed char GinNullCategory
#define GinSetPostingTree(itup, blkno)
void freeGinBtreeStack(GinBtreeStack *stack)
void ginInsertValue(GinBtree btree, GinBtreeStack *stack, void *insertdata, GinStatsData *buildStats)
GinBtreeStack * ginFindLeafPage(GinBtree btree, bool searchMode, bool rootConflictCheck)
void ginBeginBAScan(BuildAccumulator *accum)
ItemPointerData * ginGetBAEntry(BuildAccumulator *accum, OffsetNumber *attnum, Datum *key, GinNullCategory *category, uint32 *n)
void ginInsertBAEntries(BuildAccumulator *accum, ItemPointer heapptr, OffsetNumber attnum, Datum *entries, GinNullCategory *categories, int32 nentries)
void ginInitBA(BuildAccumulator *accum)
BlockNumber createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, GinStatsData *buildStats, Buffer entrybuffer)
void ginInsertItemPointers(Relation index, BlockNumber rootBlkno, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats)
ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum, IndexTuple itup, int *nitems)
IndexTuple GinFormTuple(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, Pointer data, Size dataSize, int nipd, bool errorTooBig)
void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum, Datum key, GinNullCategory category, GinState *ginstate)
void ginHeapTupleFastCollect(GinState *ginstate, GinTupleCollector *collector, OffsetNumber attnum, Datum value, bool isNull, ItemPointer ht_ctid)
void ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
static void ginBuildCallbackParallel(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
#define PARALLEL_KEY_BUFFER_USAGE
static void AssertCheckItemPointers(GinBuffer *buffer)
int _gin_compare_tuples(GinTuple *a, GinTuple *b, SortSupport ssup)
struct GinBuffer GinBuffer
struct GinLeader GinLeader
static IndexTuple addItemPointersToLeafTuple(GinState *ginstate, IndexTuple old, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats, Buffer buffer)
static bool GinBufferIsEmpty(GinBuffer *buffer)
#define PARALLEL_KEY_GIN_SHARED
IndexBuildResult * ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
static GinBuffer * GinBufferInit(Relation index)
static IndexTuple buildFreshLeafTuple(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats, Buffer buffer)
static void GinBufferReset(GinBuffer *buffer)
static void ginHeapTupleBulkInsert(GinBuildState *buildstate, OffsetNumber attnum, Datum value, bool isNull, ItemPointer heapptr)
static void AssertCheckGinBuffer(GinBuffer *buffer)
static void _gin_parallel_scan_and_build(GinBuildState *state, GinBuildShared *ginshared, Sharedsort *sharedsort, Relation heap, Relation index, int sortmem, bool progress)
void ginEntryInsert(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats)
static void GinBufferTrim(GinBuffer *buffer)
static Size _gin_parallel_estimate_shared(Relation heap, Snapshot snapshot)
static void _gin_end_parallel(GinLeader *ginleader, GinBuildState *state)
static void _gin_begin_parallel(GinBuildState *buildstate, Relation heap, Relation index, bool isconcurrent, int request)
static void ginFlushBuildState(GinBuildState *buildstate, Relation index)
struct GinBuildShared GinBuildShared
static void _gin_process_worker_data(GinBuildState *state, Tuplesortstate *worker_sort, bool progress)
static bool GinBufferKeyEquals(GinBuffer *buffer, GinTuple *tup)
static double _gin_parallel_merge(GinBuildState *state)
static void ginHeapTupleInsert(GinState *ginstate, OffsetNumber attnum, Datum value, bool isNull, ItemPointer item)
static bool GinBufferCanAddKey(GinBuffer *buffer, GinTuple *tup)
void _gin_parallel_build_main(dsm_segment *seg, shm_toc *toc)
void ginbuildempty(Relation index)
bool gininsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)
static void _gin_leader_participate_as_worker(GinBuildState *buildstate, Relation heap, Relation index)
static GinTuple * _gin_build_tuple(OffsetNumber attrnum, unsigned char category, Datum key, int16 typlen, bool typbyval, ItemPointerData *items, uint32 nitems, Size *len)
static Datum _gin_parse_tuple_key(GinTuple *a)
#define PARALLEL_KEY_TUPLESORT
static bool GinBufferShouldTrim(GinBuffer *buffer, GinTuple *tup)
#define PARALLEL_KEY_QUERY_TEXT
static void GinBufferFree(GinBuffer *buffer)
static ItemPointer _gin_parse_tuple_items(GinTuple *a)
#define ParallelTableScanFromGinBuildShared(shared)
#define PARALLEL_KEY_WAL_USAGE
static void GinBufferStoreTuple(GinBuffer *buffer, GinTuple *tup)
static void ginBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
static double _gin_parallel_heapscan(GinBuildState *state)
ItemPointer ginPostingListDecodeAllSegments(GinPostingList *segment, int len, int *ndecoded_out)
GinPostingList * ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize, int *nwritten)
ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na, ItemPointerData *b, uint32 nb, int *nmerged)
OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple)
Buffer GinNewBuffer(Relation index)
void GinInitBuffer(Buffer b, uint32 f)
Datum * ginExtractEntries(GinState *ginstate, OffsetNumber attnum, Datum value, bool isNull, int32 *nentries, GinNullCategory **categories)
Datum gintuple_get_key(GinState *ginstate, IndexTuple tuple, GinNullCategory *category)
void GinInitMetabuffer(Buffer b)
void initGinState(GinState *state, Relation index)
void ginUpdateStats(Relation index, const GinStatsData *stats, bool is_build)
Assert(PointerIsAligned(start, uint64))
static void dlist_init(dlist_head *head)
static void dlist_delete(dlist_node *node)
#define dlist_foreach_modify(iter, lhead)
static void dlist_push_tail(dlist_head *head, dlist_node *node)
#define dlist_container(type, membername, ptr)
IndexInfo * BuildIndexInfo(Relation index)
void index_close(Relation relation, LOCKMODE lockmode)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void InstrAccumParallelQuery(BufferUsage *bufusage, WalUsage *walusage)
void InstrEndParallelQuery(BufferUsage *bufusage, WalUsage *walusage)
void InstrStartParallelQuery(void)
if(TABLE==NULL||TABLE_index==NULL)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
static bool ItemPointerIsValid(const ItemPointerData *pointer)
IndexTupleData * IndexTuple
#define AccessExclusiveLock
#define ShareUpdateExclusiveLock
void MemoryContextReset(MemoryContext context)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define START_CRIT_SECTION()
#define CHECK_FOR_INTERRUPTS()
#define END_CRIT_SECTION()
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
FormData_pg_attribute * Form_pg_attribute
const char * debug_query_string
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
void CheckForSerializableConflictIn(Relation relation, ItemPointer tid, BlockNumber blkno)
#define PROGRESS_CREATEIDX_TUPLES_TOTAL
#define PROGRESS_SCAN_BLOCKS_DONE
#define PROGRESS_CREATEIDX_TUPLES_DONE
#define PROGRESS_CREATEIDX_SUBPHASE
#define PROGRESS_SCAN_BLOCKS_TOTAL
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
#define shm_toc_estimate_chunk(e, sz)
#define shm_toc_estimate_keys(e, cnt)
Size add_size(Size s1, Size s2)
Size mul_size(Size s1, Size s2)
Snapshot GetTransactionSnapshot(void)
void UnregisterSnapshot(Snapshot snapshot)
Snapshot RegisterSnapshot(Snapshot snapshot)
#define IsMVCCSnapshot(snapshot)
void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)
static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
#define SpinLockInit(lock)
#define SpinLockRelease(lock)
#define SpinLockAcquire(lock)
bool(* findItem)(GinBtree, GinBtreeStack *)
ConditionVariable workersdonecv
Tuplesortstate * bs_worker_sort
Tuplesortstate * bs_sortstate
int nparticipanttuplesorts
BufferUsage * bufferusage
GinBuildShared * ginshared
char data[FLEXIBLE_ARRAY_MEMBER]
shm_toc_estimator estimator
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TableScanDesc table_beginscan_parallel(Relation relation, ParallelTableScanDesc pscan)
Size table_parallelscan_estimate(Relation rel, Snapshot snapshot)
void table_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan, Snapshot snapshot)
static double table_index_build_scan(Relation table_rel, Relation index_rel, struct IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
void tuplesort_performsort(Tuplesortstate *state)
void tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Size tuplesort_estimate_shared(int nWorkers)
void tuplesort_end(Tuplesortstate *state)
void tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
struct SortCoordinateData * SortCoordinate
Tuplesortstate * tuplesort_begin_index_gin(Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)
GinTuple * tuplesort_getgintuple(Tuplesortstate *state, Size *len, bool forward)
void tuplesort_putgintuple(Tuplesortstate *state, GinTuple *tuple, Size size)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
#define TYPECACHE_CMP_PROC_FINFO
void ExitParallelMode(void)
void EnterParallelMode(void)
void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std)
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)