Modify heap_open()/heap_openr() API per pghackers discussion of 11 July.
authorTom Lane
Thu, 3 Aug 2000 19:19:38 +0000 (19:19 +0000)
committerTom Lane
Thu, 3 Aug 2000 19:19:38 +0000 (19:19 +0000)
These two routines will now ALWAYS elog() on failure, whether you ask for
a lock or not.  If you really want to get a NULL return on failure, call
the new routines heap_open_nofail()/heap_openr_nofail().  By my count there
are only about three places that actually want that behavior.  There were
rather more than three places that were missing the check they needed to
make under the old convention :-(.

src/backend/access/heap/heapam.c
src/backend/access/transam/transam.c
src/backend/bootstrap/bootstrap.c
src/backend/catalog/heap.c
src/backend/commands/command.c
src/backend/commands/trigger.c
src/backend/executor/execAmi.c
src/backend/executor/nodeTidscan.c
src/backend/parser/parse_func.c
src/include/access/heapam.h

index 379d0ecc5526ce515acc8064eaa209cce4548591..1e22c0304620ef9dc873c555e61b36eed34a5708 100644 (file)
@@ -8,13 +8,14 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.82 2000/07/22 11:18:46 wieck Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.83 2000/08/03 19:18:54 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
  *     heapgettup      - fetch next heap tuple from a scan
  *     heap_open       - open a heap relation by relationId
  *     heap_openr      - open a heap relation by name
+ *     heap_open[r]_nofail - same, but return NULL on failure instead of elog
  *     heap_close      - close a heap relation
  *     heap_beginscan  - begin relation scan
  *     heap_rescan     - restart a relation scan
@@ -560,19 +561,17 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
 #endif /* defined(DISABLE_COMPLEX_MACRO)*/
 
 
-
 /* ----------------------------------------------------------------
  *                  heap access method interface
  * ----------------------------------------------------------------
  */
+
 /* ----------------
  *     heap_open - open a heap relation by relationId
  *
- *     If lockmode is "NoLock", no lock is obtained on the relation,
- *     and the caller must check for a NULL return value indicating
- *     that no such relation exists.
- *     Otherwise, an error is raised if the relation does not exist,
- *     and the specified kind of lock is obtained on the relation.
+ *     If lockmode is not "NoLock", the specified kind of lock is
+ *     obtained on the relation.
+ *     An error is raised if the relation does not exist.
  * ----------------
  */
 Relation
@@ -592,17 +591,15 @@ heap_open(Oid relationId, LOCKMODE lockmode)
    /* The relcache does all the real work... */
    r = RelationIdGetRelation(relationId);
 
-   /* Under no circumstances will we return an index as a relation. */
-   if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX)
-       elog(ERROR, "%s is an index relation", RelationGetRelationName(r));
-
-   if (lockmode == NoLock)
-       return r;               /* caller must check RelationIsValid! */
-
    if (!RelationIsValid(r))
        elog(ERROR, "Relation %u does not exist", relationId);
 
-   LockRelation(r, lockmode);
+   /* Under no circumstances will we return an index as a relation. */
+   if (r->rd_rel->relkind == RELKIND_INDEX)
+       elog(ERROR, "%s is an index relation", RelationGetRelationName(r));
+
+   if (lockmode != NoLock)
+       LockRelation(r, lockmode);
 
    return r;
 }
@@ -610,11 +607,9 @@ heap_open(Oid relationId, LOCKMODE lockmode)
 /* ----------------
  *     heap_openr - open a heap relation by name
  *
- *     If lockmode is "NoLock", no lock is obtained on the relation,
- *     and the caller must check for a NULL return value indicating
- *     that no such relation exists.
- *     Otherwise, an error is raised if the relation does not exist,
- *     and the specified kind of lock is obtained on the relation.
+ *     If lockmode is not "NoLock", the specified kind of lock is
+ *     obtained on the relation.
+ *     An error is raised if the relation does not exist.
  * ----------------
  */
 Relation
@@ -624,7 +619,6 @@ heap_openr(const char *relationName, LOCKMODE lockmode)
 
    Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
 
-
    /* ----------------
     *  increment access statistics
     * ----------------
@@ -635,17 +629,77 @@ heap_openr(const char *relationName, LOCKMODE lockmode)
    /* The relcache does all the real work... */
    r = RelationNameGetRelation(relationName);
 
