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

Commit 28fc9ac

Browse files
feodorNikita Glukhov
authored and
Nikita Glukhov
committed
correct work of unnary plus/minus
1 parent fabe0d6 commit 28fc9ac

File tree

5 files changed

+115
-21
lines changed

5 files changed

+115
-21
lines changed

src/backend/utils/adt/jsonpath.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item,
9292
case jpiFilter:
9393
case jpiIsUnknown:
9494
case jpiNot:
95-
case jpiPlus:
9695
case jpiMinus:
9796
case jpiExists:
9897
{
@@ -477,7 +476,6 @@ jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
477476
case jpiExists:
478477
case jpiIsUnknown:
479478
case jpiMinus:
480-
case jpiPlus:
481479
case jpiFilter:
482480
read_int32(v->arg, base, pos);
483481
break;
@@ -502,7 +500,6 @@ jspGetArg(JsonPathItem *v, JsonPathItem *a)
502500
v->type == jpiNot ||
503501
v->type == jpiIsUnknown ||
504502
v->type == jpiExists ||
505-
v->type == jpiPlus ||
506503
v->type == jpiMinus
507504
);
508505

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -398,40 +398,61 @@ executeArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
398398
Datum rdatum;
399399
Datum res;
400400

401-
jspGetLeftArg(jsp, &elem);
401+
if (jsp->type == jpiMinus)
402+
jspGetArg(jsp, &elem);
403+
else
404+
jspGetLeftArg(jsp, &elem);
405+
402406
jper = recursiveExecute(cxt, &elem, jb, &lseq);
403-
if (jper == jperOk)
407+
408+
if (jper == jperOk && jsp->type != jpiMinus)
404409
{
405410
jspGetRightArg(jsp, &elem);
406411
jper = recursiveExecute(cxt, &elem, jb, &rseq);
407412
}
408413

409-
if (jper != jperOk || list_length(lseq) != 1 || list_length(rseq) != 1)
410-
return jperError; /* ERRCODE_SINGLETON_JSON_ITEM_REQUIRED; */
414+
if (jsp->type == jpiMinus)
415+
{
416+
if (jper != jperOk || list_length(lseq) != 1)
417+
return jperError; /* ERRCODE_SINGLETON_JSON_ITEM_REQUIRED; */
418+
}
419+
else
420+
{
421+
if (jper != jperOk || list_length(lseq) != 1 || list_length(rseq) != 1)
422+
return jperError; /* ERRCODE_SINGLETON_JSON_ITEM_REQUIRED; */
423+
}
411424

412425
lval = linitial(lseq);
413-
rval = linitial(rseq);
414426

415427
if (JsonbType(lval) == jbvScalar)
416428
lval = JsonbExtractScalar(lval->val.binary.data, &lvalbuf);
417429

418430
if (lval->type != jbvNumeric)
419431
return jperError; /* ERRCODE_SINGLETON_JSON_ITEM_REQUIRED; */
420432

421-
if (JsonbType(rval) == jbvScalar)
422-
rval = JsonbExtractScalar(rval->val.binary.data, &rvalbuf);
433+
if (jsp->type != jpiMinus)
434+
{
435+
rval = linitial(rseq);
423436

424-
if (rval->type != jbvNumeric)
425-
return jperError; /* ERRCODE_SINGLETON_JSON_ITEM_REQUIRED; */
437+
if (JsonbType(rval) == jbvScalar)
438+
rval = JsonbExtractScalar(rval->val.binary.data, &rvalbuf);
439+
440+
if (rval->type != jbvNumeric)
441+
return jperError; /* ERRCODE_SINGLETON_JSON_ITEM_REQUIRED; */
442+
}
426443

427444
if (!found)
428445
return jperOk;
429446

430447
ldatum = NumericGetDatum(lval->val.numeric);
431-
rdatum = NumericGetDatum(rval->val.numeric);
448+
if (jsp->type != jpiMinus)
449+
rdatum = NumericGetDatum(rval->val.numeric);
432450

