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

Commit d494e65

Browse files
feodorNikita Glukhov
authored and
Nikita Glukhov
committed
make beauty
1 parent 7d54629 commit d494e65

File tree

2 files changed

+94
-39
lines changed

2 files changed

+94
-39
lines changed

src/backend/utils/adt/jsonpath.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#include "utils/jsonpath.h"
2020

2121
/*****************************INPUT/OUTPUT************************************/
22+
23+
/*
24+
* Convert AST to flat jsonpath type representation
25+
*/
2226
static int
2327
flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item,
2428
bool forbiddenRoot)
@@ -33,6 +37,11 @@ flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item,
3337
alignStringInfoInt(buf);
3438

3539
next = (item->next) ? buf->len : 0;
40+
41+
/*
42+
* actual value will be recorded later, after next and
43+
* children processing
44+
*/
3645
appendBinaryStringInfo(buf, (char*)&next /* fake value */, sizeof(next));
3746

3847
switch(item->type)
@@ -83,6 +92,11 @@ flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item,
8392
int32 left, right;
8493

8594
left = buf->len;
95+
96+
/*
97+
* first, reserve place for left/right arg's positions, then
98+
* record both args and sets actual position in reserved places
99+
*/
86100
appendBinaryStringInfo(buf, (char*)&left /* fake value */, sizeof(left));
87101
right = buf->len;
88102
appendBinaryStringInfo(buf, (char*)&right /* fake value */, sizeof(right));
@@ -408,6 +422,10 @@ jsonpath_out(PG_FUNCTION_ARGS)
408422

409423
/********************Support functions for JsonPath****************************/
410424

425+
/*
426+
* Support macroses to read stored values
427+
*/
428+
411429
#define read_byte(v, b, p) do { \
412430
(v) = *(uint8*)((b) + (p)); \
413431
(p) += 1; \
@@ -423,13 +441,19 @@ jsonpath_out(PG_FUNCTION_ARGS)
423441
(p) += sizeof(int32) * (n); \
424442
} while(0) \
425443

444+
/*
445+
* Read root node and fill root node representation
446+
*/
426447
void
427448
jspInit(JsonPathItem *v, JsonPath *js)
428449
{
429450
Assert(js->header == JSONPATH_VERSION);
430451
jspInitByBuffer(v, js->data, 0);
431452
}
432453

454+
/*
455+
* Read node from buffer and fill its representation
456+
*/
433457
void
434458
jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
435459
{

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 70 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
#include "postgres.h"
1414
#include "funcapi.h"
1515
#include "miscadmin.h"
16+
#include "catalog/pg_collation.h"
1617
#include "catalog/pg_type.h"
1718
#include "lib/stringinfo.h"
1819
#include "utils/builtins.h"
1920
#include "utils/json.h"
2021
#include "utils/jsonpath.h"
22+
#include "utils/varlena.h"
2123

2224
typedef struct JsonPathExecContext
2325
{
@@ -31,6 +33,9 @@ static JsonPathExecResult recursiveExecute(JsonPathExecContext *cxt,
3133

3234
/********************Execute functions for JsonPath***************************/
3335

36+
/*
37+
* Find value of jsonpath variable in a list of passing params
38+
*/
3439
static void
3540
computeJsonPathVariable(JsonPathItem *variable, List *vars, JsonbValue *value)
3641
{
@@ -132,6 +137,9 @@ computeJsonPathVariable(JsonPathItem *variable, List *vars, JsonbValue *value)
132137
}
133138
}
134139

140+
/*
141+
* Convert jsonpath's scalar or variable node to actual jsonb value
142+
*/
135143
static void
136144
computeJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item, JsonbValue *value)
137145
{
@@ -161,6 +169,12 @@ computeJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item, JsonbValue *va
161169
}
162170

163171

172+
/*
173+
* Returns jbv* type of of JsonbValue. Note, it never returns
174+
* jbvBinary as is - jbvBinary is used as mark of store naked
175+
* scalar value. To improve readability it defines jbvScalar
176+
* as alias to jbvBinary
177+
*/
164178
#define jbvScalar jbvBinary
165179
static int
166180
JsonbType(JsonbValue *jb)
@@ -196,31 +210,10 @@ compareNumeric(Numeric a, Numeric b)
196210
);
197211
}
198212

