Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb3e5cfd

Browse files
committed
Jsonb comparison bug fixes.
Fix an over-zealous assertion, which didn't take into account that sometimesa scalar element can be compared against an array/object element.Avoid comparing possibly-uninitialized local variables when end-of-array orend-of-object is reached. Also fix and enhance comments a bit.Peter Geoghegan, per reports by Pavel Stehule and me.
1 parent45b7abe commitb3e5cfd

File tree

1 file changed

+38
-25
lines changed

1 file changed

+38
-25
lines changed

‎src/backend/utils/adt/jsonb_util.c

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ static void uniqueifyJsonbObject(JsonbValue *object);
6262
*
6363
* There isn't a JsonbToJsonbValue(), because generally we find it more
6464
* convenient to directly iterate through the Jsonb representation and only
65-
* really convert nested scalar values.formIterIsContainer() does this, so
66-
*thatclients of the iteration code don't have to directly deal with the
67-
*binaryrepresentation (JsonbDeepContains() is a notable exception, although
68-
*allexceptions are internal to this module). In general, functions that
69-
*accepta JsonbValue argument are concerned with the manipulation of scalar
70-
*values,or simple containers of scalar values, where it would be
71-
*inconvenient todeal with a great amount of other state.
65+
* really convert nested scalar values.JsonbIteratorNext() does this, so that
66+
* clients of the iteration code don't have to directly deal with the binary
67+
* representation (JsonbDeepContains() is a notable exception, although all
68+
* exceptions are internal to this module). In general, functions that accept
69+
* a JsonbValue argument are concerned with the manipulation of scalar values,
70+
* or simple containers of scalar values, where it would be inconvenient to
71+
* deal with a great amount of other state.
7272
*/
7373
Jsonb*
7474
JsonbValueToJsonb(JsonbValue*val)
@@ -137,13 +137,6 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
137137
ra=JsonbIteratorNext(&ita,&va, false);
138138
rb=JsonbIteratorNext(&itb,&vb, false);
139139

140-
/*
141-
* To a limited extent we'll redundantly iterate over an array/object
142-
* while re-performing the same test without any reasonable
143-
* expectation of the same container types having differing lengths
144-
* (as when we process a WJB_BEGIN_OBJECT, and later the corresponding
145-
* WJB_END_OBJECT), but no matter.
146-
*/
147140
if (ra==rb)
148141
{
149142
if (ra==WJB_DONE)
@@ -152,6 +145,17 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
152145
break;
153146
}
154147

148+
if (ra==WJB_END_ARRAY||ra==WJB_END_OBJECT)
149+
{
150+
/*
151+
* There is no array or object to compare at this stage of
152+
* processing. jbvArray/jbvObject values are compared
153+
* initially, at the WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT
154+
* tokens.
155+
*/
156+
continue;
157+
}
158+
155159
if (va.type==vb.type)
156160
{
157161
switch (va.type)
@@ -194,19 +198,26 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
194198
else
195199
{
196200
/*
197-
* It's safe to assume that the types differed.
201+
* It's safe to assume that the types differed, and that the va
202+
* and vb values passed were set.
198203
*
199-
* If the two values were the same container type, then there'd
204+
* If the two values wereofthe same container type, then there'd
200205
* have been a chance to observe the variation in the number of
201-
* elements/pairs (when processing WJB_BEGIN_OBJECT, say). They
202-
* can't be scalar types either, because then they'd have to be
203-
* contained in containers already ruled unequal due to differing
204-
* numbers of pairs/elements, or already directly ruled unequal
205-
* with a call to the underlying type's comparator.
206+
* elements/pairs (when processing WJB_BEGIN_OBJECT, say). They're
207+
* either two heterogeneously-typed containers, or a container and
208+
* some scalar type.
209+
*
210+
* We don't have to consider the WJB_END_ARRAY and WJB_END_OBJECT
211+
* cases here, because we would have seen the corresponding
212+
* WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT tokens first, and
213+
* concluded that they don't match.
206214
*/
215+
Assert(ra!=WJB_END_ARRAY&&ra!=WJB_END_OBJECT);
216+
Assert(rb!=WJB_END_ARRAY&&rb!=WJB_END_OBJECT);
217+
207218
Assert(va.type!=vb.type);
208-
Assert(va.type==jbvArray||va.type==jbvObject);
209-
Assert(vb.type==jbvArray||vb.type==jbvObject);
219+
Assert(va.type!=jbvBinary);
220+
Assert(vb.type!=jbvBinary);
210221
/* Type-defined order */
211222
res= (va.type>vb.type) ?1 :-1;
212223
}
@@ -630,7 +641,9 @@ JsonbIteratorInit(JsonbContainer *container)
630641
* It is our job to expand the jbvBinary representation without bothering them
631642
* with it. However, clients should not take it upon themselves to touch array
632643
* or Object element/pair buffers, since their element/pair pointers are
633-
* garbage.
644+
* garbage. Also, *val will not be set when returning WJB_END_ARRAY or
645+
* WJB_END_OBJECT, on the assumption that it's only useful to access values
646+
* when recursing in.
634647
*/
635648
JsonbIteratorToken
636649
JsonbIteratorNext(JsonbIterator**it,JsonbValue*val,boolskipNested)
@@ -686,7 +699,7 @@ JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
686699
else
687700
{
688701
/*
689-
* Scalar item in array (or a container and caller didn't
702+
* Scalar item in array,or a container and caller didn't
690703
* want us to recurse into it.
691704
*/
692705
returnWJB_ELEM;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp