diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-09-22 00:47:23 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-09-22 00:47:23 +0000 |
commit | f03d2284c093ab417093054b44c987b8c48514c2 (patch) | |
tree | b537a3e414c93912e32d11199b7d48f92252ed35 /src | |
parent | 278a13fe476f9ad5699f65c34543fee14cc1e4af (diff) | |
download | postgresql-f03d2284c093ab417093054b44c987b8c48514c2.tar.gz postgresql-f03d2284c093ab417093054b44c987b8c48514c2.zip |
HeapTupleSatisfiesVacuum() needs to be more careful about the
difference between INSERT_IN_PROGRESS and DELETE_IN_PROGRESS for
tuples inserted and then deleted by a concurrent transaction.
Example of bug:
regression=# create table foo (f1 int);
CREATE TABLE
regression=# begin;
BEGIN
regression=# insert into foo values(1);
INSERT 195531 1
regression=# delete from foo;
DELETE 1
regression=# insert into foo values(1);
INSERT 195532 1
regression=# create unique index fooi on foo(f1);
ERROR: could not create unique index
DETAIL: Table contains duplicated values.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/time/tqual.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index 43724cac27f..6a1ab38d14a 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -16,7 +16,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.67 2003/08/04 02:40:09 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.68 2003/09/22 00:47:23 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -868,7 +868,16 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin) } } else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple))) - return HEAPTUPLE_INSERT_IN_PROGRESS; + { + if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */ + return HEAPTUPLE_INSERT_IN_PROGRESS; + Assert(HeapTupleHeaderGetXmin(tuple) == + HeapTupleHeaderGetXmax(tuple)); + if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE) + return HEAPTUPLE_INSERT_IN_PROGRESS; + /* inserted and then deleted by same xact */ + return HEAPTUPLE_DELETE_IN_PROGRESS; + } else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple))) tuple->t_infomask |= HEAP_XMIN_COMMITTED; else |