jsonapi: Use const char *
authorPeter Eisentraut <peter@eisentraut.org>
Fri, 21 Jun 2024 05:50:02 +0000 (07:50 +0200)
committerPeter Eisentraut <peter@eisentraut.org>
Fri, 21 Jun 2024 05:53:30 +0000 (07:53 +0200)
Apply const qualifiers to char * arguments and fields throughout the
jsonapi.  This allows the top-level APIs such as
pg_parse_json_incremental() to declare their input argument as const.
It also reduces the number of unconstify() calls.

Reviewed-by: Andrew Dunstan <andrew@dunslane.net>
Discussion: https://www.postgresql.org/message-id/flat/f732b014-f614-4600-a437-dba5a2c3738b%40eisentraut.org

src/backend/utils/adt/jsonfuncs.c
src/common/jsonapi.c
src/include/common/jsonapi.h

index 83125b06a4395a9a06d4ff791b1cb0ce01a63292..ab5aa0ccb8a9b943e7f2e15d35a503797c320fab 100644 (file)
@@ -86,7 +86,7 @@ typedef struct GetState
 {
        JsonLexContext *lex;
        text       *tresult;
-       char       *result_start;
+       const char *result_start;
        bool            normalize_results;
        bool            next_scalar;
        int                     npath;                  /* length of each path-related array */
@@ -111,7 +111,7 @@ typedef struct EachState
        Tuplestorestate *tuple_store;
        TupleDesc       ret_tdesc;
        MemoryContext tmp_cxt;
-       char       *result_start;
+       const char *result_start;
        bool            normalize_results;
        bool            next_scalar;
        char       *normalized_scalar;
@@ -125,7 +125,7 @@ typedef struct ElementsState
        Tuplestorestate *tuple_store;
        TupleDesc       ret_tdesc;
        MemoryContext tmp_cxt;
-       char       *result_start;
+       const char *result_start;
        bool            normalize_results;
        bool            next_scalar;
        char       *normalized_scalar;
@@ -138,7 +138,7 @@ typedef struct JHashState
        const char *function_name;
        HTAB       *hash;
        char       *saved_scalar;
-       char       *save_json_start;
+       const char *save_json_start;
        JsonTokenType saved_token_type;
 } JHashState;
 
@@ -247,7 +247,7 @@ typedef struct PopulateRecordsetState
        const char *function_name;
        HTAB       *json_hash;
        char       *saved_scalar;
-       char       *save_json_start;
+       const char *save_json_start;
        JsonTokenType saved_token_type;
        Tuplestorestate *tuple_store;
        HeapTupleHeader rec;
