From 618b48991d5239eb924070b0357c5208a9d1ca5c Mon Sep 17 00:00:00 2001 From: jian he Date: Fri, 26 Jul 2024 21:15:41 +0800 Subject: [PATCH v2 1/1] save some circle in ExecInitJsonExpr if returning type is not domain and on_error->btype is JSON_BEHAVIOR_NULL or if returning type is not domain and on_empty->btype is JSON_BEHAVIOR_NULL --- src/backend/executor/execExpr.c | 139 +++++++++++++++++--------------- 1 file changed, 75 insertions(+), 64 deletions(-) diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index 3c4e503b..48324e98 100644 --- a/src/backend/executor/execExpr.c +++ b/src/backend/executor/execExpr.c @@ -4237,6 +4237,8 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state, jsexpr->on_error->btype != JSON_BEHAVIOR_ERROR ? &jsestate->escontext : NULL; + bool returning_is_domain = + get_typtype(jsexpr->returning->typid) == TYPTYPE_DOMAIN; jsestate->jsexpr = jsexpr; /* @@ -4388,8 +4390,6 @@ 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. */ @@ -4400,42 +4400,46 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state, scratch->d.jump.jumpdone = -1; /* set below */ ExprEvalPushStep(state, scratch); - /* - * 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, false, - 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)) + if (returning_is_domain || jsexpr->on_error->btype != JSON_BEHAVIOR_NULL) { - scratch->opcode = EEOP_JSONEXPR_COERCION_FINISH; - scratch->resvalue = resv; - scratch->resnull = resnull; - scratch->d.jsonexpr.jsestate = jsestate; + ErrorSaveContext *saved_escontext; + /* + * 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, false, + 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; + scratch->d.jump.jumpdone = -1; 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; - scratch->d.jump.jumpdone = -1; - ExprEvalPushStep(state, scratch); } /* @@ -4445,8 +4449,6 @@ 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. */ @@ -4458,35 +4460,44 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state, ExprEvalPushStep(state, scratch); /* - * 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, false, - 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)) + * only json_query, json_value can set on_empty if on_empty is default + * JSON_BEHAVIOR_NULL, the above EEOP_JUMP_IF_NOT_TRUE action is enough. + * but domain can have not null, so we still need coercion steps. + */ + if (returning_is_domain || jsexpr->on_empty->btype != JSON_BEHAVIOR_NULL) { + ErrorSaveContext *saved_escontext; + /* + * 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; - scratch->opcode = EEOP_JSONEXPR_COERCION_FINISH; - scratch->resvalue = resv; - scratch->resnull = resnull; - scratch->d.jsonexpr.jsestate = jsestate; - ExprEvalPushStep(state, scratch); + /* Step to coerce the ON EMPTY expression if needed */ + if (jsexpr->on_empty->coerce) + ExecInitJsonCoercion(state, jsexpr->returning, escontext, + jsexpr->omit_quotes, false, + 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); + } } } -- 2.34.1