@@ -955,11 +955,13 @@ jsonAnalyzeSortPaths(JsonAnalyzeContext *ctx, int *p_npaths)
955
955
956
956
/*
957
957
* jsonAnalyzeBuildPathStatsArray
958
- * ???
958
+ * Build jsonb datum array for path stats, that will be used as stavalues.
959
+ *
960
+ * The first element is a path prefix.
959
961
*/
960
962
static Datum *
961
963
jsonAnalyzeBuildPathStatsArray (JsonPathAnlStats * * paths , int npaths , int * nvals ,
962
- const char * prefix , int prefixlen )
964
+ const char * prefix , int prefixlen )
963
965
{
964
966
Datum * values = palloc (sizeof (Datum ) * (npaths + 1 ));
965
967
JsonbValue * jbvprefix = palloc (sizeof (JsonbValue ));
@@ -981,14 +983,14 @@ jsonAnalyzeBuildPathStatsArray(JsonPathAnlStats **paths, int npaths, int *nvals,
981
983
982
984
/*
983
985
* jsonAnalyzeMakeStats
984
- * ???
986
+ * Build stavalues jsonb array for the root path prefix.
985
987
*/
986
988
static Datum *
987
989
jsonAnalyzeMakeStats (JsonAnalyzeContext * ctx , JsonPathAnlStats * * paths ,
988
990
int npaths , int * numvalues )
989
991
{
990
- Datum * values ;
991
- MemoryContext oldcxt = MemoryContextSwitchTo (ctx -> stats -> anl_context );
992
+ Datum * values ;
993
+ MemoryContext oldcxt = MemoryContextSwitchTo (ctx -> stats -> anl_context );
992
994
993
995
values = jsonAnalyzeBuildPathStatsArray (paths , npaths , numvalues ,
994
996
JSON_PATH_ROOT , JSON_PATH_ROOT_LEN );
@@ -1000,7 +1002,10 @@ jsonAnalyzeMakeStats(JsonAnalyzeContext *ctx, JsonPathAnlStats **paths,
1000
1002
1001
1003
/*
1002
1004
* jsonAnalyzeBuildSubPathsData
1003
- * ???
1005
+ * Build statvalues and stanumbers arrays for the subset of paths starting
1006
+ * from a given prefix.
1007
+ *
1008
+ * pathsDatums[index] should point to the desired path.
1004
1009
*/
1005
1010
bool
1006
1011
jsonAnalyzeBuildSubPathsData (Datum * pathsDatums , int npaths , int index ,
@@ -1009,33 +1014,40 @@ jsonAnalyzeBuildSubPathsData(Datum *pathsDatums, int npaths, int index,
1009
1014
Datum * pvals , Datum * pnums )
1010
1015
{
1011
1016
JsonPathAnlStats * * pvalues = palloc (sizeof (* pvalues ) * npaths );
1012
- Datum * values ;
1013
- Datum numbers [1 ];
1014
- JsonbValue pathkey ;
1015
- int nsubpaths = 0 ;
1016
- int nvalues ;
1017
- int i ;
1017
+ Datum * values ;
1018
+ Datum numbers [1 ];
1019
+ JsonbValue pathkey ;
1020
+ int nsubpaths = 0 ;
1021
+ int nvalues ;
1022
+ int i ;
1018
1023
1019
1024
JsonValueInitStringWithLen (& pathkey , "path" , 4 );
1020
1025
1021
1026
for (i = index ; i < npaths ; i ++ )
1022
1027
{
1028
+ /* Extract path name */
1023
1029
Jsonb * jb = DatumGetJsonbP (pathsDatums [i ]);
1024
1030
JsonbValue * jbv = findJsonbValueFromContainer (& jb -> root , JB_FOBJECT ,
1025
1031
& pathkey );
1026
1032
1033
+ /* Check if path name starts with a given prefix */
1027
1034
if (!jbv || jbv -> type != jbvString ||
1028
1035
jbv -> val .string .len < pathlen ||
1029
1036
memcmp (jbv -> val .string .val , path , pathlen ))
1030
1037
break ;
1031
1038
1032
1039
pfree (jbv );
1033
1040
1041
+ /* Collect matching path */
1034
1042
pvalues [nsubpaths ] = palloc (sizeof (* * pvalues ));
1035
1043
pvalues [nsubpaths ]-> stats = jb ;
1036
1044
1037
1045
nsubpaths ++ ;
1038
1046
1047
+ /*
1048
+ * The path should go before its subpaths, so if subpaths are not
1049
+ * needed the loop is broken after the first matching path.
1050
+ */
1039
1051
if (!includeSubpaths )
1040
1052
break ;
1041
1053
}
@@ -1046,6 +1058,7 @@ jsonAnalyzeBuildSubPathsData(Datum *pathsDatums, int npaths, int index,
1046
1058
return false;
1047
1059
}
1048
1060
1061
+ /* Construct new array from the selected paths */
1049
1062
values = jsonAnalyzeBuildPathStatsArray (pvalues , nsubpaths , & nvalues ,
1050
1063
path , pathlen );
1051
1064
* pvals = PointerGetDatum (construct_array (values , nvalues , JSONBOID , -1 ,
0 commit comments