@@ -273,7 +273,7 @@ typedef struct PopulateArrayState
 {
        JsonLexContext *lex;            /* json lexer */
        PopulateArrayContext *ctx;      /* context */
-       char       *element_start;      /* start of the current array element */
+       const char *element_start;      /* start of the current array element */
        char       *element_scalar; /* current array element token if it is a
                                                                 * scalar */
        JsonTokenType element_type; /* current array element type */
@@ -295,7 +295,7 @@ typedef struct JsValue
        {
                struct
                {
-                       char       *str;        /* json string */
+                       const char *str;        /* json string */
                        int                     len;    /* json string length or -1 if null-terminated */
                        JsonTokenType type; /* json type */
                }                       json;           /* json value */
@@ -390,7 +390,7 @@ 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,
+static HTAB *get_json_object_as_hash(const char *json, int len, const char *funcname,
                                                                         Node *escontext);
 
 /* semantic actions for populate_array_json */
@@ -456,7 +456,7 @@ static Datum populate_record_field(ColumnIOData *col, Oid typid, int32 typmod,
 static RecordIOData *allocate_record_info(MemoryContext mcxt, int ncolumns);
 static bool JsObjectGetField(JsObject *obj, char *field, JsValue *jsv);
 static void populate_recordset_record(PopulateRecordsetState *state, JsObject *obj);
-static bool populate_array_json(PopulateArrayContext *ctx, char *json, int len);
+static bool populate_array_json(PopulateArrayContext *ctx, const char *json, int len);
 static bool populate_array_dim_jsonb(PopulateArrayContext *ctx, JsonbValue *jbv,
                                                                         int ndim);
 static void populate_array_report_expected_array(PopulateArrayContext *ctx, int ndim);
@@ -1181,7 +1181,7 @@ get_object_end(void *state)
        if (lex_level == 0 && _state->npath == 0)
        {
                /* Special case: return the entire object */
-               char       *start = _state->result_start;
+               const char *start = _state->result_start;
                int                     len = _state->lex->prev_token_terminator - start;
 
                _state->tresult = cstring_to_text_with_len(start, len);
@@ -1275,7 +1275,7 @@ get_object_field_end(void *state, char *fname, bool isnull)
                        _state->tresult = (text *) NULL;
                else
                {
-                       char       *start = _state->result_start;
+                       const char *start = _state->result_start;
                        int                     len = _state->lex->prev_token_terminator - start;
 
                        _state->tresult = cstring_to_text_with_len(start, len);
@@ -1337,7 +1337,7 @@ get_array_end(void *state)
        if (lex_level == 0 && _state->npath == 0)
        {
                /* Special case: return the entire array */
-               char       *start = _state->result_start;
+               const char *start = _state->result_start;
                int                     len = _state->lex->prev_token_terminator - start;
 
                _state->tresult = cstring_to_text_with_len(start, len);
@@ -1426,7 +1426,7 @@ get_array_element_end(void *state, bool isnull)
                        _state->tresult = (text *) NULL;
                else
                {
-                       char       *start = _state->result_start;
+                       const char *start = _state->result_start;
                        int                     len = _state->lex->prev_token_terminator - start;
 
                        _state->tresult = cstring_to_text_with_len(start, len);
@@ -1463,7 +1463,7 @@ get_scalar(void *state, char *token, JsonTokenType tokentype)
                         * scalar token, but not whitespace before it.  Probably not worth
                         * doing our own space-skipping to avoid that.
                         */
-                       char       *start = _state->lex->input;
+                       const char *start = _state->lex->input;
                        int                     len = _state->lex->prev_token_terminator - start;
 
                        _state->tresult = cstring_to_text_with_len(start, len);
@@ -2782,7 +2782,7 @@ populate_array_scalar(void *_state, char *token, JsonTokenType tokentype)
  * Returns false if an error occurs when parsing.
  */
 static bool
-populate_array_json(PopulateArrayContext *ctx, char *json, int len)
+populate_array_json(PopulateArrayContext *ctx, const char *json, int len)
 {
        PopulateArrayState state;
        JsonSemAction sem;
@@ -3123,7 +3123,7 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv,
 {
        Datum           res;
        char       *str = NULL;
-       char       *json = NULL;
+       const char *json = NULL;
 
        if (jsv->is_json)
        {
@@ -3139,7 +3139,10 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv,
                        str[len] = '\0';
                }
                else
-                       str = json;                     /* string is already null-terminated */
+               {
+                       /* string is already null-terminated */
+                       str = unconstify(char *, json);
+               }
 
                /* If converting to json/jsonb, make string into valid JSON literal */
                if ((typid == JSONOID || typid == JSONBOID) &&
@@ -3784,7 +3787,7 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname,
  * Returns the hash table if the json is parsed successfully, NULL otherwise.
  */
 static HTAB *
-get_json_object_as_hash(char *json, int len, const char *funcname,
+get_json_object_as_hash(const char *json, int len, const char *funcname,
                                                Node *escontext)
 {
        HASHCTL         ctl;
index f71c1c54b2a5c18690a4189ba0c1f4e1e82aff41..0c6374b0fc265b091afcdb149d5abffdb1725d05 100644 (file)
@@ -211,7 +211,7 @@ static td_entry td_parser_table[JSON_NUM_NONTERMINALS][JSON_NUM_TERMINALS] =
 static char JSON_PROD_GOAL[] = {JSON_TOKEN_END, JSON_NT_JSON, 0};
 
 static inline JsonParseErrorType json_lex_string(JsonLexContext *lex);
-static inline JsonParseErrorType json_lex_number(JsonLexContext *lex, char *s,
+static inline JsonParseErrorType json_lex_number(JsonLexContext *lex, const char *s,
                                                                                                 bool *num_err, size_t *total_len);
 static inline JsonParseErrorType parse_scalar(JsonLexContext *lex, JsonSemAction *sem);
 static JsonParseErrorType parse_object_field(JsonLexContext *lex, JsonSemAction *sem);
@@ -290,12 +290,12 @@ IsValidJsonNumber(const char *str, size_t len)
         */
        if (*str == '-')
        {
-               dummy_lex.input = unconstify(char *, str) + 1;
+               dummy_lex.input = str + 1;
                dummy_lex.input_length = len - 1;
        }
        else
        {
-               dummy_lex.input = unconstify(char *, str);
+               dummy_lex.input = str;
                dummy_lex.input_length = len;
        }
 
@@ -323,7 +323,7 @@ IsValidJsonNumber(const char *str, size_t len)
  * cleanup.
  */
 JsonLexContext *
-makeJsonLexContextCstringLen(JsonLexContext *lex, char *json,
+makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json,
                                                         size_t len, int encoding, bool need_escapes)
 {
        if (lex == NULL)
@@ -649,7 +649,7 @@ json_count_array_elements(JsonLexContext *lex, int *elements)
 JsonParseErrorType
 pg_parse_json_incremental(JsonLexContext *lex,
                                                  JsonSemAction *sem,
-                                                 char *json,
+                                                 const char *json,
                                                  size_t len,
                                                  bool is_last)
 {
@@ -1308,8 +1308,8 @@ parse_array(JsonLexContext *lex, JsonSemAction *sem)
 JsonParseErrorType
 json_lex(JsonLexContext *lex)
 {
-       char       *s;
-       char       *const end = lex->input + lex->input_length;
+       const char *s;
+       const char *const end = lex->input + lex->input_length;
        JsonParseErrorType result;
 
        if (lex->incremental && lex->inc_state->partial_completed)
@@ -1593,7 +1593,7 @@ json_lex(JsonLexContext *lex)
                                break;
                        default:
                                {
-                                       char       *p;
+                                       const char *p;
 
                                        /*
                                         * We're not dealing with a string, number, legal
@@ -1671,8 +1671,8 @@ json_lex(JsonLexContext *lex)
 static inline JsonParseErrorType
 json_lex_string(JsonLexContext *lex)
 {
-       char       *s;
-       char       *const end = lex->input + lex->input_length;
+       const char *s;
+       const char *const end = lex->input + lex->input_length;
        int                     hi_surrogate = -1;
 
        /* Convenience macros for error exits */
@@ -1689,7 +1689,7 @@ json_lex_string(JsonLexContext *lex)
        } while (0)
 #define FAIL_AT_CHAR_END(code) \
        do { \
-               char       *term = s + pg_encoding_mblen(lex->input_encoding, s); \
+               const char         *term = s + pg_encoding_mblen(lex->input_encoding, s); \
                lex->token_terminator = (term <= end) ? term : end; \
                return code; \
        } while (0)
@@ -1854,7 +1854,7 @@ json_lex_string(JsonLexContext *lex)
                }
                else
                {
-                       char       *p = s;
+                       const char *p = s;
 
                        if (hi_surrogate != -1)
                                FAIL_AT_CHAR_END(JSON_UNICODE_LOW_SURROGATE);
@@ -1940,7 +1940,7 @@ json_lex_string(JsonLexContext *lex)
  * the distance from lex->input to the token end+1 is returned to *total_len.
  */
 static inline JsonParseErrorType
-json_lex_number(JsonLexContext *lex, char *s,
+json_lex_number(JsonLexContext *lex, const char *s,
                                bool *num_err, size_t *total_len)
 {
        bool            error = false;
index 5d3ae4e09b8f76ea118e63a0e2c301136f2c1489..71a491d72dc0eb55baaa050085a546518a5d480e 100644 (file)
@@ -88,18 +88,18 @@ typedef struct JsonIncrementalState JsonIncrementalState;
 #define JSONLEX_FREE_STRVAL                    (1 << 1)
 typedef struct JsonLexContext
 {
-       char       *input;
+       const char *input;
        size_t          input_length;
        int                     input_encoding;
-       char       *token_start;
-       char       *token_terminator;
-       char       *prev_token_terminator;
+       const char *token_start;
+       const char *token_terminator;
+       const char *prev_token_terminator;
        bool            incremental;
        JsonTokenType token_type;
        int                     lex_level;
        bits32          flags;
        int                     line_number;    /* line number, starting from 1 */
-       char       *line_start;         /* where that line starts within input */
+       const char *line_start;         /* where that line starts within input */
        JsonParserStack *pstack;
        JsonIncrementalState *inc_state;
        StringInfo      strval;
@@ -157,7 +157,7 @@ extern JsonParseErrorType pg_parse_json(JsonLexContext *lex,
 
 extern JsonParseErrorType pg_parse_json_incremental(JsonLexContext *lex,
                                                                                                        JsonSemAction *sem,
-                                                                                                       char *json,
+                                                                                                       const char *json,
                                                                                                        size_t len,
                                                                                                        bool is_last);
 
@@ -192,7 +192,7 @@ extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex,
  * cleanup.
  */
 extern JsonLexContext *makeJsonLexContextCstringLen(JsonLexContext *lex,
-                                                                                                       char *json,
+                                                                                                       const char *json,
                                                                                                        size_t len,
                                                                                                        int encoding,
                                                                                                        bool need_escapes);