Modify heap_open()/heap_openr() API per pghackers discussion of 11 July.

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 :-(.
This commit is contained in:
Tom Lane 2000-08-03 19:19:38 +00:00
parent c298d74d49
commit 61aca818c4
10 changed files with 109 additions and 78 deletions

View 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,6 +619,73 @@ heap_openr(const char *relationName, LOCKMODE lockmode)
Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
/* ----------------
* increment access statistics
* ----------------
*/
IncrHeapAccessStat(local_openr);
IncrHeapAccessStat(global_openr);
/* 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));
return r;
}
/* ----------------
* 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;
/* ----------------
* increment access statistics
@ -639,14 +701,6 @@ heap_openr(const char *relationName, LOCKMODE lockmode)
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 '%s' does not exist", relationName);
LockRelation(r, lockmode);
return r;
}

View 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

View 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);
/*

View 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 */

View 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);

View 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);

View 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,

View 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;

View 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);
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;
newexpr = makeNode(Expr);
newexpr->typeOid = funcnode->functype;
newexpr->opType = FUNC_EXPR;
newexpr->oper = (Node *) funcnode;
newexpr->args = expr->args;
heap_close(rd, NoLock);
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);

View 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);