Skip to content

Commit 9c4cc9e

Browse files
committed
Fix broken jsonb_set() logic for replacing array elements.
Commit 0b62fd0 did a fairly sloppy job of refactoring setPath() to support jsonb_insert() along with jsonb_set(). In its defense, though, there was no regression test case exercising the case of replacing an existing element in a jsonb array. Per bug #14366 from Peng Sun. Back-patch to 9.6 where bug was introduced. Report: <20161012065349.1412.47858@wrigleys.postgresql.org>
1 parent ccbb852 commit 9c4cc9e

File tree

3 files changed

+13
-6
lines changed

3 files changed

+13
-6
lines changed

src/backend/utils/adt/jsonfuncs.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@
3434
#include "utils/typcache.h"
3535

3636
/* Operations available for setPath */
37-
#define JB_PATH_NOOP 0x0000
3837
#define JB_PATH_CREATE 0x0001
3938
#define JB_PATH_DELETE 0x0002
40-
#define JB_PATH_INSERT_BEFORE 0x0004
41-
#define JB_PATH_INSERT_AFTER 0x0008
39+
#define JB_PATH_REPLACE 0x0004
40+
#define JB_PATH_INSERT_BEFORE 0x0008
41+
#define JB_PATH_INSERT_AFTER 0x0010
4242
#define JB_PATH_CREATE_OR_INSERT \
4343
(JB_PATH_INSERT_BEFORE | JB_PATH_INSERT_AFTER | JB_PATH_CREATE)
4444

@@ -3545,7 +3545,7 @@ jsonb_set(PG_FUNCTION_ARGS)
35453545
it = JsonbIteratorInit(&in->root);
35463546

35473547
res = setPath(&it, path_elems, path_nulls, path_len, &st,
3548-
0, newval, create ? JB_PATH_CREATE : JB_PATH_NOOP);
3548+
0, newval, create ? JB_PATH_CREATE : JB_PATH_REPLACE);
35493549

35503550
Assert(res != NULL);
35513551

@@ -4003,7 +4003,7 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
40034003
if (op_type & (JB_PATH_INSERT_AFTER | JB_PATH_INSERT_BEFORE))
40044004
(void) pushJsonbValue(st, r, &v);
40054005

4006-
if (op_type & JB_PATH_INSERT_AFTER)
4006+
if (op_type & (JB_PATH_INSERT_AFTER | JB_PATH_REPLACE))
40074007
addJsonbToParseState(st, newval);
40084008

40094009
done = true;
@@ -4035,7 +4035,7 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
40354035
}
40364036
}
40374037

4038-
if (op_type & JB_PATH_CREATE_OR_INSERT && !done &&
4038+
if ((op_type & JB_PATH_CREATE_OR_INSERT) && !done &&
40394039
level == path_len - 1 && i == nelems - 1)
40404040
{
40414041
addJsonbToParseState(st, newval);

src/test/regress/expected/jsonb.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3238,6 +3238,12 @@ select jsonb_set('[]','{1}','"b"', false);
32383238
[]
32393239
(1 row)
32403240

3241+
select jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0}','[2,3,4]', false);
3242+
jsonb_set
3243+
-------------------------
3244+
[[2, 3, 4], 2, null, 3]
3245+
(1 row)
3246+
32413247
-- jsonb_set adding instead of replacing
32423248
-- prepend to array
32433249
select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{b,-33}','{"foo":123}');

src/test/regress/sql/jsonb.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ select '[]'::jsonb #- '{a}';
814814
select jsonb_set('"a"','{a}','"b"'); --error
815815
select jsonb_set('{}','{a}','"b"', false);
816816
select jsonb_set('[]','{1}','"b"', false);
817+
select jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0}','[2,3,4]', false);
817818

818819
-- jsonb_set adding instead of replacing
819820

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy