Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit dcafedf

Browse files
author
Nikita Glukhov
committed
Fix jsonpath grammar: add multiple filters support, expressions, comprasion ops for sequences
1 parent 5a330db commit dcafedf

File tree

9 files changed

+549
-215
lines changed

9 files changed

+549
-215
lines changed

src/backend/utils/adt/jsonpath.c

Lines changed: 123 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item)
5050
break;
5151
case jpiAnd:
5252
case jpiOr:
53+
case jpiEqual:
54+
case jpiNotEqual:
55+
case jpiLess:
56+
case jpiGreater:
57+
case jpiLessOrEqual:
58+
case jpiGreaterOrEqual:
59+
case jpiAdd:
60+
case jpiSub:
61+
case jpiMul:
62+
case jpiDiv:
63+
case jpiMod:
5364
{
5465
int32 left, right;
5566

@@ -64,13 +75,11 @@ flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item)
6475
*(int32*)(buf->data + right) = chld;
6576
}
6677
break;
67-
case jpiEqual:
68-
case jpiLess:
69-
case jpiGreater:
70-
case jpiLessOrEqual:
71-
case jpiGreaterOrEqual:
7278
case jpiNot:
73-
case jpiExpression:
79+
case jpiIsUnknown:
80+
case jpiPlus:
81+
case jpiMinus:
82+
case jpiFilter:
7483
{
7584
int32 arg;
7685

@@ -150,7 +159,9 @@ printOperation(StringInfo buf, JsonPathItemType type)
150159
case jpiOr:
151160
appendBinaryStringInfo(buf, " || ", 4); break;
152161
case jpiEqual:
153-
appendBinaryStringInfo(buf, " = ", 3); break;
162+
appendBinaryStringInfo(buf, " = ", 3); break; /* FIXME == */
163+
case jpiNotEqual:
164+
appendBinaryStringInfo(buf, " != ", 4); break;
154165
case jpiLess:
155166
appendBinaryStringInfo(buf, " < ", 3); break;
156167
case jpiGreater:
@@ -159,11 +170,49 @@ printOperation(StringInfo buf, JsonPathItemType type)
159170
appendBinaryStringInfo(buf, " <= ", 4); break;
160171
case jpiGreaterOrEqual:
161172
appendBinaryStringInfo(buf, " >= ", 4); break;
173+
case jpiAdd:
174+
appendBinaryStringInfo(buf, " + ", 3); break;
175+
case jpiSub:
176+
appendBinaryStringInfo(buf, " - ", 3); break;
177+
case jpiMul:
178+
appendBinaryStringInfo(buf, " * ", 3); break;
179+
case jpiDiv:
180+
appendBinaryStringInfo(buf, " / ", 3); break;
181+
case jpiMod:
182+
appendBinaryStringInfo(buf, " % ", 3); break;
162183
default:
163184
elog(ERROR, "Unknown jsonpath item type: %d", type);
164185
}
165186
}
166187

