PostgreSQL Source Code: src/common/jsonapi.c File Reference (original) (raw)

Go to the source code of this file.

Data Structures
struct JsonParserStack
struct JsonIncrementalState
struct td_entry
Macros
#define STRDUP(s) pstrdup(s)
#define ALLOC(size) palloc(size)
#define ALLOC0(size) palloc0(size)
#define REALLOC repalloc
#define FREE(s)
#define jsonapi_appendStringInfo appendStringInfo
#define jsonapi_appendBinaryStringInfo appendBinaryStringInfo
#define jsonapi_appendStringInfoChar appendStringInfoChar
#define jsonapi_appendStringInfoCharMacro appendStringInfoCharMacro
#define jsonapi_makeStringInfo makeStringInfo
#define jsonapi_initStringInfo initStringInfo
#define jsonapi_resetStringInfo resetStringInfo
#define jsonapi_termStringInfo(s) pfree((s)->data)
#define jsonapi_destroyStringInfo destroyStringInfo
#define JSON_NUM_TERMINALS 13
#define JSON_NUM_NONTERMINALS 5
#define JSON_NT_OFFSET JSON_NT_JSON
#define OFS(NT) (NT) - JSON_NT_OFFSET
#define IS_SEM(x) ((x) & 0x40)
#define IS_NT(x) ((x) & 0x20)
#define TD_ENTRY(PROD) { sizeof(PROD) - 1, (PROD) }
#define JSON_ALPHANUMERIC_CHAR(c)
#define JS_STACK_CHUNK_SIZE 64
#define JS_MAX_PROD_LEN 10 /* more than we need */
#define JSON_TD_MAX_STACK
#define FAIL_OR_INCOMPLETE_AT_CHAR_START(code)
#define FAIL_AT_CHAR_END(code)
#define json_token_error(lex, format)
Enumerations
enum JsonParseContext { JSON_PARSE_VALUE, JSON_PARSE_STRING, JSON_PARSE_ARRAY_START, JSON_PARSE_ARRAY_NEXT, JSON_PARSE_OBJECT_START, JSON_PARSE_OBJECT_LABEL, JSON_PARSE_OBJECT_NEXT, JSON_PARSE_OBJECT_COMMA, JSON_PARSE_END }
enum JsonNonTerminal { JSON_NT_JSON = 32 , JSON_NT_ARRAY_ELEMENTS, JSON_NT_MORE_ARRAY_ELEMENTS, JSON_NT_KEY_PAIRS, JSON_NT_MORE_KEY_PAIRS }
enum JsonParserSem { JSON_SEM_OSTART = 64 , JSON_SEM_OEND, JSON_SEM_ASTART, JSON_SEM_AEND, JSON_SEM_OFIELD_INIT, JSON_SEM_OFIELD_START, JSON_SEM_OFIELD_END, JSON_SEM_AELEM_START, JSON_SEM_AELEM_END, JSON_SEM_SCALAR_INIT, JSON_SEM_SCALAR_CALL }
Functions
static JsonParseErrorType json_lex_string (JsonLexContext *lex)
static JsonParseErrorType json_lex_number (JsonLexContext *lex, const char *s, bool *num_err, size_t *total_len)
static JsonParseErrorType parse_scalar (JsonLexContext *lex, const JsonSemAction *sem)
static JsonParseErrorType parse_object_field (JsonLexContext *lex, const JsonSemAction *sem)
static JsonParseErrorType parse_object (JsonLexContext *lex, const JsonSemAction *sem)
static JsonParseErrorType parse_array_element (JsonLexContext *lex, const JsonSemAction *sem)
static JsonParseErrorType parse_array (JsonLexContext *lex, const JsonSemAction *sem)
static JsonParseErrorType report_parse_error (JsonParseContext ctx, JsonLexContext *lex)
static bool allocate_incremental_state (JsonLexContext *lex)
static void set_fname (JsonLexContext *lex, char *fname)
static JsonTokenType lex_peek (JsonLexContext *lex)
static JsonParseErrorType lex_expect (JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
bool IsValidJsonNumber (const char *str, size_t len)
JsonLexContext * makeJsonLexContextCstringLen (JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)
JsonLexContext * makeJsonLexContextIncremental (JsonLexContext *lex, int encoding, bool need_escapes)
void setJsonLexContextOwnsTokens (JsonLexContext *lex, bool owned_by_context)
static bool inc_lex_level (JsonLexContext *lex)
static void dec_lex_level (JsonLexContext *lex)
static void push_prediction (JsonParserStack *pstack, td_entry entry)
static char pop_prediction (JsonParserStack *pstack)
static char next_prediction (JsonParserStack *pstack)
static bool have_prediction (JsonParserStack *pstack)
static char * get_fname (JsonLexContext *lex)
static void set_fnull (JsonLexContext *lex, bool fnull)
static bool get_fnull (JsonLexContext *lex)
void freeJsonLexContext (JsonLexContext *lex)
JsonParseErrorType pg_parse_json (JsonLexContext *lex, const JsonSemAction *sem)
JsonParseErrorType json_count_array_elements (JsonLexContext *lex, int *elements)
JsonParseErrorType pg_parse_json_incremental (JsonLexContext *lex, const JsonSemAction *sem, const char *json, size_t len, bool is_last)
JsonParseErrorType json_lex (JsonLexContext *lex)
char * json_errdetail (JsonParseErrorType error, JsonLexContext *lex)
Variables
static char JSON_PROD_EPSILON [] = {0}
static char JSON_PROD_SCALAR_STRING [] = {JSON_SEM_SCALAR_CALL, JSON_TOKEN_STRING, JSON_SEM_SCALAR_INIT, 0}
static char JSON_PROD_SCALAR_NUMBER [] = {JSON_SEM_SCALAR_CALL, JSON_TOKEN_NUMBER, JSON_SEM_SCALAR_INIT, 0}
static char JSON_PROD_SCALAR_TRUE [] = {JSON_SEM_SCALAR_CALL, JSON_TOKEN_TRUE, JSON_SEM_SCALAR_INIT, 0}
static char JSON_PROD_SCALAR_FALSE [] = {JSON_SEM_SCALAR_CALL, JSON_TOKEN_FALSE, JSON_SEM_SCALAR_INIT, 0}
static char JSON_PROD_SCALAR_NULL [] = {JSON_SEM_SCALAR_CALL, JSON_TOKEN_NULL, JSON_SEM_SCALAR_INIT, 0}
static char JSON_PROD_OBJECT [] = {JSON_SEM_OEND, JSON_TOKEN_OBJECT_END, JSON_NT_KEY_PAIRS, JSON_TOKEN_OBJECT_START, JSON_SEM_OSTART, 0}
static char JSON_PROD_ARRAY [] = {JSON_SEM_AEND, JSON_TOKEN_ARRAY_END, JSON_NT_ARRAY_ELEMENTS, JSON_TOKEN_ARRAY_START, JSON_SEM_ASTART, 0}
static char JSON_PROD_ARRAY_ELEMENTS [] = {JSON_NT_MORE_ARRAY_ELEMENTS, JSON_SEM_AELEM_END, JSON_NT_JSON, JSON_SEM_AELEM_START, 0}
static char JSON_PROD_MORE_ARRAY_ELEMENTS [] = {JSON_NT_MORE_ARRAY_ELEMENTS, JSON_SEM_AELEM_END, JSON_NT_JSON, JSON_SEM_AELEM_START, JSON_TOKEN_COMMA, 0}
static char JSON_PROD_KEY_PAIRS [] = {JSON_NT_MORE_KEY_PAIRS, JSON_SEM_OFIELD_END, JSON_NT_JSON, JSON_SEM_OFIELD_START, JSON_TOKEN_COLON, JSON_TOKEN_STRING, JSON_SEM_OFIELD_INIT, 0}
static char JSON_PROD_MORE_KEY_PAIRS [] = {JSON_NT_MORE_KEY_PAIRS, JSON_SEM_OFIELD_END, JSON_NT_JSON, JSON_SEM_OFIELD_START, JSON_TOKEN_COLON, JSON_TOKEN_STRING, JSON_SEM_OFIELD_INIT, JSON_TOKEN_COMMA, 0}
static td_entry td_parser_table [JSON_NUM_NONTERMINALS][JSON_NUM_TERMINALS]
static char JSON_PROD_GOAL [] = {JSON_TOKEN_END, JSON_NT_JSON, 0}
const JsonSemAction nullSemAction
static JsonLexContext failed_oom
static JsonIncrementalState failed_inc_oom

ALLOC

| #define ALLOC | ( | | size | ) | palloc(size) | | ------------- | - | | ---- | - | ------------------------------------------------------------------ |

ALLOC0

| #define ALLOC0 | ( | | size | ) | palloc0(size) | | -------------- | - | | ---- | - | ------------------------------------------------------------------- |

FAIL_AT_CHAR_END

| #define FAIL_AT_CHAR_END | ( | | code | ) | | --------------------------- | - | | ---- | - |

Value:

do { \

int charlen; \

lex->token_terminator = (charlen <= remaining) ? s + charlen : end; \

return code; \

} while (0)

int pg_encoding_mblen_or_incomplete(int encoding, const char *mbstr, size_t remaining)

FAIL_OR_INCOMPLETE_AT_CHAR_START

| #define FAIL_OR_INCOMPLETE_AT_CHAR_START | ( | | code | ) | | --------------------------------------------- | - | | ---- | - |

Value:

do { \

if (lex->incremental && !lex->inc_state->is_last_chunk) \

{ \

jsonapi_appendBinaryStringInfo(&lex->inc_state->partial_token, \

lex->token_start, \

end - lex->token_start); \

} \

lex->token_terminator = s; \

return code; \

} while (0)

FREE

Value:

do { \

void *__v = (s); \

if (__v) \

pfree(__v); \

} while (0)

Definition at line 69 of file jsonapi.c.

IS_NT

| #define IS_NT | ( | | x | ) | ((x) & 0x20) | | -------------- | - | | ---------------------------------------------------- | - | --------------------------------------------------------------- |

IS_SEM

| #define IS_SEM | ( | | x | ) | ((x) & 0x40) | | --------------- | - | | ---------------------------------------------------- | - | --------------------------------------------------------------- |

JS_MAX_PROD_LEN

#define JS_MAX_PROD_LEN 10 /* more than we need */

JS_STACK_CHUNK_SIZE

#define JS_STACK_CHUNK_SIZE 64

JSON_ALPHANUMERIC_CHAR

| #define JSON_ALPHANUMERIC_CHAR | ( | | c | ) | | -------------------------------- | - | | --------------------------------------------------------------- | - |

Value:

(((c) >= 'a' && (c) <= 'z') || \

((c) >= 'A' && (c) <= 'Z') || \

((c) >= '0' && (c) <= '9') || \

(c) == '_' || \

IS_HIGHBIT_SET(c))

Definition at line 326 of file jsonapi.c.

JSON_NT_OFFSET

JSON_NUM_NONTERMINALS

#define JSON_NUM_NONTERMINALS 5

JSON_NUM_TERMINALS

#define JSON_NUM_TERMINALS 13

JSON_TD_MAX_STACK

#define JSON_TD_MAX_STACK

json_token_error

| #define json_token_error | ( | | lex, | | --------------------------------------------------------------------------- | - | | ---- | | | format | | | | | ) | | | |

Value:

(int) ((lex)->token_terminator - (lex)->token_start), \

#define jsonapi_appendStringInfo

jsonapi_appendBinaryStringInfo

jsonapi_appendStringInfo

jsonapi_appendStringInfoChar

jsonapi_appendStringInfoCharMacro

jsonapi_destroyStringInfo

jsonapi_initStringInfo

jsonapi_makeStringInfo

jsonapi_resetStringInfo

jsonapi_termStringInfo

| #define jsonapi_termStringInfo | ( | | s | ) | pfree((s)->data) | | ------------------------------- | - | | - | - | ----------------------------------------------------------------------------------------------------------------------------------------------- |

OFS

REALLOC

STRDUP

TD_ENTRY

| #define TD_ENTRY | ( | | PROD | ) | { sizeof(PROD) - 1, (PROD) } | | ----------------- | - | | ---- | - | ---------------------------- |

JsonNonTerminal

Enumerator
JSON_NT_JSON
JSON_NT_ARRAY_ELEMENTS
JSON_NT_MORE_ARRAY_ELEMENTS
JSON_NT_KEY_PAIRS
JSON_NT_MORE_KEY_PAIRS

Definition at line 113 of file jsonapi.c.

114{

120};

@ JSON_NT_MORE_ARRAY_ELEMENTS

JsonParseContext

Enumerator
JSON_PARSE_VALUE
JSON_PARSE_STRING
JSON_PARSE_ARRAY_START
JSON_PARSE_ARRAY_NEXT
JSON_PARSE_OBJECT_START
JSON_PARSE_OBJECT_LABEL
JSON_PARSE_OBJECT_NEXT
JSON_PARSE_OBJECT_COMMA
JSON_PARSE_END

Definition at line 93 of file jsonapi.c.

94{

103 JSON_PARSE_END,

@ JSON_PARSE_OBJECT_LABEL

@ JSON_PARSE_OBJECT_START

@ JSON_PARSE_OBJECT_COMMA

JsonParserSem

Enumerator
JSON_SEM_OSTART
JSON_SEM_OEND
JSON_SEM_ASTART
JSON_SEM_AEND
JSON_SEM_OFIELD_INIT
JSON_SEM_OFIELD_START
JSON_SEM_OFIELD_END
JSON_SEM_AELEM_START
JSON_SEM_AELEM_END
JSON_SEM_SCALAR_INIT
JSON_SEM_SCALAR_CALL

Definition at line 122 of file jsonapi.c.

allocate_incremental_state()

Definition at line 433 of file jsonapi.c.

435{

436 void *pstack,

437 *prediction,

438 *fnames,

439 *fnull;

440

446

447#ifdef JSONAPI_USE_PQEXPBUFFER

449 || !pstack

450 || !prediction

451 || !fnames

452 || !fnull)

453 {

455 FREE(pstack);

456 FREE(prediction);

457 FREE(fnames);

459

461 return false;

462 }

463#endif

464

466 lex->pstack = pstack;

471

472

473

474

475

476

479

481 return true;

Assert(PointerIsAligned(start, uint64))

#define jsonapi_initStringInfo

#define JS_STACK_CHUNK_SIZE

static JsonIncrementalState failed_inc_oom

jsonapi_StrValType partial_token

JsonIncrementalState * inc_state

References ALLOC, ALLOC0, Assert(), failed_inc_oom, JsonParserStack::fnames, JsonParserStack::fnull, FREE, JsonLexContext::inc_state, JsonLexContext::incremental, JS_MAX_PROD_LEN, JS_STACK_CHUNK_SIZE, jsonapi_initStringInfo, JsonLexContext::lex_level, JsonIncrementalState::partial_token, JsonParserStack::prediction, JsonLexContext::pstack, and JsonParserStack::stack_size.

Referenced by makeJsonLexContextIncremental(), and pg_parse_json().

dec_lex_level()

freeJsonLexContext()

Definition at line 687 of file jsonapi.c.

689{

691

693 return;

694

697

700

702 {

706

708 {

709 int i;

710

711

714 }

715

720 }

721

724 else

725 *lex = empty;

#define jsonapi_destroyStringInfo

static JsonLexContext failed_oom

#define jsonapi_termStringInfo(s)

#define JSONLEX_FREE_STRVAL

#define JSONLEX_FREE_STRUCT

#define JSONLEX_CTX_OWNS_TOKENS

struct jsonapi_StrValType * strval

struct jsonapi_StrValType * errormsg

References JsonLexContext::errormsg, failed_oom, JsonLexContext::flags, JsonParserStack::fnames, JsonParserStack::fnull, FREE, i, JsonLexContext::inc_state, JsonLexContext::incremental, jsonapi_destroyStringInfo, jsonapi_termStringInfo, JSONLEX_CTX_OWNS_TOKENS, JSONLEX_FREE_STRUCT, JSONLEX_FREE_STRVAL, JsonLexContext::lex_level, JsonIncrementalState::partial_token, JsonParserStack::prediction, JsonLexContext::pstack, JsonParserStack::scalar_val, and JsonLexContext::strval.

Referenced by datum_to_jsonb_internal(), each_worker(), elements_worker(), get_json_object_as_hash(), get_worker(), handle_oauth_sasl_error(), iterate_json_values(), json_object_keys(), json_parse_manifest(), json_parse_manifest_incremental_shutdown(), json_validate(), main(), parse_oauth_json(), populate_array_json(), populate_recordset_worker(), test_gb18030_json(), and transform_json_string_values().

get_fname()

get_fnull()

have_prediction()

inc_lex_level()

Definition at line 561 of file jsonapi.c.

563{

565 {

566 size_t new_stack_size;

567 char *new_prediction;

568 char **new_fnames;

569 bool *new_fnull;

570

572

575#ifdef JSONAPI_USE_PQEXPBUFFER

576 if (!new_prediction)

577 return false;

578#endif

580

582 new_stack_size * sizeof(char *));

583#ifdef JSONAPI_USE_PQEXPBUFFER

584 if (!new_fnames)

585 return false;

586#endif

588

589 new_fnull = REALLOC(lex->pstack->fnull, new_stack_size * sizeof(bool));

590#ifdef JSONAPI_USE_PQEXPBUFFER

591 if (!new_fnull)

592 return false;

593#endif

595

597 }

598

600

602 {

603

604

605

606

608 }

609

610 return true;

References JsonParserStack::fnames, JsonParserStack::fnull, JsonLexContext::incremental, JS_MAX_PROD_LEN, JS_STACK_CHUNK_SIZE, JsonLexContext::lex_level, JsonParserStack::prediction, JsonLexContext::pstack, REALLOC, and JsonParserStack::stack_size.

Referenced by pg_parse_json_incremental().

IsValidJsonNumber()

bool IsValidJsonNumber ( const char * str,
size_t len
)

json_count_array_elements()

Definition at line 803 of file jsonapi.c.

805{

807 int count;

809

812

813

814

815

816

817

819 copylex.need_escapes = false;

821

822 count = 0;

826 return result;

828 {

829 while (1)

830 {

831 count++;

834 return result;

836 break;

839 return result;

840 }

841 }

845 return result;

846

847 *elements = count;

static JsonTokenType lex_peek(JsonLexContext *lex)

static JsonParseErrorType lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)

const JsonSemAction nullSemAction

JsonParseErrorType json_lex(JsonLexContext *lex)

static JsonParseErrorType parse_array_element(JsonLexContext *lex, const JsonSemAction *sem)

References failed_oom, json_lex(), JSON_OUT_OF_MEMORY, JSON_PARSE_ARRAY_NEXT, JSON_PARSE_ARRAY_START, JSON_SUCCESS, JSON_TOKEN_ARRAY_END, JSON_TOKEN_ARRAY_START, JSON_TOKEN_COMMA, lex_expect(), JsonLexContext::lex_level, lex_peek(), JsonLexContext::need_escapes, nullSemAction, parse_array_element(), and JsonLexContext::token_type.

Referenced by get_array_start().

json_errdetail()

Definition at line 2404 of file jsonapi.c.

2406{

2408 {

2409

2410 return _("out of memory");

2411 }

2412

2415 else

2417

2418

2419

2420

2421

2422#define json_token_error(lex, format) \

2423 jsonapi_appendStringInfo((lex)->errormsg, _(format), \

2424 (int) ((lex)->token_terminator - (lex)->token_start), \

2425 (lex)->token_start);

2426

2428 {

2431

2432 break;

2435 return _("Recursive descent parser cannot use incremental lexer.");

2436 else

2437 return _("Incremental parser requires incremental lexer.");

2439 return (_("JSON nested too deep, maximum permitted depth is 6400."));

2441 json_token_error(lex, "Escape sequence \"\\%.*s\" is invalid.");

2442 break;

2445 _("Character with value 0x%02x must be escaped."),

2447 break;

2449 json_token_error(lex, "Expected end of input, but found \"%.*s\".");

2450 break;

2452 json_token_error(lex, "Expected array element or \"]\", but found \"%.*s\".");

2453 break;

2455 json_token_error(lex, "Expected \",\" or \"]\", but found \"%.*s\".");

2456 break;

2458 json_token_error(lex, "Expected \":\", but found \"%.*s\".");

2459 break;

2461 json_token_error(lex, "Expected JSON value, but found \"%.*s\".");

2462 break;

2464 return _("The input string ended unexpectedly.");

2466 json_token_error(lex, "Expected string or \"}\", but found \"%.*s\".");

2467 break;

2469 json_token_error(lex, "Expected \",\" or \"}\", but found \"%.*s\".");

2470 break;

2472 json_token_error(lex, "Expected string, but found \"%.*s\".");

2473 break;

2476 break;

2478

2479 break;

2481 return _("\\u0000 cannot be converted to text.");

2483 return _("\"\\u\" must be followed by four hexadecimal digits.");

2485

2486 return _("Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8.");

2488

2489

2490

2491

2492

2493

2494#ifndef FRONTEND

2495 return psprintf(_("Unicode escape value could not be translated to the server's encoding %s."),

2497#else

2499 break;

2500#endif

2502 return _("Unicode high surrogate must not follow a high surrogate.");

2504 return _("Unicode low surrogate must follow a high surrogate.");

2506

2507 break;

2508 }

2509#undef json_token_error

2510

2511

2513 {

2514

2515

2516

2517

2518

2520 "unexpected json parse error type: %d",

2522 }

2523

2524#ifdef JSONAPI_USE_PQEXPBUFFER

2526 return _("out of memory while constructing error description");

2527#endif

2528

#define json_token_error(lex, format)

#define jsonapi_makeStringInfo

#define jsonapi_resetStringInfo

@ 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

const char * GetDatabaseEncodingName(void)

#define PQExpBufferBroken(str)

char * psprintf(const char *fmt,...)

const char * token_terminator

References _, Assert(), error(), JsonLexContext::errormsg, failed_oom, GetDatabaseEncodingName(), JsonLexContext::incremental, JSON_ESCAPING_INVALID, JSON_ESCAPING_REQUIRED, JSON_EXPECTED_ARRAY_FIRST, JSON_EXPECTED_ARRAY_NEXT, JSON_EXPECTED_COLON, JSON_EXPECTED_END, JSON_EXPECTED_JSON, JSON_EXPECTED_MORE, JSON_EXPECTED_OBJECT_FIRST, JSON_EXPECTED_OBJECT_NEXT, JSON_EXPECTED_STRING, JSON_INCOMPLETE, JSON_INVALID_LEXER_TYPE, JSON_INVALID_TOKEN, JSON_NESTING_TOO_DEEP, JSON_OUT_OF_MEMORY, JSON_SEM_ACTION_FAILED, JSON_SUCCESS, json_token_error, JSON_UNICODE_CODE_POINT_ZERO, JSON_UNICODE_ESCAPE_FORMAT, JSON_UNICODE_HIGH_ESCAPE, JSON_UNICODE_HIGH_SURROGATE, JSON_UNICODE_LOW_SURROGATE, JSON_UNICODE_UNTRANSLATABLE, jsonapi_appendStringInfo, jsonapi_makeStringInfo, jsonapi_resetStringInfo, PQExpBufferBroken, psprintf(), and JsonLexContext::token_terminator.

Referenced by handle_oauth_sasl_error(), json_errsave_error(), json_parse_manifest(), json_parse_manifest_incremental_chunk(), main(), parse_oauth_json(), and test_gb18030_json().

json_lex()

Definition at line 1588 of file jsonapi.c.

1590{

1591 const char *s;

1594

1597

1599 {

1601 {

1602

1603

1604

1605

1609 }

1610

1611#ifdef JSONAPI_USE_PQEXPBUFFER

1612

1615#endif

1616 }

1617

1619

1621 {

1622

1623

1624

1625

1627 size_t added = 0;

1628 bool tok_done = false;

1631

1632 if (ptok->data[0] == '"')

1633 {

1634

1635

1636

1637

1638 int escapes = 0;

1639

1640 for (int i = ptok->len - 1; i > 0; i--)

1641 {

1642

1643 if (ptok->data[i] == '\\')

1644 escapes++;

1645 else

1646 break;

1647 }

1648

1650 {

1652

1654 added++;

1655 if (c == '"' && escapes % 2 == 0)

1656 {

1657 tok_done = true;

1658 break;

1659 }

1660 if (c == '\\')

1661 escapes++;

1662 else

1663 escapes = 0;

1664 }

1665 }

1666 else

1667 {

1668

1669 char c = ptok->data[0];

1670

1671 if (c == '-' || (c >= '0' && c <= '9'))

1672 {

1673

1674

1675 bool numend = false;

1676

1677 for (size_t i = 0; i < lex->input_length && !numend; i++)

1678 {

1679 char cc = lex->input[i];

1680

1681 switch (cc)

1682 {

1683 case '+':

1684 case '-':

1685 case 'e':

1686 case 'E':

1687 case '0':

1688 case '1':

1689 case '2':

1690 case '3':

1691 case '4':

1692 case '5':

1693 case '6':

1694 case '7':

1695 case '8':

1696 case '9':

1697 {

1699 added++;

1700 }

1701 break;

1702 default:

1703 numend = true;

1704 }

1705 }

1706 }

1707

1708

1709

1710

1711

1712

1714 {

1715 char cc = lex->input[i];

1716

1718 {

1720 added++;

1721 }

1722 else

1723 {

1724 tok_done = true;

1725 break;

1726 }

1727 }

1730 {

1731 tok_done = true;

1732 }

1733 }

1734

1735 if (!tok_done)

1736 {

1737

1739

1742

1743

1747 }

1748

1749

1750

1751

1752

1753 lex->input += added;

1755

1764

1765 partial_result = json_lex(&dummy_lex);

1766

1767

1768

1769

1770

1771

1772

1775

1776

1777

1778

1779

1781

1782

1783

1784

1785

1789 {

1790

1792 {

1795 }

1796

1798 }

1799 return partial_result;

1800

1801 }

1802

1803

1804 while (s < end && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r'))

1805 {

1806 if (*s++ == '\n')

1807 {

1810 }

1811 }

1813

1814

1815 if (s >= end)

1816 {

1821 }

1822 else

1823 {

1824 switch (*s)

1825 {

1826

1827 case '{':

1831 break;

1832 case '}':

1836 break;

1837 case '[':

1841 break;

1842 case ']':

1846 break;

1847 case ',':

1851 break;

1852 case ':':

1856 break;

1857 case '"':

1858

1861 return result;

1863 break;

1864 case '-':

1865

1868 return result;

1870 break;

1871 case '0':

1872 case '1':

1873 case '2':

1874 case '3':

1875 case '4':

1876 case '5':

1877 case '6':

1878 case '7':

1879 case '8':

1880 case '9':

1881

1884 return result;

1886 break;

1887 default:

1888 {

1889 const char *p;

1890

1891

1892

1893

1894

1895

1896

1897

1898

1899

1901 ;

1902

1903

1904

1905

1906

1907

1908 if (p == s)

1909 {

1913 }

1914

1917 {

1920 }

1921

1922

1923

1924

1925

1926

1929 if (p - s == 4)

1930 {

1931 if (memcmp(s, "true", 4) == 0)

1933 else if (memcmp(s, "null", 4) == 0)

1935 else

1937 }

1938 else if (p - s == 5 && memcmp(s, "false", 5) == 0)

1940 else

1942 }

1943 }

1944 }

1945

1948 else

static JsonParseErrorType json_lex_string(JsonLexContext *lex)

#define JSON_ALPHANUMERIC_CHAR(c)

#define jsonapi_appendStringInfoCharMacro

#define jsonapi_appendBinaryStringInfo

#define jsonapi_StrValType

@ JSON_TOKEN_OBJECT_START

#define PQExpBufferDataBroken(buf)

const char * prev_token_terminator

References Assert(), failed_inc_oom, failed_oom, i, JsonLexContext::inc_state, JsonLexContext::incremental, JsonLexContext::input, JsonLexContext::input_encoding, JsonLexContext::input_length, JsonIncrementalState::is_last_chunk, JSON_ALPHANUMERIC_CHAR, JSON_INCOMPLETE, JSON_INVALID_TOKEN, json_lex(), json_lex_number(), json_lex_string(), JSON_OUT_OF_MEMORY, JSON_SUCCESS, JSON_TOKEN_ARRAY_END, JSON_TOKEN_ARRAY_START, JSON_TOKEN_COLON, JSON_TOKEN_COMMA, JSON_TOKEN_END, JSON_TOKEN_FALSE, JSON_TOKEN_NULL, JSON_TOKEN_NUMBER, JSON_TOKEN_OBJECT_END, JSON_TOKEN_OBJECT_START, JSON_TOKEN_STRING, JSON_TOKEN_TRUE, jsonapi_appendBinaryStringInfo, jsonapi_appendStringInfoCharMacro, jsonapi_resetStringInfo, jsonapi_StrValType, JsonLexContext::line_number, JsonLexContext::line_start, JsonLexContext::need_escapes, JsonIncrementalState::partial_completed, JsonIncrementalState::partial_token, PQExpBufferDataBroken, JsonLexContext::prev_token_terminator, JsonLexContext::strval, JsonLexContext::token_start, JsonLexContext::token_terminator, and JsonLexContext::token_type.

Referenced by json_count_array_elements(), json_get_first_token(), json_lex(), json_typeof(), lex_expect(), parse_array(), parse_object(), parse_object_field(), parse_scalar(), pg_parse_json(), and pg_parse_json_incremental().

json_lex_number()

Definition at line 2250 of file jsonapi.c.

2253{

2254 bool error = false;

2256

2257

2258

2259

2260

2261 if (len < lex->input_length && *s == '0')

2262 {

2263 s++;

2265 }

2266 else if (len < lex->input_length && *s >= '1' && *s <= '9')

2267 {

2268 do

2269 {

2270 s++;

2272 } while (len < lex->input_length && *s >= '0' && *s <= '9');

2273 }

2274 else

2276

2277

2278 if (len < lex->input_length && *s == '.')

2279 {

2280 s++;

2284 else

2285 {

2286 do

2287 {

2288 s++;

2290 } while (len < lex->input_length && *s >= '0' && *s <= '9');

2291 }

2292 }

2293

2294

2295 if (len < lex->input_length && (*s == 'e' || *s == 'E'))

2296 {

2297 s++;

2299 if (len < lex->input_length && (*s == '+' || *s == '-'))

2300 {

2301 s++;

2303 }

2306 else

2307 {

2308 do

2309 {

2310 s++;

2312 } while (len < lex->input_length && *s >= '0' && *s <= '9');

2313 }

2314 }

2315

2316

2317

2318

2319

2320

2323

2324 if (total_len != NULL)

2325 *total_len = len;

2326

2329 {

2332 if (num_err != NULL)

2333 *num_err = error;

2334

2336 }

2337 else if (num_err != NULL)

2338 {

2339

2340 *num_err = error;

2341 }

2342 else

2343 {

2344

2347

2350 }

2351

References error(), JsonLexContext::inc_state, JsonLexContext::incremental, JsonLexContext::input, JsonLexContext::input_length, JsonIncrementalState::is_last_chunk, JSON_ALPHANUMERIC_CHAR, JSON_INCOMPLETE, JSON_INVALID_TOKEN, JSON_SUCCESS, jsonapi_appendBinaryStringInfo, len, JsonIncrementalState::partial_token, JsonLexContext::prev_token_terminator, JsonLexContext::token_start, and JsonLexContext::token_terminator.

Referenced by IsValidJsonNumber(), and json_lex().

json_lex_string()

Definition at line 1963 of file jsonapi.c.

1965{

1966 const char *s;

1968 int hi_surrogate = -1;

1969

1970

1971#define FAIL_OR_INCOMPLETE_AT_CHAR_START(code) \

1972 do { \

1973 if (lex->incremental && !lex->inc_state->is_last_chunk) \

1974 { \

1975 jsonapi_appendBinaryStringInfo(&lex->inc_state->partial_token, \

1976 lex->token_start, \

1977 end - lex->token_start); \

1978 return JSON_INCOMPLETE; \

1979 } \

1980 lex->token_terminator = s; \

1981 return code; \

1982 } while (0)

1983#define FAIL_AT_CHAR_END(code) \

1984 do { \

1985 ptrdiff_t remaining = end - s; \

1986 int charlen; \

1987 charlen = pg_encoding_mblen_or_incomplete(lex->input_encoding, \

1988 s, remaining); \

1989 lex->token_terminator = (charlen <= remaining) ? s + charlen : end; \

1990 return code; \

1991 } while (0)

1992

1994 {

1995#ifdef JSONAPI_USE_PQEXPBUFFER

1996

1997 if (lex->strval == NULL)

1999#endif

2001 }

2002

2005 for (;;)

2006 {

2007 s++;

2008

2009 if (s >= end)

2011 else if (*s == '"')

2012 break;

2013 else if (*s == '\\')

2014 {

2015

2016 s++;

2017 if (s >= end)

2019 else if (*s == 'u')

2020 {

2021 int i;

2022 int ch = 0;

2023

2024 for (i = 1; i <= 4; i++)

2025 {

2026 s++;

2027 if (s >= end)

2029 else if (*s >= '0' && *s <= '9')

2030 ch = (ch * 16) + (*s - '0');

2031 else if (*s >= 'a' && *s <= 'f')

2032 ch = (ch * 16) + (*s - 'a') + 10;

2033 else if (*s >= 'A' && *s <= 'F')

2034 ch = (ch * 16) + (*s - 'A') + 10;

2035 else

2037 }

2039 {

2040

2041

2042

2044 {

2045 if (hi_surrogate != -1)

2047 hi_surrogate = ch;

2048 continue;

2049 }

2051 {

2052 if (hi_surrogate == -1)

2055 hi_surrogate = -1;

2056 }

2057

2058 if (hi_surrogate != -1)

2060

2061

2062

2063

2064

2065

2066 if (ch == 0)

2067 {

2068

2070 }

2071

2072

2073

2074

2075

2076

2077

2078#ifndef FRONTEND

2079 {

2081

2085 }

2086#else

2088 {

2089

2090 char utf8str[5];

2091 int utf8len;

2092

2094 utf8len = pg_utf_mblen((unsigned char *) utf8str);

2096 }

2097 else if (ch <= 0x007f)

2098 {

2099

2101 }

2102 else

2104#endif

2105 }

2106 }

2108 {

2109 if (hi_surrogate != -1)

2111

2112 switch (*s)

2113 {

2114 case '"':

2115 case '\\':

2116 case '/':

2118 break;

2119 case 'b':

2121 break;

2122 case 'f':

2124 break;

2125 case 'n':

2127 break;

2128 case 'r':

2130 break;

2131 case 't':

2133 break;

2134 default:

2135

2136

2137

2138

2139

2140

2143 }

2144 }

2145 else if (strchr("\"\\/bfnrt", *s) == NULL)

2146 {

2147

2148

2149

2150

2151

2152

2153

2156 }

2157 }

2158 else

2159 {

2160 const char *p = s;

2161

2162 if (hi_surrogate != -1)

2164

2165

2166

2167

2168

2169 while (p < end - sizeof(Vector8) &&

2174

2175 for (; p < end; p++)

2176 {

2177 if (*p == '\\' || *p == '"')

2178 break;

2179 else if ((unsigned char) *p <= 31)

2180 {

2181

2182

2183

2184

2185

2188 }

2189 }

2190

2193

2194

2195

2196

2197

2198 s = p - 1;

2199 }

2200 }

2201

2202 if (hi_surrogate != -1)

2203 {

2206 }

2207

2208#ifdef JSONAPI_USE_PQEXPBUFFER

2211#endif

2212

2213

2217

2218#undef FAIL_OR_INCOMPLETE_AT_CHAR_START

2219#undef FAIL_AT_CHAR_END

#define jsonapi_appendStringInfoChar

#define FAIL_OR_INCOMPLETE_AT_CHAR_START(code)

#define FAIL_AT_CHAR_END(code)

bool pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s)

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)

void appendStringInfoString(StringInfo str, const char *s)

References appendStringInfoString(), Assert(), FAIL_AT_CHAR_END, FAIL_OR_INCOMPLETE_AT_CHAR_START, i, JsonLexContext::input, JsonLexContext::input_encoding, JsonLexContext::input_length, is_utf16_surrogate_first(), is_utf16_surrogate_second(), JSON_ESCAPING_INVALID, JSON_ESCAPING_REQUIRED, JSON_INVALID_TOKEN, JSON_OUT_OF_MEMORY, JSON_SUCCESS, JSON_UNICODE_CODE_POINT_ZERO, JSON_UNICODE_ESCAPE_FORMAT, JSON_UNICODE_HIGH_ESCAPE, JSON_UNICODE_HIGH_SURROGATE, JSON_UNICODE_LOW_SURROGATE, JSON_UNICODE_UNTRANSLATABLE, jsonapi_appendBinaryStringInfo, jsonapi_appendStringInfoChar, jsonapi_resetStringInfo, MAX_UNICODE_EQUIVALENT_STRING, JsonLexContext::need_escapes, pg_lfind8(), pg_lfind8_le(), pg_unicode_to_server_noerror(), PG_UTF8, pg_utf_mblen, PQExpBufferBroken, JsonLexContext::prev_token_terminator, JsonLexContext::strval, surrogate_pair_to_codepoint(), JsonLexContext::token_start, JsonLexContext::token_terminator, and unicode_to_utf8().

Referenced by json_lex().

lex_expect()

lex_peek()

makeJsonLexContextCstringLen()

Definition at line 392 of file jsonapi.c.

394{

395 if (lex == NULL)

396 {

398 if (!lex)

401 }

402 else

404

411 if (need_escapes)

412 {

413

414

415

416

417

420 }

421

422 return lex;

423}

References ALLOC0, encoding, JsonLexContext::errormsg, failed_oom, JsonLexContext::flags, JsonLexContext::input, JsonLexContext::input_encoding, JsonLexContext::input_length, jsonapi_makeStringInfo, JSONLEX_FREE_STRUCT, JSONLEX_FREE_STRVAL, len, JsonLexContext::line_number, JsonLexContext::line_start, JsonLexContext::need_escapes, JsonLexContext::strval, and JsonLexContext::token_terminator.

Referenced by get_json_object_as_hash(), handle_oauth_sasl_error(), json_parse_manifest(), json_recv(), jsonb_from_cstring(), main(), makeJsonLexContext(), parse_oauth_json(), populate_array_json(), and test_gb18030_json().

makeJsonLexContextIncremental()

Definition at line 497 of file jsonapi.c.

500{

501 if (lex == NULL)

502 {

504 if (!lex)

506

508 }

509 else

511

514

516 {

518 {

521 }

522

523

524 return lex;

525 }

526

528 if (need_escapes)

529 {

530

531

532

533

534

537 }

538

539 return lex;

static bool allocate_incremental_state(JsonLexContext *lex)

References ALLOC0, allocate_incremental_state(), encoding, failed_oom, JsonLexContext::flags, FREE, JsonLexContext::input_encoding, jsonapi_makeStringInfo, JSONLEX_FREE_STRUCT, JSONLEX_FREE_STRVAL, JsonLexContext::line_number, JsonLexContext::need_escapes, and JsonLexContext::strval.

Referenced by json_parse_manifest_incremental_init(), and main().

next_prediction()

parse_array()

Definition at line 1511 of file jsonapi.c.

1513{

1514

1515

1516

1517

1521

1522#ifndef FRONTEND

1524#endif

1525

1526 if (astart != NULL)

1527 {

1530 return result;

1531 }

1532

1533

1534

1535

1536

1537

1538

1540

1543 {

1545

1547 {

1550 break;

1552 }

1553 }

1555 return result;

1556

1559 return result;

1560

1562

1563 if (aend != NULL)

1564 {

1567 return result;

1568 }

1569

JsonParseErrorType(* json_struct_action)(void *state)

void check_stack_depth(void)

json_struct_action array_end

json_struct_action array_start

References JsonSemAction::array_end, JsonSemAction::array_start, check_stack_depth(), json_lex(), JSON_PARSE_ARRAY_NEXT, JSON_PARSE_ARRAY_START, JSON_SUCCESS, JSON_TOKEN_ARRAY_END, JSON_TOKEN_ARRAY_START, JSON_TOKEN_COMMA, lex_expect(), JsonLexContext::lex_level, lex_peek(), parse_array_element(), sem, and JsonSemAction::semstate.

Referenced by parse_array_element(), parse_object_field(), and pg_parse_json().

parse_array_element()

Definition at line 1467 of file jsonapi.c.

1469{

1474 bool isnull;

1475

1477

1478 if (astart != NULL)

1479 {

1480 result = (*astart) (sem->semstate, isnull);

1482 return result;

1483 }

1484

1485

1486 switch (tok)

1487 {

1490 break;

1493 break;

1494 default:

1496 }

1497

1499 return result;

1500

1501 if (aend != NULL)

1502 {

1503 result = (*aend) (sem->semstate, isnull);

1505 return result;

1506 }

1507

static JsonParseErrorType parse_object(JsonLexContext *lex, const JsonSemAction *sem)

static JsonParseErrorType parse_scalar(JsonLexContext *lex, const JsonSemAction *sem)

static JsonParseErrorType parse_array(JsonLexContext *lex, const JsonSemAction *sem)

JsonParseErrorType(* json_aelem_action)(void *state, bool isnull)

json_aelem_action array_element_start

json_aelem_action array_element_end

References JsonSemAction::array_element_end, JsonSemAction::array_element_start, JSON_SUCCESS, JSON_TOKEN_ARRAY_START, JSON_TOKEN_NULL, JSON_TOKEN_OBJECT_START, lex_peek(), parse_array(), parse_object(), parse_scalar(), sem, and JsonSemAction::semstate.

Referenced by json_count_array_elements(), and parse_array().

parse_object()

Definition at line 1388 of file jsonapi.c.

1390{

1391

1392

1393

1394

1399

1400#ifndef FRONTEND

1401

1402

1403

1404

1405

1407#endif

1408

1409 if (ostart != NULL)

1410 {

1413 return result;

1414 }

1415

1416

1417

1418

1419

1420

1421

1423

1427 return result;

1428

1430 switch (tok)

1431 {

1435 {

1438 break;

1440 }

1441 break;

1443 break;

1444 default:

1445

1447 }

1449 return result;

1450

1453 return result;

1454

1456

1457 if (oend != NULL)

1458 {

1461 return result;

1462 }

1463

static JsonParseErrorType parse_object_field(JsonLexContext *lex, const JsonSemAction *sem)

json_struct_action object_start

json_struct_action object_end

References Assert(), check_stack_depth(), json_lex(), JSON_PARSE_OBJECT_NEXT, JSON_PARSE_OBJECT_START, JSON_SUCCESS, JSON_TOKEN_COMMA, JSON_TOKEN_OBJECT_END, JSON_TOKEN_OBJECT_START, JSON_TOKEN_STRING, lex_expect(), JsonLexContext::lex_level, lex_peek(), JsonSemAction::object_end, JsonSemAction::object_start, parse_object_field(), report_parse_error(), sem, and JsonSemAction::semstate.

Referenced by parse_array_element(), parse_object_field(), and pg_parse_json().

parse_object_field()

Definition at line 1312 of file jsonapi.c.

1314{

1315

1316

1317

1318

1319

1320

1321 char *fname = NULL;

1324 bool isnull;

1327

1330 if ((ostart != NULL || oend != NULL) && lex->need_escapes)

1331 {

1332

1334 if (fname == NULL)

1336 }

1339 {

1340 FREE(fname);

1341 return result;

1342 }

1343

1346 {

1347 FREE(fname);

1348 return result;

1349 }

1350

1353

1354 if (ostart != NULL)

1355 {

1356 result = (*ostart) (sem->semstate, fname, isnull);

1358 goto ofield_cleanup;

1359 }

1360

1361 switch (tok)

1362 {

1365 break;

1368 break;

1369 default:

1371 }

1373 goto ofield_cleanup;

1374

1375 if (oend != NULL)

1376 {

1377 result = (*oend) (sem->semstate, fname, isnull);

1379 goto ofield_cleanup;

1380 }

1381

1382ofield_cleanup:

1384 FREE(fname);

1385 return result;

JsonParseErrorType(* json_ofield_action)(void *state, char *fname, bool isnull)

json_ofield_action object_field_start

json_ofield_action object_field_end

References JsonLexContext::flags, FREE, json_lex(), JSON_OUT_OF_MEMORY, JSON_PARSE_OBJECT_LABEL, JSON_PARSE_STRING, JSON_SUCCESS, JSON_TOKEN_ARRAY_START, JSON_TOKEN_COLON, JSON_TOKEN_NULL, JSON_TOKEN_OBJECT_START, JSON_TOKEN_STRING, JSONLEX_CTX_OWNS_TOKENS, lex_expect(), lex_peek(), JsonLexContext::need_escapes, JsonSemAction::object_field_end, JsonSemAction::object_field_start, parse_array(), parse_object(), parse_scalar(), report_parse_error(), sem, JsonSemAction::semstate, STRDUP, and JsonLexContext::strval.

Referenced by parse_object().

parse_scalar()

Definition at line 1252 of file jsonapi.c.

1254{

1255 char *val = NULL;

1259

1260

1265

1266

1267 if (sfunc == NULL)

1269

1270

1272 {

1274 {

1276 if (val == NULL)

1278 }

1279 }

1280 else

1281 {

1283

1285 if (val == NULL)

1287

1290 }

1291

1292

1295 {

1297 return result;

1298 }

1299

1300

1301

1302

1303

1305

1308

1309 return result;

JsonParseErrorType(* json_scalar_action)(void *state, char *token, JsonTokenType tokentype)

json_scalar_action scalar

References ALLOC, JsonLexContext::flags, FREE, json_lex(), JSON_OUT_OF_MEMORY, JSON_PARSE_VALUE, JSON_SUCCESS, JSON_TOKEN_FALSE, JSON_TOKEN_NULL, JSON_TOKEN_NUMBER, JSON_TOKEN_STRING, JSON_TOKEN_TRUE, JSONLEX_CTX_OWNS_TOKENS, len, lex_peek(), JsonLexContext::need_escapes, report_parse_error(), JsonSemAction::scalar, sem, JsonSemAction::semstate, STRDUP, JsonLexContext::strval, JsonLexContext::token_start, JsonLexContext::token_terminator, and val.

Referenced by parse_array_element(), parse_object_field(), and pg_parse_json().

pg_parse_json()

Definition at line 744 of file jsonapi.c.

746{

747#ifdef FORCE_JSON_PSTACK

748

749

750

751

752

755

757

758#else

759

762

767

768

771 return result;

772

774

775

776 switch (tok)

777 {

780 break;

783 break;

784 default:

785 result = parse_scalar(lex, sem);

786 }

787

790

791 return result;

792#endif

JsonParseErrorType pg_parse_json_incremental(JsonLexContext *lex, const JsonSemAction *sem, const char *json, size_t len, bool is_last)

References allocate_incremental_state(), failed_oom, JsonLexContext::incremental, JsonLexContext::input, JsonLexContext::input_length, JSON_INVALID_LEXER_TYPE, json_lex(), JSON_OUT_OF_MEMORY, JSON_PARSE_END, JSON_SUCCESS, JSON_TOKEN_ARRAY_START, JSON_TOKEN_END, JSON_TOKEN_OBJECT_START, lex_expect(), lex_peek(), parse_array(), parse_object(), parse_scalar(), pg_parse_json_incremental(), and sem.

Referenced by handle_oauth_sasl_error(), json_parse_manifest(), json_validate(), main(), parse_oauth_json(), pg_parse_json_or_errsave(), and test_gb18030_json().

pg_parse_json_incremental()

Definition at line 868 of file jsonapi.c.

874{

879

884

889

890

893 return result;

894

896

897

898

900 {

902

904 }

905

907 {

910

911

912

913

914 if (top == tok)

915 {

916

917

918

919

921 {

924 return result;

926 }

927 }

929 {

930

931

932

933

934

936 }

937 else if (IS_SEM(top))

938 {

939

940

941

942

943

944

945

946 switch (top)

947 {

949 {

951

954

955 if (ostart != NULL)

956 {

959 return result;

960 }

961

964 }

965 break;

967 {

969

971 if (oend != NULL)

972 {

975 return result;

976 }

977 }

978 break;

980 {

982

985

986 if (astart != NULL)

987 {

990 return result;

991 }

992

995 }

996 break;

998 {

1000

1002 if (aend != NULL)

1003 {

1006 return result;

1007 }

1008 }

1009 break;

1011 {

1012

1013

1014

1015

1016

1017 char *fname = NULL;

1020

1021 if ((ostart != NULL || oend != NULL) && lex->need_escapes)

1022 {

1024 if (fname == NULL)

1026 }

1028 }

1029 break;

1031 {

1032

1033

1034

1035

1038

1040

1041 if (ostart != NULL)

1042 {

1044

1045 result = (*ostart) (sem->semstate, fname, isnull);

1047 return result;

1048 }

1049 }

1050 break;

1052 {

1054

1055 if (oend != NULL)

1056 {

1059

1060 result = (*oend) (sem->semstate, fname, isnull);

1062 return result;

1063 }

1064 }

1065 break;

1067 {

1070

1072

1073 if (astart != NULL)

1074 {

1075 result = (*astart) (sem->semstate, isnull);

1077 return result;

1078 }

1079 }

1080 break;

1082 {

1084

1085 if (aend != NULL)

1086 {

1088

1089 result = (*aend) (sem->semstate, isnull);

1091 return result;

1092 }

1093 }

1094 break;

1096 {

1098

1100

1101 if (sfunc != NULL)

1102 {

1103

1104

1105

1106

1107

1108

1109

1110

1112 {

1114 {

1118 }

1119 }

1120 else

1121 {

1123

1127

1130 }

1132 }

1133 }

1134 break;

1136 {

1137

1138

1139

1140

1141

1142

1143

1145

1146 if (sfunc != NULL)

1147 {

1149

1150

1151

1152

1153

1154

1155

1159

1161 return result;

1162 }

1163 }

1164 break;

1165 default:

1166

1167 break;

1168 }

1169 }

1170 else

1171 {

1172

1173

1174

1175

1176

1177

1178

1179

1180 switch (top)

1181 {

1185 else

1186 {

1189 }

1190 break;

1199 break;

1203 break;

1207 break;

1212 else

1214 break;

1217 break;

1220 break;

1223 break;

1226 break;

1229 break;

1232 break;

1233 default:

1235 }

1237 }

1238 }

1239

#define JSON_TD_MAX_STACK

static void set_fnull(JsonLexContext *lex, bool fnull)

static bool inc_lex_level(JsonLexContext *lex)

static bool have_prediction(JsonParserStack *pstack)

static char next_prediction(JsonParserStack *pstack)

static void push_prediction(JsonParserStack *pstack, td_entry entry)

static char * get_fname(JsonLexContext *lex)

static char JSON_PROD_GOAL[]

static td_entry td_parser_table[JSON_NUM_NONTERMINALS][JSON_NUM_TERMINALS]

static char pop_prediction(JsonParserStack *pstack)

static bool get_fnull(JsonLexContext *lex)

static void dec_lex_level(JsonLexContext *lex)

References ALLOC, JsonSemAction::array_element_end, JsonSemAction::array_element_start, JsonSemAction::array_end, JsonSemAction::array_start, Assert(), dec_lex_level(), failed_inc_oom, failed_oom, JsonLexContext::flags, FREE, get_fname(), get_fnull(), have_prediction(), inc_lex_level(), JsonLexContext::inc_state, JsonLexContext::incremental, JsonLexContext::input, JsonLexContext::input_length, JsonIncrementalState::is_last_chunk, IS_NT, IS_SEM, JSON_INVALID_LEXER_TYPE, json_lex(), JSON_NESTING_TOO_DEEP, JSON_NT_ARRAY_ELEMENTS, JSON_NT_KEY_PAIRS, JSON_NT_MORE_ARRAY_ELEMENTS, JSON_NT_MORE_KEY_PAIRS, JSON_OUT_OF_MEMORY, JSON_PARSE_ARRAY_NEXT, JSON_PARSE_ARRAY_START, JSON_PARSE_END, JSON_PARSE_OBJECT_LABEL, JSON_PARSE_OBJECT_NEXT, JSON_PARSE_OBJECT_START, JSON_PARSE_STRING, JSON_PARSE_VALUE, JSON_PROD_GOAL, JSON_SEM_AELEM_END, JSON_SEM_AELEM_START, JSON_SEM_AEND, JSON_SEM_ASTART, JSON_SEM_OEND, JSON_SEM_OFIELD_END, JSON_SEM_OFIELD_INIT, JSON_SEM_OFIELD_START, JSON_SEM_OSTART, JSON_SEM_SCALAR_CALL, JSON_SEM_SCALAR_INIT, JSON_SUCCESS, JSON_TD_MAX_STACK, JSON_TOKEN_ARRAY_END, JSON_TOKEN_ARRAY_START, JSON_TOKEN_COLON, JSON_TOKEN_COMMA, JSON_TOKEN_END, JSON_TOKEN_FALSE, JSON_TOKEN_NULL, JSON_TOKEN_NUMBER, JSON_TOKEN_OBJECT_END, JSON_TOKEN_OBJECT_START, JSON_TOKEN_STRING, JSON_TOKEN_TRUE, JSONLEX_CTX_OWNS_TOKENS, len, JsonLexContext::lex_level, lex_peek(), JsonLexContext::line_start, JsonLexContext::need_escapes, next_prediction(), JsonSemAction::object_end, JsonSemAction::object_field_end, JsonSemAction::object_field_start, JsonSemAction::object_start, OFS, pop_prediction(), JsonLexContext::pstack, push_prediction(), report_parse_error(), JsonSemAction::scalar, JsonParserStack::scalar_tok, JsonParserStack::scalar_val, sem, JsonSemAction::semstate, set_fname(), set_fnull(), JsonIncrementalState::started, STRDUP, JsonLexContext::strval, TD_ENTRY, td_parser_table, JsonLexContext::token_start, and JsonLexContext::token_terminator.

Referenced by json_parse_manifest_incremental_chunk(), main(), and pg_parse_json().

pop_prediction()

push_prediction()

report_parse_error()

Definition at line 2360 of file jsonapi.c.

2362{

2363

2366

2367

2368 switch (ctx)

2369 {

2388 }

2389

2390

2391

2392

2393

2395 return JSON_SUCCESS;

References Assert(), JSON_EXPECTED_ARRAY_FIRST, JSON_EXPECTED_ARRAY_NEXT, JSON_EXPECTED_COLON, JSON_EXPECTED_END, JSON_EXPECTED_JSON, JSON_EXPECTED_MORE, JSON_EXPECTED_OBJECT_FIRST, JSON_EXPECTED_OBJECT_NEXT, JSON_EXPECTED_STRING, JSON_PARSE_ARRAY_NEXT, JSON_PARSE_ARRAY_START, JSON_PARSE_END, JSON_PARSE_OBJECT_COMMA, JSON_PARSE_OBJECT_LABEL, JSON_PARSE_OBJECT_NEXT, JSON_PARSE_OBJECT_START, JSON_PARSE_STRING, JSON_PARSE_VALUE, JSON_SUCCESS, JSON_TOKEN_END, JsonLexContext::token_start, and JsonLexContext::token_type.

Referenced by lex_expect(), parse_object(), parse_object_field(), parse_scalar(), and pg_parse_json_incremental().

set_fname()

static void set_fname ( JsonLexContext * lex, char * fname ) inlinestatic

set_fnull()

static void set_fnull ( JsonLexContext * lex, bool fnull ) inlinestatic

setJsonLexContextOwnsTokens()

void setJsonLexContextOwnsTokens ( JsonLexContext * lex,
bool owned_by_context
)

failed_inc_oom

failed_oom

JSON_PROD_ARRAY

JSON_PROD_ARRAY_ELEMENTS

JSON_PROD_EPSILON

char JSON_PROD_EPSILON[] = {0} static

JSON_PROD_GOAL

JSON_PROD_KEY_PAIRS

JSON_PROD_MORE_ARRAY_ELEMENTS

JSON_PROD_MORE_KEY_PAIRS

JSON_PROD_OBJECT

JSON_PROD_SCALAR_FALSE

JSON_PROD_SCALAR_NULL

JSON_PROD_SCALAR_NUMBER

JSON_PROD_SCALAR_STRING

JSON_PROD_SCALAR_TRUE

nullSemAction

Initial value:

=

{

NULL, NULL, NULL, NULL, NULL,

NULL, NULL, NULL, NULL, NULL

}

Definition at line 287 of file jsonapi.c.

Referenced by json_count_array_elements(), json_in(), json_recv(), json_validate(), and main().

td_parser_table

Initial value:

=

{

}

static char JSON_PROD_MORE_KEY_PAIRS[]

static char JSON_PROD_KEY_PAIRS[]

static char JSON_PROD_SCALAR_STRING[]

static char JSON_PROD_ARRAY_ELEMENTS[]

static char JSON_PROD_SCALAR_NUMBER[]

static char JSON_PROD_EPSILON[]

static char JSON_PROD_SCALAR_NULL[]

static char JSON_PROD_MORE_ARRAY_ELEMENTS[]

static char JSON_PROD_SCALAR_FALSE[]

static char JSON_PROD_OBJECT[]

static char JSON_PROD_ARRAY[]

static char JSON_PROD_SCALAR_TRUE[]

Definition at line 241 of file jsonapi.c.

Referenced by pg_parse_json_incremental().