diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/jsonfuncs.c | 37 | ||||
-rw-r--r-- | src/test/regress/expected/json.out | 36 | ||||
-rw-r--r-- | src/test/regress/expected/jsonb.out | 36 | ||||
-rw-r--r-- | src/test/regress/sql/json.sql | 7 | ||||
-rw-r--r-- | src/test/regress/sql/jsonb.sql | 7 |
5 files changed, 102 insertions, 21 deletions
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index 28bdc7243fd..9e7035c71a1 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -2803,26 +2803,7 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv) json = jsv->val.json.str; Assert(json); - - /* already done the hard work in the json case */ - if ((typid == JSONOID || typid == JSONBOID) && - jsv->val.json.type == JSON_TOKEN_STRING) - { - /* - * Add quotes around string value (should be already escaped) if - * converting to json/jsonb. - */ - - if (len < 0) - len = strlen(json); - - str = palloc(len + sizeof(char) * 3); - str[0] = '"'; - memcpy(&str[1], json, len); - str[len + 1] = '"'; - str[len + 2] = '\0'; - } - else if (len >= 0) + if (len >= 0) { /* Need to copy non-null-terminated string */ str = palloc(len + 1 * sizeof(char)); @@ -2830,7 +2811,21 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv) str[len] = '\0'; } else - str = json; /* null-terminated string */ + str = json; /* string is already null-terminated */ + + /* If converting to json/jsonb, make string into valid JSON literal */ + if ((typid == JSONOID || typid == JSONBOID) && + jsv->val.json.type == JSON_TOKEN_STRING) + { + StringInfoData buf; + + initStringInfo(&buf); + escape_json(&buf, str); + /* free temporary buffer */ + if (str != json) + pfree(str); + str = buf.data; + } } else { diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out index cb935980394..5b8e67784f5 100644 --- a/src/test/regress/expected/json.out +++ b/src/test/regress/expected/json.out @@ -2276,6 +2276,42 @@ select * from json_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]); {{{1},{2},{3}}} (1 row) +select * from json_to_record('{"out": {"key": 1}}') as x(out json); + out +------------ + {"key": 1} +(1 row) + +select * from json_to_record('{"out": [{"key": 1}]}') as x(out json); + out +-------------- + [{"key": 1}] +(1 row) + +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out json); + out +---------------- + "{\"key\": 1}" +(1 row) + +select * from json_to_record('{"out": {"key": 1}}') as x(out jsonb); + out +------------ + {"key": 1} +(1 row) + +select * from json_to_record('{"out": [{"key": 1}]}') as x(out jsonb); + out +-------------- + [{"key": 1}] +(1 row) + +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb); + out +---------------- + "{\"key\": 1}" +(1 row) + -- json_strip_nulls select json_strip_nulls(null); json_strip_nulls diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out index 10183030068..469079c5d8f 100644 --- a/src/test/regress/expected/jsonb.out +++ b/src/test/regress/expected/jsonb.out @@ -2652,6 +2652,42 @@ select * from jsonb_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]); {{{1},{2},{3}}} (1 row) +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out json); + out +------------ + {"key": 1} +(1 row) + +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out json); + out +-------------- + [{"key": 1}] +(1 row) + +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out json); + out +---------------- + "{\"key\": 1}" +(1 row) + +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out jsonb); + out +------------ + {"key": 1} +(1 row) + +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out jsonb); + out +-------------- + [{"key": 1}] +(1 row) + +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb); + out +---------------- + "{\"key\": 1}" +(1 row) + -- test type info caching in jsonb_populate_record() CREATE TEMP TABLE jsbpoptest (js jsonb); INSERT INTO jsbpoptest diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql index 0f0a32e2a0e..a52beaa27a1 100644 --- a/src/test/regress/sql/json.sql +++ b/src/test/regress/sql/json.sql @@ -742,6 +742,13 @@ select * from json_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]); select * from json_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]); select * from json_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]); +select * from json_to_record('{"out": {"key": 1}}') as x(out json); +select * from json_to_record('{"out": [{"key": 1}]}') as x(out json); +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out json); +select * from json_to_record('{"out": {"key": 1}}') as x(out jsonb); +select * from json_to_record('{"out": [{"key": 1}]}') as x(out jsonb); +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb); + -- json_strip_nulls select json_strip_nulls(null); diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql index c1a7880792d..ba870872e80 100644 --- a/src/test/regress/sql/jsonb.sql +++ b/src/test/regress/sql/jsonb.sql @@ -709,6 +709,13 @@ select * from jsonb_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]); select * from jsonb_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]); select * from jsonb_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]); +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out json); +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out json); +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out json); +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out jsonb); +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out jsonb); +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb); + -- test type info caching in jsonb_populate_record() CREATE TEMP TABLE jsbpoptest (js jsonb); |