@@ -3722,16 +3722,19 @@ ExecEvalJsonBehavior(ExprContext *econtext, JsonBehavior *behavior,
3722
3722
*/
3723
3723
static Datum
3724
3724
ExecEvalJsonExprCoercion (ExprEvalStep * op , ExprContext * econtext ,
3725
- Datum res , bool * isNull )
3725
+ Datum res , bool * isNull , bool isJsonb )
3726
3726
{
3727
3727
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 );
3729
3730
3730
3731
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 ))))
3732
3734
{
3733
3735
/* strip quotes and call typinput function */
3734
- char * str = * isNull ? NULL : JsonbUnquote (jb );
3736
+ char * str = * isNull ? NULL :
3737
+ (isJsonb ? JsonbUnquote (jb ) : JsonUnquote (js ));
3735
3738
3736
3739
res = InputFunctionCall (& op -> d .jsonexpr .input .func , str ,
3737
3740
op -> d .jsonexpr .input .typioparam ,
@@ -3741,7 +3744,7 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
3741
3744
res = ExecEvalExprPassingCaseValue (op -> d .jsonexpr .result_expr , econtext ,
3742
3745
isNull , res , * isNull );
3743
3746
else if (jexpr -> coerce_via_populate )
3744
- res = json_populate_type (res , JSONBOID ,
3747
+ res = json_populate_type (res , isJsonb ? JSONBOID : JSONOID ,
3745
3748
jexpr -> returning .typid ,
3746
3749
jexpr -> returning .typmod ,
3747
3750
& op -> d .jsonexpr .cache ,
@@ -3775,7 +3778,8 @@ EvalJsonPathVar(void *cxt, bool *isnull)
3775
3778
* corresponding SQL type and a pointer to the coercion state.
3776
3779
*/
3777
3780
Datum
3778
- ExecPrepareJsonItemCoercion (JsonbValue * item , JsonReturning * returning ,
3781
+ ExecPrepareJsonItemCoercion (JsonbValue * item , bool is_jsonb ,
3782
+ JsonReturning * returning ,
3779
3783
struct JsonScalarCoercions * coercions ,
3780
3784
MemoryContext mcxt ,
3781
3785
struct JsonScalarCoercionExprState * * pcestate )
@@ -3785,8 +3789,14 @@ ExecPrepareJsonItemCoercion(JsonbValue *item, JsonReturning *returning,
3785
3789
Oid typid ;
3786
3790
JsonbValue jbvbuf ;
3787
3791
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
+ }
3790
3800
3791
3801
/* get coercion state reference and datum of the corresponding SQL type */
3792
3802
switch (item -> type )
@@ -3848,8 +3858,20 @@ ExecPrepareJsonItemCoercion(JsonbValue *item, JsonReturning *returning,
3848
3858
case jbvObject :
3849
3859
case jbvBinary :
3850
3860
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
+ }
3853
3875
break ;
3854
3876
3855
3877
default :
@@ -3920,7 +3942,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3920
3942
if (op -> d .jsonexpr .raw_expr -> isnull )
3921
3943
{
3922
3944
/* execute domain checks for NULLs */
3923
- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3945
+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull , isjsonb );
3924
3946
return ;
3925
3947
}
3926
3948
@@ -3950,31 +3972,32 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3950
3972
if (isnull )
3951
3973
{
3952
3974
/* execute domain checks for NULLs */
3953
- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3975
+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
3976
+ isjsonb );
3954
3977
return ;
3955
3978
}
3956
3979
}
3957
3980
3958
3981
switch (jexpr -> op )
3959
3982
{
3960
3983
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 );
3963
3986
* op -> resnull = !DatumGetPointer (res );
3964
3987
break ;
3965
3988
3966
3989
case IS_JSON_VALUE :
3967
3990
{
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 );
3970
3993
struct JsonScalarCoercionExprState * cestate ;
3971
3994
3972
3995
if (!jbv )
3973
3996
break ;
3974
3997
3975
3998
* op -> resnull = false;
3976
3999
3977
- res = ExecPrepareJsonItemCoercion (jbv ,
4000
+ res = ExecPrepareJsonItemCoercion (jbv , isjsonb ,
3978
4001
& op -> d .jsonexpr .jsexpr -> returning ,
3979
4002
& op -> d .jsonexpr .scalar ,
3980
4003
econtext -> ecxt_per_query_memory ,
@@ -3987,9 +4010,11 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3987
4010
jexpr -> returning .typid == JSONBOID )
3988
4011
{
3989
4012
/* 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 );
3993
4018
}
3994
4019
else if (cestate -> result_expr_state )
3995
4020
{
@@ -4003,8 +4028,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
4003
4028
break ;
4004
4029
4005
4030
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 ));
4008
4033
* op -> resnull = false;
4009
4034
break ;
4010
4035
@@ -4031,7 +4056,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
4031
4056
(!empty ? jexpr -> op != IS_JSON_VALUE :
4032
4057
/* result is already coerced in DEFAULT behavior case */
4033
4058
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 );
4035
4061
}
4036
4062
PG_CATCH ();
4037
4063
{
@@ -4050,7 +4076,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
4050
4076
if (jexpr -> op != IS_JSON_EXISTS &&
4051
4077
/* result is already coerced in DEFAULT behavior case */
4052
4078
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 );
4054
4081
}
4055
4082
PG_END_TRY ();
4056
4083
0 commit comments