@@ -328,6 +328,7 @@ copyJsonPathItem(JsonPathContext *cxt, JsonPathItem *item, int level,
328
328
case jpiKey :
329
329
case jpiString :
330
330
case jpiVariable :
331
+ case jpiArgument :
331
332
{
332
333
int32 len ;
333
334
char * data = jspGetString (item , & len );
@@ -542,6 +543,39 @@ copyJsonPathItem(JsonPathContext *cxt, JsonPathItem *item, int level,
542
543
}
543
544
break ;
544
545
546
+ case jpiLambda :
547
+ {
548
+ JsonPathItem arg ;
549
+ int32 nparams = item -> content .lambda .nparams ;
550
+ int offset ;
551
+ int32 elempos ;
552
+ int32 i ;
553
+
554
+ /* assign cache id */
555
+ appendBinaryStringInfo (buf , (const char * ) & cxt -> id , sizeof (cxt -> id ));
556
+ ++ cxt -> id ;
557
+
558
+ appendBinaryStringInfo (buf , (char * ) & nparams , sizeof (nparams ));
559
+ offset = buf -> len ;
560
+
561
+ appendStringInfoSpaces (buf , sizeof (int32 ) * (nparams + 1 ));
562
+
563
+ for (i = 0 ; i < nparams ; i ++ )
564
+ {
565
+ jspGetLambdaParam (item , i , & arg );
566
+ elempos = copyJsonPathItem (cxt , & arg , level , NULL , NULL );
567
+ * (int32 * ) & buf -> data [offset ] = elempos - pos ;
568
+ offset += sizeof (int32 );
569
+ }
570
+
571
+ jspGetLambdaExpr (item , & arg );
572
+ elempos = copyJsonPathItem (cxt , & arg , level , NULL , NULL );
573
+
574
+ * (int32 * ) & buf -> data [offset ] = elempos - pos ;
575
+ offset += sizeof (int32 );
576
+ }
577
+ break ;
578
+
545
579
default :
546
580
elog (ERROR , "Unknown jsonpath item type: %d" , item -> type );
547
581
}
@@ -608,6 +642,7 @@ flattenJsonPathParseItem(JsonPathContext *cxt, JsonPathParseItem *item,
608
642
case jpiString :
609
643
case jpiVariable :
610
644
case jpiKey :
645
+ case jpiArgument :
611
646
appendBinaryStringInfo (buf , (char * ) & item -> value .string .len ,
612
647
sizeof (item -> value .string .len ));
613
648
appendBinaryStringInfo (buf , item -> value .string .val ,
@@ -701,6 +736,38 @@ flattenJsonPathParseItem(JsonPathContext *cxt, JsonPathParseItem *item,
701
736
* (int32 * ) (buf -> data + arg ) = chld - pos ;
702
737
}
703
738
break ;
739
+ case jpiLambda :
740
+ {
741
+ int32 nelems = list_length (item -> value .lambda .params );
742
+ ListCell * lc ;
743
+ int offset ;
744
+ int32 elempos ;
745
+
746
+ /* assign cache id */
747
+ appendBinaryStringInfo (buf , (const char * ) & cxt -> id , sizeof (cxt -> id ));
748
+ ++ cxt -> id ;
749
+
750
+ appendBinaryStringInfo (buf , (char * ) & nelems , sizeof (nelems ));
751
+ offset = buf -> len ;
752
+
753
+ appendStringInfoSpaces (buf , sizeof (int32 ) * (nelems + 1 ));
754
+
755
+ foreach (lc , item -> value .lambda .params )
756
+ {
757
+ elempos = flattenJsonPathParseItem (cxt , lfirst (lc ),
758
+ nestingLevel ,
759
+ insideArraySubscript );
760
+ * (int32 * ) & buf -> data [offset ] = elempos - pos ;
761
+ offset += sizeof (int32 );
762
+ }
763
+
764
+ elempos = flattenJsonPathParseItem (cxt , item -> value .lambda .expr ,
765
+ nestingLevel ,
766
+ insideArraySubscript );
767
+ * (int32 * ) & buf -> data [offset ] = elempos - pos ;
768
+ offset += sizeof (int32 );
769
+ }
770
+ break ;
704
771
case jpiNull :
705
772
break ;
706
773
case jpiRoot :
@@ -917,6 +984,9 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
917
984
appendStringInfoChar (buf , '$' );
918
985
escape_json (buf , jspGetString (v , NULL ));
919
986
break ;
987
+ case jpiArgument :
988
+ appendStringInfoString (buf , jspGetString (v , NULL ));
989
+ break ;
920
990
case jpiNumeric :
921
991
appendStringInfoString (buf ,
922
992
DatumGetCString (DirectFunctionCall1 (numeric_out ,
@@ -1183,6 +1253,31 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
1183
1253
1184
1254
appendStringInfoChar (buf , '}' );
1185
1255
break ;
1256
+ case jpiLambda :
1257
+ if (printBracketes || jspHasNext (v ))
1258
+ appendStringInfoChar (buf , '(' );
1259
+
1260
+ appendStringInfoChar (buf , '(' );
1261
+
1262
+ for (i = 0 ; i < v -> content .lambda .nparams ; i ++ )
1263
+ {
1264
+ JsonPathItem elem ;
1265
+
1266
+ if (i )
1267
+ appendBinaryStringInfo (buf , ", " , 2 );
1268
+
1269
+ jspGetLambdaParam (v , i , & elem );
1270
+ printJsonPathItem (buf , & elem , false, false);
1271
+ }
1272
+
1273
+ appendStringInfoString (buf , ") => " );
1274
+
1275
+ jspGetLambdaExpr (v , & elem );
1276
+ printJsonPathItem (buf , & elem , false, false);
1277
+
1278
+ if (printBracketes || jspHasNext (v ))
1279
+ appendStringInfoChar (buf , ')' );
1280
+ break ;
1186
1281
default :
1187
1282
elog (ERROR , "unrecognized jsonpath item type: %d" , v -> type );
1188
1283
}
@@ -1350,6 +1445,7 @@ jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
1350
1445
case jpiKey :
1351
1446
case jpiString :
1352
1447
case jpiVariable :
1448
+ case jpiArgument :
1353
1449
read_int32 (v -> content .value .datalen , base , pos );
1354
1450
/* FALLTHROUGH */
1355
1451
case jpiNumeric :
@@ -1380,6 +1476,13 @@ jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
1380
1476
read_int32 (v -> content .like_regex .patternlen , base , pos );
1381
1477
v -> content .like_regex .pattern = base + pos ;
1382
1478
break ;
1479
+ case jpiLambda :
1480
+ read_int32 (v -> content .lambda .id , base , pos );
1481
+ read_int32 (v -> content .lambda .nparams , base , pos );
1482
+ read_int32_n (v -> content .lambda .params , base , pos ,
1483
+ v -> content .lambda .nparams );
1484
+ read_int32 (v -> content .lambda .expr , base , pos );
1485
+ break ;
1383
1486
case jpiNot :
1384
1487
case jpiExists :
1385
1488
case jpiIsUnknown :
@@ -1476,7 +1579,9 @@ jspGetNext(JsonPathItem *v, JsonPathItem *a)
1476
1579
v -> type == jpiStartsWith ||
1477
1580
v -> type == jpiSequence ||
1478
1581
v -> type == jpiArray ||
1479
- v -> type == jpiObject );
1582
+ v -> type == jpiObject ||
1583
+ v -> type == jpiLambda ||
1584
+ v -> type == jpiArgument );
1480
1585
1481
1586
if (a )
1482
1587
jspInitByBuffer (a , v -> base , v -> nextPos );
@@ -1551,7 +1656,8 @@ jspGetString(JsonPathItem *v, int32 *len)
1551
1656
{
1552
1657
Assert (v -> type == jpiKey ||
1553
1658
v -> type == jpiString ||
1554
- v -> type == jpiVariable );
1659
+ v -> type == jpiVariable ||
1660
+ v -> type == jpiArgument );
1555
1661
1556
1662
if (len )
1557
1663
* len = v -> content .value .datalen ;
@@ -1590,6 +1696,27 @@ jspGetObjectField(JsonPathItem *v, int i, JsonPathItem *key, JsonPathItem *val)
1590
1696
jspInitByBuffer (val , v -> base , v -> content .object .fields [i ].val );
1591
1697
}
1592
1698
1699
+ JsonPathItem *
1700
+ jspGetLambdaParam (JsonPathItem * lambda , int index , JsonPathItem * arg )
1701
+ {
1702
+ Assert (lambda -> type == jpiLambda );
1703
+ Assert (index < lambda -> content .lambda .nparams );
1704
+
1705
+ jspInitByBuffer (arg , lambda -> base , lambda -> content .lambda .params [index ]);
1706
+
1707
+ return arg ;
1708
+ }
1709
+
1710
+ JsonPathItem *
1711
+ jspGetLambdaExpr (JsonPathItem * lambda , JsonPathItem * expr )
1712
+ {
1713
+ Assert (lambda -> type == jpiLambda );
1714
+
1715
+ jspInitByBuffer (expr , lambda -> base , lambda -> content .lambda .expr );
1716
+
1717
+ return expr ;
1718
+ }
1719
+
1593
1720
static void
1594
1721
checkJsonPathArgsMismatch (JsonPath * jp1 , JsonPath * jp2 )
1595
1722
{
0 commit comments