@@ -43,7 +43,6 @@ compareNumeric(Numeric a, Numeric b)
4343);
4444}
4545
46- #define jbvScalar jbvBinary
4746static int
4847JsonbType (JsonbValue * jb )
4948{
@@ -52,15 +51,9 @@ JsonbType(JsonbValue *jb)
5251if (jb -> type == jbvBinary )
5352{
5453JsonbContainer * jbc = jb -> val .binary .data ;
55-
56- if (jbc -> header & JB_FSCALAR )
54+ type = jbc -> type ;
55+ if (type == ( jbvArray | jbvScalar ) )
5756type = jbvScalar ;
58- else if (jbc -> header & JB_FOBJECT )
59- type = jbvObject ;
60- else if (jbc -> header & JB_FARRAY )
61- type = jbvArray ;
62- else
63- elog (ERROR ,"Unknown container type: 0x%08x" ,jbc -> header );
6457}
6558
6659return type ;
@@ -174,18 +167,22 @@ checkArrayEquality(JsQueryItem *jsq, JsonbValue *jb)
174167JsonbIterator * it ;
175168JsonbValue v ;
176169JsQueryItem elem ;
170+ int nelems ;
177171
178172if (!(jsq -> type == jqiArray && JsonbType (jb )== jbvArray ))
179173return false;
180174
175+ nelems = JsonContainerSize (jb -> val .binary .data );
176+ if (nelems < 0 )
177+ nelems = JsonGetArraySize (jb -> val .binary .data );
178+
179+ if (nelems != jsq -> array .nelems )
180+ return false;
181181
182182it = JsonbIteratorInit (jb -> val .binary .data );
183183r = JsonbIteratorNext (& it ,& v , true);
184184Assert (r == WJB_BEGIN_ARRAY );
185185
186- if (v .val .array .nElems != jsq -> array .nelems )
187- return false;
188-
189186while ((r = JsonbIteratorNext (& it ,& v , true))!= WJB_DONE )
190187{
191188if (r != WJB_ELEM )
@@ -338,7 +335,28 @@ executeExpr(JsQueryItem *jsq, int32 op, JsonbValue *jb, JsQueryItem *jsqLeftArg)
338335r = JsonbIteratorNext (& it ,& v , true);
339336Assert (r == WJB_BEGIN_ARRAY || r == WJB_BEGIN_OBJECT );
340337
341- length = (r == WJB_BEGIN_ARRAY ) ?v .val .array .nElems :v .val .object .nPairs ;
338+ if (r == WJB_BEGIN_ARRAY )
339+ {
340+ length = v .val .array .nElems ;
341+
342+ if (length < 0 )
343+ length = JsonGetArraySize (jb -> val .binary .data );
344+ }
345+ else
346+ {
347+ length = v .val .object .nPairs ;
348+
349+ if (length < 0 )
350+ {
351+ length = 0 ;
352+
353+ while ((r = JsonbIteratorNext (& it ,& v , true))!= WJB_DONE )
354+ {
355+ if (r == WJB_KEY )
356+ length ++ ;
357+ }
358+ }
359+ }
342360
343361v .type = jbvNumeric ;
344362v .val .numeric = DatumGetNumeric (DirectFunctionCall1 (int4_numeric ,Int32GetDatum (length )));
@@ -609,16 +627,14 @@ jsquery_json_exec(PG_FUNCTION_ARGS)
609627JsonbValue jbv ;
610628JsQueryItem jsq ;
611629
612- jbv .type = jbvBinary ;
613- jbv .val .binary .data = & jb -> root ;
614- jbv .val .binary .len = VARSIZE_ANY_EXHDR (jb );
630+ JsonValueInitBinary (& jbv ,& jb -> root );
615631
616632jsqInit (& jsq ,jq );
617633
618634res = recursiveExecute (& jsq ,& jbv ,NULL );
619635
620636PG_FREE_IF_COPY (jq ,0 );
621- PG_FREE_IF_COPY (jb ,1 );
637+ PG_FREE_IF_COPY_JSONB (jb ,1 );
622638
623639PG_RETURN_BOOL (res );
624640}
@@ -633,15 +649,13 @@ json_jsquery_exec(PG_FUNCTION_ARGS)
633649JsonbValue jbv ;
634650JsQueryItem jsq ;
635651
636- jbv .type = jbvBinary ;
637- jbv .val .binary .data = & jb -> root ;
638- jbv .val .binary .len = VARSIZE_ANY_EXHDR (jb );
652+ JsonValueInitBinary (& jbv ,& jb -> root );
639653
640654jsqInit (& jsq ,jq );
641655
642656res = recursiveExecute (& jsq ,& jbv ,NULL );
643657
644- PG_FREE_IF_COPY (jb ,0 );
658+ PG_FREE_IF_COPY_JSONB (jb ,0 );
645659PG_FREE_IF_COPY (jq ,1 );
646660
647661PG_RETURN_BOOL (res );