mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Fix erroneous hash calculations in gin_extract_jsonb_path().
The jsonb_path_ops code calculated hash values inconsistently in some cases involving nested arrays and objects. This would result in queries possibly not finding entries that they should find, when using a jsonb_path_ops GIN index for the search. The problem cases involve JSONB values that contain both scalars and sub-objects at the same nesting level, for example an array containing both scalars and sub-arrays. To fix, reset the current stack->hash after processing each value or sub-object, not before; and don't try to be cute about the outermost level's initial hash. Correcting this means that existing jsonb_path_ops indexes may now be inconsistent with the new hash calculation code. The symptom is the same --- searches not finding entries they should find --- but the specific rows affected are likely to be different. Users will need to REINDEX jsonb_path_ops indexes to make sure that all searches work as expected. Per bug #13756 from Daniel Cheng. Back-patch to 9.4 where the faulty logic was introduced.
This commit is contained in:
@ -2420,6 +2420,56 @@ SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4},1]}';
|
||||
t
|
||||
(1 row)
|
||||
|
||||
-- check some corner cases for indexed nested containment (bug #13756)
|
||||
create temp table nestjsonb (j jsonb);
|
||||
insert into nestjsonb (j) values ('{"a":[["b",{"x":1}],["b",{"x":2}]],"c":3}');
|
||||
insert into nestjsonb (j) values ('[[14,2,3]]');
|
||||
insert into nestjsonb (j) values ('[1,[14,2,3]]');
|
||||
create index on nestjsonb using gin(j jsonb_path_ops);
|
||||
set enable_seqscan = on;
|
||||
set enable_bitmapscan = off;
|
||||
select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb;
|
||||
j
|
||||
---------------------------------------------------
|
||||
{"a": [["b", {"x": 1}], ["b", {"x": 2}]], "c": 3}
|
||||
(1 row)
|
||||
|
||||
select * from nestjsonb where j @> '{"c":3}';
|
||||
j
|
||||
---------------------------------------------------
|
||||
{"a": [["b", {"x": 1}], ["b", {"x": 2}]], "c": 3}
|
||||
(1 row)
|
||||
|
||||
select * from nestjsonb where j @> '[[14]]';
|
||||
j
|
||||
-----------------
|
||||
[[14, 2, 3]]
|
||||
[1, [14, 2, 3]]
|
||||
(2 rows)
|
||||
|
||||
set enable_seqscan = off;
|
||||
set enable_bitmapscan = on;
|
||||
select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb;
|
||||
j
|
||||
---------------------------------------------------
|
||||
{"a": [["b", {"x": 1}], ["b", {"x": 2}]], "c": 3}
|
||||
(1 row)
|
||||
|
||||
select * from nestjsonb where j @> '{"c":3}';
|
||||
j
|
||||
---------------------------------------------------
|
||||
{"a": [["b", {"x": 1}], ["b", {"x": 2}]], "c": 3}
|
||||
(1 row)
|
||||
|
||||
select * from nestjsonb where j @> '[[14]]';
|
||||
j
|
||||
-----------------
|
||||
[[14, 2, 3]]
|
||||
[1, [14, 2, 3]]
|
||||
(2 rows)
|
||||
|
||||
reset enable_seqscan;
|
||||
reset enable_bitmapscan;
|
||||
-- nested object field / array index lookup
|
||||
SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'n';
|
||||
?column?
|
||||
|
@ -618,6 +618,26 @@ SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4}]}';
|
||||
SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4},3]}';
|
||||
SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4},1]}';
|
||||
|
||||
-- check some corner cases for indexed nested containment (bug #13756)
|
||||
create temp table nestjsonb (j jsonb);
|
||||
insert into nestjsonb (j) values ('{"a":[["b",{"x":1}],["b",{"x":2}]],"c":3}');
|
||||
insert into nestjsonb (j) values ('[[14,2,3]]');
|
||||
insert into nestjsonb (j) values ('[1,[14,2,3]]');
|
||||
create index on nestjsonb using gin(j jsonb_path_ops);
|
||||
|
||||
set enable_seqscan = on;
|
||||
set enable_bitmapscan = off;
|
||||
select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb;
|
||||
select * from nestjsonb where j @> '{"c":3}';
|
||||
select * from nestjsonb where j @> '[[14]]';
|
||||
set enable_seqscan = off;
|
||||
set enable_bitmapscan = on;
|
||||
select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb;
|
||||
select * from nestjsonb where j @> '{"c":3}';
|
||||
select * from nestjsonb where j @> '[[14]]';
|
||||
reset enable_seqscan;
|
||||
reset enable_bitmapscan;
|
||||
|
||||
-- nested object field / array index lookup
|
||||
SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'n';
|
||||
SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'a';
|
||||
|
Reference in New Issue
Block a user