summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/jsonpath_exec.c
diff options
context:
space:
mode:
authorTom Lane2025-12-07 16:46:49 +0000
committerTom Lane2025-12-07 16:51:33 +0000
commit0986e95161cec929d8f39c01e9848f34526be421 (patch)
tree68142932ef76e1bf3ae95e58ac605920ecaf5c22 /src/backend/utils/adt/jsonpath_exec.c
parent3628af42107d588af73280d7e96d1c6188aadad7 (diff)
Revise APIs for pushJsonbValue() and associated routines.
Instead of passing "JsonbParseState **" to pushJsonbValue(), pass a pointer to a JsonbInState, which will contain the parseState stack pointer as well as other useful fields. Also, instead of returning a JsonbValue pointer that is often meaningless/ignored, return the top-level JsonbValue pointer in the "result" field of the JsonbInState. This involves a lot of (mostly mechanical) edits, but I think the results are notationally cleaner and easier to understand. Certainly the business with sometimes capturing the result of pushJsonbValue() and sometimes not was bug-prone and incapable of mechanical verification. In the new arrangement, JsonbInState.result remains null until we've completed a valid sequence of pushes, so that an incorrect sequence will result in a null-pointer dereference, not mistaken use of a partial result. However, this isn't simply an exercise in prettier notation. The real reason for doing it is to provide a mechanism whereby pushJsonbValue() can be told to construct the JsonbValue tree in a context that is not CurrentMemoryContext. That happens when a non-null "outcontext" is specified in the JsonbInState. No callers exercise that option in this patch, but the next patch in the series will make use of it. I tried to improve the comments in this area too. Author: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: jian he <jian.universality@gmail.com> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Discussion: https://postgr.es/m/1060917.1753202222@sss.pgh.pa.us
Diffstat (limited to 'src/backend/utils/adt/jsonpath_exec.c')
-rw-r--r--src/backend/utils/adt/jsonpath_exec.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c
index 8156695e97e..3f92baf6e82 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -2874,8 +2874,7 @@ executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
{
JsonBaseObjectInfo baseObject;
JsonbValue obj;
- JsonbParseState *ps;
- JsonbValue *keyval;
+ JsonbInState ps;
Jsonb *jsonb;
if (tok != WJB_KEY)
@@ -2889,7 +2888,8 @@ executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
tok = JsonbIteratorNext(&it, &val, true);
Assert(tok == WJB_VALUE);
- ps = NULL;
+ memset(&ps, 0, sizeof(ps));
+
pushJsonbValue(&ps, WJB_BEGIN_OBJECT, NULL);
pushJsonbValue(&ps, WJB_KEY, &keystr);
@@ -2901,9 +2901,9 @@ executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
pushJsonbValue(&ps, WJB_KEY, &idstr);
pushJsonbValue(&ps, WJB_VALUE, &idval);
- keyval = pushJsonbValue(&ps, WJB_END_OBJECT, NULL);
+ pushJsonbValue(&ps, WJB_END_OBJECT, NULL);
- jsonb = JsonbValueToJsonb(keyval);
+ jsonb = JsonbValueToJsonb(ps.result);
JsonbInitBinary(&obj, jsonb);
@@ -3649,7 +3649,7 @@ getScalar(JsonbValue *scalar, enum jbvType type)
static JsonbValue *
wrapItemsInArray(const JsonValueList *items)
{
- JsonbParseState *ps = NULL;
+ JsonbInState ps = {0};
JsonValueListIterator it;
JsonbValue *jbv;
@@ -3659,7 +3659,9 @@ wrapItemsInArray(const JsonValueList *items)
while ((jbv = JsonValueListNext(items, &it)))
pushJsonbValue(&ps, WJB_ELEM, jbv);
- return pushJsonbValue(&ps, WJB_END_ARRAY, NULL);
+ pushJsonbValue(&ps, WJB_END_ARRAY, NULL);
+
+ return ps.result;
}
/* Check if the timezone required for casting from type1 to type2 is used */