@@ -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- * that clients of the iteration code don't have to directly deal with the
67- * binary representation (JsonbDeepContains() is a notable exception, although
68- * all exceptions are internal to this module). In general, functions that
69- * accept a JsonbValue argument are concerned with the manipulation of scalar
70- * values, or simple containers of scalar values, where it would be
71- * inconvenient to deal 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 */
7373Jsonb *
7474JsonbValueToJsonb (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 were of the 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 */
635648JsonbIteratorToken
636649JsonbIteratorNext (JsonbIterator * * it , JsonbValue * val , bool skipNested )
@@ -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 return WJB_ELEM ;
0 commit comments