@@ -3664,15 +3664,18 @@ ExecEvalJsonBehavior(ExprContext *econtext, JsonBehavior *behavior,
3664
3664
3665
3665
static Datum
3666
3666
ExecEvalJsonExprCoercion (ExprEvalStep * op , ExprContext * econtext ,
3667
- Datum res , bool * isNull )
3667
+ Datum res , bool * isNull , bool isJsonb )
3668
3668
{
3669
3669
JsonExpr * jexpr = op -> d .jsonexpr .jsexpr ;
3670
- Jsonb * jb = * isNull ? NULL : DatumGetJsonb (res );
3670
+ Jsonb * jb = * isNull || !isJsonb ? NULL : DatumGetJsonb (res );
3671
+ Json * js = * isNull || isJsonb ? NULL : DatumGetJson (res );
3671
3672
3672
3673
if (jexpr -> coerce_via_io ||
3673
- (jexpr -> omit_quotes && !* isNull && JB_ROOT_IS_SCALAR (jb )))
3674
+ (jexpr -> omit_quotes && !* isNull &&
3675
+ (isJsonb ? JB_ROOT_IS_SCALAR (jb ) : JsonContainerIsScalar (& js -> root ))))
3674
3676
{
3675
- char * str = * isNull ? NULL : JsonbUnquote (jb );
3677
+ char * str = * isNull ? NULL :
3678
+ (isJsonb ? JsonbUnquote (jb ) : JsonUnquote (js ));
3676
3679
3677
3680
res = InputFunctionCall (& op -> d .jsonexpr .input .func , str ,
3678
3681
op -> d .jsonexpr .input .typioparam ,
@@ -3682,7 +3685,7 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
3682
3685
res = ExecEvalExprPassingCaseValue (op -> d .jsonexpr .result_expr , econtext ,
3683
3686
isNull , res , * isNull );
3684
3687
else if (jexpr -> coerce_via_populate )
3685
- res = json_populate_type (res , JSONBOID ,
3688
+ res = json_populate_type (res , isJsonb ? JSONBOID : JSONOID ,
3686
3689
jexpr -> returning .typid ,
3687
3690
jexpr -> returning .typmod ,
3688
3691
& op -> d .jsonexpr .cache ,
@@ -3708,7 +3711,8 @@ EvalJsonPathVar(void *cxt, bool *isnull)
3708
3711
}
3709
3712
3710
3713
Datum
3711
- ExecPrepareJsonItemCoercion (JsonbValue * jbv , JsonReturning * returning ,
3714
+ ExecPrepareJsonItemCoercion (JsonbValue * jbv , bool is_jsonb ,
3715
+ JsonReturning * returning ,
3712
3716
struct JsonScalarCoercions * coercions ,
3713
3717
MemoryContext mcxt ,
3714
3718
struct JsonScalarCoercionExprState * * pcestate )
@@ -3718,8 +3722,14 @@ ExecPrepareJsonItemCoercion(JsonbValue *jbv, JsonReturning *returning,
3718
3722
Oid typid ;
3719
3723
JsonbValue jbvbuf ;
3720
3724
3721
- if (jbv -> type == jbvBinary && JsonContainerIsScalar (jbv -> val .binary .data ))
3722
- jbv = JsonbExtractScalar (jbv -> val .binary .data , & jbvbuf );
3725
+ if (jbv -> type == jbvBinary )
3726
+ {
3727
+ if (JsonContainerIsScalar (jbv -> val .binary .data ))
3728
+ jbv = is_jsonb
3729
+ ? JsonbExtractScalar (jbv -> val .binary .data , & jbvbuf )
3730
+ : JsonExtractScalar ((JsonContainer * ) jbv -> val .binary .data ,
3731
+ & jbvbuf );
3732
+ }
3723
3733
3724
3734
switch (jbv -> type )
3725
3735
{
@@ -3780,8 +3790,20 @@ ExecPrepareJsonItemCoercion(JsonbValue *jbv, JsonReturning *returning,
3780
3790
case jbvObject :
3781
3791
case jbvBinary :
3782
3792
cestate = & coercions -> composite ;
3783
- res = JsonbGetDatum (JsonbValueToJsonb (jbv ));
3784
- typid = JSONBOID ;
3793
+ if (is_jsonb )
3794
+ {
3795
+ Jsonb * jb = JsonbValueToJsonb (jbv );
3796
+
3797
+ res = JsonbGetDatum (jb );
3798
+ typid = JSONBOID ;
3799
+ }
3800
+ else
3801
+ {
3802
+ Json * js = JsonbValueToJson (jbv );
3803
+
3804
+ res = JsonGetDatum (js );
3805
+ typid = JSONOID ;
3806
+ }
3785
3807
break ;
3786
3808
3787
3809
default :
@@ -3851,7 +3873,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3851
3873
if (op -> d .jsonexpr .raw_expr -> isnull )
3852
3874
{
3853
3875
/* execute domain checks for NULLs */
3854
- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3876
+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull , isjsonb );
3855
3877
return ;
3856
3878
}
3857
3879
@@ -3879,31 +3901,32 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3879
3901
econtext , & isnull , item , false);
3880
3902
if (isnull )
3881
3903
{
3882
- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3904
+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
3905
+ isjsonb );
3883
3906
return ;
3884
3907
}
3885
3908
}
3886
3909
3887
3910
switch (jexpr -> op )
3888
3911
{
3889
3912
case IS_JSON_QUERY :
3890
- res = JsonbPathQuery ( item , path , jexpr -> wrapper , & empty ,
3891
- op -> d .jsonexpr .args );
3913
+ res = ( isjsonb ? JsonbPathQuery : JsonPathQuery )
3914
+ ( item , path , jexpr -> wrapper , & empty , op -> d .jsonexpr .args );
3892
3915
* op -> resnull = !DatumGetPointer (res );
3893
3916
break ;
3894
3917
3895
3918
case IS_JSON_VALUE :
3896
3919
{
3897
- JsonbValue * jbv = JsonbPathValue ( item , path , & empty ,
3898
- op -> d .jsonexpr .args );
3920
+ JsonbValue * jbv = ( isjsonb ? JsonbPathValue : JsonPathValue )
3921
+ ( item , path , & empty , op -> d .jsonexpr .args );
3899
3922
struct JsonScalarCoercionExprState * cestate ;
3900
3923
3901
3924
if (!jbv )
3902
3925
break ;
3903
3926
3904
3927
* op -> resnull = false;
3905
3928
3906
- res = ExecPrepareJsonItemCoercion (jbv ,
3929
+ res = ExecPrepareJsonItemCoercion (jbv , isjsonb ,
3907
3930
& op -> d .jsonexpr .jsexpr -> returning ,
3908
3931
& op -> d .jsonexpr .scalar ,
3909
3932
econtext -> ecxt_per_query_memory ,
@@ -3914,9 +3937,11 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3914
3937
(cestate -> result_expr &&
3915
3938
IsA (cestate -> result_expr , CoerceViaIO )))
3916
3939
{
3917
- res = JsonbGetDatum (JsonbValueToJsonb (jbv ));
3918
- res = ExecEvalJsonExprCoercion (op , econtext ,
3919
- res , op -> resnull );
3940
+ res = isjsonb
3941
+ ? JsonbGetDatum (JsonbValueToJsonb (jbv ))
3942
+ : JsonGetDatum (JsonbValueToJson (jbv ));
3943
+ res = ExecEvalJsonExprCoercion (op , econtext , res ,
3944
+ op -> resnull , isjsonb );
3920
3945
}
3921
3946
else if (cestate -> result_expr_state )
3922
3947
{
@@ -3930,8 +3955,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3930
3955
break ;
3931
3956
3932
3957
case IS_JSON_EXISTS :
3933
- res = BoolGetDatum (JsonbPathExists ( item , path ,
3934
- op -> d .jsonexpr .args ));
3958
+ res = BoolGetDatum (( isjsonb ? JsonbPathExists : JsonPathExists )
3959
+ ( item , path , op -> d .jsonexpr .args ));
3935
3960
* op -> resnull = false;
3936
3961
break ;
3937
3962
@@ -3957,7 +3982,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3957
3982
(!empty ? jexpr -> op != IS_JSON_VALUE :
3958
3983
/* already coerced in DEFAULT case */
3959
3984
jexpr -> on_empty .btype != JSON_BEHAVIOR_DEFAULT ))
3960
- res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3985
+ res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
3986
+ isjsonb );
3961
3987
}
3962
3988
PG_CATCH ();
3963
3989
{
@@ -3974,7 +4000,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3974
4000
3975
4001
if (jexpr -> op != IS_JSON_EXISTS &&
3976
4002
jexpr -> on_error .btype != JSON_BEHAVIOR_DEFAULT )
3977
- res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
4003
+ res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
4004
+ isjsonb );
3978
4005
}
3979
4006
PG_END_TRY ();
3980
4007
0 commit comments