PostgreSQL Source Code git master
jsonapi.h
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * jsonapi.h
4 * Declarations for JSON API support.
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * src/include/common/jsonapi.h
10 *
11 *-------------------------------------------------------------------------
12 */
13
14#ifndef JSONAPI_H
15#define JSONAPI_H
16
17typedef enum JsonTokenType
18{
33
35{
59 JSON_SEM_ACTION_FAILED, /* error should already be reported */
61
62/* Parser state private to jsonapi.c */
65
66/*
67 * Don't depend on the internal type header for strval; if callers need access
68 * then they can include the appropriate header themselves.
69 */
70#ifdef JSONAPI_USE_PQEXPBUFFER
71#define jsonapi_StrValType PQExpBufferData
72#else
73#define jsonapi_StrValType StringInfoData
74#endif
75
76/*
77 * All the fields in this structure should be treated as read-only.
78 *
79 * If strval is not null, then it should contain the de-escaped value
80 * of the lexeme if it's a string. Otherwise most of these field names
81 * should be self-explanatory.
82 *
83 * line_number and line_start are principally for use by the parser's
84 * error reporting routines.
85 * token_terminator and prev_token_terminator point to the character
86 * AFTER the end of the token, i.e. where there would be a nul byte
87 * if we were using nul-terminated strings.
88 *
89 * The prev_token_terminator field should not be used when incremental is
90 * true, as the previous token might have started in a previous piece of input,
91 * and thus it can't be used in any pointer arithmetic or other operations in
92 * conjunction with token_start.
93 *
94 * JSONLEX_FREE_STRUCT/STRVAL are used to drive freeJsonLexContext.
95 * JSONLEX_CTX_OWNS_TOKENS is used by setJsonLexContextOwnsTokens.
96 */
97#define JSONLEX_FREE_STRUCT (1 << 0)
98#define JSONLEX_FREE_STRVAL (1 << 1)
99#define JSONLEX_CTX_OWNS_TOKENS (1 << 2)
100typedef struct JsonLexContext
101{
102 const char *input;
105 const char *token_start;
106 const char *token_terminator;
112 int line_number; /* line number, starting from 1 */
113 const char *line_start; /* where that line starts within input */
117 struct jsonapi_StrValType *strval; /* only used if need_escapes == true */
120
121/*
122 * Function types for custom json parsing actions.
123 *
124 * fname will be NULL if the context has need_escapes=false, as will token for
125 * string type values.
126 */
128typedef JsonParseErrorType (*json_ofield_action) (void *state, char *fname, bool isnull);
129typedef JsonParseErrorType (*json_aelem_action) (void *state, bool isnull);
130typedef JsonParseErrorType (*json_scalar_action) (void *state, char *token, JsonTokenType tokentype);
131
132
133/*
134 * Semantic Action structure for use in parsing json.
135 *
136 * Any of these actions can be NULL, in which case nothing is done at that
137 * point, Likewise, semstate can be NULL. Using an all-NULL structure amounts
138 * to doing a pure parse with no side-effects, and is therefore exactly
139 * what the json input routines do.
140 *
141 * By default, the 'fname' and 'token' strings passed to these actions are
142 * palloc'd. They are not free'd or used further by the parser, so the action
143 * function is free to do what it wishes with them. This behavior may be
144 * modified by setJsonLexContextOwnsTokens().
145 *
146 * All action functions return JsonParseErrorType. If the result isn't
147 * JSON_SUCCESS, the parse is abandoned and that error code is returned.
148 * If it is JSON_SEM_ACTION_FAILED, the action function is responsible
149 * for having reported the error in some appropriate way.
150 */
151typedef struct JsonSemAction
152{
153 void *semstate;
164
165/*
166 * pg_parse_json will parse the string in the lex calling the
167 * action functions in sem at the appropriate points. It is
168 * up to them to keep what state they need in semstate. If they
169 * need access to the state of the lexer, then its pointer
170 * should be passed to them as a member of whatever semstate
171 * points to. If the action pointers are NULL the parser
172 * does nothing and just continues.
173 */
175 const JsonSemAction *sem);
176
178 const JsonSemAction *sem,
179 const char *json,
180 size_t len,
181 bool is_last);
182
183/* the null action object used for pure validation */
185
186/*
187 * json_count_array_elements performs a fast secondary parse to determine the
188 * number of elements in passed array lex context. It should be called from an
189 * array_start action.
190 *
191 * The return value indicates whether any error occurred, while the number
192 * of elements is stored into *elements (but only if the return value is
193 * JSON_SUCCESS).
194 */
196 int *elements);
197
198/*
199 * initializer for JsonLexContext.
200 *
201 * If a valid 'lex' pointer is given, it is initialized. This can be used
202 * for stack-allocated structs, saving overhead. If NULL is given, a new
203 * struct is allocated.
204 *
205 * If need_escapes is true, ->strval stores the unescaped lexemes.
206 *
207 * Setting need_escapes to true is necessary if the operation needs
208 * to reference field names or scalar string values. This is true of most
209 * operations beyond purely checking the json-validity of the source
210 * document.
211 *
212 * Unescaping is expensive, so only request it when necessary.
213 *
214 * If need_escapes is true or lex was given as NULL, then the caller is
215 * responsible for freeing the returned struct, either by calling
216 * freeJsonLexContext() or (in backends) via memory context cleanup.
217 */
219 const char *json,
220 size_t len,
221 int encoding,
222 bool need_escapes);
223
224/*
225 * make a JsonLexContext suitable for incremental parsing.
226 * the string chunks will be handed to pg_parse_json_incremental,
227 * so there's no need for them here.
228 */
230 int encoding,
231 bool need_escapes);
232
233/*
234 * Sets whether tokens passed to semantic action callbacks are owned by the
235 * context (in which case, the callback must duplicate the tokens for long-term
236 * storage) or by the callback (in which case, the callback must explicitly
237 * free tokens to avoid leaks).
238 *
239 * By default, this setting is false: the callback owns the tokens that are
240 * passed to it (and if parsing fails between the two object-field callbacks,
241 * the field name token will likely leak). If set to true, tokens will be freed
242 * by the lexer after the callback completes.
243 *
244 * Setting this to true is important for long-lived clients (such as libpq)
245 * that must not leak memory during a parse failure. For a server backend using
246 * memory contexts, or a client application which will exit on parse failure,
247 * this setting is less critical.
248 */
250 bool owned_by_context);
251
252extern void freeJsonLexContext(JsonLexContext *lex);
253
254/* lex one token */
256
257/* construct an error detail string for a json error */
259
260/*
261 * Utility function to check if a string is a valid JSON number.
262 *
263 * str argument does not need to be nul-terminated.
264 */
265extern bool IsValidJsonNumber(const char *str, size_t len);
266
267#endif /* JSONAPI_H */
#define PGDLLIMPORT
Definition: c.h:1277
uint32 bits32
Definition: c.h:497
const char * str
#define token
Definition: indent_globs.h:126
JsonParseErrorType pg_parse_json_incremental(JsonLexContext *lex, const JsonSemAction *sem, const char *json, size_t len, bool is_last)
Definition: jsonapi.c:868
JsonLexContext * makeJsonLexContextIncremental(JsonLexContext *lex, int encoding, bool need_escapes)
Definition: jsonapi.c:497
bool IsValidJsonNumber(const char *str, size_t len)
Definition: jsonapi.c:339
struct JsonLexContext JsonLexContext
JsonParseErrorType(* json_struct_action)(void *state)
Definition: jsonapi.h:127
JsonParseErrorType(* json_aelem_action)(void *state, bool isnull)
Definition: jsonapi.h:129
JsonParseErrorType pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem)
Definition: jsonapi.c:744
#define jsonapi_StrValType
Definition: jsonapi.h:73
JsonParseErrorType
Definition: jsonapi.h:35
@ JSON_OUT_OF_MEMORY
Definition: jsonapi.h:52
@ JSON_SEM_ACTION_FAILED
Definition: jsonapi.h:59
@ JSON_EXPECTED_ARRAY_FIRST
Definition: jsonapi.h:42
@ JSON_EXPECTED_MORE
Definition: jsonapi.h:47
@ JSON_UNICODE_HIGH_SURROGATE
Definition: jsonapi.h:57
@ JSON_EXPECTED_COLON
Definition: jsonapi.h:44
@ JSON_EXPECTED_OBJECT_FIRST
Definition: jsonapi.h:48
@ JSON_UNICODE_CODE_POINT_ZERO
Definition: jsonapi.h:53
@ JSON_INVALID_LEXER_TYPE
Definition: jsonapi.h:38
@ JSON_EXPECTED_STRING
Definition: jsonapi.h:50
@ JSON_UNICODE_ESCAPE_FORMAT
Definition: jsonapi.h:54
@ JSON_SUCCESS
Definition: jsonapi.h:36
@ JSON_UNICODE_UNTRANSLATABLE
Definition: jsonapi.h:56
@ JSON_EXPECTED_OBJECT_NEXT
Definition: jsonapi.h:49
@ JSON_ESCAPING_REQUIRED
Definition: jsonapi.h:41
@ JSON_EXPECTED_JSON
Definition: jsonapi.h:46
@ JSON_INVALID_TOKEN
Definition: jsonapi.h:51
@ JSON_ESCAPING_INVALID
Definition: jsonapi.h:40
@ JSON_INCOMPLETE
Definition: jsonapi.h:37
@ JSON_EXPECTED_END
Definition: jsonapi.h:45
@ JSON_EXPECTED_ARRAY_NEXT
Definition: jsonapi.h:43
@ JSON_UNICODE_HIGH_ESCAPE
Definition: jsonapi.h:55
@ JSON_NESTING_TOO_DEEP
Definition: jsonapi.h:39
@ JSON_UNICODE_LOW_SURROGATE
Definition: jsonapi.h:58
JsonParseErrorType(* json_ofield_action)(void *state, char *fname, bool isnull)
Definition: jsonapi.h:128
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)
Definition: jsonapi.c:392
void setJsonLexContextOwnsTokens(JsonLexContext *lex, bool owned_by_context)
Definition: jsonapi.c:542
PGDLLIMPORT const JsonSemAction nullSemAction
Definition: jsonapi.c:287
JsonTokenType
Definition: jsonapi.h:18
@ JSON_TOKEN_INVALID
Definition: jsonapi.h:19
@ JSON_TOKEN_COMMA
Definition: jsonapi.h:26
@ JSON_TOKEN_FALSE
Definition: jsonapi.h:29
@ JSON_TOKEN_END
Definition: jsonapi.h:31
@ JSON_TOKEN_TRUE
Definition: jsonapi.h:28
@ JSON_TOKEN_OBJECT_END
Definition: jsonapi.h:23
@ JSON_TOKEN_NULL
Definition: jsonapi.h:30
@ JSON_TOKEN_ARRAY_END
Definition: jsonapi.h:25
@ JSON_TOKEN_OBJECT_START
Definition: jsonapi.h:22
@ JSON_TOKEN_NUMBER
Definition: jsonapi.h:21
@ JSON_TOKEN_STRING
Definition: jsonapi.h:20
@ JSON_TOKEN_COLON
Definition: jsonapi.h:27
@ JSON_TOKEN_ARRAY_START
Definition: jsonapi.h:24
JsonParseErrorType json_lex(JsonLexContext *lex)
Definition: jsonapi.c:1588
JsonParseErrorType(* json_scalar_action)(void *state, char *token, JsonTokenType tokentype)
Definition: jsonapi.h:130
char * json_errdetail(JsonParseErrorType error, JsonLexContext *lex)
Definition: jsonapi.c:2401
JsonParseErrorType json_count_array_elements(JsonLexContext *lex, int *elements)
Definition: jsonapi.c:803
void freeJsonLexContext(JsonLexContext *lex)
Definition: jsonapi.c:687
struct JsonSemAction JsonSemAction
const void size_t len
int32 encoding
Definition: pg_database.h:41
static void error(void)
Definition: sql-dyntest.c:147
bits32 flags
Definition: jsonapi.h:111
int input_encoding
Definition: jsonapi.h:104
const char * prev_token_terminator
Definition: jsonapi.h:107
struct jsonapi_StrValType * strval
Definition: jsonapi.h:117
bool need_escapes
Definition: jsonapi.h:116
struct jsonapi_StrValType * errormsg
Definition: jsonapi.h:118
const char * input
Definition: jsonapi.h:102
const char * token_start
Definition: jsonapi.h:105
JsonParserStack * pstack
Definition: jsonapi.h:114
size_t input_length
Definition: jsonapi.h:103
JsonIncrementalState * inc_state
Definition: jsonapi.h:115
bool incremental
Definition: jsonapi.h:108
const char * line_start
Definition: jsonapi.h:113
int line_number
Definition: jsonapi.h:112
JsonTokenType token_type
Definition: jsonapi.h:109
const char * token_terminator
Definition: jsonapi.h:106
json_struct_action array_end
Definition: jsonapi.h:157
json_struct_action object_start
Definition: jsonapi.h:154
json_ofield_action object_field_start
Definition: jsonapi.h:158
json_aelem_action array_element_start
Definition: jsonapi.h:160
json_scalar_action scalar
Definition: jsonapi.h:162
void * semstate
Definition: jsonapi.h:153
json_aelem_action array_element_end
Definition: jsonapi.h:161
json_struct_action array_start
Definition: jsonapi.h:156
json_struct_action object_end
Definition: jsonapi.h:155
json_ofield_action object_field_end
Definition: jsonapi.h:159
Definition: regguts.h:323
static JsonSemAction sem