aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execExpr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execExpr.c')
-rw-r--r--src/backend/executor/execExpr.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index ccd48637784..b10359e3d6b 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -4400,6 +4400,8 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
if (jsexpr->on_error &&
jsexpr->on_error->btype != JSON_BEHAVIOR_ERROR)
{
+ ErrorSaveContext *saved_escontext;
+
jsestate->jump_error = state->steps_len;
/* JUMP to end if false, that is, skip the ON ERROR expression. */
@@ -4410,15 +4412,36 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
scratch->d.jump.jumpdone = -1; /* set below */
ExprEvalPushStep(state, scratch);
- /* Steps to evaluate the ON ERROR expression */
+ /*
+ * Steps to evaluate the ON ERROR expression; handle errors softly to
+ * rethrow them in COERCION_FINISH step that will be added later.
+ */
+ saved_escontext = state->escontext;
+ state->escontext = escontext;
ExecInitExprRec((Expr *) jsexpr->on_error->expr,
state, resv, resnull);
+ state->escontext = saved_escontext;
/* Step to coerce the ON ERROR expression if needed */
if (jsexpr->on_error->coerce)
ExecInitJsonCoercion(state, jsexpr->returning, escontext,
jsexpr->omit_quotes, resv, resnull);
+ /*
+ * Add a COERCION_FINISH step to check for errors that may occur when
+ * coercing and rethrow them.
+ */
+ if (jsexpr->on_error->coerce ||
+ IsA(jsexpr->on_error->expr, CoerceViaIO) ||
+ IsA(jsexpr->on_error->expr, CoerceToDomain))
+ {
+ scratch->opcode = EEOP_JSONEXPR_COERCION_FINISH;
+ scratch->resvalue = resv;
+ scratch->resnull = resnull;
+ scratch->d.jsonexpr.jsestate = jsestate;
+ ExprEvalPushStep(state, scratch);
+ }
+
/* JUMP to end to skip the ON EMPTY steps added below. */
jumps_to_end = lappend_int(jumps_to_end, state->steps_len);
scratch->opcode = EEOP_JUMP;
@@ -4433,6 +4456,8 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
if (jsexpr->on_empty != NULL &&
jsexpr->on_empty->btype != JSON_BEHAVIOR_ERROR)
{
+ ErrorSaveContext *saved_escontext;
+
jsestate->jump_empty = state->steps_len;
/* JUMP to end if false, that is, skip the ON EMPTY expression. */
@@ -4443,14 +4468,36 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
scratch->d.jump.jumpdone = -1; /* set below */
ExprEvalPushStep(state, scratch);
- /* Steps to evaluate the ON EMPTY expression */
+ /*
+ * Steps to evaluate the ON EMPTY expression; handle errors softly to
+ * rethrow them in COERCION_FINISH step that will be added later.
+ */
+ saved_escontext = state->escontext;
+ state->escontext = escontext;
ExecInitExprRec((Expr *) jsexpr->on_empty->expr,
state, resv, resnull);
+ state->escontext = saved_escontext;
/* Step to coerce the ON EMPTY expression if needed */
if (jsexpr->on_empty->coerce)
ExecInitJsonCoercion(state, jsexpr->returning, escontext,
jsexpr->omit_quotes, resv, resnull);
+
+ /*
+ * Add a COERCION_FINISH step to check for errors that may occur when
+ * coercing and rethrow them.
+ */
+ if (jsexpr->on_empty->coerce ||
+ IsA(jsexpr->on_empty->expr, CoerceViaIO) ||
+ IsA(jsexpr->on_empty->expr, CoerceToDomain))
+ {
+
+ scratch->opcode = EEOP_JSONEXPR_COERCION_FINISH;
+ scratch->resvalue = resv;
+ scratch->resnull = resnull;
+ scratch->d.jsonexpr.jsestate = jsestate;
+ ExprEvalPushStep(state, scratch);
+ }
}
foreach(lc, jumps_to_end)