diff options
author | Andrew Dunstan <andrew@dunslane.net> | 2022-03-03 13:02:10 -0500 |
---|---|---|
committer | Andrew Dunstan <andrew@dunslane.net> | 2022-03-27 17:03:34 -0400 |
commit | f4fb45d15c59d7add2e1b81a9d477d0119a9691a (patch) | |
tree | 9025afb61fd4409ae48cd21d47c7fd58647e2633 /src/include | |
parent | f79b803dcc98d707450e158db3638dc67ff8380b (diff) | |
download | postgresql-f4fb45d15c59d7add2e1b81a9d477d0119a9691a.tar.gz postgresql-f4fb45d15c59d7add2e1b81a9d477d0119a9691a.zip |
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
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/catalog/pg_aggregate.dat | 22 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.dat | 70 | ||||
-rw-r--r-- | src/include/executor/execExpr.h | 14 | ||||
-rw-r--r-- | src/include/nodes/makefuncs.h | 1 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 8 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 96 | ||||
-rw-r--r-- | src/include/nodes/primnodes.h | 25 | ||||
-rw-r--r-- | src/include/parser/kwlist.h | 6 | ||||
-rw-r--r-- | src/include/utils/json.h | 6 | ||||
-rw-r--r-- | src/include/utils/jsonb.h | 9 |
10 files changed, 256 insertions, 1 deletions
diff --git a/src/include/catalog/pg_aggregate.dat b/src/include/catalog/pg_aggregate.dat index 2843f4b4159..1934f19335b 100644 --- a/src/include/catalog/pg_aggregate.dat +++ b/src/include/catalog/pg_aggregate.dat @@ -567,14 +567,36 @@ # json { aggfnoid => 'json_agg', aggtransfn => 'json_agg_transfn', aggfinalfn => 'json_agg_finalfn', aggtranstype => 'internal' }, +{ aggfnoid => 'json_agg_strict', aggtransfn => 'json_agg_strict_transfn', + aggfinalfn => 'json_agg_finalfn', aggtranstype => 'internal' }, { aggfnoid => 'json_object_agg', aggtransfn => 'json_object_agg_transfn', aggfinalfn => 'json_object_agg_finalfn', aggtranstype => 'internal' }, +{ aggfnoid => 'json_object_agg_unique', + aggtransfn => 'json_object_agg_unique_transfn', + aggfinalfn => 'json_object_agg_finalfn', aggtranstype => 'internal' }, +{ aggfnoid => 'json_object_agg_strict', + aggtransfn => 'json_object_agg_strict_transfn', + aggfinalfn => 'json_object_agg_finalfn', aggtranstype => 'internal' }, +{ aggfnoid => 'json_object_agg_unique_strict', + aggtransfn => 'json_object_agg_unique_strict_transfn', + aggfinalfn => 'json_object_agg_finalfn', aggtranstype => 'internal' }, # jsonb { aggfnoid => 'jsonb_agg', aggtransfn => 'jsonb_agg_transfn', aggfinalfn => 'jsonb_agg_finalfn', aggtranstype => 'internal' }, +{ aggfnoid => 'jsonb_agg_strict', aggtransfn => 'jsonb_agg_strict_transfn', + aggfinalfn => 'jsonb_agg_finalfn', aggtranstype => 'internal' }, { aggfnoid => 'jsonb_object_agg', aggtransfn => 'jsonb_object_agg_transfn', aggfinalfn => 'jsonb_object_agg_finalfn', aggtranstype => 'internal' }, +{ aggfnoid => 'jsonb_object_agg_unique', + aggtransfn => 'jsonb_object_agg_unique_transfn', + aggfinalfn => 'jsonb_object_agg_finalfn', aggtranstype => 'internal' }, +{ aggfnoid => 'jsonb_object_agg_strict', + aggtransfn => 'jsonb_object_agg_strict_transfn', + aggfinalfn => 'jsonb_object_agg_finalfn', aggtranstype => 'internal' }, +{ aggfnoid => 'jsonb_object_agg_unique_strict', + aggtransfn => 'jsonb_object_agg_unique_strict_transfn', + aggfinalfn => 'jsonb_object_agg_finalfn', aggtranstype => 'internal' }, # ordered-set and hypothetical-set aggregates { aggfnoid => 'percentile_disc(float8,anyelement)', aggkind => 'o', diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 699bd0aa3e3..5e612a6b67e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -8737,6 +8737,10 @@ proname => 'json_agg_transfn', proisstrict => 'f', provolatile => 's', prorettype => 'internal', proargtypes => 'internal anyelement', prosrc => 'json_agg_transfn' }, +{ oid => '8173', descr => 'json aggregate transition function', + proname => 'json_agg_strict_transfn', proisstrict => 'f', provolatile => 's', + prorettype => 'internal', proargtypes => 'internal anyelement', + prosrc => 'json_agg_strict_transfn' }, { oid => '3174', descr => 'json aggregate final function', proname => 'json_agg_finalfn', proisstrict => 'f', prorettype => 'json', proargtypes => 'internal', prosrc => 'json_agg_finalfn' }, @@ -8744,10 +8748,26 @@ proname => 'json_agg', prokind => 'a', proisstrict => 'f', provolatile => 's', prorettype => 'json', proargtypes => 'anyelement', prosrc => 'aggregate_dummy' }, +{ oid => '8174', descr => 'aggregate input into json', + proname => 'json_agg_strict', prokind => 'a', proisstrict => 'f', + provolatile => 's', prorettype => 'json', proargtypes => 'anyelement', + prosrc => 'aggregate_dummy' }, { oid => '3180', descr => 'json object aggregate transition function', proname => 'json_object_agg_transfn', proisstrict => 'f', provolatile => 's', prorettype => 'internal', proargtypes => 'internal any any', prosrc => 'json_object_agg_transfn' }, +{ oid => '8175', descr => 'json object aggregate transition function', + proname => 'json_object_agg_strict_transfn', proisstrict => 'f', + provolatile => 's', prorettype => 'internal', proargtypes => 'internal any any', + prosrc => 'json_object_agg_strict_transfn' }, +{ oid => '8176', descr => 'json object aggregate transition function', + proname => 'json_object_agg_unique_transfn', proisstrict => 'f', + provolatile => 's', prorettype => 'internal', proargtypes => 'internal any any', + prosrc => 'json_object_agg_unique_transfn' }, +{ oid => '8177', descr => 'json object aggregate transition function', + proname => 'json_object_agg_unique_strict_transfn', proisstrict => 'f', + provolatile => 's', prorettype => 'internal', proargtypes => 'internal any any', + prosrc => 'json_object_agg_unique_strict_transfn' }, { oid => '3196', descr => 'json object aggregate final function', proname => 'json_object_agg_finalfn', proisstrict => 'f', prorettype => 'json', proargtypes => 'internal', @@ -8756,6 +8776,19 @@ proname => 'json_object_agg', prokind => 'a', proisstrict => 'f', provolatile => 's', prorettype => 'json', proargtypes => 'any any', prosrc => 'aggregate_dummy' }, +{ oid => '8178', descr => 'aggregate non-NULL input into a json object', + proname => 'json_object_agg_strict', prokind => 'a', proisstrict => 'f', + provolatile => 's', prorettype => 'json', proargtypes => 'any any', + prosrc => 'aggregate_dummy' }, +{ oid => '8179', descr => 'aggregate input into a json object with unique keys', + proname => 'json_object_agg_unique', prokind => 'a', proisstrict => 'f', + provolatile => 's', prorettype => 'json', proargtypes => 'any any', + prosrc => 'aggregate_dummy' }, +{ oid => '8180', + descr => 'aggregate non-NULL input into a json object with unique keys', + proname => 'json_object_agg_unique_strict', prokind => 'a', + proisstrict => 'f', provolatile => 's', prorettype => 'json', + proargtypes => 'any any', prosrc => 'aggregate_dummy' }, { oid => '3198', descr => 'build a json array from any inputs', proname => 'json_build_array', provariadic => 'any', proisstrict => 'f', provolatile => 's', prorettype => 'json', proargtypes => 'any', @@ -9628,6 +9661,10 @@ proname => 'jsonb_agg_transfn', proisstrict => 'f', provolatile => 's', prorettype => 'internal', proargtypes => 'internal anyelement', prosrc => 'jsonb_agg_transfn' }, +{ oid => '8181', descr => 'jsonb aggregate transition function', + proname => 'jsonb_agg_strict_transfn', proisstrict => 'f', provolatile => 's', + prorettype => 'internal', proargtypes => 'internal anyelement', + prosrc => 'jsonb_agg_strict_transfn' }, { oid => '3266', descr => 'jsonb aggregate final function', proname => 'jsonb_agg_finalfn', proisstrict => 'f', provolatile => 's', prorettype => 'jsonb', proargtypes => 'internal', @@ -9636,10 +9673,29 @@ proname => 'jsonb_agg', prokind => 'a', proisstrict => 'f', provolatile => 's', prorettype => 'jsonb', proargtypes => 'anyelement', prosrc => 'aggregate_dummy' }, +{ oid => '8182', descr => 'aggregate input into jsonb skipping nulls', + proname => 'jsonb_agg_strict', prokind => 'a', proisstrict => 'f', + provolatile => 's', prorettype => 'jsonb', proargtypes => 'anyelement', + prosrc => 'aggregate_dummy' }, { oid => '3268', descr => 'jsonb object aggregate transition function', proname => 'jsonb_object_agg_transfn', proisstrict => 'f', provolatile => 's', prorettype => 'internal', proargtypes => 'internal any any', prosrc => 'jsonb_object_agg_transfn' }, +{ oid => '8183', descr => 'jsonb object aggregate transition function', + proname => 'jsonb_object_agg_strict_transfn', proisstrict => 'f', + provolatile => 's', prorettype => 'internal', + proargtypes => 'internal any any', + prosrc => 'jsonb_object_agg_strict_transfn' }, +{ oid => '8184', descr => 'jsonb object aggregate transition function', + proname => 'jsonb_object_agg_unique_transfn', proisstrict => 'f', + provolatile => 's', prorettype => 'internal', + proargtypes => 'internal any any', + prosrc => 'jsonb_object_agg_unique_transfn' }, +{ oid => '8185', descr => 'jsonb object aggregate transition function', + proname => 'jsonb_object_agg_unique_strict_transfn', proisstrict => 'f', + provolatile => 's', prorettype => 'internal', + proargtypes => 'internal any any', + prosrc => 'jsonb_object_agg_unique_strict_transfn' }, { oid => '3269', descr => 'jsonb object aggregate final function', proname => 'jsonb_object_agg_finalfn', proisstrict => 'f', provolatile => 's', prorettype => 'jsonb', proargtypes => 'internal', @@ -9648,6 +9704,20 @@ proname => 'jsonb_object_agg', prokind => 'a', proisstrict => 'f', prorettype => 'jsonb', proargtypes => 'any any', prosrc => 'aggregate_dummy' }, +{ oid => '8186', descr => 'aggregate non-NULL inputs into jsonb object', + proname => 'jsonb_object_agg_strict', prokind => 'a', proisstrict => 'f', + prorettype => 'jsonb', proargtypes => 'any any', + prosrc => 'aggregate_dummy' }, +{ oid => '8187', + descr => 'aggregate inputs into jsonb object checking key uniqueness', + proname => 'jsonb_object_agg_unique', prokind => 'a', proisstrict => 'f', + prorettype => 'jsonb', proargtypes => 'any any', + prosrc => 'aggregate_dummy' }, +{ oid => '8188', + descr => 'aggregate non-NULL inputs into jsonb object checking key uniqueness', + proname => 'jsonb_object_agg_unique_strict', prokind => 'a', + proisstrict => 'f', prorettype => 'jsonb', proargtypes => 'any any', + prosrc => 'aggregate_dummy' }, { oid => '3271', descr => 'build a jsonb array from any inputs', proname => 'jsonb_build_array', provariadic => 'any', proisstrict => 'f', provolatile => 's', prorettype => 'jsonb', proargtypes => 'any', diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h index 56a89ebafbb..c830fcf7262 100644 --- a/src/include/executor/execExpr.h +++ b/src/include/executor/execExpr.h @@ -239,6 +239,7 @@ typedef enum ExprEvalOp EEOP_GROUPING_FUNC, EEOP_WINDOW_FUNC, EEOP_SUBPLAN, + EEOP_JSON_CONSTRUCTOR, /* aggregation related nodes */ EEOP_AGG_STRICT_DESERIALIZE, @@ -668,6 +669,17 @@ typedef struct ExprEvalStep int transno; int setoff; } agg_trans; + + /* for EEOP_JSON_CONSTRUCTOR */ + struct + { + JsonConstructorExpr *constructor; + Datum *arg_values; + bool *arg_nulls; + Oid *arg_types; + int nargs; + } json_constructor; + } d; } ExprEvalStep; @@ -769,6 +781,8 @@ extern void ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext); extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext, TupleTableSlot *slot); +extern void ExecEvalJsonConstructor(ExprState *state, ExprEvalStep *op, + ExprContext *econtext); extern void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup, ExprContext *aggcontext); diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h index ec8b71a6856..e50b933288d 100644 --- a/src/include/nodes/makefuncs.h +++ b/src/include/nodes/makefuncs.h @@ -109,6 +109,7 @@ extern VacuumRelation *makeVacuumRelation(RangeVar *relation, Oid oid, List *va_ extern JsonFormat *makeJsonFormat(JsonFormatType type, JsonEncoding encoding, int location); extern JsonValueExpr *makeJsonValueExpr(Expr *expr, JsonFormat *format); +extern Node *makeJsonKeyValue(Node *key, Node *value); extern JsonEncoding makeJsonEncoding(char *name); #endif /* MAKEFUNC_H */ diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 59737f10349..05f0b79e82e 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -204,6 +204,7 @@ typedef enum NodeTag T_JsonFormat, T_JsonReturning, T_JsonValueExpr, + T_JsonConstructorExpr, /* * TAGS FOR EXPRESSION STATE NODES (execnodes.h) @@ -494,6 +495,13 @@ typedef enum NodeTag T_VacuumRelation, T_PublicationObjSpec, T_PublicationTable, + T_JsonObjectConstructor, + T_JsonArrayConstructor, + T_JsonArrayQueryConstructor, + T_JsonAggConstructor, + T_JsonObjectAgg, + T_JsonArrayAgg, + T_JsonKeyValue, T_JsonOutput, /* diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index e06d43d4dfe..3b12a708ec0 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1563,9 +1563,103 @@ typedef struct JsonOutput { NodeTag type; TypeName *typeName; /* RETURNING type name, if specified */ - JsonReturning returning; /* RETURNING FORMAT clause and type Oids */ + JsonReturning *returning; /* RETURNING FORMAT clause and type Oids */ } JsonOutput; +/* + * JsonKeyValue - + * untransformed representation of JSON object key-value pair for + * JSON_OBJECT() and JSON_OBJECTAGG() + */ +typedef struct JsonKeyValue +{ + NodeTag type; + Expr *key; /* key expression */ + JsonValueExpr *value; /* JSON value expression */ +} JsonKeyValue; + +/* + * JsonObjectConstructor - + * untransformed representation of JSON_OBJECT() constructor + */ +typedef struct JsonObjectConstructor +{ + NodeTag type; + List *exprs; /* list of JsonKeyValue pairs */ + JsonOutput *output; /* RETURNING clause, if specified */ + bool absent_on_null; /* skip NULL values? */ + bool unique; /* check key uniqueness? */ + int location; /* token location, or -1 if unknown */ +} JsonObjectConstructor; + +/* + * JsonArrayConstructor - + * untransformed representation of JSON_ARRAY(element,...) constructor + */ +typedef struct JsonArrayConstructor +{ + NodeTag type; + List *exprs; /* list of JsonValueExpr elements */ + JsonOutput *output; /* RETURNING clause, if specified */ + bool absent_on_null; /* skip NULL elements? */ + int location; /* token location, or -1 if unknown */ +} JsonArrayConstructor; + +/* + * JsonArrayQueryConstructor - + * untransformed representation of JSON_ARRAY(subquery) constructor + */ +typedef struct JsonArrayQueryConstructor +{ + NodeTag type; + Node *query; /* subquery */ + JsonOutput *output; /* RETURNING clause, if specified */ + JsonFormat *format; /* FORMAT clause for subquery, if specified */ + bool absent_on_null; /* skip NULL elements? */ + int location; /* token location, or -1 if unknown */ +} JsonArrayQueryConstructor; + +/* + * JsonAggConstructor - + * common fields of untransformed representation of + * JSON_ARRAYAGG() and JSON_OBJECTAGG() + */ +typedef struct JsonAggConstructor +{ + NodeTag type; + JsonOutput *output; /* RETURNING clause, if any */ + Node *agg_filter; /* FILTER clause, if any */ + List *agg_order; /* ORDER BY clause, if any */ + struct WindowDef *over; /* OVER clause, if any */ + int location; /* token location, or -1 if unknown */ +} JsonAggConstructor; + +/* + * JsonObjectAgg - + * untransformed representation of JSON_OBJECTAGG() + */ +typedef struct JsonObjectAgg +{ + NodeTag type; + JsonAggConstructor *constructor; /* common fields */ + JsonKeyValue *arg; /* object key-value pair */ + bool absent_on_null; /* skip NULL values? */ + bool unique; /* check key uniqueness? */ +} JsonObjectAgg; + +/* + * JsonArrayAgg - + * untransformed representation of JSON_ARRRAYAGG() + */ +typedef struct JsonArrayAgg +{ + NodeTag type; + JsonAggConstructor *constructor; /* common fields */ + JsonValueExpr *arg; /* array element expression */ + bool absent_on_null; /* skip NULL elements? */ +} JsonArrayAgg; + + /***************************************************************************** * Raw Grammar Output Statements *****************************************************************************/ diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 8e3c99bdb52..c48527e998a 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -1292,6 +1292,31 @@ typedef struct JsonValueExpr JsonFormat *format; /* FORMAT clause, if specified */ } JsonValueExpr; +typedef enum JsonConstructorType +{ + JSCTOR_JSON_OBJECT = 1, + JSCTOR_JSON_ARRAY = 2, + JSCTOR_JSON_OBJECTAGG = 3, + JSCTOR_JSON_ARRAYAGG = 4 +} JsonConstructorType; + +/* + * JsonConstructorExpr - + * wrapper over FuncExpr/Aggref/WindowFunc for SQL/JSON constructors + */ +typedef struct JsonConstructorExpr +{ + Expr xpr; + JsonConstructorType type; /* constructor type */ + List *args; + Expr *func; /* underlying json[b]_xxx() function call */ + Expr *coercion; /* coercion to RETURNING type */ + JsonReturning *returning; /* RETURNING clause */ + bool absent_on_null; /* ABSENT ON NULL? */ + bool unique; /* WITH UNIQUE KEYS? (JSON_OBJECT[AGG] only) */ + int location; +} JsonConstructorExpr; + /* ---------------- * NullTest * diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index f3502b8be4d..f44440d4a94 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -26,6 +26,7 @@ /* name, value, category, is-bare-label */ PG_KEYWORD("abort", ABORT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("absent", ABSENT, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("absolute", ABSOLUTE_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("access", ACCESS, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("action", ACTION, UNRESERVED_KEYWORD, BARE_LABEL) @@ -229,7 +230,12 @@ PG_KEYWORD("isnull", ISNULL, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) PG_KEYWORD("isolation", ISOLATION, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("join", JOIN, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("json", JSON, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_array", JSON_ARRAY, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_arrayagg", JSON_ARRAYAGG, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_object", JSON_OBJECT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_objectagg", JSON_OBJECTAGG, COL_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("keys", KEYS, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("label", LABEL, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("language", LANGUAGE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("large", LARGE_P, UNRESERVED_KEYWORD, BARE_LABEL) diff --git a/src/include/utils/json.h b/src/include/utils/json.h index 8a84a0cdb46..63d83b815fb 100644 --- a/src/include/utils/json.h +++ b/src/include/utils/json.h @@ -20,5 +20,11 @@ extern void escape_json(StringInfo buf, const char *str); extern char *JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp); +extern bool to_json_is_immutable(Oid typoid); +extern Datum json_build_object_worker(int nargs, Datum *args, bool *nulls, + Oid *types, bool absent_on_null, + bool unique_keys); +extern Datum json_build_array_worker(int nargs, Datum *args, bool *nulls, + Oid *types, bool absent_on_null); #endif /* JSON_H */ diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h index 4cbe6edf218..6bcf35dd0af 100644 --- a/src/include/utils/jsonb.h +++ b/src/include/utils/jsonb.h @@ -329,6 +329,8 @@ typedef struct JsonbParseState JsonbValue contVal; Size size; struct JsonbParseState *next; + bool unique_keys; /* Check object key uniqueness */ + bool skip_nulls; /* Skip null object fields */ } JsonbParseState; /* @@ -412,4 +414,11 @@ extern Datum jsonb_set_element(Jsonb *jb, Datum *path, int path_len, JsonbValue *newval); extern Datum jsonb_get_element(Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text); +extern bool to_jsonb_is_immutable(Oid typoid); +extern Datum jsonb_build_object_worker(int nargs, Datum *args, bool *nulls, + Oid *types, bool absent_on_null, + bool unique_keys); +extern Datum jsonb_build_array_worker(int nargs, Datum *args, bool *nulls, + Oid *types, bool absent_on_null); + #endif /* __JSONB_H__ */ |