mirror of
https://github.com/postgres/postgres.git
synced 2025-04-20 00:42:27 +03:00
Optimize get_jsonb_path_all avoiding an iterator
Instead of creating an iterator object at each step down the JSONB object/array, we can just just examine its object/array flags, which is faster. Also, use the recently introduced JsonbValueAsText instead of open-coding the same thing, for code simplicity. Author: Nikita Glukhov Discussion: https://postgr.es/m/7c417f90-f95f-247e-ba63-d95e39c0ad14@postgrespro.ru
This commit is contained in:
parent
abb014a631
commit
dbb9aeda99
@ -1329,7 +1329,6 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
|
|||||||
{
|
{
|
||||||
Jsonb *jb = PG_GETARG_JSONB_P(0);
|
Jsonb *jb = PG_GETARG_JSONB_P(0);
|
||||||
ArrayType *path = PG_GETARG_ARRAYTYPE_P(1);
|
ArrayType *path = PG_GETARG_ARRAYTYPE_P(1);
|
||||||
Jsonb *res;
|
|
||||||
Datum *pathtext;
|
Datum *pathtext;
|
||||||
bool *pathnulls;
|
bool *pathnulls;
|
||||||
int npath;
|
int npath;
|
||||||
@ -1337,7 +1336,6 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
|
|||||||
bool have_object = false,
|
bool have_object = false,
|
||||||
have_array = false;
|
have_array = false;
|
||||||
JsonbValue *jbvp = NULL;
|
JsonbValue *jbvp = NULL;
|
||||||
JsonbValue tv;
|
|
||||||
JsonbContainer *container;
|
JsonbContainer *container;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1449,41 +1447,30 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
|
|||||||
|
|
||||||
if (jbvp->type == jbvBinary)
|
if (jbvp->type == jbvBinary)
|
||||||
{
|
{
|
||||||
JsonbIterator *it = JsonbIteratorInit((JsonbContainer *) jbvp->val.binary.data);
|
container = jbvp->val.binary.data;
|
||||||
JsonbIteratorToken r;
|
have_object = JsonContainerIsObject(container);
|
||||||
|
have_array = JsonContainerIsArray(container);
|
||||||
r = JsonbIteratorNext(&it, &tv, true);
|
Assert(!JsonContainerIsScalar(container));
|
||||||
container = (JsonbContainer *) jbvp->val.binary.data;
|
|
||||||
have_object = r == WJB_BEGIN_OBJECT;
|
|
||||||
have_array = r == WJB_BEGIN_ARRAY;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
have_object = jbvp->type == jbvObject;
|
Assert(IsAJsonbScalar(jbvp));
|
||||||
have_array = jbvp->type == jbvArray;
|
have_object = false;
|
||||||
|
have_array = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (as_text)
|
if (as_text)
|
||||||
{
|
{
|
||||||
/* special-case outputs for string and null values */
|
|
||||||
if (jbvp->type == jbvString)
|
|
||||||
PG_RETURN_TEXT_P(cstring_to_text_with_len(jbvp->val.string.val,
|
|
||||||
jbvp->val.string.len));
|
|
||||||
if (jbvp->type == jbvNull)
|
if (jbvp->type == jbvNull)
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
}
|
|
||||||
|
|
||||||
res = JsonbValueToJsonb(jbvp);
|
PG_RETURN_TEXT_P(JsonbValueAsText(jbvp));
|
||||||
|
|
||||||
if (as_text)
|
|
||||||
{
|
|
||||||
PG_RETURN_TEXT_P(cstring_to_text(JsonbToCString(NULL,
|
|
||||||
&res->root,
|
|
||||||
VARSIZE(res))));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Jsonb *res = JsonbValueToJsonb(jbvp);
|
||||||
|
|
||||||
/* not text mode - just hand back the jsonb */
|
/* not text mode - just hand back the jsonb */
|
||||||
PG_RETURN_JSONB_P(res);
|
PG_RETURN_JSONB_P(res);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user