diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/pg_operator.h | 13 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.h | 31 | ||||
-rw-r--r-- | src/include/utils/json.h | 16 | ||||
-rw-r--r-- | src/include/utils/jsonapi.h | 110 |
5 files changed, 171 insertions, 1 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 0eb8eefb8ff..aa8b715a651 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201303271 +#define CATALOG_VERSION_NO 201303291 #endif diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index d79d76ee24b..d2e1fef985d 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -1724,6 +1724,19 @@ DATA(insert OID = 3899 ( "-" PGNSP PGUID b f f 3831 3831 3831 0 0 range_minu DESCR("range difference"); DATA(insert OID = 3900 ( "*" PGNSP PGUID b f f 3831 3831 3831 3900 0 range_intersect - - )); DESCR("range intersection"); +DATA(insert OID = 3962 ( "->" PGNSP PGUID b f f 114 25 114 0 0 json_object_field - - )); +DESCR("get json object field"); +DATA(insert OID = 3963 ( "->>" PGNSP PGUID b f f 114 25 25 0 0 json_object_field_text - - )); +DESCR("get json object field as text"); +DATA(insert OID = 3964 ( "->" PGNSP PGUID b f f 114 23 114 0 0 json_array_element - - )); +DESCR("get json array element"); +DATA(insert OID = 3965 ( "->>" PGNSP PGUID b f f 114 23 25 0 0 json_array_element_text - - )); +DESCR("get json array element as text"); +DATA(insert OID = 3966 ( "#>" PGNSP PGUID b f f 114 1009 114 0 0 json_extract_path_op - - )); +DESCR("get value from json with path elements"); +DATA(insert OID = 3967 ( "#>>" PGNSP PGUID b f f 114 1009 25 0 0 json_extract_path_text_op - - )); +DESCR("get value from json as text with path elements"); + /* diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 151987ec1d3..4d5cd9fdb66 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -4118,6 +4118,37 @@ DESCR("aggregate input into json"); DATA(insert OID = 3176 ( to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 114 "2283" _null_ _null_ _null_ _null_ to_json _null_ _null_ _null_ )); DESCR("map input to json"); +DATA(insert OID = 3947 ( json_object_field PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 114 "114 25" _null_ _null_ "{from_json, field_name}" _null_ json_object_field _null_ _null_ _null_ )); +DESCR("get json object field"); +DATA(insert OID = 3948 ( json_object_field_text PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 25 "114 25" _null_ _null_ "{from_json, field_name}" _null_ json_object_field_text _null_ _null_ _null_ )); +DESCR("get json object field as text"); +DATA(insert OID = 3949 ( json_array_element PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 114 "114 23" _null_ _null_ "{from_json, element_index}" _null_ json_array_element _null_ _null_ _null_ )); +DESCR("get json array element"); +DATA(insert OID = 3950 ( json_array_element_text PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 25 "114 23" _null_ _null_ "{from_json, element_index}" _null_ json_array_element_text _null_ _null_ _null_ )); +DESCR("get json array element as text"); +DATA(insert OID = 3951 ( json_extract_path PGNSP PGUID 12 1 0 25 0 f f f f t f s 2 0 114 "114 1009" "{114,1009}" "{i,v}" "{from_json,path_elems}" _null_ json_extract_path _null_ _null_ _null_ )); +DESCR("get value from json with path elements"); +DATA(insert OID = 3952 ( json_extract_path_op PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 114 "114 1009" _null_ _null_ "{from_json,path_elems}" _null_ json_extract_path _null_ _null_ _null_ )); +DESCR("get value from json with path elements"); +DATA(insert OID = 3953 ( json_extract_path_text PGNSP PGUID 12 1 0 25 0 f f f f t f s 2 0 25 "114 1009" "{114,1009}" "{i,v}" "{from_json,path_elems}" _null_ json_extract_path_text _null_ _null_ _null_ )); +DESCR("get value from json as text with path elements"); +DATA(insert OID = 3954 ( json_extract_path_text_op PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 25 "114 1009" _null_ _null_ "{from_json,path_elems}" _null_ json_extract_path_text _null_ _null_ _null_ )); +DESCR("get value from json as text with path elements"); +DATA(insert OID = 3955 ( json_array_elements PGNSP PGUID 12 1 100 0 0 f f f f t t s 1 0 114 "114" "{114,114}" "{i,o}" "{from_json,value}" _null_ json_array_elements _null_ _null_ _null_ )); +DESCR("key value pairs of a json object"); +DATA(insert OID = 3956 ( json_array_length PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 23 "114" _null_ _null_ _null_ _null_ json_array_length _null_ _null_ _null_ )); +DESCR("length of json array"); +DATA(insert OID = 3957 ( json_object_keys PGNSP PGUID 12 1 100 0 0 f f f f t t s 1 0 25 "114" _null_ _null_ _null_ _null_ json_object_keys _null_ _null_ _null_ )); +DESCR("get json object keys"); +DATA(insert OID = 3958 ( json_each PGNSP PGUID 12 1 100 0 0 f f f f t t s 1 0 2249 "114" "{114,25,114}" "{i,o,o}" "{from_json,key,value}" _null_ json_each _null_ _null_ _null_ )); +DESCR("key value pairs of a json object"); +DATA(insert OID = 3959 ( json_each_text PGNSP PGUID 12 1 100 0 0 f f f f t t s 1 0 2249 "114" "{114,25,25}" "{i,o,o}" "{from_json,key,value}" _null_ json_each_text _null_ _null_ _null_ )); +DESCR("key value pairs of a json object"); +DATA(insert OID = 3960 ( json_populate_record PGNSP PGUID 12 1 0 0 0 f f f f f f s 3 0 2283 "2283 114 16" _null_ _null_ _null_ _null_ json_populate_record _null_ _null_ _null_ )); +DESCR("get record fields from a json object"); +DATA(insert OID = 3961 ( json_populate_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 3 0 2283 "2283 114 16" _null_ _null_ _null_ _null_ json_populate_recordset _null_ _null_ _null_ )); +DESCR("get set of records with fields from a json array of objects"); + /* uuid */ DATA(insert OID = 2952 ( uuid_in PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2950 "2275" _null_ _null_ _null_ _null_ uuid_in _null_ _null_ _null_ )); DESCR("I/O"); diff --git a/src/include/utils/json.h b/src/include/utils/json.h index caaa769449a..4845f5f6183 100644 --- a/src/include/utils/json.h +++ b/src/include/utils/json.h @@ -17,6 +17,7 @@ #include "fmgr.h" #include "lib/stringinfo.h" +/* functions in json.c */ extern Datum json_in(PG_FUNCTION_ARGS); extern Datum json_out(PG_FUNCTION_ARGS); extern Datum json_recv(PG_FUNCTION_ARGS); @@ -32,4 +33,19 @@ extern Datum json_agg_finalfn(PG_FUNCTION_ARGS); extern void escape_json(StringInfo buf, const char *str); +/* functions in jsonfuncs.c */ +extern Datum json_object_field(PG_FUNCTION_ARGS); +extern Datum json_object_field_text(PG_FUNCTION_ARGS); +extern Datum json_array_element(PG_FUNCTION_ARGS); +extern Datum json_array_element_text(PG_FUNCTION_ARGS); +extern Datum json_extract_path(PG_FUNCTION_ARGS); +extern Datum json_extract_path_text(PG_FUNCTION_ARGS); +extern Datum json_object_keys(PG_FUNCTION_ARGS); +extern Datum json_array_length(PG_FUNCTION_ARGS); +extern Datum json_each(PG_FUNCTION_ARGS); +extern Datum json_each_text(PG_FUNCTION_ARGS); +extern Datum json_array_elements(PG_FUNCTION_ARGS); +extern Datum json_populate_record(PG_FUNCTION_ARGS); +extern Datum json_populate_recordset(PG_FUNCTION_ARGS); + #endif /* JSON_H */ diff --git a/src/include/utils/jsonapi.h b/src/include/utils/jsonapi.h new file mode 100644 index 00000000000..f96e9538cdc --- /dev/null +++ b/src/include/utils/jsonapi.h @@ -0,0 +1,110 @@ +/*------------------------------------------------------------------------- + * + * jsonapi.h + * Declarations for JSON API support. + * + * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/jsonapi.h + * + *------------------------------------------------------------------------- + */ + +#ifndef JSONAPI_H +#define JSONAPI_H + +#include "lib/stringinfo.h" + +typedef enum +{ + JSON_TOKEN_INVALID, + JSON_TOKEN_STRING, + JSON_TOKEN_NUMBER, + JSON_TOKEN_OBJECT_START, + JSON_TOKEN_OBJECT_END, + JSON_TOKEN_ARRAY_START, + JSON_TOKEN_ARRAY_END, + JSON_TOKEN_COMMA, + JSON_TOKEN_COLON, + JSON_TOKEN_TRUE, + JSON_TOKEN_FALSE, + JSON_TOKEN_NULL, + JSON_TOKEN_END, +} JsonTokenType; + + +/* + * All the fields in this structure should be treated as read-only. + * + * If strval is not null, then it should contain the de-escaped value + * of the lexeme if it's a string. Otherwise most of these field names + * should be self-explanatory. + * + * line_number and line_start are principally for use by the parser's + * error reporting routines. + * token_terminator and prev_token_terminator point to the character + * AFTER the end of the token, i.e. where there would be a nul byte + * if we were using nul-terminated strings. + */ +typedef struct JsonLexContext +{ + char *input; + int input_length; + char *token_start; + char *token_terminator; + char *prev_token_terminator; + JsonTokenType token_type; + int lex_level; + int line_number; + char *line_start; + StringInfo strval; +} JsonLexContext; + +typedef void (*json_struct_action) (void *state); +typedef void (*json_ofield_action) (void *state, char *fname, bool isnull); +typedef void (*json_aelem_action) (void *state, bool isnull); +typedef void (*json_scalar_action) (void *state, char *token, JsonTokenType tokentype); + + +/* + * Semantic Action structure for use in parsing json. + * Any of these actions can be NULL, in which case nothing is done at that + * point, Likewise, semstate can be NULL. Using an all-NULL structure amounts + * to doing a pure parse with no side-effects, and is therefore exactly + * what the json input routines do. + */ +typedef struct jsonSemAction +{ + void *semstate; + json_struct_action object_start; + json_struct_action object_end; + json_struct_action array_start; + json_struct_action array_end; + json_ofield_action object_field_start; + json_ofield_action object_field_end; + json_aelem_action array_element_start; + json_aelem_action array_element_end; + json_scalar_action scalar; +} jsonSemAction, *JsonSemAction; + +/* + * parse_json will parse the string in the lex calling the + * action functions in sem at the appropriate points. It is + * up to them to keep what state they need in semstate. If they + * need access to the state of the lexer, then its pointer + * should be passed to them as a member of whatever semstate + * points to. If the action pointers are NULL the parser + * does nothing and just continues. + */ +extern void pg_parse_json(JsonLexContext *lex, JsonSemAction sem); + +/* + * constructor for JsonLexContext, with or without strval element. + * If supplied, the strval element will contain a de-escaped version of + * the lexeme. However, doing this imposes a performance penalty, so + * it should be avoided if the de-escaped lexeme is not required. + */ +extern JsonLexContext *makeJsonLexContext(text *json, bool need_escapes); + +#endif /* JSONAPI_H */ |