PostgreSQL Source Code git master
Loading...
Searching...
No Matches
spginsert.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/spgist_private.h"
#include "access/tableam.h"
#include "access/xloginsert.h"
#include "miscadmin.h"
#include "nodes/execnodes.h"
#include "storage/bufmgr.h"
#include "storage/bulk_write.h"
#include "utils/memutils.h"
#include "utils/rel.h"
Include dependency graph for spginsert.c:

Go to the source code of this file.

Data Structures

struct  SpGistBuildState
 

Functions

static void spgistBuildCallback (Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
 
IndexBuildResultspgbuild (Relation heap, Relation index, IndexInfo *indexInfo)
 
void spgbuildempty (Relation index)
 
bool spginsert (Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)
 

Function Documentation

◆ spgbuild()

IndexBuildResult * spgbuild ( Relation  heap,
Relation  index,
IndexInfo indexInfo 
)

Definition at line 73 of file spginsert.c.

74{
75 IndexBuildResult *result;
76 double reltuples;
81
83 elog(ERROR, "index \"%s\" already contains data",
85
86 /*
87 * Initialize the meta page and root pages
88 */
92
96
98
105
106
108
112
113 /*
114 * Now insert all the heap data into the index
115 */
116 initSpGistState(&buildstate.spgstate, index);
117 buildstate.spgstate.isBuild = true;
118 buildstate.indtuples = 0;
119
121 "SP-GiST build temporary context",
123
124 reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
126 NULL);
127
129
131
132 /*
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.
135 */
137 {
140 true);
141 }
142
144 result->heap_tuples = reltuples;
145 result->index_tuples = buildstate.indtuples;
146
147 return result;
148}
int Buffer
Definition buf.h:23
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition bufmgr.c:4356
void UnlockReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5518
void MarkBufferDirty(Buffer buffer)
Definition bufmgr.c:3056
#define RelationGetNumberOfBlocks(reln)
Definition bufmgr.h:307
static Page BufferGetPage(Buffer buffer)
Definition bufmgr.h:466
#define Assert(condition)
Definition c.h:873
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define palloc0_object(type)
Definition fe_memutils.h:75
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
#define START_CRIT_SECTION()
Definition miscadmin.h:150
#define END_CRIT_SECTION()
Definition miscadmin.h:152
static int fb(int x)
#define RelationGetRelationName(relation)
Definition rel.h:548
#define RelationNeedsWAL(relation)
Definition rel.h:637
@ MAIN_FORKNUM
Definition relpath.h:58
static void spgistBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
Definition spginsert.c:41
#define SPGIST_NULL_BLKNO
#define SPGIST_METAPAGE_BLKNO
#define SPGIST_NULLS
#define SPGIST_LEAF
#define SPGIST_ROOT_BLKNO
void initSpGistState(SpGistState *state, Relation index)
Definition spgutils.c:349
void SpGistUpdateMetaPage(Relation index)
Definition spgutils.c:451
Buffer SpGistNewBuffer(Relation index)
Definition spgutils.c:395
void SpGistInitBuffer(Buffer b, uint16 f)
Definition spgutils.c:723
void SpGistInitMetapage(Page page)
Definition spgutils.c:733
double heap_tuples
Definition genam.h:38
double index_tuples
Definition genam.h:39
Definition type.h:96
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)
Definition tableam.h:1766
void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std)

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, BufferGetBlockNumber(), BufferGetPage(), CurrentMemoryContext, elog, END_CRIT_SECTION, ERROR, fb(), IndexBuildResult::heap_tuples, IndexBuildResult::index_tuples, initSpGistState(), log_newpage_range(), MAIN_FORKNUM, MarkBufferDirty(), MemoryContextDelete(), palloc0_object, RelationGetNumberOfBlocks, RelationGetRelationName, RelationNeedsWAL, SPGIST_LEAF, SPGIST_METAPAGE_BLKNO, SPGIST_NULL_BLKNO, SPGIST_NULLS, SPGIST_ROOT_BLKNO, spgistBuildCallback(), SpGistInitBuffer(), SpGistInitMetapage(), SpGistNewBuffer(), SpGistUpdateMetaPage(), START_CRIT_SECTION, table_index_build_scan(), and UnlockReleaseBuffer().

