diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2022-12-11 10:39:05 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2022-12-11 10:39:05 -0500 |
commit | 50428a301d5ad46316cac2192f2ca8d91898aa3c (patch) | |
tree | af6ebd0e69eed53dfdd8f87eb7d36e228d274d5f /src/backend/utils/adt/jsonfuncs.c | |
parent | d02ef65bce6575e10ac0b4e7b8552ff67687c944 (diff) | |
download | postgresql-50428a301d5ad46316cac2192f2ca8d91898aa3c.tar.gz postgresql-50428a301d5ad46316cac2192f2ca8d91898aa3c.zip |
Change JsonSemAction to allow non-throw error reporting.
Formerly, semantic action functions for the JSON parser returned void,
so that there was no way for them to affect the parser's behavior.
That means in particular that they can't force an error exit except by
longjmp'ing. That won't do in the context of our project to make input
functions return errors softly. Hence, change them to return the same
JsonParseErrorType enum value as the parser itself uses. If an action
function returns anything besides JSON_SUCCESS, the parse is abandoned
and that error code is returned.
Action functions can thus easily return the same error conditions that
the parser already knows about. As an escape hatch for expansion, also
invent a code JSON_SEM_ACTION_FAILED that the core parser does not know
the exact meaning of. When returning this code, an action function
must use some out-of-band mechanism for reporting the error details.
This commit simply makes the API change and causes all the existing
action functions to return JSON_SUCCESS, so that there is no actual
change in behavior here. This is long enough and boring enough that
it seemed best to commit it separately from the changes that make
real use of the new mechanism.
In passing, remove a duplicate assignment of
transform_string_values_scalar.
Discussion: https://postgr.es/m/1436686.1670701118@sss.pgh.pa.us
Diffstat (limited to 'src/backend/utils/adt/jsonfuncs.c')
-rw-r--r-- | src/backend/utils/adt/jsonfuncs.c | 356 |
1 files changed, 232 insertions, 124 deletions
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index bfc3f02a863..d6cad952790 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -336,20 +336,20 @@ typedef struct JsObject static int report_json_context(JsonLexContext *lex); /* semantic action functions for json_object_keys */ -static void okeys_object_field_start(void *state, char *fname, bool isnull); -static void okeys_array_start(void *state); -static void okeys_scalar(void *state, char *token, JsonTokenType tokentype); +static JsonParseErrorType okeys_object_field_start(void *state, char *fname, bool isnull); +static JsonParseErrorType okeys_array_start(void *state); +static JsonParseErrorType okeys_scalar(void *state, char *token, JsonTokenType tokentype); /* semantic action functions for json_get* functions */ -static void get_object_start(void *state); -static void get_object_end(void *state); -static void get_object_field_start(void *state, char *fname, bool isnull); -static void get_object_field_end(void *state, char *fname, bool isnull); -static void get_array_start(void *state); -static void get_array_end(void *state); -static void get_array_element_start(void *state, bool isnull); -static void get_array_element_end(void *state, bool isnull); -static void get_scalar(void *state, char *token, JsonTokenType tokentype); +static JsonParseErrorType get_object_start(void *state); +static JsonParseErrorType get_object_end(void *state); +static JsonParseErrorType get_object_field_start(void *state, char *fname, bool isnull); +static JsonParseErrorType get_object_field_end(void *state, char *fname, bool isnull); +static JsonParseErrorType get_array_start(void *state); +static JsonParseErrorType get_array_end(void *state); +static JsonParseErrorType get_array_element_start(void *state, bool isnull); +static JsonParseErrorType get_array_element_end(void *state, bool isnull); +static JsonParseErrorType get_scalar(void *state, char *token, JsonTokenType tokentype); /* common worker function for json getter functions */ static Datum get_path_all(FunctionCallInfo fcinfo, bool as_text); @@ -359,9 +359,9 @@ static Datum get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text); static text *JsonbValueAsText(JsonbValue *v); /* semantic action functions for json_array_length */ -static void alen_object_start(void *state); -static void alen_scalar(void *state, char *token, JsonTokenType tokentype); -static void alen_array_element_start(void *state, bool isnull); +static JsonParseErrorType alen_object_start(void *state); +static JsonParseErrorType alen_scalar(void *state, char *token, JsonTokenType tokentype); +static JsonParseErrorType alen_array_element_start(void *state, bool isnull); /* common workers for json{b}_each* functions */ static Datum each_worker(FunctionCallInfo fcinfo, bool as_text); @@ -369,10 +369,10 @@ static Datum each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text); /* semantic action functions for json_each */ -static void each_object_field_start(void *state, char *fname, bool isnull); -static void each_object_field_end(void *state, char *fname, bool isnull); -static void each_array_start(void *state); -static void each_scalar(void *state, char *token, JsonTokenType tokentype); +static JsonParseErrorType each_object_field_start(void *state, char *fname, bool isnull); +static JsonParseErrorType each_object_field_end(void *state, char *fname, bool isnull); +static JsonParseErrorType each_array_start(void *state); +static JsonParseErrorType each_scalar(void *state, char *token, JsonTokenType tokentype); /* common workers for json{b}_array_elements_* functions */ static Datum elements_worker(FunctionCallInfo fcinfo, const char *funcname, @@ -381,44 +381,44 @@ static Datum elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname bool as_text); /* semantic action functions for json_array_elements */ -static void elements_object_start(void *state); -static void elements_array_element_start(void *state, bool isnull); -static void elements_array_element_end(void *state, bool isnull); -static void elements_scalar(void *state, char *token, JsonTokenType tokentype); +static JsonParseErrorType elements_object_start(void *state); +static JsonParseErrorType elements_array_element_start(void *state, bool isnull); +static JsonParseErrorType elements_array_element_end(void *state, bool isnull); +static JsonParseErrorType elements_scalar(void *state, char *token, JsonTokenType tokentype); /* turn a json object into a hash table */ static HTAB *get_json_object_as_hash(char *json, int len, const char *funcname); /* semantic actions for populate_array_json */ -static void populate_array_object_start(void *_state); -static void populate_array_array_end(void *_state); -static void populate_array_element_start(void *_state, bool isnull); -static void populate_array_element_end(void *_state, bool isnull); -static void populate_array_scalar(void *_state, char *token, JsonTokenType tokentype); +static JsonParseErrorType populate_array_object_start(void *_state); +static JsonParseErrorType populate_array_array_end(void *_state); +static JsonParseErrorType populate_array_element_start(void *_state, bool isnull); +static JsonParseErrorType populate_array_element_end(void *_state, bool isnull); +static JsonParseErrorType populate_array_scalar(void *_state, char *token, JsonTokenType tokentype); /* semantic action functions for get_json_object_as_hash */ -static void hash_object_field_start(void *state, char *fname, bool isnull); -static void hash_object_field_end(void *state, char *fname, bool isnull); -static void hash_array_start(void *state); -static void hash_scalar(void *state, char *token, JsonTokenType tokentype); +static JsonParseErrorType hash_object_field_start(void *state, char *fname, bool isnull); +static JsonParseErrorType hash_object_field_end(void *state, char *fname, bool isnull); +static JsonParseErrorType hash_array_start(void *state); +static JsonParseErrorType hash_scalar(void *state, char *token, JsonTokenType tokentype); /* semantic action functions for populate_recordset */ -static void populate_recordset_object_field_start(void *state, char *fname, bool isnull); -static void populate_recordset_object_field_end(void *state, char *fname, bool isnull); -static void populate_recordset_scalar(void *state, char *token, JsonTokenType tokentype); -static void populate_recordset_object_start(void *state); -static void populate_recordset_object_end(void *state); -static void populate_recordset_array_start(void *state); -static void populate_recordset_array_element_start(void *state, bool isnull); +static JsonParseErrorType populate_recordset_object_field_start(void *state, char *fname, bool isnull); +static JsonParseErrorType populate_recordset_object_field_end(void *state, char *fname, bool isnull); +static JsonParseErrorType populate_recordset_scalar(void *state, char *token, JsonTokenType tokentype); +static JsonParseErrorType populate_recordset_object_start(void *state); +static JsonParseErrorType populate_recordset_object_end(void *state); +static JsonParseErrorType populate_recordset_array_start(void *state); +static JsonParseErrorType populate_recordset_array_element_start(void *state, bool isnull); /* semantic action functions for json_strip_nulls */ -static void sn_object_start(void *state); -static void sn_object_end(void *state); -static void sn_array_start(void *state); -static void sn_array_end(void *state); -static void sn_object_field_start(void *state, char *fname, bool isnull); -static void sn_array_element_start(void *state, bool isnull); -static void sn_scalar(void *state, char *token, JsonTokenType tokentype); +static JsonParseErrorType sn_object_start(void *state); +static JsonParseErrorType sn_object_end(void *state); +static JsonParseErrorType sn_array_start(void *state); +static JsonParseErrorType sn_array_end(void *state); +static JsonParseErrorType sn_object_field_start(void *state, char *fname, bool isnull); +static JsonParseErrorType sn_array_element_start(void *state, bool isnull); +static JsonParseErrorType sn_scalar(void *state, char *token, JsonTokenType tokentype); /* worker functions for populate_record, to_record, populate_recordset and to_recordset */ static Datum populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, @@ -478,17 +478,17 @@ static void setPathArray(JsonbIterator **it, Datum *path_elems, JsonbValue *newval, uint32 nelems, int op_type); /* function supporting iterate_json_values */ -static void iterate_values_scalar(void *state, char *token, JsonTokenType tokentype); -static void iterate_values_object_field_start(void *state, char *fname, bool isnull); +static JsonParseErrorType iterate_values_scalar(void *state, char *token, JsonTokenType tokentype); +static JsonParseErrorType iterate_values_object_field_start(void *state, char *fname, bool isnull); /* functions supporting transform_json_string_values */ -static void transform_string_values_object_start(void *state); -static void transform_string_values_object_end(void *state); -static void transform_string_values_array_start(void *state); -static void transform_string_values_array_end(void *state); -static void transform_string_values_object_field_start(void *state, char *fname, bool isnull); -static void transform_string_values_array_element_start(void *state, bool isnull); -static void transform_string_values_scalar(void *state, char *token, JsonTokenType tokentype); +static JsonParseErrorType transform_string_values_object_start(void *state); +static JsonParseErrorType transform_string_values_object_end(void *state); +static JsonParseErrorType transform_string_values_array_start(void *state); +static JsonParseErrorType transform_string_values_array_end(void *state); +static JsonParseErrorType transform_string_values_object_field_start(void *state, char *fname, bool isnull); +static JsonParseErrorType transform_string_values_array_element_start(void *state, bool isnull); +static JsonParseErrorType transform_string_values_scalar(void *state, char *token, JsonTokenType tokentype); /* * pg_parse_json_or_ereport @@ -745,14 +745,14 @@ json_object_keys(PG_FUNCTION_ARGS) SRF_RETURN_DONE(funcctx); } -static void +static JsonParseErrorType okeys_object_field_start(void *state, char *fname, bool isnull) { OkeysState *_state = (OkeysState *) state; /* only collecting keys for the top level object */ if (_state->lex->lex_level != 1) - return; + return JSON_SUCCESS; /* enlarge result array if necessary */ if (_state->result_count >= _state->result_size) @@ -764,9 +764,11 @@ okeys_object_field_start(void *state, char *fname, bool isnull) /* save a copy of the field name */ _state->result[_state->result_count++] = pstrdup(fname); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType okeys_array_start(void *state) { OkeysState *_state = (OkeysState *) state; @@ -777,9 +779,11 @@ okeys_array_start(void *state) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot call %s on an array", "json_object_keys"))); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType okeys_scalar(void *state, char *token, JsonTokenType tokentype) { OkeysState *_state = (OkeysState *) state; @@ -790,6 +794,8 @@ okeys_scalar(void *state, char *token, JsonTokenType tokentype) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot call %s on a scalar", "json_object_keys"))); + + return JSON_SUCCESS; } /* @@ -1112,7 +1118,7 @@ get_worker(text *json, return state->tresult; } -static void +static JsonParseErrorType get_object_start(void *state) { GetState *_state = (GetState *) state; @@ -1127,9 +1133,11 @@ get_object_start(void *state) */ _state->result_start = _state->lex->token_start; } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType get_object_end(void *state) { GetState *_state = (GetState *) state; @@ -1143,9 +1151,11 @@ get_object_end(void *state) _state->tresult = cstring_to_text_with_len(start, len); } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType get_object_field_start(void *state, char *fname, bool isnull) { GetState *_state = (GetState *) state; @@ -1188,9 +1198,11 @@ get_object_field_start(void *state, char *fname, bool isnull) _state->result_start = _state->lex->token_start; } } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType get_object_field_end(void *state, char *fname, bool isnull) { GetState *_state = (GetState *) state; @@ -1237,9 +1249,11 @@ get_object_field_end(void *state, char *fname, bool isnull) /* this should be unnecessary but let's do it for cleanliness: */ _state->result_start = NULL; } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType get_array_start(void *state) { GetState *_state = (GetState *) state; @@ -1275,9 +1289,11 @@ get_array_start(void *state) */ _state->result_start = _state->lex->token_start; } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType get_array_end(void *state) { GetState *_state = (GetState *) state; @@ -1291,9 +1307,11 @@ get_array_end(void *state) _state->tresult = cstring_to_text_with_len(start, len); } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType get_array_element_start(void *state, bool isnull) { GetState *_state = (GetState *) state; @@ -1337,9 +1355,11 @@ get_array_element_start(void *state, bool isnull) _state->result_start = _state->lex->token_start; } } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType get_array_element_end(void *state, bool isnull) { GetState *_state = (GetState *) state; @@ -1379,9 +1399,11 @@ get_array_element_end(void *state, bool isnull) _state->result_start = NULL; } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType get_scalar(void *state, char *token, JsonTokenType tokentype) { GetState *_state = (GetState *) state; @@ -1420,6 +1442,8 @@ get_scalar(void *state, char *token, JsonTokenType tokentype) /* make sure the next call to get_scalar doesn't overwrite it */ _state->next_scalar = false; } + + return JSON_SUCCESS; } Datum @@ -1834,7 +1858,7 @@ jsonb_array_length(PG_FUNCTION_ARGS) * a scalar or an object). */ -static void +static JsonParseErrorType alen_object_start(void *state) { AlenState *_state = (AlenState *) state; @@ -1844,9 +1868,11 @@ alen_object_start(void *state) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot get array length of a non-array"))); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType alen_scalar(void *state, char *token, JsonTokenType tokentype) { AlenState *_state = (AlenState *) state; @@ -1856,9 +1882,11 @@ alen_scalar(void *state, char *token, JsonTokenType tokentype) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot get array length of a scalar"))); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType alen_array_element_start(void *state, bool isnull) { AlenState *_state = (AlenState *) state; @@ -1866,6 +1894,8 @@ alen_array_element_start(void *state, bool isnull) /* just count up all the level 1 elements */ if (_state->lex->lex_level == 1) _state->count++; + + return JSON_SUCCESS; } /* @@ -2026,7 +2056,7 @@ each_worker(FunctionCallInfo fcinfo, bool as_text) } -static void +static JsonParseErrorType each_object_field_start(void *state, char *fname, bool isnull) { EachState *_state = (EachState *) state; @@ -2044,9 +2074,11 @@ each_object_field_start(void *state, char *fname, bool isnull) else _state->result_start = _state->lex->token_start; } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType each_object_field_end(void *state, char *fname, bool isnull) { EachState *_state = (EachState *) state; @@ -2059,7 +2091,7 @@ each_object_field_end(void *state, char *fname, bool isnull) /* skip over nested objects */ if (_state->lex->lex_level != 1) - return; + return JSON_SUCCESS; /* use the tmp context so we can clean up after each tuple is done */ old_cxt = MemoryContextSwitchTo(_state->tmp_cxt); @@ -2090,9 +2122,11 @@ each_object_field_end(void *state, char *fname, bool isnull) /* clean up and switch back */ MemoryContextSwitchTo(old_cxt); MemoryContextReset(_state->tmp_cxt); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType each_array_start(void *state) { EachState *_state = (EachState *) state; @@ -2102,9 +2136,11 @@ each_array_start(void *state) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot deconstruct an array as an object"))); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType each_scalar(void *state, char *token, JsonTokenType tokentype) { EachState *_state = (EachState *) state; @@ -2118,6 +2154,8 @@ each_scalar(void *state, char *token, JsonTokenType tokentype) /* supply de-escaped value if required */ if (_state->next_scalar) _state->normalized_scalar = token; + + return JSON_SUCCESS; } /* @@ -2268,7 +2306,7 @@ elements_worker(FunctionCallInfo fcinfo, const char *funcname, bool as_text) PG_RETURN_NULL(); } -static void +static JsonParseErrorType elements_array_element_start(void *state, bool isnull) { ElementsState *_state = (ElementsState *) state; @@ -2286,9 +2324,11 @@ elements_array_element_start(void *state, bool isnull) else _state->result_start = _state->lex->token_start; } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType elements_array_element_end(void *state, bool isnull) { ElementsState *_state = (ElementsState *) state; @@ -2301,7 +2341,7 @@ elements_array_element_end(void *state, bool isnull) /* skip over nested objects */ if (_state->lex->lex_level != 1) - return; + return JSON_SUCCESS; /* use the tmp context so we can clean up after each tuple is done */ old_cxt = MemoryContextSwitchTo(_state->tmp_cxt); @@ -2330,9 +2370,11 @@ elements_array_element_end(void *state, bool isnull) /* clean up and switch back */ MemoryContextSwitchTo(old_cxt); MemoryContextReset(_state->tmp_cxt); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType elements_object_start(void *state) { ElementsState *_state = (ElementsState *) state; @@ -2343,9 +2385,11 @@ elements_object_start(void *state) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot call %s on a non-array", _state->function_name))); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType elements_scalar(void *state, char *token, JsonTokenType tokentype) { ElementsState *_state = (ElementsState *) state; @@ -2360,6 +2404,8 @@ elements_scalar(void *state, char *token, JsonTokenType tokentype) /* supply de-escaped value if required */ if (_state->next_scalar) _state->normalized_scalar = token; + + return JSON_SUCCESS; } /* @@ -2508,7 +2554,7 @@ populate_array_element(PopulateArrayContext *ctx, int ndim, JsValue *jsv) } /* json object start handler for populate_array_json() */ -static void +static JsonParseErrorType populate_array_object_start(void *_state) { PopulateArrayState *state = (PopulateArrayState *) _state; @@ -2518,10 +2564,12 @@ populate_array_object_start(void *_state) populate_array_assign_ndims(state->ctx, ndim); else if (ndim < state->ctx->ndims) populate_array_report_expected_array(state->ctx, ndim); + + return JSON_SUCCESS; } /* json array end handler for populate_array_json() */ -static void +static JsonParseErrorType populate_array_array_end(void *_state) { PopulateArrayState *state = (PopulateArrayState *) _state; @@ -2533,10 +2581,12 @@ populate_array_array_end(void *_state) if (ndim < ctx->ndims) populate_array_check_dimension(ctx, ndim); + + return JSON_SUCCESS; } /* json array element start handler for populate_array_json() */ -static void +static JsonParseErrorType populate_array_element_start(void *_state, bool isnull) { PopulateArrayState *state = (PopulateArrayState *) _state; @@ -2549,10 +2599,12 @@ populate_array_element_start(void *_state, bool isnull) state->element_type = state->lex->token_type; state->element_scalar = NULL; } + + return JSON_SUCCESS; } /* json array element end handler for populate_array_json() */ -static void +static JsonParseErrorType populate_array_element_end(void *_state, bool isnull) { PopulateArrayState *state = (PopulateArrayState *) _state; @@ -2588,10 +2640,12 @@ populate_array_element_end(void *_state, bool isnull) populate_array_element(ctx, ndim, &jsv); } + + return JSON_SUCCESS; } /* json scalar handler for populate_array_json() */ -static void +static JsonParseErrorType populate_array_scalar(void *_state, char *token, JsonTokenType tokentype) { PopulateArrayState *state = (PopulateArrayState *) _state; @@ -2610,6 +2664,8 @@ populate_array_scalar(void *_state, char *token, JsonTokenType tokentype) /* element_type must already be set in populate_array_element_start() */ Assert(state->element_type == tokentype); } + + return JSON_SUCCESS; } /* parse a json array and populate array */ @@ -3491,13 +3547,13 @@ get_json_object_as_hash(char *json, int len, const char *funcname) return tab; } -static void +static JsonParseErrorType hash_object_field_start(void *state, char *fname, bool isnull) { JHashState *_state = (JHashState *) state; if (_state->lex->lex_level > 1) - return; + return JSON_SUCCESS; /* remember token type */ _state->saved_token_type = _state->lex->token_type; @@ -3513,9 +3569,11 @@ hash_object_field_start(void *state, char *fname, bool isnull) /* must be a scalar */ _state->save_json_start = NULL; } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType hash_object_field_end(void *state, char *fname, bool isnull) { JHashState *_state = (JHashState *) state; @@ -3526,7 +3584,7 @@ hash_object_field_end(void *state, char *fname, bool isnull) * Ignore nested fields. */ if (_state->lex->lex_level > 1) - return; + return JSON_SUCCESS; /* * Ignore field names >= NAMEDATALEN - they can't match a record field. @@ -3536,7 +3594,7 @@ hash_object_field_end(void *state, char *fname, bool isnull) * has previously insisted on exact equality, so we keep this behavior.) */ if (strlen(fname) >= NAMEDATALEN) - return; + return JSON_SUCCESS; hashentry = hash_search(_state->hash, fname, HASH_ENTER, &found); @@ -3562,9 +3620,11 @@ hash_object_field_end(void *state, char *fname, bool isnull) /* must have had a scalar instead */ hashentry->val = _state->saved_scalar; } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType hash_array_start(void *state) { JHashState *_state = (JHashState *) state; @@ -3573,9 +3633,11 @@ hash_array_start(void *state) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot call %s on an array", _state->function_name))); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType hash_scalar(void *state, char *token, JsonTokenType tokentype) { JHashState *_state = (JHashState *) state; @@ -3591,6 +3653,8 @@ hash_scalar(void *state, char *token, JsonTokenType tokentype) /* saved_token_type must already be set in hash_object_field_start() */ Assert(_state->saved_token_type == tokentype); } + + return JSON_SUCCESS; } @@ -3840,7 +3904,7 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, PG_RETURN_NULL(); } -static void +static JsonParseErrorType populate_recordset_object_start(void *state) { PopulateRecordsetState *_state = (PopulateRecordsetState *) state; @@ -3856,7 +3920,7 @@ populate_recordset_object_start(void *state) /* Nested objects require no special processing */ if (lex_level > 1) - return; + return JSON_SUCCESS; /* Object at level 1: set up a new hash table for this object */ ctl.keysize = NAMEDATALEN; @@ -3866,9 +3930,11 @@ populate_recordset_object_start(void *state) 100, &ctl, HASH_ELEM | HASH_STRINGS | HASH_CONTEXT); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType populate_recordset_object_end(void *state) { PopulateRecordsetState *_state = (PopulateRecordsetState *) state; @@ -3876,7 +3942,7 @@ populate_recordset_object_end(void *state) /* Nested objects require no special processing */ if (_state->lex->lex_level > 1) - return; + return JSON_SUCCESS; obj.is_json = true; obj.val.json_hash = _state->json_hash; @@ -3887,9 +3953,11 @@ populate_recordset_object_end(void *state) /* Done with hash for this object */ hash_destroy(_state->json_hash); _state->json_hash = NULL; + + return JSON_SUCCESS; } -static void +static JsonParseErrorType populate_recordset_array_element_start(void *state, bool isnull) { PopulateRecordsetState *_state = (PopulateRecordsetState *) state; @@ -3900,15 +3968,18 @@ populate_recordset_array_element_start(void *state, bool isnull) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("argument of %s must be an array of objects", _state->function_name))); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType populate_recordset_array_start(void *state) { /* nothing to do */ + return JSON_SUCCESS; } -static void +static JsonParseErrorType populate_recordset_scalar(void *state, char *token, JsonTokenType tokentype) { PopulateRecordsetState *_state = (PopulateRecordsetState *) state; @@ -3921,15 +3992,17 @@ populate_recordset_scalar(void *state, char *token, JsonTokenType tokentype) if (_state->lex->lex_level == 2) _state->saved_scalar = token; + + return JSON_SUCCESS; } -static void +static JsonParseErrorType populate_recordset_object_field_start(void *state, char *fname, bool isnull) { PopulateRecordsetState *_state = (PopulateRecordsetState *) state; if (_state->lex->lex_level > 2) - return; + return JSON_SUCCESS; _state->saved_token_type = _state->lex->token_type; @@ -3942,9 +4015,11 @@ populate_recordset_object_field_start(void *state, char *fname, bool isnull) { _state->save_json_start = NULL; } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType populate_recordset_object_field_end(void *state, char *fname, bool isnull) { PopulateRecordsetState *_state = (PopulateRecordsetState *) state; @@ -3955,7 +4030,7 @@ populate_recordset_object_field_end(void *state, char *fname, bool isnull) * Ignore nested fields. */ if (_state->lex->lex_level > 2) - return; + return JSON_SUCCESS; /* * Ignore field names >= NAMEDATALEN - they can't match a record field. @@ -3965,7 +4040,7 @@ populate_recordset_object_field_end(void *state, char *fname, bool isnull) * has previously insisted on exact equality, so we keep this behavior.) */ if (strlen(fname) >= NAMEDATALEN) - return; + return JSON_SUCCESS; hashentry = hash_search(_state->json_hash, fname, HASH_ENTER, &found); @@ -3991,6 +4066,8 @@ populate_recordset_object_field_end(void *state, char *fname, bool isnull) /* must have had a scalar instead */ hashentry->val = _state->saved_scalar; } + + return JSON_SUCCESS; } /* @@ -4002,39 +4079,47 @@ populate_recordset_object_field_end(void *state, char *fname, bool isnull) * is called. */ -static void +static JsonParseErrorType sn_object_start(void *state) { StripnullState *_state = (StripnullState *) state; appendStringInfoCharMacro(_state->strval, '{'); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType sn_object_end(void *state) { StripnullState *_state = (StripnullState *) state; appendStringInfoCharMacro(_state->strval, '}'); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType sn_array_start(void *state) { StripnullState *_state = (StripnullState *) state; appendStringInfoCharMacro(_state->strval, '['); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType sn_array_end(void *state) { StripnullState *_state = (StripnullState *) state; appendStringInfoCharMacro(_state->strval, ']'); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType sn_object_field_start(void *state, char *fname, bool isnull) { StripnullState *_state = (StripnullState *) state; @@ -4047,7 +4132,7 @@ sn_object_field_start(void *state, char *fname, bool isnull) * object or array. The flag will be reset in the scalar action. */ _state->skip_next_null = true; - return; + return JSON_SUCCESS; } if (_state->strval->data[_state->strval->len - 1] != '{') @@ -4060,18 +4145,22 @@ sn_object_field_start(void *state, char *fname, bool isnull) escape_json(_state->strval, fname); appendStringInfoCharMacro(_state->strval, ':'); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType sn_array_element_start(void *state, bool isnull) { StripnullState *_state = (StripnullState *) state; if (_state->strval->data[_state->strval->len - 1] != '[') appendStringInfoCharMacro(_state->strval, ','); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType sn_scalar(void *state, char *token, JsonTokenType tokentype) { StripnullState *_state = (StripnullState *) state; @@ -4080,13 +4169,15 @@ sn_scalar(void *state, char *token, JsonTokenType tokentype) { Assert(tokentype == JSON_TOKEN_NULL); _state->skip_next_null = false; - return; + return JSON_SUCCESS; } if (tokentype == JSON_TOKEN_STRING) escape_json(_state->strval, token); else appendStringInfoString(_state->strval, token); + + return JSON_SUCCESS; } /* @@ -5326,7 +5417,7 @@ iterate_json_values(text *json, uint32 flags, void *action_state, * An auxiliary function for iterate_json_values to invoke a specified * JsonIterateStringValuesAction for specified values. */ -static void +static JsonParseErrorType iterate_values_scalar(void *state, char *token, JsonTokenType tokentype) { IterateJsonStringValuesState *_state = (IterateJsonStringValuesState *) state; @@ -5350,9 +5441,11 @@ iterate_values_scalar(void *state, char *token, JsonTokenType tokentype) /* do not call callback for any other token */ break; } + + return JSON_SUCCESS; } -static void +static JsonParseErrorType iterate_values_object_field_start(void *state, char *fname, bool isnull) { IterateJsonStringValuesState *_state = (IterateJsonStringValuesState *) state; @@ -5363,6 +5456,8 @@ iterate_values_object_field_start(void *state, char *fname, bool isnull) _state->action(_state->action_state, val, strlen(val)); } + + return JSON_SUCCESS; } /* @@ -5430,7 +5525,6 @@ transform_json_string_values(text *json, void *action_state, state->action_state = action_state; sem->semstate = (void *) state; - sem->scalar = transform_string_values_scalar; sem->object_start = transform_string_values_object_start; sem->object_end = transform_string_values_object_end; sem->array_start = transform_string_values_array_start; @@ -5449,39 +5543,47 @@ transform_json_string_values(text *json, void *action_state, * specified JsonTransformStringValuesAction for all values and left everything * else untouched. */ -static void +static JsonParseErrorType transform_string_values_object_start(void *state) { TransformJsonStringValuesState *_state = (TransformJsonStringValuesState *) state; appendStringInfoCharMacro(_state->strval, '{'); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType transform_string_values_object_end(void *state) { TransformJsonStringValuesState *_state = (TransformJsonStringValuesState *) state; appendStringInfoCharMacro(_state->strval, '}'); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType transform_string_values_array_start(void *state) { TransformJsonStringValuesState *_state = (TransformJsonStringValuesState *) state; appendStringInfoCharMacro(_state->strval, '['); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType transform_string_values_array_end(void *state) { TransformJsonStringValuesState *_state = (TransformJsonStringValuesState *) state; appendStringInfoCharMacro(_state->strval, ']'); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType transform_string_values_object_field_start(void *state, char *fname, bool isnull) { TransformJsonStringValuesState *_state = (TransformJsonStringValuesState *) state; @@ -5495,18 +5597,22 @@ transform_string_values_object_field_start(void *state, char *fname, bool isnull */ escape_json(_state->strval, fname); appendStringInfoCharMacro(_state->strval, ':'); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType transform_string_values_array_element_start(void *state, bool isnull) { TransformJsonStringValuesState *_state = (TransformJsonStringValuesState *) state; if (_state->strval->data[_state->strval->len - 1] != '[') appendStringInfoCharMacro(_state->strval, ','); + + return JSON_SUCCESS; } -static void +static JsonParseErrorType transform_string_values_scalar(void *state, char *token, JsonTokenType tokentype) { TransformJsonStringValuesState *_state = (TransformJsonStringValuesState *) state; @@ -5519,4 +5625,6 @@ transform_string_values_scalar(void *state, char *token, JsonTokenType tokentype } else appendStringInfoString(_state->strval, token); + + return JSON_SUCCESS; } |