From 9bedd128d6ed83798004b3c7ddc33f33703ccf23 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 4 Nov 2009 22:26:08 +0000 Subject: 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. --- src/backend/executor/execCurrent.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/backend/executor/execCurrent.c') diff --git a/src/backend/executor/execCurrent.c b/src/backend/executor/execCurrent.c index a4103332c40..35dc05a52b8 100644 --- a/src/backend/executor/execCurrent.c +++ b/src/backend/executor/execCurrent.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/executor/execCurrent.c,v 1.12 2009/10/26 02:26:29 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execCurrent.c,v 1.13 2009/11/04 22:26:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -217,9 +217,21 @@ fetch_param_value(ExprContext *econtext, int paramId) { ParamExternData *prm = ¶mInfo->params[paramId - 1]; + /* give hook a chance in case parameter is dynamic */ + if (!OidIsValid(prm->ptype) && paramInfo->paramFetch != NULL) + (*paramInfo->paramFetch) (paramInfo, paramId); + if (OidIsValid(prm->ptype) && !prm->isnull) { - Assert(prm->ptype == REFCURSOROID); + /* safety check in case hook did something unexpected */ + if (prm->ptype != REFCURSOROID) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)", + paramId, + format_type_be(prm->ptype), + format_type_be(REFCURSOROID)))); + /* We know that refcursor uses text's I/O routines */ return TextDatumGetCString(prm->value); } -- cgit v1.2.3