Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* jsonb.c
|
|
|
|
* I/O routines for jsonb type
|
|
|
|
*
|
2024-01-04 02:49:05 +01:00
|
|
|
* Copyright (c) 2014-2024, PostgreSQL Global Development Group
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
|
|
|
* src/backend/utils/adt/jsonb.c
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
#include "access/htup_details.h"
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
#include "catalog/pg_proc.h"
|
2014-12-12 21:31:14 +01:00
|
|
|
#include "catalog/pg_type.h"
|
2017-10-25 13:34:00 +02:00
|
|
|
#include "funcapi.h"
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
#include "libpq/pqformat.h"
|
2019-11-12 04:00:16 +01:00
|
|
|
#include "miscadmin.h"
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
#include "utils/builtins.h"
|
|
|
|
#include "utils/json.h"
|
|
|
|
#include "utils/jsonb.h"
|
2020-01-27 17:22:13 +01:00
|
|
|
#include "utils/jsonfuncs.h"
|
2019-11-12 04:00:16 +01:00
|
|
|
#include "utils/lsyscache.h"
|
2014-12-12 21:31:14 +01:00
|
|
|
#include "utils/typcache.h"
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
typedef struct JsonbInState
|
|
|
|
{
|
|
|
|
JsonbParseState *parseState;
|
|
|
|
JsonbValue *res;
|
Add more SQL/JSON constructor functions
This Patch introduces three SQL standard JSON functions:
JSON()
JSON_SCALAR()
JSON_SERIALIZE()
JSON() produces json values from text, bytea, json or jsonb values,
and has facilitites for handling duplicate keys.
JSON_SCALAR() produces a json value from any scalar sql value,
including json and jsonb.
JSON_SERIALIZE() produces text or bytea from input which containis
or represents json or jsonb;
For the most part these functions don't add any significant new
capabilities, but they will be of use to users wanting standard
compliant JSON handling.
Catversion bumped as this changes ruleutils.c.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Andrew Dunstan <andrew@dunslane.net>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera,
Peter Eisentraut
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
2023-07-20 15:21:43 +02:00
|
|
|
bool unique_keys;
|
2022-12-11 17:28:15 +01:00
|
|
|
Node *escontext;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
} JsonbInState;
|
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
typedef struct JsonbAggState
|
|
|
|
{
|
2015-10-15 19:46:09 +02:00
|
|
|
JsonbInState *res;
|
2023-07-20 09:19:56 +02:00
|
|
|
JsonTypeCategory key_category;
|
2015-10-15 19:46:09 +02:00
|
|
|
Oid key_output_func;
|
2023-07-20 09:19:56 +02:00
|
|
|
JsonTypeCategory val_category;
|
2015-10-15 19:46:09 +02:00
|
|
|
Oid val_output_func;
|
2015-09-18 20:39:39 +02:00
|
|
|
} JsonbAggState;
|
|
|
|
|
Add more SQL/JSON constructor functions
This Patch introduces three SQL standard JSON functions:
JSON()
JSON_SCALAR()
JSON_SERIALIZE()
JSON() produces json values from text, bytea, json or jsonb values,
and has facilitites for handling duplicate keys.
JSON_SCALAR() produces a json value from any scalar sql value,
including json and jsonb.
JSON_SERIALIZE() produces text or bytea from input which containis
or represents json or jsonb;
For the most part these functions don't add any significant new
capabilities, but they will be of use to users wanting standard
compliant JSON handling.
Catversion bumped as this changes ruleutils.c.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Andrew Dunstan <andrew@dunslane.net>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera,
Peter Eisentraut
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
2023-07-20 15:21:43 +02:00
|
|
|
static inline Datum jsonb_from_cstring(char *json, int len, bool unique_keys,
|
|
|
|
Node *escontext);
|
2022-12-11 17:28:15 +01:00
|
|
|
static bool checkStringLen(size_t len, Node *escontext);
|
2022-12-11 16:39:05 +01:00
|
|
|
static JsonParseErrorType jsonb_in_object_start(void *pstate);
|
|
|
|
static JsonParseErrorType jsonb_in_object_end(void *pstate);
|
|
|
|
static JsonParseErrorType jsonb_in_array_start(void *pstate);
|
|
|
|
static JsonParseErrorType jsonb_in_array_end(void *pstate);
|
|
|
|
static JsonParseErrorType jsonb_in_object_field_start(void *pstate, char *fname, bool isnull);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
static void jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal);
|
2022-12-11 16:39:05 +01:00
|
|
|
static JsonParseErrorType jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype);
|
2014-12-12 21:31:14 +01:00
|
|
|
static void composite_to_jsonb(Datum composite, JsonbInState *result);
|
|
|
|
static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims,
|
2023-10-10 07:50:15 +02:00
|
|
|
const Datum *vals, const bool *nulls, int *valcount,
|
2023-07-20 09:19:56 +02:00
|
|
|
JsonTypeCategory tcategory, Oid outfuncoid);
|
2014-12-12 21:31:14 +01:00
|
|
|
static void array_to_jsonb_internal(Datum array, JsonbInState *result);
|
2023-07-21 04:46:56 +02:00
|
|
|
static void datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
|
|
|
|
JsonTypeCategory tcategory, Oid outfuncoid,
|
|
|
|
bool key_scalar);
|
2014-12-12 21:31:14 +01:00
|
|
|
static void add_jsonb(Datum val, bool is_null, JsonbInState *result,
|
|
|
|
Oid val_type, bool key_scalar);
|
|
|
|
static JsonbParseState *clone_parse_state(JsonbParseState *state);
|
2015-05-12 21:52:45 +02:00
|
|
|
static char *JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent);
|
|
|
|
static void add_indent(StringInfo out, bool indent, int level);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* jsonb type input function
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_in(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
char *json = PG_GETARG_CSTRING(0);
|
|
|
|
|
Add more SQL/JSON constructor functions
This Patch introduces three SQL standard JSON functions:
JSON()
JSON_SCALAR()
JSON_SERIALIZE()
JSON() produces json values from text, bytea, json or jsonb values,
and has facilitites for handling duplicate keys.
JSON_SCALAR() produces a json value from any scalar sql value,
including json and jsonb.
JSON_SERIALIZE() produces text or bytea from input which containis
or represents json or jsonb;
For the most part these functions don't add any significant new
capabilities, but they will be of use to users wanting standard
compliant JSON handling.
Catversion bumped as this changes ruleutils.c.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Andrew Dunstan <andrew@dunslane.net>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera,
Peter Eisentraut
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
2023-07-20 15:21:43 +02:00
|
|
|
return jsonb_from_cstring(json, strlen(json), false, fcinfo->context);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* jsonb type recv function
|
|
|
|
*
|
|
|
|
* The type is sent as text in binary mode, so this is almost the same
|
|
|
|
* as the input function, but it's prefixed with a version number so we
|
|
|
|
* can change the binary format sent in future if necessary. For now,
|
|
|
|
* only version 1 is supported.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_recv(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
|
|
|
int version = pq_getmsgint(buf, 1);
|
|
|
|
char *str;
|
|
|
|
int nbytes;
|
|
|
|
|
|
|
|
if (version == 1)
|
|
|
|
str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
|
|
|
|
else
|
2014-05-07 22:16:19 +02:00
|
|
|
elog(ERROR, "unsupported jsonb version number %d", version);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
Add more SQL/JSON constructor functions
This Patch introduces three SQL standard JSON functions:
JSON()
JSON_SCALAR()
JSON_SERIALIZE()
JSON() produces json values from text, bytea, json or jsonb values,
and has facilitites for handling duplicate keys.
JSON_SCALAR() produces a json value from any scalar sql value,
including json and jsonb.
JSON_SERIALIZE() produces text or bytea from input which containis
or represents json or jsonb;
For the most part these functions don't add any significant new
capabilities, but they will be of use to users wanting standard
compliant JSON handling.
Catversion bumped as this changes ruleutils.c.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Andrew Dunstan <andrew@dunslane.net>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera,
Peter Eisentraut
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
2023-07-20 15:21:43 +02:00
|
|
|
return jsonb_from_cstring(str, nbytes, false, NULL);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* jsonb type output function
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_out(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
Jsonb *jb = PG_GETARG_JSONB_P(0);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
char *out;
|
|
|
|
|
2014-05-07 22:16:19 +02:00
|
|
|
out = JsonbToCString(NULL, &jb->root, VARSIZE(jb));
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
PG_RETURN_CSTRING(out);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* jsonb type send function
|
|
|
|
*
|
|
|
|
* Just send jsonb as a version number, then a string of text
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_send(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
Jsonb *jb = PG_GETARG_JSONB_P(0);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
StringInfoData buf;
|
|
|
|
StringInfo jtext = makeStringInfo();
|
|
|
|
int version = 1;
|
|
|
|
|
2014-05-07 22:16:19 +02:00
|
|
|
(void) JsonbToCString(jtext, &jb->root, VARSIZE(jb));
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
pq_begintypsend(&buf);
|
2017-10-12 06:00:46 +02:00
|
|
|
pq_sendint8(&buf, version);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
pq_sendtext(&buf, jtext->data, jtext->len);
|
2024-03-16 23:18:28 +01:00
|
|
|
destroyStringInfo(jtext);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
|
|
|
}
|
|
|
|
|
2023-07-21 04:46:56 +02:00
|
|
|
/*
|
|
|
|
* jsonb_from_text
|
|
|
|
*
|
|
|
|
* Turns json text string into a jsonb Datum.
|
|
|
|
*/
|
|
|
|
Datum
|
Add more SQL/JSON constructor functions
This Patch introduces three SQL standard JSON functions:
JSON()
JSON_SCALAR()
JSON_SERIALIZE()
JSON() produces json values from text, bytea, json or jsonb values,
and has facilitites for handling duplicate keys.
JSON_SCALAR() produces a json value from any scalar sql value,
including json and jsonb.
JSON_SERIALIZE() produces text or bytea from input which containis
or represents json or jsonb;
For the most part these functions don't add any significant new
capabilities, but they will be of use to users wanting standard
compliant JSON handling.
Catversion bumped as this changes ruleutils.c.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Andrew Dunstan <andrew@dunslane.net>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera,
Peter Eisentraut
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
2023-07-20 15:21:43 +02:00
|
|
|
jsonb_from_text(text *js, bool unique_keys)
|
2023-07-21 04:46:56 +02:00
|
|
|
{
|
|
|
|
return jsonb_from_cstring(VARDATA_ANY(js),
|
|
|
|
VARSIZE_ANY_EXHDR(js),
|
Add more SQL/JSON constructor functions
This Patch introduces three SQL standard JSON functions:
JSON()
JSON_SCALAR()
JSON_SERIALIZE()
JSON() produces json values from text, bytea, json or jsonb values,
and has facilitites for handling duplicate keys.
JSON_SCALAR() produces a json value from any scalar sql value,
including json and jsonb.
JSON_SERIALIZE() produces text or bytea from input which containis
or represents json or jsonb;
For the most part these functions don't add any significant new
capabilities, but they will be of use to users wanting standard
compliant JSON handling.
Catversion bumped as this changes ruleutils.c.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Andrew Dunstan <andrew@dunslane.net>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera,
Peter Eisentraut
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
2023-07-20 15:21:43 +02:00
|
|
|
unique_keys,
|
2023-07-21 04:46:56 +02:00
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
Partial implementation of SQL/JSON path language
SQL 2016 standards among other things contains set of SQL/JSON features for
JSON processing inside of relational database. The core of SQL/JSON is JSON
path language, allowing access parts of JSON documents and make computations
over them. This commit implements partial support JSON path language as
separate datatype called "jsonpath". The implementation is partial because
it's lacking datetime support and suppression of numeric errors. Missing
features will be added later by separate commits.
Support of SQL/JSON features requires implementation of separate nodes, and it
will be considered in subsequent patches. This commit includes following
set of plain functions, allowing to execute jsonpath over jsonb values:
* jsonb_path_exists(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_match(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query_array(jsonb, jsonpath[, jsonb, bool]).
* jsonb_path_query_first(jsonb, jsonpath[, jsonb, bool]).
This commit also implements "jsonb @? jsonpath" and "jsonb @@ jsonpath", which
are wrappers over jsonpath_exists(jsonb, jsonpath) and jsonpath_predicate(jsonb,
jsonpath) correspondingly. These operators will have an index support
(implemented in subsequent patches).
Catversion bumped, to add new functions and operators.
Code was written by Nikita Glukhov and Teodor Sigaev, revised by me.
Documentation was written by Oleg Bartunov and Liudmila Mantrova. The work
was inspired by Oleg Bartunov.
Discussion: https://postgr.es/m/fcc6fc6a-b497-f39a-923d-aa34d0c588e8%402ndQuadrant.com
Author: Nikita Glukhov, Teodor Sigaev, Alexander Korotkov, Oleg Bartunov, Liudmila Mantrova
Reviewed-by: Tomas Vondra, Andrew Dunstan, Pavel Stehule, Alexander Korotkov
2019-03-16 10:15:37 +01:00
|
|
|
/*
|
|
|
|
* Get the type name of a jsonb container.
|
|
|
|
*/
|
|
|
|
static const char *
|
|
|
|
JsonbContainerTypeName(JsonbContainer *jbc)
|
|
|
|
{
|
|
|
|
JsonbValue scalar;
|
|
|
|
|
|
|
|
if (JsonbExtractScalar(jbc, &scalar))
|
|
|
|
return JsonbTypeName(&scalar);
|
|
|
|
else if (JsonContainerIsArray(jbc))
|
|
|
|
return "array";
|
|
|
|
else if (JsonContainerIsObject(jbc))
|
|
|
|
return "object";
|
|
|
|
else
|
|
|
|
{
|
|
|
|
elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
|
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the type name of a jsonb value.
|
|
|
|
*/
|
|
|
|
const char *
|
2022-09-20 22:09:30 +02:00
|
|
|
JsonbTypeName(JsonbValue *val)
|
Partial implementation of SQL/JSON path language
SQL 2016 standards among other things contains set of SQL/JSON features for
JSON processing inside of relational database. The core of SQL/JSON is JSON
path language, allowing access parts of JSON documents and make computations
over them. This commit implements partial support JSON path language as
separate datatype called "jsonpath". The implementation is partial because
it's lacking datetime support and suppression of numeric errors. Missing
features will be added later by separate commits.
Support of SQL/JSON features requires implementation of separate nodes, and it
will be considered in subsequent patches. This commit includes following
set of plain functions, allowing to execute jsonpath over jsonb values:
* jsonb_path_exists(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_match(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query_array(jsonb, jsonpath[, jsonb, bool]).
* jsonb_path_query_first(jsonb, jsonpath[, jsonb, bool]).
This commit also implements "jsonb @? jsonpath" and "jsonb @@ jsonpath", which
are wrappers over jsonpath_exists(jsonb, jsonpath) and jsonpath_predicate(jsonb,
jsonpath) correspondingly. These operators will have an index support
(implemented in subsequent patches).
Catversion bumped, to add new functions and operators.
Code was written by Nikita Glukhov and Teodor Sigaev, revised by me.
Documentation was written by Oleg Bartunov and Liudmila Mantrova. The work
was inspired by Oleg Bartunov.
Discussion: https://postgr.es/m/fcc6fc6a-b497-f39a-923d-aa34d0c588e8%402ndQuadrant.com
Author: Nikita Glukhov, Teodor Sigaev, Alexander Korotkov, Oleg Bartunov, Liudmila Mantrova
Reviewed-by: Tomas Vondra, Andrew Dunstan, Pavel Stehule, Alexander Korotkov
2019-03-16 10:15:37 +01:00
|
|
|
{
|
2022-09-20 22:09:30 +02:00
|
|
|
switch (val->type)
|
Partial implementation of SQL/JSON path language
SQL 2016 standards among other things contains set of SQL/JSON features for
JSON processing inside of relational database. The core of SQL/JSON is JSON
path language, allowing access parts of JSON documents and make computations
over them. This commit implements partial support JSON path language as
separate datatype called "jsonpath". The implementation is partial because
it's lacking datetime support and suppression of numeric errors. Missing
features will be added later by separate commits.
Support of SQL/JSON features requires implementation of separate nodes, and it
will be considered in subsequent patches. This commit includes following
set of plain functions, allowing to execute jsonpath over jsonb values:
* jsonb_path_exists(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_match(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query_array(jsonb, jsonpath[, jsonb, bool]).
* jsonb_path_query_first(jsonb, jsonpath[, jsonb, bool]).
This commit also implements "jsonb @? jsonpath" and "jsonb @@ jsonpath", which
are wrappers over jsonpath_exists(jsonb, jsonpath) and jsonpath_predicate(jsonb,
jsonpath) correspondingly. These operators will have an index support
(implemented in subsequent patches).
Catversion bumped, to add new functions and operators.
Code was written by Nikita Glukhov and Teodor Sigaev, revised by me.
Documentation was written by Oleg Bartunov and Liudmila Mantrova. The work
was inspired by Oleg Bartunov.
Discussion: https://postgr.es/m/fcc6fc6a-b497-f39a-923d-aa34d0c588e8%402ndQuadrant.com
Author: Nikita Glukhov, Teodor Sigaev, Alexander Korotkov, Oleg Bartunov, Liudmila Mantrova
Reviewed-by: Tomas Vondra, Andrew Dunstan, Pavel Stehule, Alexander Korotkov
2019-03-16 10:15:37 +01:00
|
|
|
{
|
|
|
|
case jbvBinary:
|
2022-09-20 22:09:30 +02:00
|
|
|
return JsonbContainerTypeName(val->val.binary.data);
|
Partial implementation of SQL/JSON path language
SQL 2016 standards among other things contains set of SQL/JSON features for
JSON processing inside of relational database. The core of SQL/JSON is JSON
path language, allowing access parts of JSON documents and make computations
over them. This commit implements partial support JSON path language as
separate datatype called "jsonpath". The implementation is partial because
it's lacking datetime support and suppression of numeric errors. Missing
features will be added later by separate commits.
Support of SQL/JSON features requires implementation of separate nodes, and it
will be considered in subsequent patches. This commit includes following
set of plain functions, allowing to execute jsonpath over jsonb values:
* jsonb_path_exists(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_match(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query_array(jsonb, jsonpath[, jsonb, bool]).
* jsonb_path_query_first(jsonb, jsonpath[, jsonb, bool]).
This commit also implements "jsonb @? jsonpath" and "jsonb @@ jsonpath", which
are wrappers over jsonpath_exists(jsonb, jsonpath) and jsonpath_predicate(jsonb,
jsonpath) correspondingly. These operators will have an index support
(implemented in subsequent patches).
Catversion bumped, to add new functions and operators.
Code was written by Nikita Glukhov and Teodor Sigaev, revised by me.
Documentation was written by Oleg Bartunov and Liudmila Mantrova. The work
was inspired by Oleg Bartunov.
Discussion: https://postgr.es/m/fcc6fc6a-b497-f39a-923d-aa34d0c588e8%402ndQuadrant.com
Author: Nikita Glukhov, Teodor Sigaev, Alexander Korotkov, Oleg Bartunov, Liudmila Mantrova
Reviewed-by: Tomas Vondra, Andrew Dunstan, Pavel Stehule, Alexander Korotkov
2019-03-16 10:15:37 +01:00
|
|
|
case jbvObject:
|
|
|
|
return "object";
|
|
|
|
case jbvArray:
|
|
|
|
return "array";
|
|
|
|
case jbvNumeric:
|
|
|
|
return "number";
|
|
|
|
case jbvString:
|
|
|
|
return "string";
|
|
|
|
case jbvBool:
|
|
|
|
return "boolean";
|
|
|
|
case jbvNull:
|
|
|
|
return "null";
|
2019-09-25 20:53:41 +02:00
|
|
|
case jbvDatetime:
|
2022-09-20 22:09:30 +02:00
|
|
|
switch (val->val.datetime.typid)
|
2019-09-25 20:53:41 +02:00
|
|
|
{
|
|
|
|
case DATEOID:
|
|
|
|
return "date";
|
|
|
|
case TIMEOID:
|
|
|
|
return "time without time zone";
|
|
|
|
case TIMETZOID:
|
|
|
|
return "time with time zone";
|
|
|
|
case TIMESTAMPOID:
|
|
|
|
return "timestamp without time zone";
|
|
|
|
case TIMESTAMPTZOID:
|
|
|
|
return "timestamp with time zone";
|
|
|
|
default:
|
|
|
|
elog(ERROR, "unrecognized jsonb value datetime type: %d",
|
2022-09-20 22:09:30 +02:00
|
|
|
val->val.datetime.typid);
|
2019-09-25 20:53:41 +02:00
|
|
|
}
|
|
|
|
return "unknown";
|
Partial implementation of SQL/JSON path language
SQL 2016 standards among other things contains set of SQL/JSON features for
JSON processing inside of relational database. The core of SQL/JSON is JSON
path language, allowing access parts of JSON documents and make computations
over them. This commit implements partial support JSON path language as
separate datatype called "jsonpath". The implementation is partial because
it's lacking datetime support and suppression of numeric errors. Missing
features will be added later by separate commits.
Support of SQL/JSON features requires implementation of separate nodes, and it
will be considered in subsequent patches. This commit includes following
set of plain functions, allowing to execute jsonpath over jsonb values:
* jsonb_path_exists(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_match(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query_array(jsonb, jsonpath[, jsonb, bool]).
* jsonb_path_query_first(jsonb, jsonpath[, jsonb, bool]).
This commit also implements "jsonb @? jsonpath" and "jsonb @@ jsonpath", which
are wrappers over jsonpath_exists(jsonb, jsonpath) and jsonpath_predicate(jsonb,
jsonpath) correspondingly. These operators will have an index support
(implemented in subsequent patches).
Catversion bumped, to add new functions and operators.
Code was written by Nikita Glukhov and Teodor Sigaev, revised by me.
Documentation was written by Oleg Bartunov and Liudmila Mantrova. The work
was inspired by Oleg Bartunov.
Discussion: https://postgr.es/m/fcc6fc6a-b497-f39a-923d-aa34d0c588e8%402ndQuadrant.com
Author: Nikita Glukhov, Teodor Sigaev, Alexander Korotkov, Oleg Bartunov, Liudmila Mantrova
Reviewed-by: Tomas Vondra, Andrew Dunstan, Pavel Stehule, Alexander Korotkov
2019-03-16 10:15:37 +01:00
|
|
|
default:
|
2022-09-20 22:09:30 +02:00
|
|
|
elog(ERROR, "unrecognized jsonb value type: %d", val->type);
|
Partial implementation of SQL/JSON path language
SQL 2016 standards among other things contains set of SQL/JSON features for
JSON processing inside of relational database. The core of SQL/JSON is JSON
path language, allowing access parts of JSON documents and make computations
over them. This commit implements partial support JSON path language as
separate datatype called "jsonpath". The implementation is partial because
it's lacking datetime support and suppression of numeric errors. Missing
features will be added later by separate commits.
Support of SQL/JSON features requires implementation of separate nodes, and it
will be considered in subsequent patches. This commit includes following
set of plain functions, allowing to execute jsonpath over jsonb values:
* jsonb_path_exists(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_match(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query_array(jsonb, jsonpath[, jsonb, bool]).
* jsonb_path_query_first(jsonb, jsonpath[, jsonb, bool]).
This commit also implements "jsonb @? jsonpath" and "jsonb @@ jsonpath", which
are wrappers over jsonpath_exists(jsonb, jsonpath) and jsonpath_predicate(jsonb,
jsonpath) correspondingly. These operators will have an index support
(implemented in subsequent patches).
Catversion bumped, to add new functions and operators.
Code was written by Nikita Glukhov and Teodor Sigaev, revised by me.
Documentation was written by Oleg Bartunov and Liudmila Mantrova. The work
was inspired by Oleg Bartunov.
Discussion: https://postgr.es/m/fcc6fc6a-b497-f39a-923d-aa34d0c588e8%402ndQuadrant.com
Author: Nikita Glukhov, Teodor Sigaev, Alexander Korotkov, Oleg Bartunov, Liudmila Mantrova
Reviewed-by: Tomas Vondra, Andrew Dunstan, Pavel Stehule, Alexander Korotkov
2019-03-16 10:15:37 +01:00
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
/*
|
|
|
|
* SQL function jsonb_typeof(jsonb) -> text
|
|
|
|
*
|
|
|
|
* This function is here because the analog json function is in json.c, since
|
|
|
|
* it uses the json parser internals not exposed elsewhere.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_typeof(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
Jsonb *in = PG_GETARG_JSONB_P(0);
|
Partial implementation of SQL/JSON path language
SQL 2016 standards among other things contains set of SQL/JSON features for
JSON processing inside of relational database. The core of SQL/JSON is JSON
path language, allowing access parts of JSON documents and make computations
over them. This commit implements partial support JSON path language as
separate datatype called "jsonpath". The implementation is partial because
it's lacking datetime support and suppression of numeric errors. Missing
features will be added later by separate commits.
Support of SQL/JSON features requires implementation of separate nodes, and it
will be considered in subsequent patches. This commit includes following
set of plain functions, allowing to execute jsonpath over jsonb values:
* jsonb_path_exists(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_match(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query_array(jsonb, jsonpath[, jsonb, bool]).
* jsonb_path_query_first(jsonb, jsonpath[, jsonb, bool]).
This commit also implements "jsonb @? jsonpath" and "jsonb @@ jsonpath", which
are wrappers over jsonpath_exists(jsonb, jsonpath) and jsonpath_predicate(jsonb,
jsonpath) correspondingly. These operators will have an index support
(implemented in subsequent patches).
Catversion bumped, to add new functions and operators.
Code was written by Nikita Glukhov and Teodor Sigaev, revised by me.
Documentation was written by Oleg Bartunov and Liudmila Mantrova. The work
was inspired by Oleg Bartunov.
Discussion: https://postgr.es/m/fcc6fc6a-b497-f39a-923d-aa34d0c588e8%402ndQuadrant.com
Author: Nikita Glukhov, Teodor Sigaev, Alexander Korotkov, Oleg Bartunov, Liudmila Mantrova
Reviewed-by: Tomas Vondra, Andrew Dunstan, Pavel Stehule, Alexander Korotkov
2019-03-16 10:15:37 +01:00
|
|
|
const char *result = JsonbContainerTypeName(&in->root);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
PG_RETURN_TEXT_P(cstring_to_text(result));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* jsonb_from_cstring
|
|
|
|
*
|
|
|
|
* Turns json string into a jsonb Datum.
|
|
|
|
*
|
|
|
|
* Uses the json parser (with hooks) to construct a jsonb.
|
2022-12-11 17:28:15 +01:00
|
|
|
*
|
|
|
|
* If escontext points to an ErrorSaveContext, errors are reported there
|
|
|
|
* instead of being thrown.
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
*/
|
|
|
|
static inline Datum
|
Add more SQL/JSON constructor functions
This Patch introduces three SQL standard JSON functions:
JSON()
JSON_SCALAR()
JSON_SERIALIZE()
JSON() produces json values from text, bytea, json or jsonb values,
and has facilitites for handling duplicate keys.
JSON_SCALAR() produces a json value from any scalar sql value,
including json and jsonb.
JSON_SERIALIZE() produces text or bytea from input which containis
or represents json or jsonb;
For the most part these functions don't add any significant new
capabilities, but they will be of use to users wanting standard
compliant JSON handling.
Catversion bumped as this changes ruleutils.c.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Andrew Dunstan <andrew@dunslane.net>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera,
Peter Eisentraut
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
2023-07-20 15:21:43 +02:00
|
|
|
jsonb_from_cstring(char *json, int len, bool unique_keys, Node *escontext)
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
{
|
2023-10-05 10:59:08 +02:00
|
|
|
JsonLexContext lex;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
JsonbInState state;
|
|
|
|
JsonSemAction sem;
|
|
|
|
|
|
|
|
memset(&state, 0, sizeof(state));
|
|
|
|
memset(&sem, 0, sizeof(sem));
|
2023-10-05 10:59:08 +02:00
|
|
|
makeJsonLexContextCstringLen(&lex, json, len, GetDatabaseEncoding(), true);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
Add more SQL/JSON constructor functions
This Patch introduces three SQL standard JSON functions:
JSON()
JSON_SCALAR()
JSON_SERIALIZE()
JSON() produces json values from text, bytea, json or jsonb values,
and has facilitites for handling duplicate keys.
JSON_SCALAR() produces a json value from any scalar sql value,
including json and jsonb.
JSON_SERIALIZE() produces text or bytea from input which containis
or represents json or jsonb;
For the most part these functions don't add any significant new
capabilities, but they will be of use to users wanting standard
compliant JSON handling.
Catversion bumped as this changes ruleutils.c.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Andrew Dunstan <andrew@dunslane.net>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera,
Peter Eisentraut
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
2023-07-20 15:21:43 +02:00
|
|
|
state.unique_keys = unique_keys;
|
2022-12-11 17:28:15 +01:00
|
|
|
state.escontext = escontext;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
sem.semstate = (void *) &state;
|
|
|
|
|
|
|
|
sem.object_start = jsonb_in_object_start;
|
|
|
|
sem.array_start = jsonb_in_array_start;
|
|
|
|
sem.object_end = jsonb_in_object_end;
|
|
|
|
sem.array_end = jsonb_in_array_end;
|
|
|
|
sem.scalar = jsonb_in_scalar;
|
|
|
|
sem.object_field_start = jsonb_in_object_field_start;
|
|
|
|
|
2023-10-05 10:59:08 +02:00
|
|
|
if (!pg_parse_json_or_errsave(&lex, &sem, escontext))
|
2022-12-11 17:28:15 +01:00
|
|
|
return (Datum) 0;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
/* after parsing, the item member has the composed jsonb structure */
|
|
|
|
PG_RETURN_POINTER(JsonbValueToJsonb(state.res));
|
|
|
|
}
|
|
|
|
|
2022-12-11 17:28:15 +01:00
|
|
|
static bool
|
|
|
|
checkStringLen(size_t len, Node *escontext)
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
{
|
Change JSONB's on-disk format for improved performance.
The original design used an array of offsets into the variable-length
portion of a JSONB container. However, such an array is basically
uncompressible by simple compression techniques such as TOAST's LZ
compressor. That's bad enough, but because the offset array is at the
front, it tended to trigger the give-up-after-1KB heuristic in the TOAST
code, so that the entire JSONB object was stored uncompressed; which was
the root cause of bug #11109 from Larry White.
To fix without losing the ability to extract a random array element in O(1)
time, change this scheme so that most of the JEntry array elements hold
lengths rather than offsets. With data that's compressible at all, there
tend to be fewer distinct element lengths, so that there is scope for
compression of the JEntry array. Every N'th entry is still an offset.
To determine the length or offset of any specific element, we might have
to examine up to N preceding JEntrys, but that's still O(1) so far as the
total container size is concerned. Testing shows that this cost is
negligible compared to other costs of accessing a JSONB field, and that
the method does largely fix the incompressible-data problem.
While at it, rearrange the order of elements in a JSONB object so that
it's "all the keys, then all the values" not alternating keys and values.
This doesn't really make much difference right at the moment, but it will
allow providing a fast path for extracting individual object fields from
large JSONB values stored EXTERNAL (ie, uncompressed), analogously to the
existing optimization for substring extraction from large EXTERNAL text
values.
Bump catversion to denote the incompatibility in on-disk format.
We will need to fix pg_upgrade to disallow upgrading jsonb data stored
with 9.4 betas 1 and 2.
Heikki Linnakangas and Tom Lane
2014-09-29 18:29:21 +02:00
|
|
|
if (len > JENTRY_OFFLENMASK)
|
2022-12-11 17:28:15 +01:00
|
|
|
ereturn(escontext, false,
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
|
|
|
errmsg("string too long to represent as jsonb string"),
|
|
|
|
errdetail("Due to an implementation restriction, jsonb strings cannot exceed %d bytes.",
|
Change JSONB's on-disk format for improved performance.
The original design used an array of offsets into the variable-length
portion of a JSONB container. However, such an array is basically
uncompressible by simple compression techniques such as TOAST's LZ
compressor. That's bad enough, but because the offset array is at the
front, it tended to trigger the give-up-after-1KB heuristic in the TOAST
code, so that the entire JSONB object was stored uncompressed; which was
the root cause of bug #11109 from Larry White.
To fix without losing the ability to extract a random array element in O(1)
time, change this scheme so that most of the JEntry array elements hold
lengths rather than offsets. With data that's compressible at all, there
tend to be fewer distinct element lengths, so that there is scope for
compression of the JEntry array. Every N'th entry is still an offset.
To determine the length or offset of any specific element, we might have
to examine up to N preceding JEntrys, but that's still O(1) so far as the
total container size is concerned. Testing shows that this cost is
negligible compared to other costs of accessing a JSONB field, and that
the method does largely fix the incompressible-data problem.
While at it, rearrange the order of elements in a JSONB object so that
it's "all the keys, then all the values" not alternating keys and values.
This doesn't really make much difference right at the moment, but it will
allow providing a fast path for extracting individual object fields from
large JSONB values stored EXTERNAL (ie, uncompressed), analogously to the
existing optimization for substring extraction from large EXTERNAL text
values.
Bump catversion to denote the incompatibility in on-disk format.
We will need to fix pg_upgrade to disallow upgrading jsonb data stored
with 9.4 betas 1 and 2.
Heikki Linnakangas and Tom Lane
2014-09-29 18:29:21 +02:00
|
|
|
JENTRY_OFFLENMASK)));
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
2022-12-11 17:28:15 +01:00
|
|
|
return true;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
|
|
|
|
2022-12-11 16:39:05 +01:00
|
|
|
static JsonParseErrorType
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
jsonb_in_object_start(void *pstate)
|
|
|
|
{
|
|
|
|
JsonbInState *_state = (JsonbInState *) pstate;
|
|
|
|
|
|
|
|
_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_OBJECT, NULL);
|
Add more SQL/JSON constructor functions
This Patch introduces three SQL standard JSON functions:
JSON()
JSON_SCALAR()
JSON_SERIALIZE()
JSON() produces json values from text, bytea, json or jsonb values,
and has facilitites for handling duplicate keys.
JSON_SCALAR() produces a json value from any scalar sql value,
including json and jsonb.
JSON_SERIALIZE() produces text or bytea from input which containis
or represents json or jsonb;
For the most part these functions don't add any significant new
capabilities, but they will be of use to users wanting standard
compliant JSON handling.
Catversion bumped as this changes ruleutils.c.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Andrew Dunstan <andrew@dunslane.net>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera,
Peter Eisentraut
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
2023-07-20 15:21:43 +02:00
|
|
|
_state->parseState->unique_keys = _state->unique_keys;
|
2022-12-11 16:39:05 +01:00
|
|
|
|
|
|
|
return JSON_SUCCESS;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
|
|
|
|
2022-12-11 16:39:05 +01:00
|
|
|
static JsonParseErrorType
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
jsonb_in_object_end(void *pstate)
|
|
|
|
{
|
|
|
|
JsonbInState *_state = (JsonbInState *) pstate;
|
|
|
|
|
|
|
|
_state->res = pushJsonbValue(&_state->parseState, WJB_END_OBJECT, NULL);
|
2022-12-11 16:39:05 +01:00
|
|
|
|
|
|
|
return JSON_SUCCESS;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
|
|
|
|
2022-12-11 16:39:05 +01:00
|
|
|
static JsonParseErrorType
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
jsonb_in_array_start(void *pstate)
|
|
|
|
{
|
|
|
|
JsonbInState *_state = (JsonbInState *) pstate;
|
|
|
|
|
|
|
|
_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, NULL);
|
2022-12-11 16:39:05 +01:00
|
|
|
|
|
|
|
return JSON_SUCCESS;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
|
|
|
|
2022-12-11 16:39:05 +01:00
|
|
|
static JsonParseErrorType
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
jsonb_in_array_end(void *pstate)
|
|
|
|
{
|
|
|
|
JsonbInState *_state = (JsonbInState *) pstate;
|
|
|
|
|
|
|
|
_state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
|
2022-12-11 16:39:05 +01:00
|
|
|
|
|
|
|
return JSON_SUCCESS;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
|
|
|
|
2022-12-11 16:39:05 +01:00
|
|
|
static JsonParseErrorType
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
|
|
|
|
{
|
|
|
|
JsonbInState *_state = (JsonbInState *) pstate;
|
|
|
|
JsonbValue v;
|
|
|
|
|
|
|
|
Assert(fname != NULL);
|
|
|
|
v.type = jbvString;
|
2022-12-11 17:28:15 +01:00
|
|
|
v.val.string.len = strlen(fname);
|
|
|
|
if (!checkStringLen(v.val.string.len, _state->escontext))
|
|
|
|
return JSON_SEM_ACTION_FAILED;
|
2014-05-09 10:32:28 +02:00
|
|
|
v.val.string.val = fname;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
_state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v);
|
2022-12-11 16:39:05 +01:00
|
|
|
|
|
|
|
return JSON_SUCCESS;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal)
|
|
|
|
{
|
|
|
|
switch (scalarVal->type)
|
|
|
|
{
|
|
|
|
case jbvNull:
|
|
|
|
appendBinaryStringInfo(out, "null", 4);
|
|
|
|
break;
|
|
|
|
case jbvString:
|
2014-04-02 20:30:08 +02:00
|
|
|
escape_json(out, pnstrdup(scalarVal->val.string.val, scalarVal->val.string.len));
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
break;
|
|
|
|
case jbvNumeric:
|
|
|
|
appendStringInfoString(out,
|
|
|
|
DatumGetCString(DirectFunctionCall1(numeric_out,
|
2014-04-02 20:30:08 +02:00
|
|
|
PointerGetDatum(scalarVal->val.numeric))));
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
break;
|
|
|
|
case jbvBool:
|
2014-04-02 20:30:08 +02:00
|
|
|
if (scalarVal->val.boolean)
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
appendBinaryStringInfo(out, "true", 4);
|
|
|
|
else
|
|
|
|
appendBinaryStringInfo(out, "false", 5);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
elog(ERROR, "unknown jsonb scalar type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* For jsonb we always want the de-escaped value - that's what's in token
|
|
|
|
*/
|
2022-12-11 16:39:05 +01:00
|
|
|
static JsonParseErrorType
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
|
|
|
|
{
|
|
|
|
JsonbInState *_state = (JsonbInState *) pstate;
|
|
|
|
JsonbValue v;
|
2018-05-02 21:52:54 +02:00
|
|
|
Datum numd;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
switch (tokentype)
|
|
|
|
{
|
|
|
|
|
|
|
|
case JSON_TOKEN_STRING:
|
|
|
|
Assert(token != NULL);
|
|
|
|
v.type = jbvString;
|
2022-12-11 17:28:15 +01:00
|
|
|
v.val.string.len = strlen(token);
|
|
|
|
if (!checkStringLen(v.val.string.len, _state->escontext))
|
|
|
|
return JSON_SEM_ACTION_FAILED;
|
2014-05-09 10:32:28 +02:00
|
|
|
v.val.string.val = token;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
break;
|
|
|
|
case JSON_TOKEN_NUMBER:
|
2014-05-06 18:12:18 +02:00
|
|
|
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
/*
|
|
|
|
* No need to check size of numeric values, because maximum
|
|
|
|
* numeric size is well below the JsonbValue restriction
|
|
|
|
*/
|
|
|
|
Assert(token != NULL);
|
|
|
|
v.type = jbvNumeric;
|
2022-12-11 17:28:15 +01:00
|
|
|
if (!DirectInputFunctionCallSafe(numeric_in, token,
|
|
|
|
InvalidOid, -1,
|
|
|
|
_state->escontext,
|
|
|
|
&numd))
|
|
|
|
return JSON_SEM_ACTION_FAILED;
|
2018-05-02 21:52:54 +02:00
|
|
|
v.val.numeric = DatumGetNumeric(numd);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
break;
|
|
|
|
case JSON_TOKEN_TRUE:
|
|
|
|
v.type = jbvBool;
|
2014-04-02 20:30:08 +02:00
|
|
|
v.val.boolean = true;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
break;
|
|
|
|
case JSON_TOKEN_FALSE:
|
|
|
|
v.type = jbvBool;
|
2014-04-02 20:30:08 +02:00
|
|
|
v.val.boolean = false;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
break;
|
|
|
|
case JSON_TOKEN_NULL:
|
|
|
|
v.type = jbvNull;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* should not be possible */
|
|
|
|
elog(ERROR, "invalid json token type");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_state->parseState == NULL)
|
|
|
|
{
|
|
|
|
/* single scalar */
|
|
|
|
JsonbValue va;
|
|
|
|
|
|
|
|
va.type = jbvArray;
|
2014-04-02 20:30:08 +02:00
|
|
|
va.val.array.rawScalar = true;
|
|
|
|
va.val.array.nElems = 1;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, &va);
|
|
|
|
_state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
|
|
|
|
_state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
JsonbValue *o = &_state->parseState->contVal;
|
|
|
|
|
|
|
|
switch (o->type)
|
|
|
|
{
|
|
|
|
case jbvArray:
|
|
|
|
_state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
|
|
|
|
break;
|
|
|
|
case jbvObject:
|
|
|
|
_state->res = pushJsonbValue(&_state->parseState, WJB_VALUE, &v);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
elog(ERROR, "unexpected parent of nested structure");
|
|
|
|
}
|
|
|
|
}
|
2022-12-11 16:39:05 +01:00
|
|
|
|
|
|
|
return JSON_SUCCESS;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* JsonbToCString
|
|
|
|
* Converts jsonb value to a C-string.
|
|
|
|
*
|
|
|
|
* If 'out' argument is non-null, the resulting C-string is stored inside the
|
|
|
|
* StringBuffer. The resulting string is always returned.
|
|
|
|
*
|
|
|
|
* A typical case for passing the StringInfo in rather than NULL is where the
|
|
|
|
* caller wants access to the len attribute without having to call strlen, e.g.
|
|
|
|
* if they are converting it to a text* object.
|
|
|
|
*/
|
|
|
|
char *
|
2014-05-07 22:16:19 +02:00
|
|
|
JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
|
2015-05-12 21:52:45 +02:00
|
|
|
{
|
|
|
|
return JsonbToCStringWorker(out, in, estimated_len, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* same thing but with indentation turned on
|
|
|
|
*/
|
|
|
|
char *
|
|
|
|
JsonbToCStringIndent(StringInfo out, JsonbContainer *in, int estimated_len)
|
|
|
|
{
|
|
|
|
return JsonbToCStringWorker(out, in, estimated_len, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* common worker for above two functions
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
{
|
|
|
|
bool first = true;
|
|
|
|
JsonbIterator *it;
|
|
|
|
JsonbValue v;
|
2015-10-12 05:53:35 +02:00
|
|
|
JsonbIteratorToken type = WJB_DONE;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
int level = 0;
|
|
|
|
bool redo_switch = false;
|
2015-05-24 03:35:49 +02:00
|
|
|
|
2015-05-12 21:52:45 +02:00
|
|
|
/* If we are indenting, don't add a space after a comma */
|
|
|
|
int ispaces = indent ? 1 : 2;
|
2015-05-24 03:35:49 +02:00
|
|
|
|
2015-05-12 21:52:45 +02:00
|
|
|
/*
|
|
|
|
* Don't indent the very first item. This gets set to the indent flag at
|
|
|
|
* the bottom of the loop.
|
|
|
|
*/
|
|
|
|
bool use_indent = false;
|
|
|
|
bool raw_scalar = false;
|
|
|
|
bool last_was_key = false;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
|
|
|
if (out == NULL)
|
|
|
|
out = makeStringInfo();
|
|
|
|
|
|
|
|
enlargeStringInfo(out, (estimated_len >= 0) ? estimated_len : 64);
|
|
|
|
|
|
|
|
it = JsonbIteratorInit(in);
|
|
|
|
|
|
|
|
while (redo_switch ||
|
|
|
|
((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE))
|
|
|
|
{
|
|
|
|
redo_switch = false;
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case WJB_BEGIN_ARRAY:
|
|
|
|
if (!first)
|
2015-05-12 21:52:45 +02:00
|
|
|
appendBinaryStringInfo(out, ", ", ispaces);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
2014-04-02 20:30:08 +02:00
|
|
|
if (!v.val.array.rawScalar)
|
2015-05-12 21:52:45 +02:00
|
|
|
{
|
|
|
|
add_indent(out, use_indent && !last_was_key, level);
|
|
|
|
appendStringInfoCharMacro(out, '[');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
raw_scalar = true;
|
|
|
|
|
|
|
|
first = true;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
level++;
|
|
|
|
break;
|
|
|
|
case WJB_BEGIN_OBJECT:
|
|
|
|
if (!first)
|
2015-05-12 21:52:45 +02:00
|
|
|
appendBinaryStringInfo(out, ", ", ispaces);
|
|
|
|
|
|
|
|
add_indent(out, use_indent && !last_was_key, level);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
appendStringInfoCharMacro(out, '{');
|
|
|
|
|
2015-05-12 21:52:45 +02:00
|
|
|
first = true;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
level++;
|
|
|
|
break;
|
|
|
|
case WJB_KEY:
|
|
|
|
if (!first)
|
2015-05-12 21:52:45 +02:00
|
|
|
appendBinaryStringInfo(out, ", ", ispaces);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
first = true;
|
|
|
|
|
2015-05-12 21:52:45 +02:00
|
|
|
add_indent(out, use_indent, level);
|
|
|
|
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
/* json rules guarantee this is a string */
|
|
|
|
jsonb_put_escaped_value(out, &v);
|
|
|
|
appendBinaryStringInfo(out, ": ", 2);
|
|
|
|
|
|
|
|
type = JsonbIteratorNext(&it, &v, false);
|
|
|
|
if (type == WJB_VALUE)
|
|
|
|
{
|
|
|
|
first = false;
|
|
|
|
jsonb_put_escaped_value(out, &v);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Assert(type == WJB_BEGIN_OBJECT || type == WJB_BEGIN_ARRAY);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We need to rerun the current switch() since we need to
|
|
|
|
* output the object which we just got from the iterator
|
|
|
|
* before calling the iterator again.
|
|
|
|
*/
|
|
|
|
redo_switch = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WJB_ELEM:
|
|
|
|
if (!first)
|
2015-05-12 21:52:45 +02:00
|
|
|
appendBinaryStringInfo(out, ", ", ispaces);
|
|
|
|
first = false;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
|
2015-05-12 21:52:45 +02:00
|
|
|
if (!raw_scalar)
|
|
|
|
add_indent(out, use_indent, level);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
jsonb_put_escaped_value(out, &v);
|
|
|
|
break;
|
|
|
|
case WJB_END_ARRAY:
|
|
|
|
level--;
|
2015-05-12 21:52:45 +02:00
|
|
|
if (!raw_scalar)
|
|
|
|
{
|
|
|
|
add_indent(out, use_indent, level);
|
|
|
|
appendStringInfoCharMacro(out, ']');
|
|
|
|
}
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
first = false;
|
|
|
|
break;
|
|
|
|
case WJB_END_OBJECT:
|
|
|
|
level--;
|
2015-05-12 21:52:45 +02:00
|
|
|
add_indent(out, use_indent, level);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
appendStringInfoCharMacro(out, '}');
|
|
|
|
first = false;
|
|
|
|
break;
|
|
|
|
default:
|
2015-02-27 22:54:49 +01:00
|
|
|
elog(ERROR, "unknown jsonb iterator token type");
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
2015-05-12 21:52:45 +02:00
|
|
|
use_indent = indent;
|
|
|
|
last_was_key = redo_switch;
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Assert(level == 0);
|
|
|
|
|
|
|
|
return out->data;
|
|
|
|
}
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2015-05-12 21:52:45 +02:00
|
|
|
static void
|
|
|
|
add_indent(StringInfo out, bool indent, int level)
|
|
|
|
{
|
|
|
|
if (indent)
|
|
|
|
{
|
|
|
|
appendStringInfoCharMacro(out, '\n');
|
2023-01-20 01:07:24 +01:00
|
|
|
appendStringInfoSpaces(out, level * 4);
|
2015-05-12 21:52:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Turn a Datum into jsonb, adding it to the result JsonbInState.
|
|
|
|
*
|
|
|
|
* tcategory and outfuncoid are from a previous call to json_categorize_type,
|
|
|
|
* except that if is_null is true then they can be invalid.
|
|
|
|
*
|
|
|
|
* If key_scalar is true, the value is stored as a key, so insist
|
|
|
|
* it's of an acceptable type, and force it to be a jbvString.
|
2022-12-11 17:28:15 +01:00
|
|
|
*
|
|
|
|
* Note: currently, we assume that result->escontext is NULL and errors
|
|
|
|
* will be thrown.
|
2014-12-12 21:31:14 +01:00
|
|
|
*/
|
|
|
|
static void
|
2023-07-21 04:46:56 +02:00
|
|
|
datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
|
|
|
|
JsonTypeCategory tcategory, Oid outfuncoid,
|
|
|
|
bool key_scalar)
|
2014-12-12 21:31:14 +01:00
|
|
|
{
|
|
|
|
char *outputstr;
|
|
|
|
bool numeric_error;
|
|
|
|
JsonbValue jb;
|
|
|
|
bool scalar_jsonb = false;
|
|
|
|
|
2015-10-05 16:06:29 +02:00
|
|
|
check_stack_depth();
|
|
|
|
|
2015-10-15 19:46:09 +02:00
|
|
|
/* Convert val to a JsonbValue in jb (in most cases) */
|
2014-12-12 21:31:14 +01:00
|
|
|
if (is_null)
|
|
|
|
{
|
2015-07-24 15:40:46 +02:00
|
|
|
Assert(!key_scalar);
|
2014-12-12 21:31:14 +01:00
|
|
|
jb.type = jbvNull;
|
|
|
|
}
|
|
|
|
else if (key_scalar &&
|
2023-07-20 09:19:56 +02:00
|
|
|
(tcategory == JSONTYPE_ARRAY ||
|
|
|
|
tcategory == JSONTYPE_COMPOSITE ||
|
|
|
|
tcategory == JSONTYPE_JSON ||
|
|
|
|
tcategory == JSONTYPE_JSONB ||
|
|
|
|
tcategory == JSONTYPE_JSON))
|
2014-12-12 21:31:14 +01:00
|
|
|
{
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2016-01-09 23:39:45 +01:00
|
|
|
errmsg("key value must be scalar, not array, composite, or json")));
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-07-20 09:19:56 +02:00
|
|
|
if (tcategory == JSONTYPE_CAST)
|
2014-12-12 21:31:14 +01:00
|
|
|
val = OidFunctionCall1(outfuncoid, val);
|
|
|
|
|
|
|
|
switch (tcategory)
|
|
|
|
{
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_ARRAY:
|
2014-12-12 21:31:14 +01:00
|
|
|
array_to_jsonb_internal(val, result);
|
|
|
|
break;
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_COMPOSITE:
|
2014-12-12 21:31:14 +01:00
|
|
|
composite_to_jsonb(val, result);
|
|
|
|
break;
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_BOOL:
|
2014-12-12 21:31:14 +01:00
|
|
|
if (key_scalar)
|
|
|
|
{
|
|
|
|
outputstr = DatumGetBool(val) ? "true" : "false";
|
|
|
|
jb.type = jbvString;
|
|
|
|
jb.val.string.len = strlen(outputstr);
|
|
|
|
jb.val.string.val = outputstr;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
jb.type = jbvBool;
|
|
|
|
jb.val.boolean = DatumGetBool(val);
|
|
|
|
}
|
|
|
|
break;
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_NUMERIC:
|
2014-12-12 21:31:14 +01:00
|
|
|
outputstr = OidOutputFunctionCall(outfuncoid, val);
|
|
|
|
if (key_scalar)
|
|
|
|
{
|
|
|
|
/* always quote keys */
|
|
|
|
jb.type = jbvString;
|
|
|
|
jb.val.string.len = strlen(outputstr);
|
|
|
|
jb.val.string.val = outputstr;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Make it numeric if it's a valid JSON number, otherwise
|
|
|
|
* a string. Invalid numeric output will always have an
|
|
|
|
* 'N' or 'n' in it (I think).
|
|
|
|
*/
|
|
|
|
numeric_error = (strchr(outputstr, 'N') != NULL ||
|
|
|
|
strchr(outputstr, 'n') != NULL);
|
|
|
|
if (!numeric_error)
|
|
|
|
{
|
2018-05-02 21:52:54 +02:00
|
|
|
Datum numd;
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2018-05-02 21:52:54 +02:00
|
|
|
jb.type = jbvNumeric;
|
|
|
|
numd = DirectFunctionCall3(numeric_in,
|
|
|
|
CStringGetDatum(outputstr),
|
|
|
|
ObjectIdGetDatum(InvalidOid),
|
|
|
|
Int32GetDatum(-1));
|
|
|
|
jb.val.numeric = DatumGetNumeric(numd);
|
2014-12-12 21:31:14 +01:00
|
|
|
pfree(outputstr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
jb.type = jbvString;
|
|
|
|
jb.val.string.len = strlen(outputstr);
|
|
|
|
jb.val.string.val = outputstr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_DATE:
|
2018-01-17 01:07:13 +01:00
|
|
|
jb.type = jbvString;
|
2019-09-25 20:53:41 +02:00
|
|
|
jb.val.string.val = JsonEncodeDateTime(NULL, val,
|
|
|
|
DATEOID, NULL);
|
2018-01-17 01:07:13 +01:00
|
|
|
jb.val.string.len = strlen(jb.val.string.val);
|
2014-12-12 21:31:14 +01:00
|
|
|
break;
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_TIMESTAMP:
|
2018-01-17 01:07:13 +01:00
|
|
|
jb.type = jbvString;
|
2019-09-25 20:53:41 +02:00
|
|
|
jb.val.string.val = JsonEncodeDateTime(NULL, val,
|
|
|
|
TIMESTAMPOID, NULL);
|
2018-01-17 01:07:13 +01:00
|
|
|
jb.val.string.len = strlen(jb.val.string.val);
|
2014-12-12 21:31:14 +01:00
|
|
|
break;
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_TIMESTAMPTZ:
|
2018-01-17 01:07:13 +01:00
|
|
|
jb.type = jbvString;
|
2019-09-25 20:53:41 +02:00
|
|
|
jb.val.string.val = JsonEncodeDateTime(NULL, val,
|
|
|
|
TIMESTAMPTZOID, NULL);
|
2018-01-17 01:07:13 +01:00
|
|
|
jb.val.string.len = strlen(jb.val.string.val);
|
2014-12-12 21:31:14 +01:00
|
|
|
break;
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_CAST:
|
|
|
|
case JSONTYPE_JSON:
|
2014-12-12 21:31:14 +01:00
|
|
|
{
|
|
|
|
/* parse the json right into the existing result object */
|
2023-10-05 10:59:08 +02:00
|
|
|
JsonLexContext lex;
|
2014-12-12 21:31:14 +01:00
|
|
|
JsonSemAction sem;
|
2017-03-13 00:35:34 +01:00
|
|
|
text *json = DatumGetTextPP(val);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2023-10-05 10:59:08 +02:00
|
|
|
makeJsonLexContext(&lex, json, true);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
memset(&sem, 0, sizeof(sem));
|
|
|
|
|
|
|
|
sem.semstate = (void *) result;
|
|
|
|
|
|
|
|
sem.object_start = jsonb_in_object_start;
|
|
|
|
sem.array_start = jsonb_in_array_start;
|
|
|
|
sem.object_end = jsonb_in_object_end;
|
|
|
|
sem.array_end = jsonb_in_array_end;
|
|
|
|
sem.scalar = jsonb_in_scalar;
|
|
|
|
sem.object_field_start = jsonb_in_object_field_start;
|
|
|
|
|
2023-10-05 10:59:08 +02:00
|
|
|
pg_parse_json_or_ereport(&lex, &sem);
|
|
|
|
freeJsonLexContext(&lex);
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
break;
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_JSONB:
|
2014-12-12 21:31:14 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
Jsonb *jsonb = DatumGetJsonbP(val);
|
2014-12-12 21:31:14 +01:00
|
|
|
JsonbIterator *it;
|
|
|
|
|
|
|
|
it = JsonbIteratorInit(&jsonb->root);
|
|
|
|
|
|
|
|
if (JB_ROOT_IS_SCALAR(jsonb))
|
|
|
|
{
|
|
|
|
(void) JsonbIteratorNext(&it, &jb, true);
|
|
|
|
Assert(jb.type == jbvArray);
|
|
|
|
(void) JsonbIteratorNext(&it, &jb, true);
|
|
|
|
scalar_jsonb = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-10-12 05:53:35 +02:00
|
|
|
JsonbIteratorToken type;
|
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
while ((type = JsonbIteratorNext(&it, &jb, false))
|
|
|
|
!= WJB_DONE)
|
|
|
|
{
|
|
|
|
if (type == WJB_END_ARRAY || type == WJB_END_OBJECT ||
|
|
|
|
type == WJB_BEGIN_ARRAY || type == WJB_BEGIN_OBJECT)
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
type, NULL);
|
|
|
|
else
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
type, &jb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
outputstr = OidOutputFunctionCall(outfuncoid, val);
|
|
|
|
jb.type = jbvString;
|
2022-12-11 17:28:15 +01:00
|
|
|
jb.val.string.len = strlen(outputstr);
|
|
|
|
(void) checkStringLen(jb.val.string.len, NULL);
|
2014-12-12 21:31:14 +01:00
|
|
|
jb.val.string.val = outputstr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-10-15 19:46:09 +02:00
|
|
|
|
|
|
|
/* Now insert jb into result, unless we did it recursively */
|
|
|
|
if (!is_null && !scalar_jsonb &&
|
2023-07-20 09:19:56 +02:00
|
|
|
tcategory >= JSONTYPE_JSON && tcategory <= JSONTYPE_CAST)
|
2014-12-12 21:31:14 +01:00
|
|
|
{
|
|
|
|
/* work has been done recursively */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (result->parseState == NULL)
|
|
|
|
{
|
|
|
|
/* single root scalar */
|
|
|
|
JsonbValue va;
|
|
|
|
|
|
|
|
va.type = jbvArray;
|
|
|
|
va.val.array.rawScalar = true;
|
|
|
|
va.val.array.nElems = 1;
|
|
|
|
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, &va);
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_ELEM, &jb);
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
JsonbValue *o = &result->parseState->contVal;
|
|
|
|
|
|
|
|
switch (o->type)
|
|
|
|
{
|
|
|
|
case jbvArray:
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_ELEM, &jb);
|
|
|
|
break;
|
|
|
|
case jbvObject:
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
key_scalar ? WJB_KEY : WJB_VALUE,
|
|
|
|
&jb);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
elog(ERROR, "unexpected parent of nested structure");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Process a single dimension of an array.
|
|
|
|
* If it's the innermost dimension, output the values, otherwise call
|
|
|
|
* ourselves recursively to process the next dimension.
|
|
|
|
*/
|
|
|
|
static void
|
2023-10-10 07:50:15 +02:00
|
|
|
array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, const Datum *vals,
|
|
|
|
const bool *nulls, int *valcount, JsonTypeCategory tcategory,
|
2014-12-12 21:31:14 +01:00
|
|
|
Oid outfuncoid)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
Assert(dim < ndims);
|
|
|
|
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
|
|
|
|
|
|
|
|
for (i = 1; i <= dims[dim]; i++)
|
|
|
|
{
|
|
|
|
if (dim + 1 == ndims)
|
|
|
|
{
|
2023-07-21 04:46:56 +02:00
|
|
|
datum_to_jsonb_internal(vals[*valcount], nulls[*valcount], result, tcategory,
|
|
|
|
outfuncoid, false);
|
2014-12-12 21:31:14 +01:00
|
|
|
(*valcount)++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
array_dim_to_jsonb(result, dim + 1, ndims, dims, vals, nulls,
|
|
|
|
valcount, tcategory, outfuncoid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Turn an array into JSON.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
array_to_jsonb_internal(Datum array, JsonbInState *result)
|
|
|
|
{
|
|
|
|
ArrayType *v = DatumGetArrayTypeP(array);
|
|
|
|
Oid element_type = ARR_ELEMTYPE(v);
|
|
|
|
int *dim;
|
|
|
|
int ndim;
|
|
|
|
int nitems;
|
|
|
|
int count = 0;
|
|
|
|
Datum *elements;
|
|
|
|
bool *nulls;
|
|
|
|
int16 typlen;
|
|
|
|
bool typbyval;
|
|
|
|
char typalign;
|
2023-07-20 09:19:56 +02:00
|
|
|
JsonTypeCategory tcategory;
|
2014-12-12 21:31:14 +01:00
|
|
|
Oid outfuncoid;
|
|
|
|
|
|
|
|
ndim = ARR_NDIM(v);
|
|
|
|
dim = ARR_DIMS(v);
|
|
|
|
nitems = ArrayGetNItems(ndim, dim);
|
|
|
|
|
|
|
|
if (nitems <= 0)
|
|
|
|
{
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
get_typlenbyvalalign(element_type,
|
|
|
|
&typlen, &typbyval, &typalign);
|
|
|
|
|
2023-07-20 09:19:56 +02:00
|
|
|
json_categorize_type(element_type, true,
|
|
|
|
&tcategory, &outfuncoid);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
deconstruct_array(v, element_type, typlen, typbyval,
|
|
|
|
typalign, &elements, &nulls,
|
|
|
|
&nitems);
|
|
|
|
|
|
|
|
array_dim_to_jsonb(result, 0, ndim, dim, elements, nulls, &count, tcategory,
|
|
|
|
outfuncoid);
|
|
|
|
|
|
|
|
pfree(elements);
|
|
|
|
pfree(nulls);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Turn a composite / record into JSON.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
composite_to_jsonb(Datum composite, JsonbInState *result)
|
|
|
|
{
|
|
|
|
HeapTupleHeader td;
|
|
|
|
Oid tupType;
|
|
|
|
int32 tupTypmod;
|
|
|
|
TupleDesc tupdesc;
|
|
|
|
HeapTupleData tmptup,
|
|
|
|
*tuple;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
td = DatumGetHeapTupleHeader(composite);
|
|
|
|
|
|
|
|
/* Extract rowtype info and find a tupdesc */
|
|
|
|
tupType = HeapTupleHeaderGetTypeId(td);
|
|
|
|
tupTypmod = HeapTupleHeaderGetTypMod(td);
|
|
|
|
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
|
|
|
|
|
|
|
|
/* Build a temporary HeapTuple control structure */
|
|
|
|
tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
|
|
|
|
tmptup.t_data = td;
|
|
|
|
tuple = &tmptup;
|
|
|
|
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_OBJECT, NULL);
|
|
|
|
|
|
|
|
for (i = 0; i < tupdesc->natts; i++)
|
|
|
|
{
|
|
|
|
Datum val;
|
|
|
|
bool isnull;
|
|
|
|
char *attname;
|
2023-07-20 09:19:56 +02:00
|
|
|
JsonTypeCategory tcategory;
|
2014-12-12 21:31:14 +01:00
|
|
|
Oid outfuncoid;
|
|
|
|
JsonbValue v;
|
2017-08-20 20:19:07 +02:00
|
|
|
Form_pg_attribute att = TupleDescAttr(tupdesc, i);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2017-08-20 20:19:07 +02:00
|
|
|
if (att->attisdropped)
|
2014-12-12 21:31:14 +01:00
|
|
|
continue;
|
|
|
|
|
2017-08-20 20:19:07 +02:00
|
|
|
attname = NameStr(att->attname);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
v.type = jbvString;
|
|
|
|
/* don't need checkStringLen here - can't exceed maximum name length */
|
|
|
|
v.val.string.len = strlen(attname);
|
|
|
|
v.val.string.val = attname;
|
|
|
|
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_KEY, &v);
|
|
|
|
|
|
|
|
val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
|
|
|
|
|
|
|
|
if (isnull)
|
|
|
|
{
|
2023-07-20 09:19:56 +02:00
|
|
|
tcategory = JSONTYPE_NULL;
|
2014-12-12 21:31:14 +01:00
|
|
|
outfuncoid = InvalidOid;
|
|
|
|
}
|
|
|
|
else
|
2023-07-20 09:19:56 +02:00
|
|
|
json_categorize_type(att->atttypid, true, &tcategory,
|
|
|
|
&outfuncoid);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2023-07-21 04:46:56 +02:00
|
|
|
datum_to_jsonb_internal(val, isnull, result, tcategory, outfuncoid,
|
|
|
|
false);
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
result->res = pushJsonbValue(&result->parseState, WJB_END_OBJECT, NULL);
|
|
|
|
ReleaseTupleDesc(tupdesc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Append JSON text for "val" to "result".
|
|
|
|
*
|
|
|
|
* This is just a thin wrapper around datum_to_jsonb. If the same type will be
|
2023-07-20 09:19:56 +02:00
|
|
|
* printed many times, avoid using this; better to do the json_categorize_type
|
2014-12-12 21:31:14 +01:00
|
|
|
* lookups only once.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
add_jsonb(Datum val, bool is_null, JsonbInState *result,
|
|
|
|
Oid val_type, bool key_scalar)
|
|
|
|
{
|
2023-07-20 09:19:56 +02:00
|
|
|
JsonTypeCategory tcategory;
|
2014-12-12 21:31:14 +01:00
|
|
|
Oid outfuncoid;
|
|
|
|
|
|
|
|
if (val_type == InvalidOid)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("could not determine input data type")));
|
|
|
|
|
|
|
|
if (is_null)
|
|
|
|
{
|
2023-07-20 09:19:56 +02:00
|
|
|
tcategory = JSONTYPE_NULL;
|
2014-12-12 21:31:14 +01:00
|
|
|
outfuncoid = InvalidOid;
|
|
|
|
}
|
|
|
|
else
|
2023-07-20 09:19:56 +02:00
|
|
|
json_categorize_type(val_type, true,
|
|
|
|
&tcategory, &outfuncoid);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2023-07-21 04:46:56 +02:00
|
|
|
datum_to_jsonb_internal(val, is_null, result, tcategory, outfuncoid,
|
|
|
|
key_scalar);
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
|
2023-07-21 04:46:56 +02:00
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
/*
|
|
|
|
* Is the given type immutable when coming out of a JSONB context?
|
|
|
|
*
|
|
|
|
* At present, datetimes are all considered mutable, because they
|
|
|
|
* depend on timezone. XXX we should also drill down into objects and
|
|
|
|
* arrays, but do not.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
to_jsonb_is_immutable(Oid typoid)
|
|
|
|
{
|
2023-07-20 09:19:56 +02:00
|
|
|
JsonTypeCategory tcategory;
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
Oid outfuncoid;
|
|
|
|
|
2023-07-20 09:19:56 +02:00
|
|
|
json_categorize_type(typoid, true, &tcategory, &outfuncoid);
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
|
|
|
|
switch (tcategory)
|
|
|
|
{
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_NULL:
|
|
|
|
case JSONTYPE_BOOL:
|
|
|
|
case JSONTYPE_JSON:
|
|
|
|
case JSONTYPE_JSONB:
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
return true;
|
|
|
|
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_DATE:
|
|
|
|
case JSONTYPE_TIMESTAMP:
|
|
|
|
case JSONTYPE_TIMESTAMPTZ:
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
return false;
|
|
|
|
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_ARRAY:
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
return false; /* TODO recurse into elements */
|
|
|
|
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_COMPOSITE:
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
return false; /* TODO recurse into fields */
|
|
|
|
|
2023-07-20 09:19:56 +02:00
|
|
|
case JSONTYPE_NUMERIC:
|
|
|
|
case JSONTYPE_CAST:
|
|
|
|
case JSONTYPE_OTHER:
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
return func_volatile(outfuncoid) == PROVOLATILE_IMMUTABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false; /* not reached */
|
|
|
|
}
|
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
/*
|
|
|
|
* SQL function to_jsonb(anyvalue)
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
to_jsonb(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Datum val = PG_GETARG_DATUM(0);
|
|
|
|
Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
|
2023-07-20 09:19:56 +02:00
|
|
|
JsonTypeCategory tcategory;
|
2014-12-12 21:31:14 +01:00
|
|
|
Oid outfuncoid;
|
|
|
|
|
|
|
|
if (val_type == InvalidOid)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("could not determine input data type")));
|
|
|
|
|
2023-07-20 09:19:56 +02:00
|
|
|
json_categorize_type(val_type, true,
|
|
|
|
&tcategory, &outfuncoid);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2023-07-21 04:46:56 +02:00
|
|
|
PG_RETURN_DATUM(datum_to_jsonb(val, tcategory, outfuncoid));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Turn a Datum into jsonb.
|
|
|
|
*
|
|
|
|
* tcategory and outfuncoid are from a previous call to json_categorize_type.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
datum_to_jsonb(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
|
|
|
|
{
|
|
|
|
JsonbInState result;
|
|
|
|
|
2022-09-01 23:07:14 +02:00
|
|
|
memset(&result, 0, sizeof(JsonbInState));
|
|
|
|
|
2023-07-21 04:46:56 +02:00
|
|
|
datum_to_jsonb_internal(val, false, &result, tcategory, outfuncoid,
|
|
|
|
false);
|
2022-09-01 23:07:14 +02:00
|
|
|
|
2023-07-21 04:46:56 +02:00
|
|
|
return JsonbPGetDatum(JsonbValueToJsonb(result.res));
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
2023-10-10 07:50:15 +02:00
|
|
|
jsonb_build_object_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types,
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
bool absent_on_null, bool unique_keys)
|
2014-12-12 21:31:14 +01:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
JsonbInState result;
|
|
|
|
|
|
|
|
if (nargs % 2 != 0)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2017-10-25 13:34:00 +02:00
|
|
|
errmsg("argument list must have even number of elements"),
|
2019-04-24 15:26:13 +02:00
|
|
|
/* translator: %s is a SQL function name */
|
|
|
|
errhint("The arguments of %s must consist of alternating keys and values.",
|
|
|
|
"jsonb_build_object()")));
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
memset(&result, 0, sizeof(JsonbInState));
|
|
|
|
|
|
|
|
result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
result.parseState->unique_keys = unique_keys;
|
|
|
|
result.parseState->skip_nulls = absent_on_null;
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
for (i = 0; i < nargs; i += 2)
|
|
|
|
{
|
|
|
|
/* process key */
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
bool skip;
|
|
|
|
|
2017-10-25 13:34:00 +02:00
|
|
|
if (nulls[i])
|
2014-12-12 21:31:14 +01:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2015-11-17 03:16:42 +01:00
|
|
|
errmsg("argument %d: key must not be null", i + 1)));
|
2014-12-12 21:31:14 +01:00
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
/* skip null values if absent_on_null */
|
|
|
|
skip = absent_on_null && nulls[i + 1];
|
|
|
|
|
|
|
|
/* we need to save skipped keys for the key uniqueness check */
|
|
|
|
if (skip && !unique_keys)
|
|
|
|
continue;
|
|
|
|
|
2017-10-25 13:34:00 +02:00
|
|
|
add_jsonb(args[i], false, &result, types[i], true);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
/* process value */
|
2017-10-25 13:34:00 +02:00
|
|
|
add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
|
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
return JsonbPGetDatum(JsonbValueToJsonb(result.res));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SQL function jsonb_build_object(variadic "any")
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_build_object(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Datum *args;
|
|
|
|
bool *nulls;
|
|
|
|
Oid *types;
|
|
|
|
|
|
|
|
/* build argument values to build the object */
|
|
|
|
int nargs = extract_variadic_args(fcinfo, 0, true,
|
|
|
|
&args, &types, &nulls);
|
|
|
|
|
|
|
|
if (nargs < 0)
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
|
|
|
|
PG_RETURN_DATUM(jsonb_build_object_worker(nargs, args, nulls, types, false, false));
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* degenerate case of jsonb_build_object where it gets 0 arguments.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_build_object_noargs(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
JsonbInState result;
|
|
|
|
|
|
|
|
memset(&result, 0, sizeof(JsonbInState));
|
|
|
|
|
2014-12-16 16:32:06 +01:00
|
|
|
(void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
|
2014-12-12 21:31:14 +01:00
|
|
|
result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
|
|
|
|
|
|
|
|
PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
|
|
|
|
}
|
|
|
|
|
SQL/JSON constructors
This patch introduces the SQL/JSON standard constructors for JSON:
JSON()
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
For the most part these functions provide facilities that mimic
existing json/jsonb functions. However, they also offer some useful
additional functionality. In addition to text input, the JSON() function
accepts bytea input, which it will decode and constuct a json value from.
The other functions provide useful options for handling duplicate keys
and null values.
This series of patches will be followed by a consolidated documentation
patch.
Nikita Glukhov
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
2022-03-03 19:02:10 +01:00
|
|
|
Datum
|
2023-10-10 07:50:15 +02:00
|
|
|
jsonb_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types,
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
bool absent_on_null)
|
SQL/JSON constructors
This patch introduces the SQL/JSON standard constructors for JSON:
JSON()
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
For the most part these functions provide facilities that mimic
existing json/jsonb functions. However, they also offer some useful
additional functionality. In addition to text input, the JSON() function
accepts bytea input, which it will decode and constuct a json value from.
The other functions provide useful options for handling duplicate keys
and null values.
This series of patches will be followed by a consolidated documentation
patch.
Nikita Glukhov
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
2022-03-03 19:02:10 +01:00
|
|
|
{
|
2022-09-01 23:07:14 +02:00
|
|
|
int i;
|
|
|
|
JsonbInState result;
|
SQL/JSON constructors
This patch introduces the SQL/JSON standard constructors for JSON:
JSON()
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
For the most part these functions provide facilities that mimic
existing json/jsonb functions. However, they also offer some useful
additional functionality. In addition to text input, the JSON() function
accepts bytea input, which it will decode and constuct a json value from.
The other functions provide useful options for handling duplicate keys
and null values.
This series of patches will be followed by a consolidated documentation
patch.
Nikita Glukhov
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
2022-03-03 19:02:10 +01:00
|
|
|
|
2022-09-01 23:07:14 +02:00
|
|
|
memset(&result, 0, sizeof(JsonbInState));
|
|
|
|
|
|
|
|
result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
|
SQL/JSON constructors
This patch introduces the SQL/JSON standard constructors for JSON:
JSON()
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
For the most part these functions provide facilities that mimic
existing json/jsonb functions. However, they also offer some useful
additional functionality. In addition to text input, the JSON() function
accepts bytea input, which it will decode and constuct a json value from.
The other functions provide useful options for handling duplicate keys
and null values.
This series of patches will be followed by a consolidated documentation
patch.
Nikita Glukhov
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
2022-03-03 19:02:10 +01:00
|
|
|
|
2022-09-01 23:07:14 +02:00
|
|
|
for (i = 0; i < nargs; i++)
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
{
|
|
|
|
if (absent_on_null && nulls[i])
|
|
|
|
continue;
|
|
|
|
|
2022-09-01 23:07:14 +02:00
|
|
|
add_jsonb(args[i], nulls[i], &result, types[i], false);
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
}
|
2022-09-01 23:07:14 +02:00
|
|
|
|
|
|
|
result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
|
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
return JsonbPGetDatum(JsonbValueToJsonb(result.res));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SQL function jsonb_build_array(variadic "any")
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_build_array(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Datum *args;
|
|
|
|
bool *nulls;
|
|
|
|
Oid *types;
|
|
|
|
|
|
|
|
/* build argument values to build the object */
|
|
|
|
int nargs = extract_variadic_args(fcinfo, 0, true,
|
|
|
|
&args, &types, &nulls);
|
|
|
|
|
|
|
|
if (nargs < 0)
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
|
|
|
|
PG_RETURN_DATUM(jsonb_build_array_worker(nargs, args, nulls, types, false));
|
2022-09-01 23:07:14 +02:00
|
|
|
}
|
SQL/JSON constructors
This patch introduces the SQL/JSON standard constructors for JSON:
JSON()
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
For the most part these functions provide facilities that mimic
existing json/jsonb functions. However, they also offer some useful
additional functionality. In addition to text input, the JSON() function
accepts bytea input, which it will decode and constuct a json value from.
The other functions provide useful options for handling duplicate keys
and null values.
This series of patches will be followed by a consolidated documentation
patch.
Nikita Glukhov
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
2022-03-03 19:02:10 +01:00
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
/*
|
|
|
|
* degenerate case of jsonb_build_array where it gets 0 arguments.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_build_array_noargs(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
JsonbInState result;
|
|
|
|
|
|
|
|
memset(&result, 0, sizeof(JsonbInState));
|
|
|
|
|
2014-12-16 16:32:06 +01:00
|
|
|
(void) pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
|
2014-12-12 21:31:14 +01:00
|
|
|
result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
|
|
|
|
|
|
|
|
PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SQL function jsonb_object(text[])
|
|
|
|
*
|
|
|
|
* take a one or two dimensional array of text as name value pairs
|
|
|
|
* for a jsonb object.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_object(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
|
|
|
|
int ndims = ARR_NDIM(in_array);
|
|
|
|
Datum *in_datums;
|
|
|
|
bool *in_nulls;
|
|
|
|
int in_count,
|
|
|
|
count,
|
|
|
|
i;
|
|
|
|
JsonbInState result;
|
|
|
|
|
|
|
|
memset(&result, 0, sizeof(JsonbInState));
|
|
|
|
|
2014-12-16 16:32:06 +01:00
|
|
|
(void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
switch (ndims)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
goto close_object;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
if ((ARR_DIMS(in_array)[0]) % 2)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
|
|
|
errmsg("array must have even number of elements")));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
if ((ARR_DIMS(in_array)[1]) != 2)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
|
|
|
errmsg("array must have two columns")));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
|
|
|
errmsg("wrong number of array subscripts")));
|
|
|
|
}
|
|
|
|
|
2022-07-01 10:51:45 +02:00
|
|
|
deconstruct_array_builtin(in_array, TEXTOID, &in_datums, &in_nulls, &in_count);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
count = in_count / 2;
|
|
|
|
|
|
|
|
for (i = 0; i < count; ++i)
|
|
|
|
{
|
|
|
|
JsonbValue v;
|
|
|
|
char *str;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (in_nulls[i * 2])
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
|
|
|
errmsg("null value not allowed for object key")));
|
|
|
|
|
|
|
|
str = TextDatumGetCString(in_datums[i * 2]);
|
|
|
|
len = strlen(str);
|
|
|
|
|
|
|
|
v.type = jbvString;
|
|
|
|
|
|
|
|
v.val.string.len = len;
|
|
|
|
v.val.string.val = str;
|
|
|
|
|
2014-12-16 16:32:06 +01:00
|
|
|
(void) pushJsonbValue(&result.parseState, WJB_KEY, &v);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
if (in_nulls[i * 2 + 1])
|
|
|
|
{
|
|
|
|
v.type = jbvNull;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
str = TextDatumGetCString(in_datums[i * 2 + 1]);
|
|
|
|
len = strlen(str);
|
|
|
|
|
|
|
|
v.type = jbvString;
|
|
|
|
|
|
|
|
v.val.string.len = len;
|
|
|
|
v.val.string.val = str;
|
|
|
|
}
|
|
|
|
|
2014-12-16 16:32:06 +01:00
|
|
|
(void) pushJsonbValue(&result.parseState, WJB_VALUE, &v);
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pfree(in_datums);
|
|
|
|
pfree(in_nulls);
|
|
|
|
|
|
|
|
close_object:
|
|
|
|
result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
|
|
|
|
|
|
|
|
PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SQL function jsonb_object(text[], text[])
|
|
|
|
*
|
|
|
|
* take separate name and value arrays of text to construct a jsonb object
|
|
|
|
* pairwise.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_object_two_arg(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
ArrayType *key_array = PG_GETARG_ARRAYTYPE_P(0);
|
|
|
|
ArrayType *val_array = PG_GETARG_ARRAYTYPE_P(1);
|
|
|
|
int nkdims = ARR_NDIM(key_array);
|
|
|
|
int nvdims = ARR_NDIM(val_array);
|
|
|
|
Datum *key_datums,
|
|
|
|
*val_datums;
|
|
|
|
bool *key_nulls,
|
|
|
|
*val_nulls;
|
|
|
|
int key_count,
|
|
|
|
val_count,
|
|
|
|
i;
|
|
|
|
JsonbInState result;
|
|
|
|
|
|
|
|
memset(&result, 0, sizeof(JsonbInState));
|
|
|
|
|
2014-12-16 16:32:06 +01:00
|
|
|
(void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
if (nkdims > 1 || nkdims != nvdims)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
|
|
|
errmsg("wrong number of array subscripts")));
|
|
|
|
|
|
|
|
if (nkdims == 0)
|
2016-02-21 16:30:49 +01:00
|
|
|
goto close_object;
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2022-07-01 10:51:45 +02:00
|
|
|
deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, &key_count);
|
|
|
|
deconstruct_array_builtin(val_array, TEXTOID, &val_datums, &val_nulls, &val_count);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
if (key_count != val_count)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
|
|
|
errmsg("mismatched array dimensions")));
|
|
|
|
|
|
|
|
for (i = 0; i < key_count; ++i)
|
|
|
|
{
|
|
|
|
JsonbValue v;
|
|
|
|
char *str;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (key_nulls[i])
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
|
|
|
errmsg("null value not allowed for object key")));
|
|
|
|
|
|
|
|
str = TextDatumGetCString(key_datums[i]);
|
|
|
|
len = strlen(str);
|
|
|
|
|
|
|
|
v.type = jbvString;
|
|
|
|
|
|
|
|
v.val.string.len = len;
|
|
|
|
v.val.string.val = str;
|
|
|
|
|
2014-12-16 16:32:06 +01:00
|
|
|
(void) pushJsonbValue(&result.parseState, WJB_KEY, &v);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
if (val_nulls[i])
|
|
|
|
{
|
|
|
|
v.type = jbvNull;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
str = TextDatumGetCString(val_datums[i]);
|
|
|
|
len = strlen(str);
|
|
|
|
|
|
|
|
v.type = jbvString;
|
|
|
|
|
|
|
|
v.val.string.len = len;
|
|
|
|
v.val.string.val = str;
|
|
|
|
}
|
|
|
|
|
2014-12-16 16:32:06 +01:00
|
|
|
(void) pushJsonbValue(&result.parseState, WJB_VALUE, &v);
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pfree(key_datums);
|
|
|
|
pfree(key_nulls);
|
|
|
|
pfree(val_datums);
|
|
|
|
pfree(val_nulls);
|
|
|
|
|
2016-02-21 16:30:49 +01:00
|
|
|
close_object:
|
|
|
|
result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
|
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* shallow clone of a parse state, suitable for use in aggregate
|
|
|
|
* final functions that will only append to the values rather than
|
|
|
|
* change them.
|
|
|
|
*/
|
|
|
|
static JsonbParseState *
|
|
|
|
clone_parse_state(JsonbParseState *state)
|
|
|
|
{
|
|
|
|
JsonbParseState *result,
|
|
|
|
*icursor,
|
|
|
|
*ocursor;
|
|
|
|
|
|
|
|
if (state == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
result = palloc(sizeof(JsonbParseState));
|
|
|
|
icursor = state;
|
|
|
|
ocursor = result;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
ocursor->contVal = icursor->contVal;
|
|
|
|
ocursor->size = icursor->size;
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
ocursor->unique_keys = icursor->unique_keys;
|
|
|
|
ocursor->skip_nulls = icursor->skip_nulls;
|
2014-12-12 21:31:14 +01:00
|
|
|
icursor = icursor->next;
|
|
|
|
if (icursor == NULL)
|
|
|
|
break;
|
|
|
|
ocursor->next = palloc(sizeof(JsonbParseState));
|
|
|
|
ocursor = ocursor->next;
|
|
|
|
}
|
|
|
|
ocursor->next = NULL;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
static Datum
|
|
|
|
jsonb_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
|
2014-12-12 21:31:14 +01:00
|
|
|
{
|
|
|
|
MemoryContext oldcontext,
|
|
|
|
aggcontext;
|
2015-09-18 20:39:39 +02:00
|
|
|
JsonbAggState *state;
|
2014-12-12 21:31:14 +01:00
|
|
|
JsonbInState elem;
|
|
|
|
Datum val;
|
|
|
|
JsonbInState *result;
|
|
|
|
bool single_scalar = false;
|
|
|
|
JsonbIterator *it;
|
|
|
|
Jsonb *jbelem;
|
|
|
|
JsonbValue v;
|
2015-02-27 22:54:49 +01:00
|
|
|
JsonbIteratorToken type;
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
if (!AggCheckCallContext(fcinfo, &aggcontext))
|
|
|
|
{
|
|
|
|
/* cannot be called directly because of internal-type argument */
|
|
|
|
elog(ERROR, "jsonb_agg_transfn called in non-aggregate context");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set up the accumulator on the first go round */
|
|
|
|
|
|
|
|
if (PG_ARGISNULL(0))
|
|
|
|
{
|
2015-10-15 19:46:09 +02:00
|
|
|
Oid arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
|
2015-09-18 20:39:39 +02:00
|
|
|
|
|
|
|
if (arg_type == InvalidOid)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("could not determine input data type")));
|
|
|
|
|
|
|
|
oldcontext = MemoryContextSwitchTo(aggcontext);
|
|
|
|
state = palloc(sizeof(JsonbAggState));
|
2014-12-12 21:31:14 +01:00
|
|
|
result = palloc0(sizeof(JsonbInState));
|
2015-09-18 20:39:39 +02:00
|
|
|
state->res = result;
|
2014-12-12 21:31:14 +01:00
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
WJB_BEGIN_ARRAY, NULL);
|
2015-09-18 20:39:39 +02:00
|
|
|
MemoryContextSwitchTo(oldcontext);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2023-07-20 09:19:56 +02:00
|
|
|
json_categorize_type(arg_type, true, &state->val_category,
|
|
|
|
&state->val_output_func);
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-09-18 20:39:39 +02:00
|
|
|
state = (JsonbAggState *) PG_GETARG_POINTER(0);
|
|
|
|
result = state->res;
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
if (absent_on_null && PG_ARGISNULL(1))
|
|
|
|
PG_RETURN_POINTER(state);
|
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
/* turn the argument into jsonb in the normal function context */
|
|
|
|
|
|
|
|
val = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1);
|
|
|
|
|
|
|
|
memset(&elem, 0, sizeof(JsonbInState));
|
|
|
|
|
2023-07-21 04:46:56 +02:00
|
|
|
datum_to_jsonb_internal(val, PG_ARGISNULL(1), &elem, state->val_category,
|
|
|
|
state->val_output_func, false);
|
2015-09-18 20:39:39 +02:00
|
|
|
|
|
|
|
jbelem = JsonbValueToJsonb(elem.res);
|
|
|
|
|
|
|
|
/* switch to the aggregate context for accumulation operations */
|
|
|
|
|
|
|
|
oldcontext = MemoryContextSwitchTo(aggcontext);
|
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
it = JsonbIteratorInit(&jbelem->root);
|
|
|
|
|
|
|
|
while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case WJB_BEGIN_ARRAY:
|
|
|
|
if (v.val.array.rawScalar)
|
|
|
|
single_scalar = true;
|
|
|
|
else
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
type, NULL);
|
|
|
|
break;
|
|
|
|
case WJB_END_ARRAY:
|
|
|
|
if (!single_scalar)
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
type, NULL);
|
|
|
|
break;
|
|
|
|
case WJB_BEGIN_OBJECT:
|
|
|
|
case WJB_END_OBJECT:
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
type, NULL);
|
|
|
|
break;
|
|
|
|
case WJB_ELEM:
|
|
|
|
case WJB_KEY:
|
|
|
|
case WJB_VALUE:
|
|
|
|
if (v.type == jbvString)
|
|
|
|
{
|
2015-02-27 22:54:49 +01:00
|
|
|
/* copy string values in the aggregate context */
|
2015-03-31 14:12:27 +02:00
|
|
|
char *buf = palloc(v.val.string.len + 1);
|
2015-05-24 03:35:49 +02:00
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
|
|
|
|
v.val.string.val = buf;
|
|
|
|
}
|
|
|
|
else if (v.type == jbvNumeric)
|
|
|
|
{
|
|
|
|
/* same for numeric */
|
|
|
|
v.val.numeric =
|
|
|
|
DatumGetNumeric(DirectFunctionCall1(numeric_uplus,
|
|
|
|
NumericGetDatum(v.val.numeric)));
|
|
|
|
}
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
type, &v);
|
|
|
|
break;
|
2015-02-27 22:54:49 +01:00
|
|
|
default:
|
|
|
|
elog(ERROR, "unknown jsonb iterator token type");
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MemoryContextSwitchTo(oldcontext);
|
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
PG_RETURN_POINTER(state);
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
/*
|
|
|
|
* jsonb_agg aggregate function
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_agg_transfn(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
return jsonb_agg_transfn_worker(fcinfo, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* jsonb_agg_strict aggregate function
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_agg_strict_transfn(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
return jsonb_agg_transfn_worker(fcinfo, true);
|
|
|
|
}
|
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
Datum
|
|
|
|
jsonb_agg_finalfn(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2015-09-18 20:39:39 +02:00
|
|
|
JsonbAggState *arg;
|
2014-12-12 21:31:14 +01:00
|
|
|
JsonbInState result;
|
|
|
|
Jsonb *out;
|
|
|
|
|
|
|
|
/* cannot be called directly because of internal-type argument */
|
|
|
|
Assert(AggCheckCallContext(fcinfo, NULL));
|
|
|
|
|
|
|
|
if (PG_ARGISNULL(0))
|
|
|
|
PG_RETURN_NULL(); /* returns null iff no input values */
|
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
arg = (JsonbAggState *) PG_GETARG_POINTER(0);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We need to do a shallow clone of the argument in case the final
|
|
|
|
* function is called more than once, so we avoid changing the argument. A
|
|
|
|
* shallow clone is sufficient as we aren't going to change any of the
|
|
|
|
* values, just add the final array end marker.
|
|
|
|
*/
|
2022-12-11 17:28:15 +01:00
|
|
|
memset(&result, 0, sizeof(JsonbInState));
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
result.parseState = clone_parse_state(arg->res->parseState);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
result.res = pushJsonbValue(&result.parseState,
|
|
|
|
WJB_END_ARRAY, NULL);
|
|
|
|
|
|
|
|
out = JsonbValueToJsonb(result.res);
|
|
|
|
|
|
|
|
PG_RETURN_POINTER(out);
|
|
|
|
}
|
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
static Datum
|
|
|
|
jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo,
|
|
|
|
bool absent_on_null, bool unique_keys)
|
2014-12-12 21:31:14 +01:00
|
|
|
{
|
|
|
|
MemoryContext oldcontext,
|
|
|
|
aggcontext;
|
|
|
|
JsonbInState elem;
|
2015-09-18 20:39:39 +02:00
|
|
|
JsonbAggState *state;
|
2014-12-12 21:31:14 +01:00
|
|
|
Datum val;
|
|
|
|
JsonbInState *result;
|
|
|
|
bool single_scalar;
|
|
|
|
JsonbIterator *it;
|
|
|
|
Jsonb *jbkey,
|
|
|
|
*jbval;
|
|
|
|
JsonbValue v;
|
2015-02-27 22:54:49 +01:00
|
|
|
JsonbIteratorToken type;
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
bool skip;
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
if (!AggCheckCallContext(fcinfo, &aggcontext))
|
|
|
|
{
|
|
|
|
/* cannot be called directly because of internal-type argument */
|
|
|
|
elog(ERROR, "jsonb_object_agg_transfn called in non-aggregate context");
|
|
|
|
}
|
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
/* set up the accumulator on the first go round */
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
if (PG_ARGISNULL(0))
|
|
|
|
{
|
2015-10-15 19:46:09 +02:00
|
|
|
Oid arg_type;
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
oldcontext = MemoryContextSwitchTo(aggcontext);
|
|
|
|
state = palloc(sizeof(JsonbAggState));
|
|
|
|
result = palloc0(sizeof(JsonbInState));
|
|
|
|
state->res = result;
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
WJB_BEGIN_OBJECT, NULL);
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
result->parseState->unique_keys = unique_keys;
|
|
|
|
result->parseState->skip_nulls = absent_on_null;
|
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
MemoryContextSwitchTo(oldcontext);
|
|
|
|
|
|
|
|
arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
|
|
|
|
|
|
|
|
if (arg_type == InvalidOid)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("could not determine input data type")));
|
|
|
|
|
2023-07-20 09:19:56 +02:00
|
|
|
json_categorize_type(arg_type, true, &state->key_category,
|
|
|
|
&state->key_output_func);
|
2015-09-18 20:39:39 +02:00
|
|
|
|
|
|
|
arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
|
|
|
|
|
|
|
|
if (arg_type == InvalidOid)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("could not determine input data type")));
|
|
|
|
|
2023-07-20 09:19:56 +02:00
|
|
|
json_categorize_type(arg_type, true, &state->val_category,
|
|
|
|
&state->val_output_func);
|
2015-09-18 20:39:39 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
state = (JsonbAggState *) PG_GETARG_POINTER(0);
|
|
|
|
result = state->res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* turn the argument into jsonb in the normal function context */
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2015-07-24 15:40:46 +02:00
|
|
|
if (PG_ARGISNULL(1))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("field name must not be null")));
|
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
/*
|
|
|
|
* Skip null values if absent_on_null unless key uniqueness check is
|
|
|
|
* needed (because we must save keys in this case).
|
|
|
|
*/
|
|
|
|
skip = absent_on_null && PG_ARGISNULL(2);
|
|
|
|
|
|
|
|
if (skip && !unique_keys)
|
|
|
|
PG_RETURN_POINTER(state);
|
|
|
|
|
2015-07-24 15:40:46 +02:00
|
|
|
val = PG_GETARG_DATUM(1);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
memset(&elem, 0, sizeof(JsonbInState));
|
|
|
|
|
2023-07-21 04:46:56 +02:00
|
|
|
datum_to_jsonb_internal(val, false, &elem, state->key_category,
|
|
|
|
state->key_output_func, true);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
jbkey = JsonbValueToJsonb(elem.res);
|
|
|
|
|
|
|
|
val = PG_ARGISNULL(2) ? (Datum) 0 : PG_GETARG_DATUM(2);
|
|
|
|
|
|
|
|
memset(&elem, 0, sizeof(JsonbInState));
|
|
|
|
|
2023-07-21 04:46:56 +02:00
|
|
|
datum_to_jsonb_internal(val, PG_ARGISNULL(2), &elem, state->val_category,
|
|
|
|
state->val_output_func, false);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
jbval = JsonbValueToJsonb(elem.res);
|
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
it = JsonbIteratorInit(&jbkey->root);
|
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
/* switch to the aggregate context for accumulation operations */
|
|
|
|
|
|
|
|
oldcontext = MemoryContextSwitchTo(aggcontext);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* keys should be scalar, and we should have already checked for that
|
|
|
|
* above when calling datum_to_jsonb, so we only need to look for these
|
|
|
|
* things.
|
|
|
|
*/
|
|
|
|
|
|
|
|
while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case WJB_BEGIN_ARRAY:
|
|
|
|
if (!v.val.array.rawScalar)
|
|
|
|
elog(ERROR, "unexpected structure for key");
|
|
|
|
break;
|
|
|
|
case WJB_ELEM:
|
|
|
|
if (v.type == jbvString)
|
|
|
|
{
|
2015-02-27 22:54:49 +01:00
|
|
|
/* copy string values in the aggregate context */
|
2015-03-31 14:12:27 +02:00
|
|
|
char *buf = palloc(v.val.string.len + 1);
|
2015-05-24 03:35:49 +02:00
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
|
|
|
|
v.val.string.val = buf;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("object keys must be strings")));
|
|
|
|
}
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
WJB_KEY, &v);
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
|
|
|
|
if (skip)
|
|
|
|
{
|
|
|
|
v.type = jbvNull;
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
WJB_VALUE, &v);
|
|
|
|
MemoryContextSwitchTo(oldcontext);
|
|
|
|
PG_RETURN_POINTER(state);
|
|
|
|
}
|
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
break;
|
|
|
|
case WJB_END_ARRAY:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
elog(ERROR, "unexpected structure for key");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
it = JsonbIteratorInit(&jbval->root);
|
|
|
|
|
|
|
|
single_scalar = false;
|
|
|
|
|
|
|
|
/*
|
2016-07-06 11:59:17 +02:00
|
|
|
* values can be anything, including structured and null, so we treat them
|
2014-12-12 21:31:14 +01:00
|
|
|
* as in json_agg_transfn, except that single scalars are always pushed as
|
|
|
|
* WJB_VALUE items.
|
|
|
|
*/
|
|
|
|
|
|
|
|
while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case WJB_BEGIN_ARRAY:
|
|
|
|
if (v.val.array.rawScalar)
|
|
|
|
single_scalar = true;
|
|
|
|
else
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
type, NULL);
|
|
|
|
break;
|
|
|
|
case WJB_END_ARRAY:
|
|
|
|
if (!single_scalar)
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
type, NULL);
|
|
|
|
break;
|
|
|
|
case WJB_BEGIN_OBJECT:
|
|
|
|
case WJB_END_OBJECT:
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
type, NULL);
|
|
|
|
break;
|
|
|
|
case WJB_ELEM:
|
|
|
|
case WJB_KEY:
|
|
|
|
case WJB_VALUE:
|
|
|
|
if (v.type == jbvString)
|
|
|
|
{
|
2015-02-27 22:54:49 +01:00
|
|
|
/* copy string values in the aggregate context */
|
2015-03-31 14:12:27 +02:00
|
|
|
char *buf = palloc(v.val.string.len + 1);
|
2015-05-24 03:35:49 +02:00
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
|
|
|
|
v.val.string.val = buf;
|
|
|
|
}
|
|
|
|
else if (v.type == jbvNumeric)
|
|
|
|
{
|
|
|
|
/* same for numeric */
|
|
|
|
v.val.numeric =
|
|
|
|
DatumGetNumeric(DirectFunctionCall1(numeric_uplus,
|
|
|
|
NumericGetDatum(v.val.numeric)));
|
|
|
|
}
|
|
|
|
result->res = pushJsonbValue(&result->parseState,
|
|
|
|
single_scalar ? WJB_VALUE : type,
|
|
|
|
&v);
|
|
|
|
break;
|
2015-02-27 22:54:49 +01:00
|
|
|
default:
|
|
|
|
elog(ERROR, "unknown jsonb iterator token type");
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MemoryContextSwitchTo(oldcontext);
|
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
PG_RETURN_POINTER(state);
|
2014-12-12 21:31:14 +01:00
|
|
|
}
|
|
|
|
|
SQL/JSON: add standard JSON constructor functions
This commit introduces the SQL/JSON standard-conforming constructors for
JSON types:
JSON_ARRAY()
JSON_ARRAYAGG()
JSON_OBJECT()
JSON_OBJECTAGG()
Most of the functionality was already present in PostgreSQL-specific
functions, but these include some new functionality such as the ability
to skip or include NULL values, and to allow duplicate keys or throw
error when they are found, as well as the standard specified syntax to
specify output type and format.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Amit Langote <amitlangote09@gmail.com>
Reviewers have included (in no particular order) Andres Freund, Alexander
Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,
Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.
Discussion: https://postgr.es/m/CAF4Au4w2x-5LTnN_bxky-mq4=WOqsGsxSpENCzHRAzSnEd8+WQ@mail.gmail.com
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
2023-03-29 12:11:36 +02:00
|
|
|
/*
|
|
|
|
* jsonb_object_agg aggregate function
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_object_agg_transfn(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
return jsonb_object_agg_transfn_worker(fcinfo, false, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* jsonb_object_agg_strict aggregate function
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_object_agg_strict_transfn(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
return jsonb_object_agg_transfn_worker(fcinfo, true, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* jsonb_object_agg_unique aggregate function
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_object_agg_unique_transfn(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
return jsonb_object_agg_transfn_worker(fcinfo, false, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* jsonb_object_agg_unique_strict aggregate function
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
jsonb_object_agg_unique_strict_transfn(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
return jsonb_object_agg_transfn_worker(fcinfo, true, true);
|
|
|
|
}
|
|
|
|
|
2014-12-12 21:31:14 +01:00
|
|
|
Datum
|
|
|
|
jsonb_object_agg_finalfn(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2015-09-18 20:39:39 +02:00
|
|
|
JsonbAggState *arg;
|
2014-12-12 21:31:14 +01:00
|
|
|
JsonbInState result;
|
|
|
|
Jsonb *out;
|
|
|
|
|
|
|
|
/* cannot be called directly because of internal-type argument */
|
|
|
|
Assert(AggCheckCallContext(fcinfo, NULL));
|
|
|
|
|
|
|
|
if (PG_ARGISNULL(0))
|
|
|
|
PG_RETURN_NULL(); /* returns null iff no input values */
|
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
arg = (JsonbAggState *) PG_GETARG_POINTER(0);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
/*
|
2015-09-18 20:39:39 +02:00
|
|
|
* We need to do a shallow clone of the argument's res field in case the
|
|
|
|
* final function is called more than once, so we avoid changing the
|
2015-10-15 19:46:09 +02:00
|
|
|
* aggregate state value. A shallow clone is sufficient as we aren't
|
|
|
|
* going to change any of the values, just add the final object end
|
|
|
|
* marker.
|
2014-12-12 21:31:14 +01:00
|
|
|
*/
|
2022-12-11 17:28:15 +01:00
|
|
|
memset(&result, 0, sizeof(JsonbInState));
|
2014-12-12 21:31:14 +01:00
|
|
|
|
2015-09-18 20:39:39 +02:00
|
|
|
result.parseState = clone_parse_state(arg->res->parseState);
|
2014-12-12 21:31:14 +01:00
|
|
|
|
|
|
|
result.res = pushJsonbValue(&result.parseState,
|
|
|
|
WJB_END_OBJECT, NULL);
|
|
|
|
|
|
|
|
out = JsonbValueToJsonb(result.res);
|
|
|
|
|
|
|
|
PG_RETURN_POINTER(out);
|
|
|
|
}
|
2018-03-29 15:33:56 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Extract scalar value from raw-scalar pseudo-array jsonb.
|
|
|
|
*/
|
Partial implementation of SQL/JSON path language
SQL 2016 standards among other things contains set of SQL/JSON features for
JSON processing inside of relational database. The core of SQL/JSON is JSON
path language, allowing access parts of JSON documents and make computations
over them. This commit implements partial support JSON path language as
separate datatype called "jsonpath". The implementation is partial because
it's lacking datetime support and suppression of numeric errors. Missing
features will be added later by separate commits.
Support of SQL/JSON features requires implementation of separate nodes, and it
will be considered in subsequent patches. This commit includes following
set of plain functions, allowing to execute jsonpath over jsonb values:
* jsonb_path_exists(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_match(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query(jsonb, jsonpath[, jsonb, bool]),
* jsonb_path_query_array(jsonb, jsonpath[, jsonb, bool]).
* jsonb_path_query_first(jsonb, jsonpath[, jsonb, bool]).
This commit also implements "jsonb @? jsonpath" and "jsonb @@ jsonpath", which
are wrappers over jsonpath_exists(jsonb, jsonpath) and jsonpath_predicate(jsonb,
jsonpath) correspondingly. These operators will have an index support
(implemented in subsequent patches).
Catversion bumped, to add new functions and operators.
Code was written by Nikita Glukhov and Teodor Sigaev, revised by me.
Documentation was written by Oleg Bartunov and Liudmila Mantrova. The work
was inspired by Oleg Bartunov.
Discussion: https://postgr.es/m/fcc6fc6a-b497-f39a-923d-aa34d0c588e8%402ndQuadrant.com
Author: Nikita Glukhov, Teodor Sigaev, Alexander Korotkov, Oleg Bartunov, Liudmila Mantrova
Reviewed-by: Tomas Vondra, Andrew Dunstan, Pavel Stehule, Alexander Korotkov
2019-03-16 10:15:37 +01:00
|
|
|
bool
|
2018-03-29 15:33:56 +02:00
|
|
|
JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
|
|
|
|
{
|
|
|
|
JsonbIterator *it;
|
|
|
|
JsonbIteratorToken tok PG_USED_FOR_ASSERTS_ONLY;
|
|
|
|
JsonbValue tmp;
|
|
|
|
|
|
|
|
if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc))
|
2018-05-09 12:23:16 +02:00
|
|
|
{
|
|
|
|
/* inform caller about actual type of container */
|
|
|
|
res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
|
|
|
|
return false;
|
|
|
|
}
|
2018-03-29 15:33:56 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* A root scalar is stored as an array of one element, so we get the array
|
|
|
|
* and then its first (and only) member.
|
|
|
|
*/
|
|
|
|
it = JsonbIteratorInit(jbc);
|
|
|
|
|
|
|
|
tok = JsonbIteratorNext(&it, &tmp, true);
|
|
|
|
Assert(tok == WJB_BEGIN_ARRAY);
|
|
|
|
Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
|
|
|
|
|
|
|
|
tok = JsonbIteratorNext(&it, res, true);
|
|
|
|
Assert(tok == WJB_ELEM);
|
|
|
|
Assert(IsAJsonbScalar(res));
|
|
|
|
|
|
|
|
tok = JsonbIteratorNext(&it, &tmp, true);
|
|
|
|
Assert(tok == WJB_END_ARRAY);
|
|
|
|
|
|
|
|
tok = JsonbIteratorNext(&it, &tmp, true);
|
|
|
|
Assert(tok == WJB_DONE);
|
|
|
|
|
2018-05-09 12:23:16 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Emit correct, translatable cast error message
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
cannotCastJsonbValue(enum jbvType type, const char *sqltype)
|
|
|
|
{
|
|
|
|
static const struct
|
|
|
|
{
|
|
|
|
enum jbvType type;
|
|
|
|
const char *msg;
|
|
|
|
}
|
|
|
|
messages[] =
|
|
|
|
{
|
|
|
|
{jbvNull, gettext_noop("cannot cast jsonb null to type %s")},
|
|
|
|
{jbvString, gettext_noop("cannot cast jsonb string to type %s")},
|
|
|
|
{jbvNumeric, gettext_noop("cannot cast jsonb numeric to type %s")},
|
|
|
|
{jbvBool, gettext_noop("cannot cast jsonb boolean to type %s")},
|
|
|
|
{jbvArray, gettext_noop("cannot cast jsonb array to type %s")},
|
|
|
|
{jbvObject, gettext_noop("cannot cast jsonb object to type %s")},
|
|
|
|
{jbvBinary, gettext_noop("cannot cast jsonb array or object to type %s")}
|
|
|
|
};
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < lengthof(messages); i++)
|
|
|
|
if (messages[i].type == type)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg(messages[i].msg, sqltype)));
|
|
|
|
|
|
|
|
/* should be unreachable */
|
|
|
|
elog(ERROR, "unknown jsonb type: %d", (int) type);
|
2018-03-29 15:33:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
jsonb_bool(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Jsonb *in = PG_GETARG_JSONB_P(0);
|
|
|
|
JsonbValue v;
|
|
|
|
|
|
|
|
if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvBool)
|
2018-05-09 12:23:16 +02:00
|
|
|
cannotCastJsonbValue(v.type, "boolean");
|
2018-03-29 15:33:56 +02:00
|
|
|
|
|
|
|
PG_FREE_IF_COPY(in, 0);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(v.val.boolean);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
jsonb_numeric(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Jsonb *in = PG_GETARG_JSONB_P(0);
|
|
|
|
JsonbValue v;
|
|
|
|
Numeric retValue;
|
|
|
|
|
|
|
|
if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
|
2018-05-09 12:23:16 +02:00
|
|
|
cannotCastJsonbValue(v.type, "numeric");
|
2018-03-29 15:33:56 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* v.val.numeric points into jsonb body, so we need to make a copy to
|
|
|
|
* return
|
|
|
|
*/
|
|
|
|
retValue = DatumGetNumericCopy(NumericGetDatum(v.val.numeric));
|
|
|
|
|
|
|
|
PG_FREE_IF_COPY(in, 0);
|
|
|
|
|
|
|
|
PG_RETURN_NUMERIC(retValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
jsonb_int2(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Jsonb *in = PG_GETARG_JSONB_P(0);
|
|
|
|
JsonbValue v;
|
|
|
|
Datum retValue;
|
|
|
|
|
|
|
|
if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
|
2018-05-09 12:23:16 +02:00
|
|
|
cannotCastJsonbValue(v.type, "smallint");
|
2018-03-29 15:33:56 +02:00
|
|
|
|
|
|
|
retValue = DirectFunctionCall1(numeric_int2,
|
|
|
|
NumericGetDatum(v.val.numeric));
|
|
|
|
|
|
|
|
PG_FREE_IF_COPY(in, 0);
|
|
|
|
|
|
|
|
PG_RETURN_DATUM(retValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
jsonb_int4(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Jsonb *in = PG_GETARG_JSONB_P(0);
|
|
|
|
JsonbValue v;
|
|
|
|
Datum retValue;
|
|
|
|
|
|
|
|
if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
|
2018-05-09 12:23:16 +02:00
|
|
|
cannotCastJsonbValue(v.type, "integer");
|
2018-03-29 15:33:56 +02:00
|
|
|
|
|
|
|
retValue = DirectFunctionCall1(numeric_int4,
|
|
|
|
NumericGetDatum(v.val.numeric));
|
|
|
|
|
|
|
|
PG_FREE_IF_COPY(in, 0);
|
|
|
|
|
|
|
|
PG_RETURN_DATUM(retValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
jsonb_int8(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Jsonb *in = PG_GETARG_JSONB_P(0);
|
|
|
|
JsonbValue v;
|
|
|
|
Datum retValue;
|
|
|
|
|
|
|
|
if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
|
2018-05-09 12:23:16 +02:00
|
|
|
cannotCastJsonbValue(v.type, "bigint");
|
2018-03-29 15:33:56 +02:00
|
|
|
|
|
|
|
retValue = DirectFunctionCall1(numeric_int8,
|
|
|
|
NumericGetDatum(v.val.numeric));
|
|
|
|
|
|
|
|
PG_FREE_IF_COPY(in, 0);
|
|
|
|
|
|
|
|
PG_RETURN_DATUM(retValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
jsonb_float4(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Jsonb *in = PG_GETARG_JSONB_P(0);
|
|
|
|
JsonbValue v;
|
|
|
|
Datum retValue;
|
|
|
|
|
|
|
|
if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
|
2018-05-09 12:23:16 +02:00
|
|
|
cannotCastJsonbValue(v.type, "real");
|
2018-03-29 15:33:56 +02:00
|
|
|
|
|
|
|
retValue = DirectFunctionCall1(numeric_float4,
|
|
|
|
NumericGetDatum(v.val.numeric));
|
|
|
|
|
|
|
|
PG_FREE_IF_COPY(in, 0);
|
|
|
|
|
|
|
|
PG_RETURN_DATUM(retValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
jsonb_float8(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Jsonb *in = PG_GETARG_JSONB_P(0);
|
|
|
|
JsonbValue v;
|
|
|
|
Datum retValue;
|
|
|
|
|
|
|
|
if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
|
2018-05-09 12:23:16 +02:00
|
|
|
cannotCastJsonbValue(v.type, "double precision");
|
2018-03-29 15:33:56 +02:00
|
|
|
|
|
|
|
retValue = DirectFunctionCall1(numeric_float8,
|
|
|
|
NumericGetDatum(v.val.numeric));
|
|
|
|
|
|
|
|
PG_FREE_IF_COPY(in, 0);
|
|
|
|
|
|
|
|
PG_RETURN_DATUM(retValue);
|
|
|
|
}
|
Add SQL/JSON query functions
This introduces the following SQL/JSON functions for querying JSON
data using jsonpath expressions:
JSON_EXISTS(), which can be used to apply a jsonpath expression to a
JSON value to check if it yields any values.
JSON_QUERY(), which can be used to to apply a jsonpath expression to
a JSON value to get a JSON object, an array, or a string. There are
various options to control whether multi-value result uses array
wrappers and whether the singleton scalar strings are quoted or not.
JSON_VALUE(), which can be used to apply a jsonpath expression to a
JSON value to return a single scalar value, producing an error if it
multiple values are matched.
Both JSON_VALUE() and JSON_QUERY() functions have options for
handling EMPTY and ERROR conditions, which can be used to specify
the behavior when no values are matched and when an error occurs
during jsonpath evaluation, respectively.
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Oleg Bartunov <obartunov@gmail.com>
Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Andrew Dunstan <andrew@dunslane.net>
Author: Amit Langote <amitlangote09@gmail.com>
Author: Peter Eisentraut <peter@eisentraut.org>
Author: Jian He <jian.universality@gmail.com>
Reviewers have included (in no particular order):
Andres Freund, Alexander Korotkov, Pavel Stehule, Andrew Alsup,
Erik Rijkers, Zihong Yu, Himanshu Upadhyaya, Daniel Gustafsson,
Justin Pryzby, Álvaro Herrera, Jian He, Anton A. Melnikov,
Nikita Malakhov, Peter Eisentraut, Tomas Vondra
Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de
Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org
Discussion: https://postgr.es/m/CA+HiwqHROpf9e644D8BRqYvaAPmgBZVup-xKMDPk-nd4EpgzHw@mail.gmail.com
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
2024-03-21 09:06:27 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert jsonb to a C-string stripping quotes from scalar strings.
|
|
|
|
*/
|
|
|
|
char *
|
|
|
|
JsonbUnquote(Jsonb *jb)
|
|
|
|
{
|
|
|
|
if (JB_ROOT_IS_SCALAR(jb))
|
|
|
|
{
|
|
|
|
JsonbValue v;
|
|
|
|
|
|
|
|
(void) JsonbExtractScalar(&jb->root, &v);
|
|
|
|
|
|
|
|
if (v.type == jbvString)
|
|
|
|
return pnstrdup(v.val.string.val, v.val.string.len);
|
|
|
|
else if (v.type == jbvBool)
|
|
|
|
return pstrdup(v.val.boolean ? "true" : "false");
|
|
|
|
else if (v.type == jbvNumeric)
|
|
|
|
return DatumGetCString(DirectFunctionCall1(numeric_out,
|
|
|
|
PointerGetDatum(v.val.numeric)));
|
|
|
|
else if (v.type == jbvNull)
|
|
|
|
return pstrdup("null");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
elog(ERROR, "unrecognized jsonb value type %d", v.type);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return JsonbToCString(NULL, &jb->root, VARSIZE(jb));
|
|
|
|
}
|