mirror of
https://github.com/postgres/postgres.git
synced 2026-01-27 21:43:08 +03:00
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
This commit is contained in:
@@ -67,8 +67,10 @@ typedef enum
|
||||
#define JGINFLAG_HASHED 0x10 /* OR'd into flag if value was hashed */
|
||||
#define JGIN_MAXLENGTH 125 /* max length of text part before hashing */
|
||||
|
||||
/* Forward struct references */
|
||||
typedef struct JsonbPair JsonbPair;
|
||||
typedef struct JsonbValue JsonbValue;
|
||||
typedef struct JsonbParseState JsonbParseState;
|
||||
|
||||
/*
|
||||
* Jsonbs are varlena objects, so must meet the varlena convention that the
|
||||
@@ -315,15 +317,40 @@ struct JsonbPair
|
||||
uint32 order; /* Pair's index in original sequence */
|
||||
};
|
||||
|
||||
/* Conversion state used when parsing Jsonb from text, or for type coercion */
|
||||
typedef struct JsonbParseState
|
||||
/*
|
||||
* State used while constructing or manipulating a JsonbValue.
|
||||
* For example, when parsing Jsonb from text, we construct a JsonbValue
|
||||
* data structure and then flatten that into the Jsonb on-disk format.
|
||||
* JsonbValues are also useful in aggregation and type coercion.
|
||||
*
|
||||
* Callers providing a JsonbInState must initialize it to zeroes/nulls,
|
||||
* except for optionally setting outcontext (if that's left NULL,
|
||||
* CurrentMemoryContext is used) and escontext (if that's left NULL,
|
||||
* parsing errors are thrown via ereport).
|
||||
*/
|
||||
typedef struct JsonbInState
|
||||
{
|
||||
JsonbValue contVal;
|
||||
Size size;
|
||||
struct JsonbParseState *next;
|
||||
JsonbValue *result; /* The completed value; NULL until complete */
|
||||
MemoryContext outcontext; /* The context to build it in, or NULL */
|
||||
struct Node *escontext; /* Optional soft-error-reporting context */
|
||||
/* Remaining fields should be treated as private to jsonb.c/jsonb_util.c */
|
||||
JsonbParseState *parseState; /* Stack of parsing contexts */
|
||||
bool unique_keys; /* Check object key uniqueness */
|
||||
} JsonbInState;
|
||||
|
||||
/*
|
||||
* Parsing context for one level of Jsonb array or object nesting.
|
||||
* The contVal will be part of the constructed JsonbValue tree,
|
||||
* but the other fields are just transient state.
|
||||
*/
|
||||
struct JsonbParseState
|
||||
{
|
||||
JsonbValue contVal; /* An array or object JsonbValue */
|
||||
Size size; /* Allocated length of array or object */
|
||||
JsonbParseState *next; /* Link to next outer level, if any */
|
||||
bool unique_keys; /* Check object key uniqueness */
|
||||
bool skip_nulls; /* Skip null object fields */
|
||||
} JsonbParseState;
|
||||
};
|
||||
|
||||
/*
|
||||
* JsonbIterator holds details of the type for each iteration. It also stores a
|
||||
@@ -404,8 +431,8 @@ extern JsonbValue *getKeyJsonValueFromContainer(JsonbContainer *container,
|
||||
JsonbValue *res);
|
||||
extern JsonbValue *getIthJsonbValueFromContainer(JsonbContainer *container,
|
||||
uint32 i);
|
||||
extern JsonbValue *pushJsonbValue(JsonbParseState **pstate,
|
||||
JsonbIteratorToken seq, JsonbValue *jbval);
|
||||
extern void pushJsonbValue(JsonbInState *pstate,
|
||||
JsonbIteratorToken seq, JsonbValue *jbval);
|
||||
extern JsonbIterator *JsonbIteratorInit(JsonbContainer *container);
|
||||
extern JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val,
|
||||
bool skipNested);
|
||||
|
||||
Reference in New Issue
Block a user