summaryrefslogtreecommitdiff
path: root/src/backend/executor/execQual.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execQual.c')
-rw-r--r--src/backend/executor/execQual.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index c0ca58bbb4d..01e04d3b14e 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -5350,15 +5350,24 @@ ExecCleanTargetListLength(List *targetlist)
* of *isDone = ExprMultipleResult signifies a set element, and a return
* of *isDone = ExprEndResult signifies end of the set of tuple.
* We assume that *isDone has been initialized to ExprSingleResult by caller.
+ *
+ * Since fields of the result tuple might be multiply referenced in higher
+ * plan nodes, we have to force any read/write expanded values to read-only
+ * status. It's a bit annoying to have to do that for every projected
+ * expression; in the future, consider teaching the planner to detect
+ * actually-multiply-referenced Vars and insert an expression node that
+ * would do that only where really required.
*/
static bool
ExecTargetList(List *targetlist,
+ TupleDesc tupdesc,
ExprContext *econtext,
Datum *values,
bool *isnull,
ExprDoneCond *itemIsDone,
ExprDoneCond *isDone)
{
+ Form_pg_attribute *att = tupdesc->attrs;
MemoryContext oldContext;
ListCell *tl;
bool haveDoneSets;
@@ -5384,6 +5393,10 @@ ExecTargetList(List *targetlist,
&isnull[resind],
&itemIsDone[resind]);
+ values[resind] = MakeExpandedObjectReadOnly(values[resind],
+ isnull[resind],
+ att[resind]->attlen);
+
if (itemIsDone[resind] != ExprSingleResult)
{
/* We have a set-valued expression in the tlist */
@@ -5437,6 +5450,10 @@ ExecTargetList(List *targetlist,
&isnull[resind],
&itemIsDone[resind]);
+ values[resind] = MakeExpandedObjectReadOnly(values[resind],
+ isnull[resind],
+ att[resind]->attlen);
+
if (itemIsDone[resind] == ExprEndResult)
{
/*
@@ -5470,6 +5487,7 @@ ExecTargetList(List *targetlist,
econtext,
&isnull[resind],
&itemIsDone[resind]);
+ /* no need for MakeExpandedObjectReadOnly */
}
}
@@ -5595,6 +5613,7 @@ ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
if (projInfo->pi_targetlist)
{
if (!ExecTargetList(projInfo->pi_targetlist,
+ slot->tts_tupleDescriptor,
econtext,
slot->tts_values,
slot->tts_isnull,