188+
static int
189+
operationPriority(JsonPathItemType op)
190+
{
191+
switch (op)
192+
{
193+
case jpiOr:
194+
return 0;
195+
case jpiAnd:
196+
return 1;
197+
case jpiEqual:
198+
case jpiNotEqual:
199+
case jpiLess:
200+
case jpiGreater:
201+
case jpiLessOrEqual:
202+
case jpiGreaterOrEqual:
203+
return 2;
204+
case jpiAdd:
205+
case jpiSub:
206+
return 3;
207+
case jpiMul:
208+
case jpiDiv:
209+
case jpiMod:
210+
return 4;
211+
default:
212+
return 5;
213+
}
214+
}
215+
167216
static void
168217
printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, bool printBracketes)
169218
{
@@ -202,33 +251,41 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, bool printBracket
202251
break;
203252
case jpiAnd:
204253
case jpiOr:
205-
appendStringInfoChar(buf, '(');
254+
case jpiEqual:
255+
case jpiNotEqual:
256+
case jpiLess:
257+
case jpiGreater:
258+
case jpiLessOrEqual:
259+
case jpiGreaterOrEqual:
260+
case jpiAdd:
261+
case jpiSub:
262+
case jpiMul:
263+
case jpiDiv:
264+
case jpiMod:
265+
if (printBracketes)
266+
appendStringInfoChar(buf, '(');
206267
jspGetLeftArg(v, &elem);
207-
printJsonPathItem(buf, &elem, false, true);
268+
printJsonPathItem(buf, &elem, false,
269+
operationPriority(elem.type) <=
270+
operationPriority(v->type));
208271
printOperation(buf, v->type);
209272
jspGetRightArg(v, &elem);
210-
printJsonPathItem(buf, &elem, false, true);
211-
appendStringInfoChar(buf, ')');
273+
printJsonPathItem(buf, &elem, false,
274+
operationPriority(elem.type) <=
275+
operationPriority(v->type));
276+
if (printBracketes)
277+
appendStringInfoChar(buf, ')');
212278
break;
213-
case jpiExpression:
279+
case jpiFilter:
214280
appendBinaryStringInfo(buf, "?(", 2);
215281
jspGetArg(v, &elem);
216282
printJsonPathItem(buf, &elem, false, false);
217283
appendStringInfoChar(buf, ')');
218284
break;
219-
case jpiEqual:
220-
case jpiLess:
221-
case jpiGreater:
222-
case jpiLessOrEqual:
223-
case jpiGreaterOrEqual:
224-
printOperation(buf, v->type);
225-
jspGetArg(v, &elem);
226-
printJsonPathItem(buf, &elem, false, true);
227-
break;
228285
case jpiNot:
229-
appendBinaryStringInfo(buf, "(! ", 2);
286+
appendBinaryStringInfo(buf, "!(", 2);
230287
jspGetArg(v, &elem);
231-
printJsonPathItem(buf, &elem, false, true);
288+
printJsonPathItem(buf, &elem, false, false);
232289
appendStringInfoChar(buf, ')');
233290
break;
234291
case jpiCurrent:
@@ -357,16 +414,25 @@ jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
357414
break;
358415
case jpiAnd:
359416
case jpiOr:
360-
read_int32(v->args.left, base, pos);
361-
read_int32(v->args.right, base, pos);
362-
break;
417+
case jpiAdd:
418+
case jpiSub:
419+
case jpiMul:
420+
case jpiDiv:
421+
case jpiMod:
363422
case jpiEqual:
423+
case jpiNotEqual:
364424
case jpiLess:
365425
case jpiGreater:
366426
case jpiLessOrEqual:
367427
case jpiGreaterOrEqual:
428+
read_int32(v->args.left, base, pos);
429+
read_int32(v->args.right, base, pos);
430+
break;
368431
case jpiNot:
369-
case jpiExpression:
432+
case jpiIsUnknown:
433+
case jpiMinus:
434+
case jpiPlus:
435+
case jpiFilter:
370436
read_int32(v->arg, base, pos);
371437
break;
372438
case jpiIndexArray:
@@ -386,13 +452,11 @@ void
386452
jspGetArg(JsonPathItem *v, JsonPathItem *a)
387453
{
388454
Assert(
389-
v->type == jpiEqual ||
390-
v->type == jpiLess ||
391-
v->type == jpiGreater ||
392-
v->type == jpiLessOrEqual ||
393-
v->type == jpiGreaterOrEqual ||
394-
v->type == jpiExpression ||
395-
v->type == jpiNot
455+
v->type == jpiFilter ||
456+
v->type == jpiNot ||
457+
v->type == jpiIsUnknown ||
458+
v->type == jpiPlus ||
459+
v->type == jpiMinus
396460
);
397461

398462
jspInitByBuffer(a, v->base, v->arg);
@@ -409,6 +473,7 @@ jspGetNext(JsonPathItem *v, JsonPathItem *a)
409473
v->type == jpiAnyArray ||
410474
v->type == jpiAnyKey ||
411475
v->type == jpiIndexArray ||
476+
v->type == jpiFilter ||
412477
v->type == jpiCurrent ||
413478
v->type == jpiRoot
414479
);
@@ -426,7 +491,18 @@ jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
426491
{
427492
Assert(
428493
v->type == jpiAnd ||
429-
v->type == jpiOr
494+
v->type == jpiOr ||
495+
v->type == jpiEqual ||
496+
v->type == jpiNotEqual ||
497+
v->type == jpiLess ||
498+
v->type == jpiGreater ||
499+
v->type == jpiLessOrEqual ||
500+
v->type == jpiGreaterOrEqual ||
501+
v->type == jpiAdd ||
502+
v->type == jpiSub ||
503+
v->type == jpiMul ||
504+
v->type == jpiDiv ||
505+
v->type == jpiMod
430506
);
431507

432508
jspInitByBuffer(a, v->base, v->args.left);
@@ -437,7 +513,18 @@ jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
437513
{
438514
Assert(
439515
v->type == jpiAnd ||
440-
v->type == jpiOr
516+
v->type == jpiOr ||
517+
v->type == jpiEqual ||
518+
v->type == jpiNotEqual ||
519+
v->type == jpiLess ||
520+
v->type == jpiGreater ||
521+
v->type == jpiLessOrEqual ||
522+
v->type == jpiGreaterOrEqual ||
523+
v->type == jpiAdd ||
524+
v->type == jpiSub ||
525+
v->type == jpiMul ||
526+
v->type == jpiDiv ||
527+
v->type == jpiMod
441528
);
442529

443530
jspInitByBuffer(a, v->base, v->args.right);

0 commit comments

Comments
 (0)