| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * jsonapi.h |
| 4 | * Declarations for JSON API support. |
| 5 | * |
| 6 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 7 | * Portions Copyright (c) 1994, Regents of the University of California |
| 8 | * |
| 9 | * src/include/utils/jsonapi.h |
| 10 | * |
| 11 | *------------------------------------------------------------------------- |
| 12 | */ |
| 13 | |
| 14 | #ifndef JSONAPI_H |
| 15 | #define JSONAPI_H |
| 16 | |
| 17 | #include "jsonb.h" |
| 18 | #include "lib/stringinfo.h" |
| 19 | |
| 20 | typedef enum |
| 21 | { |
| 22 | JSON_TOKEN_INVALID, |
| 23 | JSON_TOKEN_STRING, |
| 24 | JSON_TOKEN_NUMBER, |
| 25 | JSON_TOKEN_OBJECT_START, |
| 26 | JSON_TOKEN_OBJECT_END, |
| 27 | JSON_TOKEN_ARRAY_START, |
| 28 | JSON_TOKEN_ARRAY_END, |
| 29 | JSON_TOKEN_COMMA, |
| 30 | JSON_TOKEN_COLON, |
| 31 | JSON_TOKEN_TRUE, |
| 32 | JSON_TOKEN_FALSE, |
| 33 | JSON_TOKEN_NULL, |
| 34 | JSON_TOKEN_END |
| 35 | } JsonTokenType; |
| 36 | |
| 37 | |
| 38 | /* |
| 39 | * All the fields in this structure should be treated as read-only. |
| 40 | * |
| 41 | * If strval is not null, then it should contain the de-escaped value |
| 42 | * of the lexeme if it's a string. Otherwise most of these field names |
| 43 | * should be self-explanatory. |
| 44 | * |
| 45 | * line_number and line_start are principally for use by the parser's |
| 46 | * error reporting routines. |
| 47 | * token_terminator and prev_token_terminator point to the character |
| 48 | * AFTER the end of the token, i.e. where there would be a nul byte |
| 49 | * if we were using nul-terminated strings. |
| 50 | */ |
| 51 | typedef struct JsonLexContext |
| 52 | { |
| 53 | char *input; |
| 54 | int input_length; |
| 55 | char *token_start; |
| 56 | char *token_terminator; |
| 57 | char *prev_token_terminator; |
| 58 | JsonTokenType token_type; |
| 59 | int lex_level; |
| 60 | int line_number; |
| 61 | char *line_start; |
| 62 | StringInfo strval; |
| 63 | } JsonLexContext; |
| 64 | |
| 65 | typedef void (*json_struct_action) (void *state); |
| 66 | typedef void (*json_ofield_action) (void *state, char *fname, bool isnull); |
| 67 | typedef void (*json_aelem_action) (void *state, bool isnull); |
| 68 | typedef void (*json_scalar_action) (void *state, char *token, JsonTokenType tokentype); |
| 69 | |
| 70 | |
| 71 | /* |
| 72 | * Semantic Action structure for use in parsing json. |
| 73 | * Any of these actions can be NULL, in which case nothing is done at that |
| 74 | * point, Likewise, semstate can be NULL. Using an all-NULL structure amounts |
| 75 | * to doing a pure parse with no side-effects, and is therefore exactly |
| 76 | * what the json input routines do. |
| 77 | * |
| 78 | * The 'fname' and 'token' strings passed to these actions are palloc'd. |
| 79 | * They are not free'd or used further by the parser, so the action function |
| 80 | * is free to do what it wishes with them. |
| 81 | */ |
| 82 | typedef struct JsonSemAction |
| 83 | { |
| 84 | void *semstate; |
| 85 | json_struct_action object_start; |
| 86 | json_struct_action object_end; |
| 87 | json_struct_action array_start; |
| 88 | json_struct_action array_end; |
| 89 | json_ofield_action object_field_start; |
| 90 | json_ofield_action object_field_end; |
| 91 | json_aelem_action array_element_start; |
| 92 | json_aelem_action array_element_end; |
| 93 | json_scalar_action scalar; |
| 94 | } JsonSemAction; |
| 95 | |
| 96 | /* |
| 97 | * parse_json will parse the string in the lex calling the |
| 98 | * action functions in sem at the appropriate points. It is |
| 99 | * up to them to keep what state they need in semstate. If they |
| 100 | * need access to the state of the lexer, then its pointer |
| 101 | * should be passed to them as a member of whatever semstate |
| 102 | * points to. If the action pointers are NULL the parser |
| 103 | * does nothing and just continues. |
| 104 | */ |
| 105 | extern void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem); |
| 106 | |
| 107 | /* |
| 108 | * json_count_array_elements performs a fast secondary parse to determine the |
| 109 | * number of elements in passed array lex context. It should be called from an |
| 110 | * array_start action. |
| 111 | */ |
| 112 | extern int json_count_array_elements(JsonLexContext *lex); |
| 113 | |
| 114 | /* |
| 115 | * constructors for JsonLexContext, with or without strval element. |
| 116 | * If supplied, the strval element will contain a de-escaped version of |
| 117 | * the lexeme. However, doing this imposes a performance penalty, so |
| 118 | * it should be avoided if the de-escaped lexeme is not required. |
| 119 | * |
| 120 | * If you already have the json as a text* value, use the first of these |
| 121 | * functions, otherwise use makeJsonLexContextCstringLen(). |
| 122 | */ |
| 123 | extern JsonLexContext *makeJsonLexContext(text *json, bool need_escapes); |
| 124 | extern JsonLexContext *makeJsonLexContextCstringLen(char *json, |
| 125 | int len, |
| 126 | bool need_escapes); |
| 127 | |
| 128 | /* |
| 129 | * Utility function to check if a string is a valid JSON number. |
| 130 | * |
| 131 | * str argument does not need to be nul-terminated. |
| 132 | */ |
| 133 | extern bool IsValidJsonNumber(const char *str, int len); |
| 134 | |
| 135 | /* |
| 136 | * Flag types for iterate_json(b)_values to specify what elements from a |
| 137 | * json(b) document we want to iterate. |
| 138 | */ |
| 139 | typedef enum JsonToIndex |
| 140 | { |
| 141 | jtiKey = 0x01, |
| 142 | jtiString = 0x02, |
| 143 | jtiNumeric = 0x04, |
| 144 | jtiBool = 0x08, |
| 145 | jtiAll = jtiKey | jtiString | jtiNumeric | jtiBool |
| 146 | } JsonToIndex; |
| 147 | |
| 148 | /* an action that will be applied to each value in iterate_json(b)_values functions */ |
| 149 | typedef void (*JsonIterateStringValuesAction) (void *state, char *elem_value, int elem_len); |
| 150 | |
| 151 | /* an action that will be applied to each value in transform_json(b)_values functions */ |
| 152 | typedef text *(*JsonTransformStringValuesAction) (void *state, char *elem_value, int elem_len); |
| 153 | |
| 154 | extern uint32 parse_jsonb_index_flags(Jsonb *jb); |
| 155 | extern void iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state, |
| 156 | JsonIterateStringValuesAction action); |
| 157 | extern void iterate_json_values(text *json, uint32 flags, void *action_state, |
| 158 | JsonIterateStringValuesAction action); |
| 159 | extern Jsonb *transform_jsonb_string_values(Jsonb *jsonb, void *action_state, |
| 160 | JsonTransformStringValuesAction transform_action); |
| 161 | extern text *transform_json_string_values(text *json, void *action_state, |
| 162 | JsonTransformStringValuesAction transform_action); |
| 163 | |
| 164 | extern char *JsonEncodeDateTime(char *buf, Datum value, Oid typid); |
| 165 | |
| 166 | #endif /* JSONAPI_H */ |
| 167 | |