199-
static bool
200-
checkScalarEquality(JsonbValue *jb1, JsonbValue *jb2)
201-
{
202-
switch (jb1->type)
203-
{
204-
case jbvNull:
205-
return true;
206-
case jbvString:
207-
return (jb1->val.string.len == jb2->val.string.len &&
208-
memcmp(jb2->val.string.val, jb1->val.string.val,
209-
jb1->val.string.len) == 0);
210-
case jbvBool:
211-
return (jb2->val.boolean == jb1->val.boolean);
212-
case jbvNumeric:
213-
return (compareNumeric(jb1->val.numeric, jb2->val.numeric) == 0);
214-
default:
215-
elog(ERROR,"1Wrong state");
216-
return false;
217-
}
218-
}
219-
220213
static JsonPathExecResult
221214
checkEquality(JsonbValue *jb1, JsonbValue *jb2, bool not)
222215
{
223-
bool eq;
216+
bool eq = false;
224217

225218
if (jb1->type != jb2->type)
226219
{
@@ -232,14 +225,28 @@ checkEquality(JsonbValue *jb1, JsonbValue *jb2, bool not)
232225

233226
if (jb1->type == jbvBinary)
234227
return jperError;
235-
/*
236-
eq = compareJsonbContainers(jb1->val.binary.data,
237-
jb2->val.binary.data) == 0;
238-
*/
239-
else
240-
eq = checkScalarEquality(jb1, jb2);
241228

242-
return !!not ^ !!eq ? jperOk : jperNotFound;
229+
switch (jb1->type)
230+
{
231+
case jbvNull:
232+
eq = true;
233+
break;
234+
case jbvString:
235+
eq = (jb1->val.string.len == jb2->val.string.len &&
236+
memcmp(jb2->val.string.val, jb1->val.string.val,
237+
jb1->val.string.len) == 0);
238+
break;
239+
case jbvBool:
240+
eq = (jb2->val.boolean == jb1->val.boolean);
241+
break;
242+
case jbvNumeric:
243+
eq = (compareNumeric(jb1->val.numeric, jb2->val.numeric) == 0);
244+
break;
245+
default:
246+
elog(ERROR,"1Wrong state");
247+
}
248+
249+
return (not ^ eq) ? jperOk : jperNotFound;
243250
}
244251

245252
static JsonPathExecResult
@@ -269,13 +276,11 @@ makeCompare(int32 op, JsonbValue *jb1, JsonbValue *jb2)
269276
case jbvNumeric:
270277
cmp = compareNumeric(jb1->val.numeric, jb2->val.numeric);
271278
break;
272-
/*
273279
case jbvString:
274280
cmp = varstr_cmp(jb1->val.string.val, jb1->val.string.len,
275281
jb2->val.string.val, jb2->val.string.len,
276-
collationId);
282+
DEFAULT_COLLATION_OID);
277283
break;
278-
*/
279284
default:
280285
return jperError;
281286
}
@@ -532,6 +537,9 @@ executeUnaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
532537
return jper;
533538
}
534539

