Skip to content

Commit 8013850

Browse files
committed
Add try_index_open(), conditional variant of index_open()
try_index_open() is able to open an index if its relkind fits, except that it would return NULL instead of generated an error if the relation does not exist. This new routine will be used by an upcoming patch to make REINDEX on partitioned relations more robust when an index in a partition tree is dropped. Extracted from a larger patch by the same author. Author: Fei Changhong Discussion: https://postgr.es/m/tencent_6A52106095ACDE55333E3AD33F304C0C3909@qq.com Backpatch-through: 14
1 parent 2f35c14 commit 8013850

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

src/backend/access/index/indexam.c

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ do { \
107107
static IndexScanDesc index_beginscan_internal(Relation indexRelation,
108108
int nkeys, int norderbys, Snapshot snapshot,
109109
ParallelIndexScanDesc pscan, bool temp_snap);
110+
static inline void validate_relation_kind(Relation r);
110111

111112

112113
/* ----------------------------------------------------------------
@@ -135,12 +136,30 @@ index_open(Oid relationId, LOCKMODE lockmode)
135136

136137
r = relation_open(relationId, lockmode);
137138

138-
if (r->rd_rel->relkind != RELKIND_INDEX &&
139-
r->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
140-
ereport(ERROR,
141-
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
142-
errmsg("\"%s\" is not an index",
143-
RelationGetRelationName(r))));
139+
validate_relation_kind(r);
140+
141+
return r;
142+
}
143+
144+
/* ----------------
145+
* try_index_open - open a index relation by relation OID
146+
*
147+
* Same as index_open, except return NULL instead of failing
148+
* if the relation does not exist.
149+
* ----------------
150+
*/
151+
Relation
152+
try_index_open(Oid relationId, LOCKMODE lockmode)
153+
{
154+
Relation r;
155+
156+
r = try_relation_open(relationId, lockmode);
157+
158+
/* leave if index does not exist */
159+
if (!r)
160+
return NULL;
161+
162+
validate_relation_kind(r);
144163

145164
return r;
146165
}
@@ -168,6 +187,24 @@ index_close(Relation relation, LOCKMODE lockmode)
168187
UnlockRelationId(&relid, lockmode);
169188
}
170189

190+
/* ----------------
191+
* validate_relation_kind - check the relation's kind
192+
*
193+
* Make sure relkind is an index or a partitioned index.
194+
* ----------------
195+
*/
196+
static inline void
197+
validate_relation_kind(Relation r)
198+
{
199+
if (r->rd_rel->relkind != RELKIND_INDEX &&
200+
r->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
201+
ereport(ERROR,
202+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
203+
errmsg("\"%s\" is not an index",
204+
RelationGetRelationName(r))));
205+
}
206+
207+
171208
/* ----------------
172209
* index_insert - insert an index tuple into a relation
173210
* ----------------

src/include/access/genam.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ typedef struct IndexOrderByDistance
139139
#define IndexScanIsValid(scan) PointerIsValid(scan)
140140

141141
extern Relation index_open(Oid relationId, LOCKMODE lockmode);
142+
extern Relation try_index_open(Oid relationId, LOCKMODE lockmode);
142143
extern void index_close(Relation relation, LOCKMODE lockmode);
143144

144145
extern bool index_insert(Relation indexRelation,

0 commit comments

Comments
 (0)