+   if (!RelationIsValid(r))
+       elog(ERROR, "Relation '%s' does not exist", relationName);
+
+   /* Under no circumstances will we return an index as a relation. */
+   if (r->rd_rel->relkind == RELKIND_INDEX)
+       elog(ERROR, "%s is an index relation", RelationGetRelationName(r));
+
+   if (lockmode != NoLock)
+       LockRelation(r, lockmode);
+
+   return r;
+}
+
+/* ----------------
+ *     heap_open_nofail - open a heap relation by relationId,
+ *             do not raise error on failure
+ *
+ *     The caller must check for a NULL return value indicating
+ *     that no such relation exists.
+ *     No lock is obtained on the relation, either.
+ * ----------------
+ */
+Relation
+heap_open_nofail(Oid relationId)
+{
+   Relation    r;
+
+   /* ----------------
+    *  increment access statistics
+    * ----------------
+    */
+   IncrHeapAccessStat(local_open);
+   IncrHeapAccessStat(global_open);
+
+   /* The relcache does all the real work... */
+   r = RelationIdGetRelation(relationId);
+
    /* Under no circumstances will we return an index as a relation. */
    if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX)
        elog(ERROR, "%s is an index relation", RelationGetRelationName(r));
 
-   if (lockmode == NoLock)
-       return r;               /* caller must check RelationIsValid! */
+   return r;
+}
 
-   if (!RelationIsValid(r))
-       elog(ERROR, "Relation '%s' does not exist", relationName);
+/* ----------------
+ *     heap_openr_nofail - open a heap relation by name,
+ *             do not raise error on failure
+ *
+ *     The caller must check for a NULL return value indicating
+ *     that no such relation exists.
+ *     No lock is obtained on the relation, either.
+ * ----------------
+ */
+Relation
+heap_openr_nofail(const char *relationName)
+{
+   Relation    r;
 
-   LockRelation(r, lockmode);
+   /* ----------------
+    *  increment access statistics
+    * ----------------
+    */
+   IncrHeapAccessStat(local_openr);
+   IncrHeapAccessStat(global_openr);
+
+   /* The relcache does all the real work... */
+   r = RelationNameGetRelation(relationName);
+
+   /* Under no circumstances will we return an index as a relation. */
+   if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX)
+       elog(ERROR, "%s is an index relation", RelationGetRelationName(r));
 
    return r;
 }
index acca4a901a2f16083d1eff601ec4647046d1b527..52a3906ba6989dd0537aa0b5d18f12f22930722c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.34 2000/04/12 17:14:52 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.35 2000/08/03 19:18:55 tgl Exp $
  *
  * NOTES
  *   This file contains the high level access-method interface to the
@@ -408,9 +408,7 @@ InitializeTransactionLog(void)
     * ----------------
     */
    logRelation = heap_openr(LogRelationName, NoLock);
-   Assert(logRelation != NULL);
    VariableRelation = heap_openr(VariableRelationName, NoLock);
-   Assert(VariableRelation != NULL);
 
    /* ----------------
     *   XXX TransactionLogUpdate requires that LogRelation
index c3cf93717241ec962fb10b37c19dcc9f9319d48a..2eacad23dc3133ac55b7d6337548c965008dad45 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.91 2000/07/14 22:17:38 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.92 2000/08/03 19:19:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -430,7 +430,6 @@ boot_openrel(char *relname)
    if (Typ == (struct typmap **) NULL)
    {
        rel = heap_openr(TypeRelationName, NoLock);
-       Assert(rel);
        scan = heap_beginscan(rel, 0, SnapshotNow, 0, (ScanKey) NULL);
        i = 0;
        while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
@@ -462,7 +461,6 @@ boot_openrel(char *relname)
               (int) ATTRIBUTE_TUPLE_SIZE);
 
    reldesc = heap_openr(relname, NoLock);
-   Assert(reldesc);
    numattr = reldesc->rd_rel->relnatts;
    for (i = 0; i < numattr; i++)
    {
@@ -822,7 +820,6 @@ gettype(char *type)
        if (DebugMode)
            printf("bootstrap.c: External Type: %s\n", type);
        rel = heap_openr(TypeRelationName, NoLock);
-       Assert(rel);
        scan = heap_beginscan(rel, 0, SnapshotNow, 0, (ScanKey) NULL);
        i = 0;
        while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
@@ -1116,9 +1113,7 @@ build_indices()
        Relation    ind;
 
        heap = heap_openr(ILHead->il_heap, NoLock);
-       Assert(heap);
        ind = index_openr(ILHead->il_ind);
-       Assert(ind);
        index_build(heap, ind, ILHead->il_info, NULL);
 
        /*
index 6c8c95563f2d38123677ecf9e63de7bed0a8c8df..cf4b86e2e82cca3dfe0df06020584ccb2bb01b54 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.141 2000/08/03 16:33:52 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.142 2000/08/03 19:19:08 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1134,7 +1134,6 @@ RelationTruncateIndexes(Relation heapRelation)
         * by heap_truncate.
         */
        heapRelation = heap_open(heapId, NoLock);
