1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-19 13:42:17 +03:00

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
This commit is contained in:
Tom Lane
2022-12-11 10:39:05 -05:00
parent d02ef65bce
commit 50428a301d
5 changed files with 342 additions and 168 deletions

View File

@@ -63,13 +63,13 @@ typedef struct JsonbAggState
static inline Datum jsonb_from_cstring(char *json, int len);
static size_t checkStringLen(size_t len);
static void jsonb_in_object_start(void *pstate);
static void jsonb_in_object_end(void *pstate);
static void jsonb_in_array_start(void *pstate);
static void jsonb_in_array_end(void *pstate);
static void jsonb_in_object_field_start(void *pstate, char *fname, bool isnull);
static JsonParseErrorType jsonb_in_object_start(void *pstate);
static JsonParseErrorType jsonb_in_object_end(void *pstate);
static JsonParseErrorType jsonb_in_array_start(void *pstate);
static JsonParseErrorType jsonb_in_array_end(void *pstate);
static JsonParseErrorType jsonb_in_object_field_start(void *pstate, char *fname, bool isnull);
static void jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal);
static void jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype);
static JsonParseErrorType jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype);
static void jsonb_categorize_type(Oid typoid,
JsonbTypeCategory *tcategory,
Oid *outfuncoid);
@@ -291,39 +291,47 @@ checkStringLen(size_t len)
return len;
}
static void
static JsonParseErrorType
jsonb_in_object_start(void *pstate)
{
JsonbInState *_state = (JsonbInState *) pstate;
_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_OBJECT, NULL);
return JSON_SUCCESS;
}
static void
static JsonParseErrorType
jsonb_in_object_end(void *pstate)
{
JsonbInState *_state = (JsonbInState *) pstate;
_state->res = pushJsonbValue(&_state->parseState, WJB_END_OBJECT, NULL);
return JSON_SUCCESS;
}
static void
static JsonParseErrorType
jsonb_in_array_start(void *pstate)
{
JsonbInState *_state = (JsonbInState *) pstate;
_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, NULL);
return JSON_SUCCESS;
}
static void
static JsonParseErrorType
jsonb_in_array_end(void *pstate)
{
JsonbInState *_state = (JsonbInState *) pstate;
_state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
return JSON_SUCCESS;
}
static void
static JsonParseErrorType
jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
{
JsonbInState *_state = (JsonbInState *) pstate;
@@ -335,6 +343,8 @@ jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
v.val.string.val = fname;
_state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v);
return JSON_SUCCESS;
}
static void
@@ -367,7 +377,7 @@ jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal)
/*
* For jsonb we always want the de-escaped value - that's what's in token
*/
static void
static JsonParseErrorType
jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
{
JsonbInState *_state = (JsonbInState *) pstate;
@@ -443,6 +453,8 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
elog(ERROR, "unexpected parent of nested structure");
}
}
return JSON_SUCCESS;
}
/*