@@ -3673,16 +3673,19 @@ ExecEvalJsonBehavior(ExprContext *econtext, JsonBehavior *behavior,
3673
3673
*/
3674
3674
static Datum
3675
3675
ExecEvalJsonExprCoercion (ExprEvalStep * op , ExprContext * econtext ,
3676
- Datum res , bool * isNull )
3676
+ Datum res , bool * isNull , bool isJsonb )
3677
3677
{
3678
3678
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 );
3680
3681
3681
3682
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 ))))
3683
3685
{
3684
3686
/* strip quotes and call typinput function */
3685
- char * str = * isNull ? NULL : JsonbUnquote (jb );
3687
+ char * str = * isNull ? NULL :
3688
+ (isJsonb ? JsonbUnquote (jb ) : JsonUnquote (js ));
3686
3689
3687
3690
res = InputFunctionCall (& op -> d .jsonexpr .input .func , str ,
3688
3691
op -> d .jsonexpr .input .typioparam ,
@@ -3692,7 +3695,7 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
3692
3695
res = ExecEvalExprPassingCaseValue (op -> d .jsonexpr .result_expr , econtext ,
3693
3696
isNull , res , * isNull );
3694
3697
else if (jexpr -> coerce_via_populate )
3695
- res = json_populate_type (res , JSONBOID ,
3698
+ res = json_populate_type (res , isJsonb ? JSONBOID : JSONOID ,
3696
3699
jexpr -> returning .typid ,
3697
3700
jexpr -> returning .typmod ,
3698
3701
& op -> d .jsonexpr .cache ,
@@ -3726,7 +3729,8 @@ EvalJsonPathVar(void *cxt, bool *isnull)
3726
3729
* corresponding SQL type and a pointer to the coercion state.
3727
3730
*/
3728
3731
Datum
3729
- ExecPrepareJsonItemCoercion (JsonbValue * item , JsonReturning * returning ,
3732
+ ExecPrepareJsonItemCoercion (JsonbValue * item , bool is_jsonb ,
3733
+ JsonReturning * returning ,
3730
3734
struct JsonScalarCoercions * coercions ,
3731
3735
MemoryContext mcxt ,
3732
3736
struct JsonScalarCoercionExprState * * pcestate )
@@ -3736,8 +3740,14 @@ ExecPrepareJsonItemCoercion(JsonbValue *item, JsonReturning *returning,
3736
3740
Oid typid ;
3737
3741
JsonbValue jbvbuf ;
3738
3742
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
+ }
3741
3751
3742
3752
/* get coercion state reference and datum of the corresponding SQL type */
3743
3753
switch (item -> type )
@@ -3799,8 +3809,20 @@ ExecPrepareJsonItemCoercion(JsonbValue *item, JsonReturning *returning,
3799
3809
case jbvObject :
3800
3810
case jbvBinary :
3801
3811
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
+ }
3804
3826
break ;
3805
3827
3806
3828
default :
@@ -3871,7 +3893,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3871
3893
if (op -> d .jsonexpr .raw_expr -> isnull )
3872
3894
{
3873
3895
/* execute domain checks for NULLs */
3874
- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3896
+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull , isjsonb );
3875
3897
return ;
3876
3898
}
3877
3899
@@ -3901,31 +3923,32 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3901
3923
if (isnull )
3902
3924
{
3903
3925
/* execute domain checks for NULLs */
3904
- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3926
+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
3927
+ isjsonb );
3905
3928
return ;
3906
3929
}
3907
3930
}
3908
3931
3909
3932
switch (jexpr -> op )
3910
3933
{
3911
3934
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 );
3914
3937
* op -> resnull = !DatumGetPointer (res );
3915
3938
break ;
3916
3939
3917
3940
case IS_JSON_VALUE :
3918
3941
{
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 );
3921
3944
struct JsonScalarCoercionExprState * cestate ;
3922
3945
3923
3946
if (!jbv )
3924
3947
break ;
3925
3948
3926
3949
* op -> resnull = false;
3927
3950
3928
- res = ExecPrepareJsonItemCoercion (jbv ,
3951
+ res = ExecPrepareJsonItemCoercion (jbv , isjsonb ,
3929
3952
& op -> d .jsonexpr .jsexpr -> returning ,
3930
3953
& op -> d .jsonexpr .scalar ,
3931
3954
econtext -> ecxt_per_query_memory ,
@@ -3938,9 +3961,11 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3938
3961
jexpr -> returning .typid == JSONBOID )
3939
3962
{
3940
3963
/* 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 );
3944
3969
}
3945
3970
else if (cestate -> result_expr_state )
3946
3971
{
@@ -3954,8 +3979,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3954
3979
break ;
3955
3980
3956
3981
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 ));
3959
3984
* op -> resnull = false;
3960
3985
break ;
3961
3986
@@ -3982,7 +4007,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3982
4007
(!empty ? jexpr -> op != IS_JSON_VALUE :
3983
4008
/* result is already coerced in DEFAULT behavior case */
3984
4009
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 );
3986
4012
}
3987
4013
PG_CATCH ();
3988
4014
{
@@ -4001,7 +4027,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
4001
4027
if (jexpr -> op != IS_JSON_EXISTS &&
4002
4028
/* result is already coerced in DEFAULT behavior case */
4003
4029
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 );
4005
4032
}
4006
4033
PG_END_TRY ();
4007
4034
0 commit comments