From 86b889494a71bd6c9574de04d6612d367bc5a423 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 11 Oct 2014 14:13:54 -0400 Subject: Fix bogus optimization in JSONB containment tests. When determining whether one JSONB object contains another, it's okay to make a quick exit if the first object has fewer pairs than the second: because we de-duplicate keys within objects, it is impossible that the first object has all the keys the second does. However, the code was applying this rule to JSONB arrays as well, where it does *not* hold because arrays can contain duplicate entries. The test was really in the wrong place anyway; we should do it within JsonbDeepContains, where it can be applied to nested objects not only top-level ones. Report and test cases by Alexander Korotkov; fix by Peter Geoghegan and Tom Lane. --- src/backend/utils/adt/jsonb_op.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/backend/utils/adt/jsonb_op.c') diff --git a/src/backend/utils/adt/jsonb_op.c b/src/backend/utils/adt/jsonb_op.c index 2d071b2523b..d9aaac9ac27 100644 --- a/src/backend/utils/adt/jsonb_op.c +++ b/src/backend/utils/adt/jsonb_op.c @@ -57,7 +57,7 @@ jsonb_exists_any(PG_FUNCTION_ARGS) for (i = 0; i < elem_count; i++) { - JsonbValue strVal; + JsonbValue strVal; if (key_nulls[i]) continue; @@ -90,7 +90,7 @@ jsonb_exists_all(PG_FUNCTION_ARGS) for (i = 0; i < elem_count; i++) { - JsonbValue strVal; + JsonbValue strVal; if (key_nulls[i]) continue; @@ -117,8 +117,7 @@ jsonb_contains(PG_FUNCTION_ARGS) JsonbIterator *it1, *it2; - if (JB_ROOT_COUNT(val) < JB_ROOT_COUNT(tmpl) || - JB_ROOT_IS_OBJECT(val) != JB_ROOT_IS_OBJECT(tmpl)) + if (JB_ROOT_IS_OBJECT(val) != JB_ROOT_IS_OBJECT(tmpl)) PG_RETURN_BOOL(false); it1 = JsonbIteratorInit(&val->root); @@ -137,8 +136,7 @@ jsonb_contained(PG_FUNCTION_ARGS) JsonbIterator *it1, *it2; - if (JB_ROOT_COUNT(val) < JB_ROOT_COUNT(tmpl) || - JB_ROOT_IS_OBJECT(val) != JB_ROOT_IS_OBJECT(tmpl)) + if (JB_ROOT_IS_OBJECT(val) != JB_ROOT_IS_OBJECT(tmpl)) PG_RETURN_BOOL(false); it1 = JsonbIteratorInit(&val->root); -- cgit v1.2.3