-       Assert(heapRelation != NULL);
    }
 
    /* Complete the scan and close pg_index */
index 3deea360e0a19485cc206e28e1a6737d8fc5c3fe..de2597bd266016ea9a3b58aaf0c39605fcf8f5f0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.92 2000/08/03 16:34:01 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.93 2000/08/03 19:19:18 tgl Exp $
  *
  * NOTES
  *   The PerformAddAttribute() code, like most of the relation
@@ -1614,8 +1614,6 @@ LockTableCommand(LockStmt *lockstmt)
    int         aclresult;
 
    rel = heap_openr(lockstmt->relname, NoLock);
-   if (!RelationIsValid(rel))
-       elog(ERROR, "Relation '%s' does not exist", lockstmt->relname);
 
    if (lockstmt->mode == AccessShareLock)
        aclresult = pg_aclcheck(lockstmt->relname, GetPgUserName(), ACL_RD);
index 17e61a379fb6a9ca5fe74565878f45d6025b8c8b..a03f140b64f87e218f2e2a524bc866377ce744c6 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.74 2000/08/03 16:34:01 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.75 2000/08/03 19:19:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -92,9 +92,6 @@ CreateTrigger(CreateTrigStmt *stmt)
             * interested in getting the relation's OID...
             */
            rel = heap_openr(stmt->constrrelname, NoLock);
-           if (rel == NULL)
-               elog(ERROR, "table \"%s\" does not exist",
-                    stmt->constrrelname);
            constrrelid = rel->rd_id;
            heap_close(rel, NoLock);
        }
@@ -440,12 +437,12 @@ RelationRemoveTriggers(Relation rel)
        pg_trigger = (Form_pg_trigger) GETSTRUCT(tup);
 
        refrel = heap_open(pg_trigger->tgrelid, NoLock);
-
        stmt.relname = pstrdup(RelationGetRelationName(refrel));
+       heap_close(refrel, NoLock);
+
        stmt.trigname = DatumGetCString(DirectFunctionCall1(nameout,
                        NameGetDatum(&pg_trigger->tgname)));
 
-       heap_close(refrel, NoLock);
 
        elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"", stmt.relname);
 
