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

Commit 5cb0ca9

Browse files
author
Nikita Glukhov
committed
Decompose jsonpath strict/lax flag
1 parent 92d88ac commit 5cb0ca9

File tree

1 file changed

+36
-23
lines changed

1 file changed

+36
-23
lines changed

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,18 @@
2626
typedef struct JsonPathExecContext
2727
{
2828
List *vars;
29-
bool lax;
3029
JsonbValue *root; /* for $ evaluation */
3130
int innermostArraySize; /* for LAST array index evaluation */
31+
bool laxMode;
32+
bool ignoreStructuralErrors;
3233
} JsonPathExecContext;
3334

35+
/* strict/lax flags is decomposed into four [un]wrap/error flags */
36+
#define jspStrictAbsenseOfErrors(cxt) (!(cxt)->laxMode)
37+
#define jspAutoUnwrap(cxt) ((cxt)->laxMode)
38+
#define jspAutoWrap(cxt) ((cxt)->laxMode)
39+
#define jspIgnoreStructuralErrors(cxt) ((cxt)->ignoreStructuralErrors)
40+
3441
typedef struct JsonValueListIterator
3542
{
3643
ListCell *lcell;
@@ -724,7 +731,7 @@ static inline JsonPathExecResult
724731
recursiveExecuteAndUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
725732
JsonbValue *jb, JsonValueList *found)
726733
{
727-
if (cxt->lax)
734+
if (jspAutoUnwrap(cxt))
728735
{
729736
JsonValueList seq = { 0 };
730737
JsonValueListIterator it = { 0 };
@@ -816,14 +823,14 @@ executeExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)
816823

817824
if (res == jperOk)
818825
{
819-
if (cxt->lax)
826+
if (!jspStrictAbsenseOfErrors(cxt))
820827
return jperOk;
821828

822829
found = true;
823830
}
824831
else if (res == jperError)
825832
{
826-
if (!cxt->lax)
833+
if (jspStrictAbsenseOfErrors(cxt))
827834
return jperError;
828835

829836
error = true;
@@ -1153,7 +1160,7 @@ executeStartsWithPredicate(JsonPathExecContext *cxt, JsonPathItem *jsp,
11531160

11541161
if (whole->type != jbvString)
11551162
{
1156-
if (!cxt->lax)
1163+
if (jspStrictAbsenseOfErrors(cxt))
11571164
return jperError;
11581165

11591166
error = true;
@@ -1163,7 +1170,7 @@ executeStartsWithPredicate(JsonPathExecContext *cxt, JsonPathItem *jsp,
11631170
initial->val.string.val,
11641171
initial->val.string.len))
11651172
{
1166-
if (cxt->lax)
1173+
if (!jspStrictAbsenseOfErrors(cxt))
11671174
return jperOk;
11681175

11691176
found = true;
@@ -1220,7 +1227,7 @@ executeLikeRegexPredicate(JsonPathExecContext *cxt, JsonPathItem *jsp,
12201227

12211228
if (str->type != jbvString)
12221229
{
1223-
if (!cxt->lax)
1230+
if (jspStrictAbsenseOfErrors(cxt))
12241231
return jperError;
12251232

12261233
error = true;
@@ -1229,7 +1236,7 @@ executeLikeRegexPredicate(JsonPathExecContext *cxt, JsonPathItem *jsp,
12291236
str->val.string.len, cflags,
12301237
DEFAULT_COLLATION_OID, 0, NULL))
12311238
{
1232-
if (cxt->lax)
1239+
if (!jspStrictAbsenseOfErrors(cxt))
12331240
return jperOk;
12341241

12351242
found = true;
@@ -1400,13 +1407,13 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
14001407
if (jspHasNext(jsp) || !found)
14011408
pfree(v); /* free value if it was not added to found list */
14021409
}
1403-
else if (!cxt->lax)
1410+
else if (!jspIgnoreStructuralErrors(cxt))
14041411
{
14051412
Assert(found);
14061413
res = jperMakeError(ERRCODE_JSON_MEMBER_NOT_FOUND);
14071414
}
14081415
}
1409-
else if (!cxt->lax)
1416+
else if (!jspIgnoreStructuralErrors(cxt))
14101417
{
14111418
Assert(found);
14121419
res = jperMakeError(ERRCODE_JSON_MEMBER_NOT_FOUND);
@@ -1483,7 +1490,7 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
14831490
}
14841491
}
14851492
}
1486-
else
1493+
else if (!jspIgnoreStructuralErrors(cxt))
14871494
res = jperMakeError(ERRCODE_JSON_ARRAY_NOT_FOUND);
14881495
break;
14891496

@@ -1523,7 +1530,7 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
15231530
else
15241531
index_to = index_from;
15251532

1526-
if (!cxt->lax &&
1533+
if (!jspIgnoreStructuralErrors(cxt) &&
15271534
(index_from < 0 ||
15281535
index_from > index_to ||
15291536
index_to >= size))
@@ -1569,8 +1576,10 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
15691576

15701577
cxt->innermostArraySize = innermostArraySize;
15711578
}
1572-
else
1579+
else if (!jspIgnoreStructuralErrors(cxt))
1580+
{
15731581
res = jperMakeError(ERRCODE_JSON_ARRAY_NOT_FOUND);
1582+
}
15741583
break;
15751584

15761585
case jpiLast:
@@ -1631,7 +1640,7 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
16311640
}
16321641
}
16331642
}
1634-
else if (!cxt->lax)
1643+
else if (!jspIgnoreStructuralErrors(cxt))
16351644
{
16361645
Assert(found);
16371646
res = jperMakeError(ERRCODE_JSON_OBJECT_NOT_FOUND);
@@ -1693,9 +1702,7 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
16931702
case jpiExists:
16941703
jspGetArg(jsp, &elem);
16951704

1696-
if (cxt->lax)
1697-
res = recursiveExecute(cxt, &elem, jb, NULL);
1698-
else
1705+
if (jspStrictAbsenseOfErrors(cxt))
16991706
{
17001707
JsonValueList vals = { 0 };
17011708

@@ -1708,6 +1715,10 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
17081715
if (!jperIsError(res))
17091716
res = JsonValueListIsEmpty(&vals) ? jperNotFound : jperOk;
17101717
}
1718+
else
1719+
{
1720+
res = recursiveExecute(cxt, &elem, jb, NULL);
1721+
}
17111722

17121723
res = appendBoolResult(cxt, jsp, found, res, needBool);
17131724
break;
@@ -1751,9 +1762,10 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
17511762

17521763
if (size < 0)
17531764
{
1754-
if (!cxt->lax)
1765+
if (!jspAutoWrap(cxt))
17551766
{
1756-
res = jperMakeError(ERRCODE_JSON_ARRAY_NOT_FOUND);
1767+
if (!jspIgnoreStructuralErrors(cxt))
1768+
res = jperMakeError(ERRCODE_JSON_ARRAY_NOT_FOUND);
17571769
break;
17581770
}
17591771

@@ -2120,7 +2132,7 @@ static inline JsonPathExecResult
21202132
recursiveExecuteUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
21212133
JsonbValue *jb, JsonValueList *found)
21222134
{
2123-
if (cxt->lax && JsonbType(jb) == jbvArray)
2135+
if (jspAutoUnwrap(cxt) && JsonbType(jb) == jbvArray)
21242136
return recursiveExecuteUnwrapArray(cxt, jsp, jb, found);
21252137

21262138
return recursiveExecuteNoUnwrap(cxt, jsp, jb, found, false);
@@ -2172,7 +2184,7 @@ static inline JsonPathExecResult
21722184
recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
21732185
JsonValueList *found)
21742186
{
2175-
if (cxt->lax)
2187+
if (jspAutoUnwrap(cxt))
21762188
{
21772189
switch (jsp->type)
21782190
{
@@ -2247,11 +2259,12 @@ executeJsonPath(JsonPath *path, List *vars, Jsonb *json, JsonValueList *foundJso
22472259
jspInit(&jsp, path);
22482260

22492261
cxt.vars = vars;
2250-
cxt.lax = (path->header & JSONPATH_LAX) != 0;
2262+
cxt.laxMode = (path->header & JSONPATH_LAX) != 0;
2263+
cxt.ignoreStructuralErrors = cxt.laxMode;
22512264
cxt.root = JsonbInitBinary(&jbv, json);
22522265
cxt.innermostArraySize = -1;
22532266

2254-
if (!cxt.lax && !foundJson)
2267+
if (jspStrictAbsenseOfErrors(&cxt) && !foundJson)
22552268
{
22562269
/*
22572270
* In strict mode we must get a complete list of values to check

0 commit comments

Comments
 (0)