summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/bloom/blinsert.c4
-rw-r--r--contrib/bloom/bloom.h3
-rw-r--r--doc/src/sgml/indexam.sgml11
-rw-r--r--src/backend/access/brin/brin.c25
-rw-r--r--src/backend/access/gin/gininsert.c27
-rw-r--r--src/backend/access/gist/gist.c25
-rw-r--r--src/backend/access/hash/hash.c3
-rw-r--r--src/backend/access/heap/tuptoaster.c7
-rw-r--r--src/backend/access/index/indexam.c5
-rw-r--r--src/backend/access/nbtree/nbtree.c3
-rw-r--r--src/backend/access/spgist/spginsert.c3
-rw-r--r--src/backend/catalog/index.c7
-rw-r--r--src/backend/catalog/indexing.c3
-rw-r--r--src/backend/catalog/toasting.c2
-rw-r--r--src/backend/commands/constraint.c3
-rw-r--r--src/backend/commands/indexcmds.c4
-rw-r--r--src/backend/executor/execIndexing.c3
-rw-r--r--src/include/access/amapi.h3
-rw-r--r--src/include/access/brin_internal.h3
-rw-r--r--src/include/access/genam.h6
-rw-r--r--src/include/access/gin_private.h3
-rw-r--r--src/include/access/gist_private.h3
-rw-r--r--src/include/access/hash.h3
-rw-r--r--src/include/access/nbtree.h3
-rw-r--r--src/include/access/spgist.h3
-rw-r--r--src/include/nodes/execnodes.h4
26 files changed, 117 insertions, 52 deletions
diff --git a/contrib/bloom/blinsert.c b/contrib/bloom/blinsert.c
index 29bc5cea79..913f1f8a51 100644
--- a/contrib/bloom/blinsert.c
+++ b/contrib/bloom/blinsert.c
@@ -190,7 +190,9 @@ blbuildempty(Relation index)
*/
bool
blinsert(Relation index, Datum *values, bool *isnull,
- ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique)
+ ItemPointer ht_ctid, Relation heapRel,
+ IndexUniqueCheck checkUnique,
+ IndexInfo *indexInfo)
{
BloomState blstate;
BloomTuple *itup;
diff --git a/contrib/bloom/bloom.h b/contrib/bloom/bloom.h
index a75a235a4f..39d8d05c5d 100644
--- a/contrib/bloom/bloom.h
+++ b/contrib/bloom/bloom.h
@@ -189,7 +189,8 @@ extern bool blvalidate(Oid opclassoid);
/* index access method interface functions */
extern bool blinsert(Relation index, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique);
+ IndexUniqueCheck checkUnique,
+ struct IndexInfo *indexInfo);
extern IndexScanDesc blbeginscan(Relation r, int nkeys, int norderbys);
extern int64 blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
extern void blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml
index 5d8e557460..9afd7f6417 100644
--- a/doc/src/sgml/indexam.sgml
+++ b/doc/src/sgml/indexam.sgml
@@ -259,7 +259,8 @@ aminsert (Relation indexRelation,
bool *isnull,
ItemPointer heap_tid,
Relation heapRelation,
- IndexUniqueCheck checkUnique);
+ IndexUniqueCheck checkUnique,
+ IndexInfo *indexInfo);
</programlisting>
Insert a new tuple into an existing index. The <literal>values</> and
<literal>isnull</> arrays give the key values to be indexed, and
@@ -288,6 +289,14 @@ aminsert (Relation indexRelation,
</para>
<para>
+ If the index AM wishes to cache data across successive index insertions
+ within a SQL statement, it can allocate space
+ in <literal>indexInfo-&gt;ii_Context</literal> and store a pointer to the
+ data in <literal>indexInfo-&gt;ii_AmCache</literal> (which will be NULL
+ initially).
+ </para>
+
+ <para>
<programlisting>
IndexBulkDeleteResult *
ambulkdelete (IndexVacuumInfo *info,
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index b2afdb7bed..4ff046b4b0 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -131,14 +131,15 @@ brinhandler(PG_FUNCTION_ARGS)
bool
brininsert(Relation idxRel, Datum *values, bool *nulls,
ItemPointer heaptid, Relation heapRel,
- IndexUniqueCheck checkUnique)
+ IndexUniqueCheck checkUnique,
+ IndexInfo *indexInfo)
{
BlockNumber pagesPerRange;
- BrinDesc *bdesc = NULL;
+ BrinDesc *bdesc = (BrinDesc *) indexInfo->ii_AmCache;
BrinRevmap *revmap;
Buffer buf = InvalidBuffer;
MemoryContext tupcxt = NULL;
- MemoryContext oldcxt = NULL;
+ MemoryContext oldcxt = CurrentMemoryContext;
revmap = brinRevmapInitialize(idxRel, &pagesPerRange, NULL);
@@ -163,14 +164,21 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
if (!brtup)
break;
- /* First time through? */
+ /* First time through in this statement? */
if (bdesc == NULL)
{
+ MemoryContextSwitchTo(indexInfo->ii_Context);
bdesc = brin_build_desc(idxRel);
+ indexInfo->ii_AmCache = (void *) bdesc;
+ MemoryContextSwitchTo(oldcxt);
+ }
+ /* First time through in this brininsert call? */
+ if (tupcxt == NULL)
+ {
tupcxt = AllocSetContextCreate(CurrentMemoryContext,
"brininsert cxt",
ALLOCSET_DEFAULT_SIZES);
- oldcxt = MemoryContextSwitchTo(tupcxt);
+ MemoryContextSwitchTo(tupcxt);
}
dtup = brin_deform_tuple(bdesc, brtup);
@@ -261,12 +269,9 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
brinRevmapTerminate(revmap);
if (BufferIsValid(buf))
ReleaseBuffer(buf);
- if (bdesc != NULL)
- {
- brin_free_desc(bdesc);
- MemoryContextSwitchTo(oldcxt);
+ MemoryContextSwitchTo(oldcxt);
+ if (tupcxt != NULL)
MemoryContextDelete(tupcxt);
- }
return false;
}
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index 03a7235a0a..3d3b9e0840 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -482,39 +482,48 @@ ginHeapTupleInsert(GinState *ginstate, OffsetNumber attnum,
bool
gininsert(Relation index, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique)
+ IndexUniqueCheck checkUnique,
+ IndexInfo *indexInfo)
{
- GinState ginstate;
+ GinState *ginstate = (GinState *) indexInfo->ii_AmCache;
MemoryContext oldCtx;
MemoryContext insertCtx;
int i;
+ /* Initialize GinState cache if first call in this statement */
+ if (ginstate == NULL)
+ {
+ oldCtx = MemoryContextSwitchTo(indexInfo->ii_Context);
+ ginstate = (GinState *) palloc(sizeof(GinState));
+ initGinState(ginstate, index);
+ indexInfo->ii_AmCache = (void *) ginstate;
+ MemoryContextSwitchTo(oldCtx);
+ }
+
insertCtx = AllocSetContextCreate(CurrentMemoryContext,
"Gin insert temporary context",
ALLOCSET_DEFAULT_SIZES);
oldCtx = MemoryContextSwitchTo(insertCtx);
- initGinState(&ginstate, index);
-
if (GinGetUseFastUpdate(index))
{
GinTupleCollector collector;
memset(&collector, 0, sizeof(GinTupleCollector));
- for (i = 0; i < ginstate.origTupdesc->natts; i++)
- ginHeapTupleFastCollect(&ginstate, &collector,
+ for (i = 0; i < ginstate->origTupdesc->natts; i++)
+ ginHeapTupleFastCollect(ginstate, &collector,
(OffsetNumber) (i + 1),
values[i], isnull[i],
ht_ctid);
- ginHeapTupleFastInsert(&ginstate, &collector);
+ ginHeapTupleFastInsert(ginstate, &collector);
}
else
{
- for (i = 0; i < ginstate.origTupdesc->natts; i++)
- ginHeapTupleInsert(&ginstate, (OffsetNumber) (i + 1),
+ for (i = 0; i < ginstate->origTupdesc->natts; i++)
+ ginHeapTupleInsert(ginstate, (OffsetNumber) (i + 1),
values[i], isnull[i],
ht_ctid);
}
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index c2247ad2f7..96ead531ea 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -18,6 +18,7 @@
#include "access/gistscan.h"
#include "catalog/pg_collation.h"
#include "miscadmin.h"
+#include "nodes/execnodes.h"
#include "utils/builtins.h"
#include "utils/index_selfuncs.h"
#include "utils/memutils.h"
@@ -144,21 +145,23 @@ gistbuildempty(Relation index)
bool
gistinsert(Relation r, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique)
+ IndexUniqueCheck checkUnique,
+ IndexInfo *indexInfo)
{
+ GISTSTATE *giststate = (GISTSTATE *) indexInfo->ii_AmCache;
IndexTuple itup;
- GISTSTATE *giststate;
MemoryContext oldCxt;
- giststate = initGISTstate(r);
+ /* Initialize GISTSTATE cache if first call in this statement */
+ if (giststate == NULL)
+ {
+ oldCxt = MemoryContextSwitchTo(indexInfo->ii_Context);
+ giststate = initGISTstate(r);
+ giststate->tempCxt = createTempGistContext();
+ indexInfo->ii_AmCache = (void *) giststate;
+ MemoryContextSwitchTo(oldCxt);
+ }
- /*
- * We use the giststate's scan context as temp context too. This means
- * that any memory leaked by the support functions is not reclaimed until
- * end of insert. In most cases, we aren't going to call the support
- * functions very many times before finishing the insert, so this seems
- * cheaper than resetting a temp context for each function call.
- */
oldCxt = MemoryContextSwitchTo(giststate->tempCxt);
itup = gistFormTuple(giststate, r,
@@ -169,7 +172,7 @@ gistinsert(Relation r, Datum *values, bool *isnull,
/* cleanup */
MemoryContextSwitchTo(oldCxt);
- freeGISTstate(giststate);
+ MemoryContextReset(giststate->tempCxt);
return false;
}
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index 97ad22aa6f..bca77a80c3 100644
--- a/src/backend/access/hash/hash.c
+++ b/src/backend/access/hash/hash.c
@@ -232,7 +232,8 @@ hashbuildCallback(Relation index,
bool
hashinsert(Relation rel, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique)
+ IndexUniqueCheck checkUnique,
+ IndexInfo *indexInfo)
{
Datum index_values[1];
bool index_isnull[1];
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index 496648c42f..19e7048002 100644
--- a/src/backend/access/heap/tuptoaster.c
+++ b/src/backend/access/heap/tuptoaster.c
@@ -1604,7 +1604,9 @@ toast_save_datum(Relation rel, Datum value,
* Create the index entry. We cheat a little here by not using
* FormIndexDatum: this relies on the knowledge that the index columns
* are the same as the initial columns of the table for all the
- * indexes.
+ * indexes. We also cheat by not providing an IndexInfo: this is okay
+ * for now because btree doesn't need one, but we might have to be
+ * more honest someday.
*
* Note also that there had better not be any user-created index on
* the TOAST table, since we don't bother to update anything else.
@@ -1617,7 +1619,8 @@ toast_save_datum(Relation rel, Datum value,
&(toasttup->t_self),
toastrel,
toastidxs[i]->rd_index->indisunique ?
- UNIQUE_CHECK_YES : UNIQUE_CHECK_NO);
+ UNIQUE_CHECK_YES : UNIQUE_CHECK_NO,
+ NULL);
}
/*
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index ba27c1e86d..4e7eca73cc 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -196,7 +196,8 @@ index_insert(Relation indexRelation,
bool *isnull,
ItemPointer heap_t_ctid,
Relation heapRelation,
- IndexUniqueCheck checkUnique)
+ IndexUniqueCheck checkUnique,
+ IndexInfo *indexInfo)
{
RELATION_CHECKS;
CHECK_REL_PROCEDURE(aminsert);
@@ -208,7 +209,7 @@ index_insert(Relation indexRelation,
return indexRelation->rd_amroutine->aminsert(indexRelation, values, isnull,
heap_t_ctid, heapRelation,
- checkUnique);
+ checkUnique, indexInfo);
}
/*
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 469e7abe4d..945e563fcc 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -276,7 +276,8 @@ btbuildempty(Relation index)
bool
btinsert(Relation rel, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique)
+ IndexUniqueCheck checkUnique,
+ IndexInfo *indexInfo)
{
bool result;
IndexTuple itup;
diff --git a/src/backend/access/spgist/spginsert.c b/src/backend/access/spgist/spginsert.c
index b42f4b7139..14f8a9ee8e 100644
--- a/src/backend/access/spgist/spginsert.c
+++ b/src/backend/access/spgist/spginsert.c
@@ -206,7 +206,8 @@ spgbuildempty(Relation index)
bool
spginsert(Relation index, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique)
+ IndexUniqueCheck checkUnique,
+ IndexInfo *indexInfo)
{
SpGistState spgstate;
MemoryContext oldCtx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 815a694cfc..f8d92145e8 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1687,6 +1687,10 @@ BuildIndexInfo(Relation index)
ii->ii_Concurrent = false;
ii->ii_BrokenHotChain = false;
+ /* set up for possible use by index AM */
+ ii->ii_AmCache = NULL;
+ ii->ii_Context = CurrentMemoryContext;
+
return ii;
}
@@ -3158,7 +3162,8 @@ validate_index_heapscan(Relation heapRelation,
&rootTuple,
heapRelation,
indexInfo->ii_Unique ?
- UNIQUE_CHECK_YES : UNIQUE_CHECK_NO);
+ UNIQUE_CHECK_YES : UNIQUE_CHECK_NO,
+ indexInfo);
state->tups_inserted += 1;
}
diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
index 76268e1d2a..abc344ad69 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -139,7 +139,8 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
&(heapTuple->t_self), /* tid of heap tuple */
heapRelation,
relationDescs[i]->rd_index->indisunique ?
- UNIQUE_CHECK_YES : UNIQUE_CHECK_NO);
+ UNIQUE_CHECK_YES : UNIQUE_CHECK_NO,
+ indexInfo);
}
ExecDropSingleTupleTableSlot(slot);
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index e5f773d51d..0e4231668d 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -315,6 +315,8 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
indexInfo->ii_ReadyForInserts = true;
indexInfo->ii_Concurrent = false;
indexInfo->ii_BrokenHotChain = false;
+ indexInfo->ii_AmCache = NULL;
+ indexInfo->ii_Context = CurrentMemoryContext;
collationObjectId[0] = InvalidOid;
collationObjectId[1] = InvalidOid;
diff --git a/src/backend/commands/constraint.c b/src/backend/commands/constraint.c
index e9eeacd03a..e2544e51ed 100644
--- a/src/backend/commands/constraint.c
+++ b/src/backend/commands/constraint.c
@@ -165,7 +165,8 @@ unique_key_recheck(PG_FUNCTION_ARGS)
* index will know about.
*/
index_insert(indexRel, values, isnull, &(new_row->t_self),
- trigdata->tg_relation, UNIQUE_CHECK_EXISTING);
+ trigdata->tg_relation, UNIQUE_CHECK_EXISTING,
+ indexInfo);
}
else
{
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f4814c095b..265e9b33f7 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -183,6 +183,8 @@ CheckIndexCompatible(Oid oldId,
indexInfo->ii_ExclusionOps = NULL;
indexInfo->ii_ExclusionProcs = NULL;
indexInfo->ii_ExclusionStrats = NULL;
+ indexInfo->ii_AmCache = NULL;
+ indexInfo->ii_Context = CurrentMemoryContext;
typeObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
collationObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
@@ -562,6 +564,8 @@ DefineIndex(Oid relationId,
indexInfo->ii_ReadyForInserts = !stmt->concurrent;
indexInfo->ii_Concurrent = stmt->concurrent;
indexInfo->ii_BrokenHotChain = false;
+ indexInfo->ii_AmCache = NULL;
+ indexInfo->ii_Context = CurrentMemoryContext;
typeObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
collationObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c
index 8d119f6a19..5242dee006 100644
--- a/src/backend/executor/execIndexing.c
+++ b/src/backend/executor/execIndexing.c
@@ -391,7 +391,8 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
isnull, /* null flags */
tupleid, /* tid of heap tuple */
heapRelation, /* heap relation */
- checkUnique); /* type of uniqueness check to do */
+ checkUnique, /* type of uniqueness check to do */
+ indexInfo); /* index AM may need this */
/*
* If the index has an associated exclusion constraint, check that.
diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h
index e91e41dc0f..b0730bfefa 100644
--- a/src/include/access/amapi.h
+++ b/src/include/access/amapi.h
@@ -72,7 +72,8 @@ typedef bool (*aminsert_function) (Relation indexRelation,
bool *isnull,
ItemPointer heap_tid,
Relation heapRelation,
- IndexUniqueCheck checkUnique);
+ IndexUniqueCheck checkUnique,
+ struct IndexInfo *indexInfo);
/* bulk delete */
typedef IndexBulkDeleteResult *(*ambulkdelete_function) (IndexVacuumInfo *info,
diff --git a/src/include/access/brin_internal.h b/src/include/access/brin_internal.h
index 40312604f8..abe887788b 100644
--- a/src/include/access/brin_internal.h
+++ b/src/include/access/brin_internal.h
@@ -89,7 +89,8 @@ extern IndexBuildResult *brinbuild(Relation heap, Relation index,
extern void brinbuildempty(Relation index);
extern bool brininsert(Relation idxRel, Datum *values, bool *nulls,
ItemPointer heaptid, Relation heapRel,
- IndexUniqueCheck checkUnique);
+ IndexUniqueCheck checkUnique,
+ struct IndexInfo *indexInfo);
extern IndexScanDesc brinbeginscan(Relation r, int nkeys, int norderbys);
extern int64 bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
extern void brinrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 51466b96e8..f467b18a9c 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -21,6 +21,9 @@
#include "utils/relcache.h"
#include "utils/snapshot.h"
+/* We don't want this file to depend on execnodes.h. */
+struct IndexInfo;
+
/*
* Struct for statistics returned by ambuild
*/
@@ -131,7 +134,8 @@ extern bool index_insert(Relation indexRelation,
Datum *values, bool *isnull,
ItemPointer heap_t_ctid,
Relation heapRelation,
- IndexUniqueCheck checkUnique);
+ IndexUniqueCheck checkUnique,
+ struct IndexInfo *indexInfo);
extern IndexScanDesc index_beginscan(Relation heapRelation,
Relation indexRelation,
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index d46274ee85..7e1557ea85 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -617,7 +617,8 @@ extern IndexBuildResult *ginbuild(Relation heap, Relation index,
extern void ginbuildempty(Relation index);
extern bool gininsert(Relation index, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique);
+ IndexUniqueCheck checkUnique,
+ struct IndexInfo *indexInfo);
extern void ginEntryInsert(GinState *ginstate,
OffsetNumber attnum, Datum key, GinNullCategory category,
ItemPointerData *items, uint32 nitem,
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index f4beeb9209..873c52a1a2 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -426,7 +426,8 @@ typedef struct GiSTOptions
extern void gistbuildempty(Relation index);
extern bool gistinsert(Relation r, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique);
+ IndexUniqueCheck checkUnique,
+ struct IndexInfo *indexInfo);
extern MemoryContext createTempGistContext(void);
extern GISTSTATE *initGISTstate(Relation index);
extern void freeGISTstate(GISTSTATE *giststate);
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index c0455851f4..3bf587b1b7 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -277,7 +277,8 @@ extern IndexBuildResult *hashbuild(Relation heap, Relation index,
extern void hashbuildempty(Relation index);
extern bool hashinsert(Relation rel, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique);
+ IndexUniqueCheck checkUnique,
+ struct IndexInfo *indexInfo);
extern bool hashgettuple(IndexScanDesc scan, ScanDirection dir);
extern int64 hashgetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
extern IndexScanDesc hashbeginscan(Relation rel, int nkeys, int norderbys);
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index b2517623aa..344ef9933c 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -659,7 +659,8 @@ extern IndexBuildResult *btbuild(Relation heap, Relation index,
extern void btbuildempty(Relation index);
extern bool btinsert(Relation rel, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique);
+ IndexUniqueCheck checkUnique,
+ struct IndexInfo *indexInfo);
extern IndexScanDesc btbeginscan(Relation rel, int nkeys, int norderbys);
extern bool btgettuple(IndexScanDesc scan, ScanDirection dir);
extern int64 btgetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h
index 6f59c0bbc5..ee7480ad39 100644
--- a/src/include/access/spgist.h
+++ b/src/include/access/spgist.h
@@ -191,7 +191,8 @@ extern IndexBuildResult *spgbuild(Relation heap, Relation index,
extern void spgbuildempty(Relation index);
extern bool spginsert(Relation index, Datum *values, bool *isnull,
ItemPointer ht_ctid, Relation heapRel,
- IndexUniqueCheck checkUnique);
+ IndexUniqueCheck checkUnique,
+ struct IndexInfo *indexInfo);
/* spgscan.c */
extern IndexScanDesc spgbeginscan(Relation rel, int keysz, int orderbysz);
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index f9bcdd63de..42c6c58ff9 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -52,6 +52,8 @@
* ReadyForInserts is it valid for inserts?
* Concurrent are we doing a concurrent index build?
* BrokenHotChain did we detect any broken HOT chains?
+ * AmCache private cache area for index AM
+ * Context memory context holding this IndexInfo
*
* ii_Concurrent and ii_BrokenHotChain are used only during index build;
* they're conventionally set to false otherwise.
@@ -76,6 +78,8 @@ typedef struct IndexInfo
bool ii_ReadyForInserts;
bool ii_Concurrent;
bool ii_BrokenHotChain;
+ void *ii_AmCache;
+ MemoryContext ii_Context;
} IndexInfo;
/* ----------------