jsonapi: Use const char *
authorPeter Eisentraut <[email protected]>
Fri, 21 Jun 2024 05:50:02 +0000 (07:50 +0200)
committerPeter Eisentraut <[email protected]>
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 <[email protected]>
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);