aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-09-22 00:47:23 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-09-22 00:47:23 +0000
commitf03d2284c093ab417093054b44c987b8c48514c2 (patch)
treeb537a3e414c93912e32d11199b7d48f92252ed35 /src
parent278a13fe476f9ad5699f65c34543fee14cc1e4af (diff)
downloadpostgresql-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.c13
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