diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2009-11-04 22:26:08 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2009-11-04 22:26:08 +0000 |
commit | 9bedd128d6ed83798004b3c7ddc33f33703ccf23 (patch) | |
tree | 95a475a5da180f19c69b5bcf2f6e764b1bc69ea7 /src/backend/executor/execQual.c | |
parent | 48912acc089a6148529f12ab0a75b1bf026f231d (diff) | |
download | postgresql-9bedd128d6ed83798004b3c7ddc33f33703ccf23.tar.gz postgresql-9bedd128d6ed83798004b3c7ddc33f33703ccf23.zip |
Add support for invoking parser callback hooks via SPI and in cached plans.
As proof of concept, modify plpgsql to use the hooks. plpgsql is still
inserting $n symbols textually, but the "back end" of the parsing process now
goes through the ParamRef hook instead of using a fixed parameter-type array,
and then execution only fetches actually-referenced parameters, using a hook
added to ParamListInfo.
Although there's a lot left to be done in plpgsql, this already cures the
"if (TG_OP = 'INSERT' and NEW.foo ...)" problem, as illustrated by the
changed regression test.
Diffstat (limited to 'src/backend/executor/execQual.c')
-rw-r--r-- | src/backend/executor/execQual.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index fdfbd999f4f..226e15546fd 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.253 2009/10/26 02:26:29 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.254 2009/11/04 22:26:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -882,9 +882,21 @@ ExecEvalParam(ExprState *exprstate, ExprContext *econtext, { ParamExternData *prm = ¶mInfo->params[thisParamId - 1]; + /* give hook a chance in case parameter is dynamic */ + if (!OidIsValid(prm->ptype) && paramInfo->paramFetch != NULL) + (*paramInfo->paramFetch) (paramInfo, thisParamId); + if (OidIsValid(prm->ptype)) { - Assert(prm->ptype == expression->paramtype); + /* safety check in case hook did something unexpected */ + if (prm->ptype != expression->paramtype) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)", + thisParamId, + format_type_be(prm->ptype), + format_type_be(expression->paramtype)))); + *isNull = prm->isnull; return prm->value; } |