8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.86 2005/10/15 02:49:09 momjian Exp $
11
+ * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.87 2005/12/03 05:51:00 tgl Exp $
12
12
*
13
13
* INTERFACE ROUTINES
14
14
* index_open - open an index relation by relation OID
@@ -111,6 +111,7 @@ do { \
111
111
} while(0)
112
112
113
113
static IndexScanDesc index_beginscan_internal (Relation indexRelation ,
114
+ bool need_index_lock ,
114
115
int nkeys , ScanKey key );
115
116
116
117
@@ -229,16 +230,23 @@ index_insert(Relation indexRelation,
229
230
* heapRelation link (nor the snapshot). However, the caller had better
230
231
* be holding some kind of lock on the heap relation in any case, to ensure
231
232
* no one deletes it (or the index) out from under us.
233
+ *
234
+ * Most callers should pass need_index_lock = true to cause the index code
235
+ * to take AccessShareLock on the index for the duration of the scan. But
236
+ * if it is known that a lock is already held on the index, pass false to
237
+ * skip taking an unnecessary lock.
232
238
*/
233
239
IndexScanDesc
234
240
index_beginscan (Relation heapRelation ,
235
241
Relation indexRelation ,
242
+ bool need_index_lock ,
236
243
Snapshot snapshot ,
237
244
int nkeys , ScanKey key )
238
245
{
239
246
IndexScanDesc scan ;
240
247
241
- scan = index_beginscan_internal (indexRelation , nkeys , key );
248
+ scan = index_beginscan_internal (indexRelation , need_index_lock ,
249
+ nkeys , key );
242
250
243
251
/*
244
252
* Save additional parameters into the scandesc. Everything else was set
@@ -259,12 +267,14 @@ index_beginscan(Relation heapRelation,
259
267
*/
260
268
IndexScanDesc
261
269
index_beginscan_multi (Relation indexRelation ,
270
+ bool need_index_lock ,
262
271
Snapshot snapshot ,
263
272
int nkeys , ScanKey key )
264
273
{
265
274
IndexScanDesc scan ;
266
275
267
- scan = index_beginscan_internal (indexRelation , nkeys , key );
276
+ scan = index_beginscan_internal (indexRelation , need_index_lock ,
277
+ nkeys , key );
268
278
269
279
/*
270
280
* Save additional parameters into the scandesc. Everything else was set
@@ -281,6 +291,7 @@ index_beginscan_multi(Relation indexRelation,
281
291
*/
282
292
static IndexScanDesc
283
293
index_beginscan_internal (Relation indexRelation ,
294
+ bool need_index_lock ,
284
295
int nkeys , ScanKey key )
285
296
{
286
297
IndexScanDesc scan ;
@@ -291,13 +302,15 @@ index_beginscan_internal(Relation indexRelation,
291
302
RelationIncrementReferenceCount (indexRelation );
292
303
293
304
/*
294
- * Acquire AccessShareLock for the duration of the scan
305
+ * Acquire AccessShareLock for the duration of the scan, unless caller
306
+ * says it already has lock on the index.
295
307
*
296
308
* Note: we could get an SI inval message here and consequently have to
297
309
* rebuild the relcache entry. The refcount increment above ensures that
298
310
* we will rebuild it and not just flush it...
299
311
*/
300
- LockRelation (indexRelation , AccessShareLock );
312
+ if (need_index_lock )
313
+ LockRelation (indexRelation , AccessShareLock );
301
314
302
315
/*
303
316
* LockRelation can clean rd_aminfo structure, so fill procedure after
@@ -315,6 +328,9 @@ index_beginscan_internal(Relation indexRelation,
315
328
Int32GetDatum (nkeys ),
316
329
PointerGetDatum (key )));
317
330
331
+ /* Save flag to tell index_endscan whether to release lock */
332
+ scan -> have_lock = need_index_lock ;
333
+
318
334
return scan ;
319
335
}
320
336
@@ -380,7 +396,8 @@ index_endscan(IndexScanDesc scan)
380
396
381
397
/* Release index lock and refcount acquired by index_beginscan */
382
398
383
- UnlockRelation (scan -> indexRelation , AccessShareLock );
399
+ if (scan -> have_lock )
400
+ UnlockRelation (scan -> indexRelation , AccessShareLock );
384
401
385
402
RelationDecrementReferenceCount (scan -> indexRelation );
386
403
0 commit comments