/ Hex Artifact Content
Login

Artifact 226644a0eab97724e8de83061912e8bb248461b6:


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 72 22 20 63 6c 61 75 73  tokenizer" claus
00c0: 65 20 61 73 20 70 61 72 74 20 6f 66 20 74 68 65  e as part of the
00d0: 20 43 52 45 41 54 45 20 56 49 52 54 55 41 4c 20   CREATE VIRTUAL 
00e0: 54 41 42 4c 45 0a 20 20 73 74 61 74 65 6d 65 6e  TABLE.  statemen
00f0: 74 3a 0a 0a 20 20 20 20 43 52 45 41 54 45 20 56  t:..    CREATE V
0100: 49 52 54 55 41 4c 20 54 41 42 4c 45 20 3c 74 61  IRTUAL TABLE <ta
0110: 62 6c 65 2d 6e 61 6d 65 3e 20 55 53 49 4e 47 20  ble-name> USING 
0120: 66 74 73 33 28 0a 20 20 20 20 20 20 3c 63 6f 6c  fts3(.      <col
0130: 75 6d 6e 73 20 2e 2e 2e 3e 20 5b 2c 20 74 6f 6b  umns ...> [, tok
0140: 65 6e 69 7a 65 72 20 3c 74 6f 6b 65 6e 69 7a 65  enizer <tokenize
0150: 72 2d 6e 61 6d 65 3e 20 5b 3c 74 6f 6b 65 6e 69  r-name> [<tokeni
0160: 7a 65 72 2d 61 72 67 73 3e 5d 5d 0a 20 20 20 20  zer-args>]].    
0170: 29 3b 0a 0a 20 20 54 68 65 20 62 75 69 6c 74 2d  );..  The built-
0180: 69 6e 20 74 6f 6b 65 6e 69 7a 65 72 73 20 28 76  in tokenizers (v
0190: 61 6c 69 64 20 76 61 6c 75 65 73 20 74 6f 20 70  alid values to p
01a0: 61 73 73 20 61 73 20 3c 74 6f 6b 65 6e 69 7a 65  ass as <tokenize
01b0: 72 20 6e 61 6d 65 3e 29 20 61 72 65 0a 20 20 22  r name>) are.  "
01c0: 73 69 6d 70 6c 65 22 20 61 6e 64 20 22 70 6f 72  simple" and "por
01d0: 74 65 72 22 2e 0a 0a 20 20 3c 74 6f 6b 65 6e 69  ter"...  <tokeni
01e0: 7a 65 72 2d 61 72 67 73 3e 20 73 68 6f 75 6c 64  zer-args> should
01f0: 20 63 6f 6e 73 69 73 74 20 6f 66 20 7a 65 72 6f   consist of zero
0200: 20 6f 72 20 6d 6f 72 65 20 77 68 69 74 65 2d 73   or more white-s
0210: 70 61 63 65 20 73 65 70 61 72 61 74 65 64 0a 20  pace separated. 
0220: 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 70 61   arguments to pa
0230: 73 73 20 74 6f 20 74 68 65 20 73 65 6c 65 63 74  ss to the select
0240: 65 64 20 74 6f 6b 65 6e 69 7a 65 72 20 69 6d 70  ed tokenizer imp
0250: 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 20 54 68 65  lementation. The
0260: 20 0a 20 20 69 6e 74 65 72 70 72 65 74 61 74 69   .  interpretati
0270: 6f 6e 20 6f 66 20 74 68 65 20 61 72 67 75 6d 65  on of the argume
0280: 6e 74 73 2c 20 69 66 20 61 6e 79 2c 20 64 65 70  nts, if any, dep
0290: 65 6e 64 73 20 6f 6e 20 74 68 65 20 69 6e 64 69  ends on the indi
02a0: 76 69 64 75 61 6c 20 0a 20 20 74 6f 6b 65 6e 69  vidual .  tokeni
02b0: 7a 65 72 2e 0a 0a 32 2e 20 43 75 73 74 6f 6d 20  zer...2. Custom 
02c0: 54 6f 6b 65 6e 69 7a 65 72 73 0a 0a 20 20 46 54  Tokenizers..  FT
02d0: 53 33 20 61 6c 6c 6f 77 73 20 75 73 65 72 73 20  S3 allows users 
02e0: 74 6f 20 70 72 6f 76 69 64 65 20 63 75 73 74 6f  to provide custo
02f0: 6d 20 74 6f 6b 65 6e 69 7a 65 72 20 69 6d 70 6c  m tokenizer impl
0300: 65 6d 65 6e 74 61 74 69 6f 6e 73 2e 20 54 68 65  ementations. The
0310: 20 0a 20 20 69 6e 74 65 72 66 61 63 65 20 75 73   .  interface us
0320: 65 64 20 74 6f 20 63 72 65 61 74 65 20 61 20 6e  ed to create a n
0330: 65 77 20 74 6f 6b 65 6e 69 7a 65 72 20 69 73 20  ew tokenizer is 
0340: 64 65 66 69 6e 65 64 20 61 6e 64 20 64 65 73 63  defined and desc
0350: 72 69 62 65 64 20 69 6e 20 0a 20 20 74 68 65 20  ribed in .  the 
0360: 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 2e 68  fts3_tokenizer.h
0370: 20 73 6f 75 72 63 65 20 66 69 6c 65 2e 0a 0a 20   source file... 
0380: 20 52 65 67 69 73 74 65 72 69 6e 67 20 61 20 6e   Registering a n
0390: 65 77 20 46 54 53 33 20 74 6f 6b 65 6e 69 7a 65  ew FTS3 tokenize
03a0: 72 20 69 73 20 73 69 6d 69 6c 61 72 20 74 6f 20  r is similar to 
03b0: 72 65 67 69 73 74 65 72 69 6e 67 20 61 20 6e 65  registering a ne
03c0: 77 20 0a 20 20 76 69 72 74 75 61 6c 20 74 61 62  w .  virtual tab
03d0: 6c 65 20 6d 6f 64 75 6c 65 20 77 69 74 68 20 53  le module with S
03e0: 51 4c 69 74 65 2e 20 54 68 65 20 75 73 65 72 20  QLite. The user 
03f0: 70 61 73 73 65 73 20 61 20 70 6f 69 6e 74 65 72  passes a pointer
0400: 20 74 6f 20 61 0a 20 20 73 74 72 75 63 74 75 72   to a.  structur
0410: 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 70 6f 69  e containing poi
0420: 6e 74 65 72 73 20 74 6f 20 76 61 72 69 6f 75 73  nters to various
0430: 20 63 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69   callback functi
0440: 6f 6e 73 20 74 68 61 74 0a 20 20 6d 61 6b 65 20  ons that.  make 
0450: 75 70 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  up the implement
0460: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 6e 65 77  ation of the new
0470: 20 74 6f 6b 65 6e 69 7a 65 72 20 74 79 70 65 2e   tokenizer type.
0480: 20 46 6f 72 20 74 6f 6b 65 6e 69 7a 65 72 73 2c   For tokenizers,
0490: 0a 20 20 74 68 65 20 73 74 72 75 63 74 75 72 65  .  the structure
04a0: 20 28 64 65 66 69 6e 65 64 20 69 6e 20 66 74 73   (defined in fts
04b0: 33 5f 74 6f 6b 65 6e 69 7a 65 72 2e 68 29 20 69  3_tokenizer.h) i
04c0: 73 20 63 61 6c 6c 65 64 0a 20 20 22 73 71 6c 69  s called.  "sqli
04d0: 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f  te3_tokenizer_mo
04e0: 64 75 6c 65 22 2e 0a 0a 20 20 46 54 53 33 20 64  dule"...  FTS3 d
04f0: 6f 65 73 20 6e 6f 74 20 65 78 70 6f 73 65 20 61  oes not expose a
0500: 20 43 2d 66 75 6e 63 74 69 6f 6e 20 74 68 61 74   C-function that
0510: 20 75 73 65 72 73 20 63 61 6c 6c 20 74 6f 20 72   users call to r
0520: 65 67 69 73 74 65 72 20 6e 65 77 0a 20 20 74 6f  egister new.  to
0530: 6b 65 6e 69 7a 65 72 20 74 79 70 65 73 20 77 69  kenizer types wi
0540: 74 68 20 61 20 64 61 74 61 62 61 73 65 20 68 61  th a database ha
0550: 6e 64 6c 65 2e 20 49 6e 73 74 65 61 64 2c 20 74  ndle. Instead, t
0560: 68 65 20 70 6f 69 6e 74 65 72 20 6d 75 73 74 0a  he pointer must.
0570: 20 20 62 65 20 65 6e 63 6f 64 65 64 20 61 73 20    be encoded as 
0580: 61 6e 20 53 51 4c 20 62 6c 6f 62 20 76 61 6c 75  an SQL blob valu
0590: 65 20 61 6e 64 20 70 61 73 73 65 64 20 74 6f 20  e and passed to 
05a0: 46 54 53 33 20 74 68 72 6f 75 67 68 20 74 68 65  FTS3 through the
05b0: 20 53 51 4c 0a 20 20 65 6e 67 69 6e 65 20 62 79   SQL.  engine by
05c0: 20 65 76 61 6c 75 61 74 69 6e 67 20 61 20 73 70   evaluating a sp
05d0: 65 63 69 61 6c 20 73 63 61 6c 61 72 20 66 75 6e  ecial scalar fun
05e0: 63 74 69 6f 6e 2c 20 22 66 74 73 33 5f 74 6f 6b  ction, "fts3_tok
05f0: 65 6e 69 7a 65 72 28 29 22 2e 0a 20 20 54 68 65  enizer()"..  The
0600: 20 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 28   fts3_tokenizer(
0610: 29 20 66 75 6e 63 74 69 6f 6e 20 6d 61 79 20 62  ) function may b
0620: 65 20 63 61 6c 6c 65 64 20 77 69 74 68 20 6f 6e  e called with on
0630: 65 20 6f 72 20 74 77 6f 20 61 72 67 75 6d 65 6e  e or two argumen
0640: 74 73 2c 0a 20 20 61 73 20 66 6f 6c 6c 6f 77 73  ts,.  as follows
0650: 3a 0a 0a 20 20 20 20 53 45 4c 45 43 54 20 66 74  :..    SELECT ft
0660: 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 28 3c 74 6f  s3_tokenizer(<to
0670: 6b 65 6e 69 7a 65 72 2d 6e 61 6d 65 3e 29 3b 0a  kenizer-name>);.
0680: 20 20 20 20 53 45 4c 45 43 54 20 66 74 73 33 5f      SELECT fts3_
0690: 74 6f 6b 65 6e 69 7a 65 72 28 3c 74 6f 6b 65 6e  tokenizer(<token
06a0: 69 7a 65 72 2d 6e 61 6d 65 3e 2c 20 3c 73 71 6c  izer-name>, <sql
06b0: 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d  ite3_tokenizer_m
06c0: 6f 64 75 6c 65 20 70 74 72 3e 29 3b 0a 20 20 0a  odule ptr>);.  .
06d0: 20 20 57 68 65 72 65 20 3c 74 6f 6b 65 6e 69 7a    Where <tokeniz
06e0: 65 72 2d 6e 61 6d 65 3e 20 69 73 20 61 20 73 74  er-name> is a st
06f0: 72 69 6e 67 20 69 64 65 6e 74 69 66 79 69 6e 67  ring identifying
0700: 20 74 68 65 20 74 6f 6b 65 6e 69 7a 65 72 20 61   the tokenizer a
0710: 6e 64 0a 20 20 3c 73 71 6c 69 74 65 33 5f 74 6f  nd.  <sqlite3_to
0720: 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 70  kenizer_module p
0730: 74 72 3e 20 69 73 20 61 20 70 6f 69 6e 74 65 72  tr> is a pointer
0740: 20 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f 74   to an sqlite3_t
0750: 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 0a  okenizer_module.
0760: 20 20 73 74 72 75 63 74 75 72 65 20 65 6e 63 6f    structure enco
0770: 64 65 64 20 61 73 20 61 6e 20 53 51 4c 20 62 6c  ded as an SQL bl
0780: 6f 62 2e 20 49 66 20 74 68 65 20 73 65 63 6f 6e  ob. If the secon
0790: 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20 70 72  d argument is pr
07a0: 65 73 65 6e 74 2c 0a 20 20 69 74 20 69 73 20 72  esent,.  it is r
07b0: 65 67 69 73 74 65 72 65 64 20 61 73 20 74 6f 6b  egistered as tok
07c0: 65 6e 69 7a 65 72 20 3c 74 6f 6b 65 6e 69 7a 65  enizer <tokenize
07d0: 72 2d 6e 61 6d 65 3e 20 61 6e 64 20 61 20 63 6f  r-name> and a co
07e0: 70 79 20 6f 66 20 69 74 0a 20 20 72 65 74 75 72  py of it.  retur
07f0: 6e 65 64 2e 20 49 66 20 6f 6e 6c 79 20 6f 6e 65  ned. If only one
0800: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 70 61 73   argument is pas
0810: 73 65 64 2c 20 61 20 70 6f 69 6e 74 65 72 20 74  sed, a pointer t
0820: 6f 20 74 68 65 20 74 6f 6b 65 6e 69 7a 65 72 0a  o the tokenizer.
0830: 20 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e    implementation
0840: 20 63 75 72 72 65 6e 74 6c 79 20 72 65 67 69 73   currently regis
0850: 74 65 72 65 64 20 61 73 20 3c 74 6f 6b 65 6e 69  tered as <tokeni
0860: 7a 65 72 2d 6e 61 6d 65 3e 20 69 73 20 72 65 74  zer-name> is ret
0870: 75 72 6e 65 64 2c 0a 20 20 65 6e 63 6f 64 65 64  urned,.  encoded
0880: 20 61 73 20 61 20 62 6c 6f 62 2e 20 4f 72 2c 20   as a blob. Or, 
0890: 69 66 20 6e 6f 20 73 75 63 68 20 74 6f 6b 65 6e  if no such token
08a0: 69 7a 65 72 20 65 78 69 73 74 73 2c 20 61 6e 20  izer exists, an 
08b0: 53 51 4c 20 65 78 63 65 70 74 69 6f 6e 0a 20 20  SQL exception.  
08c0: 28 65 72 72 6f 72 29 20 69 73 20 72 61 69 73 65  (error) is raise
08d0: 64 2e 0a 0a 20 20 53 45 43 55 52 49 54 59 3a 20  d...  SECURITY: 
08e0: 49 66 20 74 68 65 20 66 74 73 33 20 65 78 74 65  If the fts3 exte
08f0: 6e 73 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e  nsion is used in
0900: 20 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20   an environment 
0910: 77 68 65 72 65 20 70 6f 74 65 6e 74 69 61 6c 6c  where potentiall
0920: 79 0a 20 20 20 20 6d 61 6c 69 63 69 6f 75 73 20  y.    malicious 
0930: 75 73 65 72 73 20 6d 61 79 20 65 78 65 63 75 74  users may execut
0940: 65 20 61 72 62 69 74 72 61 72 79 20 53 51 4c 20  e arbitrary SQL 
0950: 28 69 2e 65 2e 20 67 65 61 72 73 29 2c 20 74 68  (i.e. gears), th
0960: 65 79 20 73 68 6f 75 6c 64 20 62 65 0a 20 20 20  ey should be.   
0970: 20 70 72 65 76 65 6e 74 65 64 20 66 72 6f 6d 20   prevented from 
0980: 69 6e 76 6f 6b 69 6e 67 20 74 68 65 20 66 74 73  invoking the fts
0990: 33 5f 74 6f 6b 65 6e 69 7a 65 72 28 29 20 66 75  3_tokenizer() fu
09a0: 6e 63 74 69 6f 6e 2c 20 70 6f 73 73 69 62 6c 79  nction, possibly
09b0: 20 75 73 69 6e 67 20 74 68 65 0a 20 20 20 20 61   using the.    a
09c0: 75 74 68 6f 72 69 73 61 74 69 6f 6e 20 63 61 6c  uthorisation cal
09d0: 6c 62 61 63 6b 2e 0a 0a 20 20 53 65 65 20 22 53  lback...  See "S
09e0: 61 6d 70 6c 65 20 63 6f 64 65 22 20 62 65 6c 6f  ample code" belo
09f0: 77 20 66 6f 72 20 61 6e 20 65 78 61 6d 70 6c 65  w for an example
0a00: 20 6f 66 20 63 61 6c 6c 69 6e 67 20 74 68 65 20   of calling the 
0a10: 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 28 29  fts3_tokenizer()
0a20: 0a 20 20 66 75 6e 63 74 69 6f 6e 20 66 72 6f 6d  .  function from
0a30: 20 43 20 63 6f 64 65 2e 0a 0a 33 2e 20 49 43 55   C code...3. ICU
0a40: 20 4c 69 62 72 61 72 79 20 54 6f 6b 65 6e 69 7a   Library Tokeniz
0a50: 65 72 73 0a 0a 20 20 49 66 20 74 68 69 73 20 65  ers..  If this e
0a60: 78 74 65 6e 73 69 6f 6e 20 69 73 20 63 6f 6d 70  xtension is comp
0a70: 69 6c 65 64 20 77 69 74 68 20 74 68 65 20 53 51  iled with the SQ
0a80: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 49 43 55 20  LITE_ENABLE_ICU 
0a90: 70 72 65 2d 70 72 6f 63 65 73 73 6f 72 20 0a 20  pre-processor . 
0aa0: 20 73 79 6d 62 6f 6c 20 64 65 66 69 6e 65 64 2c   symbol defined,
0ab0: 20 74 68 65 6e 20 74 68 65 72 65 20 65 78 69 73   then there exis
0ac0: 74 73 20 61 20 62 75 69 6c 74 2d 69 6e 20 74 6f  ts a built-in to
0ad0: 6b 65 6e 69 7a 65 72 20 6e 61 6d 65 64 20 22 69  kenizer named "i
0ae0: 63 75 22 20 0a 20 20 69 6d 70 6c 65 6d 65 6e 74  cu" .  implement
0af0: 65 64 20 75 73 69 6e 67 20 74 68 65 20 49 43 55  ed using the ICU
0b00: 20 6c 69 62 72 61 72 79 2e 20 54 68 65 20 66 69   library. The fi
0b10: 72 73 74 20 61 72 67 75 6d 65 6e 74 20 70 61 73  rst argument pas
0b20: 73 65 64 20 74 6f 20 74 68 65 0a 20 20 78 43 72  sed to the.  xCr
0b30: 65 61 74 65 28 29 20 6d 65 74 68 6f 64 20 28 73  eate() method (s
0b40: 65 65 20 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65  ee fts3_tokenize
0b50: 72 2e 68 29 20 6f 66 20 74 68 69 73 20 74 6f 6b  r.h) of this tok
0b60: 65 6e 69 7a 65 72 20 6d 61 79 20 62 65 0a 20 20  enizer may be.  
0b70: 61 6e 20 49 43 55 20 6c 6f 63 61 6c 65 20 69 64  an ICU locale id
0b80: 65 6e 74 69 66 69 65 72 2e 20 46 6f 72 20 65 78  entifier. For ex
0b90: 61 6d 70 6c 65 20 22 74 72 5f 54 52 22 20 66 6f  ample "tr_TR" fo
0ba0: 72 20 54 75 72 6b 69 73 68 20 61 73 20 75 73 65  r Turkish as use
0bb0: 64 0a 20 20 69 6e 20 54 75 72 6b 65 79 2c 20 6f  d.  in Turkey, o
0bc0: 72 20 22 65 6e 5f 41 55 22 20 66 6f 72 20 45 6e  r "en_AU" for En
0bd0: 67 6c 69 73 68 20 61 73 20 75 73 65 64 20 69 6e  glish as used in
0be0: 20 41 75 73 74 72 61 6c 69 61 2e 20 46 6f 72 20   Australia. For 
0bf0: 65 78 61 6d 70 6c 65 3a 0a 0a 20 20 20 20 22 43  example:..    "C
0c00: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41  REATE VIRTUAL TA
0c10: 42 4c 45 20 74 68 61 69 5f 74 65 78 74 20 55 53  BLE thai_text US
0c20: 49 4e 47 20 66 74 73 33 28 74 65 78 74 2c 20 74  ING fts3(text, t
0c30: 6f 6b 65 6e 69 7a 65 72 20 69 63 75 20 74 68 5f  okenizer icu th_
0c40: 54 48 29 22 0a 0a 20 20 54 68 65 20 49 43 55 20  TH)"..  The ICU 
0c50: 74 6f 6b 65 6e 69 7a 65 72 20 69 6d 70 6c 65 6d  tokenizer implem
0c60: 65 6e 74 61 74 69 6f 6e 20 69 73 20 76 65 72 79  entation is very
0c70: 20 73 69 6d 70 6c 65 2e 20 49 74 20 73 70 6c 69   simple. It spli
0c80: 74 73 20 74 68 65 20 69 6e 70 75 74 0a 20 20 74  ts the input.  t
0c90: 65 78 74 20 61 63 63 6f 72 64 69 6e 67 20 74 6f  ext according to
0ca0: 20 74 68 65 20 49 43 55 20 72 75 6c 65 73 20 66   the ICU rules f
0cb0: 6f 72 20 66 69 6e 64 69 6e 67 20 77 6f 72 64 20  or finding word 
0cc0: 62 6f 75 6e 64 61 72 69 65 73 20 61 6e 64 20 64  boundaries and d
0cd0: 69 73 63 61 72 64 73 0a 20 20 61 6e 79 20 74 6f  iscards.  any to
0ce0: 6b 65 6e 73 20 74 68 61 74 20 63 6f 6e 73 69 73  kens that consis
0cf0: 74 20 65 6e 74 69 72 65 6c 79 20 6f 66 20 77 68  t entirely of wh
0d00: 69 74 65 2d 73 70 61 63 65 2e 20 54 68 69 73 20  ite-space. This 
0d10: 6d 61 79 20 62 65 20 73 75 69 74 61 62 6c 65 0a  may be suitable.
0d20: 20 20 66 6f 72 20 73 6f 6d 65 20 61 70 70 6c 69    for some appli
0d30: 63 61 74 69 6f 6e 73 20 69 6e 20 73 6f 6d 65 20  cations in some 
0d40: 6c 6f 63 61 6c 65 73 2c 20 62 75 74 20 6e 6f 74  locales, but not
0d50: 20 61 6c 6c 2e 20 49 66 20 6d 6f 72 65 20 63 6f   all. If more co
0d60: 6d 70 6c 65 78 0a 20 20 70 72 6f 63 65 73 73 69  mplex.  processi
0d70: 6e 67 20 69 73 20 72 65 71 75 69 72 65 64 2c 20  ng is required, 
0d80: 66 6f 72 20 65 78 61 6d 70 6c 65 20 74 6f 20 69  for example to i
0d90: 6d 70 6c 65 6d 65 6e 74 20 73 74 65 6d 6d 69 6e  mplement stemmin
0da0: 67 20 6f 72 20 0a 20 20 64 69 73 63 61 72 64 20  g or .  discard 
0db0: 70 75 6e 63 74 75 61 74 69 6f 6e 2c 20 74 68 69  punctuation, thi
0dc0: 73 20 63 61 6e 20 62 65 20 64 6f 6e 65 20 62 79  s can be done by
0dd0: 20 63 72 65 61 74 69 6e 67 20 61 20 74 6f 6b 65   creating a toke
0de0: 6e 69 7a 65 72 20 0a 20 20 69 6d 70 6c 65 6d 65  nizer .  impleme
0df0: 6e 74 61 74 69 6f 6e 20 74 68 61 74 20 75 73 65  ntation that use
0e00: 73 20 74 68 65 20 49 43 55 20 74 6f 6b 65 6e 69  s the ICU tokeni
0e10: 7a 65 72 20 61 73 20 70 61 72 74 20 6f 66 20 69  zer as part of i
0e20: 74 73 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ts implementatio
0e30: 6e 2e 0a 0a 20 20 57 68 65 6e 20 75 73 69 6e 67  n...  When using
0e40: 20 74 68 65 20 49 43 55 20 74 6f 6b 65 6e 69 7a   the ICU tokeniz
0e50: 65 72 20 74 68 69 73 20 77 61 79 2c 20 69 74 20  er this way, it 
0e60: 69 73 20 73 61 66 65 20 74 6f 20 6f 76 65 72 77  is safe to overw
0e70: 72 69 74 65 20 74 68 65 0a 20 20 63 6f 6e 74 65  rite the.  conte
0e80: 6e 74 73 20 6f 66 20 74 68 65 20 73 74 72 69 6e  nts of the strin
0e90: 67 73 20 72 65 74 75 72 6e 65 64 20 62 79 20 74  gs returned by t
0ea0: 68 65 20 78 4e 65 78 74 28 29 20 6d 65 74 68 6f  he xNext() metho
0eb0: 64 20 28 73 65 65 0a 20 20 66 74 73 33 5f 74 6f  d (see.  fts3_to
0ec0: 6b 65 6e 69 7a 65 72 2e 68 29 2e 0a 0a 34 2e 20  kenizer.h)...4. 
0ed0: 53 61 6d 70 6c 65 20 63 6f 64 65 2e 0a 0a 20 20  Sample code...  
0ee0: 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 77  The following tw
0ef0: 6f 20 63 6f 64 65 20 73 61 6d 70 6c 65 73 20 69  o code samples i
0f00: 6c 6c 75 73 74 72 61 74 65 20 74 68 65 20 77 61  llustrate the wa
0f10: 79 20 43 20 63 6f 64 65 20 73 68 6f 75 6c 64 20  y C code should 
0f20: 69 6e 76 6f 6b 65 0a 20 20 74 68 65 20 66 74 73  invoke.  the fts
0f30: 33 5f 74 6f 6b 65 6e 69 7a 65 72 28 29 20 73 63  3_tokenizer() sc
0f40: 61 6c 61 72 20 66 75 6e 63 74 69 6f 6e 3a 0a 0a  alar function:..
0f50: 20 20 20 20 20 20 69 6e 74 20 72 65 67 69 73 74        int regist
0f60: 65 72 54 6f 6b 65 6e 69 7a 65 72 28 0a 20 20 20  erTokenizer(.   
0f70: 20 20 20 20 20 73 71 6c 69 74 65 33 20 2a 64 62       sqlite3 *db
0f80: 2c 20 0a 20 20 20 20 20 20 20 20 63 68 61 72 20  , .        char 
0f90: 2a 7a 4e 61 6d 65 2c 20 0a 20 20 20 20 20 20 20  *zName, .       
0fa0: 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 74   const sqlite3_t
0fb0: 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20  okenizer_module 
0fc0: 2a 70 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20  *p.      ){.    
0fd0: 20 20 20 20 69 6e 74 20 72 63 3b 0a 20 20 20 20      int rc;.    
0fe0: 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74      sqlite3_stmt
0ff0: 20 2a 70 53 74 6d 74 3b 0a 20 20 20 20 20 20 20   *pStmt;.       
1000: 20 63 6f 6e 73 74 20 63 68 61 72 20 7a 53 71 6c   const char zSql
1010: 5b 5d 20 3d 20 22 53 45 4c 45 43 54 20 66 74 73  [] = "SELECT fts
1020: 33 5f 74 6f 6b 65 6e 69 7a 65 72 28 3f 2c 20 3f  3_tokenizer(?, ?
1030: 29 22 3b 0a 20 20 20 20 20 20 0a 20 20 20 20 20  )";.      .     
1040: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
1050: 70 72 65 70 61 72 65 5f 76 32 28 64 62 2c 20 7a  prepare_v2(db, z
1060: 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c  Sql, -1, &pStmt,
1070: 20 30 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28   0);.        if(
1080: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
1090: 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75  {.          retu
10a0: 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 20 20 7d  rn rc;.        }
10b0: 0a 20 20 20 20 20 20 0a 20 20 20 20 20 20 20 20  .      .        
10c0: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65 78  sqlite3_bind_tex
10d0: 74 28 70 53 74 6d 74 2c 20 31 2c 20 7a 4e 61 6d  t(pStmt, 1, zNam
10e0: 65 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 53 54  e, -1, SQLITE_ST
10f0: 41 54 49 43 29 3b 0a 20 20 20 20 20 20 20 20 73  ATIC);.        s
1100: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 62 6c 6f 62  qlite3_bind_blob
1110: 28 70 53 74 6d 74 2c 20 32 2c 20 26 70 2c 20 73  (pStmt, 2, &p, s
1120: 69 7a 65 6f 66 28 70 29 2c 20 53 51 4c 49 54 45  izeof(p), SQLITE
1130: 5f 53 54 41 54 49 43 29 3b 0a 20 20 20 20 20 20  _STATIC);.      
1140: 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70    sqlite3_step(p
1150: 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 0a 20 20  Stmt);.      .  
1160: 20 20 20 20 20 20 72 65 74 75 72 6e 20 73 71 6c        return sql
1170: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
1180: 74 6d 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  tmt);.      }.  
1190: 20 20 20 20 0a 20 20 20 20 20 20 69 6e 74 20 71      .      int q
11a0: 75 65 72 79 54 6f 6b 65 6e 69 7a 65 72 28 0a 20  ueryTokenizer(. 
11b0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 20 2a         sqlite3 *
11c0: 64 62 2c 20 0a 20 20 20 20 20 20 20 20 63 68 61  db, .        cha
11d0: 72 20 2a 7a 4e 61 6d 65 2c 20 20 0a 20 20 20 20  r *zName,  .    
11e0: 20 20 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65      const sqlite
11f0: 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75  3_tokenizer_modu
1200: 6c 65 20 2a 2a 70 70 0a 20 20 20 20 20 20 29 7b  le **pp.      ){
1210: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 72 63 3b  .        int rc;
1220: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
1230: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20  _stmt *pStmt;.  
1240: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
1250: 20 7a 53 71 6c 5b 5d 20 3d 20 22 53 45 4c 45 43   zSql[] = "SELEC
1260: 54 20 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72  T fts3_tokenizer
1270: 28 3f 29 22 3b 0a 20 20 20 20 20 20 0a 20 20 20  (?)";.      .   
1280: 20 20 20 20 20 2a 70 70 20 3d 20 30 3b 0a 20 20       *pp = 0;.  
1290: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
12a0: 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28 64 62  e3_prepare_v2(db
12b0: 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74  , zSql, -1, &pSt
12c0: 6d 74 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20  mt, 0);.        
12d0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
12e0: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72  K ){.          r
12f0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20  eturn rc;.      
1300: 20 20 7d 0a 20 20 20 20 20 20 0a 20 20 20 20 20    }.      .     
1310: 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
1320: 74 65 78 74 28 70 53 74 6d 74 2c 20 31 2c 20 7a  text(pStmt, 1, z
1330: 4e 61 6d 65 2c 20 2d 31 2c 20 53 51 4c 49 54 45  Name, -1, SQLITE
1340: 5f 53 54 41 54 49 43 29 3b 0a 20 20 20 20 20 20  _STATIC);.      
1350: 20 20 69 66 28 20 53 51 4c 49 54 45 5f 52 4f 57    if( SQLITE_ROW
1360: 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70  ==sqlite3_step(p
1370: 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 20 20 20  Stmt) ){.       
1380: 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 63     if( sqlite3_c
1390: 6f 6c 75 6d 6e 5f 74 79 70 65 28 70 53 74 6d 74  olumn_type(pStmt
13a0: 2c 20 30 29 3d 3d 53 51 4c 49 54 45 5f 42 4c 4f  , 0)==SQLITE_BLO
13b0: 42 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  B ){.           
13c0: 20 6d 65 6d 63 70 79 28 70 70 2c 20 73 71 6c 69   memcpy(pp, sqli
13d0: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28  te3_column_blob(
13e0: 70 53 74 6d 74 2c 20 30 29 2c 20 73 69 7a 65 6f  pStmt, 0), sizeo
13f0: 66 28 2a 70 70 29 29 3b 0a 20 20 20 20 20 20 20  f(*pp));.       
1400: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20     }.        }. 
1410: 20 20 20 20 20 0a 20 20 20 20 20 20 20 20 72 65       .        re
1420: 74 75 72 6e 20 73 71 6c 69 74 65 33 5f 66 69 6e  turn sqlite3_fin
1430: 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20  alize(pStmt);.  
1440: 20 20 20 20 7d 0a                                    }.