@@ -26,14 +26,19 @@ static int coundChildren(ExtractedNode *node, ExtractedNodeType type, bool first
2626static void fillChildren (ExtractedNode * node ,ExtractedNodeType type ,bool first ,ExtractedNode * * items ,int * i );
2727static void flatternTree (ExtractedNode * node );
2828static int comparePathItems (PathItem * i1 ,PathItem * i2 );
29- static ExtractedNode * makeEntries (ExtractedNode * node ,MakeEntryHandler handler ,Pointer extra );
3029static int compareNodes (const void * a1 ,const void * a2 );
30+ static int compareJsQueryItem (JsQueryItem * v1 ,JsQueryItem * v2 );
3131static void processGroup (ExtractedNode * node ,int start ,int end );
3232static void simplifyRecursive (ExtractedNode * node );
33- static int compareJsQueryItem (JsQueryItem * v1 ,JsQueryItem * v2 );
33+ static ExtractedNode * makeEntries (ExtractedNode * node ,MakeEntryHandler handler ,Pointer extra );
34+ static bool queryHasPositive (ExtractedNode * node );
35+ static bool needRecheckRecursive (ExtractedNode * node ,bool not );
3436
37+ /*
38+ * Recursive function that turns jsquery into tree of ExtractedNode items.
39+ */
3540static ExtractedNode *
36- recursiveExtract (JsQueryItem * jsq ,bool indirect ,PathItem * path )
41+ recursiveExtract (JsQueryItem * jsq ,bool indirect ,PathItem * path )
3742{
3843ExtractedNode * leftNode ,* rightNode ,* result ;
3944PathItem * pathItem ;
@@ -199,8 +204,12 @@ recursiveExtract(JsQueryItem *jsq,bool indirect, PathItem *path)
199204return NULL ;
200205}
201206
207+ /*
208+ * Count number of children connected with nodes of same type.
209+ */
202210static int
203- coundChildren (ExtractedNode * node ,ExtractedNodeType type ,bool first ,bool * found )
211+ coundChildren (ExtractedNode * node ,ExtractedNodeType type ,
212+ bool first ,bool * found )
204213{
205214if ((node -> indirect || node -> type != type )&& !first )
206215{
@@ -216,6 +225,9 @@ coundChildren(ExtractedNode *node, ExtractedNodeType type, bool first, bool *fou
216225}
217226}
218227
228+ /*
229+ * Fill array of children connected with nodes of same type.
230+ */
219231static void
220232fillChildren (ExtractedNode * node ,ExtractedNodeType type ,bool first ,
221233ExtractedNode * * items ,int * i )
@@ -233,6 +245,10 @@ fillChildren(ExtractedNode *node, ExtractedNodeType type, bool first,
233245}
234246}
235247
248+ /*
249+ * Turn tree into "flat" form, turning nested binary AND/OR operators into
250+ * single n-ary AND/OR operators.
251+ */
236252static void
237253flatternTree (ExtractedNode * node )
238254{
@@ -260,6 +276,9 @@ flatternTree(ExtractedNode *node)
260276}
261277}
262278
279+ /*
280+ * Compare path items chains from child to parent.
281+ */
263282static int
264283comparePathItems (PathItem * i1 ,PathItem * i2 )
265284{
@@ -295,6 +314,10 @@ comparePathItems(PathItem *i1, PathItem *i2)
295314}
296315}
297316
317+ /*
318+ * Compare nodes in the order where conditions to the same fields are located
319+ * together.
320+ */
298321static int
299322compareNodes (const void * a1 ,const void * a2 )
300323{
@@ -332,6 +355,9 @@ compareNodes(const void *a1, const void *a2)
332355}
333356}
334357
358+ /*
359+ * Compare json values represented by JsQueryItems.
360+ */
335361static int
336362compareJsQueryItem (JsQueryItem * v1 ,JsQueryItem * v2 )
337363{
@@ -368,6 +394,10 @@ compareJsQueryItem(JsQueryItem *v1, JsQueryItem *v2)
368394return 0 ;/* make compiler happy */
369395}
370396
397+ /*
398+ * Process group of nodes representing conditions for the same field. After
399+ * processing group of nodes is replaced with one node.
400+ */
371401static void
372402processGroup (ExtractedNode * node ,int start ,int end )
373403{
@@ -455,6 +485,10 @@ processGroup(ExtractedNode *node, int start, int end)
455485node -> args .items [i ]= NULL ;
456486}
457487
488+ /*
489+ * Reduce number of nodes in tree, by turning multiple conditions about
490+ * same field in same context into one node.
491+ */
458492static void
459493simplifyRecursive (ExtractedNode * node )
460494{
@@ -494,6 +528,9 @@ simplifyRecursive(ExtractedNode *node)
494528}
495529}
496530
531+ /*
532+ * Make entries for all leaf tree nodes using user-provided handler.
533+ */
497534static ExtractedNode *
498535makeEntries (ExtractedNode * node ,MakeEntryHandler handler ,Pointer extra )
499536{
@@ -542,6 +579,10 @@ makeEntries(ExtractedNode *node, MakeEntryHandler handler, Pointer extra)
542579}
543580}
544581
582+ /*
583+ * Returns false when query can be satisfied with no entries matching. True
584+ * return value guarantees than it can be evaluated using index.
585+ */
545586static bool
546587queryHasPositive (ExtractedNode * node )
547588{
@@ -578,6 +619,10 @@ queryHasPositive(ExtractedNode *node)
578619}
579620}
580621
622+ /*
623+ * Checks if node evaluating with index needs recheck assuming match of
624+ * entries itself doesn't need recheck.
625+ */
581626static bool
582627needRecheckRecursive (ExtractedNode * node ,bool not )
583628{
@@ -603,6 +648,18 @@ needRecheckRecursive(ExtractedNode *node, bool not)
603648}
604649}
605650
651+ /*
652+ * Wrapper for "needRecheckRecursive".
653+ */
654+ bool
655+ queryNeedRecheck (ExtractedNode * node )
656+ {
657+ return needRecheckRecursive (node , false);
658+ }
659+
660+ /*
661+ * Turn jsquery into tree of entries using user-provided handler.
662+ */
606663ExtractedNode *
607664extractJsQuery (JsQuery * jq ,MakeEntryHandler handler ,Pointer extra )
608665{
@@ -619,11 +676,12 @@ extractJsQuery(JsQuery *jq, MakeEntryHandler handler, Pointer extra)
619676}
620677if (root && !queryHasPositive (root ))
621678root = NULL ;
622- if (root )
623- root -> indirect = needRecheckRecursive (root , false);
624679return root ;
625680}
626681
682+ /*
683+ * Evaluate previously extracted tree.
684+ */
627685bool
628686execRecursive (ExtractedNode * node ,bool * check )
629687{
@@ -647,6 +705,9 @@ execRecursive(ExtractedNode *node, bool *check)
647705}
648706}
649707
708+ /*
709+ * Evaluate previously extracted tree using tri-state logic.
710+ */
650711bool
651712execRecursiveTristate (ExtractedNode * node ,GinTernaryValue * check )
652713{