Skip to content

Commit 50428a3

Browse files
committed
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
1 parent d02ef65 commit 50428a3

File tree

5 files changed

+342
-168
lines changed

5 files changed

+342
-168
lines changed

src/backend/utils/adt/jsonb.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ typedef struct JsonbAggState
6363

6464
static inline Datum jsonb_from_cstring(char *json, int len);
6565
static size_t checkStringLen(size_t len);
66-
static void jsonb_in_object_start(void *pstate);
67-
static void jsonb_in_object_end(void *pstate);
68-
static void jsonb_in_array_start(void *pstate);
69-
static void jsonb_in_array_end(void *pstate);
70-
static void jsonb_in_object_field_start(void *pstate, char *fname, bool isnull);
66+
static JsonParseErrorType jsonb_in_object_start(void *pstate);
67+
static JsonParseErrorType jsonb_in_object_end(void *pstate);
68+
static JsonParseErrorType jsonb_in_array_start(void *pstate);
69+
static JsonParseErrorType jsonb_in_array_end(void *pstate);
70+
static JsonParseErrorType jsonb_in_object_field_start(void *pstate, char *fname, bool isnull);
7171
static void jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal);
72-
static void jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype);
72+
static JsonParseErrorType jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype);
7373
static void jsonb_categorize_type(Oid typoid,
7474
JsonbTypeCategory *tcategory,
7575
Oid *outfuncoid);
@@ -291,39 +291,47 @@ checkStringLen(size_t len)
291291
return len;
292292
}
293293

294-
static void
294+
static JsonParseErrorType
295295
jsonb_in_object_start(void *pstate)
296296
{
297297
JsonbInState *_state = (JsonbInState *) pstate;
298298

299299
_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_OBJECT, NULL);
300+
301+
return JSON_SUCCESS;
300302
}
301303

302-
static void
304+
static JsonParseErrorType
303305
jsonb_in_object_end(void *pstate)
304306
{
305307
JsonbInState *_state = (JsonbInState *) pstate;
306308

307309
_state->res = pushJsonbValue(&_state->parseState, WJB_END_OBJECT, NULL);
310+
311+
return JSON_SUCCESS;
308312
}
309313

310-
static void
314+
static JsonParseErrorType
311315
jsonb_in_array_start(void *pstate)
312316
{
313317
JsonbInState *_state = (JsonbInState *) pstate;
314318

315319
_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, NULL);
320+
321+
return JSON_SUCCESS;
316322
}
317323

318-
static void
324+
static JsonParseErrorType
319325
jsonb_in_array_end(void *pstate)
320326
{
321327
JsonbInState *_state = (JsonbInState *) pstate;
322328

323329
_state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
330+
331+
return JSON_SUCCESS;
324332
}
325333

326-
static void
334+
static JsonParseErrorType
327335
jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
328336
{
329337
JsonbInState *_state = (JsonbInState *) pstate;
@@ -335,6 +343,8 @@ jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
335343
v.val.string.val = fname;
336344

337345
_state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v);
346+
347+
return JSON_SUCCESS;
338348
}
339349

340350
static void
@@ -367,7 +377,7 @@ jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal)
367377
/*
368378
* For jsonb we always want the de-escaped value - that's what's in token
369379
*/
370-
static void
380+
static JsonParseErrorType
371381
jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
372382
{
373383
JsonbInState *_state = (JsonbInState *) pstate;
@@ -443,6 +453,8 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
443453
elog(ERROR, "unexpected parent of nested structure");
444454
}
445455
}
456+
457+
return JSON_SUCCESS;
446458
}
447459

448460
/*

0 commit comments

Comments
 (0)