diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 551576a08b63f785d9c8323c7e3e50c57cba1424..cd2465e41c71213c029627a8ceee17e71726fea6 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -10562,8 +10562,8 @@ table2-mapping </entry> </row> <row> - <entry><para><literal>json_populate_record(base anyelement, from_json json, [, use_json_as_text bool=false])</literal> - </para><para><literal>jsonb_populate_record(base anyelement, from_json jsonb, [, use_json_as_text bool=false])</literal> + <entry><para><literal>json_populate_record(base anyelement, from_json json)</literal> + </para><para><literal>jsonb_populate_record(base anyelement, from_json jsonb)</literal> </para></entry> <entry><type>anyelement</type></entry> <entry> @@ -10581,8 +10581,8 @@ table2-mapping </entry> </row> <row> - <entry><para><literal>json_populate_recordset(base anyelement, from_json json, [, use_json_as_text bool=false])</literal> - </para><para><literal>jsonb_populate_recordset(base anyelement, from_json jsonb, [, use_json_as_text bool=false])</literal> + <entry><para><literal>json_populate_recordset(base anyelement, from_json json)</literal> + </para><para><literal>jsonb_populate_recordset(base anyelement, from_json jsonb)</literal> </para></entry> <entry><type>setof anyelement</type></entry> <entry> @@ -10655,18 +10655,17 @@ table2-mapping <entry><literal>number</literal></entry> </row> <row> - <entry><para><literal>json_to_record(json [, nested_as_text bool=false])</literal> - </para><para><literal>jsonb_to_record(jsonb [, nested_as_text bool=false])</literal> + <entry><para><literal>json_to_record(json)</literal> + </para><para><literal>jsonb_to_record(jsonb)</literal> </para></entry> <entry><type>record</type></entry> <entry> Builds an arbitrary record from a JSON object (see note below). As with all functions returning <type>record</>, the caller must explicitly define the structure of the record with an <literal>AS</> - clause. If <replaceable>nested_as_text</> is true, the function - coerces nested complex elements to text. + clause. </entry> - <entry><literal>select * from json_to_record('{"a":1,"b":[1,2,3],"c":"bar"}',true) as x(a int, b text, d text) </literal></entry> + <entry><literal>select * from json_to_record('{"a":1,"b":[1,2,3],"c":"bar"}') as x(a int, b text, d text) </literal></entry> <entry> <programlisting> a | b | d @@ -10676,18 +10675,17 @@ table2-mapping </entry> </row> <row> - <entry><para><literal>json_to_recordset(json [, nested_as_text bool=false])</literal> - </para><para><literal>jsonb_to_recordset(jsonb [, nested_as_text bool=false])</literal> + <entry><para><literal>json_to_recordset(json)</literal> + </para><para><literal>jsonb_to_recordset(jsonb)</literal> </para></entry> <entry><type>setof record</type></entry> <entry> Builds an arbitrary set of records from a JSON array of objects (see note below). As with all functions returning <type>record</>, the caller must explicitly define the structure of the record with - an <literal>AS</> clause. <replaceable>nested_as_text</> works as - with <function>json_to_record</>. + an <literal>AS</> clause. </entry> - <entry><literal>select * from json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]',true) as x(a int, b text);</literal></entry> + <entry><literal>select * from json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]') as x(a int, b text);</literal></entry> <entry> <programlisting> a | b diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 793a92b76aafdeba75bc43dad88e82ededac251b..1bde175d4566ae9ac36f783c3d06c7ef73b52fcc 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -817,38 +817,16 @@ CREATE OR REPLACE FUNCTION pg_start_backup(label text, fast boolean DEFAULT false) RETURNS pg_lsn STRICT VOLATILE LANGUAGE internal AS 'pg_start_backup'; +-- legacy definition for compatibility with 9.3 CREATE OR REPLACE FUNCTION json_populate_record(base anyelement, from_json json, use_json_as_text boolean DEFAULT false) RETURNS anyelement LANGUAGE internal STABLE AS 'json_populate_record'; +-- legacy definition for compatibility with 9.3 CREATE OR REPLACE FUNCTION json_populate_recordset(base anyelement, from_json json, use_json_as_text boolean DEFAULT false) RETURNS SETOF anyelement LANGUAGE internal STABLE ROWS 100 AS 'json_populate_recordset'; -CREATE OR REPLACE FUNCTION - jsonb_populate_record(base anyelement, from_json jsonb, use_json_as_text boolean DEFAULT false) - RETURNS anyelement LANGUAGE internal STABLE AS 'jsonb_populate_record'; - -CREATE OR REPLACE FUNCTION - 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'; - -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( IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', OUT location pg_lsn, OUT xid xid, OUT data text) diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index bd1241b620fa17a61a45a441da48f9d769585d31..6c16a953dd3fb9c0bcb903a4b17c1fb75bd2a807 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -85,8 +85,7 @@ static void elements_array_element_end(void *state, bool isnull); static void elements_scalar(void *state, char *token, JsonTokenType tokentype); /* turn a json object into a hash table */ -static HTAB *get_json_object_as_hash(text *json, const char *funcname, - bool use_json_as_text); +static HTAB *get_json_object_as_hash(text *json, const char *funcname); /* common worker for populate_record and to_record */ static Datum populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, @@ -198,7 +197,6 @@ typedef struct JhashState HTAB *hash; char *saved_scalar; char *save_json_start; - bool use_json_as_text; } JHashState; /* hashtable element */ @@ -235,7 +233,6 @@ typedef struct PopulateRecordsetState HTAB *json_hash; char *saved_scalar; char *save_json_start; - bool use_json_as_text; Tuplestorestate *tuple_store; TupleDesc ret_tdesc; HeapTupleHeader rec; @@ -1989,7 +1986,6 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, Oid jtype = get_fn_expr_argtype(fcinfo->flinfo, json_arg_num); text *json; Jsonb *jb = NULL; - bool use_json_as_text; HTAB *json_hash = NULL; HeapTupleHeader rec = NULL; Oid tupType = InvalidOid; @@ -2005,9 +2001,6 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, Assert(jtype == JSONOID || jtype == JSONBOID); - use_json_as_text = PG_ARGISNULL(json_arg_num + 1) ? false : - PG_GETARG_BOOL(json_arg_num + 1); - if (have_record_arg) { Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0); @@ -2065,7 +2058,7 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, /* just get the text */ json = PG_GETARG_TEXT_P(json_arg_num); - json_hash = get_json_object_as_hash(json, funcname, use_json_as_text); + json_hash = get_json_object_as_hash(json, funcname); /* * if the input json is empty, we can only skip the rest if we were @@ -2227,10 +2220,6 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, else if (v->type == jbvNumeric) s = DatumGetCString(DirectFunctionCall1(numeric_out, PointerGetDatum(v->val.numeric))); - else if (!use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot populate with a nested object unless use_json_as_text is true"))); else if (v->type == jbvBinary) s = JsonbToCString(NULL, (JsonbContainer *) v->val.binary.data, v->val.binary.len); else @@ -2258,15 +2247,9 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, * get_json_object_as_hash * * decompose a json object into a hash table. - * - * Currently doesn't allow anything but a flat object. Should this - * change? - * - * funcname argument allows caller to pass in its name for use in - * error messages. */ static HTAB * -get_json_object_as_hash(text *json, const char *funcname, bool use_json_as_text) +get_json_object_as_hash(text *json, const char *funcname) { HASHCTL ctl; HTAB *tab; @@ -2289,7 +2272,6 @@ get_json_object_as_hash(text *json, const char *funcname, bool use_json_as_text) state->function_name = funcname; state->hash = tab; state->lex = lex; - state->use_json_as_text = use_json_as_text; sem->semstate = (void *) state; sem->array_start = hash_array_start; @@ -2313,11 +2295,7 @@ hash_object_field_start(void *state, char *fname, bool isnull) if (_state->lex->token_type == JSON_TOKEN_ARRAY_START || _state->lex->token_type == JSON_TOKEN_OBJECT_START) { - if (!_state->use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot call %s on a nested object", - _state->function_name))); + /* remember start position of the whole text of the subobject */ _state->save_json_start = _state->lex->token_start; } else @@ -2535,10 +2513,6 @@ make_row_from_rec_and_jsonb(Jsonb *element, PopulateRecordsetState *state) else if (v->type == jbvNumeric) s = DatumGetCString(DirectFunctionCall1(numeric_out, PointerGetDatum(v->val.numeric))); - else if (!state->use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot populate with a nested object unless use_json_as_text is true"))); else if (v->type == jbvBinary) s = JsonbToCString(NULL, (JsonbContainer *) v->val.binary.data, v->val.binary.len); else @@ -2565,7 +2539,6 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, { int json_arg_num = have_record_arg ? 1 : 0; Oid jtype = get_fn_expr_argtype(fcinfo->flinfo, json_arg_num); - bool use_json_as_text; ReturnSetInfo *rsi; MemoryContext old_cxt; Oid tupType; @@ -2576,8 +2549,6 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, int ncolumns; PopulateRecordsetState *state; - use_json_as_text = PG_ARGISNULL(json_arg_num + 1) ? false : PG_GETARG_BOOL(json_arg_num + 1); - if (have_record_arg) { Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0); @@ -2667,7 +2638,6 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, state->function_name = funcname; state->my_extra = my_extra; state->rec = rec; - state->use_json_as_text = use_json_as_text; state->fn_mcxt = fcinfo->flinfo->fn_mcxt; if (jtype == JSONOID) @@ -2749,16 +2719,9 @@ populate_recordset_object_start(void *state) errmsg("cannot call %s on an object", _state->function_name))); - /* Nested objects, if allowed, require no special processing */ + /* Nested objects require no special processing */ if (lex_level > 1) - { - if (!_state->use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot call %s with nested objects", - _state->function_name))); return; - } /* Object at level 1: set up a new hash table for this object */ memset(&ctl, 0, sizeof(ctl)); @@ -2903,13 +2866,7 @@ populate_recordset_array_element_start(void *state, bool isnull) static void populate_recordset_array_start(void *state) { - PopulateRecordsetState *_state = (PopulateRecordsetState *) state; - - if (_state->lex->lex_level != 0 && !_state->use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot call %s with nested arrays", - _state->function_name))); + /* nothing to do */ } static void @@ -2938,11 +2895,6 @@ populate_recordset_object_field_start(void *state, char *fname, bool isnull) if (_state->lex->token_type == JSON_TOKEN_ARRAY_START || _state->lex->token_type == JSON_TOKEN_OBJECT_START) { - if (!_state->use_json_as_text) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot call %s on a nested object", - _state->function_name))); _state->save_json_start = _state->lex->token_start; } else diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 6f5847d0cec97f5605694bace7dd6ee5bc2f78e8..e7edb34aa394958f12a938b7ee9f532b0aadaccb 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201406262 +#define CATALOG_VERSION_NO 201406292 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 0b6105b3971ffe8d8b77ba0012225b339d88083d..f44085ca6f944b100eb40fa363a7dc8770bb6bdd 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -1061,7 +1061,7 @@ DESCR("truncate large object"); DATA(insert OID = 3172 ( lo_truncate64 PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 23 "23 20" _null_ _null_ _null_ _null_ lo_truncate64 _null_ _null_ _null_ )); DESCR("truncate large object (64 bit)"); -DATA(insert OID = 3457 ( lo_from_bytea PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 26 "26 17" _null_ _null_ _null_ _null_ lo_from_bytea _null_ _null_ _null_ )); +DATA(insert OID = 3457 ( lo_from_bytea PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 26 "26 17" _null_ _null_ _null_ _null_ lo_from_bytea _null_ _null_ _null_ )); DESCR("create new large object with given content"); DATA(insert OID = 3458 ( lo_get PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 17 "26" _null_ _null_ _null_ _null_ lo_get _null_ _null_ _null_ )); DESCR("read entire large object"); @@ -4248,9 +4248,9 @@ DATA(insert OID = 3960 ( json_populate_record PGNSP PGUID 12 1 0 0 0 f f f f DESCR("get record fields from a json object"); DATA(insert OID = 3961 ( json_populate_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 3 0 2283 "2283 114 16" _null_ _null_ _null_ _null_ json_populate_recordset _null_ _null_ _null_ )); DESCR("get set of records with fields from a json array of objects"); -DATA(insert OID = 3204 ( json_to_record PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 2249 "114 16" _null_ _null_ _null_ _null_ json_to_record _null_ _null_ _null_ )); +DATA(insert OID = 3204 ( json_to_record PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2249 "114" _null_ _null_ _null_ _null_ json_to_record _null_ _null_ _null_ )); DESCR("get record fields from a json object"); -DATA(insert OID = 3205 ( json_to_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 2 0 2249 "114 16" _null_ _null_ _null_ _null_ json_to_recordset _null_ _null_ _null_ )); +DATA(insert OID = 3205 ( json_to_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 1 0 2249 "114" _null_ _null_ _null_ _null_ json_to_recordset _null_ _null_ _null_ )); DESCR("get set of records with fields from a json array of objects"); DATA(insert OID = 3968 ( json_typeof PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "114" _null_ _null_ _null_ _null_ json_typeof _null_ _null_ _null_ )); DESCR("get the type of a json value"); @@ -4605,13 +4605,13 @@ DATA(insert OID = 3208 ( jsonb_each PGNSP PGUID 12 1 100 0 0 f f f f t t DESCR("key value pairs of a jsonb object"); DATA(insert OID = 3932 ( jsonb_each_text PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 2249 "3802" "{3802,25,25}" "{i,o,o}" "{from_json,key,value}" _null_ jsonb_each_text _null_ _null_ _null_ )); DESCR("key value pairs of a jsonb object"); -DATA(insert OID = 3209 ( jsonb_populate_record PGNSP PGUID 12 1 0 0 0 f f f f f f s 3 0 2283 "2283 3802 16" _null_ _null_ _null_ _null_ jsonb_populate_record _null_ _null_ _null_ )); +DATA(insert OID = 3209 ( jsonb_populate_record PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 2283 "2283 3802" _null_ _null_ _null_ _null_ jsonb_populate_record _null_ _null_ _null_ )); 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 2 0 2283 "2283 3802" _null_ _null_ _null_ _null_ jsonb_populate_recordset _null_ _null_ _null_ )); 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_ )); +DATA(insert OID = 3490 ( jsonb_to_record PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2249 "3802" _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_ )); +DATA(insert OID = 3491 ( jsonb_to_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 1 0 2249 "3802" _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_ )); DESCR("get the type of a jsonb value"); diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out index d1e32a19a52891dee8e2f5aaf500b40006fc11b2..99036a23ca865d20539aeb9db88636a17a00d645 100644 --- a/src/test/regress/expected/json.out +++ b/src/test/regress/expected/json.out @@ -943,78 +943,77 @@ select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a": blurfl | 3 | Mon Dec 31 15:30:56 2012 (1 row) -select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}', true) q; +select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q; a | b | c --------+---+--- blurfl | | (1 row) -select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}', true) q; +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q; a | b | c --------+---+-------------------------- blurfl | 3 | Mon Dec 31 15:30:56 2012 (1 row) -select * from json_populate_record(null::jpop,'{"a":[100,200,false],"x":43.2}', true) q; +select * from json_populate_record(null::jpop,'{"a":[100,200,false],"x":43.2}') q; a | b | c -----------------+---+--- [100,200,false] | | (1 row) -select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":[100,200,false],"x":43.2}', true) q; +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":[100,200,false],"x":43.2}') q; a | b | c -----------------+---+-------------------------- [100,200,false] | 3 | Mon Dec 31 15:30:56 2012 (1 row) -select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"c":[100,200,false],"x":43.2}', true) q; +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"c":[100,200,false],"x":43.2}') q; ERROR: invalid input syntax for type timestamp: "[100,200,false]" -- populate_recordset -select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- blurfl | | | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+----+-------------------------- blurfl | 99 | def | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- blurfl | | | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+----+-------------------------- blurfl | 99 | def | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c ---------------+----+-------------------------- [100,200,300] | 99 | {"z":true} | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; ERROR: invalid input syntax for type timestamp: "[100,200,300]" create type jpop2 as (a int, b json, c int, d int); -select * from json_populate_recordset(null::jpop2, '[{"a":2,"c":3,"b":{"z":4},"d":6}]',true) q; +select * from json_populate_recordset(null::jpop2, '[{"a":2,"c":3,"b":{"z":4},"d":6}]') q; a | b | c | d ---+---------+---+--- 2 | {"z":4} | 3 | 6 (1 row) --- using the default use_json_as_text argument select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- @@ -1030,9 +1029,12 @@ select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl"," (2 rows) select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -ERROR: cannot call json_populate_recordset on a nested object -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -ERROR: cannot call json_populate_recordset on a nested object + a | b | c +---------------+----+-------------------------- + [100,200,300] | 99 | + {"z":true} | 3 | Fri Jan 20 10:42:53 2012 +(2 rows) + -- handling of unicode surrogate pairs select json '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a' as correct_in_utf8; correct_in_utf8 @@ -1215,14 +1217,14 @@ ERROR: null value not allowed for object key select json_object('{a,b,"","d e f"}','{1,2,3,"a b c"}'); ERROR: empty value not allowed for object key -- json_to_record and json_to_recordset -select * from json_to_record('{"a":1,"b":"foo","c":"bar"}',true) +select * from json_to_record('{"a":1,"b":"foo","c":"bar"}') as x(a int, b text, d text); a | b | d ---+-----+--- 1 | foo | (1 row) -select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]',false) +select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') as x(a int, b text, c boolean); a | b | c ---+-----+--- @@ -1230,7 +1232,7 @@ select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar"," 2 | bar | t (2 rows) -select * from json_to_recordset('[{"a":1,"b":{"d":"foo"},"c":true},{"a":2,"c":false,"b":{"d":"bar"}}]', true) +select * from json_to_recordset('[{"a":1,"b":{"d":"foo"},"c":true},{"a":2,"c":false,"b":{"d":"bar"}}]') as x(a int, b json, c boolean); a | b | c ---+-------------+--- diff --git a/src/test/regress/expected/json_1.out b/src/test/regress/expected/json_1.out index 93cb693b2fbdec2bab654fbfdaf0e26d50cde51e..e74aabec8a1d3016d7fd483d9bbed30f7ed5deb9 100644 --- a/src/test/regress/expected/json_1.out +++ b/src/test/regress/expected/json_1.out @@ -943,78 +943,77 @@ select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a": blurfl | 3 | Mon Dec 31 15:30:56 2012 (1 row) -select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}', true) q; +select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q; a | b | c --------+---+--- blurfl | | (1 row) -select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}', true) q; +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q; a | b | c --------+---+-------------------------- blurfl | 3 | Mon Dec 31 15:30:56 2012 (1 row) -select * from json_populate_record(null::jpop,'{"a":[100,200,false],"x":43.2}', true) q; +select * from json_populate_record(null::jpop,'{"a":[100,200,false],"x":43.2}') q; a | b | c -----------------+---+--- [100,200,false] | | (1 row) -select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":[100,200,false],"x":43.2}', true) q; +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":[100,200,false],"x":43.2}') q; a | b | c -----------------+---+-------------------------- [100,200,false] | 3 | Mon Dec 31 15:30:56 2012 (1 row) -select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"c":[100,200,false],"x":43.2}', true) q; +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"c":[100,200,false],"x":43.2}') q; ERROR: invalid input syntax for type timestamp: "[100,200,false]" -- populate_recordset -select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- blurfl | | | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+----+-------------------------- blurfl | 99 | def | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- blurfl | | | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+----+-------------------------- blurfl | 99 | def | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c ---------------+----+-------------------------- [100,200,300] | 99 | {"z":true} | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; ERROR: invalid input syntax for type timestamp: "[100,200,300]" create type jpop2 as (a int, b json, c int, d int); -select * from json_populate_recordset(null::jpop2, '[{"a":2,"c":3,"b":{"z":4},"d":6}]',true) q; +select * from json_populate_recordset(null::jpop2, '[{"a":2,"c":3,"b":{"z":4},"d":6}]') q; a | b | c | d ---+---------+---+--- 2 | {"z":4} | 3 | 6 (1 row) --- using the default use_json_as_text argument select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- @@ -1030,9 +1029,12 @@ select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl"," (2 rows) select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -ERROR: cannot call json_populate_recordset on a nested object -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -ERROR: cannot call json_populate_recordset on a nested object + a | b | c +---------------+----+-------------------------- + [100,200,300] | 99 | + {"z":true} | 3 | Fri Jan 20 10:42:53 2012 +(2 rows) + -- handling of unicode surrogate pairs select json '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a' as correct_in_utf8; ERROR: invalid input syntax for type json @@ -1211,14 +1213,14 @@ ERROR: null value not allowed for object key select json_object('{a,b,"","d e f"}','{1,2,3,"a b c"}'); ERROR: empty value not allowed for object key -- json_to_record and json_to_recordset -select * from json_to_record('{"a":1,"b":"foo","c":"bar"}',true) +select * from json_to_record('{"a":1,"b":"foo","c":"bar"}') as x(a int, b text, d text); a | b | d ---+-----+--- 1 | foo | (1 row) -select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]',false) +select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') as x(a int, b text, c boolean); a | b | c ---+-----+--- @@ -1226,7 +1228,7 @@ select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar"," 2 | bar | t (2 rows) -select * from json_to_recordset('[{"a":1,"b":{"d":"foo"},"c":true},{"a":2,"c":false,"b":{"d":"bar"}}]', true) +select * from json_to_recordset('[{"a":1,"b":{"d":"foo"},"c":true},{"a":2,"c":false,"b":{"d":"bar"}}]') as x(a int, b json, c boolean); a | b | c ---+-------------+--- diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out index 6bc789de293df8c187f6be5ac4bf8c3b7f5b06c4..c1cc1a9dbec4c2f28a4794f953c293be2b056d66 100644 --- a/src/test/regress/expected/jsonb.out +++ b/src/test/regress/expected/jsonb.out @@ -1297,71 +1297,70 @@ SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a blurfl | 3 | Mon Dec 31 15:30:56 2012 (1 row) -SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}') q; a | b | c --------+---+--- blurfl | | (1 row) -SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}') q; a | b | c --------+---+-------------------------- blurfl | 3 | Mon Dec 31 15:30:56 2012 (1 row) -SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":[100,200,false],"x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":[100,200,false],"x":43.2}') q; a | b | c -------------------+---+--- [100, 200, false] | | (1 row) -SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":[100,200,false],"x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":[100,200,false],"x":43.2}') q; a | b | c -------------------+---+-------------------------- [100, 200, false] | 3 | Mon Dec 31 15:30:56 2012 (1 row) -SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"c":[100,200,false],"x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"c":[100,200,false],"x":43.2}') q; ERROR: invalid input syntax for type timestamp: "[100, 200, false]" -- populate_recordset -SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- blurfl | | | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+----+-------------------------- blurfl | 99 | def | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- blurfl | | | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+----+-------------------------- blurfl | 99 | def | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c -----------------+----+-------------------------- [100, 200, 300] | 99 | {"z": true} | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; ERROR: invalid input syntax for type timestamp: "[100, 200, 300]" --- using the default use_json_as_text argument SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- @@ -1377,9 +1376,12 @@ SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl" (2 rows) SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -ERROR: cannot populate with a nested object unless use_json_as_text is true -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -ERROR: cannot populate with a nested object unless use_json_as_text is true + a | b | c +-----------------+----+-------------------------- + [100, 200, 300] | 99 | + {"z": true} | 3 | Fri Jan 20 10:42:53 2012 +(2 rows) + -- handling of unicode surrogate pairs SELECT octet_length((jsonb '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a')::text) AS correct_in_utf8; correct_in_utf8 @@ -1431,14 +1433,14 @@ SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' AS not_unescaped; (1 row) -- jsonb_to_record and jsonb_to_recordset -select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}',true) +select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}') 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) +select * from jsonb_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') as x(a int, b text, c boolean); a | b | c ---+-----+--- diff --git a/src/test/regress/expected/jsonb_1.out b/src/test/regress/expected/jsonb_1.out index 0c861d3b2940db051cf0c9040c7f86fe735fa92d..249f5758442d6277322bc9809d5dcc5d2ce06c5f 100644 --- a/src/test/regress/expected/jsonb_1.out +++ b/src/test/regress/expected/jsonb_1.out @@ -1297,71 +1297,70 @@ SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a blurfl | 3 | Mon Dec 31 15:30:56 2012 (1 row) -SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}') q; a | b | c --------+---+--- blurfl | | (1 row) -SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}') q; a | b | c --------+---+-------------------------- blurfl | 3 | Mon Dec 31 15:30:56 2012 (1 row) -SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":[100,200,false],"x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":[100,200,false],"x":43.2}') q; a | b | c -------------------+---+--- [100, 200, false] | | (1 row) -SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":[100,200,false],"x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":[100,200,false],"x":43.2}') q; a | b | c -------------------+---+-------------------------- [100, 200, false] | 3 | Mon Dec 31 15:30:56 2012 (1 row) -SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"c":[100,200,false],"x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"c":[100,200,false],"x":43.2}') q; ERROR: invalid input syntax for type timestamp: "[100, 200, false]" -- populate_recordset -SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- blurfl | | | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+----+-------------------------- blurfl | 99 | def | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- blurfl | | | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+----+-------------------------- blurfl | 99 | def | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c -----------------+----+-------------------------- [100, 200, 300] | 99 | {"z": true} | 3 | Fri Jan 20 10:42:53 2012 (2 rows) -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; ERROR: invalid input syntax for type timestamp: "[100, 200, 300]" --- using the default use_json_as_text argument SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; a | b | c --------+---+-------------------------- @@ -1377,9 +1376,12 @@ SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl" (2 rows) SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -ERROR: cannot populate with a nested object unless use_json_as_text is true -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -ERROR: cannot populate with a nested object unless use_json_as_text is true + a | b | c +-----------------+----+-------------------------- + [100, 200, 300] | 99 | + {"z": true} | 3 | Fri Jan 20 10:42:53 2012 +(2 rows) + -- handling of unicode surrogate pairs SELECT octet_length((jsonb '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a')::text) AS correct_in_utf8; ERROR: invalid input syntax for type json @@ -1431,14 +1433,14 @@ SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' AS not_unescaped; (1 row) -- jsonb_to_record and jsonb_to_recordset -select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}',true) +select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}') 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) +select * from jsonb_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') as x(a int, b text, c boolean); a | b | c ---+-----+--- diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql index bc8bb62978155f672b5ab4fafd69d7cbd74869e1..3215b61a5a81100546ed415f15ddebfb8020b3db 100644 --- a/src/test/regress/sql/json.sql +++ b/src/test/regress/sql/json.sql @@ -309,31 +309,28 @@ create type jpop as (a text, b int, c timestamp); select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q; select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q; -select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}', true) q; -select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}', true) q; +select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q; +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q; -select * from json_populate_record(null::jpop,'{"a":[100,200,false],"x":43.2}', true) q; -select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":[100,200,false],"x":43.2}', true) q; -select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"c":[100,200,false],"x":43.2}', true) q; +select * from json_populate_record(null::jpop,'{"a":[100,200,false],"x":43.2}') q; +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":[100,200,false],"x":43.2}') q; +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"c":[100,200,false],"x":43.2}') q; -- populate_recordset -select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; -select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; create type jpop2 as (a int, b json, c int, d int); -select * from json_populate_recordset(null::jpop2, '[{"a":2,"c":3,"b":{"z":4},"d":6}]',true) q; - --- using the default use_json_as_text argument +select * from json_populate_recordset(null::jpop2, '[{"a":2,"c":3,"b":{"z":4},"d":6}]') q; select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -- handling of unicode surrogate pairs @@ -445,11 +442,11 @@ select json_object('{a,b,"","d e f"}','{1,2,3,"a b c"}'); -- json_to_record and json_to_recordset -select * from json_to_record('{"a":1,"b":"foo","c":"bar"}',true) +select * from json_to_record('{"a":1,"b":"foo","c":"bar"}') as x(a int, b text, d text); -select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]',false) +select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') as x(a int, b text, c boolean); -select * from json_to_recordset('[{"a":1,"b":{"d":"foo"},"c":true},{"a":2,"c":false,"b":{"d":"bar"}}]', true) +select * from json_to_recordset('[{"a":1,"b":{"d":"foo"},"c":true},{"a":2,"c":false,"b":{"d":"bar"}}]') as x(a int, b json, c boolean); diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql index 7527925b2cb1ea98a73065b0fa004b5fd78c1033..187a8e8ccc99473303dffddb624046d921d6187d 100644 --- a/src/test/regress/sql/jsonb.sql +++ b/src/test/regress/sql/jsonb.sql @@ -285,29 +285,27 @@ CREATE TYPE jbpop AS (a text, b int, c timestamp); SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}') q; SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}') q; -SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}', true) q; -SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}') q; +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}') q; -SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":[100,200,false],"x":43.2}', true) q; -SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":[100,200,false],"x":43.2}', true) q; -SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"c":[100,200,false],"x":43.2}', true) q; +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":[100,200,false],"x":43.2}') q; +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":[100,200,false],"x":43.2}') q; +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"c":[100,200,false],"x":43.2}') q; -- populate_recordset -SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',false) q; -SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]',true) q; -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; -SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]',true) q; - --- using the default use_json_as_text argument +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; -- handling of unicode surrogate pairs + SELECT octet_length((jsonb '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a')::text) AS correct_in_utf8; SELECT jsonb '{ "a": "\ud83d\ud83d" }' -> 'a'; -- 2 high surrogates in a row SELECT jsonb '{ "a": "\ude04\ud83d" }' -> 'a'; -- surrogates in wrong order @@ -321,10 +319,10 @@ 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) +select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}') 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) +select * from jsonb_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') as x(a int, b text, c boolean); -- indexing