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,