Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d3c6306

Browse files
author
Nikita Glukhov
committed
Refactor jsonAnalyzeAddPath()
1 parent e0f1434 commit d3c6306

File tree

1 file changed

+44
-28
lines changed

1 file changed

+44
-28
lines changed

src/backend/utils/adt/jsonb_typanalyze.c

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -242,15 +242,21 @@ JsonPathHash(const void *key, Size keysize)
242242
* updated.
243243
*/
244244
static inline JsonPathAnlStats *
245-
jsonAnalyzeAddPath(JsonAnalyzeContext *ctx, JsonPath path)
245+
jsonAnalyzeAddPath(JsonAnalyzeContext *ctx, JsonPath parent,
246+
const char *entry, int len)
246247
{
247-
JsonPathAnlStats *stats;
248-
bool found;
248+
JsonPathEntry path;
249+
JsonPathAnlStats *stats;
250+
bool found;
249251

250-
path->hash = JsonPathHash(path, 0);
252+
/* Init path entry */
253+
path.parent = parent;
254+
path.entry = entry;
255+
path.len = len;
256+
path.hash = JsonPathHash(&path, 0);
251257

252258
/* XXX See if we already saw this path earlier. */
253-
stats = hash_search_with_hash_value(ctx->pathshash, path, path->hash,
259+
stats = hash_search_with_hash_value(ctx->pathshash, &path, path.hash,
254260
HASH_ENTER, &found);
255261

256262
/*
@@ -430,8 +436,6 @@ jsonAnalyzeJson(JsonAnalyzeContext *ctx, Jsonb *jb, void *param)
430436
JsonbIteratorToken tok;
431437
JsonPathAnlStats *target = (JsonPathAnlStats *) param;
432438
JsonPathAnlStats *stats = ctx->root;
433-
JsonPath path = &stats->path;
434-
JsonPathEntry entry;
435439
bool scalar = false;
436440

437441
if ((!target || target == stats) &&
@@ -445,37 +449,49 @@ jsonAnalyzeJson(JsonAnalyzeContext *ctx, Jsonb *jb, void *param)
445449
switch (tok)
446450
{
447451
case WJB_BEGIN_OBJECT:
448-
entry.entry = NULL;
449-
entry.len = -1;
450-
entry.parent = path;
451-
path = &entry;
452-
453-
break;
454-
455-
case WJB_END_OBJECT:
456-
stats = (JsonPathAnlStats *)(path = path->parent);
452+
/*
453+
* Read next token to see if the object is empty or not.
454+
* If not, make stats for the first key. Subsequent WJB_KEYs
455+
* and WJB_END_OBJECT will expect that stats will be pointing
456+
* to the key of current object.
457+
*/
458+
tok = JsonbIteratorNext(&it, &jv, true);
459+
460+
if (tok == WJB_END_OBJECT)
461+
/* Empty object, simply skip stats initialization. */
462+
break;
463+
464+
if (tok != WJB_KEY)
465+
elog(ERROR, "unexpected jsonb iterator token: %d", tok);
466+
467+
stats = jsonAnalyzeAddPath(ctx, &stats->path,
468+
jv.val.string.val,
469+
jv.val.string.len);
457470
break;
458471

459472
case WJB_BEGIN_ARRAY:
473+
/* Make stats for non-scalar array and use it for all elements */
460474
if (!(scalar = jv.val.array.rawScalar))
461-
{
462-
entry.entry = NULL;
463-
entry.len = -1;
464-
entry.parent = path;
465-
path = &(stats = jsonAnalyzeAddPath(ctx, &entry))->path;
466-
}
475+
stats = jsonAnalyzeAddPath(ctx, &stats->path, NULL, -1);
467476
break;
468477

469478
case WJB_END_ARRAY:
470-
if (!scalar)
471-
stats = (JsonPathAnlStats *)(path = path->parent);
479+
if (scalar)
480+
break;
481+
/* FALLTHROUGH */
482+
case WJB_END_OBJECT:
483+
/* Reset to parent stats */
484+
stats = (JsonPathAnlStats *) stats->path.parent;
472485
break;
473486

474487
case WJB_KEY:
475-
entry.entry = jv.val.string.val;
476-
entry.len = jv.val.string.len;
477-
entry.parent = path->parent;
478-
path = &(stats = jsonAnalyzeAddPath(ctx, &entry))->path;
488+
/*
489+
* Stats should point to the previous key of current object,
490+
* use its parent path as a base path.
491+
*/
492+
stats = jsonAnalyzeAddPath(ctx, stats->path.parent,
493+
jv.val.string.val,
494+
jv.val.string.len);
479495
break;
480496

481497
case WJB_VALUE:

0 commit comments

Comments
 (0)