Skip to content

Commit 390f7df

Browse files
committed
Partly working vodka opclass...
1 parent 91f7fc0 commit 390f7df

File tree

1 file changed

+75
-94
lines changed

1 file changed

+75
-94
lines changed

jsonb_vodka_ops.c

Lines changed: 75 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ typedef struct
3737
#define JSONB_VODKA_FLAG_STRING 0x02
3838
#define JSONB_VODKA_FLAG_NUMERIC 0x04
3939
#define JSONB_VODKA_FLAG_BOOL 0x06
40+
#define JSONB_VODKA_FLAG_TYPE 0x06
4041
#define JSONB_VODKA_FLAG_TRUE 0x08
4142
#define JSONB_VODKA_FLAG_NAN 0x08
4243
#define JSONB_VODKA_FLAG_NEGATIVE 0x10
@@ -184,10 +185,7 @@ get_vodka_key(PathStack *stack, const JsonbValue *val)
184185
vallen = 5;
185186
break;
186187
case jbvNumeric:
187-
if (NUMERIC_IS_NAN(val->val.numeric))
188-
vallen = 1;
189-
else
190-
vallen = get_ndigits(val->val.numeric) + 6;
188+
vallen = 1 + VARSIZE_ANY(val->val.numeric);
191189
break;
192190
default:
193191
elog(ERROR, "invalid jsonb scalar type");
@@ -234,8 +232,8 @@ get_vodka_key(PathStack *stack, const JsonbValue *val)
234232
memcpy(ptr + 1, &hash, sizeof(hash));
235233
break;
236234
case jbvNumeric:
237-
*ptr = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_STRING;
238-
write_numeric_key(ptr, val->val.numeric);
235+
*ptr = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_NUMERIC;
236+
memcpy(ptr + 1, val->val.numeric, VARSIZE_ANY(val->val.numeric));
239237
break;
240238
default:
241239
elog(ERROR, "invalid jsonb scalar type");
@@ -244,116 +242,103 @@ get_vodka_key(PathStack *stack, const JsonbValue *val)
244242
return result;
245243
}
246244

247-
static int
248-
make_entry_handler(ExtractedNode *node, Pointer extra)
245+
typedef struct
249246
{
250-
Entries *e = (Entries *)extra;
251-
PathItem *item;
252-
int totallen = VARHDRSZ, vallen, jqPos, len;
253-
Pointer ptr;
254-
JsQueryValue *value;
255-
Numeric numeric = NULL;
256-
char *jqBase;
257-
uint32 hash;
258-
bytea *result;
259-
260-
Assert(node->type == eScalar);
261-
262-
if (node->bounds.inequality || node->bounds.exact->type == jqiAny)
263-
return -1;
264-
265-
item = node->path;
266-
while (item)
267-
{
268-
if (item->type == iKey)
269-
totallen += item->len + 2;
270-
else if (item->type == iAnyArray)
271-
totallen += 1;
272-
else
273-
return -1;
274-
item = item->parent;
275-
}
247+
uint8 type;
248+
uint32 hash;
249+
Numeric n;
250+
} JsonbVodkaValue;
276251

