aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2016-02-21 10:30:49 -0500
committerAndrew Dunstan <andrew@dunslane.net>2016-02-21 10:40:39 -0500
commit68d68ff8333c106962d4a936e07eba24d63a2e07 (patch)
tree823804eecb2e14bc0ebd5555d898217af9c1478f
parenta397f8268a6a315b8c6579124637cddc8f79ea71 (diff)
downloadpostgresql-68d68ff8333c106962d4a936e07eba24d63a2e07.tar.gz
postgresql-68d68ff8333c106962d4a936e07eba24d63a2e07.zip
Fix two-argument jsonb_object when called with empty arrays
Some over-eager copy-and-pasting on my part resulted in a nonsense result being returned in this case. I have adopted the same pattern for handling this case as is used in the one argument form of the function, i.e. we just skip over the code that adds values to the object. Diagnosis and patch from Michael Paquier, although not quite his solution. Fixes bug #13936. Backpatch to 9.5 where jsonb_object was introduced.
-rw-r--r--src/backend/utils/adt/jsonb.c7
-rw-r--r--src/test/regress/expected/json.out14
-rw-r--r--src/test/regress/expected/jsonb.out14
-rw-r--r--src/test/regress/sql/json.sql6
-rw-r--r--src/test/regress/sql/jsonb.sql6
5 files changed, 44 insertions, 3 deletions
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index 7e01432546d..14ce57e252d 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -1455,7 +1455,7 @@ jsonb_object_two_arg(PG_FUNCTION_ARGS)
errmsg("wrong number of array subscripts")));
if (nkdims == 0)
- PG_RETURN_DATUM(CStringGetTextDatum("{}"));
+ goto close_object;
deconstruct_array(key_array,
TEXTOID, -1, false, 'i',
@@ -1509,13 +1509,14 @@ jsonb_object_two_arg(PG_FUNCTION_ARGS)
(void) pushJsonbValue(&result.parseState, WJB_VALUE, &v);
}
- result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
-
pfree(key_datums);
pfree(key_nulls);
pfree(val_datums);
pfree(val_nulls);
+close_object:
+ result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
+
PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
}
diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out
index 0ced17e1306..502f9838897 100644
--- a/src/test/regress/expected/json.out
+++ b/src/test/regress/expected/json.out
@@ -1510,6 +1510,20 @@ INSERT INTO foo VALUES (999999, NULL, 'bar');
SELECT json_object_agg(name, type) FROM foo;
ERROR: field name must not be null
-- json_object
+-- empty object, one dimension
+SELECT json_object('{}');
+ json_object
+-------------
+ {}
+(1 row)
+
+-- empty object, two dimensions
+SELECT json_object('{}', '{}');
+ json_object
+-------------
+ {}
+(1 row)
+
-- one dimension
SELECT json_object('{a,1,b,2,3,NULL,"d e f","a b c"}');
json_object
diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out
index 72fe808734c..4789e4e57b9 100644
--- a/src/test/regress/expected/jsonb.out
+++ b/src/test/regress/expected/jsonb.out
@@ -1410,6 +1410,20 @@ INSERT INTO foo VALUES (999999, NULL, 'bar');
SELECT jsonb_object_agg(name, type) FROM foo;
ERROR: field name must not be null
-- jsonb_object
+-- empty object, one dimension
+SELECT jsonb_object('{}');
+ jsonb_object
+--------------
+ {}
+(1 row)
+
+-- empty object, two dimensions
+SELECT jsonb_object('{}', '{}');
+ jsonb_object
+--------------
+ {}
+(1 row)
+
-- one dimension
SELECT jsonb_object('{a,1,b,2,3,NULL,"d e f","a b c"}');
jsonb_object
diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql
index 0d2c139b4d1..39f1b70f4da 100644
--- a/src/test/regress/sql/json.sql
+++ b/src/test/regress/sql/json.sql
@@ -462,6 +462,12 @@ SELECT json_object_agg(name, type) FROM foo;
-- json_object
+-- empty object, one dimension
+SELECT json_object('{}');
+
+-- empty object, two dimensions
+SELECT json_object('{}', '{}');
+
-- one dimension
SELECT json_object('{a,1,b,2,3,NULL,"d e f","a b c"}');
diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql
index b724f0ab1f7..4b244776095 100644
--- a/src/test/regress/sql/jsonb.sql
+++ b/src/test/regress/sql/jsonb.sql
@@ -352,6 +352,12 @@ SELECT jsonb_object_agg(name, type) FROM foo;
-- jsonb_object
+-- empty object, one dimension
+SELECT jsonb_object('{}');
+
+-- empty object, two dimensions
+SELECT jsonb_object('{}', '{}');
+
-- one dimension
SELECT jsonb_object('{a,1,b,2,3,NULL,"d e f","a b c"}');