aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execQual.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 743e7d636a0..ab09691fb20 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -2992,12 +2992,18 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
if (caseExpr->arg)
{
+ Datum arg_value;
bool arg_isNull;
- econtext->caseValue_datum = ExecEvalExpr(caseExpr->arg,
- econtext,
- &arg_isNull,
- NULL);
+ arg_value = ExecEvalExpr(caseExpr->arg,
+ econtext,
+ &arg_isNull,
+ NULL);
+ /* Since caseValue_datum may be read multiple times, force to R/O */
+ econtext->caseValue_datum =
+ MakeExpandedObjectReadOnly(arg_value,
+ arg_isNull,
+ caseExpr->argtyplen);
econtext->caseValue_isNull = arg_isNull;
}
@@ -4127,11 +4133,18 @@ ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
* nodes. We must save and restore prior setting of
* econtext's domainValue fields, in case this node is
* itself within a check expression for another domain.
+ *
+ * Also, if we are working with a read-write expanded
+ * datum, be sure that what we pass to CHECK expressions
+ * is a read-only pointer; else called functions might
+ * modify or even delete the expanded object.
*/
save_datum = econtext->domainValue_datum;
save_isNull = econtext->domainValue_isNull;
- econtext->domainValue_datum = result;
+ econtext->domainValue_datum =
+ MakeExpandedObjectReadOnly(result, *isNull,
+ cstate->constraint_ref->tcache->typlen);
econtext->domainValue_isNull = *isNull;
conResult = ExecEvalExpr(con->check_expr,
@@ -4939,6 +4952,8 @@ ExecInitExpr(Expr *node, PlanState *parent)
}
cstate->args = outlist;
cstate->defresult = ExecInitExpr(caseexpr->defresult, parent);
+ if (caseexpr->arg)
+ cstate->argtyplen = get_typlen(exprType((Node *) caseexpr->arg));
state = (ExprState *) cstate;
}
break;