index c3cb019c89d679459e0cf7b08b2a8b45756d2baf..99d6b7b27be110963439d41d73323e163e3c8b86 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: execAmi.c,v 1.50 2000/07/25 23:43:38 tgl Exp $
+ * $Id: execAmi.c,v 1.51 2000/08/03 19:19:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -98,9 +98,6 @@ ExecOpenScanR(Oid relOid,
    else
        relation = heap_open(relOid, NoLock);
 
-   if (relation == NULL)
-       elog(ERROR, "ExecOpenScanR: failed to open relation %u", relOid);
-
    scanDesc = ExecBeginScan(relation,
                             nkeys,
                             skeys,
index 824ead5ec6b0de25f818a8efef8aaca09d0b3273..ac6511dcbfb5a0a4688bbc51a06738c7fa5834fe 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.10 2000/07/12 02:37:04 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.11 2000/08/03 19:19:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -481,8 +481,6 @@ ExecInitTidScan(TidScan *node, EState *estate, Plan *parent)
    reloid = rtentry->relid;
 
    currentRelation = heap_open(reloid, AccessShareLock);
-   if (currentRelation == NULL)
-       elog(ERROR, "ExecInitTidScan heap_open failed.");
    scanstate->css_currentRelation = currentRelation;
    scanstate->css_currentScanDesc = 0;
 
index 1ff6b5344472b9b2b0a496e360f1573f2d1d476d..d1a5e44f8735a2ab88f22a921ab189022091e0a3 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.85 2000/06/15 04:09:54 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.86 2000/08/03 19:19:34 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -382,7 +382,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
            if (attisset)
            {
                toid = exprType(first_arg);
-               rd = heap_openr(typeidTypeName(toid), NoLock);
+               rd = heap_openr_nofail(typeidTypeName(toid));
                if (RelationIsValid(rd))
                {
                    relname = RelationGetRelationName(rd);
@@ -1376,8 +1376,6 @@ find_inheritors(Oid relid, Oid **supervec)
 
            relid = lfirsti(elt);
            rd = heap_open(relid, NoLock);
-           if (!RelationIsValid(rd))
-               elog(ERROR, "Relid %u does not exist", relid);
            trelid = typeTypeId(typenameType(RelationGetRelationName(rd)));
            heap_close(rd, NoLock);
            *relidvec++ = trelid;
@@ -1627,7 +1625,7 @@ ParseComplexProjection(ParseState *pstate,
                     */
 
                    /* add a tlist to the func node and return the Iter */
-                   rd = heap_openr(typeidTypeName(argtype), NoLock);
+                   rd = heap_openr_nofail(typeidTypeName(argtype));
                    if (RelationIsValid(rd))
                    {
                        relid = RelationGetRelid(rd);
@@ -1679,29 +1677,24 @@ ParseComplexProjection(ParseState *pstate,
                    (attnum = get_attnum(argrelid, funcname))
                    != InvalidAttrNumber)
                {
+                   Expr       *newexpr;
 
                    /* add a tlist to the func node */
                    rd = heap_openr(typeidTypeName(argtype), NoLock);
-                   if (RelationIsValid(rd))
-                   {
-                       Expr       *newexpr;
-
-                       relid = RelationGetRelid(rd);
-                       funcnode->func_tlist = setup_tlist(funcname, argrelid);
-                       funcnode->functype = attnumTypeId(rd, attnum);
 
-                       newexpr = makeNode(Expr);
-                       newexpr->typeOid = funcnode->functype;
-                       newexpr->opType = FUNC_EXPR;
-                       newexpr->oper = (Node *) funcnode;
-                       newexpr->args = expr->args;
+                   relid = RelationGetRelid(rd);
+                   funcnode->func_tlist = setup_tlist(funcname, argrelid);
+                   funcnode->functype = attnumTypeId(rd, attnum);
 
-                       heap_close(rd, NoLock);
+                   newexpr = makeNode(Expr);
+                   newexpr->typeOid = funcnode->functype;
+                   newexpr->opType = FUNC_EXPR;
+                   newexpr->oper = (Node *) funcnode;
+                   newexpr->args = expr->args;
 
-                       return (Node *) newexpr;
-                   }
-                   /* XXX why not an error condition if it's not there? */
+                   heap_close(rd, NoLock);
 
+                   return (Node *) newexpr;
                }
 
                break;
@@ -1714,7 +1707,7 @@ ParseComplexProjection(ParseState *pstate,
                 * If the Param is a complex type, this could be a
                 * projection
                 */
-               rd = heap_openr(typeidTypeName(param->paramtype), NoLock);
+               rd = heap_openr_nofail(typeidTypeName(param->paramtype));
                if (RelationIsValid(rd))
                {
                    relid = RelationGetRelid(rd);
index c716ab239265b3c1e1d44e974b6550f39d65bfb4..d110759cb621e283fec0a18023493757d55267c5 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: heapam.h,v 1.55 2000/07/02 22:01:00 momjian Exp $
+ * $Id: heapam.h,v 1.56 2000/08/03 19:19:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -216,6 +216,8 @@ extern HeapAccessStatistics heap_access_stats;  /* in stats.c */
 
 extern Relation heap_open(Oid relationId, LOCKMODE lockmode);
 extern Relation heap_openr(const char *relationName, LOCKMODE lockmode);
+extern Relation heap_open_nofail(Oid relationId);
+extern Relation heap_openr_nofail(const char *relationName);
 extern void heap_close(Relation relation, LOCKMODE lockmode);
 extern HeapScanDesc heap_beginscan(Relation relation, int atend,
               Snapshot snapshot, unsigned nkeys, ScanKey key);