aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/relcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r--src/backend/utils/cache/relcache.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 40238e959e6..fa48b1ce1ab 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -30,10 +30,11 @@
#include <fcntl.h>
#include <unistd.h>
+#include "access/htup_details.h"
+#include "access/multixact.h"
#include "access/reloptions.h"
#include "access/sysattr.h"
#include "access/transam.h"
-#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/index.h"
@@ -2725,7 +2726,8 @@ RelationBuildLocalRelation(const char *relname,
* the XIDs that will be put into the new relation contents.
*/
void
-RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid)
+RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid,
+ MultiXactId minmulti)
{
Oid newrelfilenode;
RelFileNodeBackend newrnode;
@@ -2738,6 +2740,7 @@ RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid)
relation->rd_rel->relkind == RELKIND_SEQUENCE) ?
freezeXid == InvalidTransactionId :
TransactionIdIsNormal(freezeXid));
+ Assert(TransactionIdIsNormal(freezeXid) == MultiXactIdIsValid(minmulti));
/* Allocate a new relfilenode */
newrelfilenode = GetNewRelFileNode(relation->rd_rel->reltablespace, NULL,
@@ -2793,6 +2796,7 @@ RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid)
classform->relallvisible = 0;
}
classform->relfrozenxid = freezeXid;
+ classform->relminmxid = minmulti;
simple_heap_update(pg_class, &tuple->t_self, tuple);
CatalogUpdateIndexes(pg_class, tuple);
@@ -3764,6 +3768,9 @@ RelationGetIndexPredicate(Relation relation)
* simple index keys, but attributes used in expressions and partial-index
* predicates.)
*
+ * 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.
*
@@ -3775,16 +3782,17 @@ RelationGetIndexPredicate(Relation relation)
* be bms_free'd when not needed anymore.
*/
Bitmapset *
-RelationGetIndexAttrBitmap(Relation relation)
+RelationGetIndexAttrBitmap(Relation relation, bool keyAttrs)
{
Bitmapset *indexattrs;
+ Bitmapset *uindexattrs;
List *indexoidlist;
ListCell *l;
MemoryContext oldcxt;
/* Quick exit if we already computed the result. */
if (relation->rd_indexattr != NULL)
- return bms_copy(relation->rd_indexattr);
+ return bms_copy(keyAttrs ? relation->rd_keyattr : relation->rd_indexattr);
/* Fast path if definitely no indexes */
if (!RelationGetForm(relation)->relhasindex)
@@ -3810,26 +3818,38 @@ RelationGetIndexAttrBitmap(Relation relation)
* won't be returned at all by RelationGetIndexList.
*/
indexattrs = NULL;
+ uindexattrs = NULL;
foreach(l, indexoidlist)
{
Oid indexOid = lfirst_oid(l);
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++)
{
int attrnum = indexInfo->ii_KeyAttrNumbers[i];
if (attrnum != 0)
+ {
indexattrs = bms_add_member(indexattrs,
attrnum - FirstLowInvalidHeapAttributeNumber);
+ if (isKey)
+ uindexattrs = bms_add_member(uindexattrs,
+ attrnum - FirstLowInvalidHeapAttributeNumber);
+ }
}
/* Collect all attributes used in expressions, too */
@@ -3846,10 +3866,11 @@ RelationGetIndexAttrBitmap(Relation relation)
/* Now save a copy of the bitmap in the relcache entry. */
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
relation->rd_indexattr = bms_copy(indexattrs);
+ relation->rd_keyattr = bms_copy(uindexattrs);
MemoryContextSwitchTo(oldcxt);
/* We return our original working copy for caller to play with */
- return indexattrs;
+ return keyAttrs ? uindexattrs : indexattrs;
}
/*