/ Hex Artifact Content
Login

Artifact 24a51bdaf5abfb83f81cad61aeaa40e9db18dd419d31607c85ac520de8bded2a:


0000: 2f 2a 0a 2a 2a 20 32 30 30 37 20 4a 75 6e 65 20  /*.** 2007 June 
0010: 32 32 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74  22.**.** The aut
0020: 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f  hor disclaims co
0030: 70 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20  pyright to this 
0040: 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e  source code.  In
0050: 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c   place of.** a l
0060: 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72  egal notice, her
0070: 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a  e is a blessing:
0080: 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f  .**.**    May yo
0090: 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f  u do good and no
00a0: 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61  t evil..**    Ma
00b0: 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69  y you find forgi
00c0: 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73  veness for yours
00d0: 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20  elf and forgive 
00e0: 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61  others..**    Ma
00f0: 79 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65  y you share free
0100: 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67  ly, never taking
0110: 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67   more than you g
0120: 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a  ive..**.********
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 2a 0a 2a 2a 0a 2a 2a 20 54 68 69  ******.**.** Thi
0180: 73 20 69 73 20 70 61 72 74 20 6f 66 20 61 6e 20  s is part of an 
0190: 53 51 4c 69 74 65 20 6d 6f 64 75 6c 65 20 69 6d  SQLite module im
01a0: 70 6c 65 6d 65 6e 74 69 6e 67 20 66 75 6c 6c 2d  plementing full-
01b0: 74 65 78 74 20 73 65 61 72 63 68 2e 0a 2a 2a 20  text search..** 
01c0: 54 68 69 73 20 70 61 72 74 69 63 75 6c 61 72 20  This particular 
01d0: 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20  file implements 
01e0: 74 68 65 20 67 65 6e 65 72 69 63 20 74 6f 6b 65  the generic toke
01f0: 6e 69 7a 65 72 20 69 6e 74 65 72 66 61 63 65 2e  nizer interface.
0200: 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 63  .*/../*.** The c
0210: 6f 64 65 20 69 6e 20 74 68 69 73 20 66 69 6c 65  ode in this file
0220: 20 69 73 20 6f 6e 6c 79 20 63 6f 6d 70 69 6c 65   is only compile
0230: 64 20 69 66 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  d if:.**.**     
0240: 2a 20 54 68 65 20 46 54 53 33 20 6d 6f 64 75 6c  * The FTS3 modul
0250: 65 20 69 73 20 62 65 69 6e 67 20 62 75 69 6c 74  e is being built
0260: 20 61 73 20 61 6e 20 65 78 74 65 6e 73 69 6f 6e   as an extension
0270: 0a 2a 2a 20 20 20 20 20 20 20 28 69 6e 20 77 68  .**       (in wh
0280: 69 63 68 20 63 61 73 65 20 53 51 4c 49 54 45 5f  ich case SQLITE_
0290: 43 4f 52 45 20 69 73 20 6e 6f 74 20 64 65 66 69  CORE is not defi
02a0: 6e 65 64 29 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20  ned), or.**.**  
02b0: 20 20 20 2a 20 54 68 65 20 46 54 53 33 20 6d 6f     * The FTS3 mo
02c0: 64 75 6c 65 20 69 73 20 62 65 69 6e 67 20 62 75  dule is being bu
02d0: 69 6c 74 20 69 6e 74 6f 20 74 68 65 20 63 6f 72  ilt into the cor
02e0: 65 20 6f 66 0a 2a 2a 20 20 20 20 20 20 20 53 51  e of.**       SQ
02f0: 4c 69 74 65 20 28 69 6e 20 77 68 69 63 68 20 63  Lite (in which c
0300: 61 73 65 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c  ase SQLITE_ENABL
0310: 45 5f 46 54 53 33 20 69 73 20 64 65 66 69 6e 65  E_FTS3 is define
0320: 64 29 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20  d)..*/.#include 
0330: 22 66 74 73 33 49 6e 74 2e 68 22 0a 23 69 66 20  "fts3Int.h".#if 
0340: 21 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f  !defined(SQLITE_
0350: 43 4f 52 45 29 20 7c 7c 20 64 65 66 69 6e 65 64  CORE) || defined
0360: 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46  (SQLITE_ENABLE_F
0370: 54 53 33 29 0a 0a 23 69 6e 63 6c 75 64 65 20 3c  TS3)..#include <
0380: 61 73 73 65 72 74 2e 68 3e 0a 23 69 6e 63 6c 75  assert.h>.#inclu
0390: 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 0a 2f  de <string.h>../
03a0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65  *.** Return true
03b0: 20 69 66 20 74 68 65 20 74 77 6f 2d 61 72 67 75   if the two-argu
03c0: 6d 65 6e 74 20 76 65 72 73 69 6f 6e 20 6f 66 20  ment version of 
03d0: 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 28 29  fts3_tokenizer()
03e0: 0a 2a 2a 20 68 61 73 20 62 65 65 6e 20 61 63 74  .** has been act
03f0: 69 76 61 74 65 64 20 76 69 61 20 61 20 70 72 69  ivated via a pri
0400: 6f 72 20 63 61 6c 6c 20 74 6f 20 73 71 6c 69 74  or call to sqlit
0410: 65 33 5f 64 62 5f 63 6f 6e 66 69 67 28 64 62 2c  e3_db_config(db,
0420: 0a 2a 2a 20 53 51 4c 49 54 45 5f 44 42 43 4f 4e  .** SQLITE_DBCON
0430: 46 49 47 5f 45 4e 41 42 4c 45 5f 46 54 53 33 5f  FIG_ENABLE_FTS3_
0440: 54 4f 4b 45 4e 49 5a 45 52 2c 20 31 2c 20 30 29  TOKENIZER, 1, 0)
0450: 3b 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.*/.static int 
0460: 66 74 73 33 54 6f 6b 65 6e 69 7a 65 72 45 6e 61  fts3TokenizerEna
0470: 62 6c 65 64 28 73 71 6c 69 74 65 33 5f 63 6f 6e  bled(sqlite3_con
0480: 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 29 7b 0a  text *context){.
0490: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20    sqlite3 *db = 
04a0: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 5f  sqlite3_context_
04b0: 64 62 5f 68 61 6e 64 6c 65 28 63 6f 6e 74 65 78  db_handle(contex
04c0: 74 29 3b 0a 20 20 69 6e 74 20 69 73 45 6e 61 62  t);.  int isEnab
04d0: 6c 65 64 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74  led = 0;.  sqlit
04e0: 65 33 5f 64 62 5f 63 6f 6e 66 69 67 28 64 62 2c  e3_db_config(db,
04f0: 53 51 4c 49 54 45 5f 44 42 43 4f 4e 46 49 47 5f  SQLITE_DBCONFIG_
0500: 45 4e 41 42 4c 45 5f 46 54 53 33 5f 54 4f 4b 45  ENABLE_FTS3_TOKE
0510: 4e 49 5a 45 52 2c 2d 31 2c 26 69 73 45 6e 61 62  NIZER,-1,&isEnab
0520: 6c 65 64 29 3b 0a 20 20 72 65 74 75 72 6e 20 69  led);.  return i
0530: 73 45 6e 61 62 6c 65 64 3b 0a 7d 0a 0a 2f 2a 0a  sEnabled;.}../*.
0540: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
0550: 6e 20 6f 66 20 74 68 65 20 53 51 4c 20 73 63 61  n of the SQL sca
0560: 6c 61 72 20 66 75 6e 63 74 69 6f 6e 20 66 6f 72  lar function for
0570: 20 61 63 63 65 73 73 69 6e 67 20 74 68 65 20 75   accessing the u
0580: 6e 64 65 72 6c 79 69 6e 67 20 0a 2a 2a 20 68 61  nderlying .** ha
0590: 73 68 20 74 61 62 6c 65 2e 20 54 68 69 73 20 66  sh table. This f
05a0: 75 6e 63 74 69 6f 6e 20 6d 61 79 20 62 65 20 63  unction may be c
05b0: 61 6c 6c 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73  alled as follows
05c0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 45 4c 45 43 54  :.**.**   SELECT
05d0: 20 3c 66 75 6e 63 74 69 6f 6e 2d 6e 61 6d 65 3e   <function-name>
05e0: 28 3c 6b 65 79 2d 6e 61 6d 65 3e 29 3b 0a 2a 2a  (<key-name>);.**
05f0: 20 20 20 53 45 4c 45 43 54 20 3c 66 75 6e 63 74     SELECT <funct
0600: 69 6f 6e 2d 6e 61 6d 65 3e 28 3c 6b 65 79 2d 6e  ion-name>(<key-n
0610: 61 6d 65 3e 2c 20 3c 70 6f 69 6e 74 65 72 3e 29  ame>, <pointer>)
0620: 3b 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65 20 3c 66  ;.**.** where <f
0630: 75 6e 63 74 69 6f 6e 2d 6e 61 6d 65 3e 20 69 73  unction-name> is
0640: 20 74 68 65 20 6e 61 6d 65 20 70 61 73 73 65 64   the name passed
0650: 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61   as the second a
0660: 72 67 75 6d 65 6e 74 0a 2a 2a 20 74 6f 20 74 68  rgument.** to th
0670: 65 20 73 71 6c 69 74 65 33 46 74 73 33 49 6e 69  e sqlite3Fts3Ini
0680: 74 48 61 73 68 54 61 62 6c 65 28 29 20 66 75 6e  tHashTable() fun
0690: 63 74 69 6f 6e 20 28 65 2e 67 2e 20 27 66 74 73  ction (e.g. 'fts
06a0: 33 5f 74 6f 6b 65 6e 69 7a 65 72 27 29 2e 0a 2a  3_tokenizer')..*
06b0: 2a 0a 2a 2a 20 49 66 20 74 68 65 20 3c 70 6f 69  *.** If the <poi
06c0: 6e 74 65 72 3e 20 61 72 67 75 6d 65 6e 74 20 69  nter> argument i
06d0: 73 20 73 70 65 63 69 66 69 65 64 2c 20 69 74 20  s specified, it 
06e0: 6d 75 73 74 20 62 65 20 61 20 62 6c 6f 62 20 76  must be a blob v
06f0: 61 6c 75 65 0a 2a 2a 20 63 6f 6e 74 61 69 6e 69  alue.** containi
0700: 6e 67 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  ng a pointer to 
0710: 62 65 20 73 74 6f 72 65 64 20 61 73 20 74 68 65  be stored as the
0720: 20 68 61 73 68 20 64 61 74 61 20 63 6f 72 72 65   hash data corre
0730: 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20 74 6f 20 74  sponding.** to t
0740: 68 65 20 73 74 72 69 6e 67 20 3c 6b 65 79 2d 6e  he string <key-n
0750: 61 6d 65 3e 2e 20 49 66 20 3c 70 6f 69 6e 74 65  ame>. If <pointe
0760: 72 3e 20 69 73 20 6e 6f 74 20 73 70 65 63 69 66  r> is not specif
0770: 69 65 64 2c 20 74 68 65 6e 0a 2a 2a 20 74 68 65  ied, then.** the
0780: 20 73 74 72 69 6e 67 20 3c 6b 65 79 2d 6e 61 6d   string <key-nam
0790: 65 3e 20 6d 75 73 74 20 61 6c 72 65 61 64 79 20  e> must already 
07a0: 65 78 69 73 74 20 69 6e 20 74 68 65 20 68 61 73  exist in the has
07b0: 20 74 61 62 6c 65 2e 20 4f 74 68 65 72 77 69 73   table. Otherwis
07c0: 65 2c 0a 2a 2a 20 61 6e 20 65 72 72 6f 72 20 69  e,.** an error i
07d0: 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a  s returned..**.*
07e0: 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f 74  * Whether or not
07f0: 20 74 68 65 20 3c 70 6f 69 6e 74 65 72 3e 20 61   the <pointer> a
0800: 72 67 75 6d 65 6e 74 20 69 73 20 73 70 65 63 69  rgument is speci
0810: 66 69 65 64 2c 20 74 68 65 20 76 61 6c 75 65 20  fied, the value 
0820: 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69 73 20 61  returned.** is a
0830: 20 62 6c 6f 62 20 63 6f 6e 74 61 69 6e 69 6e 67   blob containing
0840: 20 74 68 65 20 70 6f 69 6e 74 65 72 20 73 74 6f   the pointer sto
0850: 72 65 64 20 61 73 20 74 68 65 20 68 61 73 68 20  red as the hash 
0860: 64 61 74 61 20 63 6f 72 72 65 73 70 6f 6e 64 69  data correspondi
0870: 6e 67 0a 2a 2a 20 74 6f 20 73 74 72 69 6e 67 20  ng.** to string 
0880: 3c 6b 65 79 2d 6e 61 6d 65 3e 20 28 61 66 74 65  <key-name> (afte
0890: 72 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65  r the hash-table
08a0: 20 69 73 20 75 70 64 61 74 65 64 2c 20 69 66 20   is updated, if 
08b0: 61 70 70 6c 69 63 61 62 6c 65 29 2e 0a 2a 2f 0a  applicable)..*/.
08c0: 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 33  static void fts3
08d0: 54 6f 6b 65 6e 69 7a 65 72 46 75 6e 63 28 0a 20  TokenizerFunc(. 
08e0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
08f0: 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74   *context,.  int
0900: 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33   argc,.  sqlite3
0910: 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b  _value **argv.){
0920: 0a 20 20 46 74 73 33 48 61 73 68 20 2a 70 48 61  .  Fts3Hash *pHa
0930: 73 68 3b 0a 20 20 76 6f 69 64 20 2a 70 50 74 72  sh;.  void *pPtr
0940: 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20 75 6e   = 0;.  const un
0950: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 7a 4e 61  signed char *zNa
0960: 6d 65 3b 0a 20 20 69 6e 74 20 6e 4e 61 6d 65 3b  me;.  int nName;
0970: 0a 0a 20 20 61 73 73 65 72 74 28 20 61 72 67 63  ..  assert( argc
0980: 3d 3d 31 20 7c 7c 20 61 72 67 63 3d 3d 32 20 29  ==1 || argc==2 )
0990: 3b 0a 0a 20 20 70 48 61 73 68 20 3d 20 28 46 74  ;..  pHash = (Ft
09a0: 73 33 48 61 73 68 20 2a 29 73 71 6c 69 74 65 33  s3Hash *)sqlite3
09b0: 5f 75 73 65 72 5f 64 61 74 61 28 63 6f 6e 74 65  _user_data(conte
09c0: 78 74 29 3b 0a 0a 20 20 7a 4e 61 6d 65 20 3d 20  xt);..  zName = 
09d0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
09e0: 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20 6e  xt(argv[0]);.  n
09f0: 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f 76  Name = sqlite3_v
0a00: 61 6c 75 65 5f 62 79 74 65 73 28 61 72 67 76 5b  alue_bytes(argv[
0a10: 30 5d 29 2b 31 3b 0a 0a 20 20 69 66 28 20 61 72  0])+1;..  if( ar
0a20: 67 63 3d 3d 32 20 29 7b 0a 20 20 20 20 69 66 28  gc==2 ){.    if(
0a30: 20 66 74 73 33 54 6f 6b 65 6e 69 7a 65 72 45 6e   fts3TokenizerEn
0a40: 61 62 6c 65 64 28 63 6f 6e 74 65 78 74 29 20 7c  abled(context) |
0a50: 7c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  | sqlite3_value_
0a60: 66 72 6f 6d 62 69 6e 64 28 61 72 67 76 5b 31 5d  frombind(argv[1]
0a70: 29 20 29 7b 0a 20 20 20 20 20 20 76 6f 69 64 20  ) ){.      void 
0a80: 2a 70 4f 6c 64 3b 0a 20 20 20 20 20 20 69 6e 74  *pOld;.      int
0a90: 20 6e 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c   n = sqlite3_val
0aa0: 75 65 5f 62 79 74 65 73 28 61 72 67 76 5b 31 5d  ue_bytes(argv[1]
0ab0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 4e 61  );.      if( zNa
0ac0: 6d 65 3d 3d 30 20 7c 7c 20 6e 21 3d 73 69 7a 65  me==0 || n!=size
0ad0: 6f 66 28 70 50 74 72 29 20 29 7b 0a 20 20 20 20  of(pPtr) ){.    
0ae0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
0af0: 6c 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74  lt_error(context
0b00: 2c 20 22 61 72 67 75 6d 65 6e 74 20 74 79 70 65  , "argument type
0b10: 20 6d 69 73 6d 61 74 63 68 22 2c 20 2d 31 29 3b   mismatch", -1);
0b20: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 3b  .        return;
0b30: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70  .      }.      p
0b40: 50 74 72 20 3d 20 2a 28 76 6f 69 64 20 2a 2a 29  Ptr = *(void **)
0b50: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 6c  sqlite3_value_bl
0b60: 6f 62 28 61 72 67 76 5b 31 5d 29 3b 0a 20 20 20  ob(argv[1]);.   
0b70: 20 20 20 70 4f 6c 64 20 3d 20 73 71 6c 69 74 65     pOld = sqlite
0b80: 33 46 74 73 33 48 61 73 68 49 6e 73 65 72 74 28  3Fts3HashInsert(
0b90: 70 48 61 73 68 2c 20 28 76 6f 69 64 20 2a 29 7a  pHash, (void *)z
0ba0: 4e 61 6d 65 2c 20 6e 4e 61 6d 65 2c 20 70 50 74  Name, nName, pPt
0bb0: 72 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 4f  r);.      if( pO
0bc0: 6c 64 3d 3d 70 50 74 72 20 29 7b 0a 20 20 20 20  ld==pPtr ){.    
0bd0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
0be0: 6c 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74  lt_error(context
0bf0: 2c 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79  , "out of memory
0c00: 22 2c 20 2d 31 29 3b 0a 20 20 20 20 20 20 7d 0a  ", -1);.      }.
0c10: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
0c20: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
0c30: 65 72 72 6f 72 28 63 6f 6e 74 65 78 74 2c 20 22  error(context, "
0c40: 66 74 73 33 74 6f 6b 65 6e 69 7a 65 20 64 69 73  fts3tokenize dis
0c50: 61 62 6c 65 64 22 2c 20 2d 31 29 3b 0a 20 20 20  abled", -1);.   
0c60: 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 7d     return;.    }
0c70: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66  .  }else{.    if
0c80: 28 20 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20 20  ( zName ){.     
0c90: 20 70 50 74 72 20 3d 20 73 71 6c 69 74 65 33 46   pPtr = sqlite3F
0ca0: 74 73 33 48 61 73 68 46 69 6e 64 28 70 48 61 73  ts3HashFind(pHas
0cb0: 68 2c 20 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65 29  h, zName, nName)
0cc0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
0cd0: 21 70 50 74 72 20 29 7b 0a 20 20 20 20 20 20 63  !pPtr ){.      c
0ce0: 68 61 72 20 2a 7a 45 72 72 20 3d 20 73 71 6c 69  har *zErr = sqli
0cf0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 75 6e 6b  te3_mprintf("unk
0d00: 6e 6f 77 6e 20 74 6f 6b 65 6e 69 7a 65 72 3a 20  nown tokenizer: 
0d10: 25 73 22 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20  %s", zName);.   
0d20: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
0d30: 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74 2c  t_error(context,
0d40: 20 7a 45 72 72 2c 20 2d 31 29 3b 0a 20 20 20 20   zErr, -1);.    
0d50: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
0d60: 45 72 72 29 3b 0a 20 20 20 20 20 20 72 65 74 75  Err);.      retu
0d70: 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  rn;.    }.  }.  
0d80: 69 66 28 20 66 74 73 33 54 6f 6b 65 6e 69 7a 65  if( fts3Tokenize
0d90: 72 45 6e 61 62 6c 65 64 28 63 6f 6e 74 65 78 74  rEnabled(context
0da0: 29 20 7c 7c 20 73 71 6c 69 74 65 33 5f 76 61 6c  ) || sqlite3_val
0db0: 75 65 5f 66 72 6f 6d 62 69 6e 64 28 61 72 67 76  ue_frombind(argv
0dc0: 5b 30 5d 29 20 29 7b 0a 20 20 20 20 73 71 6c 69  [0]) ){.    sqli
0dd0: 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28  te3_result_blob(
0de0: 63 6f 6e 74 65 78 74 2c 20 28 76 6f 69 64 20 2a  context, (void *
0df0: 29 26 70 50 74 72 2c 20 73 69 7a 65 6f 66 28 70  )&pPtr, sizeof(p
0e00: 50 74 72 29 2c 20 53 51 4c 49 54 45 5f 54 52 41  Ptr), SQLITE_TRA
0e10: 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 7d 0a 0a  NSIENT);.  }.}..
0e20: 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73 33 49  int sqlite3Fts3I
0e30: 73 49 64 43 68 61 72 28 63 68 61 72 20 63 29 7b  sIdChar(char c){
0e40: 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20  .  static const 
0e50: 63 68 61 72 20 69 73 46 74 73 49 64 43 68 61 72  char isFtsIdChar
0e60: 5b 5d 20 3d 20 7b 0a 20 20 20 20 20 20 30 2c 20  [] = {.      0, 
0e70: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 0, 0, 0, 0, 0
0e80: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
0e90: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 2f 2a   0, 0, 0, 0,  /*
0ea0: 20 30 78 20 2a 2f 0a 20 20 20 20 20 20 30 2c 20   0x */.      0, 
0eb0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 0, 0, 0, 0, 0
0ec0: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
0ed0: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 2f 2a   0, 0, 0, 0,  /*
0ee0: 20 31 78 20 2a 2f 0a 20 20 20 20 20 20 30 2c 20   1x */.      0, 
0ef0: 30 2c 20 30 2c 20 30 2c 20 31 2c 20 30 2c 20 30  0, 0, 0, 1, 0, 0
0f00: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
0f10: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 2f 2a   0, 0, 0, 0,  /*
0f20: 20 32 78 20 2a 2f 0a 20 20 20 20 20 20 31 2c 20   2x */.      1, 
0f30: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0f40: 2c 20 31 2c 20 31 2c 20 31 2c 20 30 2c 20 30 2c  , 1, 1, 1, 0, 0,
0f50: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 2f 2a   0, 0, 0, 0,  /*
0f60: 20 33 78 20 2a 2f 0a 20 20 20 20 20 20 30 2c 20   3x */.      0, 
0f70: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0f80: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
0f90: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20 2f 2a   1, 1, 1, 1,  /*
0fa0: 20 34 78 20 2a 2f 0a 20 20 20 20 20 20 31 2c 20   4x */.      1, 
0fb0: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0fc0: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 30 2c  , 1, 1, 1, 1, 0,
0fd0: 20 30 2c 20 30 2c 20 30 2c 20 31 2c 20 20 2f 2a   0, 0, 0, 1,  /*
0fe0: 20 35 78 20 2a 2f 0a 20 20 20 20 20 20 30 2c 20   5x */.      0, 
0ff0: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
1000: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
1010: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20 2f 2a   1, 1, 1, 1,  /*
1020: 20 36 78 20 2a 2f 0a 20 20 20 20 20 20 31 2c 20   6x */.      1, 
1030: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
1040: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 30 2c  , 1, 1, 1, 1, 0,
1050: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 2f 2a   0, 0, 0, 0,  /*
1060: 20 37 78 20 2a 2f 0a 20 20 7d 3b 0a 20 20 72 65   7x */.  };.  re
1070: 74 75 72 6e 20 28 63 26 30 78 38 30 20 7c 7c 20  turn (c&0x80 || 
1080: 69 73 46 74 73 49 64 43 68 61 72 5b 28 69 6e 74  isFtsIdChar[(int
1090: 29 28 63 29 5d 29 3b 0a 7d 0a 0a 63 6f 6e 73 74  )(c)]);.}..const
10a0: 20 63 68 61 72 20 2a 73 71 6c 69 74 65 33 46 74   char *sqlite3Ft
10b0: 73 33 4e 65 78 74 54 6f 6b 65 6e 28 63 6f 6e 73  s3NextToken(cons
10c0: 74 20 63 68 61 72 20 2a 7a 53 74 72 2c 20 69 6e  t char *zStr, in
10d0: 74 20 2a 70 6e 29 7b 0a 20 20 63 6f 6e 73 74 20  t *pn){.  const 
10e0: 63 68 61 72 20 2a 7a 31 3b 0a 20 20 63 6f 6e 73  char *z1;.  cons
10f0: 74 20 63 68 61 72 20 2a 7a 32 20 3d 20 30 3b 0a  t char *z2 = 0;.
1100: 0a 20 20 2f 2a 20 46 69 6e 64 20 74 68 65 20 73  .  /* Find the s
1110: 74 61 72 74 20 6f 66 20 74 68 65 20 6e 65 78 74  tart of the next
1120: 20 74 6f 6b 65 6e 2e 20 2a 2f 0a 20 20 7a 31 20   token. */.  z1 
1130: 3d 20 7a 53 74 72 3b 0a 20 20 77 68 69 6c 65 28  = zStr;.  while(
1140: 20 7a 32 3d 3d 30 20 29 7b 0a 20 20 20 20 63 68   z2==0 ){.    ch
1150: 61 72 20 63 20 3d 20 2a 7a 31 3b 0a 20 20 20 20  ar c = *z1;.    
1160: 73 77 69 74 63 68 28 20 63 20 29 7b 0a 20 20 20  switch( c ){.   
1170: 20 20 20 63 61 73 65 20 27 5c 30 27 3a 20 72 65     case '\0': re
1180: 74 75 72 6e 20 30 3b 20 20 20 20 20 20 20 20 2f  turn 0;        /
1190: 2a 20 4e 6f 20 6d 6f 72 65 20 74 6f 6b 65 6e 73  * No more tokens
11a0: 20 68 65 72 65 20 2a 2f 0a 20 20 20 20 20 20 63   here */.      c
11b0: 61 73 65 20 27 5c 27 27 3a 0a 20 20 20 20 20 20  ase '\'':.      
11c0: 63 61 73 65 20 27 22 27 3a 0a 20 20 20 20 20 20  case '"':.      
11d0: 63 61 73 65 20 27 60 27 3a 20 7b 0a 20 20 20 20  case '`': {.    
11e0: 20 20 20 20 7a 32 20 3d 20 7a 31 3b 0a 20 20 20      z2 = z1;.   
11f0: 20 20 20 20 20 77 68 69 6c 65 28 20 2a 2b 2b 7a       while( *++z
1200: 32 20 26 26 20 28 2a 7a 32 21 3d 63 20 7c 7c 20  2 && (*z2!=c || 
1210: 2a 2b 2b 7a 32 3d 3d 63 29 20 29 3b 0a 20 20 20  *++z2==c) );.   
1220: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
1230: 20 20 7d 0a 20 20 20 20 20 20 63 61 73 65 20 27    }.      case '
1240: 5b 27 3a 0a 20 20 20 20 20 20 20 20 7a 32 20 3d  [':.        z2 =
1250: 20 26 7a 31 5b 31 5d 3b 0a 20 20 20 20 20 20 20   &z1[1];.       
1260: 20 77 68 69 6c 65 28 20 2a 7a 32 20 26 26 20 7a   while( *z2 && z
1270: 32 5b 30 5d 21 3d 27 5d 27 20 29 20 7a 32 2b 2b  2[0]!=']' ) z2++
1280: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 2a 7a  ;.        if( *z
1290: 32 20 29 20 7a 32 2b 2b 3b 0a 20 20 20 20 20 20  2 ) z2++;.      
12a0: 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20    break;..      
12b0: 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20  default:.       
12c0: 20 69 66 28 20 73 71 6c 69 74 65 33 46 74 73 33   if( sqlite3Fts3
12d0: 49 73 49 64 43 68 61 72 28 2a 7a 31 29 20 29 7b  IsIdChar(*z1) ){
12e0: 0a 20 20 20 20 20 20 20 20 20 20 7a 32 20 3d 20  .          z2 = 
12f0: 26 7a 31 5b 31 5d 3b 0a 20 20 20 20 20 20 20 20  &z1[1];.        
1300: 20 20 77 68 69 6c 65 28 20 73 71 6c 69 74 65 33    while( sqlite3
1310: 46 74 73 33 49 73 49 64 43 68 61 72 28 2a 7a 32  Fts3IsIdChar(*z2
1320: 29 20 29 20 7a 32 2b 2b 3b 0a 20 20 20 20 20 20  ) ) z2++;.      
1330: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
1340: 20 20 20 7a 31 2b 2b 3b 0a 20 20 20 20 20 20 20     z1++;.       
1350: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
1360: 2a 70 6e 20 3d 20 28 69 6e 74 29 28 7a 32 2d 7a  *pn = (int)(z2-z
1370: 31 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a 31 3b  1);.  return z1;
1380: 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74 65 33 46  .}..int sqlite3F
1390: 74 73 33 49 6e 69 74 54 6f 6b 65 6e 69 7a 65 72  ts3InitTokenizer
13a0: 28 0a 20 20 46 74 73 33 48 61 73 68 20 2a 70 48  (.  Fts3Hash *pH
13b0: 61 73 68 2c 20 20 20 20 20 20 20 20 20 20 20 20  ash,            
13c0: 20 20 20 20 2f 2a 20 54 6f 6b 65 6e 69 7a 65 72      /* Tokenizer
13d0: 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20   hash table */. 
13e0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 72   const char *zAr
13f0: 67 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  g,              
1400: 20 2f 2a 20 54 6f 6b 65 6e 69 7a 65 72 20 6e 61   /* Tokenizer na
1410: 6d 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  me */.  sqlite3_
1420: 74 6f 6b 65 6e 69 7a 65 72 20 2a 2a 70 70 54 6f  tokenizer **ppTo
1430: 6b 2c 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20  k,      /* OUT: 
1440: 54 6f 6b 65 6e 69 7a 65 72 20 28 69 66 20 61 70  Tokenizer (if ap
1450: 70 6c 69 63 61 62 6c 65 29 20 2a 2f 0a 20 20 63  plicable) */.  c
1460: 68 61 72 20 2a 2a 70 7a 45 72 72 20 20 20 20 20  har **pzErr     
1470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1480: 2a 20 4f 55 54 3a 20 53 65 74 20 74 6f 20 6d 61  * OUT: Set to ma
1490: 6c 6c 6f 63 65 64 20 65 72 72 6f 72 20 6d 65 73  lloced error mes
14a0: 73 61 67 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  sage */.){.  int
14b0: 20 72 63 3b 0a 20 20 63 68 61 72 20 2a 7a 20 3d   rc;.  char *z =
14c0: 20 28 63 68 61 72 20 2a 29 7a 41 72 67 3b 0a 20   (char *)zArg;. 
14d0: 20 69 6e 74 20 6e 20 3d 20 30 3b 0a 20 20 63 68   int n = 0;.  ch
14e0: 61 72 20 2a 7a 43 6f 70 79 3b 0a 20 20 63 68 61  ar *zCopy;.  cha
14f0: 72 20 2a 7a 45 6e 64 3b 20 20 20 20 20 20 20 20  r *zEnd;        
1500: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1510: 50 6f 69 6e 74 65 72 20 74 6f 20 6e 75 6c 2d 74  Pointer to nul-t
1520: 65 72 6d 20 6f 66 20 7a 43 6f 70 79 20 2a 2f 0a  erm of zCopy */.
1530: 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69    sqlite3_tokeni
1540: 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a 6d 3b 0a 0a  zer_module *m;..
1550: 20 20 7a 43 6f 70 79 20 3d 20 73 71 6c 69 74 65    zCopy = sqlite
1560: 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20  3_mprintf("%s", 
1570: 7a 41 72 67 29 3b 0a 20 20 69 66 28 20 21 7a 43  zArg);.  if( !zC
1580: 6f 70 79 20 29 20 72 65 74 75 72 6e 20 53 51 4c  opy ) return SQL
1590: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7a 45 6e  ITE_NOMEM;.  zEn
15a0: 64 20 3d 20 26 7a 43 6f 70 79 5b 73 74 72 6c 65  d = &zCopy[strle
15b0: 6e 28 7a 43 6f 70 79 29 5d 3b 0a 0a 20 20 7a 20  n(zCopy)];..  z 
15c0: 3d 20 28 63 68 61 72 20 2a 29 73 71 6c 69 74 65  = (char *)sqlite
15d0: 33 46 74 73 33 4e 65 78 74 54 6f 6b 65 6e 28 7a  3Fts3NextToken(z
15e0: 43 6f 70 79 2c 20 26 6e 29 3b 0a 20 20 69 66 28  Copy, &n);.  if(
15f0: 20 7a 3d 3d 30 20 29 7b 0a 20 20 20 20 61 73 73   z==0 ){.    ass
1600: 65 72 74 28 20 6e 3d 3d 30 20 29 3b 0a 20 20 20  ert( n==0 );.   
1610: 20 7a 20 3d 20 7a 43 6f 70 79 3b 0a 20 20 7d 0a   z = zCopy;.  }.
1620: 20 20 7a 5b 6e 5d 20 3d 20 27 5c 30 27 3b 0a 20    z[n] = '\0';. 
1630: 20 73 71 6c 69 74 65 33 46 74 73 33 44 65 71 75   sqlite3Fts3Dequ
1640: 6f 74 65 28 7a 29 3b 0a 0a 20 20 6d 20 3d 20 28  ote(z);..  m = (
1650: 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
1660: 72 5f 6d 6f 64 75 6c 65 20 2a 29 73 71 6c 69 74  r_module *)sqlit
1670: 65 33 46 74 73 33 48 61 73 68 46 69 6e 64 28 70  e3Fts3HashFind(p
1680: 48 61 73 68 2c 7a 2c 28 69 6e 74 29 73 74 72 6c  Hash,z,(int)strl
1690: 65 6e 28 7a 29 2b 31 29 3b 0a 20 20 69 66 28 20  en(z)+1);.  if( 
16a0: 21 6d 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  !m ){.    sqlite
16b0: 33 46 74 73 33 45 72 72 4d 73 67 28 70 7a 45 72  3Fts3ErrMsg(pzEr
16c0: 72 2c 20 22 75 6e 6b 6e 6f 77 6e 20 74 6f 6b 65  r, "unknown toke
16d0: 6e 69 7a 65 72 3a 20 25 73 22 2c 20 7a 29 3b 0a  nizer: %s", z);.
16e0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
16f0: 45 52 52 4f 52 3b 0a 20 20 7d 65 6c 73 65 7b 0a  ERROR;.  }else{.
1700: 20 20 20 20 63 68 61 72 20 63 6f 6e 73 74 20 2a      char const *
1710: 2a 61 41 72 67 20 3d 20 30 3b 0a 20 20 20 20 69  *aArg = 0;.    i
1720: 6e 74 20 69 41 72 67 20 3d 20 30 3b 0a 20 20 20  nt iArg = 0;.   
1730: 20 7a 20 3d 20 26 7a 5b 6e 2b 31 5d 3b 0a 20 20   z = &z[n+1];.  
1740: 20 20 77 68 69 6c 65 28 20 7a 3c 7a 45 6e 64 20    while( z<zEnd 
1750: 26 26 20 28 4e 55 4c 4c 21 3d 28 7a 20 3d 20 28  && (NULL!=(z = (
1760: 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33 46 74  char *)sqlite3Ft
1770: 73 33 4e 65 78 74 54 6f 6b 65 6e 28 7a 2c 20 26  s3NextToken(z, &
1780: 6e 29 29 29 20 29 7b 0a 20 20 20 20 20 20 69 6e  n))) ){.      in
1790: 74 20 6e 4e 65 77 20 3d 20 73 69 7a 65 6f 66 28  t nNew = sizeof(
17a0: 63 68 61 72 20 2a 29 2a 28 69 41 72 67 2b 31 29  char *)*(iArg+1)
17b0: 3b 0a 20 20 20 20 20 20 63 68 61 72 20 63 6f 6e  ;.      char con
17c0: 73 74 20 2a 2a 61 4e 65 77 20 3d 20 28 63 6f 6e  st **aNew = (con
17d0: 73 74 20 63 68 61 72 20 2a 2a 29 73 71 6c 69 74  st char **)sqlit
17e0: 65 33 5f 72 65 61 6c 6c 6f 63 28 28 76 6f 69 64  e3_realloc((void
17f0: 20 2a 29 61 41 72 67 2c 20 6e 4e 65 77 29 3b 0a   *)aArg, nNew);.
1800: 20 20 20 20 20 20 69 66 28 20 21 61 4e 65 77 20        if( !aNew 
1810: 29 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  ){.        sqlit
1820: 65 33 5f 66 72 65 65 28 7a 43 6f 70 79 29 3b 0a  e3_free(zCopy);.
1830: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
1840: 66 72 65 65 28 28 76 6f 69 64 20 2a 29 61 41 72  free((void *)aAr
1850: 67 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75  g);.        retu
1860: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
1870: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61  .      }.      a
1880: 41 72 67 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20  Arg = aNew;.    
1890: 20 20 61 41 72 67 5b 69 41 72 67 2b 2b 5d 20 3d    aArg[iArg++] =
18a0: 20 7a 3b 0a 20 20 20 20 20 20 7a 5b 6e 5d 20 3d   z;.      z[n] =
18b0: 20 27 5c 30 27 3b 0a 20 20 20 20 20 20 73 71 6c   '\0';.      sql
18c0: 69 74 65 33 46 74 73 33 44 65 71 75 6f 74 65 28  ite3Fts3Dequote(
18d0: 7a 29 3b 0a 20 20 20 20 20 20 7a 20 3d 20 26 7a  z);.      z = &z
18e0: 5b 6e 2b 31 5d 3b 0a 20 20 20 20 7d 0a 20 20 20  [n+1];.    }.   
18f0: 20 72 63 20 3d 20 6d 2d 3e 78 43 72 65 61 74 65   rc = m->xCreate
1900: 28 69 41 72 67 2c 20 61 41 72 67 2c 20 70 70 54  (iArg, aArg, ppT
1910: 6f 6b 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  ok);.    assert(
1920: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc!=SQLITE_OK |
1930: 7c 20 2a 70 70 54 6f 6b 20 29 3b 0a 20 20 20 20  | *ppTok );.    
1940: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
1950: 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  K ){.      sqlit
1960: 65 33 46 74 73 33 45 72 72 4d 73 67 28 70 7a 45  e3Fts3ErrMsg(pzE
1970: 72 72 2c 20 22 75 6e 6b 6e 6f 77 6e 20 74 6f 6b  rr, "unknown tok
1980: 65 6e 69 7a 65 72 22 29 3b 0a 20 20 20 20 7d 65  enizer");.    }e
1990: 6c 73 65 7b 0a 20 20 20 20 20 20 28 2a 70 70 54  lse{.      (*ppT
19a0: 6f 6b 29 2d 3e 70 4d 6f 64 75 6c 65 20 3d 20 6d  ok)->pModule = m
19b0: 3b 20 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c  ; .    }.    sql
19c0: 69 74 65 33 5f 66 72 65 65 28 28 76 6f 69 64 20  ite3_free((void 
19d0: 2a 29 61 41 72 67 29 3b 0a 20 20 7d 0a 0a 20 20  *)aArg);.  }..  
19e0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 43 6f  sqlite3_free(zCo
19f0: 70 79 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  py);.  return rc
1a00: 3b 0a 7d 0a 0a 0a 23 69 66 64 65 66 20 53 51 4c  ;.}...#ifdef SQL
1a10: 49 54 45 5f 54 45 53 54 0a 0a 23 69 66 20 64 65  ITE_TEST..#if de
1a20: 66 69 6e 65 64 28 49 4e 43 4c 55 44 45 5f 53 51  fined(INCLUDE_SQ
1a30: 4c 49 54 45 5f 54 43 4c 5f 48 29 0a 23 20 20 69  LITE_TCL_H).#  i
1a40: 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 5f 74  nclude "sqlite_t
1a50: 63 6c 2e 68 22 0a 23 65 6c 73 65 0a 23 20 20 69  cl.h".#else.#  i
1a60: 6e 63 6c 75 64 65 20 22 74 63 6c 2e 68 22 0a 23  nclude "tcl.h".#
1a70: 65 6e 64 69 66 0a 23 69 6e 63 6c 75 64 65 20 3c  endif.#include <
1a80: 73 74 72 69 6e 67 2e 68 3e 0a 0a 2f 2a 0a 2a 2a  string.h>../*.**
1a90: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
1aa0: 6f 66 20 61 20 73 70 65 63 69 61 6c 20 53 51 4c  of a special SQL
1ab0: 20 73 63 61 6c 61 72 20 66 75 6e 63 74 69 6f 6e   scalar function
1ac0: 20 66 6f 72 20 74 65 73 74 69 6e 67 20 74 6f 6b   for testing tok
1ad0: 65 6e 69 7a 65 72 73 20 0a 2a 2a 20 64 65 73 69  enizers .** desi
1ae0: 67 6e 65 64 20 74 6f 20 62 65 20 75 73 65 64 20  gned to be used 
1af0: 69 6e 20 63 6f 6e 63 65 72 74 20 77 69 74 68 20  in concert with 
1b00: 74 68 65 20 54 63 6c 20 74 65 73 74 69 6e 67 20  the Tcl testing 
1b10: 66 72 61 6d 65 77 6f 72 6b 2e 20 54 68 69 73 0a  framework. This.
1b20: 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 6d 75 73 74  ** function must
1b30: 20 62 65 20 63 61 6c 6c 65 64 20 77 69 74 68 20   be called with 
1b40: 74 77 6f 20 6f 72 20 6d 6f 72 65 20 61 72 67 75  two or more argu
1b50: 6d 65 6e 74 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 53  ments:.**.**   S
1b60: 45 4c 45 43 54 20 3c 66 75 6e 63 74 69 6f 6e 2d  ELECT <function-
1b70: 6e 61 6d 65 3e 28 3c 6b 65 79 2d 6e 61 6d 65 3e  name>(<key-name>
1b80: 2c 20 2e 2e 2e 2c 20 3c 69 6e 70 75 74 2d 73 74  , ..., <input-st
1b90: 72 69 6e 67 3e 29 3b 0a 2a 2a 0a 2a 2a 20 77 68  ring>);.**.** wh
1ba0: 65 72 65 20 3c 66 75 6e 63 74 69 6f 6e 2d 6e 61  ere <function-na
1bb0: 6d 65 3e 20 69 73 20 74 68 65 20 6e 61 6d 65 20  me> is the name 
1bc0: 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73 65  passed as the se
1bd0: 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 0a 2a 2a  cond argument.**
1be0: 20 74 6f 20 74 68 65 20 73 71 6c 69 74 65 33 46   to the sqlite3F
1bf0: 74 73 33 49 6e 69 74 48 61 73 68 54 61 62 6c 65  ts3InitHashTable
1c00: 28 29 20 66 75 6e 63 74 69 6f 6e 20 28 65 2e 67  () function (e.g
1c10: 2e 20 27 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65  . 'fts3_tokenize
1c20: 72 27 29 0a 2a 2a 20 63 6f 6e 63 61 74 65 6e 61  r').** concatena
1c30: 74 65 64 20 77 69 74 68 20 74 68 65 20 73 74 72  ted with the str
1c40: 69 6e 67 20 27 5f 74 65 73 74 27 20 28 65 2e 67  ing '_test' (e.g
1c50: 2e 20 27 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65  . 'fts3_tokenize
1c60: 72 5f 74 65 73 74 27 29 2e 0a 2a 2a 0a 2a 2a 20  r_test')..**.** 
1c70: 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65  The return value
1c80: 20 69 73 20 61 20 73 74 72 69 6e 67 20 74 68 61   is a string tha
1c90: 74 20 6d 61 79 20 62 65 20 69 6e 74 65 72 70 72  t may be interpr
1ca0: 65 74 65 64 20 61 73 20 61 20 54 63 6c 0a 2a 2a  eted as a Tcl.**
1cb0: 20 6c 69 73 74 2e 20 46 6f 72 20 65 61 63 68 20   list. For each 
1cc0: 74 6f 6b 65 6e 20 69 6e 20 74 68 65 20 3c 69 6e  token in the <in
1cd0: 70 75 74 2d 73 74 72 69 6e 67 3e 2c 20 74 68 72  put-string>, thr
1ce0: 65 65 20 65 6c 65 6d 65 6e 74 73 20 61 72 65 0a  ee elements are.
1cf0: 2a 2a 20 61 64 64 65 64 20 74 6f 20 74 68 65 20  ** added to the 
1d00: 72 65 74 75 72 6e 65 64 20 6c 69 73 74 2e 20 54  returned list. T
1d10: 68 65 20 66 69 72 73 74 20 69 73 20 74 68 65 20  he first is the 
1d20: 74 6f 6b 65 6e 20 70 6f 73 69 74 69 6f 6e 2c 20  token position, 
1d30: 74 68 65 20 0a 2a 2a 20 73 65 63 6f 6e 64 20 69  the .** second i
1d40: 73 20 74 68 65 20 74 6f 6b 65 6e 20 74 65 78 74  s the token text
1d50: 20 28 66 6f 6c 64 65 64 2c 20 73 74 65 6d 6d 65   (folded, stemme
1d60: 64 2c 20 65 74 63 2e 29 20 61 6e 64 20 74 68 65  d, etc.) and the
1d70: 20 74 68 69 72 64 20 69 73 20 74 68 65 0a 2a 2a   third is the.**
1d80: 20 73 75 62 73 74 72 69 6e 67 20 6f 66 20 3c 69   substring of <i
1d90: 6e 70 75 74 2d 73 74 72 69 6e 67 3e 20 61 73 73  nput-string> ass
1da0: 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65  ociated with the
1db0: 20 74 6f 6b 65 6e 2e 20 46 6f 72 20 65 78 61 6d   token. For exam
1dc0: 70 6c 65 2c 20 0a 2a 2a 20 75 73 69 6e 67 20 74  ple, .** using t
1dd0: 68 65 20 62 75 69 6c 74 2d 69 6e 20 22 73 69 6d  he built-in "sim
1de0: 70 6c 65 22 20 74 6f 6b 65 6e 69 7a 65 72 3a 0a  ple" tokenizer:.
1df0: 2a 2a 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20 66  **.**   SELECT f
1e00: 74 73 5f 74 6f 6b 65 6e 69 7a 65 72 5f 74 65 73  ts_tokenizer_tes
1e10: 74 28 27 73 69 6d 70 6c 65 27 2c 20 27 49 20 64  t('simple', 'I d
1e20: 6f 6e 27 74 20 73 65 65 20 68 6f 77 27 29 3b 0a  on't see how');.
1e30: 2a 2a 0a 2a 2a 20 77 69 6c 6c 20 72 65 74 75 72  **.** will retur
1e40: 6e 20 74 68 65 20 73 74 72 69 6e 67 3a 0a 2a 2a  n the string:.**
1e50: 0a 2a 2a 20 20 20 22 7b 30 20 69 20 49 20 31 20  .**   "{0 i I 1 
1e60: 64 6f 6e 74 20 64 6f 6e 27 74 20 32 20 73 65 65  dont don't 2 see
1e70: 20 73 65 65 20 33 20 68 6f 77 20 68 6f 77 7d 22   see 3 how how}"
1e80: 0a 2a 2a 20 20 20 0a 2a 2f 0a 73 74 61 74 69 63  .**   .*/.static
1e90: 20 76 6f 69 64 20 74 65 73 74 46 75 6e 63 28 0a   void testFunc(.
1ea0: 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78    sqlite3_contex
1eb0: 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69 6e  t *context,.  in
1ec0: 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65  t argc,.  sqlite
1ed0: 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29  3_value **argv.)
1ee0: 7b 0a 20 20 46 74 73 33 48 61 73 68 20 2a 70 48  {.  Fts3Hash *pH
1ef0: 61 73 68 3b 0a 20 20 73 71 6c 69 74 65 33 5f 74  ash;.  sqlite3_t
1f00: 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20  okenizer_module 
1f10: 2a 70 3b 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f  *p;.  sqlite3_to
1f20: 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69  kenizer *pTokeni
1f30: 7a 65 72 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74  zer = 0;.  sqlit
1f40: 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72  e3_tokenizer_cur
1f50: 73 6f 72 20 2a 70 43 73 72 20 3d 20 30 3b 0a 0a  sor *pCsr = 0;..
1f60: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45    const char *zE
1f70: 72 72 20 3d 20 30 3b 0a 0a 20 20 63 6f 6e 73 74  rr = 0;..  const
1f80: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20   char *zName;.  
1f90: 69 6e 74 20 6e 4e 61 6d 65 3b 0a 20 20 63 6f 6e  int nName;.  con
1fa0: 73 74 20 63 68 61 72 20 2a 7a 49 6e 70 75 74 3b  st char *zInput;
1fb0: 0a 20 20 69 6e 74 20 6e 49 6e 70 75 74 3b 0a 0a  .  int nInput;..
1fc0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a    const char *az
1fd0: 41 72 67 5b 36 34 5d 3b 0a 0a 20 20 63 6f 6e 73  Arg[64];..  cons
1fe0: 74 20 63 68 61 72 20 2a 7a 54 6f 6b 65 6e 3b 0a  t char *zToken;.
1ff0: 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 20 3d 20 30    int nToken = 0
2000: 3b 0a 20 20 69 6e 74 20 69 53 74 61 72 74 20 3d  ;.  int iStart =
2010: 20 30 3b 0a 20 20 69 6e 74 20 69 45 6e 64 20 3d   0;.  int iEnd =
2020: 20 30 3b 0a 20 20 69 6e 74 20 69 50 6f 73 20 3d   0;.  int iPos =
2030: 20 30 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20   0;.  int i;..  
2040: 54 63 6c 5f 4f 62 6a 20 2a 70 52 65 74 3b 0a 0a  Tcl_Obj *pRet;..
2050: 20 20 69 66 28 20 61 72 67 63 3c 32 20 29 7b 0a    if( argc<2 ){.
2060: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
2070: 6c 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74  lt_error(context
2080: 2c 20 22 69 6e 73 75 66 66 69 63 69 65 6e 74 20  , "insufficient 
2090: 61 72 67 75 6d 65 6e 74 73 22 2c 20 2d 31 29 3b  arguments", -1);
20a0: 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d  .    return;.  }
20b0: 0a 0a 20 20 6e 4e 61 6d 65 20 3d 20 73 71 6c 69  ..  nName = sqli
20c0: 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28  te3_value_bytes(
20d0: 61 72 67 76 5b 30 5d 29 3b 0a 20 20 7a 4e 61 6d  argv[0]);.  zNam
20e0: 65 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 20  e = (const char 
20f0: 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  *)sqlite3_value_
2100: 74 65 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20  text(argv[0]);. 
2110: 20 6e 49 6e 70 75 74 20 3d 20 73 71 6c 69 74 65   nInput = sqlite
2120: 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61 72  3_value_bytes(ar
2130: 67 76 5b 61 72 67 63 2d 31 5d 29 3b 0a 20 20 7a  gv[argc-1]);.  z
2140: 49 6e 70 75 74 20 3d 20 28 63 6f 6e 73 74 20 63  Input = (const c
2150: 68 61 72 20 2a 29 73 71 6c 69 74 65 33 5f 76 61  har *)sqlite3_va
2160: 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 61 72  lue_text(argv[ar
2170: 67 63 2d 31 5d 29 3b 0a 0a 20 20 70 48 61 73 68  gc-1]);..  pHash
2180: 20 3d 20 28 46 74 73 33 48 61 73 68 20 2a 29 73   = (Fts3Hash *)s
2190: 71 6c 69 74 65 33 5f 75 73 65 72 5f 64 61 74 61  qlite3_user_data
21a0: 28 63 6f 6e 74 65 78 74 29 3b 0a 20 20 70 20 3d  (context);.  p =
21b0: 20 28 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69   (sqlite3_tokeni
21c0: 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a 29 73 71 6c  zer_module *)sql
21d0: 69 74 65 33 46 74 73 33 48 61 73 68 46 69 6e 64  ite3Fts3HashFind
21e0: 28 70 48 61 73 68 2c 20 7a 4e 61 6d 65 2c 20 6e  (pHash, zName, n
21f0: 4e 61 6d 65 2b 31 29 3b 0a 0a 20 20 69 66 28 20  Name+1);..  if( 
2200: 21 70 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a  !p ){.    char *
2210: 7a 45 72 72 32 20 3d 20 73 71 6c 69 74 65 33 5f  zErr2 = sqlite3_
2220: 6d 70 72 69 6e 74 66 28 22 75 6e 6b 6e 6f 77 6e  mprintf("unknown
2230: 20 74 6f 6b 65 6e 69 7a 65 72 3a 20 25 73 22 2c   tokenizer: %s",
2240: 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 73 71 6c   zName);.    sql
2250: 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f  ite3_result_erro
2260: 72 28 63 6f 6e 74 65 78 74 2c 20 7a 45 72 72 32  r(context, zErr2
2270: 2c 20 2d 31 29 3b 0a 20 20 20 20 73 71 6c 69 74  , -1);.    sqlit
2280: 65 33 5f 66 72 65 65 28 7a 45 72 72 32 29 3b 0a  e3_free(zErr2);.
2290: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a      return;.  }.
22a0: 0a 20 20 70 52 65 74 20 3d 20 54 63 6c 5f 4e 65  .  pRet = Tcl_Ne
22b0: 77 4f 62 6a 28 29 3b 0a 20 20 54 63 6c 5f 49 6e  wObj();.  Tcl_In
22c0: 63 72 52 65 66 43 6f 75 6e 74 28 70 52 65 74 29  crRefCount(pRet)
22d0: 3b 0a 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c  ;..  for(i=1; i<
22e0: 61 72 67 63 2d 31 3b 20 69 2b 2b 29 7b 0a 20 20  argc-1; i++){.  
22f0: 20 20 61 7a 41 72 67 5b 69 2d 31 5d 20 3d 20 28    azArg[i-1] = (
2300: 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 73 71 6c  const char *)sql
2310: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
2320: 61 72 67 76 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20  argv[i]);.  }.. 
2330: 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 21 3d   if( SQLITE_OK!=
2340: 70 2d 3e 78 43 72 65 61 74 65 28 61 72 67 63 2d  p->xCreate(argc-
2350: 32 2c 20 61 7a 41 72 67 2c 20 26 70 54 6f 6b 65  2, azArg, &pToke
2360: 6e 69 7a 65 72 29 20 29 7b 0a 20 20 20 20 7a 45  nizer) ){.    zE
2370: 72 72 20 3d 20 22 65 72 72 6f 72 20 69 6e 20 78  rr = "error in x
2380: 43 72 65 61 74 65 28 29 22 3b 0a 20 20 20 20 67  Create()";.    g
2390: 6f 74 6f 20 66 69 6e 69 73 68 3b 0a 20 20 7d 0a  oto finish;.  }.
23a0: 20 20 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e 70 4d    pTokenizer->pM
23b0: 6f 64 75 6c 65 20 3d 20 70 3b 0a 20 20 69 66 28  odule = p;.  if(
23c0: 20 73 71 6c 69 74 65 33 46 74 73 33 4f 70 65 6e   sqlite3Fts3Open
23d0: 54 6f 6b 65 6e 69 7a 65 72 28 70 54 6f 6b 65 6e  Tokenizer(pToken
23e0: 69 7a 65 72 2c 20 30 2c 20 7a 49 6e 70 75 74 2c  izer, 0, zInput,
23f0: 20 6e 49 6e 70 75 74 2c 20 26 70 43 73 72 29 20   nInput, &pCsr) 
2400: 29 7b 0a 20 20 20 20 7a 45 72 72 20 3d 20 22 65  ){.    zErr = "e
2410: 72 72 6f 72 20 69 6e 20 78 4f 70 65 6e 28 29 22  rror in xOpen()"
2420: 3b 0a 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73  ;.    goto finis
2430: 68 3b 0a 20 20 7d 0a 0a 20 20 77 68 69 6c 65 28  h;.  }..  while(
2440: 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 70 2d 3e 78   SQLITE_OK==p->x
2450: 4e 65 78 74 28 70 43 73 72 2c 20 26 7a 54 6f 6b  Next(pCsr, &zTok
2460: 65 6e 2c 20 26 6e 54 6f 6b 65 6e 2c 20 26 69 53  en, &nToken, &iS
2470: 74 61 72 74 2c 20 26 69 45 6e 64 2c 20 26 69 50  tart, &iEnd, &iP
2480: 6f 73 29 20 29 7b 0a 20 20 20 20 54 63 6c 5f 4c  os) ){.    Tcl_L
2490: 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d  istObjAppendElem
24a0: 65 6e 74 28 30 2c 20 70 52 65 74 2c 20 54 63 6c  ent(0, pRet, Tcl
24b0: 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 50 6f 73 29  _NewIntObj(iPos)
24c0: 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f  );.    Tcl_ListO
24d0: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
24e0: 30 2c 20 70 52 65 74 2c 20 54 63 6c 5f 4e 65 77  0, pRet, Tcl_New
24f0: 53 74 72 69 6e 67 4f 62 6a 28 7a 54 6f 6b 65 6e  StringObj(zToken
2500: 2c 20 6e 54 6f 6b 65 6e 29 29 3b 0a 20 20 20 20  , nToken));.    
2510: 7a 54 6f 6b 65 6e 20 3d 20 26 7a 49 6e 70 75 74  zToken = &zInput
2520: 5b 69 53 74 61 72 74 5d 3b 0a 20 20 20 20 6e 54  [iStart];.    nT
2530: 6f 6b 65 6e 20 3d 20 69 45 6e 64 2d 69 53 74 61  oken = iEnd-iSta
2540: 72 74 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74  rt;.    Tcl_List
2550: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
2560: 28 30 2c 20 70 52 65 74 2c 20 54 63 6c 5f 4e 65  (0, pRet, Tcl_Ne
2570: 77 53 74 72 69 6e 67 4f 62 6a 28 7a 54 6f 6b 65  wStringObj(zToke
2580: 6e 2c 20 6e 54 6f 6b 65 6e 29 29 3b 0a 20 20 7d  n, nToken));.  }
2590: 0a 0a 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4f  ..  if( SQLITE_O
25a0: 4b 21 3d 70 2d 3e 78 43 6c 6f 73 65 28 70 43 73  K!=p->xClose(pCs
25b0: 72 29 20 29 7b 0a 20 20 20 20 7a 45 72 72 20 3d  r) ){.    zErr =
25c0: 20 22 65 72 72 6f 72 20 69 6e 20 78 43 6c 6f 73   "error in xClos
25d0: 65 28 29 22 3b 0a 20 20 20 20 67 6f 74 6f 20 66  e()";.    goto f
25e0: 69 6e 69 73 68 3b 0a 20 20 7d 0a 20 20 69 66 28  inish;.  }.  if(
25f0: 20 53 51 4c 49 54 45 5f 4f 4b 21 3d 70 2d 3e 78   SQLITE_OK!=p->x
2600: 44 65 73 74 72 6f 79 28 70 54 6f 6b 65 6e 69 7a  Destroy(pTokeniz
2610: 65 72 29 20 29 7b 0a 20 20 20 20 7a 45 72 72 20  er) ){.    zErr 
2620: 3d 20 22 65 72 72 6f 72 20 69 6e 20 78 44 65 73  = "error in xDes
2630: 74 72 6f 79 28 29 22 3b 0a 20 20 20 20 67 6f 74  troy()";.    got
2640: 6f 20 66 69 6e 69 73 68 3b 0a 20 20 7d 0a 0a 66  o finish;.  }..f
2650: 69 6e 69 73 68 3a 0a 20 20 69 66 28 20 7a 45 72  inish:.  if( zEr
2660: 72 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  r ){.    sqlite3
2670: 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 63 6f  _result_error(co
2680: 6e 74 65 78 74 2c 20 7a 45 72 72 2c 20 2d 31 29  ntext, zErr, -1)
2690: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73  ;.  }else{.    s
26a0: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65  qlite3_result_te
26b0: 78 74 28 63 6f 6e 74 65 78 74 2c 20 54 63 6c 5f  xt(context, Tcl_
26c0: 47 65 74 53 74 72 69 6e 67 28 70 52 65 74 29 2c  GetString(pRet),
26d0: 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e   -1, SQLITE_TRAN
26e0: 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 20 20 54 63  SIENT);.  }.  Tc
26f0: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70  l_DecrRefCount(p
2700: 52 65 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 0a  Ret);.}..static.
2710: 69 6e 74 20 72 65 67 69 73 74 65 72 54 6f 6b 65  int registerToke
2720: 6e 69 7a 65 72 28 0a 20 20 73 71 6c 69 74 65 33  nizer(.  sqlite3
2730: 20 2a 64 62 2c 20 0a 20 20 63 68 61 72 20 2a 7a   *db, .  char *z
2740: 4e 61 6d 65 2c 20 0a 20 20 63 6f 6e 73 74 20 73  Name, .  const s
2750: 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72  qlite3_tokenizer
2760: 5f 6d 6f 64 75 6c 65 20 2a 70 0a 29 7b 0a 20 20  _module *p.){.  
2770: 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69 74 65  int rc;.  sqlite
2780: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20  3_stmt *pStmt;. 
2790: 20 63 6f 6e 73 74 20 63 68 61 72 20 7a 53 71 6c   const char zSql
27a0: 5b 5d 20 3d 20 22 53 45 4c 45 43 54 20 66 74 73  [] = "SELECT fts
27b0: 33 5f 74 6f 6b 65 6e 69 7a 65 72 28 3f 2c 20 3f  3_tokenizer(?, ?
27c0: 29 22 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69  )";..  rc = sqli
27d0: 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28 64  te3_prepare_v2(d
27e0: 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53  b, zSql, -1, &pS
27f0: 74 6d 74 2c 20 30 29 3b 0a 20 20 69 66 28 20 72  tmt, 0);.  if( r
2800: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
2810: 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
2820: 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 62 69   }..  sqlite3_bi
2830: 6e 64 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 31  nd_text(pStmt, 1
2840: 2c 20 7a 4e 61 6d 65 2c 20 2d 31 2c 20 53 51 4c  , zName, -1, SQL
2850: 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 73  ITE_STATIC);.  s
2860: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 62 6c 6f 62  qlite3_bind_blob
2870: 28 70 53 74 6d 74 2c 20 32 2c 20 26 70 2c 20 73  (pStmt, 2, &p, s
2880: 69 7a 65 6f 66 28 70 29 2c 20 53 51 4c 49 54 45  izeof(p), SQLITE
2890: 5f 53 54 41 54 49 43 29 3b 0a 20 20 73 71 6c 69  _STATIC);.  sqli
28a0: 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3b  te3_step(pStmt);
28b0: 0a 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ..  return sqlit
28c0: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
28d0: 74 29 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 0a 69  t);.}...static.i
28e0: 6e 74 20 71 75 65 72 79 54 6f 6b 65 6e 69 7a 65  nt queryTokenize
28f0: 72 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  r(.  sqlite3 *db
2900: 2c 20 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65  , .  char *zName
2910: 2c 20 20 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69  ,  .  const sqli
2920: 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f  te3_tokenizer_mo
2930: 64 75 6c 65 20 2a 2a 70 70 0a 29 7b 0a 20 20 69  dule **pp.){.  i
2940: 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69 74 65 33  nt rc;.  sqlite3
2950: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20  _stmt *pStmt;.  
2960: 63 6f 6e 73 74 20 63 68 61 72 20 7a 53 71 6c 5b  const char zSql[
2970: 5d 20 3d 20 22 53 45 4c 45 43 54 20 66 74 73 33  ] = "SELECT fts3
2980: 5f 74 6f 6b 65 6e 69 7a 65 72 28 3f 29 22 3b 0a  _tokenizer(?)";.
2990: 0a 20 20 2a 70 70 20 3d 20 30 3b 0a 20 20 72 63  .  *pp = 0;.  rc
29a0: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
29b0: 72 65 5f 76 32 28 64 62 2c 20 7a 53 71 6c 2c 20  re_v2(db, zSql, 
29c0: 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a  -1, &pStmt, 0);.
29d0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
29e0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72  _OK ){.    retur
29f0: 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c  n rc;.  }..  sql
2a00: 69 74 65 33 5f 62 69 6e 64 5f 74 65 78 74 28 70  ite3_bind_text(p
2a10: 53 74 6d 74 2c 20 31 2c 20 7a 4e 61 6d 65 2c 20  Stmt, 1, zName, 
2a20: 2d 31 2c 20 53 51 4c 49 54 45 5f 53 54 41 54 49  -1, SQLITE_STATI
2a30: 43 29 3b 0a 20 20 69 66 28 20 53 51 4c 49 54 45  C);.  if( SQLITE
2a40: 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74  _ROW==sqlite3_st
2a50: 65 70 28 70 53 74 6d 74 29 20 29 7b 0a 20 20 20  ep(pStmt) ){.   
2a60: 20 69 66 28 20 73 71 6c 69 74 65 33 5f 63 6f 6c   if( sqlite3_col
2a70: 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d 74 2c 20  umn_type(pStmt, 
2a80: 30 29 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20  0)==SQLITE_BLOB 
2a90: 29 7b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28  ){.      memcpy(
2aa0: 28 76 6f 69 64 20 2a 29 70 70 2c 20 73 71 6c 69  (void *)pp, sqli
2ab0: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28  te3_column_blob(
2ac0: 70 53 74 6d 74 2c 20 30 29 2c 20 73 69 7a 65 6f  pStmt, 0), sizeo
2ad0: 66 28 2a 70 70 29 29 3b 0a 20 20 20 20 7d 0a 20  f(*pp));.    }. 
2ae0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 73 71 6c   }..  return sql
2af0: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
2b00: 74 6d 74 29 3b 0a 7d 0a 0a 76 6f 69 64 20 73 71  tmt);.}..void sq
2b10: 6c 69 74 65 33 46 74 73 33 53 69 6d 70 6c 65 54  lite3Fts3SimpleT
2b20: 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 28 73  okenizerModule(s
2b30: 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72  qlite3_tokenizer
2b40: 5f 6d 6f 64 75 6c 65 20 63 6f 6e 73 74 2a 2a 70  _module const**p
2b50: 70 4d 6f 64 75 6c 65 29 3b 0a 0a 2f 2a 0a 2a 2a  pModule);../*.**
2b60: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
2b70: 6f 66 20 74 68 65 20 73 63 61 6c 61 72 20 66 75  of the scalar fu
2b80: 6e 63 74 69 6f 6e 20 66 74 73 33 5f 74 6f 6b 65  nction fts3_toke
2b90: 6e 69 7a 65 72 5f 69 6e 74 65 72 6e 61 6c 5f 74  nizer_internal_t
2ba0: 65 73 74 28 29 2e 0a 2a 2a 20 54 68 69 73 20 66  est()..** This f
2bb0: 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20  unction is used 
2bc0: 66 6f 72 20 74 65 73 74 69 6e 67 20 6f 6e 6c 79  for testing only
2bd0: 2c 20 69 74 20 69 73 20 6e 6f 74 20 69 6e 63 6c  , it is not incl
2be0: 75 64 65 64 20 69 6e 20 74 68 65 0a 2a 2a 20 62  uded in the.** b
2bf0: 75 69 6c 64 20 75 6e 6c 65 73 73 20 53 51 4c 49  uild unless SQLI
2c00: 54 45 5f 54 45 53 54 20 69 73 20 64 65 66 69 6e  TE_TEST is defin
2c10: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 75  ed..**.** The pu
2c20: 72 70 6f 73 65 20 6f 66 20 74 68 69 73 20 69 73  rpose of this is
2c30: 20 74 6f 20 74 65 73 74 20 74 68 61 74 20 74 68   to test that th
2c40: 65 20 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72  e fts3_tokenizer
2c50: 28 29 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 63  () function.** c
2c60: 61 6e 20 62 65 20 75 73 65 64 20 61 73 20 64 65  an be used as de
2c70: 73 69 67 6e 65 64 20 62 79 20 74 68 65 20 43 2d  signed by the C-
2c80: 63 6f 64 65 20 69 6e 20 74 68 65 20 71 75 65 72  code in the quer
2c90: 79 54 6f 6b 65 6e 69 7a 65 72 20 61 6e 64 0a 2a  yTokenizer and.*
2ca0: 2a 20 72 65 67 69 73 74 65 72 54 6f 6b 65 6e 69  * registerTokeni
2cb0: 7a 65 72 28 29 20 66 75 6e 63 74 69 6f 6e 73 20  zer() functions 
2cc0: 61 62 6f 76 65 2e 20 54 68 65 73 65 20 74 77 6f  above. These two
2cd0: 20 66 75 6e 63 74 69 6f 6e 73 20 61 72 65 20 72   functions are r
2ce0: 65 70 65 61 74 65 64 0a 2a 2a 20 69 6e 20 74 68  epeated.** in th
2cf0: 65 20 52 45 41 44 4d 45 2e 74 6f 6b 65 6e 69 7a  e README.tokeniz
2d00: 65 72 20 66 69 6c 65 20 61 73 20 61 6e 20 65 78  er file as an ex
2d10: 61 6d 70 6c 65 2c 20 73 6f 20 69 74 20 69 73 20  ample, so it is 
2d20: 69 6d 70 6f 72 74 61 6e 74 20 74 6f 0a 2a 2a 20  important to.** 
2d30: 74 65 73 74 20 74 68 65 6d 2e 0a 2a 2a 0a 2a 2a  test them..**.**
2d40: 20 54 6f 20 72 75 6e 20 74 68 65 20 74 65 73 74   To run the test
2d50: 73 2c 20 65 76 61 6c 75 61 74 65 20 74 68 65 20  s, evaluate the 
2d60: 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 69  fts3_tokenizer_i
2d70: 6e 74 65 72 6e 61 6c 5f 74 65 73 74 28 29 20 73  nternal_test() s
2d80: 63 61 6c 61 72 0a 2a 2a 20 66 75 6e 63 74 69 6f  calar.** functio
2d90: 6e 20 77 69 74 68 20 6e 6f 20 61 72 67 75 6d 65  n with no argume
2da0: 6e 74 73 2e 20 41 6e 20 61 73 73 65 72 74 28 29  nts. An assert()
2db0: 20 77 69 6c 6c 20 66 61 69 6c 20 69 66 20 61 20   will fail if a 
2dc0: 70 72 6f 62 6c 65 6d 20 69 73 0a 2a 2a 20 64 65  problem is.** de
2dd0: 74 65 63 74 65 64 2e 20 69 2e 65 2e 3a 0a 2a 2a  tected. i.e.:.**
2de0: 0a 2a 2a 20 20 20 20 20 53 45 4c 45 43 54 20 66  .**     SELECT f
2df0: 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 69 6e  ts3_tokenizer_in
2e00: 74 65 72 6e 61 6c 5f 74 65 73 74 28 29 3b 0a 2a  ternal_test();.*
2e10: 2a 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  *.*/.static void
2e20: 20 69 6e 74 54 65 73 74 46 75 6e 63 28 0a 20 20   intTestFunc(.  
2e30: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
2e40: 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20  *context,.  int 
2e50: 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argc,.  sqlite3_
2e60: 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a  value **argv.){.
2e70: 20 20 69 6e 74 20 72 63 3b 0a 20 20 63 6f 6e 73    int rc;.  cons
2e80: 74 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69  t sqlite3_tokeni
2e90: 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a 70 31 3b 0a  zer_module *p1;.
2ea0: 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f    const sqlite3_
2eb0: 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65  tokenizer_module
2ec0: 20 2a 70 32 3b 0a 20 20 73 71 6c 69 74 65 33 20   *p2;.  sqlite3 
2ed0: 2a 64 62 20 3d 20 28 73 71 6c 69 74 65 33 20 2a  *db = (sqlite3 *
2ee0: 29 73 71 6c 69 74 65 33 5f 75 73 65 72 5f 64 61  )sqlite3_user_da
2ef0: 74 61 28 63 6f 6e 74 65 78 74 29 3b 0a 0a 20 20  ta(context);..  
2f00: 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52  UNUSED_PARAMETER
2f10: 28 61 72 67 63 29 3b 0a 20 20 55 4e 55 53 45 44  (argc);.  UNUSED
2f20: 5f 50 41 52 41 4d 45 54 45 52 28 61 72 67 76 29  _PARAMETER(argv)
2f30: 3b 0a 0a 20 20 2f 2a 20 54 65 73 74 20 74 68 65  ;..  /* Test the
2f40: 20 71 75 65 72 79 20 66 75 6e 63 74 69 6f 6e 20   query function 
2f50: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 46 74 73 33  */.  sqlite3Fts3
2f60: 53 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a 65 72 4d  SimpleTokenizerM
2f70: 6f 64 75 6c 65 28 26 70 31 29 3b 0a 20 20 72 63  odule(&p1);.  rc
2f80: 20 3d 20 71 75 65 72 79 54 6f 6b 65 6e 69 7a 65   = queryTokenize
2f90: 72 28 64 62 2c 20 22 73 69 6d 70 6c 65 22 2c 20  r(db, "simple", 
2fa0: 26 70 32 29 3b 0a 20 20 61 73 73 65 72 74 28 20  &p2);.  assert( 
2fb0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b  rc==SQLITE_OK );
2fc0: 0a 20 20 61 73 73 65 72 74 28 20 70 31 3d 3d 70  .  assert( p1==p
2fd0: 32 20 29 3b 0a 20 20 72 63 20 3d 20 71 75 65 72  2 );.  rc = quer
2fe0: 79 54 6f 6b 65 6e 69 7a 65 72 28 64 62 2c 20 22  yTokenizer(db, "
2ff0: 6e 6f 73 75 63 68 74 6f 6b 65 6e 69 7a 65 72 22  nosuchtokenizer"
3000: 2c 20 26 70 32 29 3b 0a 20 20 61 73 73 65 72 74  , &p2);.  assert
3010: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 45 52 52  ( rc==SQLITE_ERR
3020: 4f 52 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  OR );.  assert( 
3030: 70 32 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  p2==0 );.  asser
3040: 74 28 20 30 3d 3d 73 74 72 63 6d 70 28 73 71 6c  t( 0==strcmp(sql
3050: 69 74 65 33 5f 65 72 72 6d 73 67 28 64 62 29 2c  ite3_errmsg(db),
3060: 20 22 75 6e 6b 6e 6f 77 6e 20 74 6f 6b 65 6e 69   "unknown tokeni
3070: 7a 65 72 3a 20 6e 6f 73 75 63 68 74 6f 6b 65 6e  zer: nosuchtoken
3080: 69 7a 65 72 22 29 20 29 3b 0a 0a 20 20 2f 2a 20  izer") );..  /* 
3090: 54 65 73 74 20 74 68 65 20 73 74 6f 72 61 67 65  Test the storage
30a0: 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 69   function */.  i
30b0: 66 28 20 66 74 73 33 54 6f 6b 65 6e 69 7a 65 72  f( fts3Tokenizer
30c0: 45 6e 61 62 6c 65 64 28 63 6f 6e 74 65 78 74 29  Enabled(context)
30d0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 72 65 67   ){.    rc = reg
30e0: 69 73 74 65 72 54 6f 6b 65 6e 69 7a 65 72 28 64  isterTokenizer(d
30f0: 62 2c 20 22 6e 6f 73 75 63 68 74 6f 6b 65 6e 69  b, "nosuchtokeni
3100: 7a 65 72 22 2c 20 70 31 29 3b 0a 20 20 20 20 61  zer", p1);.    a
3110: 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54  ssert( rc==SQLIT
3120: 45 5f 4f 4b 20 29 3b 0a 20 20 20 20 72 63 20 3d  E_OK );.    rc =
3130: 20 71 75 65 72 79 54 6f 6b 65 6e 69 7a 65 72 28   queryTokenizer(
3140: 64 62 2c 20 22 6e 6f 73 75 63 68 74 6f 6b 65 6e  db, "nosuchtoken
3150: 69 7a 65 72 22 2c 20 26 70 32 29 3b 0a 20 20 20  izer", &p2);.   
3160: 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c   assert( rc==SQL
3170: 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 20 20 61 73  ITE_OK );.    as
3180: 73 65 72 74 28 20 70 32 3d 3d 70 31 20 29 3b 0a  sert( p2==p1 );.
3190: 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 72    }..  sqlite3_r
31a0: 65 73 75 6c 74 5f 74 65 78 74 28 63 6f 6e 74 65  esult_text(conte
31b0: 78 74 2c 20 22 6f 6b 22 2c 20 2d 31 2c 20 53 51  xt, "ok", -1, SQ
31c0: 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 7d 0a  LITE_STATIC);.}.
31d0: 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 53  .#endif../*.** S
31e0: 65 74 20 75 70 20 53 51 4c 20 6f 62 6a 65 63 74  et up SQL object
31f0: 73 20 69 6e 20 64 61 74 61 62 61 73 65 20 64 62  s in database db
3200: 20 75 73 65 64 20 74 6f 20 61 63 63 65 73 73 20   used to access 
3210: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 0a  the contents of.
3220: 2a 2a 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ** the hash tabl
3230: 65 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20  e pointed to by 
3240: 61 72 67 75 6d 65 6e 74 20 70 48 61 73 68 2e 20  argument pHash. 
3250: 54 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 6d  The hash table m
3260: 75 73 74 0a 2a 2a 20 62 65 65 6e 20 69 6e 69 74  ust.** been init
3270: 69 61 6c 69 7a 65 64 20 74 6f 20 75 73 65 20 73  ialized to use s
3280: 74 72 69 6e 67 20 6b 65 79 73 2c 20 61 6e 64 20  tring keys, and 
3290: 74 6f 20 74 61 6b 65 20 61 20 70 72 69 76 61 74  to take a privat
32a0: 65 20 63 6f 70 79 20 0a 2a 2a 20 6f 66 20 74 68  e copy .** of th
32b0: 65 20 6b 65 79 20 77 68 65 6e 20 61 20 76 61 6c  e key when a val
32c0: 75 65 20 69 73 20 69 6e 73 65 72 74 65 64 2e 20  ue is inserted. 
32d0: 69 2e 65 2e 20 62 79 20 61 20 63 61 6c 6c 20 73  i.e. by a call s
32e0: 69 6d 69 6c 61 72 20 74 6f 3a 0a 2a 2a 0a 2a 2a  imilar to:.**.**
32f0: 20 20 20 20 73 71 6c 69 74 65 33 46 74 73 33 48      sqlite3Fts3H
3300: 61 73 68 49 6e 69 74 28 70 48 61 73 68 2c 20 46  ashInit(pHash, F
3310: 54 53 33 5f 48 41 53 48 5f 53 54 52 49 4e 47 2c  TS3_HASH_STRING,
3320: 20 31 29 3b 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20   1);.**.** This 
3330: 66 75 6e 63 74 69 6f 6e 20 61 64 64 73 20 61 20  function adds a 
3340: 73 63 61 6c 61 72 20 66 75 6e 63 74 69 6f 6e 20  scalar function 
3350: 28 73 65 65 20 68 65 61 64 65 72 20 63 6f 6d 6d  (see header comm
3360: 65 6e 74 20 61 62 6f 76 65 0a 2a 2a 20 66 74 73  ent above.** fts
3370: 33 54 6f 6b 65 6e 69 7a 65 72 46 75 6e 63 28 29  3TokenizerFunc()
3380: 20 69 6e 20 74 68 69 73 20 66 69 6c 65 20 66 6f   in this file fo
3390: 72 20 64 65 74 61 69 6c 73 29 20 61 6e 64 2c 20  r details) and, 
33a0: 69 66 20 45 4e 41 42 4c 45 5f 54 41 42 4c 45 20  if ENABLE_TABLE 
33b0: 69 73 0a 2a 2a 20 64 65 66 69 6e 65 64 20 61 74  is.** defined at
33c0: 20 63 6f 6d 70 69 6c 61 74 69 6f 6e 20 74 69 6d   compilation tim
33d0: 65 2c 20 61 20 74 65 6d 70 6f 72 61 72 79 20 76  e, a temporary v
33e0: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 28 73 65  irtual table (se
33f0: 65 20 68 65 61 64 65 72 20 0a 2a 2a 20 63 6f 6d  e header .** com
3400: 6d 65 6e 74 20 61 62 6f 76 65 20 73 74 72 75 63  ment above struc
3410: 74 20 48 61 73 68 54 61 62 6c 65 56 74 61 62 29  t HashTableVtab)
3420: 20 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65   to the database
3430: 20 73 63 68 65 6d 61 2e 20 42 6f 74 68 20 0a 2a   schema. Both .*
3440: 2a 20 70 72 6f 76 69 64 65 20 72 65 61 64 2f 77  * provide read/w
3450: 72 69 74 65 20 61 63 63 65 73 73 20 74 6f 20 74  rite access to t
3460: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 2a  he contents of *
3470: 70 48 61 73 68 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  pHash..**.** The
3480: 20 74 68 69 72 64 20 61 72 67 75 6d 65 6e 74 20   third argument 
3490: 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  to this function
34a0: 2c 20 7a 4e 61 6d 65 2c 20 69 73 20 75 73 65 64  , zName, is used
34b0: 20 61 73 20 74 68 65 20 6e 61 6d 65 0a 2a 2a 20   as the name.** 
34c0: 6f 66 20 62 6f 74 68 20 74 68 65 20 73 63 61 6c  of both the scal
34d0: 61 72 20 61 6e 64 2c 20 69 66 20 63 72 65 61 74  ar and, if creat
34e0: 65 64 2c 20 74 68 65 20 76 69 72 74 75 61 6c 20  ed, the virtual 
34f0: 74 61 62 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71  table..*/.int sq
3500: 6c 69 74 65 33 46 74 73 33 49 6e 69 74 48 61 73  lite3Fts3InitHas
3510: 68 54 61 62 6c 65 28 0a 20 20 73 71 6c 69 74 65  hTable(.  sqlite
3520: 33 20 2a 64 62 2c 20 0a 20 20 46 74 73 33 48 61  3 *db, .  Fts3Ha
3530: 73 68 20 2a 70 48 61 73 68 2c 20 0a 20 20 63 6f  sh *pHash, .  co
3540: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 0a  nst char *zName.
3550: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
3560: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 76 6f 69 64 20  LITE_OK;.  void 
3570: 2a 70 20 3d 20 28 76 6f 69 64 20 2a 29 70 48 61  *p = (void *)pHa
3580: 73 68 3b 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20  sh;.  const int 
3590: 61 6e 79 20 3d 20 53 51 4c 49 54 45 5f 41 4e 59  any = SQLITE_ANY
35a0: 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  ;..#ifdef SQLITE
35b0: 5f 54 45 53 54 0a 20 20 63 68 61 72 20 2a 7a 54  _TEST.  char *zT
35c0: 65 73 74 20 3d 20 30 3b 0a 20 20 63 68 61 72 20  est = 0;.  char 
35d0: 2a 7a 54 65 73 74 32 20 3d 20 30 3b 0a 20 20 76  *zTest2 = 0;.  v
35e0: 6f 69 64 20 2a 70 64 62 20 3d 20 28 76 6f 69 64  oid *pdb = (void
35f0: 20 2a 29 64 62 3b 0a 20 20 7a 54 65 73 74 20 3d   *)db;.  zTest =
3600: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
3610: 28 22 25 73 5f 74 65 73 74 22 2c 20 7a 4e 61 6d  ("%s_test", zNam
3620: 65 29 3b 0a 20 20 7a 54 65 73 74 32 20 3d 20 73  e);.  zTest2 = s
3630: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
3640: 25 73 5f 69 6e 74 65 72 6e 61 6c 5f 74 65 73 74  %s_internal_test
3650: 22 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 69 66 28  ", zName);.  if(
3660: 20 21 7a 54 65 73 74 20 7c 7c 20 21 7a 54 65 73   !zTest || !zTes
3670: 74 32 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  t2 ){.    rc = S
3680: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
3690: 0a 23 65 6e 64 69 66 0a 0a 20 20 69 66 28 20 53  .#endif..  if( S
36a0: 51 4c 49 54 45 5f 4f 4b 3d 3d 72 63 20 29 7b 0a  QLITE_OK==rc ){.
36b0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
36c0: 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e  _create_function
36d0: 28 64 62 2c 20 7a 4e 61 6d 65 2c 20 31 2c 20 61  (db, zName, 1, a
36e0: 6e 79 2c 20 70 2c 20 66 74 73 33 54 6f 6b 65 6e  ny, p, fts3Token
36f0: 69 7a 65 72 46 75 6e 63 2c 20 30 2c 20 30 29 3b  izerFunc, 0, 0);
3700: 0a 20 20 7d 0a 20 20 69 66 28 20 53 51 4c 49 54  .  }.  if( SQLIT
3710: 45 5f 4f 4b 3d 3d 72 63 20 29 7b 0a 20 20 20 20  E_OK==rc ){.    
3720: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65  rc = sqlite3_cre
3730: 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c  ate_function(db,
3740: 20 7a 4e 61 6d 65 2c 20 32 2c 20 61 6e 79 2c 20   zName, 2, any, 
3750: 70 2c 20 66 74 73 33 54 6f 6b 65 6e 69 7a 65 72  p, fts3Tokenizer
3760: 46 75 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d  Func, 0, 0);.  }
3770: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54  .#ifdef SQLITE_T
3780: 45 53 54 0a 20 20 69 66 28 20 53 51 4c 49 54 45  EST.  if( SQLITE
3790: 5f 4f 4b 3d 3d 72 63 20 29 7b 0a 20 20 20 20 72  _OK==rc ){.    r
37a0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61  c = sqlite3_crea
37b0: 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20  te_function(db, 
37c0: 7a 54 65 73 74 2c 20 2d 31 2c 20 61 6e 79 2c 20  zTest, -1, any, 
37d0: 70 2c 20 74 65 73 74 46 75 6e 63 2c 20 30 2c 20  p, testFunc, 0, 
37e0: 30 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 53 51  0);.  }.  if( SQ
37f0: 4c 49 54 45 5f 4f 4b 3d 3d 72 63 20 29 7b 0a 20  LITE_OK==rc ){. 
3800: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
3810: 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28  create_function(
3820: 64 62 2c 20 7a 54 65 73 74 32 2c 20 30 2c 20 61  db, zTest2, 0, a
3830: 6e 79 2c 20 70 64 62 2c 20 69 6e 74 54 65 73 74  ny, pdb, intTest
3840: 46 75 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d  Func, 0, 0);.  }
3850: 0a 23 65 6e 64 69 66 0a 0a 23 69 66 64 65 66 20  .#endif..#ifdef 
3860: 53 51 4c 49 54 45 5f 54 45 53 54 0a 20 20 73 71  SQLITE_TEST.  sq
3870: 6c 69 74 65 33 5f 66 72 65 65 28 7a 54 65 73 74  lite3_free(zTest
3880: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
3890: 65 28 7a 54 65 73 74 32 29 3b 0a 23 65 6e 64 69  e(zTest2);.#endi
38a0: 66 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  f..  return rc;.
38b0: 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 21 64 65  }..#endif /* !de
38c0: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 43 4f 52  fined(SQLITE_COR
38d0: 45 29 20 7c 7c 20 64 65 66 69 6e 65 64 28 53 51  E) || defined(SQ
38e0: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53 33  LITE_ENABLE_FTS3
38f0: 29 20 2a 2f 0a                                   ) */.