mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
Refactor ExecGetJunkAttribute to avoid searching for junk attributes
by name on each and every row processed. Profiling suggests this may buy a percent or two for simple UPDATE scenarios, which isn't huge, but when it's so easy to get ...
This commit is contained in:
@ -26,7 +26,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.280 2006/10/04 00:29:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.281 2006/12/04 02:06:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -567,7 +567,9 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
||||
}
|
||||
|
||||
/*
|
||||
* Have to lock relations selected FOR UPDATE/FOR SHARE
|
||||
* Have to lock relations selected FOR UPDATE/FOR SHARE before we
|
||||
* initialize the plan tree, else we'd be doing a lock upgrade.
|
||||
* While we are at it, build the ExecRowMark list.
|
||||
*/
|
||||
estate->es_rowMarks = NIL;
|
||||
foreach(l, parseTree->rowMarks)
|
||||
@ -583,7 +585,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
||||
erm->rti = rc->rti;
|
||||
erm->forUpdate = rc->forUpdate;
|
||||
erm->noWait = rc->noWait;
|
||||
snprintf(erm->resname, sizeof(erm->resname), "ctid%u", rc->rti);
|
||||
/* We'll set up ctidAttno below */
|
||||
erm->ctidAttNo = InvalidAttrNumber;
|
||||
estate->es_rowMarks = lappend(estate->es_rowMarks, erm);
|
||||
}
|
||||
|
||||
@ -703,6 +706,16 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
||||
j = ExecInitJunkFilter(subplan->plan->targetlist,
|
||||
resultRelInfo->ri_RelationDesc->rd_att->tdhasoid,
|
||||
ExecAllocTableSlot(estate->es_tupleTable));
|
||||
/*
|
||||
* Since it must be UPDATE/DELETE, there had better be
|
||||
* a "ctid" junk attribute in the tlist ... but ctid could
|
||||
* be at a different resno for each result relation.
|
||||
* We look up the ctid resnos now and save them in the
|
||||
* junkfilters.
|
||||
*/
|
||||
j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid");
|
||||
if (!AttributeNumberIsValid(j->jf_junkAttNo))
|
||||
elog(ERROR, "could not find junk ctid column");
|
||||
resultRelInfo->ri_junkFilter = j;
|
||||
resultRelInfo++;
|
||||
}
|
||||
@ -726,9 +739,30 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
||||
if (estate->es_result_relation_info)
|
||||
estate->es_result_relation_info->ri_junkFilter = j;
|
||||
|
||||
/* For SELECT, want to return the cleaned tuple type */
|
||||
if (operation == CMD_SELECT)
|
||||
{
|
||||
/* For SELECT, want to return the cleaned tuple type */
|
||||
tupType = j->jf_cleanTupType;
|
||||
/* For SELECT FOR UPDATE/SHARE, find the ctid attrs now */
|
||||
foreach(l, estate->es_rowMarks)
|
||||
{
|
||||
ExecRowMark *erm = (ExecRowMark *) lfirst(l);
|
||||
char resname[32];
|
||||
|
||||
snprintf(resname, sizeof(resname), "ctid%u", erm->rti);
|
||||
erm->ctidAttNo = ExecFindJunkAttribute(j, resname);
|
||||
if (!AttributeNumberIsValid(erm->ctidAttNo))
|
||||
elog(ERROR, "could not find junk \"%s\" column",
|
||||
resname);
|
||||
}
|
||||
}
|
||||
else if (operation == CMD_UPDATE || operation == CMD_DELETE)
|
||||
{
|
||||
/* For UPDATE/DELETE, find the ctid junk attr now */
|
||||
j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid");
|
||||
if (!AttributeNumberIsValid(j->jf_junkAttNo))
|
||||
elog(ERROR, "could not find junk ctid column");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1111,13 +1145,8 @@ lnext: ;
|
||||
*/
|
||||
if (operation == CMD_UPDATE || operation == CMD_DELETE)
|
||||
{
|
||||
if (!ExecGetJunkAttribute(junkfilter,
|
||||
slot,
|
||||
"ctid",
|
||||
&datum,
|
||||
&isNull))
|
||||
elog(ERROR, "could not find junk ctid column");
|
||||
|
||||
datum = ExecGetJunkAttribute(slot, junkfilter->jf_junkAttNo,
|
||||
&isNull);
|
||||
/* shouldn't ever get a null result... */
|
||||
if (isNull)
|
||||
elog(ERROR, "ctid is NULL");
|
||||
@ -1146,17 +1175,12 @@ lnext: ;
|
||||
LockTupleMode lockmode;
|
||||
HTSU_Result test;
|
||||
|
||||
if (!ExecGetJunkAttribute(junkfilter,
|
||||
slot,
|
||||
erm->resname,
|
||||
&datum,
|
||||
&isNull))
|
||||
elog(ERROR, "could not find junk \"%s\" column",
|
||||
erm->resname);
|
||||
|
||||
datum = ExecGetJunkAttribute(slot,
|
||||
erm->ctidAttNo,
|
||||
&isNull);
|
||||
/* shouldn't ever get a null result... */
|
||||
if (isNull)
|
||||
elog(ERROR, "\"%s\" is NULL", erm->resname);
|
||||
elog(ERROR, "ctid is NULL");
|
||||
|
||||
tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
|
||||
|
||||
|
Reference in New Issue
Block a user