@@ -261,6 +261,7 @@ typedef struct JsonTableContext
261
261
} * colexprs ;
262
262
JsonTableScanState root ;
263
263
bool empty ;
264
+ bool isJsonb ;
264
265
} JsonTableContext ;
265
266
266
267
/* strict/lax flags is decomposed into four [un]wrap/error flags */
@@ -434,7 +435,7 @@ static void popJsonItem(JsonItemStack *stack);
434
435
435
436
static JsonTableJoinState * JsonTableInitPlanState (JsonTableContext * cxt ,
436
437
Node * plan , JsonTableScanState * parent );
437
- static bool JsonTableNextRow (JsonTableScanState * scan );
438
+ static bool JsonTableNextRow (JsonTableScanState * scan , bool isJsonb );
438
439
439
440
440
441
/****************** User interface to JsonPath executor ********************/
@@ -3748,11 +3749,11 @@ JsonTableInitPlanState(JsonTableContext *cxt, Node *plan,
3748
3749
}
3749
3750
3750
3751
/*
3751
- * JsonTableInitOpaque
3752
+ * JsonxTableInitOpaque
3752
3753
* Fill in TableFuncScanState->opaque for JsonTable processor
3753
3754
*/
3754
3755
static void
3755
- JsonTableInitOpaque (TableFuncScanState * state , int natts )
3756
+ JsonxTableInitOpaque (TableFuncScanState * state , int natts , bool isJsonb )
3756
3757
{
3757
3758
JsonTableContext * cxt ;
3758
3759
PlanState * ps = & state -> ss .ps ;
@@ -3766,6 +3767,7 @@ JsonTableInitOpaque(TableFuncScanState *state, int natts)
3766
3767
3767
3768
cxt = palloc0 (sizeof (JsonTableContext ));
3768
3769
cxt -> magic = JSON_TABLE_CONTEXT_MAGIC ;
3770
+ cxt -> isJsonb = isJsonb ;
3769
3771
3770
3772
if (list_length (ci -> passing .values ) > 0 )
3771
3773
{
@@ -3816,6 +3818,18 @@ JsonTableInitOpaque(TableFuncScanState *state, int natts)
3816
3818
state -> opaque = cxt ;
3817
3819
}
3818
3820
3821
+ static void
3822
+ JsonbTableInitOpaque (TableFuncScanState * state , int natts )
3823
+ {
3824
+ JsonxTableInitOpaque (state , natts , true);
3825
+ }
3826
+
3827
+ static void
3828
+ JsonTableInitOpaque (TableFuncScanState * state , int natts )
3829
+ {
3830
+ JsonxTableInitOpaque (state , natts , false);
3831
+ }
3832
+
3819
3833
/* Reset scan iterator to the beginning of the item list */
3820
3834
static void
3821
3835
JsonTableRescan (JsonTableScanState * scan )
@@ -3829,19 +3843,19 @@ JsonTableRescan(JsonTableScanState *scan)
3829
3843
3830
3844
/* Reset context item of a scan, execute JSON path and reset a scan */
3831
3845
static void
3832
- JsonTableResetContextItem (JsonTableScanState * scan , Datum item )
3846
+ JsonTableResetContextItem (JsonTableScanState * scan , Datum item , bool isJsonb )
3833
3847
{
3834
3848
MemoryContext oldcxt ;
3835
3849
JsonPathExecResult res ;
3836
- Jsonx * js = ( Jsonx * ) DatumGetJsonbP ( item );
3850
+ Jsonx * js = DatumGetJsonxP ( item , isJsonb );
3837
3851
3838
3852
JsonValueListClear (& scan -> found );
3839
3853
3840
3854
MemoryContextResetOnly (scan -> mcxt );
3841
3855
3842
3856
oldcxt = MemoryContextSwitchTo (scan -> mcxt );
3843
3857
3844
- res = executeJsonPath (scan -> path , scan -> args , EvalJsonPathVar , js , true ,
3858
+ res = executeJsonPath (scan -> path , scan -> args , EvalJsonPathVar , js , isJsonb ,
3845
3859
scan -> errorOnError , & scan -> found );
3846
3860
3847
3861
MemoryContextSwitchTo (oldcxt );
@@ -3864,7 +3878,7 @@ JsonTableSetDocument(TableFuncScanState *state, Datum value)
3864
3878
{
3865
3879
JsonTableContext * cxt = GetJsonTableContext (state , "JsonTableSetDocument" );
3866
3880
3867
- JsonTableResetContextItem (& cxt -> root , value );
3881
+ JsonTableResetContextItem (& cxt -> root , value , cxt -> isJsonb );
3868
3882
}
3869
3883
3870
3884
/* Recursively reset scan and its child nodes */
@@ -3891,15 +3905,15 @@ JsonTableRescanRecursive(JsonTableJoinState *state)
3891
3905
* Returned false at the end of a scan, true otherwise.
3892
3906
*/
3893
3907
static bool
3894
- JsonTableNextJoinRow (JsonTableJoinState * state )
3908
+ JsonTableNextJoinRow (JsonTableJoinState * state , bool isJsonb )
3895
3909
{
3896
3910
if (!state -> is_join )
3897
- return JsonTableNextRow (& state -> u .scan );
3911
+ return JsonTableNextRow (& state -> u .scan , isJsonb );
3898
3912
3899
3913
if (state -> u .join .advanceRight )
3900
3914
{
3901
3915
/* fetch next inner row */
3902
- if (JsonTableNextJoinRow (state -> u .join .right ))
3916
+ if (JsonTableNextJoinRow (state -> u .join .right , isJsonb ))
3903
3917
return true;
3904
3918
3905
3919
/* inner rows are exhausted */
@@ -3912,7 +3926,7 @@ JsonTableNextJoinRow(JsonTableJoinState *state)
3912
3926
while (!state -> u .join .advanceRight )
3913
3927
{
3914
3928
/* fetch next outer row */
3915
- bool left = JsonTableNextJoinRow (state -> u .join .left );
3929
+ bool left = JsonTableNextJoinRow (state -> u .join .left , isJsonb );
3916
3930
3917
3931
if (state -> u .join .cross )
3918
3932
{
@@ -3921,14 +3935,14 @@ JsonTableNextJoinRow(JsonTableJoinState *state)
3921
3935
3922
3936
JsonTableRescanRecursive (state -> u .join .right );
3923
3937
3924
- if (!JsonTableNextJoinRow (state -> u .join .right ))
3938
+ if (!JsonTableNextJoinRow (state -> u .join .right , isJsonb ))
3925
3939
continue ; /* next outer row */
3926
3940
3927
3941
state -> u .join .advanceRight = true; /* next inner row */
3928
3942
}
3929
3943
else if (!left )
3930
3944
{
3931
- if (!JsonTableNextJoinRow (state -> u .join .right ))
3945
+ if (!JsonTableNextJoinRow (state -> u .join .right , isJsonb ))
3932
3946
return false; /* end of scan */
3933
3947
3934
3948
state -> u .join .advanceRight = true; /* next inner row */
@@ -3966,20 +3980,20 @@ JsonTableJoinReset(JsonTableJoinState *state)
3966
3980
* Returned false at the end of a scan, true otherwise.
3967
3981
*/
3968
3982
static bool
3969
- JsonTableNextRow (JsonTableScanState * scan )
3983
+ JsonTableNextRow (JsonTableScanState * scan , bool isJsonb )
3970
3984
{
3971
3985
/* reset context item if requested */
3972
3986
if (scan -> reset )
3973
3987
{
3974
3988
Assert (!scan -> parent -> currentIsNull );
3975
- JsonTableResetContextItem (scan , scan -> parent -> current );
3989
+ JsonTableResetContextItem (scan , scan -> parent -> current , isJsonb );
3976
3990
scan -> reset = false;
3977
3991
}
3978
3992
3979
3993
if (scan -> advanceNested )
3980
3994
{
3981
3995
/* fetch next nested row */
3982
- scan -> advanceNested = JsonTableNextJoinRow (scan -> nested );
3996
+ scan -> advanceNested = JsonTableNextJoinRow (scan -> nested , isJsonb );
3983
3997
3984
3998
if (scan -> advanceNested )
3985
3999
return true;
@@ -4000,7 +4014,7 @@ JsonTableNextRow(JsonTableScanState *scan)
4000
4014
4001
4015
/* set current row item */
4002
4016
oldcxt = MemoryContextSwitchTo (scan -> mcxt );
4003
- scan -> current = JsonbPGetDatum ( JsonItemToJsonb ( jbv ) );
4017
+ scan -> current = JsonItemToJsonxDatum ( jbv , isJsonb );
4004
4018
scan -> currentIsNull = false;
4005
4019
MemoryContextSwitchTo (oldcxt );
4006
4020
@@ -4011,7 +4025,7 @@ JsonTableNextRow(JsonTableScanState *scan)
4011
4025
4012
4026
JsonTableJoinReset (scan -> nested );
4013
4027
4014
- scan -> advanceNested = JsonTableNextJoinRow (scan -> nested );
4028
+ scan -> advanceNested = JsonTableNextJoinRow (scan -> nested , isJsonb );
4015
4029
4016
4030
if (scan -> advanceNested || scan -> outerJoin )
4017
4031
break ;
@@ -4035,7 +4049,7 @@ JsonTableFetchRow(TableFuncScanState *state)
4035
4049
if (cxt -> empty )
4036
4050
return false;
4037
4051
4038
- return JsonTableNextRow (& cxt -> root );
4052
+ return JsonTableNextRow (& cxt -> root , cxt -> isJsonb );
4039
4053
}
4040
4054
4041
4055
/*
@@ -4088,6 +4102,18 @@ JsonTableDestroyOpaque(TableFuncScanState *state)
4088
4102
}
4089
4103
4090
4104
const TableFuncRoutine JsonbTableRoutine =
4105
+ {
4106
+ JsonbTableInitOpaque ,
4107
+ JsonTableSetDocument ,
4108
+ NULL ,
4109
+ NULL ,
4110
+ NULL ,
4111
+ JsonTableFetchRow ,
4112
+ JsonTableGetValue ,
4113
+ JsonTableDestroyOpaque
4114
+ };
4115
+
4116
+ const TableFuncRoutine JsonTableRoutine =
4091
4117
{
4092
4118
JsonTableInitOpaque ,
4093
4119
JsonTableSetDocument ,
0 commit comments