Referenced by spghandler().

◆ spgbuildempty()

void spgbuildempty ( Relation  index)

Definition at line 154 of file spginsert.c.

155{
156 BulkWriteState *bulkstate;
158
160
161 /* Construct metapage. */
162 buf = smgr_bulk_get_buf(bulkstate);
164 smgr_bulk_write(bulkstate, SPGIST_METAPAGE_BLKNO, buf, true);
165
166 /* Likewise for the root page. */
167 buf = smgr_bulk_get_buf(bulkstate);
169 smgr_bulk_write(bulkstate, SPGIST_ROOT_BLKNO, buf, true);
170
171 /* Likewise for the null-tuples root page. */
172 buf = smgr_bulk_get_buf(bulkstate);
174 smgr_bulk_write(bulkstate, SPGIST_NULL_BLKNO, buf, true);
175
176 smgr_bulk_finish(bulkstate);
177}
PageData * Page
Definition bufpage.h:81
BulkWriteState * smgr_bulk_start_rel(Relation rel, ForkNumber forknum)
Definition bulk_write.c:87
void smgr_bulk_write(BulkWriteState *bulkstate, BlockNumber blocknum, BulkWriteBuffer buf, bool page_std)
Definition bulk_write.c:323
BulkWriteBuffer smgr_bulk_get_buf(BulkWriteState *bulkstate)
Definition bulk_write.c:347
void smgr_bulk_finish(BulkWriteState *bulkstate)
Definition bulk_write.c:130
static char buf[DEFAULT_XLOG_SEG_SIZE]
@ INIT_FORKNUM
Definition relpath.h:61
void SpGistInitPage(Page page, uint16 f)
Definition spgutils.c:709

References buf, INIT_FORKNUM, smgr_bulk_finish(), smgr_bulk_get_buf(), smgr_bulk_start_rel(), smgr_bulk_write(), SPGIST_LEAF, SPGIST_METAPAGE_BLKNO, SPGIST_NULL_BLKNO, SPGIST_NULLS, SPGIST_ROOT_BLKNO, SpGistInitMetapage(), and SpGistInitPage().

Referenced by spghandler().

◆ spginsert()

bool spginsert ( Relation  index,
Datum values,
bool isnull,
ItemPointer  ht_ctid,
Relation  heapRel,
IndexUniqueCheck  checkUnique,
bool  indexUnchanged,
IndexInfo indexInfo 
)

Definition at line 183 of file spginsert.c.

188{
189 SpGistState spgstate;
192
194 "SP-GiST insert temporary context",
197
198 initSpGistState(&spgstate, index);
199
200 /*
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.
205 */
206 while (!spgdoinsert(index, &spgstate, ht_ctid, values, isnull))
207 {
209 initSpGistState(&spgstate, index);
210 }
211
213
216
217 /* return false since we've not done any unique check */
218 return false;
219}
static Datum values[MAXATTR]
Definition bootstrap.c:155
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
bool spgdoinsert(Relation index, SpGistState *state, const ItemPointerData *heapPtr, const Datum *datums, const bool *isnulls)

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, CurrentMemoryContext, fb(), initSpGistState(), MemoryContextDelete(), MemoryContextReset(), MemoryContextSwitchTo(), spgdoinsert(), SpGistUpdateMetaPage(), and values.

Referenced by spghandler().

◆ spgistBuildCallback()

static void spgistBuildCallback ( Relation  index,
ItemPointer  tid,
Datum values,
bool isnull,
bool  tupleIsAlive,
void state 
)
static

Definition at line 41 of file spginsert.c.

43{
46
47 /* Work in temp context, and reset it after each tuple */
49
50 /*
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.
55 */
56 while (!spgdoinsert(index, &buildstate->spgstate, tid,
57 values, isnull))
58 {
60 }
61
62 /* Update total tuple count */
63 buildstate->indtuples += 1;
64
67}

References fb(), MemoryContextReset(), MemoryContextSwitchTo(), spgdoinsert(), and values.

Referenced by spgbuild().