of just a relation OID, thereby not having to open the relation for itself.
This actually saves code rather than adding it for most of the existing
callers, which had the rel open already. The main point though is to be
able to use this rather than plain addRangeTableEntry in setTargetTable,
thus saving one relation_openrv/relation_close cycle for every INSERT,
UPDATE, or DELETE. Seems to provide a several percent win on simple
INSERTs.
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.281 2005/03/20 22:00:51 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.282 2005/04/13 16:50:54 tgl Exp $
*
*
* INTERFACE ROUTINES
List *rawConstraints)
{
List *cookedConstraints = NIL;
- char *relname = RelationGetRelationName(rel);
TupleDesc tupleDesc;
TupleConstr *oldconstr;
int numoldchecks;
*/
pstate = make_parsestate(NULL);
rte = addRangeTableEntryForRelation(pstate,
- RelationGetRelid(rel),
- makeAlias(relname, NIL),
+ rel,
+ NULL,
false,
true);
addRTEtoQuery(pstate, rte, true, true);
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
errmsg("only table \"%s\" can be referenced in check constraint",
- relname)));
+ RelationGetRelationName(rel))));
/*
* No subplans or aggregates, either...
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.152 2005/03/29 00:16:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.153 2005/04/13 16:50:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/* Expression must be able to access vars of old table */
rte = addRangeTableEntryForRelation(pstate,
- RelationGetRelid(rel),
- makeAlias(RelationGetRelationName(rel), NIL),
+ rel,
+ NULL,
false,
true);
addRTEtoQuery(pstate, rte, false, true);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.88 2005/04/06 16:34:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.89 2005/04/13 16:50:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static Query *
UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
{
+ Relation viewRel;
List *new_rt;
RangeTblEntry *rt_entry1,
*rt_entry2;
*/
viewParse = (Query *) copyObject(viewParse);
+ /* need to open the rel for addRangeTableEntryForRelation */
+ viewRel = relation_open(viewOid, AccessShareLock);
+
/*
* Create the 2 new range table entries and form the new range
* table... OLD first, then NEW....
*/
- rt_entry1 = addRangeTableEntryForRelation(NULL, viewOid,
+ rt_entry1 = addRangeTableEntryForRelation(NULL, viewRel,
makeAlias("*OLD*", NIL),
false, false);
- rt_entry2 = addRangeTableEntryForRelation(NULL, viewOid,
+ rt_entry2 = addRangeTableEntryForRelation(NULL, viewRel,
makeAlias("*NEW*", NIL),
false, false);
/* Must override addRangeTableEntry's default access-check flags */
*/
OffsetVarNodes((Node *) viewParse, 2, 0);
+ relation_close(viewRel, AccessShareLock);
+
return viewParse;
}
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.318 2005/04/07 01:51:38 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.319 2005/04/13 16:50:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
List **extras_before, List **extras_after)
{
Query *qry;
+ Relation rel;
RangeTblEntry *oldrte;
RangeTblEntry *newrte;
* To avoid deadlock, make sure the first thing we do is grab
* AccessExclusiveLock on the target relation. This will be needed by
* DefineQueryRewrite(), and we don't want to grab a lesser lock
- * beforehand. We don't need to hold a refcount on the relcache
- * entry, however.
+ * beforehand.
*/
- heap_close(heap_openrv(stmt->relation, AccessExclusiveLock),
- NoLock);
+ rel = heap_openrv(stmt->relation, AccessExclusiveLock);
/*
* NOTE: 'OLD' must always have a varno equal to 1 and 'NEW' equal to
* rule qualification.
*/
Assert(pstate->p_rtable == NIL);
- oldrte = addRangeTableEntry(pstate, stmt->relation,
- makeAlias("*OLD*", NIL),
- false, true);
- newrte = addRangeTableEntry(pstate, stmt->relation,
- makeAlias("*NEW*", NIL),
- false, true);
+ oldrte = addRangeTableEntryForRelation(pstate, rel,
+ makeAlias("*OLD*", NIL),
+ false, true);
+ newrte = addRangeTableEntryForRelation(pstate, rel,
+ makeAlias("*NEW*", NIL),
+ false, true);
/* Must override addRangeTableEntry's default access-check flags */
oldrte->requiredPerms = 0;
newrte->requiredPerms = 0;
* or they won't be accessible at all. We decide later
* whether to put them in the joinlist.
*/
- oldrte = addRangeTableEntry(sub_pstate, stmt->relation,
- makeAlias("*OLD*", NIL),
- false, false);
- newrte = addRangeTableEntry(sub_pstate, stmt->relation,
- makeAlias("*NEW*", NIL),
- false, false);
+ oldrte = addRangeTableEntryForRelation(sub_pstate, rel,
+ makeAlias("*OLD*", NIL),
+ false, false);
+ newrte = addRangeTableEntryForRelation(sub_pstate, rel,
+ makeAlias("*NEW*", NIL),
+ false, false);
oldrte->requiredPerms = 0;
newrte->requiredPerms = 0;
addRTEtoQuery(sub_pstate, oldrte, false, true);
stmt->actions = newactions;
}
+ /* Close relation, but keep the exclusive lock */
+ heap_close(rel, NoLock);
+
return qry;
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.139 2005/04/06 16:34:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.140 2005/04/13 16:50:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
* Now build an RTE.
*/
- rte = addRangeTableEntry(pstate, relation, NULL, inh, false);
+ rte = addRangeTableEntryForRelation(pstate, pstate->p_target_relation,
+ NULL, inh, false);
pstate->p_target_rangetblentry = rte;
/* assume new rte is at end */
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.105 2005/04/07 01:51:39 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.106 2005/04/13 16:50:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* Add an entry for a relation to the pstate's range table (p_rtable).
*
* This is just like addRangeTableEntry() except that it makes an RTE
- * given a relation OID instead of a RangeVar reference.
- *
- * Note that an alias clause *must* be supplied.
+ * given an already-open relation instead of a RangeVar reference.
*/
RangeTblEntry *
addRangeTableEntryForRelation(ParseState *pstate,
- Oid relid,
+ Relation rel,
Alias *alias,
bool inh,
bool inFromCl)
{
RangeTblEntry *rte = makeNode(RangeTblEntry);
- char *refname = alias->aliasname;
- LOCKMODE lockmode;
- Relation rel;
+ char *refname = alias ? alias->aliasname : RelationGetRelationName(rel);
rte->rtekind = RTE_RELATION;
rte->alias = alias;
-
- /*
- * Get the rel's relcache entry. This access ensures that we have an
- * up-to-date relcache entry for the rel. Since this is typically the
- * first access to a rel in a statement, be careful to get the right
- * access level depending on whether we're doing SELECT FOR UPDATE.
- */
- lockmode = isForUpdate(pstate, refname) ? RowShareLock : AccessShareLock;
- rel = heap_open(relid, lockmode);
- rte->relid = relid;
+ rte->relid = RelationGetRelid(rel);
/*
* Build the list of effective column names using user-supplied
rte->eref = makeAlias(refname, NIL);
buildRelationAliases(rel->rd_att, alias, rte->eref);
- /*
- * Drop the rel refcount, but keep the access lock till end of
- * transaction so that the table can't be deleted or have its schema
- * modified underneath us.
- */
- heap_close(rel, NoLock);
-
/*----------
* Flags:
* - this RTE should be expanded to include descendant tables,
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.48 2004/12/31 22:03:38 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.49 2005/04/13 16:50:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
bool inh,
bool inFromCl);
extern RangeTblEntry *addRangeTableEntryForRelation(ParseState *pstate,
- Oid relid,
+ Relation rel,
Alias *alias,
bool inh,
bool inFromCl);