Change addRangeTableEntryForRelation() to take a Relation pointer instead

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.
This commit is contained in:
Tom Lane 2005-04-13 16:50:55 +00:00
parent 45c79a3094
commit 2fdf9e0be6
7 changed files with 45 additions and 57 deletions

View File

@ -8,7 +8,7 @@
*
*
* 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
@ -1482,7 +1482,6 @@ AddRelationRawConstraints(Relation rel,
List *rawConstraints)
{
List *cookedConstraints = NIL;
char *relname = RelationGetRelationName(rel);
TupleDesc tupleDesc;
TupleConstr *oldconstr;
int numoldchecks;
@ -1517,8 +1516,8 @@ AddRelationRawConstraints(Relation rel,
*/
pstate = make_parsestate(NULL);
rte = addRangeTableEntryForRelation(pstate,
RelationGetRelid(rel),
makeAlias(relname, NIL),
rel,
NULL,
false,
true);
addRTEtoQuery(pstate, rte, true, true);
@ -1576,7 +1575,7 @@ AddRelationRawConstraints(Relation rel,
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...

View File

@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -4732,8 +4732,8 @@ ATPrepAlterColumnType(List **wqueue,
/* 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);

View File

@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -329,6 +329,7 @@ DefineViewRules(const RangeVar *view, Query *viewParse, bool replace)
static Query *
UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
{
Relation viewRel;
List *new_rt;
RangeTblEntry *rt_entry1,
*rt_entry2;
@ -343,14 +344,17 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
*/
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 */
@ -366,6 +370,8 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
*/
OffsetVarNodes((Node *) viewParse, 2, 0);
relation_close(viewRel, AccessShareLock);
return viewParse;
}

View File

@ -6,7 +6,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -1536,6 +1536,7 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
List **extras_before, List **extras_after)
{
Query *qry;
Relation rel;
RangeTblEntry *oldrte;
RangeTblEntry *newrte;
@ -1547,11 +1548,9 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
* 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
@ -1559,12 +1558,12 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
* 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;
@ -1659,12 +1658,12 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
* 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);
@ -1791,6 +1790,9 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
stmt->actions = newactions;
}
/* Close relation, but keep the exclusive lock */
heap_close(rel, NoLock);
return qry;
}

View File

@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -144,7 +144,8 @@ setTargetTable(ParseState *pstate, RangeVar *relation,
/*
* 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 */

View File

@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -809,34 +809,21 @@ addRangeTableEntry(ParseState *pstate,
* 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
@ -845,13 +832,6 @@ addRangeTableEntryForRelation(ParseState *pstate,
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,

View File

@ -7,7 +7,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -45,7 +45,7 @@ extern RangeTblEntry *addRangeTableEntry(ParseState *pstate,
bool inh,
bool inFromCl);
extern RangeTblEntry *addRangeTableEntryForRelation(ParseState *pstate,
Oid relid,
Relation rel,
Alias *alias,
bool inh,
bool inFromCl);