433451
switch (jsp->type)
434452
{
453+
case jpiMinus:
454+
res = DirectFunctionCall1(numeric_uminus, ldatum);
455+
break;
435456
case jpiAdd:
436457
res = DirectFunctionCall2(numeric_add, ldatum, rdatum);
437458
break;
@@ -771,6 +792,7 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
771792
case jpiMul:
772793
case jpiDiv:
773794
case jpiMod:
795+
case jpiMinus:
774796
res = executeArithmExpr(cxt, jsp, jb, found);
775797
break;
776798
case jpiRoot:

src/backend/utils/adt/jsonpath_gram.y

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ makeAny(int first, int last)
214214
%token <str> ANY_P
215215

216216
%type <value> result jsonpath scalar_value path_primary expr pexpr
217-
array_accessor any_path accessor_op key unary_expr
217+
array_accessor any_path accessor_op key
218218
predicate delimited_predicate
219219

220220
%type <elems> accessor_expr /* path absolute_path relative_path */
@@ -228,6 +228,7 @@ makeAny(int first, int last)
228228
%right NOT_P
229229
%left '+' '-'
230230
%left '*' '/' '%'
231+
%left UMINUS
231232
%nonassoc '(' ')'
232233

233234
/* Grammar follows */
@@ -292,19 +293,15 @@ accessor_expr:
292293
| accessor_expr accessor_op { $$ = lappend($1, $2); }
293294
;
294295

295-
unary_expr:
296-
accessor_expr { $$ = makeItemList($1); }
297-
| '+' unary_expr { $$ = makeItemUnary(jpiPlus, $2); }
298-
| '-' unary_expr { $$ = makeItemUnary(jpiMinus, $2); }
299-
;
300-
301296
pexpr:
302297
expr { $$ = $1; }
303298
| '(' expr ')' { $$ = $2; }
304299
;
305300

306301
expr:
307-
unary_expr { $$ = $1; }
302+
accessor_expr { $$ = makeItemList($1); }
303+
| '+' pexpr %prec UMINUS { $$ = $2; }
304+
| '-' pexpr %prec UMINUS { $$ = makeItemUnary(jpiMinus, $2); }
308305
| pexpr '+' pexpr { $$ = makeItemBinary(jpiAdd, $1, $3); }
309306
| pexpr '-' pexpr { $$ = makeItemBinary(jpiSub, $1, $3); }
310307
| pexpr '*' pexpr { $$ = makeItemBinary(jpiMul, $1, $3); }

src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,3 +552,69 @@ select _jsonpath_exists(jsonb '{"c": {"a": 1, "b":1}}', '$.** ? (.a == .b)');
552552
t
553553
(1 row)
554554

555+
select _jsonpath_query(jsonb '{"c": {"a": 2, "b":1}}', '$.** ? (.a == 1 + 1)');
556+
_jsonpath_query
557+
------------------
558+
{"a": 2, "b": 1}
559+
(1 row)
560+
561+
select _jsonpath_query(jsonb '{"c": {"a": 2, "b":1}}', '$.** ? (.a == (1 + 1))');
562+
_jsonpath_query
563+
------------------
564+
{"a": 2, "b": 1}
565+
(1 row)
566+
567+
select _jsonpath_query(jsonb '{"c": {"a": 2, "b":1}}', '$.** ? (.a == .b + 1)');
568+
_jsonpath_query
569+
------------------
570+
{"a": 2, "b": 1}
571+
(1 row)
572+
573+
select _jsonpath_query(jsonb '{"c": {"a": 2, "b":1}}', '$.** ? (.a == (.b + 1))');
574+
_jsonpath_query
575+
------------------
576+
{"a": 2, "b": 1}
577+
(1 row)
578+
579+
select _jsonpath_exists(jsonb '{"c": {"a": -1, "b":1}}', '$.** ? (.a == - 1)');
580+
_jsonpath_exists
581+
------------------
582+
t
583+
(1 row)
584+
585+
select _jsonpath_exists(jsonb '{"c": {"a": -1, "b":1}}', '$.** ? (.a == -1)');
586+
_jsonpath_exists
587+
------------------
588+
t
589+
(1 row)
590+
591+
select _jsonpath_exists(jsonb '{"c": {"a": -1, "b":1}}', '$.** ? (.a == -.b)');
592+
_jsonpath_exists
593+
------------------
594+
t
595+
(1 row)
596+
597+
select _jsonpath_exists(jsonb '{"c": {"a": -1, "b":1}}', '$.** ? (.a == - .b)');
598+
_jsonpath_exists
599+
------------------
600+
t
601+
(1 row)
602+
603+
select _jsonpath_exists(jsonb '{"c": {"a": 0, "b":1}}', '$.** ? (.a == 1 - .b)');
604+
_jsonpath_exists
605+
------------------
606+
t
607+
(1 row)
608+
609+
select _jsonpath_exists(jsonb '{"c": {"a": 2, "b":1}}', '$.** ? (.a == 1 - - .b)');
610+
_jsonpath_exists
611+
------------------
612+
t
613+
(1 row)
614+
615+
select _jsonpath_exists(jsonb '{"c": {"a": 0, "b":1}}', '$.** ? (.a == 1 - +.b)');
616+
_jsonpath_exists
617+
------------------
618+
t
619+
(1 row)
620+

src/test/regress/sql/jsonb_jsonpath.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,15 @@ select _jsonpath_exists(jsonb '{"c": {"a": 1, "b":1}}', '$.c ? (.a == .b)');
116116
select _jsonpath_exists(jsonb '{"c": {"a": 1, "b":1}}', '$.* ? (.a == .b)');
117117
select _jsonpath_exists(jsonb '{"a": 1, "b":1}', '$.** ? (.a == .b)');
118118
select _jsonpath_exists(jsonb '{"c": {"a": 1, "b":1}}', '$.** ? (.a == .b)');
119+
120+
select _jsonpath_query(jsonb '{"c": {"a": 2, "b":1}}', '$.** ? (.a == 1 + 1)');
121+
select _jsonpath_query(jsonb '{"c": {"a": 2, "b":1}}', '$.** ? (.a == (1 + 1))');
122+
select _jsonpath_query(jsonb '{"c": {"a": 2, "b":1}}', '$.** ? (.a == .b + 1)');
123+
select _jsonpath_query(jsonb '{"c": {"a": 2, "b":1}}', '$.** ? (.a == (.b + 1))');
124+
select _jsonpath_exists(jsonb '{"c": {"a": -1, "b":1}}', '$.** ? (.a == - 1)');
125+
select _jsonpath_exists(jsonb '{"c": {"a": -1, "b":1}}', '$.** ? (.a == -1)');
126+
select _jsonpath_exists(jsonb '{"c": {"a": -1, "b":1}}', '$.** ? (.a == -.b)');
127+
select _jsonpath_exists(jsonb '{"c": {"a": -1, "b":1}}', '$.** ? (.a == - .b)');
128+
select _jsonpath_exists(jsonb '{"c": {"a": 0, "b":1}}', '$.** ? (.a == 1 - .b)');
129+
select _jsonpath_exists(jsonb '{"c": {"a": 2, "b":1}}', '$.** ? (.a == 1 - - .b)');
130+
select _jsonpath_exists(jsonb '{"c": {"a": 0, "b":1}}', '$.** ? (.a == 1 - +.b)');

0 commit comments

Comments
 (0)