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

Commit 4261dfd

Browse files
author
Nikita Glukhov
committed
Add jsonpath binary arithmetic expression evaluation
1 parent c44f35d commit 4261dfd

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,84 @@ executeExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)
382382
return jperNotFound;
383383
}
384384

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+
385463
static JsonbValue*
386464
copyJsonbValue(JsonbValue *src)
387465
{
@@ -688,6 +766,13 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
688766
case jpiGreaterOrEqual:
689767
res = executeExpr(cxt, jsp, jb);
690768
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;
691776
case jpiRoot:
692777
if (jspGetNext(jsp, &elem))
693778
{

0 commit comments

Comments
 (0)