diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execExpr.c | 28 | ||||
-rw-r--r-- | src/backend/executor/execExprInterp.c | 36 |
2 files changed, 28 insertions, 36 deletions
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index 2c62b0c9c84..f6780bbf52c 100644 --- a/src/backend/executor/execExpr.c +++ b/src/backend/executor/execExpr.c @@ -139,6 +139,7 @@ ExecInitExpr(Expr *node, PlanState *parent) state->expr = node; state->parent = parent; state->ext_params = NULL; + state->escontext = NULL; /* Insert setup steps as needed */ ExecCreateExprSetupSteps(state, (Node *) node); @@ -176,6 +177,7 @@ ExecInitExprWithParams(Expr *node, ParamListInfo ext_params) state->expr = node; state->parent = NULL; state->ext_params = ext_params; + state->escontext = NULL; /* Insert setup steps as needed */ ExecCreateExprSetupSteps(state, (Node *) node); @@ -228,6 +230,7 @@ ExecInitQual(List *qual, PlanState *parent) state->expr = (Expr *) qual; state->parent = parent; state->ext_params = NULL; + state->escontext = NULL; /* mark expression as to be used with ExecQual() */ state->flags = EEO_FLAG_IS_QUAL; @@ -373,6 +376,7 @@ ExecBuildProjectionInfo(List *targetList, state->expr = (Expr *) targetList; state->parent = parent; state->ext_params = NULL; + state->escontext = NULL; state->resultslot = slot; @@ -544,6 +548,7 @@ ExecBuildUpdateProjection(List *targetList, state->expr = NULL; /* not used */ state->parent = parent; state->ext_params = NULL; + state->escontext = NULL; state->resultslot = slot; @@ -1549,8 +1554,6 @@ ExecInitExprRec(Expr *node, ExprState *state, CoerceViaIO *iocoerce = (CoerceViaIO *) node; Oid iofunc; bool typisvarlena; - Oid typioparam; - FunctionCallInfo fcinfo_in; /* evaluate argument into step's result area */ ExecInitExprRec(iocoerce->arg, state, resv, resnull); @@ -1579,25 +1582,13 @@ ExecInitExprRec(Expr *node, ExprState *state, /* lookup the result type's input function */ scratch.d.iocoerce.finfo_in = palloc0(sizeof(FmgrInfo)); - scratch.d.iocoerce.fcinfo_data_in = palloc0(SizeForFunctionCallInfo(3)); - getTypeInputInfo(iocoerce->resulttype, - &iofunc, &typioparam); + &iofunc, &scratch.d.iocoerce.typioparam); fmgr_info(iofunc, scratch.d.iocoerce.finfo_in); fmgr_info_set_expr((Node *) node, scratch.d.iocoerce.finfo_in); - InitFunctionCallInfoData(*scratch.d.iocoerce.fcinfo_data_in, - scratch.d.iocoerce.finfo_in, - 3, InvalidOid, NULL, NULL); - /* - * We can preload the second and third arguments for the input - * function, since they're constants. - */ - fcinfo_in = scratch.d.iocoerce.fcinfo_data_in; - fcinfo_in->args[1].value = ObjectIdGetDatum(typioparam); - fcinfo_in->args[1].isnull = false; - fcinfo_in->args[2].value = Int32GetDatum(-1); - fcinfo_in->args[2].isnull = false; + /* Set ErrorSaveContext if passed by the caller. */ + scratch.d.iocoerce.escontext = state->escontext; ExprEvalPushStep(state, &scratch); break; @@ -1628,6 +1619,7 @@ ExecInitExprRec(Expr *node, ExprState *state, elemstate->expr = acoerce->elemexpr; elemstate->parent = state->parent; elemstate->ext_params = state->ext_params; + state->escontext = NULL; elemstate->innermost_caseval = (Datum *) palloc(sizeof(Datum)); elemstate->innermost_casenull = (bool *) palloc(sizeof(bool)); @@ -3306,6 +3298,8 @@ ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest, /* we'll allocate workspace only if needed */ scratch->d.domaincheck.checkvalue = NULL; scratch->d.domaincheck.checknull = NULL; + /* Set ErrorSaveContext if passed by the caller. */ + scratch->d.domaincheck.escontext = state->escontext; /* * Evaluate argument - it's fine to directly store it into resv/resnull, diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index 24c2b60c62a..e55fd10e3b8 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -1177,29 +1177,27 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) /* call input function (similar to InputFunctionCall) */ if (!op->d.iocoerce.finfo_in->fn_strict || str != NULL) { - FunctionCallInfo fcinfo_in; - Datum d; + bool error; - fcinfo_in = op->d.iocoerce.fcinfo_data_in; - fcinfo_in->args[0].value = PointerGetDatum(str); - fcinfo_in->args[0].isnull = *op->resnull; - /* second and third arguments are already set up */ - - fcinfo_in->isnull = false; - d = FunctionCallInvoke(fcinfo_in); - *op->resvalue = d; + /* + * InputFunctionCallSafe() writes directly into *op->resvalue. + * Return NULL if an error is reported. + */ + error = !InputFunctionCallSafe(op->d.iocoerce.finfo_in, str, + op->d.iocoerce.typioparam, -1, + (Node *) op->d.iocoerce.escontext, + op->resvalue); + if (error) + *op->resnull = true; - /* Should get null result if and only if str is NULL */ - if (str == NULL) - { + /* + * Should get null result if and only if str is NULL or if we + * got an error above. + */ + if (str == NULL || error) Assert(*op->resnull); - Assert(fcinfo_in->isnull); - } else - { Assert(!*op->resnull); - Assert(!fcinfo_in->isnull); - } } EEO_NEXT(); @@ -3745,7 +3743,7 @@ ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op) { if (!*op->d.domaincheck.checknull && !DatumGetBool(*op->d.domaincheck.checkvalue)) - ereport(ERROR, + errsave((Node *) op->d.domaincheck.escontext, (errcode(ERRCODE_CHECK_VIOLATION), errmsg("value for domain %s violates check constraint \"%s\"", format_type_be(op->d.domaincheck.resulttype), |