540+
/*
541+
* implements jpiAny node (** operator)
542+
*/
535543
static JsonPathExecResult
536544
recursiveAny(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
537545
List **found, uint32 level, uint32 first, uint32 last)
@@ -548,6 +556,9 @@ recursiveAny(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
548556

549557
it = JsonbIteratorInit(jb->val.binary.data);
550558

559+
/*
560+
* Recursivly iterate over jsonb objects/arrays
561+
*/
551562
while((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
552563
{
553564
if (r == WJB_KEY)
@@ -590,12 +601,23 @@ recursiveAny(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
590601
return res;
591602
}
592603

604+
/*
605+
* Main executor function: walks on jsonpath structure and tries to find
606+
* correspoding parts of jsonb. Note, jsonb and jsonpath values should be
607+
* avaliable and untoasted during work because JsonPathItem, JsonbValue
608+
* and found could have pointers into input values. If caller wants just to
609+
* check matching of json by jsonpath then it doesn't provide a found arg.
610+
* In this case executor works till first positive result and does not check
611+
* the rest if it is possible. In other case it tries to find all satisfied
612+
* results
613+
*/
593614
static JsonPathExecResult
594615
recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
595616
List **found)
596617
{
597618
JsonPathItem elem;
598619
JsonPathExecResult res = jperNotFound;
620+
bool hasNext;
599621

600622
check_stack_depth();
601623

@@ -607,10 +629,15 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
607629
{
608630
JsonPathExecResult res2;
609631

632+
/*
633+
* SQL/JSON says that we should check second arg
634+
* in case of jperError
635+
*/
636+
610637
jspGetRightArg(jsp, &elem);
611638
res2 = recursiveExecute(cxt, &elem, jb, NULL);
612639

613-
res = res2 == jperOk ? res : res2;
640+
res = (res2 == jperOk) ? res : res2;
614641
}
615642
break;
616643
case jpiOr:
@@ -623,7 +650,7 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
623650
jspGetRightArg(jsp, &elem);
624651
res2 = recursiveExecute(cxt, &elem, jb, NULL);
625652

626-
res = res2 == jperNotFound ? res : res2;
653+
res = (res2 == jperNotFound) ? res : res2;
627654
}
628655
break;
629656
case jpiNot:
@@ -643,7 +670,7 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
643670
case jpiIsUnknown:
644671
jspGetArg(jsp, &elem);
645672
res = recursiveExecute(cxt, &elem, jb, NULL);
646-
res = res == jperError ? jperOk : jperNotFound;
673+
res = (res == jperError) ? jperOk : jperNotFound;
647674
break;
648675
case jpiKey:
649676
if (JsonbType(jb) == jbvObject)
@@ -676,6 +703,7 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
676703
case jpiCurrent:
677704
if (!jspGetNext(jsp, &elem))
678705
{
706+
/* we are last in chain of node */
679707
res = jperOk;
680708
if (found)
681709
{
@@ -685,7 +713,7 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
685713
v = JsonbExtractScalar(jb->val.binary.data,
686714
palloc(sizeof(*v)));
687715
else
688-
v = copyJsonbValue(jb); /* FIXME */
716+
v = copyJsonbValue(jb);
689717

690718
*found = lappend(*found, v);
691719
}
@@ -709,7 +737,6 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
709737
JsonbIterator *it;
710738
int32 r;
711739
JsonbValue v;
712-
bool hasNext;
713740

714741
hasNext = jspGetNext(jsp, &elem);
715742
it = JsonbIteratorInit(jb->val.binary.data);
@@ -746,7 +773,6 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
746773
if (JsonbType(jb) == jbvArray)
747774
{
748775
JsonbValue *v;
749-
bool hasNext;
750776
int i;
751777

752778
hasNext = jspGetNext(jsp, &elem);
@@ -788,7 +814,6 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
788814
JsonbIterator *it;
789815
int32 r;
790816
JsonbValue v;
791-
bool hasNext;
792817

793818
hasNext = jspGetNext(jsp, &elem);
794819
it = JsonbIteratorInit(jb->val.binary.data);
@@ -915,6 +940,9 @@ recursiveExecute(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb,
915940
return res;
916941
}
917942

943+
/*
944+
* Public interface to jsonpath executor
945+
*/
918946
JsonPathExecResult
919947
executeJsonPath(JsonPath *path, List *vars, Jsonb *json, List **foundJson)
920948
{
@@ -948,6 +976,9 @@ returnNULL(void *arg, bool *isNull)
948976
return Int32GetDatum(0);
949977
}
950978

979+
/*
980+
* Convert jsonb object into list of vars for executor
981+
*/
951982
static List*
952983
makePassingVars(Jsonb *jb)
953984
{

0 commit comments

Comments
 (0)