Use a bitmask for ExecInsertIndexTuples options

... instead of passing a bunch of separate booleans.

Also, rearrange the argument list in a hopefully more sensible order.

Discussion: https://postgr.es/m/202602111846.xpvuccb3inbx@alvherre.pgsql
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Fabrízio de Royes Mello <fabriziomello@gmail.com> (older version)
This commit is contained in:
Álvaro Herrera
2026-02-17 17:59:45 +01:00
parent 661237056b
commit b7271aa1d7
5 changed files with 68 additions and 54 deletions

View File

@ -572,8 +572,8 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo,
cstate->cur_lineno = buffer->linenos[i];
recheckIndexes =
ExecInsertIndexTuples(resultRelInfo,
buffer->slots[i], estate, false,
false, NULL, NIL, false);
estate, 0, buffer->slots[i],
NIL, NULL);
ExecARInsertTriggers(estate, resultRelInfo,
slots[i], recheckIndexes,
cstate->transition_capture);
@ -1429,13 +1429,9 @@ CopyFrom(CopyFromState cstate)
if (resultRelInfo->ri_NumIndices > 0)
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
myslot,
estate,
false,
false,
NULL,
NIL,
false);
estate, 0,
myslot, NIL,
NULL);
}
/* AFTER ROW INSERT Triggers */

View File

