Skip to content

Commit

Permalink
Fix JSON_OBJECTAGG uniquefying bug
Browse files Browse the repository at this point in the history
Commit f4fb45d contained a bug in removing items with null values when
unique keys are required, where the leading items that are sorted
contained such values. Fix that and add a test for it.

Discussion: https://postgr.es/m/CAJA4AWQ_XbSmsNbW226UqNyRLJ+wb=iQkQMj77cQyoNkqtf=2Q@mail.gmail.com
  • Loading branch information
adunstan committed Apr 28, 2022
1 parent 5c854e7 commit 9c3d25e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/backend/utils/adt/jsonb_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1959,8 +1959,18 @@ uniqueifyJsonbObject(JsonbValue *object, bool unique_keys, bool skip_nulls)

if (hasNonUniq || skip_nulls)
{
JsonbPair *ptr = object->val.object.pairs + 1,
*res = object->val.object.pairs;
JsonbPair *ptr, *res;

while (skip_nulls && object->val.object.nPairs > 0 &&
object->val.object.pairs->value.type == jbvNull)
{
/* If skip_nulls is true, remove leading items with null */
object->val.object.pairs++;
object->val.object.nPairs--;
}

ptr = object->val.object.pairs + 1;
res = object->val.object.pairs;

while (ptr - object->val.object.pairs < object->val.object.nPairs)
{
Expand Down
7 changes: 7 additions & 0 deletions src/test/regress/expected/sqljson.out
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,13 @@ ERROR: duplicate JSON object key value
SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb)
FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v);
ERROR: duplicate JSON object key value
SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb)
FROM (VALUES (1, 1), (0, NULL),(4, null), (5, null),(6, null),(2, 2)) foo(k, v);
json_objectagg
------------------
{"1": 1, "2": 2}
(1 row)

-- Test JSON_OBJECT deparsing
EXPLAIN (VERBOSE, COSTS OFF)
SELECT JSON_OBJECT('foo' : '1' FORMAT JSON, 'bar' : 'baz' RETURNING json);
Expand Down
3 changes: 3 additions & 0 deletions src/test/regress/sql/sqljson.sql
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v);
SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb)
FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v);

SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb)
FROM (VALUES (1, 1), (0, NULL),(4, null), (5, null),(6, null),(2, 2)) foo(k, v);

-- Test JSON_OBJECT deparsing
EXPLAIN (VERBOSE, COSTS OFF)
SELECT JSON_OBJECT('foo' : '1' FORMAT JSON, 'bar' : 'baz' RETURNING json);
Expand Down

0 comments on commit 9c3d25e

Please sign in to comment.