@@ -382,6 +382,84 @@ executeExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)
382
382
return jperNotFound ;
383
383
}
384
384
385
+ static JsonPathExecResult
386
+ executeArithmExpr (JsonPathExecContext * cxt , JsonPathItem * jsp , JsonbValue * jb ,
387
+ List * * found )
388
+ {
389
+ JsonPathExecResult jper ;
390
+ JsonPathItem elem ;
391
+ List * lseq = NIL ;
392
+ List * rseq = NIL ;
393
+ JsonbValue * lval ;
394
+ JsonbValue * rval ;
395
+ JsonbValue lvalbuf ;
396
+ JsonbValue rvalbuf ;
397
+ Datum ldatum ;
398
+ Datum rdatum ;
399
+ Datum res ;
400
+
401
+ jspGetLeftArg (jsp , & elem );
402
+ jper = recursiveExecute (cxt , & elem , jb , & lseq );
403
+ if (jper == jperOk )
404
+ {
405
+ jspGetRightArg (jsp , & elem );
406
+ jper = recursiveExecute (cxt , & elem , jb , & rseq );
407
+ }
408
+
409
+ if (jper != jperOk || list_length (lseq ) != 1 || list_length (rseq ) != 1 )
410
+ return jperError ; /* ERRCODE_SINGLETON_JSON_ITEM_REQUIRED; */
411
+
412
+ lval = linitial (lseq );
413
+ rval = linitial (rseq );
414
+
415
+ if (JsonbType (lval ) == jbvScalar )
416
+ lval = JsonbExtractScalar (lval -> val .binary .data , & lvalbuf );
417
+
418
+ if (lval -> type != jbvNumeric )
419
+ return jperError ; /* ERRCODE_SINGLETON_JSON_ITEM_REQUIRED; */
420
+
421
+ if (JsonbType (rval ) == jbvScalar )
422
+ rval = JsonbExtractScalar (rval -> val .binary .data , & rvalbuf );
423
+
424
+ if (rval -> type != jbvNumeric )
425
+ return jperError ; /* ERRCODE_SINGLETON_JSON_ITEM_REQUIRED; */
426
+
427
+ if (!found )
428
+ return jperOk ;
429
+
430
+ ldatum = NumericGetDatum (lval -> val .numeric );
431
+ rdatum = NumericGetDatum (rval -> val .numeric );
432
+
433
+ switch (jsp -> type )
434
+ {
435
+ case jpiAdd :
436
+ res = DirectFunctionCall2 (numeric_add , ldatum , rdatum );
437
+ break ;
438
+ case jpiSub :
439
+ res = DirectFunctionCall2 (numeric_sub , ldatum , rdatum );
440
+ break ;
441
+ case jpiMul :
442
+ res = DirectFunctionCall2 (numeric_mul , ldatum , rdatum );
443
+ break ;
444
+ case jpiDiv :
445
+ res = DirectFunctionCall2 (numeric_div , ldatum , rdatum );
446
+ break ;
447
+ case jpiMod :
448
+ res = DirectFunctionCall2 (numeric_mod , ldatum , rdatum );
449
+ break ;
450
+ default :
451
+ elog (ERROR , "unknown jsonpath arithmetic operation %d" , jsp -> type );
452
+ }
453
+
454
+ lval = palloc (sizeof (* lval ));
455
+ lval -> type = jbvNumeric ;
456
+ lval -> val .numeric = DatumGetNumeric (res );
457
+
458
+ * found = lappend (* found , lval );
459
+
460
+ return jperOk ;
461
+ }
462
+
385
463
static JsonbValue *
386
464
copyJsonbValue (JsonbValue * src )
387
465
{
@@ -688,6 +766,13 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
688
766
case jpiGreaterOrEqual :
689
767
res = executeExpr (cxt , jsp , jb );
690
768
break ;
769
+ case jpiAdd :
770
+ case jpiSub :
771
+ case jpiMul :
772
+ case jpiDiv :
773
+ case jpiMod :
774
+ res = executeArithmExpr (cxt , jsp , jb , found );
775
+ break ;
691
776
case jpiRoot :
692
777
if (jspGetNext (jsp , & elem ))
693
778
{
0 commit comments