diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 7195df85ff533e86c94eb11913b1a5d1bf89aa6e..3a7cfa93c2706a0acc28ebc6d4063eee4087d50d 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -10309,13 +10309,11 @@ table2-mapping </row> <row> <entry> - <literal>row_to_json(rowval record [, pretty bool [, ignore_nulls bool] ])</literal> + <literal>row_to_json(record [, pretty_bool])</literal> </entry> <entry> Returns the row as a JSON object. Line feeds will be added between - level-1 elements if <parameter>pretty_bool</parameter> is true. Elements - with NULL values will be skipped when <parameter>ignore_nulls</parameter> - is true. + level-1 elements if <parameter>pretty_bool</parameter> is true. </entry> <entry><literal>row_to_json(row(1,'foo'))</literal></entry> <entry><literal>{"f1":1,"f2":"foo"}</literal></entry> diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 9d9d2394848d56dcaf4626dfbdfabff4582352ad..da99fd63e82df6c2eb52c049bafa81cdcf9f7eaf 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -897,17 +897,3 @@ RETURNS interval LANGUAGE INTERNAL STRICT IMMUTABLE AS 'make_interval'; - -CREATE OR REPLACE FUNCTION - row_to_json(rowval record, pretty boolean DEFAULT false, ignore_nulls boolean DEFAULT false) -RETURNS json -LANGUAGE INTERNAL -STRICT STABLE -AS 'row_to_json'; - -CREATE OR REPLACE FUNCTION - array_to_json(arrayval anyarray, pretty boolean DEFAULT false) -RETURNS json -LANGUAGE INTERNAL -STRICT STABLE -AS 'array_to_json'; diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c index 6f678eb8b2232a7685e4d8d908ce334a5ece9c54..d2bf640e54e72541591434d0ffa8a29411d32948 100644 --- a/src/backend/utils/adt/json.c +++ b/src/backend/utils/adt/json.c @@ -79,8 +79,7 @@ static void report_invalid_token(JsonLexContext *lex); static int report_json_context(JsonLexContext *lex); static char *extract_mb_char(char *s); static void composite_to_json(Datum composite, StringInfo result, - bool use_line_feeds, - bool ignore_nulls); + bool use_line_feeds); static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid, @@ -1366,7 +1365,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result, array_to_json_internal(val, result, false); break; case JSONTYPE_COMPOSITE: - composite_to_json(val, result, false, false); + composite_to_json(val, result, false); break; case JSONTYPE_BOOL: outputstr = DatumGetBool(val) ? "true" : "false"; @@ -1591,8 +1590,7 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds) * Turn a composite / record into JSON. */ static void -composite_to_json(Datum composite, StringInfo result, bool use_line_feeds, - bool ignore_nulls) +composite_to_json(Datum composite, StringInfo result, bool use_line_feeds) { HeapTupleHeader td; Oid tupType; @@ -1631,12 +1629,6 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds, if (tupdesc->attrs[i]->attisdropped) continue; - val = heap_getattr(tuple, i + 1, tupdesc, &isnull); - - /* Don't serialize NULL field when we don't want it */ - if (isnull && ignore_nulls) - continue; - if (needsep) appendStringInfoString(result, sep); needsep = true; @@ -1645,6 +1637,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds, escape_json(result, attname); appendStringInfoChar(result, ':'); + val = heap_getattr(tuple, i + 1, tupdesc, &isnull); + if (isnull) { tcategory = JSONTYPE_NULL; @@ -1693,10 +1687,26 @@ add_json(Datum val, bool is_null, StringInfo result, } /* - * SQL function array_to_json(row, prettybool) + * SQL function array_to_json(row) */ extern Datum array_to_json(PG_FUNCTION_ARGS) +{ + Datum array = PG_GETARG_DATUM(0); + StringInfo result; + + result = makeStringInfo(); + + array_to_json_internal(array, result, false); + + PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len)); +} + +/* + * SQL function array_to_json(row, prettybool) + */ +extern Datum +array_to_json_pretty(PG_FUNCTION_ARGS) { Datum array = PG_GETARG_DATUM(0); bool use_line_feeds = PG_GETARG_BOOL(1); @@ -1710,19 +1720,34 @@ array_to_json(PG_FUNCTION_ARGS) } /* - * SQL function row_to_json(rowval record, pretty bool, ignore_nulls bool) + * SQL function row_to_json(row) */ extern Datum row_to_json(PG_FUNCTION_ARGS) +{ + Datum array = PG_GETARG_DATUM(0); + StringInfo result; + + result = makeStringInfo(); + + composite_to_json(array, result, false); + + PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len)); +} + +/* + * SQL function row_to_json(row, prettybool) + */ +extern Datum +row_to_json_pretty(PG_FUNCTION_ARGS) { Datum array = PG_GETARG_DATUM(0); bool use_line_feeds = PG_GETARG_BOOL(1); - bool ignore_nulls = PG_GETARG_BOOL(2); StringInfo result; result = makeStringInfo(); - composite_to_json(array, result, use_line_feeds, ignore_nulls); + composite_to_json(array, result, use_line_feeds); PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len)); } diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index e5800f942511885167cbbbcf17df1b4523534f13..a3464a5df90cd4ebbb9ecc02b759cc868172133e 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201409292 +#define CATALOG_VERSION_NO 201409293 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 3ce9849abffa9293da6d6aa0850183458fe17c1f..4736532851003457d18574b4afa8a0d671412a0d 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -4203,10 +4203,14 @@ DATA(insert OID = 323 ( json_recv PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 DESCR("I/O"); DATA(insert OID = 324 ( json_send PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "114" _null_ _null_ _null_ _null_ json_send _null_ _null_ _null_ )); DESCR("I/O"); -DATA(insert OID = 3153 ( array_to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 114 "2277 16" _null_ _null_ "{arrayval,pretty}" _null_ array_to_json _null_ _null_ _null_ )); +DATA(insert OID = 3153 ( array_to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 114 "2277" _null_ _null_ _null_ _null_ array_to_json _null_ _null_ _null_ )); DESCR("map array to json"); -DATA(insert OID = 3155 ( row_to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 114 "2249 16 16" _null_ _null_ "{rowval,pretty,ignore_nulls}" _null_ row_to_json _null_ _null_ _null_ )); +DATA(insert OID = 3154 ( array_to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 114 "2277 16" _null_ _null_ _null_ _null_ array_to_json_pretty _null_ _null_ _null_ )); +DESCR("map array to json with optional pretty printing"); +DATA(insert OID = 3155 ( row_to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 114 "2249" _null_ _null_ _null_ _null_ row_to_json _null_ _null_ _null_ )); DESCR("map row to json"); +DATA(insert OID = 3156 ( row_to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 114 "2249 16" _null_ _null_ _null_ _null_ row_to_json_pretty _null_ _null_ _null_ )); +DESCR("map row to json with optional pretty printing"); DATA(insert OID = 3173 ( json_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 2283" _null_ _null_ _null_ _null_ json_agg_transfn _null_ _null_ _null_ )); DESCR("json aggregate transition function"); DATA(insert OID = 3174 ( json_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 114 "2281" _null_ _null_ _null_ _null_ json_agg_finalfn _null_ _null_ _null_ )); diff --git a/src/include/utils/json.h b/src/include/utils/json.h index 9d8a0a55a887bd94a9dd440888c0eaa3113eee76..82cc48b7113e1b0bb30da53f5e96fedb85d18299 100644 --- a/src/include/utils/json.h +++ b/src/include/utils/json.h @@ -23,7 +23,9 @@ extern Datum json_out(PG_FUNCTION_ARGS); extern Datum json_recv(PG_FUNCTION_ARGS); extern Datum json_send(PG_FUNCTION_ARGS); extern Datum array_to_json(PG_FUNCTION_ARGS); +extern Datum array_to_json_pretty(PG_FUNCTION_ARGS); extern Datum row_to_json(PG_FUNCTION_ARGS); +extern Datum row_to_json_pretty(PG_FUNCTION_ARGS); extern Datum to_json(PG_FUNCTION_ARGS); extern Datum json_agg_transfn(PG_FUNCTION_ARGS); diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out index 968e02a1e1e7ea723768c73bda13a08e0db90fea..bb4d9ed4bebca91f9c1e37b54fc1f8dbc17832f3 100644 --- a/src/test/regress/expected/json.out +++ b/src/test/regress/expected/json.out @@ -397,70 +397,12 @@ FROM rows q; "y":"txt3"} (3 rows) -SELECT row_to_json(q,pretty := true) -FROM rows q; - row_to_json --------------- - {"x":1, + - "y":"txt1"} - {"x":2, + - "y":"txt2"} - {"x":3, + - "y":"txt3"} -(3 rows) - SELECT row_to_json(row((select array_agg(x) as d from generate_series(5,10) x)),false); row_to_json ----------------------- {"f1":[5,6,7,8,9,10]} (1 row) -WITH x AS (SELECT a,b,c FROM (VALUES(10,20,30), - (10,NULL, NULL), - (NULL, NULL, NULL)) g(a,b,c)) - SELECT row_to_json(x, false, false) FROM x; - row_to_json ------------------------------- - {"a":10,"b":20,"c":30} - {"a":10,"b":null,"c":null} - {"a":null,"b":null,"c":null} -(3 rows) - -WITH x AS (SELECT a,b,c FROM (VALUES(10,20,30), - (10,NULL, NULL), - (NULL, NULL, NULL)) g(a,b,c)) - SELECT row_to_json(x, false, true) FROM x; - row_to_json ------------------------- - {"a":10,"b":20,"c":30} - {"a":10} - {} -(3 rows) - -WITH x AS (SELECT a,b,c FROM (VALUES(10,20,30), - (10,NULL, NULL), - (NULL, NULL, NULL)) g(a,b,c)) - SELECT row_to_json(x, ignore_nulls := true) FROM x; - row_to_json ------------------------- - {"a":10,"b":20,"c":30} - {"a":10} - {} -(3 rows) - -WITH x AS (SELECT a,b,c FROM (VALUES(10,20,30), - (10,NULL, NULL), - (NULL, NULL, NULL)) g(a,b,c)) - SELECT row_to_json(x, ignore_nulls := true, pretty := true) FROM x; - row_to_json -------------- - {"a":10, + - "b":20, + - "c":30} - {"a":10} - {} -(3 rows) - -- to_json, timestamps select to_json(timestamp '2014-05-28 12:22:35.614298'); to_json diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql index 3ddf6564e0c0daa78143662f8ed378d19fc017bd..c9801321e09069570e7e79db341ba7848c7af065 100644 --- a/src/test/regress/sql/json.sql +++ b/src/test/regress/sql/json.sql @@ -98,32 +98,8 @@ FROM generate_series(1,3) AS x; SELECT row_to_json(q,true) FROM rows q; -SELECT row_to_json(q,pretty := true) -FROM rows q; - SELECT row_to_json(row((select array_agg(x) as d from generate_series(5,10) x)),false); -WITH x AS (SELECT a,b,c FROM (VALUES(10,20,30), - (10,NULL, NULL), - (NULL, NULL, NULL)) g(a,b,c)) - SELECT row_to_json(x, false, false) FROM x; - -WITH x AS (SELECT a,b,c FROM (VALUES(10,20,30), - (10,NULL, NULL), - (NULL, NULL, NULL)) g(a,b,c)) - SELECT row_to_json(x, false, true) FROM x; - -WITH x AS (SELECT a,b,c FROM (VALUES(10,20,30), - (10,NULL, NULL), - (NULL, NULL, NULL)) g(a,b,c)) - SELECT row_to_json(x, ignore_nulls := true) FROM x; - -WITH x AS (SELECT a,b,c FROM (VALUES(10,20,30), - (10,NULL, NULL), - (NULL, NULL, NULL)) g(a,b,c)) - SELECT row_to_json(x, ignore_nulls := true, pretty := true) FROM x; - - -- to_json, timestamps select to_json(timestamp '2014-05-28 12:22:35.614298');