From 07ef035129586ca26a713c4cd15e550dfe35e643 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Wed, 17 Aug 2016 17:03:36 -0700 Subject: Fix deletion of speculatively inserted TOAST on conflict INSERT .. ON CONFLICT runs a pre-check of the possible conflicting constraints before performing the actual speculative insertion. In case the inserted tuple included TOASTed columns the ON CONFLICT condition would be handled correctly in case the conflict was caught by the pre-check, but if two transactions entered the speculative insertion phase at the same time, one would have to re-try, and the code for aborting a speculative insertion did not handle deleting the speculatively inserted TOAST datums correctly. TOAST deletion would fail with "ERROR: attempted to delete invisible tuple" as we attempted to remove the TOAST tuples using simple_heap_delete which reasoned that the given tuples should not be visible to the command that wrote them. This commit updates the heap_abort_speculative() function which aborts the conflicting tuple to use itself, via toast_delete, for deleting associated TOAST datums. Like before, the inserted toast rows are not marked as being speculative. This commit also adds a isolationtester spec test, exercising the relevant code path. Unfortunately 9.5 cannot handle two waiting sessions, and thus cannot execute this test. Reported-By: Viren Negi, Oskari Saarenmaa Author: Oskari Saarenmaa, edited a bit by me Bug: #14150 Discussion: <20160519123338.12513.20271@wrigleys.postgresql.org> Backpatch: 9.5, where ON CONFLICT was introduced --- src/backend/utils/time/tqual.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/backend/utils/time/tqual.c') diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index d99c847000e..26a3be3a618 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -418,8 +418,8 @@ HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot, /* * An invalid Xmin can be left behind by a speculative insertion that - * is canceled by super-deleting the tuple. We shouldn't see any of - * those in TOAST tables, but better safe than sorry. + * is canceled by super-deleting the tuple. This also applies to + * TOAST tuples created during speculative insertion. */ else if (!TransactionIdIsValid(HeapTupleHeaderGetXmin(tuple))) return false; -- cgit v1.2.3