@@ -169,8 +169,6 @@ typedef struct JsonAnalyzeContext
169
169
AnalyzeAttrFetchFunc fetchfunc ;
170
170
HTAB * pathshash ;
171
171
JsonPathAnlStats * root ;
172
- JsonPathAnlStats * * paths ;
173
- int npaths ;
174
172
double totalrows ;
175
173
double total_width ;
176
174
int samplerows ;
@@ -929,30 +927,29 @@ JsonPathStatsCompare(const void *pv1, const void *pv2)
929
927
/*
930
928
* jsonAnalyzeSortPaths
931
929
* Reads all stats stored in the hash table and sorts them.
932
- *
933
- * XXX It's a bit strange we simply store the result in the context instead
934
- * of just returning it.
935
930
*/
936
- static void
937
- jsonAnalyzeSortPaths (JsonAnalyzeContext * ctx )
931
+ static JsonPathAnlStats * *
932
+ jsonAnalyzeSortPaths (JsonAnalyzeContext * ctx , int * p_npaths )
938
933
{
939
- HASH_SEQ_STATUS hseq ;
940
- JsonPathAnlStats * path ;
941
- int i ;
934
+ HASH_SEQ_STATUS hseq ;
935
+ JsonPathAnlStats * path ;
936
+ JsonPathAnlStats * * paths ;
937
+ int npaths ;
942
938
943
- ctx -> npaths = hash_get_num_entries (ctx -> pathshash ) + 1 ;
944
- ctx -> paths = MemoryContextAlloc (ctx -> mcxt ,
945
- sizeof (* ctx -> paths ) * ctx -> npaths );
939
+ npaths = hash_get_num_entries (ctx -> pathshash ) + 1 ;
940
+ paths = MemoryContextAlloc (ctx -> mcxt , sizeof (* paths ) * npaths );
946
941
947
- ctx -> paths [0 ] = ctx -> root ;
942
+ paths [0 ] = ctx -> root ;
948
943
949
944
hash_seq_init (& hseq , ctx -> pathshash );
950
945
951
- for (i = 1 ; (path = hash_seq_search (& hseq )); i ++ )
952
- ctx -> paths [i ] = path ;
946
+ for (int i = 1 ; (path = hash_seq_search (& hseq )) != NULL ; i ++ )
947
+ paths [i ] = path ;
953
948
954
- pg_qsort (ctx -> paths , ctx -> npaths , sizeof (* ctx -> paths ),
955
- JsonPathStatsCompare );
949
+ pg_qsort (paths , npaths , sizeof (* paths ), JsonPathStatsCompare );
950
+
951
+ * p_npaths = npaths ;
952
+ return paths ;
956
953
}
957
954
958
955
/*
@@ -986,12 +983,13 @@ jsonAnalyzeBuildPathStatsArray(JsonPathAnlStats **paths, int npaths, int *nvals,
986
983
* ???
987
984
*/
988
985
static Datum *
989
- jsonAnalyzeMakeStats (JsonAnalyzeContext * ctx , int * numvalues )
986
+ jsonAnalyzeMakeStats (JsonAnalyzeContext * ctx , JsonPathAnlStats * * paths ,
987
+ int npaths , int * numvalues )
990
988
{
991
989
Datum * values ;
992
990
MemoryContext oldcxt = MemoryContextSwitchTo (ctx -> stats -> anl_context );
993
991
994
- values = jsonAnalyzeBuildPathStatsArray (ctx -> paths , ctx -> npaths , numvalues ,
992
+ values = jsonAnalyzeBuildPathStatsArray (paths , npaths , numvalues ,
995
993
JSON_PATH_ROOT , JSON_PATH_ROOT_LEN );
996
994
997
995
MemoryContextSwitchTo (oldcxt );
@@ -1175,6 +1173,8 @@ compute_json_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
1175
1173
int samplerows , double totalrows )
1176
1174
{
1177
1175
JsonAnalyzeContext ctx ;
1176
+ JsonPathAnlStats * * paths ;
1177
+ int npaths ;
1178
1178
bool sigle_pass = false; /* FIXME make GUC or simply remove */
1179
1179
1180
1180
jsonAnalyzeInit (& ctx , stats , fetchfunc , samplerows , totalrows );
@@ -1196,14 +1196,13 @@ compute_json_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
1196
1196
* XXX I wonder if we could do this in two phases, to maybe not collect
1197
1197
* (or even accumulate) values for paths that are not interesting.
1198
1198
*/
1199
- jsonAnalyzeSortPaths (& ctx );
1199
+ paths = jsonAnalyzeSortPaths (& ctx , & npaths );
1200
1200
1201
- for (int i = 0 ; i < ctx . npaths ; i ++ )
1202
- jsonAnalyzePath (& ctx , ctx . paths [i ]);
1201
+ for (int i = 0 ; i < npaths ; i ++ )
1202
+ jsonAnalyzePath (& ctx , paths [i ]);
1203
1203
}
1204
1204
else
1205
1205
{
1206
- int i ;
1207
1206
MemoryContext oldcxt ;
1208
1207
MemoryContext tmpcxt = AllocSetContextCreate (CurrentMemoryContext ,
1209
1208
"Json Analyze Tmp Context" ,
@@ -1221,20 +1220,20 @@ compute_json_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
1221
1220
1222
1221
/* Collect all paths first without accumulating any Values, sort them */
1223
1222
jsonAnalyzePass (& ctx , jsonAnalyzeCollectPaths , (void * )(intptr_t ) false);
1224
- jsonAnalyzeSortPaths (& ctx );
1223
+ paths = jsonAnalyzeSortPaths (& ctx , & npaths );
1225
1224
1226
1225
/*
1227
1226
* Next, process each path independently to save memory (we don't want
1228
1227
* to accumulate all values for all paths, with a lot of duplicities).
1229
1228
*/
1230
1229
MemoryContextReset (tmpcxt );
1231
1230
1232
- for (i = 0 ; i < ctx . npaths ; i ++ )
1231
+ for (int i = 0 ; i < npaths ; i ++ )
1233
1232
{
1234
- JsonPathAnlStats * path = ctx . paths [i ];
1233
+ JsonPathAnlStats * path = paths [i ];
1235
1234
1236
1235
elog (DEBUG1 , "analyzing json path (%d/%d) %s" ,
1237
- i + 1 , ctx . npaths , path -> pathstr );
1236
+ i + 1 , npaths , path -> pathstr );
1238
1237
1239
1238
jsonAnalyzePass (& ctx , jsonAnalyzeCollectPath , path );
1240
1239
jsonAnalyzePath (& ctx , path );
@@ -1315,7 +1314,8 @@ compute_json_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
1315
1314
sizeof (float4 ));
1316
1315
stats -> stanumbers [empty_slot ][0 ] = 0.0 ; /* nullfrac */
1317
1316
stats -> stavalues [empty_slot ] =
1318
- jsonAnalyzeMakeStats (& ctx , & stats -> numvalues [empty_slot ]);
1317
+ jsonAnalyzeMakeStats (& ctx , paths , npaths ,
1318
+ & stats -> numvalues [empty_slot ]);
1319
1319
1320
1320
/* We are storing jsonb values */
1321
1321
stats -> statypid [empty_slot ] = JSONBOID ;
0 commit comments