@@ -3673,17 +3673,20 @@ ExecEvalJsonBehavior(ExprContext *econtext, JsonBehavior *behavior,
36733673 */
36743674static Datum
36753675ExecEvalJsonExprCoercion (ExprEvalStep * op , ExprContext * econtext ,
3676- Datum res , bool * isNull )
3676+ Datum res , bool * isNull , bool isJsonb )
36773677{
36783678 JsonExpr * jexpr = op -> d .jsonexpr .jsexpr ;
36793679 JsonCoercion * coercion = jexpr -> result_coercion ;
3680- Jsonb * jb = * isNull ? NULL : DatumGetJsonbP (res );
3680+ Jsonb * jb = * isNull || !isJsonb ? NULL : DatumGetJsonbP (res );
3681+ Json * js = * isNull || isJsonb ? NULL : DatumGetJsonP (res );
36813682
36823683 if ((coercion && coercion -> via_io ) ||
3683- (jexpr -> omit_quotes && !* isNull && JB_ROOT_IS_SCALAR (jb )))
3684+ (jexpr -> omit_quotes && !* isNull &&
3685+ (isJsonb ? JB_ROOT_IS_SCALAR (jb ) : JsonContainerIsScalar (& js -> root ))))
36843686 {
36853687 /* strip quotes and call typinput function */
3686- char * str = * isNull ? NULL : JsonbUnquote (jb );
3688+ char * str = * isNull ? NULL :
3689+ (isJsonb ? JsonbUnquote (jb ) : JsonUnquote (js ));
36873690
36883691 res = InputFunctionCall (& op -> d .jsonexpr .input .func , str ,
36893692 op -> d .jsonexpr .input .typioparam ,
@@ -3693,7 +3696,7 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
36933696 res = ExecEvalExprPassingCaseValue (op -> d .jsonexpr .result_expr , econtext ,
36943697 isNull , res , * isNull );
36953698 else if (coercion && coercion -> via_populate )
3696- res = json_populate_type (res , JSONBOID ,
3699+ res = json_populate_type (res , isJsonb ? JSONBOID : JSONOID ,
36973700 jexpr -> returning .typid ,
36983701 jexpr -> returning .typmod ,
36993702 & op -> d .jsonexpr .cache ,
@@ -3727,7 +3730,7 @@ EvalJsonPathVar(void *cxt, bool *isnull)
37273730 * corresponding SQL type and a pointer to the coercion state.
37283731 */
37293732Datum
3730- ExecPrepareJsonItemCoercion (JsonbValue * item ,
3733+ ExecPrepareJsonItemCoercion (JsonbValue * item , bool is_jsonb ,
37313734 JsonReturning * returning ,
37323735 struct JsonCoercionsState * coercions ,
37333736 struct JsonCoercionState * * pcoercion )
@@ -3736,8 +3739,14 @@ ExecPrepareJsonItemCoercion(JsonbValue *item,
37363739 Datum res ;
37373740 JsonbValue jbvbuf ;
37383741
3739- if (item -> type == jbvBinary && JsonContainerIsScalar (item -> val .binary .data ))
3740- item = JsonbExtractScalar (item -> val .binary .data , & jbvbuf );
3742+ if (item -> type == jbvBinary )
3743+ {
3744+ if (JsonContainerIsScalar (item -> val .binary .data ))
3745+ item = is_jsonb
3746+ ? JsonbExtractScalar (item -> val .binary .data , & jbvbuf )
3747+ : JsonExtractScalar ((JsonContainer * ) item -> val .binary .data ,
3748+ & jbvbuf );
3749+ }
37413750
37423751 /* get coercion state reference and datum of the corresponding SQL type */
37433752 switch (item -> type )
@@ -3794,7 +3803,18 @@ ExecPrepareJsonItemCoercion(JsonbValue *item,
37943803 case jbvObject :
37953804 case jbvBinary :
37963805 coercion = & coercions -> composite ;
3797- res = JsonbPGetDatum (JsonbValueToJsonb (item ));
3806+ if (is_jsonb )
3807+ {
3808+ Jsonb * jb = JsonbValueToJsonb (item );
3809+
3810+ res = JsonbPGetDatum (jb );
3811+ }
3812+ else
3813+ {
3814+ Json * js = JsonbValueToJson (item );
3815+
3816+ res = JsonPGetDatum (js );
3817+ }
37983818 break ;
37993819
38003820 default :
@@ -3809,7 +3829,8 @@ ExecPrepareJsonItemCoercion(JsonbValue *item,
38093829
38103830static Datum
38113831ExecEvalJsonExpr (ExprState * state , ExprEvalStep * op , ExprContext * econtext ,
3812- JsonExpr * jexpr , JsonPath * path , Datum item , bool * resnull )
3832+ JsonExpr * jexpr , JsonPath * path , Datum item , bool isjsonb ,
3833+ bool * resnull )
38133834{
38143835 bool empty = false;
38153836 Datum res = (Datum ) 0 ;
@@ -3823,7 +3844,8 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
38233844 if (isnull )
38243845 {
38253846 /* execute domain checks for NULLs */
3826- (void ) ExecEvalJsonExprCoercion (op , econtext , res , resnull );
3847+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , resnull ,
3848+ isjsonb );
38273849 * resnull = true;
38283850 return (Datum ) 0 ;
38293851 }
@@ -3832,23 +3854,23 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
38323854 switch (jexpr -> op )
38333855 {
38343856 case IS_JSON_QUERY :
3835- res = JsonbPathQuery ( item , path , jexpr -> wrapper , & empty ,
3836- op -> d .jsonexpr .args );
3857+ res = ( isjsonb ? JsonbPathQuery : JsonPathQuery )
3858+ ( item , path , jexpr -> wrapper , & empty , op -> d .jsonexpr .args );
38373859 * resnull = !DatumGetPointer (res );
38383860 break ;
38393861
38403862 case IS_JSON_VALUE :
38413863 {
3842- JsonbValue * jbv = JsonbPathValue ( item , path , & empty ,
3843- op -> d .jsonexpr .args );
3864+ JsonbValue * jbv = ( isjsonb ? JsonbPathValue : JsonPathValue )
3865+ ( item , path , & empty , op -> d .jsonexpr .args );
38443866 struct JsonCoercionState * jcstate ;
38453867
38463868 if (!jbv )
38473869 break ;
38483870
38493871 * resnull = false;
38503872
3851- res = ExecPrepareJsonItemCoercion (jbv ,
3873+ res = ExecPrepareJsonItemCoercion (jbv , isjsonb ,
38523874 & op -> d .jsonexpr .jsexpr -> returning ,
38533875 & op -> d .jsonexpr .coercions ,
38543876 & jcstate );
@@ -3861,8 +3883,11 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
38613883 jexpr -> returning .typid == JSONBOID )
38623884 {
38633885 /* use coercion via I/O from json[b] to the output type */
3864- res = JsonbPGetDatum (JsonbValueToJsonb (jbv ));
3865- res = ExecEvalJsonExprCoercion (op , econtext , res , resnull );
3886+ res = isjsonb
3887+ ? JsonbPGetDatum (JsonbValueToJsonb (jbv ))
3888+ : JsonPGetDatum (JsonbValueToJson (jbv ));
3889+ res = ExecEvalJsonExprCoercion (op , econtext , res ,
3890+ resnull , isjsonb );
38663891 }
38673892 else if (jcstate -> estate )
38683893 {
@@ -3876,7 +3901,8 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
38763901 break ;
38773902
38783903 case IS_JSON_EXISTS :
3879- res = BoolGetDatum (JsonbPathExists (item , path , op -> d .jsonexpr .args ));
3904+ res = BoolGetDatum ((isjsonb ? JsonbPathExists : JsonPathExists )
3905+ (item , path , op -> d .jsonexpr .args ));
38803906 * resnull = false;
38813907 break ;
38823908
@@ -3895,15 +3921,15 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
38953921
38963922 /* execute ON EMPTY behavior */
38973923 res = ExecEvalJsonBehavior (econtext , & jexpr -> on_empty ,
3898- op -> d .jsonexpr .default_on_empty , true,
3899- resnull );
3924+ op -> d .jsonexpr .default_on_empty ,
3925+ isjsonb , resnull );
39003926 }
39013927
39023928 if (jexpr -> op != IS_JSON_EXISTS &&
39033929 (!empty ? jexpr -> op != IS_JSON_VALUE :
39043930 /* result is already coerced in DEFAULT behavior case */
39053931 jexpr -> on_empty .btype != JSON_BEHAVIOR_DEFAULT ))
3906- res = ExecEvalJsonExprCoercion (op , econtext , res , resnull );
3932+ res = ExecEvalJsonExprCoercion (op , econtext , res , resnull , isjsonb );
39073933
39083934 return res ;
39093935}
@@ -3931,7 +3957,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39313957 if (op -> d .jsonexpr .raw_expr -> isnull || op -> d .jsonexpr .pathspec -> isnull )
39323958 {
39333959 /* execute domain checks for NULLs */
3934- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3960+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull , isjsonb );
39353961
39363962 Assert (* op -> resnull );
39373963 * op -> resnull = true;
@@ -3954,7 +3980,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39543980 if (jexpr -> on_error .btype == JSON_BEHAVIOR_ERROR )
39553981 {
39563982 /* No need to use PG_TRY/PG_CATCH. */
3957- res = ExecEvalJsonExpr (state , op , econtext , jexpr , path , item ,
3983+ res = ExecEvalJsonExpr (state , op , econtext , jexpr , path , item , isjsonb ,
39583984 op -> resnull );
39593985 }
39603986 else
@@ -3964,7 +3990,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39643990 PG_TRY ();
39653991 {
39663992 res = ExecEvalJsonExpr (state , op , econtext , jexpr , path , item ,
3967- op -> resnull );
3993+ isjsonb , op -> resnull );
39683994 }
39693995 PG_CATCH ();
39703996 {
@@ -3986,7 +4012,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39864012 if (jexpr -> op != IS_JSON_EXISTS &&
39874013 /* Result is already coerced in DEFAULT behavior case. */
39884014 jexpr -> on_error .btype != JSON_BEHAVIOR_DEFAULT )
3989- res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
4015+ res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
4016+ isjsonb );
39904017 }
39914018 PG_END_TRY ();
39924019 }
0 commit comments