/ Hex Artifact Content
Login

Artifact afe8c2394cf6de2a48f278442f4f4342365bf99a5983709ef8e6955c2cf4daf9:


0000: 2f 2a 0a 2a 2a 20 32 30 31 34 20 4d 61 79 20 33  /*.** 2014 May 3
0010: 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  1.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2f 0a 0a 0a 23 69 6e 63 6c  *****.*/...#incl
0180: 75 64 65 20 22 66 74 73 35 49 6e 74 2e 68 22 0a  ude "fts5Int.h".
0190: 23 69 6e 63 6c 75 64 65 20 3c 6d 61 74 68 2e 68  #include <math.h
01a0: 3e 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  >               
01b0: 20 20 2f 2a 20 61 6d 61 6c 67 61 6d 61 74 6f 72    /* amalgamator
01c0: 3a 20 6b 65 65 70 20 2a 2f 0a 0a 2f 2a 0a 2a 2a  : keep */../*.**
01d0: 20 4f 62 6a 65 63 74 20 75 73 65 64 20 74 6f 20   Object used to 
01e0: 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20  iterate through 
01f0: 61 6c 6c 20 22 63 6f 61 6c 65 73 63 65 64 20 70  all "coalesced p
0200: 68 72 61 73 65 20 69 6e 73 74 61 6e 63 65 73 22  hrase instances"
0210: 20 69 6e 20 0a 2a 2a 20 61 20 73 69 6e 67 6c 65   in .** a single
0220: 20 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65 20 63   column of the c
0230: 75 72 72 65 6e 74 20 72 6f 77 2e 20 49 66 20 74  urrent row. If t
0240: 68 65 20 70 68 72 61 73 65 20 69 6e 73 74 61 6e  he phrase instan
0250: 63 65 73 20 69 6e 20 74 68 65 0a 2a 2a 20 63 6f  ces in the.** co
0260: 6c 75 6d 6e 20 62 65 69 6e 67 20 63 6f 6e 73 69  lumn being consi
0270: 64 65 72 65 64 20 64 6f 20 6e 6f 74 20 6f 76 65  dered do not ove
0280: 72 6c 61 70 2c 20 74 68 69 73 20 6f 62 6a 65 63  rlap, this objec
0290: 74 20 73 69 6d 70 6c 79 20 69 74 65 72 61 74 65  t simply iterate
02a0: 73 0a 2a 2a 20 74 68 72 6f 75 67 68 20 74 68 65  s.** through the
02b0: 6d 2e 20 4f 72 2c 20 69 66 20 74 68 65 79 20 64  m. Or, if they d
02c0: 6f 20 6f 76 65 72 6c 61 70 20 28 73 68 61 72 65  o overlap (share
02d0: 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 74 6f 6b   one or more tok
02e0: 65 6e 73 20 69 6e 0a 2a 2a 20 63 6f 6d 6d 6f 6e  ens in.** common
02f0: 29 2c 20 65 61 63 68 20 73 65 74 20 6f 66 20 6f  ), each set of o
0300: 76 65 72 6c 61 70 70 69 6e 67 20 69 6e 73 74 61  verlapping insta
0310: 6e 63 65 73 20 69 73 20 74 72 65 61 74 65 64 20  nces is treated 
0320: 61 73 20 61 20 73 69 6e 67 6c 65 0a 2a 2a 20 6d  as a single.** m
0330: 61 74 63 68 2e 20 53 65 65 20 64 6f 63 75 6d 65  atch. See docume
0340: 6e 74 61 74 69 6f 6e 20 66 6f 72 20 74 68 65 20  ntation for the 
0350: 68 69 67 68 6c 69 67 68 74 28 29 20 61 75 78 69  highlight() auxi
0360: 6c 69 61 72 79 20 66 75 6e 63 74 69 6f 6e 20 66  liary function f
0370: 6f 72 0a 2a 2a 20 64 65 74 61 69 6c 73 2e 0a 2a  or.** details..*
0380: 2a 0a 2a 2a 20 55 73 61 67 65 20 69 73 3a 0a 2a  *.** Usage is:.*
0390: 2a 0a 2a 2a 20 20 20 66 6f 72 28 72 63 20 3d 20  *.**   for(rc = 
03a0: 66 74 73 35 43 49 6e 73 74 49 74 65 72 4e 65 78  fts5CInstIterNex
03b0: 74 28 70 41 70 69 2c 20 70 46 74 73 2c 20 69 43  t(pApi, pFts, iC
03c0: 6f 6c 2c 20 26 69 74 65 72 29 3b 0a 2a 2a 20 20  ol, &iter);.**  
03d0: 20 20 20 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f      (rc==SQLITE_
03e0: 4f 4b 20 26 26 20 30 3d 3d 66 74 73 35 43 49 6e  OK && 0==fts5CIn
03f0: 73 74 49 74 65 72 45 6f 66 28 26 69 74 65 72 29  stIterEof(&iter)
0400: 3b 0a 2a 2a 20 20 20 20 20 20 72 63 20 3d 20 66  ;.**      rc = f
0410: 74 73 35 43 49 6e 73 74 49 74 65 72 4e 65 78 74  ts5CInstIterNext
0420: 28 26 69 74 65 72 29 0a 2a 2a 20 20 20 29 7b 0a  (&iter).**   ){.
0430: 2a 2a 20 20 20 20 20 70 72 69 6e 74 66 28 22 69  **     printf("i
0440: 6e 73 74 61 6e 63 65 20 73 74 61 72 74 73 20 61  nstance starts a
0450: 74 20 25 64 2c 20 65 6e 64 73 20 61 74 20 25 64  t %d, ends at %d
0460: 5c 6e 22 2c 20 69 74 65 72 2e 69 53 74 61 72 74  \n", iter.iStart
0470: 2c 20 69 74 65 72 2e 69 45 6e 64 29 3b 0a 2a 2a  , iter.iEnd);.**
0480: 20 20 20 7d 0a 2a 2a 0a 2a 2f 0a 74 79 70 65 64     }.**.*/.typed
0490: 65 66 20 73 74 72 75 63 74 20 43 49 6e 73 74 49  ef struct CInstI
04a0: 74 65 72 20 43 49 6e 73 74 49 74 65 72 3b 0a 73  ter CInstIter;.s
04b0: 74 72 75 63 74 20 43 49 6e 73 74 49 74 65 72 20  truct CInstIter 
04c0: 7b 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45 78  {.  const Fts5Ex
04d0: 74 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70 69  tensionApi *pApi
04e0: 3b 20 20 20 2f 2a 20 41 50 49 20 6f 66 66 65 72  ;   /* API offer
04f0: 65 64 20 62 79 20 63 75 72 72 65 6e 74 20 46 54  ed by current FT
0500: 53 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 46  S version */.  F
0510: 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73  ts5Context *pFts
0520: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
0530: 2a 20 46 69 72 73 74 20 61 72 67 20 74 6f 20 70  * First arg to p
0540: 61 73 73 20 74 6f 20 70 41 70 69 20 66 75 6e 63  ass to pApi func
0550: 74 69 6f 6e 73 20 2a 2f 0a 20 20 69 6e 74 20 69  tions */.  int i
0560: 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  Col;            
0570: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
0580: 6c 75 6d 6e 20 74 6f 20 73 65 61 72 63 68 20 2a  lumn to search *
0590: 2f 0a 20 20 69 6e 74 20 69 49 6e 73 74 3b 20 20  /.  int iInst;  
05a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05b0: 20 20 20 20 2f 2a 20 4e 65 78 74 20 70 68 72 61      /* Next phra
05c0: 73 65 20 69 6e 73 74 61 6e 63 65 20 69 6e 64 65  se instance inde
05d0: 78 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 6e 73 74  x */.  int nInst
05e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
05f0: 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20         /* Total 
0600: 6e 75 6d 62 65 72 20 6f 66 20 70 68 72 61 73 65  number of phrase
0610: 20 69 6e 73 74 61 6e 63 65 73 20 2a 2f 0a 0a 20   instances */.. 
0620: 20 2f 2a 20 4f 75 74 70 75 74 20 76 61 72 69 61   /* Output varia
0630: 62 6c 65 73 20 2a 2f 0a 20 20 69 6e 74 20 69 53  bles */.  int iS
0640: 74 61 72 74 3b 20 20 20 20 20 20 20 20 20 20 20  tart;           
0650: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72            /* Fir
0660: 73 74 20 74 6f 6b 65 6e 20 69 6e 20 63 6f 61 6c  st token in coal
0670: 65 73 63 65 64 20 70 68 72 61 73 65 20 69 6e 73  esced phrase ins
0680: 74 61 6e 63 65 20 2a 2f 0a 20 20 69 6e 74 20 69  tance */.  int i
0690: 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  End;            
06a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
06b0: 73 74 20 74 6f 6b 65 6e 20 69 6e 20 63 6f 61 6c  st token in coal
06c0: 65 73 63 65 64 20 70 68 72 61 73 65 20 69 6e 73  esced phrase ins
06d0: 74 61 6e 63 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  tance */.};../*.
06e0: 2a 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20 69  ** Advance the i
06f0: 74 65 72 61 74 6f 72 20 74 6f 20 74 68 65 20 6e  terator to the n
0700: 65 78 74 20 63 6f 61 6c 65 73 63 65 64 20 70 68  ext coalesced ph
0710: 72 61 73 65 20 69 6e 73 74 61 6e 63 65 2e 20 52  rase instance. R
0720: 65 74 75 72 6e 0a 2a 2a 20 61 6e 20 53 51 4c 69  eturn.** an SQLi
0730: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66  te error code if
0740: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
0750: 2c 20 6f 72 20 53 51 4c 49 54 45 5f 4f 4b 20 6f  , or SQLITE_OK o
0760: 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61  therwise..*/.sta
0770: 74 69 63 20 69 6e 74 20 66 74 73 35 43 49 6e 73  tic int fts5CIns
0780: 74 49 74 65 72 4e 65 78 74 28 43 49 6e 73 74 49  tIterNext(CInstI
0790: 74 65 72 20 2a 70 49 74 65 72 29 7b 0a 20 20 69  ter *pIter){.  i
07a0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
07b0: 4b 3b 0a 20 20 70 49 74 65 72 2d 3e 69 53 74 61  K;.  pIter->iSta
07c0: 72 74 20 3d 20 2d 31 3b 0a 20 20 70 49 74 65 72  rt = -1;.  pIter
07d0: 2d 3e 69 45 6e 64 20 3d 20 2d 31 3b 0a 0a 20 20  ->iEnd = -1;..  
07e0: 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54  while( rc==SQLIT
07f0: 45 5f 4f 4b 20 26 26 20 70 49 74 65 72 2d 3e 69  E_OK && pIter->i
0800: 49 6e 73 74 3c 70 49 74 65 72 2d 3e 6e 49 6e 73  Inst<pIter->nIns
0810: 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 70 3b  t ){.    int ip;
0820: 20 69 6e 74 20 69 63 3b 20 69 6e 74 20 69 6f 3b   int ic; int io;
0830: 0a 20 20 20 20 72 63 20 3d 20 70 49 74 65 72 2d  .    rc = pIter-
0840: 3e 70 41 70 69 2d 3e 78 49 6e 73 74 28 70 49 74  >pApi->xInst(pIt
0850: 65 72 2d 3e 70 46 74 73 2c 20 70 49 74 65 72 2d  er->pFts, pIter-
0860: 3e 69 49 6e 73 74 2c 20 26 69 70 2c 20 26 69 63  >iInst, &ip, &ic
0870: 2c 20 26 69 6f 29 3b 0a 20 20 20 20 69 66 28 20  , &io);.    if( 
0880: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
0890: 0a 20 20 20 20 20 20 69 66 28 20 69 63 3d 3d 70  .      if( ic==p
08a0: 49 74 65 72 2d 3e 69 43 6f 6c 20 29 7b 0a 20 20  Iter->iCol ){.  
08b0: 20 20 20 20 20 20 69 6e 74 20 69 45 6e 64 20 3d        int iEnd =
08c0: 20 69 6f 20 2d 20 31 20 2b 20 70 49 74 65 72 2d   io - 1 + pIter-
08d0: 3e 70 41 70 69 2d 3e 78 50 68 72 61 73 65 53 69  >pApi->xPhraseSi
08e0: 7a 65 28 70 49 74 65 72 2d 3e 70 46 74 73 2c 20  ze(pIter->pFts, 
08f0: 69 70 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  ip);.        if(
0900: 20 70 49 74 65 72 2d 3e 69 53 74 61 72 74 3c 30   pIter->iStart<0
0910: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 49   ){.          pI
0920: 74 65 72 2d 3e 69 53 74 61 72 74 20 3d 20 69 6f  ter->iStart = io
0930: 3b 0a 20 20 20 20 20 20 20 20 20 20 70 49 74 65  ;.          pIte
0940: 72 2d 3e 69 45 6e 64 20 3d 20 69 45 6e 64 3b 0a  r->iEnd = iEnd;.
0950: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66          }else if
0960: 28 20 69 6f 3c 3d 70 49 74 65 72 2d 3e 69 45 6e  ( io<=pIter->iEn
0970: 64 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  d ){.          i
0980: 66 28 20 69 45 6e 64 3e 70 49 74 65 72 2d 3e 69  f( iEnd>pIter->i
0990: 45 6e 64 20 29 20 70 49 74 65 72 2d 3e 69 45 6e  End ) pIter->iEn
09a0: 64 20 3d 20 69 45 6e 64 3b 0a 20 20 20 20 20 20  d = iEnd;.      
09b0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
09c0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
09d0: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
09e0: 20 20 70 49 74 65 72 2d 3e 69 49 6e 73 74 2b 2b    pIter->iInst++
09f0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
0a00: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
0a10: 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68  ** Initialize th
0a20: 65 20 69 74 65 72 61 74 6f 72 20 6f 62 6a 65 63  e iterator objec
0a30: 74 20 69 6e 64 69 63 61 74 65 64 20 62 79 20 74  t indicated by t
0a40: 68 65 20 66 69 6e 61 6c 20 70 61 72 61 6d 65 74  he final paramet
0a50: 65 72 20 74 6f 20 0a 2a 2a 20 69 74 65 72 61 74  er to .** iterat
0a60: 65 20 74 68 72 6f 75 67 68 20 63 6f 61 6c 65 73  e through coales
0a70: 63 65 64 20 70 68 72 61 73 65 20 69 6e 73 74 61  ced phrase insta
0a80: 6e 63 65 73 20 69 6e 20 63 6f 6c 75 6d 6e 20 69  nces in column i
0a90: 43 6f 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  Col..*/.static i
0aa0: 6e 74 20 66 74 73 35 43 49 6e 73 74 49 74 65 72  nt fts5CInstIter
0ab0: 49 6e 69 74 28 0a 20 20 63 6f 6e 73 74 20 46 74  Init(.  const Ft
0ac0: 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a  s5ExtensionApi *
0ad0: 70 41 70 69 2c 0a 20 20 46 74 73 35 43 6f 6e 74  pApi,.  Fts5Cont
0ae0: 65 78 74 20 2a 70 46 74 73 2c 0a 20 20 69 6e 74  ext *pFts,.  int
0af0: 20 69 43 6f 6c 2c 0a 20 20 43 49 6e 73 74 49 74   iCol,.  CInstIt
0b00: 65 72 20 2a 70 49 74 65 72 0a 29 7b 0a 20 20 69  er *pIter.){.  i
0b10: 6e 74 20 72 63 3b 0a 0a 20 20 6d 65 6d 73 65 74  nt rc;..  memset
0b20: 28 70 49 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f  (pIter, 0, sizeo
0b30: 66 28 43 49 6e 73 74 49 74 65 72 29 29 3b 0a 20  f(CInstIter));. 
0b40: 20 70 49 74 65 72 2d 3e 70 41 70 69 20 3d 20 70   pIter->pApi = p
0b50: 41 70 69 3b 0a 20 20 70 49 74 65 72 2d 3e 70 46  Api;.  pIter->pF
0b60: 74 73 20 3d 20 70 46 74 73 3b 0a 20 20 70 49 74  ts = pFts;.  pIt
0b70: 65 72 2d 3e 69 43 6f 6c 20 3d 20 69 43 6f 6c 3b  er->iCol = iCol;
0b80: 0a 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 49  .  rc = pApi->xI
0b90: 6e 73 74 43 6f 75 6e 74 28 70 46 74 73 2c 20 26  nstCount(pFts, &
0ba0: 70 49 74 65 72 2d 3e 6e 49 6e 73 74 29 3b 0a 0a  pIter->nInst);..
0bb0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
0bc0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
0bd0: 66 74 73 35 43 49 6e 73 74 49 74 65 72 4e 65 78  fts5CInstIterNex
0be0: 74 28 70 49 74 65 72 29 3b 0a 20 20 7d 0a 0a 20  t(pIter);.  }.. 
0bf0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a   return rc;.}...
0c00: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
0c10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0c20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0c30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0c40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 53  ***********.** S
0c50: 74 61 72 74 20 6f 66 20 68 69 67 68 6c 69 67 68  tart of highligh
0c60: 74 28 29 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  t() implementati
0c70: 6f 6e 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73  on..*/.typedef s
0c80: 74 72 75 63 74 20 48 69 67 68 6c 69 67 68 74 43  truct HighlightC
0c90: 6f 6e 74 65 78 74 20 48 69 67 68 6c 69 67 68 74  ontext Highlight
0ca0: 43 6f 6e 74 65 78 74 3b 0a 73 74 72 75 63 74 20  Context;.struct 
0cb0: 48 69 67 68 6c 69 67 68 74 43 6f 6e 74 65 78 74  HighlightContext
0cc0: 20 7b 0a 20 20 43 49 6e 73 74 49 74 65 72 20 69   {.  CInstIter i
0cd0: 74 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  ter;            
0ce0: 20 20 20 20 20 2f 2a 20 43 6f 61 6c 65 73 63 65       /* Coalesce
0cf0: 64 20 49 6e 73 74 61 6e 63 65 20 49 74 65 72 61  d Instance Itera
0d00: 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 69 50 6f  tor */.  int iPo
0d10: 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s;              
0d20: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72           /* Curr
0d30: 65 6e 74 20 74 6f 6b 65 6e 20 6f 66 66 73 65 74  ent token offset
0d40: 20 69 6e 20 7a 49 6e 5b 5d 20 2a 2f 0a 20 20 69   in zIn[] */.  i
0d50: 6e 74 20 69 52 61 6e 67 65 53 74 61 72 74 3b 20  nt iRangeStart; 
0d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0d70: 2a 20 46 69 72 73 74 20 74 6f 6b 65 6e 20 74 6f  * First token to
0d80: 20 69 6e 63 6c 75 64 65 20 2a 2f 0a 20 20 69 6e   include */.  in
0d90: 74 20 69 52 61 6e 67 65 45 6e 64 3b 20 20 20 20  t iRangeEnd;    
0da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0db0: 20 49 66 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 6c 61   If non-zero, la
0dc0: 73 74 20 74 6f 6b 65 6e 20 74 6f 20 69 6e 63 6c  st token to incl
0dd0: 75 64 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ude */.  const c
0de0: 68 61 72 20 2a 7a 4f 70 65 6e 3b 20 20 20 20 20  har *zOpen;     
0df0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 70 65 6e           /* Open
0e00: 69 6e 67 20 68 69 67 68 6c 69 67 68 74 20 2a 2f  ing highlight */
0e10: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
0e20: 43 6c 6f 73 65 3b 20 20 20 20 20 20 20 20 20 20  Close;          
0e30: 20 20 20 2f 2a 20 43 6c 6f 73 69 6e 67 20 68 69     /* Closing hi
0e40: 67 68 6c 69 67 68 74 20 2a 2f 0a 20 20 63 6f 6e  ghlight */.  con
0e50: 73 74 20 63 68 61 72 20 2a 7a 49 6e 3b 20 20 20  st char *zIn;   
0e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0e70: 49 6e 70 75 74 20 74 65 78 74 20 2a 2f 0a 20 20  Input text */.  
0e80: 69 6e 74 20 6e 49 6e 3b 20 20 20 20 20 20 20 20  int nIn;        
0e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ea0: 2f 2a 20 53 69 7a 65 20 6f 66 20 69 6e 70 75 74  /* Size of input
0eb0: 20 74 65 78 74 20 69 6e 20 62 79 74 65 73 20 2a   text in bytes *
0ec0: 2f 0a 20 20 69 6e 74 20 69 4f 66 66 3b 20 20 20  /.  int iOff;   
0ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ee0: 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 6f      /* Current o
0ef0: 66 66 73 65 74 20 77 69 74 68 69 6e 20 7a 49 6e  ffset within zIn
0f00: 5b 5d 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 4f  [] */.  char *zO
0f10: 75 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ut;             
0f20: 20 20 20 20 20 20 20 20 2f 2a 20 4f 75 74 70 75          /* Outpu
0f30: 74 20 76 61 6c 75 65 20 2a 2f 0a 7d 3b 0a 0a 2f  t value */.};../
0f40: 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74 65 78 74  *.** Append text
0f50: 20 74 6f 20 74 68 65 20 48 69 67 68 6c 69 67 68   to the Highligh
0f60: 74 43 6f 6e 74 65 78 74 20 6f 75 74 70 75 74 20  tContext output 
0f70: 73 74 72 69 6e 67 20 2d 20 70 2d 3e 7a 4f 75 74  string - p->zOut
0f80: 2e 20 41 72 67 75 6d 65 6e 74 0a 2a 2a 20 7a 20  . Argument.** z 
0f90: 70 6f 69 6e 74 73 20 74 6f 20 61 20 62 75 66 66  points to a buff
0fa0: 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 6e 20  er containing n 
0fb0: 62 79 74 65 73 20 6f 66 20 74 65 78 74 20 74 6f  bytes of text to
0fc0: 20 61 70 70 65 6e 64 2e 20 49 66 20 6e 20 69 73   append. If n is
0fd0: 20 0a 2a 2a 20 6e 65 67 61 74 69 76 65 2c 20 65   .** negative, e
0fe0: 76 65 72 79 74 68 69 6e 67 20 75 70 20 75 6e 74  verything up unt
0ff0: 69 6c 20 74 68 65 20 66 69 72 73 74 20 27 5c 30  il the first '\0
1000: 27 20 69 73 20 61 70 70 65 6e 64 65 64 20 74 6f  ' is appended to
1010: 20 74 68 65 20 6f 75 74 70 75 74 2e 0a 2a 2a 0a   the output..**.
1020: 2a 2a 20 49 66 20 2a 70 52 63 20 69 73 20 73 65  ** If *pRc is se
1030: 74 20 74 6f 20 61 6e 79 20 76 61 6c 75 65 20 6f  t to any value o
1040: 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45  ther than SQLITE
1050: 5f 4f 4b 20 77 68 65 6e 20 74 68 69 73 20 66 75  _OK when this fu
1060: 6e 63 74 69 6f 6e 20 69 73 20 0a 2a 2a 20 63 61  nction is .** ca
1070: 6c 6c 65 64 2c 20 69 74 20 69 73 20 61 20 6e 6f  lled, it is a no
1080: 2d 6f 70 2e 20 49 66 20 61 6e 20 65 72 72 6f 72  -op. If an error
1090: 20 28 69 2e 65 2e 20 61 6e 20 4f 4f 4d 20 63 6f   (i.e. an OOM co
10a0: 6e 64 69 74 69 6f 6e 29 20 69 73 20 65 6e 63 6f  ndition) is enco
10b0: 75 6e 74 65 72 65 64 2c 20 0a 2a 2a 20 2a 70 52  untered, .** *pR
10c0: 63 20 69 73 20 73 65 74 20 74 6f 20 61 6e 20 65  c is set to an e
10d0: 72 72 6f 72 20 63 6f 64 65 20 62 65 66 6f 72 65  rror code before
10e0: 20 72 65 74 75 72 6e 69 6e 67 2e 20 0a 2a 2f 0a   returning. .*/.
10f0: 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35  static void fts5
1100: 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e 64 28  HighlightAppend(
1110: 0a 20 20 69 6e 74 20 2a 70 52 63 2c 20 0a 20 20  .  int *pRc, .  
1120: 48 69 67 68 6c 69 67 68 74 43 6f 6e 74 65 78 74  HighlightContext
1130: 20 2a 70 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68   *p, .  const ch
1140: 61 72 20 2a 7a 2c 20 69 6e 74 20 6e 0a 29 7b 0a  ar *z, int n.){.
1150: 20 20 69 66 28 20 2a 70 52 63 3d 3d 53 51 4c 49    if( *pRc==SQLI
1160: 54 45 5f 4f 4b 20 26 26 20 7a 20 29 7b 0a 20 20  TE_OK && z ){.  
1170: 20 20 69 66 28 20 6e 3c 30 20 29 20 6e 20 3d 20    if( n<0 ) n = 
1180: 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a 29 3b 0a  (int)strlen(z);.
1190: 20 20 20 20 70 2d 3e 7a 4f 75 74 20 3d 20 73 71      p->zOut = sq
11a0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25  lite3_mprintf("%
11b0: 7a 25 2e 2a 73 22 2c 20 70 2d 3e 7a 4f 75 74 2c  z%.*s", p->zOut,
11c0: 20 6e 2c 20 7a 29 3b 0a 20 20 20 20 69 66 28 20   n, z);.    if( 
11d0: 70 2d 3e 7a 4f 75 74 3d 3d 30 20 29 20 2a 70 52  p->zOut==0 ) *pR
11e0: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
11f0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  ;.  }.}../*.** T
1200: 6f 6b 65 6e 69 7a 65 72 20 63 61 6c 6c 62 61 63  okenizer callbac
1210: 6b 20 75 73 65 64 20 62 79 20 69 6d 70 6c 65 6d  k used by implem
1220: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 68 69 67 68  entation of high
1230: 6c 69 67 68 74 28 29 20 66 75 6e 63 74 69 6f 6e  light() function
1240: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1250: 66 74 73 35 48 69 67 68 6c 69 67 68 74 43 62 28  fts5HighlightCb(
1260: 0a 20 20 76 6f 69 64 20 2a 70 43 6f 6e 74 65 78  .  void *pContex
1270: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
1280: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
1290: 20 48 69 67 68 6c 69 67 68 74 43 6f 6e 74 65 78   HighlightContex
12a0: 74 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e  t object */.  in
12b0: 74 20 74 66 6c 61 67 73 2c 20 20 20 20 20 20 20  t tflags,       
12c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
12d0: 20 4d 61 73 6b 20 6f 66 20 46 54 53 35 5f 54 4f   Mask of FTS5_TO
12e0: 4b 45 4e 5f 2a 20 66 6c 61 67 73 20 2a 2f 0a 20  KEN_* flags */. 
12f0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 6f   const char *pTo
1300: 6b 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  ken,            
1310: 20 2f 2a 20 42 75 66 66 65 72 20 63 6f 6e 74 61   /* Buffer conta
1320: 69 6e 69 6e 67 20 74 6f 6b 65 6e 20 2a 2f 0a 20  ining token */. 
1330: 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 20 20 20   int nToken,    
1340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1350: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74 6f 6b 65   /* Size of toke
1360: 6e 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  n in bytes */.  
1370: 69 6e 74 20 69 53 74 61 72 74 4f 66 66 2c 20 20  int iStartOff,  
1380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1390: 2f 2a 20 53 74 61 72 74 20 6f 66 66 73 65 74 20  /* Start offset 
13a0: 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e  of token */.  in
13b0: 74 20 69 45 6e 64 4f 66 66 20 20 20 20 20 20 20  t iEndOff       
13c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
13d0: 20 45 6e 64 20 6f 66 66 73 65 74 20 6f 66 20 74   End offset of t
13e0: 6f 6b 65 6e 20 2a 2f 0a 29 7b 0a 20 20 48 69 67  oken */.){.  Hig
13f0: 68 6c 69 67 68 74 43 6f 6e 74 65 78 74 20 2a 70  hlightContext *p
1400: 20 3d 20 28 48 69 67 68 6c 69 67 68 74 43 6f 6e   = (HighlightCon
1410: 74 65 78 74 2a 29 70 43 6f 6e 74 65 78 74 3b 0a  text*)pContext;.
1420: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
1430: 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 69 50 6f 73  E_OK;.  int iPos
1440: 3b 0a 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41  ;..  UNUSED_PARA
1450: 4d 32 28 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65  M2(pToken, nToke
1460: 6e 29 3b 0a 0a 20 20 69 66 28 20 74 66 6c 61 67  n);..  if( tflag
1470: 73 20 26 20 46 54 53 35 5f 54 4f 4b 45 4e 5f 43  s & FTS5_TOKEN_C
1480: 4f 4c 4f 43 41 54 45 44 20 29 20 72 65 74 75 72  OLOCATED ) retur
1490: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  n SQLITE_OK;.  i
14a0: 50 6f 73 20 3d 20 70 2d 3e 69 50 6f 73 2b 2b 3b  Pos = p->iPos++;
14b0: 0a 0a 20 20 69 66 28 20 70 2d 3e 69 52 61 6e 67  ..  if( p->iRang
14c0: 65 45 6e 64 3e 30 20 29 7b 0a 20 20 20 20 69 66  eEnd>0 ){.    if
14d0: 28 20 69 50 6f 73 3c 70 2d 3e 69 52 61 6e 67 65  ( iPos<p->iRange
14e0: 53 74 61 72 74 20 7c 7c 20 69 50 6f 73 3e 70 2d  Start || iPos>p-
14f0: 3e 69 52 61 6e 67 65 45 6e 64 20 29 20 72 65 74  >iRangeEnd ) ret
1500: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  urn SQLITE_OK;. 
1510: 20 20 20 69 66 28 20 70 2d 3e 69 52 61 6e 67 65     if( p->iRange
1520: 53 74 61 72 74 20 26 26 20 69 50 6f 73 3d 3d 70  Start && iPos==p
1530: 2d 3e 69 52 61 6e 67 65 53 74 61 72 74 20 29 20  ->iRangeStart ) 
1540: 70 2d 3e 69 4f 66 66 20 3d 20 69 53 74 61 72 74  p->iOff = iStart
1550: 4f 66 66 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  Off;.  }..  if( 
1560: 69 50 6f 73 3d 3d 70 2d 3e 69 74 65 72 2e 69 53  iPos==p->iter.iS
1570: 74 61 72 74 20 29 7b 0a 20 20 20 20 66 74 73 35  tart ){.    fts5
1580: 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e 64 28  HighlightAppend(
1590: 26 72 63 2c 20 70 2c 20 26 70 2d 3e 7a 49 6e 5b  &rc, p, &p->zIn[
15a0: 70 2d 3e 69 4f 66 66 5d 2c 20 69 53 74 61 72 74  p->iOff], iStart
15b0: 4f 66 66 20 2d 20 70 2d 3e 69 4f 66 66 29 3b 0a  Off - p->iOff);.
15c0: 20 20 20 20 66 74 73 35 48 69 67 68 6c 69 67 68      fts5Highligh
15d0: 74 41 70 70 65 6e 64 28 26 72 63 2c 20 70 2c 20  tAppend(&rc, p, 
15e0: 70 2d 3e 7a 4f 70 65 6e 2c 20 2d 31 29 3b 0a 20  p->zOpen, -1);. 
15f0: 20 20 20 70 2d 3e 69 4f 66 66 20 3d 20 69 53 74     p->iOff = iSt
1600: 61 72 74 4f 66 66 3b 0a 20 20 7d 0a 0a 20 20 69  artOff;.  }..  i
1610: 66 28 20 69 50 6f 73 3d 3d 70 2d 3e 69 74 65 72  f( iPos==p->iter
1620: 2e 69 45 6e 64 20 29 7b 0a 20 20 20 20 69 66 28  .iEnd ){.    if(
1630: 20 70 2d 3e 69 52 61 6e 67 65 45 6e 64 20 26 26   p->iRangeEnd &&
1640: 20 70 2d 3e 69 74 65 72 2e 69 53 74 61 72 74 3c   p->iter.iStart<
1650: 70 2d 3e 69 52 61 6e 67 65 53 74 61 72 74 20 29  p->iRangeStart )
1660: 7b 0a 20 20 20 20 20 20 66 74 73 35 48 69 67 68  {.      fts5High
1670: 6c 69 67 68 74 41 70 70 65 6e 64 28 26 72 63 2c  lightAppend(&rc,
1680: 20 70 2c 20 70 2d 3e 7a 4f 70 65 6e 2c 20 2d 31   p, p->zOpen, -1
1690: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 74 73  );.    }.    fts
16a0: 35 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e 64  5HighlightAppend
16b0: 28 26 72 63 2c 20 70 2c 20 26 70 2d 3e 7a 49 6e  (&rc, p, &p->zIn
16c0: 5b 70 2d 3e 69 4f 66 66 5d 2c 20 69 45 6e 64 4f  [p->iOff], iEndO
16d0: 66 66 20 2d 20 70 2d 3e 69 4f 66 66 29 3b 0a 20  ff - p->iOff);. 
16e0: 20 20 20 66 74 73 35 48 69 67 68 6c 69 67 68 74     fts5Highlight
16f0: 41 70 70 65 6e 64 28 26 72 63 2c 20 70 2c 20 70  Append(&rc, p, p
1700: 2d 3e 7a 43 6c 6f 73 65 2c 20 2d 31 29 3b 0a 20  ->zClose, -1);. 
1710: 20 20 20 70 2d 3e 69 4f 66 66 20 3d 20 69 45 6e     p->iOff = iEn
1720: 64 4f 66 66 3b 0a 20 20 20 20 69 66 28 20 72 63  dOff;.    if( rc
1730: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
1740: 20 20 20 20 20 72 63 20 3d 20 66 74 73 35 43 49       rc = fts5CI
1750: 6e 73 74 49 74 65 72 4e 65 78 74 28 26 70 2d 3e  nstIterNext(&p->
1760: 69 74 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  iter);.    }.  }
1770: 0a 0a 20 20 69 66 28 20 70 2d 3e 69 52 61 6e 67  ..  if( p->iRang
1780: 65 45 6e 64 3e 30 20 26 26 20 69 50 6f 73 3d 3d  eEnd>0 && iPos==
1790: 70 2d 3e 69 52 61 6e 67 65 45 6e 64 20 29 7b 0a  p->iRangeEnd ){.
17a0: 20 20 20 20 66 74 73 35 48 69 67 68 6c 69 67 68      fts5Highligh
17b0: 74 41 70 70 65 6e 64 28 26 72 63 2c 20 70 2c 20  tAppend(&rc, p, 
17c0: 26 70 2d 3e 7a 49 6e 5b 70 2d 3e 69 4f 66 66 5d  &p->zIn[p->iOff]
17d0: 2c 20 69 45 6e 64 4f 66 66 20 2d 20 70 2d 3e 69  , iEndOff - p->i
17e0: 4f 66 66 29 3b 0a 20 20 20 20 70 2d 3e 69 4f 66  Off);.    p->iOf
17f0: 66 20 3d 20 69 45 6e 64 4f 66 66 3b 0a 20 20 20  f = iEndOff;.   
1800: 20 69 66 28 20 69 50 6f 73 3e 3d 70 2d 3e 69 74   if( iPos>=p->it
1810: 65 72 2e 69 53 74 61 72 74 20 26 26 20 69 50 6f  er.iStart && iPo
1820: 73 3c 70 2d 3e 69 74 65 72 2e 69 45 6e 64 20 29  s<p->iter.iEnd )
1830: 7b 0a 20 20 20 20 20 20 66 74 73 35 48 69 67 68  {.      fts5High
1840: 6c 69 67 68 74 41 70 70 65 6e 64 28 26 72 63 2c  lightAppend(&rc,
1850: 20 70 2c 20 70 2d 3e 7a 43 6c 6f 73 65 2c 20 2d   p, p->zClose, -
1860: 31 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  1);.    }.  }.. 
1870: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
1880: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
1890: 69 6f 6e 20 6f 66 20 68 69 67 68 6c 69 67 68 74  ion of highlight
18a0: 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a  () function..*/.
18b0: 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35  static void fts5
18c0: 48 69 67 68 6c 69 67 68 74 46 75 6e 63 74 69 6f  HighlightFunctio
18d0: 6e 28 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45  n(.  const Fts5E
18e0: 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70  xtensionApi *pAp
18f0: 69 2c 20 20 20 2f 2a 20 41 50 49 20 6f 66 66 65  i,   /* API offe
1900: 72 65 64 20 62 79 20 63 75 72 72 65 6e 74 20 46  red by current F
1910: 54 53 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20  TS version */.  
1920: 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74  Fts5Context *pFt
1930: 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s,              
1940: 2f 2a 20 46 69 72 73 74 20 61 72 67 20 74 6f 20  /* First arg to 
1950: 70 61 73 73 20 74 6f 20 70 41 70 69 20 66 75 6e  pass to pApi fun
1960: 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 73 71 6c 69  ctions */.  sqli
1970: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43 74  te3_context *pCt
1980: 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43  x,          /* C
1990: 6f 6e 74 65 78 74 20 66 6f 72 20 72 65 74 75 72  ontext for retur
19a0: 6e 69 6e 67 20 72 65 73 75 6c 74 2f 65 72 72 6f  ning result/erro
19b0: 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 56 61 6c 2c  r */.  int nVal,
19c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19d0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
19e0: 20 6f 66 20 76 61 6c 75 65 73 20 69 6e 20 61 70   of values in ap
19f0: 56 61 6c 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20  Val[] array */. 
1a00: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
1a10: 2a 61 70 56 61 6c 20 20 20 20 20 20 20 20 20 20  *apVal          
1a20: 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 74 72 61   /* Array of tra
1a30: 69 6c 69 6e 67 20 61 72 67 75 6d 65 6e 74 73 20  iling arguments 
1a40: 2a 2f 0a 29 7b 0a 20 20 48 69 67 68 6c 69 67 68  */.){.  Highligh
1a50: 74 43 6f 6e 74 65 78 74 20 63 74 78 3b 0a 20 20  tContext ctx;.  
1a60: 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 43  int rc;.  int iC
1a70: 6f 6c 3b 0a 0a 20 20 69 66 28 20 6e 56 61 6c 21  ol;..  if( nVal!
1a80: 3d 33 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20  =3 ){.    const 
1a90: 63 68 61 72 20 2a 7a 45 72 72 20 3d 20 22 77 72  char *zErr = "wr
1aa0: 6f 6e 67 20 6e 75 6d 62 65 72 20 6f 66 20 61 72  ong number of ar
1ab0: 67 75 6d 65 6e 74 73 20 74 6f 20 66 75 6e 63 74  guments to funct
1ac0: 69 6f 6e 20 68 69 67 68 6c 69 67 68 74 28 29 22  ion highlight()"
1ad0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65  ;.    sqlite3_re
1ae0: 73 75 6c 74 5f 65 72 72 6f 72 28 70 43 74 78 2c  sult_error(pCtx,
1af0: 20 7a 45 72 72 2c 20 2d 31 29 3b 0a 20 20 20 20   zErr, -1);.    
1b00: 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 69  return;.  }..  i
1b10: 43 6f 6c 20 3d 20 73 71 6c 69 74 65 33 5f 76 61  Col = sqlite3_va
1b20: 6c 75 65 5f 69 6e 74 28 61 70 56 61 6c 5b 30 5d  lue_int(apVal[0]
1b30: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 63 74 78  );.  memset(&ctx
1b40: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 48 69 67 68  , 0, sizeof(High
1b50: 6c 69 67 68 74 43 6f 6e 74 65 78 74 29 29 3b 0a  lightContext));.
1b60: 20 20 63 74 78 2e 7a 4f 70 65 6e 20 3d 20 28 63    ctx.zOpen = (c
1b70: 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74  onst char*)sqlit
1b80: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70  e3_value_text(ap
1b90: 56 61 6c 5b 31 5d 29 3b 0a 20 20 63 74 78 2e 7a  Val[1]);.  ctx.z
1ba0: 43 6c 6f 73 65 20 3d 20 28 63 6f 6e 73 74 20 63  Close = (const c
1bb0: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  har*)sqlite3_val
1bc0: 75 65 5f 74 65 78 74 28 61 70 56 61 6c 5b 32 5d  ue_text(apVal[2]
1bd0: 29 3b 0a 20 20 72 63 20 3d 20 70 41 70 69 2d 3e  );.  rc = pApi->
1be0: 78 43 6f 6c 75 6d 6e 54 65 78 74 28 70 46 74 73  xColumnText(pFts
1bf0: 2c 20 69 43 6f 6c 2c 20 26 63 74 78 2e 7a 49 6e  , iCol, &ctx.zIn
1c00: 2c 20 26 63 74 78 2e 6e 49 6e 29 3b 0a 0a 20 20  , &ctx.nIn);..  
1c10: 69 66 28 20 63 74 78 2e 7a 49 6e 20 29 7b 0a 20  if( ctx.zIn ){. 
1c20: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
1c30: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63  E_OK ){.      rc
1c40: 20 3d 20 66 74 73 35 43 49 6e 73 74 49 74 65 72   = fts5CInstIter
1c50: 49 6e 69 74 28 70 41 70 69 2c 20 70 46 74 73 2c  Init(pApi, pFts,
1c60: 20 69 43 6f 6c 2c 20 26 63 74 78 2e 69 74 65 72   iCol, &ctx.iter
1c70: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66  );.    }..    if
1c80: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1c90: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 70 41  ){.      rc = pA
1ca0: 70 69 2d 3e 78 54 6f 6b 65 6e 69 7a 65 28 70 46  pi->xTokenize(pF
1cb0: 74 73 2c 20 63 74 78 2e 7a 49 6e 2c 20 63 74 78  ts, ctx.zIn, ctx
1cc0: 2e 6e 49 6e 2c 20 28 76 6f 69 64 2a 29 26 63 74  .nIn, (void*)&ct
1cd0: 78 2c 66 74 73 35 48 69 67 68 6c 69 67 68 74 43  x,fts5HighlightC
1ce0: 62 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 74  b);.    }.    ft
1cf0: 73 35 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e  s5HighlightAppen
1d00: 64 28 26 72 63 2c 20 26 63 74 78 2c 20 26 63 74  d(&rc, &ctx, &ct
1d10: 78 2e 7a 49 6e 5b 63 74 78 2e 69 4f 66 66 5d 2c  x.zIn[ctx.iOff],
1d20: 20 63 74 78 2e 6e 49 6e 20 2d 20 63 74 78 2e 69   ctx.nIn - ctx.i
1d30: 4f 66 66 29 3b 0a 0a 20 20 20 20 69 66 28 20 72  Off);..    if( r
1d40: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
1d50: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65        sqlite3_re
1d60: 73 75 6c 74 5f 74 65 78 74 28 70 43 74 78 2c 20  sult_text(pCtx, 
1d70: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 63 74 78  (const char*)ctx
1d80: 2e 7a 4f 75 74 2c 20 2d 31 2c 20 53 51 4c 49 54  .zOut, -1, SQLIT
1d90: 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20  E_TRANSIENT);.  
1da0: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f    }.    sqlite3_
1db0: 66 72 65 65 28 63 74 78 2e 7a 4f 75 74 29 3b 0a  free(ctx.zOut);.
1dc0: 20 20 7d 0a 20 20 69 66 28 20 72 63 21 3d 53 51    }.  if( rc!=SQ
1dd0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73  LITE_OK ){.    s
1de0: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72  qlite3_result_er
1df0: 72 6f 72 5f 63 6f 64 65 28 70 43 74 78 2c 20 72  ror_code(pCtx, r
1e00: 63 29 3b 0a 20 20 7d 0a 7d 0a 2f 2a 0a 2a 2a 20  c);.  }.}./*.** 
1e10: 45 6e 64 20 6f 66 20 68 69 67 68 6c 69 67 68 74  End of highlight
1e20: 28 29 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  () implementatio
1e30: 6e 2e 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  n..*************
1e40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1e50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1e60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1e70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a  *************/..
1e80: 2f 2a 0a 2a 2a 20 43 6f 6e 74 65 78 74 20 6f 62  /*.** Context ob
1e90: 6a 65 63 74 20 70 61 73 73 65 64 20 74 6f 20 74  ject passed to t
1ea0: 68 65 20 66 74 73 35 53 65 6e 74 65 6e 63 65 46  he fts5SentenceF
1eb0: 69 6e 64 65 72 43 62 28 29 20 66 75 6e 63 74 69  inderCb() functi
1ec0: 6f 6e 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73  on..*/.typedef s
1ed0: 74 72 75 63 74 20 46 74 73 35 53 46 69 6e 64 65  truct Fts5SFinde
1ee0: 72 20 46 74 73 35 53 46 69 6e 64 65 72 3b 0a 73  r Fts5SFinder;.s
1ef0: 74 72 75 63 74 20 46 74 73 35 53 46 69 6e 64 65  truct Fts5SFinde
1f00: 72 20 7b 0a 20 20 69 6e 74 20 69 50 6f 73 3b 20  r {.  int iPos; 
1f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f20: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
1f30: 20 74 6f 6b 65 6e 20 70 6f 73 69 74 69 6f 6e 20   token position 
1f40: 2a 2f 0a 20 20 69 6e 74 20 6e 46 69 72 73 74 41  */.  int nFirstA
1f50: 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20 20 20 20  lloc;           
1f60: 20 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65       /* Allocate
1f70: 64 20 73 69 7a 65 20 6f 66 20 61 46 69 72 73 74  d size of aFirst
1f80: 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20 6e 46 69 72  [] */.  int nFir
1f90: 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  st;             
1fa0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
1fb0: 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20  r of entries in 
1fc0: 61 46 69 72 73 74 5b 5d 20 2a 2f 0a 20 20 69 6e  aFirst[] */.  in
1fd0: 74 20 2a 61 46 69 72 73 74 3b 20 20 20 20 20 20  t *aFirst;      
1fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1ff0: 20 41 72 72 61 79 20 6f 66 20 66 69 72 73 74 20   Array of first 
2000: 74 6f 6b 65 6e 20 69 6e 20 65 61 63 68 20 73 65  token in each se
2010: 6e 74 65 6e 63 65 20 2a 2f 0a 20 20 63 6f 6e 73  ntence */.  cons
2020: 74 20 63 68 61 72 20 2a 7a 44 6f 63 3b 20 20 20  t char *zDoc;   
2030: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
2040: 6f 63 75 6d 65 6e 74 20 62 65 69 6e 67 20 74 6f  ocument being to
2050: 6b 65 6e 69 7a 65 64 20 2a 2f 0a 7d 3b 0a 0a 2f  kenized */.};../
2060: 2a 0a 2a 2a 20 41 64 64 20 61 6e 20 65 6e 74 72  *.** Add an entr
2070: 79 20 74 6f 20 74 68 65 20 46 74 73 35 53 46 69  y to the Fts5SFi
2080: 6e 64 65 72 2e 61 46 69 72 73 74 5b 5d 20 61 72  nder.aFirst[] ar
2090: 72 61 79 2e 20 47 72 6f 77 20 74 68 65 20 61 72  ray. Grow the ar
20a0: 72 61 79 20 69 66 0a 2a 2a 20 6e 65 63 65 73 73  ray if.** necess
20b0: 61 72 79 2e 20 52 65 74 75 72 6e 20 53 51 4c 49  ary. Return SQLI
20c0: 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73  TE_OK if success
20d0: 66 75 6c 2c 20 6f 72 20 53 51 4c 49 54 45 5f 4e  ful, or SQLITE_N
20e0: 4f 4d 45 4d 20 69 66 20 61 6e 0a 2a 2a 20 65 72  OMEM if an.** er
20f0: 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  ror occurs..*/.s
2100: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 53 65  tatic int fts5Se
2110: 6e 74 65 6e 63 65 46 69 6e 64 65 72 41 64 64 28  ntenceFinderAdd(
2120: 46 74 73 35 53 46 69 6e 64 65 72 20 2a 70 2c 20  Fts5SFinder *p, 
2130: 69 6e 74 20 69 41 64 64 29 7b 0a 20 20 69 66 28  int iAdd){.  if(
2140: 20 70 2d 3e 6e 46 69 72 73 74 41 6c 6c 6f 63 3d   p->nFirstAlloc=
2150: 3d 70 2d 3e 6e 46 69 72 73 74 20 29 7b 0a 20 20  =p->nFirst ){.  
2160: 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20 70 2d 3e    int nNew = p->
2170: 6e 46 69 72 73 74 41 6c 6c 6f 63 20 3f 20 70 2d  nFirstAlloc ? p-
2180: 3e 6e 46 69 72 73 74 41 6c 6c 6f 63 2a 32 20 3a  >nFirstAlloc*2 :
2190: 20 36 34 3b 0a 20 20 20 20 69 6e 74 20 2a 61 4e   64;.    int *aN
21a0: 65 77 3b 0a 0a 20 20 20 20 61 4e 65 77 20 3d 20  ew;..    aNew = 
21b0: 28 69 6e 74 2a 29 73 71 6c 69 74 65 33 5f 72 65  (int*)sqlite3_re
21c0: 61 6c 6c 6f 63 36 34 28 70 2d 3e 61 46 69 72 73  alloc64(p->aFirs
21d0: 74 2c 20 6e 4e 65 77 2a 73 69 7a 65 6f 66 28 69  t, nNew*sizeof(i
21e0: 6e 74 29 29 3b 0a 20 20 20 20 69 66 28 20 61 4e  nt));.    if( aN
21f0: 65 77 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  ew==0 ) return S
2200: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
2210: 20 70 2d 3e 61 46 69 72 73 74 20 3d 20 61 4e 65   p->aFirst = aNe
2220: 77 3b 0a 20 20 20 20 70 2d 3e 6e 46 69 72 73 74  w;.    p->nFirst
2230: 41 6c 6c 6f 63 20 3d 20 6e 4e 65 77 3b 0a 20 20  Alloc = nNew;.  
2240: 7d 0a 20 20 70 2d 3e 61 46 69 72 73 74 5b 70 2d  }.  p->aFirst[p-
2250: 3e 6e 46 69 72 73 74 2b 2b 5d 20 3d 20 69 41 64  >nFirst++] = iAd
2260: 64 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  d;.  return SQLI
2270: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
2280: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
2290: 20 61 6e 20 78 54 6f 6b 65 6e 69 7a 65 28 29 20   an xTokenize() 
22a0: 63 61 6c 6c 62 61 63 6b 20 75 73 65 64 20 62 79  callback used by
22b0: 20 74 68 65 20 61 75 78 69 6c 69 61 72 79 20 73   the auxiliary s
22c0: 6e 69 70 70 65 74 28 29 0a 2a 2a 20 66 75 6e 63  nippet().** func
22d0: 74 69 6f 6e 2e 20 49 74 73 20 6a 6f 62 20 69 73  tion. Its job is
22e0: 20 74 6f 20 69 64 65 6e 74 69 66 79 20 74 6f 6b   to identify tok
22f0: 65 6e 73 20 74 68 61 74 20 61 72 65 20 74 68 65  ens that are the
2300: 20 66 69 72 73 74 20 69 6e 20 61 20 73 65 6e 74   first in a sent
2310: 65 6e 63 65 2e 0a 2a 2a 20 46 6f 72 20 65 61 63  ence..** For eac
2320: 68 20 73 75 63 68 20 74 6f 6b 65 6e 2c 20 61 6e  h such token, an
2330: 20 65 6e 74 72 79 20 69 73 20 61 64 64 65 64 20   entry is added 
2340: 74 6f 20 74 68 65 20 53 46 69 6e 64 65 72 2e 61  to the SFinder.a
2350: 46 69 72 73 74 5b 5d 20 61 72 72 61 79 2e 0a 2a  First[] array..*
2360: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
2370: 35 53 65 6e 74 65 6e 63 65 46 69 6e 64 65 72 43  5SentenceFinderC
2380: 62 28 0a 20 20 76 6f 69 64 20 2a 70 43 6f 6e 74  b(.  void *pCont
2390: 65 78 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  ext,            
23a0: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
23b0: 74 6f 20 48 69 67 68 6c 69 67 68 74 43 6f 6e 74  to HighlightCont
23c0: 65 78 74 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  ext object */.  
23d0: 69 6e 74 20 74 66 6c 61 67 73 2c 20 20 20 20 20  int tflags,     
23e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23f0: 2f 2a 20 4d 61 73 6b 20 6f 66 20 46 54 53 35 5f  /* Mask of FTS5_
2400: 54 4f 4b 45 4e 5f 2a 20 66 6c 61 67 73 20 2a 2f  TOKEN_* flags */
2410: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  .  const char *p
2420: 54 6f 6b 65 6e 2c 20 20 20 20 20 20 20 20 20 20  Token,          
2430: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 63 6f 6e     /* Buffer con
2440: 74 61 69 6e 69 6e 67 20 74 6f 6b 65 6e 20 2a 2f  taining token */
2450: 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 20  .  int nToken,  
2460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2470: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74 6f     /* Size of to
2480: 6b 65 6e 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ken in bytes */.
2490: 20 20 69 6e 74 20 69 53 74 61 72 74 4f 66 66 2c    int iStartOff,
24a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24b0: 20 20 2f 2a 20 53 74 61 72 74 20 6f 66 66 73 65    /* Start offse
24c0: 74 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20  t of token */.  
24d0: 69 6e 74 20 69 45 6e 64 4f 66 66 20 20 20 20 20  int iEndOff     
24e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24f0: 2f 2a 20 45 6e 64 20 6f 66 66 73 65 74 20 6f 66  /* End offset of
2500: 20 74 6f 6b 65 6e 20 2a 2f 0a 29 7b 0a 20 20 69   token */.){.  i
2510: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
2520: 4b 3b 0a 0a 20 20 55 4e 55 53 45 44 5f 50 41 52  K;..  UNUSED_PAR
2530: 41 4d 32 28 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b  AM2(pToken, nTok
2540: 65 6e 29 3b 0a 20 20 55 4e 55 53 45 44 5f 50 41  en);.  UNUSED_PA
2550: 52 41 4d 28 69 45 6e 64 4f 66 66 29 3b 0a 0a 20  RAM(iEndOff);.. 
2560: 20 69 66 28 20 28 74 66 6c 61 67 73 20 26 20 46   if( (tflags & F
2570: 54 53 35 5f 54 4f 4b 45 4e 5f 43 4f 4c 4f 43 41  TS5_TOKEN_COLOCA
2580: 54 45 44 29 3d 3d 30 20 29 7b 0a 20 20 20 20 46  TED)==0 ){.    F
2590: 74 73 35 53 46 69 6e 64 65 72 20 2a 70 20 3d 20  ts5SFinder *p = 
25a0: 28 46 74 73 35 53 46 69 6e 64 65 72 2a 29 70 43  (Fts5SFinder*)pC
25b0: 6f 6e 74 65 78 74 3b 0a 20 20 20 20 69 66 28 20  ontext;.    if( 
25c0: 70 2d 3e 69 50 6f 73 3e 30 20 29 7b 0a 20 20 20  p->iPos>0 ){.   
25d0: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20     int i;.      
25e0: 63 68 61 72 20 63 20 3d 20 30 3b 0a 20 20 20 20  char c = 0;.    
25f0: 20 20 66 6f 72 28 69 3d 69 53 74 61 72 74 4f 66    for(i=iStartOf
2600: 66 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29 7b  f-1; i>=0; i--){
2610: 0a 20 20 20 20 20 20 20 20 63 20 3d 20 70 2d 3e  .        c = p->
2620: 7a 44 6f 63 5b 69 5d 3b 0a 20 20 20 20 20 20 20  zDoc[i];.       
2630: 20 69 66 28 20 63 21 3d 27 20 27 20 26 26 20 63   if( c!=' ' && c
2640: 21 3d 27 5c 74 27 20 26 26 20 63 21 3d 27 5c 6e  !='\t' && c!='\n
2650: 27 20 26 26 20 63 21 3d 27 5c 72 27 20 29 20 62  ' && c!='\r' ) b
2660: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
2670: 20 20 20 20 69 66 28 20 69 21 3d 69 53 74 61 72      if( i!=iStar
2680: 74 4f 66 66 2d 31 20 26 26 20 28 63 3d 3d 27 2e  tOff-1 && (c=='.
2690: 27 20 7c 7c 20 63 3d 3d 27 3a 27 29 20 29 7b 0a  ' || c==':') ){.
26a0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 66 74 73          rc = fts
26b0: 35 53 65 6e 74 65 6e 63 65 46 69 6e 64 65 72 41  5SentenceFinderA
26c0: 64 64 28 70 2c 20 70 2d 3e 69 50 6f 73 29 3b 0a  dd(p, p->iPos);.
26d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
26e0: 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 66 74  e{.      rc = ft
26f0: 73 35 53 65 6e 74 65 6e 63 65 46 69 6e 64 65 72  s5SentenceFinder
2700: 41 64 64 28 70 2c 20 30 29 3b 0a 20 20 20 20 7d  Add(p, 0);.    }
2710: 0a 20 20 20 20 70 2d 3e 69 50 6f 73 2b 2b 3b 0a  .    p->iPos++;.
2720: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
2730: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
2740: 74 73 35 53 6e 69 70 70 65 74 53 63 6f 72 65 28  ts5SnippetScore(
2750: 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45 78 74  .  const Fts5Ext
2760: 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c  ensionApi *pApi,
2770: 20 20 20 2f 2a 20 41 50 49 20 6f 66 66 65 72 65     /* API offere
2780: 64 20 62 79 20 63 75 72 72 65 6e 74 20 46 54 53  d by current FTS
2790: 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 46 74   version */.  Ft
27a0: 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c  s5Context *pFts,
27b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
27c0: 20 46 69 72 73 74 20 61 72 67 20 74 6f 20 70 61   First arg to pa
27d0: 73 73 20 74 6f 20 70 41 70 69 20 66 75 6e 63 74  ss to pApi funct
27e0: 69 6f 6e 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 44  ions */.  int nD
27f0: 6f 63 73 69 7a 65 2c 20 20 20 20 20 20 20 20 20  ocsize,         
2800: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
2810: 65 20 6f 66 20 63 6f 6c 75 6d 6e 20 69 6e 20 74  e of column in t
2820: 6f 6b 65 6e 73 20 2a 2f 0a 20 20 75 6e 73 69 67  okens */.  unsig
2830: 6e 65 64 20 63 68 61 72 20 2a 61 53 65 65 6e 2c  ned char *aSeen,
2840: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72             /* Ar
2850: 72 61 79 20 77 69 74 68 20 6f 6e 65 20 65 6c 65  ray with one ele
2860: 6d 65 6e 74 20 70 65 72 20 71 75 65 72 79 20 70  ment per query p
2870: 68 72 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20 69  hrase */.  int i
2880: 43 6f 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Col,            
2890: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
28a0: 6c 75 6d 6e 20 74 6f 20 73 63 6f 72 65 20 2a 2f  lumn to score */
28b0: 0a 20 20 69 6e 74 20 69 50 6f 73 2c 20 20 20 20  .  int iPos,    
28c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28d0: 20 20 20 2f 2a 20 53 74 61 72 74 69 6e 67 20 6f     /* Starting o
28e0: 66 66 73 65 74 20 74 6f 20 73 63 6f 72 65 20 2a  ffset to score *
28f0: 2f 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20  /.  int nToken, 
2900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2910: 20 20 20 20 2f 2a 20 4d 61 78 20 74 6f 6b 65 6e      /* Max token
2920: 73 20 70 65 72 20 73 6e 69 70 70 65 74 20 2a 2f  s per snippet */
2930: 0a 20 20 69 6e 74 20 2a 70 6e 53 63 6f 72 65 2c  .  int *pnScore,
2940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2950: 20 20 20 2f 2a 20 4f 55 54 3a 20 53 63 6f 72 65     /* OUT: Score
2960: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 69 50 6f 73   */.  int *piPos
2970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2980: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 41 64        /* OUT: Ad
2990: 6a 75 73 74 65 64 20 6f 66 66 73 65 74 20 2a 2f  justed offset */
29a0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  .){.  int rc;.  
29b0: 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 69 70 20  int i;.  int ip 
29c0: 3d 20 30 3b 0a 20 20 69 6e 74 20 69 63 20 3d 20  = 0;.  int ic = 
29d0: 30 3b 0a 20 20 69 6e 74 20 69 4f 66 66 20 3d 20  0;.  int iOff = 
29e0: 30 3b 0a 20 20 69 6e 74 20 69 46 69 72 73 74 20  0;.  int iFirst 
29f0: 3d 20 2d 31 3b 0a 20 20 69 6e 74 20 6e 49 6e 73  = -1;.  int nIns
2a00: 74 3b 0a 20 20 69 6e 74 20 6e 53 63 6f 72 65 20  t;.  int nScore 
2a10: 3d 20 30 3b 0a 20 20 69 6e 74 20 69 4c 61 73 74  = 0;.  int iLast
2a20: 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f   = 0;.  sqlite3_
2a30: 69 6e 74 36 34 20 69 45 6e 64 20 3d 20 28 73 71  int64 iEnd = (sq
2a40: 6c 69 74 65 33 5f 69 6e 74 36 34 29 69 50 6f 73  lite3_int64)iPos
2a50: 20 2b 20 6e 54 6f 6b 65 6e 3b 0a 0a 20 20 72 63   + nToken;..  rc
2a60: 20 3d 20 70 41 70 69 2d 3e 78 49 6e 73 74 43 6f   = pApi->xInstCo
2a70: 75 6e 74 28 70 46 74 73 2c 20 26 6e 49 6e 73 74  unt(pFts, &nInst
2a80: 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  );.  for(i=0; i<
2a90: 6e 49 6e 73 74 20 26 26 20 72 63 3d 3d 53 51 4c  nInst && rc==SQL
2aa0: 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20  ITE_OK; i++){.  
2ab0: 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 49 6e    rc = pApi->xIn
2ac0: 73 74 28 70 46 74 73 2c 20 69 2c 20 26 69 70 2c  st(pFts, i, &ip,
2ad0: 20 26 69 63 2c 20 26 69 4f 66 66 29 3b 0a 20 20   &ic, &iOff);.  
2ae0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2af0: 5f 4f 4b 20 26 26 20 69 63 3d 3d 69 43 6f 6c 20  _OK && ic==iCol 
2b00: 26 26 20 69 4f 66 66 3e 3d 69 50 6f 73 20 26 26  && iOff>=iPos &&
2b10: 20 69 4f 66 66 3c 69 45 6e 64 20 29 7b 0a 20 20   iOff<iEnd ){.  
2b20: 20 20 20 20 6e 53 63 6f 72 65 20 2b 3d 20 28 61      nScore += (a
2b30: 53 65 65 6e 5b 69 70 5d 20 3f 20 31 20 3a 20 31  Seen[ip] ? 1 : 1
2b40: 30 30 30 29 3b 0a 20 20 20 20 20 20 61 53 65 65  000);.      aSee
2b50: 6e 5b 69 70 5d 20 3d 20 31 3b 0a 20 20 20 20 20  n[ip] = 1;.     
2b60: 20 69 66 28 20 69 46 69 72 73 74 3c 30 20 29 20   if( iFirst<0 ) 
2b70: 69 46 69 72 73 74 20 3d 20 69 4f 66 66 3b 0a 20  iFirst = iOff;. 
2b80: 20 20 20 20 20 69 4c 61 73 74 20 3d 20 69 4f 66       iLast = iOf
2b90: 66 20 2b 20 70 41 70 69 2d 3e 78 50 68 72 61 73  f + pApi->xPhras
2ba0: 65 53 69 7a 65 28 70 46 74 73 2c 20 69 70 29 3b  eSize(pFts, ip);
2bb0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70  .    }.  }..  *p
2bc0: 6e 53 63 6f 72 65 20 3d 20 6e 53 63 6f 72 65 3b  nScore = nScore;
2bd0: 0a 20 20 69 66 28 20 70 69 50 6f 73 20 29 7b 0a  .  if( piPos ){.
2be0: 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36      sqlite3_int6
2bf0: 34 20 69 41 64 6a 20 3d 20 69 46 69 72 73 74 20  4 iAdj = iFirst 
2c00: 2d 20 28 6e 54 6f 6b 65 6e 20 2d 20 28 69 4c 61  - (nToken - (iLa
2c10: 73 74 2d 69 46 69 72 73 74 29 29 20 2f 20 32 3b  st-iFirst)) / 2;
2c20: 0a 20 20 20 20 69 66 28 20 28 69 41 64 6a 2b 6e  .    if( (iAdj+n
2c30: 54 6f 6b 65 6e 29 3e 6e 44 6f 63 73 69 7a 65 20  Token)>nDocsize 
2c40: 29 20 69 41 64 6a 20 3d 20 6e 44 6f 63 73 69 7a  ) iAdj = nDocsiz
2c50: 65 20 2d 20 6e 54 6f 6b 65 6e 3b 0a 20 20 20 20  e - nToken;.    
2c60: 69 66 28 20 69 41 64 6a 3c 30 20 29 20 69 41 64  if( iAdj<0 ) iAd
2c70: 6a 20 3d 20 30 3b 0a 20 20 20 20 2a 70 69 50 6f  j = 0;.    *piPo
2c80: 73 20 3d 20 69 41 64 6a 3b 0a 20 20 7d 0a 0a 20  s = iAdj;.  }.. 
2c90: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
2ca0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
2cb0: 76 61 6c 75 65 20 69 6e 20 70 56 61 6c 20 69 6e  value in pVal in
2cc0: 74 65 72 70 72 65 74 65 64 20 61 73 20 75 74 66  terpreted as utf
2cd0: 2d 38 20 74 65 78 74 2e 20 45 78 63 65 70 74 2c  -8 text. Except,
2ce0: 20 69 66 20 70 56 61 6c 20 0a 2a 2a 20 63 6f 6e   if pVal .** con
2cf0: 74 61 69 6e 73 20 61 20 4e 55 4c 4c 20 76 61 6c  tains a NULL val
2d00: 75 65 2c 20 72 65 74 75 72 6e 20 61 20 70 6f 69  ue, return a poi
2d10: 6e 74 65 72 20 74 6f 20 61 20 73 74 61 74 69 63  nter to a static
2d20: 20 73 74 72 69 6e 67 20 7a 65 72 6f 0a 2a 2a 20   string zero.** 
2d30: 62 79 74 65 73 20 69 6e 20 6c 65 6e 67 74 68 20  bytes in length 
2d40: 69 6e 73 74 65 61 64 20 6f 66 20 61 20 4e 55 4c  instead of a NUL
2d50: 4c 20 70 6f 69 6e 74 65 72 2e 0a 2a 2f 0a 73 74  L pointer..*/.st
2d60: 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20  atic const char 
2d70: 2a 66 74 73 35 56 61 6c 75 65 54 6f 54 65 78 74  *fts5ValueToText
2d80: 28 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a  (sqlite3_value *
2d90: 70 56 61 6c 29 7b 0a 20 20 63 6f 6e 73 74 20 63  pVal){.  const c
2da0: 68 61 72 20 2a 7a 52 65 74 20 3d 20 28 63 6f 6e  har *zRet = (con
2db0: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
2dc0: 5f 76 61 6c 75 65 5f 74 65 78 74 28 70 56 61 6c  _value_text(pVal
2dd0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a 52 65 74  );.  return zRet
2de0: 20 3f 20 7a 52 65 74 20 3a 20 22 22 3b 0a 7d 0a   ? zRet : "";.}.
2df0: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
2e00: 61 74 69 6f 6e 20 6f 66 20 73 6e 69 70 70 65 74  ation of snippet
2e10: 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a  () function..*/.
2e20: 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35  static void fts5
2e30: 53 6e 69 70 70 65 74 46 75 6e 63 74 69 6f 6e 28  SnippetFunction(
2e40: 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45 78 74  .  const Fts5Ext
2e50: 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c  ensionApi *pApi,
2e60: 20 20 20 2f 2a 20 41 50 49 20 6f 66 66 65 72 65     /* API offere
2e70: 64 20 62 79 20 63 75 72 72 65 6e 74 20 46 54 53  d by current FTS
2e80: 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 46 74   version */.  Ft
2e90: 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c  s5Context *pFts,
2ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2eb0: 20 46 69 72 73 74 20 61 72 67 20 74 6f 20 70 61   First arg to pa
2ec0: 73 73 20 74 6f 20 70 41 70 69 20 66 75 6e 63 74  ss to pApi funct
2ed0: 69 6f 6e 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ions */.  sqlite
2ee0: 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c  3_context *pCtx,
2ef0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e            /* Con
2f00: 74 65 78 74 20 66 6f 72 20 72 65 74 75 72 6e 69  text for returni
2f10: 6e 67 20 72 65 73 75 6c 74 2f 65 72 72 6f 72 20  ng result/error 
2f20: 2a 2f 0a 20 20 69 6e 74 20 6e 56 61 6c 2c 20 20  */.  int nVal,  
2f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f40: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
2f50: 66 20 76 61 6c 75 65 73 20 69 6e 20 61 70 56 61  f values in apVa
2f60: 6c 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20 20 73  l[] array */.  s
2f70: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
2f80: 70 56 61 6c 20 20 20 20 20 20 20 20 20 20 20 2f  pVal           /
2f90: 2a 20 41 72 72 61 79 20 6f 66 20 74 72 61 69 6c  * Array of trail
2fa0: 69 6e 67 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f  ing arguments */
2fb0: 0a 29 7b 0a 20 20 48 69 67 68 6c 69 67 68 74 43  .){.  HighlightC
2fc0: 6f 6e 74 65 78 74 20 63 74 78 3b 0a 20 20 69 6e  ontext ctx;.  in
2fd0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
2fe0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
2ff0: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
3000: 20 20 69 6e 74 20 69 43 6f 6c 3b 20 20 20 20 20    int iCol;     
3010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3020: 20 20 2f 2a 20 31 73 74 20 61 72 67 75 6d 65 6e    /* 1st argumen
3030: 74 20 74 6f 20 73 6e 69 70 70 65 74 28 29 20 2a  t to snippet() *
3040: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
3050: 7a 45 6c 6c 69 70 73 3b 20 20 20 20 20 20 20 20  zEllips;        
3060: 20 20 20 20 2f 2a 20 34 74 68 20 61 72 67 75 6d      /* 4th argum
3070: 65 6e 74 20 74 6f 20 73 6e 69 70 70 65 74 28 29  ent to snippet()
3080: 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e   */.  int nToken
3090: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
30a0: 20 20 20 20 20 20 2f 2a 20 35 74 68 20 61 72 67        /* 5th arg
30b0: 75 6d 65 6e 74 20 74 6f 20 73 6e 69 70 70 65 74  ument to snippet
30c0: 28 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 6e 73  () */.  int nIns
30d0: 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  t = 0;          
30e0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
30f0: 72 20 6f 66 20 69 6e 73 74 61 6e 63 65 20 6d 61  r of instance ma
3100: 74 63 68 65 73 20 74 68 69 73 20 72 6f 77 20 2a  tches this row *
3110: 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20  /.  int i;      
3120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3130: 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69      /* Used to i
3140: 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 69  terate through i
3150: 6e 73 74 61 6e 63 65 73 20 2a 2f 0a 20 20 69 6e  nstances */.  in
3160: 74 20 6e 50 68 72 61 73 65 3b 20 20 20 20 20 20  t nPhrase;      
3170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3180: 20 4e 75 6d 62 65 72 20 6f 66 20 70 68 72 61 73   Number of phras
3190: 65 73 20 69 6e 20 71 75 65 72 79 20 2a 2f 0a 20  es in query */. 
31a0: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a   unsigned char *
31b0: 61 53 65 65 6e 3b 20 20 20 20 20 20 20 20 20 20  aSeen;          
31c0: 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 22 73 65   /* Array of "se
31d0: 65 6e 20 69 6e 73 74 61 6e 63 65 22 20 66 6c 61  en instance" fla
31e0: 67 73 20 2a 2f 0a 20 20 69 6e 74 20 69 42 65 73  gs */.  int iBes
31f0: 74 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20  tCol;           
3200: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6c 75 6d          /* Colum
3210: 6e 20 63 6f 6e 74 61 69 6e 69 6e 67 20 62 65 73  n containing bes
3220: 74 20 73 6e 69 70 70 65 74 20 2a 2f 0a 20 20 69  t snippet */.  i
3230: 6e 74 20 69 42 65 73 74 53 74 61 72 74 20 3d 20  nt iBestStart = 
3240: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  0;             /
3250: 2a 20 46 69 72 73 74 20 74 6f 6b 65 6e 20 6f 66  * First token of
3260: 20 62 65 73 74 20 73 6e 69 70 70 65 74 20 2a 2f   best snippet */
3270: 0a 20 20 69 6e 74 20 6e 42 65 73 74 53 63 6f 72  .  int nBestScor
3280: 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  e = 0;          
3290: 20 20 20 2f 2a 20 53 63 6f 72 65 20 6f 66 20 62     /* Score of b
32a0: 65 73 74 20 73 6e 69 70 70 65 74 20 2a 2f 0a 20  est snippet */. 
32b0: 20 69 6e 74 20 6e 43 6f 6c 53 69 7a 65 20 3d 20   int nColSize = 
32c0: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
32d0: 20 2f 2a 20 54 6f 74 61 6c 20 73 69 7a 65 20 6f   /* Total size o
32e0: 66 20 69 42 65 73 74 43 6f 6c 20 69 6e 20 74 6f  f iBestCol in to
32f0: 6b 65 6e 73 20 2a 2f 0a 20 20 46 74 73 35 53 46  kens */.  Fts5SF
3300: 69 6e 64 65 72 20 73 46 69 6e 64 65 72 3b 20 20  inder sFinder;  
3310: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65            /* Use
3320: 64 20 74 6f 20 66 69 6e 64 20 74 68 65 20 62 65  d to find the be
3330: 67 69 6e 6e 69 6e 67 73 20 6f 66 20 73 65 6e 74  ginnings of sent
3340: 65 6e 63 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e  ences */.  int n
3350: 43 6f 6c 3b 0a 0a 20 20 69 66 28 20 6e 56 61 6c  Col;..  if( nVal
3360: 21 3d 35 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74  !=5 ){.    const
3370: 20 63 68 61 72 20 2a 7a 45 72 72 20 3d 20 22 77   char *zErr = "w
3380: 72 6f 6e 67 20 6e 75 6d 62 65 72 20 6f 66 20 61  rong number of a
3390: 72 67 75 6d 65 6e 74 73 20 74 6f 20 66 75 6e 63  rguments to func
33a0: 74 69 6f 6e 20 73 6e 69 70 70 65 74 28 29 22 3b  tion snippet()";
33b0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
33c0: 75 6c 74 5f 65 72 72 6f 72 28 70 43 74 78 2c 20  ult_error(pCtx, 
33d0: 7a 45 72 72 2c 20 2d 31 29 3b 0a 20 20 20 20 72  zErr, -1);.    r
33e0: 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 6e 43  eturn;.  }..  nC
33f0: 6f 6c 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75  ol = pApi->xColu
3400: 6d 6e 43 6f 75 6e 74 28 70 46 74 73 29 3b 0a 20  mnCount(pFts);. 
3410: 20 6d 65 6d 73 65 74 28 26 63 74 78 2c 20 30 2c   memset(&ctx, 0,
3420: 20 73 69 7a 65 6f 66 28 48 69 67 68 6c 69 67 68   sizeof(Highligh
3430: 74 43 6f 6e 74 65 78 74 29 29 3b 0a 20 20 69 43  tContext));.  iC
3440: 6f 6c 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c  ol = sqlite3_val
3450: 75 65 5f 69 6e 74 28 61 70 56 61 6c 5b 30 5d 29  ue_int(apVal[0])
3460: 3b 0a 20 20 63 74 78 2e 7a 4f 70 65 6e 20 3d 20  ;.  ctx.zOpen = 
3470: 66 74 73 35 56 61 6c 75 65 54 6f 54 65 78 74 28  fts5ValueToText(
3480: 61 70 56 61 6c 5b 31 5d 29 3b 0a 20 20 63 74 78  apVal[1]);.  ctx
3490: 2e 7a 43 6c 6f 73 65 20 3d 20 66 74 73 35 56 61  .zClose = fts5Va
34a0: 6c 75 65 54 6f 54 65 78 74 28 61 70 56 61 6c 5b  lueToText(apVal[
34b0: 32 5d 29 3b 0a 20 20 7a 45 6c 6c 69 70 73 20 3d  2]);.  zEllips =
34c0: 20 66 74 73 35 56 61 6c 75 65 54 6f 54 65 78 74   fts5ValueToText
34d0: 28 61 70 56 61 6c 5b 33 5d 29 3b 0a 20 20 6e 54  (apVal[3]);.  nT
34e0: 6f 6b 65 6e 20 3d 20 73 71 6c 69 74 65 33 5f 76  oken = sqlite3_v
34f0: 61 6c 75 65 5f 69 6e 74 28 61 70 56 61 6c 5b 34  alue_int(apVal[4
3500: 5d 29 3b 0a 0a 20 20 69 42 65 73 74 43 6f 6c 20  ]);..  iBestCol 
3510: 3d 20 28 69 43 6f 6c 3e 3d 30 20 3f 20 69 43 6f  = (iCol>=0 ? iCo
3520: 6c 20 3a 20 30 29 3b 0a 20 20 6e 50 68 72 61 73  l : 0);.  nPhras
3530: 65 20 3d 20 70 41 70 69 2d 3e 78 50 68 72 61 73  e = pApi->xPhras
3540: 65 43 6f 75 6e 74 28 70 46 74 73 29 3b 0a 20 20  eCount(pFts);.  
3550: 61 53 65 65 6e 20 3d 20 73 71 6c 69 74 65 33 5f  aSeen = sqlite3_
3560: 6d 61 6c 6c 6f 63 28 6e 50 68 72 61 73 65 29 3b  malloc(nPhrase);
3570: 0a 20 20 69 66 28 20 61 53 65 65 6e 3d 3d 30 20  .  if( aSeen==0 
3580: 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  ){.    rc = SQLI
3590: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
35a0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
35b0: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 70 41  K ){.    rc = pA
35c0: 70 69 2d 3e 78 49 6e 73 74 43 6f 75 6e 74 28 70  pi->xInstCount(p
35d0: 46 74 73 2c 20 26 6e 49 6e 73 74 29 3b 0a 20 20  Fts, &nInst);.  
35e0: 7d 0a 0a 20 20 6d 65 6d 73 65 74 28 26 73 46 69  }..  memset(&sFi
35f0: 6e 64 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  nder, 0, sizeof(
3600: 46 74 73 35 53 46 69 6e 64 65 72 29 29 3b 0a 20  Fts5SFinder));. 
3610: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c   for(i=0; i<nCol
3620: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20  ; i++){.    if( 
3630: 69 43 6f 6c 3c 30 20 7c 7c 20 69 43 6f 6c 3d 3d  iCol<0 || iCol==
3640: 69 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e  i ){.      int n
3650: 44 6f 63 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e  Doc;.      int n
3660: 44 6f 63 73 69 7a 65 3b 0a 20 20 20 20 20 20 69  Docsize;.      i
3670: 6e 74 20 69 69 3b 0a 20 20 20 20 20 20 73 46 69  nt ii;.      sFi
3680: 6e 64 65 72 2e 69 50 6f 73 20 3d 20 30 3b 0a 20  nder.iPos = 0;. 
3690: 20 20 20 20 20 73 46 69 6e 64 65 72 2e 6e 46 69       sFinder.nFi
36a0: 72 73 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 72  rst = 0;.      r
36b0: 63 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d  c = pApi->xColum
36c0: 6e 54 65 78 74 28 70 46 74 73 2c 20 69 2c 20 26  nText(pFts, i, &
36d0: 73 46 69 6e 64 65 72 2e 7a 44 6f 63 2c 20 26 6e  sFinder.zDoc, &n
36e0: 44 6f 63 29 3b 0a 20 20 20 20 20 20 69 66 28 20  Doc);.      if( 
36f0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
3700: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 72 63 20  break;.      rc 
3710: 3d 20 70 41 70 69 2d 3e 78 54 6f 6b 65 6e 69 7a  = pApi->xTokeniz
3720: 65 28 70 46 74 73 2c 20 0a 20 20 20 20 20 20 20  e(pFts, .       
3730: 20 20 20 73 46 69 6e 64 65 72 2e 7a 44 6f 63 2c     sFinder.zDoc,
3740: 20 6e 44 6f 63 2c 20 28 76 6f 69 64 2a 29 26 73   nDoc, (void*)&s
3750: 46 69 6e 64 65 72 2c 66 74 73 35 53 65 6e 74 65  Finder,fts5Sente
3760: 6e 63 65 46 69 6e 64 65 72 43 62 0a 20 20 20 20  nceFinderCb.    
3770: 20 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72    );.      if( r
3780: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62  c!=SQLITE_OK ) b
3790: 72 65 61 6b 3b 0a 20 20 20 20 20 20 72 63 20 3d  reak;.      rc =
37a0: 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e 53 69   pApi->xColumnSi
37b0: 7a 65 28 70 46 74 73 2c 20 69 2c 20 26 6e 44 6f  ze(pFts, i, &nDo
37c0: 63 73 69 7a 65 29 3b 0a 20 20 20 20 20 20 69 66  csize);.      if
37d0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
37e0: 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20  ) break;..      
37f0: 66 6f 72 28 69 69 3d 30 3b 20 72 63 3d 3d 53 51  for(ii=0; rc==SQ
3800: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 69 3c 6e 49  LITE_OK && ii<nI
3810: 6e 73 74 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20  nst; ii++){.    
3820: 20 20 20 20 69 6e 74 20 69 70 2c 20 69 63 2c 20      int ip, ic, 
3830: 69 6f 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  io;.        int 
3840: 69 41 64 6a 3b 0a 20 20 20 20 20 20 20 20 69 6e  iAdj;.        in
3850: 74 20 6e 53 63 6f 72 65 3b 0a 20 20 20 20 20 20  t nScore;.      
3860: 20 20 69 6e 74 20 6a 6a 3b 0a 0a 20 20 20 20 20    int jj;..     
3870: 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 49     rc = pApi->xI
3880: 6e 73 74 28 70 46 74 73 2c 20 69 69 2c 20 26 69  nst(pFts, ii, &i
3890: 70 2c 20 26 69 63 2c 20 26 69 6f 29 3b 0a 20 20  p, &ic, &io);.  
38a0: 20 20 20 20 20 20 69 66 28 20 69 63 21 3d 69 20        if( ic!=i 
38b0: 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20  ) continue;.    
38c0: 20 20 20 20 69 66 28 20 69 6f 3e 6e 44 6f 63 73      if( io>nDocs
38d0: 69 7a 65 20 29 20 72 63 20 3d 20 46 54 53 35 5f  ize ) rc = FTS5_
38e0: 43 4f 52 52 55 50 54 3b 0a 20 20 20 20 20 20 20  CORRUPT;.       
38f0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
3900: 4f 4b 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20  OK ) continue;. 
3910: 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28 61 53         memset(aS
3920: 65 65 6e 2c 20 30 2c 20 6e 50 68 72 61 73 65 29  een, 0, nPhrase)
3930: 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 66  ;.        rc = f
3940: 74 73 35 53 6e 69 70 70 65 74 53 63 6f 72 65 28  ts5SnippetScore(
3950: 70 41 70 69 2c 20 70 46 74 73 2c 20 6e 44 6f 63  pApi, pFts, nDoc
3960: 73 69 7a 65 2c 20 61 53 65 65 6e 2c 20 69 2c 0a  size, aSeen, i,.
3970: 20 20 20 20 20 20 20 20 20 20 20 20 69 6f 2c 20              io, 
3980: 6e 54 6f 6b 65 6e 2c 20 26 6e 53 63 6f 72 65 2c  nToken, &nScore,
3990: 20 26 69 41 64 6a 0a 20 20 20 20 20 20 20 20 29   &iAdj.        )
39a0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
39b0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 6e  ==SQLITE_OK && n
39c0: 53 63 6f 72 65 3e 6e 42 65 73 74 53 63 6f 72 65  Score>nBestScore
39d0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6e 42   ){.          nB
39e0: 65 73 74 53 63 6f 72 65 20 3d 20 6e 53 63 6f 72  estScore = nScor
39f0: 65 3b 0a 20 20 20 20 20 20 20 20 20 20 69 42 65  e;.          iBe
3a00: 73 74 43 6f 6c 20 3d 20 69 3b 0a 20 20 20 20 20  stCol = i;.     
3a10: 20 20 20 20 20 69 42 65 73 74 53 74 61 72 74 20       iBestStart 
3a20: 3d 20 69 41 64 6a 3b 0a 20 20 20 20 20 20 20 20  = iAdj;.        
3a30: 20 20 6e 43 6f 6c 53 69 7a 65 20 3d 20 6e 44 6f    nColSize = nDo
3a40: 63 73 69 7a 65 3b 0a 20 20 20 20 20 20 20 20 7d  csize;.        }
3a50: 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ..        if( rc
3a60: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 73  ==SQLITE_OK && s
3a70: 46 69 6e 64 65 72 2e 6e 46 69 72 73 74 20 26 26  Finder.nFirst &&
3a80: 20 6e 44 6f 63 73 69 7a 65 3e 6e 54 6f 6b 65 6e   nDocsize>nToken
3a90: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 66 6f   ){.          fo
3aa0: 72 28 6a 6a 3d 30 3b 20 6a 6a 3c 28 73 46 69 6e  r(jj=0; jj<(sFin
3ab0: 64 65 72 2e 6e 46 69 72 73 74 2d 31 29 3b 20 6a  der.nFirst-1); j
3ac0: 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20  j++){.          
3ad0: 20 20 69 66 28 20 73 46 69 6e 64 65 72 2e 61 46    if( sFinder.aF
3ae0: 69 72 73 74 5b 6a 6a 2b 31 5d 3e 69 6f 20 29 20  irst[jj+1]>io ) 
3af0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20  break;.         
3b00: 20 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 69 66   }..          if
3b10: 28 20 73 46 69 6e 64 65 72 2e 61 46 69 72 73 74  ( sFinder.aFirst
3b20: 5b 6a 6a 5d 3c 69 6f 20 29 7b 0a 20 20 20 20 20  [jj]<io ){.     
3b30: 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28 61 53         memset(aS
3b40: 65 65 6e 2c 20 30 2c 20 6e 50 68 72 61 73 65 29  een, 0, nPhrase)
3b50: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63  ;.            rc
3b60: 20 3d 20 66 74 73 35 53 6e 69 70 70 65 74 53 63   = fts5SnippetSc
3b70: 6f 72 65 28 70 41 70 69 2c 20 70 46 74 73 2c 20  ore(pApi, pFts, 
3b80: 6e 44 6f 63 73 69 7a 65 2c 20 61 53 65 65 6e 2c  nDocsize, aSeen,
3b90: 20 69 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20   i, .           
3ba0: 20 20 20 73 46 69 6e 64 65 72 2e 61 46 69 72 73     sFinder.aFirs
3bb0: 74 5b 6a 6a 5d 2c 20 6e 54 6f 6b 65 6e 2c 20 26  t[jj], nToken, &
3bc0: 6e 53 63 6f 72 65 2c 20 30 0a 20 20 20 20 20 20  nScore, 0.      
3bd0: 20 20 20 20 20 20 29 3b 0a 0a 20 20 20 20 20 20        );..      
3be0: 20 20 20 20 20 20 6e 53 63 6f 72 65 20 2b 3d 20        nScore += 
3bf0: 28 73 46 69 6e 64 65 72 2e 61 46 69 72 73 74 5b  (sFinder.aFirst[
3c00: 6a 6a 5d 3d 3d 30 20 3f 20 31 32 30 20 3a 20 31  jj]==0 ? 120 : 1
3c10: 30 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  00);.           
3c20: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
3c30: 4f 4b 20 26 26 20 6e 53 63 6f 72 65 3e 6e 42 65  OK && nScore>nBe
3c40: 73 74 53 63 6f 72 65 20 29 7b 0a 20 20 20 20 20  stScore ){.     
3c50: 20 20 20 20 20 20 20 20 20 6e 42 65 73 74 53 63           nBestSc
3c60: 6f 72 65 20 3d 20 6e 53 63 6f 72 65 3b 0a 20 20  ore = nScore;.  
3c70: 20 20 20 20 20 20 20 20 20 20 20 20 69 42 65 73              iBes
3c80: 74 43 6f 6c 20 3d 20 69 3b 0a 20 20 20 20 20 20  tCol = i;.      
3c90: 20 20 20 20 20 20 20 20 69 42 65 73 74 53 74 61          iBestSta
3ca0: 72 74 20 3d 20 73 46 69 6e 64 65 72 2e 61 46 69  rt = sFinder.aFi
3cb0: 72 73 74 5b 6a 6a 5d 3b 0a 20 20 20 20 20 20 20  rst[jj];.       
3cc0: 20 20 20 20 20 20 20 6e 43 6f 6c 53 69 7a 65 20         nColSize 
3cd0: 3d 20 6e 44 6f 63 73 69 7a 65 3b 0a 20 20 20 20  = nDocsize;.    
3ce0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
3cf0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
3d00: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
3d10: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
3d20: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
3d30: 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e   = pApi->xColumn
3d40: 54 65 78 74 28 70 46 74 73 2c 20 69 42 65 73 74  Text(pFts, iBest
3d50: 43 6f 6c 2c 20 26 63 74 78 2e 7a 49 6e 2c 20 26  Col, &ctx.zIn, &
3d60: 63 74 78 2e 6e 49 6e 29 3b 0a 20 20 7d 0a 20 20  ctx.nIn);.  }.  
3d70: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
3d80: 4b 20 26 26 20 6e 43 6f 6c 53 69 7a 65 3d 3d 30  K && nColSize==0
3d90: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 70 41 70   ){.    rc = pAp
3da0: 69 2d 3e 78 43 6f 6c 75 6d 6e 53 69 7a 65 28 70  i->xColumnSize(p
3db0: 46 74 73 2c 20 69 42 65 73 74 43 6f 6c 2c 20 26  Fts, iBestCol, &
3dc0: 6e 43 6f 6c 53 69 7a 65 29 3b 0a 20 20 7d 0a 20  nColSize);.  }. 
3dd0: 20 69 66 28 20 63 74 78 2e 7a 49 6e 20 29 7b 0a   if( ctx.zIn ){.
3de0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
3df0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  TE_OK ){.      r
3e00: 63 20 3d 20 66 74 73 35 43 49 6e 73 74 49 74 65  c = fts5CInstIte
3e10: 72 49 6e 69 74 28 70 41 70 69 2c 20 70 46 74 73  rInit(pApi, pFts
3e20: 2c 20 69 42 65 73 74 43 6f 6c 2c 20 26 63 74 78  , iBestCol, &ctx
3e30: 2e 69 74 65 72 29 3b 0a 20 20 20 20 7d 0a 0a 20  .iter);.    }.. 
3e40: 20 20 20 63 74 78 2e 69 52 61 6e 67 65 53 74 61     ctx.iRangeSta
3e50: 72 74 20 3d 20 69 42 65 73 74 53 74 61 72 74 3b  rt = iBestStart;
3e60: 0a 20 20 20 20 63 74 78 2e 69 52 61 6e 67 65 45  .    ctx.iRangeE
3e70: 6e 64 20 3d 20 69 42 65 73 74 53 74 61 72 74 20  nd = iBestStart 
3e80: 2b 20 6e 54 6f 6b 65 6e 20 2d 20 31 3b 0a 0a 20  + nToken - 1;.. 
3e90: 20 20 20 69 66 28 20 69 42 65 73 74 53 74 61 72     if( iBestStar
3ea0: 74 3e 30 20 29 7b 0a 20 20 20 20 20 20 66 74 73  t>0 ){.      fts
3eb0: 35 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e 64  5HighlightAppend
3ec0: 28 26 72 63 2c 20 26 63 74 78 2c 20 7a 45 6c 6c  (&rc, &ctx, zEll
3ed0: 69 70 73 2c 20 2d 31 29 3b 0a 20 20 20 20 7d 0a  ips, -1);.    }.
3ee0: 0a 20 20 20 20 2f 2a 20 41 64 76 61 6e 63 65 20  .    /* Advance 
3ef0: 69 74 65 72 61 74 6f 72 20 63 74 78 2e 69 74 65  iterator ctx.ite
3f00: 72 20 73 6f 20 74 68 61 74 20 69 74 20 70 6f 69  r so that it poi
3f10: 6e 74 73 20 74 6f 20 74 68 65 20 66 69 72 73 74  nts to the first
3f20: 20 63 6f 61 6c 65 73 63 65 64 0a 20 20 20 20 2a   coalesced.    *
3f30: 2a 20 70 68 72 61 73 65 20 69 6e 73 74 61 6e 63  * phrase instanc
3f40: 65 20 61 74 20 6f 72 20 66 6f 6c 6c 6f 77 69 6e  e at or followin
3f50: 67 20 70 6f 73 69 74 69 6f 6e 20 69 42 65 73 74  g position iBest
3f60: 53 74 61 72 74 2e 20 2a 2f 0a 20 20 20 20 77 68  Start. */.    wh
3f70: 69 6c 65 28 20 63 74 78 2e 69 74 65 72 2e 69 53  ile( ctx.iter.iS
3f80: 74 61 72 74 3e 3d 30 20 26 26 20 63 74 78 2e 69  tart>=0 && ctx.i
3f90: 74 65 72 2e 69 53 74 61 72 74 3c 69 42 65 73 74  ter.iStart<iBest
3fa0: 53 74 61 72 74 20 26 26 20 72 63 3d 3d 53 51 4c  Start && rc==SQL
3fb0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
3fc0: 72 63 20 3d 20 66 74 73 35 43 49 6e 73 74 49 74  rc = fts5CInstIt
3fd0: 65 72 4e 65 78 74 28 26 63 74 78 2e 69 74 65 72  erNext(&ctx.iter
3fe0: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66  );.    }..    if
3ff0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4000: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 70 41  ){.      rc = pA
4010: 70 69 2d 3e 78 54 6f 6b 65 6e 69 7a 65 28 70 46  pi->xTokenize(pF
4020: 74 73 2c 20 63 74 78 2e 7a 49 6e 2c 20 63 74 78  ts, ctx.zIn, ctx
4030: 2e 6e 49 6e 2c 20 28 76 6f 69 64 2a 29 26 63 74  .nIn, (void*)&ct
4040: 78 2c 66 74 73 35 48 69 67 68 6c 69 67 68 74 43  x,fts5HighlightC
4050: 62 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  b);.    }.    if
4060: 28 20 63 74 78 2e 69 52 61 6e 67 65 45 6e 64 3e  ( ctx.iRangeEnd>
4070: 3d 28 6e 43 6f 6c 53 69 7a 65 2d 31 29 20 29 7b  =(nColSize-1) ){
4080: 0a 20 20 20 20 20 20 66 74 73 35 48 69 67 68 6c  .      fts5Highl
4090: 69 67 68 74 41 70 70 65 6e 64 28 26 72 63 2c 20  ightAppend(&rc, 
40a0: 26 63 74 78 2c 20 26 63 74 78 2e 7a 49 6e 5b 63  &ctx, &ctx.zIn[c
40b0: 74 78 2e 69 4f 66 66 5d 2c 20 63 74 78 2e 6e 49  tx.iOff], ctx.nI
40c0: 6e 20 2d 20 63 74 78 2e 69 4f 66 66 29 3b 0a 20  n - ctx.iOff);. 
40d0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
40e0: 66 74 73 35 48 69 67 68 6c 69 67 68 74 41 70 70  fts5HighlightApp
40f0: 65 6e 64 28 26 72 63 2c 20 26 63 74 78 2c 20 7a  end(&rc, &ctx, z
4100: 45 6c 6c 69 70 73 2c 20 2d 31 29 3b 0a 20 20 20  Ellips, -1);.   
4110: 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d   }.  }.  if( rc=
4120: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
4130: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
4140: 5f 74 65 78 74 28 70 43 74 78 2c 20 28 63 6f 6e  _text(pCtx, (con
4150: 73 74 20 63 68 61 72 2a 29 63 74 78 2e 7a 4f 75  st char*)ctx.zOu
4160: 74 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52  t, -1, SQLITE_TR
4170: 41 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 65 6c 73  ANSIENT);.  }els
4180: 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  e{.    sqlite3_r
4190: 65 73 75 6c 74 5f 65 72 72 6f 72 5f 63 6f 64 65  esult_error_code
41a0: 28 70 43 74 78 2c 20 72 63 29 3b 0a 20 20 7d 0a  (pCtx, rc);.  }.
41b0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 63    sqlite3_free(c
41c0: 74 78 2e 7a 4f 75 74 29 3b 0a 20 20 73 71 6c 69  tx.zOut);.  sqli
41d0: 74 65 33 5f 66 72 65 65 28 61 53 65 65 6e 29 3b  te3_free(aSeen);
41e0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
41f0: 73 46 69 6e 64 65 72 2e 61 46 69 72 73 74 29 3b  sFinder.aFirst);
4200: 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .}../***********
4210: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4220: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4230: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a  *************/..
4250: 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 72 73 74 20  /*.** The first 
4260: 74 69 6d 65 20 74 68 65 20 62 6d 32 35 28 29 20  time the bm25() 
4270: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
4280: 65 64 20 66 6f 72 20 61 20 71 75 65 72 79 2c 20  ed for a query, 
4290: 61 6e 20 69 6e 73 74 61 6e 63 65 0a 2a 2a 20 6f  an instance.** o
42a0: 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
42b0: 73 74 72 75 63 74 75 72 65 20 69 73 20 61 6c 6c  structure is all
42c0: 6f 63 61 74 65 64 20 61 6e 64 20 70 6f 70 75 6c  ocated and popul
42d0: 61 74 65 64 2e 0a 2a 2f 0a 74 79 70 65 64 65 66  ated..*/.typedef
42e0: 20 73 74 72 75 63 74 20 46 74 73 35 42 6d 32 35   struct Fts5Bm25
42f0: 44 61 74 61 20 46 74 73 35 42 6d 32 35 44 61 74  Data Fts5Bm25Dat
4300: 61 3b 0a 73 74 72 75 63 74 20 46 74 73 35 42 6d  a;.struct Fts5Bm
4310: 32 35 44 61 74 61 20 7b 0a 20 20 69 6e 74 20 6e  25Data {.  int n
4320: 50 68 72 61 73 65 3b 20 20 20 20 20 20 20 20 20  Phrase;         
4330: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
4340: 6d 62 65 72 20 6f 66 20 70 68 72 61 73 65 73 20  mber of phrases 
4350: 69 6e 20 71 75 65 72 79 20 2a 2f 0a 20 20 64 6f  in query */.  do
4360: 75 62 6c 65 20 61 76 67 64 6c 3b 20 20 20 20 20  uble avgdl;     
4370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4380: 20 41 76 65 72 61 67 65 20 6e 75 6d 62 65 72 20   Average number 
4390: 6f 66 20 74 6f 6b 65 6e 73 20 69 6e 20 65 61 63  of tokens in eac
43a0: 68 20 72 6f 77 20 2a 2f 0a 20 20 64 6f 75 62 6c  h row */.  doubl
43b0: 65 20 2a 61 49 44 46 3b 20 20 20 20 20 20 20 20  e *aIDF;        
43c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 44             /* ID
43d0: 46 20 66 6f 72 20 65 61 63 68 20 70 68 72 61 73  F for each phras
43e0: 65 20 2a 2f 0a 20 20 64 6f 75 62 6c 65 20 2a 61  e */.  double *a
43f0: 46 72 65 71 3b 20 20 20 20 20 20 20 20 20 20 20  Freq;           
4400: 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20         /* Array 
4410: 75 73 65 64 20 74 6f 20 63 61 6c 63 75 6c 61 74  used to calculat
4420: 65 20 70 68 72 61 73 65 20 66 72 65 71 2e 20 2a  e phrase freq. *
4430: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 43 61 6c 6c  /.};../*.** Call
4440: 62 61 63 6b 20 75 73 65 64 20 62 79 20 66 74 73  back used by fts
4450: 35 42 6d 32 35 47 65 74 44 61 74 61 28 29 20 74  5Bm25GetData() t
4460: 6f 20 63 6f 75 6e 74 20 74 68 65 20 6e 75 6d 62  o count the numb
4470: 65 72 20 6f 66 20 72 6f 77 73 20 69 6e 20 74 68  er of rows in th
4480: 65 0a 2a 2a 20 74 61 62 6c 65 20 6d 61 74 63 68  e.** table match
4490: 65 64 20 62 79 20 65 61 63 68 20 69 6e 64 69 76  ed by each indiv
44a0: 69 64 75 61 6c 20 70 68 72 61 73 65 20 77 69 74  idual phrase wit
44b0: 68 69 6e 20 74 68 65 20 71 75 65 72 79 2e 0a 2a  hin the query..*
44c0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
44d0: 35 43 6f 75 6e 74 43 62 28 0a 20 20 63 6f 6e 73  5CountCb(.  cons
44e0: 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f 6e 41  t Fts5ExtensionA
44f0: 70 69 20 2a 70 41 70 69 2c 20 0a 20 20 46 74 73  pi *pApi, .  Fts
4500: 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c 0a  5Context *pFts,.
4510: 20 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61 74    void *pUserDat
4520: 61 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  a               
4530: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
4540: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 76 61  sqlite3_int64 va
4550: 72 69 61 62 6c 65 20 2a 2f 0a 29 7b 0a 20 20 73  riable */.){.  s
4560: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a 70 6e  qlite3_int64 *pn
4570: 20 3d 20 28 73 71 6c 69 74 65 33 5f 69 6e 74 36   = (sqlite3_int6
4580: 34 2a 29 70 55 73 65 72 44 61 74 61 3b 0a 20 20  4*)pUserData;.  
4590: 55 4e 55 53 45 44 5f 50 41 52 41 4d 32 28 70 41  UNUSED_PARAM2(pA
45a0: 70 69 2c 20 70 46 74 73 29 3b 0a 20 20 28 2a 70  pi, pFts);.  (*p
45b0: 6e 29 2b 2b 3b 0a 20 20 72 65 74 75 72 6e 20 53  n)++;.  return S
45c0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
45d0: 2a 2a 20 53 65 74 20 2a 70 70 44 61 74 61 20 74  ** Set *ppData t
45e0: 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 46  o point to the F
45f0: 74 73 35 42 6d 32 35 44 61 74 61 20 6f 62 6a 65  ts5Bm25Data obje
4600: 63 74 20 66 6f 72 20 74 68 65 20 63 75 72 72 65  ct for the curre
4610: 6e 74 20 71 75 65 72 79 2e 20 0a 2a 2a 20 49 66  nt query. .** If
4620: 20 74 68 65 20 6f 62 6a 65 63 74 20 68 61 73 20   the object has 
4630: 6e 6f 74 20 61 6c 72 65 61 64 79 20 62 65 65 6e  not already been
4640: 20 61 6c 6c 6f 63 61 74 65 64 2c 20 61 6c 6c 6f   allocated, allo
4650: 63 61 74 65 20 61 6e 64 20 70 6f 70 75 6c 61 74  cate and populat
4660: 65 20 69 74 0a 2a 2a 20 6e 6f 77 2e 0a 2a 2f 0a  e it.** now..*/.
4670: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 42  static int fts5B
4680: 6d 32 35 47 65 74 44 61 74 61 28 0a 20 20 63 6f  m25GetData(.  co
4690: 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f  nst Fts5Extensio
46a0: 6e 41 70 69 20 2a 70 41 70 69 2c 20 0a 20 20 46  nApi *pApi, .  F
46b0: 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73  ts5Context *pFts
46c0: 2c 0a 20 20 46 74 73 35 42 6d 32 35 44 61 74 61  ,.  Fts5Bm25Data
46d0: 20 2a 2a 70 70 44 61 74 61 20 20 20 20 20 20 20   **ppData       
46e0: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 62 6d 32 35      /* OUT: bm25
46f0: 2d 64 61 74 61 20 6f 62 6a 65 63 74 20 66 6f 72  -data object for
4700: 20 74 68 69 73 20 71 75 65 72 79 20 2a 2f 0a 29   this query */.)
4710: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
4720: 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  ITE_OK;         
4730: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
4740: 64 65 20 2a 2f 0a 20 20 46 74 73 35 42 6d 32 35  de */.  Fts5Bm25
4750: 44 61 74 61 20 2a 70 3b 20 20 20 20 20 20 20 20  Data *p;        
4760: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63          /* Objec
4770: 74 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f 0a 0a  t to return */..
4780: 20 20 70 20 3d 20 70 41 70 69 2d 3e 78 47 65 74    p = pApi->xGet
4790: 41 75 78 64 61 74 61 28 70 46 74 73 2c 20 30 29  Auxdata(pFts, 0)
47a0: 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 7b 0a  ;.  if( p==0 ){.
47b0: 20 20 20 20 69 6e 74 20 6e 50 68 72 61 73 65 3b      int nPhrase;
47c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
47d0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70    /* Number of p
47e0: 68 72 61 73 65 73 20 69 6e 20 71 75 65 72 79 20  hrases in query 
47f0: 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 69  */.    sqlite3_i
4800: 6e 74 36 34 20 6e 52 6f 77 20 3d 20 30 3b 20 20  nt64 nRow = 0;  
4810: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
4820: 66 20 72 6f 77 73 20 69 6e 20 74 61 62 6c 65 20  f rows in table 
4830: 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 69  */.    sqlite3_i
4840: 6e 74 36 34 20 6e 54 6f 6b 65 6e 20 3d 20 30 3b  nt64 nToken = 0;
4850: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
4860: 66 20 74 6f 6b 65 6e 73 20 69 6e 20 74 61 62 6c  f tokens in tabl
4870: 65 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33  e */.    sqlite3
4880: 5f 69 6e 74 36 34 20 6e 42 79 74 65 3b 20 20 20  _int64 nByte;   
4890: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
48a0: 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f  of space to allo
48b0: 63 61 74 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20  cate */.    int 
48c0: 69 3b 0a 0a 20 20 20 20 2f 2a 20 41 6c 6c 6f 63  i;..    /* Alloc
48d0: 61 74 65 20 74 68 65 20 46 74 73 35 42 6d 32 35  ate the Fts5Bm25
48e0: 44 61 74 61 20 6f 62 6a 65 63 74 20 2a 2f 0a 20  Data object */. 
48f0: 20 20 20 6e 50 68 72 61 73 65 20 3d 20 70 41 70     nPhrase = pAp
4900: 69 2d 3e 78 50 68 72 61 73 65 43 6f 75 6e 74 28  i->xPhraseCount(
4910: 70 46 74 73 29 3b 0a 20 20 20 20 6e 42 79 74 65  pFts);.    nByte
4920: 20 3d 20 73 69 7a 65 6f 66 28 46 74 73 35 42 6d   = sizeof(Fts5Bm
4930: 32 35 44 61 74 61 29 20 2b 20 6e 50 68 72 61 73  25Data) + nPhras
4940: 65 2a 32 2a 73 69 7a 65 6f 66 28 64 6f 75 62 6c  e*2*sizeof(doubl
4950: 65 29 3b 0a 20 20 20 20 70 20 3d 20 28 46 74 73  e);.    p = (Fts
4960: 35 42 6d 32 35 44 61 74 61 2a 29 73 71 6c 69 74  5Bm25Data*)sqlit
4970: 65 33 5f 6d 61 6c 6c 6f 63 36 34 28 6e 42 79 74  e3_malloc64(nByt
4980: 65 29 3b 0a 20 20 20 20 69 66 28 20 70 3d 3d 30  e);.    if( p==0
4990: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
49a0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
49b0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6d 65   }else{.      me
49c0: 6d 73 65 74 28 70 2c 20 30 2c 20 6e 42 79 74 65  mset(p, 0, nByte
49d0: 29 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 50 68 72  );.      p->nPhr
49e0: 61 73 65 20 3d 20 6e 50 68 72 61 73 65 3b 0a 20  ase = nPhrase;. 
49f0: 20 20 20 20 20 70 2d 3e 61 49 44 46 20 3d 20 28       p->aIDF = (
4a00: 64 6f 75 62 6c 65 2a 29 26 70 5b 31 5d 3b 0a 20  double*)&p[1];. 
4a10: 20 20 20 20 20 70 2d 3e 61 46 72 65 71 20 3d 20       p->aFreq = 
4a20: 26 70 2d 3e 61 49 44 46 5b 6e 50 68 72 61 73 65  &p->aIDF[nPhrase
4a30: 5d 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  ];.    }..    /*
4a40: 20 43 61 6c 63 75 6c 61 74 65 20 74 68 65 20 61   Calculate the a
4a50: 76 65 72 61 67 65 20 64 6f 63 75 6d 65 6e 74 20  verage document 
4a60: 6c 65 6e 67 74 68 20 66 6f 72 20 74 68 69 73 20  length for this 
4a70: 46 54 53 35 20 74 61 62 6c 65 20 2a 2f 0a 20 20  FTS5 table */.  
4a80: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
4a90: 5f 4f 4b 20 29 20 72 63 20 3d 20 70 41 70 69 2d  _OK ) rc = pApi-
4aa0: 3e 78 52 6f 77 43 6f 75 6e 74 28 70 46 74 73 2c  >xRowCount(pFts,
4ab0: 20 26 6e 52 6f 77 29 3b 0a 20 20 20 20 61 73 73   &nRow);.    ass
4ac0: 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f  ert( rc!=SQLITE_
4ad0: 4f 4b 20 7c 7c 20 6e 52 6f 77 3e 30 20 29 3b 0a  OK || nRow>0 );.
4ae0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
4af0: 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 70 41 70  TE_OK ) rc = pAp
4b00: 69 2d 3e 78 43 6f 6c 75 6d 6e 54 6f 74 61 6c 53  i->xColumnTotalS
4b10: 69 7a 65 28 70 46 74 73 2c 20 2d 31 2c 20 26 6e  ize(pFts, -1, &n
4b20: 54 6f 6b 65 6e 29 3b 0a 20 20 20 20 69 66 28 20  Token);.    if( 
4b30: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc==SQLITE_OK ) 
4b40: 70 2d 3e 61 76 67 64 6c 20 3d 20 28 64 6f 75 62  p->avgdl = (doub
4b50: 6c 65 29 6e 54 6f 6b 65 6e 20 20 2f 20 28 64 6f  le)nToken  / (do
4b60: 75 62 6c 65 29 6e 52 6f 77 3b 0a 0a 20 20 20 20  uble)nRow;..    
4b70: 2f 2a 20 43 61 6c 63 75 6c 61 74 65 20 61 6e 20  /* Calculate an 
4b80: 49 44 46 20 66 6f 72 20 65 61 63 68 20 70 68 72  IDF for each phr
4b90: 61 73 65 20 69 6e 20 74 68 65 20 71 75 65 72 79  ase in the query
4ba0: 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b   */.    for(i=0;
4bb0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
4bc0: 26 20 69 3c 6e 50 68 72 61 73 65 3b 20 69 2b 2b  & i<nPhrase; i++
4bd0: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
4be0: 5f 69 6e 74 36 34 20 6e 48 69 74 20 3d 20 30 3b  _int64 nHit = 0;
4bf0: 0a 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 69  .      rc = pApi
4c00: 2d 3e 78 51 75 65 72 79 50 68 72 61 73 65 28 70  ->xQueryPhrase(p
4c10: 46 74 73 2c 20 69 2c 20 28 76 6f 69 64 2a 29 26  Fts, i, (void*)&
4c20: 6e 48 69 74 2c 20 66 74 73 35 43 6f 75 6e 74 43  nHit, fts5CountC
4c30: 62 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  b);.      if( rc
4c40: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
4c50: 20 20 20 20 20 20 20 2f 2a 20 43 61 6c 63 75 6c         /* Calcul
4c60: 61 74 65 20 74 68 65 20 49 44 46 20 28 49 6e 76  ate the IDF (Inv
4c70: 65 72 73 65 20 44 6f 63 75 6d 65 6e 74 20 46 72  erse Document Fr
4c80: 65 71 75 65 6e 63 79 29 20 66 6f 72 20 70 68 72  equency) for phr
4c90: 61 73 65 20 69 2e 0a 20 20 20 20 20 20 20 20 2a  ase i..        *
4ca0: 2a 20 54 68 69 73 20 69 73 20 64 6f 6e 65 20 75  * This is done u
4cb0: 73 69 6e 67 20 74 68 65 20 73 74 61 6e 64 61 72  sing the standar
4cc0: 64 20 42 4d 32 35 20 66 6f 72 6d 75 6c 61 20 61  d BM25 formula a
4cd0: 73 20 66 6f 75 6e 64 20 6f 6e 20 77 69 6b 69 70  s found on wikip
4ce0: 65 64 69 61 3a 0a 20 20 20 20 20 20 20 20 2a 2a  edia:.        **
4cf0: 0a 20 20 20 20 20 20 20 20 2a 2a 20 20 20 49 44  .        **   ID
4d00: 46 20 3d 20 6c 6f 67 28 20 28 4e 20 2d 20 6e 48  F = log( (N - nH
4d10: 69 74 20 2b 20 30 2e 35 29 20 2f 20 28 6e 48 69  it + 0.5) / (nHi
4d20: 74 20 2b 20 30 2e 35 29 20 29 0a 20 20 20 20 20  t + 0.5) ).     
4d30: 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a     **.        **
4d40: 20 77 68 65 72 65 20 22 4e 22 20 69 73 20 74 68   where "N" is th
4d50: 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  e total number o
4d60: 66 20 64 6f 63 75 6d 65 6e 74 73 20 69 6e 20 74  f documents in t
4d70: 68 65 20 73 65 74 20 61 6e 64 20 6e 48 69 74 0a  he set and nHit.
4d80: 20 20 20 20 20 20 20 20 2a 2a 20 69 73 20 74 68          ** is th
4d90: 65 20 6e 75 6d 62 65 72 20 74 68 61 74 20 63 6f  e number that co
4da0: 6e 74 61 69 6e 20 61 74 20 6c 65 61 73 74 20 6f  ntain at least o
4db0: 6e 65 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74  ne instance of t
4dc0: 68 65 20 70 68 72 61 73 65 0a 20 20 20 20 20 20  he phrase.      
4dd0: 20 20 2a 2a 20 75 6e 64 65 72 20 63 6f 6e 73 69    ** under consi
4de0: 64 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20 20 20  deration..      
4df0: 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20    **.        ** 
4e00: 54 68 65 20 70 72 6f 62 6c 65 6d 20 77 69 74 68  The problem with
4e10: 20 74 68 69 73 20 69 73 20 74 68 61 74 20 69 66   this is that if
4e20: 20 28 4e 20 3c 20 32 2a 6e 48 69 74 29 2c 20 74   (N < 2*nHit), t
4e30: 68 65 20 49 44 46 20 69 73 20 0a 20 20 20 20 20  he IDF is .     
4e40: 20 20 20 2a 2a 20 6e 65 67 61 74 69 76 65 2e 20     ** negative. 
4e50: 57 68 69 63 68 20 69 73 20 75 6e 64 65 73 69 72  Which is undesir
4e60: 61 62 6c 65 2e 20 53 6f 20 74 68 65 20 6d 69 6d  able. So the mim
4e70: 69 6d 75 6d 20 61 6c 6c 6f 77 61 62 6c 65 20 49  imum allowable I
4e80: 44 46 20 69 73 0a 20 20 20 20 20 20 20 20 2a 2a  DF is.        **
4e90: 20 28 31 65 2d 36 29 20 2d 20 72 6f 75 67 68 6c   (1e-6) - roughl
4ea0: 79 20 74 68 65 20 73 61 6d 65 20 61 73 20 61 20  y the same as a 
4eb0: 74 65 72 6d 20 74 68 61 74 20 61 70 70 65 61 72  term that appear
4ec0: 73 20 69 6e 20 6a 75 73 74 20 6f 76 65 72 0a 20  s in just over. 
4ed0: 20 20 20 20 20 20 20 2a 2a 20 68 61 6c 66 20 6f         ** half o
4ee0: 66 20 73 65 74 20 6f 66 20 35 2c 30 30 30 2c 30  f set of 5,000,0
4ef0: 30 30 20 64 6f 63 75 6d 65 6e 74 73 2e 20 20 2a  00 documents.  *
4f00: 2f 0a 20 20 20 20 20 20 20 20 64 6f 75 62 6c 65  /.        double
4f10: 20 69 64 66 20 3d 20 6c 6f 67 28 20 28 6e 52 6f   idf = log( (nRo
4f20: 77 20 2d 20 6e 48 69 74 20 2b 20 30 2e 35 29 20  w - nHit + 0.5) 
4f30: 2f 20 28 6e 48 69 74 20 2b 20 30 2e 35 29 20 29  / (nHit + 0.5) )
4f40: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 64  ;.        if( id
4f50: 66 3c 3d 30 2e 30 20 29 20 69 64 66 20 3d 20 31  f<=0.0 ) idf = 1
4f60: 65 2d 36 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e  e-6;.        p->
4f70: 61 49 44 46 5b 69 5d 20 3d 20 69 64 66 3b 0a 20  aIDF[i] = idf;. 
4f80: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
4f90: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
4fa0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c  _OK ){.      sql
4fb0: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20  ite3_free(p);.  
4fc0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72    }else{.      r
4fd0: 63 20 3d 20 70 41 70 69 2d 3e 78 53 65 74 41 75  c = pApi->xSetAu
4fe0: 78 64 61 74 61 28 70 46 74 73 2c 20 70 2c 20 73  xdata(pFts, p, s
4ff0: 71 6c 69 74 65 33 5f 66 72 65 65 29 3b 0a 20 20  qlite3_free);.  
5000: 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 21 3d    }.    if( rc!=
5010: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 70 20 3d 20  SQLITE_OK ) p = 
5020: 30 3b 0a 20 20 7d 0a 20 20 2a 70 70 44 61 74 61  0;.  }.  *ppData
5030: 20 3d 20 70 3b 0a 20 20 72 65 74 75 72 6e 20 72   = p;.  return r
5040: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  c;.}../*.** Impl
5050: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 62 6d  ementation of bm
5060: 32 35 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a  25() function..*
5070: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 74  /.static void ft
5080: 73 35 42 6d 32 35 46 75 6e 63 74 69 6f 6e 28 0a  s5Bm25Function(.
5090: 20 20 63 6f 6e 73 74 20 46 74 73 35 45 78 74 65    const Fts5Exte
50a0: 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c 20  nsionApi *pApi, 
50b0: 20 20 2f 2a 20 41 50 49 20 6f 66 66 65 72 65 64    /* API offered
50c0: 20 62 79 20 63 75 72 72 65 6e 74 20 46 54 53 20   by current FTS 
50d0: 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 46 74 73  version */.  Fts
50e0: 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c 20  5Context *pFts, 
50f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5100: 46 69 72 73 74 20 61 72 67 20 74 6f 20 70 61 73  First arg to pas
5110: 73 20 74 6f 20 70 41 70 69 20 66 75 6e 63 74 69  s to pApi functi
5120: 6f 6e 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ons */.  sqlite3
5130: 5f 63 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20  _context *pCtx, 
5140: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74           /* Cont
5150: 65 78 74 20 66 6f 72 20 72 65 74 75 72 6e 69 6e  ext for returnin
5160: 67 20 72 65 73 75 6c 74 2f 65 72 72 6f 72 20 2a  g result/error *
5170: 2f 0a 20 20 69 6e 74 20 6e 56 61 6c 2c 20 20 20  /.  int nVal,   
5180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5190: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
51a0: 20 76 61 6c 75 65 73 20 69 6e 20 61 70 56 61 6c   values in apVal
51b0: 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 71  [] array */.  sq
51c0: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70  lite3_value **ap
51d0: 56 61 6c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  Val           /*
51e0: 20 41 72 72 61 79 20 6f 66 20 74 72 61 69 6c 69   Array of traili
51f0: 6e 67 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  ng arguments */.
5200: 29 7b 0a 20 20 63 6f 6e 73 74 20 64 6f 75 62 6c  ){.  const doubl
5210: 65 20 6b 31 20 3d 20 31 2e 32 3b 20 20 20 20 20  e k1 = 1.2;     
5220: 20 20 20 20 20 2f 2a 20 43 6f 6e 73 74 61 6e 74       /* Constant
5230: 20 22 6b 31 22 20 66 72 6f 6d 20 42 4d 32 35 20   "k1" from BM25 
5240: 66 6f 72 6d 75 6c 61 20 2a 2f 0a 20 20 63 6f 6e  formula */.  con
5250: 73 74 20 64 6f 75 62 6c 65 20 62 20 3d 20 30 2e  st double b = 0.
5260: 37 35 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20  75;          /* 
5270: 43 6f 6e 73 74 61 6e 74 20 22 62 22 20 66 72 6f  Constant "b" fro
5280: 6d 20 42 4d 32 35 20 66 6f 72 6d 75 6c 61 20 2a  m BM25 formula *
5290: 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  /.  int rc = SQL
52a0: 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  ITE_OK;         
52b0: 20 20 20 20 2f 2a 20 45 72 72 6f 72 20 63 6f 64      /* Error cod
52c0: 65 20 2a 2f 0a 20 20 64 6f 75 62 6c 65 20 73 63  e */.  double sc
52d0: 6f 72 65 20 3d 20 30 2e 30 3b 20 20 20 20 20 20  ore = 0.0;      
52e0: 20 20 20 20 20 20 20 2f 2a 20 53 51 4c 20 66 75         /* SQL fu
52f0: 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 20 76 61  nction return va
5300: 6c 75 65 20 2a 2f 0a 20 20 46 74 73 35 42 6d 32  lue */.  Fts5Bm2
5310: 35 44 61 74 61 20 2a 70 44 61 74 61 3b 20 20 20  5Data *pData;   
5320: 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75           /* Valu
5330: 65 73 20 61 6c 6c 6f 63 61 74 65 64 2f 63 61 6c  es allocated/cal
5340: 63 75 6c 61 74 65 64 20 6f 6e 63 65 20 6f 6e 6c  culated once onl
5350: 79 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  y */.  int i;   
5360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5370: 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74         /* Iterat
5380: 6f 72 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20  or variable */. 
5390: 20 69 6e 74 20 6e 49 6e 73 74 20 3d 20 30 3b 20   int nInst = 0; 
53a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
53b0: 20 2f 2a 20 56 61 6c 75 65 20 72 65 74 75 72 6e   /* Value return
53c0: 65 64 20 62 79 20 78 49 6e 73 74 43 6f 75 6e 74  ed by xInstCount
53d0: 28 29 20 2a 2f 0a 20 20 64 6f 75 62 6c 65 20 44  () */.  double D
53e0: 20 3d 20 30 2e 30 3b 20 20 20 20 20 20 20 20 20   = 0.0;         
53f0: 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c          /* Total
5400: 20 6e 75 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e   number of token
5410: 73 20 69 6e 20 72 6f 77 20 2a 2f 0a 20 20 64 6f  s in row */.  do
5420: 75 62 6c 65 20 2a 61 46 72 65 71 20 3d 20 30 3b  uble *aFreq = 0;
5430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5440: 20 41 72 72 61 79 20 6f 66 20 70 68 72 61 73 65   Array of phrase
5450: 20 66 72 65 71 2e 20 66 6f 72 20 63 75 72 72 65   freq. for curre
5460: 6e 74 20 72 6f 77 20 2a 2f 0a 0a 20 20 2f 2a 20  nt row */..  /* 
5470: 43 61 6c 63 75 6c 61 74 65 20 74 68 65 20 70 68  Calculate the ph
5480: 72 61 73 65 20 66 72 65 71 75 65 6e 63 79 20 28  rase frequency (
5490: 73 79 6d 62 6f 6c 20 22 66 28 71 69 2c 44 29 22  symbol "f(qi,D)"
54a0: 20 69 6e 20 74 68 65 20 64 6f 63 75 6d 65 6e 74   in the document
54b0: 61 74 69 6f 6e 29 0a 20 20 2a 2a 20 66 6f 72 20  ation).  ** for 
54c0: 65 61 63 68 20 70 68 72 61 73 65 20 69 6e 20 74  each phrase in t
54d0: 68 65 20 71 75 65 72 79 20 66 6f 72 20 74 68 65  he query for the
54e0: 20 63 75 72 72 65 6e 74 20 72 6f 77 2e 20 2a 2f   current row. */
54f0: 0a 20 20 72 63 20 3d 20 66 74 73 35 42 6d 32 35  .  rc = fts5Bm25
5500: 47 65 74 44 61 74 61 28 70 41 70 69 2c 20 70 46  GetData(pApi, pF
5510: 74 73 2c 20 26 70 44 61 74 61 29 3b 0a 20 20 69  ts, &pData);.  i
5520: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
5530: 20 29 7b 0a 20 20 20 20 61 46 72 65 71 20 3d 20   ){.    aFreq = 
5540: 70 44 61 74 61 2d 3e 61 46 72 65 71 3b 0a 20 20  pData->aFreq;.  
5550: 20 20 6d 65 6d 73 65 74 28 61 46 72 65 71 2c 20    memset(aFreq, 
5560: 30 2c 20 73 69 7a 65 6f 66 28 64 6f 75 62 6c 65  0, sizeof(double
5570: 29 20 2a 20 70 44 61 74 61 2d 3e 6e 50 68 72 61  ) * pData->nPhra
5580: 73 65 29 3b 0a 20 20 20 20 72 63 20 3d 20 70 41  se);.    rc = pA
5590: 70 69 2d 3e 78 49 6e 73 74 43 6f 75 6e 74 28 70  pi->xInstCount(p
55a0: 46 74 73 2c 20 26 6e 49 6e 73 74 29 3b 0a 20 20  Fts, &nInst);.  
55b0: 7d 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d  }.  for(i=0; rc=
55c0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c  =SQLITE_OK && i<
55d0: 6e 49 6e 73 74 3b 20 69 2b 2b 29 7b 0a 20 20 20  nInst; i++){.   
55e0: 20 69 6e 74 20 69 70 3b 20 69 6e 74 20 69 63 3b   int ip; int ic;
55f0: 20 69 6e 74 20 69 6f 3b 0a 20 20 20 20 72 63 20   int io;.    rc 
5600: 3d 20 70 41 70 69 2d 3e 78 49 6e 73 74 28 70 46  = pApi->xInst(pF
5610: 74 73 2c 20 69 2c 20 26 69 70 2c 20 26 69 63 2c  ts, i, &ip, &ic,
5620: 20 26 69 6f 29 3b 0a 20 20 20 20 69 66 28 20 72   &io);.    if( r
5630: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
5640: 20 20 20 20 20 20 64 6f 75 62 6c 65 20 77 20 3d        double w =
5650: 20 28 6e 56 61 6c 20 3e 20 69 63 29 20 3f 20 73   (nVal > ic) ? s
5660: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 64 6f 75  qlite3_value_dou
5670: 62 6c 65 28 61 70 56 61 6c 5b 69 63 5d 29 20 3a  ble(apVal[ic]) :
5680: 20 31 2e 30 3b 0a 20 20 20 20 20 20 61 46 72 65   1.0;.      aFre
5690: 71 5b 69 70 5d 20 2b 3d 20 77 3b 0a 20 20 20 20  q[ip] += w;.    
56a0: 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 46 69 67 75  }.  }..  /* Figu
56b0: 72 65 20 6f 75 74 20 74 68 65 20 74 6f 74 61 6c  re out the total
56c0: 20 73 69 7a 65 20 6f 66 20 74 68 65 20 63 75 72   size of the cur
56d0: 72 65 6e 74 20 72 6f 77 20 69 6e 20 74 6f 6b 65  rent row in toke
56e0: 6e 73 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  ns. */.  if( rc=
56f0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
5700: 20 20 69 6e 74 20 6e 54 6f 6b 3b 0a 20 20 20 20    int nTok;.    
5710: 72 63 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75  rc = pApi->xColu
5720: 6d 6e 53 69 7a 65 28 70 46 74 73 2c 20 2d 31 2c  mnSize(pFts, -1,
5730: 20 26 6e 54 6f 6b 29 3b 0a 20 20 20 20 44 20 3d   &nTok);.    D =
5740: 20 28 64 6f 75 62 6c 65 29 6e 54 6f 6b 3b 0a 20   (double)nTok;. 
5750: 20 7d 0a 0a 20 20 2f 2a 20 44 65 74 65 72 6d 69   }..  /* Determi
5760: 6e 65 20 74 68 65 20 42 4d 32 35 20 73 63 6f 72  ne the BM25 scor
5770: 65 20 66 6f 72 20 74 68 65 20 63 75 72 72 65 6e  e for the curren
5780: 74 20 72 6f 77 2e 20 2a 2f 0a 20 20 66 6f 72 28  t row. */.  for(
5790: 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f  i=0; rc==SQLITE_
57a0: 4f 4b 20 26 26 20 69 3c 70 44 61 74 61 2d 3e 6e  OK && i<pData->n
57b0: 50 68 72 61 73 65 3b 20 69 2b 2b 29 7b 0a 20 20  Phrase; i++){.  
57c0: 20 20 73 63 6f 72 65 20 2b 3d 20 70 44 61 74 61    score += pData
57d0: 2d 3e 61 49 44 46 5b 69 5d 20 2a 20 28 0a 20 20  ->aIDF[i] * (.  
57e0: 20 20 20 20 28 20 61 46 72 65 71 5b 69 5d 20 2a      ( aFreq[i] *
57f0: 20 28 6b 31 20 2b 20 31 2e 30 29 20 29 20 2f 20   (k1 + 1.0) ) / 
5800: 0a 20 20 20 20 20 20 28 20 61 46 72 65 71 5b 69  .      ( aFreq[i
5810: 5d 20 2b 20 6b 31 20 2a 20 28 31 20 2d 20 62 20  ] + k1 * (1 - b 
5820: 2b 20 62 20 2a 20 44 20 2f 20 70 44 61 74 61 2d  + b * D / pData-
5830: 3e 61 76 67 64 6c 29 20 29 0a 20 20 20 20 29 3b  >avgdl) ).    );
5840: 0a 20 20 7d 0a 20 20 0a 20 20 2f 2a 20 49 66 20  .  }.  .  /* If 
5850: 6e 6f 20 65 72 72 6f 72 20 68 61 73 20 6f 63 63  no error has occ
5860: 75 72 72 65 64 2c 20 72 65 74 75 72 6e 20 74 68  urred, return th
5870: 65 20 63 61 6c 63 75 6c 61 74 65 64 20 73 63 6f  e calculated sco
5880: 72 65 2e 20 4f 74 68 65 72 77 69 73 65 2c 0a 20  re. Otherwise,. 
5890: 20 2a 2a 20 74 68 72 6f 77 20 61 6e 20 53 51 4c   ** throw an SQL
58a0: 20 65 78 63 65 70 74 69 6f 6e 2e 20 20 2a 2f 0a   exception.  */.
58b0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
58c0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  _OK ){.    sqlit
58d0: 65 33 5f 72 65 73 75 6c 74 5f 64 6f 75 62 6c 65  e3_result_double
58e0: 28 70 43 74 78 2c 20 2d 31 2e 30 20 2a 20 73 63  (pCtx, -1.0 * sc
58f0: 6f 72 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ore);.  }else{. 
5900: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
5910: 74 5f 65 72 72 6f 72 5f 63 6f 64 65 28 70 43 74  t_error_code(pCt
5920: 78 2c 20 72 63 29 3b 0a 20 20 7d 0a 7d 0a 0a 69  x, rc);.  }.}..i
5930: 6e 74 20 73 71 6c 69 74 65 33 46 74 73 35 41 75  nt sqlite3Fts5Au
5940: 78 49 6e 69 74 28 66 74 73 35 5f 61 70 69 20 2a  xInit(fts5_api *
5950: 70 41 70 69 29 7b 0a 20 20 73 74 72 75 63 74 20  pApi){.  struct 
5960: 42 75 69 6c 74 69 6e 20 7b 0a 20 20 20 20 63 6f  Builtin {.    co
5970: 6e 73 74 20 63 68 61 72 20 2a 7a 46 75 6e 63 3b  nst char *zFunc;
5980: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
5990: 75 6e 63 74 69 6f 6e 20 6e 61 6d 65 20 28 6e 75  unction name (nu
59a0: 6c 2d 74 65 72 6d 69 6e 61 74 65 64 29 20 2a 2f  l-terminated) */
59b0: 0a 20 20 20 20 76 6f 69 64 20 2a 70 55 73 65 72  .    void *pUser
59c0: 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
59d0: 20 20 20 2f 2a 20 55 73 65 72 2d 64 61 74 61 20     /* User-data 
59e0: 70 6f 69 6e 74 65 72 20 2a 2f 0a 20 20 20 20 66  pointer */.    f
59f0: 74 73 35 5f 65 78 74 65 6e 73 69 6f 6e 5f 66 75  ts5_extension_fu
5a00: 6e 63 74 69 6f 6e 20 78 46 75 6e 63 3b 2f 2a 20  nction xFunc;/* 
5a10: 43 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f  Callback functio
5a20: 6e 20 2a 2f 0a 20 20 20 20 76 6f 69 64 20 28 2a  n */.    void (*
5a30: 78 44 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29  xDestroy)(void*)
5a40: 3b 20 20 20 20 20 20 2f 2a 20 44 65 73 74 72 75  ;      /* Destru
5a50: 63 74 6f 72 20 66 75 6e 63 74 69 6f 6e 20 2a 2f  ctor function */
5a60: 0a 20 20 7d 20 61 42 75 69 6c 74 69 6e 20 5b 5d  .  } aBuiltin []
5a70: 20 3d 20 7b 0a 20 20 20 20 7b 20 22 73 6e 69 70   = {.    { "snip
5a80: 70 65 74 22 2c 20 20 20 30 2c 20 66 74 73 35 53  pet",   0, fts5S
5a90: 6e 69 70 70 65 74 46 75 6e 63 74 69 6f 6e 2c 20  nippetFunction, 
5aa0: 30 20 7d 2c 0a 20 20 20 20 7b 20 22 68 69 67 68  0 },.    { "high
5ab0: 6c 69 67 68 74 22 2c 20 30 2c 20 66 74 73 35 48  light", 0, fts5H
5ac0: 69 67 68 6c 69 67 68 74 46 75 6e 63 74 69 6f 6e  ighlightFunction
5ad0: 2c 20 30 20 7d 2c 0a 20 20 20 20 7b 20 22 62 6d  , 0 },.    { "bm
5ae0: 32 35 22 2c 20 20 20 20 20 20 30 2c 20 66 74 73  25",      0, fts
5af0: 35 42 6d 32 35 46 75 6e 63 74 69 6f 6e 2c 20 20  5Bm25Function,  
5b00: 20 20 30 20 7d 2c 0a 20 20 7d 3b 0a 20 20 69 6e    0 },.  };.  in
5b10: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
5b20: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
5b30: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
5b40: 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
5b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5b60: 20 20 2f 2a 20 54 6f 20 69 74 65 72 61 74 65 20    /* To iterate 
5b70: 74 68 72 6f 75 67 68 20 62 75 69 6c 74 69 6e 20  through builtin 
5b80: 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 0a 20 20  functions */..  
5b90: 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c  for(i=0; rc==SQL
5ba0: 49 54 45 5f 4f 4b 20 26 26 20 69 3c 41 72 72 61  ITE_OK && i<Arra
5bb0: 79 53 69 7a 65 28 61 42 75 69 6c 74 69 6e 29 3b  ySize(aBuiltin);
5bc0: 20 69 2b 2b 29 7b 0a 20 20 20 20 72 63 20 3d 20   i++){.    rc = 
5bd0: 70 41 70 69 2d 3e 78 43 72 65 61 74 65 46 75 6e  pApi->xCreateFun
5be0: 63 74 69 6f 6e 28 70 41 70 69 2c 0a 20 20 20 20  ction(pApi,.    
5bf0: 20 20 20 20 61 42 75 69 6c 74 69 6e 5b 69 5d 2e      aBuiltin[i].
5c00: 7a 46 75 6e 63 2c 0a 20 20 20 20 20 20 20 20 61  zFunc,.        a
5c10: 42 75 69 6c 74 69 6e 5b 69 5d 2e 70 55 73 65 72  Builtin[i].pUser
5c20: 44 61 74 61 2c 0a 20 20 20 20 20 20 20 20 61 42  Data,.        aB
5c30: 75 69 6c 74 69 6e 5b 69 5d 2e 78 46 75 6e 63 2c  uiltin[i].xFunc,
5c40: 0a 20 20 20 20 20 20 20 20 61 42 75 69 6c 74 69  .        aBuilti
5c50: 6e 5b 69 5d 2e 78 44 65 73 74 72 6f 79 0a 20 20  n[i].xDestroy.  
5c60: 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75    );.  }..  retu
5c70: 72 6e 20 72 63 3b 0a 7d 0a                       rn rc;.}.