/ Hex Artifact Content
Login

Artifact ca666a3bbe07c5a3bbe9fffaea19c935a1efaf337333e28bad7bdd1971ffd093:


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 29 7b 0a 20 20 20 20 69 66 28  TE_OK ){.    if(
1170: 20 6e 3c 30 20 29 20 6e 20 3d 20 28 69 6e 74 29   n<0 ) n = (int)
1180: 73 74 72 6c 65 6e 28 7a 29 3b 0a 20 20 20 20 70  strlen(z);.    p
1190: 2d 3e 7a 4f 75 74 20 3d 20 73 71 6c 69 74 65 33  ->zOut = sqlite3
11a0: 5f 6d 70 72 69 6e 74 66 28 22 25 7a 25 2e 2a 73  _mprintf("%z%.*s
11b0: 22 2c 20 70 2d 3e 7a 4f 75 74 2c 20 6e 2c 20 7a  ", p->zOut, n, z
11c0: 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 7a 4f  );.    if( p->zO
11d0: 75 74 3d 3d 30 20 29 20 2a 70 52 63 20 3d 20 53  ut==0 ) *pRc = S
11e0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
11f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e 69  .}../*.** Tokeni
1200: 7a 65 72 20 63 61 6c 6c 62 61 63 6b 20 75 73 65  zer callback use
1210: 64 20 62 79 20 69 6d 70 6c 65 6d 65 6e 74 61 74  d by implementat
1220: 69 6f 6e 20 6f 66 20 68 69 67 68 6c 69 67 68 74  ion of highlight
1230: 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a  () function..*/.
1240: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 48  static int fts5H
1250: 69 67 68 6c 69 67 68 74 43 62 28 0a 20 20 76 6f  ighlightCb(.  vo
1260: 69 64 20 2a 70 43 6f 6e 74 65 78 74 2c 20 20 20  id *pContext,   
1270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1280: 20 50 6f 69 6e 74 65 72 20 74 6f 20 48 69 67 68   Pointer to High
1290: 6c 69 67 68 74 43 6f 6e 74 65 78 74 20 6f 62 6a  lightContext obj
12a0: 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20 74 66 6c  ect */.  int tfl
12b0: 61 67 73 2c 20 20 20 20 20 20 20 20 20 20 20 20  ags,            
12c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 73 6b           /* Mask
12d0: 20 6f 66 20 46 54 53 35 5f 54 4f 4b 45 4e 5f 2a   of FTS5_TOKEN_*
12e0: 20 66 6c 61 67 73 20 2a 2f 0a 20 20 63 6f 6e 73   flags */.  cons
12f0: 74 20 63 68 61 72 20 2a 70 54 6f 6b 65 6e 2c 20  t char *pToken, 
1300: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
1310: 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67  uffer containing
1320: 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20   token */.  int 
1330: 6e 54 6f 6b 65 6e 2c 20 20 20 20 20 20 20 20 20  nToken,         
1340: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
1350: 69 7a 65 20 6f 66 20 74 6f 6b 65 6e 20 69 6e 20  ize of token in 
1360: 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 69  bytes */.  int i
1370: 53 74 61 72 74 4f 66 66 2c 20 20 20 20 20 20 20  StartOff,       
1380: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74             /* St
1390: 61 72 74 20 6f 66 66 73 65 74 20 6f 66 20 74 6f  art offset of to
13a0: 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 45 6e  ken */.  int iEn
13b0: 64 4f 66 66 20 20 20 20 20 20 20 20 20 20 20 20  dOff            
13c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 45 6e 64 20           /* End 
13d0: 6f 66 66 73 65 74 20 6f 66 20 74 6f 6b 65 6e 20  offset of token 
13e0: 2a 2f 0a 29 7b 0a 20 20 48 69 67 68 6c 69 67 68  */.){.  Highligh
13f0: 74 43 6f 6e 74 65 78 74 20 2a 70 20 3d 20 28 48  tContext *p = (H
1400: 69 67 68 6c 69 67 68 74 43 6f 6e 74 65 78 74 2a  ighlightContext*
1410: 29 70 43 6f 6e 74 65 78 74 3b 0a 20 20 69 6e 74  )pContext;.  int
1420: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
1430: 0a 20 20 69 6e 74 20 69 50 6f 73 3b 0a 0a 20 20  .  int iPos;..  
1440: 55 4e 55 53 45 44 5f 50 41 52 41 4d 32 28 70 54  UNUSED_PARAM2(pT
1450: 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 29 3b 0a 0a  oken, nToken);..
1460: 20 20 69 66 28 20 74 66 6c 61 67 73 20 26 20 46    if( tflags & F
1470: 54 53 35 5f 54 4f 4b 45 4e 5f 43 4f 4c 4f 43 41  TS5_TOKEN_COLOCA
1480: 54 45 44 20 29 20 72 65 74 75 72 6e 20 53 51 4c  TED ) return SQL
1490: 49 54 45 5f 4f 4b 3b 0a 20 20 69 50 6f 73 20 3d  ITE_OK;.  iPos =
14a0: 20 70 2d 3e 69 50 6f 73 2b 2b 3b 0a 0a 20 20 69   p->iPos++;..  i
14b0: 66 28 20 70 2d 3e 69 52 61 6e 67 65 45 6e 64 3e  f( p->iRangeEnd>
14c0: 30 20 29 7b 0a 20 20 20 20 69 66 28 20 69 50 6f  0 ){.    if( iPo
14d0: 73 3c 70 2d 3e 69 52 61 6e 67 65 53 74 61 72 74  s<p->iRangeStart
14e0: 20 7c 7c 20 69 50 6f 73 3e 70 2d 3e 69 52 61 6e   || iPos>p->iRan
14f0: 67 65 45 6e 64 20 29 20 72 65 74 75 72 6e 20 53  geEnd ) return S
1500: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 69 66  QLITE_OK;.    if
1510: 28 20 70 2d 3e 69 52 61 6e 67 65 53 74 61 72 74  ( p->iRangeStart
1520: 20 26 26 20 69 50 6f 73 3d 3d 70 2d 3e 69 52 61   && iPos==p->iRa
1530: 6e 67 65 53 74 61 72 74 20 29 20 70 2d 3e 69 4f  ngeStart ) p->iO
1540: 66 66 20 3d 20 69 53 74 61 72 74 4f 66 66 3b 0a  ff = iStartOff;.
1550: 20 20 7d 0a 0a 20 20 69 66 28 20 69 50 6f 73 3d    }..  if( iPos=
1560: 3d 70 2d 3e 69 74 65 72 2e 69 53 74 61 72 74 20  =p->iter.iStart 
1570: 29 7b 0a 20 20 20 20 66 74 73 35 48 69 67 68 6c  ){.    fts5Highl
1580: 69 67 68 74 41 70 70 65 6e 64 28 26 72 63 2c 20  ightAppend(&rc, 
1590: 70 2c 20 26 70 2d 3e 7a 49 6e 5b 70 2d 3e 69 4f  p, &p->zIn[p->iO
15a0: 66 66 5d 2c 20 69 53 74 61 72 74 4f 66 66 20 2d  ff], iStartOff -
15b0: 20 70 2d 3e 69 4f 66 66 29 3b 0a 20 20 20 20 66   p->iOff);.    f
15c0: 74 73 35 48 69 67 68 6c 69 67 68 74 41 70 70 65  ts5HighlightAppe
15d0: 6e 64 28 26 72 63 2c 20 70 2c 20 70 2d 3e 7a 4f  nd(&rc, p, p->zO
15e0: 70 65 6e 2c 20 2d 31 29 3b 0a 20 20 20 20 70 2d  pen, -1);.    p-
15f0: 3e 69 4f 66 66 20 3d 20 69 53 74 61 72 74 4f 66  >iOff = iStartOf
1600: 66 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 50  f;.  }..  if( iP
1610: 6f 73 3d 3d 70 2d 3e 69 74 65 72 2e 69 45 6e 64  os==p->iter.iEnd
1620: 20 29 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 69   ){.    if( p->i
1630: 52 61 6e 67 65 45 6e 64 20 26 26 20 70 2d 3e 69  RangeEnd && p->i
1640: 74 65 72 2e 69 53 74 61 72 74 3c 70 2d 3e 69 52  ter.iStart<p->iR
1650: 61 6e 67 65 53 74 61 72 74 20 29 7b 0a 20 20 20  angeStart ){.   
1660: 20 20 20 66 74 73 35 48 69 67 68 6c 69 67 68 74     fts5Highlight
1670: 41 70 70 65 6e 64 28 26 72 63 2c 20 70 2c 20 70  Append(&rc, p, p
1680: 2d 3e 7a 4f 70 65 6e 2c 20 2d 31 29 3b 0a 20 20  ->zOpen, -1);.  
1690: 20 20 7d 0a 20 20 20 20 66 74 73 35 48 69 67 68    }.    fts5High
16a0: 6c 69 67 68 74 41 70 70 65 6e 64 28 26 72 63 2c  lightAppend(&rc,
16b0: 20 70 2c 20 26 70 2d 3e 7a 49 6e 5b 70 2d 3e 69   p, &p->zIn[p->i
16c0: 4f 66 66 5d 2c 20 69 45 6e 64 4f 66 66 20 2d 20  Off], iEndOff - 
16d0: 70 2d 3e 69 4f 66 66 29 3b 0a 20 20 20 20 66 74  p->iOff);.    ft
16e0: 73 35 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e  s5HighlightAppen
16f0: 64 28 26 72 63 2c 20 70 2c 20 70 2d 3e 7a 43 6c  d(&rc, p, p->zCl
1700: 6f 73 65 2c 20 2d 31 29 3b 0a 20 20 20 20 70 2d  ose, -1);.    p-
1710: 3e 69 4f 66 66 20 3d 20 69 45 6e 64 4f 66 66 3b  >iOff = iEndOff;
1720: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
1730: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
1740: 72 63 20 3d 20 66 74 73 35 43 49 6e 73 74 49 74  rc = fts5CInstIt
1750: 65 72 4e 65 78 74 28 26 70 2d 3e 69 74 65 72 29  erNext(&p->iter)
1760: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
1770: 66 28 20 70 2d 3e 69 52 61 6e 67 65 45 6e 64 3e  f( p->iRangeEnd>
1780: 30 20 26 26 20 69 50 6f 73 3d 3d 70 2d 3e 69 52  0 && iPos==p->iR
1790: 61 6e 67 65 45 6e 64 20 29 7b 0a 20 20 20 20 66  angeEnd ){.    f
17a0: 74 73 35 48 69 67 68 6c 69 67 68 74 41 70 70 65  ts5HighlightAppe
17b0: 6e 64 28 26 72 63 2c 20 70 2c 20 26 70 2d 3e 7a  nd(&rc, p, &p->z
17c0: 49 6e 5b 70 2d 3e 69 4f 66 66 5d 2c 20 69 45 6e  In[p->iOff], iEn
17d0: 64 4f 66 66 20 2d 20 70 2d 3e 69 4f 66 66 29 3b  dOff - p->iOff);
17e0: 0a 20 20 20 20 70 2d 3e 69 4f 66 66 20 3d 20 69  .    p->iOff = i
17f0: 45 6e 64 4f 66 66 3b 0a 20 20 20 20 69 66 28 20  EndOff;.    if( 
1800: 69 50 6f 73 3e 3d 70 2d 3e 69 74 65 72 2e 69 53  iPos>=p->iter.iS
1810: 74 61 72 74 20 26 26 20 69 50 6f 73 3c 70 2d 3e  tart && iPos<p->
1820: 69 74 65 72 2e 69 45 6e 64 20 29 7b 0a 20 20 20  iter.iEnd ){.   
1830: 20 20 20 66 74 73 35 48 69 67 68 6c 69 67 68 74     fts5Highlight
1840: 41 70 70 65 6e 64 28 26 72 63 2c 20 70 2c 20 70  Append(&rc, p, p
1850: 2d 3e 7a 43 6c 6f 73 65 2c 20 2d 31 29 3b 0a 20  ->zClose, -1);. 
1860: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
1870: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
1880: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
1890: 66 20 68 69 67 68 6c 69 67 68 74 28 29 20 66 75  f highlight() fu
18a0: 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69  nction..*/.stati
18b0: 63 20 76 6f 69 64 20 66 74 73 35 48 69 67 68 6c  c void fts5Highl
18c0: 69 67 68 74 46 75 6e 63 74 69 6f 6e 28 0a 20 20  ightFunction(.  
18d0: 63 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73  const Fts5Extens
18e0: 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c 20 20 20  ionApi *pApi,   
18f0: 2f 2a 20 41 50 49 20 6f 66 66 65 72 65 64 20 62  /* API offered b
1900: 79 20 63 75 72 72 65 6e 74 20 46 54 53 20 76 65  y current FTS ve
1910: 72 73 69 6f 6e 20 2a 2f 0a 20 20 46 74 73 35 43  rsion */.  Fts5C
1920: 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c 20 20 20  ontext *pFts,   
1930: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
1940: 72 73 74 20 61 72 67 20 74 6f 20 70 61 73 73 20  rst arg to pass 
1950: 74 6f 20 70 41 70 69 20 66 75 6e 63 74 69 6f 6e  to pApi function
1960: 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63  s */.  sqlite3_c
1970: 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 20 20  ontext *pCtx,   
1980: 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78         /* Contex
1990: 74 20 66 6f 72 20 72 65 74 75 72 6e 69 6e 67 20  t for returning 
19a0: 72 65 73 75 6c 74 2f 65 72 72 6f 72 20 2a 2f 0a  result/error */.
19b0: 20 20 69 6e 74 20 6e 56 61 6c 2c 20 20 20 20 20    int nVal,     
19c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19d0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 76    /* Number of v
19e0: 61 6c 75 65 73 20 69 6e 20 61 70 56 61 6c 5b 5d  alues in apVal[]
19f0: 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69   array */.  sqli
1a00: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61  te3_value **apVa
1a10: 6c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41  l           /* A
1a20: 72 72 61 79 20 6f 66 20 74 72 61 69 6c 69 6e 67  rray of trailing
1a30: 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b   arguments */.){
1a40: 0a 20 20 48 69 67 68 6c 69 67 68 74 43 6f 6e 74  .  HighlightCont
1a50: 65 78 74 20 63 74 78 3b 0a 20 20 69 6e 74 20 72  ext ctx;.  int r
1a60: 63 3b 0a 20 20 69 6e 74 20 69 43 6f 6c 3b 0a 0a  c;.  int iCol;..
1a70: 20 20 69 66 28 20 6e 56 61 6c 21 3d 33 20 29 7b    if( nVal!=3 ){
1a80: 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20  .    const char 
1a90: 2a 7a 45 72 72 20 3d 20 22 77 72 6f 6e 67 20 6e  *zErr = "wrong n
1aa0: 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e  umber of argumen
1ab0: 74 73 20 74 6f 20 66 75 6e 63 74 69 6f 6e 20 68  ts to function h
1ac0: 69 67 68 6c 69 67 68 74 28 29 22 3b 0a 20 20 20  ighlight()";.   
1ad0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
1ae0: 65 72 72 6f 72 28 70 43 74 78 2c 20 7a 45 72 72  error(pCtx, zErr
1af0: 2c 20 2d 31 29 3b 0a 20 20 20 20 72 65 74 75 72  , -1);.    retur
1b00: 6e 3b 0a 20 20 7d 0a 0a 20 20 69 43 6f 6c 20 3d  n;.  }..  iCol =
1b10: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69   sqlite3_value_i
1b20: 6e 74 28 61 70 56 61 6c 5b 30 5d 29 3b 0a 20 20  nt(apVal[0]);.  
1b30: 6d 65 6d 73 65 74 28 26 63 74 78 2c 20 30 2c 20  memset(&ctx, 0, 
1b40: 73 69 7a 65 6f 66 28 48 69 67 68 6c 69 67 68 74  sizeof(Highlight
1b50: 43 6f 6e 74 65 78 74 29 29 3b 0a 20 20 63 74 78  Context));.  ctx
1b60: 2e 7a 4f 70 65 6e 20 3d 20 28 63 6f 6e 73 74 20  .zOpen = (const 
1b70: 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61  char*)sqlite3_va
1b80: 6c 75 65 5f 74 65 78 74 28 61 70 56 61 6c 5b 31  lue_text(apVal[1
1b90: 5d 29 3b 0a 20 20 63 74 78 2e 7a 43 6c 6f 73 65  ]);.  ctx.zClose
1ba0: 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29   = (const char*)
1bb0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
1bc0: 78 74 28 61 70 56 61 6c 5b 32 5d 29 3b 0a 20 20  xt(apVal[2]);.  
1bd0: 72 63 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75  rc = pApi->xColu
1be0: 6d 6e 54 65 78 74 28 70 46 74 73 2c 20 69 43 6f  mnText(pFts, iCo
1bf0: 6c 2c 20 26 63 74 78 2e 7a 49 6e 2c 20 26 63 74  l, &ctx.zIn, &ct
1c00: 78 2e 6e 49 6e 29 3b 0a 0a 20 20 69 66 28 20 63  x.nIn);..  if( c
1c10: 74 78 2e 7a 49 6e 20 29 7b 0a 20 20 20 20 69 66  tx.zIn ){.    if
1c20: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1c30: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 66 74  ){.      rc = ft
1c40: 73 35 43 49 6e 73 74 49 74 65 72 49 6e 69 74 28  s5CInstIterInit(
1c50: 70 41 70 69 2c 20 70 46 74 73 2c 20 69 43 6f 6c  pApi, pFts, iCol
1c60: 2c 20 26 63 74 78 2e 69 74 65 72 29 3b 0a 20 20  , &ctx.iter);.  
1c70: 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d    }..    if( rc=
1c80: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
1c90: 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78      rc = pApi->x
1ca0: 54 6f 6b 65 6e 69 7a 65 28 70 46 74 73 2c 20 63  Tokenize(pFts, c
1cb0: 74 78 2e 7a 49 6e 2c 20 63 74 78 2e 6e 49 6e 2c  tx.zIn, ctx.nIn,
1cc0: 20 28 76 6f 69 64 2a 29 26 63 74 78 2c 66 74 73   (void*)&ctx,fts
1cd0: 35 48 69 67 68 6c 69 67 68 74 43 62 29 3b 0a 20  5HighlightCb);. 
1ce0: 20 20 20 7d 0a 20 20 20 20 66 74 73 35 48 69 67     }.    fts5Hig
1cf0: 68 6c 69 67 68 74 41 70 70 65 6e 64 28 26 72 63  hlightAppend(&rc
1d00: 2c 20 26 63 74 78 2c 20 26 63 74 78 2e 7a 49 6e  , &ctx, &ctx.zIn
1d10: 5b 63 74 78 2e 69 4f 66 66 5d 2c 20 63 74 78 2e  [ctx.iOff], ctx.
1d20: 6e 49 6e 20 2d 20 63 74 78 2e 69 4f 66 66 29 3b  nIn - ctx.iOff);
1d30: 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ..    if( rc==SQ
1d40: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
1d50: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
1d60: 74 65 78 74 28 70 43 74 78 2c 20 28 63 6f 6e 73  text(pCtx, (cons
1d70: 74 20 63 68 61 72 2a 29 63 74 78 2e 7a 4f 75 74  t char*)ctx.zOut
1d80: 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41  , -1, SQLITE_TRA
1d90: 4e 53 49 45 4e 54 29 3b 0a 20 20 20 20 7d 0a 20  NSIENT);.    }. 
1da0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
1db0: 63 74 78 2e 7a 4f 75 74 29 3b 0a 20 20 7d 0a 20  ctx.zOut);.  }. 
1dc0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
1dd0: 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  OK ){.    sqlite
1de0: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f 63  3_result_error_c
1df0: 6f 64 65 28 70 43 74 78 2c 20 72 63 29 3b 0a 20  ode(pCtx, rc);. 
1e00: 20 7d 0a 7d 0a 2f 2a 0a 2a 2a 20 45 6e 64 20 6f   }.}./*.** End o
1e10: 66 20 68 69 67 68 6c 69 67 68 74 28 29 20 69 6d  f highlight() im
1e20: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2a  plementation..**
1e30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
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 2f 0a 0a 2f 2a 0a 2a 2a  ********/../*.**
1e80: 20 43 6f 6e 74 65 78 74 20 6f 62 6a 65 63 74 20   Context object 
1e90: 70 61 73 73 65 64 20 74 6f 20 74 68 65 20 66 74  passed to the ft
1ea0: 73 35 53 65 6e 74 65 6e 63 65 46 69 6e 64 65 72  s5SentenceFinder
1eb0: 43 62 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a  Cb() function..*
1ec0: 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
1ed0: 20 46 74 73 35 53 46 69 6e 64 65 72 20 46 74 73   Fts5SFinder Fts
1ee0: 35 53 46 69 6e 64 65 72 3b 0a 73 74 72 75 63 74  5SFinder;.struct
1ef0: 20 46 74 73 35 53 46 69 6e 64 65 72 20 7b 0a 20   Fts5SFinder {. 
1f00: 20 69 6e 74 20 69 50 6f 73 3b 20 20 20 20 20 20   int iPos;      
1f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f20: 20 2f 2a 20 43 75 72 72 65 6e 74 20 74 6f 6b 65   /* Current toke
1f30: 6e 20 70 6f 73 69 74 69 6f 6e 20 2a 2f 0a 20 20  n position */.  
1f40: 69 6e 74 20 6e 46 69 72 73 74 41 6c 6c 6f 63 3b  int nFirstAlloc;
1f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f60: 2f 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73 69 7a  /* Allocated siz
1f70: 65 20 6f 66 20 61 46 69 72 73 74 5b 5d 20 2a 2f  e of aFirst[] */
1f80: 0a 20 20 69 6e 74 20 6e 46 69 72 73 74 3b 20 20  .  int nFirst;  
1f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fa0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
1fb0: 65 6e 74 72 69 65 73 20 69 6e 20 61 46 69 72 73  entries in aFirs
1fc0: 74 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 46  t[] */.  int *aF
1fd0: 69 72 73 74 3b 20 20 20 20 20 20 20 20 20 20 20  irst;           
1fe0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61           /* Arra
1ff0: 79 20 6f 66 20 66 69 72 73 74 20 74 6f 6b 65 6e  y of first token
2000: 20 69 6e 20 65 61 63 68 20 73 65 6e 74 65 6e 63   in each sentenc
2010: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  e */.  const cha
2020: 72 20 2a 7a 44 6f 63 3b 20 20 20 20 20 20 20 20  r *zDoc;        
2030: 20 20 20 20 20 20 20 2f 2a 20 44 6f 63 75 6d 65         /* Docume
2040: 6e 74 20 62 65 69 6e 67 20 74 6f 6b 65 6e 69 7a  nt being tokeniz
2050: 65 64 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ed */.};../*.** 
2060: 41 64 64 20 61 6e 20 65 6e 74 72 79 20 74 6f 20  Add an entry to 
2070: 74 68 65 20 46 74 73 35 53 46 69 6e 64 65 72 2e  the Fts5SFinder.
2080: 61 46 69 72 73 74 5b 5d 20 61 72 72 61 79 2e 20  aFirst[] array. 
2090: 47 72 6f 77 20 74 68 65 20 61 72 72 61 79 20 69  Grow the array i
20a0: 66 0a 2a 2a 20 6e 65 63 65 73 73 61 72 79 2e 20  f.** necessary. 
20b0: 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  Return SQLITE_OK
20c0: 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
20d0: 6f 72 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20  or SQLITE_NOMEM 
20e0: 69 66 20 61 6e 0a 2a 2a 20 65 72 72 6f 72 20 6f  if an.** error o
20f0: 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  ccurs..*/.static
2100: 20 69 6e 74 20 66 74 73 35 53 65 6e 74 65 6e 63   int fts5Sentenc
2110: 65 46 69 6e 64 65 72 41 64 64 28 46 74 73 35 53  eFinderAdd(Fts5S
2120: 46 69 6e 64 65 72 20 2a 70 2c 20 69 6e 74 20 69  Finder *p, int i
2130: 41 64 64 29 7b 0a 20 20 69 66 28 20 70 2d 3e 6e  Add){.  if( p->n
2140: 46 69 72 73 74 41 6c 6c 6f 63 3d 3d 70 2d 3e 6e  FirstAlloc==p->n
2150: 46 69 72 73 74 20 29 7b 0a 20 20 20 20 69 6e 74  First ){.    int
2160: 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 46 69 72 73   nNew = p->nFirs
2170: 74 41 6c 6c 6f 63 20 3f 20 70 2d 3e 6e 46 69 72  tAlloc ? p->nFir
2180: 73 74 41 6c 6c 6f 63 2a 32 20 3a 20 36 34 3b 0a  stAlloc*2 : 64;.
2190: 20 20 20 20 69 6e 74 20 2a 61 4e 65 77 3b 0a 0a      int *aNew;..
21a0: 20 20 20 20 61 4e 65 77 20 3d 20 28 69 6e 74 2a      aNew = (int*
21b0: 29 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63  )sqlite3_realloc
21c0: 28 70 2d 3e 61 46 69 72 73 74 2c 20 6e 4e 65 77  (p->aFirst, nNew
21d0: 2a 73 69 7a 65 6f 66 28 69 6e 74 29 29 3b 0a 20  *sizeof(int));. 
21e0: 20 20 20 69 66 28 20 61 4e 65 77 3d 3d 30 20 29     if( aNew==0 )
21f0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
2200: 4f 4d 45 4d 3b 0a 20 20 20 20 70 2d 3e 61 46 69  OMEM;.    p->aFi
2210: 72 73 74 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20  rst = aNew;.    
2220: 70 2d 3e 6e 46 69 72 73 74 41 6c 6c 6f 63 20 3d  p->nFirstAlloc =
2230: 20 6e 4e 65 77 3b 0a 20 20 7d 0a 20 20 70 2d 3e   nNew;.  }.  p->
2240: 61 46 69 72 73 74 5b 70 2d 3e 6e 46 69 72 73 74  aFirst[p->nFirst
2250: 2b 2b 5d 20 3d 20 69 41 64 64 3b 0a 20 20 72 65  ++] = iAdd;.  re
2260: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
2270: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
2280: 6e 63 74 69 6f 6e 20 69 73 20 61 6e 20 78 54 6f  nction is an xTo
2290: 6b 65 6e 69 7a 65 28 29 20 63 61 6c 6c 62 61 63  kenize() callbac
22a0: 6b 20 75 73 65 64 20 62 79 20 74 68 65 20 61 75  k used by the au
22b0: 78 69 6c 69 61 72 79 20 73 6e 69 70 70 65 74 28  xiliary snippet(
22c0: 29 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 2e 20 49  ).** function. I
22d0: 74 73 20 6a 6f 62 20 69 73 20 74 6f 20 69 64 65  ts job is to ide
22e0: 6e 74 69 66 79 20 74 6f 6b 65 6e 73 20 74 68 61  ntify tokens tha
22f0: 74 20 61 72 65 20 74 68 65 20 66 69 72 73 74 20  t are the first 
2300: 69 6e 20 61 20 73 65 6e 74 65 6e 63 65 2e 0a 2a  in a sentence..*
2310: 2a 20 46 6f 72 20 65 61 63 68 20 73 75 63 68 20  * For each such 
2320: 74 6f 6b 65 6e 2c 20 61 6e 20 65 6e 74 72 79 20  token, an entry 
2330: 69 73 20 61 64 64 65 64 20 74 6f 20 74 68 65 20  is added to the 
2340: 53 46 69 6e 64 65 72 2e 61 46 69 72 73 74 5b 5d  SFinder.aFirst[]
2350: 20 61 72 72 61 79 2e 0a 2a 2f 0a 73 74 61 74 69   array..*/.stati
2360: 63 20 69 6e 74 20 66 74 73 35 53 65 6e 74 65 6e  c int fts5Senten
2370: 63 65 46 69 6e 64 65 72 43 62 28 0a 20 20 76 6f  ceFinderCb(.  vo
2380: 69 64 20 2a 70 43 6f 6e 74 65 78 74 2c 20 20 20  id *pContext,   
2390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
23a0: 20 50 6f 69 6e 74 65 72 20 74 6f 20 48 69 67 68   Pointer to High
23b0: 6c 69 67 68 74 43 6f 6e 74 65 78 74 20 6f 62 6a  lightContext obj
23c0: 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20 74 66 6c  ect */.  int tfl
23d0: 61 67 73 2c 20 20 20 20 20 20 20 20 20 20 20 20  ags,            
23e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 73 6b           /* Mask
23f0: 20 6f 66 20 46 54 53 35 5f 54 4f 4b 45 4e 5f 2a   of FTS5_TOKEN_*
2400: 20 66 6c 61 67 73 20 2a 2f 0a 20 20 63 6f 6e 73   flags */.  cons
2410: 74 20 63 68 61 72 20 2a 70 54 6f 6b 65 6e 2c 20  t char *pToken, 
2420: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
2430: 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67  uffer containing
2440: 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20   token */.  int 
2450: 6e 54 6f 6b 65 6e 2c 20 20 20 20 20 20 20 20 20  nToken,         
2460: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
2470: 69 7a 65 20 6f 66 20 74 6f 6b 65 6e 20 69 6e 20  ize of token in 
2480: 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 69  bytes */.  int i
2490: 53 74 61 72 74 4f 66 66 2c 20 20 20 20 20 20 20  StartOff,       
24a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74             /* St
24b0: 61 72 74 20 6f 66 66 73 65 74 20 6f 66 20 74 6f  art offset of to
24c0: 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 45 6e  ken */.  int iEn
24d0: 64 4f 66 66 20 20 20 20 20 20 20 20 20 20 20 20  dOff            
24e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 45 6e 64 20           /* End 
24f0: 6f 66 66 73 65 74 20 6f 66 20 74 6f 6b 65 6e 20  offset of token 
2500: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  */.){.  int rc =
2510: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 55   SQLITE_OK;..  U
2520: 4e 55 53 45 44 5f 50 41 52 41 4d 32 28 70 54 6f  NUSED_PARAM2(pTo
2530: 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 29 3b 0a 20 20  ken, nToken);.  
2540: 55 4e 55 53 45 44 5f 50 41 52 41 4d 28 69 45 6e  UNUSED_PARAM(iEn
2550: 64 4f 66 66 29 3b 0a 0a 20 20 69 66 28 20 28 74  dOff);..  if( (t
2560: 66 6c 61 67 73 20 26 20 46 54 53 35 5f 54 4f 4b  flags & FTS5_TOK
2570: 45 4e 5f 43 4f 4c 4f 43 41 54 45 44 29 3d 3d 30  EN_COLOCATED)==0
2580: 20 29 7b 0a 20 20 20 20 46 74 73 35 53 46 69 6e   ){.    Fts5SFin
2590: 64 65 72 20 2a 70 20 3d 20 28 46 74 73 35 53 46  der *p = (Fts5SF
25a0: 69 6e 64 65 72 2a 29 70 43 6f 6e 74 65 78 74 3b  inder*)pContext;
25b0: 0a 20 20 20 20 69 66 28 20 70 2d 3e 69 50 6f 73  .    if( p->iPos
25c0: 3e 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  >0 ){.      int 
25d0: 69 3b 0a 20 20 20 20 20 20 63 68 61 72 20 63 20  i;.      char c 
25e0: 3d 20 30 3b 0a 20 20 20 20 20 20 66 6f 72 28 69  = 0;.      for(i
25f0: 3d 69 53 74 61 72 74 4f 66 66 2d 31 3b 20 69 3e  =iStartOff-1; i>
2600: 3d 30 3b 20 69 2d 2d 29 7b 0a 20 20 20 20 20 20  =0; i--){.      
2610: 20 20 63 20 3d 20 70 2d 3e 7a 44 6f 63 5b 69 5d    c = p->zDoc[i]
2620: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 63 21  ;.        if( c!
2630: 3d 27 20 27 20 26 26 20 63 21 3d 27 5c 74 27 20  =' ' && c!='\t' 
2640: 26 26 20 63 21 3d 27 5c 6e 27 20 26 26 20 63 21  && c!='\n' && c!
2650: 3d 27 5c 72 27 20 29 20 62 72 65 61 6b 3b 0a 20  ='\r' ) break;. 
2660: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
2670: 20 69 21 3d 69 53 74 61 72 74 4f 66 66 2d 31 20   i!=iStartOff-1 
2680: 26 26 20 28 63 3d 3d 27 2e 27 20 7c 7c 20 63 3d  && (c=='.' || c=
2690: 3d 27 3a 27 29 20 29 7b 0a 20 20 20 20 20 20 20  =':') ){.       
26a0: 20 72 63 20 3d 20 66 74 73 35 53 65 6e 74 65 6e   rc = fts5Senten
26b0: 63 65 46 69 6e 64 65 72 41 64 64 28 70 2c 20 70  ceFinderAdd(p, p
26c0: 2d 3e 69 50 6f 73 29 3b 0a 20 20 20 20 20 20 7d  ->iPos);.      }
26d0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
26e0: 20 20 72 63 20 3d 20 66 74 73 35 53 65 6e 74 65    rc = fts5Sente
26f0: 6e 63 65 46 69 6e 64 65 72 41 64 64 28 70 2c 20  nceFinderAdd(p, 
2700: 30 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d  0);.    }.    p-
2710: 3e 69 50 6f 73 2b 2b 3b 0a 20 20 7d 0a 20 20 72  >iPos++;.  }.  r
2720: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
2730: 74 69 63 20 69 6e 74 20 66 74 73 35 53 6e 69 70  tic int fts5Snip
2740: 70 65 74 53 63 6f 72 65 28 0a 20 20 63 6f 6e 73  petScore(.  cons
2750: 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f 6e 41  t Fts5ExtensionA
2760: 70 69 20 2a 70 41 70 69 2c 20 20 20 2f 2a 20 41  pi *pApi,   /* A
2770: 50 49 20 6f 66 66 65 72 65 64 20 62 79 20 63 75  PI offered by cu
2780: 72 72 65 6e 74 20 46 54 53 20 76 65 72 73 69 6f  rrent FTS versio
2790: 6e 20 2a 2f 0a 20 20 46 74 73 35 43 6f 6e 74 65  n */.  Fts5Conte
27a0: 78 74 20 2a 70 46 74 73 2c 20 20 20 20 20 20 20  xt *pFts,       
27b0: 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20         /* First 
27c0: 61 72 67 20 74 6f 20 70 61 73 73 20 74 6f 20 70  arg to pass to p
27d0: 41 70 69 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f  Api functions */
27e0: 0a 20 20 69 6e 74 20 6e 44 6f 63 73 69 7a 65 2c  .  int nDocsize,
27f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2800: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 63 6f     /* Size of co
2810: 6c 75 6d 6e 20 69 6e 20 74 6f 6b 65 6e 73 20 2a  lumn in tokens *
2820: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61  /.  unsigned cha
2830: 72 20 2a 61 53 65 65 6e 2c 20 20 20 20 20 20 20  r *aSeen,       
2840: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 77 69 74      /* Array wit
2850: 68 20 6f 6e 65 20 65 6c 65 6d 65 6e 74 20 70 65  h one element pe
2860: 72 20 71 75 65 72 79 20 70 68 72 61 73 65 20 2a  r query phrase *
2870: 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 2c 20 20 20  /.  int iCol,   
2880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2890: 20 20 20 20 2f 2a 20 43 6f 6c 75 6d 6e 20 74 6f      /* Column to
28a0: 20 73 63 6f 72 65 20 2a 2f 0a 20 20 69 6e 74 20   score */.  int 
28b0: 69 50 6f 73 2c 20 20 20 20 20 20 20 20 20 20 20  iPos,           
28c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
28d0: 74 61 72 74 69 6e 67 20 6f 66 66 73 65 74 20 74  tarting offset t
28e0: 6f 20 73 63 6f 72 65 20 2a 2f 0a 20 20 69 6e 74  o score */.  int
28f0: 20 6e 54 6f 6b 65 6e 2c 20 20 20 20 20 20 20 20   nToken,        
2900: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2910: 4d 61 78 20 74 6f 6b 65 6e 73 20 70 65 72 20 73  Max tokens per s
2920: 6e 69 70 70 65 74 20 2a 2f 0a 20 20 69 6e 74 20  nippet */.  int 
2930: 2a 70 6e 53 63 6f 72 65 2c 20 20 20 20 20 20 20  *pnScore,       
2940: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
2950: 55 54 3a 20 53 63 6f 72 65 20 2a 2f 0a 20 20 69  UT: Score */.  i
2960: 6e 74 20 2a 70 69 50 6f 73 20 20 20 20 20 20 20  nt *piPos       
2970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2980: 2a 20 4f 55 54 3a 20 41 64 6a 75 73 74 65 64 20  * OUT: Adjusted 
2990: 6f 66 66 73 65 74 20 2a 2f 0a 29 7b 0a 20 20 69  offset */.){.  i
29a0: 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b 0a  nt rc;.  int i;.
29b0: 20 20 69 6e 74 20 69 70 20 3d 20 30 3b 0a 20 20    int ip = 0;.  
29c0: 69 6e 74 20 69 63 20 3d 20 30 3b 0a 20 20 69 6e  int ic = 0;.  in
29d0: 74 20 69 4f 66 66 20 3d 20 30 3b 0a 20 20 69 6e  t iOff = 0;.  in
29e0: 74 20 69 46 69 72 73 74 20 3d 20 2d 31 3b 0a 20  t iFirst = -1;. 
29f0: 20 69 6e 74 20 6e 49 6e 73 74 3b 0a 20 20 69 6e   int nInst;.  in
2a00: 74 20 6e 53 63 6f 72 65 20 3d 20 30 3b 0a 20 20  t nScore = 0;.  
2a10: 69 6e 74 20 69 4c 61 73 74 20 3d 20 30 3b 0a 0a  int iLast = 0;..
2a20: 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 49 6e    rc = pApi->xIn
2a30: 73 74 43 6f 75 6e 74 28 70 46 74 73 2c 20 26 6e  stCount(pFts, &n
2a40: 49 6e 73 74 29 3b 0a 20 20 66 6f 72 28 69 3d 30  Inst);.  for(i=0
2a50: 3b 20 69 3c 6e 49 6e 73 74 20 26 26 20 72 63 3d  ; i<nInst && rc=
2a60: 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29  =SQLITE_OK; i++)
2a70: 7b 0a 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d  {.    rc = pApi-
2a80: 3e 78 49 6e 73 74 28 70 46 74 73 2c 20 69 2c 20  >xInst(pFts, i, 
2a90: 26 69 70 2c 20 26 69 63 2c 20 26 69 4f 66 66 29  &ip, &ic, &iOff)
2aa0: 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
2ab0: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 63 3d 3d 69  LITE_OK && ic==i
2ac0: 43 6f 6c 20 26 26 20 69 4f 66 66 3e 3d 69 50 6f  Col && iOff>=iPo
2ad0: 73 20 26 26 20 69 4f 66 66 3c 28 69 50 6f 73 2b  s && iOff<(iPos+
2ae0: 6e 54 6f 6b 65 6e 29 20 29 7b 0a 20 20 20 20 20  nToken) ){.     
2af0: 20 6e 53 63 6f 72 65 20 2b 3d 20 28 61 53 65 65   nScore += (aSee
2b00: 6e 5b 69 70 5d 20 3f 20 31 20 3a 20 31 30 30 30  n[ip] ? 1 : 1000
2b10: 29 3b 0a 20 20 20 20 20 20 61 53 65 65 6e 5b 69  );.      aSeen[i
2b20: 70 5d 20 3d 20 31 3b 0a 20 20 20 20 20 20 69 66  p] = 1;.      if
2b30: 28 20 69 46 69 72 73 74 3c 30 20 29 20 69 46 69  ( iFirst<0 ) iFi
2b40: 72 73 74 20 3d 20 69 4f 66 66 3b 0a 20 20 20 20  rst = iOff;.    
2b50: 20 20 69 4c 61 73 74 20 3d 20 69 4f 66 66 20 2b    iLast = iOff +
2b60: 20 70 41 70 69 2d 3e 78 50 68 72 61 73 65 53 69   pApi->xPhraseSi
2b70: 7a 65 28 70 46 74 73 2c 20 69 70 29 3b 0a 20 20  ze(pFts, ip);.  
2b80: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 6e 53 63    }.  }..  *pnSc
2b90: 6f 72 65 20 3d 20 6e 53 63 6f 72 65 3b 0a 20 20  ore = nScore;.  
2ba0: 69 66 28 20 70 69 50 6f 73 20 29 7b 0a 20 20 20  if( piPos ){.   
2bb0: 20 69 6e 74 20 69 41 64 6a 20 3d 20 69 46 69 72   int iAdj = iFir
2bc0: 73 74 20 2d 20 28 6e 54 6f 6b 65 6e 20 2d 20 28  st - (nToken - (
2bd0: 69 4c 61 73 74 2d 69 46 69 72 73 74 29 29 20 2f  iLast-iFirst)) /
2be0: 20 32 3b 0a 20 20 20 20 69 66 28 20 28 69 41 64   2;.    if( (iAd
2bf0: 6a 2b 6e 54 6f 6b 65 6e 29 3e 6e 44 6f 63 73 69  j+nToken)>nDocsi
2c00: 7a 65 20 29 20 69 41 64 6a 20 3d 20 6e 44 6f 63  ze ) iAdj = nDoc
2c10: 73 69 7a 65 20 2d 20 6e 54 6f 6b 65 6e 3b 0a 20  size - nToken;. 
2c20: 20 20 20 69 66 28 20 69 41 64 6a 3c 30 20 29 20     if( iAdj<0 ) 
2c30: 69 41 64 6a 20 3d 20 30 3b 0a 20 20 20 20 2a 70  iAdj = 0;.    *p
2c40: 69 50 6f 73 20 3d 20 69 41 64 6a 3b 0a 20 20 7d  iPos = iAdj;.  }
2c50: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
2c60: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
2c70: 68 65 20 76 61 6c 75 65 20 69 6e 20 70 56 61 6c  he value in pVal
2c80: 20 69 6e 74 65 72 70 72 65 74 65 64 20 61 73 20   interpreted as 
2c90: 75 74 66 2d 38 20 74 65 78 74 2e 20 45 78 63 65  utf-8 text. Exce
2ca0: 70 74 2c 20 69 66 20 70 56 61 6c 20 0a 2a 2a 20  pt, if pVal .** 
2cb0: 63 6f 6e 74 61 69 6e 73 20 61 20 4e 55 4c 4c 20  contains a NULL 
2cc0: 76 61 6c 75 65 2c 20 72 65 74 75 72 6e 20 61 20  value, return a 
2cd0: 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 73 74 61  pointer to a sta
2ce0: 74 69 63 20 73 74 72 69 6e 67 20 7a 65 72 6f 0a  tic string zero.
2cf0: 2a 2a 20 62 79 74 65 73 20 69 6e 20 6c 65 6e 67  ** bytes in leng
2d00: 74 68 20 69 6e 73 74 65 61 64 20 6f 66 20 61 20  th instead of a 
2d10: 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2e 0a 2a 2f  NULL pointer..*/
2d20: 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68  .static const ch
2d30: 61 72 20 2a 66 74 73 35 56 61 6c 75 65 54 6f 54  ar *fts5ValueToT
2d40: 65 78 74 28 73 71 6c 69 74 65 33 5f 76 61 6c 75  ext(sqlite3_valu
2d50: 65 20 2a 70 56 61 6c 29 7b 0a 20 20 63 6f 6e 73  e *pVal){.  cons
2d60: 74 20 63 68 61 72 20 2a 7a 52 65 74 20 3d 20 28  t char *zRet = (
2d70: 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69  const char*)sqli
2d80: 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 70  te3_value_text(p
2d90: 56 61 6c 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a  Val);.  return z
2da0: 52 65 74 20 3f 20 7a 52 65 74 20 3a 20 22 22 3b  Ret ? zRet : "";
2db0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
2dc0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 73 6e 69 70  entation of snip
2dd0: 70 65 74 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a  pet() function..
2de0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66  */.static void f
2df0: 74 73 35 53 6e 69 70 70 65 74 46 75 6e 63 74 69  ts5SnippetFuncti
2e00: 6f 6e 28 0a 20 20 63 6f 6e 73 74 20 46 74 73 35  on(.  const Fts5
2e10: 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41  ExtensionApi *pA
2e20: 70 69 2c 20 20 20 2f 2a 20 41 50 49 20 6f 66 66  pi,   /* API off
2e30: 65 72 65 64 20 62 79 20 63 75 72 72 65 6e 74 20  ered by current 
2e40: 46 54 53 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20  FTS version */. 
2e50: 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46   Fts5Context *pF
2e60: 74 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ts,             
2e70: 20 2f 2a 20 46 69 72 73 74 20 61 72 67 20 74 6f   /* First arg to
2e80: 20 70 61 73 73 20 74 6f 20 70 41 70 69 20 66 75   pass to pApi fu
2e90: 6e 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 73 71 6c  nctions */.  sql
2ea0: 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43  ite3_context *pC
2eb0: 74 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  tx,          /* 
2ec0: 43 6f 6e 74 65 78 74 20 66 6f 72 20 72 65 74 75  Context for retu
2ed0: 72 6e 69 6e 67 20 72 65 73 75 6c 74 2f 65 72 72  rning result/err
2ee0: 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 56 61 6c  or */.  int nVal
2ef0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2f00: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
2f10: 72 20 6f 66 20 76 61 6c 75 65 73 20 69 6e 20 61  r of values in a
2f20: 70 56 61 6c 5b 5d 20 61 72 72 61 79 20 2a 2f 0a  pVal[] array */.
2f30: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
2f40: 2a 2a 61 70 56 61 6c 20 20 20 20 20 20 20 20 20  **apVal         
2f50: 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 74 72    /* Array of tr
2f60: 61 69 6c 69 6e 67 20 61 72 67 75 6d 65 6e 74 73  ailing arguments
2f70: 20 2a 2f 0a 29 7b 0a 20 20 48 69 67 68 6c 69 67   */.){.  Highlig
2f80: 68 74 43 6f 6e 74 65 78 74 20 63 74 78 3b 0a 20  htContext ctx;. 
2f90: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
2fa0: 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
2fb0: 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
2fc0: 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 3b 20 20  */.  int iCol;  
2fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2fe0: 20 20 20 20 20 2f 2a 20 31 73 74 20 61 72 67 75       /* 1st argu
2ff0: 6d 65 6e 74 20 74 6f 20 73 6e 69 70 70 65 74 28  ment to snippet(
3000: 29 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  ) */.  const cha
3010: 72 20 2a 7a 45 6c 6c 69 70 73 3b 20 20 20 20 20  r *zEllips;     
3020: 20 20 20 20 20 20 20 2f 2a 20 34 74 68 20 61 72         /* 4th 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 69 6e 74 20 6e 54 6f  t() */.  int nTo
3050: 6b 65 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20  ken;            
3060: 20 20 20 20 20 20 20 20 20 2f 2a 20 35 74 68 20           /* 5th 
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: 49 6e 73 74 20 3d 20 30 3b 20 20 20 20 20 20 20  Inst = 0;       
30a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
30b0: 6d 62 65 72 20 6f 66 20 69 6e 73 74 61 6e 63 65  mber of instance
30c0: 20 6d 61 74 63 68 65 73 20 74 68 69 73 20 72 6f   matches this ro
30d0: 77 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  w */.  int i;   
30e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30f0: 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
3100: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
3110: 68 20 69 6e 73 74 61 6e 63 65 73 20 2a 2f 0a 20  h instances */. 
3120: 20 69 6e 74 20 6e 50 68 72 61 73 65 3b 20 20 20   int nPhrase;   
3130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3140: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 68   /* Number of ph
3150: 72 61 73 65 73 20 69 6e 20 71 75 65 72 79 20 2a  rases in query *
3160: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61  /.  unsigned cha
3170: 72 20 2a 61 53 65 65 6e 3b 20 20 20 20 20 20 20  r *aSeen;       
3180: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20      /* Array of 
3190: 22 73 65 65 6e 20 69 6e 73 74 61 6e 63 65 22 20  "seen instance" 
31a0: 66 6c 61 67 73 20 2a 2f 0a 20 20 69 6e 74 20 69  flags */.  int i
31b0: 42 65 73 74 43 6f 6c 3b 20 20 20 20 20 20 20 20  BestCol;        
31c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
31d0: 6c 75 6d 6e 20 63 6f 6e 74 61 69 6e 69 6e 67 20  lumn containing 
31e0: 62 65 73 74 20 73 6e 69 70 70 65 74 20 2a 2f 0a  best snippet */.
31f0: 20 20 69 6e 74 20 69 42 65 73 74 53 74 61 72 74    int iBestStart
3200: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
3210: 20 20 2f 2a 20 46 69 72 73 74 20 74 6f 6b 65 6e    /* First token
3220: 20 6f 66 20 62 65 73 74 20 73 6e 69 70 70 65 74   of best snippet
3230: 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 65 73 74 53   */.  int nBestS
3240: 63 6f 72 65 20 3d 20 30 3b 20 20 20 20 20 20 20  core = 0;       
3250: 20 20 20 20 20 20 2f 2a 20 53 63 6f 72 65 20 6f        /* Score o
3260: 66 20 62 65 73 74 20 73 6e 69 70 70 65 74 20 2a  f best snippet *
3270: 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 53 69 7a 65  /.  int nColSize
3280: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
3290: 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 73 69 7a      /* Total siz
32a0: 65 20 6f 66 20 69 42 65 73 74 43 6f 6c 20 69 6e  e of iBestCol in
32b0: 20 74 6f 6b 65 6e 73 20 2a 2f 0a 20 20 46 74 73   tokens */.  Fts
32c0: 35 53 46 69 6e 64 65 72 20 73 46 69 6e 64 65 72  5SFinder sFinder
32d0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
32e0: 55 73 65 64 20 74 6f 20 66 69 6e 64 20 74 68 65  Used to find the
32f0: 20 62 65 67 69 6e 6e 69 6e 67 73 20 6f 66 20 73   beginnings of s
3300: 65 6e 74 65 6e 63 65 73 20 2a 2f 0a 20 20 69 6e  entences */.  in
3310: 74 20 6e 43 6f 6c 3b 0a 0a 20 20 69 66 28 20 6e  t nCol;..  if( n
3320: 56 61 6c 21 3d 35 20 29 7b 0a 20 20 20 20 63 6f  Val!=5 ){.    co
3330: 6e 73 74 20 63 68 61 72 20 2a 7a 45 72 72 20 3d  nst char *zErr =
3340: 20 22 77 72 6f 6e 67 20 6e 75 6d 62 65 72 20 6f   "wrong number o
3350: 66 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 66  f arguments to f
3360: 75 6e 63 74 69 6f 6e 20 73 6e 69 70 70 65 74 28  unction snippet(
3370: 29 22 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  )";.    sqlite3_
3380: 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 70 43 74  result_error(pCt
3390: 78 2c 20 7a 45 72 72 2c 20 2d 31 29 3b 0a 20 20  x, zErr, -1);.  
33a0: 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20    return;.  }.. 
33b0: 20 6e 43 6f 6c 20 3d 20 70 41 70 69 2d 3e 78 43   nCol = pApi->xC
33c0: 6f 6c 75 6d 6e 43 6f 75 6e 74 28 70 46 74 73 29  olumnCount(pFts)
33d0: 3b 0a 20 20 6d 65 6d 73 65 74 28 26 63 74 78 2c  ;.  memset(&ctx,
33e0: 20 30 2c 20 73 69 7a 65 6f 66 28 48 69 67 68 6c   0, sizeof(Highl
33f0: 69 67 68 74 43 6f 6e 74 65 78 74 29 29 3b 0a 20  ightContext));. 
3400: 20 69 43 6f 6c 20 3d 20 73 71 6c 69 74 65 33 5f   iCol = sqlite3_
3410: 76 61 6c 75 65 5f 69 6e 74 28 61 70 56 61 6c 5b  value_int(apVal[
3420: 30 5d 29 3b 0a 20 20 63 74 78 2e 7a 4f 70 65 6e  0]);.  ctx.zOpen
3430: 20 3d 20 66 74 73 35 56 61 6c 75 65 54 6f 54 65   = fts5ValueToTe
3440: 78 74 28 61 70 56 61 6c 5b 31 5d 29 3b 0a 20 20  xt(apVal[1]);.  
3450: 63 74 78 2e 7a 43 6c 6f 73 65 20 3d 20 66 74 73  ctx.zClose = fts
3460: 35 56 61 6c 75 65 54 6f 54 65 78 74 28 61 70 56  5ValueToText(apV
3470: 61 6c 5b 32 5d 29 3b 0a 20 20 7a 45 6c 6c 69 70  al[2]);.  zEllip
3480: 73 20 3d 20 66 74 73 35 56 61 6c 75 65 54 6f 54  s = fts5ValueToT
3490: 65 78 74 28 61 70 56 61 6c 5b 33 5d 29 3b 0a 20  ext(apVal[3]);. 
34a0: 20 6e 54 6f 6b 65 6e 20 3d 20 73 71 6c 69 74 65   nToken = sqlite
34b0: 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 70 56 61  3_value_int(apVa
34c0: 6c 5b 34 5d 29 3b 0a 0a 20 20 69 42 65 73 74 43  l[4]);..  iBestC
34d0: 6f 6c 20 3d 20 28 69 43 6f 6c 3e 3d 30 20 3f 20  ol = (iCol>=0 ? 
34e0: 69 43 6f 6c 20 3a 20 30 29 3b 0a 20 20 6e 50 68  iCol : 0);.  nPh
34f0: 72 61 73 65 20 3d 20 70 41 70 69 2d 3e 78 50 68  rase = pApi->xPh
3500: 72 61 73 65 43 6f 75 6e 74 28 70 46 74 73 29 3b  raseCount(pFts);
3510: 0a 20 20 61 53 65 65 6e 20 3d 20 73 71 6c 69 74  .  aSeen = sqlit
3520: 65 33 5f 6d 61 6c 6c 6f 63 28 6e 50 68 72 61 73  e3_malloc(nPhras
3530: 65 29 3b 0a 20 20 69 66 28 20 61 53 65 65 6e 3d  e);.  if( aSeen=
3540: 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  =0 ){.    rc = S
3550: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
3560: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
3570: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
3580: 20 70 41 70 69 2d 3e 78 49 6e 73 74 43 6f 75 6e   pApi->xInstCoun
3590: 74 28 70 46 74 73 2c 20 26 6e 49 6e 73 74 29 3b  t(pFts, &nInst);
35a0: 0a 20 20 7d 0a 0a 20 20 6d 65 6d 73 65 74 28 26  .  }..  memset(&
35b0: 73 46 69 6e 64 65 72 2c 20 30 2c 20 73 69 7a 65  sFinder, 0, size
35c0: 6f 66 28 46 74 73 35 53 46 69 6e 64 65 72 29 29  of(Fts5SFinder))
35d0: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e  ;.  for(i=0; i<n
35e0: 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69  Col; i++){.    i
35f0: 66 28 20 69 43 6f 6c 3c 30 20 7c 7c 20 69 43 6f  f( iCol<0 || iCo
3600: 6c 3d 3d 69 20 29 7b 0a 20 20 20 20 20 20 69 6e  l==i ){.      in
3610: 74 20 6e 44 6f 63 3b 0a 20 20 20 20 20 20 69 6e  t nDoc;.      in
3620: 74 20 6e 44 6f 63 73 69 7a 65 3b 0a 20 20 20 20  t nDocsize;.    
3630: 20 20 69 6e 74 20 69 69 3b 0a 20 20 20 20 20 20    int ii;.      
3640: 73 46 69 6e 64 65 72 2e 69 50 6f 73 20 3d 20 30  sFinder.iPos = 0
3650: 3b 0a 20 20 20 20 20 20 73 46 69 6e 64 65 72 2e  ;.      sFinder.
3660: 6e 46 69 72 73 74 20 3d 20 30 3b 0a 20 20 20 20  nFirst = 0;.    
3670: 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 43 6f    rc = pApi->xCo
3680: 6c 75 6d 6e 54 65 78 74 28 70 46 74 73 2c 20 69  lumnText(pFts, i
3690: 2c 20 26 73 46 69 6e 64 65 72 2e 7a 44 6f 63 2c  , &sFinder.zDoc,
36a0: 20 26 6e 44 6f 63 29 3b 0a 20 20 20 20 20 20 69   &nDoc);.      i
36b0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
36c0: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20   ) break;.      
36d0: 72 63 20 3d 20 70 41 70 69 2d 3e 78 54 6f 6b 65  rc = pApi->xToke
36e0: 6e 69 7a 65 28 70 46 74 73 2c 20 0a 20 20 20 20  nize(pFts, .    
36f0: 20 20 20 20 20 20 73 46 69 6e 64 65 72 2e 7a 44        sFinder.zD
3700: 6f 63 2c 20 6e 44 6f 63 2c 20 28 76 6f 69 64 2a  oc, nDoc, (void*
3710: 29 26 73 46 69 6e 64 65 72 2c 66 74 73 35 53 65  )&sFinder,fts5Se
3720: 6e 74 65 6e 63 65 46 69 6e 64 65 72 43 62 0a 20  ntenceFinderCb. 
3730: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 69 66       );.      if
3740: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
3750: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 72  ) break;.      r
3760: 63 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d  c = pApi->xColum
3770: 6e 53 69 7a 65 28 70 46 74 73 2c 20 69 2c 20 26  nSize(pFts, i, &
3780: 6e 44 6f 63 73 69 7a 65 29 3b 0a 20 20 20 20 20  nDocsize);.     
3790: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
37a0: 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20  OK ) break;..   
37b0: 20 20 20 66 6f 72 28 69 69 3d 30 3b 20 72 63 3d     for(ii=0; rc=
37c0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 69  =SQLITE_OK && ii
37d0: 3c 6e 49 6e 73 74 3b 20 69 69 2b 2b 29 7b 0a 20  <nInst; ii++){. 
37e0: 20 20 20 20 20 20 20 69 6e 74 20 69 70 2c 20 69         int ip, i
37f0: 63 2c 20 69 6f 3b 0a 20 20 20 20 20 20 20 20 69  c, io;.        i
3800: 6e 74 20 69 41 64 6a 3b 0a 20 20 20 20 20 20 20  nt iAdj;.       
3810: 20 69 6e 74 20 6e 53 63 6f 72 65 3b 0a 20 20 20   int nScore;.   
3820: 20 20 20 20 20 69 6e 74 20 6a 6a 3b 0a 0a 20 20       int jj;..  
3830: 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d        rc = pApi-
3840: 3e 78 49 6e 73 74 28 70 46 74 73 2c 20 69 69 2c  >xInst(pFts, ii,
3850: 20 26 69 70 2c 20 26 69 63 2c 20 26 69 6f 29 3b   &ip, &ic, &io);
3860: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 63 21  .        if( ic!
3870: 3d 69 20 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45  =i || rc!=SQLITE
3880: 5f 4f 4b 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a  _OK ) continue;.
3890: 20 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28 61          memset(a
38a0: 53 65 65 6e 2c 20 30 2c 20 6e 50 68 72 61 73 65  Seen, 0, nPhrase
38b0: 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  );.        rc = 
38c0: 66 74 73 35 53 6e 69 70 70 65 74 53 63 6f 72 65  fts5SnippetScore
38d0: 28 70 41 70 69 2c 20 70 46 74 73 2c 20 6e 44 6f  (pApi, pFts, nDo
38e0: 63 73 69 7a 65 2c 20 61 53 65 65 6e 2c 20 69 2c  csize, aSeen, i,
38f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 6f 2c  .            io,
3900: 20 6e 54 6f 6b 65 6e 2c 20 26 6e 53 63 6f 72 65   nToken, &nScore
3910: 2c 20 26 69 41 64 6a 0a 20 20 20 20 20 20 20 20  , &iAdj.        
3920: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72  );.        if( r
3930: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
3940: 6e 53 63 6f 72 65 3e 6e 42 65 73 74 53 63 6f 72  nScore>nBestScor
3950: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6e  e ){.          n
3960: 42 65 73 74 53 63 6f 72 65 20 3d 20 6e 53 63 6f  BestScore = nSco
3970: 72 65 3b 0a 20 20 20 20 20 20 20 20 20 20 69 42  re;.          iB
3980: 65 73 74 43 6f 6c 20 3d 20 69 3b 0a 20 20 20 20  estCol = i;.    
3990: 20 20 20 20 20 20 69 42 65 73 74 53 74 61 72 74        iBestStart
39a0: 20 3d 20 69 41 64 6a 3b 0a 20 20 20 20 20 20 20   = iAdj;.       
39b0: 20 20 20 6e 43 6f 6c 53 69 7a 65 20 3d 20 6e 44     nColSize = nD
39c0: 6f 63 73 69 7a 65 3b 0a 20 20 20 20 20 20 20 20  ocsize;.        
39d0: 7d 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20 72  }..        if( r
39e0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
39f0: 73 46 69 6e 64 65 72 2e 6e 46 69 72 73 74 20 26  sFinder.nFirst &
3a00: 26 20 6e 44 6f 63 73 69 7a 65 3e 6e 54 6f 6b 65  & nDocsize>nToke
3a10: 6e 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 66  n ){.          f
3a20: 6f 72 28 6a 6a 3d 30 3b 20 6a 6a 3c 28 73 46 69  or(jj=0; jj<(sFi
3a30: 6e 64 65 72 2e 6e 46 69 72 73 74 2d 31 29 3b 20  nder.nFirst-1); 
3a40: 6a 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20  jj++){.         
3a50: 20 20 20 69 66 28 20 73 46 69 6e 64 65 72 2e 61     if( sFinder.a
3a60: 46 69 72 73 74 5b 6a 6a 2b 31 5d 3e 69 6f 20 29  First[jj+1]>io )
3a70: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
3a80: 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 69    }..          i
3a90: 66 28 20 73 46 69 6e 64 65 72 2e 61 46 69 72 73  f( sFinder.aFirs
3aa0: 74 5b 6a 6a 5d 3c 69 6f 20 29 7b 0a 20 20 20 20  t[jj]<io ){.    
3ab0: 20 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28 61          memset(a
3ac0: 53 65 65 6e 2c 20 30 2c 20 6e 50 68 72 61 73 65  Seen, 0, nPhrase
3ad0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72  );.            r
3ae0: 63 20 3d 20 66 74 73 35 53 6e 69 70 70 65 74 53  c = fts5SnippetS
3af0: 63 6f 72 65 28 70 41 70 69 2c 20 70 46 74 73 2c  core(pApi, pFts,
3b00: 20 6e 44 6f 63 73 69 7a 65 2c 20 61 53 65 65 6e   nDocsize, aSeen
3b10: 2c 20 69 2c 20 0a 20 20 20 20 20 20 20 20 20 20  , i, .          
3b20: 20 20 20 20 73 46 69 6e 64 65 72 2e 61 46 69 72      sFinder.aFir
3b30: 73 74 5b 6a 6a 5d 2c 20 6e 54 6f 6b 65 6e 2c 20  st[jj], nToken, 
3b40: 26 6e 53 63 6f 72 65 2c 20 30 0a 20 20 20 20 20  &nScore, 0.     
3b50: 20 20 20 20 20 20 20 29 3b 0a 0a 20 20 20 20 20         );..     
3b60: 20 20 20 20 20 20 20 6e 53 63 6f 72 65 20 2b 3d         nScore +=
3b70: 20 28 73 46 69 6e 64 65 72 2e 61 46 69 72 73 74   (sFinder.aFirst
3b80: 5b 6a 6a 5d 3d 3d 30 20 3f 20 31 32 30 20 3a 20  [jj]==0 ? 120 : 
3b90: 31 30 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20  100);.          
3ba0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
3bb0: 5f 4f 4b 20 26 26 20 6e 53 63 6f 72 65 3e 6e 42  _OK && nScore>nB
3bc0: 65 73 74 53 63 6f 72 65 20 29 7b 0a 20 20 20 20  estScore ){.    
3bd0: 20 20 20 20 20 20 20 20 20 20 6e 42 65 73 74 53            nBestS
3be0: 63 6f 72 65 20 3d 20 6e 53 63 6f 72 65 3b 0a 20  core = nScore;. 
3bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 42 65               iBe
3c00: 73 74 43 6f 6c 20 3d 20 69 3b 0a 20 20 20 20 20  stCol = i;.     
3c10: 20 20 20 20 20 20 20 20 20 69 42 65 73 74 53 74           iBestSt
3c20: 61 72 74 20 3d 20 73 46 69 6e 64 65 72 2e 61 46  art = sFinder.aF
3c30: 69 72 73 74 5b 6a 6a 5d 3b 0a 20 20 20 20 20 20  irst[jj];.      
3c40: 20 20 20 20 20 20 20 20 6e 43 6f 6c 53 69 7a 65          nColSize
3c50: 20 3d 20 6e 44 6f 63 73 69 7a 65 3b 0a 20 20 20   = nDocsize;.   
3c60: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
3c70: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
3c80: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3c90: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
3ca0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
3cb0: 63 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d  c = pApi->xColum
3cc0: 6e 54 65 78 74 28 70 46 74 73 2c 20 69 42 65 73  nText(pFts, iBes
3cd0: 74 43 6f 6c 2c 20 26 63 74 78 2e 7a 49 6e 2c 20  tCol, &ctx.zIn, 
3ce0: 26 63 74 78 2e 6e 49 6e 29 3b 0a 20 20 7d 0a 20  &ctx.nIn);.  }. 
3cf0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
3d00: 4f 4b 20 26 26 20 6e 43 6f 6c 53 69 7a 65 3d 3d  OK && nColSize==
3d10: 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 70 41  0 ){.    rc = pA
3d20: 70 69 2d 3e 78 43 6f 6c 75 6d 6e 53 69 7a 65 28  pi->xColumnSize(
3d30: 70 46 74 73 2c 20 69 42 65 73 74 43 6f 6c 2c 20  pFts, iBestCol, 
3d40: 26 6e 43 6f 6c 53 69 7a 65 29 3b 0a 20 20 7d 0a  &nColSize);.  }.
3d50: 20 20 69 66 28 20 63 74 78 2e 7a 49 6e 20 29 7b    if( ctx.zIn ){
3d60: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
3d70: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
3d80: 72 63 20 3d 20 66 74 73 35 43 49 6e 73 74 49 74  rc = fts5CInstIt
3d90: 65 72 49 6e 69 74 28 70 41 70 69 2c 20 70 46 74  erInit(pApi, pFt
3da0: 73 2c 20 69 42 65 73 74 43 6f 6c 2c 20 26 63 74  s, iBestCol, &ct
3db0: 78 2e 69 74 65 72 29 3b 0a 20 20 20 20 7d 0a 0a  x.iter);.    }..
3dc0: 20 20 20 20 63 74 78 2e 69 52 61 6e 67 65 53 74      ctx.iRangeSt
3dd0: 61 72 74 20 3d 20 69 42 65 73 74 53 74 61 72 74  art = iBestStart
3de0: 3b 0a 20 20 20 20 63 74 78 2e 69 52 61 6e 67 65  ;.    ctx.iRange
3df0: 45 6e 64 20 3d 20 69 42 65 73 74 53 74 61 72 74  End = iBestStart
3e00: 20 2b 20 6e 54 6f 6b 65 6e 20 2d 20 31 3b 0a 0a   + nToken - 1;..
3e10: 20 20 20 20 69 66 28 20 69 42 65 73 74 53 74 61      if( iBestSta
3e20: 72 74 3e 30 20 29 7b 0a 20 20 20 20 20 20 66 74  rt>0 ){.      ft
3e30: 73 35 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e  s5HighlightAppen
3e40: 64 28 26 72 63 2c 20 26 63 74 78 2c 20 7a 45 6c  d(&rc, &ctx, zEl
3e50: 6c 69 70 73 2c 20 2d 31 29 3b 0a 20 20 20 20 7d  lips, -1);.    }
3e60: 0a 0a 20 20 20 20 2f 2a 20 41 64 76 61 6e 63 65  ..    /* Advance
3e70: 20 69 74 65 72 61 74 6f 72 20 63 74 78 2e 69 74   iterator ctx.it
3e80: 65 72 20 73 6f 20 74 68 61 74 20 69 74 20 70 6f  er so that it po
3e90: 69 6e 74 73 20 74 6f 20 74 68 65 20 66 69 72 73  ints to the firs
3ea0: 74 20 63 6f 61 6c 65 73 63 65 64 0a 20 20 20 20  t coalesced.    
3eb0: 2a 2a 20 70 68 72 61 73 65 20 69 6e 73 74 61 6e  ** phrase instan
3ec0: 63 65 20 61 74 20 6f 72 20 66 6f 6c 6c 6f 77 69  ce at or followi
3ed0: 6e 67 20 70 6f 73 69 74 69 6f 6e 20 69 42 65 73  ng position iBes
3ee0: 74 53 74 61 72 74 2e 20 2a 2f 0a 20 20 20 20 77  tStart. */.    w
3ef0: 68 69 6c 65 28 20 63 74 78 2e 69 74 65 72 2e 69  hile( ctx.iter.i
3f00: 53 74 61 72 74 3e 3d 30 20 26 26 20 63 74 78 2e  Start>=0 && ctx.
3f10: 69 74 65 72 2e 69 53 74 61 72 74 3c 69 42 65 73  iter.iStart<iBes
3f20: 74 53 74 61 72 74 20 26 26 20 72 63 3d 3d 53 51  tStart && rc==SQ
3f30: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
3f40: 20 72 63 20 3d 20 66 74 73 35 43 49 6e 73 74 49   rc = fts5CInstI
3f50: 74 65 72 4e 65 78 74 28 26 63 74 78 2e 69 74 65  terNext(&ctx.ite
3f60: 72 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69  r);.    }..    i
3f70: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
3f80: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 70   ){.      rc = p
3f90: 41 70 69 2d 3e 78 54 6f 6b 65 6e 69 7a 65 28 70  Api->xTokenize(p
3fa0: 46 74 73 2c 20 63 74 78 2e 7a 49 6e 2c 20 63 74  Fts, ctx.zIn, ct
3fb0: 78 2e 6e 49 6e 2c 20 28 76 6f 69 64 2a 29 26 63  x.nIn, (void*)&c
3fc0: 74 78 2c 66 74 73 35 48 69 67 68 6c 69 67 68 74  tx,fts5Highlight
3fd0: 43 62 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  Cb);.    }.    i
3fe0: 66 28 20 63 74 78 2e 69 52 61 6e 67 65 45 6e 64  f( ctx.iRangeEnd
3ff0: 3e 3d 28 6e 43 6f 6c 53 69 7a 65 2d 31 29 20 29  >=(nColSize-1) )
4000: 7b 0a 20 20 20 20 20 20 66 74 73 35 48 69 67 68  {.      fts5High
4010: 6c 69 67 68 74 41 70 70 65 6e 64 28 26 72 63 2c  lightAppend(&rc,
4020: 20 26 63 74 78 2c 20 26 63 74 78 2e 7a 49 6e 5b   &ctx, &ctx.zIn[
4030: 63 74 78 2e 69 4f 66 66 5d 2c 20 63 74 78 2e 6e  ctx.iOff], ctx.n
4040: 49 6e 20 2d 20 63 74 78 2e 69 4f 66 66 29 3b 0a  In - ctx.iOff);.
4050: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4060: 20 66 74 73 35 48 69 67 68 6c 69 67 68 74 41 70   fts5HighlightAp
4070: 70 65 6e 64 28 26 72 63 2c 20 26 63 74 78 2c 20  pend(&rc, &ctx, 
4080: 7a 45 6c 6c 69 70 73 2c 20 2d 31 29 3b 0a 20 20  zEllips, -1);.  
4090: 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72 63    }.  }.  if( rc
40a0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
40b0: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
40c0: 74 5f 74 65 78 74 28 70 43 74 78 2c 20 28 63 6f  t_text(pCtx, (co
40d0: 6e 73 74 20 63 68 61 72 2a 29 63 74 78 2e 7a 4f  nst char*)ctx.zO
40e0: 75 74 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54  ut, -1, SQLITE_T
40f0: 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 65 6c  RANSIENT);.  }el
4100: 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  se{.    sqlite3_
4110: 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f 63 6f 64  result_error_cod
4120: 65 28 70 43 74 78 2c 20 72 63 29 3b 0a 20 20 7d  e(pCtx, rc);.  }
4130: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
4140: 63 74 78 2e 7a 4f 75 74 29 3b 0a 20 20 73 71 6c  ctx.zOut);.  sql
4150: 69 74 65 33 5f 66 72 65 65 28 61 53 65 65 6e 29  ite3_free(aSeen)
4160: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
4170: 28 73 46 69 6e 64 65 72 2e 61 46 69 72 73 74 29  (sFinder.aFirst)
4180: 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ;.}../**********
4190: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
41a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
41b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
41c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
41d0: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 72 73 74  ./*.** The first
41e0: 20 74 69 6d 65 20 74 68 65 20 62 6d 32 35 28 29   time the bm25()
41f0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
4200: 6c 65 64 20 66 6f 72 20 61 20 71 75 65 72 79 2c  led for a query,
4210: 20 61 6e 20 69 6e 73 74 61 6e 63 65 0a 2a 2a 20   an instance.** 
4220: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
4230: 20 73 74 72 75 63 74 75 72 65 20 69 73 20 61 6c   structure is al
4240: 6c 6f 63 61 74 65 64 20 61 6e 64 20 70 6f 70 75  located and popu
4250: 6c 61 74 65 64 2e 0a 2a 2f 0a 74 79 70 65 64 65  lated..*/.typede
4260: 66 20 73 74 72 75 63 74 20 46 74 73 35 42 6d 32  f struct Fts5Bm2
4270: 35 44 61 74 61 20 46 74 73 35 42 6d 32 35 44 61  5Data Fts5Bm25Da
4280: 74 61 3b 0a 73 74 72 75 63 74 20 46 74 73 35 42  ta;.struct Fts5B
4290: 6d 32 35 44 61 74 61 20 7b 0a 20 20 69 6e 74 20  m25Data {.  int 
42a0: 6e 50 68 72 61 73 65 3b 20 20 20 20 20 20 20 20  nPhrase;        
42b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
42c0: 75 6d 62 65 72 20 6f 66 20 70 68 72 61 73 65 73  umber of phrases
42d0: 20 69 6e 20 71 75 65 72 79 20 2a 2f 0a 20 20 64   in query */.  d
42e0: 6f 75 62 6c 65 20 61 76 67 64 6c 3b 20 20 20 20  ouble avgdl;    
42f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4300: 2a 20 41 76 65 72 61 67 65 20 6e 75 6d 62 65 72  * Average number
4310: 20 6f 66 20 74 6f 6b 65 6e 73 20 69 6e 20 65 61   of tokens in ea
4320: 63 68 20 72 6f 77 20 2a 2f 0a 20 20 64 6f 75 62  ch row */.  doub
4330: 6c 65 20 2a 61 49 44 46 3b 20 20 20 20 20 20 20  le *aIDF;       
4340: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
4350: 44 46 20 66 6f 72 20 65 61 63 68 20 70 68 72 61  DF for each phra
4360: 73 65 20 2a 2f 0a 20 20 64 6f 75 62 6c 65 20 2a  se */.  double *
4370: 61 46 72 65 71 3b 20 20 20 20 20 20 20 20 20 20  aFreq;          
4380: 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79          /* Array
4390: 20 75 73 65 64 20 74 6f 20 63 61 6c 63 75 6c 61   used to calcula
43a0: 74 65 20 70 68 72 61 73 65 20 66 72 65 71 2e 20  te phrase freq. 
43b0: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 43 61 6c  */.};../*.** Cal
43c0: 6c 62 61 63 6b 20 75 73 65 64 20 62 79 20 66 74  lback used by ft
43d0: 73 35 42 6d 32 35 47 65 74 44 61 74 61 28 29 20  s5Bm25GetData() 
43e0: 74 6f 20 63 6f 75 6e 74 20 74 68 65 20 6e 75 6d  to count the num
43f0: 62 65 72 20 6f 66 20 72 6f 77 73 20 69 6e 20 74  ber of rows in t
4400: 68 65 0a 2a 2a 20 74 61 62 6c 65 20 6d 61 74 63  he.** table matc
4410: 68 65 64 20 62 79 20 65 61 63 68 20 69 6e 64 69  hed by each indi
4420: 76 69 64 75 61 6c 20 70 68 72 61 73 65 20 77 69  vidual phrase wi
4430: 74 68 69 6e 20 74 68 65 20 71 75 65 72 79 2e 0a  thin the query..
4440: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
4450: 73 35 43 6f 75 6e 74 43 62 28 0a 20 20 63 6f 6e  s5CountCb(.  con
4460: 73 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f 6e  st Fts5Extension
4470: 41 70 69 20 2a 70 41 70 69 2c 20 0a 20 20 46 74  Api *pApi, .  Ft
4480: 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c  s5Context *pFts,
4490: 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61  .  void *pUserDa
44a0: 74 61 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ta              
44b0: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
44c0: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 76   sqlite3_int64 v
44d0: 61 72 69 61 62 6c 65 20 2a 2f 0a 29 7b 0a 20 20  ariable */.){.  
44e0: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a 70  sqlite3_int64 *p
44f0: 6e 20 3d 20 28 73 71 6c 69 74 65 33 5f 69 6e 74  n = (sqlite3_int
4500: 36 34 2a 29 70 55 73 65 72 44 61 74 61 3b 0a 20  64*)pUserData;. 
4510: 20 55 4e 55 53 45 44 5f 50 41 52 41 4d 32 28 70   UNUSED_PARAM2(p
4520: 41 70 69 2c 20 70 46 74 73 29 3b 0a 20 20 28 2a  Api, pFts);.  (*
4530: 70 6e 29 2b 2b 3b 0a 20 20 72 65 74 75 72 6e 20  pn)++;.  return 
4540: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
4550: 0a 2a 2a 20 53 65 74 20 2a 70 70 44 61 74 61 20  .** Set *ppData 
4560: 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20  to point to the 
4570: 46 74 73 35 42 6d 32 35 44 61 74 61 20 6f 62 6a  Fts5Bm25Data obj
4580: 65 63 74 20 66 6f 72 20 74 68 65 20 63 75 72 72  ect for the curr
4590: 65 6e 74 20 71 75 65 72 79 2e 20 0a 2a 2a 20 49  ent query. .** I
45a0: 66 20 74 68 65 20 6f 62 6a 65 63 74 20 68 61 73  f the object has
45b0: 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 62 65 65   not already bee
45c0: 6e 20 61 6c 6c 6f 63 61 74 65 64 2c 20 61 6c 6c  n allocated, all
45d0: 6f 63 61 74 65 20 61 6e 64 20 70 6f 70 75 6c 61  ocate and popula
45e0: 74 65 20 69 74 0a 2a 2a 20 6e 6f 77 2e 0a 2a 2f  te it.** now..*/
45f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
4600: 42 6d 32 35 47 65 74 44 61 74 61 28 0a 20 20 63  Bm25GetData(.  c
4610: 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73 69  onst Fts5Extensi
4620: 6f 6e 41 70 69 20 2a 70 41 70 69 2c 20 0a 20 20  onApi *pApi, .  
4630: 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74  Fts5Context *pFt
4640: 73 2c 0a 20 20 46 74 73 35 42 6d 32 35 44 61 74  s,.  Fts5Bm25Dat
4650: 61 20 2a 2a 70 70 44 61 74 61 20 20 20 20 20 20  a **ppData      
4660: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 62 6d 32       /* OUT: bm2
4670: 35 2d 64 61 74 61 20 6f 62 6a 65 63 74 20 66 6f  5-data object fo
4680: 72 20 74 68 69 73 20 71 75 65 72 79 20 2a 2f 0a  r this query */.
4690: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
46a0: 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20  LITE_OK;        
46b0: 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
46c0: 6f 64 65 20 2a 2f 0a 20 20 46 74 73 35 42 6d 32  ode */.  Fts5Bm2
46d0: 35 44 61 74 61 20 2a 70 3b 20 20 20 20 20 20 20  5Data *p;       
46e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65           /* Obje
46f0: 63 74 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f 0a  ct to return */.
4700: 0a 20 20 70 20 3d 20 70 41 70 69 2d 3e 78 47 65  .  p = pApi->xGe
4710: 74 41 75 78 64 61 74 61 28 70 46 74 73 2c 20 30  tAuxdata(pFts, 0
4720: 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 7b  );.  if( p==0 ){
4730: 0a 20 20 20 20 69 6e 74 20 6e 50 68 72 61 73 65  .    int nPhrase
4740: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4750: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
4760: 70 68 72 61 73 65 73 20 69 6e 20 71 75 65 72 79  phrases in query
4770: 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   */.    sqlite3_
4780: 69 6e 74 36 34 20 6e 52 6f 77 20 3d 20 30 3b 20  int64 nRow = 0; 
4790: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
47a0: 6f 66 20 72 6f 77 73 20 69 6e 20 74 61 62 6c 65  of rows in table
47b0: 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   */.    sqlite3_
47c0: 69 6e 74 36 34 20 6e 54 6f 6b 65 6e 20 3d 20 30  int64 nToken = 0
47d0: 3b 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20  ;     /* Number 
47e0: 6f 66 20 74 6f 6b 65 6e 73 20 69 6e 20 74 61 62  of tokens in tab
47f0: 6c 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 42  le */.    int nB
4800: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
4810: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
4820: 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c   of space to all
4830: 6f 63 61 74 65 20 2a 2f 0a 20 20 20 20 69 6e 74  ocate */.    int
4840: 20 69 3b 0a 0a 20 20 20 20 2f 2a 20 41 6c 6c 6f   i;..    /* Allo
4850: 63 61 74 65 20 74 68 65 20 46 74 73 35 42 6d 32  cate the Fts5Bm2
4860: 35 44 61 74 61 20 6f 62 6a 65 63 74 20 2a 2f 0a  5Data object */.
4870: 20 20 20 20 6e 50 68 72 61 73 65 20 3d 20 70 41      nPhrase = pA
4880: 70 69 2d 3e 78 50 68 72 61 73 65 43 6f 75 6e 74  pi->xPhraseCount
4890: 28 70 46 74 73 29 3b 0a 20 20 20 20 6e 42 79 74  (pFts);.    nByt
48a0: 65 20 3d 20 73 69 7a 65 6f 66 28 46 74 73 35 42  e = sizeof(Fts5B
48b0: 6d 32 35 44 61 74 61 29 20 2b 20 6e 50 68 72 61  m25Data) + nPhra
48c0: 73 65 2a 32 2a 73 69 7a 65 6f 66 28 64 6f 75 62  se*2*sizeof(doub
48d0: 6c 65 29 3b 0a 20 20 20 20 70 20 3d 20 28 46 74  le);.    p = (Ft
48e0: 73 35 42 6d 32 35 44 61 74 61 2a 29 73 71 6c 69  s5Bm25Data*)sqli
48f0: 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65  te3_malloc(nByte
4900: 29 3b 0a 20 20 20 20 69 66 28 20 70 3d 3d 30 20  );.    if( p==0 
4910: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  ){.      rc = SQ
4920: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
4930: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6d 65 6d  }else{.      mem
4940: 73 65 74 28 70 2c 20 30 2c 20 6e 42 79 74 65 29  set(p, 0, nByte)
4950: 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 50 68 72 61  ;.      p->nPhra
4960: 73 65 20 3d 20 6e 50 68 72 61 73 65 3b 0a 20 20  se = nPhrase;.  
4970: 20 20 20 20 70 2d 3e 61 49 44 46 20 3d 20 28 64      p->aIDF = (d
4980: 6f 75 62 6c 65 2a 29 26 70 5b 31 5d 3b 0a 20 20  ouble*)&p[1];.  
4990: 20 20 20 20 70 2d 3e 61 46 72 65 71 20 3d 20 26      p->aFreq = &
49a0: 70 2d 3e 61 49 44 46 5b 6e 50 68 72 61 73 65 5d  p->aIDF[nPhrase]
49b0: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
49c0: 43 61 6c 63 75 6c 61 74 65 20 74 68 65 20 61 76  Calculate the av
49d0: 65 72 61 67 65 20 64 6f 63 75 6d 65 6e 74 20 6c  erage document l
49e0: 65 6e 67 74 68 20 66 6f 72 20 74 68 69 73 20 46  ength for this F
49f0: 54 53 35 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20  TS5 table */.   
4a00: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
4a10: 4f 4b 20 29 20 72 63 20 3d 20 70 41 70 69 2d 3e  OK ) rc = pApi->
4a20: 78 52 6f 77 43 6f 75 6e 74 28 70 46 74 73 2c 20  xRowCount(pFts, 
4a30: 26 6e 52 6f 77 29 3b 0a 20 20 20 20 69 66 28 20  &nRow);.    if( 
4a40: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc==SQLITE_OK ) 
4a50: 72 63 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75  rc = pApi->xColu
4a60: 6d 6e 54 6f 74 61 6c 53 69 7a 65 28 70 46 74 73  mnTotalSize(pFts
4a70: 2c 20 2d 31 2c 20 26 6e 54 6f 6b 65 6e 29 3b 0a  , -1, &nToken);.
4a80: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
4a90: 54 45 5f 4f 4b 20 29 20 70 2d 3e 61 76 67 64 6c  TE_OK ) p->avgdl
4aa0: 20 3d 20 28 64 6f 75 62 6c 65 29 6e 54 6f 6b 65   = (double)nToke
4ab0: 6e 20 20 2f 20 28 64 6f 75 62 6c 65 29 6e 52 6f  n  / (double)nRo
4ac0: 77 3b 0a 0a 20 20 20 20 2f 2a 20 43 61 6c 63 75  w;..    /* Calcu
4ad0: 6c 61 74 65 20 61 6e 20 49 44 46 20 66 6f 72 20  late an IDF for 
4ae0: 65 61 63 68 20 70 68 72 61 73 65 20 69 6e 20 74  each phrase in t
4af0: 68 65 20 71 75 65 72 79 20 2a 2f 0a 20 20 20 20  he query */.    
4b00: 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c  for(i=0; rc==SQL
4b10: 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 50 68 72  ITE_OK && i<nPhr
4b20: 61 73 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  ase; i++){.     
4b30: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 6e   sqlite3_int64 n
4b40: 48 69 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 72  Hit = 0;.      r
4b50: 63 20 3d 20 70 41 70 69 2d 3e 78 51 75 65 72 79  c = pApi->xQuery
4b60: 50 68 72 61 73 65 28 70 46 74 73 2c 20 69 2c 20  Phrase(pFts, i, 
4b70: 28 76 6f 69 64 2a 29 26 6e 48 69 74 2c 20 66 74  (void*)&nHit, ft
4b80: 73 35 43 6f 75 6e 74 43 62 29 3b 0a 20 20 20 20  s5CountCb);.    
4b90: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
4ba0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 2f  _OK ){.        /
4bb0: 2a 20 43 61 6c 63 75 6c 61 74 65 20 74 68 65 20  * Calculate the 
4bc0: 49 44 46 20 28 49 6e 76 65 72 73 65 20 44 6f 63  IDF (Inverse Doc
4bd0: 75 6d 65 6e 74 20 46 72 65 71 75 65 6e 63 79 29  ument Frequency)
4be0: 20 66 6f 72 20 70 68 72 61 73 65 20 69 2e 0a 20   for phrase i.. 
4bf0: 20 20 20 20 20 20 20 2a 2a 20 54 68 69 73 20 69         ** This i
4c00: 73 20 64 6f 6e 65 20 75 73 69 6e 67 20 74 68 65  s done using the
4c10: 20 73 74 61 6e 64 61 72 64 20 42 4d 32 35 20 66   standard BM25 f
4c20: 6f 72 6d 75 6c 61 20 61 73 20 66 6f 75 6e 64 20  ormula as found 
4c30: 6f 6e 20 77 69 6b 69 70 65 64 69 61 3a 0a 20 20  on wikipedia:.  
4c40: 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20        **.       
4c50: 20 2a 2a 20 20 20 49 44 46 20 3d 20 6c 6f 67 28   **   IDF = log(
4c60: 20 28 4e 20 2d 20 6e 48 69 74 20 2b 20 30 2e 35   (N - nHit + 0.5
4c70: 29 20 2f 20 28 6e 48 69 74 20 2b 20 30 2e 35 29  ) / (nHit + 0.5)
4c80: 20 29 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20   ).        **.  
4c90: 20 20 20 20 20 20 2a 2a 20 77 68 65 72 65 20 22        ** where "
4ca0: 4e 22 20 69 73 20 74 68 65 20 74 6f 74 61 6c 20  N" is the total 
4cb0: 6e 75 6d 62 65 72 20 6f 66 20 64 6f 63 75 6d 65  number of docume
4cc0: 6e 74 73 20 69 6e 20 74 68 65 20 73 65 74 20 61  nts in the set a
4cd0: 6e 64 20 6e 48 69 74 0a 20 20 20 20 20 20 20 20  nd nHit.        
4ce0: 2a 2a 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72  ** is the number
4cf0: 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 20 61 74   that contain at
4d00: 20 6c 65 61 73 74 20 6f 6e 65 20 69 6e 73 74 61   least one insta
4d10: 6e 63 65 20 6f 66 20 74 68 65 20 70 68 72 61 73  nce of the phras
4d20: 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 75 6e 64  e.        ** und
4d30: 65 72 20 63 6f 6e 73 69 64 65 72 61 74 69 6f 6e  er consideration
4d40: 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20 20  ..        **.   
4d50: 20 20 20 20 20 2a 2a 20 54 68 65 20 70 72 6f 62       ** The prob
4d60: 6c 65 6d 20 77 69 74 68 20 74 68 69 73 20 69 73  lem with this is
4d70: 20 74 68 61 74 20 69 66 20 28 4e 20 3c 20 32 2a   that if (N < 2*
4d80: 6e 48 69 74 29 2c 20 74 68 65 20 49 44 46 20 69  nHit), the IDF i
4d90: 73 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 6e 65  s .        ** ne
4da0: 67 61 74 69 76 65 2e 20 57 68 69 63 68 20 69 73  gative. Which is
4db0: 20 75 6e 64 65 73 69 72 61 62 6c 65 2e 20 53 6f   undesirable. So
4dc0: 20 74 68 65 20 6d 69 6d 69 6d 75 6d 20 61 6c 6c   the mimimum all
4dd0: 6f 77 61 62 6c 65 20 49 44 46 20 69 73 0a 20 20  owable IDF is.  
4de0: 20 20 20 20 20 20 2a 2a 20 28 31 65 2d 36 29 20        ** (1e-6) 
4df0: 2d 20 72 6f 75 67 68 6c 79 20 74 68 65 20 73 61  - roughly the sa
4e00: 6d 65 20 61 73 20 61 20 74 65 72 6d 20 74 68 61  me as a term tha
4e10: 74 20 61 70 70 65 61 72 73 20 69 6e 20 6a 75 73  t appears in jus
4e20: 74 20 6f 76 65 72 0a 20 20 20 20 20 20 20 20 2a  t over.        *
4e30: 2a 20 68 61 6c 66 20 6f 66 20 73 65 74 20 6f 66  * half of set of
4e40: 20 35 2c 30 30 30 2c 30 30 30 20 64 6f 63 75 6d   5,000,000 docum
4e50: 65 6e 74 73 2e 20 20 2a 2f 0a 20 20 20 20 20 20  ents.  */.      
4e60: 20 20 64 6f 75 62 6c 65 20 69 64 66 20 3d 20 6c    double idf = l
4e70: 6f 67 28 20 28 6e 52 6f 77 20 2d 20 6e 48 69 74  og( (nRow - nHit
4e80: 20 2b 20 30 2e 35 29 20 2f 20 28 6e 48 69 74 20   + 0.5) / (nHit 
4e90: 2b 20 30 2e 35 29 20 29 3b 0a 20 20 20 20 20 20  + 0.5) );.      
4ea0: 20 20 69 66 28 20 69 64 66 3c 3d 30 2e 30 20 29    if( idf<=0.0 )
4eb0: 20 69 64 66 20 3d 20 31 65 2d 36 3b 0a 20 20 20   idf = 1e-6;.   
4ec0: 20 20 20 20 20 70 2d 3e 61 49 44 46 5b 69 5d 20       p->aIDF[i] 
4ed0: 3d 20 69 64 66 3b 0a 20 20 20 20 20 20 7d 0a 20  = idf;.      }. 
4ee0: 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63     }..    if( rc
4ef0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
4f00: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65       sqlite3_fre
4f10: 65 28 70 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  e(p);.    }else{
4f20: 0a 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 69  .      rc = pApi
4f30: 2d 3e 78 53 65 74 41 75 78 64 61 74 61 28 70 46  ->xSetAuxdata(pF
4f40: 74 73 2c 20 70 2c 20 73 71 6c 69 74 65 33 5f 66  ts, p, sqlite3_f
4f50: 72 65 65 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  ree);.    }.    
4f60: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
4f70: 4b 20 29 20 70 20 3d 20 30 3b 0a 20 20 7d 0a 20  K ) p = 0;.  }. 
4f80: 20 2a 70 70 44 61 74 61 20 3d 20 70 3b 0a 20 20   *ppData = p;.  
4f90: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
4fa0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
4fb0: 6f 6e 20 6f 66 20 62 6d 32 35 28 29 20 66 75 6e  on of bm25() fun
4fc0: 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  ction..*/.static
4fd0: 20 76 6f 69 64 20 66 74 73 35 42 6d 32 35 46 75   void fts5Bm25Fu
4fe0: 6e 63 74 69 6f 6e 28 0a 20 20 63 6f 6e 73 74 20  nction(.  const 
4ff0: 46 74 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69  Fts5ExtensionApi
5000: 20 2a 70 41 70 69 2c 20 20 20 2f 2a 20 41 50 49   *pApi,   /* API
5010: 20 6f 66 66 65 72 65 64 20 62 79 20 63 75 72 72   offered by curr
5020: 65 6e 74 20 46 54 53 20 76 65 72 73 69 6f 6e 20  ent FTS version 
5030: 2a 2f 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74  */.  Fts5Context
5040: 20 2a 70 46 74 73 2c 20 20 20 20 20 20 20 20 20   *pFts,         
5050: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72       /* First ar
5060: 67 20 74 6f 20 70 61 73 73 20 74 6f 20 70 41 70  g to pass to pAp
5070: 69 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 20  i functions */. 
5080: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
5090: 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20   *pCtx,         
50a0: 20 2f 2a 20 43 6f 6e 74 65 78 74 20 66 6f 72 20   /* Context for 
50b0: 72 65 74 75 72 6e 69 6e 67 20 72 65 73 75 6c 74  returning result
50c0: 2f 65 72 72 6f 72 20 2a 2f 0a 20 20 69 6e 74 20  /error */.  int 
50d0: 6e 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  nVal,           
50e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
50f0: 75 6d 62 65 72 20 6f 66 20 76 61 6c 75 65 73 20  umber of values 
5100: 69 6e 20 61 70 56 61 6c 5b 5d 20 61 72 72 61 79  in apVal[] array
5110: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61   */.  sqlite3_va
5120: 6c 75 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20  lue **apVal     
5130: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
5140: 66 20 74 72 61 69 6c 69 6e 67 20 61 72 67 75 6d  f trailing argum
5150: 65 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e  ents */.){.  con
5160: 73 74 20 64 6f 75 62 6c 65 20 6b 31 20 3d 20 31  st double k1 = 1
5170: 2e 32 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20  .2;          /* 
5180: 43 6f 6e 73 74 61 6e 74 20 22 6b 31 22 20 66 72  Constant "k1" fr
5190: 6f 6d 20 42 4d 32 35 20 66 6f 72 6d 75 6c 61 20  om BM25 formula 
51a0: 2a 2f 0a 20 20 63 6f 6e 73 74 20 64 6f 75 62 6c  */.  const doubl
51b0: 65 20 62 20 3d 20 30 2e 37 35 3b 20 20 20 20 20  e b = 0.75;     
51c0: 20 20 20 20 20 2f 2a 20 43 6f 6e 73 74 61 6e 74       /* Constant
51d0: 20 22 62 22 20 66 72 6f 6d 20 42 4d 32 35 20 66   "b" from BM25 f
51e0: 6f 72 6d 75 6c 61 20 2a 2f 0a 20 20 69 6e 74 20  ormula */.  int 
51f0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
5200: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45              /* E
5210: 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 20 20 64  rror code */.  d
5220: 6f 75 62 6c 65 20 73 63 6f 72 65 20 3d 20 30 2e  ouble score = 0.
5230: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  0;             /
5240: 2a 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e 20 72  * SQL function r
5250: 65 74 75 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 20  eturn value */. 
5260: 20 46 74 73 35 42 6d 32 35 44 61 74 61 20 2a 70   Fts5Bm25Data *p
5270: 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
5280: 20 2f 2a 20 56 61 6c 75 65 73 20 61 6c 6c 6f 63   /* Values alloc
5290: 61 74 65 64 2f 63 61 6c 63 75 6c 61 74 65 64 20  ated/calculated 
52a0: 6f 6e 63 65 20 6f 6e 6c 79 20 2a 2f 0a 20 20 69  once only */.  i
52b0: 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20  nt i;           
52c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
52d0: 2a 20 49 74 65 72 61 74 6f 72 20 76 61 72 69 61  * Iterator varia
52e0: 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 6e  ble */.  int nIn
52f0: 73 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  st = 0;         
5300: 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75           /* Valu
5310: 65 20 72 65 74 75 72 6e 65 64 20 62 79 20 78 49  e returned by xI
5320: 6e 73 74 43 6f 75 6e 74 28 29 20 2a 2f 0a 20 20  nstCount() */.  
5330: 64 6f 75 62 6c 65 20 44 20 3d 20 30 2e 30 3b 20  double D = 0.0; 
5340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5350: 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20  /* Total number 
5360: 6f 66 20 74 6f 6b 65 6e 73 20 69 6e 20 72 6f 77  of tokens in row
5370: 20 2a 2f 0a 20 20 64 6f 75 62 6c 65 20 2a 61 46   */.  double *aF
5380: 72 65 71 20 3d 20 30 3b 20 20 20 20 20 20 20 20  req = 0;        
5390: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
53a0: 66 20 70 68 72 61 73 65 20 66 72 65 71 2e 20 66  f phrase freq. f
53b0: 6f 72 20 63 75 72 72 65 6e 74 20 72 6f 77 20 2a  or current row *
53c0: 2f 0a 0a 20 20 2f 2a 20 43 61 6c 63 75 6c 61 74  /..  /* Calculat
53d0: 65 20 74 68 65 20 70 68 72 61 73 65 20 66 72 65  e the phrase fre
53e0: 71 75 65 6e 63 79 20 28 73 79 6d 62 6f 6c 20 22  quency (symbol "
53f0: 66 28 71 69 2c 44 29 22 20 69 6e 20 74 68 65 20  f(qi,D)" in the 
5400: 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 29 0a 20  documentation). 
5410: 20 2a 2a 20 66 6f 72 20 65 61 63 68 20 70 68 72   ** for each phr
5420: 61 73 65 20 69 6e 20 74 68 65 20 71 75 65 72 79  ase in the query
5430: 20 66 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74   for the current
5440: 20 72 6f 77 2e 20 2a 2f 0a 20 20 72 63 20 3d 20   row. */.  rc = 
5450: 66 74 73 35 42 6d 32 35 47 65 74 44 61 74 61 28  fts5Bm25GetData(
5460: 70 41 70 69 2c 20 70 46 74 73 2c 20 26 70 44 61  pApi, pFts, &pDa
5470: 74 61 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  ta);.  if( rc==S
5480: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
5490: 61 46 72 65 71 20 3d 20 70 44 61 74 61 2d 3e 61  aFreq = pData->a
54a0: 46 72 65 71 3b 0a 20 20 20 20 6d 65 6d 73 65 74  Freq;.    memset
54b0: 28 61 46 72 65 71 2c 20 30 2c 20 73 69 7a 65 6f  (aFreq, 0, sizeo
54c0: 66 28 64 6f 75 62 6c 65 29 20 2a 20 70 44 61 74  f(double) * pDat
54d0: 61 2d 3e 6e 50 68 72 61 73 65 29 3b 0a 20 20 20  a->nPhrase);.   
54e0: 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 49 6e 73   rc = pApi->xIns
54f0: 74 43 6f 75 6e 74 28 70 46 74 73 2c 20 26 6e 49  tCount(pFts, &nI
5500: 6e 73 74 29 3b 0a 20 20 7d 0a 20 20 66 6f 72 28  nst);.  }.  for(
5510: 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f  i=0; rc==SQLITE_
5520: 4f 4b 20 26 26 20 69 3c 6e 49 6e 73 74 3b 20 69  OK && i<nInst; i
5530: 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20 69 70 3b  ++){.    int ip;
5540: 20 69 6e 74 20 69 63 3b 20 69 6e 74 20 69 6f 3b   int ic; int io;
5550: 0a 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e  .    rc = pApi->
5560: 78 49 6e 73 74 28 70 46 74 73 2c 20 69 2c 20 26  xInst(pFts, i, &
5570: 69 70 2c 20 26 69 63 2c 20 26 69 6f 29 3b 0a 20  ip, &ic, &io);. 
5580: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
5590: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 64 6f  E_OK ){.      do
55a0: 75 62 6c 65 20 77 20 3d 20 28 6e 56 61 6c 20 3e  uble w = (nVal >
55b0: 20 69 63 29 20 3f 20 73 71 6c 69 74 65 33 5f 76   ic) ? sqlite3_v
55c0: 61 6c 75 65 5f 64 6f 75 62 6c 65 28 61 70 56 61  alue_double(apVa
55d0: 6c 5b 69 63 5d 29 20 3a 20 31 2e 30 3b 0a 20 20  l[ic]) : 1.0;.  
55e0: 20 20 20 20 61 46 72 65 71 5b 69 70 5d 20 2b 3d      aFreq[ip] +=
55f0: 20 77 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20   w;.    }.  }.. 
5600: 20 2f 2a 20 46 69 67 75 72 65 20 6f 75 74 20 74   /* Figure out t
5610: 68 65 20 74 6f 74 61 6c 20 73 69 7a 65 20 6f 66  he total size of
5620: 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 6f 77   the current row
5630: 20 69 6e 20 74 6f 6b 65 6e 73 2e 20 2a 2f 0a 20   in tokens. */. 
5640: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
5650: 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 54  OK ){.    int nT
5660: 6f 6b 3b 0a 20 20 20 20 72 63 20 3d 20 70 41 70  ok;.    rc = pAp
5670: 69 2d 3e 78 43 6f 6c 75 6d 6e 53 69 7a 65 28 70  i->xColumnSize(p
5680: 46 74 73 2c 20 2d 31 2c 20 26 6e 54 6f 6b 29 3b  Fts, -1, &nTok);
5690: 0a 20 20 20 20 44 20 3d 20 28 64 6f 75 62 6c 65  .    D = (double
56a0: 29 6e 54 6f 6b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  )nTok;.  }..  /*
56b0: 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65 20 42   Determine the B
56c0: 4d 32 35 20 73 63 6f 72 65 20 66 6f 72 20 74 68  M25 score for th
56d0: 65 20 63 75 72 72 65 6e 74 20 72 6f 77 2e 20 2a  e current row. *
56e0: 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d  /.  for(i=0; rc=
56f0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c  =SQLITE_OK && i<
5700: 70 44 61 74 61 2d 3e 6e 50 68 72 61 73 65 3b 20  pData->nPhrase; 
5710: 69 2b 2b 29 7b 0a 20 20 20 20 73 63 6f 72 65 20  i++){.    score 
5720: 2b 3d 20 70 44 61 74 61 2d 3e 61 49 44 46 5b 69  += pData->aIDF[i
5730: 5d 20 2a 20 28 0a 20 20 20 20 20 20 28 20 61 46  ] * (.      ( aF
5740: 72 65 71 5b 69 5d 20 2a 20 28 6b 31 20 2b 20 31  req[i] * (k1 + 1
5750: 2e 30 29 20 29 20 2f 20 0a 20 20 20 20 20 20 28  .0) ) / .      (
5760: 20 61 46 72 65 71 5b 69 5d 20 2b 20 6b 31 20 2a   aFreq[i] + k1 *
5770: 20 28 31 20 2d 20 62 20 2b 20 62 20 2a 20 44 20   (1 - b + b * D 
5780: 2f 20 70 44 61 74 61 2d 3e 61 76 67 64 6c 29 20  / pData->avgdl) 
5790: 29 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 20 20 0a  ).    );.  }.  .
57a0: 20 20 2f 2a 20 49 66 20 6e 6f 20 65 72 72 6f 72    /* If no error
57b0: 20 68 61 73 20 6f 63 63 75 72 72 65 64 2c 20 72   has occurred, r
57c0: 65 74 75 72 6e 20 74 68 65 20 63 61 6c 63 75 6c  eturn the calcul
57d0: 61 74 65 64 20 73 63 6f 72 65 2e 20 4f 74 68 65  ated score. Othe
57e0: 72 77 69 73 65 2c 0a 20 20 2a 2a 20 74 68 72 6f  rwise,.  ** thro
57f0: 77 20 61 6e 20 53 51 4c 20 65 78 63 65 70 74 69  w an SQL excepti
5800: 6f 6e 2e 20 20 2a 2f 0a 20 20 69 66 28 20 72 63  on.  */.  if( rc
5810: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
5820: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
5830: 74 5f 64 6f 75 62 6c 65 28 70 43 74 78 2c 20 2d  t_double(pCtx, -
5840: 31 2e 30 20 2a 20 73 63 6f 72 65 29 3b 0a 20 20  1.0 * score);.  
5850: 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74  }else{.    sqlit
5860: 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f  e3_result_error_
5870: 63 6f 64 65 28 70 43 74 78 2c 20 72 63 29 3b 0a  code(pCtx, rc);.
5880: 20 20 7d 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74    }.}..int sqlit
5890: 65 33 46 74 73 35 41 75 78 49 6e 69 74 28 66 74  e3Fts5AuxInit(ft
58a0: 73 35 5f 61 70 69 20 2a 70 41 70 69 29 7b 0a 20  s5_api *pApi){. 
58b0: 20 73 74 72 75 63 74 20 42 75 69 6c 74 69 6e 20   struct Builtin 
58c0: 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  {.    const char
58d0: 20 2a 7a 46 75 6e 63 3b 20 20 20 20 20 20 20 20   *zFunc;        
58e0: 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20      /* Function 
58f0: 6e 61 6d 65 20 28 6e 75 6c 2d 74 65 72 6d 69 6e  name (nul-termin
5900: 61 74 65 64 29 20 2a 2f 0a 20 20 20 20 76 6f 69  ated) */.    voi
5910: 64 20 2a 70 55 73 65 72 44 61 74 61 3b 20 20 20  d *pUserData;   
5920: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
5930: 65 72 2d 64 61 74 61 20 70 6f 69 6e 74 65 72 20  er-data pointer 
5940: 2a 2f 0a 20 20 20 20 66 74 73 35 5f 65 78 74 65  */.    fts5_exte
5950: 6e 73 69 6f 6e 5f 66 75 6e 63 74 69 6f 6e 20 78  nsion_function x
5960: 46 75 6e 63 3b 2f 2a 20 43 61 6c 6c 62 61 63 6b  Func;/* Callback
5970: 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 20   function */.   
5980: 20 76 6f 69 64 20 28 2a 78 44 65 73 74 72 6f 79   void (*xDestroy
5990: 29 28 76 6f 69 64 2a 29 3b 20 20 20 20 20 20 2f  )(void*);      /
59a0: 2a 20 44 65 73 74 72 75 63 74 6f 72 20 66 75 6e  * Destructor fun
59b0: 63 74 69 6f 6e 20 2a 2f 0a 20 20 7d 20 61 42 75  ction */.  } aBu
59c0: 69 6c 74 69 6e 20 5b 5d 20 3d 20 7b 0a 20 20 20  iltin [] = {.   
59d0: 20 7b 20 22 73 6e 69 70 70 65 74 22 2c 20 20 20   { "snippet",   
59e0: 30 2c 20 66 74 73 35 53 6e 69 70 70 65 74 46 75  0, fts5SnippetFu
59f0: 6e 63 74 69 6f 6e 2c 20 30 20 7d 2c 0a 20 20 20  nction, 0 },.   
5a00: 20 7b 20 22 68 69 67 68 6c 69 67 68 74 22 2c 20   { "highlight", 
5a10: 30 2c 20 66 74 73 35 48 69 67 68 6c 69 67 68 74  0, fts5Highlight
5a20: 46 75 6e 63 74 69 6f 6e 2c 20 30 20 7d 2c 0a 20  Function, 0 },. 
5a30: 20 20 20 7b 20 22 62 6d 32 35 22 2c 20 20 20 20     { "bm25",    
5a40: 20 20 30 2c 20 66 74 73 35 42 6d 32 35 46 75 6e    0, fts5Bm25Fun
5a50: 63 74 69 6f 6e 2c 20 20 20 20 30 20 7d 2c 0a 20  ction,    0 },. 
5a60: 20 7d 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   };.  int rc = S
5a70: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
5a80: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
5a90: 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b  code */.  int i;
5aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ab0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 20            /* To 
5ac0: 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20  iterate through 
5ad0: 62 75 69 6c 74 69 6e 20 66 75 6e 63 74 69 6f 6e  builtin function
5ae0: 73 20 2a 2f 0a 0a 20 20 66 6f 72 28 69 3d 30 3b  s */..  for(i=0;
5af0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
5b00: 26 20 69 3c 41 72 72 61 79 53 69 7a 65 28 61 42  & i<ArraySize(aB
5b10: 75 69 6c 74 69 6e 29 3b 20 69 2b 2b 29 7b 0a 20  uiltin); i++){. 
5b20: 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 43     rc = pApi->xC
5b30: 72 65 61 74 65 46 75 6e 63 74 69 6f 6e 28 70 41  reateFunction(pA
5b40: 70 69 2c 0a 20 20 20 20 20 20 20 20 61 42 75 69  pi,.        aBui
5b50: 6c 74 69 6e 5b 69 5d 2e 7a 46 75 6e 63 2c 0a 20  ltin[i].zFunc,. 
5b60: 20 20 20 20 20 20 20 61 42 75 69 6c 74 69 6e 5b         aBuiltin[
5b70: 69 5d 2e 70 55 73 65 72 44 61 74 61 2c 0a 20 20  i].pUserData,.  
5b80: 20 20 20 20 20 20 61 42 75 69 6c 74 69 6e 5b 69        aBuiltin[i
5b90: 5d 2e 78 46 75 6e 63 2c 0a 20 20 20 20 20 20 20  ].xFunc,.       
5ba0: 20 61 42 75 69 6c 74 69 6e 5b 69 5d 2e 78 44 65   aBuiltin[i].xDe
5bb0: 73 74 72 6f 79 0a 20 20 20 20 29 3b 0a 20 20 7d  stroy.    );.  }
5bc0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
5bd0: 0a 0a 0a                                         ...