@ -276,18 +276,18 @@ ExecCloseIndices(ResultRelInfo *resultRelInfo)
* into all the relations indexing the result relation
* when a heap tuple is inserted into the result relation.
*
* When 'update' is true and 'onlySummarizing' is false,
* When EIIT_IS_UPDATE is set and EIIT_ONLY_SUMMARIZING isn't,
* executor is performing an UPDATE that could not use an
* optimization like heapam's HOT (in more general terms a
* call to table_tuple_update() took place and set
* 'update_indexes' to TU_All). Receiving this hint makes
* us consider if we should pass down the 'indexUnchanged'
* hint in turn. That's something that we figure out for
* each index_insert() call iff 'update' is true.
* (When 'update' is false we already know not to pass the
* each index_insert() call iff EIIT_IS_UPDATE is set.
* (When that flag is not set we already know not to pass the
* hint to any index.)
*
* If onlySummarizing is set, an equivalent optimization to
* If EIIT_ONLY_SUMMARIZING is set, an equivalent optimization to
* HOT has been applied and any updated columns are indexed
* only by summarizing indexes (or in more general terms a
* call to table_tuple_update() took place and set
@ -298,23 +298,21 @@ ExecCloseIndices(ResultRelInfo *resultRelInfo)
* Unique and exclusion constraints are enforced at the same
* time. This returns a list of index OIDs for any unique or
* exclusion constraints that are deferred and that had
* potential (unconfirmed) conflicts. (if noDupErr == true,
* potential (unconfirmed) conflicts. (if EIIT_NO_DUPE_ERROR,
* the same is done for non-deferred constraints, but report
* if conflict was speculative or deferred conflict to caller)
*
* If 'arbiterIndexes' is nonempty, noDupErr applies only to
* those indexes. NIL means noDupErr applies to all indexes.
* If 'arbiterIndexes' is nonempty, EIIT_NO_DUPE_ERROR applies only to
* those indexes. NIL means EIIT_NO_DUPE_ERROR applies to all indexes.
* ----------------------------------------------------------------
*/
List *
ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
TupleTableSlot *slot,
EState *estate,
bool update,
bool noDupErr,
bool *specConflict,
bits32 flags,
TupleTableSlot *slot,
List *arbiterIndexes,
bool onlySummarizing)
bool *specConflict)
{
ItemPointer tupleid = &slot->tts_tid;
List *result = NIL;
@ -374,7 +372,7 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
* Skip processing of non-summarizing indexes if we only update
* summarizing indexes
*/
if (onlySummarizing && !indexInfo->ii_Summarizing)
if ((flags & EIIT_ONLY_SUMMARIZING) && !indexInfo->ii_Summarizing)
continue;
/* Check for partial index */
@ -409,7 +407,7 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
isnull);
/* Check whether to apply noDupErr to this index */
applyNoDupErr = noDupErr &&
applyNoDupErr = (flags & EIIT_NO_DUPE_ERROR) &&
(arbiterIndexes == NIL ||
list_member_oid(arbiterIndexes,
indexRelation->rd_index->indexrelid));
@ -441,10 +439,11 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
* index. If we're being called as part of an UPDATE statement,
* consider if the 'indexUnchanged' = true hint should be passed.
*/
indexUnchanged = update && index_unchanged_by_update(resultRelInfo,
estate,
indexInfo,
indexRelation);
indexUnchanged = ((flags & EIIT_IS_UPDATE) &&
index_unchanged_by_update(resultRelInfo,
estate,
indexInfo,
indexRelation));
satisfiesConstraint =
index_insert(indexRelation, /* index relation */

View File

@ -846,11 +846,18 @@ ExecSimpleRelationInsert(ResultRelInfo *resultRelInfo,
conflictindexes = resultRelInfo->ri_onConflictArbiterIndexes;
if (resultRelInfo->ri_NumIndices > 0)
{
bits32 flags;
if (conflictindexes != NIL)
flags = EIIT_NO_DUPE_ERROR;
else
flags = 0;
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
slot, estate, false,
conflictindexes ? true : false,
&conflict,
conflictindexes, false);
estate, flags,
slot, conflictindexes,
&conflict);
}
/*
* Checks the conflict indexes to fetch the conflicting local row and
@ -943,11 +950,18 @@ ExecSimpleRelationUpdate(ResultRelInfo *resultRelInfo,
conflictindexes = resultRelInfo->ri_onConflictArbiterIndexes;
if (resultRelInfo->ri_NumIndices > 0 && (update_indexes != TU_None))
{
bits32 flags = EIIT_IS_UPDATE;
if (conflictindexes != NIL)
flags |= EIIT_NO_DUPE_ERROR;
if (update_indexes == TU_Summarizing)
flags |= EIIT_ONLY_SUMMARIZING;
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
slot, estate, true,
conflictindexes ? true : false,
&conflict, conflictindexes,
(update_indexes == TU_Summarizing));
estate, flags,
slot, conflictindexes,
&conflict);
}
/*
* Refer to the comments above the call to CheckAndReportConflict() in

View File

@ -1226,10 +1226,9 @@ ExecInsert(ModifyTableContext *context,
/* insert index entries for tuple */
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
slot, estate, false, true,
&specConflict,
arbiterIndexes,
false);
estate, EIIT_NO_DUPE_ERROR,
slot, arbiterIndexes,
&specConflict);
/* adjust the tuple's state accordingly */
table_tuple_complete_speculative(resultRelationDesc, slot,
@ -1266,10 +1265,9 @@ ExecInsert(ModifyTableContext *context,
/* insert index entries for tuple */
if (resultRelInfo->ri_NumIndices > 0)
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
slot, estate, false,
false, NULL, NIL,
false);
recheckIndexes = ExecInsertIndexTuples(resultRelInfo, estate,
0, slot, NIL,
NULL);
}
}
@ -2356,11 +2354,15 @@ ExecUpdateEpilogue(ModifyTableContext *context, UpdateContext *updateCxt,
/* insert index entries for tuple if necessary */
if (resultRelInfo->ri_NumIndices > 0 && (updateCxt->updateIndexes != TU_None))
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
slot, context->estate,
true, false,
NULL, NIL,
(updateCxt->updateIndexes == TU_Summarizing));
{
bits32 flags = EIIT_IS_UPDATE;
if (updateCxt->updateIndexes == TU_Summarizing)
flags |= EIIT_ONLY_SUMMARIZING;
recheckIndexes = ExecInsertIndexTuples(resultRelInfo, context->estate,
flags, slot, NIL,
NULL);
}
/* AFTER ROW UPDATE Triggers */
ExecARUpdateTriggers(context->estate, resultRelInfo,

View File

@ -739,12 +739,15 @@ extern Bitmapset *ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate);
*/
extern void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative);
extern void ExecCloseIndices(ResultRelInfo *resultRelInfo);
extern List *ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
TupleTableSlot *slot, EState *estate,
bool update,
bool noDupErr,
bool *specConflict, List *arbiterIndexes,
bool onlySummarizing);
/* flags for ExecInsertIndexTuples */
#define EIIT_IS_UPDATE (1<<0)
#define EIIT_NO_DUPE_ERROR (1<<1)
#define EIIT_ONLY_SUMMARIZING (1<<2)
extern List *ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, EState *estate,
bits32 options, TupleTableSlot *slot,
List *arbiterIndexes,
bool *specConflict);
extern bool ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo,
TupleTableSlot *slot,
EState *estate, ItemPointer conflictTid,