diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execQual.c | 25 |
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; |