/ Hex Artifact Content
Login

Artifact f96c6e193c466711d6d7828d5f190407fe7ab897062d371426dd3036f01258e7:


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 36 34 28 73 69 7a 65  e3_malloc64(size
1020: 6f 66 28 63 68 61 72 20 2a 29 2a 61 72 67 63 20  of(char *)*argc 
1030: 2b 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66  + nByte);.    if
1040: 28 20 61 7a 44 65 71 75 6f 74 65 3d 3d 30 20 29  ( azDequote==0 )
1050: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
1060: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
1070: 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 68 61 72  else{.      char
1080: 20 2a 70 53 70 61 63 65 20 3d 20 28 63 68 61 72   *pSpace = (char
1090: 20 2a 29 26 61 7a 44 65 71 75 6f 74 65 5b 61 72   *)&azDequote[ar
10a0: 67 63 5d 3b 0a 20 20 20 20 20 20 66 6f 72 28 69  gc];.      for(i
10b0: 3d 30 3b 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29  =0; i<argc; i++)
10c0: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 20  {.        int n 
10d0: 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 61 72  = (int)strlen(ar
10e0: 67 76 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20 20  gv[i]);.        
10f0: 61 7a 44 65 71 75 6f 74 65 5b 69 5d 20 3d 20 70  azDequote[i] = p
1100: 53 70 61 63 65 3b 0a 20 20 20 20 20 20 20 20 6d  Space;.        m
1110: 65 6d 63 70 79 28 70 53 70 61 63 65 2c 20 61 72  emcpy(pSpace, ar
1120: 67 76 5b 69 5d 2c 20 6e 2b 31 29 3b 0a 20 20 20  gv[i], n+1);.   
1130: 20 20 20 20 20 66 74 73 35 74 6f 6b 44 65 71 75       fts5tokDequ
1140: 6f 74 65 28 70 53 70 61 63 65 29 3b 0a 20 20 20  ote(pSpace);.   
1150: 20 20 20 20 20 70 53 70 61 63 65 20 2b 3d 20 28       pSpace += (
1160: 6e 2b 31 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  n+1);.      }.  
1170: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
1180: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  n rc;.}../*.** S
1190: 63 68 65 6d 61 20 6f 66 20 74 68 65 20 74 6f 6b  chema of the tok
11a0: 65 6e 69 7a 65 72 20 74 61 62 6c 65 2e 0a 2a 2f  enizer table..*/
11b0: 0a 23 64 65 66 69 6e 65 20 46 54 53 33 5f 54 4f  .#define FTS3_TO
11c0: 4b 5f 53 43 48 45 4d 41 20 22 43 52 45 41 54 45  K_SCHEMA "CREATE
11d0: 20 54 41 42 4c 45 20 78 28 69 6e 70 75 74 20 48   TABLE x(input H
11e0: 49 44 44 45 4e 2c 20 74 6f 6b 65 6e 2c 20 73 74  IDDEN, token, st
11f0: 61 72 74 2c 20 65 6e 64 2c 20 70 6f 73 69 74 69  art, end, positi
1200: 6f 6e 29 22 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  on)"../*.** This
1210: 20 66 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20 61   function does a
1220: 6c 6c 20 74 68 65 20 77 6f 72 6b 20 66 6f 72 20  ll the work for 
1230: 62 6f 74 68 20 74 68 65 20 78 43 6f 6e 6e 65 63  both the xConnec
1240: 74 20 61 6e 64 20 78 43 72 65 61 74 65 20 6d 65  t and xCreate me
1250: 74 68 6f 64 73 2e 0a 2a 2a 20 54 68 65 73 65 20  thods..** These 
1260: 74 61 62 6c 65 73 20 68 61 76 65 20 6e 6f 20 70  tables have no p
1270: 65 72 73 69 73 74 65 6e 74 20 72 65 70 72 65 73  ersistent repres
1280: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 69  entation of thei
1290: 72 20 6f 77 6e 2c 20 73 6f 20 78 43 6f 6e 6e 65  r own, so xConne
12a0: 63 74 0a 2a 2a 20 61 6e 64 20 78 43 72 65 61 74  ct.** and xCreat
12b0: 65 20 61 72 65 20 69 64 65 6e 74 69 63 61 6c 20  e are identical 
12c0: 6f 70 65 72 61 74 69 6f 6e 73 2e 0a 2a 2a 0a 2a  operations..**.*
12d0: 2a 20 20 20 61 72 67 76 5b 30 5d 3a 20 6d 6f 64  *   argv[0]: mod
12e0: 75 6c 65 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72  ule name.**   ar
12f0: 67 76 5b 31 5d 3a 20 64 61 74 61 62 61 73 65 20  gv[1]: database 
1300: 6e 61 6d 65 20 0a 2a 2a 20 20 20 61 72 67 76 5b  name .**   argv[
1310: 32 5d 3a 20 74 61 62 6c 65 20 6e 61 6d 65 0a 2a  2]: table name.*
1320: 2a 20 20 20 61 72 67 76 5b 33 5d 3a 20 66 69 72  *   argv[3]: fir
1330: 73 74 20 61 72 67 75 6d 65 6e 74 20 28 74 6f 6b  st argument (tok
1340: 65 6e 69 7a 65 72 20 6e 61 6d 65 29 0a 2a 2f 0a  enizer name).*/.
1350: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 74  static int fts5t
1360: 6f 6b 43 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 28  okConnectMethod(
1370: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  .  sqlite3 *db, 
1380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1390: 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63     /* Database c
13a0: 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 76  onnection */.  v
13b0: 6f 69 64 20 2a 70 43 74 78 2c 20 20 20 20 20 20  oid *pCtx,      
13c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
13d0: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 66 74 73  * Pointer to fts
13e0: 35 5f 61 70 69 20 6f 62 6a 65 63 74 20 2a 2f 0a  5_api object */.
13f0: 20 20 69 6e 74 20 61 72 67 63 2c 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: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65    /* Number of e
1420: 6c 65 6d 65 6e 74 73 20 69 6e 20 61 72 67 76 20  lements in argv 
1430: 61 72 72 61 79 20 2a 2f 0a 20 20 63 6f 6e 73 74  array */.  const
1440: 20 63 68 61 72 20 2a 20 63 6f 6e 73 74 20 2a 61   char * const *a
1450: 72 67 76 2c 20 20 20 20 20 20 20 2f 2a 20 78 43  rgv,       /* xC
1460: 72 65 61 74 65 2f 78 43 6f 6e 6e 65 63 74 20 61  reate/xConnect a
1470: 72 67 75 6d 65 6e 74 20 61 72 72 61 79 20 2a 2f  rgument array */
1480: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
1490: 2a 2a 70 70 56 74 61 62 2c 20 20 20 20 20 20 20  **ppVtab,       
14a0: 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 73     /* OUT: New s
14b0: 71 6c 69 74 65 33 5f 76 74 61 62 20 6f 62 6a 65  qlite3_vtab obje
14c0: 63 74 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 70  ct */.  char **p
14d0: 7a 45 72 72 20 20 20 20 20 20 20 20 20 20 20 20  zErr            
14e0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
14f0: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 27 64  sqlite3_malloc'd
1500: 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 20 2a   error message *
1510: 2f 0a 29 7b 0a 20 20 66 74 73 35 5f 61 70 69 20  /.){.  fts5_api 
1520: 2a 70 41 70 69 20 3d 20 28 66 74 73 35 5f 61 70  *pApi = (fts5_ap
1530: 69 2a 29 70 43 74 78 3b 0a 20 20 46 74 73 35 74  i*)pCtx;.  Fts5t
1540: 6f 6b 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20  okTable *pTab = 
1550: 30 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 63  0;.  int rc;.  c
1560: 68 61 72 20 2a 2a 61 7a 44 65 71 75 6f 74 65 20  har **azDequote 
1570: 3d 20 30 3b 0a 20 20 69 6e 74 20 6e 44 65 71 75  = 0;.  int nDequ
1580: 6f 74 65 20 3d 20 30 3b 0a 0a 20 20 72 63 20 3d  ote = 0;..  rc =
1590: 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65   sqlite3_declare
15a0: 5f 76 74 61 62 28 64 62 2c 20 0a 20 20 20 20 20  _vtab(db, .     
15b0: 20 20 22 43 52 45 41 54 45 20 54 41 42 4c 45 20    "CREATE TABLE 
15c0: 78 28 69 6e 70 75 74 20 48 49 44 44 45 4e 2c 20  x(input HIDDEN, 
15d0: 74 6f 6b 65 6e 2c 20 73 74 61 72 74 2c 20 65 6e  token, start, en
15e0: 64 2c 20 70 6f 73 69 74 69 6f 6e 29 22 0a 20 20  d, position)".  
15f0: 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  );..  if( rc==SQ
1600: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 6e  LITE_OK ){.    n
1610: 44 65 71 75 6f 74 65 20 3d 20 61 72 67 63 2d 33  Dequote = argc-3
1620: 3b 0a 20 20 20 20 72 63 20 3d 20 66 74 73 35 74  ;.    rc = fts5t
1630: 6f 6b 44 65 71 75 6f 74 65 41 72 72 61 79 28 6e  okDequoteArray(n
1640: 44 65 71 75 6f 74 65 2c 20 26 61 72 67 76 5b 33  Dequote, &argv[3
1650: 5d 2c 20 26 61 7a 44 65 71 75 6f 74 65 29 3b 0a  ], &azDequote);.
1660: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
1670: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1680: 70 54 61 62 20 3d 20 28 46 74 73 35 74 6f 6b 54  pTab = (Fts5tokT
1690: 61 62 6c 65 2a 29 73 71 6c 69 74 65 33 5f 6d 61  able*)sqlite3_ma
16a0: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 46 74 73 35  lloc(sizeof(Fts5
16b0: 74 6f 6b 54 61 62 6c 65 29 29 3b 0a 20 20 20 20  tokTable));.    
16c0: 69 66 28 20 70 54 61 62 3d 3d 30 20 29 7b 0a 20  if( pTab==0 ){. 
16d0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
16e0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c 73  _NOMEM;.    }els
16f0: 65 7b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28  e{.      memset(
1700: 70 54 61 62 2c 20 30 2c 20 73 69 7a 65 6f 66 28  pTab, 0, sizeof(
1710: 46 74 73 35 74 6f 6b 54 61 62 6c 65 29 29 3b 0a  Fts5tokTable));.
1720: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28      }.  }..  if(
1730: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
1740: 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 54 6f 6b  {.    void *pTok
1750: 43 74 78 20 3d 20 30 3b 0a 20 20 20 20 63 6f 6e  Ctx = 0;.    con
1760: 73 74 20 63 68 61 72 20 2a 7a 4d 6f 64 75 6c 65  st char *zModule
1770: 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 6e 44   = 0;.    if( nD
1780: 65 71 75 6f 74 65 3e 30 20 29 7b 0a 20 20 20 20  equote>0 ){.    
1790: 20 20 7a 4d 6f 64 75 6c 65 20 3d 20 61 7a 44 65    zModule = azDe
17a0: 71 75 6f 74 65 5b 30 5d 3b 0a 20 20 20 20 7d 0a  quote[0];.    }.
17b0: 0a 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e  .    rc = pApi->
17c0: 78 46 69 6e 64 54 6f 6b 65 6e 69 7a 65 72 28 70  xFindTokenizer(p
17d0: 41 70 69 2c 20 7a 4d 6f 64 75 6c 65 2c 20 26 70  Api, zModule, &p
17e0: 54 6f 6b 43 74 78 2c 20 26 70 54 61 62 2d 3e 74  TokCtx, &pTab->t
17f0: 6f 6b 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  ok);.    if( rc=
1800: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
1810: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
1820: 2a 61 7a 41 72 67 20 3d 20 28 63 6f 6e 73 74 20  *azArg = (const 
1830: 63 68 61 72 20 2a 2a 29 26 61 7a 44 65 71 75 6f  char **)&azDequo
1840: 74 65 5b 31 5d 3b 0a 20 20 20 20 20 20 69 6e 74  te[1];.      int
1850: 20 6e 41 72 67 20 3d 20 6e 44 65 71 75 6f 74 65   nArg = nDequote
1860: 3e 30 20 3f 20 6e 44 65 71 75 6f 74 65 2d 31 20  >0 ? nDequote-1 
1870: 3a 20 30 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  : 0;.      rc = 
1880: 70 54 61 62 2d 3e 74 6f 6b 2e 78 43 72 65 61 74  pTab->tok.xCreat
1890: 65 28 70 54 6f 6b 43 74 78 2c 20 61 7a 41 72 67  e(pTokCtx, azArg
18a0: 2c 20 6e 41 72 67 2c 20 26 70 54 61 62 2d 3e 70  , nArg, &pTab->p
18b0: 54 6f 6b 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  Tok);.    }.  }.
18c0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
18d0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69  E_OK ){.    sqli
18e0: 74 65 33 5f 66 72 65 65 28 70 54 61 62 29 3b 0a  te3_free(pTab);.
18f0: 20 20 20 20 70 54 61 62 20 3d 20 30 3b 0a 20 20      pTab = 0;.  
1900: 7d 0a 0a 20 20 2a 70 70 56 74 61 62 20 3d 20 28  }..  *ppVtab = (
1910: 73 71 6c 69 74 65 33 5f 76 74 61 62 2a 29 70 54  sqlite3_vtab*)pT
1920: 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  ab;.  sqlite3_fr
1930: 65 65 28 61 7a 44 65 71 75 6f 74 65 29 3b 0a 20  ee(azDequote);. 
1940: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
1950: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
1960: 6f 6e 20 64 6f 65 73 20 74 68 65 20 77 6f 72 6b  on does the work
1970: 20 66 6f 72 20 62 6f 74 68 20 74 68 65 20 78 44   for both the xD
1980: 69 73 63 6f 6e 6e 65 63 74 20 61 6e 64 20 78 44  isconnect and xD
1990: 65 73 74 72 6f 79 20 6d 65 74 68 6f 64 73 2e 0a  estroy methods..
19a0: 2a 2a 20 54 68 65 73 65 20 74 61 62 6c 65 73 20  ** These tables 
19b0: 68 61 76 65 20 6e 6f 20 70 65 72 73 69 73 74 65  have no persiste
19c0: 6e 74 20 72 65 70 72 65 73 65 6e 74 61 74 69 6f  nt representatio
19d0: 6e 20 6f 66 20 74 68 65 69 72 20 6f 77 6e 2c 20  n of their own, 
19e0: 73 6f 20 78 44 69 73 63 6f 6e 6e 65 63 74 0a 2a  so xDisconnect.*
19f0: 2a 20 61 6e 64 20 78 44 65 73 74 72 6f 79 20 61  * and xDestroy a
1a00: 72 65 20 69 64 65 6e 74 69 63 61 6c 20 6f 70 65  re identical ope
1a10: 72 61 74 69 6f 6e 73 2e 0a 2a 2f 0a 73 74 61 74  rations..*/.stat
1a20: 69 63 20 69 6e 74 20 66 74 73 35 74 6f 6b 44 69  ic int fts5tokDi
1a30: 73 63 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 28 73  sconnectMethod(s
1a40: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
1a50: 61 62 29 7b 0a 20 20 46 74 73 35 74 6f 6b 54 61  ab){.  Fts5tokTa
1a60: 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73  ble *pTab = (Fts
1a70: 35 74 6f 6b 54 61 62 6c 65 20 2a 29 70 56 74 61  5tokTable *)pVta
1a80: 62 3b 0a 20 20 69 66 28 20 70 54 61 62 2d 3e 70  b;.  if( pTab->p
1a90: 54 6f 6b 20 29 7b 0a 20 20 20 20 70 54 61 62 2d  Tok ){.    pTab-
1aa0: 3e 74 6f 6b 2e 78 44 65 6c 65 74 65 28 70 54 61  >tok.xDelete(pTa
1ab0: 62 2d 3e 70 54 6f 6b 29 3b 0a 20 20 7d 0a 20 20  b->pTok);.  }.  
1ac0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54 61  sqlite3_free(pTa
1ad0: 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  b);.  return SQL
1ae0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
1af0: 20 78 42 65 73 74 49 6e 64 65 78 20 2d 20 41 6e   xBestIndex - An
1b00: 61 6c 79 7a 65 20 61 20 57 48 45 52 45 20 61 6e  alyze a WHERE an
1b10: 64 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75 73  d ORDER BY claus
1b20: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
1b30: 20 66 74 73 35 74 6f 6b 42 65 73 74 49 6e 64 65   fts5tokBestInde
1b40: 78 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c 69 74  xMethod(.  sqlit
1b50: 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20  e3_vtab *pVTab, 
1b60: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  .  sqlite3_index
1b70: 5f 69 6e 66 6f 20 2a 70 49 6e 66 6f 0a 29 7b 0a  _info *pInfo.){.
1b80: 20 20 69 6e 74 20 69 3b 0a 0a 20 20 66 6f 72 28    int i;..  for(
1b90: 69 3d 30 3b 20 69 3c 70 49 6e 66 6f 2d 3e 6e 43  i=0; i<pInfo->nC
1ba0: 6f 6e 73 74 72 61 69 6e 74 3b 20 69 2b 2b 29 7b  onstraint; i++){
1bb0: 0a 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e  .    if( pInfo->
1bc0: 61 43 6f 6e 73 74 72 61 69 6e 74 5b 69 5d 2e 75  aConstraint[i].u
1bd0: 73 61 62 6c 65 20 0a 20 20 20 20 20 26 26 20 70  sable .     && p
1be0: 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e  Info->aConstrain
1bf0: 74 5b 69 5d 2e 69 43 6f 6c 75 6d 6e 3d 3d 30 20  t[i].iColumn==0 
1c00: 0a 20 20 20 20 20 26 26 20 70 49 6e 66 6f 2d 3e  .     && pInfo->
1c10: 61 43 6f 6e 73 74 72 61 69 6e 74 5b 69 5d 2e 6f  aConstraint[i].o
1c20: 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f  p==SQLITE_INDEX_
1c30: 43 4f 4e 53 54 52 41 49 4e 54 5f 45 51 20 0a 20  CONSTRAINT_EQ . 
1c40: 20 20 20 29 7b 0a 20 20 20 20 20 20 70 49 6e 66     ){.      pInf
1c50: 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 31 3b 0a 20  o->idxNum = 1;. 
1c60: 20 20 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e       pInfo->aCon
1c70: 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69 5d 2e  straintUsage[i].
1c80: 61 72 67 76 49 6e 64 65 78 20 3d 20 31 3b 0a 20  argvIndex = 1;. 
1c90: 20 20 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e       pInfo->aCon
1ca0: 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69 5d 2e  straintUsage[i].
1cb0: 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20 20 20 20  omit = 1;.      
1cc0: 70 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64  pInfo->estimated
1cd0: 43 6f 73 74 20 3d 20 31 3b 0a 20 20 20 20 20 20  Cost = 1;.      
1ce0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
1cf0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70  ;.    }.  }..  p
1d00: 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 30  Info->idxNum = 0
1d10: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 49 6e 66  ;.  assert( pInf
1d20: 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74  o->estimatedCost
1d30: 3e 31 30 30 30 30 30 30 2e 30 20 29 3b 0a 0a 20  >1000000.0 );.. 
1d40: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
1d50: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 4f 70 65  K;.}../*.** xOpe
1d60: 6e 20 2d 20 4f 70 65 6e 20 61 20 63 75 72 73 6f  n - Open a curso
1d70: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  r..*/.static int
1d80: 20 66 74 73 35 74 6f 6b 4f 70 65 6e 4d 65 74 68   fts5tokOpenMeth
1d90: 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  od(sqlite3_vtab 
1da0: 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f  *pVTab, sqlite3_
1db0: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70  vtab_cursor **pp
1dc0: 43 73 72 29 7b 0a 20 20 46 74 73 35 74 6f 6b 43  Csr){.  Fts5tokC
1dd0: 75 72 73 6f 72 20 2a 70 43 73 72 3b 0a 0a 20 20  ursor *pCsr;..  
1de0: 70 43 73 72 20 3d 20 28 46 74 73 35 74 6f 6b 43  pCsr = (Fts5tokC
1df0: 75 72 73 6f 72 20 2a 29 73 71 6c 69 74 65 33 5f  ursor *)sqlite3_
1e00: 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 46 74  malloc(sizeof(Ft
1e10: 73 35 74 6f 6b 43 75 72 73 6f 72 29 29 3b 0a 20  s5tokCursor));. 
1e20: 20 69 66 28 20 70 43 73 72 3d 3d 30 20 29 7b 0a   if( pCsr==0 ){.
1e30: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
1e40: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 6d  E_NOMEM;.  }.  m
1e50: 65 6d 73 65 74 28 70 43 73 72 2c 20 30 2c 20 73  emset(pCsr, 0, s
1e60: 69 7a 65 6f 66 28 46 74 73 35 74 6f 6b 43 75 72  izeof(Fts5tokCur
1e70: 73 6f 72 29 29 3b 0a 0a 20 20 2a 70 70 43 73 72  sor));..  *ppCsr
1e80: 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62   = (sqlite3_vtab
1e90: 5f 63 75 72 73 6f 72 20 2a 29 70 43 73 72 3b 0a  _cursor *)pCsr;.
1ea0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
1eb0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73  OK;.}../*.** Res
1ec0: 65 74 20 74 68 65 20 74 6f 6b 65 6e 69 7a 65 72  et the tokenizer
1ed0: 20 63 75 72 73 6f 72 20 70 61 73 73 65 64 20 61   cursor passed a
1ee0: 73 20 74 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d  s the only argum
1ef0: 65 6e 74 2e 20 41 73 20 69 66 20 69 74 20 68 61  ent. As if it ha
1f00: 64 0a 2a 2a 20 6a 75 73 74 20 62 65 65 6e 20 72  d.** just been r
1f10: 65 74 75 72 6e 65 64 20 62 79 20 66 74 73 35 74  eturned by fts5t
1f20: 6f 6b 4f 70 65 6e 4d 65 74 68 6f 64 28 29 2e 0a  okOpenMethod()..
1f30: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66  */.static void f
1f40: 74 73 35 74 6f 6b 52 65 73 65 74 43 75 72 73 6f  ts5tokResetCurso
1f50: 72 28 46 74 73 35 74 6f 6b 43 75 72 73 6f 72 20  r(Fts5tokCursor 
1f60: 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74 20 69 3b  *pCsr){.  int i;
1f70: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 43  .  for(i=0; i<pC
1f80: 73 72 2d 3e 6e 52 6f 77 3b 20 69 2b 2b 29 7b 0a  sr->nRow; i++){.
1f90: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
1fa0: 28 70 43 73 72 2d 3e 61 52 6f 77 5b 69 5d 2e 7a  (pCsr->aRow[i].z
1fb0: 54 6f 6b 65 6e 29 3b 0a 20 20 7d 0a 20 20 73 71  Token);.  }.  sq
1fc0: 6c 69 74 65 33 5f 66 72 65 65 28 70 43 73 72 2d  lite3_free(pCsr-
1fd0: 3e 7a 49 6e 70 75 74 29 3b 0a 20 20 73 71 6c 69  >zInput);.  sqli
1fe0: 74 65 33 5f 66 72 65 65 28 70 43 73 72 2d 3e 61  te3_free(pCsr->a
1ff0: 52 6f 77 29 3b 0a 20 20 70 43 73 72 2d 3e 7a 49  Row);.  pCsr->zI
2000: 6e 70 75 74 20 3d 20 30 3b 0a 20 20 70 43 73 72  nput = 0;.  pCsr
2010: 2d 3e 61 52 6f 77 20 3d 20 30 3b 0a 20 20 70 43  ->aRow = 0;.  pC
2020: 73 72 2d 3e 6e 52 6f 77 20 3d 20 30 3b 0a 20 20  sr->nRow = 0;.  
2030: 70 43 73 72 2d 3e 69 52 6f 77 69 64 20 3d 20 30  pCsr->iRowid = 0
2040: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 43 6c 6f 73  ;.}../*.** xClos
2050: 65 20 2d 20 43 6c 6f 73 65 20 61 20 63 75 72 73  e - Close a curs
2060: 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  or..*/.static in
2070: 74 20 66 74 73 35 74 6f 6b 43 6c 6f 73 65 4d 65  t fts5tokCloseMe
2080: 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61  thod(sqlite3_vta
2090: 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f  b_cursor *pCurso
20a0: 72 29 7b 0a 20 20 46 74 73 35 74 6f 6b 43 75 72  r){.  Fts5tokCur
20b0: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
20c0: 35 74 6f 6b 43 75 72 73 6f 72 20 2a 29 70 43 75  5tokCursor *)pCu
20d0: 72 73 6f 72 3b 0a 20 20 66 74 73 35 74 6f 6b 52  rsor;.  fts5tokR
20e0: 65 73 65 74 43 75 72 73 6f 72 28 70 43 73 72 29  esetCursor(pCsr)
20f0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
2100: 28 70 43 73 72 29 3b 0a 20 20 72 65 74 75 72 6e  (pCsr);.  return
2110: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
2120: 2a 0a 2a 2a 20 78 4e 65 78 74 20 2d 20 41 64 76  *.** xNext - Adv
2130: 61 6e 63 65 20 74 68 65 20 63 75 72 73 6f 72 20  ance the cursor 
2140: 74 6f 20 74 68 65 20 6e 65 78 74 20 72 6f 77 2c  to the next row,
2150: 20 69 66 20 61 6e 79 2e 0a 2a 2f 0a 73 74 61 74   if any..*/.stat
2160: 69 63 20 69 6e 74 20 66 74 73 35 74 6f 6b 4e 65  ic int fts5tokNe
2170: 78 74 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33  xtMethod(sqlite3
2180: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 43  _vtab_cursor *pC
2190: 75 72 73 6f 72 29 7b 0a 20 20 46 74 73 35 74 6f  ursor){.  Fts5to
21a0: 6b 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20  kCursor *pCsr = 
21b0: 28 46 74 73 35 74 6f 6b 43 75 72 73 6f 72 20 2a  (Fts5tokCursor *
21c0: 29 70 43 75 72 73 6f 72 3b 0a 20 20 70 43 73 72  )pCursor;.  pCsr
21d0: 2d 3e 69 52 6f 77 69 64 2b 2b 3b 0a 20 20 72 65  ->iRowid++;.  re
21e0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
21f0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  }..static int ft
2200: 73 35 74 6f 6b 43 62 28 0a 20 20 76 6f 69 64 20  s5tokCb(.  void 
2210: 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 2f  *pCtx,         /
2220: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 46 74 73  * Pointer to Fts
2230: 35 74 6f 6b 43 75 72 73 6f 72 20 2a 2f 0a 20 20  5tokCursor */.  
2240: 69 6e 74 20 74 66 6c 61 67 73 2c 20 20 20 20 20  int tflags,     
2250: 20 20 20 20 2f 2a 20 4d 61 73 6b 20 6f 66 20 46      /* Mask of F
2260: 54 53 35 5f 54 4f 4b 45 4e 5f 2a 20 66 6c 61 67  TS5_TOKEN_* flag
2270: 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  s */.  const cha
2280: 72 20 2a 70 54 6f 6b 65 6e 2c 20 2f 2a 20 50 6f  r *pToken, /* Po
2290: 69 6e 74 65 72 20 74 6f 20 62 75 66 66 65 72 20  inter to buffer 
22a0: 63 6f 6e 74 61 69 6e 69 6e 67 20 74 6f 6b 65 6e  containing token
22b0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e   */.  int nToken
22c0: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a  ,         /* Siz
22d0: 65 20 6f 66 20 74 6f 6b 65 6e 20 69 6e 20 62 79  e of token in by
22e0: 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 69 53 74  tes */.  int iSt
22f0: 61 72 74 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  art,         /* 
2300: 42 79 74 65 20 6f 66 66 73 65 74 20 6f 66 20 74  Byte offset of t
2310: 6f 6b 65 6e 20 77 69 74 68 69 6e 20 69 6e 70 75  oken within inpu
2320: 74 20 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74 20  t text */.  int 
2330: 69 45 6e 64 20 20 20 20 20 20 20 20 20 20 20 20  iEnd            
2340: 2f 2a 20 42 79 74 65 20 6f 66 66 73 65 74 20 6f  /* Byte offset o
2350: 66 20 65 6e 64 20 6f 66 20 74 6f 6b 65 6e 20 77  f end of token w
2360: 69 74 68 69 6e 20 69 6e 70 75 74 20 74 65 78 74  ithin input text
2370: 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 74 6f 6b   */.){.  Fts5tok
2380: 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28  Cursor *pCsr = (
2390: 46 74 73 35 74 6f 6b 43 75 72 73 6f 72 2a 29 70  Fts5tokCursor*)p
23a0: 43 74 78 3b 0a 20 20 46 74 73 35 74 6f 6b 52 6f  Ctx;.  Fts5tokRo
23b0: 77 20 2a 70 52 6f 77 3b 0a 0a 20 20 69 66 28 20  w *pRow;..  if( 
23c0: 28 70 43 73 72 2d 3e 6e 52 6f 77 20 26 20 28 70  (pCsr->nRow & (p
23d0: 43 73 72 2d 3e 6e 52 6f 77 2d 31 29 29 3d 3d 30  Csr->nRow-1))==0
23e0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 4e 65 77   ){.    int nNew
23f0: 20 3d 20 70 43 73 72 2d 3e 6e 52 6f 77 20 3f 20   = pCsr->nRow ? 
2400: 70 43 73 72 2d 3e 6e 52 6f 77 2a 32 20 3a 20 33  pCsr->nRow*2 : 3
2410: 32 3b 0a 20 20 20 20 46 74 73 35 74 6f 6b 52 6f  2;.    Fts5tokRo
2420: 77 20 2a 61 4e 65 77 3b 0a 20 20 20 20 61 4e 65  w *aNew;.    aNe
2430: 77 20 3d 20 28 46 74 73 35 74 6f 6b 52 6f 77 2a  w = (Fts5tokRow*
2440: 29 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63  )sqlite3_realloc
2450: 36 34 28 70 43 73 72 2d 3e 61 52 6f 77 2c 20 6e  64(pCsr->aRow, n
2460: 4e 65 77 2a 73 69 7a 65 6f 66 28 46 74 73 35 74  New*sizeof(Fts5t
2470: 6f 6b 52 6f 77 29 29 3b 0a 20 20 20 20 69 66 28  okRow));.    if(
2480: 20 61 4e 65 77 3d 3d 30 20 29 20 72 65 74 75 72   aNew==0 ) retur
2490: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
24a0: 20 20 20 20 6d 65 6d 73 65 74 28 26 61 4e 65 77      memset(&aNew
24b0: 5b 70 43 73 72 2d 3e 6e 52 6f 77 5d 2c 20 30 2c  [pCsr->nRow], 0,
24c0: 20 73 69 7a 65 6f 66 28 46 74 73 35 74 6f 6b 52   sizeof(Fts5tokR
24d0: 6f 77 29 2a 28 6e 4e 65 77 2d 70 43 73 72 2d 3e  ow)*(nNew-pCsr->
24e0: 6e 52 6f 77 29 29 3b 0a 20 20 20 20 70 43 73 72  nRow));.    pCsr
24f0: 2d 3e 61 52 6f 77 20 3d 20 61 4e 65 77 3b 0a 20  ->aRow = aNew;. 
2500: 20 7d 0a 0a 20 20 70 52 6f 77 20 3d 20 26 70 43   }..  pRow = &pC
2510: 73 72 2d 3e 61 52 6f 77 5b 70 43 73 72 2d 3e 6e  sr->aRow[pCsr->n
2520: 52 6f 77 5d 3b 0a 20 20 70 52 6f 77 2d 3e 69 53  Row];.  pRow->iS
2530: 74 61 72 74 20 3d 20 69 53 74 61 72 74 3b 0a 20  tart = iStart;. 
2540: 20 70 52 6f 77 2d 3e 69 45 6e 64 20 3d 20 69 45   pRow->iEnd = iE
2550: 6e 64 3b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e  nd;.  if( pCsr->
2560: 6e 52 6f 77 20 29 7b 0a 20 20 20 20 70 52 6f 77  nRow ){.    pRow
2570: 2d 3e 69 50 6f 73 20 3d 20 70 52 6f 77 5b 2d 31  ->iPos = pRow[-1
2580: 5d 2e 69 50 6f 73 20 2b 20 28 28 74 66 6c 61 67  ].iPos + ((tflag
2590: 73 20 26 20 46 54 53 35 5f 54 4f 4b 45 4e 5f 43  s & FTS5_TOKEN_C
25a0: 4f 4c 4f 43 41 54 45 44 29 20 3f 20 30 20 3a 20  OLOCATED) ? 0 : 
25b0: 31 29 3b 0a 20 20 7d 0a 20 20 70 52 6f 77 2d 3e  1);.  }.  pRow->
25c0: 7a 54 6f 6b 65 6e 20 3d 20 73 71 6c 69 74 65 33  zToken = sqlite3
25d0: 5f 6d 61 6c 6c 6f 63 28 6e 54 6f 6b 65 6e 2b 31  _malloc(nToken+1
25e0: 29 3b 0a 20 20 69 66 28 20 70 52 6f 77 2d 3e 7a  );.  if( pRow->z
25f0: 54 6f 6b 65 6e 3d 3d 30 20 29 20 72 65 74 75 72  Token==0 ) retur
2600: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
2610: 20 20 6d 65 6d 63 70 79 28 70 52 6f 77 2d 3e 7a    memcpy(pRow->z
2620: 54 6f 6b 65 6e 2c 20 70 54 6f 6b 65 6e 2c 20 6e  Token, pToken, n
2630: 54 6f 6b 65 6e 29 3b 0a 20 20 70 52 6f 77 2d 3e  Token);.  pRow->
2640: 7a 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 5d 20 3d  zToken[nToken] =
2650: 20 30 3b 0a 20 20 70 43 73 72 2d 3e 6e 52 6f 77   0;.  pCsr->nRow
2660: 2b 2b 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53 51  ++;..  return SQ
2670: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
2680: 2a 20 78 46 69 6c 74 65 72 20 2d 20 49 6e 69 74  * xFilter - Init
2690: 69 61 6c 69 7a 65 20 61 20 63 75 72 73 6f 72 20  ialize a cursor 
26a0: 74 6f 20 70 6f 69 6e 74 20 61 74 20 74 68 65 20  to point at the 
26b0: 73 74 61 72 74 20 6f 66 20 69 74 73 20 64 61 74  start of its dat
26c0: 61 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  a..*/.static int
26d0: 20 66 74 73 35 74 6f 6b 46 69 6c 74 65 72 4d 65   fts5tokFilterMe
26e0: 74 68 6f 64 28 0a 20 20 73 71 6c 69 74 65 33 5f  thod(.  sqlite3_
26f0: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75  vtab_cursor *pCu
2700: 72 73 6f 72 2c 20 20 20 2f 2a 20 54 68 65 20 63  rsor,   /* The c
2710: 75 72 73 6f 72 20 75 73 65 64 20 66 6f 72 20 74  ursor used for t
2720: 68 69 73 20 71 75 65 72 79 20 2a 2f 0a 20 20 69  his query */.  i
2730: 6e 74 20 69 64 78 4e 75 6d 2c 20 20 20 20 20 20  nt idxNum,      
2740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2750: 2a 20 53 74 72 61 74 65 67 79 20 69 6e 64 65 78  * Strategy index
2760: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
2770: 20 2a 69 64 78 53 74 72 2c 20 20 20 20 20 20 20   *idxStr,       
2780: 20 20 20 20 20 20 2f 2a 20 55 6e 75 73 65 64 20        /* Unused 
2790: 2a 2f 0a 20 20 69 6e 74 20 6e 56 61 6c 2c 20 20  */.  int nVal,  
27a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27b0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
27c0: 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 70  f elements in ap
27d0: 56 61 6c 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  Val */.  sqlite3
27e0: 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61 6c 20 20  _value **apVal  
27f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 67 75           /* Argu
2800: 6d 65 6e 74 73 20 66 6f 72 20 74 68 65 20 69 6e  ments for the in
2810: 64 65 78 69 6e 67 20 73 63 68 65 6d 65 20 2a 2f  dexing scheme */
2820: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
2830: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 46  QLITE_ERROR;.  F
2840: 74 73 35 74 6f 6b 43 75 72 73 6f 72 20 2a 70 43  ts5tokCursor *pC
2850: 73 72 20 3d 20 28 46 74 73 35 74 6f 6b 43 75 72  sr = (Fts5tokCur
2860: 73 6f 72 20 2a 29 70 43 75 72 73 6f 72 3b 0a 20  sor *)pCursor;. 
2870: 20 46 74 73 35 74 6f 6b 54 61 62 6c 65 20 2a 70   Fts5tokTable *p
2880: 54 61 62 20 3d 20 28 46 74 73 35 74 6f 6b 54 61  Tab = (Fts5tokTa
2890: 62 6c 65 20 2a 29 28 70 43 75 72 73 6f 72 2d 3e  ble *)(pCursor->
28a0: 70 56 74 61 62 29 3b 0a 0a 20 20 66 74 73 35 74  pVtab);..  fts5t
28b0: 6f 6b 52 65 73 65 74 43 75 72 73 6f 72 28 70 43  okResetCursor(pC
28c0: 73 72 29 3b 0a 20 20 69 66 28 20 69 64 78 4e 75  sr);.  if( idxNu
28d0: 6d 3d 3d 31 20 29 7b 0a 20 20 20 20 63 6f 6e 73  m==1 ){.    cons
28e0: 74 20 63 68 61 72 20 2a 7a 42 79 74 65 20 3d 20  t char *zByte = 
28f0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 73 71  (const char *)sq
2900: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74  lite3_value_text
2910: 28 61 70 56 61 6c 5b 30 5d 29 3b 0a 20 20 20 20  (apVal[0]);.    
2920: 69 6e 74 20 6e 42 79 74 65 20 3d 20 73 71 6c 69  int nByte = sqli
2930: 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28  te3_value_bytes(
2940: 61 70 56 61 6c 5b 30 5d 29 3b 0a 20 20 20 20 70  apVal[0]);.    p
2950: 43 73 72 2d 3e 7a 49 6e 70 75 74 20 3d 20 73 71  Csr->zInput = sq
2960: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79  lite3_malloc(nBy
2970: 74 65 2b 31 29 3b 0a 20 20 20 20 69 66 28 20 70  te+1);.    if( p
2980: 43 73 72 2d 3e 7a 49 6e 70 75 74 3d 3d 30 20 29  Csr->zInput==0 )
2990: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
29a0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
29b0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20  else{.      if( 
29c0: 6e 42 79 74 65 3e 30 20 29 20 6d 65 6d 63 70 79  nByte>0 ) memcpy
29d0: 28 70 43 73 72 2d 3e 7a 49 6e 70 75 74 2c 20 7a  (pCsr->zInput, z
29e0: 42 79 74 65 2c 20 6e 42 79 74 65 29 3b 0a 20 20  Byte, nByte);.  
29f0: 20 20 20 20 70 43 73 72 2d 3e 7a 49 6e 70 75 74      pCsr->zInput
2a00: 5b 6e 42 79 74 65 5d 20 3d 20 30 3b 0a 20 20 20  [nByte] = 0;.   
2a10: 20 20 20 72 63 20 3d 20 70 54 61 62 2d 3e 74 6f     rc = pTab->to
2a20: 6b 2e 78 54 6f 6b 65 6e 69 7a 65 28 0a 20 20 20  k.xTokenize(.   
2a30: 20 20 20 20 20 20 20 70 54 61 62 2d 3e 70 54 6f         pTab->pTo
2a40: 6b 2c 20 28 76 6f 69 64 2a 29 70 43 73 72 2c 20  k, (void*)pCsr, 
2a50: 30 2c 20 7a 42 79 74 65 2c 20 6e 42 79 74 65 2c  0, zByte, nByte,
2a60: 20 66 74 73 35 74 6f 6b 43 62 0a 20 20 20 20 20   fts5tokCb.     
2a70: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20   );.    }.  }.. 
2a80: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
2a90: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
2aa0: 20 20 72 65 74 75 72 6e 20 66 74 73 35 74 6f 6b    return fts5tok
2ab0: 4e 65 78 74 4d 65 74 68 6f 64 28 70 43 75 72 73  NextMethod(pCurs
2ac0: 6f 72 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 45  or);.}../*.** xE
2ad0: 6f 66 20 2d 20 52 65 74 75 72 6e 20 74 72 75 65  of - Return true
2ae0: 20 69 66 20 74 68 65 20 63 75 72 73 6f 72 20 69   if the cursor i
2af0: 73 20 61 74 20 45 4f 46 2c 20 6f 72 20 66 61 6c  s at EOF, or fal
2b00: 73 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f  se otherwise..*/
2b10: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
2b20: 74 6f 6b 45 6f 66 4d 65 74 68 6f 64 28 73 71 6c  tokEofMethod(sql
2b30: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
2b40: 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20 46 74   *pCursor){.  Ft
2b50: 73 35 74 6f 6b 43 75 72 73 6f 72 20 2a 70 43 73  s5tokCursor *pCs
2b60: 72 20 3d 20 28 46 74 73 35 74 6f 6b 43 75 72 73  r = (Fts5tokCurs
2b70: 6f 72 20 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20  or *)pCursor;.  
2b80: 72 65 74 75 72 6e 20 28 70 43 73 72 2d 3e 69 52  return (pCsr->iR
2b90: 6f 77 69 64 3e 70 43 73 72 2d 3e 6e 52 6f 77 29  owid>pCsr->nRow)
2ba0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 43 6f 6c 75  ;.}../*.** xColu
2bb0: 6d 6e 20 2d 20 52 65 74 75 72 6e 20 61 20 63 6f  mn - Return a co
2bc0: 6c 75 6d 6e 20 76 61 6c 75 65 2e 0a 2a 2f 0a 73  lumn value..*/.s
2bd0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 74 6f  tatic int fts5to
2be0: 6b 43 6f 6c 75 6d 6e 4d 65 74 68 6f 64 28 0a 20  kColumnMethod(. 
2bf0: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75   sqlite3_vtab_cu
2c00: 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 20  rsor *pCursor,  
2c10: 20 2f 2a 20 43 75 72 73 6f 72 20 74 6f 20 72 65   /* Cursor to re
2c20: 74 72 69 65 76 65 20 76 61 6c 75 65 20 66 72 6f  trieve value fro
2c30: 6d 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63  m */.  sqlite3_c
2c40: 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 20 20  ontext *pCtx,   
2c50: 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78         /* Contex
2c60: 74 20 66 6f 72 20 73 71 6c 69 74 65 33 5f 72 65  t for sqlite3_re
2c70: 73 75 6c 74 5f 78 78 78 28 29 20 63 61 6c 6c 73  sult_xxx() calls
2c80: 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 20 20   */.  int iCol  
2c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ca0: 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f        /* Index o
2cb0: 66 20 63 6f 6c 75 6d 6e 20 74 6f 20 72 65 61 64  f column to read
2cc0: 20 76 61 6c 75 65 20 66 72 6f 6d 20 2a 2f 0a 29   value from */.)
2cd0: 7b 0a 20 20 46 74 73 35 74 6f 6b 43 75 72 73 6f  {.  Fts5tokCurso
2ce0: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 74  r *pCsr = (Fts5t
2cf0: 6f 6b 43 75 72 73 6f 72 20 2a 29 70 43 75 72 73  okCursor *)pCurs
2d00: 6f 72 3b 0a 20 20 46 74 73 35 74 6f 6b 52 6f 77  or;.  Fts5tokRow
2d10: 20 2a 70 52 6f 77 20 3d 20 26 70 43 73 72 2d 3e   *pRow = &pCsr->
2d20: 61 52 6f 77 5b 70 43 73 72 2d 3e 69 52 6f 77 69  aRow[pCsr->iRowi
2d30: 64 2d 31 5d 3b 0a 0a 20 20 2f 2a 20 43 52 45 41  d-1];..  /* CREA
2d40: 54 45 20 54 41 42 4c 45 20 78 28 69 6e 70 75 74  TE TABLE x(input
2d50: 2c 20 74 6f 6b 65 6e 2c 20 73 74 61 72 74 2c 20  , token, start, 
2d60: 65 6e 64 2c 20 70 6f 73 69 74 69 6f 6e 29 20 2a  end, position) *
2d70: 2f 0a 20 20 73 77 69 74 63 68 28 20 69 43 6f 6c  /.  switch( iCol
2d80: 20 29 7b 0a 20 20 20 20 63 61 73 65 20 30 3a 0a   ){.    case 0:.
2d90: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65        sqlite3_re
2da0: 73 75 6c 74 5f 74 65 78 74 28 70 43 74 78 2c 20  sult_text(pCtx, 
2db0: 70 43 73 72 2d 3e 7a 49 6e 70 75 74 2c 20 2d 31  pCsr->zInput, -1
2dc0: 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45  , SQLITE_TRANSIE
2dd0: 4e 54 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  NT);.      break
2de0: 3b 0a 20 20 20 20 63 61 73 65 20 31 3a 0a 20 20  ;.    case 1:.  
2df0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
2e00: 6c 74 5f 74 65 78 74 28 70 43 74 78 2c 20 70 52  lt_text(pCtx, pR
2e10: 6f 77 2d 3e 7a 54 6f 6b 65 6e 2c 20 2d 31 2c 20  ow->zToken, -1, 
2e20: 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54  SQLITE_TRANSIENT
2e30: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
2e40: 20 20 20 20 63 61 73 65 20 32 3a 0a 20 20 20 20      case 2:.    
2e50: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
2e60: 5f 69 6e 74 28 70 43 74 78 2c 20 70 52 6f 77 2d  _int(pCtx, pRow-
2e70: 3e 69 53 74 61 72 74 29 3b 0a 20 20 20 20 20 20  >iStart);.      
2e80: 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20  break;.    case 
2e90: 33 3a 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  3:.      sqlite3
2ea0: 5f 72 65 73 75 6c 74 5f 69 6e 74 28 70 43 74 78  _result_int(pCtx
2eb0: 2c 20 70 52 6f 77 2d 3e 69 45 6e 64 29 3b 0a 20  , pRow->iEnd);. 
2ec0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
2ed0: 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 61  default:.      a
2ee0: 73 73 65 72 74 28 20 69 43 6f 6c 3d 3d 34 20 29  ssert( iCol==4 )
2ef0: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
2f00: 72 65 73 75 6c 74 5f 69 6e 74 28 70 43 74 78 2c  result_int(pCtx,
2f10: 20 70 52 6f 77 2d 3e 69 50 6f 73 29 3b 0a 20 20   pRow->iPos);.  
2f20: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20      break;.  }. 
2f30: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
2f40: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 52 6f 77  K;.}../*.** xRow
2f50: 69 64 20 2d 20 52 65 74 75 72 6e 20 74 68 65 20  id - Return the 
2f60: 63 75 72 72 65 6e 74 20 72 6f 77 69 64 20 66 6f  current rowid fo
2f70: 72 20 74 68 65 20 63 75 72 73 6f 72 2e 0a 2a 2f  r the cursor..*/
2f80: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
2f90: 74 6f 6b 52 6f 77 69 64 4d 65 74 68 6f 64 28 0a  tokRowidMethod(.
2fa0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63    sqlite3_vtab_c
2fb0: 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20  ursor *pCursor, 
2fc0: 20 20 2f 2a 20 43 75 72 73 6f 72 20 74 6f 20 72    /* Cursor to r
2fd0: 65 74 72 69 65 76 65 20 76 61 6c 75 65 20 66 72  etrieve value fr
2fe0: 6f 6d 20 2a 2f 0a 20 20 73 71 6c 69 74 65 5f 69  om */.  sqlite_i
2ff0: 6e 74 36 34 20 2a 70 52 6f 77 69 64 20 20 20 20  nt64 *pRowid    
3000: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
3010: 52 6f 77 69 64 20 76 61 6c 75 65 20 2a 2f 0a 29  Rowid value */.)
3020: 7b 0a 20 20 46 74 73 35 74 6f 6b 43 75 72 73 6f  {.  Fts5tokCurso
3030: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 74  r *pCsr = (Fts5t
3040: 6f 6b 43 75 72 73 6f 72 20 2a 29 70 43 75 72 73  okCursor *)pCurs
3050: 6f 72 3b 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20  or;.  *pRowid = 
3060: 28 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 29 70  (sqlite3_int64)p
3070: 43 73 72 2d 3e 69 52 6f 77 69 64 3b 0a 20 20 72  Csr->iRowid;.  r
3080: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
3090: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74  .}../*.** Regist
30a0: 65 72 20 74 68 65 20 66 74 73 35 74 6f 6b 20 6d  er the fts5tok m
30b0: 6f 64 75 6c 65 20 77 69 74 68 20 64 61 74 61 62  odule with datab
30c0: 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 64  ase connection d
30d0: 62 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45  b. Return SQLITE
30e0: 5f 4f 4b 0a 2a 2a 20 69 66 20 73 75 63 63 65 73  _OK.** if succes
30f0: 73 66 75 6c 20 6f 72 20 61 6e 20 65 72 72 6f 72  sful or an error
3100: 20 63 6f 64 65 20 69 66 20 73 71 6c 69 74 65 33   code if sqlite3
3110: 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 29  _create_module()
3120: 20 66 61 69 6c 73 2e 0a 2a 2f 0a 69 6e 74 20 73   fails..*/.int s
3130: 71 6c 69 74 65 33 46 74 73 35 54 65 73 74 52 65  qlite3Fts5TestRe
3140: 67 69 73 74 65 72 54 6f 6b 28 73 71 6c 69 74 65  gisterTok(sqlite
3150: 33 20 2a 64 62 2c 20 66 74 73 35 5f 61 70 69 20  3 *db, fts5_api 
3160: 2a 70 41 70 69 29 7b 0a 20 20 73 74 61 74 69 63  *pApi){.  static
3170: 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 6d   const sqlite3_m
3180: 6f 64 75 6c 65 20 66 74 73 35 74 6f 6b 5f 6d 6f  odule fts5tok_mo
3190: 64 75 6c 65 20 3d 20 7b 0a 20 20 20 20 20 30 2c  dule = {.     0,
31a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
31b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56             /* iV
31c0: 65 72 73 69 6f 6e 20 20 20 20 20 20 2a 2f 0a 20  ersion      */. 
31d0: 20 20 20 20 66 74 73 35 74 6f 6b 43 6f 6e 6e 65      fts5tokConne
31e0: 63 74 4d 65 74 68 6f 64 2c 20 20 20 20 20 20 20  ctMethod,       
31f0: 20 2f 2a 20 78 43 72 65 61 74 65 20 20 20 20 20   /* xCreate     
3200: 20 20 2a 2f 0a 20 20 20 20 20 66 74 73 35 74 6f    */.     fts5to
3210: 6b 43 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 2c 20  kConnectMethod, 
3220: 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6e 6e 65         /* xConne
3230: 63 74 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20  ct      */.     
3240: 66 74 73 35 74 6f 6b 42 65 73 74 49 6e 64 65 78  fts5tokBestIndex
3250: 4d 65 74 68 6f 64 2c 20 20 20 20 20 20 2f 2a 20  Method,      /* 
3260: 78 42 65 73 74 49 6e 64 65 78 20 20 20 20 2a 2f  xBestIndex    */
3270: 0a 20 20 20 20 20 66 74 73 35 74 6f 6b 44 69 73  .     fts5tokDis
3280: 63 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 2c 20 20  connectMethod,  
3290: 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e 6e 65 63     /* xDisconnec
32a0: 74 20 20 20 2a 2f 0a 20 20 20 20 20 66 74 73 35  t   */.     fts5
32b0: 74 6f 6b 44 69 73 63 6f 6e 6e 65 63 74 4d 65 74  tokDisconnectMet
32c0: 68 6f 64 2c 20 20 20 20 20 2f 2a 20 78 44 65 73  hod,     /* xDes
32d0: 74 72 6f 79 20 20 20 20 20 20 2a 2f 0a 20 20 20  troy      */.   
32e0: 20 20 66 74 73 35 74 6f 6b 4f 70 65 6e 4d 65 74    fts5tokOpenMet
32f0: 68 6f 64 2c 20 20 20 20 20 20 20 20 20 20 20 2f  hod,           /
3300: 2a 20 78 4f 70 65 6e 20 20 20 20 20 20 20 20 20  * xOpen         
3310: 2a 2f 0a 20 20 20 20 20 66 74 73 35 74 6f 6b 43  */.     fts5tokC
3320: 6c 6f 73 65 4d 65 74 68 6f 64 2c 20 20 20 20 20  loseMethod,     
3330: 20 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 20       /* xClose  
3340: 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 66 74        */.     ft
3350: 73 35 74 6f 6b 46 69 6c 74 65 72 4d 65 74 68 6f  s5tokFilterMetho
3360: 64 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46  d,         /* xF
3370: 69 6c 74 65 72 20 20 20 20 20 20 20 2a 2f 0a 20  ilter       */. 
3380: 20 20 20 20 66 74 73 35 74 6f 6b 4e 65 78 74 4d      fts5tokNextM
3390: 65 74 68 6f 64 2c 20 20 20 20 20 20 20 20 20 20  ethod,          
33a0: 20 2f 2a 20 78 4e 65 78 74 20 20 20 20 20 20 20   /* xNext       
33b0: 20 20 2a 2f 0a 20 20 20 20 20 66 74 73 35 74 6f    */.     fts5to
33c0: 6b 45 6f 66 4d 65 74 68 6f 64 2c 20 20 20 20 20  kEofMethod,     
33d0: 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66 20 20         /* xEof  
33e0: 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20          */.     
33f0: 66 74 73 35 74 6f 6b 43 6f 6c 75 6d 6e 4d 65 74  fts5tokColumnMet
3400: 68 6f 64 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  hod,         /* 
3410: 78 43 6f 6c 75 6d 6e 20 20 20 20 20 20 20 2a 2f  xColumn       */
3420: 0a 20 20 20 20 20 66 74 73 35 74 6f 6b 52 6f 77  .     fts5tokRow
3430: 69 64 4d 65 74 68 6f 64 2c 20 20 20 20 20 20 20  idMethod,       
3440: 20 20 20 2f 2a 20 78 52 6f 77 69 64 20 20 20 20     /* xRowid    
3450: 20 20 20 20 2a 2f 0a 20 20 20 20 20 30 2c 20 20      */.     0,  
3460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3470: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55 70 64           /* xUpd
3480: 61 74 65 20 20 20 20 20 20 20 2a 2f 0a 20 20 20  ate       */.   
3490: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
34a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
34b0: 2a 20 78 42 65 67 69 6e 20 20 20 20 20 20 20 20  * xBegin        
34c0: 2a 2f 0a 20 20 20 20 20 30 2c 20 20 20 20 20 20  */.     0,      
34d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34e0: 20 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 20 20       /* xSync   
34f0: 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 30 2c        */.     0,
3500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3510: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
3520: 6f 6d 6d 69 74 20 20 20 20 20 20 20 2a 2f 0a 20  ommit       */. 
3530: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
3540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3550: 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 20 20   /* xRollback   
3560: 20 20 2a 2f 0a 20 20 20 20 20 30 2c 20 20 20 20    */.     0,    
3570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3580: 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 46         /* xFindF
3590: 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 20  unction */.     
35a0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
35b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
35c0: 78 52 65 6e 61 6d 65 20 20 20 20 20 20 20 2a 2f  xRename       */
35d0: 0a 20 20 20 20 20 30 2c 20 20 20 20 20 20 20 20  .     0,        
35e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
35f0: 20 20 20 2f 2a 20 78 53 61 76 65 70 6f 69 6e 74     /* xSavepoint
3600: 20 20 20 20 2a 2f 0a 20 20 20 20 20 30 2c 20 20      */.     0,  
3610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3620: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6c           /* xRel
3630: 65 61 73 65 20 20 20 20 20 20 2a 2f 0a 20 20 20  ease      */.   
3640: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
3650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3660: 2a 20 78 52 6f 6c 6c 62 61 63 6b 54 6f 20 20 20  * xRollbackTo   
3670: 2a 2f 0a 20 20 20 20 20 30 20 20 20 20 20 20 20  */.     0       
3680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3690: 20 20 20 20 20 2f 2a 20 78 53 68 61 64 6f 77 4e       /* xShadowN
36a0: 61 6d 65 20 20 20 2a 2f 0a 20 20 7d 3b 0a 20 20  ame   */.  };.  
36b0: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
36c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
36d0: 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
36e0: 2f 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  /..  rc = sqlite
36f0: 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28  3_create_module(
3700: 64 62 2c 20 22 66 74 73 35 74 6f 6b 65 6e 69 7a  db, "fts5tokeniz
3710: 65 22 2c 20 26 66 74 73 35 74 6f 6b 5f 6d 6f 64  e", &fts5tok_mod
3720: 75 6c 65 2c 20 28 76 6f 69 64 2a 29 70 41 70 69  ule, (void*)pApi
3730: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
3740: 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 64 65 66  }..#endif /* def
3750: 69 6e 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54  ined(SQLITE_TEST
3760: 29 20 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c  ) && defined(SQL
3770: 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53 35 29  ITE_ENABLE_FTS5)
3780: 20 2a 2f 0a                                       */.