19
19
#include "utils/json.h"
20
20
#include "utils/jsonpath.h"
21
21
22
- static JsonPathExecResult
23
- recursiveExecute (JsonPathItem * jsp , List * vars , JsonbValue * jb , List * * found );
22
+ typedef struct JsonPathExecContext
23
+ {
24
+ List * vars ;
25
+ bool lax ;
26
+ } JsonPathExecContext ;
27
+
28
+ static JsonPathExecResult recursiveExecute (JsonPathExecContext * cxt ,
29
+ JsonPathItem * jsp , JsonbValue * jb ,
30
+ List * * found );
24
31
25
32
/********************Execute functions for JsonPath***************************/
26
33
@@ -126,7 +133,7 @@ computeJsonPathVariable(JsonPathItem *variable, List *vars, JsonbValue *value)
126
133
}
127
134
128
135
static void
129
- computeJsonPathItem (JsonPathItem * item , List * vars , JsonbValue * value )
136
+ computeJsonPathItem (JsonPathExecContext * cxt , JsonPathItem * item , JsonbValue * value )
130
137
{
131
138
switch (item -> type )
132
139
{
@@ -146,7 +153,7 @@ computeJsonPathItem(JsonPathItem *item, List *vars, JsonbValue *value)
146
153
value -> val .string .val = jspGetString (item , & value -> val .string .len );
147
154
break ;
148
155
case jpiVariable :
149
- computeJsonPathVariable (item , vars , value );
156
+ computeJsonPathVariable (item , cxt -> vars , value );
150
157
break ;
151
158
default :
152
159
elog (ERROR , "Wrong type" );
@@ -302,25 +309,24 @@ makeCompare(int32 op, JsonbValue *jb1, JsonbValue *jb2)
302
309
}
303
310
304
311
static JsonPathExecResult
305
- executeExpr (JsonPathItem * jsp , List * vars , JsonbValue * jb )
312
+ executeExpr (JsonPathExecContext * cxt , JsonPathItem * jsp , JsonbValue * jb )
306
313
{
307
314
JsonPathExecResult res ;
308
315
JsonPathItem elem ;
309
316
List * lseq = NIL ;
310
317
List * rseq = NIL ;
311
318
ListCell * llc ;
312
319
ListCell * rlc ;
313
- bool strict = true; /* FIXME pass */
314
320
bool error = false;
315
321
bool found = false;
316
322
317
323
jspGetLeftArg (jsp , & elem );
318
- res = recursiveExecute (& elem , vars , jb , & lseq );
324
+ res = recursiveExecute (cxt , & elem , jb , & lseq );
319
325
if (res != jperOk )
320
326
return res ;
321
327
322
328
jspGetRightArg (jsp , & elem );
323
- res = recursiveExecute (& elem , vars , jb , & rseq );
329
+ res = recursiveExecute (cxt , & elem , jb , & rseq );
324
330
if (res != jperOk )
325
331
return res ;
326
332
@@ -352,14 +358,14 @@ executeExpr(JsonPathItem *jsp, List *vars, JsonbValue *jb)
352
358
353
359
if (res == jperOk )
354
360
{
355
- if (! strict )
361
+ if (cxt -> lax )
356
362
return jperOk ;
357
363
358
364
found = true;
359
365
}
360
366
else if (res == jperError )
361
367
{
362
- if (strict )
368
+ if (! cxt -> lax )
363
369
return jperError ;
364
370
365
371
error = true;
@@ -387,10 +393,7 @@ copyJsonbValue(JsonbValue *src)
387
393
}
388
394
389
395
static JsonPathExecResult
390
- recursiveExecute (JsonPathItem * jsp , List * vars , JsonbValue * jb , List * * found );
391
-
392
- static JsonPathExecResult
393
- recursiveAny (JsonPathItem * jsp , List * vars , JsonbValue * jb ,
396
+ recursiveAny (JsonPathExecContext * cxt , JsonPathItem * jsp , JsonbValue * jb ,
394
397
List * * found , uint32 level , uint32 first , uint32 last )
395
398
{
396
399
JsonPathExecResult res = jperNotFound ;
@@ -421,7 +424,7 @@ recursiveAny(JsonPathItem *jsp, List *vars, JsonbValue *jb,
421
424
/* check expression */
422
425
if (jsp )
423
426
{
424
- res = recursiveExecute (jsp , vars , & v , found );
427
+ res = recursiveExecute (cxt , jsp , & v , found );
425
428
if (res == jperOk && !found )
426
429
break ;
427
430
}
@@ -436,7 +439,7 @@ recursiveAny(JsonPathItem *jsp, List *vars, JsonbValue *jb,
436
439
437
440
if (level < last && v .type == jbvBinary )
438
441
{
439
- res = recursiveAny (jsp , vars , & v , found , level + 1 , first , last );
442
+ res = recursiveAny (cxt , jsp , & v , found , level + 1 , first , last );
440
443
441
444
if (res == jperOk && found == NULL )
442
445
break ;
@@ -448,7 +451,8 @@ recursiveAny(JsonPathItem *jsp, List *vars, JsonbValue *jb,
448
451
}
449
452
450
453
static JsonPathExecResult
451
- recursiveExecute (JsonPathItem * jsp , List * vars , JsonbValue * jb , List * * found )
454
+ recursiveExecute (JsonPathExecContext * cxt , JsonPathItem * jsp , JsonbValue * jb ,
455
+ List * * found )
452
456
{
453
457
JsonPathItem elem ;
454
458
JsonPathExecResult res = jperNotFound ;
@@ -458,33 +462,33 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
458
462
switch (jsp -> type ) {
459
463
case jpiAnd :
460
464
jspGetLeftArg (jsp , & elem );
461
- res = recursiveExecute (& elem , vars , jb , NULL );
465
+ res = recursiveExecute (cxt , & elem , jb , NULL );
462
466
if (res != jperNotFound )
463
467
{
464
468
JsonPathExecResult res2 ;
465
469
466
470
jspGetRightArg (jsp , & elem );
467
- res2 = recursiveExecute (& elem , vars , jb , NULL );
471
+ res2 = recursiveExecute (cxt , & elem , jb , NULL );
468
472
469
473
res = res2 == jperOk ? res : res2 ;
470
474
}
471
475
break ;
472
476
case jpiOr :
473
477
jspGetLeftArg (jsp , & elem );
474
- res = recursiveExecute (& elem , vars , jb , NULL );
478
+ res = recursiveExecute (cxt , & elem , jb , NULL );
475
479
if (res != jperOk )
476
480
{
477
481
JsonPathExecResult res2 ;
478
482
479
483
jspGetRightArg (jsp , & elem );
480
- res2 = recursiveExecute (& elem , vars , jb , NULL );
484
+ res2 = recursiveExecute (cxt , & elem , jb , NULL );
481
485
482
486
res = res2 == jperNotFound ? res : res2 ;
483
487
}
484
488
break ;
485
489
case jpiNot :
486
490
jspGetArg (jsp , & elem );
487
- switch ((res = recursiveExecute (& elem , vars , jb , NULL )))
491
+ switch ((res = recursiveExecute (cxt , & elem , jb , NULL )))
488
492
{
489
493
case jperOk :
490
494
res = jperNotFound ;
@@ -498,7 +502,7 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
498
502
break ;
499
503
case jpiIsUnknown :
500
504
jspGetArg (jsp , & elem );
501
- res = recursiveExecute (& elem , vars , jb , NULL );
505
+ res = recursiveExecute (cxt , & elem , jb , NULL );
502
506
res = res == jperError ? jperOk : jperNotFound ;
503
507
break ;
504
508
case jpiKey :
@@ -515,7 +519,7 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
515
519
{
516
520
if (jspGetNext (jsp , & elem ))
517
521
{
518
- res = recursiveExecute (& elem , vars , v , found );
522
+ res = recursiveExecute (cxt , & elem , v , found );
519
523
pfree (v );
520
524
}
521
525
else
@@ -552,11 +556,11 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
552
556
553
557
JsonbExtractScalar (jb -> val .binary .data , & v );
554
558
555
- res = recursiveExecute (& elem , vars , & v , found );
559
+ res = recursiveExecute (cxt , & elem , & v , found );
556
560
}
557
561
else
558
562
{
559
- res = recursiveExecute (& elem , vars , jb , found );
563
+ res = recursiveExecute (cxt , & elem , jb , found );
560
564
}
561
565
break ;
562
566
case jpiAnyArray :
@@ -576,7 +580,7 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
576
580
{
577
581
if (hasNext == true)
578
582
{
579
- res = recursiveExecute (& elem , vars , & v , found );
583
+ res = recursiveExecute (cxt , & elem , & v , found );
580
584
581
585
if (res == jperError )
582
586
break ;
@@ -618,7 +622,7 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
618
622
619
623
if (hasNext == true)
620
624
{
621
- res = recursiveExecute (& elem , vars , v , found );
625
+ res = recursiveExecute (cxt , & elem , v , found );
622
626
623
627
if (res == jperError || found == NULL )
624
628
break ;
@@ -655,7 +659,7 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
655
659
{
656
660
if (hasNext == true)
657
661
{
658
- res = recursiveExecute (& elem , vars , & v , found );
662
+ res = recursiveExecute (cxt , & elem , & v , found );
659
663
660
664
if (res == jperError )
661
665
break ;
@@ -682,12 +686,12 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
682
686
case jpiGreater :
683
687
case jpiLessOrEqual :
684
688
case jpiGreaterOrEqual :
685
- res = executeExpr (jsp , vars , jb );
689
+ res = executeExpr (cxt , jsp , jb );
686
690
break ;
687
691
case jpiRoot :
688
692
if (jspGetNext (jsp , & elem ))
689
693
{
690
- res = recursiveExecute (& elem , vars , jb , found );
694
+ res = recursiveExecute (cxt , & elem , jb , found );
691
695
}
692
696
else
693
697
{
@@ -699,11 +703,11 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
699
703
break ;
700
704
case jpiFilter :
701
705
jspGetArg (jsp , & elem );
702
- res = recursiveExecute (& elem , vars , jb , NULL );
706
+ res = recursiveExecute (cxt , & elem , jb , NULL );
703
707
if (res != jperOk )
704
708
res = jperNotFound ;
705
709
else if (jspGetNext (jsp , & elem ))
706
- res = recursiveExecute (& elem , vars , jb , found );
710
+ res = recursiveExecute (cxt , & elem , jb , found );
707
711
else if (found )
708
712
* found = lappend (* found , copyJsonbValue (jb ));
709
713
break ;
@@ -716,7 +720,7 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
716
720
{
717
721
if (hasNext )
718
722
{
719
- res = recursiveExecute (& elem , vars , jb , found );
723
+ res = recursiveExecute (cxt , & elem , jb , found );
720
724
if (res == jperOk && !found )
721
725
break ;
722
726
}
@@ -730,15 +734,15 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
730
734
}
731
735
732
736
if (jb -> type == jbvBinary )
733
- res = recursiveAny (hasNext ? & elem : NULL , vars , jb , found ,
737
+ res = recursiveAny (cxt , hasNext ? & elem : NULL , jb , found ,
734
738
1 ,
735
739
jsp -> anybounds .first ,
736
740
jsp -> anybounds .last );
737
741
break ;
738
742
}
739
743
case jpiExists :
740
744
jspGetArg (jsp , & elem );
741
- res = recursiveExecute (& elem , vars , jb , NULL );
745
+ res = recursiveExecute (cxt , & elem , jb , NULL );
742
746
break ;
743
747
case jpiNull :
744
748
case jpiBool :
@@ -749,7 +753,7 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
749
753
if (found )
750
754
{
751
755
JsonbValue * jbv = palloc (sizeof (* jbv ));
752
- computeJsonPathItem (jsp , vars , jbv );
756
+ computeJsonPathItem (cxt , jsp , jbv );
753
757
* found = lappend (* found , jbv );
754
758
}
755
759
break ;
@@ -763,16 +767,20 @@ recursiveExecute(JsonPathItem *jsp, List *vars, JsonbValue *jb, List **found)
763
767
JsonPathExecResult
764
768
executeJsonPath (JsonPath * path , List * vars , Jsonb * json , List * * foundJson )
765
769
{
770
+ JsonPathExecContext cxt ;
766
771
JsonPathItem jsp ;
767
772
JsonbValue jbv ;
768
773
774
+ cxt .vars = vars ;
775
+ cxt .lax = false; /* FIXME */
776
+
769
777
jbv .type = jbvBinary ;
770
778
jbv .val .binary .data = & json -> root ;
771
779
jbv .val .binary .len = VARSIZE_ANY_EXHDR (json );
772
780
773
781
jspInit (& jsp , path );
774
782
775
- return recursiveExecute (& jsp , vars , & jbv , foundJson );
783
+ return recursiveExecute (& cxt , & jsp , & jbv , foundJson );
776
784
}
777
785
778
786
static Datum
0 commit comments