/* * Insert one new tuple into an SPGiST index. */ Datum spginsert(PG_FUNCTION_ARGS) { Relation index = (Relation) PG_GETARG_POINTER(0); Datum *values = (Datum *) PG_GETARG_POINTER(1); bool *isnull = (bool *) PG_GETARG_POINTER(2); ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3); #ifdef NOT_USED Relation heapRel = (Relation) PG_GETARG_POINTER(4); IndexUniqueCheck checkUnique = (IndexUniqueCheck) PG_GETARG_INT32(5); #endif SpGistState spgstate; MemoryContext oldCtx; MemoryContext insertCtx; insertCtx = AllocSetContextCreate(CurrentMemoryContext, "SP-GiST insert temporary context", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); oldCtx = MemoryContextSwitchTo(insertCtx); initSpGistState(&spgstate, index); spgdoinsert(index, &spgstate, ht_ctid, *values, *isnull); SpGistUpdateMetaPage(index); MemoryContextSwitchTo(oldCtx); MemoryContextDelete(insertCtx); /* return false since we've not done any unique check */ PG_RETURN_BOOL(false); }
/* Callback to process one heap tuple during IndexBuildHeapScan */ static void spgistBuildCallback(Relation index, HeapTuple htup, Datum *values, bool *isnull, bool tupleIsAlive, void *state) { SpGistBuildState *buildstate = (SpGistBuildState *) state; MemoryContext oldCtx; /* Work in temp context, and reset it after each tuple */ oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); /* * Even though no concurrent insertions can be happening, we still might * get a buffer-locking failure due to bgwriter or checkpointer taking a * lock on some buffer. So we need to be willing to retry. We can flush * any temp data when retrying. */ while (!spgdoinsert(index, &buildstate->spgstate, &htup->t_self, *values, *isnull)) { MemoryContextReset(buildstate->tmpCtx); } MemoryContextSwitchTo(oldCtx); MemoryContextReset(buildstate->tmpCtx); }
/* Callback to process one heap tuple during IndexBuildHeapScan */ static void spgistBuildCallback(Relation index, HeapTuple htup, Datum *values, bool *isnull, bool tupleIsAlive, void *state) { SpGistBuildState *buildstate = (SpGistBuildState *) state; MemoryContext oldCtx; /* Work in temp context, and reset it after each tuple */ oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); spgdoinsert(index, &buildstate->spgstate, &htup->t_self, *values, *isnull); MemoryContextSwitchTo(oldCtx); MemoryContextReset(buildstate->tmpCtx); }
/* * Insert one new tuple into an SPGiST index. */ Datum spginsert(PG_FUNCTION_ARGS) { Relation index = (Relation) PG_GETARG_POINTER(0); Datum *values = (Datum *) PG_GETARG_POINTER(1); bool *isnull = (bool *) PG_GETARG_POINTER(2); ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3); #ifdef NOT_USED Relation heapRel = (Relation) PG_GETARG_POINTER(4); IndexUniqueCheck checkUnique = (IndexUniqueCheck) PG_GETARG_INT32(5); #endif SpGistState spgstate; MemoryContext oldCtx; MemoryContext insertCtx; insertCtx = AllocSetContextCreate(CurrentMemoryContext, "SP-GiST insert temporary context", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); oldCtx = MemoryContextSwitchTo(insertCtx); initSpGistState(&spgstate, index); /* * We might have to repeat spgdoinsert() multiple times, if conflicts * occur with concurrent insertions. If so, reset the insertCtx each time * to avoid cumulative memory consumption. That means we also have to * redo initSpGistState(), but it's cheap enough not to matter. */ while (!spgdoinsert(index, &spgstate, ht_ctid, *values, *isnull)) { MemoryContextReset(insertCtx); initSpGistState(&spgstate, index); } SpGistUpdateMetaPage(index); MemoryContextSwitchTo(oldCtx); MemoryContextDelete(insertCtx); /* return false since we've not done any unique check */ PG_RETURN_BOOL(false); }
/* * Insert one new tuple into an SPGiST index. */ bool spginsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique) { SpGistState spgstate; MemoryContext oldCtx; MemoryContext insertCtx; insertCtx = AllocSetContextCreate(CurrentMemoryContext, "SP-GiST insert temporary context", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); oldCtx = MemoryContextSwitchTo(insertCtx); initSpGistState(&spgstate, index); /* * We might have to repeat spgdoinsert() multiple times, if conflicts * occur with concurrent insertions. If so, reset the insertCtx each time * to avoid cumulative memory consumption. That means we also have to * redo initSpGistState(), but it's cheap enough not to matter. */ while (!spgdoinsert(index, &spgstate, ht_ctid, *values, *isnull)) { MemoryContextReset(insertCtx); initSpGistState(&spgstate, index); } SpGistUpdateMetaPage(index); MemoryContextSwitchTo(oldCtx); MemoryContextDelete(insertCtx); /* return false since we've not done any unique check */ return false; }