24#ifdef JSONAPI_USE_PQEXPBUFFER
35#ifdef JSONAPI_USE_PQEXPBUFFER
37#define STRDUP(s) strdup(s)
38#define ALLOC(size) malloc(size)
39#define ALLOC0(size) calloc(1, size)
40#define REALLOC realloc
41#define FREE(s) free(s)
43#define jsonapi_appendStringInfo appendPQExpBuffer
44#define jsonapi_appendBinaryStringInfo appendBinaryPQExpBuffer
45#define jsonapi_appendStringInfoChar appendPQExpBufferChar
47#define jsonapi_appendStringInfoCharMacro appendPQExpBufferChar
48#define jsonapi_makeStringInfo createPQExpBuffer
49#define jsonapi_initStringInfo initPQExpBuffer
50#define jsonapi_resetStringInfo resetPQExpBuffer
51#define jsonapi_termStringInfo termPQExpBuffer
52#define jsonapi_destroyStringInfo destroyPQExpBuffer
56#define STRDUP(s) pstrdup(s)
57#define ALLOC(size) palloc(size)
58#define ALLOC0(size) palloc0(size)
59#define REALLOC repalloc
76#define jsonapi_appendStringInfo appendStringInfo
77#define jsonapi_appendBinaryStringInfo appendBinaryStringInfo
78#define jsonapi_appendStringInfoChar appendStringInfoChar
79#define jsonapi_appendStringInfoCharMacro appendStringInfoCharMacro
80#define jsonapi_makeStringInfo makeStringInfo
81#define jsonapi_initStringInfo initStringInfo
82#define jsonapi_resetStringInfo resetStringInfo
83#define jsonapi_termStringInfo(s) pfree((s)->data)
84#define jsonapi_destroyStringInfo destroyStringInfo
173#define JSON_NUM_TERMINALS 13
174#define JSON_NUM_NONTERMINALS 5
175#define JSON_NT_OFFSET JSON_NT_JSON
177#define OFS(NT) (NT) - JSON_NT_OFFSET
179#define IS_SEM(x) ((x) & 0x40)
180#define IS_NT(x) ((x) & 0x20)
239#define TD_ENTRY(PROD) { sizeof(PROD) - 1, (PROD) }
276 bool *num_err,
size_t *total_len);
289 NULL, NULL, NULL, NULL, NULL,
290 NULL, NULL, NULL, NULL, NULL
326#define JSON_ALPHANUMERIC_CHAR(c) \
327 (((c) >= 'a' && (c) <= 'z') || \
328 ((c) >= 'A' && (c) <= 'Z') || \
329 ((c) >= '0' && (c) <= '9') || \
369 return (!numeric_error) && (total_len == dummy_lex.
input_length);
429#define JS_STACK_CHUNK_SIZE 64
430#define JS_MAX_PROD_LEN 10
431#define JSON_TD_MAX_STACK 6400
447#ifdef JSONAPI_USE_PQEXPBUFFER
555 if (owned_by_context)
558 lex->
flags &= ~JSONLEX_CTX_OWNS_TOKENS;
566 size_t new_stack_size;
567 char *new_prediction;
575#ifdef JSONAPI_USE_PQEXPBUFFER
582 new_stack_size *
sizeof(
char *));
583#ifdef JSONAPI_USE_PQEXPBUFFER
590#ifdef JSONAPI_USE_PQEXPBUFFER
747#ifdef FORCE_JSON_PSTACK
1021 if ((ostart != NULL || oend != NULL) && lex->
need_escapes)
1045 result = (*ostart) (
sem->
semstate, fname, isnull);
1330 if ((ostart != NULL || oend != NULL) && lex->
need_escapes)
1356 result = (*ostart) (
sem->
semstate, fname, isnull);
1358 goto ofield_cleanup;
1373 goto ofield_cleanup;
1379 goto ofield_cleanup;
1611#ifdef JSONAPI_USE_PQEXPBUFFER
1628 bool tok_done =
false;
1632 if (ptok->data[0] ==
'"')
1640 for (
int i = ptok->len - 1;
i > 0;
i--)
1643 if (ptok->data[
i] ==
'\\')
1655 if (
c ==
'"' && escapes % 2 == 0)
1669 char c = ptok->data[0];
1671 if (
c ==
'-' || (
c >=
'0' &&
c <=
'9'))
1675 bool numend =
false;
1753 lex->
input += added;
1765 partial_result =
json_lex(&dummy_lex);
1799 return partial_result;
1804 while (s < end && (*s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r'))
1931 if (memcmp(s,
"true", 4) == 0)
1933 else if (memcmp(s,
"null", 4) == 0)
1938 else if (p - s == 5 && memcmp(s,
"false", 5) == 0)
1968 int hi_surrogate = -1;
1971#define FAIL_OR_INCOMPLETE_AT_CHAR_START(code) \
1973 if (lex->incremental && !lex->inc_state->is_last_chunk) \
1975 jsonapi_appendBinaryStringInfo(&lex->inc_state->partial_token, \
1977 end - lex->token_start); \
1978 return JSON_INCOMPLETE; \
1980 lex->token_terminator = s; \
1983#define FAIL_AT_CHAR_END(code) \
1985 const char *term = s + pg_encoding_mblen(lex->input_encoding, s); \
1986 lex->token_terminator = (term <= end) ? term : end; \
1992#ifdef JSONAPI_USE_PQEXPBUFFER
2010 else if (*s ==
'\\')
2021 for (
i = 1;
i <= 4;
i++)
2026 else if (*s >=
'0' && *s <=
'9')
2027 ch = (ch * 16) + (*s -
'0');
2028 else if (*s >=
'a' && *s <=
'f')
2029 ch = (ch * 16) + (*s -
'a') + 10;
2030 else if (*s >=
'A' && *s <=
'F')
2031 ch = (ch * 16) + (*s -
'A') + 10;
2042 if (hi_surrogate != -1)
2049 if (hi_surrogate == -1)
2055 if (hi_surrogate != -1)
2094 else if (ch <= 0x007f)
2106 if (hi_surrogate != -1)
2142 else if (strchr(
"\"\\/bfnrt", *s) == NULL)
2159 if (hi_surrogate != -1)
2166 while (p < end -
sizeof(
Vector8) &&
2172 for (; p < end; p++)
2174 if (*p ==
'\\' || *p ==
'"')
2176 else if ((
unsigned char) *p <= 31)
2199 if (hi_surrogate != -1)
2205#ifdef JSONAPI_USE_PQEXPBUFFER
2215#undef FAIL_OR_INCOMPLETE_AT_CHAR_START
2216#undef FAIL_AT_CHAR_END
2249 bool *num_err,
size_t *total_len)
2258 if (len < lex->input_length && *s ==
'0')
2263 else if (len < lex->input_length && *s >=
'1' && *s <=
'9')
2269 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
2275 if (len < lex->input_length && *s ==
'.')
2287 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
2292 if (len < lex->input_length && (*s ==
'e' || *s ==
'E'))
2296 if (len < lex->input_length && (*s ==
'+' || *s ==
'-'))
2309 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
2321 if (total_len != NULL)
2329 if (num_err != NULL)
2334 else if (num_err != NULL)
2407 return _(
"out of memory");
2419#define json_token_error(lex, format) \
2420 jsonapi_appendStringInfo((lex)->errormsg, _(format), \
2421 (int) ((lex)->token_terminator - (lex)->token_start), \
2422 (lex)->token_start);
2432 return _(
"Recursive descent parser cannot use incremental lexer.");
2434 return _(
"Incremental parser requires incremental lexer.");
2436 return (
_(
"JSON nested too deep, maximum permitted depth is 6400."));
2442 _(
"Character with value 0x%02x must be escaped."),
2449 json_token_error(lex,
"Expected array element or \"]\", but found \"%.*s\".");
2461 return _(
"The input string ended unexpectedly.");
2478 return _(
"\\u0000 cannot be converted to text.");
2480 return _(
"\"\\u\" must be followed by four hexadecimal digits.");
2483 return _(
"Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8.");
2492 return psprintf(
_(
"Unicode escape value could not be translated to the server's encoding %s."),
2499 return _(
"Unicode high surrogate must not follow a high surrogate.");
2501 return _(
"Unicode low surrogate must follow a high surrogate.");
2506#undef json_token_error
2517 "unexpected json parse error type: %d",
2521#ifdef JSONAPI_USE_PQEXPBUFFER
2523 return _(
"out of memory while constructing error description");
Assert(PointerIsAligned(start, uint64))
JsonParseErrorType pg_parse_json_incremental(JsonLexContext *lex, const JsonSemAction *sem, const char *json, size_t len, bool is_last)
#define JSON_TD_MAX_STACK
@ JSON_PARSE_OBJECT_LABEL
@ JSON_PARSE_OBJECT_START
@ JSON_PARSE_OBJECT_COMMA
JsonLexContext * makeJsonLexContextIncremental(JsonLexContext *lex, int encoding, bool need_escapes)
static void set_fnull(JsonLexContext *lex, bool fnull)
#define JSON_NUM_TERMINALS
static char JSON_PROD_MORE_KEY_PAIRS[]
bool IsValidJsonNumber(const char *str, size_t len)
#define jsonapi_destroyStringInfo
static JsonParseErrorType json_lex_string(JsonLexContext *lex)
#define JSON_ALPHANUMERIC_CHAR(c)
static char JSON_PROD_KEY_PAIRS[]
#define JSON_NUM_NONTERMINALS
static char JSON_PROD_SCALAR_STRING[]
JsonParseErrorType pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem)
static bool inc_lex_level(JsonLexContext *lex)
static char JSON_PROD_ARRAY_ELEMENTS[]
static bool have_prediction(JsonParserStack *pstack)
static void set_fname(JsonLexContext *lex, char *fname)
static char JSON_PROD_SCALAR_NUMBER[]
#define json_token_error(lex, format)
static char next_prediction(JsonParserStack *pstack)
static void push_prediction(JsonParserStack *pstack, td_entry entry)
static JsonLexContext failed_oom
#define jsonapi_appendStringInfoCharMacro
static char * get_fname(JsonLexContext *lex)
static char JSON_PROD_GOAL[]
#define jsonapi_makeStringInfo
static JsonTokenType lex_peek(JsonLexContext *lex)
static char JSON_PROD_EPSILON[]
static JsonParseErrorType parse_object(JsonLexContext *lex, const JsonSemAction *sem)
#define jsonapi_initStringInfo
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)
#define JS_STACK_CHUNK_SIZE
void setJsonLexContextOwnsTokens(JsonLexContext *lex, bool owned_by_context)
static char JSON_PROD_SCALAR_NULL[]
static bool allocate_incremental_state(JsonLexContext *lex)
#define jsonapi_resetStringInfo
static JsonParseErrorType report_parse_error(JsonParseContext ctx, JsonLexContext *lex)
static JsonParseErrorType lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
static JsonIncrementalState failed_inc_oom
static JsonParseErrorType json_lex_number(JsonLexContext *lex, const char *s, bool *num_err, size_t *total_len)
static char JSON_PROD_MORE_ARRAY_ELEMENTS[]
const JsonSemAction nullSemAction
static td_entry td_parser_table[JSON_NUM_NONTERMINALS][JSON_NUM_TERMINALS]
static JsonParseErrorType parse_scalar(JsonLexContext *lex, const JsonSemAction *sem)
static char pop_prediction(JsonParserStack *pstack)
static JsonParseErrorType parse_object_field(JsonLexContext *lex, const JsonSemAction *sem)
#define jsonapi_termStringInfo(s)
#define jsonapi_appendBinaryStringInfo
static char JSON_PROD_SCALAR_FALSE[]
static bool get_fnull(JsonLexContext *lex)
JsonParseErrorType json_lex(JsonLexContext *lex)
#define jsonapi_appendStringInfoChar
static char JSON_PROD_OBJECT[]
#define jsonapi_appendStringInfo
char * json_errdetail(JsonParseErrorType error, JsonLexContext *lex)
JsonParseErrorType json_count_array_elements(JsonLexContext *lex, int *elements)
static JsonParseErrorType parse_array(JsonLexContext *lex, const JsonSemAction *sem)
static JsonParseErrorType parse_array_element(JsonLexContext *lex, const JsonSemAction *sem)
void freeJsonLexContext(JsonLexContext *lex)
@ JSON_NT_MORE_ARRAY_ELEMENTS
static char JSON_PROD_ARRAY[]
#define FAIL_OR_INCOMPLETE_AT_CHAR_START(code)
static char JSON_PROD_SCALAR_TRUE[]
#define FAIL_AT_CHAR_END(code)
static void dec_lex_level(JsonLexContext *lex)
JsonParseErrorType(* json_struct_action)(void *state)
JsonParseErrorType(* json_aelem_action)(void *state, bool isnull)
#define JSONLEX_FREE_STRVAL
#define jsonapi_StrValType
@ JSON_EXPECTED_ARRAY_FIRST
@ JSON_UNICODE_HIGH_SURROGATE
@ JSON_EXPECTED_OBJECT_FIRST
@ JSON_UNICODE_CODE_POINT_ZERO
@ JSON_INVALID_LEXER_TYPE
@ JSON_UNICODE_ESCAPE_FORMAT
@ JSON_UNICODE_UNTRANSLATABLE
@ JSON_EXPECTED_OBJECT_NEXT
@ JSON_EXPECTED_ARRAY_NEXT
@ JSON_UNICODE_HIGH_ESCAPE
@ JSON_UNICODE_LOW_SURROGATE
JsonParseErrorType(* json_ofield_action)(void *state, char *fname, bool isnull)
#define JSONLEX_FREE_STRUCT
@ JSON_TOKEN_OBJECT_START
#define JSONLEX_CTX_OWNS_TOKENS
JsonParseErrorType(* json_scalar_action)(void *state, char *token, JsonTokenType tokentype)
bool pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s)
const char * GetDatabaseEncodingName(void)
static bool pg_lfind8_le(uint8 key, uint8 *base, uint32 nelem)
static bool pg_lfind8(uint8 key, uint8 *base, uint32 nelem)
static unsigned char * unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
#define MAX_UNICODE_EQUIVALENT_STRING
static pg_wchar surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
static bool is_utf16_surrogate_first(pg_wchar c)
static bool is_utf16_surrogate_second(pg_wchar c)
#define PQExpBufferBroken(str)
#define PQExpBufferDataBroken(buf)
char * psprintf(const char *fmt,...)
void check_stack_depth(void)
void appendStringInfoString(StringInfo str, const char *s)
jsonapi_StrValType partial_token
const char * prev_token_terminator
struct jsonapi_StrValType * strval
struct jsonapi_StrValType * errormsg
JsonIncrementalState * inc_state
const char * token_terminator
json_struct_action array_end
json_struct_action object_start
json_ofield_action object_field_start
json_aelem_action array_element_start
json_scalar_action scalar
json_aelem_action array_element_end
json_struct_action array_start
json_struct_action object_end
json_ofield_action object_field_end