/ Hex Artifact Content
Login

Artifact e0a8b81383ea60d0334d274fadf305ea14a8c314:


0000: 0a 31 2e 20 46 54 53 33 20 54 6f 6b 65 6e 69 7a  .1. FTS3 Tokeniz
0010: 65 72 73 0a 0a 20 20 57 68 65 6e 20 63 72 65 61  ers..  When crea
0020: 74 69 6e 67 20 61 20 6e 65 77 20 66 75 6c 6c 2d  ting a new full-
0030: 74 65 78 74 20 74 61 62 6c 65 2c 20 46 54 53 33  text table, FTS3
0040: 20 61 6c 6c 6f 77 73 20 74 68 65 20 75 73 65 72   allows the user
0050: 20 74 6f 20 73 65 6c 65 63 74 0a 20 20 74 68 65   to select.  the
0060: 20 74 65 78 74 20 74 6f 6b 65 6e 69 7a 65 72 20   text tokenizer 
0070: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 74  implementation t
0080: 6f 20 62 65 20 75 73 65 64 20 77 68 65 6e 20 69  o be used when i
0090: 6e 64 65 78 69 6e 67 20 74 65 78 74 0a 20 20 62  ndexing text.  b
00a0: 79 20 73 70 65 63 69 66 79 69 6e 67 20 61 20 22  y specifying a "
00b0: 74 6f 6b 65 6e 69 7a 65 22 20 63 6c 61 75 73 65  tokenize" clause
00c0: 20 61 73 20 70 61 72 74 20 6f 66 20 74 68 65 20   as part of the 
00d0: 43 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54  CREATE VIRTUAL T
00e0: 41 42 4c 45 0a 20 20 73 74 61 74 65 6d 65 6e 74  ABLE.  statement
00f0: 3a 0a 0a 20 20 20 20 43 52 45 41 54 45 20 56 49  :..    CREATE VI
0100: 52 54 55 41 4c 20 54 41 42 4c 45 20 3c 74 61 62  RTUAL TABLE <tab
0110: 6c 65 2d 6e 61 6d 65 3e 20 55 53 49 4e 47 20 66  le-name> USING f
0120: 74 73 33 28 0a 20 20 20 20 20 20 3c 63 6f 6c 75  ts3(.      <colu
0130: 6d 6e 73 20 2e 2e 2e 3e 20 5b 2c 20 74 6f 6b 65  mns ...> [, toke
0140: 6e 69 7a 65 20 3c 74 6f 6b 65 6e 69 7a 65 72 2d  nize <tokenizer-
0150: 6e 61 6d 65 3e 20 5b 3c 74 6f 6b 65 6e 69 7a 65  name> [<tokenize
0160: 72 2d 61 72 67 73 3e 5d 5d 0a 20 20 20 20 29 3b  r-args>]].    );
0170: 0a 0a 20 20 54 68 65 20 62 75 69 6c 74 2d 69 6e  ..  The built-in
0180: 20 74 6f 6b 65 6e 69 7a 65 72 73 20 28 76 61 6c   tokenizers (val
0190: 69 64 20 76 61 6c 75 65 73 20 74 6f 20 70 61 73  id values to pas
01a0: 73 20 61 73 20 3c 74 6f 6b 65 6e 69 7a 65 72 20  s as <tokenizer 
01b0: 6e 61 6d 65 3e 29 20 61 72 65 0a 20 20 22 73 69  name>) are.  "si
01c0: 6d 70 6c 65 22 2c 20 22 70 6f 72 74 65 72 22 20  mple", "porter" 
01d0: 61 6e 64 20 22 75 6e 69 63 6f 64 65 22 2e 0a 0a  and "unicode"...
01e0: 20 20 3c 74 6f 6b 65 6e 69 7a 65 72 2d 61 72 67    <tokenizer-arg
01f0: 73 3e 20 73 68 6f 75 6c 64 20 63 6f 6e 73 69 73  s> should consis
0200: 74 20 6f 66 20 7a 65 72 6f 20 6f 72 20 6d 6f 72  t of zero or mor
0210: 65 20 77 68 69 74 65 2d 73 70 61 63 65 20 73 65  e white-space se
0220: 70 61 72 61 74 65 64 0a 20 20 61 72 67 75 6d 65  parated.  argume
0230: 6e 74 73 20 74 6f 20 70 61 73 73 20 74 6f 20 74  nts to pass to t
0240: 68 65 20 73 65 6c 65 63 74 65 64 20 74 6f 6b 65  he selected toke
0250: 6e 69 7a 65 72 20 69 6d 70 6c 65 6d 65 6e 74 61  nizer implementa
0260: 74 69 6f 6e 2e 20 54 68 65 20 0a 20 20 69 6e 74  tion. The .  int
0270: 65 72 70 72 65 74 61 74 69 6f 6e 20 6f 66 20 74  erpretation of t
0280: 68 65 20 61 72 67 75 6d 65 6e 74 73 2c 20 69 66  he arguments, if
0290: 20 61 6e 79 2c 20 64 65 70 65 6e 64 73 20 6f 6e   any, depends on
02a0: 20 74 68 65 20 69 6e 64 69 76 69 64 75 61 6c 20   the individual 
02b0: 0a 20 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 0a 32  .  tokenizer...2
02c0: 2e 20 43 75 73 74 6f 6d 20 54 6f 6b 65 6e 69 7a  . Custom Tokeniz
02d0: 65 72 73 0a 0a 20 20 46 54 53 33 20 61 6c 6c 6f  ers..  FTS3 allo
02e0: 77 73 20 75 73 65 72 73 20 74 6f 20 70 72 6f 76  ws users to prov
02f0: 69 64 65 20 63 75 73 74 6f 6d 20 74 6f 6b 65 6e  ide custom token
0300: 69 7a 65 72 20 69 6d 70 6c 65 6d 65 6e 74 61 74  izer implementat
0310: 69 6f 6e 73 2e 20 54 68 65 20 0a 20 20 69 6e 74  ions. The .  int
0320: 65 72 66 61 63 65 20 75 73 65 64 20 74 6f 20 63  erface used to c
0330: 72 65 61 74 65 20 61 20 6e 65 77 20 74 6f 6b 65  reate a new toke
0340: 6e 69 7a 65 72 20 69 73 20 64 65 66 69 6e 65 64  nizer is defined
0350: 20 61 6e 64 20 64 65 73 63 72 69 62 65 64 20 69   and described i
0360: 6e 20 0a 20 20 74 68 65 20 66 74 73 33 5f 74 6f  n .  the fts3_to
0370: 6b 65 6e 69 7a 65 72 2e 68 20 73 6f 75 72 63 65  kenizer.h source
0380: 20 66 69 6c 65 2e 0a 0a 20 20 52 65 67 69 73 74   file...  Regist
0390: 65 72 69 6e 67 20 61 20 6e 65 77 20 46 54 53 33  ering a new FTS3
03a0: 20 74 6f 6b 65 6e 69 7a 65 72 20 69 73 20 73 69   tokenizer is si
03b0: 6d 69 6c 61 72 20 74 6f 20 72 65 67 69 73 74 65  milar to registe
03c0: 72 69 6e 67 20 61 20 6e 65 77 20 0a 20 20 76 69  ring a new .  vi
03d0: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
03e0: 6c 65 20 77 69 74 68 20 53 51 4c 69 74 65 2e 20  le with SQLite. 
03f0: 54 68 65 20 75 73 65 72 20 70 61 73 73 65 73 20  The user passes 
0400: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 0a 20  a pointer to a. 
0410: 20 73 74 72 75 63 74 75 72 65 20 63 6f 6e 74 61   structure conta
0420: 69 6e 69 6e 67 20 70 6f 69 6e 74 65 72 73 20 74  ining pointers t
0430: 6f 20 76 61 72 69 6f 75 73 20 63 61 6c 6c 62 61  o various callba
0440: 63 6b 20 66 75 6e 63 74 69 6f 6e 73 20 74 68 61  ck functions tha
0450: 74 0a 20 20 6d 61 6b 65 20 75 70 20 74 68 65 20  t.  make up the 
0460: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  implementation o
0470: 66 20 74 68 65 20 6e 65 77 20 74 6f 6b 65 6e 69  f the new tokeni
0480: 7a 65 72 20 74 79 70 65 2e 20 46 6f 72 20 74 6f  zer type. For to
0490: 6b 65 6e 69 7a 65 72 73 2c 0a 20 20 74 68 65 20  kenizers,.  the 
04a0: 73 74 72 75 63 74 75 72 65 20 28 64 65 66 69 6e  structure (defin
04b0: 65 64 20 69 6e 20 66 74 73 33 5f 74 6f 6b 65 6e  ed in fts3_token
04c0: 69 7a 65 72 2e 68 29 20 69 73 20 63 61 6c 6c 65  izer.h) is calle
04d0: 64 0a 20 20 22 73 71 6c 69 74 65 33 5f 74 6f 6b  d.  "sqlite3_tok
04e0: 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 22 2e 0a  enizer_module"..
04f0: 0a 20 20 46 54 53 33 20 64 6f 65 73 20 6e 6f 74  .  FTS3 does not
0500: 20 65 78 70 6f 73 65 20 61 20 43 2d 66 75 6e 63   expose a C-func
0510: 74 69 6f 6e 20 74 68 61 74 20 75 73 65 72 73 20  tion that users 
0520: 63 61 6c 6c 20 74 6f 20 72 65 67 69 73 74 65 72  call to register
0530: 20 6e 65 77 0a 20 20 74 6f 6b 65 6e 69 7a 65 72   new.  tokenizer
0540: 20 74 79 70 65 73 20 77 69 74 68 20 61 20 64 61   types with a da
0550: 74 61 62 61 73 65 20 68 61 6e 64 6c 65 2e 20 49  tabase handle. I
0560: 6e 73 74 65 61 64 2c 20 74 68 65 20 70 6f 69 6e  nstead, the poin
0570: 74 65 72 20 6d 75 73 74 0a 20 20 62 65 20 65 6e  ter must.  be en
0580: 63 6f 64 65 64 20 61 73 20 61 6e 20 53 51 4c 20  coded as an SQL 
0590: 62 6c 6f 62 20 76 61 6c 75 65 20 61 6e 64 20 70  blob value and p
05a0: 61 73 73 65 64 20 74 6f 20 46 54 53 33 20 74 68  assed to FTS3 th
05b0: 72 6f 75 67 68 20 74 68 65 20 53 51 4c 0a 20 20  rough the SQL.  
05c0: 65 6e 67 69 6e 65 20 62 79 20 65 76 61 6c 75 61  engine by evalua
05d0: 74 69 6e 67 20 61 20 73 70 65 63 69 61 6c 20 73  ting a special s
05e0: 63 61 6c 61 72 20 66 75 6e 63 74 69 6f 6e 2c 20  calar function, 
05f0: 22 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 28  "fts3_tokenizer(
0600: 29 22 2e 0a 20 20 54 68 65 20 66 74 73 33 5f 74  )"..  The fts3_t
0610: 6f 6b 65 6e 69 7a 65 72 28 29 20 66 75 6e 63 74  okenizer() funct
0620: 69 6f 6e 20 6d 61 79 20 62 65 20 63 61 6c 6c 65  ion may be calle
0630: 64 20 77 69 74 68 20 6f 6e 65 20 6f 72 20 74 77  d with one or tw
0640: 6f 20 61 72 67 75 6d 65 6e 74 73 2c 0a 20 20 61  o arguments,.  a
0650: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 0a 20 20 20 20  s follows:..    
0660: 53 45 4c 45 43 54 20 66 74 73 33 5f 74 6f 6b 65  SELECT fts3_toke
0670: 6e 69 7a 65 72 28 3c 74 6f 6b 65 6e 69 7a 65 72  nizer(<tokenizer
0680: 2d 6e 61 6d 65 3e 29 3b 0a 20 20 20 20 53 45 4c  -name>);.    SEL
0690: 45 43 54 20 66 74 73 33 5f 74 6f 6b 65 6e 69 7a  ECT fts3_tokeniz
06a0: 65 72 28 3c 74 6f 6b 65 6e 69 7a 65 72 2d 6e 61  er(<tokenizer-na
06b0: 6d 65 3e 2c 20 3c 73 71 6c 69 74 65 33 5f 74 6f  me>, <sqlite3_to
06c0: 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 70  kenizer_module p
06d0: 74 72 3e 29 3b 0a 20 20 0a 20 20 57 68 65 72 65  tr>);.  .  Where
06e0: 20 3c 74 6f 6b 65 6e 69 7a 65 72 2d 6e 61 6d 65   <tokenizer-name
06f0: 3e 20 69 73 20 61 20 73 74 72 69 6e 67 20 69 64  > is a string id
0700: 65 6e 74 69 66 79 69 6e 67 20 74 68 65 20 74 6f  entifying the to
0710: 6b 65 6e 69 7a 65 72 20 61 6e 64 0a 20 20 3c 73  kenizer and.  <s
0720: 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72  qlite3_tokenizer
0730: 5f 6d 6f 64 75 6c 65 20 70 74 72 3e 20 69 73 20  _module ptr> is 
0740: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 6e 20  a pointer to an 
0750: 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
0760: 72 5f 6d 6f 64 75 6c 65 0a 20 20 73 74 72 75 63  r_module.  struc
0770: 74 75 72 65 20 65 6e 63 6f 64 65 64 20 61 73 20  ture encoded as 
0780: 61 6e 20 53 51 4c 20 62 6c 6f 62 2e 20 49 66 20  an SQL blob. If 
0790: 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d  the second argum
07a0: 65 6e 74 20 69 73 20 70 72 65 73 65 6e 74 2c 0a  ent is present,.
07b0: 20 20 69 74 20 69 73 20 72 65 67 69 73 74 65 72    it is register
07c0: 65 64 20 61 73 20 74 6f 6b 65 6e 69 7a 65 72 20  ed as tokenizer 
07d0: 3c 74 6f 6b 65 6e 69 7a 65 72 2d 6e 61 6d 65 3e  <tokenizer-name>
07e0: 20 61 6e 64 20 61 20 63 6f 70 79 20 6f 66 20 69   and a copy of i
07f0: 74 0a 20 20 72 65 74 75 72 6e 65 64 2e 20 49 66  t.  returned. If
0800: 20 6f 6e 6c 79 20 6f 6e 65 20 61 72 67 75 6d 65   only one argume
0810: 6e 74 20 69 73 20 70 61 73 73 65 64 2c 20 61 20  nt is passed, a 
0820: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 74  pointer to the t
0830: 6f 6b 65 6e 69 7a 65 72 0a 20 20 69 6d 70 6c 65  okenizer.  imple
0840: 6d 65 6e 74 61 74 69 6f 6e 20 63 75 72 72 65 6e  mentation curren
0850: 74 6c 79 20 72 65 67 69 73 74 65 72 65 64 20 61  tly registered a
0860: 73 20 3c 74 6f 6b 65 6e 69 7a 65 72 2d 6e 61 6d  s <tokenizer-nam
0870: 65 3e 20 69 73 20 72 65 74 75 72 6e 65 64 2c 0a  e> is returned,.
0880: 20 20 65 6e 63 6f 64 65 64 20 61 73 20 61 20 62    encoded as a b
0890: 6c 6f 62 2e 20 4f 72 2c 20 69 66 20 6e 6f 20 73  lob. Or, if no s
08a0: 75 63 68 20 74 6f 6b 65 6e 69 7a 65 72 20 65 78  uch tokenizer ex
08b0: 69 73 74 73 2c 20 61 6e 20 53 51 4c 20 65 78 63  ists, an SQL exc
08c0: 65 70 74 69 6f 6e 0a 20 20 28 65 72 72 6f 72 29  eption.  (error)
08d0: 20 69 73 20 72 61 69 73 65 64 2e 0a 0a 20 20 53   is raised...  S
08e0: 45 43 55 52 49 54 59 3a 20 49 66 20 74 68 65 20  ECURITY: If the 
08f0: 66 74 73 33 20 65 78 74 65 6e 73 69 6f 6e 20 69  fts3 extension i
0900: 73 20 75 73 65 64 20 69 6e 20 61 6e 20 65 6e 76  s used in an env
0910: 69 72 6f 6e 6d 65 6e 74 20 77 68 65 72 65 20 70  ironment where p
0920: 6f 74 65 6e 74 69 61 6c 6c 79 0a 20 20 20 20 6d  otentially.    m
0930: 61 6c 69 63 69 6f 75 73 20 75 73 65 72 73 20 6d  alicious users m
0940: 61 79 20 65 78 65 63 75 74 65 20 61 72 62 69 74  ay execute arbit
0950: 72 61 72 79 20 53 51 4c 20 28 69 2e 65 2e 20 67  rary SQL (i.e. g
0960: 65 61 72 73 29 2c 20 74 68 65 79 20 73 68 6f 75  ears), they shou
0970: 6c 64 20 62 65 0a 20 20 20 20 70 72 65 76 65 6e  ld be.    preven
0980: 74 65 64 20 66 72 6f 6d 20 69 6e 76 6f 6b 69 6e  ted from invokin
0990: 67 20 74 68 65 20 66 74 73 33 5f 74 6f 6b 65 6e  g the fts3_token
09a0: 69 7a 65 72 28 29 20 66 75 6e 63 74 69 6f 6e 2c  izer() function,
09b0: 20 70 6f 73 73 69 62 6c 79 20 75 73 69 6e 67 20   possibly using 
09c0: 74 68 65 0a 20 20 20 20 61 75 74 68 6f 72 69 73  the.    authoris
09d0: 61 74 69 6f 6e 20 63 61 6c 6c 62 61 63 6b 2e 0a  ation callback..
09e0: 0a 20 20 53 65 65 20 22 53 61 6d 70 6c 65 20 63  .  See "Sample c
09f0: 6f 64 65 22 20 62 65 6c 6f 77 20 66 6f 72 20 61  ode" below for a
0a00: 6e 20 65 78 61 6d 70 6c 65 20 6f 66 20 63 61 6c  n example of cal
0a10: 6c 69 6e 67 20 74 68 65 20 66 74 73 33 5f 74 6f  ling the fts3_to
0a20: 6b 65 6e 69 7a 65 72 28 29 0a 20 20 66 75 6e 63  kenizer().  func
0a30: 74 69 6f 6e 20 66 72 6f 6d 20 43 20 63 6f 64 65  tion from C code
0a40: 2e 0a 0a 33 2e 20 49 43 55 20 4c 69 62 72 61 72  ...3. ICU Librar
0a50: 79 20 54 6f 6b 65 6e 69 7a 65 72 73 0a 0a 20 20  y Tokenizers..  
0a60: 49 66 20 74 68 69 73 20 65 78 74 65 6e 73 69 6f  If this extensio
0a70: 6e 20 69 73 20 63 6f 6d 70 69 6c 65 64 20 77 69  n is compiled wi
0a80: 74 68 20 74 68 65 20 53 51 4c 49 54 45 5f 45 4e  th the SQLITE_EN
0a90: 41 42 4c 45 5f 49 43 55 20 70 72 65 2d 70 72 6f  ABLE_ICU pre-pro
0aa0: 63 65 73 73 6f 72 20 0a 20 20 73 79 6d 62 6f 6c  cessor .  symbol
0ab0: 20 64 65 66 69 6e 65 64 2c 20 74 68 65 6e 20 74   defined, then t
0ac0: 68 65 72 65 20 65 78 69 73 74 73 20 61 20 62 75  here exists a bu
0ad0: 69 6c 74 2d 69 6e 20 74 6f 6b 65 6e 69 7a 65 72  ilt-in tokenizer
0ae0: 20 6e 61 6d 65 64 20 22 69 63 75 22 20 0a 20 20   named "icu" .  
0af0: 69 6d 70 6c 65 6d 65 6e 74 65 64 20 75 73 69 6e  implemented usin
0b00: 67 20 74 68 65 20 49 43 55 20 6c 69 62 72 61 72  g the ICU librar
0b10: 79 2e 20 54 68 65 20 66 69 72 73 74 20 61 72 67  y. The first arg
0b20: 75 6d 65 6e 74 20 70 61 73 73 65 64 20 74 6f 20  ument passed to 
0b30: 74 68 65 0a 20 20 78 43 72 65 61 74 65 28 29 20  the.  xCreate() 
0b40: 6d 65 74 68 6f 64 20 28 73 65 65 20 66 74 73 33  method (see fts3
0b50: 5f 74 6f 6b 65 6e 69 7a 65 72 2e 68 29 20 6f 66  _tokenizer.h) of
0b60: 20 74 68 69 73 20 74 6f 6b 65 6e 69 7a 65 72 20   this tokenizer 
0b70: 6d 61 79 20 62 65 0a 20 20 61 6e 20 49 43 55 20  may be.  an ICU 
0b80: 6c 6f 63 61 6c 65 20 69 64 65 6e 74 69 66 69 65  locale identifie
0b90: 72 2e 20 46 6f 72 20 65 78 61 6d 70 6c 65 20 22  r. For example "
0ba0: 74 72 5f 54 52 22 20 66 6f 72 20 54 75 72 6b 69  tr_TR" for Turki
0bb0: 73 68 20 61 73 20 75 73 65 64 0a 20 20 69 6e 20  sh as used.  in 
0bc0: 54 75 72 6b 65 79 2c 20 6f 72 20 22 65 6e 5f 41  Turkey, or "en_A
0bd0: 55 22 20 66 6f 72 20 45 6e 67 6c 69 73 68 20 61  U" for English a
0be0: 73 20 75 73 65 64 20 69 6e 20 41 75 73 74 72 61  s used in Austra
0bf0: 6c 69 61 2e 20 46 6f 72 20 65 78 61 6d 70 6c 65  lia. For example
0c00: 3a 0a 0a 20 20 20 20 22 43 52 45 41 54 45 20 56  :..    "CREATE V
0c10: 49 52 54 55 41 4c 20 54 41 42 4c 45 20 74 68 61  IRTUAL TABLE tha
0c20: 69 5f 74 65 78 74 20 55 53 49 4e 47 20 66 74 73  i_text USING fts
0c30: 33 28 74 65 78 74 2c 20 74 6f 6b 65 6e 69 7a 65  3(text, tokenize
0c40: 72 20 69 63 75 20 74 68 5f 54 48 29 22 0a 0a 20  r icu th_TH)".. 
0c50: 20 54 68 65 20 49 43 55 20 74 6f 6b 65 6e 69 7a   The ICU tokeniz
0c60: 65 72 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  er implementatio
0c70: 6e 20 69 73 20 76 65 72 79 20 73 69 6d 70 6c 65  n is very simple
0c80: 2e 20 49 74 20 73 70 6c 69 74 73 20 74 68 65 20  . It splits the 
0c90: 69 6e 70 75 74 0a 20 20 74 65 78 74 20 61 63 63  input.  text acc
0ca0: 6f 72 64 69 6e 67 20 74 6f 20 74 68 65 20 49 43  ording to the IC
0cb0: 55 20 72 75 6c 65 73 20 66 6f 72 20 66 69 6e 64  U rules for find
0cc0: 69 6e 67 20 77 6f 72 64 20 62 6f 75 6e 64 61 72  ing word boundar
0cd0: 69 65 73 20 61 6e 64 20 64 69 73 63 61 72 64 73  ies and discards
0ce0: 0a 20 20 61 6e 79 20 74 6f 6b 65 6e 73 20 74 68  .  any tokens th
0cf0: 61 74 20 63 6f 6e 73 69 73 74 20 65 6e 74 69 72  at consist entir
0d00: 65 6c 79 20 6f 66 20 77 68 69 74 65 2d 73 70 61  ely of white-spa
0d10: 63 65 2e 20 54 68 69 73 20 6d 61 79 20 62 65 20  ce. This may be 
0d20: 73 75 69 74 61 62 6c 65 0a 20 20 66 6f 72 20 73  suitable.  for s
0d30: 6f 6d 65 20 61 70 70 6c 69 63 61 74 69 6f 6e 73  ome applications
0d40: 20 69 6e 20 73 6f 6d 65 20 6c 6f 63 61 6c 65 73   in some locales
0d50: 2c 20 62 75 74 20 6e 6f 74 20 61 6c 6c 2e 20 49  , but not all. I
0d60: 66 20 6d 6f 72 65 20 63 6f 6d 70 6c 65 78 0a 20  f more complex. 
0d70: 20 70 72 6f 63 65 73 73 69 6e 67 20 69 73 20 72   processing is r
0d80: 65 71 75 69 72 65 64 2c 20 66 6f 72 20 65 78 61  equired, for exa
0d90: 6d 70 6c 65 20 74 6f 20 69 6d 70 6c 65 6d 65 6e  mple to implemen
0da0: 74 20 73 74 65 6d 6d 69 6e 67 20 6f 72 20 0a 20  t stemming or . 
0db0: 20 64 69 73 63 61 72 64 20 70 75 6e 63 74 75 61   discard punctua
0dc0: 74 69 6f 6e 2c 20 74 68 69 73 20 63 61 6e 20 62  tion, this can b
0dd0: 65 20 64 6f 6e 65 20 62 79 20 63 72 65 61 74 69  e done by creati
0de0: 6e 67 20 61 20 74 6f 6b 65 6e 69 7a 65 72 20 0a  ng a tokenizer .
0df0: 20 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e    implementation
0e00: 20 74 68 61 74 20 75 73 65 73 20 74 68 65 20 49   that uses the I
0e10: 43 55 20 74 6f 6b 65 6e 69 7a 65 72 20 61 73 20  CU tokenizer as 
0e20: 70 61 72 74 20 6f 66 20 69 74 73 20 69 6d 70 6c  part of its impl
0e30: 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 0a 20 20 57  ementation...  W
0e40: 68 65 6e 20 75 73 69 6e 67 20 74 68 65 20 49 43  hen using the IC
0e50: 55 20 74 6f 6b 65 6e 69 7a 65 72 20 74 68 69 73  U tokenizer this
0e60: 20 77 61 79 2c 20 69 74 20 69 73 20 73 61 66 65   way, it is safe
0e70: 20 74 6f 20 6f 76 65 72 77 72 69 74 65 20 74 68   to overwrite th
0e80: 65 0a 20 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  e.  contents of 
0e90: 74 68 65 20 73 74 72 69 6e 67 73 20 72 65 74 75  the strings retu
0ea0: 72 6e 65 64 20 62 79 20 74 68 65 20 78 4e 65 78  rned by the xNex
0eb0: 74 28 29 20 6d 65 74 68 6f 64 20 28 73 65 65 0a  t() method (see.
0ec0: 20 20 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72    fts3_tokenizer
0ed0: 2e 68 29 2e 0a 0a 34 2e 20 53 61 6d 70 6c 65 20  .h)...4. Sample 
0ee0: 63 6f 64 65 2e 0a 0a 20 20 54 68 65 20 66 6f 6c  code...  The fol
0ef0: 6c 6f 77 69 6e 67 20 74 77 6f 20 63 6f 64 65 20  lowing two code 
0f00: 73 61 6d 70 6c 65 73 20 69 6c 6c 75 73 74 72 61  samples illustra
0f10: 74 65 20 74 68 65 20 77 61 79 20 43 20 63 6f 64  te the way C cod
0f20: 65 20 73 68 6f 75 6c 64 20 69 6e 76 6f 6b 65 0a  e should invoke.
0f30: 20 20 74 68 65 20 66 74 73 33 5f 74 6f 6b 65 6e    the fts3_token
0f40: 69 7a 65 72 28 29 20 73 63 61 6c 61 72 20 66 75  izer() scalar fu
0f50: 6e 63 74 69 6f 6e 3a 0a 0a 20 20 20 20 20 20 69  nction:..      i
0f60: 6e 74 20 72 65 67 69 73 74 65 72 54 6f 6b 65 6e  nt registerToken
0f70: 69 7a 65 72 28 0a 20 20 20 20 20 20 20 20 73 71  izer(.        sq
0f80: 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20 20 20 20  lite3 *db, .    
0f90: 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c      char *zName,
0fa0: 20 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20   .        const 
0fb0: 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
0fc0: 72 5f 6d 6f 64 75 6c 65 20 2a 70 0a 20 20 20 20  r_module *p.    
0fd0: 20 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74    ){.        int
0fe0: 20 72 63 3b 0a 20 20 20 20 20 20 20 20 73 71 6c   rc;.        sql
0ff0: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
1000: 3b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20  ;.        const 
1010: 63 68 61 72 20 7a 53 71 6c 5b 5d 20 3d 20 22 53  char zSql[] = "S
1020: 45 4c 45 43 54 20 66 74 73 33 5f 74 6f 6b 65 6e  ELECT fts3_token
1030: 69 7a 65 72 28 3f 2c 20 3f 29 22 3b 0a 20 20 20  izer(?, ?)";.   
1040: 20 20 20 0a 20 20 20 20 20 20 20 20 72 63 20 3d     .        rc =
1050: 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
1060: 5f 76 32 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31  _v2(db, zSql, -1
1070: 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  , &pStmt, 0);.  
1080: 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
1090: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
10a0: 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a       return rc;.
10b0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
10c0: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
10d0: 5f 62 69 6e 64 5f 74 65 78 74 28 70 53 74 6d 74  _bind_text(pStmt
10e0: 2c 20 31 2c 20 7a 4e 61 6d 65 2c 20 2d 31 2c 20  , 1, zName, -1, 
10f0: 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a  SQLITE_STATIC);.
1100: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
1110: 62 69 6e 64 5f 62 6c 6f 62 28 70 53 74 6d 74 2c  bind_blob(pStmt,
1120: 20 32 2c 20 26 70 2c 20 73 69 7a 65 6f 66 28 70   2, &p, sizeof(p
1130: 29 2c 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43  ), SQLITE_STATIC
1140: 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  );.        sqlit
1150: 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3b 0a  e3_step(pStmt);.
1160: 20 20 20 20 20 20 0a 20 20 20 20 20 20 20 20 72        .        r
1170: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 5f 66 69  eturn sqlite3_fi
1180: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
1190: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 0a 20 20       }.      .  
11a0: 20 20 20 20 69 6e 74 20 71 75 65 72 79 54 6f 6b      int queryTok
11b0: 65 6e 69 7a 65 72 28 0a 20 20 20 20 20 20 20 20  enizer(.        
11c0: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20 20  sqlite3 *db, .  
11d0: 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d        char *zNam
11e0: 65 2c 20 20 0a 20 20 20 20 20 20 20 20 63 6f 6e  e,  .        con
11f0: 73 74 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  st sqlite3_token
1200: 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a 2a 70 70  izer_module **pp
1210: 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20  .      ){.      
1220: 20 20 69 6e 74 20 72 63 3b 0a 20 20 20 20 20 20    int rc;.      
1230: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
1240: 70 53 74 6d 74 3b 0a 20 20 20 20 20 20 20 20 63  pStmt;.        c
1250: 6f 6e 73 74 20 63 68 61 72 20 7a 53 71 6c 5b 5d  onst char zSql[]
1260: 20 3d 20 22 53 45 4c 45 43 54 20 66 74 73 33 5f   = "SELECT fts3_
1270: 74 6f 6b 65 6e 69 7a 65 72 28 3f 29 22 3b 0a 20  tokenizer(?)";. 
1280: 20 20 20 20 20 0a 20 20 20 20 20 20 20 20 2a 70       .        *p
1290: 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 72  p = 0;.        r
12a0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
12b0: 61 72 65 5f 76 32 28 64 62 2c 20 7a 53 71 6c 2c  are_v2(db, zSql,
12c0: 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b   -1, &pStmt, 0);
12d0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 21  .        if( rc!
12e0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
12f0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72          return r
1300: 63 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  c;.        }.   
1310: 20 20 20 0a 20 20 20 20 20 20 20 20 73 71 6c 69     .        sqli
1320: 74 65 33 5f 62 69 6e 64 5f 74 65 78 74 28 70 53  te3_bind_text(pS
1330: 74 6d 74 2c 20 31 2c 20 7a 4e 61 6d 65 2c 20 2d  tmt, 1, zName, -
1340: 31 2c 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43  1, SQLITE_STATIC
1350: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 53  );.        if( S
1360: 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74  QLITE_ROW==sqlit
1370: 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 20 29  e3_step(pStmt) )
1380: 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  {.          if( 
1390: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
13a0: 79 70 65 28 70 53 74 6d 74 2c 20 30 29 3d 3d 53  ype(pStmt, 0)==S
13b0: 51 4c 49 54 45 5f 42 4c 4f 42 20 29 7b 0a 20 20  QLITE_BLOB ){.  
13c0: 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79            memcpy
13d0: 28 70 70 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c  (pp, sqlite3_col
13e0: 75 6d 6e 5f 62 6c 6f 62 28 70 53 74 6d 74 2c 20  umn_blob(pStmt, 
13f0: 30 29 2c 20 73 69 7a 65 6f 66 28 2a 70 70 29 29  0), sizeof(*pp))
1400: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
1410: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 0a 20        }.      . 
1420: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 73 71         return sq
1430: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
1440: 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 7d 0a     Stmt);.      }.