xref: /sqlite-3.40.0/ext/fts5/fts5_expr.c (revision 38d69855)
1 /*
2 ** 2014 May 31
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 ******************************************************************************
12 **
13 */
14 
15 
16 
17 #include "fts5Int.h"
18 #include "fts5parse.h"
19 
20 /*
21 ** All token types in the generated fts5parse.h file are greater than 0.
22 */
23 #define FTS5_EOF 0
24 
25 #define FTS5_LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))
26 
27 typedef struct Fts5ExprTerm Fts5ExprTerm;
28 
29 /*
30 ** Functions generated by lemon from fts5parse.y.
31 */
32 void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64));
33 void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*));
34 void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
35 #ifndef NDEBUG
36 #include <stdio.h>
37 void sqlite3Fts5ParserTrace(FILE*, char*);
38 #endif
39 
40 
41 struct Fts5Expr {
42   Fts5Index *pIndex;
43   Fts5Config *pConfig;
44   Fts5ExprNode *pRoot;
45   int bDesc;                      /* Iterate in descending rowid order */
46   int nPhrase;                    /* Number of phrases in expression */
47   Fts5ExprPhrase **apExprPhrase;  /* Pointers to phrase objects */
48 };
49 
50 /*
51 ** eType:
52 **   Expression node type. Always one of:
53 **
54 **       FTS5_AND                 (nChild, apChild valid)
55 **       FTS5_OR                  (nChild, apChild valid)
56 **       FTS5_NOT                 (nChild, apChild valid)
57 **       FTS5_STRING              (pNear valid)
58 **       FTS5_TERM                (pNear valid)
59 */
60 struct Fts5ExprNode {
61   int eType;                      /* Node type */
62   int bEof;                       /* True at EOF */
63   int bNomatch;                   /* True if entry is not a match */
64 
65   /* Next method for this node. */
66   int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64);
67 
68   i64 iRowid;                     /* Current rowid */
69   Fts5ExprNearset *pNear;         /* For FTS5_STRING - cluster of phrases */
70 
71   /* Child nodes. For a NOT node, this array always contains 2 entries. For
72   ** AND or OR nodes, it contains 2 or more entries.  */
73   int nChild;                     /* Number of child nodes */
74   Fts5ExprNode *apChild[1];       /* Array of child nodes */
75 };
76 
77 #define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING)
78 
79 /*
80 ** Invoke the xNext method of an Fts5ExprNode object. This macro should be
81 ** used as if it has the same signature as the xNext() methods themselves.
82 */
83 #define fts5ExprNodeNext(a,b,c,d) (b)->xNext((a), (b), (c), (d))
84 
85 /*
86 ** An instance of the following structure represents a single search term
87 ** or term prefix.
88 */
89 struct Fts5ExprTerm {
90   int bPrefix;                    /* True for a prefix term */
91   char *zTerm;                    /* nul-terminated term */
92   Fts5IndexIter *pIter;           /* Iterator for this term */
93   Fts5ExprTerm *pSynonym;         /* Pointer to first in list of synonyms */
94 };
95 
96 /*
97 ** A phrase. One or more terms that must appear in a contiguous sequence
98 ** within a document for it to match.
99 */
100 struct Fts5ExprPhrase {
101   Fts5ExprNode *pNode;            /* FTS5_STRING node this phrase is part of */
102   Fts5Buffer poslist;             /* Current position list */
103   int nTerm;                      /* Number of entries in aTerm[] */
104   Fts5ExprTerm aTerm[1];          /* Terms that make up this phrase */
105 };
106 
107 /*
108 ** One or more phrases that must appear within a certain token distance of
109 ** each other within each matching document.
110 */
111 struct Fts5ExprNearset {
112   int nNear;                      /* NEAR parameter */
113   Fts5Colset *pColset;            /* Columns to search (NULL -> all columns) */
114   int nPhrase;                    /* Number of entries in aPhrase[] array */
115   Fts5ExprPhrase *apPhrase[1];    /* Array of phrase pointers */
116 };
117 
118 
119 /*
120 ** Parse context.
121 */
122 struct Fts5Parse {
123   Fts5Config *pConfig;
124   char *zErr;
125   int rc;
126   int nPhrase;                    /* Size of apPhrase array */
127   Fts5ExprPhrase **apPhrase;      /* Array of all phrases */
128   Fts5ExprNode *pExpr;            /* Result of a successful parse */
129 };
130 
131 void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
132   va_list ap;
133   va_start(ap, zFmt);
134   if( pParse->rc==SQLITE_OK ){
135     pParse->zErr = sqlite3_vmprintf(zFmt, ap);
136     pParse->rc = SQLITE_ERROR;
137   }
138   va_end(ap);
139 }
140 
141 static int fts5ExprIsspace(char t){
142   return t==' ' || t=='\t' || t=='\n' || t=='\r';
143 }
144 
145 /*
146 ** Read the first token from the nul-terminated string at *pz.
147 */
148 static int fts5ExprGetToken(
149   Fts5Parse *pParse,
150   const char **pz,                /* IN/OUT: Pointer into buffer */
151   Fts5Token *pToken
152 ){
153   const char *z = *pz;
154   int tok;
155 
156   /* Skip past any whitespace */
157   while( fts5ExprIsspace(*z) ) z++;
158 
159   pToken->p = z;
160   pToken->n = 1;
161   switch( *z ){
162     case '(':  tok = FTS5_LP;    break;
163     case ')':  tok = FTS5_RP;    break;
164     case '{':  tok = FTS5_LCP;   break;
165     case '}':  tok = FTS5_RCP;   break;
166     case ':':  tok = FTS5_COLON; break;
167     case ',':  tok = FTS5_COMMA; break;
168     case '+':  tok = FTS5_PLUS;  break;
169     case '*':  tok = FTS5_STAR;  break;
170     case '\0': tok = FTS5_EOF;   break;
171 
172     case '"': {
173       const char *z2;
174       tok = FTS5_STRING;
175 
176       for(z2=&z[1]; 1; z2++){
177         if( z2[0]=='"' ){
178           z2++;
179           if( z2[0]!='"' ) break;
180         }
181         if( z2[0]=='\0' ){
182           sqlite3Fts5ParseError(pParse, "unterminated string");
183           return FTS5_EOF;
184         }
185       }
186       pToken->n = (z2 - z);
187       break;
188     }
189 
190     default: {
191       const char *z2;
192       if( sqlite3Fts5IsBareword(z[0])==0 ){
193         sqlite3Fts5ParseError(pParse, "fts5: syntax error near \"%.1s\"", z);
194         return FTS5_EOF;
195       }
196       tok = FTS5_STRING;
197       for(z2=&z[1]; sqlite3Fts5IsBareword(*z2); z2++);
198       pToken->n = (z2 - z);
199       if( pToken->n==2 && memcmp(pToken->p, "OR", 2)==0 )  tok = FTS5_OR;
200       if( pToken->n==3 && memcmp(pToken->p, "NOT", 3)==0 ) tok = FTS5_NOT;
201       if( pToken->n==3 && memcmp(pToken->p, "AND", 3)==0 ) tok = FTS5_AND;
202       break;
203     }
204   }
205 
206   *pz = &pToken->p[pToken->n];
207   return tok;
208 }
209 
210 static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); }
211 static void fts5ParseFree(void *p){ sqlite3_free(p); }
212 
213 int sqlite3Fts5ExprNew(
214   Fts5Config *pConfig,            /* FTS5 Configuration */
215   const char *zExpr,              /* Expression text */
216   Fts5Expr **ppNew,
217   char **pzErr
218 ){
219   Fts5Parse sParse;
220   Fts5Token token;
221   const char *z = zExpr;
222   int t;                          /* Next token type */
223   void *pEngine;
224   Fts5Expr *pNew;
225 
226   *ppNew = 0;
227   *pzErr = 0;
228   memset(&sParse, 0, sizeof(sParse));
229   pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc);
230   if( pEngine==0 ){ return SQLITE_NOMEM; }
231   sParse.pConfig = pConfig;
232 
233   do {
234     t = fts5ExprGetToken(&sParse, &z, &token);
235     sqlite3Fts5Parser(pEngine, t, token, &sParse);
236   }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
237   sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
238 
239   assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
240   if( sParse.rc==SQLITE_OK ){
241     *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
242     if( pNew==0 ){
243       sParse.rc = SQLITE_NOMEM;
244       sqlite3Fts5ParseNodeFree(sParse.pExpr);
245     }else{
246       if( !sParse.pExpr ){
247         const int nByte = sizeof(Fts5ExprNode);
248         pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte);
249         if( pNew->pRoot ){
250           pNew->pRoot->bEof = 1;
251         }
252       }else{
253         pNew->pRoot = sParse.pExpr;
254       }
255       pNew->pIndex = 0;
256       pNew->pConfig = pConfig;
257       pNew->apExprPhrase = sParse.apPhrase;
258       pNew->nPhrase = sParse.nPhrase;
259       sParse.apPhrase = 0;
260     }
261   }
262 
263   sqlite3_free(sParse.apPhrase);
264   *pzErr = sParse.zErr;
265   return sParse.rc;
266 }
267 
268 /*
269 ** Free the expression node object passed as the only argument.
270 */
271 void sqlite3Fts5ParseNodeFree(Fts5ExprNode *p){
272   if( p ){
273     int i;
274     for(i=0; i<p->nChild; i++){
275       sqlite3Fts5ParseNodeFree(p->apChild[i]);
276     }
277     sqlite3Fts5ParseNearsetFree(p->pNear);
278     sqlite3_free(p);
279   }
280 }
281 
282 /*
283 ** Free the expression object passed as the only argument.
284 */
285 void sqlite3Fts5ExprFree(Fts5Expr *p){
286   if( p ){
287     sqlite3Fts5ParseNodeFree(p->pRoot);
288     sqlite3_free(p->apExprPhrase);
289     sqlite3_free(p);
290   }
291 }
292 
293 /*
294 ** Argument pTerm must be a synonym iterator. Return the current rowid
295 ** that it points to.
296 */
297 static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
298   i64 iRet = 0;
299   int bRetValid = 0;
300   Fts5ExprTerm *p;
301 
302   assert( pTerm->pSynonym );
303   assert( bDesc==0 || bDesc==1 );
304   for(p=pTerm; p; p=p->pSynonym){
305     if( 0==sqlite3Fts5IterEof(p->pIter) ){
306       i64 iRowid = p->pIter->iRowid;
307       if( bRetValid==0 || (bDesc!=(iRowid<iRet)) ){
308         iRet = iRowid;
309         bRetValid = 1;
310       }
311     }
312   }
313 
314   if( pbEof && bRetValid==0 ) *pbEof = 1;
315   return iRet;
316 }
317 
318 /*
319 ** Argument pTerm must be a synonym iterator.
320 */
321 static int fts5ExprSynonymList(
322   Fts5ExprTerm *pTerm,
323   i64 iRowid,
324   Fts5Buffer *pBuf,               /* Use this buffer for space if required */
325   u8 **pa, int *pn
326 ){
327   Fts5PoslistReader aStatic[4];
328   Fts5PoslistReader *aIter = aStatic;
329   int nIter = 0;
330   int nAlloc = 4;
331   int rc = SQLITE_OK;
332   Fts5ExprTerm *p;
333 
334   assert( pTerm->pSynonym );
335   for(p=pTerm; p; p=p->pSynonym){
336     Fts5IndexIter *pIter = p->pIter;
337     if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){
338       if( pIter->nData==0 ) continue;
339       if( nIter==nAlloc ){
340         int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
341         Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
342         if( aNew==0 ){
343           rc = SQLITE_NOMEM;
344           goto synonym_poslist_out;
345         }
346         memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
347         nAlloc = nAlloc*2;
348         if( aIter!=aStatic ) sqlite3_free(aIter);
349         aIter = aNew;
350       }
351       sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]);
352       assert( aIter[nIter].bEof==0 );
353       nIter++;
354     }
355   }
356 
357   if( nIter==1 ){
358     *pa = (u8*)aIter[0].a;
359     *pn = aIter[0].n;
360   }else{
361     Fts5PoslistWriter writer = {0};
362     i64 iPrev = -1;
363     fts5BufferZero(pBuf);
364     while( 1 ){
365       int i;
366       i64 iMin = FTS5_LARGEST_INT64;
367       for(i=0; i<nIter; i++){
368         if( aIter[i].bEof==0 ){
369           if( aIter[i].iPos==iPrev ){
370             if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) continue;
371           }
372           if( aIter[i].iPos<iMin ){
373             iMin = aIter[i].iPos;
374           }
375         }
376       }
377       if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break;
378       rc = sqlite3Fts5PoslistWriterAppend(pBuf, &writer, iMin);
379       iPrev = iMin;
380     }
381     if( rc==SQLITE_OK ){
382       *pa = pBuf->p;
383       *pn = pBuf->n;
384     }
385   }
386 
387  synonym_poslist_out:
388   if( aIter!=aStatic ) sqlite3_free(aIter);
389   return rc;
390 }
391 
392 
393 /*
394 ** All individual term iterators in pPhrase are guaranteed to be valid and
395 ** pointing to the same rowid when this function is called. This function
396 ** checks if the current rowid really is a match, and if so populates
397 ** the pPhrase->poslist buffer accordingly. Output parameter *pbMatch
398 ** is set to true if this is really a match, or false otherwise.
399 **
400 ** SQLITE_OK is returned if an error occurs, or an SQLite error code
401 ** otherwise. It is not considered an error code if the current rowid is
402 ** not a match.
403 */
404 static int fts5ExprPhraseIsMatch(
405   Fts5ExprNode *pNode,            /* Node pPhrase belongs to */
406   Fts5ExprPhrase *pPhrase,        /* Phrase object to initialize */
407   int *pbMatch                    /* OUT: Set to true if really a match */
408 ){
409   Fts5PoslistWriter writer = {0};
410   Fts5PoslistReader aStatic[4];
411   Fts5PoslistReader *aIter = aStatic;
412   int i;
413   int rc = SQLITE_OK;
414 
415   fts5BufferZero(&pPhrase->poslist);
416 
417   /* If the aStatic[] array is not large enough, allocate a large array
418   ** using sqlite3_malloc(). This approach could be improved upon. */
419   if( pPhrase->nTerm>ArraySize(aStatic) ){
420     int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
421     aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
422     if( !aIter ) return SQLITE_NOMEM;
423   }
424   memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
425 
426   /* Initialize a term iterator for each term in the phrase */
427   for(i=0; i<pPhrase->nTerm; i++){
428     Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
429     int n = 0;
430     int bFlag = 0;
431     u8 *a = 0;
432     if( pTerm->pSynonym ){
433       Fts5Buffer buf = {0, 0, 0};
434       rc = fts5ExprSynonymList(pTerm, pNode->iRowid, &buf, &a, &n);
435       if( rc ){
436         sqlite3_free(a);
437         goto ismatch_out;
438       }
439       if( a==buf.p ) bFlag = 1;
440     }else{
441       a = (u8*)pTerm->pIter->pData;
442       n = pTerm->pIter->nData;
443     }
444     sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
445     aIter[i].bFlag = (u8)bFlag;
446     if( aIter[i].bEof ) goto ismatch_out;
447   }
448 
449   while( 1 ){
450     int bMatch;
451     i64 iPos = aIter[0].iPos;
452     do {
453       bMatch = 1;
454       for(i=0; i<pPhrase->nTerm; i++){
455         Fts5PoslistReader *pPos = &aIter[i];
456         i64 iAdj = iPos + i;
457         if( pPos->iPos!=iAdj ){
458           bMatch = 0;
459           while( pPos->iPos<iAdj ){
460             if( sqlite3Fts5PoslistReaderNext(pPos) ) goto ismatch_out;
461           }
462           if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
463         }
464       }
465     }while( bMatch==0 );
466 
467     /* Append position iPos to the output */
468     rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
469     if( rc!=SQLITE_OK ) goto ismatch_out;
470 
471     for(i=0; i<pPhrase->nTerm; i++){
472       if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
473     }
474   }
475 
476  ismatch_out:
477   *pbMatch = (pPhrase->poslist.n>0);
478   for(i=0; i<pPhrase->nTerm; i++){
479     if( aIter[i].bFlag ) sqlite3_free((u8*)aIter[i].a);
480   }
481   if( aIter!=aStatic ) sqlite3_free(aIter);
482   return rc;
483 }
484 
485 typedef struct Fts5LookaheadReader Fts5LookaheadReader;
486 struct Fts5LookaheadReader {
487   const u8 *a;                    /* Buffer containing position list */
488   int n;                          /* Size of buffer a[] in bytes */
489   int i;                          /* Current offset in position list */
490   i64 iPos;                       /* Current position */
491   i64 iLookahead;                 /* Next position */
492 };
493 
494 #define FTS5_LOOKAHEAD_EOF (((i64)1) << 62)
495 
496 static int fts5LookaheadReaderNext(Fts5LookaheadReader *p){
497   p->iPos = p->iLookahead;
498   if( sqlite3Fts5PoslistNext64(p->a, p->n, &p->i, &p->iLookahead) ){
499     p->iLookahead = FTS5_LOOKAHEAD_EOF;
500   }
501   return (p->iPos==FTS5_LOOKAHEAD_EOF);
502 }
503 
504 static int fts5LookaheadReaderInit(
505   const u8 *a, int n,             /* Buffer to read position list from */
506   Fts5LookaheadReader *p          /* Iterator object to initialize */
507 ){
508   memset(p, 0, sizeof(Fts5LookaheadReader));
509   p->a = a;
510   p->n = n;
511   fts5LookaheadReaderNext(p);
512   return fts5LookaheadReaderNext(p);
513 }
514 
515 typedef struct Fts5NearTrimmer Fts5NearTrimmer;
516 struct Fts5NearTrimmer {
517   Fts5LookaheadReader reader;     /* Input iterator */
518   Fts5PoslistWriter writer;       /* Writer context */
519   Fts5Buffer *pOut;               /* Output poslist */
520 };
521 
522 /*
523 ** The near-set object passed as the first argument contains more than
524 ** one phrase. All phrases currently point to the same row. The
525 ** Fts5ExprPhrase.poslist buffers are populated accordingly. This function
526 ** tests if the current row contains instances of each phrase sufficiently
527 ** close together to meet the NEAR constraint. Non-zero is returned if it
528 ** does, or zero otherwise.
529 **
530 ** If in/out parameter (*pRc) is set to other than SQLITE_OK when this
531 ** function is called, it is a no-op. Or, if an error (e.g. SQLITE_NOMEM)
532 ** occurs within this function (*pRc) is set accordingly before returning.
533 ** The return value is undefined in both these cases.
534 **
535 ** If no error occurs and non-zero (a match) is returned, the position-list
536 ** of each phrase object is edited to contain only those entries that
537 ** meet the constraint before returning.
538 */
539 static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
540   Fts5NearTrimmer aStatic[4];
541   Fts5NearTrimmer *a = aStatic;
542   Fts5ExprPhrase **apPhrase = pNear->apPhrase;
543 
544   int i;
545   int rc = *pRc;
546   int bMatch;
547 
548   assert( pNear->nPhrase>1 );
549 
550   /* If the aStatic[] array is not large enough, allocate a large array
551   ** using sqlite3_malloc(). This approach could be improved upon. */
552   if( pNear->nPhrase>ArraySize(aStatic) ){
553     int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
554     a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
555   }else{
556     memset(aStatic, 0, sizeof(aStatic));
557   }
558   if( rc!=SQLITE_OK ){
559     *pRc = rc;
560     return 0;
561   }
562 
563   /* Initialize a lookahead iterator for each phrase. After passing the
564   ** buffer and buffer size to the lookaside-reader init function, zero
565   ** the phrase poslist buffer. The new poslist for the phrase (containing
566   ** the same entries as the original with some entries removed on account
567   ** of the NEAR constraint) is written over the original even as it is
568   ** being read. This is safe as the entries for the new poslist are a
569   ** subset of the old, so it is not possible for data yet to be read to
570   ** be overwritten.  */
571   for(i=0; i<pNear->nPhrase; i++){
572     Fts5Buffer *pPoslist = &apPhrase[i]->poslist;
573     fts5LookaheadReaderInit(pPoslist->p, pPoslist->n, &a[i].reader);
574     pPoslist->n = 0;
575     a[i].pOut = pPoslist;
576   }
577 
578   while( 1 ){
579     int iAdv;
580     i64 iMin;
581     i64 iMax;
582 
583     /* This block advances the phrase iterators until they point to a set of
584     ** entries that together comprise a match.  */
585     iMax = a[0].reader.iPos;
586     do {
587       bMatch = 1;
588       for(i=0; i<pNear->nPhrase; i++){
589         Fts5LookaheadReader *pPos = &a[i].reader;
590         iMin = iMax - pNear->apPhrase[i]->nTerm - pNear->nNear;
591         if( pPos->iPos<iMin || pPos->iPos>iMax ){
592           bMatch = 0;
593           while( pPos->iPos<iMin ){
594             if( fts5LookaheadReaderNext(pPos) ) goto ismatch_out;
595           }
596           if( pPos->iPos>iMax ) iMax = pPos->iPos;
597         }
598       }
599     }while( bMatch==0 );
600 
601     /* Add an entry to each output position list */
602     for(i=0; i<pNear->nPhrase; i++){
603       i64 iPos = a[i].reader.iPos;
604       Fts5PoslistWriter *pWriter = &a[i].writer;
605       if( a[i].pOut->n==0 || iPos!=pWriter->iPrev ){
606         sqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos);
607       }
608     }
609 
610     iAdv = 0;
611     iMin = a[0].reader.iLookahead;
612     for(i=0; i<pNear->nPhrase; i++){
613       if( a[i].reader.iLookahead < iMin ){
614         iMin = a[i].reader.iLookahead;
615         iAdv = i;
616       }
617     }
618     if( fts5LookaheadReaderNext(&a[iAdv].reader) ) goto ismatch_out;
619   }
620 
621   ismatch_out: {
622     int bRet = a[0].pOut->n>0;
623     *pRc = rc;
624     if( a!=aStatic ) sqlite3_free(a);
625     return bRet;
626   }
627 }
628 
629 /*
630 ** Advance iterator pIter until it points to a value equal to or laster
631 ** than the initial value of *piLast. If this means the iterator points
632 ** to a value laster than *piLast, update *piLast to the new lastest value.
633 **
634 ** If the iterator reaches EOF, set *pbEof to true before returning. If
635 ** an error occurs, set *pRc to an error code. If either *pbEof or *pRc
636 ** are set, return a non-zero value. Otherwise, return zero.
637 */
638 static int fts5ExprAdvanceto(
639   Fts5IndexIter *pIter,           /* Iterator to advance */
640   int bDesc,                      /* True if iterator is "rowid DESC" */
641   i64 *piLast,                    /* IN/OUT: Lastest rowid seen so far */
642   int *pRc,                       /* OUT: Error code */
643   int *pbEof                      /* OUT: Set to true if EOF */
644 ){
645   i64 iLast = *piLast;
646   i64 iRowid;
647 
648   iRowid = pIter->iRowid;
649   if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
650     int rc = sqlite3Fts5IterNextFrom(pIter, iLast);
651     if( rc || sqlite3Fts5IterEof(pIter) ){
652       *pRc = rc;
653       *pbEof = 1;
654       return 1;
655     }
656     iRowid = pIter->iRowid;
657     assert( (bDesc==0 && iRowid>=iLast) || (bDesc==1 && iRowid<=iLast) );
658   }
659   *piLast = iRowid;
660 
661   return 0;
662 }
663 
664 static int fts5ExprSynonymAdvanceto(
665   Fts5ExprTerm *pTerm,            /* Term iterator to advance */
666   int bDesc,                      /* True if iterator is "rowid DESC" */
667   i64 *piLast,                    /* IN/OUT: Lastest rowid seen so far */
668   int *pRc                        /* OUT: Error code */
669 ){
670   int rc = SQLITE_OK;
671   i64 iLast = *piLast;
672   Fts5ExprTerm *p;
673   int bEof = 0;
674 
675   for(p=pTerm; rc==SQLITE_OK && p; p=p->pSynonym){
676     if( sqlite3Fts5IterEof(p->pIter)==0 ){
677       i64 iRowid = p->pIter->iRowid;
678       if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
679         rc = sqlite3Fts5IterNextFrom(p->pIter, iLast);
680       }
681     }
682   }
683 
684   if( rc!=SQLITE_OK ){
685     *pRc = rc;
686     bEof = 1;
687   }else{
688     *piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
689   }
690   return bEof;
691 }
692 
693 
694 static int fts5ExprNearTest(
695   int *pRc,
696   Fts5Expr *pExpr,                /* Expression that pNear is a part of */
697   Fts5ExprNode *pNode             /* The "NEAR" node (FTS5_STRING) */
698 ){
699   Fts5ExprNearset *pNear = pNode->pNear;
700   int rc = *pRc;
701 
702   if( pExpr->pConfig->eDetail!=FTS5_DETAIL_FULL ){
703     Fts5ExprTerm *pTerm;
704     Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
705     pPhrase->poslist.n = 0;
706     for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
707       Fts5IndexIter *pIter = pTerm->pIter;
708       if( sqlite3Fts5IterEof(pIter)==0 ){
709         if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){
710           pPhrase->poslist.n = 1;
711         }
712       }
713     }
714     return pPhrase->poslist.n;
715   }else{
716     int i;
717 
718     /* Check that each phrase in the nearset matches the current row.
719     ** Populate the pPhrase->poslist buffers at the same time. If any
720     ** phrase is not a match, break out of the loop early.  */
721     for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
722       Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
723       if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
724         int bMatch = 0;
725         rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
726         if( bMatch==0 ) break;
727       }else{
728         Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
729         fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData);
730       }
731     }
732 
733     *pRc = rc;
734     if( i==pNear->nPhrase && (i==1 || fts5ExprNearIsMatch(pRc, pNear)) ){
735       return 1;
736     }
737     return 0;
738   }
739 }
740 
741 
742 /*
743 ** Initialize all term iterators in the pNear object. If any term is found
744 ** to match no documents at all, return immediately without initializing any
745 ** further iterators.
746 */
747 static int fts5ExprNearInitAll(
748   Fts5Expr *pExpr,
749   Fts5ExprNode *pNode
750 ){
751   Fts5ExprNearset *pNear = pNode->pNear;
752   int i, j;
753   int rc = SQLITE_OK;
754 
755   assert( pNode->bNomatch==0 );
756   for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
757     Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
758     for(j=0; j<pPhrase->nTerm; j++){
759       Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
760       Fts5ExprTerm *p;
761       int bEof = 1;
762 
763       for(p=pTerm; p && rc==SQLITE_OK; p=p->pSynonym){
764         if( p->pIter ){
765           sqlite3Fts5IterClose(p->pIter);
766           p->pIter = 0;
767         }
768         rc = sqlite3Fts5IndexQuery(
769             pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
770             (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
771             (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
772             pNear->pColset,
773             &p->pIter
774         );
775         assert( rc==SQLITE_OK || p->pIter==0 );
776         if( p->pIter && 0==sqlite3Fts5IterEof(p->pIter) ){
777           bEof = 0;
778         }
779       }
780 
781       if( bEof ){
782         pNode->bEof = 1;
783         return rc;
784       }
785     }
786   }
787 
788   return rc;
789 }
790 
791 /*
792 ** If pExpr is an ASC iterator, this function returns a value with the
793 ** same sign as:
794 **
795 **   (iLhs - iRhs)
796 **
797 ** Otherwise, if this is a DESC iterator, the opposite is returned:
798 **
799 **   (iRhs - iLhs)
800 */
801 static int fts5RowidCmp(
802   Fts5Expr *pExpr,
803   i64 iLhs,
804   i64 iRhs
805 ){
806   assert( pExpr->bDesc==0 || pExpr->bDesc==1 );
807   if( pExpr->bDesc==0 ){
808     if( iLhs<iRhs ) return -1;
809     return (iLhs > iRhs);
810   }else{
811     if( iLhs>iRhs ) return -1;
812     return (iLhs < iRhs);
813   }
814 }
815 
816 static void fts5ExprSetEof(Fts5ExprNode *pNode){
817   int i;
818   pNode->bEof = 1;
819   pNode->bNomatch = 0;
820   for(i=0; i<pNode->nChild; i++){
821     fts5ExprSetEof(pNode->apChild[i]);
822   }
823 }
824 
825 static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){
826   if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
827     Fts5ExprNearset *pNear = pNode->pNear;
828     int i;
829     for(i=0; i<pNear->nPhrase; i++){
830       Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
831       pPhrase->poslist.n = 0;
832     }
833   }else{
834     int i;
835     for(i=0; i<pNode->nChild; i++){
836       fts5ExprNodeZeroPoslist(pNode->apChild[i]);
837     }
838   }
839 }
840 
841 
842 
843 /*
844 ** Compare the values currently indicated by the two nodes as follows:
845 **
846 **    res = (*p1) - (*p2)
847 **
848 ** Nodes that point to values that come later in the iteration order are
849 ** considered to be larger. Nodes at EOF are the largest of all.
850 **
851 ** This means that if the iteration order is ASC, then numerically larger
852 ** rowids are considered larger. Or if it is the default DESC, numerically
853 ** smaller rowids are larger.
854 */
855 static int fts5NodeCompare(
856   Fts5Expr *pExpr,
857   Fts5ExprNode *p1,
858   Fts5ExprNode *p2
859 ){
860   if( p2->bEof ) return -1;
861   if( p1->bEof ) return +1;
862   return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid);
863 }
864 
865 /*
866 ** All individual term iterators in pNear are guaranteed to be valid when
867 ** this function is called. This function checks if all term iterators
868 ** point to the same rowid, and if not, advances them until they do.
869 ** If an EOF is reached before this happens, *pbEof is set to true before
870 ** returning.
871 **
872 ** SQLITE_OK is returned if an error occurs, or an SQLite error code
873 ** otherwise. It is not considered an error code if an iterator reaches
874 ** EOF.
875 */
876 static int fts5ExprNodeTest_STRING(
877   Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
878   Fts5ExprNode *pNode
879 ){
880   Fts5ExprNearset *pNear = pNode->pNear;
881   Fts5ExprPhrase *pLeft = pNear->apPhrase[0];
882   int rc = SQLITE_OK;
883   i64 iLast;                      /* Lastest rowid any iterator points to */
884   int i, j;                       /* Phrase and token index, respectively */
885   int bMatch;                     /* True if all terms are at the same rowid */
886   const int bDesc = pExpr->bDesc;
887 
888   /* Check that this node should not be FTS5_TERM */
889   assert( pNear->nPhrase>1
890        || pNear->apPhrase[0]->nTerm>1
891        || pNear->apPhrase[0]->aTerm[0].pSynonym
892   );
893 
894   /* Initialize iLast, the "lastest" rowid any iterator points to. If the
895   ** iterator skips through rowids in the default ascending order, this means
896   ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it
897   ** means the minimum rowid.  */
898   if( pLeft->aTerm[0].pSynonym ){
899     iLast = fts5ExprSynonymRowid(&pLeft->aTerm[0], bDesc, 0);
900   }else{
901     iLast = pLeft->aTerm[0].pIter->iRowid;
902   }
903 
904   do {
905     bMatch = 1;
906     for(i=0; i<pNear->nPhrase; i++){
907       Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
908       for(j=0; j<pPhrase->nTerm; j++){
909         Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
910         if( pTerm->pSynonym ){
911           i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0);
912           if( iRowid==iLast ) continue;
913           bMatch = 0;
914           if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){
915             pNode->bNomatch = 0;
916             pNode->bEof = 1;
917             return rc;
918           }
919         }else{
920           Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
921           if( pIter->iRowid==iLast ) continue;
922           bMatch = 0;
923           if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
924             return rc;
925           }
926         }
927       }
928     }
929   }while( bMatch==0 );
930 
931   pNode->iRowid = iLast;
932   pNode->bNomatch = ((0==fts5ExprNearTest(&rc, pExpr, pNode)) && rc==SQLITE_OK);
933   assert( pNode->bEof==0 || pNode->bNomatch==0 );
934 
935   return rc;
936 }
937 
938 /*
939 ** Advance the first term iterator in the first phrase of pNear. Set output
940 ** variable *pbEof to true if it reaches EOF or if an error occurs.
941 **
942 ** Return SQLITE_OK if successful, or an SQLite error code if an error
943 ** occurs.
944 */
945 static int fts5ExprNodeNext_STRING(
946   Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
947   Fts5ExprNode *pNode,            /* FTS5_STRING or FTS5_TERM node */
948   int bFromValid,
949   i64 iFrom
950 ){
951   Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0];
952   int rc = SQLITE_OK;
953 
954   pNode->bNomatch = 0;
955   if( pTerm->pSynonym ){
956     int bEof = 1;
957     Fts5ExprTerm *p;
958 
959     /* Find the firstest rowid any synonym points to. */
960     i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0);
961 
962     /* Advance each iterator that currently points to iRowid. Or, if iFrom
963     ** is valid - each iterator that points to a rowid before iFrom.  */
964     for(p=pTerm; p; p=p->pSynonym){
965       if( sqlite3Fts5IterEof(p->pIter)==0 ){
966         i64 ii = p->pIter->iRowid;
967         if( ii==iRowid
968          || (bFromValid && ii!=iFrom && (ii>iFrom)==pExpr->bDesc)
969         ){
970           if( bFromValid ){
971             rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom);
972           }else{
973             rc = sqlite3Fts5IterNext(p->pIter);
974           }
975           if( rc!=SQLITE_OK ) break;
976           if( sqlite3Fts5IterEof(p->pIter)==0 ){
977             bEof = 0;
978           }
979         }else{
980           bEof = 0;
981         }
982       }
983     }
984 
985     /* Set the EOF flag if either all synonym iterators are at EOF or an
986     ** error has occurred.  */
987     pNode->bEof = (rc || bEof);
988   }else{
989     Fts5IndexIter *pIter = pTerm->pIter;
990 
991     assert( Fts5NodeIsString(pNode) );
992     if( bFromValid ){
993       rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
994     }else{
995       rc = sqlite3Fts5IterNext(pIter);
996     }
997 
998     pNode->bEof = (rc || sqlite3Fts5IterEof(pIter));
999   }
1000 
1001   if( pNode->bEof==0 ){
1002     assert( rc==SQLITE_OK );
1003     rc = fts5ExprNodeTest_STRING(pExpr, pNode);
1004   }
1005 
1006   return rc;
1007 }
1008 
1009 
1010 static int fts5ExprNodeTest_TERM(
1011   Fts5Expr *pExpr,                /* Expression that pNear is a part of */
1012   Fts5ExprNode *pNode             /* The "NEAR" node (FTS5_TERM) */
1013 ){
1014   /* As this "NEAR" object is actually a single phrase that consists
1015   ** of a single term only, grab pointers into the poslist managed by the
1016   ** fts5_index.c iterator object. This is much faster than synthesizing
1017   ** a new poslist the way we have to for more complicated phrase or NEAR
1018   ** expressions.  */
1019   Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0];
1020   Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
1021 
1022   assert( pNode->eType==FTS5_TERM );
1023   assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 );
1024   assert( pPhrase->aTerm[0].pSynonym==0 );
1025 
1026   pPhrase->poslist.n = pIter->nData;
1027   if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){
1028     pPhrase->poslist.p = (u8*)pIter->pData;
1029   }
1030   pNode->iRowid = pIter->iRowid;
1031   pNode->bNomatch = (pPhrase->poslist.n==0);
1032   return SQLITE_OK;
1033 }
1034 
1035 /*
1036 ** xNext() method for a node of type FTS5_TERM.
1037 */
1038 static int fts5ExprNodeNext_TERM(
1039   Fts5Expr *pExpr,
1040   Fts5ExprNode *pNode,
1041   int bFromValid,
1042   i64 iFrom
1043 ){
1044   int rc;
1045   Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter;
1046 
1047   assert( pNode->bEof==0 );
1048   if( bFromValid ){
1049     rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
1050   }else{
1051     rc = sqlite3Fts5IterNext(pIter);
1052   }
1053   if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){
1054     rc = fts5ExprNodeTest_TERM(pExpr, pNode);
1055   }else{
1056     pNode->bEof = 1;
1057     pNode->bNomatch = 0;
1058   }
1059   return rc;
1060 }
1061 
1062 static void fts5ExprNodeTest_OR(
1063   Fts5Expr *pExpr,                /* Expression of which pNode is a part */
1064   Fts5ExprNode *pNode             /* Expression node to test */
1065 ){
1066   Fts5ExprNode *pNext = pNode->apChild[0];
1067   int i;
1068 
1069   for(i=1; i<pNode->nChild; i++){
1070     Fts5ExprNode *pChild = pNode->apChild[i];
1071     int cmp = fts5NodeCompare(pExpr, pNext, pChild);
1072     if( cmp>0 || (cmp==0 && pChild->bNomatch==0) ){
1073       pNext = pChild;
1074     }
1075   }
1076   pNode->iRowid = pNext->iRowid;
1077   pNode->bEof = pNext->bEof;
1078   pNode->bNomatch = pNext->bNomatch;
1079 }
1080 
1081 static int fts5ExprNodeNext_OR(
1082   Fts5Expr *pExpr,
1083   Fts5ExprNode *pNode,
1084   int bFromValid,
1085   i64 iFrom
1086 ){
1087   int i;
1088   i64 iLast = pNode->iRowid;
1089 
1090   for(i=0; i<pNode->nChild; i++){
1091     Fts5ExprNode *p1 = pNode->apChild[i];
1092     assert( p1->bEof || fts5RowidCmp(pExpr, p1->iRowid, iLast)>=0 );
1093     if( p1->bEof==0 ){
1094       if( (p1->iRowid==iLast)
1095        || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
1096       ){
1097         int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
1098         if( rc!=SQLITE_OK ) return rc;
1099       }
1100     }
1101   }
1102 
1103   fts5ExprNodeTest_OR(pExpr, pNode);
1104   return SQLITE_OK;
1105 }
1106 
1107 /*
1108 ** Argument pNode is an FTS5_AND node.
1109 */
1110 static int fts5ExprNodeTest_AND(
1111   Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
1112   Fts5ExprNode *pAnd              /* FTS5_AND node to advance */
1113 ){
1114   int iChild;
1115   i64 iLast = pAnd->iRowid;
1116   int rc = SQLITE_OK;
1117   int bMatch;
1118 
1119   assert( pAnd->bEof==0 );
1120   do {
1121     pAnd->bNomatch = 0;
1122     bMatch = 1;
1123     for(iChild=0; iChild<pAnd->nChild; iChild++){
1124       Fts5ExprNode *pChild = pAnd->apChild[iChild];
1125       int cmp = fts5RowidCmp(pExpr, iLast, pChild->iRowid);
1126       if( cmp>0 ){
1127         /* Advance pChild until it points to iLast or laster */
1128         rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
1129         if( rc!=SQLITE_OK ) return rc;
1130       }
1131 
1132       /* If the child node is now at EOF, so is the parent AND node. Otherwise,
1133       ** the child node is guaranteed to have advanced at least as far as
1134       ** rowid iLast. So if it is not at exactly iLast, pChild->iRowid is the
1135       ** new lastest rowid seen so far.  */
1136       assert( pChild->bEof || fts5RowidCmp(pExpr, iLast, pChild->iRowid)<=0 );
1137       if( pChild->bEof ){
1138         fts5ExprSetEof(pAnd);
1139         bMatch = 1;
1140         break;
1141       }else if( iLast!=pChild->iRowid ){
1142         bMatch = 0;
1143         iLast = pChild->iRowid;
1144       }
1145 
1146       if( pChild->bNomatch ){
1147         pAnd->bNomatch = 1;
1148       }
1149     }
1150   }while( bMatch==0 );
1151 
1152   if( pAnd->bNomatch && pAnd!=pExpr->pRoot ){
1153     fts5ExprNodeZeroPoslist(pAnd);
1154   }
1155   pAnd->iRowid = iLast;
1156   return SQLITE_OK;
1157 }
1158 
1159 static int fts5ExprNodeNext_AND(
1160   Fts5Expr *pExpr,
1161   Fts5ExprNode *pNode,
1162   int bFromValid,
1163   i64 iFrom
1164 ){
1165   int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
1166   if( rc==SQLITE_OK ){
1167     rc = fts5ExprNodeTest_AND(pExpr, pNode);
1168   }
1169   return rc;
1170 }
1171 
1172 static int fts5ExprNodeTest_NOT(
1173   Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
1174   Fts5ExprNode *pNode             /* FTS5_NOT node to advance */
1175 ){
1176   int rc = SQLITE_OK;
1177   Fts5ExprNode *p1 = pNode->apChild[0];
1178   Fts5ExprNode *p2 = pNode->apChild[1];
1179   assert( pNode->nChild==2 );
1180 
1181   while( rc==SQLITE_OK && p1->bEof==0 ){
1182     int cmp = fts5NodeCompare(pExpr, p1, p2);
1183     if( cmp>0 ){
1184       rc = fts5ExprNodeNext(pExpr, p2, 1, p1->iRowid);
1185       cmp = fts5NodeCompare(pExpr, p1, p2);
1186     }
1187     assert( rc!=SQLITE_OK || cmp<=0 );
1188     if( cmp || p2->bNomatch ) break;
1189     rc = fts5ExprNodeNext(pExpr, p1, 0, 0);
1190   }
1191   pNode->bEof = p1->bEof;
1192   pNode->bNomatch = p1->bNomatch;
1193   pNode->iRowid = p1->iRowid;
1194   if( p1->bEof ){
1195     fts5ExprNodeZeroPoslist(p2);
1196   }
1197   return rc;
1198 }
1199 
1200 static int fts5ExprNodeNext_NOT(
1201   Fts5Expr *pExpr,
1202   Fts5ExprNode *pNode,
1203   int bFromValid,
1204   i64 iFrom
1205 ){
1206   int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
1207   if( rc==SQLITE_OK ){
1208     rc = fts5ExprNodeTest_NOT(pExpr, pNode);
1209   }
1210   return rc;
1211 }
1212 
1213 /*
1214 ** If pNode currently points to a match, this function returns SQLITE_OK
1215 ** without modifying it. Otherwise, pNode is advanced until it does point
1216 ** to a match or EOF is reached.
1217 */
1218 static int fts5ExprNodeTest(
1219   Fts5Expr *pExpr,                /* Expression of which pNode is a part */
1220   Fts5ExprNode *pNode             /* Expression node to test */
1221 ){
1222   int rc = SQLITE_OK;
1223   if( pNode->bEof==0 ){
1224     switch( pNode->eType ){
1225 
1226       case FTS5_STRING: {
1227         rc = fts5ExprNodeTest_STRING(pExpr, pNode);
1228         break;
1229       }
1230 
1231       case FTS5_TERM: {
1232         rc = fts5ExprNodeTest_TERM(pExpr, pNode);
1233         break;
1234       }
1235 
1236       case FTS5_AND: {
1237         rc = fts5ExprNodeTest_AND(pExpr, pNode);
1238         break;
1239       }
1240 
1241       case FTS5_OR: {
1242         fts5ExprNodeTest_OR(pExpr, pNode);
1243         break;
1244       }
1245 
1246       default: assert( pNode->eType==FTS5_NOT ); {
1247         rc = fts5ExprNodeTest_NOT(pExpr, pNode);
1248         break;
1249       }
1250     }
1251   }
1252   return rc;
1253 }
1254 
1255 
1256 /*
1257 ** Set node pNode, which is part of expression pExpr, to point to the first
1258 ** match. If there are no matches, set the Node.bEof flag to indicate EOF.
1259 **
1260 ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
1261 ** It is not an error if there are no matches.
1262 */
1263 static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
1264   int rc = SQLITE_OK;
1265   pNode->bEof = 0;
1266   pNode->bNomatch = 0;
1267 
1268   if( Fts5NodeIsString(pNode) ){
1269     /* Initialize all term iterators in the NEAR object. */
1270     rc = fts5ExprNearInitAll(pExpr, pNode);
1271   }else{
1272     int i;
1273     int nEof = 0;
1274     for(i=0; i<pNode->nChild && rc==SQLITE_OK; i++){
1275       Fts5ExprNode *pChild = pNode->apChild[i];
1276       rc = fts5ExprNodeFirst(pExpr, pNode->apChild[i]);
1277       assert( pChild->bEof==0 || pChild->bEof==1 );
1278       nEof += pChild->bEof;
1279     }
1280     pNode->iRowid = pNode->apChild[0]->iRowid;
1281 
1282     switch( pNode->eType ){
1283       case FTS5_AND:
1284         if( nEof>0 ) fts5ExprSetEof(pNode);
1285         break;
1286 
1287       case FTS5_OR:
1288         if( pNode->nChild==nEof ) fts5ExprSetEof(pNode);
1289         break;
1290 
1291       default:
1292         assert( pNode->eType==FTS5_NOT );
1293         pNode->bEof = pNode->apChild[0]->bEof;
1294         break;
1295     }
1296   }
1297 
1298   if( rc==SQLITE_OK ){
1299     rc = fts5ExprNodeTest(pExpr, pNode);
1300   }
1301   return rc;
1302 }
1303 
1304 
1305 /*
1306 ** Begin iterating through the set of documents in index pIdx matched by
1307 ** the MATCH expression passed as the first argument. If the "bDesc"
1308 ** parameter is passed a non-zero value, iteration is in descending rowid
1309 ** order. Or, if it is zero, in ascending order.
1310 **
1311 ** If iterating in ascending rowid order (bDesc==0), the first document
1312 ** visited is that with the smallest rowid that is larger than or equal
1313 ** to parameter iFirst. Or, if iterating in ascending order (bDesc==1),
1314 ** then the first document visited must have a rowid smaller than or
1315 ** equal to iFirst.
1316 **
1317 ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
1318 ** is not considered an error if the query does not match any documents.
1319 */
1320 int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
1321   Fts5ExprNode *pRoot = p->pRoot;
1322   int rc = SQLITE_OK;
1323   if( pRoot->xNext ){
1324     p->pIndex = pIdx;
1325     p->bDesc = bDesc;
1326     rc = fts5ExprNodeFirst(p, pRoot);
1327 
1328     /* If not at EOF but the current rowid occurs earlier than iFirst in
1329     ** the iteration order, move to document iFirst or later. */
1330     if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){
1331       rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
1332     }
1333 
1334     /* If the iterator is not at a real match, skip forward until it is. */
1335     while( pRoot->bNomatch ){
1336       assert( pRoot->bEof==0 && rc==SQLITE_OK );
1337       rc = fts5ExprNodeNext(p, pRoot, 0, 0);
1338     }
1339   }
1340   return rc;
1341 }
1342 
1343 /*
1344 ** Move to the next document
1345 **
1346 ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
1347 ** is not considered an error if the query does not match any documents.
1348 */
1349 int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){
1350   int rc;
1351   Fts5ExprNode *pRoot = p->pRoot;
1352   assert( pRoot->bEof==0 && pRoot->bNomatch==0 );
1353   do {
1354     rc = fts5ExprNodeNext(p, pRoot, 0, 0);
1355     assert( pRoot->bNomatch==0 || (rc==SQLITE_OK && pRoot->bEof==0) );
1356   }while( pRoot->bNomatch );
1357   if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){
1358     pRoot->bEof = 1;
1359   }
1360   return rc;
1361 }
1362 
1363 int sqlite3Fts5ExprEof(Fts5Expr *p){
1364   return p->pRoot->bEof;
1365 }
1366 
1367 i64 sqlite3Fts5ExprRowid(Fts5Expr *p){
1368   return p->pRoot->iRowid;
1369 }
1370 
1371 static int fts5ParseStringFromToken(Fts5Token *pToken, char **pz){
1372   int rc = SQLITE_OK;
1373   *pz = sqlite3Fts5Strndup(&rc, pToken->p, pToken->n);
1374   return rc;
1375 }
1376 
1377 /*
1378 ** Free the phrase object passed as the only argument.
1379 */
1380 static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){
1381   if( pPhrase ){
1382     int i;
1383     for(i=0; i<pPhrase->nTerm; i++){
1384       Fts5ExprTerm *pSyn;
1385       Fts5ExprTerm *pNext;
1386       Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
1387       sqlite3_free(pTerm->zTerm);
1388       sqlite3Fts5IterClose(pTerm->pIter);
1389       for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
1390         pNext = pSyn->pSynonym;
1391         sqlite3Fts5IterClose(pSyn->pIter);
1392         fts5BufferFree((Fts5Buffer*)&pSyn[1]);
1393         sqlite3_free(pSyn);
1394       }
1395     }
1396     if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist);
1397     sqlite3_free(pPhrase);
1398   }
1399 }
1400 
1401 /*
1402 ** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
1403 ** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
1404 ** appended to it and the results returned.
1405 **
1406 ** If an OOM error occurs, both the pNear and pPhrase objects are freed and
1407 ** NULL returned.
1408 */
1409 Fts5ExprNearset *sqlite3Fts5ParseNearset(
1410   Fts5Parse *pParse,              /* Parse context */
1411   Fts5ExprNearset *pNear,         /* Existing nearset, or NULL */
1412   Fts5ExprPhrase *pPhrase         /* Recently parsed phrase */
1413 ){
1414   const int SZALLOC = 8;
1415   Fts5ExprNearset *pRet = 0;
1416 
1417   if( pParse->rc==SQLITE_OK ){
1418     if( pPhrase==0 ){
1419       return pNear;
1420     }
1421     if( pNear==0 ){
1422       int nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
1423       pRet = sqlite3_malloc(nByte);
1424       if( pRet==0 ){
1425         pParse->rc = SQLITE_NOMEM;
1426       }else{
1427         memset(pRet, 0, nByte);
1428       }
1429     }else if( (pNear->nPhrase % SZALLOC)==0 ){
1430       int nNew = pNear->nPhrase + SZALLOC;
1431       int nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
1432 
1433       pRet = (Fts5ExprNearset*)sqlite3_realloc(pNear, nByte);
1434       if( pRet==0 ){
1435         pParse->rc = SQLITE_NOMEM;
1436       }
1437     }else{
1438       pRet = pNear;
1439     }
1440   }
1441 
1442   if( pRet==0 ){
1443     assert( pParse->rc!=SQLITE_OK );
1444     sqlite3Fts5ParseNearsetFree(pNear);
1445     sqlite3Fts5ParsePhraseFree(pPhrase);
1446   }else{
1447     pRet->apPhrase[pRet->nPhrase++] = pPhrase;
1448   }
1449   return pRet;
1450 }
1451 
1452 typedef struct TokenCtx TokenCtx;
1453 struct TokenCtx {
1454   Fts5ExprPhrase *pPhrase;
1455   int rc;
1456 };
1457 
1458 /*
1459 ** Callback for tokenizing terms used by ParseTerm().
1460 */
1461 static int fts5ParseTokenize(
1462   void *pContext,                 /* Pointer to Fts5InsertCtx object */
1463   int tflags,                     /* Mask of FTS5_TOKEN_* flags */
1464   const char *pToken,             /* Buffer containing token */
1465   int nToken,                     /* Size of token in bytes */
1466   int iUnused1,                   /* Start offset of token */
1467   int iUnused2                    /* End offset of token */
1468 ){
1469   int rc = SQLITE_OK;
1470   const int SZALLOC = 8;
1471   TokenCtx *pCtx = (TokenCtx*)pContext;
1472   Fts5ExprPhrase *pPhrase = pCtx->pPhrase;
1473 
1474   UNUSED_PARAM2(iUnused1, iUnused2);
1475 
1476   /* If an error has already occurred, this is a no-op */
1477   if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
1478 
1479   assert( pPhrase==0 || pPhrase->nTerm>0 );
1480   if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){
1481     Fts5ExprTerm *pSyn;
1482     int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
1483     pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
1484     if( pSyn==0 ){
1485       rc = SQLITE_NOMEM;
1486     }else{
1487       memset(pSyn, 0, nByte);
1488       pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
1489       memcpy(pSyn->zTerm, pToken, nToken);
1490       pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
1491       pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
1492     }
1493   }else{
1494     Fts5ExprTerm *pTerm;
1495     if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){
1496       Fts5ExprPhrase *pNew;
1497       int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
1498 
1499       pNew = (Fts5ExprPhrase*)sqlite3_realloc(pPhrase,
1500           sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
1501       );
1502       if( pNew==0 ){
1503         rc = SQLITE_NOMEM;
1504       }else{
1505         if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase));
1506         pCtx->pPhrase = pPhrase = pNew;
1507         pNew->nTerm = nNew - SZALLOC;
1508       }
1509     }
1510 
1511     if( rc==SQLITE_OK ){
1512       pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
1513       memset(pTerm, 0, sizeof(Fts5ExprTerm));
1514       pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
1515     }
1516   }
1517 
1518   pCtx->rc = rc;
1519   return rc;
1520 }
1521 
1522 
1523 /*
1524 ** Free the phrase object passed as the only argument.
1525 */
1526 void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase *pPhrase){
1527   fts5ExprPhraseFree(pPhrase);
1528 }
1529 
1530 /*
1531 ** Free the phrase object passed as the second argument.
1532 */
1533 void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset *pNear){
1534   if( pNear ){
1535     int i;
1536     for(i=0; i<pNear->nPhrase; i++){
1537       fts5ExprPhraseFree(pNear->apPhrase[i]);
1538     }
1539     sqlite3_free(pNear->pColset);
1540     sqlite3_free(pNear);
1541   }
1542 }
1543 
1544 void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){
1545   assert( pParse->pExpr==0 );
1546   pParse->pExpr = p;
1547 }
1548 
1549 /*
1550 ** This function is called by the parser to process a string token. The
1551 ** string may or may not be quoted. In any case it is tokenized and a
1552 ** phrase object consisting of all tokens returned.
1553 */
1554 Fts5ExprPhrase *sqlite3Fts5ParseTerm(
1555   Fts5Parse *pParse,              /* Parse context */
1556   Fts5ExprPhrase *pAppend,        /* Phrase to append to */
1557   Fts5Token *pToken,              /* String to tokenize */
1558   int bPrefix                     /* True if there is a trailing "*" */
1559 ){
1560   Fts5Config *pConfig = pParse->pConfig;
1561   TokenCtx sCtx;                  /* Context object passed to callback */
1562   int rc;                         /* Tokenize return code */
1563   char *z = 0;
1564 
1565   memset(&sCtx, 0, sizeof(TokenCtx));
1566   sCtx.pPhrase = pAppend;
1567 
1568   rc = fts5ParseStringFromToken(pToken, &z);
1569   if( rc==SQLITE_OK ){
1570     int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_QUERY : 0);
1571     int n;
1572     sqlite3Fts5Dequote(z);
1573     n = (int)strlen(z);
1574     rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize);
1575   }
1576   sqlite3_free(z);
1577   if( rc || (rc = sCtx.rc) ){
1578     pParse->rc = rc;
1579     fts5ExprPhraseFree(sCtx.pPhrase);
1580     sCtx.pPhrase = 0;
1581   }else if( sCtx.pPhrase ){
1582 
1583     if( pAppend==0 ){
1584       if( (pParse->nPhrase % 8)==0 ){
1585         int nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
1586         Fts5ExprPhrase **apNew;
1587         apNew = (Fts5ExprPhrase**)sqlite3_realloc(pParse->apPhrase, nByte);
1588         if( apNew==0 ){
1589           pParse->rc = SQLITE_NOMEM;
1590           fts5ExprPhraseFree(sCtx.pPhrase);
1591           return 0;
1592         }
1593         pParse->apPhrase = apNew;
1594       }
1595       pParse->nPhrase++;
1596     }
1597 
1598     pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
1599     assert( sCtx.pPhrase->nTerm>0 );
1600     sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
1601   }
1602 
1603   return sCtx.pPhrase;
1604 }
1605 
1606 /*
1607 ** Create a new FTS5 expression by cloning phrase iPhrase of the
1608 ** expression passed as the second argument.
1609 */
1610 int sqlite3Fts5ExprClonePhrase(
1611   Fts5Expr *pExpr,
1612   int iPhrase,
1613   Fts5Expr **ppNew
1614 ){
1615   int rc = SQLITE_OK;             /* Return code */
1616   Fts5ExprPhrase *pOrig;          /* The phrase extracted from pExpr */
1617   int i;                          /* Used to iterate through phrase terms */
1618   Fts5Expr *pNew = 0;             /* Expression to return via *ppNew */
1619   TokenCtx sCtx = {0,0};          /* Context object for fts5ParseTokenize */
1620 
1621   pOrig = pExpr->apExprPhrase[iPhrase];
1622   pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
1623   if( rc==SQLITE_OK ){
1624     pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
1625         sizeof(Fts5ExprPhrase*));
1626   }
1627   if( rc==SQLITE_OK ){
1628     pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc,
1629         sizeof(Fts5ExprNode));
1630   }
1631   if( rc==SQLITE_OK ){
1632     pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
1633         sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
1634   }
1635 
1636   for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
1637     int tflags = 0;
1638     Fts5ExprTerm *p;
1639     for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
1640       const char *zTerm = p->zTerm;
1641       rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
1642           0, 0);
1643       tflags = FTS5_TOKEN_COLOCATED;
1644     }
1645     if( rc==SQLITE_OK ){
1646       sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
1647     }
1648   }
1649 
1650   if( rc==SQLITE_OK ){
1651     /* All the allocations succeeded. Put the expression object together. */
1652     pNew->pIndex = pExpr->pIndex;
1653     pNew->pConfig = pExpr->pConfig;
1654     pNew->nPhrase = 1;
1655     pNew->apExprPhrase[0] = sCtx.pPhrase;
1656     pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase;
1657     pNew->pRoot->pNear->nPhrase = 1;
1658     sCtx.pPhrase->pNode = pNew->pRoot;
1659 
1660     if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){
1661       pNew->pRoot->eType = FTS5_TERM;
1662       pNew->pRoot->xNext = fts5ExprNodeNext_TERM;
1663     }else{
1664       pNew->pRoot->eType = FTS5_STRING;
1665       pNew->pRoot->xNext = fts5ExprNodeNext_STRING;
1666     }
1667   }else{
1668     sqlite3Fts5ExprFree(pNew);
1669     fts5ExprPhraseFree(sCtx.pPhrase);
1670     pNew = 0;
1671   }
1672 
1673   *ppNew = pNew;
1674   return rc;
1675 }
1676 
1677 
1678 /*
1679 ** Token pTok has appeared in a MATCH expression where the NEAR operator
1680 ** is expected. If token pTok does not contain "NEAR", store an error
1681 ** in the pParse object.
1682 */
1683 void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token *pTok){
1684   if( pTok->n!=4 || memcmp("NEAR", pTok->p, 4) ){
1685     sqlite3Fts5ParseError(
1686         pParse, "fts5: syntax error near \"%.*s\"", pTok->n, pTok->p
1687     );
1688   }
1689 }
1690 
1691 void sqlite3Fts5ParseSetDistance(
1692   Fts5Parse *pParse,
1693   Fts5ExprNearset *pNear,
1694   Fts5Token *p
1695 ){
1696   int nNear = 0;
1697   int i;
1698   if( p->n ){
1699     for(i=0; i<p->n; i++){
1700       char c = (char)p->p[i];
1701       if( c<'0' || c>'9' ){
1702         sqlite3Fts5ParseError(
1703             pParse, "expected integer, got \"%.*s\"", p->n, p->p
1704         );
1705         return;
1706       }
1707       nNear = nNear * 10 + (p->p[i] - '0');
1708     }
1709   }else{
1710     nNear = FTS5_DEFAULT_NEARDIST;
1711   }
1712   pNear->nNear = nNear;
1713 }
1714 
1715 /*
1716 ** The second argument passed to this function may be NULL, or it may be
1717 ** an existing Fts5Colset object. This function returns a pointer to
1718 ** a new colset object containing the contents of (p) with new value column
1719 ** number iCol appended.
1720 **
1721 ** If an OOM error occurs, store an error code in pParse and return NULL.
1722 ** The old colset object (if any) is not freed in this case.
1723 */
1724 static Fts5Colset *fts5ParseColset(
1725   Fts5Parse *pParse,              /* Store SQLITE_NOMEM here if required */
1726   Fts5Colset *p,                  /* Existing colset object */
1727   int iCol                        /* New column to add to colset object */
1728 ){
1729   int nCol = p ? p->nCol : 0;     /* Num. columns already in colset object */
1730   Fts5Colset *pNew;               /* New colset object to return */
1731 
1732   assert( pParse->rc==SQLITE_OK );
1733   assert( iCol>=0 && iCol<pParse->pConfig->nCol );
1734 
1735   pNew = sqlite3_realloc(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
1736   if( pNew==0 ){
1737     pParse->rc = SQLITE_NOMEM;
1738   }else{
1739     int *aiCol = pNew->aiCol;
1740     int i, j;
1741     for(i=0; i<nCol; i++){
1742       if( aiCol[i]==iCol ) return pNew;
1743       if( aiCol[i]>iCol ) break;
1744     }
1745     for(j=nCol; j>i; j--){
1746       aiCol[j] = aiCol[j-1];
1747     }
1748     aiCol[i] = iCol;
1749     pNew->nCol = nCol+1;
1750 
1751 #ifndef NDEBUG
1752     /* Check that the array is in order and contains no duplicate entries. */
1753     for(i=1; i<pNew->nCol; i++) assert( pNew->aiCol[i]>pNew->aiCol[i-1] );
1754 #endif
1755   }
1756 
1757   return pNew;
1758 }
1759 
1760 Fts5Colset *sqlite3Fts5ParseColset(
1761   Fts5Parse *pParse,              /* Store SQLITE_NOMEM here if required */
1762   Fts5Colset *pColset,            /* Existing colset object */
1763   Fts5Token *p
1764 ){
1765   Fts5Colset *pRet = 0;
1766   int iCol;
1767   char *z;                        /* Dequoted copy of token p */
1768 
1769   z = sqlite3Fts5Strndup(&pParse->rc, p->p, p->n);
1770   if( pParse->rc==SQLITE_OK ){
1771     Fts5Config *pConfig = pParse->pConfig;
1772     sqlite3Fts5Dequote(z);
1773     for(iCol=0; iCol<pConfig->nCol; iCol++){
1774       if( 0==sqlite3_stricmp(pConfig->azCol[iCol], z) ) break;
1775     }
1776     if( iCol==pConfig->nCol ){
1777       sqlite3Fts5ParseError(pParse, "no such column: %s", z);
1778     }else{
1779       pRet = fts5ParseColset(pParse, pColset, iCol);
1780     }
1781     sqlite3_free(z);
1782   }
1783 
1784   if( pRet==0 ){
1785     assert( pParse->rc!=SQLITE_OK );
1786     sqlite3_free(pColset);
1787   }
1788 
1789   return pRet;
1790 }
1791 
1792 void sqlite3Fts5ParseSetColset(
1793   Fts5Parse *pParse,
1794   Fts5ExprNearset *pNear,
1795   Fts5Colset *pColset
1796 ){
1797   if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
1798     pParse->rc = SQLITE_ERROR;
1799     pParse->zErr = sqlite3_mprintf(
1800       "fts5: column queries are not supported (detail=none)"
1801     );
1802     sqlite3_free(pColset);
1803     return;
1804   }
1805 
1806   if( pNear ){
1807     pNear->pColset = pColset;
1808   }else{
1809     sqlite3_free(pColset);
1810   }
1811 }
1812 
1813 static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
1814   switch( pNode->eType ){
1815     case FTS5_STRING: {
1816       Fts5ExprNearset *pNear = pNode->pNear;
1817       if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1
1818        && pNear->apPhrase[0]->aTerm[0].pSynonym==0
1819       ){
1820         pNode->eType = FTS5_TERM;
1821         pNode->xNext = fts5ExprNodeNext_TERM;
1822       }else{
1823         pNode->xNext = fts5ExprNodeNext_STRING;
1824       }
1825       break;
1826     };
1827 
1828     case FTS5_OR: {
1829       pNode->xNext = fts5ExprNodeNext_OR;
1830       break;
1831     };
1832 
1833     case FTS5_AND: {
1834       pNode->xNext = fts5ExprNodeNext_AND;
1835       break;
1836     };
1837 
1838     default: assert( pNode->eType==FTS5_NOT ); {
1839       pNode->xNext = fts5ExprNodeNext_NOT;
1840       break;
1841     };
1842   }
1843 }
1844 
1845 static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
1846   if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){
1847     int nByte = sizeof(Fts5ExprNode*) * pSub->nChild;
1848     memcpy(&p->apChild[p->nChild], pSub->apChild, nByte);
1849     p->nChild += pSub->nChild;
1850     sqlite3_free(pSub);
1851   }else{
1852     p->apChild[p->nChild++] = pSub;
1853   }
1854 }
1855 
1856 /*
1857 ** Allocate and return a new expression object. If anything goes wrong (i.e.
1858 ** OOM error), leave an error code in pParse and return NULL.
1859 */
1860 Fts5ExprNode *sqlite3Fts5ParseNode(
1861   Fts5Parse *pParse,              /* Parse context */
1862   int eType,                      /* FTS5_STRING, AND, OR or NOT */
1863   Fts5ExprNode *pLeft,            /* Left hand child expression */
1864   Fts5ExprNode *pRight,           /* Right hand child expression */
1865   Fts5ExprNearset *pNear          /* For STRING expressions, the near cluster */
1866 ){
1867   Fts5ExprNode *pRet = 0;
1868 
1869   if( pParse->rc==SQLITE_OK ){
1870     int nChild = 0;               /* Number of children of returned node */
1871     int nByte;                    /* Bytes of space to allocate for this node */
1872 
1873     assert( (eType!=FTS5_STRING && !pNear)
1874          || (eType==FTS5_STRING && !pLeft && !pRight)
1875     );
1876     if( eType==FTS5_STRING && pNear==0 ) return 0;
1877     if( eType!=FTS5_STRING && pLeft==0 ) return pRight;
1878     if( eType!=FTS5_STRING && pRight==0 ) return pLeft;
1879 
1880     if( eType==FTS5_NOT ){
1881       nChild = 2;
1882     }else if( eType==FTS5_AND || eType==FTS5_OR ){
1883       nChild = 2;
1884       if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
1885       if( pRight->eType==eType ) nChild += pRight->nChild-1;
1886     }
1887 
1888     nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
1889     pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
1890 
1891     if( pRet ){
1892       pRet->eType = eType;
1893       pRet->pNear = pNear;
1894       fts5ExprAssignXNext(pRet);
1895       if( eType==FTS5_STRING ){
1896         int iPhrase;
1897         for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
1898           pNear->apPhrase[iPhrase]->pNode = pRet;
1899         }
1900 
1901         if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL
1902          && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm!=1)
1903         ){
1904           assert( pParse->rc==SQLITE_OK );
1905           pParse->rc = SQLITE_ERROR;
1906           assert( pParse->zErr==0 );
1907           pParse->zErr = sqlite3_mprintf(
1908               "fts5: %s queries are not supported (detail!=full)",
1909               pNear->nPhrase==1 ? "phrase": "NEAR"
1910           );
1911           sqlite3_free(pRet);
1912           pRet = 0;
1913         }
1914 
1915       }else{
1916         fts5ExprAddChildren(pRet, pLeft);
1917         fts5ExprAddChildren(pRet, pRight);
1918       }
1919     }
1920   }
1921 
1922   if( pRet==0 ){
1923     assert( pParse->rc!=SQLITE_OK );
1924     sqlite3Fts5ParseNodeFree(pLeft);
1925     sqlite3Fts5ParseNodeFree(pRight);
1926     sqlite3Fts5ParseNearsetFree(pNear);
1927   }
1928   return pRet;
1929 }
1930 
1931 static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
1932   int nByte = 0;
1933   Fts5ExprTerm *p;
1934   char *zQuoted;
1935 
1936   /* Determine the maximum amount of space required. */
1937   for(p=pTerm; p; p=p->pSynonym){
1938     nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
1939   }
1940   zQuoted = sqlite3_malloc(nByte);
1941 
1942   if( zQuoted ){
1943     int i = 0;
1944     for(p=pTerm; p; p=p->pSynonym){
1945       char *zIn = p->zTerm;
1946       zQuoted[i++] = '"';
1947       while( *zIn ){
1948         if( *zIn=='"' ) zQuoted[i++] = '"';
1949         zQuoted[i++] = *zIn++;
1950       }
1951       zQuoted[i++] = '"';
1952       if( p->pSynonym ) zQuoted[i++] = '|';
1953     }
1954     if( pTerm->bPrefix ){
1955       zQuoted[i++] = ' ';
1956       zQuoted[i++] = '*';
1957     }
1958     zQuoted[i++] = '\0';
1959   }
1960   return zQuoted;
1961 }
1962 
1963 static char *fts5PrintfAppend(char *zApp, const char *zFmt, ...){
1964   char *zNew;
1965   va_list ap;
1966   va_start(ap, zFmt);
1967   zNew = sqlite3_vmprintf(zFmt, ap);
1968   va_end(ap);
1969   if( zApp && zNew ){
1970     char *zNew2 = sqlite3_mprintf("%s%s", zApp, zNew);
1971     sqlite3_free(zNew);
1972     zNew = zNew2;
1973   }
1974   sqlite3_free(zApp);
1975   return zNew;
1976 }
1977 
1978 /*
1979 ** Compose a tcl-readable representation of expression pExpr. Return a
1980 ** pointer to a buffer containing that representation. It is the
1981 ** responsibility of the caller to at some point free the buffer using
1982 ** sqlite3_free().
1983 */
1984 static char *fts5ExprPrintTcl(
1985   Fts5Config *pConfig,
1986   const char *zNearsetCmd,
1987   Fts5ExprNode *pExpr
1988 ){
1989   char *zRet = 0;
1990   if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
1991     Fts5ExprNearset *pNear = pExpr->pNear;
1992     int i;
1993     int iTerm;
1994 
1995     zRet = fts5PrintfAppend(zRet, "%s ", zNearsetCmd);
1996     if( zRet==0 ) return 0;
1997     if( pNear->pColset ){
1998       int *aiCol = pNear->pColset->aiCol;
1999       int nCol = pNear->pColset->nCol;
2000       if( nCol==1 ){
2001         zRet = fts5PrintfAppend(zRet, "-col %d ", aiCol[0]);
2002       }else{
2003         zRet = fts5PrintfAppend(zRet, "-col {%d", aiCol[0]);
2004         for(i=1; i<pNear->pColset->nCol; i++){
2005           zRet = fts5PrintfAppend(zRet, " %d", aiCol[i]);
2006         }
2007         zRet = fts5PrintfAppend(zRet, "} ");
2008       }
2009       if( zRet==0 ) return 0;
2010     }
2011 
2012     if( pNear->nPhrase>1 ){
2013       zRet = fts5PrintfAppend(zRet, "-near %d ", pNear->nNear);
2014       if( zRet==0 ) return 0;
2015     }
2016 
2017     zRet = fts5PrintfAppend(zRet, "--");
2018     if( zRet==0 ) return 0;
2019 
2020     for(i=0; i<pNear->nPhrase; i++){
2021       Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
2022 
2023       zRet = fts5PrintfAppend(zRet, " {");
2024       for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){
2025         char *zTerm = pPhrase->aTerm[iTerm].zTerm;
2026         zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm);
2027         if( pPhrase->aTerm[iTerm].bPrefix ){
2028           zRet = fts5PrintfAppend(zRet, "*");
2029         }
2030       }
2031 
2032       if( zRet ) zRet = fts5PrintfAppend(zRet, "}");
2033       if( zRet==0 ) return 0;
2034     }
2035 
2036   }else{
2037     char const *zOp = 0;
2038     int i;
2039     switch( pExpr->eType ){
2040       case FTS5_AND: zOp = "AND"; break;
2041       case FTS5_NOT: zOp = "NOT"; break;
2042       default:
2043         assert( pExpr->eType==FTS5_OR );
2044         zOp = "OR";
2045         break;
2046     }
2047 
2048     zRet = sqlite3_mprintf("%s", zOp);
2049     for(i=0; zRet && i<pExpr->nChild; i++){
2050       char *z = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->apChild[i]);
2051       if( !z ){
2052         sqlite3_free(zRet);
2053         zRet = 0;
2054       }else{
2055         zRet = fts5PrintfAppend(zRet, " [%z]", z);
2056       }
2057     }
2058   }
2059 
2060   return zRet;
2061 }
2062 
2063 static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
2064   char *zRet = 0;
2065   if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
2066     Fts5ExprNearset *pNear = pExpr->pNear;
2067     int i;
2068     int iTerm;
2069 
2070     if( pNear->pColset ){
2071       int iCol = pNear->pColset->aiCol[0];
2072       zRet = fts5PrintfAppend(zRet, "%s : ", pConfig->azCol[iCol]);
2073       if( zRet==0 ) return 0;
2074     }
2075 
2076     if( pNear->nPhrase>1 ){
2077       zRet = fts5PrintfAppend(zRet, "NEAR(");
2078       if( zRet==0 ) return 0;
2079     }
2080 
2081     for(i=0; i<pNear->nPhrase; i++){
2082       Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
2083       if( i!=0 ){
2084         zRet = fts5PrintfAppend(zRet, " ");
2085         if( zRet==0 ) return 0;
2086       }
2087       for(iTerm=0; iTerm<pPhrase->nTerm; iTerm++){
2088         char *zTerm = fts5ExprTermPrint(&pPhrase->aTerm[iTerm]);
2089         if( zTerm ){
2090           zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" + ", zTerm);
2091           sqlite3_free(zTerm);
2092         }
2093         if( zTerm==0 || zRet==0 ){
2094           sqlite3_free(zRet);
2095           return 0;
2096         }
2097       }
2098     }
2099 
2100     if( pNear->nPhrase>1 ){
2101       zRet = fts5PrintfAppend(zRet, ", %d)", pNear->nNear);
2102       if( zRet==0 ) return 0;
2103     }
2104 
2105   }else{
2106     char const *zOp = 0;
2107     int i;
2108 
2109     switch( pExpr->eType ){
2110       case FTS5_AND: zOp = " AND "; break;
2111       case FTS5_NOT: zOp = " NOT "; break;
2112       default:
2113         assert( pExpr->eType==FTS5_OR );
2114         zOp = " OR ";
2115         break;
2116     }
2117 
2118     for(i=0; i<pExpr->nChild; i++){
2119       char *z = fts5ExprPrint(pConfig, pExpr->apChild[i]);
2120       if( z==0 ){
2121         sqlite3_free(zRet);
2122         zRet = 0;
2123       }else{
2124         int e = pExpr->apChild[i]->eType;
2125         int b = (e!=FTS5_STRING && e!=FTS5_TERM);
2126         zRet = fts5PrintfAppend(zRet, "%s%s%z%s",
2127             (i==0 ? "" : zOp),
2128             (b?"(":""), z, (b?")":"")
2129         );
2130       }
2131       if( zRet==0 ) break;
2132     }
2133   }
2134 
2135   return zRet;
2136 }
2137 
2138 /*
2139 ** The implementation of user-defined scalar functions fts5_expr() (bTcl==0)
2140 ** and fts5_expr_tcl() (bTcl!=0).
2141 */
2142 static void fts5ExprFunction(
2143   sqlite3_context *pCtx,          /* Function call context */
2144   int nArg,                       /* Number of args */
2145   sqlite3_value **apVal,          /* Function arguments */
2146   int bTcl
2147 ){
2148   Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
2149   sqlite3 *db = sqlite3_context_db_handle(pCtx);
2150   const char *zExpr = 0;
2151   char *zErr = 0;
2152   Fts5Expr *pExpr = 0;
2153   int rc;
2154   int i;
2155 
2156   const char **azConfig;          /* Array of arguments for Fts5Config */
2157   const char *zNearsetCmd = "nearset";
2158   int nConfig;                    /* Size of azConfig[] */
2159   Fts5Config *pConfig = 0;
2160   int iArg = 1;
2161 
2162   if( nArg<1 ){
2163     zErr = sqlite3_mprintf("wrong number of arguments to function %s",
2164         bTcl ? "fts5_expr_tcl" : "fts5_expr"
2165     );
2166     sqlite3_result_error(pCtx, zErr, -1);
2167     sqlite3_free(zErr);
2168     return;
2169   }
2170 
2171   if( bTcl && nArg>1 ){
2172     zNearsetCmd = (const char*)sqlite3_value_text(apVal[1]);
2173     iArg = 2;
2174   }
2175 
2176   nConfig = 3 + (nArg-iArg);
2177   azConfig = (const char**)sqlite3_malloc(sizeof(char*) * nConfig);
2178   if( azConfig==0 ){
2179     sqlite3_result_error_nomem(pCtx);
2180     return;
2181   }
2182   azConfig[0] = 0;
2183   azConfig[1] = "main";
2184   azConfig[2] = "tbl";
2185   for(i=3; iArg<nArg; iArg++){
2186     azConfig[i++] = (const char*)sqlite3_value_text(apVal[iArg]);
2187   }
2188 
2189   zExpr = (const char*)sqlite3_value_text(apVal[0]);
2190 
2191   rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
2192   if( rc==SQLITE_OK ){
2193     rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr);
2194   }
2195   if( rc==SQLITE_OK ){
2196     char *zText;
2197     if( pExpr->pRoot->xNext==0 ){
2198       zText = sqlite3_mprintf("");
2199     }else if( bTcl ){
2200       zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot);
2201     }else{
2202       zText = fts5ExprPrint(pConfig, pExpr->pRoot);
2203     }
2204     if( zText==0 ){
2205       rc = SQLITE_NOMEM;
2206     }else{
2207       sqlite3_result_text(pCtx, zText, -1, SQLITE_TRANSIENT);
2208       sqlite3_free(zText);
2209     }
2210   }
2211 
2212   if( rc!=SQLITE_OK ){
2213     if( zErr ){
2214       sqlite3_result_error(pCtx, zErr, -1);
2215       sqlite3_free(zErr);
2216     }else{
2217       sqlite3_result_error_code(pCtx, rc);
2218     }
2219   }
2220   sqlite3_free((void *)azConfig);
2221   sqlite3Fts5ConfigFree(pConfig);
2222   sqlite3Fts5ExprFree(pExpr);
2223 }
2224 
2225 static void fts5ExprFunctionHr(
2226   sqlite3_context *pCtx,          /* Function call context */
2227   int nArg,                       /* Number of args */
2228   sqlite3_value **apVal           /* Function arguments */
2229 ){
2230   fts5ExprFunction(pCtx, nArg, apVal, 0);
2231 }
2232 static void fts5ExprFunctionTcl(
2233   sqlite3_context *pCtx,          /* Function call context */
2234   int nArg,                       /* Number of args */
2235   sqlite3_value **apVal           /* Function arguments */
2236 ){
2237   fts5ExprFunction(pCtx, nArg, apVal, 1);
2238 }
2239 
2240 /*
2241 ** The implementation of an SQLite user-defined-function that accepts a
2242 ** single integer as an argument. If the integer is an alpha-numeric
2243 ** unicode code point, 1 is returned. Otherwise 0.
2244 */
2245 static void fts5ExprIsAlnum(
2246   sqlite3_context *pCtx,          /* Function call context */
2247   int nArg,                       /* Number of args */
2248   sqlite3_value **apVal           /* Function arguments */
2249 ){
2250   int iCode;
2251   if( nArg!=1 ){
2252     sqlite3_result_error(pCtx,
2253         "wrong number of arguments to function fts5_isalnum", -1
2254     );
2255     return;
2256   }
2257   iCode = sqlite3_value_int(apVal[0]);
2258   sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode));
2259 }
2260 
2261 static void fts5ExprFold(
2262   sqlite3_context *pCtx,          /* Function call context */
2263   int nArg,                       /* Number of args */
2264   sqlite3_value **apVal           /* Function arguments */
2265 ){
2266   if( nArg!=1 && nArg!=2 ){
2267     sqlite3_result_error(pCtx,
2268         "wrong number of arguments to function fts5_fold", -1
2269     );
2270   }else{
2271     int iCode;
2272     int bRemoveDiacritics = 0;
2273     iCode = sqlite3_value_int(apVal[0]);
2274     if( nArg==2 ) bRemoveDiacritics = sqlite3_value_int(apVal[1]);
2275     sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics));
2276   }
2277 }
2278 
2279 /*
2280 ** This is called during initialization to register the fts5_expr() scalar
2281 ** UDF with the SQLite handle passed as the only argument.
2282 */
2283 int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
2284   struct Fts5ExprFunc {
2285     const char *z;
2286     void (*x)(sqlite3_context*,int,sqlite3_value**);
2287   } aFunc[] = {
2288     { "fts5_expr",     fts5ExprFunctionHr },
2289     { "fts5_expr_tcl", fts5ExprFunctionTcl },
2290     { "fts5_isalnum",  fts5ExprIsAlnum },
2291     { "fts5_fold",     fts5ExprFold },
2292   };
2293   int i;
2294   int rc = SQLITE_OK;
2295   void *pCtx = (void*)pGlobal;
2296 
2297   for(i=0; rc==SQLITE_OK && i<ArraySize(aFunc); i++){
2298     struct Fts5ExprFunc *p = &aFunc[i];
2299     rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
2300   }
2301 
2302   /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
2303 #ifndef NDEBUG
2304   (void)sqlite3Fts5ParserTrace;
2305 #endif
2306 
2307   return rc;
2308 }
2309 
2310 /*
2311 ** Return the number of phrases in expression pExpr.
2312 */
2313 int sqlite3Fts5ExprPhraseCount(Fts5Expr *pExpr){
2314   return (pExpr ? pExpr->nPhrase : 0);
2315 }
2316 
2317 /*
2318 ** Return the number of terms in the iPhrase'th phrase in pExpr.
2319 */
2320 int sqlite3Fts5ExprPhraseSize(Fts5Expr *pExpr, int iPhrase){
2321   if( iPhrase<0 || iPhrase>=pExpr->nPhrase ) return 0;
2322   return pExpr->apExprPhrase[iPhrase]->nTerm;
2323 }
2324 
2325 /*
2326 ** This function is used to access the current position list for phrase
2327 ** iPhrase.
2328 */
2329 int sqlite3Fts5ExprPoslist(Fts5Expr *pExpr, int iPhrase, const u8 **pa){
2330   int nRet;
2331   Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
2332   Fts5ExprNode *pNode = pPhrase->pNode;
2333   if( pNode->bEof==0 && pNode->iRowid==pExpr->pRoot->iRowid ){
2334     *pa = pPhrase->poslist.p;
2335     nRet = pPhrase->poslist.n;
2336   }else{
2337     *pa = 0;
2338     nRet = 0;
2339   }
2340   return nRet;
2341 }
2342 
2343 struct Fts5PoslistPopulator {
2344   Fts5PoslistWriter writer;
2345   int bOk;                        /* True if ok to populate */
2346   int bMiss;
2347 };
2348 
2349 Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
2350   Fts5PoslistPopulator *pRet;
2351   pRet = sqlite3_malloc(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
2352   if( pRet ){
2353     int i;
2354     memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
2355     for(i=0; i<pExpr->nPhrase; i++){
2356       Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
2357       Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
2358       assert( pExpr->apExprPhrase[i]->nTerm==1 );
2359       if( bLive &&
2360           (pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
2361       ){
2362         pRet[i].bMiss = 1;
2363       }else{
2364         pBuf->n = 0;
2365       }
2366     }
2367   }
2368   return pRet;
2369 }
2370 
2371 struct Fts5ExprCtx {
2372   Fts5Expr *pExpr;
2373   Fts5PoslistPopulator *aPopulator;
2374   i64 iOff;
2375 };
2376 typedef struct Fts5ExprCtx Fts5ExprCtx;
2377 
2378 /*
2379 ** TODO: Make this more efficient!
2380 */
2381 static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){
2382   int i;
2383   for(i=0; i<pColset->nCol; i++){
2384     if( pColset->aiCol[i]==iCol ) return 1;
2385   }
2386   return 0;
2387 }
2388 
2389 static int fts5ExprPopulatePoslistsCb(
2390   void *pCtx,                /* Copy of 2nd argument to xTokenize() */
2391   int tflags,                /* Mask of FTS5_TOKEN_* flags */
2392   const char *pToken,        /* Pointer to buffer containing token */
2393   int nToken,                /* Size of token in bytes */
2394   int iUnused1,              /* Byte offset of token within input text */
2395   int iUnused2               /* Byte offset of end of token within input text */
2396 ){
2397   Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx;
2398   Fts5Expr *pExpr = p->pExpr;
2399   int i;
2400 
2401   UNUSED_PARAM2(iUnused1, iUnused2);
2402 
2403   if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
2404   for(i=0; i<pExpr->nPhrase; i++){
2405     Fts5ExprTerm *pTerm;
2406     if( p->aPopulator[i].bOk==0 ) continue;
2407     for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
2408       int nTerm = strlen(pTerm->zTerm);
2409       if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix))
2410        && memcmp(pTerm->zTerm, pToken, nTerm)==0
2411       ){
2412         int rc = sqlite3Fts5PoslistWriterAppend(
2413             &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
2414         );
2415         if( rc ) return rc;
2416         break;
2417       }
2418     }
2419   }
2420   return SQLITE_OK;
2421 }
2422 
2423 int sqlite3Fts5ExprPopulatePoslists(
2424   Fts5Config *pConfig,
2425   Fts5Expr *pExpr,
2426   Fts5PoslistPopulator *aPopulator,
2427   int iCol,
2428   const char *z, int n
2429 ){
2430   int i;
2431   Fts5ExprCtx sCtx;
2432   sCtx.pExpr = pExpr;
2433   sCtx.aPopulator = aPopulator;
2434   sCtx.iOff = (((i64)iCol) << 32) - 1;
2435 
2436   for(i=0; i<pExpr->nPhrase; i++){
2437     Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
2438     Fts5Colset *pColset = pNode->pNear->pColset;
2439     if( (pColset && 0==fts5ExprColsetTest(pColset, iCol))
2440      || aPopulator[i].bMiss
2441     ){
2442       aPopulator[i].bOk = 0;
2443     }else{
2444       aPopulator[i].bOk = 1;
2445     }
2446   }
2447 
2448   return sqlite3Fts5Tokenize(pConfig,
2449       FTS5_TOKENIZE_DOCUMENT, z, n, (void*)&sCtx, fts5ExprPopulatePoslistsCb
2450   );
2451 }
2452 
2453 static void fts5ExprClearPoslists(Fts5ExprNode *pNode){
2454   if( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING ){
2455     pNode->pNear->apPhrase[0]->poslist.n = 0;
2456   }else{
2457     int i;
2458     for(i=0; i<pNode->nChild; i++){
2459       fts5ExprClearPoslists(pNode->apChild[i]);
2460     }
2461   }
2462 }
2463 
2464 static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){
2465   pNode->iRowid = iRowid;
2466   pNode->bEof = 0;
2467   switch( pNode->eType ){
2468     case FTS5_TERM:
2469     case FTS5_STRING:
2470       return (pNode->pNear->apPhrase[0]->poslist.n>0);
2471 
2472     case FTS5_AND: {
2473       int i;
2474       for(i=0; i<pNode->nChild; i++){
2475         if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid)==0 ){
2476           fts5ExprClearPoslists(pNode);
2477           return 0;
2478         }
2479       }
2480       break;
2481     }
2482 
2483     case FTS5_OR: {
2484       int i;
2485       int bRet = 0;
2486       for(i=0; i<pNode->nChild; i++){
2487         if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid) ){
2488           bRet = 1;
2489         }
2490       }
2491       return bRet;
2492     }
2493 
2494     default: {
2495       assert( pNode->eType==FTS5_NOT );
2496       if( 0==fts5ExprCheckPoslists(pNode->apChild[0], iRowid)
2497           || 0!=fts5ExprCheckPoslists(pNode->apChild[1], iRowid)
2498         ){
2499         fts5ExprClearPoslists(pNode);
2500         return 0;
2501       }
2502       break;
2503     }
2504   }
2505   return 1;
2506 }
2507 
2508 void sqlite3Fts5ExprCheckPoslists(Fts5Expr *pExpr, i64 iRowid){
2509   fts5ExprCheckPoslists(pExpr->pRoot, iRowid);
2510 }
2511 
2512 static void fts5ExprClearEof(Fts5ExprNode *pNode){
2513   int i;
2514   for(i=0; i<pNode->nChild; i++){
2515     fts5ExprClearEof(pNode->apChild[i]);
2516   }
2517   pNode->bEof = 0;
2518 }
2519 void sqlite3Fts5ExprClearEof(Fts5Expr *pExpr){
2520   fts5ExprClearEof(pExpr->pRoot);
2521 }
2522 
2523 /*
2524 ** This function is only called for detail=columns tables.
2525 */
2526 int sqlite3Fts5ExprPhraseCollist(
2527   Fts5Expr *pExpr,
2528   int iPhrase,
2529   const u8 **ppCollist,
2530   int *pnCollist
2531 ){
2532   Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
2533   Fts5ExprNode *pNode = pPhrase->pNode;
2534   int rc = SQLITE_OK;
2535 
2536   assert( iPhrase>=0 && iPhrase<pExpr->nPhrase );
2537   assert( pExpr->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
2538 
2539   if( pNode->bEof==0
2540    && pNode->iRowid==pExpr->pRoot->iRowid
2541    && pPhrase->poslist.n>0
2542   ){
2543     Fts5ExprTerm *pTerm = &pPhrase->aTerm[0];
2544     if( pTerm->pSynonym ){
2545       Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1];
2546       rc = fts5ExprSynonymList(
2547           pTerm, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
2548       );
2549     }else{
2550       *ppCollist = pPhrase->aTerm[0].pIter->pData;
2551       *pnCollist = pPhrase->aTerm[0].pIter->nData;
2552     }
2553   }else{
2554     *ppCollist = 0;
2555     *pnCollist = 0;
2556   }
2557 
2558   return rc;
2559 }
2560 
2561