Commit dbb9aeda authored by Alvaro Herrera's avatar Alvaro Herrera

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
parent abb014a6
...@@ -1329,7 +1329,6 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) ...@@ -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) ...@@ -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) ...@@ -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);
if (as_text) PG_RETURN_TEXT_P(JsonbValueAsText(jbvp));
{
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);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment