Commit f9c6d72c authored by Andrew Dunstan's avatar Andrew Dunstan

Cleanup around json_to_record/json_to_recordset

Set function parameter names and defaults. Add jsonb versions (which the
code already provided for so the actual new code is trivial). Add jsonb
regression tests and docs.

Bump catalog version (which I apparently forgot to do when jsonb was
committed).
parent 28475f8e
...@@ -10443,9 +10443,15 @@ table2-mapping ...@@ -10443,9 +10443,15 @@ table2-mapping
<indexterm> <indexterm>
<primary>json_to_record</primary> <primary>json_to_record</primary>
</indexterm> </indexterm>
<indexterm>
<primary>jsonb_to_record</primary>
</indexterm>
<indexterm> <indexterm>
<primary>json_to_recordset</primary> <primary>json_to_recordset</primary>
</indexterm> </indexterm>
<indexterm>
<primary>jsonb_to_recordset</primary>
</indexterm>
<table id="functions-json-processing-table"> <table id="functions-json-processing-table">
<title>JSON Processing Functions</title> <title>JSON Processing Functions</title>
...@@ -10649,9 +10655,9 @@ table2-mapping ...@@ -10649,9 +10655,9 @@ table2-mapping
<entry><literal>number</literal></entry> <entry><literal>number</literal></entry>
</row> </row>
<row> <row>
<entry> <entry><para><literal>json_to_record(json [, nested_as_text bool=false])</literal>
<literal>json_to_record(json, nested_as_text bool)</literal> </para><para><literal>jsonb_to_record(jsonb [, nested_as_text bool=false])</literal>
</entry> </para></entry>
<entry><type>record</type></entry> <entry><type>record</type></entry>
<entry> <entry>
Returns an arbitrary record from a JSON object. As with all functions Returns an arbitrary record from a JSON object. As with all functions
...@@ -10670,9 +10676,9 @@ table2-mapping ...@@ -10670,9 +10676,9 @@ table2-mapping
</entry> </entry>
</row> </row>
<row> <row>
<entry> <entry><para><literal>json_to_recordset(json [, nested_as_text bool=false])</literal>
<literal>json_to_recordset(json, nested_as_text bool)</literal> </para><para><literal>jsonb_to_recordset(jsonb [, nested_as_text bool=false])</literal>
</entry> </para></entry>
<entry><type>setof record</type></entry> <entry><type>setof record</type></entry>
<entry> <entry>
Returns an arbitrary set of records from a JSON object. As with Returns an arbitrary set of records from a JSON object. As with
......
...@@ -833,6 +833,22 @@ CREATE OR REPLACE FUNCTION ...@@ -833,6 +833,22 @@ CREATE OR REPLACE FUNCTION
jsonb_populate_recordset(base anyelement, from_json jsonb, use_json_as_text boolean DEFAULT false) jsonb_populate_recordset(base anyelement, from_json jsonb, use_json_as_text boolean DEFAULT false)
RETURNS SETOF anyelement LANGUAGE internal STABLE ROWS 100 AS 'jsonb_populate_recordset'; RETURNS SETOF anyelement LANGUAGE internal STABLE ROWS 100 AS 'jsonb_populate_recordset';
CREATE OR REPLACE FUNCTION
json_to_record(from_json json, nested_as_text boolean DEFAULT false)
RETURNS record LANGUAGE internal STABLE AS 'json_to_record';
CREATE OR REPLACE FUNCTION
json_to_recordset(from_json json, nested_as_text boolean DEFAULT false)
RETURNS SETOF record LANGUAGE internal STABLE ROWS 100 AS 'json_to_recordset';
CREATE OR REPLACE FUNCTION
jsonb_to_record(from_json jsonb, nested_as_text boolean DEFAULT false)
RETURNS record LANGUAGE internal STABLE AS 'jsonb_to_record';
CREATE OR REPLACE FUNCTION
jsonb_to_recordset(from_json jsonb, nested_as_text boolean DEFAULT false)
RETURNS SETOF record LANGUAGE internal STABLE ROWS 100 AS 'jsonb_to_recordset';
CREATE OR REPLACE FUNCTION pg_logical_slot_get_changes( CREATE OR REPLACE FUNCTION pg_logical_slot_get_changes(
IN slotname name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', IN slotname name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}',
OUT location pg_lsn, OUT xid xid, OUT data text) OUT location pg_lsn, OUT xid xid, OUT data text)
......
...@@ -2014,6 +2014,12 @@ jsonb_populate_record(PG_FUNCTION_ARGS) ...@@ -2014,6 +2014,12 @@ jsonb_populate_record(PG_FUNCTION_ARGS)
return populate_record_worker(fcinfo, true); return populate_record_worker(fcinfo, true);
} }
Datum
jsonb_to_record(PG_FUNCTION_ARGS)
{
return populate_record_worker(fcinfo, false);
}
Datum Datum
json_populate_record(PG_FUNCTION_ARGS) json_populate_record(PG_FUNCTION_ARGS)
{ {
...@@ -2449,6 +2455,24 @@ jsonb_populate_recordset(PG_FUNCTION_ARGS) ...@@ -2449,6 +2455,24 @@ jsonb_populate_recordset(PG_FUNCTION_ARGS)
return populate_recordset_worker(fcinfo, true); return populate_recordset_worker(fcinfo, true);
} }
Datum
jsonb_to_recordset(PG_FUNCTION_ARGS)
{
return populate_recordset_worker(fcinfo, false);
}
Datum
json_populate_recordset(PG_FUNCTION_ARGS)
{
return populate_recordset_worker(fcinfo, true);
}
Datum
json_to_recordset(PG_FUNCTION_ARGS)
{
return populate_recordset_worker(fcinfo, false);
}
static void static void
make_row_from_rec_and_jsonb(Jsonb * element, PopulateRecordsetState *state) make_row_from_rec_and_jsonb(Jsonb * element, PopulateRecordsetState *state)
{ {
...@@ -2571,18 +2595,6 @@ make_row_from_rec_and_jsonb(Jsonb * element, PopulateRecordsetState *state) ...@@ -2571,18 +2595,6 @@ make_row_from_rec_and_jsonb(Jsonb * element, PopulateRecordsetState *state)
tuplestore_puttuple(state->tuple_store, rettuple); tuplestore_puttuple(state->tuple_store, rettuple);
} }
Datum
json_populate_recordset(PG_FUNCTION_ARGS)
{
return populate_recordset_worker(fcinfo, true);
}
Datum
json_to_recordset(PG_FUNCTION_ARGS)
{
return populate_recordset_worker(fcinfo, false);
}
/* /*
* common worker for json_populate_recordset() and json_to_recordset() * common worker for json_populate_recordset() and json_to_recordset()
*/ */
......
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 201403121 #define CATALOG_VERSION_NO 201403261
#endif #endif
...@@ -4546,6 +4546,10 @@ DATA(insert OID = 3209 ( jsonb_populate_record PGNSP PGUID 12 1 0 0 0 f f f ...@@ -4546,6 +4546,10 @@ DATA(insert OID = 3209 ( jsonb_populate_record PGNSP PGUID 12 1 0 0 0 f f f
DESCR("get record fields from a jsonb object"); DESCR("get record fields from a jsonb object");
DATA(insert OID = 3475 ( jsonb_populate_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 3 0 2283 "2283 3802 16" _null_ _null_ _null_ _null_ jsonb_populate_recordset _null_ _null_ _null_ )); DATA(insert OID = 3475 ( jsonb_populate_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 3 0 2283 "2283 3802 16" _null_ _null_ _null_ _null_ jsonb_populate_recordset _null_ _null_ _null_ ));
DESCR("get set of records with fields from a jsonb array of objects"); DESCR("get set of records with fields from a jsonb array of objects");
DATA(insert OID = 3490 ( jsonb_to_record PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 2249 "3802 16" _null_ _null_ _null_ _null_ jsonb_to_record _null_ _null_ _null_ ));
DESCR("get record fields from a json object");
DATA(insert OID = 3491 ( jsonb_to_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 2 0 2249 "3802 16" _null_ _null_ _null_ _null_ jsonb_to_recordset _null_ _null_ _null_ ));
DESCR("get set of records with fields from a json array of objects");
DATA(insert OID = 3210 ( jsonb_typeof PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "3802" _null_ _null_ _null_ _null_ jsonb_typeof _null_ _null_ _null_ )); DATA(insert OID = 3210 ( jsonb_typeof PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "3802" _null_ _null_ _null_ _null_ jsonb_typeof _null_ _null_ _null_ ));
DESCR("get the type of a jsonb value"); DESCR("get the type of a jsonb value");
DATA(insert OID = 4038 ( jsonb_ne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 3802" _null_ _null_ _null_ _null_ jsonb_ne _null_ _null_ _null_ )); DATA(insert OID = 4038 ( jsonb_ne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 3802" _null_ _null_ _null_ _null_ jsonb_ne _null_ _null_ _null_ ));
......
...@@ -78,5 +78,7 @@ extern Datum jsonb_array_elements_text(PG_FUNCTION_ARGS); ...@@ -78,5 +78,7 @@ extern Datum jsonb_array_elements_text(PG_FUNCTION_ARGS);
extern Datum jsonb_array_elements(PG_FUNCTION_ARGS); extern Datum jsonb_array_elements(PG_FUNCTION_ARGS);
extern Datum jsonb_populate_record(PG_FUNCTION_ARGS); extern Datum jsonb_populate_record(PG_FUNCTION_ARGS);
extern Datum jsonb_populate_recordset(PG_FUNCTION_ARGS); extern Datum jsonb_populate_recordset(PG_FUNCTION_ARGS);
extern Datum jsonb_to_record(PG_FUNCTION_ARGS);
extern Datum jsonb_to_recordset(PG_FUNCTION_ARGS);
#endif /* JSON_H */ #endif /* JSON_H */
...@@ -1430,6 +1430,22 @@ SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' AS not_unescaped; ...@@ -1430,6 +1430,22 @@ SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' AS not_unescaped;
null \u0000 escape null \u0000 escape
(1 row) (1 row)
-- jsonb_to_record and jsonb_to_recordset
select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}',true)
as x(a int, b text, d text);
a | b | d
---+-----+---
1 | foo |
(1 row)
select * from jsonb_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]',false)
as x(a int, b text, c boolean);
a | b | c
---+-----+---
1 | foo |
2 | bar | t
(2 rows)
-- indexing -- indexing
SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}'; SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}';
count count
......
...@@ -1430,6 +1430,22 @@ SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' AS not_unescaped; ...@@ -1430,6 +1430,22 @@ SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' AS not_unescaped;
null \u0000 escape null \u0000 escape
(1 row) (1 row)
-- jsonb_to_record and jsonb_to_recordset
select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}',true)
as x(a int, b text, d text);
a | b | d
---+-----+---
1 | foo |
(1 row)
select * from jsonb_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]',false)
as x(a int, b text, c boolean);
a | b | c
---+-----+---
1 | foo |
2 | bar | t
(2 rows)
-- indexing -- indexing
SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}'; SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}';
count count
......
...@@ -319,6 +319,14 @@ SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' ->> 'a' AS correct_in_utf8; ...@@ -319,6 +319,14 @@ SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' ->> 'a' AS correct_in_utf8;
SELECT jsonb '{ "a": "dollar \u0024 character" }' ->> 'a' AS correct_everyWHERE; SELECT jsonb '{ "a": "dollar \u0024 character" }' ->> 'a' AS correct_everyWHERE;
SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' AS not_unescaped; SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' AS not_unescaped;
-- jsonb_to_record and jsonb_to_recordset
select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}',true)
as x(a int, b text, d text);
select * from jsonb_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]',false)
as x(a int, b text, c boolean);
-- indexing -- indexing
SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}'; SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}';
SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}'; SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment