modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/fts5/fts5_expr.c (about)

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