277-
value = node->bounds.exact;
278-
switch(value->type)
279-
{
280-
case jqiNull:
281-
case jqiBool:
282-
vallen = 1;
283-
break;
284-
case jqiString:
285-
vallen = 5;
286-
break;
287-
case jqiNumeric:
288-
numeric = (Numeric)(value->jqBase + value->jqPos);
289-
if (NUMERIC_IS_NAN(numeric))
290-
vallen = 1;
291-
else
292-
vallen = get_ndigits(numeric) + 6;
293-
break;
294-
default:
295-
elog(ERROR,"Wrong state");
296-
}
252+
typedef struct
253+
{
254+
int pathLength;
255+
PathItem *path;
256+
JsonbVodkaValue *exact, *leftBound, *rightBound;
257+
bool inequality, leftInclusive, rightInclusive;
258+
} JsonbVodkaKey;
259+
260+
static JsonbVodkaValue *
261+
make_vodka_value(JsQueryValue *value)
262+
{
263+
JsonbVodkaValue *result;
264+
int32 len, jqPos;
265+
char *jqBase;
297266

298-
totallen += vallen;
299-
result = (bytea *)palloc(totallen);
300-
SET_VARSIZE(result, totallen);
301-
ptr = (Pointer)result + totallen - vallen;
267+
if (!value)
268+
return NULL;
302269

303-
item = node->path;
304-
while (item)
305-
{
306-
if (item->type == iKey)
307-
{
308-
ptr -= item->len + 2;
309-
ptr[0] = 0;
310-
memcpy(ptr + 1, item->s, item->len);
311-
ptr[item->len + 1] = 0;
312-
}
313-
else if (item->type == iAnyArray)
314-
{
315-
ptr--;
316-
*ptr = JSONB_VODKA_FLAG_ARRAY;
317-
}
318-
else
319-
{
320-
return -1;
321-
}
322-
item = item->parent;
323-
}
270+
result = (JsonbVodkaValue *)palloc(sizeof(JsonbVodkaValue));
324271

325-
ptr = (Pointer)result + totallen - vallen;
326272
jqBase = value->jqBase;
327273
jqPos = value->jqPos;
328274

329275
switch (value->type)
330276
{
331277
case jbvNull:
332-
*ptr = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_NULL;
278+
result->type = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_NULL;
333279
break;
334280
case jbvBool:
335-
*ptr = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_BOOL;
281+
result->type = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_BOOL;
336282
read_byte(len, jqBase, jqPos);
337283
if (len)
338-
*ptr |= JSONB_VODKA_FLAG_TRUE;
284+
result->type |= JSONB_VODKA_FLAG_TRUE;
339285
break;
340286
case jbvString:
341-
*ptr = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_STRING;
287+
result->type = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_STRING;
342288
read_int32(len, jqBase, jqPos);
343-
hash = hash_any((unsigned char *)jqBase + jqPos, len);
344-
memcpy(ptr + 1, &hash, sizeof(hash));
289+
result->hash = hash_any((unsigned char *)jqBase + jqPos, len);
345290
break;
346291
case jbvNumeric:
347-
*ptr = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_STRING;
348-
write_numeric_key(ptr, numeric);
292+
result->type = JSONB_VODKA_FLAG_VALUE | JSONB_VODKA_FLAG_NUMERIC;
293+
result->n = (Numeric)(jqBase + jqPos);
349294
break;
350295
default:
351296
elog(ERROR, "invalid jsonb scalar type");
352297
}
353-
354-
return add_entry(e, PointerGetDatum(result), NULL, ByteaEqualOperator, false);
298+
return result;
355299
}
356300

301+
static int
302+
make_entry_handler(ExtractedNode *node, Pointer extra)
303+
{
304+
Entries *e = (Entries *)extra;
305+
PathItem *item;
306+
JsonbVodkaKey *key = (JsonbVodkaKey *)palloc(sizeof(JsonbVodkaKey));
307+
int length = 0, i;
308+
309+
item = node->path;
310+
while (item)
311+
{
312+
length++;
313+
item = item->parent;
314+
}
315+
key->pathLength = length;
316+
key->path = (PathItem *)palloc(sizeof(PathItem) * length);
317+
318+
i = length - 1;
319+
item = node->path;
320+
while (item)
321+
{
322+
key->path[i] = *item;
323+
i--;
324+
item = item->parent;
325+
}
326+
327+
key->inequality = node->bounds.inequality;
328+
key->leftInclusive = node->bounds.leftInclusive;
329+
key->rightInclusive = node->bounds.rightInclusive;
330+
if (key->inequality)
331+
{
332+
key->leftBound = make_vodka_value(node->bounds.leftBound);
333+
key->rightBound = make_vodka_value(node->bounds.rightBound);
334+
}
335+
else
336+
{
337+
key->exact = make_vodka_value(node->bounds.exact);
338+
}
339+
340+
return add_entry(e, PointerGetDatum(key), NULL, VodkaMatchOperator, false);
341+
}
357342

358343
/*
359344
* extractValue support function
@@ -474,15 +459,11 @@ vodkaqueryjsonbextract(PG_FUNCTION_ARGS)
474459
keys[i].extra = (Pointer)root;
475460
break;
476461

477-
478-
break;
479-
480462
default:
481463
elog(ERROR, "unrecognized strategy number: %d", strategy);
482464
break;
483465
}
484466

485-
486467
/* ...although "contains {}" requires a full index scan */
487468
if (*nentries == 0)
488469
*searchMode = VODKA_SEARCH_MODE_ALL;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy