@@ -43,7 +43,6 @@ compareNumeric(Numeric a, Numeric b)
43
43
);
44
44
}
45
45
46
- #define jbvScalar jbvBinary
47
46
static int
48
47
JsonbType (JsonbValue * jb )
49
48
{
@@ -52,15 +51,9 @@ JsonbType(JsonbValue *jb)
52
51
if (jb -> type == jbvBinary )
53
52
{
54
53
JsonbContainer * jbc = jb -> val .binary .data ;
55
-
56
- if (jbc -> header & JB_FSCALAR )
54
+ type = jbc -> type ;
55
+ if (type == ( jbvArray | jbvScalar ) )
57
56
type = 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 );
64
57
}
65
58
66
59
return type ;
@@ -174,18 +167,22 @@ checkArrayEquality(JsQueryItem *jsq, JsonbValue *jb)
174
167
JsonbIterator * it ;
175
168
JsonbValue v ;
176
169
JsQueryItem elem ;
170
+ int nelems ;
177
171
178
172
if (!(jsq -> type == jqiArray && JsonbType (jb ) == jbvArray ))
179
173
return false;
180
174
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;
181
181
182
182
it = JsonbIteratorInit (jb -> val .binary .data );
183
183
r = JsonbIteratorNext (& it , & v , true);
184
184
Assert (r == WJB_BEGIN_ARRAY );
185
185
186
- if (v .val .array .nElems != jsq -> array .nelems )
187
- return false;
188
-
189
186
while ((r = JsonbIteratorNext (& it , & v , true)) != WJB_DONE )
190
187
{
191
188
if (r != WJB_ELEM )
@@ -338,7 +335,28 @@ executeExpr(JsQueryItem *jsq, int32 op, JsonbValue *jb, JsQueryItem *jsqLeftArg)
338
335
r = JsonbIteratorNext (& it , & v , true);
339
336
Assert (r == WJB_BEGIN_ARRAY || r == WJB_BEGIN_OBJECT );
340
337
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
+ }
342
360
343
361
v .type = jbvNumeric ;
344
362
v .val .numeric = DatumGetNumeric (DirectFunctionCall1 (int4_numeric , Int32GetDatum (length )));
@@ -609,16 +627,14 @@ jsquery_json_exec(PG_FUNCTION_ARGS)
609
627
JsonbValue jbv ;
610
628
JsQueryItem jsq ;
611
629
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 );
615
631
616
632
jsqInit (& jsq , jq );
617
633
618
634
res = recursiveExecute (& jsq , & jbv , NULL );
619
635
620
636
PG_FREE_IF_COPY (jq , 0 );
621
- PG_FREE_IF_COPY (jb , 1 );
637
+ PG_FREE_IF_COPY_JSONB (jb , 1 );
622
638
623
639
PG_RETURN_BOOL (res );
624
640
}
@@ -633,15 +649,13 @@ json_jsquery_exec(PG_FUNCTION_ARGS)
633
649
JsonbValue jbv ;
634
650
JsQueryItem jsq ;
635
651
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 );
639
653
640
654
jsqInit (& jsq , jq );
641
655
642
656
res = recursiveExecute (& jsq , & jbv , NULL );
643
657
644
- PG_FREE_IF_COPY (jb , 0 );
658
+ PG_FREE_IF_COPY_JSONB (jb , 0 );
645
659
PG_FREE_IF_COPY (jq , 1 );
646
660
647
661
PG_RETURN_BOOL (res );
0 commit comments