/ Hex Artifact Content
Login

Artifact 4bd72f767f61c9ce5a7575c844e8d1ed2c3c561a:


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 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
03b0: 69 6f 6e 20 6f 66 20 74 68 65 20 53 51 4c 20 73  ion of the SQL s
03c0: 63 61 6c 61 72 20 66 75 6e 63 74 69 6f 6e 20 66  calar function f
03d0: 6f 72 20 61 63 63 65 73 73 69 6e 67 20 74 68 65  or accessing the
03e0: 20 75 6e 64 65 72 6c 79 69 6e 67 20 0a 2a 2a 20   underlying .** 
03f0: 68 61 73 68 20 74 61 62 6c 65 2e 20 54 68 69 73  hash table. This
0400: 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 62 65   function may be
0410: 20 63 61 6c 6c 65 64 20 61 73 20 66 6f 6c 6c 6f   called as follo
0420: 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 45 4c 45  ws:.**.**   SELE
0430: 43 54 20 3c 66 75 6e 63 74 69 6f 6e 2d 6e 61 6d  CT <function-nam
0440: 65 3e 28 3c 6b 65 79 2d 6e 61 6d 65 3e 29 3b 0a  e>(<key-name>);.
0450: 2a 2a 20 20 20 53 45 4c 45 43 54 20 3c 66 75 6e  **   SELECT <fun
0460: 63 74 69 6f 6e 2d 6e 61 6d 65 3e 28 3c 6b 65 79  ction-name>(<key
0470: 2d 6e 61 6d 65 3e 2c 20 3c 70 6f 69 6e 74 65 72  -name>, <pointer
0480: 3e 29 3b 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65 20  >);.**.** where 
0490: 3c 66 75 6e 63 74 69 6f 6e 2d 6e 61 6d 65 3e 20  <function-name> 
04a0: 69 73 20 74 68 65 20 6e 61 6d 65 20 70 61 73 73  is the name pass
04b0: 65 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64  ed as the second
04c0: 20 61 72 67 75 6d 65 6e 74 0a 2a 2a 20 74 6f 20   argument.** to 
04d0: 74 68 65 20 73 71 6c 69 74 65 33 46 74 73 33 49  the sqlite3Fts3I
04e0: 6e 69 74 48 61 73 68 54 61 62 6c 65 28 29 20 66  nitHashTable() f
04f0: 75 6e 63 74 69 6f 6e 20 28 65 2e 67 2e 20 27 66  unction (e.g. 'f
0500: 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 27 29 2e  ts3_tokenizer').
0510: 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 3c 70  .**.** If the <p
0520: 6f 69 6e 74 65 72 3e 20 61 72 67 75 6d 65 6e 74  ointer> argument
0530: 20 69 73 20 73 70 65 63 69 66 69 65 64 2c 20 69   is specified, i
0540: 74 20 6d 75 73 74 20 62 65 20 61 20 62 6c 6f 62  t must be a blob
0550: 20 76 61 6c 75 65 0a 2a 2a 20 63 6f 6e 74 61 69   value.** contai
0560: 6e 69 6e 67 20 61 20 70 6f 69 6e 74 65 72 20 74  ning a pointer t
0570: 6f 20 62 65 20 73 74 6f 72 65 64 20 61 73 20 74  o be stored as t
0580: 68 65 20 68 61 73 68 20 64 61 74 61 20 63 6f 72  he hash data cor
0590: 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20 74 6f  responding.** to
05a0: 20 74 68 65 20 73 74 72 69 6e 67 20 3c 6b 65 79   the string <key
05b0: 2d 6e 61 6d 65 3e 2e 20 49 66 20 3c 70 6f 69 6e  -name>. If <poin
05c0: 74 65 72 3e 20 69 73 20 6e 6f 74 20 73 70 65 63  ter> is not spec
05d0: 69 66 69 65 64 2c 20 74 68 65 6e 0a 2a 2a 20 74  ified, then.** t
05e0: 68 65 20 73 74 72 69 6e 67 20 3c 6b 65 79 2d 6e  he string <key-n
05f0: 61 6d 65 3e 20 6d 75 73 74 20 61 6c 72 65 61 64  ame> must alread
0600: 79 20 65 78 69 73 74 20 69 6e 20 74 68 65 20 68  y exist in the h
0610: 61 73 20 74 61 62 6c 65 2e 20 4f 74 68 65 72 77  as table. Otherw
0620: 69 73 65 2c 0a 2a 2a 20 61 6e 20 65 72 72 6f 72  ise,.** an error
0630: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a   is returned..**
0640: 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e  .** Whether or n
0650: 6f 74 20 74 68 65 20 3c 70 6f 69 6e 74 65 72 3e  ot the <pointer>
0660: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 73 70 65   argument is spe
0670: 63 69 66 69 65 64 2c 20 74 68 65 20 76 61 6c 75  cified, the valu
0680: 65 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69 73  e returned.** is
0690: 20 61 20 62 6c 6f 62 20 63 6f 6e 74 61 69 6e 69   a blob containi
06a0: 6e 67 20 74 68 65 20 70 6f 69 6e 74 65 72 20 73  ng the pointer s
06b0: 74 6f 72 65 64 20 61 73 20 74 68 65 20 68 61 73  tored as the has
06c0: 68 20 64 61 74 61 20 63 6f 72 72 65 73 70 6f 6e  h data correspon
06d0: 64 69 6e 67 0a 2a 2a 20 74 6f 20 73 74 72 69 6e  ding.** to strin
06e0: 67 20 3c 6b 65 79 2d 6e 61 6d 65 3e 20 28 61 66  g <key-name> (af
06f0: 74 65 72 20 74 68 65 20 68 61 73 68 2d 74 61 62  ter the hash-tab
0700: 6c 65 20 69 73 20 75 70 64 61 74 65 64 2c 20 69  le is updated, i
0710: 66 20 61 70 70 6c 69 63 61 62 6c 65 29 2e 0a 2a  f applicable)..*
0720: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 63  /.static void sc
0730: 61 6c 61 72 46 75 6e 63 28 0a 20 20 73 71 6c 69  alarFunc(.  sqli
0740: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e  te3_context *con
0750: 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63  text,.  int argc
0760: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  ,.  sqlite3_valu
0770: 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 46 74  e **argv.){.  Ft
0780: 73 33 48 61 73 68 20 2a 70 48 61 73 68 3b 0a 20  s3Hash *pHash;. 
0790: 20 76 6f 69 64 20 2a 70 50 74 72 20 3d 20 30 3b   void *pPtr = 0;
07a0: 0a 20 20 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65  .  const unsigne
07b0: 64 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20  d char *zName;. 
07c0: 20 69 6e 74 20 6e 4e 61 6d 65 3b 0a 0a 20 20 61   int nName;..  a
07d0: 73 73 65 72 74 28 20 61 72 67 63 3d 3d 31 20 7c  ssert( argc==1 |
07e0: 7c 20 61 72 67 63 3d 3d 32 20 29 3b 0a 0a 20 20  | argc==2 );..  
07f0: 70 48 61 73 68 20 3d 20 28 46 74 73 33 48 61 73  pHash = (Fts3Has
0800: 68 20 2a 29 73 71 6c 69 74 65 33 5f 75 73 65 72  h *)sqlite3_user
0810: 5f 64 61 74 61 28 63 6f 6e 74 65 78 74 29 3b 0a  _data(context);.
0820: 0a 20 20 7a 4e 61 6d 65 20 3d 20 73 71 6c 69 74  .  zName = sqlit
0830: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72  e3_value_text(ar
0840: 67 76 5b 30 5d 29 3b 0a 20 20 6e 4e 61 6d 65 20  gv[0]);.  nName 
0850: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
0860: 62 79 74 65 73 28 61 72 67 76 5b 30 5d 29 2b 31  bytes(argv[0])+1
0870: 3b 0a 0a 20 20 69 66 28 20 61 72 67 63 3d 3d 32  ;..  if( argc==2
0880: 20 29 7b 0a 23 69 66 64 65 66 20 53 51 4c 49 54   ){.#ifdef SQLIT
0890: 45 5f 45 4e 41 42 4c 45 5f 46 54 53 33 5f 54 4f  E_ENABLE_FTS3_TO
08a0: 4b 45 4e 49 5a 45 52 0a 20 20 20 20 76 6f 69 64  KENIZER.    void
08b0: 20 2a 70 4f 6c 64 3b 0a 20 20 20 20 69 6e 74 20   *pOld;.    int 
08c0: 6e 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  n = sqlite3_valu
08d0: 65 5f 62 79 74 65 73 28 61 72 67 76 5b 31 5d 29  e_bytes(argv[1])
08e0: 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 3d  ;.    if( zName=
08f0: 3d 30 20 7c 7c 20 6e 21 3d 73 69 7a 65 6f 66 28  =0 || n!=sizeof(
0900: 70 50 74 72 29 20 29 7b 0a 20 20 20 20 20 20 73  pPtr) ){.      s
0910: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72  qlite3_result_er
0920: 72 6f 72 28 63 6f 6e 74 65 78 74 2c 20 22 61 72  ror(context, "ar
0930: 67 75 6d 65 6e 74 20 74 79 70 65 20 6d 69 73 6d  gument type mism
0940: 61 74 63 68 22 2c 20 2d 31 29 3b 0a 20 20 20 20  atch", -1);.    
0950: 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 7d 0a    return;.    }.
0960: 20 20 20 20 70 50 74 72 20 3d 20 2a 28 76 6f 69      pPtr = *(voi
0970: 64 20 2a 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  d **)sqlite3_val
0980: 75 65 5f 62 6c 6f 62 28 61 72 67 76 5b 31 5d 29  ue_blob(argv[1])
0990: 3b 0a 20 20 20 20 70 4f 6c 64 20 3d 20 73 71 6c  ;.    pOld = sql
09a0: 69 74 65 33 46 74 73 33 48 61 73 68 49 6e 73 65  ite3Fts3HashInse
09b0: 72 74 28 70 48 61 73 68 2c 20 28 76 6f 69 64 20  rt(pHash, (void 
09c0: 2a 29 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65 2c 20  *)zName, nName, 
09d0: 70 50 74 72 29 3b 0a 20 20 20 20 69 66 28 20 70  pPtr);.    if( p
09e0: 4f 6c 64 3d 3d 70 50 74 72 20 29 7b 0a 20 20 20  Old==pPtr ){.   
09f0: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
0a00: 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74 2c  t_error(context,
0a10: 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 22   "out of memory"
0a20: 2c 20 2d 31 29 3b 0a 20 20 20 20 20 20 72 65 74  , -1);.      ret
0a30: 75 72 6e 3b 0a 20 20 20 20 7d 0a 23 65 6c 73 65  urn;.    }.#else
0a40: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
0a50: 75 6c 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78  ult_error(contex
0a60: 74 2c 20 22 66 74 73 33 74 6f 6b 65 6e 69 7a 65  t, "fts3tokenize
0a70: 3a 20 22 20 0a 20 20 20 20 20 20 20 20 22 64 69  : " .        "di
0a80: 73 61 62 6c 65 64 20 2d 20 72 65 62 75 69 6c 64  sabled - rebuild
0a90: 20 77 69 74 68 20 2d 44 53 51 4c 49 54 45 5f 45   with -DSQLITE_E
0aa0: 4e 41 42 4c 45 5f 46 54 53 33 5f 54 4f 4b 45 4e  NABLE_FTS3_TOKEN
0ab0: 49 5a 45 52 22 2c 20 2d 31 0a 20 20 20 20 29 3b  IZER", -1.    );
0ac0: 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 23 65 6e  .    return;.#en
0ad0: 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e  dif /* SQLITE_EN
0ae0: 41 42 4c 45 5f 46 54 53 33 5f 54 4f 4b 45 4e 49  ABLE_FTS3_TOKENI
0af0: 5a 45 52 20 2a 2f 0a 20 20 7d 65 6c 73 65 0a 20  ZER */.  }else. 
0b00: 20 7b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65   {.    if( zName
0b10: 20 29 7b 0a 20 20 20 20 20 20 70 50 74 72 20 3d   ){.      pPtr =
0b20: 20 73 71 6c 69 74 65 33 46 74 73 33 48 61 73 68   sqlite3Fts3Hash
0b30: 46 69 6e 64 28 70 48 61 73 68 2c 20 7a 4e 61 6d  Find(pHash, zNam
0b40: 65 2c 20 6e 4e 61 6d 65 29 3b 0a 20 20 20 20 7d  e, nName);.    }
0b50: 0a 20 20 20 20 69 66 28 20 21 70 50 74 72 20 29  .    if( !pPtr )
0b60: 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 45  {.      char *zE
0b70: 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  rr = sqlite3_mpr
0b80: 69 6e 74 66 28 22 75 6e 6b 6e 6f 77 6e 20 74 6f  intf("unknown to
0b90: 6b 65 6e 69 7a 65 72 3a 20 25 73 22 2c 20 7a 4e  kenizer: %s", zN
0ba0: 61 6d 65 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  ame);.      sqli
0bb0: 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72  te3_result_error
0bc0: 28 63 6f 6e 74 65 78 74 2c 20 7a 45 72 72 2c 20  (context, zErr, 
0bd0: 2d 31 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  -1);.      sqlit
0be0: 65 33 5f 66 72 65 65 28 7a 45 72 72 29 3b 0a 20  e3_free(zErr);. 
0bf0: 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20       return;.   
0c00: 20 7d 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65   }.  }..  sqlite
0c10: 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28 63 6f  3_result_blob(co
0c20: 6e 74 65 78 74 2c 20 28 76 6f 69 64 20 2a 29 26  ntext, (void *)&
0c30: 70 50 74 72 2c 20 73 69 7a 65 6f 66 28 70 50 74  pPtr, sizeof(pPt
0c40: 72 29 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53  r), SQLITE_TRANS
0c50: 49 45 4e 54 29 3b 0a 7d 0a 0a 69 6e 74 20 73 71  IENT);.}..int sq
0c60: 6c 69 74 65 33 46 74 73 33 49 73 49 64 43 68 61  lite3Fts3IsIdCha
0c70: 72 28 63 68 61 72 20 63 29 7b 0a 20 20 73 74 61  r(char c){.  sta
0c80: 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 69  tic const char i
0c90: 73 46 74 73 49 64 43 68 61 72 5b 5d 20 3d 20 7b  sFtsIdChar[] = {
0ca0: 0a 20 20 20 20 20 20 30 2c 20 30 2c 20 30 2c 20  .      0, 0, 0, 
0cb0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 0, 0, 0, 0, 0
0cc0: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
0cd0: 20 30 2c 20 30 2c 20 20 2f 2a 20 30 78 20 2a 2f   0, 0,  /* 0x */
0ce0: 0a 20 20 20 20 20 20 30 2c 20 30 2c 20 30 2c 20  .      0, 0, 0, 
0cf0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 0, 0, 0, 0, 0
0d00: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
0d10: 20 30 2c 20 30 2c 20 20 2f 2a 20 31 78 20 2a 2f   0, 0,  /* 1x */
0d20: 0a 20 20 20 20 20 20 30 2c 20 30 2c 20 30 2c 20  .      0, 0, 0, 
0d30: 30 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30  0, 1, 0, 0, 0, 0
0d40: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
0d50: 20 30 2c 20 30 2c 20 20 2f 2a 20 32 78 20 2a 2f   0, 0,  /* 2x */
0d60: 0a 20 20 20 20 20 20 31 2c 20 31 2c 20 31 2c 20  .      1, 1, 1, 
0d70: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0d80: 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 1, 0, 0, 0, 0,
0d90: 20 30 2c 20 30 2c 20 20 2f 2a 20 33 78 20 2a 2f   0, 0,  /* 3x */
0da0: 0a 20 20 20 20 20 20 30 2c 20 31 2c 20 31 2c 20  .      0, 1, 1, 
0db0: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0dc0: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
0dd0: 20 31 2c 20 31 2c 20 20 2f 2a 20 34 78 20 2a 2f   1, 1,  /* 4x */
0de0: 0a 20 20 20 20 20 20 31 2c 20 31 2c 20 31 2c 20  .      1, 1, 1, 
0df0: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0e00: 2c 20 31 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c  , 1, 1, 0, 0, 0,
0e10: 20 30 2c 20 31 2c 20 20 2f 2a 20 35 78 20 2a 2f   0, 1,  /* 5x */
0e20: 0a 20 20 20 20 20 20 30 2c 20 31 2c 20 31 2c 20  .      0, 1, 1, 
0e30: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0e40: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
0e50: 20 31 2c 20 31 2c 20 20 2f 2a 20 36 78 20 2a 2f   1, 1,  /* 6x */
0e60: 0a 20 20 20 20 20 20 31 2c 20 31 2c 20 31 2c 20  .      1, 1, 1, 
0e70: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
0e80: 2c 20 31 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c  , 1, 1, 0, 0, 0,
0e90: 20 30 2c 20 30 2c 20 20 2f 2a 20 37 78 20 2a 2f   0, 0,  /* 7x */
0ea0: 0a 20 20 7d 3b 0a 20 20 72 65 74 75 72 6e 20 28  .  };.  return (
0eb0: 63 26 30 78 38 30 20 7c 7c 20 69 73 46 74 73 49  c&0x80 || isFtsI
0ec0: 64 43 68 61 72 5b 28 69 6e 74 29 28 63 29 5d 29  dChar[(int)(c)])
0ed0: 3b 0a 7d 0a 0a 63 6f 6e 73 74 20 63 68 61 72 20  ;.}..const char 
0ee0: 2a 73 71 6c 69 74 65 33 46 74 73 33 4e 65 78 74  *sqlite3Fts3Next
0ef0: 54 6f 6b 65 6e 28 63 6f 6e 73 74 20 63 68 61 72  Token(const char
0f00: 20 2a 7a 53 74 72 2c 20 69 6e 74 20 2a 70 6e 29   *zStr, int *pn)
0f10: 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  {.  const char *
0f20: 7a 31 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  z1;.  const char
0f30: 20 2a 7a 32 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20   *z2 = 0;..  /* 
0f40: 46 69 6e 64 20 74 68 65 20 73 74 61 72 74 20 6f  Find the start o
0f50: 66 20 74 68 65 20 6e 65 78 74 20 74 6f 6b 65 6e  f the next token
0f60: 2e 20 2a 2f 0a 20 20 7a 31 20 3d 20 7a 53 74 72  . */.  z1 = zStr
0f70: 3b 0a 20 20 77 68 69 6c 65 28 20 7a 32 3d 3d 30  ;.  while( z2==0
0f80: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 63 20 3d   ){.    char c =
0f90: 20 2a 7a 31 3b 0a 20 20 20 20 73 77 69 74 63 68   *z1;.    switch
0fa0: 28 20 63 20 29 7b 0a 20 20 20 20 20 20 63 61 73  ( c ){.      cas
0fb0: 65 20 27 5c 30 27 3a 20 72 65 74 75 72 6e 20 30  e '\0': return 0
0fc0: 3b 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 20 6d  ;        /* No m
0fd0: 6f 72 65 20 74 6f 6b 65 6e 73 20 68 65 72 65 20  ore tokens here 
0fe0: 2a 2f 0a 20 20 20 20 20 20 63 61 73 65 20 27 5c  */.      case '\
0ff0: 27 27 3a 0a 20 20 20 20 20 20 63 61 73 65 20 27  '':.      case '
1000: 22 27 3a 0a 20 20 20 20 20 20 63 61 73 65 20 27  "':.      case '
1010: 60 27 3a 20 7b 0a 20 20 20 20 20 20 20 20 7a 32  `': {.        z2
1020: 20 3d 20 7a 31 3b 0a 20 20 20 20 20 20 20 20 77   = z1;.        w
1030: 68 69 6c 65 28 20 2a 2b 2b 7a 32 20 26 26 20 28  hile( *++z2 && (
1040: 2a 7a 32 21 3d 63 20 7c 7c 20 2a 2b 2b 7a 32 3d  *z2!=c || *++z2=
1050: 3d 63 29 20 29 3b 0a 20 20 20 20 20 20 20 20 62  =c) );.        b
1060: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
1070: 20 20 20 20 63 61 73 65 20 27 5b 27 3a 0a 20 20      case '[':.  
1080: 20 20 20 20 20 20 7a 32 20 3d 20 26 7a 31 5b 31        z2 = &z1[1
1090: 5d 3b 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65  ];.        while
10a0: 28 20 2a 7a 32 20 26 26 20 7a 32 5b 30 5d 21 3d  ( *z2 && z2[0]!=
10b0: 27 5d 27 20 29 20 7a 32 2b 2b 3b 0a 20 20 20 20  ']' ) z2++;.    
10c0: 20 20 20 20 69 66 28 20 2a 7a 32 20 29 20 7a 32      if( *z2 ) z2
10d0: 2b 2b 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  ++;.        brea
10e0: 6b 3b 0a 0a 20 20 20 20 20 20 64 65 66 61 75 6c  k;..      defaul
10f0: 74 3a 0a 20 20 20 20 20 20 20 20 69 66 28 20 73  t:.        if( s
1100: 71 6c 69 74 65 33 46 74 73 33 49 73 49 64 43 68  qlite3Fts3IsIdCh
1110: 61 72 28 2a 7a 31 29 20 29 7b 0a 20 20 20 20 20  ar(*z1) ){.     
1120: 20 20 20 20 20 7a 32 20 3d 20 26 7a 31 5b 31 5d       z2 = &z1[1]
1130: 3b 0a 20 20 20 20 20 20 20 20 20 20 77 68 69 6c  ;.          whil
1140: 65 28 20 73 71 6c 69 74 65 33 46 74 73 33 49 73  e( sqlite3Fts3Is
1150: 49 64 43 68 61 72 28 2a 7a 32 29 20 29 20 7a 32  IdChar(*z2) ) z2
1160: 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  ++;.        }els
1170: 65 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 31 2b  e{.          z1+
1180: 2b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  +;.        }.   
1190: 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 6e 20 3d 20   }.  }..  *pn = 
11a0: 28 69 6e 74 29 28 7a 32 2d 7a 31 29 3b 0a 20 20  (int)(z2-z1);.  
11b0: 72 65 74 75 72 6e 20 7a 31 3b 0a 7d 0a 0a 69 6e  return z1;.}..in
11c0: 74 20 73 71 6c 69 74 65 33 46 74 73 33 49 6e 69  t sqlite3Fts3Ini
11d0: 74 54 6f 6b 65 6e 69 7a 65 72 28 0a 20 20 46 74  tTokenizer(.  Ft
11e0: 73 33 48 61 73 68 20 2a 70 48 61 73 68 2c 20 20  s3Hash *pHash,  
11f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1200: 20 54 6f 6b 65 6e 69 7a 65 72 20 68 61 73 68 20   Tokenizer hash 
1210: 74 61 62 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74  table */.  const
1220: 20 63 68 61 72 20 2a 7a 41 72 67 2c 20 20 20 20   char *zArg,    
1230: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f             /* To
1240: 6b 65 6e 69 7a 65 72 20 6e 61 6d 65 20 2a 2f 0a  kenizer name */.
1250: 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69    sqlite3_tokeni
1260: 7a 65 72 20 2a 2a 70 70 54 6f 6b 2c 20 20 20 20  zer **ppTok,    
1270: 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 6b 65 6e 69    /* OUT: Tokeni
1280: 7a 65 72 20 28 69 66 20 61 70 70 6c 69 63 61 62  zer (if applicab
1290: 6c 65 29 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a  le) */.  char **
12a0: 70 7a 45 72 72 20 20 20 20 20 20 20 20 20 20 20  pzErr           
12b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
12c0: 20 53 65 74 20 74 6f 20 6d 61 6c 6c 6f 63 65 64   Set to malloced
12d0: 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 20 2a   error message *
12e0: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  /.){.  int rc;. 
12f0: 20 63 68 61 72 20 2a 7a 20 3d 20 28 63 68 61 72   char *z = (char
1300: 20 2a 29 7a 41 72 67 3b 0a 20 20 69 6e 74 20 6e   *)zArg;.  int n
1310: 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 43   = 0;.  char *zC
1320: 6f 70 79 3b 0a 20 20 63 68 61 72 20 2a 7a 45 6e  opy;.  char *zEn
1330: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
1340: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
1350: 72 20 74 6f 20 6e 75 6c 2d 74 65 72 6d 20 6f 66  r to nul-term of
1360: 20 7a 43 6f 70 79 20 2a 2f 0a 20 20 73 71 6c 69   zCopy */.  sqli
1370: 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f  te3_tokenizer_mo
1380: 64 75 6c 65 20 2a 6d 3b 0a 0a 20 20 7a 43 6f 70  dule *m;..  zCop
1390: 79 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  y = sqlite3_mpri
13a0: 6e 74 66 28 22 25 73 22 2c 20 7a 41 72 67 29 3b  ntf("%s", zArg);
13b0: 0a 20 20 69 66 28 20 21 7a 43 6f 70 79 20 29 20  .  if( !zCopy ) 
13c0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
13d0: 4d 45 4d 3b 0a 20 20 7a 45 6e 64 20 3d 20 26 7a  MEM;.  zEnd = &z
13e0: 43 6f 70 79 5b 73 74 72 6c 65 6e 28 7a 43 6f 70  Copy[strlen(zCop
13f0: 79 29 5d 3b 0a 0a 20 20 7a 20 3d 20 28 63 68 61  y)];..  z = (cha
1400: 72 20 2a 29 73 71 6c 69 74 65 33 46 74 73 33 4e  r *)sqlite3Fts3N
1410: 65 78 74 54 6f 6b 65 6e 28 7a 43 6f 70 79 2c 20  extToken(zCopy, 
1420: 26 6e 29 3b 0a 20 20 69 66 28 20 7a 3d 3d 30 20  &n);.  if( z==0 
1430: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 6e  ){.    assert( n
1440: 3d 3d 30 20 29 3b 0a 20 20 20 20 7a 20 3d 20 7a  ==0 );.    z = z
1450: 43 6f 70 79 3b 0a 20 20 7d 0a 20 20 7a 5b 6e 5d  Copy;.  }.  z[n]
1460: 20 3d 20 27 5c 30 27 3b 0a 20 20 73 71 6c 69 74   = '\0';.  sqlit
1470: 65 33 46 74 73 33 44 65 71 75 6f 74 65 28 7a 29  e3Fts3Dequote(z)
1480: 3b 0a 0a 20 20 6d 20 3d 20 28 73 71 6c 69 74 65  ;..  m = (sqlite
1490: 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75  3_tokenizer_modu
14a0: 6c 65 20 2a 29 73 71 6c 69 74 65 33 46 74 73 33  le *)sqlite3Fts3
14b0: 48 61 73 68 46 69 6e 64 28 70 48 61 73 68 2c 7a  HashFind(pHash,z
14c0: 2c 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a 29 2b  ,(int)strlen(z)+
14d0: 31 29 3b 0a 20 20 69 66 28 20 21 6d 20 29 7b 0a  1);.  if( !m ){.
14e0: 20 20 20 20 73 71 6c 69 74 65 33 46 74 73 33 45      sqlite3Fts3E
14f0: 72 72 4d 73 67 28 70 7a 45 72 72 2c 20 22 75 6e  rrMsg(pzErr, "un
1500: 6b 6e 6f 77 6e 20 74 6f 6b 65 6e 69 7a 65 72 3a  known tokenizer:
1510: 20 25 73 22 2c 20 7a 29 3b 0a 20 20 20 20 72 63   %s", z);.    rc
1520: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
1530: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 63 68  .  }else{.    ch
1540: 61 72 20 63 6f 6e 73 74 20 2a 2a 61 41 72 67 20  ar const **aArg 
1550: 3d 20 30 3b 0a 20 20 20 20 69 6e 74 20 69 41 72  = 0;.    int iAr
1560: 67 20 3d 20 30 3b 0a 20 20 20 20 7a 20 3d 20 26  g = 0;.    z = &
1570: 7a 5b 6e 2b 31 5d 3b 0a 20 20 20 20 77 68 69 6c  z[n+1];.    whil
1580: 65 28 20 7a 3c 7a 45 6e 64 20 26 26 20 28 4e 55  e( z<zEnd && (NU
1590: 4c 4c 21 3d 28 7a 20 3d 20 28 63 68 61 72 20 2a  LL!=(z = (char *
15a0: 29 73 71 6c 69 74 65 33 46 74 73 33 4e 65 78 74  )sqlite3Fts3Next
15b0: 54 6f 6b 65 6e 28 7a 2c 20 26 6e 29 29 29 20 29  Token(z, &n))) )
15c0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65 77  {.      int nNew
15d0: 20 3d 20 73 69 7a 65 6f 66 28 63 68 61 72 20 2a   = sizeof(char *
15e0: 29 2a 28 69 41 72 67 2b 31 29 3b 0a 20 20 20 20  )*(iArg+1);.    
15f0: 20 20 63 68 61 72 20 63 6f 6e 73 74 20 2a 2a 61    char const **a
1600: 4e 65 77 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  New = (const cha
1610: 72 20 2a 2a 29 73 71 6c 69 74 65 33 5f 72 65 61  r **)sqlite3_rea
1620: 6c 6c 6f 63 28 28 76 6f 69 64 20 2a 29 61 41 72  lloc((void *)aAr
1630: 67 2c 20 6e 4e 65 77 29 3b 0a 20 20 20 20 20 20  g, nNew);.      
1640: 69 66 28 20 21 61 4e 65 77 20 29 7b 0a 20 20 20  if( !aNew ){.   
1650: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65       sqlite3_fre
1660: 65 28 7a 43 6f 70 79 29 3b 0a 20 20 20 20 20 20  e(zCopy);.      
1670: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 28    sqlite3_free((
1680: 76 6f 69 64 20 2a 29 61 41 72 67 29 3b 0a 20 20  void *)aArg);.  
1690: 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c        return SQL
16a0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
16b0: 20 7d 0a 20 20 20 20 20 20 61 41 72 67 20 3d 20   }.      aArg = 
16c0: 61 4e 65 77 3b 0a 20 20 20 20 20 20 61 41 72 67  aNew;.      aArg
16d0: 5b 69 41 72 67 2b 2b 5d 20 3d 20 7a 3b 0a 20 20  [iArg++] = z;.  
16e0: 20 20 20 20 7a 5b 6e 5d 20 3d 20 27 5c 30 27 3b      z[n] = '\0';
16f0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 46 74  .      sqlite3Ft
1700: 73 33 44 65 71 75 6f 74 65 28 7a 29 3b 0a 20 20  s3Dequote(z);.  
1710: 20 20 20 20 7a 20 3d 20 26 7a 5b 6e 2b 31 5d 3b      z = &z[n+1];
1720: 0a 20 20 20 20 7d 0a 20 20 20 20 72 63 20 3d 20  .    }.    rc = 
1730: 6d 2d 3e 78 43 72 65 61 74 65 28 69 41 72 67 2c  m->xCreate(iArg,
1740: 20 61 41 72 67 2c 20 70 70 54 6f 6b 29 3b 0a 20   aArg, ppTok);. 
1750: 20 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53     assert( rc!=S
1760: 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 2a 70 70 54  QLITE_OK || *ppT
1770: 6f 6b 20 29 3b 0a 20 20 20 20 69 66 28 20 72 63  ok );.    if( rc
1780: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
1790: 20 20 20 20 20 73 71 6c 69 74 65 33 46 74 73 33       sqlite3Fts3
17a0: 45 72 72 4d 73 67 28 70 7a 45 72 72 2c 20 22 75  ErrMsg(pzErr, "u
17b0: 6e 6b 6e 6f 77 6e 20 74 6f 6b 65 6e 69 7a 65 72  nknown tokenizer
17c0: 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ");.    }else{. 
17d0: 20 20 20 20 20 28 2a 70 70 54 6f 6b 29 2d 3e 70       (*ppTok)->p
17e0: 4d 6f 64 75 6c 65 20 3d 20 6d 3b 20 0a 20 20 20  Module = m; .   
17f0: 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66   }.    sqlite3_f
1800: 72 65 65 28 28 76 6f 69 64 20 2a 29 61 41 72 67  ree((void *)aArg
1810: 29 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65  );.  }..  sqlite
1820: 33 5f 66 72 65 65 28 7a 43 6f 70 79 29 3b 0a 20  3_free(zCopy);. 
1830: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a   return rc;.}...
1840: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45  #ifdef SQLITE_TE
1850: 53 54 0a 0a 23 69 6e 63 6c 75 64 65 20 3c 74 63  ST..#include <tc
1860: 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73  l.h>.#include <s
1870: 74 72 69 6e 67 2e 68 3e 0a 0a 2f 2a 0a 2a 2a 20  tring.h>../*.** 
1880: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
1890: 66 20 61 20 73 70 65 63 69 61 6c 20 53 51 4c 20  f a special SQL 
18a0: 73 63 61 6c 61 72 20 66 75 6e 63 74 69 6f 6e 20  scalar function 
18b0: 66 6f 72 20 74 65 73 74 69 6e 67 20 74 6f 6b 65  for testing toke
18c0: 6e 69 7a 65 72 73 20 0a 2a 2a 20 64 65 73 69 67  nizers .** desig
18d0: 6e 65 64 20 74 6f 20 62 65 20 75 73 65 64 20 69  ned to be used i
18e0: 6e 20 63 6f 6e 63 65 72 74 20 77 69 74 68 20 74  n concert with t
18f0: 68 65 20 54 63 6c 20 74 65 73 74 69 6e 67 20 66  he Tcl testing f
1900: 72 61 6d 65 77 6f 72 6b 2e 20 54 68 69 73 0a 2a  ramework. This.*
1910: 2a 20 66 75 6e 63 74 69 6f 6e 20 6d 75 73 74 20  * function must 
1920: 62 65 20 63 61 6c 6c 65 64 20 77 69 74 68 20 74  be called with t
1930: 77 6f 20 6f 72 20 6d 6f 72 65 20 61 72 67 75 6d  wo or more argum
1940: 65 6e 74 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 45  ents:.**.**   SE
1950: 4c 45 43 54 20 3c 66 75 6e 63 74 69 6f 6e 2d 6e  LECT <function-n
1960: 61 6d 65 3e 28 3c 6b 65 79 2d 6e 61 6d 65 3e 2c  ame>(<key-name>,
1970: 20 2e 2e 2e 2c 20 3c 69 6e 70 75 74 2d 73 74 72   ..., <input-str
1980: 69 6e 67 3e 29 3b 0a 2a 2a 0a 2a 2a 20 77 68 65  ing>);.**.** whe
1990: 72 65 20 3c 66 75 6e 63 74 69 6f 6e 2d 6e 61 6d  re <function-nam
19a0: 65 3e 20 69 73 20 74 68 65 20 6e 61 6d 65 20 70  e> is the name p
19b0: 61 73 73 65 64 20 61 73 20 74 68 65 20 73 65 63  assed as the sec
19c0: 6f 6e 64 20 61 72 67 75 6d 65 6e 74 0a 2a 2a 20  ond argument.** 
19d0: 74 6f 20 74 68 65 20 73 71 6c 69 74 65 33 46 74  to the sqlite3Ft
19e0: 73 33 49 6e 69 74 48 61 73 68 54 61 62 6c 65 28  s3InitHashTable(
19f0: 29 20 66 75 6e 63 74 69 6f 6e 20 28 65 2e 67 2e  ) function (e.g.
1a00: 20 27 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72   'fts3_tokenizer
1a10: 27 29 0a 2a 2a 20 63 6f 6e 63 61 74 65 6e 61 74  ').** concatenat
1a20: 65 64 20 77 69 74 68 20 74 68 65 20 73 74 72 69  ed with the stri
1a30: 6e 67 20 27 5f 74 65 73 74 27 20 28 65 2e 67 2e  ng '_test' (e.g.
1a40: 20 27 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72   'fts3_tokenizer
1a50: 5f 74 65 73 74 27 29 2e 0a 2a 2a 0a 2a 2a 20 54  _test')..**.** T
1a60: 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65 20  he return value 
1a70: 69 73 20 61 20 73 74 72 69 6e 67 20 74 68 61 74  is a string that
1a80: 20 6d 61 79 20 62 65 20 69 6e 74 65 72 70 72 65   may be interpre
1a90: 74 65 64 20 61 73 20 61 20 54 63 6c 0a 2a 2a 20  ted as a Tcl.** 
1aa0: 6c 69 73 74 2e 20 46 6f 72 20 65 61 63 68 20 74  list. For each t
1ab0: 6f 6b 65 6e 20 69 6e 20 74 68 65 20 3c 69 6e 70  oken in the <inp
1ac0: 75 74 2d 73 74 72 69 6e 67 3e 2c 20 74 68 72 65  ut-string>, thre
1ad0: 65 20 65 6c 65 6d 65 6e 74 73 20 61 72 65 0a 2a  e elements are.*
1ae0: 2a 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 72  * added to the r
1af0: 65 74 75 72 6e 65 64 20 6c 69 73 74 2e 20 54 68  eturned list. Th
1b00: 65 20 66 69 72 73 74 20 69 73 20 74 68 65 20 74  e first is the t
1b10: 6f 6b 65 6e 20 70 6f 73 69 74 69 6f 6e 2c 20 74  oken position, t
1b20: 68 65 20 0a 2a 2a 20 73 65 63 6f 6e 64 20 69 73  he .** second is
1b30: 20 74 68 65 20 74 6f 6b 65 6e 20 74 65 78 74 20   the token text 
1b40: 28 66 6f 6c 64 65 64 2c 20 73 74 65 6d 6d 65 64  (folded, stemmed
1b50: 2c 20 65 74 63 2e 29 20 61 6e 64 20 74 68 65 20  , etc.) and the 
1b60: 74 68 69 72 64 20 69 73 20 74 68 65 0a 2a 2a 20  third is the.** 
1b70: 73 75 62 73 74 72 69 6e 67 20 6f 66 20 3c 69 6e  substring of <in
1b80: 70 75 74 2d 73 74 72 69 6e 67 3e 20 61 73 73 6f  put-string> asso
1b90: 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20  ciated with the 
1ba0: 74 6f 6b 65 6e 2e 20 46 6f 72 20 65 78 61 6d 70  token. For examp
1bb0: 6c 65 2c 20 0a 2a 2a 20 75 73 69 6e 67 20 74 68  le, .** using th
1bc0: 65 20 62 75 69 6c 74 2d 69 6e 20 22 73 69 6d 70  e built-in "simp
1bd0: 6c 65 22 20 74 6f 6b 65 6e 69 7a 65 72 3a 0a 2a  le" tokenizer:.*
1be0: 2a 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20 66 74  *.**   SELECT ft
1bf0: 73 5f 74 6f 6b 65 6e 69 7a 65 72 5f 74 65 73 74  s_tokenizer_test
1c00: 28 27 73 69 6d 70 6c 65 27 2c 20 27 49 20 64 6f  ('simple', 'I do
1c10: 6e 27 74 20 73 65 65 20 68 6f 77 27 29 3b 0a 2a  n't see how');.*
1c20: 2a 0a 2a 2a 20 77 69 6c 6c 20 72 65 74 75 72 6e  *.** will return
1c30: 20 74 68 65 20 73 74 72 69 6e 67 3a 0a 2a 2a 0a   the string:.**.
1c40: 2a 2a 20 20 20 22 7b 30 20 69 20 49 20 31 20 64  **   "{0 i I 1 d
1c50: 6f 6e 74 20 64 6f 6e 27 74 20 32 20 73 65 65 20  ont don't 2 see 
1c60: 73 65 65 20 33 20 68 6f 77 20 68 6f 77 7d 22 0a  see 3 how how}".
1c70: 2a 2a 20 20 20 0a 2a 2f 0a 73 74 61 74 69 63 20  **   .*/.static 
1c80: 76 6f 69 64 20 74 65 73 74 46 75 6e 63 28 0a 20  void testFunc(. 
1c90: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
1ca0: 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74   *context,.  int
1cb0: 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33   argc,.  sqlite3
1cc0: 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b  _value **argv.){
1cd0: 0a 20 20 46 74 73 33 48 61 73 68 20 2a 70 48 61  .  Fts3Hash *pHa
1ce0: 73 68 3b 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f  sh;.  sqlite3_to
1cf0: 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a  kenizer_module *
1d00: 70 3b 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b  p;.  sqlite3_tok
1d10: 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a  enizer *pTokeniz
1d20: 65 72 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65  er = 0;.  sqlite
1d30: 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73  3_tokenizer_curs
1d40: 6f 72 20 2a 70 43 73 72 20 3d 20 30 3b 0a 0a 20  or *pCsr = 0;.. 
1d50: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 72   const char *zEr
1d60: 72 20 3d 20 30 3b 0a 0a 20 20 63 6f 6e 73 74 20  r = 0;..  const 
1d70: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 69  char *zName;.  i
1d80: 6e 74 20 6e 4e 61 6d 65 3b 0a 20 20 63 6f 6e 73  nt nName;.  cons
1d90: 74 20 63 68 61 72 20 2a 7a 49 6e 70 75 74 3b 0a  t char *zInput;.
1da0: 20 20 69 6e 74 20 6e 49 6e 70 75 74 3b 0a 0a 20    int nInput;.. 
1db0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a 41   const char *azA
1dc0: 72 67 5b 36 34 5d 3b 0a 0a 20 20 63 6f 6e 73 74  rg[64];..  const
1dd0: 20 63 68 61 72 20 2a 7a 54 6f 6b 65 6e 3b 0a 20   char *zToken;. 
1de0: 20 69 6e 74 20 6e 54 6f 6b 65 6e 20 3d 20 30 3b   int nToken = 0;
1df0: 0a 20 20 69 6e 74 20 69 53 74 61 72 74 20 3d 20  .  int iStart = 
1e00: 30 3b 0a 20 20 69 6e 74 20 69 45 6e 64 20 3d 20  0;.  int iEnd = 
1e10: 30 3b 0a 20 20 69 6e 74 20 69 50 6f 73 20 3d 20  0;.  int iPos = 
1e20: 30 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 54  0;.  int i;..  T
1e30: 63 6c 5f 4f 62 6a 20 2a 70 52 65 74 3b 0a 0a 20  cl_Obj *pRet;.. 
1e40: 20 69 66 28 20 61 72 67 63 3c 32 20 29 7b 0a 20   if( argc<2 ){. 
1e50: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
1e60: 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74 2c  t_error(context,
1e70: 20 22 69 6e 73 75 66 66 69 63 69 65 6e 74 20 61   "insufficient a
1e80: 72 67 75 6d 65 6e 74 73 22 2c 20 2d 31 29 3b 0a  rguments", -1);.
1e90: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a      return;.  }.
1ea0: 0a 20 20 6e 4e 61 6d 65 20 3d 20 73 71 6c 69 74  .  nName = sqlit
1eb0: 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61  e3_value_bytes(a
1ec0: 72 67 76 5b 30 5d 29 3b 0a 20 20 7a 4e 61 6d 65  rgv[0]);.  zName
1ed0: 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 20 2a   = (const char *
1ee0: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74  )sqlite3_value_t
1ef0: 65 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20  ext(argv[0]);.  
1f00: 6e 49 6e 70 75 74 20 3d 20 73 71 6c 69 74 65 33  nInput = sqlite3
1f10: 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61 72 67  _value_bytes(arg
1f20: 76 5b 61 72 67 63 2d 31 5d 29 3b 0a 20 20 7a 49  v[argc-1]);.  zI
1f30: 6e 70 75 74 20 3d 20 28 63 6f 6e 73 74 20 63 68  nput = (const ch
1f40: 61 72 20 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  ar *)sqlite3_val
1f50: 75 65 5f 74 65 78 74 28 61 72 67 76 5b 61 72 67  ue_text(argv[arg
1f60: 63 2d 31 5d 29 3b 0a 0a 20 20 70 48 61 73 68 20  c-1]);..  pHash 
1f70: 3d 20 28 46 74 73 33 48 61 73 68 20 2a 29 73 71  = (Fts3Hash *)sq
1f80: 6c 69 74 65 33 5f 75 73 65 72 5f 64 61 74 61 28  lite3_user_data(
1f90: 63 6f 6e 74 65 78 74 29 3b 0a 20 20 70 20 3d 20  context);.  p = 
1fa0: 28 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a  (sqlite3_tokeniz
1fb0: 65 72 5f 6d 6f 64 75 6c 65 20 2a 29 73 71 6c 69  er_module *)sqli
1fc0: 74 65 33 46 74 73 33 48 61 73 68 46 69 6e 64 28  te3Fts3HashFind(
1fd0: 70 48 61 73 68 2c 20 7a 4e 61 6d 65 2c 20 6e 4e  pHash, zName, nN
1fe0: 61 6d 65 2b 31 29 3b 0a 0a 20 20 69 66 28 20 21  ame+1);..  if( !
1ff0: 70 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  p ){.    char *z
2000: 45 72 72 32 20 3d 20 73 71 6c 69 74 65 33 5f 6d  Err2 = sqlite3_m
2010: 70 72 69 6e 74 66 28 22 75 6e 6b 6e 6f 77 6e 20  printf("unknown 
2020: 74 6f 6b 65 6e 69 7a 65 72 3a 20 25 73 22 2c 20  tokenizer: %s", 
2030: 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 73 71 6c 69  zName);.    sqli
2040: 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72  te3_result_error
2050: 28 63 6f 6e 74 65 78 74 2c 20 7a 45 72 72 32 2c  (context, zErr2,
2060: 20 2d 31 29 3b 0a 20 20 20 20 73 71 6c 69 74 65   -1);.    sqlite
2070: 33 5f 66 72 65 65 28 7a 45 72 72 32 29 3b 0a 20  3_free(zErr2);. 
2080: 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a     return;.  }..
2090: 20 20 70 52 65 74 20 3d 20 54 63 6c 5f 4e 65 77    pRet = Tcl_New
20a0: 4f 62 6a 28 29 3b 0a 20 20 54 63 6c 5f 49 6e 63  Obj();.  Tcl_Inc
20b0: 72 52 65 66 43 6f 75 6e 74 28 70 52 65 74 29 3b  rRefCount(pRet);
20c0: 0a 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 61  ..  for(i=1; i<a
20d0: 72 67 63 2d 31 3b 20 69 2b 2b 29 7b 0a 20 20 20  rgc-1; i++){.   
20e0: 20 61 7a 41 72 67 5b 69 2d 31 5d 20 3d 20 28 63   azArg[i-1] = (c
20f0: 6f 6e 73 74 20 63 68 61 72 20 2a 29 73 71 6c 69  onst char *)sqli
2100: 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61  te3_value_text(a
2110: 72 67 76 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20  rgv[i]);.  }..  
2120: 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 21 3d 70  if( SQLITE_OK!=p
2130: 2d 3e 78 43 72 65 61 74 65 28 61 72 67 63 2d 32  ->xCreate(argc-2
2140: 2c 20 61 7a 41 72 67 2c 20 26 70 54 6f 6b 65 6e  , azArg, &pToken
2150: 69 7a 65 72 29 20 29 7b 0a 20 20 20 20 7a 45 72  izer) ){.    zEr
2160: 72 20 3d 20 22 65 72 72 6f 72 20 69 6e 20 78 43  r = "error in xC
2170: 72 65 61 74 65 28 29 22 3b 0a 20 20 20 20 67 6f  reate()";.    go
2180: 74 6f 20 66 69 6e 69 73 68 3b 0a 20 20 7d 0a 20  to finish;.  }. 
2190: 20 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e 70 4d 6f   pTokenizer->pMo
21a0: 64 75 6c 65 20 3d 20 70 3b 0a 20 20 69 66 28 20  dule = p;.  if( 
21b0: 73 71 6c 69 74 65 33 46 74 73 33 4f 70 65 6e 54  sqlite3Fts3OpenT
21c0: 6f 6b 65 6e 69 7a 65 72 28 70 54 6f 6b 65 6e 69  okenizer(pTokeni
21d0: 7a 65 72 2c 20 30 2c 20 7a 49 6e 70 75 74 2c 20  zer, 0, zInput, 
21e0: 6e 49 6e 70 75 74 2c 20 26 70 43 73 72 29 20 29  nInput, &pCsr) )
21f0: 7b 0a 20 20 20 20 7a 45 72 72 20 3d 20 22 65 72  {.    zErr = "er
2200: 72 6f 72 20 69 6e 20 78 4f 70 65 6e 28 29 22 3b  ror in xOpen()";
2210: 0a 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73 68  .    goto finish
2220: 3b 0a 20 20 7d 0a 0a 20 20 77 68 69 6c 65 28 20  ;.  }..  while( 
2230: 53 51 4c 49 54 45 5f 4f 4b 3d 3d 70 2d 3e 78 4e  SQLITE_OK==p->xN
2240: 65 78 74 28 70 43 73 72 2c 20 26 7a 54 6f 6b 65  ext(pCsr, &zToke
2250: 6e 2c 20 26 6e 54 6f 6b 65 6e 2c 20 26 69 53 74  n, &nToken, &iSt
2260: 61 72 74 2c 20 26 69 45 6e 64 2c 20 26 69 50 6f  art, &iEnd, &iPo
2270: 73 29 20 29 7b 0a 20 20 20 20 54 63 6c 5f 4c 69  s) ){.    Tcl_Li
2280: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
2290: 6e 74 28 30 2c 20 70 52 65 74 2c 20 54 63 6c 5f  nt(0, pRet, Tcl_
22a0: 4e 65 77 49 6e 74 4f 62 6a 28 69 50 6f 73 29 29  NewIntObj(iPos))
22b0: 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62  ;.    Tcl_ListOb
22c0: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30  jAppendElement(0
22d0: 2c 20 70 52 65 74 2c 20 54 63 6c 5f 4e 65 77 53  , pRet, Tcl_NewS
22e0: 74 72 69 6e 67 4f 62 6a 28 7a 54 6f 6b 65 6e 2c  tringObj(zToken,
22f0: 20 6e 54 6f 6b 65 6e 29 29 3b 0a 20 20 20 20 7a   nToken));.    z
2300: 54 6f 6b 65 6e 20 3d 20 26 7a 49 6e 70 75 74 5b  Token = &zInput[
2310: 69 53 74 61 72 74 5d 3b 0a 20 20 20 20 6e 54 6f  iStart];.    nTo
2320: 6b 65 6e 20 3d 20 69 45 6e 64 2d 69 53 74 61 72  ken = iEnd-iStar
2330: 74 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f  t;.    Tcl_ListO
2340: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
2350: 30 2c 20 70 52 65 74 2c 20 54 63 6c 5f 4e 65 77  0, pRet, Tcl_New
2360: 53 74 72 69 6e 67 4f 62 6a 28 7a 54 6f 6b 65 6e  StringObj(zToken
2370: 2c 20 6e 54 6f 6b 65 6e 29 29 3b 0a 20 20 7d 0a  , nToken));.  }.
2380: 0a 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b  .  if( SQLITE_OK
2390: 21 3d 70 2d 3e 78 43 6c 6f 73 65 28 70 43 73 72  !=p->xClose(pCsr
23a0: 29 20 29 7b 0a 20 20 20 20 7a 45 72 72 20 3d 20  ) ){.    zErr = 
23b0: 22 65 72 72 6f 72 20 69 6e 20 78 43 6c 6f 73 65  "error in xClose
23c0: 28 29 22 3b 0a 20 20 20 20 67 6f 74 6f 20 66 69  ()";.    goto fi
23d0: 6e 69 73 68 3b 0a 20 20 7d 0a 20 20 69 66 28 20  nish;.  }.  if( 
23e0: 53 51 4c 49 54 45 5f 4f 4b 21 3d 70 2d 3e 78 44  SQLITE_OK!=p->xD
23f0: 65 73 74 72 6f 79 28 70 54 6f 6b 65 6e 69 7a 65  estroy(pTokenize
2400: 72 29 20 29 7b 0a 20 20 20 20 7a 45 72 72 20 3d  r) ){.    zErr =
2410: 20 22 65 72 72 6f 72 20 69 6e 20 78 44 65 73 74   "error in xDest
2420: 72 6f 79 28 29 22 3b 0a 20 20 20 20 67 6f 74 6f  roy()";.    goto
2430: 20 66 69 6e 69 73 68 3b 0a 20 20 7d 0a 0a 66 69   finish;.  }..fi
2440: 6e 69 73 68 3a 0a 20 20 69 66 28 20 7a 45 72 72  nish:.  if( zErr
2450: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
2460: 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 63 6f 6e  result_error(con
2470: 74 65 78 74 2c 20 7a 45 72 72 2c 20 2d 31 29 3b  text, zErr, -1);
2480: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71  .  }else{.    sq
2490: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78  lite3_result_tex
24a0: 74 28 63 6f 6e 74 65 78 74 2c 20 54 63 6c 5f 47  t(context, Tcl_G
24b0: 65 74 53 74 72 69 6e 67 28 70 52 65 74 29 2c 20  etString(pRet), 
24c0: 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53  -1, SQLITE_TRANS
24d0: 49 45 4e 54 29 3b 0a 20 20 7d 0a 20 20 54 63 6c  IENT);.  }.  Tcl
24e0: 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70 52  _DecrRefCount(pR
24f0: 65 74 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53  et);.}..#ifdef S
2500: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53  QLITE_ENABLE_FTS
2510: 33 5f 54 4f 4b 45 4e 49 5a 45 52 0a 73 74 61 74  3_TOKENIZER.stat
2520: 69 63 0a 69 6e 74 20 72 65 67 69 73 74 65 72 54  ic.int registerT
2530: 6f 6b 65 6e 69 7a 65 72 28 0a 20 20 73 71 6c 69  okenizer(.  sqli
2540: 74 65 33 20 2a 64 62 2c 20 0a 20 20 63 68 61 72  te3 *db, .  char
2550: 20 2a 7a 4e 61 6d 65 2c 20 0a 20 20 63 6f 6e 73   *zName, .  cons
2560: 74 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69  t sqlite3_tokeni
2570: 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a 70 0a 29 7b  zer_module *p.){
2580: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c  .  int rc;.  sql
2590: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
25a0: 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 7a  ;.  const char z
25b0: 53 71 6c 5b 5d 20 3d 20 22 53 45 4c 45 43 54 20  Sql[] = "SELECT 
25c0: 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 28 3f  fts3_tokenizer(?
25d0: 2c 20 3f 29 22 3b 0a 0a 20 20 72 63 20 3d 20 73  , ?)";..  rc = s
25e0: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76  qlite3_prepare_v
25f0: 32 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20  2(db, zSql, -1, 
2600: 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 69 66  &pStmt, 0);.  if
2610: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
2620: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  ){.    return rc
2630: 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  ;.  }..  sqlite3
2640: 5f 62 69 6e 64 5f 74 65 78 74 28 70 53 74 6d 74  _bind_text(pStmt
2650: 2c 20 31 2c 20 7a 4e 61 6d 65 2c 20 2d 31 2c 20  , 1, zName, -1, 
2660: 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a  SQLITE_STATIC);.
2670: 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 62    sqlite3_bind_b
2680: 6c 6f 62 28 70 53 74 6d 74 2c 20 32 2c 20 26 70  lob(pStmt, 2, &p
2690: 2c 20 73 69 7a 65 6f 66 28 70 29 2c 20 53 51 4c  , sizeof(p), SQL
26a0: 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 73  ITE_STATIC);.  s
26b0: 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d  qlite3_step(pStm
26c0: 74 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 73 71  t);..  return sq
26d0: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
26e0: 53 74 6d 74 29 3b 0a 7d 0a 23 65 6e 64 69 66 20  Stmt);.}.#endif 
26f0: 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45  /* SQLITE_ENABLE
2700: 5f 46 54 53 33 5f 54 4f 4b 45 4e 49 5a 45 52 20  _FTS3_TOKENIZER 
2710: 2a 2f 0a 0a 0a 73 74 61 74 69 63 0a 69 6e 74 20  */...static.int 
2720: 71 75 65 72 79 54 6f 6b 65 6e 69 7a 65 72 28 0a  queryTokenizer(.
2730: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a    sqlite3 *db, .
2740: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20    char *zName,  
2750: 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33  .  const sqlite3
2760: 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c  _tokenizer_modul
2770: 65 20 2a 2a 70 70 0a 29 7b 0a 20 20 69 6e 74 20  e **pp.){.  int 
2780: 72 63 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  rc;.  sqlite3_st
2790: 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20 63 6f 6e  mt *pStmt;.  con
27a0: 73 74 20 63 68 61 72 20 7a 53 71 6c 5b 5d 20 3d  st char zSql[] =
27b0: 20 22 53 45 4c 45 43 54 20 66 74 73 33 5f 74 6f   "SELECT fts3_to
27c0: 6b 65 6e 69 7a 65 72 28 3f 29 22 3b 0a 0a 20 20  kenizer(?)";..  
27d0: 2a 70 70 20 3d 20 30 3b 0a 20 20 72 63 20 3d 20  *pp = 0;.  rc = 
27e0: 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f  sqlite3_prepare_
27f0: 76 32 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c  v2(db, zSql, -1,
2800: 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 69   &pStmt, 0);.  i
2810: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
2820: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72   ){.    return r
2830: 63 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65  c;.  }..  sqlite
2840: 33 5f 62 69 6e 64 5f 74 65 78 74 28 70 53 74 6d  3_bind_text(pStm
2850: 74 2c 20 31 2c 20 7a 4e 61 6d 65 2c 20 2d 31 2c  t, 1, zName, -1,
2860: 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b   SQLITE_STATIC);
2870: 0a 20 20 69 66 28 20 53 51 4c 49 54 45 5f 52 4f  .  if( SQLITE_RO
2880: 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28  W==sqlite3_step(
2890: 70 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 69 66  pStmt) ){.    if
28a0: 28 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  ( sqlite3_column
28b0: 5f 74 79 70 65 28 70 53 74 6d 74 2c 20 30 29 3d  _type(pStmt, 0)=
28c0: 3d 53 51 4c 49 54 45 5f 42 4c 4f 42 20 29 7b 0a  =SQLITE_BLOB ){.
28d0: 20 20 20 20 20 20 6d 65 6d 63 70 79 28 28 76 6f        memcpy((vo
28e0: 69 64 20 2a 29 70 70 2c 20 73 71 6c 69 74 65 33  id *)pp, sqlite3
28f0: 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28 70 53 74  _column_blob(pSt
2900: 6d 74 2c 20 30 29 2c 20 73 69 7a 65 6f 66 28 2a  mt, 0), sizeof(*
2910: 70 70 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  pp));.    }.  }.
2920: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
2930: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
2940: 29 3b 0a 7d 0a 0a 76 6f 69 64 20 73 71 6c 69 74  );.}..void sqlit
2950: 65 33 46 74 73 33 53 69 6d 70 6c 65 54 6f 6b 65  e3Fts3SimpleToke
2960: 6e 69 7a 65 72 4d 6f 64 75 6c 65 28 73 71 6c 69  nizerModule(sqli
2970: 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f  te3_tokenizer_mo
2980: 64 75 6c 65 20 63 6f 6e 73 74 2a 2a 70 70 4d 6f  dule const**ppMo
2990: 64 75 6c 65 29 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6d  dule);../*.** Im
29a0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
29b0: 74 68 65 20 73 63 61 6c 61 72 20 66 75 6e 63 74  the scalar funct
29c0: 69 6f 6e 20 66 74 73 33 5f 74 6f 6b 65 6e 69 7a  ion fts3_tokeniz
29d0: 65 72 5f 69 6e 74 65 72 6e 61 6c 5f 74 65 73 74  er_internal_test
29e0: 28 29 2e 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ()..** This func
29f0: 74 69 6f 6e 20 69 73 20 75 73 65 64 20 66 6f 72  tion is used for
2a00: 20 74 65 73 74 69 6e 67 20 6f 6e 6c 79 2c 20 69   testing only, i
2a10: 74 20 69 73 20 6e 6f 74 20 69 6e 63 6c 75 64 65  t is not include
2a20: 64 20 69 6e 20 74 68 65 0a 2a 2a 20 62 75 69 6c  d in the.** buil
2a30: 64 20 75 6e 6c 65 73 73 20 53 51 4c 49 54 45 5f  d unless SQLITE_
2a40: 54 45 53 54 20 69 73 20 64 65 66 69 6e 65 64 2e  TEST is defined.
2a50: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 75 72 70 6f  .**.** The purpo
2a60: 73 65 20 6f 66 20 74 68 69 73 20 69 73 20 74 6f  se of this is to
2a70: 20 74 65 73 74 20 74 68 61 74 20 74 68 65 20 66   test that the f
2a80: 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 28 29 20  ts3_tokenizer() 
2a90: 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 63 61 6e 20  function.** can 
2aa0: 62 65 20 75 73 65 64 20 61 73 20 64 65 73 69 67  be used as desig
2ab0: 6e 65 64 20 62 79 20 74 68 65 20 43 2d 63 6f 64  ned by the C-cod
2ac0: 65 20 69 6e 20 74 68 65 20 71 75 65 72 79 54 6f  e in the queryTo
2ad0: 6b 65 6e 69 7a 65 72 20 61 6e 64 0a 2a 2a 20 72  kenizer and.** r
2ae0: 65 67 69 73 74 65 72 54 6f 6b 65 6e 69 7a 65 72  egisterTokenizer
2af0: 28 29 20 66 75 6e 63 74 69 6f 6e 73 20 61 62 6f  () functions abo
2b00: 76 65 2e 20 54 68 65 73 65 20 74 77 6f 20 66 75  ve. These two fu
2b10: 6e 63 74 69 6f 6e 73 20 61 72 65 20 72 65 70 65  nctions are repe
2b20: 61 74 65 64 0a 2a 2a 20 69 6e 20 74 68 65 20 52  ated.** in the R
2b30: 45 41 44 4d 45 2e 74 6f 6b 65 6e 69 7a 65 72 20  EADME.tokenizer 
2b40: 66 69 6c 65 20 61 73 20 61 6e 20 65 78 61 6d 70  file as an examp
2b50: 6c 65 2c 20 73 6f 20 69 74 20 69 73 20 69 6d 70  le, so it is imp
2b60: 6f 72 74 61 6e 74 20 74 6f 0a 2a 2a 20 74 65 73  ortant to.** tes
2b70: 74 20 74 68 65 6d 2e 0a 2a 2a 0a 2a 2a 20 54 6f  t them..**.** To
2b80: 20 72 75 6e 20 74 68 65 20 74 65 73 74 73 2c 20   run the tests, 
2b90: 65 76 61 6c 75 61 74 65 20 74 68 65 20 66 74 73  evaluate the fts
2ba0: 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 69 6e 74 65  3_tokenizer_inte
2bb0: 72 6e 61 6c 5f 74 65 73 74 28 29 20 73 63 61 6c  rnal_test() scal
2bc0: 61 72 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 77  ar.** function w
2bd0: 69 74 68 20 6e 6f 20 61 72 67 75 6d 65 6e 74 73  ith no arguments
2be0: 2e 20 41 6e 20 61 73 73 65 72 74 28 29 20 77 69  . An assert() wi
2bf0: 6c 6c 20 66 61 69 6c 20 69 66 20 61 20 70 72 6f  ll fail if a pro
2c00: 62 6c 65 6d 20 69 73 0a 2a 2a 20 64 65 74 65 63  blem is.** detec
2c10: 74 65 64 2e 20 69 2e 65 2e 3a 0a 2a 2a 0a 2a 2a  ted. i.e.:.**.**
2c20: 20 20 20 20 20 53 45 4c 45 43 54 20 66 74 73 33       SELECT fts3
2c30: 5f 74 6f 6b 65 6e 69 7a 65 72 5f 69 6e 74 65 72  _tokenizer_inter
2c40: 6e 61 6c 5f 74 65 73 74 28 29 3b 0a 2a 2a 0a 2a  nal_test();.**.*
2c50: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 69 6e  /.static void in
2c60: 74 54 65 73 74 46 75 6e 63 28 0a 20 20 73 71 6c  tTestFunc(.  sql
2c70: 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f  ite3_context *co
2c80: 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67  ntext,.  int arg
2c90: 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  c,.  sqlite3_val
2ca0: 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 69  ue **argv.){.  i
2cb0: 6e 74 20 72 63 3b 0a 20 20 63 6f 6e 73 74 20 73  nt rc;.  const s
2cc0: 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72  qlite3_tokenizer
2cd0: 5f 6d 6f 64 75 6c 65 20 2a 70 31 3b 0a 20 20 63  _module *p1;.  c
2ce0: 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 74 6f 6b  onst sqlite3_tok
2cf0: 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a 70  enizer_module *p
2d00: 32 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  2;.  sqlite3 *db
2d10: 20 3d 20 28 73 71 6c 69 74 65 33 20 2a 29 73 71   = (sqlite3 *)sq
2d20: 6c 69 74 65 33 5f 75 73 65 72 5f 64 61 74 61 28  lite3_user_data(
2d30: 63 6f 6e 74 65 78 74 29 3b 0a 0a 20 20 55 4e 55  context);..  UNU
2d40: 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 61 72  SED_PARAMETER(ar
2d50: 67 63 29 3b 0a 20 20 55 4e 55 53 45 44 5f 50 41  gc);.  UNUSED_PA
2d60: 52 41 4d 45 54 45 52 28 61 72 67 76 29 3b 0a 0a  RAMETER(argv);..
2d70: 20 20 2f 2a 20 54 65 73 74 20 74 68 65 20 71 75    /* Test the qu
2d80: 65 72 79 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a  ery function */.
2d90: 20 20 73 71 6c 69 74 65 33 46 74 73 33 53 69 6d    sqlite3Fts3Sim
2da0: 70 6c 65 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  pleTokenizerModu
2db0: 6c 65 28 26 70 31 29 3b 0a 20 20 72 63 20 3d 20  le(&p1);.  rc = 
2dc0: 71 75 65 72 79 54 6f 6b 65 6e 69 7a 65 72 28 64  queryTokenizer(d
2dd0: 62 2c 20 22 73 69 6d 70 6c 65 22 2c 20 26 70 32  b, "simple", &p2
2de0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d  );.  assert( rc=
2df0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
2e00: 61 73 73 65 72 74 28 20 70 31 3d 3d 70 32 20 29  assert( p1==p2 )
2e10: 3b 0a 20 20 72 63 20 3d 20 71 75 65 72 79 54 6f  ;.  rc = queryTo
2e20: 6b 65 6e 69 7a 65 72 28 64 62 2c 20 22 6e 6f 73  kenizer(db, "nos
2e30: 75 63 68 74 6f 6b 65 6e 69 7a 65 72 22 2c 20 26  uchtokenizer", &
2e40: 70 32 29 3b 0a 20 20 61 73 73 65 72 74 28 20 72  p2);.  assert( r
2e50: 63 3d 3d 53 51 4c 49 54 45 5f 45 52 52 4f 52 20  c==SQLITE_ERROR 
2e60: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 32 3d  );.  assert( p2=
2e70: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
2e80: 30 3d 3d 73 74 72 63 6d 70 28 73 71 6c 69 74 65  0==strcmp(sqlite
2e90: 33 5f 65 72 72 6d 73 67 28 64 62 29 2c 20 22 75  3_errmsg(db), "u
2ea0: 6e 6b 6e 6f 77 6e 20 74 6f 6b 65 6e 69 7a 65 72  nknown tokenizer
2eb0: 3a 20 6e 6f 73 75 63 68 74 6f 6b 65 6e 69 7a 65  : nosuchtokenize
2ec0: 72 22 29 20 29 3b 0a 0a 20 20 2f 2a 20 54 65 73  r") );..  /* Tes
2ed0: 74 20 74 68 65 20 73 74 6f 72 61 67 65 20 66 75  t the storage fu
2ee0: 6e 63 74 69 6f 6e 20 2a 2f 0a 23 69 66 64 65 66  nction */.#ifdef
2ef0: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46   SQLITE_ENABLE_F
2f00: 54 53 33 5f 54 4f 4b 45 4e 49 5a 45 52 0a 20 20  TS3_TOKENIZER.  
2f10: 72 63 20 3d 20 72 65 67 69 73 74 65 72 54 6f 6b  rc = registerTok
2f20: 65 6e 69 7a 65 72 28 64 62 2c 20 22 6e 6f 73 75  enizer(db, "nosu
2f30: 63 68 74 6f 6b 65 6e 69 7a 65 72 22 2c 20 70 31  chtokenizer", p1
2f40: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d  );.  assert( rc=
2f50: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
2f60: 72 63 20 3d 20 71 75 65 72 79 54 6f 6b 65 6e 69  rc = queryTokeni
2f70: 7a 65 72 28 64 62 2c 20 22 6e 6f 73 75 63 68 74  zer(db, "nosucht
2f80: 6f 6b 65 6e 69 7a 65 72 22 2c 20 26 70 32 29 3b  okenizer", &p2);
2f90: 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53  .  assert( rc==S
2fa0: 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 61 73  QLITE_OK );.  as
2fb0: 73 65 72 74 28 20 70 32 3d 3d 70 31 20 29 3b 0a  sert( p2==p1 );.
2fc0: 23 65 6e 64 69 66 0a 0a 20 20 73 71 6c 69 74 65  #endif..  sqlite
2fd0: 33 5f 72 65 73 75 6c 74 5f 74 65 78 74 28 63 6f  3_result_text(co
2fe0: 6e 74 65 78 74 2c 20 22 6f 6b 22 2c 20 2d 31 2c  ntext, "ok", -1,
2ff0: 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b   SQLITE_STATIC);
3000: 0a 7d 0a 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a  .}..#endif../*.*
3010: 2a 20 53 65 74 20 75 70 20 53 51 4c 20 6f 62 6a  * Set up SQL obj
3020: 65 63 74 73 20 69 6e 20 64 61 74 61 62 61 73 65  ects in database
3030: 20 64 62 20 75 73 65 64 20 74 6f 20 61 63 63 65   db used to acce
3040: 73 73 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  ss the contents 
3050: 6f 66 0a 2a 2a 20 74 68 65 20 68 61 73 68 20 74  of.** the hash t
3060: 61 62 6c 65 20 70 6f 69 6e 74 65 64 20 74 6f 20  able pointed to 
3070: 62 79 20 61 72 67 75 6d 65 6e 74 20 70 48 61 73  by argument pHas
3080: 68 2e 20 54 68 65 20 68 61 73 68 20 74 61 62 6c  h. The hash tabl
3090: 65 20 6d 75 73 74 0a 2a 2a 20 62 65 65 6e 20 69  e must.** been i
30a0: 6e 69 74 69 61 6c 69 7a 65 64 20 74 6f 20 75 73  nitialized to us
30b0: 65 20 73 74 72 69 6e 67 20 6b 65 79 73 2c 20 61  e string keys, a
30c0: 6e 64 20 74 6f 20 74 61 6b 65 20 61 20 70 72 69  nd to take a pri
30d0: 76 61 74 65 20 63 6f 70 79 20 0a 2a 2a 20 6f 66  vate copy .** of
30e0: 20 74 68 65 20 6b 65 79 20 77 68 65 6e 20 61 20   the key when a 
30f0: 76 61 6c 75 65 20 69 73 20 69 6e 73 65 72 74 65  value is inserte
3100: 64 2e 20 69 2e 65 2e 20 62 79 20 61 20 63 61 6c  d. i.e. by a cal
3110: 6c 20 73 69 6d 69 6c 61 72 20 74 6f 3a 0a 2a 2a  l similar to:.**
3120: 0a 2a 2a 20 20 20 20 73 71 6c 69 74 65 33 46 74  .**    sqlite3Ft
3130: 73 33 48 61 73 68 49 6e 69 74 28 70 48 61 73 68  s3HashInit(pHash
3140: 2c 20 46 54 53 33 5f 48 41 53 48 5f 53 54 52 49  , FTS3_HASH_STRI
3150: 4e 47 2c 20 31 29 3b 0a 2a 2a 0a 2a 2a 20 54 68  NG, 1);.**.** Th
3160: 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 64 64 73  is function adds
3170: 20 61 20 73 63 61 6c 61 72 20 66 75 6e 63 74 69   a scalar functi
3180: 6f 6e 20 28 73 65 65 20 68 65 61 64 65 72 20 63  on (see header c
3190: 6f 6d 6d 65 6e 74 20 61 62 6f 76 65 0a 2a 2a 20  omment above.** 
31a0: 73 63 61 6c 61 72 46 75 6e 63 28 29 20 69 6e 20  scalarFunc() in 
31b0: 74 68 69 73 20 66 69 6c 65 20 66 6f 72 20 64 65  this file for de
31c0: 74 61 69 6c 73 29 20 61 6e 64 2c 20 69 66 20 45  tails) and, if E
31d0: 4e 41 42 4c 45 5f 54 41 42 4c 45 20 69 73 0a 2a  NABLE_TABLE is.*
31e0: 2a 20 64 65 66 69 6e 65 64 20 61 74 20 63 6f 6d  * defined at com
31f0: 70 69 6c 61 74 69 6f 6e 20 74 69 6d 65 2c 20 61  pilation time, a
3200: 20 74 65 6d 70 6f 72 61 72 79 20 76 69 72 74 75   temporary virtu
3210: 61 6c 20 74 61 62 6c 65 20 28 73 65 65 20 68 65  al table (see he
3220: 61 64 65 72 20 0a 2a 2a 20 63 6f 6d 6d 65 6e 74  ader .** comment
3230: 20 61 62 6f 76 65 20 73 74 72 75 63 74 20 48 61   above struct Ha
3240: 73 68 54 61 62 6c 65 56 74 61 62 29 20 74 6f 20  shTableVtab) to 
3250: 74 68 65 20 64 61 74 61 62 61 73 65 20 73 63 68  the database sch
3260: 65 6d 61 2e 20 42 6f 74 68 20 0a 2a 2a 20 70 72  ema. Both .** pr
3270: 6f 76 69 64 65 20 72 65 61 64 2f 77 72 69 74 65  ovide read/write
3280: 20 61 63 63 65 73 73 20 74 6f 20 74 68 65 20 63   access to the c
3290: 6f 6e 74 65 6e 74 73 20 6f 66 20 2a 70 48 61 73  ontents of *pHas
32a0: 68 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 74 68 69  h..**.** The thi
32b0: 72 64 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 74  rd argument to t
32c0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 2c 20 7a 4e  his function, zN
32d0: 61 6d 65 2c 20 69 73 20 75 73 65 64 20 61 73 20  ame, is used as 
32e0: 74 68 65 20 6e 61 6d 65 0a 2a 2a 20 6f 66 20 62  the name.** of b
32f0: 6f 74 68 20 74 68 65 20 73 63 61 6c 61 72 20 61  oth the scalar a
3300: 6e 64 2c 20 69 66 20 63 72 65 61 74 65 64 2c 20  nd, if created, 
3310: 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c  the virtual tabl
3320: 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
3330: 33 46 74 73 33 49 6e 69 74 48 61 73 68 54 61 62  3Fts3InitHashTab
3340: 6c 65 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  le(.  sqlite3 *d
3350: 62 2c 20 0a 20 20 46 74 73 33 48 61 73 68 20 2a  b, .  Fts3Hash *
3360: 70 48 61 73 68 2c 20 0a 20 20 63 6f 6e 73 74 20  pHash, .  const 
3370: 63 68 61 72 20 2a 7a 4e 61 6d 65 0a 29 7b 0a 20  char *zName.){. 
3380: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
3390: 5f 4f 4b 3b 0a 20 20 76 6f 69 64 20 2a 70 20 3d  _OK;.  void *p =
33a0: 20 28 76 6f 69 64 20 2a 29 70 48 61 73 68 3b 0a   (void *)pHash;.
33b0: 20 20 63 6f 6e 73 74 20 69 6e 74 20 61 6e 79 20    const int any 
33c0: 3d 20 53 51 4c 49 54 45 5f 41 4e 59 3b 0a 0a 23  = SQLITE_ANY;..#
33d0: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45 53  ifdef SQLITE_TES
33e0: 54 0a 20 20 63 68 61 72 20 2a 7a 54 65 73 74 20  T.  char *zTest 
33f0: 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 54 65  = 0;.  char *zTe
3400: 73 74 32 20 3d 20 30 3b 0a 20 20 76 6f 69 64 20  st2 = 0;.  void 
3410: 2a 70 64 62 20 3d 20 28 76 6f 69 64 20 2a 29 64  *pdb = (void *)d
3420: 62 3b 0a 20 20 7a 54 65 73 74 20 3d 20 73 71 6c  b;.  zTest = sql
3430: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73  ite3_mprintf("%s
3440: 5f 74 65 73 74 22 2c 20 7a 4e 61 6d 65 29 3b 0a  _test", zName);.
3450: 20 20 7a 54 65 73 74 32 20 3d 20 73 71 6c 69 74    zTest2 = sqlit
3460: 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 5f 69  e3_mprintf("%s_i
3470: 6e 74 65 72 6e 61 6c 5f 74 65 73 74 22 2c 20 7a  nternal_test", z
3480: 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20 21 7a 54  Name);.  if( !zT
3490: 65 73 74 20 7c 7c 20 21 7a 54 65 73 74 32 20 29  est || !zTest2 )
34a0: 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  {.    rc = SQLIT
34b0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 23 65 6e  E_NOMEM;.  }.#en
34c0: 64 69 66 0a 0a 20 20 69 66 28 20 53 51 4c 49 54  dif..  if( SQLIT
34d0: 45 5f 4f 4b 3d 3d 72 63 20 29 7b 0a 20 20 20 20  E_OK==rc ){.    
34e0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65  rc = sqlite3_cre
34f0: 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c  ate_function(db,
3500: 20 7a 4e 61 6d 65 2c 20 31 2c 20 61 6e 79 2c 20   zName, 1, any, 
3510: 70 2c 20 73 63 61 6c 61 72 46 75 6e 63 2c 20 30  p, scalarFunc, 0
3520: 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  , 0);.  }.  if( 
3530: 53 51 4c 49 54 45 5f 4f 4b 3d 3d 72 63 20 29 7b  SQLITE_OK==rc ){
3540: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
3550: 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f  3_create_functio
3560: 6e 28 64 62 2c 20 7a 4e 61 6d 65 2c 20 32 2c 20  n(db, zName, 2, 
3570: 61 6e 79 2c 20 70 2c 20 73 63 61 6c 61 72 46 75  any, p, scalarFu
3580: 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 23  nc, 0, 0);.  }.#
3590: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45 53  ifdef SQLITE_TES
35a0: 54 0a 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4f  T.  if( SQLITE_O
35b0: 4b 3d 3d 72 63 20 29 7b 0a 20 20 20 20 72 63 20  K==rc ){.    rc 
35c0: 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65  = sqlite3_create
35d0: 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20 7a 54  _function(db, zT
35e0: 65 73 74 2c 20 2d 31 2c 20 61 6e 79 2c 20 70 2c  est, -1, any, p,
35f0: 20 74 65 73 74 46 75 6e 63 2c 20 30 2c 20 30 29   testFunc, 0, 0)
3600: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 53 51 4c 49  ;.  }.  if( SQLI
3610: 54 45 5f 4f 4b 3d 3d 72 63 20 29 7b 0a 20 20 20  TE_OK==rc ){.   
3620: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72   rc = sqlite3_cr
3630: 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62  eate_function(db
3640: 2c 20 7a 54 65 73 74 32 2c 20 30 2c 20 61 6e 79  , zTest2, 0, any
3650: 2c 20 70 64 62 2c 20 69 6e 74 54 65 73 74 46 75  , pdb, intTestFu
3660: 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 23  nc, 0, 0);.  }.#
3670: 65 6e 64 69 66 0a 0a 23 69 66 64 65 66 20 53 51  endif..#ifdef SQ
3680: 4c 49 54 45 5f 54 45 53 54 0a 20 20 73 71 6c 69  LITE_TEST.  sqli
3690: 74 65 33 5f 66 72 65 65 28 7a 54 65 73 74 29 3b  te3_free(zTest);
36a0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
36b0: 7a 54 65 73 74 32 29 3b 0a 23 65 6e 64 69 66 0a  zTest2);.#endif.
36c0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
36d0: 0a 23 65 6e 64 69 66 20 2f 2a 20 21 64 65 66 69  .#endif /* !defi
36e0: 6e 65 64 28 53 51 4c 49 54 45 5f 43 4f 52 45 29  ned(SQLITE_CORE)
36f0: 20 7c 7c 20 64 65 66 69 6e 65 64 28 53 51 4c 49   || defined(SQLI
3700: 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53 33 29 20  TE_ENABLE_FTS3) 
3710: 2a 2f 0a                                         */.