@@ -3673,17 +3673,20 @@ 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
3679
JsonCoercion * coercion = jexpr -> result_coercion ;
3680
- Jsonb * jb = * isNull ? NULL : DatumGetJsonbP (res );
3680
+ Jsonb * jb = * isNull || !isJsonb ? NULL : DatumGetJsonbP (res );
3681
+ Json * js = * isNull || isJsonb ? NULL : DatumGetJsonP (res );
3681
3682
3682
3683
if ((coercion && coercion -> via_io ) ||
3683
- (jexpr -> omit_quotes && !* isNull && JB_ROOT_IS_SCALAR (jb )))
3684
+ (jexpr -> omit_quotes && !* isNull &&
3685
+ (isJsonb ? JB_ROOT_IS_SCALAR (jb ) : JsonContainerIsScalar (& js -> root ))))
3684
3686
{
3685
3687
/* strip quotes and call typinput function */
3686
- char * str = * isNull ? NULL : JsonbUnquote (jb );
3688
+ char * str = * isNull ? NULL :
3689
+ (isJsonb ? JsonbUnquote (jb ) : JsonUnquote (js ));
3687
3690
3688
3691
res = InputFunctionCall (& op -> d .jsonexpr .input .func , str ,
3689
3692
op -> d .jsonexpr .input .typioparam ,
@@ -3693,7 +3696,7 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
3693
3696
res = ExecEvalExprPassingCaseValue (op -> d .jsonexpr .result_expr , econtext ,
3694
3697
isNull , res , * isNull );
3695
3698
else if (coercion && coercion -> via_populate )
3696
- res = json_populate_type (res , JSONBOID ,
3699
+ res = json_populate_type (res , isJsonb ? JSONBOID : JSONOID ,
3697
3700
jexpr -> returning .typid ,
3698
3701
jexpr -> returning .typmod ,
3699
3702
& op -> d .jsonexpr .cache ,
@@ -3727,7 +3730,7 @@ EvalJsonPathVar(void *cxt, bool *isnull)
3727
3730
* corresponding SQL type and a pointer to the coercion state.
3728
3731
*/
3729
3732
Datum
3730
- ExecPrepareJsonItemCoercion (JsonbValue * item ,
3733
+ ExecPrepareJsonItemCoercion (JsonbValue * item , bool is_jsonb ,
3731
3734
JsonReturning * returning ,
3732
3735
struct JsonCoercionsState * coercions ,
3733
3736
struct JsonCoercionState * * pcoercion )
@@ -3736,8 +3739,14 @@ ExecPrepareJsonItemCoercion(JsonbValue *item,
3736
3739
Datum res ;
3737
3740
JsonbValue jbvbuf ;
3738
3741
3739
- if (item -> type == jbvBinary && JsonContainerIsScalar (item -> val .binary .data ))
3740
- item = JsonbExtractScalar (item -> val .binary .data , & jbvbuf );
3742
+ if (item -> type == jbvBinary )
3743
+ {
3744
+ if (JsonContainerIsScalar (item -> val .binary .data ))
3745
+ item = is_jsonb
3746
+ ? JsonbExtractScalar (item -> val .binary .data , & jbvbuf )
3747
+ : JsonExtractScalar ((JsonContainer * ) item -> val .binary .data ,
3748
+ & jbvbuf );
3749
+ }
3741
3750
3742
3751
/* get coercion state reference and datum of the corresponding SQL type */
3743
3752
switch (item -> type )
@@ -3794,7 +3803,18 @@ ExecPrepareJsonItemCoercion(JsonbValue *item,
3794
3803
case jbvObject :
3795
3804
case jbvBinary :
3796
3805
coercion = & coercions -> composite ;
3797
- res = JsonbPGetDatum (JsonbValueToJsonb (item ));
3806
+ if (is_jsonb )
3807
+ {
3808
+ Jsonb * jb = JsonbValueToJsonb (item );
3809
+
3810
+ res = JsonbPGetDatum (jb );
3811
+ }
3812
+ else
3813
+ {
3814
+ Json * js = JsonbValueToJson (item );
3815
+
3816
+ res = JsonPGetDatum (js );
3817
+ }
3798
3818
break ;
3799
3819
3800
3820
default :
@@ -3809,7 +3829,8 @@ ExecPrepareJsonItemCoercion(JsonbValue *item,
3809
3829
3810
3830
static Datum
3811
3831
ExecEvalJsonExpr (ExprState * state , ExprEvalStep * op , ExprContext * econtext ,
3812
- JsonExpr * jexpr , JsonPath * path , Datum item , bool * resnull )
3832
+ JsonExpr * jexpr , JsonPath * path , Datum item , bool isjsonb ,
3833
+ bool * resnull )
3813
3834
{
3814
3835
bool empty = false;
3815
3836
Datum res = (Datum ) 0 ;
@@ -3823,7 +3844,8 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
3823
3844
if (isnull )
3824
3845
{
3825
3846
/* execute domain checks for NULLs */
3826
- (void ) ExecEvalJsonExprCoercion (op , econtext , res , resnull );
3847
+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , resnull ,
3848
+ isjsonb );
3827
3849
* resnull = true;
3828
3850
return (Datum ) 0 ;
3829
3851
}
@@ -3832,23 +3854,23 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
3832
3854
switch (jexpr -> op )
3833
3855
{
3834
3856
case IS_JSON_QUERY :
3835
- res = JsonbPathQuery ( item , path , jexpr -> wrapper , & empty ,
3836
- op -> d .jsonexpr .args );
3857
+ res = ( isjsonb ? JsonbPathQuery : JsonPathQuery )
3858
+ ( item , path , jexpr -> wrapper , & empty , op -> d .jsonexpr .args );
3837
3859
* resnull = !DatumGetPointer (res );
3838
3860
break ;
3839
3861
3840
3862
case IS_JSON_VALUE :
3841
3863
{
3842
- JsonbValue * jbv = JsonbPathValue ( item , path , & empty ,
3843
- op -> d .jsonexpr .args );
3864
+ JsonbValue * jbv = ( isjsonb ? JsonbPathValue : JsonPathValue )
3865
+ ( item , path , & empty , op -> d .jsonexpr .args );
3844
3866
struct JsonCoercionState * jcstate ;
3845
3867
3846
3868
if (!jbv )
3847
3869
break ;
3848
3870
3849
3871
* resnull = false;
3850
3872
3851
- res = ExecPrepareJsonItemCoercion (jbv ,
3873
+ res = ExecPrepareJsonItemCoercion (jbv , isjsonb ,
3852
3874
& op -> d .jsonexpr .jsexpr -> returning ,
3853
3875
& op -> d .jsonexpr .coercions ,
3854
3876
& jcstate );
@@ -3861,8 +3883,11 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
3861
3883
jexpr -> returning .typid == JSONBOID )
3862
3884
{
3863
3885
/* use coercion via I/O from json[b] to the output type */
3864
- res = JsonbPGetDatum (JsonbValueToJsonb (jbv ));
3865
- res = ExecEvalJsonExprCoercion (op , econtext , res , resnull );
3886
+ res = isjsonb
3887
+ ? JsonbPGetDatum (JsonbValueToJsonb (jbv ))
3888
+ : JsonPGetDatum (JsonbValueToJson (jbv ));
3889
+ res = ExecEvalJsonExprCoercion (op , econtext , res ,
3890
+ resnull , isjsonb );
3866
3891
}
3867
3892
else if (jcstate -> estate )
3868
3893
{
@@ -3876,7 +3901,8 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
3876
3901
break ;
3877
3902
3878
3903
case IS_JSON_EXISTS :
3879
- res = BoolGetDatum (JsonbPathExists (item , path , op -> d .jsonexpr .args ));
3904
+ res = BoolGetDatum ((isjsonb ? JsonbPathExists : JsonPathExists )
3905
+ (item , path , op -> d .jsonexpr .args ));
3880
3906
* resnull = false;
3881
3907
break ;
3882
3908
@@ -3895,15 +3921,15 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
3895
3921
3896
3922
/* execute ON EMPTY behavior */
3897
3923
res = ExecEvalJsonBehavior (econtext , & jexpr -> on_empty ,
3898
- op -> d .jsonexpr .default_on_empty , true,
3899
- resnull );
3924
+ op -> d .jsonexpr .default_on_empty ,
3925
+ isjsonb , resnull );
3900
3926
}
3901
3927
3902
3928
if (jexpr -> op != IS_JSON_EXISTS &&
3903
3929
(!empty ? jexpr -> op != IS_JSON_VALUE :
3904
3930
/* result is already coerced in DEFAULT behavior case */
3905
3931
jexpr -> on_empty .btype != JSON_BEHAVIOR_DEFAULT ))
3906
- res = ExecEvalJsonExprCoercion (op , econtext , res , resnull );
3932
+ res = ExecEvalJsonExprCoercion (op , econtext , res , resnull , isjsonb );
3907
3933
3908
3934
return res ;
3909
3935
}
@@ -3931,7 +3957,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3931
3957
if (op -> d .jsonexpr .raw_expr -> isnull || op -> d .jsonexpr .pathspec -> isnull )
3932
3958
{
3933
3959
/* execute domain checks for NULLs */
3934
- (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
3960
+ (void ) ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull , isjsonb );
3935
3961
3936
3962
Assert (* op -> resnull );
3937
3963
* op -> resnull = true;
@@ -3954,7 +3980,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3954
3980
if (jexpr -> on_error .btype == JSON_BEHAVIOR_ERROR )
3955
3981
{
3956
3982
/* No need to use PG_TRY/PG_CATCH. */
3957
- res = ExecEvalJsonExpr (state , op , econtext , jexpr , path , item ,
3983
+ res = ExecEvalJsonExpr (state , op , econtext , jexpr , path , item , isjsonb ,
3958
3984
op -> resnull );
3959
3985
}
3960
3986
else
@@ -3964,7 +3990,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3964
3990
PG_TRY ();
3965
3991
{
3966
3992
res = ExecEvalJsonExpr (state , op , econtext , jexpr , path , item ,
3967
- op -> resnull );
3993
+ isjsonb , op -> resnull );
3968
3994
}
3969
3995
PG_CATCH ();
3970
3996
{
@@ -3986,7 +4012,8 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
3986
4012
if (jexpr -> op != IS_JSON_EXISTS &&
3987
4013
/* Result is already coerced in DEFAULT behavior case. */
3988
4014
jexpr -> on_error .btype != JSON_BEHAVIOR_DEFAULT )
3989
- res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull );
4015
+ res = ExecEvalJsonExprCoercion (op , econtext , res , op -> resnull ,
4016
+ isjsonb );
3990
4017
}
3991
4018
PG_END_TRY ();
3992
4019
}
0 commit comments