@@ -3673,16 +3673,19 @@ 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 ;
3679- Jsonb * jb = * isNull ? NULL : DatumGetJsonbP (res );
3679+ Jsonb * jb = * isNull || !isJsonb ? NULL : DatumGetJsonbP (res );
3680+ Json * js = * isNull || isJsonb ? NULL : DatumGetJsonP (res );
36803681
36813682 if (jexpr -> coerce_via_io ||
3682- (jexpr -> omit_quotes && !* isNull && JB_ROOT_IS_SCALAR (jb )))
3683+ (jexpr -> omit_quotes && !* isNull &&
3684+ (isJsonb ? JB_ROOT_IS_SCALAR (jb ) : JsonContainerIsScalar (& js -> root ))))
36833685 {
36843686 /* strip quotes and call typinput function */
3685- char * str = * isNull ? NULL : JsonbUnquote (jb );
3687+ char * str = * isNull ? NULL :
3688+ (isJsonb ? JsonbUnquote (jb ) : JsonUnquote (js ));
36863689
36873690 res = InputFunctionCall (& op -> d .jsonexpr .input .func , str ,
36883691 op -> d .jsonexpr .input .typioparam ,
@@ -3692,7 +3695,7 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
36923695 res = ExecEvalExprPassingCaseValue (op -> d .jsonexpr .result_expr , econtext ,
36933696 isNull , res , * isNull );
36943697 else if (jexpr -> coerce_via_populate )
3695- res = json_populate_type (res , JSONBOID ,
3698+ res = json_populate_type (res , isJsonb ? JSONBOID : JSONOID ,
36963699 jexpr -> returning .typid ,
36973700 jexpr -> returning .typmod ,
36983701 & op -> d .jsonexpr .cache ,
@@ -3726,7 +3729,8 @@ EvalJsonPathVar(void *cxt, bool *isnull)
37263729 * corresponding SQL type and a pointer to the coercion state.
37273730 */
37283731Datum
3729- ExecPrepareJsonItemCoercion (JsonbValue * item , JsonReturning * returning ,
3732+ ExecPrepareJsonItemCoercion (JsonbValue * item , bool is_jsonb ,
3733+ JsonReturning * returning ,
37303734 struct JsonScalarCoercions * coercions ,
37313735 MemoryContext mcxt ,
37323736 struct JsonScalarCoercionExprState * * pcestate )
@@ -3736,8 +3740,14 @@ ExecPrepareJsonItemCoercion(JsonbValue *item, JsonReturning *returning,
37363740 Oid typid ;
37373741 JsonbValue jbvbuf ;
37383742
3739- if (item -> type == jbvBinary && JsonContainerIsScalar (item -> val .binary .data ))
3740- item = JsonbExtractScalar (item -> val .binary .data , & jbvbuf );
3743+ if (item -> type == jbvBinary )
3744+ {
3745+ if (JsonContainerIsScalar (item -> val .binary .data ))
3746+ item = is_jsonb
3747+ ? JsonbExtractScalar (item -> val .binary .data , & jbvbuf )
3748+ : JsonExtractScalar ((JsonContainer * ) item -> val .binary .data ,
3749+ & jbvbuf );
3750+ }
37413751
37423752 /* get coercion state reference and datum of the corresponding SQL type */
37433753 switch (item -> type )
@@ -3799,8 +3809,20 @@ ExecPrepareJsonItemCoercion(JsonbValue *item, JsonReturning *returning,
37993809 case jbvObject :
38003810 case jbvBinary :
38013811 cestate = & coercions -> composite ;
3802- res = JsonbPGetDatum (JsonbValueToJsonb (item ));
3803- typid = JSONBOID ;
3812+ if (is_jsonb )
3813+ {
3814+ Jsonb * jb = JsonbValueToJsonb (item );
3815+
3816+ res = JsonbPGetDatum (jb );
3817+ typid = JSONBOID ;
3818+ }
3819+ else
3820+ {
3821+ Json * js = JsonbValueToJson (item );
3822+
3823+ res = JsonPGetDatum (js );
3824+ typid = JSONOID ;
3825+ }
38043826 break ;
38053827
38063828 default :
@@ -3871,7 +3893,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
38713893 if (op -> d .jsonexpr .raw_expr -> isnull )
38723894 {
38733895 /* execute domain checks for NULLs */
3874- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3896+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull , isjsonb );
38753897 return ;
38763898 }
38773899
@@ -3901,31 +3923,32 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39013923 if (isnull )
39023924 {
39033925 /* execute domain checks for NULLs */
3904- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3926+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
3927+ isjsonb );
39053928 return ;
39063929 }
39073930 }
39083931
39093932 switch (jexpr -> op )
39103933 {
39113934 case IS_JSON_QUERY :
3912- res = JsonbPathQuery ( item , path , jexpr -> wrapper , & empty ,
3913- op -> d .jsonexpr .args );
3935+ res = ( isjsonb ? JsonbPathQuery : JsonPathQuery )
3936+ ( item , path , jexpr -> wrapper , & empty , op -> d .jsonexpr .args );
39143937 * op -> resnull = !DatumGetPointer (res );
39153938 break ;
39163939
39173940 case IS_JSON_VALUE :
39183941 {
3919- JsonbValue * jbv = JsonbPathValue ( item , path , & empty ,
3920- op -> d .jsonexpr .args );
3942+ JsonbValue * jbv = ( isjsonb ? JsonbPathValue : JsonPathValue )
3943+ ( item , path , & empty , op -> d .jsonexpr .args );
39213944 struct JsonScalarCoercionExprState * cestate ;
39223945
39233946 if (!jbv )
39243947 break ;
39253948
39263949 * op -> resnull = false;
39273950
3928- res = ExecPrepareJsonItemCoercion (jbv ,
3951+ res = ExecPrepareJsonItemCoercion (jbv , isjsonb ,
39293952 & op -> d .jsonexpr .jsexpr -> returning ,
39303953 & op -> d .jsonexpr .scalar ,
39313954 econtext -> ecxt_per_query_memory ,
@@ -3938,9 +3961,11 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39383961 jexpr -> returning .typid == JSONBOID )
39393962 {
39403963 /* use coercion from json[b] to the output type */
3941- res = JsonbPGetDatum (JsonbValueToJsonb (jbv ));
3942- res = ExecEvalJsonExprCoercion (op , econtext ,
3943- res , op -> resnull );
3964+ res = isjsonb
3965+ ? JsonbPGetDatum (JsonbValueToJsonb (jbv ))
3966+ : JsonPGetDatum (JsonbValueToJson (jbv ));
3967+ res = ExecEvalJsonExprCoercion (op , econtext , res ,
3968+ op -> resnull , isjsonb );
39443969 }
39453970 else if (cestate -> result_expr_state )
39463971 {
@@ -3954,8 +3979,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39543979 break ;
39553980
39563981 case IS_JSON_EXISTS :
3957- res = BoolGetDatum (JsonbPathExists ( item , path ,
3958- op -> d .jsonexpr .args ));
3982+ res = BoolGetDatum (( isjsonb ? JsonbPathExists : JsonPathExists )
3983+ ( item , path , op -> d .jsonexpr .args ));
39593984 * op -> resnull = false;
39603985 break ;
39613986
@@ -3982,7 +4007,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39824007 (!empty ? jexpr -> op != IS_JSON_VALUE :
39834008 /* result is already coerced in DEFAULT behavior case */
39844009 jexpr -> on_empty .btype != JSON_BEHAVIOR_DEFAULT ))
3985- res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
4010+ res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
4011+ isjsonb );
39864012 }
39874013 PG_CATCH ();
39884014 {
@@ -4001,7 +4027,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
40014027 if (jexpr -> op != IS_JSON_EXISTS &&
40024028 /* result is already coerced in DEFAULT behavior case */
40034029 jexpr -> on_error .btype != JSON_BEHAVIOR_DEFAULT )
4004- res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
4030+ res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
4031+ isjsonb );
40054032 }
40064033 PG_END_TRY ();
40074034
0 commit comments