0000: 2f 2a 0a 2a 2a 20 32 30 31 34 20 4d 61 79 20 33 /*.** 2014 May 3
0010: 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 1.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 ource code. In
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 **.** May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 evil..** May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 thers..** May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 y, never taking
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a ve..**.*********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2f 0a 0a 0a 23 69 6e 63 6c *****.*/...#incl
0180: 75 64 65 20 22 66 74 73 35 49 6e 74 2e 68 22 0a ude "fts5Int.h".
0190: 23 69 6e 63 6c 75 64 65 20 3c 6d 61 74 68 2e 68 #include <math.h
01a0: 3e 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 >
01b0: 20 20 2f 2a 20 61 6d 61 6c 67 61 6d 61 74 6f 72 /* amalgamator
01c0: 3a 20 6b 65 65 70 20 2a 2f 0a 0a 2f 2a 0a 2a 2a : keep */../*.**
01d0: 20 4f 62 6a 65 63 74 20 75 73 65 64 20 74 6f 20 Object used to
01e0: 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 iterate through
01f0: 61 6c 6c 20 22 63 6f 61 6c 65 73 63 65 64 20 70 all "coalesced p
0200: 68 72 61 73 65 20 69 6e 73 74 61 6e 63 65 73 22 hrase instances"
0210: 20 69 6e 20 0a 2a 2a 20 61 20 73 69 6e 67 6c 65 in .** a single
0220: 20 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65 20 63 column of the c
0230: 75 72 72 65 6e 74 20 72 6f 77 2e 20 49 66 20 74 urrent row. If t
0240: 68 65 20 70 68 72 61 73 65 20 69 6e 73 74 61 6e he phrase instan
0250: 63 65 73 20 69 6e 20 74 68 65 0a 2a 2a 20 63 6f ces in the.** co
0260: 6c 75 6d 6e 20 62 65 69 6e 67 20 63 6f 6e 73 69 lumn being consi
0270: 64 65 72 65 64 20 64 6f 20 6e 6f 74 20 6f 76 65 dered do not ove
0280: 72 6c 61 70 2c 20 74 68 69 73 20 6f 62 6a 65 63 rlap, this objec
0290: 74 20 73 69 6d 70 6c 79 20 69 74 65 72 61 74 65 t simply iterate
02a0: 73 0a 2a 2a 20 74 68 72 6f 75 67 68 20 74 68 65 s.** through the
02b0: 6d 2e 20 4f 72 2c 20 69 66 20 74 68 65 79 20 64 m. Or, if they d
02c0: 6f 20 6f 76 65 72 6c 61 70 20 28 73 68 61 72 65 o overlap (share
02d0: 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 74 6f 6b one or more tok
02e0: 65 6e 73 20 69 6e 0a 2a 2a 20 63 6f 6d 6d 6f 6e ens in.** common
02f0: 29 2c 20 65 61 63 68 20 73 65 74 20 6f 66 20 6f ), each set of o
0300: 76 65 72 6c 61 70 70 69 6e 67 20 69 6e 73 74 61 verlapping insta
0310: 6e 63 65 73 20 69 73 20 74 72 65 61 74 65 64 20 nces is treated
0320: 61 73 20 61 20 73 69 6e 67 6c 65 0a 2a 2a 20 6d as a single.** m
0330: 61 74 63 68 2e 20 53 65 65 20 64 6f 63 75 6d 65 atch. See docume
0340: 6e 74 61 74 69 6f 6e 20 66 6f 72 20 74 68 65 20 ntation for the
0350: 68 69 67 68 6c 69 67 68 74 28 29 20 61 75 78 69 highlight() auxi
0360: 6c 69 61 72 79 20 66 75 6e 63 74 69 6f 6e 20 66 liary function f
0370: 6f 72 0a 2a 2a 20 64 65 74 61 69 6c 73 2e 0a 2a or.** details..*
0380: 2a 0a 2a 2a 20 55 73 61 67 65 20 69 73 3a 0a 2a *.** Usage is:.*
0390: 2a 0a 2a 2a 20 20 20 66 6f 72 28 72 63 20 3d 20 *.** for(rc =
03a0: 66 74 73 35 43 49 6e 73 74 49 74 65 72 4e 65 78 fts5CInstIterNex
03b0: 74 28 70 41 70 69 2c 20 70 46 74 73 2c 20 69 43 t(pApi, pFts, iC
03c0: 6f 6c 2c 20 26 69 74 65 72 29 3b 0a 2a 2a 20 20 ol, &iter);.**
03d0: 20 20 20 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f (rc==SQLITE_
03e0: 4f 4b 20 26 26 20 30 3d 3d 66 74 73 35 43 49 6e OK && 0==fts5CIn
03f0: 73 74 49 74 65 72 45 6f 66 28 26 69 74 65 72 29 stIterEof(&iter)
0400: 3b 0a 2a 2a 20 20 20 20 20 20 72 63 20 3d 20 66 ;.** rc = f
0410: 74 73 35 43 49 6e 73 74 49 74 65 72 4e 65 78 74 ts5CInstIterNext
0420: 28 26 69 74 65 72 29 0a 2a 2a 20 20 20 29 7b 0a (&iter).** ){.
0430: 2a 2a 20 20 20 20 20 70 72 69 6e 74 66 28 22 69 ** printf("i
0440: 6e 73 74 61 6e 63 65 20 73 74 61 72 74 73 20 61 nstance starts a
0450: 74 20 25 64 2c 20 65 6e 64 73 20 61 74 20 25 64 t %d, ends at %d
0460: 5c 6e 22 2c 20 69 74 65 72 2e 69 53 74 61 72 74 \n", iter.iStart
0470: 2c 20 69 74 65 72 2e 69 45 6e 64 29 3b 0a 2a 2a , iter.iEnd);.**
0480: 20 20 20 7d 0a 2a 2a 0a 2a 2f 0a 74 79 70 65 64 }.**.*/.typed
0490: 65 66 20 73 74 72 75 63 74 20 43 49 6e 73 74 49 ef struct CInstI
04a0: 74 65 72 20 43 49 6e 73 74 49 74 65 72 3b 0a 73 ter CInstIter;.s
04b0: 74 72 75 63 74 20 43 49 6e 73 74 49 74 65 72 20 truct CInstIter
04c0: 7b 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45 78 {. const Fts5Ex
04d0: 74 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70 69 tensionApi *pApi
04e0: 3b 20 20 20 2f 2a 20 41 50 49 20 6f 66 66 65 72 ; /* API offer
04f0: 65 64 20 62 79 20 63 75 72 72 65 6e 74 20 46 54 ed by current FT
0500: 53 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 46 S version */. F
0510: 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 ts5Context *pFts
0520: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f ; /
0530: 2a 20 46 69 72 73 74 20 61 72 67 20 74 6f 20 70 * First arg to p
0540: 61 73 73 20 74 6f 20 70 41 70 69 20 66 75 6e 63 ass to pApi func
0550: 74 69 6f 6e 73 20 2a 2f 0a 20 20 69 6e 74 20 69 tions */. int i
0560: 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 Col;
0570: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f /* Co
0580: 6c 75 6d 6e 20 74 6f 20 73 65 61 72 63 68 20 2a lumn to search *
0590: 2f 0a 20 20 69 6e 74 20 69 49 6e 73 74 3b 20 20 /. int iInst;
05a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
05b0: 20 20 20 20 2f 2a 20 4e 65 78 74 20 70 68 72 61 /* Next phra
05c0: 73 65 20 69 6e 73 74 61 6e 63 65 20 69 6e 64 65 se instance inde
05d0: 78 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 6e 73 74 x */. int nInst
05e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ;
05f0: 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 /* Total
0600: 6e 75 6d 62 65 72 20 6f 66 20 70 68 72 61 73 65 number of phrase
0610: 20 69 6e 73 74 61 6e 63 65 73 20 2a 2f 0a 0a 20 instances */..
0620: 20 2f 2a 20 4f 75 74 70 75 74 20 76 61 72 69 61 /* Output varia
0630: 62 6c 65 73 20 2a 2f 0a 20 20 69 6e 74 20 69 53 bles */. int iS
0640: 74 61 72 74 3b 20 20 20 20 20 20 20 20 20 20 20 tart;
0650: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 /* Fir
0660: 73 74 20 74 6f 6b 65 6e 20 69 6e 20 63 6f 61 6c st token in coal
0670: 65 73 63 65 64 20 70 68 72 61 73 65 20 69 6e 73 esced phrase ins
0680: 74 61 6e 63 65 20 2a 2f 0a 20 20 69 6e 74 20 69 tance */. int i
0690: 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 End;
06a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 /* La
06b0: 73 74 20 74 6f 6b 65 6e 20 69 6e 20 63 6f 61 6c st token in coal
06c0: 65 73 63 65 64 20 70 68 72 61 73 65 20 69 6e 73 esced phrase ins
06d0: 74 61 6e 63 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a tance */.};../*.
06e0: 2a 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20 69 ** Advance the i
06f0: 74 65 72 61 74 6f 72 20 74 6f 20 74 68 65 20 6e terator to the n
0700: 65 78 74 20 63 6f 61 6c 65 73 63 65 64 20 70 68 ext coalesced ph
0710: 72 61 73 65 20 69 6e 73 74 61 6e 63 65 2e 20 52 rase instance. R
0720: 65 74 75 72 6e 0a 2a 2a 20 61 6e 20 53 51 4c 69 eturn.** an SQLi
0730: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 te error code if
0740: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 an error occurs
0750: 2c 20 6f 72 20 53 51 4c 49 54 45 5f 4f 4b 20 6f , or SQLITE_OK o
0760: 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 therwise..*/.sta
0770: 74 69 63 20 69 6e 74 20 66 74 73 35 43 49 6e 73 tic int fts5CIns
0780: 74 49 74 65 72 4e 65 78 74 28 43 49 6e 73 74 49 tIterNext(CInstI
0790: 74 65 72 20 2a 70 49 74 65 72 29 7b 0a 20 20 69 ter *pIter){. i
07a0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f nt rc = SQLITE_O
07b0: 4b 3b 0a 20 20 70 49 74 65 72 2d 3e 69 53 74 61 K;. pIter->iSta
07c0: 72 74 20 3d 20 2d 31 3b 0a 20 20 70 49 74 65 72 rt = -1;. pIter
07d0: 2d 3e 69 45 6e 64 20 3d 20 2d 31 3b 0a 0a 20 20 ->iEnd = -1;..
07e0: 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 while( rc==SQLIT
07f0: 45 5f 4f 4b 20 26 26 20 70 49 74 65 72 2d 3e 69 E_OK && pIter->i
0800: 49 6e 73 74 3c 70 49 74 65 72 2d 3e 6e 49 6e 73 Inst<pIter->nIns
0810: 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 70 3b t ){. int ip;
0820: 20 69 6e 74 20 69 63 3b 20 69 6e 74 20 69 6f 3b int ic; int io;
0830: 0a 20 20 20 20 72 63 20 3d 20 70 49 74 65 72 2d . rc = pIter-
0840: 3e 70 41 70 69 2d 3e 78 49 6e 73 74 28 70 49 74 >pApi->xInst(pIt
0850: 65 72 2d 3e 70 46 74 73 2c 20 70 49 74 65 72 2d er->pFts, pIter-
0860: 3e 69 49 6e 73 74 2c 20 26 69 70 2c 20 26 69 63 >iInst, &ip, &ic
0870: 2c 20 26 69 6f 29 3b 0a 20 20 20 20 69 66 28 20 , &io);. if(
0880: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b rc==SQLITE_OK ){
0890: 0a 20 20 20 20 20 20 69 66 28 20 69 63 3d 3d 70 . if( ic==p
08a0: 49 74 65 72 2d 3e 69 43 6f 6c 20 29 7b 0a 20 20 Iter->iCol ){.
08b0: 20 20 20 20 20 20 69 6e 74 20 69 45 6e 64 20 3d int iEnd =
08c0: 20 69 6f 20 2d 20 31 20 2b 20 70 49 74 65 72 2d io - 1 + pIter-
08d0: 3e 70 41 70 69 2d 3e 78 50 68 72 61 73 65 53 69 >pApi->xPhraseSi
08e0: 7a 65 28 70 49 74 65 72 2d 3e 70 46 74 73 2c 20 ze(pIter->pFts,
08f0: 69 70 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 ip);. if(
0900: 20 70 49 74 65 72 2d 3e 69 53 74 61 72 74 3c 30 pIter->iStart<0
0910: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 49 ){. pI
0920: 74 65 72 2d 3e 69 53 74 61 72 74 20 3d 20 69 6f ter->iStart = io
0930: 3b 0a 20 20 20 20 20 20 20 20 20 20 70 49 74 65 ;. pIte
0940: 72 2d 3e 69 45 6e 64 20 3d 20 69 45 6e 64 3b 0a r->iEnd = iEnd;.
0950: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 }else if
0960: 28 20 69 6f 3c 3d 70 49 74 65 72 2d 3e 69 45 6e ( io<=pIter->iEn
0970: 64 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 d ){. i
0980: 66 28 20 69 45 6e 64 3e 70 49 74 65 72 2d 3e 69 f( iEnd>pIter->i
0990: 45 6e 64 20 29 20 70 49 74 65 72 2d 3e 69 45 6e End ) pIter->iEn
09a0: 64 20 3d 20 69 45 6e 64 3b 0a 20 20 20 20 20 20 d = iEnd;.
09b0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 }else{.
09c0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 break;.
09d0: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 }. }.
09e0: 20 20 70 49 74 65 72 2d 3e 69 49 6e 73 74 2b 2b pIter->iInst++
09f0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 ;. }. }.. r
0a00: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a eturn rc;.}../*.
0a10: 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 ** Initialize th
0a20: 65 20 69 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 e iterator objec
0a30: 74 20 69 6e 64 69 63 61 74 65 64 20 62 79 20 74 t indicated by t
0a40: 68 65 20 66 69 6e 61 6c 20 70 61 72 61 6d 65 74 he final paramet
0a50: 65 72 20 74 6f 20 0a 2a 2a 20 69 74 65 72 61 74 er to .** iterat
0a60: 65 20 74 68 72 6f 75 67 68 20 63 6f 61 6c 65 73 e through coales
0a70: 63 65 64 20 70 68 72 61 73 65 20 69 6e 73 74 61 ced phrase insta
0a80: 6e 63 65 73 20 69 6e 20 63 6f 6c 75 6d 6e 20 69 nces in column i
0a90: 43 6f 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 Col..*/.static i
0aa0: 6e 74 20 66 74 73 35 43 49 6e 73 74 49 74 65 72 nt fts5CInstIter
0ab0: 49 6e 69 74 28 0a 20 20 63 6f 6e 73 74 20 46 74 Init(. const Ft
0ac0: 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a s5ExtensionApi *
0ad0: 70 41 70 69 2c 0a 20 20 46 74 73 35 43 6f 6e 74 pApi,. Fts5Cont
0ae0: 65 78 74 20 2a 70 46 74 73 2c 0a 20 20 69 6e 74 ext *pFts,. int
0af0: 20 69 43 6f 6c 2c 0a 20 20 43 49 6e 73 74 49 74 iCol,. CInstIt
0b00: 65 72 20 2a 70 49 74 65 72 0a 29 7b 0a 20 20 69 er *pIter.){. i
0b10: 6e 74 20 72 63 3b 0a 0a 20 20 6d 65 6d 73 65 74 nt rc;.. memset
0b20: 28 70 49 74 65 72 2c 20 30 2c 20 73 69 7a 65 6f (pIter, 0, sizeo
0b30: 66 28 43 49 6e 73 74 49 74 65 72 29 29 3b 0a 20 f(CInstIter));.
0b40: 20 70 49 74 65 72 2d 3e 70 41 70 69 20 3d 20 70 pIter->pApi = p
0b50: 41 70 69 3b 0a 20 20 70 49 74 65 72 2d 3e 70 46 Api;. pIter->pF
0b60: 74 73 20 3d 20 70 46 74 73 3b 0a 20 20 70 49 74 ts = pFts;. pIt
0b70: 65 72 2d 3e 69 43 6f 6c 20 3d 20 69 43 6f 6c 3b er->iCol = iCol;
0b80: 0a 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 49 . rc = pApi->xI
0b90: 6e 73 74 43 6f 75 6e 74 28 70 46 74 73 2c 20 26 nstCount(pFts, &
0ba0: 70 49 74 65 72 2d 3e 6e 49 6e 73 74 29 3b 0a 0a pIter->nInst);..
0bb0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 if( rc==SQLITE
0bc0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 _OK ){. rc =
0bd0: 66 74 73 35 43 49 6e 73 74 49 74 65 72 4e 65 78 fts5CInstIterNex
0be0: 74 28 70 49 74 65 72 29 3b 0a 20 20 7d 0a 0a 20 t(pIter);. }..
0bf0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a return rc;.}...
0c00: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ./**************
0c10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0c20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0c30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0c40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 53 ***********.** S
0c50: 74 61 72 74 20 6f 66 20 68 69 67 68 6c 69 67 68 tart of highligh
0c60: 74 28 29 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 t() implementati
0c70: 6f 6e 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 on..*/.typedef s
0c80: 74 72 75 63 74 20 48 69 67 68 6c 69 67 68 74 43 truct HighlightC
0c90: 6f 6e 74 65 78 74 20 48 69 67 68 6c 69 67 68 74 ontext Highlight
0ca0: 43 6f 6e 74 65 78 74 3b 0a 73 74 72 75 63 74 20 Context;.struct
0cb0: 48 69 67 68 6c 69 67 68 74 43 6f 6e 74 65 78 74 HighlightContext
0cc0: 20 7b 0a 20 20 43 49 6e 73 74 49 74 65 72 20 69 {. CInstIter i
0cd0: 74 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 ter;
0ce0: 20 20 20 20 20 2f 2a 20 43 6f 61 6c 65 73 63 65 /* Coalesce
0cf0: 64 20 49 6e 73 74 61 6e 63 65 20 49 74 65 72 61 d Instance Itera
0d00: 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 69 50 6f tor */. int iPo
0d10: 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 s;
0d20: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 /* Curr
0d30: 65 6e 74 20 74 6f 6b 65 6e 20 6f 66 66 73 65 74 ent token offset
0d40: 20 69 6e 20 7a 49 6e 5b 5d 20 2a 2f 0a 20 20 69 in zIn[] */. i
0d50: 6e 74 20 69 52 61 6e 67 65 53 74 61 72 74 3b 20 nt iRangeStart;
0d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
0d70: 2a 20 46 69 72 73 74 20 74 6f 6b 65 6e 20 74 6f * First token to
0d80: 20 69 6e 63 6c 75 64 65 20 2a 2f 0a 20 20 69 6e include */. in
0d90: 74 20 69 52 61 6e 67 65 45 6e 64 3b 20 20 20 20 t iRangeEnd;
0da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
0db0: 20 49 66 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 6c 61 If non-zero, la
0dc0: 73 74 20 74 6f 6b 65 6e 20 74 6f 20 69 6e 63 6c st token to incl
0dd0: 75 64 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 ude */. const c
0de0: 68 61 72 20 2a 7a 4f 70 65 6e 3b 20 20 20 20 20 har *zOpen;
0df0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 70 65 6e /* Open
0e00: 69 6e 67 20 68 69 67 68 6c 69 67 68 74 20 2a 2f ing highlight */
0e10: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a . const char *z
0e20: 43 6c 6f 73 65 3b 20 20 20 20 20 20 20 20 20 20 Close;
0e30: 20 20 20 2f 2a 20 43 6c 6f 73 69 6e 67 20 68 69 /* Closing hi
0e40: 67 68 6c 69 67 68 74 20 2a 2f 0a 20 20 63 6f 6e ghlight */. con
0e50: 73 74 20 63 68 61 72 20 2a 7a 49 6e 3b 20 20 20 st char *zIn;
0e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
0e70: 49 6e 70 75 74 20 74 65 78 74 20 2a 2f 0a 20 20 Input text */.
0e80: 69 6e 74 20 6e 49 6e 3b 20 20 20 20 20 20 20 20 int nIn;
0e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
0ea0: 2f 2a 20 53 69 7a 65 20 6f 66 20 69 6e 70 75 74 /* Size of input
0eb0: 20 74 65 78 74 20 69 6e 20 62 79 74 65 73 20 2a text in bytes *
0ec0: 2f 0a 20 20 69 6e 74 20 69 4f 66 66 3b 20 20 20 /. int iOff;
0ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
0ee0: 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 6f /* Current o
0ef0: 66 66 73 65 74 20 77 69 74 68 69 6e 20 7a 49 6e ffset within zIn
0f00: 5b 5d 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 4f [] */. char *zO
0f10: 75 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 ut;
0f20: 20 20 20 20 20 20 20 20 2f 2a 20 4f 75 74 70 75 /* Outpu
0f30: 74 20 76 61 6c 75 65 20 2a 2f 0a 7d 3b 0a 0a 2f t value */.};../
0f40: 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74 65 78 74 *.** Append text
0f50: 20 74 6f 20 74 68 65 20 48 69 67 68 6c 69 67 68 to the Highligh
0f60: 74 43 6f 6e 74 65 78 74 20 6f 75 74 70 75 74 20 tContext output
0f70: 73 74 72 69 6e 67 20 2d 20 70 2d 3e 7a 4f 75 74 string - p->zOut
0f80: 2e 20 41 72 67 75 6d 65 6e 74 0a 2a 2a 20 7a 20 . Argument.** z
0f90: 70 6f 69 6e 74 73 20 74 6f 20 61 20 62 75 66 66 points to a buff
0fa0: 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 6e 20 er containing n
0fb0: 62 79 74 65 73 20 6f 66 20 74 65 78 74 20 74 6f bytes of text to
0fc0: 20 61 70 70 65 6e 64 2e 20 49 66 20 6e 20 69 73 append. If n is
0fd0: 20 0a 2a 2a 20 6e 65 67 61 74 69 76 65 2c 20 65 .** negative, e
0fe0: 76 65 72 79 74 68 69 6e 67 20 75 70 20 75 6e 74 verything up unt
0ff0: 69 6c 20 74 68 65 20 66 69 72 73 74 20 27 5c 30 il the first '\0
1000: 27 20 69 73 20 61 70 70 65 6e 64 65 64 20 74 6f ' is appended to
1010: 20 74 68 65 20 6f 75 74 70 75 74 2e 0a 2a 2a 0a the output..**.
1020: 2a 2a 20 49 66 20 2a 70 52 63 20 69 73 20 73 65 ** If *pRc is se
1030: 74 20 74 6f 20 61 6e 79 20 76 61 6c 75 65 20 6f t to any value o
1040: 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45 ther than SQLITE
1050: 5f 4f 4b 20 77 68 65 6e 20 74 68 69 73 20 66 75 _OK when this fu
1060: 6e 63 74 69 6f 6e 20 69 73 20 0a 2a 2a 20 63 61 nction is .** ca
1070: 6c 6c 65 64 2c 20 69 74 20 69 73 20 61 20 6e 6f lled, it is a no
1080: 2d 6f 70 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 -op. If an error
1090: 20 28 69 2e 65 2e 20 61 6e 20 4f 4f 4d 20 63 6f (i.e. an OOM co
10a0: 6e 64 69 74 69 6f 6e 29 20 69 73 20 65 6e 63 6f ndition) is enco
10b0: 75 6e 74 65 72 65 64 2c 20 0a 2a 2a 20 2a 70 52 untered, .** *pR
10c0: 63 20 69 73 20 73 65 74 20 74 6f 20 61 6e 20 65 c is set to an e
10d0: 72 72 6f 72 20 63 6f 64 65 20 62 65 66 6f 72 65 rror code before
10e0: 20 72 65 74 75 72 6e 69 6e 67 2e 20 0a 2a 2f 0a returning. .*/.
10f0: 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 static void fts5
1100: 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e 64 28 HighlightAppend(
1110: 0a 20 20 69 6e 74 20 2a 70 52 63 2c 20 0a 20 20 . int *pRc, .
1120: 48 69 67 68 6c 69 67 68 74 43 6f 6e 74 65 78 74 HighlightContext
1130: 20 2a 70 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 *p, . const ch
1140: 61 72 20 2a 7a 2c 20 69 6e 74 20 6e 0a 29 7b 0a ar *z, int n.){.
1150: 20 20 69 66 28 20 2a 70 52 63 3d 3d 53 51 4c 49 if( *pRc==SQLI
1160: 54 45 5f 4f 4b 20 26 26 20 7a 20 29 7b 0a 20 20 TE_OK && z ){.
1170: 20 20 69 66 28 20 6e 3c 30 20 29 20 6e 20 3d 20 if( n<0 ) n =
1180: 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a 29 3b 0a (int)strlen(z);.
1190: 20 20 20 20 70 2d 3e 7a 4f 75 74 20 3d 20 73 71 p->zOut = sq
11a0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 lite3_mprintf("%
11b0: 7a 25 2e 2a 73 22 2c 20 70 2d 3e 7a 4f 75 74 2c z%.*s", p->zOut,
11c0: 20 6e 2c 20 7a 29 3b 0a 20 20 20 20 69 66 28 20 n, z);. if(
11d0: 70 2d 3e 7a 4f 75 74 3d 3d 30 20 29 20 2a 70 52 p->zOut==0 ) *pR
11e0: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d c = SQLITE_NOMEM
11f0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 ;. }.}../*.** T
1200: 6f 6b 65 6e 69 7a 65 72 20 63 61 6c 6c 62 61 63 okenizer callbac
1210: 6b 20 75 73 65 64 20 62 79 20 69 6d 70 6c 65 6d k used by implem
1220: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 68 69 67 68 entation of high
1230: 6c 69 67 68 74 28 29 20 66 75 6e 63 74 69 6f 6e light() function
1240: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 ..*/.static int
1250: 66 74 73 35 48 69 67 68 6c 69 67 68 74 43 62 28 fts5HighlightCb(
1260: 0a 20 20 76 6f 69 64 20 2a 70 43 6f 6e 74 65 78 . void *pContex
1270: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 t,
1280: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f /* Pointer to
1290: 20 48 69 67 68 6c 69 67 68 74 43 6f 6e 74 65 78 HighlightContex
12a0: 74 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e t object */. in
12b0: 74 20 74 66 6c 61 67 73 2c 20 20 20 20 20 20 20 t tflags,
12c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
12d0: 20 4d 61 73 6b 20 6f 66 20 46 54 53 35 5f 54 4f Mask of FTS5_TO
12e0: 4b 45 4e 5f 2a 20 66 6c 61 67 73 20 2a 2f 0a 20 KEN_* flags */.
12f0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 6f const char *pTo
1300: 6b 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 ken,
1310: 20 2f 2a 20 42 75 66 66 65 72 20 63 6f 6e 74 61 /* Buffer conta
1320: 69 6e 69 6e 67 20 74 6f 6b 65 6e 20 2a 2f 0a 20 ining token */.
1330: 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 20 20 20 int nToken,
1340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1350: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74 6f 6b 65 /* Size of toke
1360: 6e 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 n in bytes */.
1370: 69 6e 74 20 69 53 74 61 72 74 4f 66 66 2c 20 20 int iStartOff,
1380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1390: 2f 2a 20 53 74 61 72 74 20 6f 66 66 73 65 74 20 /* Start offset
13a0: 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e of token */. in
13b0: 74 20 69 45 6e 64 4f 66 66 20 20 20 20 20 20 20 t iEndOff
13c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
13d0: 20 45 6e 64 20 6f 66 66 73 65 74 20 6f 66 20 74 End offset of t
13e0: 6f 6b 65 6e 20 2a 2f 0a 29 7b 0a 20 20 48 69 67 oken */.){. Hig
13f0: 68 6c 69 67 68 74 43 6f 6e 74 65 78 74 20 2a 70 hlightContext *p
1400: 20 3d 20 28 48 69 67 68 6c 69 67 68 74 43 6f 6e = (HighlightCon
1410: 74 65 78 74 2a 29 70 43 6f 6e 74 65 78 74 3b 0a text*)pContext;.
1420: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 int rc = SQLIT
1430: 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 69 50 6f 73 E_OK;. int iPos
1440: 3b 0a 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41 ;.. UNUSED_PARA
1450: 4d 32 28 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 M2(pToken, nToke
1460: 6e 29 3b 0a 0a 20 20 69 66 28 20 74 66 6c 61 67 n);.. if( tflag
1470: 73 20 26 20 46 54 53 35 5f 54 4f 4b 45 4e 5f 43 s & FTS5_TOKEN_C
1480: 4f 4c 4f 43 41 54 45 44 20 29 20 72 65 74 75 72 OLOCATED ) retur
1490: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 n SQLITE_OK;. i
14a0: 50 6f 73 20 3d 20 70 2d 3e 69 50 6f 73 2b 2b 3b Pos = p->iPos++;
14b0: 0a 0a 20 20 69 66 28 20 70 2d 3e 69 52 61 6e 67 .. if( p->iRang
14c0: 65 45 6e 64 3e 30 20 29 7b 0a 20 20 20 20 69 66 eEnd>0 ){. if
14d0: 28 20 69 50 6f 73 3c 70 2d 3e 69 52 61 6e 67 65 ( iPos<p->iRange
14e0: 53 74 61 72 74 20 7c 7c 20 69 50 6f 73 3e 70 2d Start || iPos>p-
14f0: 3e 69 52 61 6e 67 65 45 6e 64 20 29 20 72 65 74 >iRangeEnd ) ret
1500: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 urn SQLITE_OK;.
1510: 20 20 20 69 66 28 20 70 2d 3e 69 52 61 6e 67 65 if( p->iRange
1520: 53 74 61 72 74 20 26 26 20 69 50 6f 73 3d 3d 70 Start && iPos==p
1530: 2d 3e 69 52 61 6e 67 65 53 74 61 72 74 20 29 20 ->iRangeStart )
1540: 70 2d 3e 69 4f 66 66 20 3d 20 69 53 74 61 72 74 p->iOff = iStart
1550: 4f 66 66 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 Off;. }.. if(
1560: 69 50 6f 73 3d 3d 70 2d 3e 69 74 65 72 2e 69 53 iPos==p->iter.iS
1570: 74 61 72 74 20 29 7b 0a 20 20 20 20 66 74 73 35 tart ){. fts5
1580: 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e 64 28 HighlightAppend(
1590: 26 72 63 2c 20 70 2c 20 26 70 2d 3e 7a 49 6e 5b &rc, p, &p->zIn[
15a0: 70 2d 3e 69 4f 66 66 5d 2c 20 69 53 74 61 72 74 p->iOff], iStart
15b0: 4f 66 66 20 2d 20 70 2d 3e 69 4f 66 66 29 3b 0a Off - p->iOff);.
15c0: 20 20 20 20 66 74 73 35 48 69 67 68 6c 69 67 68 fts5Highligh
15d0: 74 41 70 70 65 6e 64 28 26 72 63 2c 20 70 2c 20 tAppend(&rc, p,
15e0: 70 2d 3e 7a 4f 70 65 6e 2c 20 2d 31 29 3b 0a 20 p->zOpen, -1);.
15f0: 20 20 20 70 2d 3e 69 4f 66 66 20 3d 20 69 53 74 p->iOff = iSt
1600: 61 72 74 4f 66 66 3b 0a 20 20 7d 0a 0a 20 20 69 artOff;. }.. i
1610: 66 28 20 69 50 6f 73 3d 3d 70 2d 3e 69 74 65 72 f( iPos==p->iter
1620: 2e 69 45 6e 64 20 29 7b 0a 20 20 20 20 69 66 28 .iEnd ){. if(
1630: 20 70 2d 3e 69 52 61 6e 67 65 45 6e 64 20 26 26 p->iRangeEnd &&
1640: 20 70 2d 3e 69 74 65 72 2e 69 53 74 61 72 74 3c p->iter.iStart<
1650: 70 2d 3e 69 52 61 6e 67 65 53 74 61 72 74 20 29 p->iRangeStart )
1660: 7b 0a 20 20 20 20 20 20 66 74 73 35 48 69 67 68 {. fts5High
1670: 6c 69 67 68 74 41 70 70 65 6e 64 28 26 72 63 2c lightAppend(&rc,
1680: 20 70 2c 20 70 2d 3e 7a 4f 70 65 6e 2c 20 2d 31 p, p->zOpen, -1
1690: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 74 73 );. }. fts
16a0: 35 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e 64 5HighlightAppend
16b0: 28 26 72 63 2c 20 70 2c 20 26 70 2d 3e 7a 49 6e (&rc, p, &p->zIn
16c0: 5b 70 2d 3e 69 4f 66 66 5d 2c 20 69 45 6e 64 4f [p->iOff], iEndO
16d0: 66 66 20 2d 20 70 2d 3e 69 4f 66 66 29 3b 0a 20 ff - p->iOff);.
16e0: 20 20 20 66 74 73 35 48 69 67 68 6c 69 67 68 74 fts5Highlight
16f0: 41 70 70 65 6e 64 28 26 72 63 2c 20 70 2c 20 70 Append(&rc, p, p
1700: 2d 3e 7a 43 6c 6f 73 65 2c 20 2d 31 29 3b 0a 20 ->zClose, -1);.
1710: 20 20 20 70 2d 3e 69 4f 66 66 20 3d 20 69 45 6e p->iOff = iEn
1720: 64 4f 66 66 3b 0a 20 20 20 20 69 66 28 20 72 63 dOff;. if( rc
1730: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 ==SQLITE_OK ){.
1740: 20 20 20 20 20 72 63 20 3d 20 66 74 73 35 43 49 rc = fts5CI
1750: 6e 73 74 49 74 65 72 4e 65 78 74 28 26 70 2d 3e nstIterNext(&p->
1760: 69 74 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d iter);. }. }
1770: 0a 0a 20 20 69 66 28 20 70 2d 3e 69 52 61 6e 67 .. if( p->iRang
1780: 65 45 6e 64 3e 30 20 26 26 20 69 50 6f 73 3d 3d eEnd>0 && iPos==
1790: 70 2d 3e 69 52 61 6e 67 65 45 6e 64 20 29 7b 0a p->iRangeEnd ){.
17a0: 20 20 20 20 66 74 73 35 48 69 67 68 6c 69 67 68 fts5Highligh
17b0: 74 41 70 70 65 6e 64 28 26 72 63 2c 20 70 2c 20 tAppend(&rc, p,
17c0: 26 70 2d 3e 7a 49 6e 5b 70 2d 3e 69 4f 66 66 5d &p->zIn[p->iOff]
17d0: 2c 20 69 45 6e 64 4f 66 66 20 2d 20 70 2d 3e 69 , iEndOff - p->i
17e0: 4f 66 66 29 3b 0a 20 20 20 20 70 2d 3e 69 4f 66 Off);. p->iOf
17f0: 66 20 3d 20 69 45 6e 64 4f 66 66 3b 0a 20 20 20 f = iEndOff;.
1800: 20 69 66 28 20 69 50 6f 73 3e 3d 70 2d 3e 69 74 if( iPos>=p->it
1810: 65 72 2e 69 53 74 61 72 74 20 26 26 20 69 50 6f er.iStart && iPo
1820: 73 3c 70 2d 3e 69 74 65 72 2e 69 45 6e 64 20 29 s<p->iter.iEnd )
1830: 7b 0a 20 20 20 20 20 20 66 74 73 35 48 69 67 68 {. fts5High
1840: 6c 69 67 68 74 41 70 70 65 6e 64 28 26 72 63 2c lightAppend(&rc,
1850: 20 70 2c 20 70 2d 3e 7a 43 6c 6f 73 65 2c 20 2d p, p->zClose, -
1860: 31 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 1);. }. }..
1870: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f return rc;.}../
1880: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 *.** Implementat
1890: 69 6f 6e 20 6f 66 20 68 69 67 68 6c 69 67 68 74 ion of highlight
18a0: 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a () function..*/.
18b0: 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 static void fts5
18c0: 48 69 67 68 6c 69 67 68 74 46 75 6e 63 74 69 6f HighlightFunctio
18d0: 6e 28 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45 n(. const Fts5E
18e0: 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70 xtensionApi *pAp
18f0: 69 2c 20 20 20 2f 2a 20 41 50 49 20 6f 66 66 65 i, /* API offe
1900: 72 65 64 20 62 79 20 63 75 72 72 65 6e 74 20 46 red by current F
1910: 54 53 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 TS version */.
1920: 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 Fts5Context *pFt
1930: 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 s,
1940: 2f 2a 20 46 69 72 73 74 20 61 72 67 20 74 6f 20 /* First arg to
1950: 70 61 73 73 20 74 6f 20 70 41 70 69 20 66 75 6e pass to pApi fun
1960: 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 73 71 6c 69 ctions */. sqli
1970: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43 74 te3_context *pCt
1980: 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 x, /* C
1990: 6f 6e 74 65 78 74 20 66 6f 72 20 72 65 74 75 72 ontext for retur
19a0: 6e 69 6e 67 20 72 65 73 75 6c 74 2f 65 72 72 6f ning result/erro
19b0: 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 56 61 6c 2c r */. int nVal,
19c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
19d0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 /* Number
19e0: 20 6f 66 20 76 61 6c 75 65 73 20 69 6e 20 61 70 of values in ap
19f0: 56 61 6c 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20 Val[] array */.
1a00: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a sqlite3_value *
1a10: 2a 61 70 56 61 6c 20 20 20 20 20 20 20 20 20 20 *apVal
1a20: 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 74 72 61 /* Array of tra
1a30: 69 6c 69 6e 67 20 61 72 67 75 6d 65 6e 74 73 20 iling arguments
1a40: 2a 2f 0a 29 7b 0a 20 20 48 69 67 68 6c 69 67 68 */.){. Highligh
1a50: 74 43 6f 6e 74 65 78 74 20 63 74 78 3b 0a 20 20 tContext ctx;.
1a60: 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 43 int rc;. int iC
1a70: 6f 6c 3b 0a 0a 20 20 69 66 28 20 6e 56 61 6c 21 ol;.. if( nVal!
1a80: 3d 33 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 =3 ){. const
1a90: 63 68 61 72 20 2a 7a 45 72 72 20 3d 20 22 77 72 char *zErr = "wr
1aa0: 6f 6e 67 20 6e 75 6d 62 65 72 20 6f 66 20 61 72 ong number of ar
1ab0: 67 75 6d 65 6e 74 73 20 74 6f 20 66 75 6e 63 74 guments to funct
1ac0: 69 6f 6e 20 68 69 67 68 6c 69 67 68 74 28 29 22 ion highlight()"
1ad0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 ;. sqlite3_re
1ae0: 73 75 6c 74 5f 65 72 72 6f 72 28 70 43 74 78 2c sult_error(pCtx,
1af0: 20 7a 45 72 72 2c 20 2d 31 29 3b 0a 20 20 20 20 zErr, -1);.
1b00: 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 69 return;. }.. i
1b10: 43 6f 6c 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 Col = sqlite3_va
1b20: 6c 75 65 5f 69 6e 74 28 61 70 56 61 6c 5b 30 5d lue_int(apVal[0]
1b30: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 63 74 78 );. memset(&ctx
1b40: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 48 69 67 68 , 0, sizeof(High
1b50: 6c 69 67 68 74 43 6f 6e 74 65 78 74 29 29 3b 0a lightContext));.
1b60: 20 20 63 74 78 2e 7a 4f 70 65 6e 20 3d 20 28 63 ctx.zOpen = (c
1b70: 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 onst char*)sqlit
1b80: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70 e3_value_text(ap
1b90: 56 61 6c 5b 31 5d 29 3b 0a 20 20 63 74 78 2e 7a Val[1]);. ctx.z
1ba0: 43 6c 6f 73 65 20 3d 20 28 63 6f 6e 73 74 20 63 Close = (const c
1bb0: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c har*)sqlite3_val
1bc0: 75 65 5f 74 65 78 74 28 61 70 56 61 6c 5b 32 5d ue_text(apVal[2]
1bd0: 29 3b 0a 20 20 72 63 20 3d 20 70 41 70 69 2d 3e );. rc = pApi->
1be0: 78 43 6f 6c 75 6d 6e 54 65 78 74 28 70 46 74 73 xColumnText(pFts
1bf0: 2c 20 69 43 6f 6c 2c 20 26 63 74 78 2e 7a 49 6e , iCol, &ctx.zIn
1c00: 2c 20 26 63 74 78 2e 6e 49 6e 29 3b 0a 0a 20 20 , &ctx.nIn);..
1c10: 69 66 28 20 63 74 78 2e 7a 49 6e 20 29 7b 0a 20 if( ctx.zIn ){.
1c20: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 if( rc==SQLIT
1c30: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 E_OK ){. rc
1c40: 20 3d 20 66 74 73 35 43 49 6e 73 74 49 74 65 72 = fts5CInstIter
1c50: 49 6e 69 74 28 70 41 70 69 2c 20 70 46 74 73 2c Init(pApi, pFts,
1c60: 20 69 43 6f 6c 2c 20 26 63 74 78 2e 69 74 65 72 iCol, &ctx.iter
1c70: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 );. }.. if
1c80: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 ( rc==SQLITE_OK
1c90: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 70 41 ){. rc = pA
1ca0: 70 69 2d 3e 78 54 6f 6b 65 6e 69 7a 65 28 70 46 pi->xTokenize(pF
1cb0: 74 73 2c 20 63 74 78 2e 7a 49 6e 2c 20 63 74 78 ts, ctx.zIn, ctx
1cc0: 2e 6e 49 6e 2c 20 28 76 6f 69 64 2a 29 26 63 74 .nIn, (void*)&ct
1cd0: 78 2c 66 74 73 35 48 69 67 68 6c 69 67 68 74 43 x,fts5HighlightC
1ce0: 62 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 74 b);. }. ft
1cf0: 73 35 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e s5HighlightAppen
1d00: 64 28 26 72 63 2c 20 26 63 74 78 2c 20 26 63 74 d(&rc, &ctx, &ct
1d10: 78 2e 7a 49 6e 5b 63 74 78 2e 69 4f 66 66 5d 2c x.zIn[ctx.iOff],
1d20: 20 63 74 78 2e 6e 49 6e 20 2d 20 63 74 78 2e 69 ctx.nIn - ctx.i
1d30: 4f 66 66 29 3b 0a 0a 20 20 20 20 69 66 28 20 72 Off);.. if( r
1d40: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a c==SQLITE_OK ){.
1d50: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 sqlite3_re
1d60: 73 75 6c 74 5f 74 65 78 74 28 70 43 74 78 2c 20 sult_text(pCtx,
1d70: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 63 74 78 (const char*)ctx
1d80: 2e 7a 4f 75 74 2c 20 2d 31 2c 20 53 51 4c 49 54 .zOut, -1, SQLIT
1d90: 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 E_TRANSIENT);.
1da0: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f }. sqlite3_
1db0: 66 72 65 65 28 63 74 78 2e 7a 4f 75 74 29 3b 0a free(ctx.zOut);.
1dc0: 20 20 7d 0a 20 20 69 66 28 20 72 63 21 3d 53 51 }. if( rc!=SQ
1dd0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 LITE_OK ){. s
1de0: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 qlite3_result_er
1df0: 72 6f 72 5f 63 6f 64 65 28 70 43 74 78 2c 20 72 ror_code(pCtx, r
1e00: 63 29 3b 0a 20 20 7d 0a 7d 0a 2f 2a 0a 2a 2a 20 c);. }.}./*.**
1e10: 45 6e 64 20 6f 66 20 68 69 67 68 6c 69 67 68 74 End of highlight
1e20: 28 29 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f () implementatio
1e30: 6e 2e 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a n..*************
1e40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
1e50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
1e60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
1e70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a *************/..
1e80: 2f 2a 0a 2a 2a 20 43 6f 6e 74 65 78 74 20 6f 62 /*.** Context ob
1e90: 6a 65 63 74 20 70 61 73 73 65 64 20 74 6f 20 74 ject passed to t
1ea0: 68 65 20 66 74 73 35 53 65 6e 74 65 6e 63 65 46 he fts5SentenceF
1eb0: 69 6e 64 65 72 43 62 28 29 20 66 75 6e 63 74 69 inderCb() functi
1ec0: 6f 6e 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 on..*/.typedef s
1ed0: 74 72 75 63 74 20 46 74 73 35 53 46 69 6e 64 65 truct Fts5SFinde
1ee0: 72 20 46 74 73 35 53 46 69 6e 64 65 72 3b 0a 73 r Fts5SFinder;.s
1ef0: 74 72 75 63 74 20 46 74 73 35 53 46 69 6e 64 65 truct Fts5SFinde
1f00: 72 20 7b 0a 20 20 69 6e 74 20 69 50 6f 73 3b 20 r {. int iPos;
1f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
1f20: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 /* Current
1f30: 20 74 6f 6b 65 6e 20 70 6f 73 69 74 69 6f 6e 20 token position
1f40: 2a 2f 0a 20 20 69 6e 74 20 6e 46 69 72 73 74 41 */. int nFirstA
1f50: 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20 20 20 20 lloc;
1f60: 20 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 /* Allocate
1f70: 64 20 73 69 7a 65 20 6f 66 20 61 46 69 72 73 74 d size of aFirst
1f80: 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20 6e 46 69 72 [] */. int nFir
1f90: 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 st;
1fa0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 /* Numbe
1fb0: 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 r of entries in
1fc0: 61 46 69 72 73 74 5b 5d 20 2a 2f 0a 20 20 69 6e aFirst[] */. in
1fd0: 74 20 2a 61 46 69 72 73 74 3b 20 20 20 20 20 20 t *aFirst;
1fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
1ff0: 20 41 72 72 61 79 20 6f 66 20 66 69 72 73 74 20 Array of first
2000: 74 6f 6b 65 6e 20 69 6e 20 65 61 63 68 20 73 65 token in each se
2010: 6e 74 65 6e 63 65 20 2a 2f 0a 20 20 63 6f 6e 73 ntence */. cons
2020: 74 20 63 68 61 72 20 2a 7a 44 6f 63 3b 20 20 20 t char *zDoc;
2030: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 /* D
2040: 6f 63 75 6d 65 6e 74 20 62 65 69 6e 67 20 74 6f ocument being to
2050: 6b 65 6e 69 7a 65 64 20 2a 2f 0a 7d 3b 0a 0a 2f kenized */.};../
2060: 2a 0a 2a 2a 20 41 64 64 20 61 6e 20 65 6e 74 72 *.** Add an entr
2070: 79 20 74 6f 20 74 68 65 20 46 74 73 35 53 46 69 y to the Fts5SFi
2080: 6e 64 65 72 2e 61 46 69 72 73 74 5b 5d 20 61 72 nder.aFirst[] ar
2090: 72 61 79 2e 20 47 72 6f 77 20 74 68 65 20 61 72 ray. Grow the ar
20a0: 72 61 79 20 69 66 0a 2a 2a 20 6e 65 63 65 73 73 ray if.** necess
20b0: 61 72 79 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 ary. Return SQLI
20c0: 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73 TE_OK if success
20d0: 66 75 6c 2c 20 6f 72 20 53 51 4c 49 54 45 5f 4e ful, or SQLITE_N
20e0: 4f 4d 45 4d 20 69 66 20 61 6e 0a 2a 2a 20 65 72 OMEM if an.** er
20f0: 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 ror occurs..*/.s
2100: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 53 65 tatic int fts5Se
2110: 6e 74 65 6e 63 65 46 69 6e 64 65 72 41 64 64 28 ntenceFinderAdd(
2120: 46 74 73 35 53 46 69 6e 64 65 72 20 2a 70 2c 20 Fts5SFinder *p,
2130: 69 6e 74 20 69 41 64 64 29 7b 0a 20 20 69 66 28 int iAdd){. if(
2140: 20 70 2d 3e 6e 46 69 72 73 74 41 6c 6c 6f 63 3d p->nFirstAlloc=
2150: 3d 70 2d 3e 6e 46 69 72 73 74 20 29 7b 0a 20 20 =p->nFirst ){.
2160: 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20 70 2d 3e int nNew = p->
2170: 6e 46 69 72 73 74 41 6c 6c 6f 63 20 3f 20 70 2d nFirstAlloc ? p-
2180: 3e 6e 46 69 72 73 74 41 6c 6c 6f 63 2a 32 20 3a >nFirstAlloc*2 :
2190: 20 36 34 3b 0a 20 20 20 20 69 6e 74 20 2a 61 4e 64;. int *aN
21a0: 65 77 3b 0a 0a 20 20 20 20 61 4e 65 77 20 3d 20 ew;.. aNew =
21b0: 28 69 6e 74 2a 29 73 71 6c 69 74 65 33 5f 72 65 (int*)sqlite3_re
21c0: 61 6c 6c 6f 63 36 34 28 70 2d 3e 61 46 69 72 73 alloc64(p->aFirs
21d0: 74 2c 20 6e 4e 65 77 2a 73 69 7a 65 6f 66 28 69 t, nNew*sizeof(i
21e0: 6e 74 29 29 3b 0a 20 20 20 20 69 66 28 20 61 4e nt));. if( aN
21f0: 65 77 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 ew==0 ) return S
2200: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 QLITE_NOMEM;.
2210: 20 70 2d 3e 61 46 69 72 73 74 20 3d 20 61 4e 65 p->aFirst = aNe
2220: 77 3b 0a 20 20 20 20 70 2d 3e 6e 46 69 72 73 74 w;. p->nFirst
2230: 41 6c 6c 6f 63 20 3d 20 6e 4e 65 77 3b 0a 20 20 Alloc = nNew;.
2240: 7d 0a 20 20 70 2d 3e 61 46 69 72 73 74 5b 70 2d }. p->aFirst[p-
2250: 3e 6e 46 69 72 73 74 2b 2b 5d 20 3d 20 69 41 64 >nFirst++] = iAd
2260: 64 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 d;. return SQLI
2270: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 TE_OK;.}../*.**
2280: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 This function is
2290: 20 61 6e 20 78 54 6f 6b 65 6e 69 7a 65 28 29 20 an xTokenize()
22a0: 63 61 6c 6c 62 61 63 6b 20 75 73 65 64 20 62 79 callback used by
22b0: 20 74 68 65 20 61 75 78 69 6c 69 61 72 79 20 73 the auxiliary s
22c0: 6e 69 70 70 65 74 28 29 0a 2a 2a 20 66 75 6e 63 nippet().** func
22d0: 74 69 6f 6e 2e 20 49 74 73 20 6a 6f 62 20 69 73 tion. Its job is
22e0: 20 74 6f 20 69 64 65 6e 74 69 66 79 20 74 6f 6b to identify tok
22f0: 65 6e 73 20 74 68 61 74 20 61 72 65 20 74 68 65 ens that are the
2300: 20 66 69 72 73 74 20 69 6e 20 61 20 73 65 6e 74 first in a sent
2310: 65 6e 63 65 2e 0a 2a 2a 20 46 6f 72 20 65 61 63 ence..** For eac
2320: 68 20 73 75 63 68 20 74 6f 6b 65 6e 2c 20 61 6e h such token, an
2330: 20 65 6e 74 72 79 20 69 73 20 61 64 64 65 64 20 entry is added
2340: 74 6f 20 74 68 65 20 53 46 69 6e 64 65 72 2e 61 to the SFinder.a
2350: 46 69 72 73 74 5b 5d 20 61 72 72 61 79 2e 0a 2a First[] array..*
2360: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 /.static int fts
2370: 35 53 65 6e 74 65 6e 63 65 46 69 6e 64 65 72 43 5SentenceFinderC
2380: 62 28 0a 20 20 76 6f 69 64 20 2a 70 43 6f 6e 74 b(. void *pCont
2390: 65 78 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 ext,
23a0: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 /* Pointer
23b0: 74 6f 20 48 69 67 68 6c 69 67 68 74 43 6f 6e 74 to HighlightCont
23c0: 65 78 74 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 ext object */.
23d0: 69 6e 74 20 74 66 6c 61 67 73 2c 20 20 20 20 20 int tflags,
23e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
23f0: 2f 2a 20 4d 61 73 6b 20 6f 66 20 46 54 53 35 5f /* Mask of FTS5_
2400: 54 4f 4b 45 4e 5f 2a 20 66 6c 61 67 73 20 2a 2f TOKEN_* flags */
2410: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 . const char *p
2420: 54 6f 6b 65 6e 2c 20 20 20 20 20 20 20 20 20 20 Token,
2430: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 63 6f 6e /* Buffer con
2440: 74 61 69 6e 69 6e 67 20 74 6f 6b 65 6e 20 2a 2f taining token */
2450: 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 20 . int nToken,
2460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2470: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74 6f /* Size of to
2480: 6b 65 6e 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a ken in bytes */.
2490: 20 20 69 6e 74 20 69 53 74 61 72 74 4f 66 66 2c int iStartOff,
24a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
24b0: 20 20 2f 2a 20 53 74 61 72 74 20 6f 66 66 73 65 /* Start offse
24c0: 74 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 t of token */.
24d0: 69 6e 74 20 69 45 6e 64 4f 66 66 20 20 20 20 20 int iEndOff
24e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
24f0: 2f 2a 20 45 6e 64 20 6f 66 66 73 65 74 20 6f 66 /* End offset of
2500: 20 74 6f 6b 65 6e 20 2a 2f 0a 29 7b 0a 20 20 69 token */.){. i
2510: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f nt rc = SQLITE_O
2520: 4b 3b 0a 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 K;.. UNUSED_PAR
2530: 41 4d 32 28 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b AM2(pToken, nTok
2540: 65 6e 29 3b 0a 20 20 55 4e 55 53 45 44 5f 50 41 en);. UNUSED_PA
2550: 52 41 4d 28 69 45 6e 64 4f 66 66 29 3b 0a 0a 20 RAM(iEndOff);..
2560: 20 69 66 28 20 28 74 66 6c 61 67 73 20 26 20 46 if( (tflags & F
2570: 54 53 35 5f 54 4f 4b 45 4e 5f 43 4f 4c 4f 43 41 TS5_TOKEN_COLOCA
2580: 54 45 44 29 3d 3d 30 20 29 7b 0a 20 20 20 20 46 TED)==0 ){. F
2590: 74 73 35 53 46 69 6e 64 65 72 20 2a 70 20 3d 20 ts5SFinder *p =
25a0: 28 46 74 73 35 53 46 69 6e 64 65 72 2a 29 70 43 (Fts5SFinder*)pC
25b0: 6f 6e 74 65 78 74 3b 0a 20 20 20 20 69 66 28 20 ontext;. if(
25c0: 70 2d 3e 69 50 6f 73 3e 30 20 29 7b 0a 20 20 20 p->iPos>0 ){.
25d0: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 int i;.
25e0: 63 68 61 72 20 63 20 3d 20 30 3b 0a 20 20 20 20 char c = 0;.
25f0: 20 20 66 6f 72 28 69 3d 69 53 74 61 72 74 4f 66 for(i=iStartOf
2600: 66 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29 7b f-1; i>=0; i--){
2610: 0a 20 20 20 20 20 20 20 20 63 20 3d 20 70 2d 3e . c = p->
2620: 7a 44 6f 63 5b 69 5d 3b 0a 20 20 20 20 20 20 20 zDoc[i];.
2630: 20 69 66 28 20 63 21 3d 27 20 27 20 26 26 20 63 if( c!=' ' && c
2640: 21 3d 27 5c 74 27 20 26 26 20 63 21 3d 27 5c 6e !='\t' && c!='\n
2650: 27 20 26 26 20 63 21 3d 27 5c 72 27 20 29 20 62 ' && c!='\r' ) b
2660: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 reak;. }.
2670: 20 20 20 20 69 66 28 20 69 21 3d 69 53 74 61 72 if( i!=iStar
2680: 74 4f 66 66 2d 31 20 26 26 20 28 63 3d 3d 27 2e tOff-1 && (c=='.
2690: 27 20 7c 7c 20 63 3d 3d 27 3a 27 29 20 29 7b 0a ' || c==':') ){.
26a0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 66 74 73 rc = fts
26b0: 35 53 65 6e 74 65 6e 63 65 46 69 6e 64 65 72 41 5SentenceFinderA
26c0: 64 64 28 70 2c 20 70 2d 3e 69 50 6f 73 29 3b 0a dd(p, p->iPos);.
26d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 }. }els
26e0: 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 66 74 e{. rc = ft
26f0: 73 35 53 65 6e 74 65 6e 63 65 46 69 6e 64 65 72 s5SentenceFinder
2700: 41 64 64 28 70 2c 20 30 29 3b 0a 20 20 20 20 7d Add(p, 0);. }
2710: 0a 20 20 20 20 70 2d 3e 69 50 6f 73 2b 2b 3b 0a . p->iPos++;.
2720: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b }. return rc;
2730: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 .}..static int f
2740: 74 73 35 53 6e 69 70 70 65 74 53 63 6f 72 65 28 ts5SnippetScore(
2750: 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45 78 74 . const Fts5Ext
2760: 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c ensionApi *pApi,
2770: 20 20 20 2f 2a 20 41 50 49 20 6f 66 66 65 72 65 /* API offere
2780: 64 20 62 79 20 63 75 72 72 65 6e 74 20 46 54 53 d by current FTS
2790: 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 46 74 version */. Ft
27a0: 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c s5Context *pFts,
27b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
27c0: 20 46 69 72 73 74 20 61 72 67 20 74 6f 20 70 61 First arg to pa
27d0: 73 73 20 74 6f 20 70 41 70 69 20 66 75 6e 63 74 ss to pApi funct
27e0: 69 6f 6e 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 44 ions */. int nD
27f0: 6f 63 73 69 7a 65 2c 20 20 20 20 20 20 20 20 20 ocsize,
2800: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a /* Siz
2810: 65 20 6f 66 20 63 6f 6c 75 6d 6e 20 69 6e 20 74 e of column in t
2820: 6f 6b 65 6e 73 20 2a 2f 0a 20 20 75 6e 73 69 67 okens */. unsig
2830: 6e 65 64 20 63 68 61 72 20 2a 61 53 65 65 6e 2c ned char *aSeen,
2840: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 /* Ar
2850: 72 61 79 20 77 69 74 68 20 6f 6e 65 20 65 6c 65 ray with one ele
2860: 6d 65 6e 74 20 70 65 72 20 71 75 65 72 79 20 70 ment per query p
2870: 68 72 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20 69 hrase */. int i
2880: 43 6f 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 Col,
2890: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f /* Co
28a0: 6c 75 6d 6e 20 74 6f 20 73 63 6f 72 65 20 2a 2f lumn to score */
28b0: 0a 20 20 69 6e 74 20 69 50 6f 73 2c 20 20 20 20 . int iPos,
28c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
28d0: 20 20 20 2f 2a 20 53 74 61 72 74 69 6e 67 20 6f /* Starting o
28e0: 66 66 73 65 74 20 74 6f 20 73 63 6f 72 65 20 2a ffset to score *
28f0: 2f 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20 /. int nToken,
2900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2910: 20 20 20 20 2f 2a 20 4d 61 78 20 74 6f 6b 65 6e /* Max token
2920: 73 20 70 65 72 20 73 6e 69 70 70 65 74 20 2a 2f s per snippet */
2930: 0a 20 20 69 6e 74 20 2a 70 6e 53 63 6f 72 65 2c . int *pnScore,
2940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2950: 20 20 20 2f 2a 20 4f 55 54 3a 20 53 63 6f 72 65 /* OUT: Score
2960: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 69 50 6f 73 */. int *piPos
2970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2980: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 41 64 /* OUT: Ad
2990: 6a 75 73 74 65 64 20 6f 66 66 73 65 74 20 2a 2f justed offset */
29a0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 .){. int rc;.
29b0: 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 69 70 20 int i;. int ip
29c0: 3d 20 30 3b 0a 20 20 69 6e 74 20 69 63 20 3d 20 = 0;. int ic =
29d0: 30 3b 0a 20 20 69 6e 74 20 69 4f 66 66 20 3d 20 0;. int iOff =
29e0: 30 3b 0a 20 20 69 6e 74 20 69 46 69 72 73 74 20 0;. int iFirst
29f0: 3d 20 2d 31 3b 0a 20 20 69 6e 74 20 6e 49 6e 73 = -1;. int nIns
2a00: 74 3b 0a 20 20 69 6e 74 20 6e 53 63 6f 72 65 20 t;. int nScore
2a10: 3d 20 30 3b 0a 20 20 69 6e 74 20 69 4c 61 73 74 = 0;. int iLast
2a20: 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f = 0;. sqlite3_
2a30: 69 6e 74 36 34 20 69 45 6e 64 20 3d 20 28 73 71 int64 iEnd = (sq
2a40: 6c 69 74 65 33 5f 69 6e 74 36 34 29 69 50 6f 73 lite3_int64)iPos
2a50: 20 2b 20 6e 54 6f 6b 65 6e 3b 0a 0a 20 20 72 63 + nToken;.. rc
2a60: 20 3d 20 70 41 70 69 2d 3e 78 49 6e 73 74 43 6f = pApi->xInstCo
2a70: 75 6e 74 28 70 46 74 73 2c 20 26 6e 49 6e 73 74 unt(pFts, &nInst
2a80: 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c );. for(i=0; i<
2a90: 6e 49 6e 73 74 20 26 26 20 72 63 3d 3d 53 51 4c nInst && rc==SQL
2aa0: 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 ITE_OK; i++){.
2ab0: 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 49 6e rc = pApi->xIn
2ac0: 73 74 28 70 46 74 73 2c 20 69 2c 20 26 69 70 2c st(pFts, i, &ip,
2ad0: 20 26 69 63 2c 20 26 69 4f 66 66 29 3b 0a 20 20 &ic, &iOff);.
2ae0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 if( rc==SQLITE
2af0: 5f 4f 4b 20 26 26 20 69 63 3d 3d 69 43 6f 6c 20 _OK && ic==iCol
2b00: 26 26 20 69 4f 66 66 3e 3d 69 50 6f 73 20 26 26 && iOff>=iPos &&
2b10: 20 69 4f 66 66 3c 69 45 6e 64 20 29 7b 0a 20 20 iOff<iEnd ){.
2b20: 20 20 20 20 6e 53 63 6f 72 65 20 2b 3d 20 28 61 nScore += (a
2b30: 53 65 65 6e 5b 69 70 5d 20 3f 20 31 20 3a 20 31 Seen[ip] ? 1 : 1
2b40: 30 30 30 29 3b 0a 20 20 20 20 20 20 61 53 65 65 000);. aSee
2b50: 6e 5b 69 70 5d 20 3d 20 31 3b 0a 20 20 20 20 20 n[ip] = 1;.
2b60: 20 69 66 28 20 69 46 69 72 73 74 3c 30 20 29 20 if( iFirst<0 )
2b70: 69 46 69 72 73 74 20 3d 20 69 4f 66 66 3b 0a 20 iFirst = iOff;.
2b80: 20 20 20 20 20 69 4c 61 73 74 20 3d 20 69 4f 66 iLast = iOf
2b90: 66 20 2b 20 70 41 70 69 2d 3e 78 50 68 72 61 73 f + pApi->xPhras
2ba0: 65 53 69 7a 65 28 70 46 74 73 2c 20 69 70 29 3b eSize(pFts, ip);
2bb0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 . }. }.. *p
2bc0: 6e 53 63 6f 72 65 20 3d 20 6e 53 63 6f 72 65 3b nScore = nScore;
2bd0: 0a 20 20 69 66 28 20 70 69 50 6f 73 20 29 7b 0a . if( piPos ){.
2be0: 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 sqlite3_int6
2bf0: 34 20 69 41 64 6a 20 3d 20 69 46 69 72 73 74 20 4 iAdj = iFirst
2c00: 2d 20 28 6e 54 6f 6b 65 6e 20 2d 20 28 69 4c 61 - (nToken - (iLa
2c10: 73 74 2d 69 46 69 72 73 74 29 29 20 2f 20 32 3b st-iFirst)) / 2;
2c20: 0a 20 20 20 20 69 66 28 20 28 69 41 64 6a 2b 6e . if( (iAdj+n
2c30: 54 6f 6b 65 6e 29 3e 6e 44 6f 63 73 69 7a 65 20 Token)>nDocsize
2c40: 29 20 69 41 64 6a 20 3d 20 6e 44 6f 63 73 69 7a ) iAdj = nDocsiz
2c50: 65 20 2d 20 6e 54 6f 6b 65 6e 3b 0a 20 20 20 20 e - nToken;.
2c60: 69 66 28 20 69 41 64 6a 3c 30 20 29 20 69 41 64 if( iAdj<0 ) iAd
2c70: 6a 20 3d 20 30 3b 0a 20 20 20 20 2a 70 69 50 6f j = 0;. *piPo
2c80: 73 20 3d 20 28 69 6e 74 29 69 41 64 6a 3b 0a 20 s = (int)iAdj;.
2c90: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b }.. return rc;
2ca0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e .}../*.** Return
2cb0: 20 74 68 65 20 76 61 6c 75 65 20 69 6e 20 70 56 the value in pV
2cc0: 61 6c 20 69 6e 74 65 72 70 72 65 74 65 64 20 61 al interpreted a
2cd0: 73 20 75 74 66 2d 38 20 74 65 78 74 2e 20 45 78 s utf-8 text. Ex
2ce0: 63 65 70 74 2c 20 69 66 20 70 56 61 6c 20 0a 2a cept, if pVal .*
2cf0: 2a 20 63 6f 6e 74 61 69 6e 73 20 61 20 4e 55 4c * contains a NUL
2d00: 4c 20 76 61 6c 75 65 2c 20 72 65 74 75 72 6e 20 L value, return
2d10: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 73 a pointer to a s
2d20: 74 61 74 69 63 20 73 74 72 69 6e 67 20 7a 65 72 tatic string zer
2d30: 6f 0a 2a 2a 20 62 79 74 65 73 20 69 6e 20 6c 65 o.** bytes in le
2d40: 6e 67 74 68 20 69 6e 73 74 65 61 64 20 6f 66 20 ngth instead of
2d50: 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2e 0a a NULL pointer..
2d60: 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 */.static const
2d70: 63 68 61 72 20 2a 66 74 73 35 56 61 6c 75 65 54 char *fts5ValueT
2d80: 6f 54 65 78 74 28 73 71 6c 69 74 65 33 5f 76 61 oText(sqlite3_va
2d90: 6c 75 65 20 2a 70 56 61 6c 29 7b 0a 20 20 63 6f lue *pVal){. co
2da0: 6e 73 74 20 63 68 61 72 20 2a 7a 52 65 74 20 3d nst char *zRet =
2db0: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 (const char*)sq
2dc0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 lite3_value_text
2dd0: 28 70 56 61 6c 29 3b 0a 20 20 72 65 74 75 72 6e (pVal);. return
2de0: 20 7a 52 65 74 20 3f 20 7a 52 65 74 20 3a 20 22 zRet ? zRet : "
2df0: 22 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c ";.}../*.** Impl
2e00: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 73 6e ementation of sn
2e10: 69 70 70 65 74 28 29 20 66 75 6e 63 74 69 6f 6e ippet() function
2e20: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 ..*/.static void
2e30: 20 66 74 73 35 53 6e 69 70 70 65 74 46 75 6e 63 fts5SnippetFunc
2e40: 74 69 6f 6e 28 0a 20 20 63 6f 6e 73 74 20 46 74 tion(. const Ft
2e50: 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a s5ExtensionApi *
2e60: 70 41 70 69 2c 20 20 20 2f 2a 20 41 50 49 20 6f pApi, /* API o
2e70: 66 66 65 72 65 64 20 62 79 20 63 75 72 72 65 6e ffered by curren
2e80: 74 20 46 54 53 20 76 65 72 73 69 6f 6e 20 2a 2f t FTS version */
2e90: 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a . Fts5Context *
2ea0: 70 46 74 73 2c 20 20 20 20 20 20 20 20 20 20 20 pFts,
2eb0: 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72 67 20 /* First arg
2ec0: 74 6f 20 70 61 73 73 20 74 6f 20 70 41 70 69 20 to pass to pApi
2ed0: 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 73 functions */. s
2ee0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a qlite3_context *
2ef0: 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 2f pCtx, /
2f00: 2a 20 43 6f 6e 74 65 78 74 20 66 6f 72 20 72 65 * Context for re
2f10: 74 75 72 6e 69 6e 67 20 72 65 73 75 6c 74 2f 65 turning result/e
2f20: 72 72 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 56 rror */. int nV
2f30: 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 al,
2f40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d /* Num
2f50: 62 65 72 20 6f 66 20 76 61 6c 75 65 73 20 69 6e ber of values in
2f60: 20 61 70 56 61 6c 5b 5d 20 61 72 72 61 79 20 2a apVal[] array *
2f70: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 /. sqlite3_valu
2f80: 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20 20 20 e **apVal
2f90: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 /* Array of
2fa0: 74 72 61 69 6c 69 6e 67 20 61 72 67 75 6d 65 6e trailing argumen
2fb0: 74 73 20 2a 2f 0a 29 7b 0a 20 20 48 69 67 68 6c ts */.){. Highl
2fc0: 69 67 68 74 43 6f 6e 74 65 78 74 20 63 74 78 3b ightContext ctx;
2fd0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 . int rc = SQLI
2fe0: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 TE_OK;
2ff0: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 /* Return cod
3000: 65 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 3b e */. int iCol;
3010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
3020: 20 20 20 20 20 20 20 2f 2a 20 31 73 74 20 61 72 /* 1st ar
3030: 67 75 6d 65 6e 74 20 74 6f 20 73 6e 69 70 70 65 gument to snippe
3040: 74 28 29 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 t() */. const c
3050: 68 61 72 20 2a 7a 45 6c 6c 69 70 73 3b 20 20 20 har *zEllips;
3060: 20 20 20 20 20 20 20 20 20 2f 2a 20 34 74 68 20 /* 4th
3070: 61 72 67 75 6d 65 6e 74 20 74 6f 20 73 6e 69 70 argument to snip
3080: 70 65 74 28 29 20 2a 2f 0a 20 20 69 6e 74 20 6e pet() */. int n
3090: 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20 20 20 Token;
30a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 35 74 /* 5t
30b0: 68 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 73 6e h argument to sn
30c0: 69 70 70 65 74 28 29 20 2a 2f 0a 20 20 69 6e 74 ippet() */. int
30d0: 20 6e 49 6e 73 74 20 3d 20 30 3b 20 20 20 20 20 nInst = 0;
30e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
30f0: 4e 75 6d 62 65 72 20 6f 66 20 69 6e 73 74 61 6e Number of instan
3100: 63 65 20 6d 61 74 63 68 65 73 20 74 68 69 73 20 ce matches this
3110: 72 6f 77 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 row */. int i;
3120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
3130: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 /* Used
3140: 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f to iterate thro
3150: 75 67 68 20 69 6e 73 74 61 6e 63 65 73 20 2a 2f ugh instances */
3160: 0a 20 20 69 6e 74 20 6e 50 68 72 61 73 65 3b 20 . int nPhrase;
3170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
3180: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 /* Number of
3190: 70 68 72 61 73 65 73 20 69 6e 20 71 75 65 72 79 phrases in query
31a0: 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 */. unsigned c
31b0: 68 61 72 20 2a 61 53 65 65 6e 3b 20 20 20 20 20 har *aSeen;
31c0: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f /* Array o
31d0: 66 20 22 73 65 65 6e 20 69 6e 73 74 61 6e 63 65 f "seen instance
31e0: 22 20 66 6c 61 67 73 20 2a 2f 0a 20 20 69 6e 74 " flags */. int
31f0: 20 69 42 65 73 74 43 6f 6c 3b 20 20 20 20 20 20 iBestCol;
3200: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
3210: 43 6f 6c 75 6d 6e 20 63 6f 6e 74 61 69 6e 69 6e Column containin
3220: 67 20 62 65 73 74 20 73 6e 69 70 70 65 74 20 2a g best snippet *
3230: 2f 0a 20 20 69 6e 74 20 69 42 65 73 74 53 74 61 /. int iBestSta
3240: 72 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 rt = 0;
3250: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 74 6f 6b /* First tok
3260: 65 6e 20 6f 66 20 62 65 73 74 20 73 6e 69 70 70 en of best snipp
3270: 65 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 65 73 et */. int nBes
3280: 74 53 63 6f 72 65 20 3d 20 30 3b 20 20 20 20 20 tScore = 0;
3290: 20 20 20 20 20 20 20 20 2f 2a 20 53 63 6f 72 65 /* Score
32a0: 20 6f 66 20 62 65 73 74 20 73 6e 69 70 70 65 74 of best snippet
32b0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 53 69 */. int nColSi
32c0: 7a 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 ze = 0;
32d0: 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 73 /* Total s
32e0: 69 7a 65 20 6f 66 20 69 42 65 73 74 43 6f 6c 20 ize of iBestCol
32f0: 69 6e 20 74 6f 6b 65 6e 73 20 2a 2f 0a 20 20 46 in tokens */. F
3300: 74 73 35 53 46 69 6e 64 65 72 20 73 46 69 6e 64 ts5SFinder sFind
3310: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f er; /
3320: 2a 20 55 73 65 64 20 74 6f 20 66 69 6e 64 20 74 * Used to find t
3330: 68 65 20 62 65 67 69 6e 6e 69 6e 67 73 20 6f 66 he beginnings of
3340: 20 73 65 6e 74 65 6e 63 65 73 20 2a 2f 0a 20 20 sentences */.
3350: 69 6e 74 20 6e 43 6f 6c 3b 0a 0a 20 20 69 66 28 int nCol;.. if(
3360: 20 6e 56 61 6c 21 3d 35 20 29 7b 0a 20 20 20 20 nVal!=5 ){.
3370: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 72 72 const char *zErr
3380: 20 3d 20 22 77 72 6f 6e 67 20 6e 75 6d 62 65 72 = "wrong number
3390: 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 74 6f of arguments to
33a0: 20 66 75 6e 63 74 69 6f 6e 20 73 6e 69 70 70 65 function snippe
33b0: 74 28 29 22 3b 0a 20 20 20 20 73 71 6c 69 74 65 t()";. sqlite
33c0: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 70 3_result_error(p
33d0: 43 74 78 2c 20 7a 45 72 72 2c 20 2d 31 29 3b 0a Ctx, zErr, -1);.
33e0: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a return;. }.
33f0: 0a 20 20 6e 43 6f 6c 20 3d 20 70 41 70 69 2d 3e . nCol = pApi->
3400: 78 43 6f 6c 75 6d 6e 43 6f 75 6e 74 28 70 46 74 xColumnCount(pFt
3410: 73 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 63 74 s);. memset(&ct
3420: 78 2c 20 30 2c 20 73 69 7a 65 6f 66 28 48 69 67 x, 0, sizeof(Hig
3430: 68 6c 69 67 68 74 43 6f 6e 74 65 78 74 29 29 3b hlightContext));
3440: 0a 20 20 69 43 6f 6c 20 3d 20 73 71 6c 69 74 65 . iCol = sqlite
3450: 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 70 56 61 3_value_int(apVa
3460: 6c 5b 30 5d 29 3b 0a 20 20 63 74 78 2e 7a 4f 70 l[0]);. ctx.zOp
3470: 65 6e 20 3d 20 66 74 73 35 56 61 6c 75 65 54 6f en = fts5ValueTo
3480: 54 65 78 74 28 61 70 56 61 6c 5b 31 5d 29 3b 0a Text(apVal[1]);.
3490: 20 20 63 74 78 2e 7a 43 6c 6f 73 65 20 3d 20 66 ctx.zClose = f
34a0: 74 73 35 56 61 6c 75 65 54 6f 54 65 78 74 28 61 ts5ValueToText(a
34b0: 70 56 61 6c 5b 32 5d 29 3b 0a 20 20 7a 45 6c 6c pVal[2]);. zEll
34c0: 69 70 73 20 3d 20 66 74 73 35 56 61 6c 75 65 54 ips = fts5ValueT
34d0: 6f 54 65 78 74 28 61 70 56 61 6c 5b 33 5d 29 3b oText(apVal[3]);
34e0: 0a 20 20 6e 54 6f 6b 65 6e 20 3d 20 73 71 6c 69 . nToken = sqli
34f0: 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 70 te3_value_int(ap
3500: 56 61 6c 5b 34 5d 29 3b 0a 0a 20 20 69 42 65 73 Val[4]);.. iBes
3510: 74 43 6f 6c 20 3d 20 28 69 43 6f 6c 3e 3d 30 20 tCol = (iCol>=0
3520: 3f 20 69 43 6f 6c 20 3a 20 30 29 3b 0a 20 20 6e ? iCol : 0);. n
3530: 50 68 72 61 73 65 20 3d 20 70 41 70 69 2d 3e 78 Phrase = pApi->x
3540: 50 68 72 61 73 65 43 6f 75 6e 74 28 70 46 74 73 PhraseCount(pFts
3550: 29 3b 0a 20 20 61 53 65 65 6e 20 3d 20 73 71 6c );. aSeen = sql
3560: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 50 68 72 ite3_malloc(nPhr
3570: 61 73 65 29 3b 0a 20 20 69 66 28 20 61 53 65 65 ase);. if( aSee
3580: 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d n==0 ){. rc =
3590: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 SQLITE_NOMEM;.
35a0: 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c }. if( rc==SQL
35b0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 ITE_OK ){. rc
35c0: 20 3d 20 70 41 70 69 2d 3e 78 49 6e 73 74 43 6f = pApi->xInstCo
35d0: 75 6e 74 28 70 46 74 73 2c 20 26 6e 49 6e 73 74 unt(pFts, &nInst
35e0: 29 3b 0a 20 20 7d 0a 0a 20 20 6d 65 6d 73 65 74 );. }.. memset
35f0: 28 26 73 46 69 6e 64 65 72 2c 20 30 2c 20 73 69 (&sFinder, 0, si
3600: 7a 65 6f 66 28 46 74 73 35 53 46 69 6e 64 65 72 zeof(Fts5SFinder
3610: 29 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 ));. for(i=0; i
3620: 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 <nCol; i++){.
3630: 20 69 66 28 20 69 43 6f 6c 3c 30 20 7c 7c 20 69 if( iCol<0 || i
3640: 43 6f 6c 3d 3d 69 20 29 7b 0a 20 20 20 20 20 20 Col==i ){.
3650: 69 6e 74 20 6e 44 6f 63 3b 0a 20 20 20 20 20 20 int nDoc;.
3660: 69 6e 74 20 6e 44 6f 63 73 69 7a 65 3b 0a 20 20 int nDocsize;.
3670: 20 20 20 20 69 6e 74 20 69 69 3b 0a 20 20 20 20 int ii;.
3680: 20 20 73 46 69 6e 64 65 72 2e 69 50 6f 73 20 3d sFinder.iPos =
3690: 20 30 3b 0a 20 20 20 20 20 20 73 46 69 6e 64 65 0;. sFinde
36a0: 72 2e 6e 46 69 72 73 74 20 3d 20 30 3b 0a 20 20 r.nFirst = 0;.
36b0: 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 rc = pApi->x
36c0: 43 6f 6c 75 6d 6e 54 65 78 74 28 70 46 74 73 2c ColumnText(pFts,
36d0: 20 69 2c 20 26 73 46 69 6e 64 65 72 2e 7a 44 6f i, &sFinder.zDo
36e0: 63 2c 20 26 6e 44 6f 63 29 3b 0a 20 20 20 20 20 c, &nDoc);.
36f0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f if( rc!=SQLITE_
3700: 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 OK ) break;.
3710: 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 54 6f rc = pApi->xTo
3720: 6b 65 6e 69 7a 65 28 70 46 74 73 2c 20 0a 20 20 kenize(pFts, .
3730: 20 20 20 20 20 20 20 20 73 46 69 6e 64 65 72 2e sFinder.
3740: 7a 44 6f 63 2c 20 6e 44 6f 63 2c 20 28 76 6f 69 zDoc, nDoc, (voi
3750: 64 2a 29 26 73 46 69 6e 64 65 72 2c 66 74 73 35 d*)&sFinder,fts5
3760: 53 65 6e 74 65 6e 63 65 46 69 6e 64 65 72 43 62 SentenceFinderCb
3770: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 . );.
3780: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f if( rc!=SQLITE_O
3790: 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 K ) break;.
37a0: 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c rc = pApi->xCol
37b0: 75 6d 6e 53 69 7a 65 28 70 46 74 73 2c 20 69 2c umnSize(pFts, i,
37c0: 20 26 6e 44 6f 63 73 69 7a 65 29 3b 0a 20 20 20 &nDocsize);.
37d0: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 if( rc!=SQLIT
37e0: 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a 20 E_OK ) break;..
37f0: 20 20 20 20 20 66 6f 72 28 69 69 3d 30 3b 20 72 for(ii=0; r
3800: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 c==SQLITE_OK &&
3810: 69 69 3c 6e 49 6e 73 74 3b 20 69 69 2b 2b 29 7b ii<nInst; ii++){
3820: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 70 2c . int ip,
3830: 20 69 63 2c 20 69 6f 3b 0a 20 20 20 20 20 20 20 ic, io;.
3840: 20 69 6e 74 20 69 41 64 6a 3b 0a 20 20 20 20 20 int iAdj;.
3850: 20 20 20 69 6e 74 20 6e 53 63 6f 72 65 3b 0a 20 int nScore;.
3860: 20 20 20 20 20 20 20 69 6e 74 20 6a 6a 3b 0a 0a int jj;..
3870: 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 rc = pAp
3880: 69 2d 3e 78 49 6e 73 74 28 70 46 74 73 2c 20 69 i->xInst(pFts, i
3890: 69 2c 20 26 69 70 2c 20 26 69 63 2c 20 26 69 6f i, &ip, &ic, &io
38a0: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 );. if( i
38b0: 63 21 3d 69 20 29 20 63 6f 6e 74 69 6e 75 65 3b c!=i ) continue;
38c0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 6f 3e . if( io>
38d0: 6e 44 6f 63 73 69 7a 65 20 29 20 72 63 20 3d 20 nDocsize ) rc =
38e0: 46 54 53 35 5f 43 4f 52 52 55 50 54 3b 0a 20 20 FTS5_CORRUPT;.
38f0: 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 if( rc!=SQ
3900: 4c 49 54 45 5f 4f 4b 20 29 20 63 6f 6e 74 69 6e LITE_OK ) contin
3910: 75 65 3b 0a 20 20 20 20 20 20 20 20 6d 65 6d 73 ue;. mems
3920: 65 74 28 61 53 65 65 6e 2c 20 30 2c 20 6e 50 68 et(aSeen, 0, nPh
3930: 72 61 73 65 29 3b 0a 20 20 20 20 20 20 20 20 72 rase);. r
3940: 63 20 3d 20 66 74 73 35 53 6e 69 70 70 65 74 53 c = fts5SnippetS
3950: 63 6f 72 65 28 70 41 70 69 2c 20 70 46 74 73 2c core(pApi, pFts,
3960: 20 6e 44 6f 63 73 69 7a 65 2c 20 61 53 65 65 6e nDocsize, aSeen
3970: 2c 20 69 2c 0a 20 20 20 20 20 20 20 20 20 20 20 , i,.
3980: 20 69 6f 2c 20 6e 54 6f 6b 65 6e 2c 20 26 6e 53 io, nToken, &nS
3990: 63 6f 72 65 2c 20 26 69 41 64 6a 0a 20 20 20 20 core, &iAdj.
39a0: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 69 );. i
39b0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b f( rc==SQLITE_OK
39c0: 20 26 26 20 6e 53 63 6f 72 65 3e 6e 42 65 73 74 && nScore>nBest
39d0: 53 63 6f 72 65 20 29 7b 0a 20 20 20 20 20 20 20 Score ){.
39e0: 20 20 20 6e 42 65 73 74 53 63 6f 72 65 20 3d 20 nBestScore =
39f0: 6e 53 63 6f 72 65 3b 0a 20 20 20 20 20 20 20 20 nScore;.
3a00: 20 20 69 42 65 73 74 43 6f 6c 20 3d 20 69 3b 0a iBestCol = i;.
3a10: 20 20 20 20 20 20 20 20 20 20 69 42 65 73 74 53 iBestS
3a20: 74 61 72 74 20 3d 20 69 41 64 6a 3b 0a 20 20 20 tart = iAdj;.
3a30: 20 20 20 20 20 20 20 6e 43 6f 6c 53 69 7a 65 20 nColSize
3a40: 3d 20 6e 44 6f 63 73 69 7a 65 3b 0a 20 20 20 20 = nDocsize;.
3a50: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 69 }.. i
3a60: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b f( rc==SQLITE_OK
3a70: 20 26 26 20 73 46 69 6e 64 65 72 2e 6e 46 69 72 && sFinder.nFir
3a80: 73 74 20 26 26 20 6e 44 6f 63 73 69 7a 65 3e 6e st && nDocsize>n
3a90: 54 6f 6b 65 6e 20 29 7b 0a 20 20 20 20 20 20 20 Token ){.
3aa0: 20 20 20 66 6f 72 28 6a 6a 3d 30 3b 20 6a 6a 3c for(jj=0; jj<
3ab0: 28 73 46 69 6e 64 65 72 2e 6e 46 69 72 73 74 2d (sFinder.nFirst-
3ac0: 31 29 3b 20 6a 6a 2b 2b 29 7b 0a 20 20 20 20 20 1); jj++){.
3ad0: 20 20 20 20 20 20 20 69 66 28 20 73 46 69 6e 64 if( sFind
3ae0: 65 72 2e 61 46 69 72 73 74 5b 6a 6a 2b 31 5d 3e er.aFirst[jj+1]>
3af0: 69 6f 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 io ) break;.
3b00: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 }..
3b10: 20 20 20 69 66 28 20 73 46 69 6e 64 65 72 2e 61 if( sFinder.a
3b20: 46 69 72 73 74 5b 6a 6a 5d 3c 69 6f 20 29 7b 0a First[jj]<io ){.
3b30: 20 20 20 20 20 20 20 20 20 20 20 20 6d 65 6d 73 mems
3b40: 65 74 28 61 53 65 65 6e 2c 20 30 2c 20 6e 50 68 et(aSeen, 0, nPh
3b50: 72 61 73 65 29 3b 0a 20 20 20 20 20 20 20 20 20 rase);.
3b60: 20 20 20 72 63 20 3d 20 66 74 73 35 53 6e 69 70 rc = fts5Snip
3b70: 70 65 74 53 63 6f 72 65 28 70 41 70 69 2c 20 70 petScore(pApi, p
3b80: 46 74 73 2c 20 6e 44 6f 63 73 69 7a 65 2c 20 61 Fts, nDocsize, a
3b90: 53 65 65 6e 2c 20 69 2c 20 0a 20 20 20 20 20 20 Seen, i, .
3ba0: 20 20 20 20 20 20 20 20 73 46 69 6e 64 65 72 2e sFinder.
3bb0: 61 46 69 72 73 74 5b 6a 6a 5d 2c 20 6e 54 6f 6b aFirst[jj], nTok
3bc0: 65 6e 2c 20 26 6e 53 63 6f 72 65 2c 20 30 0a 20 en, &nScore, 0.
3bd0: 20 20 20 20 20 20 20 20 20 20 20 29 3b 0a 0a 20 );..
3be0: 20 20 20 20 20 20 20 20 20 20 20 6e 53 63 6f 72 nScor
3bf0: 65 20 2b 3d 20 28 73 46 69 6e 64 65 72 2e 61 46 e += (sFinder.aF
3c00: 69 72 73 74 5b 6a 6a 5d 3d 3d 30 20 3f 20 31 32 irst[jj]==0 ? 12
3c10: 30 20 3a 20 31 30 30 29 3b 0a 20 20 20 20 20 20 0 : 100);.
3c20: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 if( rc==SQ
3c30: 4c 49 54 45 5f 4f 4b 20 26 26 20 6e 53 63 6f 72 LITE_OK && nScor
3c40: 65 3e 6e 42 65 73 74 53 63 6f 72 65 20 29 7b 0a e>nBestScore ){.
3c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 42 nB
3c60: 65 73 74 53 63 6f 72 65 20 3d 20 6e 53 63 6f 72 estScore = nScor
3c70: 65 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 e;.
3c80: 20 69 42 65 73 74 43 6f 6c 20 3d 20 69 3b 0a 20 iBestCol = i;.
3c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 42 65 iBe
3ca0: 73 74 53 74 61 72 74 20 3d 20 73 46 69 6e 64 65 stStart = sFinde
3cb0: 72 2e 61 46 69 72 73 74 5b 6a 6a 5d 3b 0a 20 20 r.aFirst[jj];.
3cc0: 20 20 20 20 20 20 20 20 20 20 20 20 6e 43 6f 6c nCol
3cd0: 53 69 7a 65 20 3d 20 6e 44 6f 63 73 69 7a 65 3b Size = nDocsize;
3ce0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 . }.
3cf0: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 }.
3d00: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 }. }.
3d10: 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 }. }.. if( rc
3d20: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 ==SQLITE_OK ){.
3d30: 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 43 rc = pApi->xC
3d40: 6f 6c 75 6d 6e 54 65 78 74 28 70 46 74 73 2c 20 olumnText(pFts,
3d50: 69 42 65 73 74 43 6f 6c 2c 20 26 63 74 78 2e 7a iBestCol, &ctx.z
3d60: 49 6e 2c 20 26 63 74 78 2e 6e 49 6e 29 3b 0a 20 In, &ctx.nIn);.
3d70: 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c }. if( rc==SQL
3d80: 49 54 45 5f 4f 4b 20 26 26 20 6e 43 6f 6c 53 69 ITE_OK && nColSi
3d90: 7a 65 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 ze==0 ){. rc
3da0: 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e 53 = pApi->xColumnS
3db0: 69 7a 65 28 70 46 74 73 2c 20 69 42 65 73 74 43 ize(pFts, iBestC
3dc0: 6f 6c 2c 20 26 6e 43 6f 6c 53 69 7a 65 29 3b 0a ol, &nColSize);.
3dd0: 20 20 7d 0a 20 20 69 66 28 20 63 74 78 2e 7a 49 }. if( ctx.zI
3de0: 6e 20 29 7b 0a 20 20 20 20 69 66 28 20 72 63 3d n ){. if( rc=
3df0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 =SQLITE_OK ){.
3e00: 20 20 20 20 72 63 20 3d 20 66 74 73 35 43 49 6e rc = fts5CIn
3e10: 73 74 49 74 65 72 49 6e 69 74 28 70 41 70 69 2c stIterInit(pApi,
3e20: 20 70 46 74 73 2c 20 69 42 65 73 74 43 6f 6c 2c pFts, iBestCol,
3e30: 20 26 63 74 78 2e 69 74 65 72 29 3b 0a 20 20 20 &ctx.iter);.
3e40: 20 7d 0a 0a 20 20 20 20 63 74 78 2e 69 52 61 6e }.. ctx.iRan
3e50: 67 65 53 74 61 72 74 20 3d 20 69 42 65 73 74 53 geStart = iBestS
3e60: 74 61 72 74 3b 0a 20 20 20 20 63 74 78 2e 69 52 tart;. ctx.iR
3e70: 61 6e 67 65 45 6e 64 20 3d 20 69 42 65 73 74 53 angeEnd = iBestS
3e80: 74 61 72 74 20 2b 20 6e 54 6f 6b 65 6e 20 2d 20 tart + nToken -
3e90: 31 3b 0a 0a 20 20 20 20 69 66 28 20 69 42 65 73 1;.. if( iBes
3ea0: 74 53 74 61 72 74 3e 30 20 29 7b 0a 20 20 20 20 tStart>0 ){.
3eb0: 20 20 66 74 73 35 48 69 67 68 6c 69 67 68 74 41 fts5HighlightA
3ec0: 70 70 65 6e 64 28 26 72 63 2c 20 26 63 74 78 2c ppend(&rc, &ctx,
3ed0: 20 7a 45 6c 6c 69 70 73 2c 20 2d 31 29 3b 0a 20 zEllips, -1);.
3ee0: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 41 64 76 }.. /* Adv
3ef0: 61 6e 63 65 20 69 74 65 72 61 74 6f 72 20 63 74 ance iterator ct
3f00: 78 2e 69 74 65 72 20 73 6f 20 74 68 61 74 20 69 x.iter so that i
3f10: 74 20 70 6f 69 6e 74 73 20 74 6f 20 74 68 65 20 t points to the
3f20: 66 69 72 73 74 20 63 6f 61 6c 65 73 63 65 64 0a first coalesced.
3f30: 20 20 20 20 2a 2a 20 70 68 72 61 73 65 20 69 6e ** phrase in
3f40: 73 74 61 6e 63 65 20 61 74 20 6f 72 20 66 6f 6c stance at or fol
3f50: 6c 6f 77 69 6e 67 20 70 6f 73 69 74 69 6f 6e 20 lowing position
3f60: 69 42 65 73 74 53 74 61 72 74 2e 20 2a 2f 0a 20 iBestStart. */.
3f70: 20 20 20 77 68 69 6c 65 28 20 63 74 78 2e 69 74 while( ctx.it
3f80: 65 72 2e 69 53 74 61 72 74 3e 3d 30 20 26 26 20 er.iStart>=0 &&
3f90: 63 74 78 2e 69 74 65 72 2e 69 53 74 61 72 74 3c ctx.iter.iStart<
3fa0: 69 42 65 73 74 53 74 61 72 74 20 26 26 20 72 63 iBestStart && rc
3fb0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 ==SQLITE_OK ){.
3fc0: 20 20 20 20 20 72 63 20 3d 20 66 74 73 35 43 49 rc = fts5CI
3fd0: 6e 73 74 49 74 65 72 4e 65 78 74 28 26 63 74 78 nstIterNext(&ctx
3fe0: 2e 69 74 65 72 29 3b 0a 20 20 20 20 7d 0a 0a 20 .iter);. }..
3ff0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 if( rc==SQLIT
4000: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 E_OK ){. rc
4010: 20 3d 20 70 41 70 69 2d 3e 78 54 6f 6b 65 6e 69 = pApi->xTokeni
4020: 7a 65 28 70 46 74 73 2c 20 63 74 78 2e 7a 49 6e ze(pFts, ctx.zIn
4030: 2c 20 63 74 78 2e 6e 49 6e 2c 20 28 76 6f 69 64 , ctx.nIn, (void
4040: 2a 29 26 63 74 78 2c 66 74 73 35 48 69 67 68 6c *)&ctx,fts5Highl
4050: 69 67 68 74 43 62 29 3b 0a 20 20 20 20 7d 0a 20 ightCb);. }.
4060: 20 20 20 69 66 28 20 63 74 78 2e 69 52 61 6e 67 if( ctx.iRang
4070: 65 45 6e 64 3e 3d 28 6e 43 6f 6c 53 69 7a 65 2d eEnd>=(nColSize-
4080: 31 29 20 29 7b 0a 20 20 20 20 20 20 66 74 73 35 1) ){. fts5
4090: 48 69 67 68 6c 69 67 68 74 41 70 70 65 6e 64 28 HighlightAppend(
40a0: 26 72 63 2c 20 26 63 74 78 2c 20 26 63 74 78 2e &rc, &ctx, &ctx.
40b0: 7a 49 6e 5b 63 74 78 2e 69 4f 66 66 5d 2c 20 63 zIn[ctx.iOff], c
40c0: 74 78 2e 6e 49 6e 20 2d 20 63 74 78 2e 69 4f 66 tx.nIn - ctx.iOf
40d0: 66 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 f);. }else{.
40e0: 20 20 20 20 20 66 74 73 35 48 69 67 68 6c 69 67 fts5Highlig
40f0: 68 74 41 70 70 65 6e 64 28 26 72 63 2c 20 26 63 htAppend(&rc, &c
4100: 74 78 2c 20 7a 45 6c 6c 69 70 73 2c 20 2d 31 29 tx, zEllips, -1)
4110: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 ;. }. }. if
4120: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 ( rc==SQLITE_OK
4130: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 ){. sqlite3_r
4140: 65 73 75 6c 74 5f 74 65 78 74 28 70 43 74 78 2c esult_text(pCtx,
4150: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 63 74 (const char*)ct
4160: 78 2e 7a 4f 75 74 2c 20 2d 31 2c 20 53 51 4c 49 x.zOut, -1, SQLI
4170: 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 TE_TRANSIENT);.
4180: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 }else{. sqli
4190: 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 te3_result_error
41a0: 5f 63 6f 64 65 28 70 43 74 78 2c 20 72 63 29 3b _code(pCtx, rc);
41b0: 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 . }. sqlite3_f
41c0: 72 65 65 28 63 74 78 2e 7a 4f 75 74 29 3b 0a 20 ree(ctx.zOut);.
41d0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 53 sqlite3_free(aS
41e0: 65 65 6e 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f een);. sqlite3_
41f0: 66 72 65 65 28 73 46 69 6e 64 65 72 2e 61 46 69 free(sFinder.aFi
4200: 72 73 74 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a rst);.}../******
4210: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
4220: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
4230: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
4240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
4250: 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 **/../*.** The f
4260: 69 72 73 74 20 74 69 6d 65 20 74 68 65 20 62 6d irst time the bm
4270: 32 35 28 29 20 66 75 6e 63 74 69 6f 6e 20 69 73 25() function is
4280: 20 63 61 6c 6c 65 64 20 66 6f 72 20 61 20 71 75 called for a qu
4290: 65 72 79 2c 20 61 6e 20 69 6e 73 74 61 6e 63 65 ery, an instance
42a0: 0a 2a 2a 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f .** of the follo
42b0: 77 69 6e 67 20 73 74 72 75 63 74 75 72 65 20 69 wing structure i
42c0: 73 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e 64 20 s allocated and
42d0: 70 6f 70 75 6c 61 74 65 64 2e 0a 2a 2f 0a 74 79 populated..*/.ty
42e0: 70 65 64 65 66 20 73 74 72 75 63 74 20 46 74 73 pedef struct Fts
42f0: 35 42 6d 32 35 44 61 74 61 20 46 74 73 35 42 6d 5Bm25Data Fts5Bm
4300: 32 35 44 61 74 61 3b 0a 73 74 72 75 63 74 20 46 25Data;.struct F
4310: 74 73 35 42 6d 32 35 44 61 74 61 20 7b 0a 20 20 ts5Bm25Data {.
4320: 69 6e 74 20 6e 50 68 72 61 73 65 3b 20 20 20 20 int nPhrase;
4330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4340: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 68 72 /* Number of phr
4350: 61 73 65 73 20 69 6e 20 71 75 65 72 79 20 2a 2f ases in query */
4360: 0a 20 20 64 6f 75 62 6c 65 20 61 76 67 64 6c 3b . double avgdl;
4370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4380: 20 20 20 2f 2a 20 41 76 65 72 61 67 65 20 6e 75 /* Average nu
4390: 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73 20 69 mber of tokens i
43a0: 6e 20 65 61 63 68 20 72 6f 77 20 2a 2f 0a 20 20 n each row */.
43b0: 64 6f 75 62 6c 65 20 2a 61 49 44 46 3b 20 20 20 double *aIDF;
43c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
43d0: 2f 2a 20 49 44 46 20 66 6f 72 20 65 61 63 68 20 /* IDF for each
43e0: 70 68 72 61 73 65 20 2a 2f 0a 20 20 64 6f 75 62 phrase */. doub
43f0: 6c 65 20 2a 61 46 72 65 71 3b 20 20 20 20 20 20 le *aFreq;
4400: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 /* A
4410: 72 72 61 79 20 75 73 65 64 20 74 6f 20 63 61 6c rray used to cal
4420: 63 75 6c 61 74 65 20 70 68 72 61 73 65 20 66 72 culate phrase fr
4430: 65 71 2e 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a eq. */.};../*.**
4440: 20 43 61 6c 6c 62 61 63 6b 20 75 73 65 64 20 62 Callback used b
4450: 79 20 66 74 73 35 42 6d 32 35 47 65 74 44 61 74 y fts5Bm25GetDat
4460: 61 28 29 20 74 6f 20 63 6f 75 6e 74 20 74 68 65 a() to count the
4470: 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 20 number of rows
4480: 69 6e 20 74 68 65 0a 2a 2a 20 74 61 62 6c 65 20 in the.** table
4490: 6d 61 74 63 68 65 64 20 62 79 20 65 61 63 68 20 matched by each
44a0: 69 6e 64 69 76 69 64 75 61 6c 20 70 68 72 61 73 individual phras
44b0: 65 20 77 69 74 68 69 6e 20 74 68 65 20 71 75 65 e within the que
44c0: 72 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e ry..*/.static in
44d0: 74 20 66 74 73 35 43 6f 75 6e 74 43 62 28 0a 20 t fts5CountCb(.
44e0: 20 63 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e const Fts5Exten
44f0: 73 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c 20 0a sionApi *pApi, .
4500: 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 Fts5Context *p
4510: 46 74 73 2c 0a 20 20 76 6f 69 64 20 2a 70 55 73 Fts,. void *pUs
4520: 65 72 44 61 74 61 20 20 20 20 20 20 20 20 20 20 erData
4530: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 /* Pointe
4540: 72 20 74 6f 20 73 71 6c 69 74 65 33 5f 69 6e 74 r to sqlite3_int
4550: 36 34 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 29 64 variable */.)
4560: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 {. sqlite3_int6
4570: 34 20 2a 70 6e 20 3d 20 28 73 71 6c 69 74 65 33 4 *pn = (sqlite3
4580: 5f 69 6e 74 36 34 2a 29 70 55 73 65 72 44 61 74 _int64*)pUserDat
4590: 61 3b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41 a;. UNUSED_PARA
45a0: 4d 32 28 70 41 70 69 2c 20 70 46 74 73 29 3b 0a M2(pApi, pFts);.
45b0: 20 20 28 2a 70 6e 29 2b 2b 3b 0a 20 20 72 65 74 (*pn)++;. ret
45c0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d urn SQLITE_OK;.}
45d0: 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 2a 70 70 44 ../*.** Set *ppD
45e0: 61 74 61 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 ata to point to
45f0: 74 68 65 20 46 74 73 35 42 6d 32 35 44 61 74 61 the Fts5Bm25Data
4600: 20 6f 62 6a 65 63 74 20 66 6f 72 20 74 68 65 20 object for the
4610: 63 75 72 72 65 6e 74 20 71 75 65 72 79 2e 20 0a current query. .
4620: 2a 2a 20 49 66 20 74 68 65 20 6f 62 6a 65 63 74 ** If the object
4630: 20 68 61 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 has not already
4640: 20 62 65 65 6e 20 61 6c 6c 6f 63 61 74 65 64 2c been allocated,
4650: 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64 20 70 6f allocate and po
4660: 70 75 6c 61 74 65 20 69 74 0a 2a 2a 20 6e 6f 77 pulate it.** now
4670: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 ..*/.static int
4680: 66 74 73 35 42 6d 32 35 47 65 74 44 61 74 61 28 fts5Bm25GetData(
4690: 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45 78 74 . const Fts5Ext
46a0: 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c ensionApi *pApi,
46b0: 20 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 . Fts5Context
46c0: 2a 70 46 74 73 2c 0a 20 20 46 74 73 35 42 6d 32 *pFts,. Fts5Bm2
46d0: 35 44 61 74 61 20 2a 2a 70 70 44 61 74 61 20 20 5Data **ppData
46e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a /* OUT:
46f0: 20 62 6d 32 35 2d 64 61 74 61 20 6f 62 6a 65 63 bm25-data objec
4700: 74 20 66 6f 72 20 74 68 69 73 20 71 75 65 72 79 t for this query
4710: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 */.){. int rc
4720: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 = SQLITE_OK;
4730: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 /* Retu
4740: 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 46 74 73 rn code */. Fts
4750: 35 42 6d 32 35 44 61 74 61 20 2a 70 3b 20 20 20 5Bm25Data *p;
4760: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
4770: 4f 62 6a 65 63 74 20 74 6f 20 72 65 74 75 72 6e Object to return
4780: 20 2a 2f 0a 0a 20 20 70 20 3d 20 70 41 70 69 2d */.. p = pApi-
4790: 3e 78 47 65 74 41 75 78 64 61 74 61 28 70 46 74 >xGetAuxdata(pFt
47a0: 73 2c 20 30 29 3b 0a 20 20 69 66 28 20 70 3d 3d s, 0);. if( p==
47b0: 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 50 68 0 ){. int nPh
47c0: 72 61 73 65 3b 20 20 20 20 20 20 20 20 20 20 20 rase;
47d0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 /* Number
47e0: 20 6f 66 20 70 68 72 61 73 65 73 20 69 6e 20 71 of phrases in q
47f0: 75 65 72 79 20 2a 2f 0a 20 20 20 20 73 71 6c 69 uery */. sqli
4800: 74 65 33 5f 69 6e 74 36 34 20 6e 52 6f 77 20 3d te3_int64 nRow =
4810: 20 30 3b 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 0; /* Num
4820: 62 65 72 20 6f 66 20 72 6f 77 73 20 69 6e 20 74 ber of rows in t
4830: 61 62 6c 65 20 2a 2f 0a 20 20 20 20 73 71 6c 69 able */. sqli
4840: 74 65 33 5f 69 6e 74 36 34 20 6e 54 6f 6b 65 6e te3_int64 nToken
4850: 20 3d 20 30 3b 20 20 20 20 20 2f 2a 20 4e 75 6d = 0; /* Num
4860: 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73 20 69 6e ber of tokens in
4870: 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 73 71 table */. sq
4880: 6c 69 74 65 33 5f 69 6e 74 36 34 20 6e 42 79 74 lite3_int64 nByt
4890: 65 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 e; /* B
48a0: 79 74 65 73 20 6f 66 20 73 70 61 63 65 20 74 6f ytes of space to
48b0: 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 20 allocate */.
48c0: 20 69 6e 74 20 69 3b 0a 0a 20 20 20 20 2f 2a 20 int i;.. /*
48d0: 41 6c 6c 6f 63 61 74 65 20 74 68 65 20 46 74 73 Allocate the Fts
48e0: 35 42 6d 32 35 44 61 74 61 20 6f 62 6a 65 63 74 5Bm25Data object
48f0: 20 2a 2f 0a 20 20 20 20 6e 50 68 72 61 73 65 20 */. nPhrase
4900: 3d 20 70 41 70 69 2d 3e 78 50 68 72 61 73 65 43 = pApi->xPhraseC
4910: 6f 75 6e 74 28 70 46 74 73 29 3b 0a 20 20 20 20 ount(pFts);.
4920: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 46 nByte = sizeof(F
4930: 74 73 35 42 6d 32 35 44 61 74 61 29 20 2b 20 6e ts5Bm25Data) + n
4940: 50 68 72 61 73 65 2a 32 2a 73 69 7a 65 6f 66 28 Phrase*2*sizeof(
4950: 64 6f 75 62 6c 65 29 3b 0a 20 20 20 20 70 20 3d double);. p =
4960: 20 28 46 74 73 35 42 6d 32 35 44 61 74 61 2a 29 (Fts5Bm25Data*)
4970: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34 sqlite3_malloc64
4980: 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 (nByte);. if(
4990: 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 p==0 ){. r
49a0: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d c = SQLITE_NOMEM
49b0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 ;. }else{.
49c0: 20 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 memset(p, 0,
49d0: 28 73 69 7a 65 5f 74 29 6e 42 79 74 65 29 3b 0a (size_t)nByte);.
49e0: 20 20 20 20 20 20 70 2d 3e 6e 50 68 72 61 73 65 p->nPhrase
49f0: 20 3d 20 6e 50 68 72 61 73 65 3b 0a 20 20 20 20 = nPhrase;.
4a00: 20 20 70 2d 3e 61 49 44 46 20 3d 20 28 64 6f 75 p->aIDF = (dou
4a10: 62 6c 65 2a 29 26 70 5b 31 5d 3b 0a 20 20 20 20 ble*)&p[1];.
4a20: 20 20 70 2d 3e 61 46 72 65 71 20 3d 20 26 70 2d p->aFreq = &p-
4a30: 3e 61 49 44 46 5b 6e 50 68 72 61 73 65 5d 3b 0a >aIDF[nPhrase];.
4a40: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 61 }.. /* Ca
4a50: 6c 63 75 6c 61 74 65 20 74 68 65 20 61 76 65 72 lculate the aver
4a60: 61 67 65 20 64 6f 63 75 6d 65 6e 74 20 6c 65 6e age document len
4a70: 67 74 68 20 66 6f 72 20 74 68 69 73 20 46 54 53 gth for this FTS
4a80: 35 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 69 5 table */. i
4a90: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b f( rc==SQLITE_OK
4aa0: 20 29 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 52 ) rc = pApi->xR
4ab0: 6f 77 43 6f 75 6e 74 28 70 46 74 73 2c 20 26 6e owCount(pFts, &n
4ac0: 52 6f 77 29 3b 0a 20 20 20 20 61 73 73 65 72 74 Row);. assert
4ad0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 ( rc!=SQLITE_OK
4ae0: 7c 7c 20 6e 52 6f 77 3e 30 20 29 3b 0a 20 20 20 || nRow>0 );.
4af0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f if( rc==SQLITE_
4b00: 4f 4b 20 29 20 72 63 20 3d 20 70 41 70 69 2d 3e OK ) rc = pApi->
4b10: 78 43 6f 6c 75 6d 6e 54 6f 74 61 6c 53 69 7a 65 xColumnTotalSize
4b20: 28 70 46 74 73 2c 20 2d 31 2c 20 26 6e 54 6f 6b (pFts, -1, &nTok
4b30: 65 6e 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d en);. if( rc=
4b40: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 70 2d 3e =SQLITE_OK ) p->
4b50: 61 76 67 64 6c 20 3d 20 28 64 6f 75 62 6c 65 29 avgdl = (double)
4b60: 6e 54 6f 6b 65 6e 20 20 2f 20 28 64 6f 75 62 6c nToken / (doubl
4b70: 65 29 6e 52 6f 77 3b 0a 0a 20 20 20 20 2f 2a 20 e)nRow;.. /*
4b80: 43 61 6c 63 75 6c 61 74 65 20 61 6e 20 49 44 46 Calculate an IDF
4b90: 20 66 6f 72 20 65 61 63 68 20 70 68 72 61 73 65 for each phrase
4ba0: 20 69 6e 20 74 68 65 20 71 75 65 72 79 20 2a 2f in the query */
4bb0: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 . for(i=0; rc
4bc0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 ==SQLITE_OK && i
4bd0: 3c 6e 50 68 72 61 73 65 3b 20 69 2b 2b 29 7b 0a <nPhrase; i++){.
4be0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e sqlite3_in
4bf0: 74 36 34 20 6e 48 69 74 20 3d 20 30 3b 0a 20 20 t64 nHit = 0;.
4c00: 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 rc = pApi->x
4c10: 51 75 65 72 79 50 68 72 61 73 65 28 70 46 74 73 QueryPhrase(pFts
4c20: 2c 20 69 2c 20 28 76 6f 69 64 2a 29 26 6e 48 69 , i, (void*)&nHi
4c30: 74 2c 20 66 74 73 35 43 6f 75 6e 74 43 62 29 3b t, fts5CountCb);
4c40: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 . if( rc==S
4c50: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 QLITE_OK ){.
4c60: 20 20 20 20 2f 2a 20 43 61 6c 63 75 6c 61 74 65 /* Calculate
4c70: 20 74 68 65 20 49 44 46 20 28 49 6e 76 65 72 73 the IDF (Invers
4c80: 65 20 44 6f 63 75 6d 65 6e 74 20 46 72 65 71 75 e Document Frequ
4c90: 65 6e 63 79 29 20 66 6f 72 20 70 68 72 61 73 65 ency) for phrase
4ca0: 20 69 2e 0a 20 20 20 20 20 20 20 20 2a 2a 20 54 i.. ** T
4cb0: 68 69 73 20 69 73 20 64 6f 6e 65 20 75 73 69 6e his is done usin
4cc0: 67 20 74 68 65 20 73 74 61 6e 64 61 72 64 20 42 g the standard B
4cd0: 4d 32 35 20 66 6f 72 6d 75 6c 61 20 61 73 20 66 M25 formula as f
4ce0: 6f 75 6e 64 20 6f 6e 20 77 69 6b 69 70 65 64 69 ound on wikipedi
4cf0: 61 3a 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20 a:. **.
4d00: 20 20 20 20 20 20 2a 2a 20 20 20 49 44 46 20 3d ** IDF =
4d10: 20 6c 6f 67 28 20 28 4e 20 2d 20 6e 48 69 74 20 log( (N - nHit
4d20: 2b 20 30 2e 35 29 20 2f 20 28 6e 48 69 74 20 2b + 0.5) / (nHit +
4d30: 20 30 2e 35 29 20 29 0a 20 20 20 20 20 20 20 20 0.5) ).
4d40: 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 77 68 **. ** wh
4d50: 65 72 65 20 22 4e 22 20 69 73 20 74 68 65 20 74 ere "N" is the t
4d60: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 64 otal number of d
4d70: 6f 63 75 6d 65 6e 74 73 20 69 6e 20 74 68 65 20 ocuments in the
4d80: 73 65 74 20 61 6e 64 20 6e 48 69 74 0a 20 20 20 set and nHit.
4d90: 20 20 20 20 20 2a 2a 20 69 73 20 74 68 65 20 6e ** is the n
4da0: 75 6d 62 65 72 20 74 68 61 74 20 63 6f 6e 74 61 umber that conta
4db0: 69 6e 20 61 74 20 6c 65 61 73 74 20 6f 6e 65 20 in at least one
4dc0: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 instance of the
4dd0: 70 68 72 61 73 65 0a 20 20 20 20 20 20 20 20 2a phrase. *
4de0: 2a 20 75 6e 64 65 72 20 63 6f 6e 73 69 64 65 72 * under consider
4df0: 61 74 69 6f 6e 2e 0a 20 20 20 20 20 20 20 20 2a ation.. *
4e00: 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 54 68 65 *. ** The
4e10: 20 70 72 6f 62 6c 65 6d 20 77 69 74 68 20 74 68 problem with th
4e20: 69 73 20 69 73 20 74 68 61 74 20 69 66 20 28 4e is is that if (N
4e30: 20 3c 20 32 2a 6e 48 69 74 29 2c 20 74 68 65 20 < 2*nHit), the
4e40: 49 44 46 20 69 73 20 0a 20 20 20 20 20 20 20 20 IDF is .
4e50: 2a 2a 20 6e 65 67 61 74 69 76 65 2e 20 57 68 69 ** negative. Whi
4e60: 63 68 20 69 73 20 75 6e 64 65 73 69 72 61 62 6c ch is undesirabl
4e70: 65 2e 20 53 6f 20 74 68 65 20 6d 69 6d 69 6d 75 e. So the mimimu
4e80: 6d 20 61 6c 6c 6f 77 61 62 6c 65 20 49 44 46 20 m allowable IDF
4e90: 69 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 28 31 is. ** (1
4ea0: 65 2d 36 29 20 2d 20 72 6f 75 67 68 6c 79 20 74 e-6) - roughly t
4eb0: 68 65 20 73 61 6d 65 20 61 73 20 61 20 74 65 72 he same as a ter
4ec0: 6d 20 74 68 61 74 20 61 70 70 65 61 72 73 20 69 m that appears i
4ed0: 6e 20 6a 75 73 74 20 6f 76 65 72 0a 20 20 20 20 n just over.
4ee0: 20 20 20 20 2a 2a 20 68 61 6c 66 20 6f 66 20 73 ** half of s
4ef0: 65 74 20 6f 66 20 35 2c 30 30 30 2c 30 30 30 20 et of 5,000,000
4f00: 64 6f 63 75 6d 65 6e 74 73 2e 20 20 2a 2f 0a 20 documents. */.
4f10: 20 20 20 20 20 20 20 64 6f 75 62 6c 65 20 69 64 double id
4f20: 66 20 3d 20 6c 6f 67 28 20 28 6e 52 6f 77 20 2d f = log( (nRow -
4f30: 20 6e 48 69 74 20 2b 20 30 2e 35 29 20 2f 20 28 nHit + 0.5) / (
4f40: 6e 48 69 74 20 2b 20 30 2e 35 29 20 29 3b 0a 20 nHit + 0.5) );.
4f50: 20 20 20 20 20 20 20 69 66 28 20 69 64 66 3c 3d if( idf<=
4f60: 30 2e 30 20 29 20 69 64 66 20 3d 20 31 65 2d 36 0.0 ) idf = 1e-6
4f70: 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e 61 49 44 ;. p->aID
4f80: 46 5b 69 5d 20 3d 20 69 64 66 3b 0a 20 20 20 20 F[i] = idf;.
4f90: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 }. }.. i
4fa0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b f( rc!=SQLITE_OK
4fb0: 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 ){. sqlite
4fc0: 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20 7d 3_free(p);. }
4fd0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d else{. rc =
4fe0: 20 70 41 70 69 2d 3e 78 53 65 74 41 75 78 64 61 pApi->xSetAuxda
4ff0: 74 61 28 70 46 74 73 2c 20 70 2c 20 73 71 6c 69 ta(pFts, p, sqli
5000: 74 65 33 5f 66 72 65 65 29 3b 0a 20 20 20 20 7d te3_free);. }
5010: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c . if( rc!=SQL
5020: 49 54 45 5f 4f 4b 20 29 20 70 20 3d 20 30 3b 0a ITE_OK ) p = 0;.
5030: 20 20 7d 0a 20 20 2a 70 70 44 61 74 61 20 3d 20 }. *ppData =
5040: 70 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a p;. return rc;.
5050: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 }../*.** Impleme
5060: 6e 74 61 74 69 6f 6e 20 6f 66 20 62 6d 32 35 28 ntation of bm25(
5070: 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 ) function..*/.s
5080: 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 42 tatic void fts5B
5090: 6d 32 35 46 75 6e 63 74 69 6f 6e 28 0a 20 20 63 m25Function(. c
50a0: 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73 69 onst Fts5Extensi
50b0: 6f 6e 41 70 69 20 2a 70 41 70 69 2c 20 20 20 2f onApi *pApi, /
50c0: 2a 20 41 50 49 20 6f 66 66 65 72 65 64 20 62 79 * API offered by
50d0: 20 63 75 72 72 65 6e 74 20 46 54 53 20 76 65 72 current FTS ver
50e0: 73 69 6f 6e 20 2a 2f 0a 20 20 46 74 73 35 43 6f sion */. Fts5Co
50f0: 6e 74 65 78 74 20 2a 70 46 74 73 2c 20 20 20 20 ntext *pFts,
5100: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 /* Fir
5110: 73 74 20 61 72 67 20 74 6f 20 70 61 73 73 20 74 st arg to pass t
5120: 6f 20 70 41 70 69 20 66 75 6e 63 74 69 6f 6e 73 o pApi functions
5130: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f */. sqlite3_co
5140: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 20 20 20 ntext *pCtx,
5150: 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74 /* Context
5160: 20 66 6f 72 20 72 65 74 75 72 6e 69 6e 67 20 72 for returning r
5170: 65 73 75 6c 74 2f 65 72 72 6f 72 20 2a 2f 0a 20 esult/error */.
5180: 20 69 6e 74 20 6e 56 61 6c 2c 20 20 20 20 20 20 int nVal,
5190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
51a0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 76 61 /* Number of va
51b0: 6c 75 65 73 20 69 6e 20 61 70 56 61 6c 5b 5d 20 lues in apVal[]
51c0: 61 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69 74 array */. sqlit
51d0: 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61 6c e3_value **apVal
51e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 /* Ar
51f0: 72 61 79 20 6f 66 20 74 72 61 69 6c 69 6e 67 20 ray of trailing
5200: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b 0a arguments */.){.
5210: 20 20 63 6f 6e 73 74 20 64 6f 75 62 6c 65 20 6b const double k
5220: 31 20 3d 20 31 2e 32 3b 20 20 20 20 20 20 20 20 1 = 1.2;
5230: 20 20 2f 2a 20 43 6f 6e 73 74 61 6e 74 20 22 6b /* Constant "k
5240: 31 22 20 66 72 6f 6d 20 42 4d 32 35 20 66 6f 72 1" from BM25 for
5250: 6d 75 6c 61 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 mula */. const
5260: 64 6f 75 62 6c 65 20 62 20 3d 20 30 2e 37 35 3b double b = 0.75;
5270: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e /* Con
5280: 73 74 61 6e 74 20 22 62 22 20 66 72 6f 6d 20 42 stant "b" from B
5290: 4d 32 35 20 66 6f 72 6d 75 6c 61 20 2a 2f 0a 20 M25 formula */.
52a0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 int rc = SQLITE
52b0: 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 _OK;
52c0: 20 2f 2a 20 45 72 72 6f 72 20 63 6f 64 65 20 2a /* Error code *
52d0: 2f 0a 20 20 64 6f 75 62 6c 65 20 73 63 6f 72 65 /. double score
52e0: 20 3d 20 30 2e 30 3b 20 20 20 20 20 20 20 20 20 = 0.0;
52f0: 20 20 20 20 2f 2a 20 53 51 4c 20 66 75 6e 63 74 /* SQL funct
5300: 69 6f 6e 20 72 65 74 75 72 6e 20 76 61 6c 75 65 ion return value
5310: 20 2a 2f 0a 20 20 46 74 73 35 42 6d 32 35 44 61 */. Fts5Bm25Da
5320: 74 61 20 2a 70 44 61 74 61 3b 20 20 20 20 20 20 ta *pData;
5330: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 73 20 /* Values
5340: 61 6c 6c 6f 63 61 74 65 64 2f 63 61 6c 63 75 6c allocated/calcul
5350: 61 74 65 64 20 6f 6e 63 65 20 6f 6e 6c 79 20 2a ated once only *
5360: 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 /. int i;
5370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
5380: 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 /* Iterator
5390: 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 69 6e variable */. in
53a0: 74 20 6e 49 6e 73 74 20 3d 20 30 3b 20 20 20 20 t nInst = 0;
53b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
53c0: 20 56 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20 Value returned
53d0: 62 79 20 78 49 6e 73 74 43 6f 75 6e 74 28 29 20 by xInstCount()
53e0: 2a 2f 0a 20 20 64 6f 75 62 6c 65 20 44 20 3d 20 */. double D =
53f0: 30 2e 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 0.0;
5400: 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 /* Total nu
5410: 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73 20 69 mber of tokens i
5420: 6e 20 72 6f 77 20 2a 2f 0a 20 20 64 6f 75 62 6c n row */. doubl
5430: 65 20 2a 61 46 72 65 71 20 3d 20 30 3b 20 20 20 e *aFreq = 0;
5440: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 /* Ar
5450: 72 61 79 20 6f 66 20 70 68 72 61 73 65 20 66 72 ray of phrase fr
5460: 65 71 2e 20 66 6f 72 20 63 75 72 72 65 6e 74 20 eq. for current
5470: 72 6f 77 20 2a 2f 0a 0a 20 20 2f 2a 20 43 61 6c row */.. /* Cal
5480: 63 75 6c 61 74 65 20 74 68 65 20 70 68 72 61 73 culate the phras
5490: 65 20 66 72 65 71 75 65 6e 63 79 20 28 73 79 6d e frequency (sym
54a0: 62 6f 6c 20 22 66 28 71 69 2c 44 29 22 20 69 6e bol "f(qi,D)" in
54b0: 20 74 68 65 20 64 6f 63 75 6d 65 6e 74 61 74 69 the documentati
54c0: 6f 6e 29 0a 20 20 2a 2a 20 66 6f 72 20 65 61 63 on). ** for eac
54d0: 68 20 70 68 72 61 73 65 20 69 6e 20 74 68 65 20 h phrase in the
54e0: 71 75 65 72 79 20 66 6f 72 20 74 68 65 20 63 75 query for the cu
54f0: 72 72 65 6e 74 20 72 6f 77 2e 20 2a 2f 0a 20 20 rrent row. */.
5500: 72 63 20 3d 20 66 74 73 35 42 6d 32 35 47 65 74 rc = fts5Bm25Get
5510: 44 61 74 61 28 70 41 70 69 2c 20 70 46 74 73 2c Data(pApi, pFts,
5520: 20 26 70 44 61 74 61 29 3b 0a 20 20 69 66 28 20 &pData);. if(
5530: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b rc==SQLITE_OK ){
5540: 0a 20 20 20 20 61 46 72 65 71 20 3d 20 70 44 61 . aFreq = pDa
5550: 74 61 2d 3e 61 46 72 65 71 3b 0a 20 20 20 20 6d ta->aFreq;. m
5560: 65 6d 73 65 74 28 61 46 72 65 71 2c 20 30 2c 20 emset(aFreq, 0,
5570: 73 69 7a 65 6f 66 28 64 6f 75 62 6c 65 29 20 2a sizeof(double) *
5580: 20 70 44 61 74 61 2d 3e 6e 50 68 72 61 73 65 29 pData->nPhrase)
5590: 3b 0a 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d ;. rc = pApi-
55a0: 3e 78 49 6e 73 74 43 6f 75 6e 74 28 70 46 74 73 >xInstCount(pFts
55b0: 2c 20 26 6e 49 6e 73 74 29 3b 0a 20 20 7d 0a 20 , &nInst);. }.
55c0: 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 for(i=0; rc==SQ
55d0: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 49 6e LITE_OK && i<nIn
55e0: 73 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e st; i++){. in
55f0: 74 20 69 70 3b 20 69 6e 74 20 69 63 3b 20 69 6e t ip; int ic; in
5600: 74 20 69 6f 3b 0a 20 20 20 20 72 63 20 3d 20 70 t io;. rc = p
5610: 41 70 69 2d 3e 78 49 6e 73 74 28 70 46 74 73 2c Api->xInst(pFts,
5620: 20 69 2c 20 26 69 70 2c 20 26 69 63 2c 20 26 69 i, &ip, &ic, &i
5630: 6f 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d o);. if( rc==
5640: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 SQLITE_OK ){.
5650: 20 20 20 64 6f 75 62 6c 65 20 77 20 3d 20 28 6e double w = (n
5660: 56 61 6c 20 3e 20 69 63 29 20 3f 20 73 71 6c 69 Val > ic) ? sqli
5670: 74 65 33 5f 76 61 6c 75 65 5f 64 6f 75 62 6c 65 te3_value_double
5680: 28 61 70 56 61 6c 5b 69 63 5d 29 20 3a 20 31 2e (apVal[ic]) : 1.
5690: 30 3b 0a 20 20 20 20 20 20 61 46 72 65 71 5b 69 0;. aFreq[i
56a0: 70 5d 20 2b 3d 20 77 3b 0a 20 20 20 20 7d 0a 20 p] += w;. }.
56b0: 20 7d 0a 0a 20 20 2f 2a 20 46 69 67 75 72 65 20 }.. /* Figure
56c0: 6f 75 74 20 74 68 65 20 74 6f 74 61 6c 20 73 69 out the total si
56d0: 7a 65 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e ze of the curren
56e0: 74 20 72 6f 77 20 69 6e 20 74 6f 6b 65 6e 73 2e t row in tokens.
56f0: 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 */. if( rc==SQ
5700: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 LITE_OK ){. i
5710: 6e 74 20 6e 54 6f 6b 3b 0a 20 20 20 20 72 63 20 nt nTok;. rc
5720: 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e 53 = pApi->xColumnS
5730: 69 7a 65 28 70 46 74 73 2c 20 2d 31 2c 20 26 6e ize(pFts, -1, &n
5740: 54 6f 6b 29 3b 0a 20 20 20 20 44 20 3d 20 28 64 Tok);. D = (d
5750: 6f 75 62 6c 65 29 6e 54 6f 6b 3b 0a 20 20 7d 0a ouble)nTok;. }.
5760: 0a 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 . /* Determine
5770: 74 68 65 20 42 4d 32 35 20 73 63 6f 72 65 20 66 the BM25 score f
5780: 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 or the current r
5790: 6f 77 2e 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 ow. */. for(i=0
57a0: 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 ; rc==SQLITE_OK
57b0: 26 26 20 69 3c 70 44 61 74 61 2d 3e 6e 50 68 72 && i<pData->nPhr
57c0: 61 73 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 ase; i++){. s
57d0: 63 6f 72 65 20 2b 3d 20 70 44 61 74 61 2d 3e 61 core += pData->a
57e0: 49 44 46 5b 69 5d 20 2a 20 28 0a 20 20 20 20 20 IDF[i] * (.
57f0: 20 28 20 61 46 72 65 71 5b 69 5d 20 2a 20 28 6b ( aFreq[i] * (k
5800: 31 20 2b 20 31 2e 30 29 20 29 20 2f 20 0a 20 20 1 + 1.0) ) / .
5810: 20 20 20 20 28 20 61 46 72 65 71 5b 69 5d 20 2b ( aFreq[i] +
5820: 20 6b 31 20 2a 20 28 31 20 2d 20 62 20 2b 20 62 k1 * (1 - b + b
5830: 20 2a 20 44 20 2f 20 70 44 61 74 61 2d 3e 61 76 * D / pData->av
5840: 67 64 6c 29 20 29 0a 20 20 20 20 29 3b 0a 20 20 gdl) ). );.
5850: 7d 0a 20 20 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 }. . /* If no
5860: 65 72 72 6f 72 20 68 61 73 20 6f 63 63 75 72 72 error has occurr
5870: 65 64 2c 20 72 65 74 75 72 6e 20 74 68 65 20 63 ed, return the c
5880: 61 6c 63 75 6c 61 74 65 64 20 73 63 6f 72 65 2e alculated score.
5890: 20 4f 74 68 65 72 77 69 73 65 2c 0a 20 20 2a 2a Otherwise,. **
58a0: 20 74 68 72 6f 77 20 61 6e 20 53 51 4c 20 65 78 throw an SQL ex
58b0: 63 65 70 74 69 6f 6e 2e 20 20 2a 2f 0a 20 20 69 ception. */. i
58c0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b f( rc==SQLITE_OK
58d0: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f ){. sqlite3_
58e0: 72 65 73 75 6c 74 5f 64 6f 75 62 6c 65 28 70 43 result_double(pC
58f0: 74 78 2c 20 2d 31 2e 30 20 2a 20 73 63 6f 72 65 tx, -1.0 * score
5900: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 );. }else{.
5910: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 sqlite3_result_e
5920: 72 72 6f 72 5f 63 6f 64 65 28 70 43 74 78 2c 20 rror_code(pCtx,
5930: 72 63 29 3b 0a 20 20 7d 0a 7d 0a 0a 69 6e 74 20 rc);. }.}..int
5940: 73 71 6c 69 74 65 33 46 74 73 35 41 75 78 49 6e sqlite3Fts5AuxIn
5950: 69 74 28 66 74 73 35 5f 61 70 69 20 2a 70 41 70 it(fts5_api *pAp
5960: 69 29 7b 0a 20 20 73 74 72 75 63 74 20 42 75 69 i){. struct Bui
5970: 6c 74 69 6e 20 7b 0a 20 20 20 20 63 6f 6e 73 74 ltin {. const
5980: 20 63 68 61 72 20 2a 7a 46 75 6e 63 3b 20 20 20 char *zFunc;
5990: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 /* Func
59a0: 74 69 6f 6e 20 6e 61 6d 65 20 28 6e 75 6c 2d 74 tion name (nul-t
59b0: 65 72 6d 69 6e 61 74 65 64 29 20 2a 2f 0a 20 20 erminated) */.
59c0: 20 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61 74 void *pUserDat
59d0: 61 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 a;
59e0: 2f 2a 20 55 73 65 72 2d 64 61 74 61 20 70 6f 69 /* User-data poi
59f0: 6e 74 65 72 20 2a 2f 0a 20 20 20 20 66 74 73 35 nter */. fts5
5a00: 5f 65 78 74 65 6e 73 69 6f 6e 5f 66 75 6e 63 74 _extension_funct
5a10: 69 6f 6e 20 78 46 75 6e 63 3b 2f 2a 20 43 61 6c ion xFunc;/* Cal
5a20: 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20 2a lback function *
5a30: 2f 0a 20 20 20 20 76 6f 69 64 20 28 2a 78 44 65 /. void (*xDe
5a40: 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 3b 20 20 stroy)(void*);
5a50: 20 20 20 20 2f 2a 20 44 65 73 74 72 75 63 74 6f /* Destructo
5a60: 72 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 r function */.
5a70: 7d 20 61 42 75 69 6c 74 69 6e 20 5b 5d 20 3d 20 } aBuiltin [] =
5a80: 7b 0a 20 20 20 20 7b 20 22 73 6e 69 70 70 65 74 {. { "snippet
5a90: 22 2c 20 20 20 30 2c 20 66 74 73 35 53 6e 69 70 ", 0, fts5Snip
5aa0: 70 65 74 46 75 6e 63 74 69 6f 6e 2c 20 30 20 7d petFunction, 0 }
5ab0: 2c 0a 20 20 20 20 7b 20 22 68 69 67 68 6c 69 67 ,. { "highlig
5ac0: 68 74 22 2c 20 30 2c 20 66 74 73 35 48 69 67 68 ht", 0, fts5High
5ad0: 6c 69 67 68 74 46 75 6e 63 74 69 6f 6e 2c 20 30 lightFunction, 0
5ae0: 20 7d 2c 0a 20 20 20 20 7b 20 22 62 6d 32 35 22 },. { "bm25"
5af0: 2c 20 20 20 20 20 20 30 2c 20 66 74 73 35 42 6d , 0, fts5Bm
5b00: 32 35 46 75 6e 63 74 69 6f 6e 2c 20 20 20 20 30 25Function, 0
5b10: 20 7d 2c 0a 20 20 7d 3b 0a 20 20 69 6e 74 20 72 },. };. int r
5b20: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 c = SQLITE_OK;
5b30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 /* Re
5b40: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 turn code */. i
5b50: 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 nt i;
5b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
5b70: 2a 20 54 6f 20 69 74 65 72 61 74 65 20 74 68 72 * To iterate thr
5b80: 6f 75 67 68 20 62 75 69 6c 74 69 6e 20 66 75 6e ough builtin fun
5b90: 63 74 69 6f 6e 73 20 2a 2f 0a 0a 20 20 66 6f 72 ctions */.. for
5ba0: 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 (i=0; rc==SQLITE
5bb0: 5f 4f 4b 20 26 26 20 69 3c 41 72 72 61 79 53 69 _OK && i<ArraySi
5bc0: 7a 65 28 61 42 75 69 6c 74 69 6e 29 3b 20 69 2b ze(aBuiltin); i+
5bd0: 2b 29 7b 0a 20 20 20 20 72 63 20 3d 20 70 41 70 +){. rc = pAp
5be0: 69 2d 3e 78 43 72 65 61 74 65 46 75 6e 63 74 69 i->xCreateFuncti
5bf0: 6f 6e 28 70 41 70 69 2c 0a 20 20 20 20 20 20 20 on(pApi,.
5c00: 20 61 42 75 69 6c 74 69 6e 5b 69 5d 2e 7a 46 75 aBuiltin[i].zFu
5c10: 6e 63 2c 0a 20 20 20 20 20 20 20 20 61 42 75 69 nc,. aBui
5c20: 6c 74 69 6e 5b 69 5d 2e 70 55 73 65 72 44 61 74 ltin[i].pUserDat
5c30: 61 2c 0a 20 20 20 20 20 20 20 20 61 42 75 69 6c a,. aBuil
5c40: 74 69 6e 5b 69 5d 2e 78 46 75 6e 63 2c 0a 20 20 tin[i].xFunc,.
5c50: 20 20 20 20 20 20 61 42 75 69 6c 74 69 6e 5b 69 aBuiltin[i
5c60: 5d 2e 78 44 65 73 74 72 6f 79 0a 20 20 20 20 29 ].xDestroy. )
5c70: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 ;. }.. return
5c80: 72 63 3b 0a 7d 0a rc;.}.