The 'succeeded' argument seems backwards here:
static void heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, uint32 spekToken, bool succeeded) { bool shouldFree = true; HeapTuple tuple = ExecFetchSlotHeapTuple(slot, true, &shouldFree);/* adjust the tuple's state accordingly */ if (!succeeded) heap_finish_speculative(relation, &slot->tts_tid); else heap_abort_speculative(relation, &slot->tts_tid); if (shouldFree) pfree(tuple); }
According to the comments, if "succeeded = true", the insertion is completed, and otherwise it's killed. It works, because the only caller is also passing the argument wrong.
Barring objections, I'll push the attached patch to fix that. - Heikki
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index bc47856ad5..00505ec3f4 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -282,7 +282,7 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, HeapTuple tuple = ExecFetchSlotHeapTuple(slot, true, &shouldFree); /* adjust the tuple's state accordingly */ - if (!succeeded) + if (succeeded) heap_finish_speculative(relation, &slot->tts_tid); else heap_abort_speculative(relation, &slot->tts_tid); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 444c0c0574..d545bbce8a 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -556,7 +556,7 @@ ExecInsert(ModifyTableState *mtstate, /* adjust the tuple's state accordingly */ table_complete_speculative(resultRelationDesc, slot, - specToken, specConflict); + specToken, !specConflict); /* * Wake up anyone waiting for our decision. They will re-check
