8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.218 2006/07/31 20:08:59 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.219 2006/08/18 16:09:08 tgl Exp $
12
12
*
13
13
*
14
14
* INTERFACE ROUTINES
53
53
#include "utils/inval.h"
54
54
#include "utils/lsyscache.h"
55
55
#include "utils/relcache.h"
56
+ #include "utils/syscache.h"
56
57
57
58
58
59
static XLogRecPtr log_heap_update (Relation reln ,Buffer oldbuf ,
@@ -702,14 +703,56 @@ relation_open(Oid relationId, LOCKMODE lockmode)
702
703
}
703
704
704
705
/* ----------------
705
- *conditional_relation_open - openwith option not to wait
706
+ *try_relation_open - openany relation by relation OID
706
707
*
707
- *As above, but if nowait is true, then throw an error rather than
708
- *waiting when thelock is notimmediately obtainable .
708
+ *Same as relation_open, except return NULL instead of failing
709
+ *if therelation does notexist .
709
710
* ----------------
710
711
*/
711
712
Relation
712
- conditional_relation_open (Oid relationId ,LOCKMODE lockmode ,bool nowait )
713
+ try_relation_open (Oid relationId ,LOCKMODE lockmode )
714
+ {
715
+ Relation r ;
716
+
717
+ Assert (lockmode >=NoLock && lockmode < MAX_LOCKMODES );
718
+
719
+ /* Get the lock first */
720
+ if (lockmode != NoLock )
721
+ LockRelationOid (relationId ,lockmode );
722
+
723
+ /*
724
+ * Now that we have the lock, probe to see if the relation really
725
+ * exists or not.
726
+ */
727
+ if (!SearchSysCacheExists (RELOID ,
728
+ ObjectIdGetDatum (relationId ),
729
+ 0 ,0 ,0 ))
730
+ {
731
+ /* Release useless lock */
732
+ if (lockmode != NoLock )
733
+ UnlockRelationOid (relationId ,lockmode );
734
+
735
+ return NULL ;
736
+ }
737
+
738
+ /* Should be safe to do a relcache load */
739
+ r = RelationIdGetRelation (relationId );
740
+
741
+ if (!RelationIsValid (r ))
742
+ elog (ERROR ,"could not open relation with OID %u" ,relationId );
743
+
744
+ return r ;
745
+ }
746
+
747
+ /* ----------------
748
+ *relation_open_nowait - open but don't wait for lock
749
+ *
750
+ *Same as relation_open, except throw an error instead of waiting
751
+ *when the requested lock is not immediately obtainable.
752
+ * ----------------
753
+ */
754
+ Relation
755
+ relation_open_nowait (Oid relationId ,LOCKMODE lockmode )
713
756
{
714
757
Relation r ;
715
758
@@ -718,27 +761,22 @@ conditional_relation_open(Oid relationId, LOCKMODE lockmode, bool nowait)
718
761
/* Get the lock before trying to open the relcache entry */
719
762
if (lockmode != NoLock )
720
763
{
721
- if (nowait )
764
+ if (! ConditionalLockRelationOid ( relationId , lockmode ) )
722
765
{
723
- if (!ConditionalLockRelationOid (relationId ,lockmode ))
724
- {
725
- /* try to throw error by name; relation could be deleted... */
726
- char * relname = get_rel_name (relationId );
727
-
728
- if (relname )
729
- ereport (ERROR ,
730
- (errcode (ERRCODE_LOCK_NOT_AVAILABLE ),
731
- errmsg ("could not obtain lock on relation \"%s\"" ,
732
- relname )));
733
- else
734
- ereport (ERROR ,
735
- (errcode (ERRCODE_LOCK_NOT_AVAILABLE ),
736
- errmsg ("could not obtain lock on relation with OID %u" ,
737
- relationId )));
738
- }
766
+ /* try to throw error by name; relation could be deleted... */
767
+ char * relname = get_rel_name (relationId );
768
+
769
+ if (relname )
770
+ ereport (ERROR ,
771
+ (errcode (ERRCODE_LOCK_NOT_AVAILABLE ),
772
+ errmsg ("could not obtain lock on relation \"%s\"" ,
773
+ relname )));
774
+ else
775
+ ereport (ERROR ,
776
+ (errcode (ERRCODE_LOCK_NOT_AVAILABLE ),
777
+ errmsg ("could not obtain lock on relation with OID %u" ,
778
+ relationId )));
739
779
}
740
- else
741
- LockRelationOid (relationId ,lockmode );
742
780
}
743
781
744
782
/* The relcache does all the real work... */
@@ -753,7 +791,7 @@ conditional_relation_open(Oid relationId, LOCKMODE lockmode, bool nowait)
753
791
/* ----------------
754
792
*relation_openrv - open any relation specified by a RangeVar
755
793
*
756
- *As above , but the relation is specified by a RangeVar.
794
+ *Same as relation_open , but the relation is specified by a RangeVar.
757
795
* ----------------
758
796
*/
759
797
Relation