diff options
| author | Tom Lane | 2025-12-07 16:46:49 +0000 |
|---|---|---|
| committer | Tom Lane | 2025-12-07 16:51:33 +0000 |
| commit | 0986e95161cec929d8f39c01e9848f34526be421 (patch) | |
| tree | 68142932ef76e1bf3ae95e58ac605920ecaf5c22 /src/backend/utils/adt/jsonpath_exec.c | |
| parent | 3628af42107d588af73280d7e96d1c6188aadad7 (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.c | 16 |
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 */ |
