@@ -43,6 +43,9 @@ static inline JsonPathExecResult recursiveExecute(JsonPathExecContext *cxt,
43
43
JsonPathItem * jsp , JsonbValue * jb ,
44
44
JsonValueList * found );
45
45
46
+ static inline JsonPathExecResult recursiveExecuteBool (JsonPathExecContext * cxt ,
47
+ JsonPathItem * jsp , JsonbValue * jb );
48
+
46
49
static inline JsonPathExecResult recursiveExecuteUnwrap (JsonPathExecContext * cxt ,
47
50
JsonPathItem * jsp , JsonbValue * jb , JsonValueList * found );
48
51
@@ -1211,6 +1214,34 @@ tryToParseDatetime(const char *template, text *datetime,
1211
1214
return ok ;
1212
1215
}
1213
1216
1217
+ static inline JsonPathExecResult
1218
+ appendBoolResult (JsonPathExecContext * cxt , JsonPathItem * jsp ,
1219
+ JsonValueList * found , JsonPathExecResult res , bool needBool )
1220
+ {
1221
+ JsonPathItem next ;
1222
+ JsonbValue jbv ;
1223
+ bool hasNext = jspGetNext (jsp , & next );
1224
+
1225
+ if (needBool )
1226
+ {
1227
+ Assert (!hasNext );
1228
+ return res ;
1229
+ }
1230
+
1231
+ if (!found && !hasNext )
1232
+ return jperOk ; /* found singleton boolean value */
1233
+
1234
+ if (jperIsError (res ))
1235
+ jbv .type = jbvNull ;
1236
+ else
1237
+ {
1238
+ jbv .type = jbvBool ;
1239
+ jbv .val .boolean = res == jperOk ;
1240
+ }
1241
+
1242
+ return recursiveExecuteNext (cxt , jsp , & next , & jbv , found , true);
1243
+ }
1244
+
1214
1245
/*
1215
1246
* Main executor function: walks on jsonpath structure and tries to find
1216
1247
* correspoding parts of jsonb. Note, jsonb and jsonpath values should be
@@ -1223,7 +1254,7 @@ tryToParseDatetime(const char *template, text *datetime,
1223
1254
*/
1224
1255
static JsonPathExecResult
1225
1256
recursiveExecuteNoUnwrap (JsonPathExecContext * cxt , JsonPathItem * jsp ,
1226
- JsonbValue * jb , JsonValueList * found )
1257
+ JsonbValue * jb , JsonValueList * found , bool needBool )
1227
1258
{
1228
1259
JsonPathItem elem ;
1229
1260
JsonPathExecResult res = jperNotFound ;
@@ -1235,7 +1266,7 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
1235
1266
switch (jsp -> type ) {
1236
1267
case jpiAnd :
1237
1268
jspGetLeftArg (jsp , & elem );
1238
- res = recursiveExecute (cxt , & elem , jb , NULL );
1269
+ res = recursiveExecuteBool (cxt , & elem , jb );
1239
1270
if (res != jperNotFound )
1240
1271
{
1241
1272
JsonPathExecResult res2 ;
@@ -1246,27 +1277,29 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
1246
1277
*/
1247
1278
1248
1279
jspGetRightArg (jsp , & elem );
1249
- res2 = recursiveExecute (cxt , & elem , jb , NULL );
1280
+ res2 = recursiveExecuteBool (cxt , & elem , jb );
1250
1281
1251
1282
res = (res2 == jperOk ) ? res : res2 ;
1252
1283
}
1284
+ res = appendBoolResult (cxt , jsp , found , res , needBool );
1253
1285
break ;
1254
1286
case jpiOr :
1255
1287
jspGetLeftArg (jsp , & elem );
1256
- res = recursiveExecute (cxt , & elem , jb , NULL );
1288
+ res = recursiveExecuteBool (cxt , & elem , jb );
1257
1289
if (res != jperOk )
1258
1290
{
1259
1291
JsonPathExecResult res2 ;
1260
1292
1261
1293
jspGetRightArg (jsp , & elem );
1262
- res2 = recursiveExecute (cxt , & elem , jb , NULL );
1294
+ res2 = recursiveExecuteBool (cxt , & elem , jb );
1263
1295
1264
1296
res = (res2 == jperNotFound ) ? res : res2 ;
1265
1297
}
1298
+ res = appendBoolResult (cxt , jsp , found , res , needBool );
1266
1299
break ;
1267
1300
case jpiNot :
1268
1301
jspGetArg (jsp , & elem );
1269
- switch ((res = recursiveExecute (cxt , & elem , jb , NULL )))
1302
+ switch ((res = recursiveExecuteBool (cxt , & elem , jb )))
1270
1303
{
1271
1304
case jperOk :
1272
1305
res = jperNotFound ;
@@ -1277,11 +1310,13 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
1277
1310
default :
1278
1311
break ;
1279
1312
}
1313
+ res = appendBoolResult (cxt , jsp , found , res , needBool );
1280
1314
break ;
1281
1315
case jpiIsUnknown :
1282
1316
jspGetArg (jsp , & elem );
1283
- res = recursiveExecute (cxt , & elem , jb , NULL );
1317
+ res = recursiveExecuteBool (cxt , & elem , jb );
1284
1318
res = jperIsError (res ) ? jperOk : jperNotFound ;
1319
+ res = appendBoolResult (cxt , jsp , found , res , needBool );
1285
1320
break ;
1286
1321
case jpiKey :
1287
1322
if (JsonbType (jb ) == jbvObject )
@@ -1548,6 +1583,7 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
1548
1583
case jpiLessOrEqual :
1549
1584
case jpiGreaterOrEqual :
1550
1585
res = executeExpr (cxt , jsp , jb );
1586
+ res = appendBoolResult (cxt , jsp , found , res , needBool );
1551
1587
break ;
1552
1588
case jpiAdd :
1553
1589
case jpiSub :
@@ -1562,7 +1598,7 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
1562
1598
break ;
1563
1599
case jpiFilter :
1564
1600
jspGetArg (jsp , & elem );
1565
- res = recursiveExecute (cxt , & elem , jb , NULL );
1601
+ res = recursiveExecuteBool (cxt , & elem , jb );
1566
1602
if (res != jperOk )
1567
1603
res = jperNotFound ;
1568
1604
else
@@ -1611,6 +1647,8 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
1611
1647
if (!jperIsError (res ))
1612
1648
res = JsonValueListIsEmpty (& vals ) ? jperNotFound : jperOk ;
1613
1649
}
1650
+
1651
+ res = appendBoolResult (cxt , jsp , found , res , needBool );
1614
1652
break ;
1615
1653
case jpiNull :
1616
1654
case jpiBool :
@@ -1946,9 +1984,11 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
1946
1984
break ;
1947
1985
case jpiStartsWith :
1948
1986
res = executeStartsWithPredicate (cxt , jsp , jb );
1987
+ res = appendBoolResult (cxt , jsp , found , res , needBool );
1949
1988
break ;
1950
1989
case jpiLikeRegex :
1951
1990
res = executeLikeRegexPredicate (cxt , jsp , jb );
1991
+ res = appendBoolResult (cxt , jsp , found , res , needBool );
1952
1992
break ;
1953
1993
default :
1954
1994
elog (ERROR , "unrecognized jsonpath item type: %d" , jsp -> type );
@@ -1970,7 +2010,7 @@ recursiveExecuteUnwrapArray(JsonPathExecContext *cxt, JsonPathItem *jsp,
1970
2010
1971
2011
for (; elem < last ; elem ++ )
1972
2012
{
1973
- res = recursiveExecuteNoUnwrap (cxt , jsp , elem , found );
2013
+ res = recursiveExecuteNoUnwrap (cxt , jsp , elem , found , false );
1974
2014
1975
2015
if (jperIsError (res ))
1976
2016
break ;
@@ -1990,7 +2030,7 @@ recursiveExecuteUnwrapArray(JsonPathExecContext *cxt, JsonPathItem *jsp,
1990
2030
{
1991
2031
if (tok == WJB_ELEM )
1992
2032
{
1993
- res = recursiveExecuteNoUnwrap (cxt , jsp , & v , found );
2033
+ res = recursiveExecuteNoUnwrap (cxt , jsp , & v , found , false );
1994
2034
if (jperIsError (res ))
1995
2035
break ;
1996
2036
if (res == jperOk && !found )
@@ -2009,7 +2049,7 @@ recursiveExecuteUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
2009
2049
if (cxt -> lax && JsonbType (jb ) == jbvArray )
2010
2050
return recursiveExecuteUnwrapArray (cxt , jsp , jb , found );
2011
2051
2012
- return recursiveExecuteNoUnwrap (cxt , jsp , jb , found );
2052
+ return recursiveExecuteNoUnwrap (cxt , jsp , jb , found , false );
2013
2053
}
2014
2054
2015
2055
/*
@@ -2085,7 +2125,39 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
2085
2125
}
2086
2126
}
2087
2127
2088
- return recursiveExecuteNoUnwrap (cxt , jsp , jb , found );
2128
+ return recursiveExecuteNoUnwrap (cxt , jsp , jb , found , false);
2129
+ }
2130
+
2131
+ static inline JsonPathExecResult
2132
+ recursiveExecuteBool (JsonPathExecContext * cxt , JsonPathItem * jsp ,
2133
+ JsonbValue * jb )
2134
+ {
2135
+ if (jspHasNext (jsp ))
2136
+ elog (ERROR , "boolean jsonpath item can not have next item" );
2137
+
2138
+ switch (jsp -> type )
2139
+ {
2140
+ case jpiAnd :
2141
+ case jpiOr :
2142
+ case jpiNot :
2143
+ case jpiIsUnknown :
2144
+ case jpiEqual :
2145
+ case jpiNotEqual :
2146
+ case jpiGreater :
2147
+ case jpiGreaterOrEqual :
2148
+ case jpiLess :
2149
+ case jpiLessOrEqual :
2150
+ case jpiExists :
2151
+ case jpiStartsWith :
2152
+ case jpiLikeRegex :
2153
+ break ;
2154
+
2155
+ default :
2156
+ elog (ERROR , "invalid boolean jsonpath item type: %d" , jsp -> type );
2157
+ break ;
2158
+ }
2159
+
2160
+ return recursiveExecuteNoUnwrap (cxt , jsp , jb , NULL , true);
2089
2161
}
2090
2162
2091
2163
/*
0 commit comments