aboutsummaryrefslogtreecommitdiff
path: root/src/include/utils/jsonapi.h
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2020-01-27 11:03:21 -0500
committerRobert Haas <rhaas@postgresql.org>2020-01-27 11:04:51 -0500
commit1f3a021730be98b880d94cabbe21de7e4d8136f5 (patch)
treea1eacb3d158bef0a800bb751906bc2640e5eb908 /src/include/utils/jsonapi.h
parent3e4818e9dd5be294d97ca67012528cb1c0b0ccaa (diff)
downloadpostgresql-1f3a021730be98b880d94cabbe21de7e4d8136f5.tar.gz
postgresql-1f3a021730be98b880d94cabbe21de7e4d8136f5.zip
Adjust pg_parse_json() so that it does not directly ereport().
Instead, it now returns a value indicating either success or the type of error which occurred. The old behavior is still available by calling pg_parse_json_or_ereport(). If the new interface is used, an error can be thrown by passing the return value of pg_parse_json() to json_ereport_error(). pg_parse_json() can still elog() in can't-happen cases, but it seems like that issue is best handled separately. Adjust json_lex() and json_count_array_elements() to return an error code, too. This is all in preparation for making the backend's json parser available to frontend code. Reviewed and/or tested by Mark Dilger and Andrew Dunstan. Discussion: http://postgr.es/m/CA+TgmoYfOXhd27MUDGioVh6QtpD0C1K-f6ObSA10AWiHBAL5bA@mail.gmail.com
Diffstat (limited to 'src/include/utils/jsonapi.h')
-rw-r--r--src/include/utils/jsonapi.h46
1 files changed, 43 insertions, 3 deletions
diff --git a/src/include/utils/jsonapi.h b/src/include/utils/jsonapi.h
index bbca121bb72..74dc35c41c6 100644
--- a/src/include/utils/jsonapi.h
+++ b/src/include/utils/jsonapi.h
@@ -33,6 +33,28 @@ typedef enum
JSON_TOKEN_END
} JsonTokenType;
+typedef enum
+{
+ JSON_SUCCESS,
+ JSON_ESCAPING_INVALID,
+ JSON_ESCAPING_REQUIRED,
+ JSON_EXPECTED_ARRAY_FIRST,
+ JSON_EXPECTED_ARRAY_NEXT,
+ JSON_EXPECTED_COLON,
+ JSON_EXPECTED_END,
+ JSON_EXPECTED_JSON,
+ JSON_EXPECTED_MORE,
+ JSON_EXPECTED_OBJECT_FIRST,
+ JSON_EXPECTED_OBJECT_NEXT,
+ JSON_EXPECTED_STRING,
+ JSON_INVALID_TOKEN,
+ JSON_UNICODE_CODE_POINT_ZERO,
+ JSON_UNICODE_ESCAPE_FORMAT,
+ JSON_UNICODE_HIGH_ESCAPE,
+ JSON_UNICODE_HIGH_SURROGATE,
+ JSON_UNICODE_LOW_SURROGATE
+} JsonParseErrorType;
+
/*
* All the fields in this structure should be treated as read-only.
@@ -101,7 +123,14 @@ typedef struct JsonSemAction
* points to. If the action pointers are NULL the parser
* does nothing and just continues.
*/
-extern void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem);
+extern JsonParseErrorType pg_parse_json(JsonLexContext *lex,
+ JsonSemAction *sem);
+
+/*
+ * Same thing, but signal errors via ereport(ERROR) instead of returning
+ * a result code.
+ */
+extern void pg_parse_json_or_ereport(JsonLexContext *lex, JsonSemAction *sem);
/* the null action object used for pure validation */
extern JsonSemAction nullSemAction;
@@ -110,8 +139,13 @@ extern JsonSemAction nullSemAction;
* json_count_array_elements performs a fast secondary parse to determine the
* number of elements in passed array lex context. It should be called from an
* array_start action.
+ *
+ * The return value indicates whether any error occurred, while the number
+ * of elements is stored into *elements (but only if the return value is
+ * JSON_SUCCESS).
*/
-extern int json_count_array_elements(JsonLexContext *lex);
+extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex,
+ int *elements);
/*
* constructors for JsonLexContext, with or without strval element.
@@ -128,7 +162,13 @@ extern JsonLexContext *makeJsonLexContextCstringLen(char *json,
bool need_escapes);
/* lex one token */
-extern void json_lex(JsonLexContext *lex);
+extern JsonParseErrorType json_lex(JsonLexContext *lex);
+
+/* report an error during json lexing or parsing */
+extern void json_ereport_error(JsonParseErrorType error, JsonLexContext *lex);
+
+/* construct an error detail string for a json error */
+extern char *json_errdetail(JsonParseErrorType error, JsonLexContext *lex);
/*
* Utility function to check if a string is a valid JSON number.