1/*-------------------------------------------------------------------------
4 * Externally visible index creation/insertion routines
6 * All the actual insertion logic is in spgdoinsert.c.
8 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
12 * src/backend/access/spgist/spginsert.c
14 *-------------------------------------------------------------------------
39/* Callback to process one heap tuple during table_index_build_scan */
42 bool *isnull,
bool tupleIsAlive,
void *
state)
47 /* Work in temp context, and reset it after each tuple */
51 * Even though no concurrent insertions can be happening, we still might
52 * get a buffer-locking failure due to bgwriter or checkpointer taking a
53 * lock on some buffer. So we need to be willing to retry. We can flush
54 * any temp data when retrying.
62 /* Update total tuple count */
70 * Build an SP-GiST index.
83 elog(
ERROR,
"index \"%s\" already contains data",
87 * Initialize the meta page and root pages
114 * Now insert all the heap data into the index
121 "SP-GiST build temporary context",
133 * We didn't write WAL records as we built the index, so if WAL-logging is
134 * required, write all pages to the WAL now.
151 * Build an empty SPGiST index in the initialization fork
161 /* Construct metapage. */
166 /* Likewise for the root page. */
171 /* Likewise for the null-tuples root page. */
180 * Insert one new tuple into an SPGiST index.
194 "SP-GiST insert temporary context",
201 * We might have to repeat spgdoinsert() multiple times, if conflicts
202 * occur with concurrent insertions. If so, reset the insertCtx each time
203 * to avoid cumulative memory consumption. That means we also have to
204 * redo initSpGistState(), but it's cheap enough not to matter.
217 /* return false since we've not done any unique check */
static Datum values[MAXATTR]
BlockNumber BufferGetBlockNumber(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
BulkWriteState * smgr_bulk_start_rel(Relation rel, ForkNumber forknum)
void smgr_bulk_write(BulkWriteState *bulkstate, BlockNumber blocknum, BulkWriteBuffer buf, bool page_std)
BulkWriteBuffer smgr_bulk_get_buf(BulkWriteState *bulkstate)
void smgr_bulk_finish(BulkWriteState *bulkstate)
Assert(PointerIsAligned(start, uint64))
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()
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
bool spgdoinsert(Relation index, SpGistState *state, ItemPointer heapPtr, Datum *datums, bool *isnulls)
IndexBuildResult * spgbuild(Relation heap, Relation index, IndexInfo *indexInfo)
static void spgistBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
bool spginsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)
void spgbuildempty(Relation index)
#define SPGIST_NULL_BLKNO
#define SPGIST_METAPAGE_BLKNO
#define SPGIST_ROOT_BLKNO
void initSpGistState(SpGistState *state, Relation index)
void SpGistUpdateMetaPage(Relation index)
Buffer SpGistNewBuffer(Relation index)
void SpGistInitBuffer(Buffer b, uint16 f)
void SpGistInitPage(Page page, uint16 f)
void SpGistInitMetapage(Page page)
static double table_index_build_scan(Relation table_rel, Relation index_rel, IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std)