Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit63e6c5f

Browse files
committed
SQL/JSON: Fix error-handling of some JsonBehavior expressions
To ensure that the errors of executing a JsonBehavior expression thatis coerced in the parser are caught instead of being thrown directly,pass ErrorSaveContext to ExecInitExprRec() when initializing it.Also, add a EEOP_JSONEXPR_COERCION_FINISH step to handle the errorsthat are caught that way.Discussion:https://postgr.es/m/CACJufxEo4sUjKCYtda0_qt9tazqqKPmF1cqhW9KBOUeJFqQd2g@mail.gmail.comBackpatch-through: 17
1 parentc7301c3 commit63e6c5f

File tree

4 files changed

+65
-4
lines changed

4 files changed

+65
-4
lines changed

‎src/backend/executor/execExpr.c

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4400,6 +4400,8 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
44004400
if (jsexpr->on_error&&
44014401
jsexpr->on_error->btype!=JSON_BEHAVIOR_ERROR)
44024402
{
4403+
ErrorSaveContext*saved_escontext;
4404+
44034405
jsestate->jump_error=state->steps_len;
44044406

44054407
/* JUMP to end if false, that is, skip the ON ERROR expression. */
@@ -4410,15 +4412,36 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
44104412
scratch->d.jump.jumpdone=-1;/* set below */
44114413
ExprEvalPushStep(state,scratch);
44124414

4413-
/* Steps to evaluate the ON ERROR expression */
4415+
/*
4416+
* Steps to evaluate the ON ERROR expression; handle errors softly to
4417+
* rethrow them in COERCION_FINISH step that will be added later.
4418+
*/
4419+
saved_escontext=state->escontext;
4420+
state->escontext=escontext;
44144421
ExecInitExprRec((Expr*)jsexpr->on_error->expr,
44154422
state,resv,resnull);
4423+
state->escontext=saved_escontext;
44164424

44174425
/* Step to coerce the ON ERROR expression if needed */
44184426
if (jsexpr->on_error->coerce)
44194427
ExecInitJsonCoercion(state,jsexpr->returning,escontext,
44204428
jsexpr->omit_quotes,resv,resnull);
44214429

4430+
/*
4431+
* Add a COERCION_FINISH step to check for errors that may occur when
4432+
* coercing and rethrow them.
4433+
*/
4434+
if (jsexpr->on_error->coerce||
4435+
IsA(jsexpr->on_error->expr,CoerceViaIO)||
4436+
IsA(jsexpr->on_error->expr,CoerceToDomain))
4437+
{
4438+
scratch->opcode=EEOP_JSONEXPR_COERCION_FINISH;
4439+
scratch->resvalue=resv;
4440+
scratch->resnull=resnull;
4441+
scratch->d.jsonexpr.jsestate=jsestate;
4442+
ExprEvalPushStep(state,scratch);
4443+
}
4444+
44224445
/* JUMP to end to skip the ON EMPTY steps added below. */
44234446
jumps_to_end=lappend_int(jumps_to_end,state->steps_len);
44244447
scratch->opcode=EEOP_JUMP;
@@ -4433,6 +4456,8 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
44334456
if (jsexpr->on_empty!=NULL&&
44344457
jsexpr->on_empty->btype!=JSON_BEHAVIOR_ERROR)
44354458
{
4459+
ErrorSaveContext*saved_escontext;
4460+
44364461
jsestate->jump_empty=state->steps_len;
44374462

44384463
/* JUMP to end if false, that is, skip the ON EMPTY expression. */
@@ -4443,14 +4468,36 @@ ExecInitJsonExpr(JsonExpr *jsexpr, ExprState *state,
44434468
scratch->d.jump.jumpdone=-1;/* set below */
44444469
ExprEvalPushStep(state,scratch);
44454470

4446-
/* Steps to evaluate the ON EMPTY expression */
4471+
/*
4472+
* Steps to evaluate the ON EMPTY expression; handle errors softly to
4473+
* rethrow them in COERCION_FINISH step that will be added later.
4474+
*/
4475+
saved_escontext=state->escontext;
4476+
state->escontext=escontext;
44474477
ExecInitExprRec((Expr*)jsexpr->on_empty->expr,
44484478
state,resv,resnull);
4479+
state->escontext=saved_escontext;
44494480

44504481
/* Step to coerce the ON EMPTY expression if needed */
44514482
if (jsexpr->on_empty->coerce)
44524483
ExecInitJsonCoercion(state,jsexpr->returning,escontext,
44534484
jsexpr->omit_quotes,resv,resnull);
4485+
4486+
/*
4487+
* Add a COERCION_FINISH step to check for errors that may occur when
4488+
* coercing and rethrow them.
4489+
*/
4490+
if (jsexpr->on_empty->coerce||
4491+
IsA(jsexpr->on_empty->expr,CoerceViaIO)||
4492+
IsA(jsexpr->on_empty->expr,CoerceToDomain))
4493+
{
4494+
4495+
scratch->opcode=EEOP_JSONEXPR_COERCION_FINISH;
4496+
scratch->resvalue=resv;
4497+
scratch->resnull=resnull;
4498+
scratch->d.jsonexpr.jsestate=jsestate;
4499+
ExprEvalPushStep(state,scratch);
4500+
}
44544501
}
44554502

44564503
foreach(lc,jumps_to_end)

‎src/backend/executor/execExprInterp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4558,6 +4558,12 @@ ExecEvalJsonCoercionFinish(ExprState *state, ExprEvalStep *op)
45584558
*op->resvalue= (Datum)0;
45594559
*op->resnull= true;
45604560
jsestate->error.value=BoolGetDatum(true);
4561+
4562+
/*
4563+
* Reset for next use such as for catching errors when coercing a
4564+
* JsonBehavior expression.
4565+
*/
4566+
jsestate->escontext.error_occurred= false;
45614567
}
45624568
}
45634569

‎src/test/regress/expected/sqljson_jsontable.out

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,11 @@ SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$'
227227

228228
SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$'
229229
COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT 'foo'::jsonb_test_domain ON EMPTY));
230-
ERROR: value for domain jsonb_test_domain violates check constraint "jsonb_test_domain_check"
230+
js1
231+
-----
232+
233+
(1 row)
234+
231235
SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$'
232236
COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT 'foo1'::jsonb_test_domain ON EMPTY));
233237
js1

‎src/test/regress/expected/sqljson_queryfuncs.out

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,11 @@ DROP TABLE test_jsonb_mutability;
12321232
DROP FUNCTION ret_setint;
12331233
CREATE DOMAIN queryfuncs_test_domain AS text CHECK (value <> 'foo');
12341234
SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo'::queryfuncs_test_domain ON EMPTY);
1235-
ERROR: value for domain queryfuncs_test_domain violates check constraint "queryfuncs_test_domain_check"
1235+
json_value
1236+
------------
1237+
1238+
(1 row)
1239+
12361240
SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo1'::queryfuncs_test_domain ON EMPTY);
12371241
json_value
12381242
------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp