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

Commit 1073039

Browse files
author
Nikita Glukhov
committed
Add jsonpath support for JsonbValue objects and arrays
1 parent c07afbe commit 1073039

File tree

1 file changed

+109
-40
lines changed

1 file changed

+109
-40
lines changed

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 109 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -526,9 +526,6 @@ checkEquality(JsonbValue *jb1, JsonbValue *jb2, bool not)
526526
return jperError;
527527
}
528528

529-
if (jb1->type == jbvBinary)
530-
return jperError;
531-
532529
switch (jb1->type)
533530
{
534531
case jbvNull:
@@ -560,8 +557,14 @@ checkEquality(JsonbValue *jb1, JsonbValue *jb2, bool not)
560557

561558
break;
562559
}
560+
561+
case jbvBinary:
562+
case jbvObject:
563+
case jbvArray:
564+
return jperError;
565+
563566
default:
564-
elog(ERROR,"1Wrong state");
567+
elog(ERROR, "Unknown jsonb value type %d", jb1->type);
565568
}
566569

567570
return (not ^ eq) ? jperOk : jperNotFound;
@@ -1284,6 +1287,10 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
12841287
if (JsonbType(jb) == jbvObject)
12851288
{
12861289
JsonbValue *v, key;
1290+
JsonbValue obj;
1291+
1292+
if (jb->type == jbvObject)
1293+
jb = JsonbWrapInBinary(jb, &obj);
12871294

12881295
key.type = jbvString;
12891296
key.val.string.val = jspGetString(jsp, &key.val.string.len);
@@ -1339,18 +1346,16 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
13391346
case jpiAnyArray:
13401347
if (JsonbType(jb) == jbvArray)
13411348
{
1342-
JsonbIterator *it;
1343-
int32 r;
1344-
JsonbValue v;
1345-
13461349
hasNext = jspGetNext(jsp, &elem);
1347-
it = JsonbIteratorInit(jb->val.binary.data);
13481350

1349-
while((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
1351+
if (jb->type == jbvArray)
13501352
{
1351-
if (r == WJB_ELEM)
1353+
JsonbValue *el = jb->val.array.elems;
1354+
JsonbValue *last_el = el + jb->val.array.nElems;
1355+
1356+
for (; el < last_el; el++)
13521357
{
1353-
res = recursiveExecuteNext(cxt, jsp, &elem, &v, found, true);
1358+
res = recursiveExecuteNext(cxt, jsp, &elem, el, found, true);
13541359

13551360
if (jperIsError(res))
13561361
break;
@@ -1359,6 +1364,28 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
13591364
break;
13601365
}
13611366
}
1367+
else
1368+
{
1369+
JsonbValue v;
1370+
JsonbIterator *it;
1371+
JsonbIteratorToken r;
1372+
1373+
it = JsonbIteratorInit(jb->val.binary.data);
1374+
1375+
while((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
1376+
{
1377+
if (r == WJB_ELEM)
1378+
{
1379+
res = recursiveExecuteNext(cxt, jsp, &elem, &v, found, true);
1380+
1381+
if (jperIsError(res))
1382+
break;
1383+
1384+
if (res == jperOk && !found)
1385+
break;
1386+
}
1387+
}
1388+
}
13621389
}
13631390
else
13641391
res = jperMakeError(ERRCODE_JSON_ARRAY_NOT_FOUND);
@@ -1370,6 +1397,7 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
13701397
int innermostArraySize = cxt->innermostArraySize;
13711398
int i;
13721399
int size = JsonbArraySize(jb);
1400+
bool binary = jb->type == jbvBinary;
13731401

13741402
cxt->innermostArraySize = size; /* for LAST evaluation */
13751403

@@ -1418,14 +1446,16 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
14181446

14191447
for (index = index_from; index <= index_to; index++)
14201448
{
1421-
JsonbValue *v =
1449+
JsonbValue *v = binary ?
14221450
getIthJsonbValueFromContainer(jb->val.binary.data,
1423-
(uint32) index);
1451+
(uint32) index) :
1452+
&jb->val.array.elems[index];
14241453

14251454
if (v == NULL)
14261455
continue;
14271456

1428-
res = recursiveExecuteNext(cxt, jsp, &elem, v, found, false);
1457+
res = recursiveExecuteNext(cxt, jsp, &elem, v, found,
1458+
!binary);
14291459

14301460
if (jperIsError(res))
14311461
break;
@@ -1483,6 +1513,10 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
14831513
JsonbIterator *it;
14841514
int32 r;
14851515
JsonbValue v;
1516+
JsonbValue bin;
1517+
1518+
if (jb->type == jbvObject)
1519+
jb = JsonbWrapInBinary(jb, &bin);
14861520

14871521
hasNext = jspGetNext(jsp, &elem);
14881522
it = JsonbIteratorInit(jb->val.binary.data);
@@ -1535,25 +1569,30 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
15351569
res = recursiveExecuteNext(cxt, jsp, NULL, jb, found, true);
15361570
break;
15371571
case jpiAny:
1538-
{
1539-
bool hasNext = jspGetNext(jsp, &elem);
1540-
1541-
/* first try without any intermediate steps */
1542-
if (jsp->content.anybounds.first == 0)
15431572
{
1544-
res = recursiveExecuteNext(cxt, jsp, &elem, jb, found, true);
1573+
JsonbValue jbvbuf;
15451574

1546-
if (res == jperOk && !found)
1547-
break;
1548-
}
1575+
hasNext = jspGetNext(jsp, &elem);
15491576

1550-
if (jb->type == jbvBinary)
1551-
res = recursiveAny(cxt, hasNext ? &elem : NULL, jb, found,
1552-
1,
1553-
jsp->content.anybounds.first,
1554-
jsp->content.anybounds.last);
1555-
break;
1556-
}
1577+
/* first try without any intermediate steps */
1578+
if (jsp->content.anybounds.first == 0)
1579+
{
1580+
res = recursiveExecuteNext(cxt, jsp, &elem, jb, found, true);
1581+
1582+
if (res == jperOk && !found)
1583+
break;
1584+
}
1585+
1586+
if (jb->type == jbvArray || jb->type == jbvObject)
1587+
jb = JsonbWrapInBinary(jb, &jbvbuf);
1588+
1589+
if (jb->type == jbvBinary)
1590+
res = recursiveAny(cxt, hasNext ? &elem : NULL, jb, found,
1591+
1,
1592+
jsp->content.anybounds.first,
1593+
jsp->content.anybounds.last);
1594+
break;
1595+
}
15571596
case jpiExists:
15581597
jspGetArg(jsp, &elem);
15591598

@@ -1829,6 +1868,7 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
18291868
else
18301869
{
18311870
int32 r;
1871+
JsonbValue bin;
18321872
JsonbValue key;
18331873
JsonbValue val;
18341874
JsonbValue obj;
@@ -1839,7 +1879,9 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
18391879

18401880
hasNext = jspGetNext(jsp, &elem);
18411881

1842-
if (!JsonContainerSize(jb->val.binary.data))
1882+
if (jb->type == jbvBinary
1883+
? !JsonContainerSize(jb->val.binary.data)
1884+
: !jb->val.object.nPairs)
18431885
{
18441886
res = jperNotFound;
18451887
break;
@@ -1856,6 +1898,9 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
18561898
valstr.val.string.val = "value";
18571899
valstr.val.string.len = 5;
18581900

1901+
if (jb->type == jbvObject)
1902+
jb = JsonbWrapInBinary(jb, &bin);
1903+
18591904
it = JsonbIteratorInit(jb->val.binary.data);
18601905

18611906
while ((r = JsonbIteratorNext(&it, &key, true)) != WJB_DONE)
@@ -1918,24 +1963,43 @@ recursiveExecuteUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
19181963
{
19191964
if (cxt->lax && JsonbType(jb) == jbvArray)
19201965
{
1921-
JsonbValue v;
1922-
JsonbIterator *it;
1923-
JsonbIteratorToken tok;
19241966
JsonPathExecResult res = jperNotFound;
19251967

1926-
it = JsonbIteratorInit(jb->val.binary.data);
1927-
1928-
while ((tok = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
1968+
if (jb->type == jbvArray)
19291969
{
1930-
if (tok == WJB_ELEM)
1970+
JsonbValue *elem = jb->val.array.elems;
1971+
JsonbValue *last = elem + jb->val.array.nElems;
1972+
1973+
for (; elem < last; elem++)
19311974
{
1932-
res = recursiveExecuteNoUnwrap(cxt, jsp, &v, found);
1975+
res = recursiveExecuteNoUnwrap(cxt, jsp, elem, found);
1976+
19331977
if (jperIsError(res))
19341978
break;
19351979
if (res == jperOk && !found)
19361980
break;
19371981
}
19381982
}
1983+
else
1984+
{
1985+
JsonbValue v;
1986+
JsonbIterator *it;
1987+
JsonbIteratorToken tok;
1988+
1989+
it = JsonbIteratorInit(jb->val.binary.data);
1990+
1991+
while ((tok = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
1992+
{
1993+
if (tok == WJB_ELEM)
1994+
{
1995+
res = recursiveExecuteNoUnwrap(cxt, jsp, &v, found);
1996+
if (jperIsError(res))
1997+
break;
1998+
if (res == jperOk && !found)
1999+
break;
2000+
}
2001+
}
2002+
}
19392003

19402004
return res;
19412005
}
@@ -2305,10 +2369,15 @@ wrapItemsInArray(const JsonValueList *items)
23052369

23062370
while ((jbv = JsonValueListNext(items, &it)))
23072371
{
2372+
JsonbValue bin;
2373+
23082374
if (jbv->type == jbvBinary &&
23092375
JsonContainerIsScalar(jbv->val.binary.data))
23102376
JsonbExtractScalar(jbv->val.binary.data, jbv);
23112377

2378+
if (jbv->type == jbvObject || jbv->type == jbvArray)
2379+
jbv = JsonbWrapInBinary(jbv, &bin);
2380+
23122381
pushJsonbValue(&ps, WJB_ELEM, jbv);
23132382
}
23142383

0 commit comments

Comments
 (0)