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)