diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c index f23fbb1d9e0..d92858a3433 100644 --- a/contrib/bloom/blutils.c +++ b/contrib/bloom/blutils.c @@ -130,7 +130,8 @@ blhandler(PG_FUNCTION_ARGS) amroutine->ambuild = blbuild; amroutine->ambuildempty = blbuildempty; - amroutine->aminsert = blinsert; + amroutine->aminsert = NULL; + amroutine->aminsertextended = blinsert; amroutine->ambulkdelete = blbulkdelete; amroutine->amvacuumcleanup = blvacuumcleanup; amroutine->amcanreturn = NULL; diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml index 30eda37afa8..cee79776683 100644 --- a/doc/src/sgml/indexam.sgml +++ b/doc/src/sgml/indexam.sgml @@ -139,6 +139,7 @@ typedef struct IndexAmRoutine ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; + aminsert_extended_function aminsertextended; ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; amcanreturn_function amcanreturn; /* can be NULL */ diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index a0052239645..38469a5a554 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -116,7 +116,8 @@ brinhandler(PG_FUNCTION_ARGS) amroutine->ambuild = brinbuild; amroutine->ambuildempty = brinbuildempty; - amroutine->aminsert = brininsert; + amroutine->aminsert = NULL; + amroutine->aminsertextended = brininsert; amroutine->ambulkdelete = brinbulkdelete; amroutine->amvacuumcleanup = brinvacuumcleanup; amroutine->amcanreturn = NULL; diff --git a/src/backend/access/common/toast_internals.c b/src/backend/access/common/toast_internals.c index 653a4f7d469..9b6a5d9091c 100644 --- a/src/backend/access/common/toast_internals.c +++ b/src/backend/access/common/toast_internals.c @@ -339,7 +339,7 @@ toast_save_datum(Relation rel, Datum value, /* Only index relations marked as ready can be updated */ if (toastidxs[i]->rd_index->indisready) index_insert(toastidxs[i], t_values, t_isnull, - ItemPointerGetDatum(&(toasttup->t_self)), + &(toasttup->t_self), toastrel, toastidxs[i]->rd_index->indisunique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index 7a4cd93f301..52d9a725fc4 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -63,7 +63,8 @@ ginhandler(PG_FUNCTION_ARGS) amroutine->ambuild = ginbuild; amroutine->ambuildempty = ginbuildempty; - amroutine->aminsert = gininsert; + amroutine->aminsert = NULL; + amroutine->aminsertextended = gininsert; amroutine->ambulkdelete = ginbulkdelete; amroutine->amvacuumcleanup = ginvacuumcleanup; amroutine->amcanreturn = NULL; diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 53680b30d87..73193f0970d 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -85,7 +85,8 @@ gisthandler(PG_FUNCTION_ARGS) amroutine->ambuild = gistbuild; amroutine->ambuildempty = gistbuildempty; - amroutine->aminsert = gistinsert; + amroutine->aminsert = NULL; + amroutine->aminsertextended = gistinsert; amroutine->ambulkdelete = gistbulkdelete; amroutine->amvacuumcleanup = gistvacuumcleanup; amroutine->amcanreturn = gistcanreturn; diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index c8202e9349d..ffddf7b900c 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -82,7 +82,8 @@ hashhandler(PG_FUNCTION_ARGS) amroutine->ambuild = hashbuild; amroutine->ambuildempty = hashbuildempty; - amroutine->aminsert = hashinsert; + amroutine->aminsert = NULL; + amroutine->aminsertextended = hashinsert; amroutine->ambulkdelete = hashbulkdelete; amroutine->amvacuumcleanup = hashvacuumcleanup; amroutine->amcanreturn = NULL; diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 8f6559c9c3e..a32fc3b69fb 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -2310,7 +2310,7 @@ heapam_index_validate_scan(Relation heapRelation, index_insert(indexRelation, values, isnull, - ItemPointerGetDatum(&rootTuple), + &rootTuple, heapRelation, indexInfo->ii_Unique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 0dabdabca8e..94bdec63666 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -218,24 +218,39 @@ bool index_insert(Relation indexRelation, Datum *values, bool *isnull, - Datum tupleid, + ItemPointer tupleid, Relation heapRelation, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo) { RELATION_CHECKS; - CHECK_REL_PROCEDURE(aminsert); + + if (indexRelation->rd_indam->aminsertextended == NULL && indexRelation->rd_indam->aminsert == NULL ) + elog(ERROR, "at least one function aminsert or aminsertextended should be defined for index \"%s\"", \ + RelationGetRelationName(indexRelation)); if (!(indexRelation->rd_indam->ampredlocks)) CheckForSerializableConflictIn(indexRelation, (ItemPointer) NULL, InvalidBlockNumber); - return indexRelation->rd_indam->aminsert(indexRelation, values, isnull, + if (indexRelation->rd_indam->aminsert) + { + /* compatibility method for extension AM's not aware of aminsertextended */ + return indexRelation->rd_indam->aminsert(indexRelation, values, isnull, tupleid, heapRelation, checkUnique, indexUnchanged, indexInfo); + } + else + { + /* index insert method for internal AM's and Orioledb that are aware of aminsertextended */ + return indexRelation->rd_indam->aminsertextended(indexRelation, values, isnull, + ItemPointerGetDatum(tupleid), heapRelation, + checkUnique, indexUnchanged, + indexInfo); + } } /* ---------------- diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 32ec09b1ec7..44daed95baf 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -121,7 +121,8 @@ bthandler(PG_FUNCTION_ARGS) amroutine->ambuild = btbuild; amroutine->ambuildempty = btbuildempty; - amroutine->aminsert = btinsert; + amroutine->aminsert = NULL; + amroutine->aminsertextended = btinsert; amroutine->ambulkdelete = btbulkdelete; amroutine->amvacuumcleanup = btvacuumcleanup; amroutine->amcanreturn = btcanreturn; diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index 5fa9e230c08..127ff3922d1 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -69,7 +69,8 @@ spghandler(PG_FUNCTION_ARGS) amroutine->ambuild = spgbuild; amroutine->ambuildempty = spgbuildempty; - amroutine->aminsert = spginsert; + amroutine->aminsert = NULL; + amroutine->aminsertextended = spginsert; amroutine->ambulkdelete = spgbulkdelete; amroutine->amvacuumcleanup = spgvacuumcleanup; amroutine->amcanreturn = spgcanreturn; diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index 9846637537c..522da0ac855 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -170,7 +170,7 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple, index_insert(index, /* index relation */ values, /* array of index Datums */ isnull, /* is-null flags */ - ItemPointerGetDatum(&(heapTuple->t_self)), /* tid of heap tuple */ + &(heapTuple->t_self), /* tid of heap tuple */ heapRelation, index->rd_index->indisunique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, diff --git a/src/backend/commands/constraint.c b/src/backend/commands/constraint.c index 04e718c95cd..982bae9ed42 100644 --- a/src/backend/commands/constraint.c +++ b/src/backend/commands/constraint.c @@ -173,7 +173,7 @@ unique_key_recheck(PG_FUNCTION_ARGS) * the row is now dead, because that is the TID the index will know * about. */ - index_insert(indexRel, values, isnull, ItemPointerGetDatum(&checktid), + index_insert(indexRel, values, isnull, &checktid, trigdata->tg_relation, UNIQUE_CHECK_EXISTING, false, indexInfo); } diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c index 266c876c8f6..a40aebb1ef1 100644 --- a/src/backend/executor/execIndexing.c +++ b/src/backend/executor/execIndexing.c @@ -308,19 +308,19 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, ExprContext *econtext; Datum values[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS]; - Datum tupleid; + ItemPointer tupleid; if (table_get_row_ref_type(resultRelInfo->ri_RelationDesc) == ROW_REF_ROWID) { bool isnull; - tupleid = slot_getsysattr(slot, RowIdAttributeNumber, &isnull); + tupleid = DatumGetItemPointer(slot_getsysattr(slot, RowIdAttributeNumber, &isnull)); Assert(!isnull); } else { Assert(ItemPointerIsValid(&slot->tts_tid)); - tupleid = PointerGetDatum(&slot->tts_tid); + tupleid = &slot->tts_tid; } /* @@ -468,7 +468,6 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, { bool violationOK; CEOUC_WAIT_MODE waitMode; - ItemPointer raw_tupleid = DatumGetItemPointer(tupleid); if (applyNoDupErr) { @@ -489,7 +488,7 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, satisfiesConstraint = check_exclusion_or_unique_constraint(heapRelation, indexRelation, indexInfo, - raw_tupleid, values, isnull, + tupleid, values, isnull, estate, false, waitMode, violationOK, NULL); } @@ -532,18 +531,18 @@ ExecUpdateIndexTuples(ResultRelInfo *resultRelInfo, ExprContext *econtext; Datum values[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS]; - Datum tupleid; + ItemPointer tupleid; if (table_get_row_ref_type(resultRelInfo->ri_RelationDesc) == ROW_REF_ROWID) { bool isnull; - tupleid = slot_getsysattr(slot, RowIdAttributeNumber, &isnull); + tupleid = DatumGetItemPointer(slot_getsysattr(slot, RowIdAttributeNumber, &isnull)); Assert(!isnull); } else { Assert(ItemPointerIsValid(&slot->tts_tid)); - tupleid = PointerGetDatum(&slot->tts_tid); + tupleid = &slot->tts_tid; } /* @@ -712,7 +711,7 @@ ExecUpdateIndexTuples(ResultRelInfo *resultRelInfo, old_valid, values, /* array of index Datums */ isnull, /* null flags */ - tupleid, /* tid of heap tuple */ + ItemPointerGetDatum(tupleid), /* tid of heap tuple */ valuesOld, isnullOld, oldTupleid, @@ -763,7 +762,6 @@ ExecUpdateIndexTuples(ResultRelInfo *resultRelInfo, { bool violationOK; CEOUC_WAIT_MODE waitMode; - ItemPointer raw_tupleid = DatumGetItemPointer(tupleid); if (applyNoDupErr) { @@ -784,7 +782,7 @@ ExecUpdateIndexTuples(ResultRelInfo *resultRelInfo, satisfiesConstraint = check_exclusion_or_unique_constraint(heapRelation, indexRelation, indexInfo, - raw_tupleid, values, isnull, + tupleid, values, isnull, estate, false, waitMode, violationOK, NULL); } diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h index bb226d85fad..73320f93be7 100644 --- a/src/include/access/amapi.h +++ b/src/include/access/amapi.h @@ -105,6 +105,16 @@ typedef void (*ambuildempty_function) (Relation indexRelation); /* insert this tuple */ typedef bool (*aminsert_function) (Relation indexRelation, + Datum *values, + bool *isnull, + ItemPointer tupleid, + Relation heapRelation, + IndexUniqueCheck checkUnique, + bool indexUnchanged, + struct IndexInfo *indexInfo); + +/* extended version of aminsert taking Datum tupleid */ +typedef bool (*aminsert_extended_function) (Relation indexRelation, Datum *values, bool *isnull, Datum tupleid, @@ -112,6 +122,7 @@ typedef bool (*aminsert_function) (Relation indexRelation, IndexUniqueCheck checkUnique, bool indexUnchanged, struct IndexInfo *indexInfo); + /* update this tuple */ typedef bool (*amupdate_function) (Relation indexRelation, bool new_valid, @@ -282,6 +293,7 @@ typedef struct IndexAmRoutine ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; + aminsert_extended_function aminsertextended; amupdate_function amupdate; amdelete_function amdelete; ambulkdelete_function ambulkdelete; diff --git a/src/include/access/genam.h b/src/include/access/genam.h index 696c063373e..0de79f782a5 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -144,7 +144,7 @@ extern void index_close(Relation relation, LOCKMODE lockmode); extern bool index_insert(Relation indexRelation, Datum *values, bool *isnull, - Datum tupleid, + ItemPointer tupleid, Relation heapRelation, IndexUniqueCheck checkUnique, bool indexUnchanged, diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c index 562a578cad2..09c5d20479d 100644 --- a/src/test/modules/dummy_index_am/dummy_index_am.c +++ b/src/test/modules/dummy_index_am/dummy_index_am.c @@ -302,7 +302,8 @@ dihandler(PG_FUNCTION_ARGS) amroutine->ambuild = dibuild; amroutine->ambuildempty = dibuildempty; - amroutine->aminsert = diinsert; + amroutine->aminsert = NULL; + amroutine->aminsertextended = diinsert; amroutine->ambulkdelete = dibulkdelete; amroutine->amvacuumcleanup = divacuumcleanup; amroutine->amcanreturn = NULL; diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 4791528e140..264bdbdee0f 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -3146,6 +3146,7 @@ amgetbitmap_function amgettuple_function aminitparallelscan_function aminsert_function +aminsert_extended_function ammarkpos_function amoptions_function amparallelrescan_function