/ Hex Artifact Content
Login

Artifact dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa:


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 28 69 6e 74 29 69 41 64 6a 3b 0a 20  s = (int)iAdj;. 
2c90: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
2ca0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
2cb0: 20 74 68 65 20 76 61 6c 75 65 20 69 6e 20 70 56   the value in pV
2cc0: 61 6c 20 69 6e 74 65 72 70 72 65 74 65 64 20 61  al interpreted a
2cd0: 73 20 75 74 66 2d 38 20 74 65 78 74 2e 20 45 78  s utf-8 text. Ex
2ce0: 63 65 70 74 2c 20 69 66 20 70 56 61 6c 20 0a 2a  cept, if pVal .*
2cf0: 2a 20 63 6f 6e 74 61 69 6e 73 20 61 20 4e 55 4c  * contains a NUL
2d00: 4c 20 76 61 6c 75 65 2c 20 72 65 74 75 72 6e 20  L value, return 
2d10: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 73  a pointer to a s
2d20: 74 61 74 69 63 20 73 74 72 69 6e 67 20 7a 65 72  tatic string zer
2d30: 6f 0a 2a 2a 20 62 79 74 65 73 20 69 6e 20 6c 65  o.** bytes in le
2d40: 6e 67 74 68 20 69 6e 73 74 65 61 64 20 6f 66 20  ngth instead of 
2d50: 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2e 0a  a NULL pointer..
2d60: 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20  */.static const 
2d70: 63 68 61 72 20 2a 66 74 73 35 56 61 6c 75 65 54  char *fts5ValueT
2d80: 6f 54 65 78 74 28 73 71 6c 69 74 65 33 5f 76 61  oText(sqlite3_va
2d90: 6c 75 65 20 2a 70 56 61 6c 29 7b 0a 20 20 63 6f  lue *pVal){.  co
2da0: 6e 73 74 20 63 68 61 72 20 2a 7a 52 65 74 20 3d  nst char *zRet =
2db0: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71   (const char*)sq
2dc0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74  lite3_value_text
2dd0: 28 70 56 61 6c 29 3b 0a 20 20 72 65 74 75 72 6e  (pVal);.  return
2de0: 20 7a 52 65 74 20 3f 20 7a 52 65 74 20 3a 20 22   zRet ? zRet : "
2df0: 22 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  ";.}../*.** Impl
2e00: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 73 6e  ementation of sn
2e10: 69 70 70 65 74 28 29 20 66 75 6e 63 74 69 6f 6e  ippet() function
2e20: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
2e30: 20 66 74 73 35 53 6e 69 70 70 65 74 46 75 6e 63   fts5SnippetFunc
2e40: 74 69 6f 6e 28 0a 20 20 63 6f 6e 73 74 20 46 74  tion(.  const Ft
2e50: 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a  s5ExtensionApi *
2e60: 70 41 70 69 2c 20 20 20 2f 2a 20 41 50 49 20 6f  pApi,   /* API o
2e70: 66 66 65 72 65 64 20 62 79 20 63 75 72 72 65 6e  ffered by curren
2e80: 74 20 46 54 53 20 76 65 72 73 69 6f 6e 20 2a 2f  t FTS version */
2e90: 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a  .  Fts5Context *
2ea0: 70 46 74 73 2c 20 20 20 20 20 20 20 20 20 20 20  pFts,           
2eb0: 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72 67 20     /* First arg 
2ec0: 74 6f 20 70 61 73 73 20 74 6f 20 70 41 70 69 20  to pass to pApi 
2ed0: 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 73  functions */.  s
2ee0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
2ef0: 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 2f  pCtx,          /
2f00: 2a 20 43 6f 6e 74 65 78 74 20 66 6f 72 20 72 65  * Context for re
2f10: 74 75 72 6e 69 6e 67 20 72 65 73 75 6c 74 2f 65  turning result/e
2f20: 72 72 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 56  rror */.  int nV
2f30: 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
2f40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
2f50: 62 65 72 20 6f 66 20 76 61 6c 75 65 73 20 69 6e  ber of values in
2f60: 20 61 70 56 61 6c 5b 5d 20 61 72 72 61 79 20 2a   apVal[] array *
2f70: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  /.  sqlite3_valu
2f80: 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20 20 20  e **apVal       
2f90: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20      /* Array of 
2fa0: 74 72 61 69 6c 69 6e 67 20 61 72 67 75 6d 65 6e  trailing argumen
2fb0: 74 73 20 2a 2f 0a 29 7b 0a 20 20 48 69 67 68 6c  ts */.){.  Highl
2fc0: 69 67 68 74 43 6f 6e 74 65 78 74 20 63 74 78 3b  ightContext ctx;
2fd0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
2fe0: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
2ff0: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
3000: 65 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 3b  e */.  int iCol;
3010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3020: 20 20 20 20 20 20 20 2f 2a 20 31 73 74 20 61 72         /* 1st ar
3030: 67 75 6d 65 6e 74 20 74 6f 20 73 6e 69 70 70 65  gument to snippe
3040: 74 28 29 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  t() */.  const c
3050: 68 61 72 20 2a 7a 45 6c 6c 69 70 73 3b 20 20 20  har *zEllips;   
3060: 20 20 20 20 20 20 20 20 20 2f 2a 20 34 74 68 20           /* 4th 
3070: 61 72 67 75 6d 65 6e 74 20 74 6f 20 73 6e 69 70  argument to snip
3080: 70 65 74 28 29 20 2a 2f 0a 20 20 69 6e 74 20 6e  pet() */.  int n
3090: 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20 20 20  Token;          
30a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 35 74             /* 5t
30b0: 68 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 73 6e  h argument to sn
30c0: 69 70 70 65 74 28 29 20 2a 2f 0a 20 20 69 6e 74  ippet() */.  int
30d0: 20 6e 49 6e 73 74 20 3d 20 30 3b 20 20 20 20 20   nInst = 0;     
30e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
30f0: 4e 75 6d 62 65 72 20 6f 66 20 69 6e 73 74 61 6e  Number of instan
3100: 63 65 20 6d 61 74 63 68 65 73 20 74 68 69 73 20  ce matches this 
3110: 72 6f 77 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20  row */.  int i; 
3120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3130: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64           /* Used
3140: 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
3150: 75 67 68 20 69 6e 73 74 61 6e 63 65 73 20 2a 2f  ugh instances */
3160: 0a 20 20 69 6e 74 20 6e 50 68 72 61 73 65 3b 20  .  int nPhrase; 
3170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3180: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
3190: 70 68 72 61 73 65 73 20 69 6e 20 71 75 65 72 79  phrases in query
31a0: 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 63   */.  unsigned c
31b0: 68 61 72 20 2a 61 53 65 65 6e 3b 20 20 20 20 20  har *aSeen;     
31c0: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
31d0: 66 20 22 73 65 65 6e 20 69 6e 73 74 61 6e 63 65  f "seen instance
31e0: 22 20 66 6c 61 67 73 20 2a 2f 0a 20 20 69 6e 74  " flags */.  int
31f0: 20 69 42 65 73 74 43 6f 6c 3b 20 20 20 20 20 20   iBestCol;      
3200: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3210: 43 6f 6c 75 6d 6e 20 63 6f 6e 74 61 69 6e 69 6e  Column containin
3220: 67 20 62 65 73 74 20 73 6e 69 70 70 65 74 20 2a  g best snippet *
3230: 2f 0a 20 20 69 6e 74 20 69 42 65 73 74 53 74 61  /.  int iBestSta
3240: 72 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  rt = 0;         
3250: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 74 6f 6b      /* First tok
3260: 65 6e 20 6f 66 20 62 65 73 74 20 73 6e 69 70 70  en of best snipp
3270: 65 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 65 73  et */.  int nBes
3280: 74 53 63 6f 72 65 20 3d 20 30 3b 20 20 20 20 20  tScore = 0;     
3290: 20 20 20 20 20 20 20 20 2f 2a 20 53 63 6f 72 65          /* Score
32a0: 20 6f 66 20 62 65 73 74 20 73 6e 69 70 70 65 74   of best snippet
32b0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 53 69   */.  int nColSi
32c0: 7a 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  ze = 0;         
32d0: 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 73        /* Total s
32e0: 69 7a 65 20 6f 66 20 69 42 65 73 74 43 6f 6c 20  ize of iBestCol 
32f0: 69 6e 20 74 6f 6b 65 6e 73 20 2a 2f 0a 20 20 46  in tokens */.  F
3300: 74 73 35 53 46 69 6e 64 65 72 20 73 46 69 6e 64  ts5SFinder sFind
3310: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  er;            /
3320: 2a 20 55 73 65 64 20 74 6f 20 66 69 6e 64 20 74  * Used to find t
3330: 68 65 20 62 65 67 69 6e 6e 69 6e 67 73 20 6f 66  he beginnings of
3340: 20 73 65 6e 74 65 6e 63 65 73 20 2a 2f 0a 20 20   sentences */.  
3350: 69 6e 74 20 6e 43 6f 6c 3b 0a 0a 20 20 69 66 28  int nCol;..  if(
3360: 20 6e 56 61 6c 21 3d 35 20 29 7b 0a 20 20 20 20   nVal!=5 ){.    
3370: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 72 72  const char *zErr
3380: 20 3d 20 22 77 72 6f 6e 67 20 6e 75 6d 62 65 72   = "wrong number
3390: 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 74 6f   of arguments to
33a0: 20 66 75 6e 63 74 69 6f 6e 20 73 6e 69 70 70 65   function snippe
33b0: 74 28 29 22 3b 0a 20 20 20 20 73 71 6c 69 74 65  t()";.    sqlite
33c0: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 70  3_result_error(p
33d0: 43 74 78 2c 20 7a 45 72 72 2c 20 2d 31 29 3b 0a  Ctx, zErr, -1);.
33e0: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a      return;.  }.
33f0: 0a 20 20 6e 43 6f 6c 20 3d 20 70 41 70 69 2d 3e  .  nCol = pApi->
3400: 78 43 6f 6c 75 6d 6e 43 6f 75 6e 74 28 70 46 74  xColumnCount(pFt
3410: 73 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 63 74  s);.  memset(&ct
3420: 78 2c 20 30 2c 20 73 69 7a 65 6f 66 28 48 69 67  x, 0, sizeof(Hig
3430: 68 6c 69 67 68 74 43 6f 6e 74 65 78 74 29 29 3b  hlightContext));
3440: 0a 20 20 69 43 6f 6c 20 3d 20 73 71 6c 69 74 65  .  iCol = sqlite
3450: 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 70 56 61  3_value_int(apVa
3460: 6c 5b 30 5d 29 3b 0a 20 20 63 74 78 2e 7a 4f 70  l[0]);.  ctx.zOp
3470: 65 6e 20 3d 20 66 74 73 35 56 61 6c 75 65 54 6f  en = fts5ValueTo
3480: 54 65 78 74 28 61 70 56 61 6c 5b 31 5d 29 3b 0a  Text(apVal[1]);.
3490: 20 20 63 74 78 2e 7a 43 6c 6f 73 65 20 3d 20 66    ctx.zClose = f
34a0: 74 73 35 56 61 6c 75 65 54 6f 54 65 78 74 28 61  ts5ValueToText(a
34b0: 70 56 61 6c 5b 32 5d 29 3b 0a 20 20 7a 45 6c 6c  pVal[2]);.  zEll
34c0: 69 70 73 20 3d 20 66 74 73 35 56 61 6c 75 65 54  ips = fts5ValueT
34d0: 6f 54 65 78 74 28 61 70 56 61 6c 5b 33 5d 29 3b  oText(apVal[3]);
34e0: 0a 20 20 6e 54 6f 6b 65 6e 20 3d 20 73 71 6c 69  .  nToken = sqli
34f0: 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 70  te3_value_int(ap
3500: 56 61 6c 5b 34 5d 29 3b 0a 0a 20 20 69 42 65 73  Val[4]);..  iBes
3510: 74 43 6f 6c 20 3d 20 28 69 43 6f 6c 3e 3d 30 20  tCol = (iCol>=0 
3520: 3f 20 69 43 6f 6c 20 3a 20 30 29 3b 0a 20 20 6e  ? iCol : 0);.  n
3530: 50 68 72 61 73 65 20 3d 20 70 41 70 69 2d 3e 78  Phrase = pApi->x
3540: 50 68 72 61 73 65 43 6f 75 6e 74 28 70 46 74 73  PhraseCount(pFts
3550: 29 3b 0a 20 20 61 53 65 65 6e 20 3d 20 73 71 6c  );.  aSeen = sql
3560: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 50 68 72  ite3_malloc(nPhr
3570: 61 73 65 29 3b 0a 20 20 69 66 28 20 61 53 65 65  ase);.  if( aSee
3580: 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d  n==0 ){.    rc =
3590: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
35a0: 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c   }.  if( rc==SQL
35b0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
35c0: 20 3d 20 70 41 70 69 2d 3e 78 49 6e 73 74 43 6f   = pApi->xInstCo
35d0: 75 6e 74 28 70 46 74 73 2c 20 26 6e 49 6e 73 74  unt(pFts, &nInst
35e0: 29 3b 0a 20 20 7d 0a 0a 20 20 6d 65 6d 73 65 74  );.  }..  memset
35f0: 28 26 73 46 69 6e 64 65 72 2c 20 30 2c 20 73 69  (&sFinder, 0, si
3600: 7a 65 6f 66 28 46 74 73 35 53 46 69 6e 64 65 72  zeof(Fts5SFinder
3610: 29 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  ));.  for(i=0; i
3620: 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  <nCol; i++){.   
3630: 20 69 66 28 20 69 43 6f 6c 3c 30 20 7c 7c 20 69   if( iCol<0 || i
3640: 43 6f 6c 3d 3d 69 20 29 7b 0a 20 20 20 20 20 20  Col==i ){.      
3650: 69 6e 74 20 6e 44 6f 63 3b 0a 20 20 20 20 20 20  int nDoc;.      
3660: 69 6e 74 20 6e 44 6f 63 73 69 7a 65 3b 0a 20 20  int nDocsize;.  
3670: 20 20 20 20 69 6e 74 20 69 69 3b 0a 20 20 20 20      int ii;.    
3680: 20 20 73 46 69 6e 64 65 72 2e 69 50 6f 73 20 3d    sFinder.iPos =
3690: 20 30 3b 0a 20 20 20 20 20 20 73 46 69 6e 64 65   0;.      sFinde
36a0: 72 2e 6e 46 69 72 73 74 20 3d 20 30 3b 0a 20 20  r.nFirst = 0;.  
36b0: 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78      rc = pApi->x
36c0: 43 6f 6c 75 6d 6e 54 65 78 74 28 70 46 74 73 2c  ColumnText(pFts,
36d0: 20 69 2c 20 26 73 46 69 6e 64 65 72 2e 7a 44 6f   i, &sFinder.zDo
36e0: 63 2c 20 26 6e 44 6f 63 29 3b 0a 20 20 20 20 20  c, &nDoc);.     
36f0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
3700: 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  OK ) break;.    
3710: 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 54 6f    rc = pApi->xTo
3720: 6b 65 6e 69 7a 65 28 70 46 74 73 2c 20 0a 20 20  kenize(pFts, .  
3730: 20 20 20 20 20 20 20 20 73 46 69 6e 64 65 72 2e          sFinder.
3740: 7a 44 6f 63 2c 20 6e 44 6f 63 2c 20 28 76 6f 69  zDoc, nDoc, (voi
3750: 64 2a 29 26 73 46 69 6e 64 65 72 2c 66 74 73 35  d*)&sFinder,fts5
3760: 53 65 6e 74 65 6e 63 65 46 69 6e 64 65 72 43 62  SentenceFinderCb
3770: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20  .      );.      
3780: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
3790: 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  K ) break;.     
37a0: 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c   rc = pApi->xCol
37b0: 75 6d 6e 53 69 7a 65 28 70 46 74 73 2c 20 69 2c  umnSize(pFts, i,
37c0: 20 26 6e 44 6f 63 73 69 7a 65 29 3b 0a 20 20 20   &nDocsize);.   
37d0: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
37e0: 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a 20  E_OK ) break;.. 
37f0: 20 20 20 20 20 66 6f 72 28 69 69 3d 30 3b 20 72       for(ii=0; r
3800: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
3810: 69 69 3c 6e 49 6e 73 74 3b 20 69 69 2b 2b 29 7b  ii<nInst; ii++){
3820: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 70 2c  .        int ip,
3830: 20 69 63 2c 20 69 6f 3b 0a 20 20 20 20 20 20 20   ic, io;.       
3840: 20 69 6e 74 20 69 41 64 6a 3b 0a 20 20 20 20 20   int iAdj;.     
3850: 20 20 20 69 6e 74 20 6e 53 63 6f 72 65 3b 0a 20     int nScore;. 
3860: 20 20 20 20 20 20 20 69 6e 74 20 6a 6a 3b 0a 0a         int jj;..
3870: 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 41 70          rc = pAp
3880: 69 2d 3e 78 49 6e 73 74 28 70 46 74 73 2c 20 69  i->xInst(pFts, i
3890: 69 2c 20 26 69 70 2c 20 26 69 63 2c 20 26 69 6f  i, &ip, &ic, &io
38a0: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 69  );.        if( i
38b0: 63 21 3d 69 20 29 20 63 6f 6e 74 69 6e 75 65 3b  c!=i ) continue;
38c0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 6f 3e  .        if( io>
38d0: 6e 44 6f 63 73 69 7a 65 20 29 20 72 63 20 3d 20  nDocsize ) rc = 
38e0: 46 54 53 35 5f 43 4f 52 52 55 50 54 3b 0a 20 20  FTS5_CORRUPT;.  
38f0: 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
3900: 4c 49 54 45 5f 4f 4b 20 29 20 63 6f 6e 74 69 6e  LITE_OK ) contin
3910: 75 65 3b 0a 20 20 20 20 20 20 20 20 6d 65 6d 73  ue;.        mems
3920: 65 74 28 61 53 65 65 6e 2c 20 30 2c 20 6e 50 68  et(aSeen, 0, nPh
3930: 72 61 73 65 29 3b 0a 20 20 20 20 20 20 20 20 72  rase);.        r
3940: 63 20 3d 20 66 74 73 35 53 6e 69 70 70 65 74 53  c = fts5SnippetS
3950: 63 6f 72 65 28 70 41 70 69 2c 20 70 46 74 73 2c  core(pApi, pFts,
3960: 20 6e 44 6f 63 73 69 7a 65 2c 20 61 53 65 65 6e   nDocsize, aSeen
3970: 2c 20 69 2c 0a 20 20 20 20 20 20 20 20 20 20 20  , i,.           
3980: 20 69 6f 2c 20 6e 54 6f 6b 65 6e 2c 20 26 6e 53   io, nToken, &nS
3990: 63 6f 72 65 2c 20 26 69 41 64 6a 0a 20 20 20 20  core, &iAdj.    
39a0: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 69      );.        i
39b0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
39c0: 20 26 26 20 6e 53 63 6f 72 65 3e 6e 42 65 73 74   && nScore>nBest
39d0: 53 63 6f 72 65 20 29 7b 0a 20 20 20 20 20 20 20  Score ){.       
39e0: 20 20 20 6e 42 65 73 74 53 63 6f 72 65 20 3d 20     nBestScore = 
39f0: 6e 53 63 6f 72 65 3b 0a 20 20 20 20 20 20 20 20  nScore;.        
3a00: 20 20 69 42 65 73 74 43 6f 6c 20 3d 20 69 3b 0a    iBestCol = i;.
3a10: 20 20 20 20 20 20 20 20 20 20 69 42 65 73 74 53            iBestS
3a20: 74 61 72 74 20 3d 20 69 41 64 6a 3b 0a 20 20 20  tart = iAdj;.   
3a30: 20 20 20 20 20 20 20 6e 43 6f 6c 53 69 7a 65 20         nColSize 
3a40: 3d 20 6e 44 6f 63 73 69 7a 65 3b 0a 20 20 20 20  = nDocsize;.    
3a50: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 69      }..        i
3a60: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
3a70: 20 26 26 20 73 46 69 6e 64 65 72 2e 6e 46 69 72   && sFinder.nFir
3a80: 73 74 20 26 26 20 6e 44 6f 63 73 69 7a 65 3e 6e  st && nDocsize>n
3a90: 54 6f 6b 65 6e 20 29 7b 0a 20 20 20 20 20 20 20  Token ){.       
3aa0: 20 20 20 66 6f 72 28 6a 6a 3d 30 3b 20 6a 6a 3c     for(jj=0; jj<
3ab0: 28 73 46 69 6e 64 65 72 2e 6e 46 69 72 73 74 2d  (sFinder.nFirst-
3ac0: 31 29 3b 20 6a 6a 2b 2b 29 7b 0a 20 20 20 20 20  1); jj++){.     
3ad0: 20 20 20 20 20 20 20 69 66 28 20 73 46 69 6e 64         if( sFind
3ae0: 65 72 2e 61 46 69 72 73 74 5b 6a 6a 2b 31 5d 3e  er.aFirst[jj+1]>
3af0: 69 6f 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  io ) break;.    
3b00: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20        }..       
3b10: 20 20 20 69 66 28 20 73 46 69 6e 64 65 72 2e 61     if( sFinder.a
3b20: 46 69 72 73 74 5b 6a 6a 5d 3c 69 6f 20 29 7b 0a  First[jj]<io ){.
3b30: 20 20 20 20 20 20 20 20 20 20 20 20 6d 65 6d 73              mems
3b40: 65 74 28 61 53 65 65 6e 2c 20 30 2c 20 6e 50 68  et(aSeen, 0, nPh
3b50: 72 61 73 65 29 3b 0a 20 20 20 20 20 20 20 20 20  rase);.         
3b60: 20 20 20 72 63 20 3d 20 66 74 73 35 53 6e 69 70     rc = fts5Snip
3b70: 70 65 74 53 63 6f 72 65 28 70 41 70 69 2c 20 70  petScore(pApi, p
3b80: 46 74 73 2c 20 6e 44 6f 63 73 69 7a 65 2c 20 61  Fts, nDocsize, a
3b90: 53 65 65 6e 2c 20 69 2c 20 0a 20 20 20 20 20 20  Seen, i, .      
3ba0: 20 20 20 20 20 20 20 20 73 46 69 6e 64 65 72 2e          sFinder.
3bb0: 61 46 69 72 73 74 5b 6a 6a 5d 2c 20 6e 54 6f 6b  aFirst[jj], nTok
3bc0: 65 6e 2c 20 26 6e 53 63 6f 72 65 2c 20 30 0a 20  en, &nScore, 0. 
3bd0: 20 20 20 20 20 20 20 20 20 20 20 29 3b 0a 0a 20             );.. 
3be0: 20 20 20 20 20 20 20 20 20 20 20 6e 53 63 6f 72             nScor
3bf0: 65 20 2b 3d 20 28 73 46 69 6e 64 65 72 2e 61 46  e += (sFinder.aF
3c00: 69 72 73 74 5b 6a 6a 5d 3d 3d 30 20 3f 20 31 32  irst[jj]==0 ? 12
3c10: 30 20 3a 20 31 30 30 29 3b 0a 20 20 20 20 20 20  0 : 100);.      
3c20: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
3c30: 4c 49 54 45 5f 4f 4b 20 26 26 20 6e 53 63 6f 72  LITE_OK && nScor
3c40: 65 3e 6e 42 65 73 74 53 63 6f 72 65 20 29 7b 0a  e>nBestScore ){.
3c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 42                nB
3c60: 65 73 74 53 63 6f 72 65 20 3d 20 6e 53 63 6f 72  estScore = nScor
3c70: 65 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e;.             
3c80: 20 69 42 65 73 74 43 6f 6c 20 3d 20 69 3b 0a 20   iBestCol = i;. 
3c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 42 65               iBe
3ca0: 73 74 53 74 61 72 74 20 3d 20 73 46 69 6e 64 65  stStart = sFinde
3cb0: 72 2e 61 46 69 72 73 74 5b 6a 6a 5d 3b 0a 20 20  r.aFirst[jj];.  
3cc0: 20 20 20 20 20 20 20 20 20 20 20 20 6e 43 6f 6c              nCol
3cd0: 53 69 7a 65 20 3d 20 6e 44 6f 63 73 69 7a 65 3b  Size = nDocsize;
3ce0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20  .            }. 
3cf0: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
3d00: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
3d10: 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63   }.  }..  if( rc
3d20: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
3d30: 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 43     rc = pApi->xC
3d40: 6f 6c 75 6d 6e 54 65 78 74 28 70 46 74 73 2c 20  olumnText(pFts, 
3d50: 69 42 65 73 74 43 6f 6c 2c 20 26 63 74 78 2e 7a  iBestCol, &ctx.z
3d60: 49 6e 2c 20 26 63 74 78 2e 6e 49 6e 29 3b 0a 20  In, &ctx.nIn);. 
3d70: 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c   }.  if( rc==SQL
3d80: 49 54 45 5f 4f 4b 20 26 26 20 6e 43 6f 6c 53 69  ITE_OK && nColSi
3d90: 7a 65 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20  ze==0 ){.    rc 
3da0: 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e 53  = pApi->xColumnS
3db0: 69 7a 65 28 70 46 74 73 2c 20 69 42 65 73 74 43  ize(pFts, iBestC
3dc0: 6f 6c 2c 20 26 6e 43 6f 6c 53 69 7a 65 29 3b 0a  ol, &nColSize);.
3dd0: 20 20 7d 0a 20 20 69 66 28 20 63 74 78 2e 7a 49    }.  if( ctx.zI
3de0: 6e 20 29 7b 0a 20 20 20 20 69 66 28 20 72 63 3d  n ){.    if( rc=
3df0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
3e00: 20 20 20 20 72 63 20 3d 20 66 74 73 35 43 49 6e      rc = fts5CIn
3e10: 73 74 49 74 65 72 49 6e 69 74 28 70 41 70 69 2c  stIterInit(pApi,
3e20: 20 70 46 74 73 2c 20 69 42 65 73 74 43 6f 6c 2c   pFts, iBestCol,
3e30: 20 26 63 74 78 2e 69 74 65 72 29 3b 0a 20 20 20   &ctx.iter);.   
3e40: 20 7d 0a 0a 20 20 20 20 63 74 78 2e 69 52 61 6e   }..    ctx.iRan
3e50: 67 65 53 74 61 72 74 20 3d 20 69 42 65 73 74 53  geStart = iBestS
3e60: 74 61 72 74 3b 0a 20 20 20 20 63 74 78 2e 69 52  tart;.    ctx.iR
3e70: 61 6e 67 65 45 6e 64 20 3d 20 69 42 65 73 74 53  angeEnd = iBestS
3e80: 74 61 72 74 20 2b 20 6e 54 6f 6b 65 6e 20 2d 20  tart + nToken - 
3e90: 31 3b 0a 0a 20 20 20 20 69 66 28 20 69 42 65 73  1;..    if( iBes
3ea0: 74 53 74 61 72 74 3e 30 20 29 7b 0a 20 20 20 20  tStart>0 ){.    
3eb0: 20 20 66 74 73 35 48 69 67 68 6c 69 67 68 74 41    fts5HighlightA
3ec0: 70 70 65 6e 64 28 26 72 63 2c 20 26 63 74 78 2c  ppend(&rc, &ctx,
3ed0: 20 7a 45 6c 6c 69 70 73 2c 20 2d 31 29 3b 0a 20   zEllips, -1);. 
3ee0: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 41 64 76     }..    /* Adv
3ef0: 61 6e 63 65 20 69 74 65 72 61 74 6f 72 20 63 74  ance iterator ct
3f00: 78 2e 69 74 65 72 20 73 6f 20 74 68 61 74 20 69  x.iter so that i
3f10: 74 20 70 6f 69 6e 74 73 20 74 6f 20 74 68 65 20  t points to the 
3f20: 66 69 72 73 74 20 63 6f 61 6c 65 73 63 65 64 0a  first coalesced.
3f30: 20 20 20 20 2a 2a 20 70 68 72 61 73 65 20 69 6e      ** phrase in
3f40: 73 74 61 6e 63 65 20 61 74 20 6f 72 20 66 6f 6c  stance at or fol
3f50: 6c 6f 77 69 6e 67 20 70 6f 73 69 74 69 6f 6e 20  lowing position 
3f60: 69 42 65 73 74 53 74 61 72 74 2e 20 2a 2f 0a 20  iBestStart. */. 
3f70: 20 20 20 77 68 69 6c 65 28 20 63 74 78 2e 69 74     while( ctx.it
3f80: 65 72 2e 69 53 74 61 72 74 3e 3d 30 20 26 26 20  er.iStart>=0 && 
3f90: 63 74 78 2e 69 74 65 72 2e 69 53 74 61 72 74 3c  ctx.iter.iStart<
3fa0: 69 42 65 73 74 53 74 61 72 74 20 26 26 20 72 63  iBestStart && rc
3fb0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
3fc0: 20 20 20 20 20 72 63 20 3d 20 66 74 73 35 43 49       rc = fts5CI
3fd0: 6e 73 74 49 74 65 72 4e 65 78 74 28 26 63 74 78  nstIterNext(&ctx
3fe0: 2e 69 74 65 72 29 3b 0a 20 20 20 20 7d 0a 0a 20  .iter);.    }.. 
3ff0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
4000: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63  E_OK ){.      rc
4010: 20 3d 20 70 41 70 69 2d 3e 78 54 6f 6b 65 6e 69   = pApi->xTokeni
4020: 7a 65 28 70 46 74 73 2c 20 63 74 78 2e 7a 49 6e  ze(pFts, ctx.zIn
4030: 2c 20 63 74 78 2e 6e 49 6e 2c 20 28 76 6f 69 64  , ctx.nIn, (void
4040: 2a 29 26 63 74 78 2c 66 74 73 35 48 69 67 68 6c  *)&ctx,fts5Highl
4050: 69 67 68 74 43 62 29 3b 0a 20 20 20 20 7d 0a 20  ightCb);.    }. 
4060: 20 20 20 69 66 28 20 63 74 78 2e 69 52 61 6e 67     if( ctx.iRang
4070: 65 45 6e 64 3e 3d 28 6e 43 6f 6c 53 69 7a 65 2d  eEnd>=(nColSize-
4080: 31 29 20 29 7b 0a 20 20 20 20 20 20 66 74 73 35  1) ){.      fts5
4090: 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e 64 28  HighlightAppend(
40a0: 26 72 63 2c 20 26 63 74 78 2c 20 26 63 74 78 2e  &rc, &ctx, &ctx.
40b0: 7a 49 6e 5b 63 74 78 2e 69 4f 66 66 5d 2c 20 63  zIn[ctx.iOff], c
40c0: 74 78 2e 6e 49 6e 20 2d 20 63 74 78 2e 69 4f 66  tx.nIn - ctx.iOf
40d0: 66 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  f);.    }else{. 
40e0: 20 20 20 20 20 66 74 73 35 48 69 67 68 6c 69 67       fts5Highlig
40f0: 68 74 41 70 70 65 6e 64 28 26 72 63 2c 20 26 63  htAppend(&rc, &c
4100: 74 78 2c 20 7a 45 6c 6c 69 70 73 2c 20 2d 31 29  tx, zEllips, -1)
4110: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ;.    }.  }.  if
4120: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4130: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  ){.    sqlite3_r
4140: 65 73 75 6c 74 5f 74 65 78 74 28 70 43 74 78 2c  esult_text(pCtx,
4150: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 63 74   (const char*)ct
4160: 78 2e 7a 4f 75 74 2c 20 2d 31 2c 20 53 51 4c 49  x.zOut, -1, SQLI
4170: 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20  TE_TRANSIENT);. 
4180: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69   }else{.    sqli
4190: 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72  te3_result_error
41a0: 5f 63 6f 64 65 28 70 43 74 78 2c 20 72 63 29 3b  _code(pCtx, rc);
41b0: 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66  .  }.  sqlite3_f
41c0: 72 65 65 28 63 74 78 2e 7a 4f 75 74 29 3b 0a 20  ree(ctx.zOut);. 
41d0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 53   sqlite3_free(aS
41e0: 65 65 6e 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  een);.  sqlite3_
41f0: 66 72 65 65 28 73 46 69 6e 64 65 72 2e 61 46 69  free(sFinder.aFi
4200: 72 73 74 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a  rst);.}../******
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 2a 2a 2a  ****************
4250: 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66  **/../*.** The f
4260: 69 72 73 74 20 74 69 6d 65 20 74 68 65 20 62 6d  irst time the bm
4270: 32 35 28 29 20 66 75 6e 63 74 69 6f 6e 20 69 73  25() function is
4280: 20 63 61 6c 6c 65 64 20 66 6f 72 20 61 20 71 75   called for a qu
4290: 65 72 79 2c 20 61 6e 20 69 6e 73 74 61 6e 63 65  ery, an instance
42a0: 0a 2a 2a 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  .** of the follo
42b0: 77 69 6e 67 20 73 74 72 75 63 74 75 72 65 20 69  wing structure i
42c0: 73 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e 64 20  s allocated and 
42d0: 70 6f 70 75 6c 61 74 65 64 2e 0a 2a 2f 0a 74 79  populated..*/.ty
42e0: 70 65 64 65 66 20 73 74 72 75 63 74 20 46 74 73  pedef struct Fts
42f0: 35 42 6d 32 35 44 61 74 61 20 46 74 73 35 42 6d  5Bm25Data Fts5Bm
4300: 32 35 44 61 74 61 3b 0a 73 74 72 75 63 74 20 46  25Data;.struct F
4310: 74 73 35 42 6d 32 35 44 61 74 61 20 7b 0a 20 20  ts5Bm25Data {.  
4320: 69 6e 74 20 6e 50 68 72 61 73 65 3b 20 20 20 20  int nPhrase;    
4330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4340: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 68 72  /* Number of phr
4350: 61 73 65 73 20 69 6e 20 71 75 65 72 79 20 2a 2f  ases in query */
4360: 0a 20 20 64 6f 75 62 6c 65 20 61 76 67 64 6c 3b  .  double avgdl;
4370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4380: 20 20 20 2f 2a 20 41 76 65 72 61 67 65 20 6e 75     /* Average nu
4390: 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73 20 69  mber of tokens i
43a0: 6e 20 65 61 63 68 20 72 6f 77 20 2a 2f 0a 20 20  n each row */.  
43b0: 64 6f 75 62 6c 65 20 2a 61 49 44 46 3b 20 20 20  double *aIDF;   
43c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
43d0: 2f 2a 20 49 44 46 20 66 6f 72 20 65 61 63 68 20  /* IDF for each 
43e0: 70 68 72 61 73 65 20 2a 2f 0a 20 20 64 6f 75 62  phrase */.  doub
43f0: 6c 65 20 2a 61 46 72 65 71 3b 20 20 20 20 20 20  le *aFreq;      
4400: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
4410: 72 72 61 79 20 75 73 65 64 20 74 6f 20 63 61 6c  rray used to cal
4420: 63 75 6c 61 74 65 20 70 68 72 61 73 65 20 66 72  culate phrase fr
4430: 65 71 2e 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  eq. */.};../*.**
4440: 20 43 61 6c 6c 62 61 63 6b 20 75 73 65 64 20 62   Callback used b
4450: 79 20 66 74 73 35 42 6d 32 35 47 65 74 44 61 74  y fts5Bm25GetDat
4460: 61 28 29 20 74 6f 20 63 6f 75 6e 74 20 74 68 65  a() to count the
4470: 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 20   number of rows 
4480: 69 6e 20 74 68 65 0a 2a 2a 20 74 61 62 6c 65 20  in the.** table 
4490: 6d 61 74 63 68 65 64 20 62 79 20 65 61 63 68 20  matched by each 
44a0: 69 6e 64 69 76 69 64 75 61 6c 20 70 68 72 61 73  individual phras
44b0: 65 20 77 69 74 68 69 6e 20 74 68 65 20 71 75 65  e within the que
44c0: 72 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ry..*/.static in
44d0: 74 20 66 74 73 35 43 6f 75 6e 74 43 62 28 0a 20  t fts5CountCb(. 
44e0: 20 63 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e   const Fts5Exten
44f0: 73 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c 20 0a  sionApi *pApi, .
4500: 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70    Fts5Context *p
4510: 46 74 73 2c 0a 20 20 76 6f 69 64 20 2a 70 55 73  Fts,.  void *pUs
4520: 65 72 44 61 74 61 20 20 20 20 20 20 20 20 20 20  erData          
4530: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
4540: 72 20 74 6f 20 73 71 6c 69 74 65 33 5f 69 6e 74  r to sqlite3_int
4550: 36 34 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 29  64 variable */.)
4560: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  {.  sqlite3_int6
4570: 34 20 2a 70 6e 20 3d 20 28 73 71 6c 69 74 65 33  4 *pn = (sqlite3
4580: 5f 69 6e 74 36 34 2a 29 70 55 73 65 72 44 61 74  _int64*)pUserDat
4590: 61 3b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41  a;.  UNUSED_PARA
45a0: 4d 32 28 70 41 70 69 2c 20 70 46 74 73 29 3b 0a  M2(pApi, pFts);.
45b0: 20 20 28 2a 70 6e 29 2b 2b 3b 0a 20 20 72 65 74    (*pn)++;.  ret
45c0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
45d0: 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 2a 70 70 44  ../*.** Set *ppD
45e0: 61 74 61 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  ata to point to 
45f0: 74 68 65 20 46 74 73 35 42 6d 32 35 44 61 74 61  the Fts5Bm25Data
4600: 20 6f 62 6a 65 63 74 20 66 6f 72 20 74 68 65 20   object for the 
4610: 63 75 72 72 65 6e 74 20 71 75 65 72 79 2e 20 0a  current query. .
4620: 2a 2a 20 49 66 20 74 68 65 20 6f 62 6a 65 63 74  ** If the object
4630: 20 68 61 73 20 6e 6f 74 20 61 6c 72 65 61 64 79   has not already
4640: 20 62 65 65 6e 20 61 6c 6c 6f 63 61 74 65 64 2c   been allocated,
4650: 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64 20 70 6f   allocate and po
4660: 70 75 6c 61 74 65 20 69 74 0a 2a 2a 20 6e 6f 77  pulate it.** now
4670: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
4680: 66 74 73 35 42 6d 32 35 47 65 74 44 61 74 61 28  fts5Bm25GetData(
4690: 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45 78 74  .  const Fts5Ext
46a0: 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c  ensionApi *pApi,
46b0: 20 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20   .  Fts5Context 
46c0: 2a 70 46 74 73 2c 0a 20 20 46 74 73 35 42 6d 32  *pFts,.  Fts5Bm2
46d0: 35 44 61 74 61 20 2a 2a 70 70 44 61 74 61 20 20  5Data **ppData  
46e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
46f0: 20 62 6d 32 35 2d 64 61 74 61 20 6f 62 6a 65 63   bm25-data objec
4700: 74 20 66 6f 72 20 74 68 69 73 20 71 75 65 72 79  t for this query
4710: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20   */.){.  int rc 
4720: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20  = SQLITE_OK;    
4730: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
4740: 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 46 74 73  rn code */.  Fts
4750: 35 42 6d 32 35 44 61 74 61 20 2a 70 3b 20 20 20  5Bm25Data *p;   
4760: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4770: 4f 62 6a 65 63 74 20 74 6f 20 72 65 74 75 72 6e  Object to return
4780: 20 2a 2f 0a 0a 20 20 70 20 3d 20 70 41 70 69 2d   */..  p = pApi-
4790: 3e 78 47 65 74 41 75 78 64 61 74 61 28 70 46 74  >xGetAuxdata(pFt
47a0: 73 2c 20 30 29 3b 0a 20 20 69 66 28 20 70 3d 3d  s, 0);.  if( p==
47b0: 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 50 68  0 ){.    int nPh
47c0: 72 61 73 65 3b 20 20 20 20 20 20 20 20 20 20 20  rase;           
47d0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
47e0: 20 6f 66 20 70 68 72 61 73 65 73 20 69 6e 20 71   of phrases in q
47f0: 75 65 72 79 20 2a 2f 0a 20 20 20 20 73 71 6c 69  uery */.    sqli
4800: 74 65 33 5f 69 6e 74 36 34 20 6e 52 6f 77 20 3d  te3_int64 nRow =
4810: 20 30 3b 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d   0;       /* Num
4820: 62 65 72 20 6f 66 20 72 6f 77 73 20 69 6e 20 74  ber of rows in t
4830: 61 62 6c 65 20 2a 2f 0a 20 20 20 20 73 71 6c 69  able */.    sqli
4840: 74 65 33 5f 69 6e 74 36 34 20 6e 54 6f 6b 65 6e  te3_int64 nToken
4850: 20 3d 20 30 3b 20 20 20 20 20 2f 2a 20 4e 75 6d   = 0;     /* Num
4860: 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73 20 69 6e  ber of tokens in
4870: 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 73 71   table */.    sq
4880: 6c 69 74 65 33 5f 69 6e 74 36 34 20 6e 42 79 74  lite3_int64 nByt
4890: 65 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42  e;          /* B
48a0: 79 74 65 73 20 6f 66 20 73 70 61 63 65 20 74 6f  ytes of space to
48b0: 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 20   allocate */.   
48c0: 20 69 6e 74 20 69 3b 0a 0a 20 20 20 20 2f 2a 20   int i;..    /* 
48d0: 41 6c 6c 6f 63 61 74 65 20 74 68 65 20 46 74 73  Allocate the Fts
48e0: 35 42 6d 32 35 44 61 74 61 20 6f 62 6a 65 63 74  5Bm25Data object
48f0: 20 2a 2f 0a 20 20 20 20 6e 50 68 72 61 73 65 20   */.    nPhrase 
4900: 3d 20 70 41 70 69 2d 3e 78 50 68 72 61 73 65 43  = pApi->xPhraseC
4910: 6f 75 6e 74 28 70 46 74 73 29 3b 0a 20 20 20 20  ount(pFts);.    
4920: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 46  nByte = sizeof(F
4930: 74 73 35 42 6d 32 35 44 61 74 61 29 20 2b 20 6e  ts5Bm25Data) + n
4940: 50 68 72 61 73 65 2a 32 2a 73 69 7a 65 6f 66 28  Phrase*2*sizeof(
4950: 64 6f 75 62 6c 65 29 3b 0a 20 20 20 20 70 20 3d  double);.    p =
4960: 20 28 46 74 73 35 42 6d 32 35 44 61 74 61 2a 29   (Fts5Bm25Data*)
4970: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34  sqlite3_malloc64
4980: 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28  (nByte);.    if(
4990: 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72   p==0 ){.      r
49a0: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
49b0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
49c0: 20 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20     memset(p, 0, 
49d0: 28 73 69 7a 65 5f 74 29 6e 42 79 74 65 29 3b 0a  (size_t)nByte);.
49e0: 20 20 20 20 20 20 70 2d 3e 6e 50 68 72 61 73 65        p->nPhrase
49f0: 20 3d 20 6e 50 68 72 61 73 65 3b 0a 20 20 20 20   = nPhrase;.    
4a00: 20 20 70 2d 3e 61 49 44 46 20 3d 20 28 64 6f 75    p->aIDF = (dou
4a10: 62 6c 65 2a 29 26 70 5b 31 5d 3b 0a 20 20 20 20  ble*)&p[1];.    
4a20: 20 20 70 2d 3e 61 46 72 65 71 20 3d 20 26 70 2d    p->aFreq = &p-
4a30: 3e 61 49 44 46 5b 6e 50 68 72 61 73 65 5d 3b 0a  >aIDF[nPhrase];.
4a40: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 61      }..    /* Ca
4a50: 6c 63 75 6c 61 74 65 20 74 68 65 20 61 76 65 72  lculate the aver
4a60: 61 67 65 20 64 6f 63 75 6d 65 6e 74 20 6c 65 6e  age document len
4a70: 67 74 68 20 66 6f 72 20 74 68 69 73 20 46 54 53  gth for this FTS
4a80: 35 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 69  5 table */.    i
4a90: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
4aa0: 20 29 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 52   ) rc = pApi->xR
4ab0: 6f 77 43 6f 75 6e 74 28 70 46 74 73 2c 20 26 6e  owCount(pFts, &n
4ac0: 52 6f 77 29 3b 0a 20 20 20 20 61 73 73 65 72 74  Row);.    assert
4ad0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
4ae0: 7c 7c 20 6e 52 6f 77 3e 30 20 29 3b 0a 20 20 20  || nRow>0 );.   
4af0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
4b00: 4f 4b 20 29 20 72 63 20 3d 20 70 41 70 69 2d 3e  OK ) rc = pApi->
4b10: 78 43 6f 6c 75 6d 6e 54 6f 74 61 6c 53 69 7a 65  xColumnTotalSize
4b20: 28 70 46 74 73 2c 20 2d 31 2c 20 26 6e 54 6f 6b  (pFts, -1, &nTok
4b30: 65 6e 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  en);.    if( rc=
4b40: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 70 2d 3e  =SQLITE_OK ) p->
4b50: 61 76 67 64 6c 20 3d 20 28 64 6f 75 62 6c 65 29  avgdl = (double)
4b60: 6e 54 6f 6b 65 6e 20 20 2f 20 28 64 6f 75 62 6c  nToken  / (doubl
4b70: 65 29 6e 52 6f 77 3b 0a 0a 20 20 20 20 2f 2a 20  e)nRow;..    /* 
4b80: 43 61 6c 63 75 6c 61 74 65 20 61 6e 20 49 44 46  Calculate an IDF
4b90: 20 66 6f 72 20 65 61 63 68 20 70 68 72 61 73 65   for each phrase
4ba0: 20 69 6e 20 74 68 65 20 71 75 65 72 79 20 2a 2f   in the query */
4bb0: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63  .    for(i=0; rc
4bc0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
4bd0: 3c 6e 50 68 72 61 73 65 3b 20 69 2b 2b 29 7b 0a  <nPhrase; i++){.
4be0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e        sqlite3_in
4bf0: 74 36 34 20 6e 48 69 74 20 3d 20 30 3b 0a 20 20  t64 nHit = 0;.  
4c00: 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78      rc = pApi->x
4c10: 51 75 65 72 79 50 68 72 61 73 65 28 70 46 74 73  QueryPhrase(pFts
4c20: 2c 20 69 2c 20 28 76 6f 69 64 2a 29 26 6e 48 69  , i, (void*)&nHi
4c30: 74 2c 20 66 74 73 35 43 6f 75 6e 74 43 62 29 3b  t, fts5CountCb);
4c40: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
4c50: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
4c60: 20 20 20 20 2f 2a 20 43 61 6c 63 75 6c 61 74 65      /* Calculate
4c70: 20 74 68 65 20 49 44 46 20 28 49 6e 76 65 72 73   the IDF (Invers
4c80: 65 20 44 6f 63 75 6d 65 6e 74 20 46 72 65 71 75  e Document Frequ
4c90: 65 6e 63 79 29 20 66 6f 72 20 70 68 72 61 73 65  ency) for phrase
4ca0: 20 69 2e 0a 20 20 20 20 20 20 20 20 2a 2a 20 54   i..        ** T
4cb0: 68 69 73 20 69 73 20 64 6f 6e 65 20 75 73 69 6e  his is done usin
4cc0: 67 20 74 68 65 20 73 74 61 6e 64 61 72 64 20 42  g the standard B
4cd0: 4d 32 35 20 66 6f 72 6d 75 6c 61 20 61 73 20 66  M25 formula as f
4ce0: 6f 75 6e 64 20 6f 6e 20 77 69 6b 69 70 65 64 69  ound on wikipedi
4cf0: 61 3a 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20  a:.        **.  
4d00: 20 20 20 20 20 20 2a 2a 20 20 20 49 44 46 20 3d        **   IDF =
4d10: 20 6c 6f 67 28 20 28 4e 20 2d 20 6e 48 69 74 20   log( (N - nHit 
4d20: 2b 20 30 2e 35 29 20 2f 20 28 6e 48 69 74 20 2b  + 0.5) / (nHit +
4d30: 20 30 2e 35 29 20 29 0a 20 20 20 20 20 20 20 20   0.5) ).        
4d40: 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 77 68  **.        ** wh
4d50: 65 72 65 20 22 4e 22 20 69 73 20 74 68 65 20 74  ere "N" is the t
4d60: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 64  otal number of d
4d70: 6f 63 75 6d 65 6e 74 73 20 69 6e 20 74 68 65 20  ocuments in the 
4d80: 73 65 74 20 61 6e 64 20 6e 48 69 74 0a 20 20 20  set and nHit.   
4d90: 20 20 20 20 20 2a 2a 20 69 73 20 74 68 65 20 6e       ** is the n
4da0: 75 6d 62 65 72 20 74 68 61 74 20 63 6f 6e 74 61  umber that conta
4db0: 69 6e 20 61 74 20 6c 65 61 73 74 20 6f 6e 65 20  in at least one 
4dc0: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20  instance of the 
4dd0: 70 68 72 61 73 65 0a 20 20 20 20 20 20 20 20 2a  phrase.        *
4de0: 2a 20 75 6e 64 65 72 20 63 6f 6e 73 69 64 65 72  * under consider
4df0: 61 74 69 6f 6e 2e 0a 20 20 20 20 20 20 20 20 2a  ation..        *
4e00: 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 54 68 65  *.        ** The
4e10: 20 70 72 6f 62 6c 65 6d 20 77 69 74 68 20 74 68   problem with th
4e20: 69 73 20 69 73 20 74 68 61 74 20 69 66 20 28 4e  is is that if (N
4e30: 20 3c 20 32 2a 6e 48 69 74 29 2c 20 74 68 65 20   < 2*nHit), the 
4e40: 49 44 46 20 69 73 20 0a 20 20 20 20 20 20 20 20  IDF is .        
4e50: 2a 2a 20 6e 65 67 61 74 69 76 65 2e 20 57 68 69  ** negative. Whi
4e60: 63 68 20 69 73 20 75 6e 64 65 73 69 72 61 62 6c  ch is undesirabl
4e70: 65 2e 20 53 6f 20 74 68 65 20 6d 69 6d 69 6d 75  e. So the mimimu
4e80: 6d 20 61 6c 6c 6f 77 61 62 6c 65 20 49 44 46 20  m allowable IDF 
4e90: 69 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 28 31  is.        ** (1
4ea0: 65 2d 36 29 20 2d 20 72 6f 75 67 68 6c 79 20 74  e-6) - roughly t
4eb0: 68 65 20 73 61 6d 65 20 61 73 20 61 20 74 65 72  he same as a ter
4ec0: 6d 20 74 68 61 74 20 61 70 70 65 61 72 73 20 69  m that appears i
4ed0: 6e 20 6a 75 73 74 20 6f 76 65 72 0a 20 20 20 20  n just over.    
4ee0: 20 20 20 20 2a 2a 20 68 61 6c 66 20 6f 66 20 73      ** half of s
4ef0: 65 74 20 6f 66 20 35 2c 30 30 30 2c 30 30 30 20  et of 5,000,000 
4f00: 64 6f 63 75 6d 65 6e 74 73 2e 20 20 2a 2f 0a 20  documents.  */. 
4f10: 20 20 20 20 20 20 20 64 6f 75 62 6c 65 20 69 64         double id
4f20: 66 20 3d 20 6c 6f 67 28 20 28 6e 52 6f 77 20 2d  f = log( (nRow -
4f30: 20 6e 48 69 74 20 2b 20 30 2e 35 29 20 2f 20 28   nHit + 0.5) / (
4f40: 6e 48 69 74 20 2b 20 30 2e 35 29 20 29 3b 0a 20  nHit + 0.5) );. 
4f50: 20 20 20 20 20 20 20 69 66 28 20 69 64 66 3c 3d         if( idf<=
4f60: 30 2e 30 20 29 20 69 64 66 20 3d 20 31 65 2d 36  0.0 ) idf = 1e-6
4f70: 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e 61 49 44  ;.        p->aID
4f80: 46 5b 69 5d 20 3d 20 69 64 66 3b 0a 20 20 20 20  F[i] = idf;.    
4f90: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69    }.    }..    i
4fa0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
4fb0: 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ){.      sqlite
4fc0: 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20 7d  3_free(p);.    }
4fd0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d  else{.      rc =
4fe0: 20 70 41 70 69 2d 3e 78 53 65 74 41 75 78 64 61   pApi->xSetAuxda
4ff0: 74 61 28 70 46 74 73 2c 20 70 2c 20 73 71 6c 69  ta(pFts, p, sqli
5000: 74 65 33 5f 66 72 65 65 29 3b 0a 20 20 20 20 7d  te3_free);.    }
5010: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
5020: 49 54 45 5f 4f 4b 20 29 20 70 20 3d 20 30 3b 0a  ITE_OK ) p = 0;.
5030: 20 20 7d 0a 20 20 2a 70 70 44 61 74 61 20 3d 20    }.  *ppData = 
5040: 70 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  p;.  return rc;.
5050: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
5060: 6e 74 61 74 69 6f 6e 20 6f 66 20 62 6d 32 35 28  ntation of bm25(
5070: 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73  ) function..*/.s
5080: 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 42  tatic void fts5B
5090: 6d 32 35 46 75 6e 63 74 69 6f 6e 28 0a 20 20 63  m25Function(.  c
50a0: 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73 69  onst Fts5Extensi
50b0: 6f 6e 41 70 69 20 2a 70 41 70 69 2c 20 20 20 2f  onApi *pApi,   /
50c0: 2a 20 41 50 49 20 6f 66 66 65 72 65 64 20 62 79  * API offered by
50d0: 20 63 75 72 72 65 6e 74 20 46 54 53 20 76 65 72   current FTS ver
50e0: 73 69 6f 6e 20 2a 2f 0a 20 20 46 74 73 35 43 6f  sion */.  Fts5Co
50f0: 6e 74 65 78 74 20 2a 70 46 74 73 2c 20 20 20 20  ntext *pFts,    
5100: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72            /* Fir
5110: 73 74 20 61 72 67 20 74 6f 20 70 61 73 73 20 74  st arg to pass t
5120: 6f 20 70 41 70 69 20 66 75 6e 63 74 69 6f 6e 73  o pApi functions
5130: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f   */.  sqlite3_co
5140: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 20 20 20  ntext *pCtx,    
5150: 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74        /* Context
5160: 20 66 6f 72 20 72 65 74 75 72 6e 69 6e 67 20 72   for returning r
5170: 65 73 75 6c 74 2f 65 72 72 6f 72 20 2a 2f 0a 20  esult/error */. 
5180: 20 69 6e 74 20 6e 56 61 6c 2c 20 20 20 20 20 20   int nVal,      
5190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
51a0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 76 61   /* Number of va
51b0: 6c 75 65 73 20 69 6e 20 61 70 56 61 6c 5b 5d 20  lues in apVal[] 
51c0: 61 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69 74  array */.  sqlit
51d0: 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61 6c  e3_value **apVal
51e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72             /* Ar
51f0: 72 61 79 20 6f 66 20 74 72 61 69 6c 69 6e 67 20  ray of trailing 
5200: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b 0a  arguments */.){.
5210: 20 20 63 6f 6e 73 74 20 64 6f 75 62 6c 65 20 6b    const double k
5220: 31 20 3d 20 31 2e 32 3b 20 20 20 20 20 20 20 20  1 = 1.2;        
5230: 20 20 2f 2a 20 43 6f 6e 73 74 61 6e 74 20 22 6b    /* Constant "k
5240: 31 22 20 66 72 6f 6d 20 42 4d 32 35 20 66 6f 72  1" from BM25 for
5250: 6d 75 6c 61 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  mula */.  const 
5260: 64 6f 75 62 6c 65 20 62 20 3d 20 30 2e 37 35 3b  double b = 0.75;
5270: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e            /* Con
5280: 73 74 61 6e 74 20 22 62 22 20 66 72 6f 6d 20 42  stant "b" from B
5290: 4d 32 35 20 66 6f 72 6d 75 6c 61 20 2a 2f 0a 20  M25 formula */. 
52a0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
52b0: 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
52c0: 20 2f 2a 20 45 72 72 6f 72 20 63 6f 64 65 20 2a   /* Error code *
52d0: 2f 0a 20 20 64 6f 75 62 6c 65 20 73 63 6f 72 65  /.  double score
52e0: 20 3d 20 30 2e 30 3b 20 20 20 20 20 20 20 20 20   = 0.0;         
52f0: 20 20 20 20 2f 2a 20 53 51 4c 20 66 75 6e 63 74      /* SQL funct
5300: 69 6f 6e 20 72 65 74 75 72 6e 20 76 61 6c 75 65  ion return value
5310: 20 2a 2f 0a 20 20 46 74 73 35 42 6d 32 35 44 61   */.  Fts5Bm25Da
5320: 74 61 20 2a 70 44 61 74 61 3b 20 20 20 20 20 20  ta *pData;      
5330: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 73 20        /* Values 
5340: 61 6c 6c 6f 63 61 74 65 64 2f 63 61 6c 63 75 6c  allocated/calcul
5350: 61 74 65 64 20 6f 6e 63 65 20 6f 6e 6c 79 20 2a  ated once only *
5360: 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20  /.  int i;      
5370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5380: 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20      /* Iterator 
5390: 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 69 6e  variable */.  in
53a0: 74 20 6e 49 6e 73 74 20 3d 20 30 3b 20 20 20 20  t nInst = 0;    
53b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
53c0: 20 56 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20   Value returned 
53d0: 62 79 20 78 49 6e 73 74 43 6f 75 6e 74 28 29 20  by xInstCount() 
53e0: 2a 2f 0a 20 20 64 6f 75 62 6c 65 20 44 20 3d 20  */.  double D = 
53f0: 30 2e 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  0.0;            
5400: 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75       /* Total nu
5410: 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73 20 69  mber of tokens i
5420: 6e 20 72 6f 77 20 2a 2f 0a 20 20 64 6f 75 62 6c  n row */.  doubl
5430: 65 20 2a 61 46 72 65 71 20 3d 20 30 3b 20 20 20  e *aFreq = 0;   
5440: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72             /* Ar
5450: 72 61 79 20 6f 66 20 70 68 72 61 73 65 20 66 72  ray of phrase fr
5460: 65 71 2e 20 66 6f 72 20 63 75 72 72 65 6e 74 20  eq. for current 
5470: 72 6f 77 20 2a 2f 0a 0a 20 20 2f 2a 20 43 61 6c  row */..  /* Cal
5480: 63 75 6c 61 74 65 20 74 68 65 20 70 68 72 61 73  culate the phras
5490: 65 20 66 72 65 71 75 65 6e 63 79 20 28 73 79 6d  e frequency (sym
54a0: 62 6f 6c 20 22 66 28 71 69 2c 44 29 22 20 69 6e  bol "f(qi,D)" in
54b0: 20 74 68 65 20 64 6f 63 75 6d 65 6e 74 61 74 69   the documentati
54c0: 6f 6e 29 0a 20 20 2a 2a 20 66 6f 72 20 65 61 63  on).  ** for eac
54d0: 68 20 70 68 72 61 73 65 20 69 6e 20 74 68 65 20  h phrase in the 
54e0: 71 75 65 72 79 20 66 6f 72 20 74 68 65 20 63 75  query for the cu
54f0: 72 72 65 6e 74 20 72 6f 77 2e 20 2a 2f 0a 20 20  rrent row. */.  
5500: 72 63 20 3d 20 66 74 73 35 42 6d 32 35 47 65 74  rc = fts5Bm25Get
5510: 44 61 74 61 28 70 41 70 69 2c 20 70 46 74 73 2c  Data(pApi, pFts,
5520: 20 26 70 44 61 74 61 29 3b 0a 20 20 69 66 28 20   &pData);.  if( 
5530: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
5540: 0a 20 20 20 20 61 46 72 65 71 20 3d 20 70 44 61  .    aFreq = pDa
5550: 74 61 2d 3e 61 46 72 65 71 3b 0a 20 20 20 20 6d  ta->aFreq;.    m
5560: 65 6d 73 65 74 28 61 46 72 65 71 2c 20 30 2c 20  emset(aFreq, 0, 
5570: 73 69 7a 65 6f 66 28 64 6f 75 62 6c 65 29 20 2a  sizeof(double) *
5580: 20 70 44 61 74 61 2d 3e 6e 50 68 72 61 73 65 29   pData->nPhrase)
5590: 3b 0a 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d  ;.    rc = pApi-
55a0: 3e 78 49 6e 73 74 43 6f 75 6e 74 28 70 46 74 73  >xInstCount(pFts
55b0: 2c 20 26 6e 49 6e 73 74 29 3b 0a 20 20 7d 0a 20  , &nInst);.  }. 
55c0: 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51   for(i=0; rc==SQ
55d0: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 49 6e  LITE_OK && i<nIn
55e0: 73 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e  st; i++){.    in
55f0: 74 20 69 70 3b 20 69 6e 74 20 69 63 3b 20 69 6e  t ip; int ic; in
5600: 74 20 69 6f 3b 0a 20 20 20 20 72 63 20 3d 20 70  t io;.    rc = p
5610: 41 70 69 2d 3e 78 49 6e 73 74 28 70 46 74 73 2c  Api->xInst(pFts,
5620: 20 69 2c 20 26 69 70 2c 20 26 69 63 2c 20 26 69   i, &ip, &ic, &i
5630: 6f 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  o);.    if( rc==
5640: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
5650: 20 20 20 64 6f 75 62 6c 65 20 77 20 3d 20 28 6e     double w = (n
5660: 56 61 6c 20 3e 20 69 63 29 20 3f 20 73 71 6c 69  Val > ic) ? sqli
5670: 74 65 33 5f 76 61 6c 75 65 5f 64 6f 75 62 6c 65  te3_value_double
5680: 28 61 70 56 61 6c 5b 69 63 5d 29 20 3a 20 31 2e  (apVal[ic]) : 1.
5690: 30 3b 0a 20 20 20 20 20 20 61 46 72 65 71 5b 69  0;.      aFreq[i
56a0: 70 5d 20 2b 3d 20 77 3b 0a 20 20 20 20 7d 0a 20  p] += w;.    }. 
56b0: 20 7d 0a 0a 20 20 2f 2a 20 46 69 67 75 72 65 20   }..  /* Figure 
56c0: 6f 75 74 20 74 68 65 20 74 6f 74 61 6c 20 73 69  out the total si
56d0: 7a 65 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e  ze of the curren
56e0: 74 20 72 6f 77 20 69 6e 20 74 6f 6b 65 6e 73 2e  t row in tokens.
56f0: 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   */.  if( rc==SQ
5700: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  LITE_OK ){.    i
5710: 6e 74 20 6e 54 6f 6b 3b 0a 20 20 20 20 72 63 20  nt nTok;.    rc 
5720: 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e 53  = pApi->xColumnS
5730: 69 7a 65 28 70 46 74 73 2c 20 2d 31 2c 20 26 6e  ize(pFts, -1, &n
5740: 54 6f 6b 29 3b 0a 20 20 20 20 44 20 3d 20 28 64  Tok);.    D = (d
5750: 6f 75 62 6c 65 29 6e 54 6f 6b 3b 0a 20 20 7d 0a  ouble)nTok;.  }.
5760: 0a 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20  .  /* Determine 
5770: 74 68 65 20 42 4d 32 35 20 73 63 6f 72 65 20 66  the BM25 score f
5780: 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 72  or the current r
5790: 6f 77 2e 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30  ow. */.  for(i=0
57a0: 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ; rc==SQLITE_OK 
57b0: 26 26 20 69 3c 70 44 61 74 61 2d 3e 6e 50 68 72  && i<pData->nPhr
57c0: 61 73 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73  ase; i++){.    s
57d0: 63 6f 72 65 20 2b 3d 20 70 44 61 74 61 2d 3e 61  core += pData->a
57e0: 49 44 46 5b 69 5d 20 2a 20 28 0a 20 20 20 20 20  IDF[i] * (.     
57f0: 20 28 20 61 46 72 65 71 5b 69 5d 20 2a 20 28 6b   ( aFreq[i] * (k
5800: 31 20 2b 20 31 2e 30 29 20 29 20 2f 20 0a 20 20  1 + 1.0) ) / .  
5810: 20 20 20 20 28 20 61 46 72 65 71 5b 69 5d 20 2b      ( aFreq[i] +
5820: 20 6b 31 20 2a 20 28 31 20 2d 20 62 20 2b 20 62   k1 * (1 - b + b
5830: 20 2a 20 44 20 2f 20 70 44 61 74 61 2d 3e 61 76   * D / pData->av
5840: 67 64 6c 29 20 29 0a 20 20 20 20 29 3b 0a 20 20  gdl) ).    );.  
5850: 7d 0a 20 20 0a 20 20 2f 2a 20 49 66 20 6e 6f 20  }.  .  /* If no 
5860: 65 72 72 6f 72 20 68 61 73 20 6f 63 63 75 72 72  error has occurr
5870: 65 64 2c 20 72 65 74 75 72 6e 20 74 68 65 20 63  ed, return the c
5880: 61 6c 63 75 6c 61 74 65 64 20 73 63 6f 72 65 2e  alculated score.
5890: 20 4f 74 68 65 72 77 69 73 65 2c 0a 20 20 2a 2a   Otherwise,.  **
58a0: 20 74 68 72 6f 77 20 61 6e 20 53 51 4c 20 65 78   throw an SQL ex
58b0: 63 65 70 74 69 6f 6e 2e 20 20 2a 2f 0a 20 20 69  ception.  */.  i
58c0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
58d0: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
58e0: 72 65 73 75 6c 74 5f 64 6f 75 62 6c 65 28 70 43  result_double(pC
58f0: 74 78 2c 20 2d 31 2e 30 20 2a 20 73 63 6f 72 65  tx, -1.0 * score
5900: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
5910: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65  sqlite3_result_e
5920: 72 72 6f 72 5f 63 6f 64 65 28 70 43 74 78 2c 20  rror_code(pCtx, 
5930: 72 63 29 3b 0a 20 20 7d 0a 7d 0a 0a 69 6e 74 20  rc);.  }.}..int 
5940: 73 71 6c 69 74 65 33 46 74 73 35 41 75 78 49 6e  sqlite3Fts5AuxIn
5950: 69 74 28 66 74 73 35 5f 61 70 69 20 2a 70 41 70  it(fts5_api *pAp
5960: 69 29 7b 0a 20 20 73 74 72 75 63 74 20 42 75 69  i){.  struct Bui
5970: 6c 74 69 6e 20 7b 0a 20 20 20 20 63 6f 6e 73 74  ltin {.    const
5980: 20 63 68 61 72 20 2a 7a 46 75 6e 63 3b 20 20 20   char *zFunc;   
5990: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63           /* Func
59a0: 74 69 6f 6e 20 6e 61 6d 65 20 28 6e 75 6c 2d 74  tion name (nul-t
59b0: 65 72 6d 69 6e 61 74 65 64 29 20 2a 2f 0a 20 20  erminated) */.  
59c0: 20 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61 74    void *pUserDat
59d0: 61 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  a;              
59e0: 2f 2a 20 55 73 65 72 2d 64 61 74 61 20 70 6f 69  /* User-data poi
59f0: 6e 74 65 72 20 2a 2f 0a 20 20 20 20 66 74 73 35  nter */.    fts5
5a00: 5f 65 78 74 65 6e 73 69 6f 6e 5f 66 75 6e 63 74  _extension_funct
5a10: 69 6f 6e 20 78 46 75 6e 63 3b 2f 2a 20 43 61 6c  ion xFunc;/* Cal
5a20: 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20 2a  lback function *
5a30: 2f 0a 20 20 20 20 76 6f 69 64 20 28 2a 78 44 65  /.    void (*xDe
5a40: 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 3b 20 20  stroy)(void*);  
5a50: 20 20 20 20 2f 2a 20 44 65 73 74 72 75 63 74 6f      /* Destructo
5a60: 72 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20  r function */.  
5a70: 7d 20 61 42 75 69 6c 74 69 6e 20 5b 5d 20 3d 20  } aBuiltin [] = 
5a80: 7b 0a 20 20 20 20 7b 20 22 73 6e 69 70 70 65 74  {.    { "snippet
5a90: 22 2c 20 20 20 30 2c 20 66 74 73 35 53 6e 69 70  ",   0, fts5Snip
5aa0: 70 65 74 46 75 6e 63 74 69 6f 6e 2c 20 30 20 7d  petFunction, 0 }
5ab0: 2c 0a 20 20 20 20 7b 20 22 68 69 67 68 6c 69 67  ,.    { "highlig
5ac0: 68 74 22 2c 20 30 2c 20 66 74 73 35 48 69 67 68  ht", 0, fts5High
5ad0: 6c 69 67 68 74 46 75 6e 63 74 69 6f 6e 2c 20 30  lightFunction, 0
5ae0: 20 7d 2c 0a 20 20 20 20 7b 20 22 62 6d 32 35 22   },.    { "bm25"
5af0: 2c 20 20 20 20 20 20 30 2c 20 66 74 73 35 42 6d  ,      0, fts5Bm
5b00: 32 35 46 75 6e 63 74 69 6f 6e 2c 20 20 20 20 30  25Function,    0
5b10: 20 7d 2c 0a 20 20 7d 3b 0a 20 20 69 6e 74 20 72   },.  };.  int r
5b20: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
5b30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
5b40: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69  turn code */.  i
5b50: 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20  nt i;           
5b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5b70: 2a 20 54 6f 20 69 74 65 72 61 74 65 20 74 68 72  * To iterate thr
5b80: 6f 75 67 68 20 62 75 69 6c 74 69 6e 20 66 75 6e  ough builtin fun
5b90: 63 74 69 6f 6e 73 20 2a 2f 0a 0a 20 20 66 6f 72  ctions */..  for
5ba0: 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45  (i=0; rc==SQLITE
5bb0: 5f 4f 4b 20 26 26 20 69 3c 41 72 72 61 79 53 69  _OK && i<ArraySi
5bc0: 7a 65 28 61 42 75 69 6c 74 69 6e 29 3b 20 69 2b  ze(aBuiltin); i+
5bd0: 2b 29 7b 0a 20 20 20 20 72 63 20 3d 20 70 41 70  +){.    rc = pAp
5be0: 69 2d 3e 78 43 72 65 61 74 65 46 75 6e 63 74 69  i->xCreateFuncti
5bf0: 6f 6e 28 70 41 70 69 2c 0a 20 20 20 20 20 20 20  on(pApi,.       
5c00: 20 61 42 75 69 6c 74 69 6e 5b 69 5d 2e 7a 46 75   aBuiltin[i].zFu
5c10: 6e 63 2c 0a 20 20 20 20 20 20 20 20 61 42 75 69  nc,.        aBui
5c20: 6c 74 69 6e 5b 69 5d 2e 70 55 73 65 72 44 61 74  ltin[i].pUserDat
5c30: 61 2c 0a 20 20 20 20 20 20 20 20 61 42 75 69 6c  a,.        aBuil
5c40: 74 69 6e 5b 69 5d 2e 78 46 75 6e 63 2c 0a 20 20  tin[i].xFunc,.  
5c50: 20 20 20 20 20 20 61 42 75 69 6c 74 69 6e 5b 69        aBuiltin[i
5c60: 5d 2e 78 44 65 73 74 72 6f 79 0a 20 20 20 20 29  ].xDestroy.    )
5c70: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
5c80: 72 63 3b 0a 7d 0a                                rc;.}.