8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.126 2001/10/25 05:49:21 momjian Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.127 2001/11/02 16:30:29 tgl Exp $
12
12
*
13
13
*
14
14
* INTERFACE ROUTINES
15
- * heap_open - open a heap relation by relationId
15
+ * relation_open - open any relation by relation OID
16
+ * relation_openr - open any relation by name
17
+ * relation_close - close any relation
18
+ * heap_open - open a heap relation by relation OID
16
19
* heap_openr - open a heap relation by name
17
- * heap_open[r]_nofail - same, but return NULL on failure instead of elog
18
- * heap_close - close a heap relation
20
+ * heap_close - (now just a macro for relation_close)
19
21
* heap_beginscan - begin relation scan
20
22
* heap_rescan - restart a relation scan
21
23
* heap_endscan - end relation scan
@@ -440,15 +442,21 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
440
442
*/
441
443
442
444
/* ----------------
443
- * heap_open - open a heap relation by relationId
445
+ * relation_open - open any relation by relation OID
444
446
*
445
447
* If lockmode is not "NoLock", the specified kind of lock is
446
- * obtained on the relation.
448
+ * obtained on the relation. (Generally, NoLock should only be
449
+ * used if the caller knows it has some appropriate lock on the
450
+ * relation already.)
451
+ *
447
452
* An error is raised if the relation does not exist.
453
+ *
454
+ * NB: a "relation" is anything with a pg_class entry. The caller is
455
+ * expected to check whether the relkind is something it can handle.
448
456
* ----------------
449
457
*/
450
458
Relation
451
- heap_open (Oid relationId , LOCKMODE lockmode )
459
+ relation_open (Oid relationId , LOCKMODE lockmode )
452
460
{
453
461
Relation r ;
454
462
@@ -466,26 +474,20 @@ heap_open(Oid relationId, LOCKMODE lockmode)
466
474
if (!RelationIsValid (r ))
467
475
elog (ERROR , "Relation %u does not exist" , relationId );
468
476
469
- /* Under no circumstances will we return an index as a relation. */
470
- if (r -> rd_rel -> relkind == RELKIND_INDEX )
471
- elog (ERROR , "%s is an index relation" , RelationGetRelationName (r ));
472
-
473
477
if (lockmode != NoLock )
474
478
LockRelation (r , lockmode );
475
479
476
480
return r ;
477
481
}
478
482
479
483
/* ----------------
480
- * heap_openr - open a heap relation by name
484
+ * relation_openr - open any relation by name
481
485
*
482
- * If lockmode is not "NoLock", the specified kind of lock is
483
- * obtained on the relation.
484
- * An error is raised if the relation does not exist.
486
+ * As above, but lookup by name instead of OID.
485
487
* ----------------
486
488
*/
487
489
Relation
488
- heap_openr (const char * relationName , LOCKMODE lockmode )
490
+ relation_openr (const char * relationName , LOCKMODE lockmode )
489
491
{
490
492
Relation r ;
491
493
@@ -497,116 +499,111 @@ heap_openr(const char *relationName, LOCKMODE lockmode)
497
499
IncrHeapAccessStat (local_openr );
498
500
IncrHeapAccessStat (global_openr );
499
501
502
+ /*
503
+ * Check for shared-cache-inval messages before trying to open the
504
+ * relation. This is needed to cover the case where the name identifies
505
+ * a rel that has been dropped and recreated since the start of our
506
+ * transaction: if we don't flush the old relcache entry then we'll
507
+ * latch onto that entry and suffer an error when we do LockRelation.
508
+ * Note that relation_open does not need to do this, since a relation's
509
+ * OID never changes.
510
+ *
511
+ * We skip this if asked for NoLock, on the assumption that the caller
512
+ * has already ensured some appropriate lock is held.
513
+ */
514
+ if (lockmode != NoLock )
515
+ AcceptInvalidationMessages ();
516
+
500
517
/* The relcache does all the real work... */
501
518
r = RelationNameGetRelation (relationName );
502
519
503
520
if (!RelationIsValid (r ))
504
- elog (ERROR , "Relation '%s' does not exist" , relationName );
505
-
506
- /* Under no circumstances will we return an index as a relation. */
507
- if (r -> rd_rel -> relkind == RELKIND_INDEX )
508
- elog (ERROR , "%s is an index relation" , RelationGetRelationName (r ));
521
+ elog (ERROR , "Relation \"%s\" does not exist" , relationName );
509
522
510
523
if (lockmode != NoLock )
511
524
LockRelation (r , lockmode );
512
525
513
- pgstat_initstats (& r -> pgstat_info , r );
514
-
515
- pgstat_initstats (& r -> pgstat_info , r );
516
-
517
526
return r ;
518
527
}
519
528
520
529
/* ----------------
521
- * heap_open_nofail - open a heap relation by relationId,
522
- * do not raise error on failure
530
+ * relation_close - close any relation
531
+ *
532
+ * If lockmode is not "NoLock", we first release the specified lock.
523
533
*
524
- * The caller must check for a NULL return value indicating
525
- * that no such relation exists.
526
- * No lock is obtained on the relation, either.
534
+ * Note that it is often sensible to hold a lock beyond relation_close;
535
+ * in that case, the lock is released automatically at xact end.
527
536
* ----------------
528
537
*/
529
- Relation
530
- heap_open_nofail ( Oid relationId )
538
+ void
539
+ relation_close ( Relation relation , LOCKMODE lockmode )
531
540
{
532
- Relation r ;
541
+ Assert ( lockmode >= NoLock && lockmode < MAX_LOCKMODES ) ;
533
542
534
543
/*
535
544
* increment access statistics
536
545
*/
537
- IncrHeapAccessStat (local_open );
538
- IncrHeapAccessStat (global_open );
539
-
540
- /* The relcache does all the real work... */
541
- r = RelationIdGetRelation (relationId );
546
+ IncrHeapAccessStat (local_close );
547
+ IncrHeapAccessStat (global_close );
542
548
543
- /* Under no circumstances will we return an index as a relation. */
544
- if (RelationIsValid (r ) && r -> rd_rel -> relkind == RELKIND_INDEX )
545
- elog (ERROR , "%s is an index relation" , RelationGetRelationName (r ));
549
+ if (lockmode != NoLock )
550
+ UnlockRelation (relation , lockmode );
546
551
547
- return r ;
552
+ /* The relcache does the real work... */
553
+ RelationClose (relation );
548
554
}
549
555
556
+
550
557
/* ----------------
551
- * heap_openr_nofail - open a heap relation by name,
552
- * do not raise error on failure
558
+ * heap_open - open a heap relation by relation OID
553
559
*
554
- * The caller must check for a NULL return value indicating
555
- * that no such relation exists.
556
- * No lock is obtained on the relation, either.
560
+ * This is essentially relation_open plus check that the relation
561
+ * is not an index or special relation. (The caller should also check
562
+ * that it's not a view before assuming it has storage.)
557
563
* ----------------
558
564
*/
559
565
Relation
560
- heap_openr_nofail ( const char * relationName )
566
+ heap_open ( Oid relationId , LOCKMODE lockmode )
561
567
{
562
568
Relation r ;
563
569
564
- /*
565
- * increment access statistics
566
- */
567
- IncrHeapAccessStat (local_openr );
568
- IncrHeapAccessStat (global_openr );
570
+ r = relation_open (relationId , lockmode );
569
571
570
- /* The relcache does all the real work... */
571
- r = RelationNameGetRelation (relationName );
572
-
573
- /* Under no circumstances will we return an index as a relation. */
574
- if (RelationIsValid (r ) && r -> rd_rel -> relkind == RELKIND_INDEX )
575
- elog (ERROR , "%s is an index relation" , RelationGetRelationName (r ));
576
-
577
- if (RelationIsValid (r ))
578
- pgstat_initstats (& r -> pgstat_info , r );
572
+ if (r -> rd_rel -> relkind == RELKIND_INDEX )
573
+ elog (ERROR , "%s is an index relation" ,
574
+ RelationGetRelationName (r ));
575
+ else if (r -> rd_rel -> relkind == RELKIND_SPECIAL )
576
+ elog (ERROR , "%s is a special relation" ,
577
+ RelationGetRelationName (r ));
579
578
580
- if (RelationIsValid (r ))
581
- pgstat_initstats (& r -> pgstat_info , r );
579
+ pgstat_initstats (& r -> pgstat_info , r );
582
580
583
581
return r ;
584
582
}
585
583
586
584
/* ----------------
587
- * heap_close - close a heap relation
585
+ * heap_openr - open a heap relation by name
588
586
*
589
- * If lockmode is not "NoLock", we first release the specified lock.
590
- * Note that it is often sensible to hold a lock beyond heap_close;
591
- * in that case, the lock is released automatically at xact end.
587
+ * As above, but lookup by name instead of OID.
592
588
* ----------------
593
589
*/
594
- void
595
- heap_close ( Relation relation , LOCKMODE lockmode )
590
+ Relation
591
+ heap_openr ( const char * relationName , LOCKMODE lockmode )
596
592
{
597
- Assert ( lockmode >= NoLock && lockmode < MAX_LOCKMODES ) ;
593
+ Relation r ;
598
594
599
- /*
600
- * increment access statistics
601
- */
602
- IncrHeapAccessStat (local_close );
603
- IncrHeapAccessStat (global_close );
595
+ r = relation_openr (relationName , lockmode );
604
596
605
- if (lockmode != NoLock )
606
- UnlockRelation (relation , lockmode );
597
+ if (r -> rd_rel -> relkind == RELKIND_INDEX )
598
+ elog (ERROR , "%s is an index relation" ,
599
+ RelationGetRelationName (r ));
600
+ else if (r -> rd_rel -> relkind == RELKIND_SPECIAL )
601
+ elog (ERROR , "%s is a special relation" ,
602
+ RelationGetRelationName (r ));
607
603
608
- /* The relcache does the real work... */
609
- RelationClose (relation );
604
+ pgstat_initstats (& r -> pgstat_info , r );
605
+
606
+ return r ;
610
607
}
611
608
612
609
@@ -2332,8 +2329,7 @@ newsame:;
2332
2329
}
2333
2330
2334
2331
/* undo */
2335
- if (XLByteLT (PageGetLSN (page ), lsn )) /* changes are not applied
2336
- * ?! */
2332
+ if (XLByteLT (PageGetLSN (page ), lsn )) /* changes not applied?! */
2337
2333
elog (STOP , "heap_update_undo: bad new tuple page LSN" );
2338
2334
2339
2335
elog (STOP , "heap_update_undo: unimplemented" );
0 commit comments