diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-12-04 02:06:55 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-12-04 02:06:55 +0000 |
commit | 8dcc8e376149adcfba012a9e9b7b0692bcbff9a2 (patch) | |
tree | be2c6c7978e6a041ee7a0b70bbd833d391108500 /src/backend/executor/execMain.c | |
parent | 406d028a9bb1a531d8e413918709f8d99f5c7783 (diff) | |
download | postgresql-8dcc8e376149adcfba012a9e9b7b0692bcbff9a2.tar.gz postgresql-8dcc8e376149adcfba012a9e9b7b0692bcbff9a2.zip |
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 ...
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r-- | src/backend/executor/execMain.c | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 5e5ca085ba4..6db354cd4f9 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -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)); |