v1-try_index_open.patch
application/octet-stream
Filename: v1-try_index_open.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v1
| File | + | − |
|---|---|---|
| src/backend/access/index/indexam.c | 44 | 6 |
| src/backend/catalog/index.c | 18 | 1 |
| src/include/access/genam.h | 1 | 0 |
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index b25b03f7ab..f598eb7f74 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -114,6 +114,8 @@ static IndexScanDesc index_beginscan_internal(Relation indexRelation,
* ----------------------------------------------------------------
*/
+static inline void validate_index_relation_kind(Relation r);
+
/* ----------------
* index_open - open an index relation by relation OID
*
@@ -135,12 +137,30 @@ index_open(Oid relationId, LOCKMODE lockmode)
r = relation_open(relationId, lockmode);
- if (r->rd_rel->relkind != RELKIND_INDEX &&
- r->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not an index",
- RelationGetRelationName(r))));
+ validate_index_relation_kind(r);
+
+ return r;
+}
+
+/* ----------------
+ * try_index_open - open a index relation by relation OID
+ *
+ * Same as index_open, except return NULL instead of failing
+ * if the relation does not exist.
+ * ----------------
+ */
+Relation
+try_index_open(Oid relationId, LOCKMODE lockmode)
+{
+ Relation r;
+
+ r = try_relation_open(relationId, lockmode);
+
+ /* leave if index does not exist */
+ if (!r)
+ return NULL;
+
+ validate_index_relation_kind(r);
return r;
}
@@ -168,6 +188,24 @@ index_close(Relation relation, LOCKMODE lockmode)
UnlockRelationId(&relid, lockmode);
}
+/* ----------------
+ * validate_index_relation_kind - check the index relation's kind
+ *
+ * Make sure relkind is index or partitioned index
+ * ----------------
+ */
+static inline void
+validate_index_relation_kind(Relation r)
+{
+ if (r->rd_rel->relkind != RELKIND_INDEX &&
+ r->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not an index",
+ RelationGetRelationName(r))));
+}
+
+
/* ----------------
* index_insert - insert an index tuple into a relation
* ----------------
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 143fae01eb..07fc6d57f3 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3624,7 +3624,24 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
* Open the target index relation and get an exclusive lock on it, to
* ensure that no one else is touching this particular index.
*/
- iRel = index_open(indexId, AccessExclusiveLock);
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ iRel = try_index_open(indexId, AccessExclusiveLock);
+ else
+ iRel = index_open(indexId, AccessExclusiveLock);
+
+ /* if index relation is gone, leave */
+ if (!iRel)
+ {
+ /* Roll back any GUC changes before exit */
+ AtEOXact_GUC(false, save_nestlevel);
+
+ /* Restore userid and security context */
+ SetUserIdAndSecContext(save_userid, save_sec_context);
+
+ /* Close rels, but keep locks */
+ table_close(heapRelation, NoLock);
+ return;
+ }
if (progress)
pgstat_progress_update_param(PROGRESS_CREATEIDX_ACCESS_METHOD_OID,
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index f31dec6ee0..958fe85235 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -139,6 +139,7 @@ typedef struct IndexOrderByDistance
#define IndexScanIsValid(scan) PointerIsValid(scan)
extern Relation index_open(Oid relationId, LOCKMODE lockmode);
+extern Relation try_index_open(Oid relationId, LOCKMODE lockmode);
extern void index_close(Relation relation, LOCKMODE lockmode);
extern bool index_insert(Relation indexRelation,