/ Hex Artifact Content
Login

Artifact 80de1a4b1a3caa216c3be8862440f0117a8357dd9b7cfc5a2a2ce11fe6eb64ae:


0000: 2f 2a 0a 2a 2a 20 32 30 31 33 20 41 70 72 20 32  /*.** 2013 Apr 2
0010: 32 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  2.**.** 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 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 63   file contains c
0190: 6f 64 65 20 66 6f 72 20 74 68 65 20 22 66 74 73  ode for the "fts
01a0: 35 74 6f 6b 65 6e 69 7a 65 22 20 76 69 72 74 75  5tokenize" virtu
01b0: 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 2e  al table module.
01c0: 0a 2a 2a 20 41 6e 20 66 74 73 35 74 6f 6b 65 6e  .** An fts5token
01d0: 69 7a 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c  ize virtual tabl
01e0: 65 20 69 73 20 63 72 65 61 74 65 64 20 61 73 20  e is created as 
01f0: 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
0200: 20 43 52 45 41 54 45 20 56 49 52 54 55 41 4c 20   CREATE VIRTUAL 
0210: 54 41 42 4c 45 20 3c 74 62 6c 3e 20 55 53 49 4e  TABLE <tbl> USIN
0220: 47 20 66 74 73 35 74 6f 6b 65 6e 69 7a 65 28 0a  G fts5tokenize(.
0230: 2a 2a 20 20 20 20 20 20 20 3c 74 6f 6b 65 6e 69  **       <tokeni
0240: 7a 65 72 2d 6e 61 6d 65 3e 2c 20 3c 61 72 67 2d  zer-name>, <arg-
0250: 31 3e 2c 20 2e 2e 2e 0a 2a 2a 20 20 20 29 3b 0a  1>, ....**   );.
0260: 2a 2a 0a 2a 2a 20 54 68 65 20 74 61 62 6c 65 20  **.** The table 
0270: 63 72 65 61 74 65 64 20 68 61 73 20 74 68 65 20  created has the 
0280: 66 6f 6c 6c 6f 77 69 6e 67 20 73 63 68 65 6d 61  following schema
0290: 3a 0a 2a 2a 0a 2a 2a 20 20 20 43 52 45 41 54 45  :.**.**   CREATE
02a0: 20 54 41 42 4c 45 20 3c 74 62 6c 3e 28 69 6e 70   TABLE <tbl>(inp
02b0: 75 74 20 48 49 44 44 45 4e 2c 20 74 6f 6b 65 6e  ut HIDDEN, token
02c0: 2c 20 73 74 61 72 74 2c 20 65 6e 64 2c 20 70 6f  , start, end, po
02d0: 73 69 74 69 6f 6e 29 0a 2a 2a 0a 2a 2a 20 57 68  sition).**.** Wh
02e0: 65 6e 20 71 75 65 72 69 65 64 2c 20 74 68 65 20  en queried, the 
02f0: 71 75 65 72 79 20 6d 75 73 74 20 69 6e 63 6c 75  query must inclu
0300: 64 65 20 61 20 57 48 45 52 45 20 63 6c 61 75 73  de a WHERE claus
0310: 65 20 6f 66 20 74 79 70 65 3a 0a 2a 2a 0a 2a 2a  e of type:.**.**
0320: 20 20 20 69 6e 70 75 74 20 3d 20 3c 73 74 72 69     input = <stri
0330: 6e 67 3e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 69  ng>.**.** The vi
0340: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
0350: 6c 65 20 74 6f 6b 65 6e 69 7a 65 73 20 74 68 69  le tokenizes thi
0360: 73 20 3c 73 74 72 69 6e 67 3e 2c 20 75 73 69 6e  s <string>, usin
0370: 67 20 74 68 65 20 46 54 53 33 20 0a 2a 2a 20 74  g the FTS3 .** t
0380: 6f 6b 65 6e 69 7a 65 72 20 73 70 65 63 69 66 69  okenizer specifi
0390: 65 64 20 62 79 20 74 68 65 20 61 72 67 75 6d 65  ed by the argume
03a0: 6e 74 73 20 74 6f 20 74 68 65 20 43 52 45 41 54  nts to the CREAT
03b0: 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20  E VIRTUAL TABLE 
03c0: 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74 20 61 6e  .** statement an
03d0: 64 20 72 65 74 75 72 6e 73 20 6f 6e 65 20 72 6f  d returns one ro
03e0: 77 20 66 6f 72 20 65 61 63 68 20 74 6f 6b 65 6e  w for each token
03f0: 20 69 6e 20 74 68 65 20 72 65 73 75 6c 74 2e 20   in the result. 
0400: 57 69 74 68 0a 2a 2a 20 66 69 65 6c 64 73 20 73  With.** fields s
0410: 65 74 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  et as follows:.*
0420: 2a 0a 2a 2a 20 20 20 69 6e 70 75 74 3a 20 20 20  *.**   input:   
0430: 41 6c 77 61 79 73 20 73 65 74 20 74 6f 20 61 20  Always set to a 
0440: 63 6f 70 79 20 6f 66 20 3c 73 74 72 69 6e 67 3e  copy of <string>
0450: 0a 2a 2a 20 20 20 74 6f 6b 65 6e 3a 20 20 20 41  .**   token:   A
0460: 20 74 6f 6b 65 6e 20 66 72 6f 6d 20 74 68 65 20   token from the 
0470: 69 6e 70 75 74 2e 0a 2a 2a 20 20 20 73 74 61 72  input..**   star
0480: 74 3a 20 20 20 42 79 74 65 20 6f 66 66 73 65 74  t:   Byte offset
0490: 20 6f 66 20 74 68 65 20 74 6f 6b 65 6e 20 77 69   of the token wi
04a0: 74 68 69 6e 20 74 68 65 20 69 6e 70 75 74 20 3c  thin the input <
04b0: 73 74 72 69 6e 67 3e 2e 0a 2a 2a 20 20 20 65 6e  string>..**   en
04c0: 64 3a 20 20 20 20 20 42 79 74 65 20 6f 66 66 73  d:     Byte offs
04d0: 65 74 20 6f 66 20 74 68 65 20 62 79 74 65 20 69  et of the byte i
04e0: 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f  mmediately follo
04f0: 77 69 6e 67 20 74 68 65 20 65 6e 64 20 6f 66 20  wing the end of 
0500: 74 68 65 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  the.**          
0510: 20 20 74 6f 6b 65 6e 20 77 69 74 68 69 6e 20 74    token within t
0520: 68 65 20 69 6e 70 75 74 20 73 74 72 69 6e 67 2e  he input string.
0530: 0a 2a 2a 20 20 20 70 6f 73 3a 20 20 20 20 20 54  .**   pos:     T
0540: 6f 6b 65 6e 20 6f 66 66 73 65 74 20 6f 66 20 74  oken offset of t
0550: 6f 6b 65 6e 20 77 69 74 68 69 6e 20 69 6e 70 75  oken within inpu
0560: 74 2e 0a 2a 2a 0a 2a 2f 0a 23 69 66 20 64 65 66  t..**.*/.#if def
0570: 69 6e 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54  ined(SQLITE_TEST
0580: 29 20 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c  ) && defined(SQL
0590: 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53 35 29  ITE_ENABLE_FTS5)
05a0: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 66 74 73 35  ..#include "fts5
05b0: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h".#include <st
05c0: 72 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  ring.h>.#include
05d0: 20 3c 61 73 73 65 72 74 2e 68 3e 0a 0a 74 79 70   <assert.h>..typ
05e0: 65 64 65 66 20 73 74 72 75 63 74 20 46 74 73 35  edef struct Fts5
05f0: 74 6f 6b 54 61 62 6c 65 20 46 74 73 35 74 6f 6b  tokTable Fts5tok
0600: 54 61 62 6c 65 3b 0a 74 79 70 65 64 65 66 20 73  Table;.typedef s
0610: 74 72 75 63 74 20 46 74 73 35 74 6f 6b 43 75 72  truct Fts5tokCur
0620: 73 6f 72 20 46 74 73 35 74 6f 6b 43 75 72 73 6f  sor Fts5tokCurso
0630: 72 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  r;.typedef struc
0640: 74 20 46 74 73 35 74 6f 6b 52 6f 77 20 46 74 73  t Fts5tokRow Fts
0650: 35 74 6f 6b 52 6f 77 3b 0a 0a 2f 2a 0a 2a 2a 20  5tokRow;../*.** 
0660: 56 69 72 74 75 61 6c 20 74 61 62 6c 65 20 73 74  Virtual table st
0670: 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 73 74 72 75  ructure..*/.stru
0680: 63 74 20 46 74 73 35 74 6f 6b 54 61 62 6c 65 20  ct Fts5tokTable 
0690: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  {.  sqlite3_vtab
06a0: 20 62 61 73 65 3b 20 20 20 20 20 20 20 20 20 20   base;          
06b0: 20 20 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73      /* Base clas
06c0: 73 20 75 73 65 64 20 62 79 20 53 51 4c 69 74 65  s used by SQLite
06d0: 20 63 6f 72 65 20 2a 2f 0a 20 20 66 74 73 35 5f   core */.  fts5_
06e0: 74 6f 6b 65 6e 69 7a 65 72 20 74 6f 6b 3b 20 20  tokenizer tok;  
06f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f             /* To
0700: 6b 65 6e 69 7a 65 72 20 66 75 6e 63 74 69 6f 6e  kenizer function
0710: 73 20 2a 2f 0a 20 20 46 74 73 35 54 6f 6b 65 6e  s */.  Fts5Token
0720: 69 7a 65 72 20 2a 70 54 6f 6b 3b 20 20 20 20 20  izer *pTok;     
0730: 20 20 20 20 20 20 20 2f 2a 20 54 6f 6b 65 6e 69         /* Tokeni
0740: 7a 65 72 20 69 6e 73 74 61 6e 63 65 20 2a 2f 0a  zer instance */.
0750: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 63 6f 6e 74  };../*.** A cont
0760: 61 69 6e 65 72 20 66 6f 72 20 61 20 72 6f 77 73  ainer for a rows
0770: 20 76 61 6c 75 65 73 2e 0a 2a 2f 0a 73 74 72 75   values..*/.stru
0780: 63 74 20 46 74 73 35 74 6f 6b 52 6f 77 20 7b 0a  ct Fts5tokRow {.
0790: 20 20 63 68 61 72 20 2a 7a 54 6f 6b 65 6e 3b 0a    char *zToken;.
07a0: 20 20 69 6e 74 20 69 53 74 61 72 74 3b 0a 20 20    int iStart;.  
07b0: 69 6e 74 20 69 45 6e 64 3b 0a 20 20 69 6e 74 20  int iEnd;.  int 
07c0: 69 50 6f 73 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  iPos;.};../*.** 
07d0: 56 69 72 74 75 61 6c 20 74 61 62 6c 65 20 63 75  Virtual table cu
07e0: 72 73 6f 72 20 73 74 72 75 63 74 75 72 65 2e 0a  rsor structure..
07f0: 2a 2f 0a 73 74 72 75 63 74 20 46 74 73 35 74 6f  */.struct Fts5to
0800: 6b 43 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c 69  kCursor {.  sqli
0810: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
0820: 62 61 73 65 3b 20 20 20 20 20 20 20 2f 2a 20 42  base;       /* B
0830: 61 73 65 20 63 6c 61 73 73 20 75 73 65 64 20 62  ase class used b
0840: 79 20 53 51 4c 69 74 65 20 63 6f 72 65 20 2a 2f  y SQLite core */
0850: 0a 20 20 69 6e 74 20 69 52 6f 77 69 64 3b 20 20  .  int iRowid;  
0860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0870: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 27 72     /* Current 'r
0880: 6f 77 69 64 27 20 76 61 6c 75 65 20 2a 2f 0a 20  owid' value */. 
0890: 20 63 68 61 72 20 2a 7a 49 6e 70 75 74 3b 20 20   char *zInput;  
08a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08b0: 20 2f 2a 20 49 6e 70 75 74 20 73 74 72 69 6e 67   /* Input string
08c0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 6f 77 3b 20   */.  int nRow; 
08d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08e0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
08f0: 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 61 52  of entries in aR
0900: 6f 77 5b 5d 20 2a 2f 0a 20 20 46 74 73 35 74 6f  ow[] */.  Fts5to
0910: 6b 52 6f 77 20 2a 61 52 6f 77 3b 20 20 20 20 20  kRow *aRow;     
0920: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72            /* Arr
0930: 61 79 20 6f 66 20 72 6f 77 73 20 74 6f 20 72 65  ay of rows to re
0940: 74 75 72 6e 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74  turn */.};..stat
0950: 69 63 20 76 6f 69 64 20 66 74 73 35 74 6f 6b 44  ic void fts5tokD
0960: 65 71 75 6f 74 65 28 63 68 61 72 20 2a 7a 29 7b  equote(char *z){
0970: 0a 20 20 63 68 61 72 20 71 20 3d 20 7a 5b 30 5d  .  char q = z[0]
0980: 3b 0a 0a 20 20 69 66 28 20 71 3d 3d 27 5b 27 20  ;..  if( q=='[' 
0990: 7c 7c 20 71 3d 3d 27 5c 27 27 20 7c 7c 20 71 3d  || q=='\'' || q=
09a0: 3d 27 22 27 20 7c 7c 20 71 3d 3d 27 60 27 20 29  ='"' || q=='`' )
09b0: 7b 0a 20 20 20 20 69 6e 74 20 69 49 6e 20 3d 20  {.    int iIn = 
09c0: 31 3b 0a 20 20 20 20 69 6e 74 20 69 4f 75 74 20  1;.    int iOut 
09d0: 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 71 3d 3d  = 0;.    if( q==
09e0: 27 5b 27 20 29 20 71 20 3d 20 27 5d 27 3b 20 20  '[' ) q = ']';  
09f0: 0a 0a 20 20 20 20 77 68 69 6c 65 28 20 7a 5b 69  ..    while( z[i
0a00: 49 6e 5d 20 29 7b 0a 20 20 20 20 20 20 69 66 28  In] ){.      if(
0a10: 20 7a 5b 69 49 6e 5d 3d 3d 71 20 29 7b 0a 20 20   z[iIn]==q ){.  
0a20: 20 20 20 20 20 20 69 66 28 20 7a 5b 69 49 6e 2b        if( z[iIn+
0a30: 31 5d 21 3d 71 20 29 7b 0a 20 20 20 20 20 20 20  1]!=q ){.       
0a40: 20 20 20 2f 2a 20 43 68 61 72 61 63 74 65 72 20     /* Character 
0a50: 69 49 6e 20 77 61 73 20 74 68 65 20 63 6c 6f 73  iIn was the clos
0a60: 65 20 71 75 6f 74 65 2e 20 2a 2f 0a 20 20 20 20  e quote. */.    
0a70: 20 20 20 20 20 20 69 49 6e 2b 2b 3b 0a 20 20 20        iIn++;.   
0a80: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
0a90: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
0aa0: 20 20 20 20 20 20 20 2f 2a 20 43 68 61 72 61 63         /* Charac
0ab0: 74 65 72 20 69 49 6e 20 61 6e 64 20 69 49 6e 2b  ter iIn and iIn+
0ac0: 31 20 66 6f 72 6d 20 61 6e 20 65 73 63 61 70 65  1 form an escape
0ad0: 64 20 71 75 6f 74 65 20 63 68 61 72 61 63 74 65  d quote characte
0ae0: 72 2e 20 53 6b 69 70 0a 20 20 20 20 20 20 20 20  r. Skip.        
0af0: 20 20 2a 2a 20 74 68 65 20 69 6e 70 75 74 20 63    ** the input c
0b00: 75 72 73 6f 72 20 70 61 73 74 20 62 6f 74 68 20  ursor past both 
0b10: 61 6e 64 20 63 6f 70 79 20 61 20 73 69 6e 67 6c  and copy a singl
0b20: 65 20 71 75 6f 74 65 20 63 68 61 72 61 63 74 65  e quote characte
0b30: 72 20 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20  r .          ** 
0b40: 74 6f 20 74 68 65 20 6f 75 74 70 75 74 20 62 75  to the output bu
0b50: 66 66 65 72 2e 20 2a 2f 0a 20 20 20 20 20 20 20  ffer. */.       
0b60: 20 20 20 69 49 6e 20 2b 3d 20 32 3b 0a 20 20 20     iIn += 2;.   
0b70: 20 20 20 20 20 20 20 7a 5b 69 4f 75 74 2b 2b 5d         z[iOut++]
0b80: 20 3d 20 71 3b 0a 20 20 20 20 20 20 20 20 7d 0a   = q;.        }.
0b90: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
0ba0: 20 20 20 20 20 7a 5b 69 4f 75 74 2b 2b 5d 20 3d       z[iOut++] =
0bb0: 20 7a 5b 69 49 6e 2b 2b 5d 3b 0a 20 20 20 20 20   z[iIn++];.     
0bc0: 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 7a 5b   }.    }..    z[
0bd0: 69 4f 75 74 5d 20 3d 20 27 5c 30 27 3b 0a 20 20  iOut] = '\0';.  
0be0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 73  }.}../*.** The s
0bf0: 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 2c 20  econd argument, 
0c00: 61 72 67 76 5b 5d 2c 20 69 73 20 61 6e 20 61 72  argv[], is an ar
0c10: 72 61 79 20 6f 66 20 70 6f 69 6e 74 65 72 73 20  ray of pointers 
0c20: 74 6f 20 6e 75 6c 2d 74 65 72 6d 69 6e 61 74 65  to nul-terminate
0c30: 64 0a 2a 2a 20 73 74 72 69 6e 67 73 2e 20 54 68  d.** strings. Th
0c40: 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d 61 6b 65  is function make
0c50: 73 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20  s a copy of the 
0c60: 61 72 72 61 79 20 61 6e 64 20 73 74 72 69 6e 67  array and string
0c70: 73 20 69 6e 74 6f 20 61 20 0a 2a 2a 20 73 69 6e  s into a .** sin
0c80: 67 6c 65 20 62 6c 6f 63 6b 20 6f 66 20 6d 65 6d  gle block of mem
0c90: 6f 72 79 2e 20 49 74 20 74 68 65 6e 20 64 65 71  ory. It then deq
0ca0: 75 6f 74 65 73 20 61 6e 79 20 6f 66 20 74 68 65  uotes any of the
0cb0: 20 73 74 72 69 6e 67 73 20 74 68 61 74 20 61 70   strings that ap
0cc0: 70 65 61 72 0a 2a 2a 20 74 6f 20 62 65 20 71 75  pear.** to be qu
0cd0: 6f 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73  oted..**.** If s
0ce0: 75 63 63 65 73 73 66 75 6c 2c 20 6f 75 74 70 75  uccessful, outpu
0cf0: 74 20 70 61 72 61 6d 65 74 65 72 20 2a 70 61 7a  t parameter *paz
0d00: 44 65 71 75 6f 74 65 20 69 73 20 73 65 74 20 74  Dequote is set t
0d10: 6f 20 70 6f 69 6e 74 20 61 74 20 74 68 65 0a 2a  o point at the.*
0d20: 2a 20 61 72 72 61 79 20 6f 66 20 64 65 71 75 6f  * array of dequo
0d30: 74 65 64 20 73 74 72 69 6e 67 73 20 61 6e 64 20  ted strings and 
0d40: 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
0d50: 75 72 6e 65 64 2e 20 54 68 65 20 63 61 6c 6c 65  urned. The calle
0d60: 72 20 69 73 0a 2a 2a 20 72 65 73 70 6f 6e 73 69  r is.** responsi
0d70: 62 6c 65 20 66 6f 72 20 65 76 65 6e 74 75 61 6c  ble for eventual
0d80: 6c 79 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74  ly calling sqlit
0d90: 65 33 5f 66 72 65 65 28 29 20 74 6f 20 66 72 65  e3_free() to fre
0da0: 65 20 74 68 65 20 61 72 72 61 79 0a 2a 2a 20 69  e the array.** i
0db0: 6e 20 74 68 69 73 20 63 61 73 65 2e 20 4f 72 2c  n this case. Or,
0dc0: 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
0dd0: 75 72 73 2c 20 61 6e 20 53 51 4c 69 74 65 20 65  urs, an SQLite e
0de0: 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74  rror code is ret
0df0: 75 72 6e 65 64 2e 0a 2a 2a 20 54 68 65 20 66 69  urned..** The fi
0e00: 6e 61 6c 20 76 61 6c 75 65 20 6f 66 20 2a 70 61  nal value of *pa
0e10: 7a 44 65 71 75 6f 74 65 20 69 73 20 75 6e 64 65  zDequote is unde
0e20: 66 69 6e 65 64 20 69 6e 20 74 68 69 73 20 63 61  fined in this ca
0e30: 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  se..*/.static in
0e40: 74 20 66 74 73 35 74 6f 6b 44 65 71 75 6f 74 65  t fts5tokDequote
0e50: 41 72 72 61 79 28 0a 20 20 69 6e 74 20 61 72 67  Array(.  int arg
0e60: 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
0e70: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
0e80: 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69  er of elements i
0e90: 6e 20 61 72 67 76 5b 5d 20 2a 2f 0a 20 20 63 6f  n argv[] */.  co
0ea0: 6e 73 74 20 63 68 61 72 20 2a 20 63 6f 6e 73 74  nst char * const
0eb0: 20 2a 61 72 67 76 2c 20 20 20 20 20 20 20 2f 2a   *argv,       /*
0ec0: 20 49 6e 70 75 74 20 61 72 72 61 79 20 2a 2f 0a   Input array */.
0ed0: 20 20 63 68 61 72 20 2a 2a 2a 70 61 7a 44 65 71    char ***pazDeq
0ee0: 75 6f 74 65 20 20 20 20 20 20 20 20 20 20 20 20  uote            
0ef0: 20 20 2f 2a 20 4f 75 74 70 75 74 20 61 72 72 61    /* Output arra
0f00: 79 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  y */.){.  int rc
0f10: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20   = SQLITE_OK;   
0f20: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
0f30: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 66  urn code */.  if
0f40: 28 20 61 72 67 63 3d 3d 30 20 29 7b 0a 20 20 20  ( argc==0 ){.   
0f50: 20 2a 70 61 7a 44 65 71 75 6f 74 65 20 3d 20 30   *pazDequote = 0
0f60: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
0f70: 6e 74 20 69 3b 0a 20 20 20 20 69 6e 74 20 6e 42  nt i;.    int nB
0f80: 79 74 65 20 3d 20 30 3b 0a 20 20 20 20 63 68 61  yte = 0;.    cha
0f90: 72 20 2a 2a 61 7a 44 65 71 75 6f 74 65 3b 0a 0a  r **azDequote;..
0fa0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 61      for(i=0; i<a
0fb0: 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  rgc; i++){.     
0fc0: 20 6e 42 79 74 65 20 2b 3d 20 28 69 6e 74 29 28   nByte += (int)(
0fd0: 73 74 72 6c 65 6e 28 61 72 67 76 5b 69 5d 29 20  strlen(argv[i]) 
0fe0: 2b 20 31 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  + 1);.    }..   
0ff0: 20 2a 70 61 7a 44 65 71 75 6f 74 65 20 3d 20 61   *pazDequote = a
1000: 7a 44 65 71 75 6f 74 65 20 3d 20 73 71 6c 69 74  zDequote = sqlit
1010: 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  e3_malloc(sizeof
1020: 28 63 68 61 72 20 2a 29 2a 61 72 67 63 20 2b 20  (char *)*argc + 
1030: 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20  nByte);.    if( 
1040: 61 7a 44 65 71 75 6f 74 65 3d 3d 30 20 29 7b 0a  azDequote==0 ){.
1050: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
1060: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c  E_NOMEM;.    }el
1070: 73 65 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a  se{.      char *
1080: 70 53 70 61 63 65 20 3d 20 28 63 68 61 72 20 2a  pSpace = (char *
1090: 29 26 61 7a 44 65 71 75 6f 74 65 5b 61 72 67 63  )&azDequote[argc
10a0: 5d 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30  ];.      for(i=0
10b0: 3b 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a  ; i<argc; i++){.
10c0: 20 20 20 20 20 20 20 20 69 6e 74 20 6e 20 3d 20          int n = 
10d0: 28 69 6e 74 29 73 74 72 6c 65 6e 28 61 72 67 76  (int)strlen(argv
10e0: 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20 20 61 7a  [i]);.        az
10f0: 44 65 71 75 6f 74 65 5b 69 5d 20 3d 20 70 53 70  Dequote[i] = pSp
1100: 61 63 65 3b 0a 20 20 20 20 20 20 20 20 6d 65 6d  ace;.        mem
1110: 63 70 79 28 70 53 70 61 63 65 2c 20 61 72 67 76  cpy(pSpace, argv
1120: 5b 69 5d 2c 20 6e 2b 31 29 3b 0a 20 20 20 20 20  [i], n+1);.     
1130: 20 20 20 66 74 73 35 74 6f 6b 44 65 71 75 6f 74     fts5tokDequot
1140: 65 28 70 53 70 61 63 65 29 3b 0a 20 20 20 20 20  e(pSpace);.     
1150: 20 20 20 70 53 70 61 63 65 20 2b 3d 20 28 6e 2b     pSpace += (n+
1160: 31 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  1);.      }.    
1170: 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  }.  }..  return 
1180: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 63 68  rc;.}../*.** Sch
1190: 65 6d 61 20 6f 66 20 74 68 65 20 74 6f 6b 65 6e  ema of the token
11a0: 69 7a 65 72 20 74 61 62 6c 65 2e 0a 2a 2f 0a 23  izer table..*/.#
11b0: 64 65 66 69 6e 65 20 46 54 53 33 5f 54 4f 4b 5f  define FTS3_TOK_
11c0: 53 43 48 45 4d 41 20 22 43 52 45 41 54 45 20 54  SCHEMA "CREATE T
11d0: 41 42 4c 45 20 78 28 69 6e 70 75 74 20 48 49 44  ABLE x(input HID
11e0: 44 45 4e 2c 20 74 6f 6b 65 6e 2c 20 73 74 61 72  DEN, token, star
11f0: 74 2c 20 65 6e 64 2c 20 70 6f 73 69 74 69 6f 6e  t, end, position
1200: 29 22 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  )"../*.** This f
1210: 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20 61 6c 6c  unction does all
1220: 20 74 68 65 20 77 6f 72 6b 20 66 6f 72 20 62 6f   the work for bo
1230: 74 68 20 74 68 65 20 78 43 6f 6e 6e 65 63 74 20  th the xConnect 
1240: 61 6e 64 20 78 43 72 65 61 74 65 20 6d 65 74 68  and xCreate meth
1250: 6f 64 73 2e 0a 2a 2a 20 54 68 65 73 65 20 74 61  ods..** These ta
1260: 62 6c 65 73 20 68 61 76 65 20 6e 6f 20 70 65 72  bles have no per
1270: 73 69 73 74 65 6e 74 20 72 65 70 72 65 73 65 6e  sistent represen
1280: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 69 72 20  tation of their 
1290: 6f 77 6e 2c 20 73 6f 20 78 43 6f 6e 6e 65 63 74  own, so xConnect
12a0: 0a 2a 2a 20 61 6e 64 20 78 43 72 65 61 74 65 20  .** and xCreate 
12b0: 61 72 65 20 69 64 65 6e 74 69 63 61 6c 20 6f 70  are identical op
12c0: 65 72 61 74 69 6f 6e 73 2e 0a 2a 2a 0a 2a 2a 20  erations..**.** 
12d0: 20 20 61 72 67 76 5b 30 5d 3a 20 6d 6f 64 75 6c    argv[0]: modul
12e0: 65 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72 67 76  e name.**   argv
12f0: 5b 31 5d 3a 20 64 61 74 61 62 61 73 65 20 6e 61  [1]: database na
1300: 6d 65 20 0a 2a 2a 20 20 20 61 72 67 76 5b 32 5d  me .**   argv[2]
1310: 3a 20 74 61 62 6c 65 20 6e 61 6d 65 0a 2a 2a 20  : table name.** 
1320: 20 20 61 72 67 76 5b 33 5d 3a 20 66 69 72 73 74    argv[3]: first
1330: 20 61 72 67 75 6d 65 6e 74 20 28 74 6f 6b 65 6e   argument (token
1340: 69 7a 65 72 20 6e 61 6d 65 29 0a 2a 2f 0a 73 74  izer name).*/.st
1350: 61 74 69 63 20 69 6e 74 20 66 74 73 35 74 6f 6b  atic int fts5tok
1360: 43 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 28 0a 20  ConnectMethod(. 
1370: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
1380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1390: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e   /* Database con
13a0: 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69  nection */.  voi
13b0: 64 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  d *pCtx,        
13c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
13d0: 50 6f 69 6e 74 65 72 20 74 6f 20 66 74 73 35 5f  Pointer to fts5_
13e0: 61 70 69 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  api object */.  
13f0: 69 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20 20  int argc,       
1400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1410: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65  /* Number of ele
1420: 6d 65 6e 74 73 20 69 6e 20 61 72 67 76 20 61 72  ments in argv ar
1430: 72 61 79 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ray */.  const c
1440: 68 61 72 20 2a 20 63 6f 6e 73 74 20 2a 61 72 67  har * const *arg
1450: 76 2c 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65  v,       /* xCre
1460: 61 74 65 2f 78 43 6f 6e 6e 65 63 74 20 61 72 67  ate/xConnect arg
1470: 75 6d 65 6e 74 20 61 72 72 61 79 20 2a 2f 0a 20  ument array */. 
1480: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a   sqlite3_vtab **
1490: 70 70 56 74 61 62 2c 20 20 20 20 20 20 20 20 20  ppVtab,         
14a0: 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 73 71 6c   /* OUT: New sql
14b0: 69 74 65 33 5f 76 74 61 62 20 6f 62 6a 65 63 74  ite3_vtab object
14c0: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45   */.  char **pzE
14d0: 72 72 20 20 20 20 20 20 20 20 20 20 20 20 20 20  rr              
14e0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 73 71        /* OUT: sq
14f0: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 27 64 20 65  lite3_malloc'd e
1500: 72 72 6f 72 20 6d 65 73 73 61 67 65 20 2a 2f 0a  rror message */.
1510: 29 7b 0a 20 20 66 74 73 35 5f 61 70 69 20 2a 70  ){.  fts5_api *p
1520: 41 70 69 20 3d 20 28 66 74 73 35 5f 61 70 69 2a  Api = (fts5_api*
1530: 29 70 43 74 78 3b 0a 20 20 46 74 73 35 74 6f 6b  )pCtx;.  Fts5tok
1540: 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 30 3b  Table *pTab = 0;
1550: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 63 68 61  .  int rc;.  cha
1560: 72 20 2a 2a 61 7a 44 65 71 75 6f 74 65 20 3d 20  r **azDequote = 
1570: 30 3b 0a 20 20 69 6e 74 20 6e 44 65 71 75 6f 74  0;.  int nDequot
1580: 65 20 3d 20 30 3b 0a 0a 20 20 72 63 20 3d 20 73  e = 0;..  rc = s
1590: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
15a0: 74 61 62 28 64 62 2c 20 0a 20 20 20 20 20 20 20  tab(db, .       
15b0: 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 28  "CREATE TABLE x(
15c0: 69 6e 70 75 74 20 48 49 44 44 45 4e 2c 20 74 6f  input HIDDEN, to
15d0: 6b 65 6e 2c 20 73 74 61 72 74 2c 20 65 6e 64 2c  ken, start, end,
15e0: 20 70 6f 73 69 74 69 6f 6e 29 22 0a 20 20 29 3b   position)".  );
15f0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
1600: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 6e 44 65  TE_OK ){.    nDe
1610: 71 75 6f 74 65 20 3d 20 61 72 67 63 2d 33 3b 0a  quote = argc-3;.
1620: 20 20 20 20 72 63 20 3d 20 66 74 73 35 74 6f 6b      rc = fts5tok
1630: 44 65 71 75 6f 74 65 41 72 72 61 79 28 6e 44 65  DequoteArray(nDe
1640: 71 75 6f 74 65 2c 20 26 61 72 67 76 5b 33 5d 2c  quote, &argv[3],
1650: 20 26 61 7a 44 65 71 75 6f 74 65 29 3b 0a 20 20   &azDequote);.  
1660: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
1670: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 54  ITE_OK ){.    pT
1680: 61 62 20 3d 20 28 46 74 73 35 74 6f 6b 54 61 62  ab = (Fts5tokTab
1690: 6c 65 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  le*)sqlite3_mall
16a0: 6f 63 28 73 69 7a 65 6f 66 28 46 74 73 35 74 6f  oc(sizeof(Fts5to
16b0: 6b 54 61 62 6c 65 29 29 3b 0a 20 20 20 20 69 66  kTable));.    if
16c0: 28 20 70 54 61 62 3d 3d 30 20 29 7b 0a 20 20 20  ( pTab==0 ){.   
16d0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
16e0: 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  OMEM;.    }else{
16f0: 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70 54  .      memset(pT
1700: 61 62 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 74  ab, 0, sizeof(Ft
1710: 73 35 74 6f 6b 54 61 62 6c 65 29 29 3b 0a 20 20  s5tokTable));.  
1720: 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72    }.  }..  if( r
1730: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
1740: 20 20 20 20 76 6f 69 64 20 2a 70 54 6f 6b 43 74      void *pTokCt
1750: 78 20 3d 20 30 3b 0a 20 20 20 20 63 6f 6e 73 74  x = 0;.    const
1760: 20 63 68 61 72 20 2a 7a 4d 6f 64 75 6c 65 20 3d   char *zModule =
1770: 20 30 3b 0a 20 20 20 20 69 66 28 20 6e 44 65 71   0;.    if( nDeq
1780: 75 6f 74 65 3e 30 20 29 7b 0a 20 20 20 20 20 20  uote>0 ){.      
1790: 7a 4d 6f 64 75 6c 65 20 3d 20 61 7a 44 65 71 75  zModule = azDequ
17a0: 6f 74 65 5b 30 5d 3b 0a 20 20 20 20 7d 0a 0a 20  ote[0];.    }.. 
17b0: 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 46     rc = pApi->xF
17c0: 69 6e 64 54 6f 6b 65 6e 69 7a 65 72 28 70 41 70  indTokenizer(pAp
17d0: 69 2c 20 7a 4d 6f 64 75 6c 65 2c 20 26 70 54 6f  i, zModule, &pTo
17e0: 6b 43 74 78 2c 20 26 70 54 61 62 2d 3e 74 6f 6b  kCtx, &pTab->tok
17f0: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  );.    if( rc==S
1800: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1810: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61    const char **a
1820: 7a 41 72 67 20 3d 20 28 63 6f 6e 73 74 20 63 68  zArg = (const ch
1830: 61 72 20 2a 2a 29 26 61 7a 44 65 71 75 6f 74 65  ar **)&azDequote
1840: 5b 31 5d 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e  [1];.      int n
1850: 41 72 67 20 3d 20 6e 44 65 71 75 6f 74 65 3e 30  Arg = nDequote>0
1860: 20 3f 20 6e 44 65 71 75 6f 74 65 2d 31 20 3a 20   ? nDequote-1 : 
1870: 30 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 70 54  0;.      rc = pT
1880: 61 62 2d 3e 74 6f 6b 2e 78 43 72 65 61 74 65 28  ab->tok.xCreate(
1890: 70 54 6f 6b 43 74 78 2c 20 61 7a 41 72 67 2c 20  pTokCtx, azArg, 
18a0: 6e 41 72 67 2c 20 26 70 54 61 62 2d 3e 70 54 6f  nArg, &pTab->pTo
18b0: 6b 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  k);.    }.  }.. 
18c0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
18d0: 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  OK ){.    sqlite
18e0: 33 5f 66 72 65 65 28 70 54 61 62 29 3b 0a 20 20  3_free(pTab);.  
18f0: 20 20 70 54 61 62 20 3d 20 30 3b 0a 20 20 7d 0a    pTab = 0;.  }.
1900: 0a 20 20 2a 70 70 56 74 61 62 20 3d 20 28 73 71  .  *ppVtab = (sq
1910: 6c 69 74 65 33 5f 76 74 61 62 2a 29 70 54 61 62  lite3_vtab*)pTab
1920: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
1930: 28 61 7a 44 65 71 75 6f 74 65 29 3b 0a 20 20 72  (azDequote);.  r
1940: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
1950: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
1960: 20 64 6f 65 73 20 74 68 65 20 77 6f 72 6b 20 66   does the work f
1970: 6f 72 20 62 6f 74 68 20 74 68 65 20 78 44 69 73  or both the xDis
1980: 63 6f 6e 6e 65 63 74 20 61 6e 64 20 78 44 65 73  connect and xDes
1990: 74 72 6f 79 20 6d 65 74 68 6f 64 73 2e 0a 2a 2a  troy methods..**
19a0: 20 54 68 65 73 65 20 74 61 62 6c 65 73 20 68 61   These tables ha
19b0: 76 65 20 6e 6f 20 70 65 72 73 69 73 74 65 6e 74  ve no persistent
19c0: 20 72 65 70 72 65 73 65 6e 74 61 74 69 6f 6e 20   representation 
19d0: 6f 66 20 74 68 65 69 72 20 6f 77 6e 2c 20 73 6f  of their own, so
19e0: 20 78 44 69 73 63 6f 6e 6e 65 63 74 0a 2a 2a 20   xDisconnect.** 
19f0: 61 6e 64 20 78 44 65 73 74 72 6f 79 20 61 72 65  and xDestroy are
1a00: 20 69 64 65 6e 74 69 63 61 6c 20 6f 70 65 72 61   identical opera
1a10: 74 69 6f 6e 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  tions..*/.static
1a20: 20 69 6e 74 20 66 74 73 35 74 6f 6b 44 69 73 63   int fts5tokDisc
1a30: 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 28 73 71 6c  onnectMethod(sql
1a40: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62  ite3_vtab *pVtab
1a50: 29 7b 0a 20 20 46 74 73 35 74 6f 6b 54 61 62 6c  ){.  Fts5tokTabl
1a60: 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35 74  e *pTab = (Fts5t
1a70: 6f 6b 54 61 62 6c 65 20 2a 29 70 56 74 61 62 3b  okTable *)pVtab;
1a80: 0a 20 20 69 66 28 20 70 54 61 62 2d 3e 70 54 6f  .  if( pTab->pTo
1a90: 6b 20 29 7b 0a 20 20 20 20 70 54 61 62 2d 3e 74  k ){.    pTab->t
1aa0: 6f 6b 2e 78 44 65 6c 65 74 65 28 70 54 61 62 2d  ok.xDelete(pTab-
1ab0: 3e 70 54 6f 6b 29 3b 0a 20 20 7d 0a 20 20 73 71  >pTok);.  }.  sq
1ac0: 6c 69 74 65 33 5f 66 72 65 65 28 70 54 61 62 29  lite3_free(pTab)
1ad0: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
1ae0: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78  E_OK;.}../*.** x
1af0: 42 65 73 74 49 6e 64 65 78 20 2d 20 41 6e 61 6c  BestIndex - Anal
1b00: 79 7a 65 20 61 20 57 48 45 52 45 20 61 6e 64 20  yze a WHERE and 
1b10: 4f 52 44 45 52 20 42 59 20 63 6c 61 75 73 65 2e  ORDER BY clause.
1b20: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
1b30: 74 73 35 74 6f 6b 42 65 73 74 49 6e 64 65 78 4d  ts5tokBestIndexM
1b40: 65 74 68 6f 64 28 0a 20 20 73 71 6c 69 74 65 33  ethod(.  sqlite3
1b50: 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20 0a 20  _vtab *pVTab, . 
1b60: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69   sqlite3_index_i
1b70: 6e 66 6f 20 2a 70 49 6e 66 6f 0a 29 7b 0a 20 20  nfo *pInfo.){.  
1b80: 69 6e 74 20 69 3b 0a 0a 20 20 66 6f 72 28 69 3d  int i;..  for(i=
1b90: 30 3b 20 69 3c 70 49 6e 66 6f 2d 3e 6e 43 6f 6e  0; i<pInfo->nCon
1ba0: 73 74 72 61 69 6e 74 3b 20 69 2b 2b 29 7b 0a 20  straint; i++){. 
1bb0: 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 61 43     if( pInfo->aC
1bc0: 6f 6e 73 74 72 61 69 6e 74 5b 69 5d 2e 75 73 61  onstraint[i].usa
1bd0: 62 6c 65 20 0a 20 20 20 20 20 26 26 20 70 49 6e  ble .     && pIn
1be0: 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 5b  fo->aConstraint[
1bf0: 69 5d 2e 69 43 6f 6c 75 6d 6e 3d 3d 30 20 0a 20  i].iColumn==0 . 
1c00: 20 20 20 20 26 26 20 70 49 6e 66 6f 2d 3e 61 43      && pInfo->aC
1c10: 6f 6e 73 74 72 61 69 6e 74 5b 69 5d 2e 6f 70 3d  onstraint[i].op=
1c20: 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f  =SQLITE_INDEX_CO
1c30: 4e 53 54 52 41 49 4e 54 5f 45 51 20 0a 20 20 20  NSTRAINT_EQ .   
1c40: 20 29 7b 0a 20 20 20 20 20 20 70 49 6e 66 6f 2d   ){.      pInfo-
1c50: 3e 69 64 78 4e 75 6d 20 3d 20 31 3b 0a 20 20 20  >idxNum = 1;.   
1c60: 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74     pInfo->aConst
1c70: 72 61 69 6e 74 55 73 61 67 65 5b 69 5d 2e 61 72  raintUsage[i].ar
1c80: 67 76 49 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20  gvIndex = 1;.   
1c90: 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74     pInfo->aConst
1ca0: 72 61 69 6e 74 55 73 61 67 65 5b 69 5d 2e 6f 6d  raintUsage[i].om
1cb0: 69 74 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 49  it = 1;.      pI
1cc0: 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f  nfo->estimatedCo
1cd0: 73 74 20 3d 20 31 3b 0a 20 20 20 20 20 20 72 65  st = 1;.      re
1ce0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
1cf0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70 49 6e      }.  }..  pIn
1d00: 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 30 3b 0a  fo->idxNum = 0;.
1d10: 20 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d    assert( pInfo-
1d20: 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 3e 31  >estimatedCost>1
1d30: 30 30 30 30 30 30 2e 30 20 29 3b 0a 0a 20 20 72  000000.0 );..  r
1d40: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
1d50: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 4f 70 65 6e 20  .}../*.** xOpen 
1d60: 2d 20 4f 70 65 6e 20 61 20 63 75 72 73 6f 72 2e  - Open a cursor.
1d70: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
1d80: 74 73 35 74 6f 6b 4f 70 65 6e 4d 65 74 68 6f 64  ts5tokOpenMethod
1d90: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
1da0: 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 74  VTab, sqlite3_vt
1db0: 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43 73  ab_cursor **ppCs
1dc0: 72 29 7b 0a 20 20 46 74 73 35 74 6f 6b 43 75 72  r){.  Fts5tokCur
1dd0: 73 6f 72 20 2a 70 43 73 72 3b 0a 0a 20 20 70 43  sor *pCsr;..  pC
1de0: 73 72 20 3d 20 28 46 74 73 35 74 6f 6b 43 75 72  sr = (Fts5tokCur
1df0: 73 6f 72 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61  sor *)sqlite3_ma
1e00: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 46 74 73 35  lloc(sizeof(Fts5
1e10: 74 6f 6b 43 75 72 73 6f 72 29 29 3b 0a 20 20 69  tokCursor));.  i
1e20: 66 28 20 70 43 73 72 3d 3d 30 20 29 7b 0a 20 20  f( pCsr==0 ){.  
1e30: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
1e40: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 6d 65 6d  NOMEM;.  }.  mem
1e50: 73 65 74 28 70 43 73 72 2c 20 30 2c 20 73 69 7a  set(pCsr, 0, siz
1e60: 65 6f 66 28 46 74 73 35 74 6f 6b 43 75 72 73 6f  eof(Fts5tokCurso
1e70: 72 29 29 3b 0a 0a 20 20 2a 70 70 43 73 72 20 3d  r));..  *ppCsr =
1e80: 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63   (sqlite3_vtab_c
1e90: 75 72 73 6f 72 20 2a 29 70 43 73 72 3b 0a 20 20  ursor *)pCsr;.  
1ea0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
1eb0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74  ;.}../*.** Reset
1ec0: 20 74 68 65 20 74 6f 6b 65 6e 69 7a 65 72 20 63   the tokenizer c
1ed0: 75 72 73 6f 72 20 70 61 73 73 65 64 20 61 73 20  ursor passed as 
1ee0: 74 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e  the only argumen
1ef0: 74 2e 20 41 73 20 69 66 20 69 74 20 68 61 64 0a  t. As if it had.
1f00: 2a 2a 20 6a 75 73 74 20 62 65 65 6e 20 72 65 74  ** just been ret
1f10: 75 72 6e 65 64 20 62 79 20 66 74 73 35 74 6f 6b  urned by fts5tok
1f20: 4f 70 65 6e 4d 65 74 68 6f 64 28 29 2e 0a 2a 2f  OpenMethod()..*/
1f30: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73  .static void fts
1f40: 35 74 6f 6b 52 65 73 65 74 43 75 72 73 6f 72 28  5tokResetCursor(
1f50: 46 74 73 35 74 6f 6b 43 75 72 73 6f 72 20 2a 70  Fts5tokCursor *p
1f60: 43 73 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  Csr){.  int i;. 
1f70: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 43 73 72   for(i=0; i<pCsr
1f80: 2d 3e 6e 52 6f 77 3b 20 69 2b 2b 29 7b 0a 20 20  ->nRow; i++){.  
1f90: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
1fa0: 43 73 72 2d 3e 61 52 6f 77 5b 69 5d 2e 7a 54 6f  Csr->aRow[i].zTo
1fb0: 6b 65 6e 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69  ken);.  }.  sqli
1fc0: 74 65 33 5f 66 72 65 65 28 70 43 73 72 2d 3e 7a  te3_free(pCsr->z
1fd0: 49 6e 70 75 74 29 3b 0a 20 20 73 71 6c 69 74 65  Input);.  sqlite
1fe0: 33 5f 66 72 65 65 28 70 43 73 72 2d 3e 61 52 6f  3_free(pCsr->aRo
1ff0: 77 29 3b 0a 20 20 70 43 73 72 2d 3e 7a 49 6e 70  w);.  pCsr->zInp
2000: 75 74 20 3d 20 30 3b 0a 20 20 70 43 73 72 2d 3e  ut = 0;.  pCsr->
2010: 61 52 6f 77 20 3d 20 30 3b 0a 20 20 70 43 73 72  aRow = 0;.  pCsr
2020: 2d 3e 6e 52 6f 77 20 3d 20 30 3b 0a 20 20 70 43  ->nRow = 0;.  pC
2030: 73 72 2d 3e 69 52 6f 77 69 64 20 3d 20 30 3b 0a  sr->iRowid = 0;.
2040: 7d 0a 0a 2f 2a 0a 2a 2a 20 78 43 6c 6f 73 65 20  }../*.** xClose 
2050: 2d 20 43 6c 6f 73 65 20 61 20 63 75 72 73 6f 72  - Close a cursor
2060: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2070: 66 74 73 35 74 6f 6b 43 6c 6f 73 65 4d 65 74 68  fts5tokCloseMeth
2080: 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  od(sqlite3_vtab_
2090: 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29  cursor *pCursor)
20a0: 7b 0a 20 20 46 74 73 35 74 6f 6b 43 75 72 73 6f  {.  Fts5tokCurso
20b0: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 74  r *pCsr = (Fts5t
20c0: 6f 6b 43 75 72 73 6f 72 20 2a 29 70 43 75 72 73  okCursor *)pCurs
20d0: 6f 72 3b 0a 20 20 66 74 73 35 74 6f 6b 52 65 73  or;.  fts5tokRes
20e0: 65 74 43 75 72 73 6f 72 28 70 43 73 72 29 3b 0a  etCursor(pCsr);.
20f0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
2100: 43 73 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  Csr);.  return S
2110: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
2120: 2a 2a 20 78 4e 65 78 74 20 2d 20 41 64 76 61 6e  ** xNext - Advan
2130: 63 65 20 74 68 65 20 63 75 72 73 6f 72 20 74 6f  ce the cursor to
2140: 20 74 68 65 20 6e 65 78 74 20 72 6f 77 2c 20 69   the next row, i
2150: 66 20 61 6e 79 2e 0a 2a 2f 0a 73 74 61 74 69 63  f any..*/.static
2160: 20 69 6e 74 20 66 74 73 35 74 6f 6b 4e 65 78 74   int fts5tokNext
2170: 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76  Method(sqlite3_v
2180: 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  tab_cursor *pCur
2190: 73 6f 72 29 7b 0a 20 20 46 74 73 35 74 6f 6b 43  sor){.  Fts5tokC
21a0: 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46  ursor *pCsr = (F
21b0: 74 73 35 74 6f 6b 43 75 72 73 6f 72 20 2a 29 70  ts5tokCursor *)p
21c0: 43 75 72 73 6f 72 3b 0a 20 20 70 43 73 72 2d 3e  Cursor;.  pCsr->
21d0: 69 52 6f 77 69 64 2b 2b 3b 0a 20 20 72 65 74 75  iRowid++;.  retu
21e0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
21f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
2200: 74 6f 6b 43 62 28 0a 20 20 76 6f 69 64 20 2a 70  tokCb(.  void *p
2210: 43 74 78 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  Ctx,         /* 
2220: 50 6f 69 6e 74 65 72 20 74 6f 20 46 74 73 35 74  Pointer to Fts5t
2230: 6f 6b 43 75 72 73 6f 72 20 2a 2f 0a 20 20 69 6e  okCursor */.  in
2240: 74 20 74 66 6c 61 67 73 2c 20 20 20 20 20 20 20  t tflags,       
2250: 20 20 2f 2a 20 4d 61 73 6b 20 6f 66 20 46 54 53    /* Mask of FTS
2260: 35 5f 54 4f 4b 45 4e 5f 2a 20 66 6c 61 67 73 20  5_TOKEN_* flags 
2270: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
2280: 2a 70 54 6f 6b 65 6e 2c 20 2f 2a 20 50 6f 69 6e  *pToken, /* Poin
2290: 74 65 72 20 74 6f 20 62 75 66 66 65 72 20 63 6f  ter to buffer co
22a0: 6e 74 61 69 6e 69 6e 67 20 74 6f 6b 65 6e 20 2a  ntaining token *
22b0: 2f 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 2c 20  /.  int nToken, 
22c0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
22d0: 6f 66 20 74 6f 6b 65 6e 20 69 6e 20 62 79 74 65  of token in byte
22e0: 73 20 2a 2f 0a 20 20 69 6e 74 20 69 53 74 61 72  s */.  int iStar
22f0: 74 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79  t,         /* By
2300: 74 65 20 6f 66 66 73 65 74 20 6f 66 20 74 6f 6b  te offset of tok
2310: 65 6e 20 77 69 74 68 69 6e 20 69 6e 70 75 74 20  en within input 
2320: 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74 20 69 45  text */.  int iE
2330: 6e 64 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  nd            /*
2340: 20 42 79 74 65 20 6f 66 66 73 65 74 20 6f 66 20   Byte offset of 
2350: 65 6e 64 20 6f 66 20 74 6f 6b 65 6e 20 77 69 74  end of token wit
2360: 68 69 6e 20 69 6e 70 75 74 20 74 65 78 74 20 2a  hin input text *
2370: 2f 0a 29 7b 0a 20 20 46 74 73 35 74 6f 6b 43 75  /.){.  Fts5tokCu
2380: 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74  rsor *pCsr = (Ft
2390: 73 35 74 6f 6b 43 75 72 73 6f 72 2a 29 70 43 74  s5tokCursor*)pCt
23a0: 78 3b 0a 20 20 46 74 73 35 74 6f 6b 52 6f 77 20  x;.  Fts5tokRow 
23b0: 2a 70 52 6f 77 3b 0a 0a 20 20 69 66 28 20 28 70  *pRow;..  if( (p
23c0: 43 73 72 2d 3e 6e 52 6f 77 20 26 20 28 70 43 73  Csr->nRow & (pCs
23d0: 72 2d 3e 6e 52 6f 77 2d 31 29 29 3d 3d 30 20 29  r->nRow-1))==0 )
23e0: 7b 0a 20 20 20 20 69 6e 74 20 6e 4e 65 77 20 3d  {.    int nNew =
23f0: 20 70 43 73 72 2d 3e 6e 52 6f 77 20 3f 20 70 43   pCsr->nRow ? pC
2400: 73 72 2d 3e 6e 52 6f 77 2a 32 20 3a 20 33 32 3b  sr->nRow*2 : 32;
2410: 0a 20 20 20 20 46 74 73 35 74 6f 6b 52 6f 77 20  .    Fts5tokRow 
2420: 2a 61 4e 65 77 3b 0a 20 20 20 20 61 4e 65 77 20  *aNew;.    aNew 
2430: 3d 20 28 46 74 73 35 74 6f 6b 52 6f 77 2a 29 73  = (Fts5tokRow*)s
2440: 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63 28 70  qlite3_realloc(p
2450: 43 73 72 2d 3e 61 52 6f 77 2c 20 6e 4e 65 77 2a  Csr->aRow, nNew*
2460: 73 69 7a 65 6f 66 28 46 74 73 35 74 6f 6b 52 6f  sizeof(Fts5tokRo
2470: 77 29 29 3b 0a 20 20 20 20 69 66 28 20 61 4e 65  w));.    if( aNe
2480: 77 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  w==0 ) return SQ
2490: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
24a0: 6d 65 6d 73 65 74 28 26 61 4e 65 77 5b 70 43 73  memset(&aNew[pCs
24b0: 72 2d 3e 6e 52 6f 77 5d 2c 20 30 2c 20 73 69 7a  r->nRow], 0, siz
24c0: 65 6f 66 28 46 74 73 35 74 6f 6b 52 6f 77 29 2a  eof(Fts5tokRow)*
24d0: 28 6e 4e 65 77 2d 70 43 73 72 2d 3e 6e 52 6f 77  (nNew-pCsr->nRow
24e0: 29 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 61 52  ));.    pCsr->aR
24f0: 6f 77 20 3d 20 61 4e 65 77 3b 0a 20 20 7d 0a 0a  ow = aNew;.  }..
2500: 20 20 70 52 6f 77 20 3d 20 26 70 43 73 72 2d 3e    pRow = &pCsr->
2510: 61 52 6f 77 5b 70 43 73 72 2d 3e 6e 52 6f 77 5d  aRow[pCsr->nRow]
2520: 3b 0a 20 20 70 52 6f 77 2d 3e 69 53 74 61 72 74  ;.  pRow->iStart
2530: 20 3d 20 69 53 74 61 72 74 3b 0a 20 20 70 52 6f   = iStart;.  pRo
2540: 77 2d 3e 69 45 6e 64 20 3d 20 69 45 6e 64 3b 0a  w->iEnd = iEnd;.
2550: 20 20 69 66 28 20 70 43 73 72 2d 3e 6e 52 6f 77    if( pCsr->nRow
2560: 20 29 7b 0a 20 20 20 20 70 52 6f 77 2d 3e 69 50   ){.    pRow->iP
2570: 6f 73 20 3d 20 70 52 6f 77 5b 2d 31 5d 2e 69 50  os = pRow[-1].iP
2580: 6f 73 20 2b 20 28 28 74 66 6c 61 67 73 20 26 20  os + ((tflags & 
2590: 46 54 53 35 5f 54 4f 4b 45 4e 5f 43 4f 4c 4f 43  FTS5_TOKEN_COLOC
25a0: 41 54 45 44 29 20 3f 20 30 20 3a 20 31 29 3b 0a  ATED) ? 0 : 1);.
25b0: 20 20 7d 0a 20 20 70 52 6f 77 2d 3e 7a 54 6f 6b    }.  pRow->zTok
25c0: 65 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c  en = sqlite3_mal
25d0: 6c 6f 63 28 6e 54 6f 6b 65 6e 2b 31 29 3b 0a 20  loc(nToken+1);. 
25e0: 20 69 66 28 20 70 52 6f 77 2d 3e 7a 54 6f 6b 65   if( pRow->zToke
25f0: 6e 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  n==0 ) return SQ
2600: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65  LITE_NOMEM;.  me
2610: 6d 63 70 79 28 70 52 6f 77 2d 3e 7a 54 6f 6b 65  mcpy(pRow->zToke
2620: 6e 2c 20 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65  n, pToken, nToke
2630: 6e 29 3b 0a 20 20 70 52 6f 77 2d 3e 7a 54 6f 6b  n);.  pRow->zTok
2640: 65 6e 5b 6e 54 6f 6b 65 6e 5d 20 3d 20 30 3b 0a  en[nToken] = 0;.
2650: 20 20 70 43 73 72 2d 3e 6e 52 6f 77 2b 2b 3b 0a    pCsr->nRow++;.
2660: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
2670: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 46  _OK;.}../*.** xF
2680: 69 6c 74 65 72 20 2d 20 49 6e 69 74 69 61 6c 69  ilter - Initiali
2690: 7a 65 20 61 20 63 75 72 73 6f 72 20 74 6f 20 70  ze a cursor to p
26a0: 6f 69 6e 74 20 61 74 20 74 68 65 20 73 74 61 72  oint at the star
26b0: 74 20 6f 66 20 69 74 73 20 64 61 74 61 2e 0a 2a  t of its data..*
26c0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
26d0: 35 74 6f 6b 46 69 6c 74 65 72 4d 65 74 68 6f 64  5tokFilterMethod
26e0: 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  (.  sqlite3_vtab
26f0: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72  _cursor *pCursor
2700: 2c 20 20 20 2f 2a 20 54 68 65 20 63 75 72 73 6f  ,   /* The curso
2710: 72 20 75 73 65 64 20 66 6f 72 20 74 68 69 73 20  r used for this 
2720: 71 75 65 72 79 20 2a 2f 0a 20 20 69 6e 74 20 69  query */.  int i
2730: 64 78 4e 75 6d 2c 20 20 20 20 20 20 20 20 20 20  dxNum,          
2740: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74             /* St
2750: 72 61 74 65 67 79 20 69 6e 64 65 78 20 2a 2f 0a  rategy index */.
2760: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64    const char *id
2770: 78 53 74 72 2c 20 20 20 20 20 20 20 20 20 20 20  xStr,           
2780: 20 20 2f 2a 20 55 6e 75 73 65 64 20 2a 2f 0a 20    /* Unused */. 
2790: 20 69 6e 74 20 6e 56 61 6c 2c 20 20 20 20 20 20   int nVal,      
27a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27b0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c   /* Number of el
27c0: 65 6d 65 6e 74 73 20 69 6e 20 61 70 56 61 6c 20  ements in apVal 
27d0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  */.  sqlite3_val
27e0: 75 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20 20  ue **apVal      
27f0: 20 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74       /* Argument
2800: 73 20 66 6f 72 20 74 68 65 20 69 6e 64 65 78 69  s for the indexi
2810: 6e 67 20 73 63 68 65 6d 65 20 2a 2f 0a 29 7b 0a  ng scheme */.){.
2820: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
2830: 45 5f 45 52 52 4f 52 3b 0a 20 20 46 74 73 35 74  E_ERROR;.  Fts5t
2840: 6f 6b 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d  okCursor *pCsr =
2850: 20 28 46 74 73 35 74 6f 6b 43 75 72 73 6f 72 20   (Fts5tokCursor 
2860: 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20 46 74 73  *)pCursor;.  Fts
2870: 35 74 6f 6b 54 61 62 6c 65 20 2a 70 54 61 62 20  5tokTable *pTab 
2880: 3d 20 28 46 74 73 35 74 6f 6b 54 61 62 6c 65 20  = (Fts5tokTable 
2890: 2a 29 28 70 43 75 72 73 6f 72 2d 3e 70 56 74 61  *)(pCursor->pVta
28a0: 62 29 3b 0a 0a 20 20 66 74 73 35 74 6f 6b 52 65  b);..  fts5tokRe
28b0: 73 65 74 43 75 72 73 6f 72 28 70 43 73 72 29 3b  setCursor(pCsr);
28c0: 0a 20 20 69 66 28 20 69 64 78 4e 75 6d 3d 3d 31  .  if( idxNum==1
28d0: 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68   ){.    const ch
28e0: 61 72 20 2a 7a 42 79 74 65 20 3d 20 28 63 6f 6e  ar *zByte = (con
28f0: 73 74 20 63 68 61 72 20 2a 29 73 71 6c 69 74 65  st char *)sqlite
2900: 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70 56  3_value_text(apV
2910: 61 6c 5b 30 5d 29 3b 0a 20 20 20 20 69 6e 74 20  al[0]);.    int 
2920: 6e 42 79 74 65 20 3d 20 73 71 6c 69 74 65 33 5f  nByte = sqlite3_
2930: 76 61 6c 75 65 5f 62 79 74 65 73 28 61 70 56 61  value_bytes(apVa
2940: 6c 5b 30 5d 29 3b 0a 20 20 20 20 70 43 73 72 2d  l[0]);.    pCsr-
2950: 3e 7a 49 6e 70 75 74 20 3d 20 73 71 6c 69 74 65  >zInput = sqlite
2960: 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 2b 31  3_malloc(nByte+1
2970: 29 3b 0a 20 20 20 20 69 66 28 20 70 43 73 72 2d  );.    if( pCsr-
2980: 3e 7a 49 6e 70 75 74 3d 3d 30 20 29 7b 0a 20 20  >zInput==0 ){.  
2990: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
29a0: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c 73 65  NOMEM;.    }else
29b0: 7b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70  {.      memcpy(p
29c0: 43 73 72 2d 3e 7a 49 6e 70 75 74 2c 20 7a 42 79  Csr->zInput, zBy
29d0: 74 65 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20  te, nByte);.    
29e0: 20 20 70 43 73 72 2d 3e 7a 49 6e 70 75 74 5b 6e    pCsr->zInput[n
29f0: 42 79 74 65 5d 20 3d 20 30 3b 0a 20 20 20 20 20  Byte] = 0;.     
2a00: 20 72 63 20 3d 20 70 54 61 62 2d 3e 74 6f 6b 2e   rc = pTab->tok.
2a10: 78 54 6f 6b 65 6e 69 7a 65 28 0a 20 20 20 20 20  xTokenize(.     
2a20: 20 20 20 20 20 70 54 61 62 2d 3e 70 54 6f 6b 2c       pTab->pTok,
2a30: 20 28 76 6f 69 64 2a 29 70 43 73 72 2c 20 30 2c   (void*)pCsr, 0,
2a40: 20 7a 42 79 74 65 2c 20 6e 42 79 74 65 2c 20 66   zByte, nByte, f
2a50: 74 73 35 74 6f 6b 43 62 0a 20 20 20 20 20 20 29  ts5tokCb.      )
2a60: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
2a70: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
2a80: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
2a90: 72 65 74 75 72 6e 20 66 74 73 35 74 6f 6b 4e 65  return fts5tokNe
2aa0: 78 74 4d 65 74 68 6f 64 28 70 43 75 72 73 6f 72  xtMethod(pCursor
2ab0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 45 6f 66  );.}../*.** xEof
2ac0: 20 2d 20 52 65 74 75 72 6e 20 74 72 75 65 20 69   - Return true i
2ad0: 66 20 74 68 65 20 63 75 72 73 6f 72 20 69 73 20  f the cursor is 
2ae0: 61 74 20 45 4f 46 2c 20 6f 72 20 66 61 6c 73 65  at EOF, or false
2af0: 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73   otherwise..*/.s
2b00: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 74 6f  tatic int fts5to
2b10: 6b 45 6f 66 4d 65 74 68 6f 64 28 73 71 6c 69 74  kEofMethod(sqlit
2b20: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
2b30: 70 43 75 72 73 6f 72 29 7b 0a 20 20 46 74 73 35  pCursor){.  Fts5
2b40: 74 6f 6b 43 75 72 73 6f 72 20 2a 70 43 73 72 20  tokCursor *pCsr 
2b50: 3d 20 28 46 74 73 35 74 6f 6b 43 75 72 73 6f 72  = (Fts5tokCursor
2b60: 20 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20 72 65   *)pCursor;.  re
2b70: 74 75 72 6e 20 28 70 43 73 72 2d 3e 69 52 6f 77  turn (pCsr->iRow
2b80: 69 64 3e 70 43 73 72 2d 3e 6e 52 6f 77 29 3b 0a  id>pCsr->nRow);.
2b90: 7d 0a 0a 2f 2a 0a 2a 2a 20 78 43 6f 6c 75 6d 6e  }../*.** xColumn
2ba0: 20 2d 20 52 65 74 75 72 6e 20 61 20 63 6f 6c 75   - Return a colu
2bb0: 6d 6e 20 76 61 6c 75 65 2e 0a 2a 2f 0a 73 74 61  mn value..*/.sta
2bc0: 74 69 63 20 69 6e 74 20 66 74 73 35 74 6f 6b 43  tic int fts5tokC
2bd0: 6f 6c 75 6d 6e 4d 65 74 68 6f 64 28 0a 20 20 73  olumnMethod(.  s
2be0: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
2bf0: 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 20 20 2f  or *pCursor,   /
2c00: 2a 20 43 75 72 73 6f 72 20 74 6f 20 72 65 74 72  * Cursor to retr
2c10: 69 65 76 65 20 76 61 6c 75 65 20 66 72 6f 6d 20  ieve value from 
2c20: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e  */.  sqlite3_con
2c30: 74 65 78 74 20 2a 70 43 74 78 2c 20 20 20 20 20  text *pCtx,     
2c40: 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20       /* Context 
2c50: 66 6f 72 20 73 71 6c 69 74 65 33 5f 72 65 73 75  for sqlite3_resu
2c60: 6c 74 5f 78 78 78 28 29 20 63 61 6c 6c 73 20 2a  lt_xxx() calls *
2c70: 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 20 20 20 20  /.  int iCol    
2c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2c90: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20      /* Index of 
2ca0: 63 6f 6c 75 6d 6e 20 74 6f 20 72 65 61 64 20 76  column to read v
2cb0: 61 6c 75 65 20 66 72 6f 6d 20 2a 2f 0a 29 7b 0a  alue from */.){.
2cc0: 20 20 46 74 73 35 74 6f 6b 43 75 72 73 6f 72 20    Fts5tokCursor 
2cd0: 2a 70 43 73 72 20 3d 20 28 46 74 73 35 74 6f 6b  *pCsr = (Fts5tok
2ce0: 43 75 72 73 6f 72 20 2a 29 70 43 75 72 73 6f 72  Cursor *)pCursor
2cf0: 3b 0a 20 20 46 74 73 35 74 6f 6b 52 6f 77 20 2a  ;.  Fts5tokRow *
2d00: 70 52 6f 77 20 3d 20 26 70 43 73 72 2d 3e 61 52  pRow = &pCsr->aR
2d10: 6f 77 5b 70 43 73 72 2d 3e 69 52 6f 77 69 64 2d  ow[pCsr->iRowid-
2d20: 31 5d 3b 0a 0a 20 20 2f 2a 20 43 52 45 41 54 45  1];..  /* CREATE
2d30: 20 54 41 42 4c 45 20 78 28 69 6e 70 75 74 2c 20   TABLE x(input, 
2d40: 74 6f 6b 65 6e 2c 20 73 74 61 72 74 2c 20 65 6e  token, start, en
2d50: 64 2c 20 70 6f 73 69 74 69 6f 6e 29 20 2a 2f 0a  d, position) */.
2d60: 20 20 73 77 69 74 63 68 28 20 69 43 6f 6c 20 29    switch( iCol )
2d70: 7b 0a 20 20 20 20 63 61 73 65 20 30 3a 0a 20 20  {.    case 0:.  
2d80: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
2d90: 6c 74 5f 74 65 78 74 28 70 43 74 78 2c 20 70 43  lt_text(pCtx, pC
2da0: 73 72 2d 3e 7a 49 6e 70 75 74 2c 20 2d 31 2c 20  sr->zInput, -1, 
2db0: 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54  SQLITE_TRANSIENT
2dc0: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
2dd0: 20 20 20 20 63 61 73 65 20 31 3a 0a 20 20 20 20      case 1:.    
2de0: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
2df0: 5f 74 65 78 74 28 70 43 74 78 2c 20 70 52 6f 77  _text(pCtx, pRow
2e00: 2d 3e 7a 54 6f 6b 65 6e 2c 20 2d 31 2c 20 53 51  ->zToken, -1, SQ
2e10: 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b  LITE_TRANSIENT);
2e20: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
2e30: 20 20 63 61 73 65 20 32 3a 0a 20 20 20 20 20 20    case 2:.      
2e40: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 69  sqlite3_result_i
2e50: 6e 74 28 70 43 74 78 2c 20 70 52 6f 77 2d 3e 69  nt(pCtx, pRow->i
2e60: 53 74 61 72 74 29 3b 0a 20 20 20 20 20 20 62 72  Start);.      br
2e70: 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 33 3a  eak;.    case 3:
2e80: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72  .      sqlite3_r
2e90: 65 73 75 6c 74 5f 69 6e 74 28 70 43 74 78 2c 20  esult_int(pCtx, 
2ea0: 70 52 6f 77 2d 3e 69 45 6e 64 29 3b 0a 20 20 20  pRow->iEnd);.   
2eb0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 64 65     break;.    de
2ec0: 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 61 73 73  fault:.      ass
2ed0: 65 72 74 28 20 69 43 6f 6c 3d 3d 34 20 29 3b 0a  ert( iCol==4 );.
2ee0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65        sqlite3_re
2ef0: 73 75 6c 74 5f 69 6e 74 28 70 43 74 78 2c 20 70  sult_int(pCtx, p
2f00: 52 6f 77 2d 3e 69 50 6f 73 29 3b 0a 20 20 20 20  Row->iPos);.    
2f10: 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 72    break;.  }.  r
2f20: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
2f30: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 52 6f 77 69 64  .}../*.** xRowid
2f40: 20 2d 20 52 65 74 75 72 6e 20 74 68 65 20 63 75   - Return the cu
2f50: 72 72 65 6e 74 20 72 6f 77 69 64 20 66 6f 72 20  rrent rowid for 
2f60: 74 68 65 20 63 75 72 73 6f 72 2e 0a 2a 2f 0a 73  the cursor..*/.s
2f70: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 74 6f  tatic int fts5to
2f80: 6b 52 6f 77 69 64 4d 65 74 68 6f 64 28 0a 20 20  kRowidMethod(.  
2f90: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
2fa0: 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 20 20  sor *pCursor,   
2fb0: 2f 2a 20 43 75 72 73 6f 72 20 74 6f 20 72 65 74  /* Cursor to ret
2fc0: 72 69 65 76 65 20 76 61 6c 75 65 20 66 72 6f 6d  rieve value from
2fd0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74   */.  sqlite_int
2fe0: 36 34 20 2a 70 52 6f 77 69 64 20 20 20 20 20 20  64 *pRowid      
2ff0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 52 6f        /* OUT: Ro
3000: 77 69 64 20 76 61 6c 75 65 20 2a 2f 0a 29 7b 0a  wid value */.){.
3010: 20 20 46 74 73 35 74 6f 6b 43 75 72 73 6f 72 20    Fts5tokCursor 
3020: 2a 70 43 73 72 20 3d 20 28 46 74 73 35 74 6f 6b  *pCsr = (Fts5tok
3030: 43 75 72 73 6f 72 20 2a 29 70 43 75 72 73 6f 72  Cursor *)pCursor
3040: 3b 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20 28 73  ;.  *pRowid = (s
3050: 71 6c 69 74 65 33 5f 69 6e 74 36 34 29 70 43 73  qlite3_int64)pCs
3060: 72 2d 3e 69 52 6f 77 69 64 3b 0a 20 20 72 65 74  r->iRowid;.  ret
3070: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
3080: 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72  ../*.** Register
3090: 20 74 68 65 20 66 74 73 35 74 6f 6b 20 6d 6f 64   the fts5tok mod
30a0: 75 6c 65 20 77 69 74 68 20 64 61 74 61 62 61 73  ule with databas
30b0: 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 64 62 2e  e connection db.
30c0: 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   Return SQLITE_O
30d0: 4b 0a 2a 2a 20 69 66 20 73 75 63 63 65 73 73 66  K.** if successf
30e0: 75 6c 20 6f 72 20 61 6e 20 65 72 72 6f 72 20 63  ul or an error c
30f0: 6f 64 65 20 69 66 20 73 71 6c 69 74 65 33 5f 63  ode if sqlite3_c
3100: 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 29 20 66  reate_module() f
3110: 61 69 6c 73 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ails..*/.int sql
3120: 69 74 65 33 46 74 73 35 54 65 73 74 52 65 67 69  ite3Fts5TestRegi
3130: 73 74 65 72 54 6f 6b 28 73 71 6c 69 74 65 33 20  sterTok(sqlite3 
3140: 2a 64 62 2c 20 66 74 73 35 5f 61 70 69 20 2a 70  *db, fts5_api *p
3150: 41 70 69 29 7b 0a 20 20 73 74 61 74 69 63 20 63  Api){.  static c
3160: 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 6d 6f 64  onst sqlite3_mod
3170: 75 6c 65 20 66 74 73 35 74 6f 6b 5f 6d 6f 64 75  ule fts5tok_modu
3180: 6c 65 20 3d 20 7b 0a 20 20 20 20 20 30 2c 20 20  le = {.     0,  
3190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
31a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72           /* iVer
31b0: 73 69 6f 6e 20 20 20 20 20 20 2a 2f 0a 20 20 20  sion      */.   
31c0: 20 20 66 74 73 35 74 6f 6b 43 6f 6e 6e 65 63 74    fts5tokConnect
31d0: 4d 65 74 68 6f 64 2c 20 20 20 20 20 20 20 20 2f  Method,        /
31e0: 2a 20 78 43 72 65 61 74 65 20 20 20 20 20 20 20  * xCreate       
31f0: 2a 2f 0a 20 20 20 20 20 66 74 73 35 74 6f 6b 43  */.     fts5tokC
3200: 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 2c 20 20 20  onnectMethod,   
3210: 20 20 20 20 20 2f 2a 20 78 43 6f 6e 6e 65 63 74       /* xConnect
3220: 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 66 74        */.     ft
3230: 73 35 74 6f 6b 42 65 73 74 49 6e 64 65 78 4d 65  s5tokBestIndexMe
3240: 74 68 6f 64 2c 20 20 20 20 20 20 2f 2a 20 78 42  thod,      /* xB
3250: 65 73 74 49 6e 64 65 78 20 20 20 20 2a 2f 0a 20  estIndex    */. 
3260: 20 20 20 20 66 74 73 35 74 6f 6b 44 69 73 63 6f      fts5tokDisco
3270: 6e 6e 65 63 74 4d 65 74 68 6f 64 2c 20 20 20 20  nnectMethod,    
3280: 20 2f 2a 20 78 44 69 73 63 6f 6e 6e 65 63 74 20   /* xDisconnect 
3290: 20 20 2a 2f 0a 20 20 20 20 20 66 74 73 35 74 6f    */.     fts5to
32a0: 6b 44 69 73 63 6f 6e 6e 65 63 74 4d 65 74 68 6f  kDisconnectMetho
32b0: 64 2c 20 20 20 20 20 2f 2a 20 78 44 65 73 74 72  d,     /* xDestr
32c0: 6f 79 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20  oy      */.     
32d0: 66 74 73 35 74 6f 6b 4f 70 65 6e 4d 65 74 68 6f  fts5tokOpenMetho
32e0: 64 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  d,           /* 
32f0: 78 4f 70 65 6e 20 20 20 20 20 20 20 20 20 2a 2f  xOpen         */
3300: 0a 20 20 20 20 20 66 74 73 35 74 6f 6b 43 6c 6f  .     fts5tokClo
3310: 73 65 4d 65 74 68 6f 64 2c 20 20 20 20 20 20 20  seMethod,       
3320: 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 20 20 20     /* xClose    
3330: 20 20 20 20 2a 2f 0a 20 20 20 20 20 66 74 73 35      */.     fts5
3340: 74 6f 6b 46 69 6c 74 65 72 4d 65 74 68 6f 64 2c  tokFilterMethod,
3350: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c           /* xFil
3360: 74 65 72 20 20 20 20 20 20 20 2a 2f 0a 20 20 20  ter       */.   
3370: 20 20 66 74 73 35 74 6f 6b 4e 65 78 74 4d 65 74    fts5tokNextMet
3380: 68 6f 64 2c 20 20 20 20 20 20 20 20 20 20 20 2f  hod,           /
3390: 2a 20 78 4e 65 78 74 20 20 20 20 20 20 20 20 20  * xNext         
33a0: 2a 2f 0a 20 20 20 20 20 66 74 73 35 74 6f 6b 45  */.     fts5tokE
33b0: 6f 66 4d 65 74 68 6f 64 2c 20 20 20 20 20 20 20  ofMethod,       
33c0: 20 20 20 20 20 2f 2a 20 78 45 6f 66 20 20 20 20       /* xEof    
33d0: 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 66 74        */.     ft
33e0: 73 35 74 6f 6b 43 6f 6c 75 6d 6e 4d 65 74 68 6f  s5tokColumnMetho
33f0: 64 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43  d,         /* xC
3400: 6f 6c 75 6d 6e 20 20 20 20 20 20 20 2a 2f 0a 20  olumn       */. 
3410: 20 20 20 20 66 74 73 35 74 6f 6b 52 6f 77 69 64      fts5tokRowid
3420: 4d 65 74 68 6f 64 2c 20 20 20 20 20 20 20 20 20  Method,         
3430: 20 2f 2a 20 78 52 6f 77 69 64 20 20 20 20 20 20   /* xRowid      
3440: 20 20 2a 2f 0a 20 20 20 20 20 30 2c 20 20 20 20    */.     0,    
3450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3460: 20 20 20 20 20 20 20 2f 2a 20 78 55 70 64 61 74         /* xUpdat
3470: 65 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20  e       */.     
3480: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
3490: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
34a0: 78 42 65 67 69 6e 20 20 20 20 20 20 20 20 2a 2f  xBegin        */
34b0: 0a 20 20 20 20 20 30 2c 20 20 20 20 20 20 20 20  .     0,        
34c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34d0: 20 20 20 2f 2a 20 78 53 79 6e 63 20 20 20 20 20     /* xSync     
34e0: 20 20 20 20 2a 2f 0a 20 20 20 20 20 30 2c 20 20      */.     0,  
34f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3500: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6d           /* xCom
3510: 6d 69 74 20 20 20 20 20 20 20 2a 2f 0a 20 20 20  mit       */.   
3520: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
3530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3540: 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 20 20 20 20  * xRollback     
3550: 2a 2f 0a 20 20 20 20 20 30 2c 20 20 20 20 20 20  */.     0,      
3560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3570: 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 46 75 6e       /* xFindFun
3580: 63 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 20 30 2c  ction */.     0,
3590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
35a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52             /* xR
35b0: 65 6e 61 6d 65 20 20 20 20 20 20 20 2a 2f 0a 20  ename       */. 
35c0: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
35d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
35e0: 20 2f 2a 20 78 53 61 76 65 70 6f 69 6e 74 20 20   /* xSavepoint  
35f0: 20 20 2a 2f 0a 20 20 20 20 20 30 2c 20 20 20 20    */.     0,    
3600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3610: 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6c 65 61         /* xRelea
3620: 73 65 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20  se      */.     
3630: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
3640: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3650: 78 52 6f 6c 6c 62 61 63 6b 54 6f 20 20 20 2a 2f  xRollbackTo   */
3660: 0a 20 20 20 20 20 30 20 20 20 20 20 20 20 20 20  .     0         
3670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3680: 20 20 20 2f 2a 20 78 53 68 61 64 6f 77 4e 61 6d     /* xShadowNam
3690: 65 20 20 20 2a 2f 0a 20 20 7d 3b 0a 20 20 69 6e  e   */.  };.  in
36a0: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
36b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
36c0: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
36d0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
36e0: 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 64 62  create_module(db
36f0: 2c 20 22 66 74 73 35 74 6f 6b 65 6e 69 7a 65 22  , "fts5tokenize"
3700: 2c 20 26 66 74 73 35 74 6f 6b 5f 6d 6f 64 75 6c  , &fts5tok_modul
3710: 65 2c 20 28 76 6f 69 64 2a 29 70 41 70 69 29 3b  e, (void*)pApi);
3720: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
3730: 0a 23 65 6e 64 69 66 20 2f 2a 20 64 65 66 69 6e  .#endif /* defin
3740: 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20  ed(SQLITE_TEST) 
3750: 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  && defined(SQLIT
3760: 45 5f 45 4e 41 42 4c 45 5f 46 54 53 35 29 20 2a  E_ENABLE_FTS5) *
3770: 2f 0a                                            /.