@@ -33,14 +33,15 @@ typedef struct
33
33
34
34
#define JSONB_VODKA_FLAG_VALUE 0x01
35
35
36
- #define JSONB_VODKA_FLAG_NULL 0x00
37
- #define JSONB_VODKA_FLAG_STRING 0x02
38
- #define JSONB_VODKA_FLAG_NUMERIC 0x04
39
- #define JSONB_VODKA_FLAG_BOOL 0x06
40
- #define JSONB_VODKA_FLAG_TYPE 0x06
41
- #define JSONB_VODKA_FLAG_TRUE 0x08
42
- #define JSONB_VODKA_FLAG_NAN 0x08
43
- #define JSONB_VODKA_FLAG_NEGATIVE 0x10
36
+ #define JSONB_VODKA_FLAG_NULL 0x00
37
+ #define JSONB_VODKA_FLAG_STRING 0x02
38
+ #define JSONB_VODKA_FLAG_NUMERIC 0x04
39
+ #define JSONB_VODKA_FLAG_BOOL 0x06
40
+ #define JSONB_VODKA_FLAG_EMPTY_ARRAY 0x08
41
+ #define JSONB_VODKA_FLAG_EMPTY_OBJECT 0x0A
42
+ #define JSONB_VODKA_FLAG_TYPE 0x0E
43
+ #define JSONB_VODKA_FLAG_TRUE 0x10
44
+ #define JSONB_VODKA_FLAG_NAN 0x10
44
45
45
46
#define JSONB_VODKA_FLAG_ARRAY 0x02
46
47
@@ -100,58 +101,6 @@ typedef struct PathStack
100
101
struct PathStack * parent ;
101
102
} PathStack ;
102
103
103
- static int
104
- get_ndigits (Numeric val )
105
- {
106
- const NumericDigit * digits ;
107
- int ndigits ;
108
-
109
- ndigits = NUMERIC_NDIGITS (val );
110
- digits = NUMERIC_DIGITS (val );
111
-
112
- while (ndigits > 0 && * digits == 0 )
113
- {
114
- ndigits -- ;
115
- digits ++ ;
116
- }
117
- return ndigits ;
118
- }
119
-
120
- static void
121
- write_numeric_key (Pointer ptr , Numeric val )
122
- {
123
- * ptr = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_NUMERIC ;
124
- if (NUMERIC_IS_NAN (val ))
125
- {
126
- * ptr |= JSONB_VODKA_FLAG_NAN ;
127
- }
128
- else
129
- {
130
- const NumericDigit * digits = NUMERIC_DIGITS (val );
131
- int ndigits = NUMERIC_NDIGITS (val );
132
- int weight = NUMERIC_WEIGHT (val );
133
- int sign = NUMERIC_SIGN (val );
134
-
135
- if (sign == NUMERIC_NEG )
136
- * ptr |= JSONB_VODKA_FLAG_NEGATIVE ;
137
- ptr ++ ;
138
-
139
- while (ndigits > 0 && * digits == 0 )
140
- {
141
- ndigits -- ;
142
- digits ++ ;
143
- }
144
-
145
- memcpy (ptr , & weight , sizeof (weight ));
146
- ptr += sizeof (weight );
147
-
148
- memcpy (ptr , digits , sizeof (NumericDigit ) * ndigits );
149
- ptr += sizeof (NumericDigit ) * ndigits ;
150
-
151
- * ptr = 0 ;
152
- }
153
- }
154
-
155
104
static bytea *
156
105
get_vodka_key (PathStack * stack , const JsonbValue * val )
157
106
{
@@ -179,6 +128,8 @@ get_vodka_key(PathStack *stack, const JsonbValue *val)
179
128
{
180
129
case jbvNull :
181
130
case jbvBool :
131
+ case jbvObject :
132
+ case jbvArray :
182
133
vallen = 1 ;
183
134
break ;
184
135
case jbvString :
@@ -226,6 +177,12 @@ get_vodka_key(PathStack *stack, const JsonbValue *val)
226
177
if (val -> val .boolean )
227
178
* ptr |= JSONB_VODKA_FLAG_TRUE ;
228
179
break ;
180
+ case jbvArray :
181
+ * ptr = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_EMPTY_ARRAY ;
182
+ break ;
183
+ case jbvObject :
184
+ * ptr = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_EMPTY_OBJECT ;
185
+ break ;
229
186
case jbvString :
230
187
* ptr = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_STRING ;
231
188
hash = hash_any ((unsigned char * )val -> val .string .val , val -> val .string .len );
@@ -302,11 +259,19 @@ static int
302
259
make_entry_handler (ExtractedNode * node , Pointer extra )
303
260
{
304
261
Entries * e = (Entries * )extra ;
305
- PathItem * item ;
262
+ PathItem * item , * leaf = node -> path ;
306
263
JsonbVodkaKey * key = (JsonbVodkaKey * )palloc (sizeof (JsonbVodkaKey ));
307
264
int length = 0 , i ;
308
265
309
- item = node -> path ;
266
+ if (!node -> bounds .inequality && node -> bounds .exact && node -> bounds .exact -> type == jqiAny )
267
+ {
268
+ item = (PathItem * )palloc (sizeof (PathItem ));
269
+ item -> type = iAny ;
270
+ item -> parent = leaf ;
271
+ leaf = item ;
272
+ }
273
+
274
+ item = leaf ;
310
275
while (item )
311
276
{
312
277
length ++ ;
@@ -316,7 +281,7 @@ make_entry_handler(ExtractedNode *node, Pointer extra)
316
281
key -> path = (PathItem * )palloc (sizeof (PathItem ) * length );
317
282
318
283
i = length - 1 ;
319
- item = node -> path ;
284
+ item = leaf ;
320
285
while (item )
321
286
{
322
287
key -> path [i ] = * item ;
@@ -380,7 +345,17 @@ vodkajsonbextract(PG_FUNCTION_ARGS)
380
345
switch (r )
381
346
{
382
347
case WJB_BEGIN_ARRAY :
348
+ if (v .val .array .nElems == 0 )
349
+ entries [i ++ ] = PointerGetDatum (get_vodka_key (stack , & v ));
350
+ tmp = stack ;
351
+ stack = (PathStack * ) palloc (sizeof (PathStack ));
352
+ stack -> s = NULL ;
353
+ stack -> len = 0 ;
354
+ stack -> parent = tmp ;
355
+ break ;
383
356
case WJB_BEGIN_OBJECT :
357
+ if (v .val .object .nPairs == 0 )
358
+ entries [i ++ ] = PointerGetDatum (get_vodka_key (stack , & v ));
384
359
tmp = stack ;
385
360
stack = (PathStack * ) palloc (sizeof (PathStack ));
386
361
stack -> s = NULL ;
0 commit comments