Be clearer about when jsonapi's need_escapes is needed
authorAndrew Dunstan <[email protected]>
Sun, 19 Jan 2025 14:09:58 +0000 (09:09 -0500)
committerAndrew Dunstan <[email protected]>
Sun, 19 Jan 2025 14:09:58 +0000 (09:09 -0500)
Most operations beyond pure json parsing need to set need_escapes to
true to get access to field names and string scalars. Document this
fact more explicitly.

Slightly tweaked  from:

Author: Corey Huinker <[email protected]>

Discussion: https://postgr.es/m/CADkLM=c49Vkfg2+A8ubSuEtaGEjuaKZXCA6SrXA8kdwHjx3uxQ@mail.gmail.com

src/common/jsonapi.c
src/include/common/jsonapi.h

index 1069e8c5b3ff429fad60b23d42656b5505633857..f1c80933c92cd626f9b33c7e222673a91bda0ec1 100644 (file)
@@ -1297,7 +1297,10 @@ parse_scalar(JsonLexContext *lex, const JsonSemAction *sem)
                return result;
        }
 
-       /* invoke the callback, which may take ownership of val */
+       /*
+        * invoke the callback, which may take ownership of val. For string
+        * values, val is NULL if need_escapes is false.
+        */
        result = (*sfunc) (sem->semstate, val, tok);
 
        if (lex->flags & JSONLEX_CTX_OWNS_TOKENS)
@@ -1326,6 +1329,7 @@ parse_object_field(JsonLexContext *lex, const JsonSemAction *sem)
                return report_parse_error(JSON_PARSE_STRING, lex);
        if ((ostart != NULL || oend != NULL) && lex->need_escapes)
        {
+               /* fname is NULL if need_escapes is false */
                fname = STRDUP(lex->strval->data);
                if (fname == NULL)
                        return JSON_OUT_OF_MEMORY;
index c3a1b04ca718028b1dd97613de2c1584afe88ab0..5d1a3ef3833bd11ee8393cf028c6dbe4d490f0bc 100644 (file)
@@ -118,6 +118,12 @@ typedef struct JsonLexContext
        struct jsonapi_StrValType *errormsg;
 } JsonLexContext;
 
+/*
+ * Function types for custom json parsing actions.
+ *
+ * fname will be NULL if the context has need_escapes=false, as will token for
+ * string type values.
+ */
 typedef JsonParseErrorType (*json_struct_action) (void *state);
 typedef JsonParseErrorType (*json_ofield_action) (void *state, char *fname, bool isnull);
 typedef JsonParseErrorType (*json_aelem_action) (void *state, bool isnull);
@@ -197,12 +203,17 @@ extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex,
  * struct is allocated.
  *
  * If need_escapes is true, ->strval stores the unescaped lexemes.
+ *
+ * Setting need_escapes to true is necessary if the operation needs
+ * to reference field names or scalar string values. This is true of most
+ * operations beyond purely checking the json-validity of the source
+ * document.
+ *
  * Unescaping is expensive, so only request it when necessary.
  *
  * If need_escapes is true or lex was given as NULL, then the caller is
  * responsible for freeing the returned struct, either by calling
- * freeJsonLexContext() or (in backend environment) via memory context
- * cleanup.
+ * freeJsonLexContext() or (in backends) via memory context cleanup.
  */
 extern JsonLexContext *makeJsonLexContextCstringLen(JsonLexContext *lex,
                                                                                                        const char *json,