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.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 8c9ebe0f6f8..9a504f80251 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1731,9 +1731,23 @@ RelationReloadIndexInfo(Relation relation)
RelationGetRelid(relation));
index = (Form_pg_index) GETSTRUCT(tuple);
+ /*
+ * Basically, let's just copy all the bool fields. There are one or
+ * two of these that can't actually change in the current code, but
+ * it's not worth it to track exactly which ones they are. None of
+ * the array fields are allowed to change, though.
+ */
+ relation->rd_index->indisunique = index->indisunique;
+ relation->rd_index->indisprimary = index->indisprimary;
+ relation->rd_index->indisexclusion = index->indisexclusion;
+ relation->rd_index->indimmediate = index->indimmediate;
+ relation->rd_index->indisclustered = index->indisclustered;
relation->rd_index->indisvalid = index->indisvalid;
relation->rd_index->indcheckxmin = index->indcheckxmin;
relation->rd_index->indisready = index->indisready;
+ relation->rd_index->indislive = index->indislive;
+
+ /* Copy xmin too, as that is needed to make sense of indcheckxmin */
HeapTupleHeaderSetXmin(relation->rd_indextuple->t_data,
HeapTupleHeaderGetXmin(tuple->t_data));
@@ -3299,6 +3313,10 @@ CheckConstraintFetch(Relation relation)
* so that we must recompute the index list on next request. This handles
* creation or deletion of an index.
*
+ * Indexes that are marked not IndexIsLive are omitted from the returned list.
+ * Such indexes are expected to be dropped momentarily, and should not be
+ * touched at all by any caller of this function.
+ *
* The returned list is guaranteed to be sorted in order by OID. This is
* needed by the executor, since for index types that we obtain exclusive
* locks on when updating the index, all backends must lock the indexes in
@@ -3358,9 +3376,12 @@ RelationGetIndexList(Relation relation)
bool isnull;
/*
- * Ignore any indexes that are currently being dropped
+ * Ignore any indexes that are currently being dropped. This will
+ * prevent them from being searched, inserted into, or considered in
+ * HOT-safety decisions. It's unsafe to touch such an index at all
+ * since its catalog entries could disappear at any instant.
*/
- if (!index->indisvalid && !index->indisready)
+ if (!IndexIsLive(index))
continue;
/* Add index's OID to result list in the proper order */
@@ -3379,7 +3400,8 @@ RelationGetIndexList(Relation relation)
indclass = (oidvector *) DatumGetPointer(indclassDatum);
/* Check to see if it is a unique, non-partial btree index on OID */
- if (index->indnatts == 1 &&
+ if (IndexIsValid(index) &&
+ index->indnatts == 1 &&
index->indisunique && index->indimmediate &&
index->indkey.values[0] == ObjectIdAttributeNumber &&
indclass->values[0] == OID_BTREE_OPS_OID &&
@@ -3674,6 +3696,13 @@ RelationGetIndexAttrBitmap(Relation relation)
/*
* For each index, add referenced attributes to indexattrs.
+ *
+ * Note: we consider all indexes returned by RelationGetIndexList, even if
+ * they are not indisready or indisvalid. This is important because an
+ * index for which CREATE INDEX CONCURRENTLY has just started must be
+ * included in HOT-safety decisions (see README.HOT). If a DROP INDEX
+ * CONCURRENTLY is far enough along that we should ignore the index, it
+ * won't be returned at all by RelationGetIndexList.
*/
indexattrs = NULL;
foreach(l, indexoidlist)