88 *
99 *
1010 * 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 $
1212 *
1313 *
1414 * INTERFACE ROUTINES
5353#include "utils/inval.h"
5454#include "utils/lsyscache.h"
5555#include "utils/relcache.h"
56+ #include "utils/syscache.h"
5657
5758
5859static XLogRecPtr log_heap_update (Relation reln ,Buffer oldbuf ,
@@ -702,14 +703,56 @@ relation_open(Oid relationId, LOCKMODE lockmode)
702703}
703704
704705/* ----------------
705- *conditional_relation_open - openwith option not to wait
706+ *try_relation_open - openany relation by relation OID
706707 *
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 .
709710 * ----------------
710711 */
711712Relation
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 )
713756{
714757Relation r ;
715758
@@ -718,27 +761,22 @@ conditional_relation_open(Oid relationId, LOCKMODE lockmode, bool nowait)
718761/* Get the lock before trying to open the relcache entry */
719762if (lockmode != NoLock )
720763{
721- if (nowait )
764+ if (! ConditionalLockRelationOid ( relationId , lockmode ) )
722765{
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 )));
739779}
740- else
741- LockRelationOid (relationId ,lockmode );
742780}
743781
744782/* The relcache does all the real work... */
@@ -753,7 +791,7 @@ conditional_relation_open(Oid relationId, LOCKMODE lockmode, bool nowait)
753791/* ----------------
754792 *relation_openrv - open any relation specified by a RangeVar
755793 *
756- *As above , but the relation is specified by a RangeVar.
794+ *Same as relation_open , but the relation is specified by a RangeVar.
757795 * ----------------
758796 */
759797Relation