From 1c72d0dec1d9e087ddf4010fac098153677bf77d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 28 Aug 2004 20:31:44 +0000 Subject: Fix relcache to account properly for subtransaction status of 'new' relcache entries. Also, change TransactionIdIsCurrentTransactionId() so that if consulted during transaction abort, it will not say that the aborted xact is still current. (It would be better to ensure that it's never called at all during abort, but I'm not sure we can easily guarantee that.) In combination, these fix a crash we have seen occasionally during parallel regression tests of 8.0. --- src/include/utils/rel.h | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'src/include/utils/rel.h') diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 481cdb2465f..7f0c1351bd6 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.76 2004/07/17 03:31:47 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.77 2004/08/28 20:31:44 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -110,17 +110,18 @@ typedef struct RelationData BlockNumber rd_targblock; /* current insertion target block, or * InvalidBlockNumber */ int rd_refcnt; /* reference count */ - bool rd_isnew; /* rel was created in current xact */ - - /* - * NOTE: rd_isnew should be relied on only for optimization purposes; - * it is possible for new-ness to be "forgotten" (eg, after CLUSTER). - */ bool rd_istemp; /* rel uses the local buffer mgr */ - char rd_isnailed; /* rel is nailed in cache: 0 = no, 1 = yes, - * 2 = yes but possibly invalid */ + bool rd_isnailed; /* rel is nailed in cache */ + bool rd_isvalid; /* relcache entry is valid */ char rd_indexvalid; /* state of rd_indexlist: 0 = not valid, * 1 = valid, 2 = temporarily forced */ + TransactionId rd_createxact; /* rel was created in current xact */ + /* + * rd_createxact is the XID of the highest subtransaction the rel has + * survived into; or zero if the rel was not created in the current + * transaction. This should be relied on only for optimization purposes; + * it is possible for new-ness to be "forgotten" (eg, after CLUSTER). + */ Form_pg_class rd_rel; /* RELATION tuple */ TupleDesc rd_att; /* tuple descriptor */ Oid rd_id; /* relation's object id */ @@ -230,6 +231,16 @@ typedef Relation *RelationPtr; #define RelationGetNamespace(relation) \ ((relation)->rd_rel->relnamespace) +/* + * RELATION_IS_LOCAL + * If a rel is either temp or newly created in the current transaction, + * it can be assumed to be visible only to the current backend. + * + * Beware of multiple eval of argument + */ +#define RELATION_IS_LOCAL(relation) \ + ((relation)->rd_istemp || TransactionIdIsValid((relation)->rd_createxact)) + /* routines in utils/cache/relcache.c */ extern void RelationIncrementReferenceCount(Relation rel); extern void RelationDecrementReferenceCount(Relation rel); -- cgit v1.2.3