On Fri, Feb 11, 2011 at 09:13, Noah Misch <n...@leadboat.com> wrote: > The patch had a trivial conflict in planner.c, plus plenty of offsets. I've > attached the rebased patch that I used for review. For anyone following > along, > all the interesting hunks touch heapam.c; the rest is largely mechanical. A > "diff -w" patch is also considerably easier to follow.
Here's a simple patch for the RelationGetIndexAttrBitmap() function, as explained in my last post. I don't know if it's any help to you, but since I wrote it I might as well send it up. This applies on top of Noah's rebased patch. I did some tests and it seems to work, although I also hit the same visibility bug as Noah. Test case I used: THREAD A: create table foo (pk int primary key, ak int); create unique index on foo (ak) where ak != 0; create unique index on foo ((-ak)); create table bar (foo_pk int references foo (pk)); insert into foo values(1,1); begin; insert into bar values(1); THREAD B: begin; update foo set ak=2 where ak=1; Regards, Marti
From e069cef91c686aa87e220336198267e5a5a2aeac Mon Sep 17 00:00:00 2001 From: Marti Raudsepp <ma...@juffo.org> Date: Tue, 15 Feb 2011 00:33:35 +0200 Subject: [PATCH] Only acquire KEY LOCK for colums that can be referenced by foreign keys Don't consider columns in unique indexes that have expressions or WHERE predicates. --- src/backend/utils/cache/relcache.c | 23 +++++++++++++---------- src/include/utils/rel.h | 2 +- src/include/utils/relcache.h | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 4d37e8e..5119288 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -3608,7 +3608,8 @@ RelationGetIndexPredicate(Relation relation) * simple index keys, but attributes used in expressions and partial-index * predicates.) * - * If "unique" is true, only attributes of unique indexes are considered. + * If "keyAttrs" is true, only attributes that can be referenced by foreign + * keys are considered. * * Attribute numbers are offset by FirstLowInvalidHeapAttributeNumber so that * we can include system attributes (e.g., OID) in the bitmap representation. @@ -3617,7 +3618,7 @@ RelationGetIndexPredicate(Relation relation) * be bms_free'd when not needed anymore. */ Bitmapset * -RelationGetIndexAttrBitmap(Relation relation, bool unique) +RelationGetIndexAttrBitmap(Relation relation, bool keyAttrs) { Bitmapset *indexattrs; Bitmapset *uindexattrs; @@ -3627,7 +3628,7 @@ RelationGetIndexAttrBitmap(Relation relation, bool unique) /* Quick exit if we already computed the result. */ if (relation->rd_indexattr != NULL) - return bms_copy(unique ? relation->rd_uindexattr : relation->rd_indexattr); + return bms_copy(keyAttrs ? relation->rd_keyattr : relation->rd_indexattr); /* Fast path if definitely no indexes */ if (!RelationGetForm(relation)->relhasindex) @@ -3653,12 +3654,18 @@ RelationGetIndexAttrBitmap(Relation relation, bool unique) Relation indexDesc; IndexInfo *indexInfo; int i; + bool isKey; indexDesc = index_open(indexOid, AccessShareLock); /* Extract index key information from the index's pg_index row */ indexInfo = BuildIndexInfo(indexDesc); + /* Can this index be referenced by a foreign key? */ + isKey = indexInfo->ii_Unique && + indexInfo->ii_Expressions == NIL && + indexInfo->ii_Predicate == NIL; + /* Collect simple attribute references */ for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) { @@ -3668,7 +3675,7 @@ RelationGetIndexAttrBitmap(Relation relation, bool unique) { indexattrs = bms_add_member(indexattrs, attrnum - FirstLowInvalidHeapAttributeNumber); - if (indexInfo->ii_Unique) + if (isKey) uindexattrs = bms_add_member(uindexattrs, attrnum - FirstLowInvalidHeapAttributeNumber); } @@ -3676,13 +3683,9 @@ RelationGetIndexAttrBitmap(Relation relation, bool unique) /* Collect all attributes used in expressions, too */ pull_varattnos((Node *) indexInfo->ii_Expressions, &indexattrs); - if (indexInfo->ii_Unique) - pull_varattnos((Node *) indexInfo->ii_Expressions, &uindexattrs); /* Collect all attributes in the index predicate, too */ pull_varattnos((Node *) indexInfo->ii_Predicate, &indexattrs); - if (indexInfo->ii_Unique) - pull_varattnos((Node *) indexInfo->ii_Predicate, &uindexattrs); index_close(indexDesc, AccessShareLock); } @@ -3692,11 +3695,11 @@ RelationGetIndexAttrBitmap(Relation relation, bool unique) /* Now save a copy of the bitmap in the relcache entry. */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); relation->rd_indexattr = bms_copy(indexattrs); - relation->rd_uindexattr = bms_copy(uindexattrs); + relation->rd_keyattr = bms_copy(uindexattrs); MemoryContextSwitchTo(oldcxt); /* We return our original working copy for caller to play with */ - return unique ? uindexattrs : indexattrs; + return keyAttrs ? uindexattrs : indexattrs; } /* diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 2251b25..9b70d81 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -156,7 +156,7 @@ typedef struct RelationData Oid rd_id; /* relation's object id */ List *rd_indexlist; /* list of OIDs of indexes on relation */ Bitmapset *rd_indexattr; /* identifies columns used in indexes */ - Bitmapset *rd_uindexattr; /* identifies columns used in unique indexes */ + Bitmapset *rd_keyattr; /* cols that can be ref'd by foreign keys */ Oid rd_oidindex; /* OID of unique index on OID, if any */ LockInfoData rd_lockInfo; /* lock mgr's info for locking relation */ RuleLock *rd_rules; /* rewrite rules */ diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index 6d1e64f..d4a09e3 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -42,7 +42,7 @@ extern List *RelationGetIndexList(Relation relation); extern Oid RelationGetOidIndex(Relation relation); extern List *RelationGetIndexExpressions(Relation relation); extern List *RelationGetIndexPredicate(Relation relation); -extern Bitmapset *RelationGetIndexAttrBitmap(Relation relation, bool unique); +extern Bitmapset *RelationGetIndexAttrBitmap(Relation relation, bool keyAttrs); extern void RelationGetExclusionInfo(Relation indexRelation, Oid **operators, Oid **procs, -- 1.7.4
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers