@@ -3722,16 +3722,19 @@ ExecEvalJsonBehavior(ExprContext *econtext, JsonBehavior *behavior,
37223722 */
37233723static Datum
37243724ExecEvalJsonExprCoercion (ExprEvalStep * op , ExprContext * econtext ,
3725- Datum res , bool * isNull )
3725+ Datum res , bool * isNull , bool isJsonb )
37263726{
37273727 JsonExpr * jexpr = op -> d .jsonexpr .jsexpr ;
3728- Jsonb * jb = * isNull ? NULL : DatumGetJsonbP (res );
3728+ Jsonb * jb = * isNull || !isJsonb ? NULL : DatumGetJsonbP (res );
3729+ Json * js = * isNull || isJsonb ? NULL : DatumGetJsonP (res );
37293730
37303731 if (jexpr -> coerce_via_io ||
3731- (jexpr -> omit_quotes && !* isNull && JB_ROOT_IS_SCALAR (jb )))
3732+ (jexpr -> omit_quotes && !* isNull &&
3733+ (isJsonb ? JB_ROOT_IS_SCALAR (jb ) : JsonContainerIsScalar (& js -> root ))))
37323734 {
37333735 /* strip quotes and call typinput function */
3734- char * str = * isNull ? NULL : JsonbUnquote (jb );
3736+ char * str = * isNull ? NULL :
3737+ (isJsonb ? JsonbUnquote (jb ) : JsonUnquote (js ));
37353738
37363739 res = InputFunctionCall (& op -> d .jsonexpr .input .func , str ,
37373740 op -> d .jsonexpr .input .typioparam ,
@@ -3741,7 +3744,7 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
37413744 res = ExecEvalExprPassingCaseValue (op -> d .jsonexpr .result_expr , econtext ,
37423745 isNull , res , * isNull );
37433746 else if (jexpr -> coerce_via_populate )
3744- res = json_populate_type (res , JSONBOID ,
3747+ res = json_populate_type (res , isJsonb ? JSONBOID : JSONOID ,
37453748 jexpr -> returning .typid ,
37463749 jexpr -> returning .typmod ,
37473750 & op -> d .jsonexpr .cache ,
@@ -3775,7 +3778,8 @@ EvalJsonPathVar(void *cxt, bool *isnull)
37753778 * corresponding SQL type and a pointer to the coercion state.
37763779 */
37773780Datum
3778- ExecPrepareJsonItemCoercion (JsonbValue * item , JsonReturning * returning ,
3781+ ExecPrepareJsonItemCoercion (JsonbValue * item , bool is_jsonb ,
3782+ JsonReturning * returning ,
37793783 struct JsonScalarCoercions * coercions ,
37803784 MemoryContext mcxt ,
37813785 struct JsonScalarCoercionExprState * * pcestate )
@@ -3785,8 +3789,14 @@ ExecPrepareJsonItemCoercion(JsonbValue *item, JsonReturning *returning,
37853789 Oid typid ;
37863790 JsonbValue jbvbuf ;
37873791
3788- if (item -> type == jbvBinary && JsonContainerIsScalar (item -> val .binary .data ))
3789- item = JsonbExtractScalar (item -> val .binary .data , & jbvbuf );
3792+ if (item -> type == jbvBinary )
3793+ {
3794+ if (JsonContainerIsScalar (item -> val .binary .data ))
3795+ item = is_jsonb
3796+ ? JsonbExtractScalar (item -> val .binary .data , & jbvbuf )
3797+ : JsonExtractScalar ((JsonContainer * ) item -> val .binary .data ,
3798+ & jbvbuf );
3799+ }
37903800
37913801 /* get coercion state reference and datum of the corresponding SQL type */
37923802 switch (item -> type )
@@ -3848,8 +3858,20 @@ ExecPrepareJsonItemCoercion(JsonbValue *item, JsonReturning *returning,
38483858 case jbvObject :
38493859 case jbvBinary :
38503860 cestate = & coercions -> composite ;
3851- res = JsonbPGetDatum (JsonbValueToJsonb (item ));
3852- typid = JSONBOID ;
3861+ if (is_jsonb )
3862+ {
3863+ Jsonb * jb = JsonbValueToJsonb (item );
3864+
3865+ res = JsonbPGetDatum (jb );
3866+ typid = JSONBOID ;
3867+ }
3868+ else
3869+ {
3870+ Json * js = JsonbValueToJson (item );
3871+
3872+ res = JsonPGetDatum (js );
3873+ typid = JSONOID ;
3874+ }
38533875 break ;
38543876
38553877 default :
@@ -3920,7 +3942,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39203942 if (op -> d .jsonexpr .raw_expr -> isnull )
39213943 {
39223944 /* execute domain checks for NULLs */
3923- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3945+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull , isjsonb );
39243946 return ;
39253947 }
39263948
@@ -3950,31 +3972,32 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39503972 if (isnull )
39513973 {
39523974 /* execute domain checks for NULLs */
3953- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3975+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
3976+ isjsonb );
39543977 return ;
39553978 }
39563979 }
39573980
39583981 switch (jexpr -> op )
39593982 {
39603983 case IS_JSON_QUERY :
3961- res = JsonbPathQuery ( item , path , jexpr -> wrapper , & empty ,
3962- op -> d .jsonexpr .args );
3984+ res = ( isjsonb ? JsonbPathQuery : JsonPathQuery )
3985+ ( item , path , jexpr -> wrapper , & empty , op -> d .jsonexpr .args );
39633986 * op -> resnull = !DatumGetPointer (res );
39643987 break ;
39653988
39663989 case IS_JSON_VALUE :
39673990 {
3968- JsonbValue * jbv = JsonbPathValue ( item , path , & empty ,
3969- op -> d .jsonexpr .args );
3991+ JsonbValue * jbv = ( isjsonb ? JsonbPathValue : JsonPathValue )
3992+ ( item , path , & empty , op -> d .jsonexpr .args );
39703993 struct JsonScalarCoercionExprState * cestate ;
39713994
39723995 if (!jbv )
39733996 break ;
39743997
39753998 * op -> resnull = false;
39763999
3977- res = ExecPrepareJsonItemCoercion (jbv ,
4000+ res = ExecPrepareJsonItemCoercion (jbv , isjsonb ,
39784001 & op -> d .jsonexpr .jsexpr -> returning ,
39794002 & op -> d .jsonexpr .scalar ,
39804003 econtext -> ecxt_per_query_memory ,
@@ -3987,9 +4010,11 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
39874010 jexpr -> returning .typid == JSONBOID )
39884011 {
39894012 /* use coercion from json[b] to the output type */
3990- res = JsonbPGetDatum (JsonbValueToJsonb (jbv ));
3991- res = ExecEvalJsonExprCoercion (op , econtext ,
3992- res , op -> resnull );
4013+ res = isjsonb
4014+ ? JsonbPGetDatum (JsonbValueToJsonb (jbv ))
4015+ : JsonPGetDatum (JsonbValueToJson (jbv ));
4016+ res = ExecEvalJsonExprCoercion (op , econtext , res ,
4017+ op -> resnull , isjsonb );
39934018 }
39944019 else if (cestate -> result_expr_state )
39954020 {
@@ -4003,8 +4028,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
40034028 break ;
40044029
40054030 case IS_JSON_EXISTS :
4006- res = BoolGetDatum (JsonbPathExists ( item , path ,
4007- op -> d .jsonexpr .args ));
4031+ res = BoolGetDatum (( isjsonb ? JsonbPathExists : JsonPathExists )
4032+ ( item , path , op -> d .jsonexpr .args ));
40084033 * op -> resnull = false;
40094034 break ;
40104035
@@ -4031,7 +4056,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
40314056 (!empty ? jexpr -> op != IS_JSON_VALUE :
40324057 /* result is already coerced in DEFAULT behavior case */
40334058 jexpr -> on_empty .btype != JSON_BEHAVIOR_DEFAULT ))
4034- res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
4059+ res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
4060+ isjsonb );
40354061 }
40364062 PG_CATCH ();
40374063 {
@@ -4050,7 +4076,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
40504076 if (jexpr -> op != IS_JSON_EXISTS &&
40514077 /* result is already coerced in DEFAULT behavior case */
40524078 jexpr -> on_error .btype != JSON_BEHAVIOR_DEFAULT )
4053- res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
4079+ res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
4080+ isjsonb );
40544081 }
40554082 PG_END_TRY ();
40564083
0 commit comments