diff options
Diffstat (limited to 'src/backend/executor/functions.c')
-rw-r--r-- | src/backend/executor/functions.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 296e54e60a4..db5191d3295 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -941,6 +941,7 @@ postquel_sub_params(SQLFunctionCachePtr fcache, if (nargs > 0) { ParamListInfo paramLI; + Oid *argtypes = fcache->pinfo->argtypes; if (fcache->paramLI == NULL) { @@ -957,10 +958,24 @@ postquel_sub_params(SQLFunctionCachePtr fcache, { ParamExternData *prm = ¶mLI->params[i]; - prm->value = fcinfo->args[i].value; + /* + * If an incoming parameter value is a R/W expanded datum, we + * force it to R/O. We'd be perfectly entitled to scribble on it, + * but the problem is that if the parameter is referenced more + * than once in the function, earlier references might mutate the + * value seen by later references, which won't do at all. We + * could do better if we could be sure of the number of Param + * nodes in the function's plans; but we might not have planned + * all the statements yet, nor do we have plan tree walker + * infrastructure. (Examining the parse trees is not good enough, + * because of possible function inlining during planning.) + */ prm->isnull = fcinfo->args[i].isnull; + prm->value = MakeExpandedObjectReadOnly(fcinfo->args[i].value, + prm->isnull, + get_typlen(argtypes[i])); prm->pflags = 0; - prm->ptype = fcache->pinfo->argtypes[i]; + prm->ptype = argtypes[i]; } } else |