aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/functions.c')
-rw-r--r--src/backend/executor/functions.c19
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 = &paramLI->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