Hi. based on v22. I added some tests again json_value for the sake of coverager test.
A previous email thread mentioned needing to check *empty in ExecEvalJsonExpr. since JSON_VALUE_OP, JSON_QUERY_OP, JSON_EXISTS_OP all need to have *empty cases, So I refactored a little bit. might be helpful. Maybe we can also refactor *error cases. The following part is not easy to understand. res = ExecPrepareJsonItemCoercion(jbv, + jsestate->item_jcstates, + &post_eval->jcstate); + if (post_eval->jcstate && + post_eval->jcstate->coercion && + (post_eval->jcstate->coercion->via_io || + post_eval->jcstate->coercion->via_populate))
From 439f98ae55e6f67ca6c5bf023c6e9ab2796f4c49 Mon Sep 17 00:00:00 2001 From: pgaddict <jian.universal...@gmail.com> Date: Wed, 18 Oct 2023 10:12:33 +0800 Subject: [PATCH v22 1/1] add some test, refactor ExecEvalJsonExpr add some tests again json_value for code coverage. refactor ExecEvalJsonExpr, let JSON_VALUE_OP, JSON_QUERY_OP, JSON_EXISTS_OP handle *empty in a common way. --- src/backend/executor/execExprInterp.c | 41 +++++++++------------ src/test/regress/expected/jsonb_sqljson.out | 36 ++++++++++++++++++ src/test/regress/sql/jsonb_sqljson.sql | 6 +++ 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index 123121a9..1a1f2089 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -4218,7 +4218,8 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext) *op->resvalue = (Datum) 0; return; } - + if(*empty) + goto return_empty; resnull = false; res = BoolGetDatum(exists); break; @@ -4236,7 +4237,10 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext) *op->resvalue = (Datum) 0; return; } + if (*empty) + goto return_empty; resnull = !DatumGetPointer(res); + break; case JSON_VALUE_OP: @@ -4253,15 +4257,14 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext) *op->resvalue = (Datum) 0; return; } - - if (!jbv) /* NULL or empty */ + if (*empty) + goto return_empty; + if (!jbv) /* NULL */ { resnull = true; + res = (Datum) 0; break; } - - Assert(!*empty); - resnull = false; /* Coerce scalar item to the output type */ @@ -4322,31 +4325,23 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext) return; } + *op->resvalue = res; + *op->resnull = resnull; + return; /* * If the ON EMPTY behavior is to cause an error, do so here. Other * behaviors will be handled in ExecEvalJsonExprBehavior(). */ - if (*empty) - { - Assert(jexpr->on_empty); /* it is not JSON_EXISTS */ - - if (jexpr->on_empty->btype == JSON_BEHAVIOR_ERROR) +return_empty: + Assert(jexpr->on_empty); + *op->resnull = true; + *op->resvalue = (Datum) 0; + if (jexpr->on_empty->btype == JSON_BEHAVIOR_ERROR && throw_error) { - if (!throw_error) - { - *op->resnull = true; - *op->resvalue = (Datum) 0; - return; - } - ereport(ERROR, (errcode(ERRCODE_NO_SQL_JSON_ITEM), errmsg("no SQL/JSON item"))); } - } - - *op->resvalue = res; - *op->resnull = resnull; } /* @@ -4467,7 +4462,7 @@ ExecEvalJsonExprCoercion(ExprState *state, ExprEvalStep *op, { Jsonb *jb = resnull ? NULL : DatumGetJsonbP(res); - if (jb && JB_ROOT_IS_SCALAR(jb)) + if (jb) { omit_quotes = true; val_string = JsonbUnquote(jb); diff --git a/src/test/regress/expected/jsonb_sqljson.out b/src/test/regress/expected/jsonb_sqljson.out index a3ba44cf..0526ff00 100644 --- a/src/test/regress/expected/jsonb_sqljson.out +++ b/src/test/regress/expected/jsonb_sqljson.out @@ -512,6 +512,42 @@ SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 + Tue Feb 20 18:34:56 2018 PST (1 row) +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamp '2018-02-21 12:34:56 +10' AS ts); + json_value +-------------------------- + Wed Feb 21 12:34:56 2018 +(1 row) + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamp(3) '2018-02-21 12:34:56.123456 +10' AS ts); + json_value +------------------------------ + Wed Feb 21 12:34:56.123 2018 +(1 row) + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz(3) '2018-02-21 12:34:56.123456 +10' AS ts); + json_value +---------------------------------- + Tue Feb 20 18:34:56.123 2018 PST +(1 row) + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING date '2018-02-21 12:34:56 +10' AS ts); + json_value +------------ + 02-21-2018 +(1 row) + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING time '2018-02-21 12:34:56 +10' AS ts); + json_value +------------ + 12:34:56 +(1 row) + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timetz '2018-02-21 12:34:56 +10' AS ts); + json_value +------------- + 12:34:56+10 +(1 row) + SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING timestamptz); json_value ------------------------------ diff --git a/src/test/regress/sql/jsonb_sqljson.sql b/src/test/regress/sql/jsonb_sqljson.sql index ab73a011..e28be0a2 100644 --- a/src/test/regress/sql/jsonb_sqljson.sql +++ b/src/test/regress/sql/jsonb_sqljson.sql @@ -138,6 +138,12 @@ SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a RETURNING poi -- Test timestamptz passing and output SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts); +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamp '2018-02-21 12:34:56 +10' AS ts); +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamp(3) '2018-02-21 12:34:56.123456 +10' AS ts); +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz(3) '2018-02-21 12:34:56.123456 +10' AS ts); +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING date '2018-02-21 12:34:56 +10' AS ts); +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING time '2018-02-21 12:34:56 +10' AS ts); +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timetz '2018-02-21 12:34:56 +10' AS ts); SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING timestamptz); SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING timestamp); SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING json); -- 2.34.1