diff options
Diffstat (limited to 'src/backend/utils/adt')
-rw-r--r-- | src/backend/utils/adt/jsonb_op.c | 10 | ||||
-rw-r--r-- | src/backend/utils/adt/jsonb_util.c | 16 |
2 files changed, 18 insertions, 8 deletions
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); diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c index f157df3532d..2ff85396d01 100644 --- a/src/backend/utils/adt/jsonb_util.c +++ b/src/backend/utils/adt/jsonb_util.c @@ -957,13 +957,24 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained) } else if (rcont == WJB_BEGIN_OBJECT) { - JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */ - + Assert(vval.type == jbvObject); Assert(vcontained.type == jbvObject); + /* + * If the lhs has fewer pairs than the rhs, it can't possibly contain + * the rhs. (This conclusion is safe only because we de-duplicate + * keys in all Jsonb objects; thus there can be no corresponding + * optimization in the array case.) The case probably won't arise + * often, but since it's such a cheap check we may as well make it. + */ + if (vval.val.object.nPairs < vcontained.val.object.nPairs) + return false; + /* Work through rhs "is it contained within?" object */ for (;;) { + JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */ + rcont = JsonbIteratorNext(mContained, &vcontained, false); /* @@ -1047,6 +1058,7 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained) JsonbValue *lhsConts = NULL; uint32 nLhsElems = vval.val.array.nElems; + Assert(vval.type == jbvArray); Assert(vcontained.type == jbvArray); /* |