/ Hex Artifact Content
Login

Artifact 3dbe8058e97afb55fff3ea844120ce3208b114cc:


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 32 20 6d 6f 64 75 6c  * The FTS2 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 32 20 6d 6f     * The FTS2 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 32 20 69 73 20 64 65 66 69 6e 65  E_FTS2 is define
0320: 64 29 2e 0a 2a 2f 0a 23 69 66 20 21 64 65 66 69  d)..*/.#if !defi
0330: 6e 65 64 28 53 51 4c 49 54 45 5f 43 4f 52 45 29  ned(SQLITE_CORE)
0340: 20 7c 7c 20 64 65 66 69 6e 65 64 28 53 51 4c 49   || defined(SQLI
0350: 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53 32 29 0a  TE_ENABLE_FTS2).
0360: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69  ..#include "sqli
0370: 74 65 33 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20  te3.h".#include 
0380: 22 73 71 6c 69 74 65 33 65 78 74 2e 68 22 0a 53  "sqlite3ext.h".S
0390: 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e 5f  QLITE_EXTENSION_
03a0: 49 4e 49 54 33 0a 0a 23 69 6e 63 6c 75 64 65 20  INIT3..#include 
03b0: 22 66 74 73 32 5f 68 61 73 68 2e 68 22 0a 23 69  "fts2_hash.h".#i
03c0: 6e 63 6c 75 64 65 20 22 66 74 73 32 5f 74 6f 6b  nclude "fts2_tok
03d0: 65 6e 69 7a 65 72 2e 68 22 0a 23 69 6e 63 6c 75  enizer.h".#inclu
03e0: 64 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a 0a 2f  de <assert.h>../
03f0: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
0400: 69 6f 6e 20 6f 66 20 74 68 65 20 53 51 4c 20 73  ion of the SQL s
0410: 63 61 6c 61 72 20 66 75 6e 63 74 69 6f 6e 20 66  calar function f
0420: 6f 72 20 61 63 63 65 73 73 69 6e 67 20 74 68 65  or accessing the
0430: 20 75 6e 64 65 72 6c 79 69 6e 67 20 0a 2a 2a 20   underlying .** 
0440: 68 61 73 68 20 74 61 62 6c 65 2e 20 54 68 69 73  hash table. This
0450: 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 62 65   function may be
0460: 20 63 61 6c 6c 65 64 20 61 73 20 66 6f 6c 6c 6f   called as follo
0470: 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 45 4c 45  ws:.**.**   SELE
0480: 43 54 20 3c 66 75 6e 63 74 69 6f 6e 2d 6e 61 6d  CT <function-nam
0490: 65 3e 28 3c 6b 65 79 2d 6e 61 6d 65 3e 29 3b 0a  e>(<key-name>);.
04a0: 2a 2a 20 20 20 53 45 4c 45 43 54 20 3c 66 75 6e  **   SELECT <fun
04b0: 63 74 69 6f 6e 2d 6e 61 6d 65 3e 28 3c 6b 65 79  ction-name>(<key
04c0: 2d 6e 61 6d 65 3e 2c 20 3c 70 6f 69 6e 74 65 72  -name>, <pointer
04d0: 3e 29 3b 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65 20  >);.**.** where 
04e0: 3c 66 75 6e 63 74 69 6f 6e 2d 6e 61 6d 65 3e 20  <function-name> 
04f0: 69 73 20 74 68 65 20 6e 61 6d 65 20 70 61 73 73  is the name pass
0500: 65 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64  ed as the second
0510: 20 61 72 67 75 6d 65 6e 74 0a 2a 2a 20 74 6f 20   argument.** to 
0520: 74 68 65 20 73 71 6c 69 74 65 33 46 74 73 32 49  the sqlite3Fts2I
0530: 6e 69 74 48 61 73 68 54 61 62 6c 65 28 29 20 66  nitHashTable() f
0540: 75 6e 63 74 69 6f 6e 20 28 65 2e 67 2e 20 27 66  unction (e.g. 'f
0550: 74 73 32 5f 74 6f 6b 65 6e 69 7a 65 72 27 29 2e  ts2_tokenizer').
0560: 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 3c 70  .**.** If the <p
0570: 6f 69 6e 74 65 72 3e 20 61 72 67 75 6d 65 6e 74  ointer> argument
0580: 20 69 73 20 73 70 65 63 69 66 69 65 64 2c 20 69   is specified, i
0590: 74 20 6d 75 73 74 20 62 65 20 61 20 62 6c 6f 62  t must be a blob
05a0: 20 76 61 6c 75 65 0a 2a 2a 20 63 6f 6e 74 61 69   value.** contai
05b0: 6e 69 6e 67 20 61 20 70 6f 69 6e 74 65 72 20 74  ning a pointer t
05c0: 6f 20 62 65 20 73 74 6f 72 65 64 20 61 73 20 74  o be stored as t
05d0: 68 65 20 68 61 73 68 20 64 61 74 61 20 63 6f 72  he hash data cor
05e0: 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20 74 6f  responding.** to
05f0: 20 74 68 65 20 73 74 72 69 6e 67 20 3c 6b 65 79   the string <key
0600: 2d 6e 61 6d 65 3e 2e 20 49 66 20 3c 70 6f 69 6e  -name>. If <poin
0610: 74 65 72 3e 20 69 73 20 6e 6f 74 20 73 70 65 63  ter> is not spec
0620: 69 66 69 65 64 2c 20 74 68 65 6e 0a 2a 2a 20 74  ified, then.** t
0630: 68 65 20 73 74 72 69 6e 67 20 3c 6b 65 79 2d 6e  he string <key-n
0640: 61 6d 65 3e 20 6d 75 73 74 20 61 6c 72 65 61 64  ame> must alread
0650: 79 20 65 78 69 73 74 20 69 6e 20 74 68 65 20 68  y exist in the h
0660: 61 73 20 74 61 62 6c 65 2e 20 4f 74 68 65 72 77  as table. Otherw
0670: 69 73 65 2c 0a 2a 2a 20 61 6e 20 65 72 72 6f 72  ise,.** an error
0680: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a   is returned..**
0690: 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e  .** Whether or n
06a0: 6f 74 20 74 68 65 20 3c 70 6f 69 6e 74 65 72 3e  ot the <pointer>
06b0: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 73 70 65   argument is spe
06c0: 63 69 66 69 65 64 2c 20 74 68 65 20 76 61 6c 75  cified, the valu
06d0: 65 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69 73  e returned.** is
06e0: 20 61 20 62 6c 6f 62 20 63 6f 6e 74 61 69 6e 69   a blob containi
06f0: 6e 67 20 74 68 65 20 70 6f 69 6e 74 65 72 20 73  ng the pointer s
0700: 74 6f 72 65 64 20 61 73 20 74 68 65 20 68 61 73  tored as the has
0710: 68 20 64 61 74 61 20 63 6f 72 72 65 73 70 6f 6e  h data correspon
0720: 64 69 6e 67 0a 2a 2a 20 74 6f 20 73 74 72 69 6e  ding.** to strin
0730: 67 20 3c 6b 65 79 2d 6e 61 6d 65 3e 20 28 61 66  g <key-name> (af
0740: 74 65 72 20 74 68 65 20 68 61 73 68 2d 74 61 62  ter the hash-tab
0750: 6c 65 20 69 73 20 75 70 64 61 74 65 64 2c 20 69  le is updated, i
0760: 66 20 61 70 70 6c 69 63 61 62 6c 65 29 2e 0a 2a  f applicable)..*
0770: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 63  /.static void sc
0780: 61 6c 61 72 46 75 6e 63 28 0a 20 20 73 71 6c 69  alarFunc(.  sqli
0790: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e  te3_context *con
07a0: 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63  text,.  int argc
07b0: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  ,.  sqlite3_valu
07c0: 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 66 74  e **argv.){.  ft
07d0: 73 32 48 61 73 68 20 2a 70 48 61 73 68 3b 0a 20  s2Hash *pHash;. 
07e0: 20 76 6f 69 64 20 2a 70 50 74 72 20 3d 20 30 3b   void *pPtr = 0;
07f0: 0a 20 20 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65  .  const unsigne
0800: 64 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20  d char *zName;. 
0810: 20 69 6e 74 20 6e 4e 61 6d 65 3b 0a 0a 20 20 61   int nName;..  a
0820: 73 73 65 72 74 28 20 61 72 67 63 3d 3d 31 20 7c  ssert( argc==1 |
0830: 7c 20 61 72 67 63 3d 3d 32 20 29 3b 0a 0a 20 20  | argc==2 );..  
0840: 70 48 61 73 68 20 3d 20 28 66 74 73 32 48 61 73  pHash = (fts2Has
0850: 68 20 2a 29 73 71 6c 69 74 65 33 5f 75 73 65 72  h *)sqlite3_user
0860: 5f 64 61 74 61 28 63 6f 6e 74 65 78 74 29 3b 0a  _data(context);.
0870: 0a 20 20 7a 4e 61 6d 65 20 3d 20 73 71 6c 69 74  .  zName = sqlit
0880: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72  e3_value_text(ar
0890: 67 76 5b 30 5d 29 3b 0a 20 20 6e 4e 61 6d 65 20  gv[0]);.  nName 
08a0: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
08b0: 62 79 74 65 73 28 61 72 67 76 5b 30 5d 29 2b 31  bytes(argv[0])+1
08c0: 3b 0a 0a 20 20 69 66 28 20 61 72 67 63 3d 3d 32  ;..  if( argc==2
08d0: 20 29 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 4f   ){.    void *pO
08e0: 6c 64 3b 0a 20 20 20 20 69 6e 74 20 6e 20 3d 20  ld;.    int n = 
08f0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79  sqlite3_value_by
0900: 74 65 73 28 61 72 67 76 5b 31 5d 29 3b 0a 20 20  tes(argv[1]);.  
0910: 20 20 69 66 28 20 6e 21 3d 73 69 7a 65 6f 66 28    if( n!=sizeof(
0920: 70 50 74 72 29 20 29 7b 0a 20 20 20 20 20 20 73  pPtr) ){.      s
0930: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72  qlite3_result_er
0940: 72 6f 72 28 63 6f 6e 74 65 78 74 2c 20 22 61 72  ror(context, "ar
0950: 67 75 6d 65 6e 74 20 74 79 70 65 20 6d 69 73 6d  gument type mism
0960: 61 74 63 68 22 2c 20 2d 31 29 3b 0a 20 20 20 20  atch", -1);.    
0970: 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 7d 0a    return;.    }.
0980: 20 20 20 20 70 50 74 72 20 3d 20 2a 28 76 6f 69      pPtr = *(voi
0990: 64 20 2a 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  d **)sqlite3_val
09a0: 75 65 5f 62 6c 6f 62 28 61 72 67 76 5b 31 5d 29  ue_blob(argv[1])
09b0: 3b 0a 20 20 20 20 70 4f 6c 64 20 3d 20 73 71 6c  ;.    pOld = sql
09c0: 69 74 65 33 46 74 73 32 48 61 73 68 49 6e 73 65  ite3Fts2HashInse
09d0: 72 74 28 70 48 61 73 68 2c 20 28 76 6f 69 64 20  rt(pHash, (void 
09e0: 2a 29 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65 2c 20  *)zName, nName, 
09f0: 70 50 74 72 29 3b 0a 20 20 20 20 69 66 28 20 70  pPtr);.    if( p
0a00: 4f 6c 64 3d 3d 70 50 74 72 20 29 7b 0a 20 20 20  Old==pPtr ){.   
0a10: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
0a20: 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74 2c  t_error(context,
0a30: 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 22   "out of memory"
0a40: 2c 20 2d 31 29 3b 0a 20 20 20 20 20 20 72 65 74  , -1);.      ret
0a50: 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c  urn;.    }.  }el
0a60: 73 65 7b 0a 20 20 20 20 70 50 74 72 20 3d 20 73  se{.    pPtr = s
0a70: 71 6c 69 74 65 33 46 74 73 32 48 61 73 68 46 69  qlite3Fts2HashFi
0a80: 6e 64 28 70 48 61 73 68 2c 20 7a 4e 61 6d 65 2c  nd(pHash, zName,
0a90: 20 6e 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28   nName);.    if(
0aa0: 20 21 70 50 74 72 20 29 7b 0a 20 20 20 20 20 20   !pPtr ){.      
0ab0: 63 68 61 72 20 2a 7a 45 72 72 20 3d 20 73 71 6c  char *zErr = sql
0ac0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 75 6e  ite3_mprintf("un
0ad0: 6b 6e 6f 77 6e 20 74 6f 6b 65 6e 69 7a 65 72 3a  known tokenizer:
0ae0: 20 25 73 22 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20   %s", zName);.  
0af0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
0b00: 6c 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74  lt_error(context
0b10: 2c 20 7a 45 72 72 2c 20 2d 31 29 3b 0a 20 20 20  , zErr, -1);.   
0b20: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
0b30: 7a 45 72 72 29 3b 0a 20 20 20 20 20 20 72 65 74  zErr);.      ret
0b40: 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  urn;.    }.  }..
0b50: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
0b60: 5f 62 6c 6f 62 28 63 6f 6e 74 65 78 74 2c 20 28  _blob(context, (
0b70: 76 6f 69 64 20 2a 29 26 70 50 74 72 2c 20 73 69  void *)&pPtr, si
0b80: 7a 65 6f 66 28 70 50 74 72 29 2c 20 53 51 4c 49  zeof(pPtr), SQLI
0b90: 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 7d  TE_TRANSIENT);.}
0ba0: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
0bb0: 54 45 53 54 0a 0a 23 69 6e 63 6c 75 64 65 20 3c  TEST..#include <
0bc0: 74 63 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  tcl.h>.#include 
0bd0: 3c 73 74 72 69 6e 67 2e 68 3e 0a 0a 2f 2a 0a 2a  <string.h>../*.*
0be0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
0bf0: 20 6f 66 20 61 20 73 70 65 63 69 61 6c 20 53 51   of a special SQ
0c00: 4c 20 73 63 61 6c 61 72 20 66 75 6e 63 74 69 6f  L scalar functio
0c10: 6e 20 66 6f 72 20 74 65 73 74 69 6e 67 20 74 6f  n for testing to
0c20: 6b 65 6e 69 7a 65 72 73 20 0a 2a 2a 20 64 65 73  kenizers .** des
0c30: 69 67 6e 65 64 20 74 6f 20 62 65 20 75 73 65 64  igned to be used
0c40: 20 69 6e 20 63 6f 6e 63 65 72 74 20 77 69 74 68   in concert with
0c50: 20 74 68 65 20 54 63 6c 20 74 65 73 74 69 6e 67   the Tcl testing
0c60: 20 66 72 61 6d 65 77 6f 72 6b 2e 20 54 68 69 73   framework. This
0c70: 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 6d 75 73  .** function mus
0c80: 74 20 62 65 20 63 61 6c 6c 65 64 20 77 69 74 68  t be called with
0c90: 20 74 77 6f 20 61 72 67 75 6d 65 6e 74 73 3a 0a   two arguments:.
0ca0: 2a 2a 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20 3c  **.**   SELECT <
0cb0: 66 75 6e 63 74 69 6f 6e 2d 6e 61 6d 65 3e 28 3c  function-name>(<
0cc0: 6b 65 79 2d 6e 61 6d 65 3e 2c 20 3c 69 6e 70 75  key-name>, <inpu
0cd0: 74 2d 73 74 72 69 6e 67 3e 29 3b 0a 2a 2a 20 20  t-string>);.**  
0ce0: 20 53 45 4c 45 43 54 20 3c 66 75 6e 63 74 69 6f   SELECT <functio
0cf0: 6e 2d 6e 61 6d 65 3e 28 3c 6b 65 79 2d 6e 61 6d  n-name>(<key-nam
0d00: 65 3e 2c 20 3c 70 6f 69 6e 74 65 72 3e 29 3b 0a  e>, <pointer>);.
0d10: 2a 2a 0a 2a 2a 20 77 68 65 72 65 20 3c 66 75 6e  **.** where <fun
0d20: 63 74 69 6f 6e 2d 6e 61 6d 65 3e 20 69 73 20 74  ction-name> is t
0d30: 68 65 20 6e 61 6d 65 20 70 61 73 73 65 64 20 61  he name passed a
0d40: 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67  s the second arg
0d50: 75 6d 65 6e 74 0a 2a 2a 20 74 6f 20 74 68 65 20  ument.** to the 
0d60: 73 71 6c 69 74 65 33 46 74 73 32 49 6e 69 74 48  sqlite3Fts2InitH
0d70: 61 73 68 54 61 62 6c 65 28 29 20 66 75 6e 63 74  ashTable() funct
0d80: 69 6f 6e 20 28 65 2e 67 2e 20 27 66 74 73 32 5f  ion (e.g. 'fts2_
0d90: 74 6f 6b 65 6e 69 7a 65 72 27 29 0a 2a 2a 20 63  tokenizer').** c
0da0: 6f 6e 63 61 74 65 6e 61 74 65 64 20 77 69 74 68  oncatenated with
0db0: 20 74 68 65 20 73 74 72 69 6e 67 20 27 5f 74 65   the string '_te
0dc0: 73 74 27 20 28 65 2e 67 2e 20 27 66 74 73 32 5f  st' (e.g. 'fts2_
0dd0: 74 6f 6b 65 6e 69 7a 65 72 5f 74 65 73 74 27 29  tokenizer_test')
0de0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 72 65 74 75  ..**.** The retu
0df0: 72 6e 20 76 61 6c 75 65 20 69 73 20 61 20 73 74  rn value is a st
0e00: 72 69 6e 67 20 74 68 61 74 20 6d 61 79 20 62 65  ring that may be
0e10: 20 69 6e 74 65 72 70 72 65 74 65 64 20 61 73 20   interpreted as 
0e20: 61 20 54 63 6c 0a 2a 2a 20 6c 69 73 74 2e 20 46  a Tcl.** list. F
0e30: 6f 72 20 65 61 63 68 20 74 6f 6b 65 6e 20 69 6e  or each token in
0e40: 20 74 68 65 20 3c 69 6e 70 75 74 2d 73 74 72 69   the <input-stri
0e50: 6e 67 3e 2c 20 74 68 72 65 65 20 65 6c 65 6d 65  ng>, three eleme
0e60: 6e 74 73 20 61 72 65 0a 2a 2a 20 61 64 64 65 64  nts are.** added
0e70: 20 74 6f 20 74 68 65 20 72 65 74 75 72 6e 65 64   to the returned
0e80: 20 6c 69 73 74 2e 20 54 68 65 20 66 69 72 73 74   list. The first
0e90: 20 69 73 20 74 68 65 20 74 6f 6b 65 6e 20 70 6f   is the token po
0ea0: 73 69 74 69 6f 6e 2c 20 74 68 65 20 0a 2a 2a 20  sition, the .** 
0eb0: 73 65 63 6f 6e 64 20 69 73 20 74 68 65 20 74 6f  second is the to
0ec0: 6b 65 6e 20 74 65 78 74 20 28 66 6f 6c 64 65 64  ken text (folded
0ed0: 2c 20 73 74 65 6d 6d 65 64 2c 20 65 74 63 2e 29  , stemmed, etc.)
0ee0: 20 61 6e 64 20 74 68 65 20 74 68 69 72 64 20 69   and the third i
0ef0: 73 20 74 68 65 0a 2a 2a 20 73 75 62 73 74 72 69  s the.** substri
0f00: 6e 67 20 6f 66 20 3c 69 6e 70 75 74 2d 73 74 72  ng of <input-str
0f10: 69 6e 67 3e 20 61 73 73 6f 63 69 61 74 65 64 20  ing> associated 
0f20: 77 69 74 68 20 74 68 65 20 74 6f 6b 65 6e 2e 20  with the token. 
0f30: 46 6f 72 20 65 78 61 6d 70 6c 65 2c 20 0a 2a 2a  For example, .**
0f40: 20 75 73 69 6e 67 20 74 68 65 20 62 75 69 6c 74   using the built
0f50: 2d 69 6e 20 22 73 69 6d 70 6c 65 22 20 74 6f 6b  -in "simple" tok
0f60: 65 6e 69 7a 65 72 3a 0a 2a 2a 0a 2a 2a 20 20 20  enizer:.**.**   
0f70: 53 45 4c 45 43 54 20 66 74 73 5f 74 6f 6b 65 6e  SELECT fts_token
0f80: 69 7a 65 72 5f 74 65 73 74 28 27 73 69 6d 70 6c  izer_test('simpl
0f90: 65 27 2c 20 27 49 20 64 6f 6e 27 74 20 73 65 65  e', 'I don't see
0fa0: 20 68 6f 77 27 29 3b 0a 2a 2a 0a 2a 2a 20 77 69   how');.**.** wi
0fb0: 6c 6c 20 72 65 74 75 72 6e 20 74 68 65 20 73 74  ll return the st
0fc0: 72 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 22 7b  ring:.**.**   "{
0fd0: 30 20 69 20 49 20 31 20 64 6f 6e 74 20 64 6f 6e  0 i I 1 dont don
0fe0: 27 74 20 32 20 73 65 65 20 73 65 65 20 33 20 68  't 2 see see 3 h
0ff0: 6f 77 20 68 6f 77 7d 22 0a 2a 2a 20 20 20 0a 2a  ow how}".**   .*
1000: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 65  /.static void te
1010: 73 74 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 65  stFunc(.  sqlite
1020: 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65  3_context *conte
1030: 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a  xt,.  int argc,.
1040: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
1050: 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 66 74 73 32  **argv.){.  fts2
1060: 48 61 73 68 20 2a 70 48 61 73 68 3b 0a 20 20 73  Hash *pHash;.  s
1070: 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72  qlite3_tokenizer
1080: 5f 6d 6f 64 75 6c 65 20 2a 70 3b 0a 20 20 73 71  _module *p;.  sq
1090: 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 20  lite3_tokenizer 
10a0: 2a 70 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 30 3b  *pTokenizer = 0;
10b0: 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  .  sqlite3_token
10c0: 69 7a 65 72 5f 63 75 72 73 6f 72 20 2a 70 43 73  izer_cursor *pCs
10d0: 72 20 3d 20 30 3b 0a 0a 20 20 63 6f 6e 73 74 20  r = 0;..  const 
10e0: 63 68 61 72 20 2a 7a 45 72 72 20 3d 20 30 3b 0a  char *zErr = 0;.
10f0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
1100: 4e 61 6d 65 3b 0a 20 20 69 6e 74 20 6e 4e 61 6d  Name;.  int nNam
1110: 65 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  e;.  const char 
1120: 2a 7a 49 6e 70 75 74 3b 0a 20 20 69 6e 74 20 6e  *zInput;.  int n
1130: 49 6e 70 75 74 3b 0a 0a 20 20 63 6f 6e 73 74 20  Input;..  const 
1140: 63 68 61 72 20 2a 7a 41 72 67 20 3d 20 30 3b 0a  char *zArg = 0;.
1150: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
1160: 54 6f 6b 65 6e 3b 0a 20 20 69 6e 74 20 6e 54 6f  Token;.  int nTo
1170: 6b 65 6e 3b 0a 20 20 69 6e 74 20 69 53 74 61 72  ken;.  int iStar
1180: 74 3b 0a 20 20 69 6e 74 20 69 45 6e 64 3b 0a 20  t;.  int iEnd;. 
1190: 20 69 6e 74 20 69 50 6f 73 3b 0a 0a 20 20 54 63   int iPos;..  Tc
11a0: 6c 5f 4f 62 6a 20 2a 70 52 65 74 3b 0a 0a 20 20  l_Obj *pRet;..  
11b0: 61 73 73 65 72 74 28 20 61 72 67 63 3d 3d 32 20  assert( argc==2 
11c0: 7c 7c 20 61 72 67 63 3d 3d 33 20 29 3b 0a 0a 20  || argc==3 );.. 
11d0: 20 6e 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33   nName = sqlite3
11e0: 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61 72 67  _value_bytes(arg
11f0: 76 5b 30 5d 29 3b 0a 20 20 7a 4e 61 6d 65 20 3d  v[0]);.  zName =
1200: 20 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 73   (const char *)s
1210: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78  qlite3_value_tex
1220: 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20 6e 49  t(argv[0]);.  nI
1230: 6e 70 75 74 20 3d 20 73 71 6c 69 74 65 33 5f 76  nput = sqlite3_v
1240: 61 6c 75 65 5f 62 79 74 65 73 28 61 72 67 76 5b  alue_bytes(argv[
1250: 61 72 67 63 2d 31 5d 29 3b 0a 20 20 7a 49 6e 70  argc-1]);.  zInp
1260: 75 74 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72  ut = (const char
1270: 20 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65   *)sqlite3_value
1280: 5f 74 65 78 74 28 61 72 67 76 5b 61 72 67 63 2d  _text(argv[argc-
1290: 31 5d 29 3b 0a 0a 20 20 69 66 28 20 61 72 67 63  1]);..  if( argc
12a0: 3d 3d 33 20 29 7b 0a 20 20 20 20 7a 41 72 67 20  ==3 ){.    zArg 
12b0: 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 29  = (const char *)
12c0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
12d0: 78 74 28 61 72 67 76 5b 31 5d 29 3b 0a 20 20 7d  xt(argv[1]);.  }
12e0: 0a 0a 20 20 70 48 61 73 68 20 3d 20 28 66 74 73  ..  pHash = (fts
12f0: 32 48 61 73 68 20 2a 29 73 71 6c 69 74 65 33 5f  2Hash *)sqlite3_
1300: 75 73 65 72 5f 64 61 74 61 28 63 6f 6e 74 65 78  user_data(contex
1310: 74 29 3b 0a 20 20 70 20 3d 20 28 73 71 6c 69 74  t);.  p = (sqlit
1320: 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64  e3_tokenizer_mod
1330: 75 6c 65 20 2a 29 73 71 6c 69 74 65 33 46 74 73  ule *)sqlite3Fts
1340: 32 48 61 73 68 46 69 6e 64 28 70 48 61 73 68 2c  2HashFind(pHash,
1350: 20 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65 2b 31 29   zName, nName+1)
1360: 3b 0a 0a 20 20 69 66 28 20 21 70 20 29 7b 0a 20  ;..  if( !p ){. 
1370: 20 20 20 63 68 61 72 20 2a 7a 45 72 72 20 3d 20     char *zErr = 
1380: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
1390: 22 75 6e 6b 6e 6f 77 6e 20 74 6f 6b 65 6e 69 7a  "unknown tokeniz
13a0: 65 72 3a 20 25 73 22 2c 20 7a 4e 61 6d 65 29 3b  er: %s", zName);
13b0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
13c0: 75 6c 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78  ult_error(contex
13d0: 74 2c 20 7a 45 72 72 2c 20 2d 31 29 3b 0a 20 20  t, zErr, -1);.  
13e0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
13f0: 45 72 72 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  Err);.    return
1400: 3b 0a 20 20 7d 0a 0a 20 20 70 52 65 74 20 3d 20  ;.  }..  pRet = 
1410: 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20  Tcl_NewObj();.  
1420: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
1430: 28 70 52 65 74 29 3b 0a 0a 20 20 69 66 28 20 53  (pRet);..  if( S
1440: 51 4c 49 54 45 5f 4f 4b 21 3d 70 2d 3e 78 43 72  QLITE_OK!=p->xCr
1450: 65 61 74 65 28 7a 41 72 67 20 3f 20 31 20 3a 20  eate(zArg ? 1 : 
1460: 30 2c 20 26 7a 41 72 67 2c 20 26 70 54 6f 6b 65  0, &zArg, &pToke
1470: 6e 69 7a 65 72 29 20 29 7b 0a 20 20 20 20 7a 45  nizer) ){.    zE
1480: 72 72 20 3d 20 22 65 72 72 6f 72 20 69 6e 20 78  rr = "error in x
1490: 43 72 65 61 74 65 28 29 22 3b 0a 20 20 20 20 67  Create()";.    g
14a0: 6f 74 6f 20 66 69 6e 69 73 68 3b 0a 20 20 7d 0a  oto finish;.  }.
14b0: 20 20 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e 70 4d    pTokenizer->pM
14c0: 6f 64 75 6c 65 20 3d 20 70 3b 0a 20 20 69 66 28  odule = p;.  if(
14d0: 20 53 51 4c 49 54 45 5f 4f 4b 21 3d 70 2d 3e 78   SQLITE_OK!=p->x
14e0: 4f 70 65 6e 28 70 54 6f 6b 65 6e 69 7a 65 72 2c  Open(pTokenizer,
14f0: 20 7a 49 6e 70 75 74 2c 20 6e 49 6e 70 75 74 2c   zInput, nInput,
1500: 20 26 70 43 73 72 29 20 29 7b 0a 20 20 20 20 7a   &pCsr) ){.    z
1510: 45 72 72 20 3d 20 22 65 72 72 6f 72 20 69 6e 20  Err = "error in 
1520: 78 4f 70 65 6e 28 29 22 3b 0a 20 20 20 20 67 6f  xOpen()";.    go
1530: 74 6f 20 66 69 6e 69 73 68 3b 0a 20 20 7d 0a 20  to finish;.  }. 
1540: 20 70 43 73 72 2d 3e 70 54 6f 6b 65 6e 69 7a 65   pCsr->pTokenize
1550: 72 20 3d 20 70 54 6f 6b 65 6e 69 7a 65 72 3b 0a  r = pTokenizer;.
1560: 0a 20 20 77 68 69 6c 65 28 20 53 51 4c 49 54 45  .  while( SQLITE
1570: 5f 4f 4b 3d 3d 70 2d 3e 78 4e 65 78 74 28 70 43  _OK==p->xNext(pC
1580: 73 72 2c 20 26 7a 54 6f 6b 65 6e 2c 20 26 6e 54  sr, &zToken, &nT
1590: 6f 6b 65 6e 2c 20 26 69 53 74 61 72 74 2c 20 26  oken, &iStart, &
15a0: 69 45 6e 64 2c 20 26 69 50 6f 73 29 20 29 7b 0a  iEnd, &iPos) ){.
15b0: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
15c0: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20  ppendElement(0, 
15d0: 70 52 65 74 2c 20 54 63 6c 5f 4e 65 77 49 6e 74  pRet, Tcl_NewInt
15e0: 4f 62 6a 28 69 50 6f 73 29 29 3b 0a 20 20 20 20  Obj(iPos));.    
15f0: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
1600: 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 52 65 74  dElement(0, pRet
1610: 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  , Tcl_NewStringO
1620: 62 6a 28 7a 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65  bj(zToken, nToke
1630: 6e 29 29 3b 0a 20 20 20 20 7a 54 6f 6b 65 6e 20  n));.    zToken 
1640: 3d 20 26 7a 49 6e 70 75 74 5b 69 53 74 61 72 74  = &zInput[iStart
1650: 5d 3b 0a 20 20 20 20 6e 54 6f 6b 65 6e 20 3d 20  ];.    nToken = 
1660: 69 45 6e 64 2d 69 53 74 61 72 74 3b 0a 20 20 20  iEnd-iStart;.   
1670: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
1680: 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 52 65  ndElement(0, pRe
1690: 74 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67  t, Tcl_NewString
16a0: 4f 62 6a 28 7a 54 6f 6b 65 6e 2c 20 6e 54 6f 6b  Obj(zToken, nTok
16b0: 65 6e 29 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  en));.  }..  if(
16c0: 20 53 51 4c 49 54 45 5f 4f 4b 21 3d 70 2d 3e 78   SQLITE_OK!=p->x
16d0: 43 6c 6f 73 65 28 70 43 73 72 29 20 29 7b 0a 20  Close(pCsr) ){. 
16e0: 20 20 20 7a 45 72 72 20 3d 20 22 65 72 72 6f 72     zErr = "error
16f0: 20 69 6e 20 78 43 6c 6f 73 65 28 29 22 3b 0a 20   in xClose()";. 
1700: 20 20 20 67 6f 74 6f 20 66 69 6e 69 73 68 3b 0a     goto finish;.
1710: 20 20 7d 0a 20 20 69 66 28 20 53 51 4c 49 54 45    }.  if( SQLITE
1720: 5f 4f 4b 21 3d 70 2d 3e 78 44 65 73 74 72 6f 79  _OK!=p->xDestroy
1730: 28 70 54 6f 6b 65 6e 69 7a 65 72 29 20 29 7b 0a  (pTokenizer) ){.
1740: 20 20 20 20 7a 45 72 72 20 3d 20 22 65 72 72 6f      zErr = "erro
1750: 72 20 69 6e 20 78 44 65 73 74 72 6f 79 28 29 22  r in xDestroy()"
1760: 3b 0a 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73  ;.    goto finis
1770: 68 3b 0a 20 20 7d 0a 0a 66 69 6e 69 73 68 3a 0a  h;.  }..finish:.
1780: 20 20 69 66 28 20 7a 45 72 72 20 29 7b 0a 20 20    if( zErr ){.  
1790: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
17a0: 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74 2c 20  _error(context, 
17b0: 7a 45 72 72 2c 20 2d 31 29 3b 0a 20 20 7d 65 6c  zErr, -1);.  }el
17c0: 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  se{.    sqlite3_
17d0: 72 65 73 75 6c 74 5f 74 65 78 74 28 63 6f 6e 74  result_text(cont
17e0: 65 78 74 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  ext, Tcl_GetStri
17f0: 6e 67 28 70 52 65 74 29 2c 20 2d 31 2c 20 53 51  ng(pRet), -1, SQ
1800: 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b  LITE_TRANSIENT);
1810: 0a 20 20 7d 0a 20 20 54 63 6c 5f 44 65 63 72 52  .  }.  Tcl_DecrR
1820: 65 66 43 6f 75 6e 74 28 70 52 65 74 29 3b 0a 7d  efCount(pRet);.}
1830: 0a 0a 73 74 61 74 69 63 0a 69 6e 74 20 72 65 67  ..static.int reg
1840: 69 73 74 65 72 54 6f 6b 65 6e 69 7a 65 72 28 0a  isterTokenizer(.
1850: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a    sqlite3 *db, .
1860: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 0a    char *zName, .
1870: 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f    const sqlite3_
1880: 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65  tokenizer_module
1890: 20 2a 70 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b   *p.){.  int rc;
18a0: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
18b0: 2a 70 53 74 6d 74 3b 0a 20 20 63 6f 6e 73 74 20  *pStmt;.  const 
18c0: 63 68 61 72 20 7a 53 71 6c 5b 5d 20 3d 20 22 53  char zSql[] = "S
18d0: 45 4c 45 43 54 20 66 74 73 32 5f 74 6f 6b 65 6e  ELECT fts2_token
18e0: 69 7a 65 72 28 3f 2c 20 3f 29 22 3b 0a 0a 20 20  izer(?, ?)";..  
18f0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65  rc = sqlite3_pre
1900: 70 61 72 65 5f 76 32 28 64 62 2c 20 7a 53 71 6c  pare_v2(db, zSql
1910: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
1920: 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
1930: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74  TE_OK ){.    ret
1940: 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 73  urn rc;.  }..  s
1950: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65 78 74  qlite3_bind_text
1960: 28 70 53 74 6d 74 2c 20 31 2c 20 7a 4e 61 6d 65  (pStmt, 1, zName
1970: 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 53 54 41  , -1, SQLITE_STA
1980: 54 49 43 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  TIC);.  sqlite3_
1990: 62 69 6e 64 5f 62 6c 6f 62 28 70 53 74 6d 74 2c  bind_blob(pStmt,
19a0: 20 32 2c 20 26 70 2c 20 73 69 7a 65 6f 66 28 70   2, &p, sizeof(p
19b0: 29 2c 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43  ), SQLITE_STATIC
19c0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 65  );.  sqlite3_ste
19d0: 70 28 70 53 74 6d 74 29 3b 0a 0a 20 20 72 65 74  p(pStmt);..  ret
19e0: 75 72 6e 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  urn sqlite3_fina
19f0: 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 7d 0a 0a  lize(pStmt);.}..
1a00: 73 74 61 74 69 63 0a 69 6e 74 20 71 75 65 72 79  static.int query
1a10: 46 74 73 32 54 6f 6b 65 6e 69 7a 65 72 28 0a 20  Fts2Tokenizer(. 
1a20: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20   sqlite3 *db, . 
1a30: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 0a   char *zName,  .
1a40: 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f    const sqlite3_
1a50: 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65  tokenizer_module
1a60: 20 2a 2a 70 70 0a 29 7b 0a 20 20 69 6e 74 20 72   **pp.){.  int r
1a70: 63 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  c;.  sqlite3_stm
1a80: 74 20 2a 70 53 74 6d 74 3b 0a 20 20 63 6f 6e 73  t *pStmt;.  cons
1a90: 74 20 63 68 61 72 20 7a 53 71 6c 5b 5d 20 3d 20  t char zSql[] = 
1aa0: 22 53 45 4c 45 43 54 20 66 74 73 32 5f 74 6f 6b  "SELECT fts2_tok
1ab0: 65 6e 69 7a 65 72 28 3f 29 22 3b 0a 0a 20 20 2a  enizer(?)";..  *
1ac0: 70 70 20 3d 20 30 3b 0a 20 20 72 63 20 3d 20 73  pp = 0;.  rc = s
1ad0: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76  qlite3_prepare_v
1ae0: 32 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20  2(db, zSql, -1, 
1af0: 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 69 66  &pStmt, 0);.  if
1b00: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
1b10: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  ){.    return rc
1b20: 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  ;.  }..  sqlite3
1b30: 5f 62 69 6e 64 5f 74 65 78 74 28 70 53 74 6d 74  _bind_text(pStmt
1b40: 2c 20 31 2c 20 7a 4e 61 6d 65 2c 20 2d 31 2c 20  , 1, zName, -1, 
1b50: 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a  SQLITE_STATIC);.
1b60: 20 20 69 66 28 20 53 51 4c 49 54 45 5f 52 4f 57    if( SQLITE_ROW
1b70: 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70  ==sqlite3_step(p
1b80: 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 69 66 28  Stmt) ){.    if(
1b90: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
1ba0: 74 79 70 65 28 70 53 74 6d 74 2c 20 30 29 3d 3d  type(pStmt, 0)==
1bb0: 53 51 4c 49 54 45 5f 42 4c 4f 42 20 29 7b 0a 20  SQLITE_BLOB ){. 
1bc0: 20 20 20 20 20 6d 65 6d 63 70 79 28 70 70 2c 20       memcpy(pp, 
1bd0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62  sqlite3_column_b
1be0: 6c 6f 62 28 70 53 74 6d 74 2c 20 30 29 2c 20 73  lob(pStmt, 0), s
1bf0: 69 7a 65 6f 66 28 2a 70 70 29 29 3b 0a 20 20 20  izeof(*pp));.   
1c00: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
1c10: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
1c20: 65 28 70 53 74 6d 74 29 3b 0a 7d 0a 0a 76 6f 69  e(pStmt);.}..voi
1c30: 64 20 73 71 6c 69 74 65 33 46 74 73 32 53 69 6d  d sqlite3Fts2Sim
1c40: 70 6c 65 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  pleTokenizerModu
1c50: 6c 65 28 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  le(sqlite3_token
1c60: 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 63 6f 6e 73  izer_module cons
1c70: 74 2a 2a 70 70 4d 6f 64 75 6c 65 29 3b 0a 0a 2f  t**ppModule);../
1c80: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
1c90: 69 6f 6e 20 6f 66 20 74 68 65 20 73 63 61 6c 61  ion of the scala
1ca0: 72 20 66 75 6e 63 74 69 6f 6e 20 66 74 73 32 5f  r function fts2_
1cb0: 74 6f 6b 65 6e 69 7a 65 72 5f 69 6e 74 65 72 6e  tokenizer_intern
1cc0: 61 6c 5f 74 65 73 74 28 29 2e 0a 2a 2a 20 54 68  al_test()..** Th
1cd0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75  is function is u
1ce0: 73 65 64 20 66 6f 72 20 74 65 73 74 69 6e 67 20  sed for testing 
1cf0: 6f 6e 6c 79 2c 20 69 74 20 69 73 20 6e 6f 74 20  only, it is not 
1d00: 69 6e 63 6c 75 64 65 64 20 69 6e 20 74 68 65 0a  included in the.
1d10: 2a 2a 20 62 75 69 6c 64 20 75 6e 6c 65 73 73 20  ** build unless 
1d20: 53 51 4c 49 54 45 5f 54 45 53 54 20 69 73 20 64  SQLITE_TEST is d
1d30: 65 66 69 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68  efined..**.** Th
1d40: 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74 68 69  e purpose of thi
1d50: 73 20 69 73 20 74 6f 20 74 65 73 74 20 74 68 61  s is to test tha
1d60: 74 20 74 68 65 20 66 74 73 32 5f 74 6f 6b 65 6e  t the fts2_token
1d70: 69 7a 65 72 28 29 20 66 75 6e 63 74 69 6f 6e 0a  izer() function.
1d80: 2a 2a 20 63 61 6e 20 62 65 20 75 73 65 64 20 61  ** can be used a
1d90: 73 20 64 65 73 69 67 6e 65 64 20 62 79 20 74 68  s designed by th
1da0: 65 20 43 2d 63 6f 64 65 20 69 6e 20 74 68 65 20  e C-code in the 
1db0: 71 75 65 72 79 46 74 73 32 54 6f 6b 65 6e 69 7a  queryFts2Tokeniz
1dc0: 65 72 20 61 6e 64 0a 2a 2a 20 72 65 67 69 73 74  er and.** regist
1dd0: 65 72 54 6f 6b 65 6e 69 7a 65 72 28 29 20 66 75  erTokenizer() fu
1de0: 6e 63 74 69 6f 6e 73 20 61 62 6f 76 65 2e 20 54  nctions above. T
1df0: 68 65 73 65 20 74 77 6f 20 66 75 6e 63 74 69 6f  hese two functio
1e00: 6e 73 20 61 72 65 20 72 65 70 65 61 74 65 64 0a  ns are repeated.
1e10: 2a 2a 20 69 6e 20 74 68 65 20 52 45 41 44 4d 45  ** in the README
1e20: 2e 74 6f 6b 65 6e 69 7a 65 72 20 66 69 6c 65 20  .tokenizer file 
1e30: 61 73 20 61 6e 20 65 78 61 6d 70 6c 65 2c 20 73  as an example, s
1e40: 6f 20 69 74 20 69 73 20 69 6d 70 6f 72 74 61 6e  o it is importan
1e50: 74 20 74 6f 0a 2a 2a 20 74 65 73 74 20 74 68 65  t to.** test the
1e60: 6d 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 72 75 6e 20  m..**.** To run 
1e70: 74 68 65 20 74 65 73 74 73 2c 20 65 76 61 6c 75  the tests, evalu
1e80: 61 74 65 20 74 68 65 20 66 74 73 32 5f 74 6f 6b  ate the fts2_tok
1e90: 65 6e 69 7a 65 72 5f 69 6e 74 65 72 6e 61 6c 5f  enizer_internal_
1ea0: 74 65 73 74 28 29 20 73 63 61 6c 61 72 0a 2a 2a  test() scalar.**
1eb0: 20 66 75 6e 63 74 69 6f 6e 20 77 69 74 68 20 6e   function with n
1ec0: 6f 20 61 72 67 75 6d 65 6e 74 73 2e 20 41 6e 20  o arguments. An 
1ed0: 61 73 73 65 72 74 28 29 20 77 69 6c 6c 20 66 61  assert() will fa
1ee0: 69 6c 20 69 66 20 61 20 70 72 6f 62 6c 65 6d 20  il if a problem 
1ef0: 69 73 0a 2a 2a 20 64 65 74 65 63 74 65 64 2e 20  is.** detected. 
1f00: 69 2e 65 2e 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  i.e.:.**.**     
1f10: 53 45 4c 45 43 54 20 66 74 73 32 5f 74 6f 6b 65  SELECT fts2_toke
1f20: 6e 69 7a 65 72 5f 69 6e 74 65 72 6e 61 6c 5f 74  nizer_internal_t
1f30: 65 73 74 28 29 3b 0a 2a 2a 0a 2a 2f 0a 73 74 61  est();.**.*/.sta
1f40: 74 69 63 20 76 6f 69 64 20 69 6e 74 54 65 73 74  tic void intTest
1f50: 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 65 33 5f  Func(.  sqlite3_
1f60: 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 74  context *context
1f70: 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 20  ,.  int argc,.  
1f80: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
1f90: 61 72 67 76 0a 29 7b 0a 20 20 69 6e 74 20 72 63  argv.){.  int rc
1fa0: 3b 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65  ;.  const sqlite
1fb0: 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75  3_tokenizer_modu
1fc0: 6c 65 20 2a 70 31 3b 0a 20 20 63 6f 6e 73 74 20  le *p1;.  const 
1fd0: 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
1fe0: 72 5f 6d 6f 64 75 6c 65 20 2a 70 32 3b 0a 20 20  r_module *p2;.  
1ff0: 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20 28 73  sqlite3 *db = (s
2000: 71 6c 69 74 65 33 20 2a 29 73 71 6c 69 74 65 33  qlite3 *)sqlite3
2010: 5f 75 73 65 72 5f 64 61 74 61 28 63 6f 6e 74 65  _user_data(conte
2020: 78 74 29 3b 0a 0a 20 20 2f 2a 20 54 65 73 74 20  xt);..  /* Test 
2030: 74 68 65 20 71 75 65 72 79 20 66 75 6e 63 74 69  the query functi
2040: 6f 6e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 46  on */.  sqlite3F
2050: 74 73 32 53 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a  ts2SimpleTokeniz
2060: 65 72 4d 6f 64 75 6c 65 28 26 70 31 29 3b 0a 20  erModule(&p1);. 
2070: 20 72 63 20 3d 20 71 75 65 72 79 46 74 73 32 54   rc = queryFts2T
2080: 6f 6b 65 6e 69 7a 65 72 28 64 62 2c 20 22 73 69  okenizer(db, "si
2090: 6d 70 6c 65 22 2c 20 26 70 32 29 3b 0a 20 20 61  mple", &p2);.  a
20a0: 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54  ssert( rc==SQLIT
20b0: 45 5f 4f 4b 20 29 3b 0a 20 20 61 73 73 65 72 74  E_OK );.  assert
20c0: 28 20 70 31 3d 3d 70 32 20 29 3b 0a 20 20 72 63  ( p1==p2 );.  rc
20d0: 20 3d 20 71 75 65 72 79 46 74 73 32 54 6f 6b 65   = queryFts2Toke
20e0: 6e 69 7a 65 72 28 64 62 2c 20 22 6e 6f 73 75 63  nizer(db, "nosuc
20f0: 68 74 6f 6b 65 6e 69 7a 65 72 22 2c 20 26 70 32  htokenizer", &p2
2100: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d  );.  assert( rc=
2110: 3d 53 51 4c 49 54 45 5f 45 52 52 4f 52 20 29 3b  =SQLITE_ERROR );
2120: 0a 20 20 61 73 73 65 72 74 28 20 70 32 3d 3d 30  .  assert( p2==0
2130: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 30 3d   );.  assert( 0=
2140: 3d 73 74 72 63 6d 70 28 73 71 6c 69 74 65 33 5f  =strcmp(sqlite3_
2150: 65 72 72 6d 73 67 28 64 62 29 2c 20 22 75 6e 6b  errmsg(db), "unk
2160: 6e 6f 77 6e 20 74 6f 6b 65 6e 69 7a 65 72 3a 20  nown tokenizer: 
2170: 6e 6f 73 75 63 68 74 6f 6b 65 6e 69 7a 65 72 22  nosuchtokenizer"
2180: 29 20 29 3b 0a 0a 20 20 2f 2a 20 54 65 73 74 20  ) );..  /* Test 
2190: 74 68 65 20 73 74 6f 72 61 67 65 20 66 75 6e 63  the storage func
21a0: 74 69 6f 6e 20 2a 2f 0a 20 20 72 63 20 3d 20 72  tion */.  rc = r
21b0: 65 67 69 73 74 65 72 54 6f 6b 65 6e 69 7a 65 72  egisterTokenizer
21c0: 28 64 62 2c 20 22 6e 6f 73 75 63 68 74 6f 6b 65  (db, "nosuchtoke
21d0: 6e 69 7a 65 72 22 2c 20 70 31 29 3b 0a 20 20 61  nizer", p1);.  a
21e0: 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54  ssert( rc==SQLIT
21f0: 45 5f 4f 4b 20 29 3b 0a 20 20 72 63 20 3d 20 71  E_OK );.  rc = q
2200: 75 65 72 79 46 74 73 32 54 6f 6b 65 6e 69 7a 65  ueryFts2Tokenize
2210: 72 28 64 62 2c 20 22 6e 6f 73 75 63 68 74 6f 6b  r(db, "nosuchtok
2220: 65 6e 69 7a 65 72 22 2c 20 26 70 32 29 3b 0a 20  enizer", &p2);. 
2230: 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c   assert( rc==SQL
2240: 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 61 73 73 65  ITE_OK );.  asse
2250: 72 74 28 20 70 32 3d 3d 70 31 20 29 3b 0a 0a 20  rt( p2==p1 );.. 
2260: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
2270: 74 65 78 74 28 63 6f 6e 74 65 78 74 2c 20 22 6f  text(context, "o
2280: 6b 22 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 53  k", -1, SQLITE_S
2290: 54 41 54 49 43 29 3b 0a 7d 0a 0a 23 65 6e 64 69  TATIC);.}..#endi
22a0: 66 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 75 70 20  f../*.** Set up 
22b0: 53 51 4c 20 6f 62 6a 65 63 74 73 20 69 6e 20 64  SQL objects in d
22c0: 61 74 61 62 61 73 65 20 64 62 20 75 73 65 64 20  atabase db used 
22d0: 74 6f 20 61 63 63 65 73 73 20 74 68 65 20 63 6f  to access the co
22e0: 6e 74 65 6e 74 73 20 6f 66 0a 2a 2a 20 74 68 65  ntents of.** the
22f0: 20 68 61 73 68 20 74 61 62 6c 65 20 70 6f 69 6e   hash table poin
2300: 74 65 64 20 74 6f 20 62 79 20 61 72 67 75 6d 65  ted to by argume
2310: 6e 74 20 70 48 61 73 68 2e 20 54 68 65 20 68 61  nt pHash. The ha
2320: 73 68 20 74 61 62 6c 65 20 6d 75 73 74 0a 2a 2a  sh table must.**
2330: 20 62 65 65 6e 20 69 6e 69 74 69 61 6c 69 7a 65   been initialize
2340: 64 20 74 6f 20 75 73 65 20 73 74 72 69 6e 67 20  d to use string 
2350: 6b 65 79 73 2c 20 61 6e 64 20 74 6f 20 74 61 6b  keys, and to tak
2360: 65 20 61 20 70 72 69 76 61 74 65 20 63 6f 70 79  e a private copy
2370: 20 0a 2a 2a 20 6f 66 20 74 68 65 20 6b 65 79 20   .** of the key 
2380: 77 68 65 6e 20 61 20 76 61 6c 75 65 20 69 73 20  when a value is 
2390: 69 6e 73 65 72 74 65 64 2e 20 69 2e 65 2e 20 62  inserted. i.e. b
23a0: 79 20 61 20 63 61 6c 6c 20 73 69 6d 69 6c 61 72  y a call similar
23b0: 20 74 6f 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 73 71   to:.**.**    sq
23c0: 6c 69 74 65 33 46 74 73 32 48 61 73 68 49 6e 69  lite3Fts2HashIni
23d0: 74 28 70 48 61 73 68 2c 20 46 54 53 32 5f 48 41  t(pHash, FTS2_HA
23e0: 53 48 5f 53 54 52 49 4e 47 2c 20 31 29 3b 0a 2a  SH_STRING, 1);.*
23f0: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
2400: 6f 6e 20 61 64 64 73 20 61 20 73 63 61 6c 61 72  on adds a scalar
2410: 20 66 75 6e 63 74 69 6f 6e 20 28 73 65 65 20 68   function (see h
2420: 65 61 64 65 72 20 63 6f 6d 6d 65 6e 74 20 61 62  eader comment ab
2430: 6f 76 65 0a 2a 2a 20 73 63 61 6c 61 72 46 75 6e  ove.** scalarFun
2440: 63 28 29 20 69 6e 20 74 68 69 73 20 66 69 6c 65  c() in this file
2450: 20 66 6f 72 20 64 65 74 61 69 6c 73 29 20 61 6e   for details) an
2460: 64 2c 20 69 66 20 45 4e 41 42 4c 45 5f 54 41 42  d, if ENABLE_TAB
2470: 4c 45 20 69 73 0a 2a 2a 20 64 65 66 69 6e 65 64  LE is.** defined
2480: 20 61 74 20 63 6f 6d 70 69 6c 61 74 69 6f 6e 20   at compilation 
2490: 74 69 6d 65 2c 20 61 20 74 65 6d 70 6f 72 61 72  time, a temporar
24a0: 79 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  y virtual table 
24b0: 28 73 65 65 20 68 65 61 64 65 72 20 0a 2a 2a 20  (see header .** 
24c0: 63 6f 6d 6d 65 6e 74 20 61 62 6f 76 65 20 73 74  comment above st
24d0: 72 75 63 74 20 48 61 73 68 54 61 62 6c 65 56 74  ruct HashTableVt
24e0: 61 62 29 20 74 6f 20 74 68 65 20 64 61 74 61 62  ab) to the datab
24f0: 61 73 65 20 73 63 68 65 6d 61 2e 20 42 6f 74 68  ase schema. Both
2500: 20 0a 2a 2a 20 70 72 6f 76 69 64 65 20 72 65 61   .** provide rea
2510: 64 2f 77 72 69 74 65 20 61 63 63 65 73 73 20 74  d/write access t
2520: 6f 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  o the contents o
2530: 66 20 2a 70 48 61 73 68 2e 0a 2a 2a 0a 2a 2a 20  f *pHash..**.** 
2540: 54 68 65 20 74 68 69 72 64 20 61 72 67 75 6d 65  The third argume
2550: 6e 74 20 74 6f 20 74 68 69 73 20 66 75 6e 63 74  nt to this funct
2560: 69 6f 6e 2c 20 7a 4e 61 6d 65 2c 20 69 73 20 75  ion, zName, is u
2570: 73 65 64 20 61 73 20 74 68 65 20 6e 61 6d 65 0a  sed as the name.
2580: 2a 2a 20 6f 66 20 62 6f 74 68 20 74 68 65 20 73  ** of both the s
2590: 63 61 6c 61 72 20 61 6e 64 2c 20 69 66 20 63 72  calar and, if cr
25a0: 65 61 74 65 64 2c 20 74 68 65 20 76 69 72 74 75  eated, the virtu
25b0: 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 69 6e 74  al table..*/.int
25c0: 20 73 71 6c 69 74 65 33 46 74 73 32 49 6e 69 74   sqlite3Fts2Init
25d0: 48 61 73 68 54 61 62 6c 65 28 0a 20 20 73 71 6c  HashTable(.  sql
25e0: 69 74 65 33 20 2a 64 62 2c 20 0a 20 20 66 74 73  ite3 *db, .  fts
25f0: 32 48 61 73 68 20 2a 70 48 61 73 68 2c 20 0a 20  2Hash *pHash, . 
2600: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
2610: 6d 65 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  me.){.  int rc =
2620: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 76 6f   SQLITE_OK;.  vo
2630: 69 64 20 2a 70 20 3d 20 28 76 6f 69 64 20 2a 29  id *p = (void *)
2640: 70 48 61 73 68 3b 0a 20 20 63 6f 6e 73 74 20 69  pHash;.  const i
2650: 6e 74 20 61 6e 79 20 3d 20 53 51 4c 49 54 45 5f  nt any = SQLITE_
2660: 41 4e 59 3b 0a 20 20 63 68 61 72 20 2a 7a 54 65  ANY;.  char *zTe
2670: 73 74 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a  st = 0;.  char *
2680: 7a 54 65 73 74 32 20 3d 20 30 3b 0a 0a 23 69 66  zTest2 = 0;..#if
2690: 64 65 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a  def SQLITE_TEST.
26a0: 20 20 76 6f 69 64 20 2a 70 64 62 20 3d 20 28 76    void *pdb = (v
26b0: 6f 69 64 20 2a 29 64 62 3b 0a 20 20 7a 54 65 73  oid *)db;.  zTes
26c0: 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  t = sqlite3_mpri
26d0: 6e 74 66 28 22 25 73 5f 74 65 73 74 22 2c 20 7a  ntf("%s_test", z
26e0: 4e 61 6d 65 29 3b 0a 20 20 7a 54 65 73 74 32 20  Name);.  zTest2 
26f0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
2700: 66 28 22 25 73 5f 69 6e 74 65 72 6e 61 6c 5f 74  f("%s_internal_t
2710: 65 73 74 22 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20  est", zName);.  
2720: 69 66 28 20 21 7a 54 65 73 74 20 7c 7c 20 21 7a  if( !zTest || !z
2730: 54 65 73 74 32 20 29 7b 0a 20 20 20 20 72 63 20  Test2 ){.    rc 
2740: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
2750: 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 69 66    }.#endif..  if
2760: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 0a  ( rc!=SQLITE_OK.
2770: 20 20 20 7c 7c 20 28 72 63 20 3d 20 73 71 6c 69     || (rc = sqli
2780: 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74  te3_create_funct
2790: 69 6f 6e 28 64 62 2c 20 7a 4e 61 6d 65 2c 20 31  ion(db, zName, 1
27a0: 2c 20 61 6e 79 2c 20 70 2c 20 73 63 61 6c 61 72  , any, p, scalar
27b0: 46 75 6e 63 2c 20 30 2c 20 30 29 29 0a 20 20 20  Func, 0, 0)).   
27c0: 7c 7c 20 28 72 63 20 3d 20 73 71 6c 69 74 65 33  || (rc = sqlite3
27d0: 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e  _create_function
27e0: 28 64 62 2c 20 7a 4e 61 6d 65 2c 20 32 2c 20 61  (db, zName, 2, a
27f0: 6e 79 2c 20 70 2c 20 73 63 61 6c 61 72 46 75 6e  ny, p, scalarFun
2800: 63 2c 20 30 2c 20 30 29 29 0a 23 69 66 64 65 66  c, 0, 0)).#ifdef
2810: 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 20 20 20   SQLITE_TEST.   
2820: 7c 7c 20 28 72 63 20 3d 20 73 71 6c 69 74 65 33  || (rc = sqlite3
2830: 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e  _create_function
2840: 28 64 62 2c 20 7a 54 65 73 74 2c 20 32 2c 20 61  (db, zTest, 2, a
2850: 6e 79 2c 20 70 2c 20 74 65 73 74 46 75 6e 63 2c  ny, p, testFunc,
2860: 20 30 2c 20 30 29 29 0a 20 20 20 7c 7c 20 28 72   0, 0)).   || (r
2870: 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61  c = sqlite3_crea
2880: 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20  te_function(db, 
2890: 7a 54 65 73 74 2c 20 33 2c 20 61 6e 79 2c 20 70  zTest, 3, any, p
28a0: 2c 20 74 65 73 74 46 75 6e 63 2c 20 30 2c 20 30  , testFunc, 0, 0
28b0: 29 29 0a 20 20 20 7c 7c 20 28 72 63 20 3d 20 73  )).   || (rc = s
28c0: 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 66 75  qlite3_create_fu
28d0: 6e 63 74 69 6f 6e 28 64 62 2c 20 7a 54 65 73 74  nction(db, zTest
28e0: 32 2c 20 30 2c 20 61 6e 79 2c 20 70 64 62 2c 20  2, 0, any, pdb, 
28f0: 69 6e 74 54 65 73 74 46 75 6e 63 2c 20 30 2c 20  intTestFunc, 0, 
2900: 30 29 29 0a 23 65 6e 64 69 66 0a 20 20 29 3b 0a  0)).#endif.  );.
2910: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
2920: 7a 54 65 73 74 29 3b 0a 20 20 73 71 6c 69 74 65  zTest);.  sqlite
2930: 33 5f 66 72 65 65 28 7a 54 65 73 74 32 29 3b 0a  3_free(zTest2);.
2940: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
2950: 23 65 6e 64 69 66 20 2f 2a 20 21 64 65 66 69 6e  #endif /* !defin
2960: 65 64 28 53 51 4c 49 54 45 5f 43 4f 52 45 29 20  ed(SQLITE_CORE) 
2970: 7c 7c 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  || defined(SQLIT
2980: 45 5f 45 4e 41 42 4c 45 5f 46 54 53 32 29 20 2a  E_ENABLE_FTS2) *
2990: 2f 0a                                            /.