/ Hex Artifact Content
Login

Artifact b26f0d2fae967fbe5722f82d08506d35f10ac4e7:


0000: 2f 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f 72  /*.** The author
0010: 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79 72   disclaims copyr
0020: 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f 75  ight to this sou
0030: 72 63 65 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 2a  rce code..**.***
0040: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0050: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0060: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0070: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0080: 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  ******.** Implem
0090: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
00a0: 22 73 69 6d 70 6c 65 22 20 66 75 6c 6c 2d 74 65  "simple" full-te
00b0: 78 74 2d 73 65 61 72 63 68 20 74 6f 6b 65 6e 69  xt-search tokeni
00c0: 7a 65 72 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54  zer..*/../*.** T
00d0: 68 65 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20  he code in this 
00e0: 66 69 6c 65 20 69 73 20 6f 6e 6c 79 20 63 6f 6d  file is only com
00f0: 70 69 6c 65 64 20 69 66 3a 0a 2a 2a 0a 2a 2a 20  piled if:.**.** 
0100: 20 20 20 20 2a 20 54 68 65 20 46 54 53 32 20 6d      * The FTS2 m
0110: 6f 64 75 6c 65 20 69 73 20 62 65 69 6e 67 20 62  odule is being b
0120: 75 69 6c 74 20 61 73 20 61 6e 20 65 78 74 65 6e  uilt as an exten
0130: 73 69 6f 6e 0a 2a 2a 20 20 20 20 20 20 20 28 69  sion.**       (i
0140: 6e 20 77 68 69 63 68 20 63 61 73 65 20 53 51 4c  n which case SQL
0150: 49 54 45 5f 43 4f 52 45 20 69 73 20 6e 6f 74 20  ITE_CORE is not 
0160: 64 65 66 69 6e 65 64 29 2c 20 6f 72 0a 2a 2a 0a  defined), or.**.
0170: 2a 2a 20 20 20 20 20 2a 20 54 68 65 20 46 54 53  **     * The FTS
0180: 32 20 6d 6f 64 75 6c 65 20 69 73 20 62 65 69 6e  2 module is bein
0190: 67 20 62 75 69 6c 74 20 69 6e 74 6f 20 74 68 65  g built into the
01a0: 20 63 6f 72 65 20 6f 66 0a 2a 2a 20 20 20 20 20   core of.**     
01b0: 20 20 53 51 4c 69 74 65 20 28 69 6e 20 77 68 69    SQLite (in whi
01c0: 63 68 20 63 61 73 65 20 53 51 4c 49 54 45 5f 45  ch case SQLITE_E
01d0: 4e 41 42 4c 45 5f 46 54 53 32 20 69 73 20 64 65  NABLE_FTS2 is de
01e0: 66 69 6e 65 64 29 2e 0a 2a 2f 0a 23 69 66 20 21  fined)..*/.#if !
01f0: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 43  defined(SQLITE_C
0200: 4f 52 45 29 20 7c 7c 20 64 65 66 69 6e 65 64 28  ORE) || defined(
0210: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54  SQLITE_ENABLE_FT
0220: 53 32 29 0a 0a 0a 23 69 6e 63 6c 75 64 65 20 3c  S2)...#include <
0230: 61 73 73 65 72 74 2e 68 3e 0a 23 69 66 20 21 64  assert.h>.#if !d
0240: 65 66 69 6e 65 64 28 5f 5f 41 50 50 4c 45 5f 5f  efined(__APPLE__
0250: 29 0a 23 69 6e 63 6c 75 64 65 20 3c 6d 61 6c 6c  ).#include <mall
0260: 6f 63 2e 68 3e 0a 23 65 6c 73 65 0a 23 69 6e 63  oc.h>.#else.#inc
0270: 6c 75 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a  lude <stdlib.h>.
0280: 23 65 6e 64 69 66 0a 23 69 6e 63 6c 75 64 65 20  #endif.#include 
0290: 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75  <stdio.h>.#inclu
02a0: 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69  de <string.h>.#i
02b0: 6e 63 6c 75 64 65 20 3c 63 74 79 70 65 2e 68 3e  nclude <ctype.h>
02c0: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 66 74 73 32  ..#include "fts2
02d0: 5f 74 6f 6b 65 6e 69 7a 65 72 2e 68 22 0a 0a 74  _tokenizer.h"..t
02e0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 73 69  ypedef struct si
02f0: 6d 70 6c 65 5f 74 6f 6b 65 6e 69 7a 65 72 20 7b  mple_tokenizer {
0300: 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  .  sqlite3_token
0310: 69 7a 65 72 20 62 61 73 65 3b 0a 20 20 63 68 61  izer base;.  cha
0320: 72 20 64 65 6c 69 6d 5b 31 32 38 5d 3b 20 20 20  r delim[128];   
0330: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 66 6c 61            /* fla
0340: 67 20 41 53 43 49 49 20 64 65 6c 69 6d 69 74 65  g ASCII delimite
0350: 72 73 20 2a 2f 0a 7d 20 73 69 6d 70 6c 65 5f 74  rs */.} simple_t
0360: 6f 6b 65 6e 69 7a 65 72 3b 0a 0a 74 79 70 65 64  okenizer;..typed
0370: 65 66 20 73 74 72 75 63 74 20 73 69 6d 70 6c 65  ef struct simple
0380: 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f  _tokenizer_curso
0390: 72 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f  r {.  sqlite3_to
03a0: 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72 20 62  kenizer_cursor b
03b0: 61 73 65 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61  ase;.  const cha
03c0: 72 20 2a 70 49 6e 70 75 74 3b 20 20 20 20 20 20  r *pInput;      
03d0: 20 20 20 20 2f 2a 20 69 6e 70 75 74 20 77 65 20      /* input we 
03e0: 61 72 65 20 74 6f 6b 65 6e 69 7a 69 6e 67 20 2a  are tokenizing *
03f0: 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 73 3b 20  /.  int nBytes; 
0400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0410: 20 2f 2a 20 73 69 7a 65 20 6f 66 20 74 68 65 20   /* size of the 
0420: 69 6e 70 75 74 20 2a 2f 0a 20 20 69 6e 74 20 69  input */.  int i
0430: 4f 66 66 73 65 74 3b 20 20 20 20 20 20 20 20 20  Offset;         
0440: 20 20 20 20 20 20 20 20 2f 2a 20 63 75 72 72 65          /* curre
0450: 6e 74 20 70 6f 73 69 74 69 6f 6e 20 69 6e 20 70  nt position in p
0460: 49 6e 70 75 74 20 2a 2f 0a 20 20 69 6e 74 20 69  Input */.  int i
0470: 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20 20 20  Token;          
0480: 20 20 20 20 20 20 20 20 2f 2a 20 69 6e 64 65 78          /* index
0490: 20 6f 66 20 6e 65 78 74 20 74 6f 6b 65 6e 20 74   of next token t
04a0: 6f 20 62 65 20 72 65 74 75 72 6e 65 64 20 2a 2f  o be returned */
04b0: 0a 20 20 63 68 61 72 20 2a 70 54 6f 6b 65 6e 3b  .  char *pToken;
04c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04d0: 2f 2a 20 73 74 6f 72 61 67 65 20 66 6f 72 20 63  /* storage for c
04e0: 75 72 72 65 6e 74 20 74 6f 6b 65 6e 20 2a 2f 0a  urrent token */.
04f0: 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 41 6c 6c 6f    int nTokenAllo
0500: 63 61 74 65 64 3b 20 20 20 20 20 20 20 20 20 2f  cated;         /
0510: 2a 20 73 70 61 63 65 20 61 6c 6c 6f 63 61 74 65  * space allocate
0520: 64 20 74 6f 20 7a 54 6f 6b 65 6e 20 62 75 66 66  d to zToken buff
0530: 65 72 20 2a 2f 0a 7d 20 73 69 6d 70 6c 65 5f 74  er */.} simple_t
0540: 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72 3b  okenizer_cursor;
0550: 0a 0a 0a 2f 2a 20 46 6f 72 77 61 72 64 20 64 65  .../* Forward de
0560: 63 6c 61 72 61 74 69 6f 6e 20 2a 2f 0a 73 74 61  claration */.sta
0570: 74 69 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65  tic const sqlite
0580: 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75  3_tokenizer_modu
0590: 6c 65 20 73 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a  le simpleTokeniz
05a0: 65 72 4d 6f 64 75 6c 65 3b 0a 0a 73 74 61 74 69  erModule;..stati
05b0: 63 20 69 6e 74 20 69 73 44 65 6c 69 6d 28 73 69  c int isDelim(si
05c0: 6d 70 6c 65 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a  mple_tokenizer *
05d0: 74 2c 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  t, unsigned char
05e0: 20 63 29 7b 0a 20 20 72 65 74 75 72 6e 20 63 3c   c){.  return c<
05f0: 30 78 38 30 20 26 26 20 74 2d 3e 64 65 6c 69 6d  0x80 && t->delim
0600: 5b 63 5d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72  [c];.}../*.** Cr
0610: 65 61 74 65 20 61 20 6e 65 77 20 74 6f 6b 65 6e  eate a new token
0620: 69 7a 65 72 20 69 6e 73 74 61 6e 63 65 2e 0a 2a  izer instance..*
0630: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 69 6d  /.static int sim
0640: 70 6c 65 43 72 65 61 74 65 28 0a 20 20 69 6e 74  pleCreate(.  int
0650: 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61   argc, const cha
0660: 72 20 2a 20 63 6f 6e 73 74 20 2a 61 72 67 76 2c  r * const *argv,
0670: 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  .  sqlite3_token
0680: 69 7a 65 72 20 2a 2a 70 70 54 6f 6b 65 6e 69 7a  izer **ppTokeniz
0690: 65 72 0a 29 7b 0a 20 20 73 69 6d 70 6c 65 5f 74  er.){.  simple_t
06a0: 6f 6b 65 6e 69 7a 65 72 20 2a 74 3b 0a 0a 20 20  okenizer *t;..  
06b0: 74 20 3d 20 28 73 69 6d 70 6c 65 5f 74 6f 6b 65  t = (simple_toke
06c0: 6e 69 7a 65 72 20 2a 29 20 63 61 6c 6c 6f 63 28  nizer *) calloc(
06d0: 73 69 7a 65 6f 66 28 73 69 6d 70 6c 65 5f 74 6f  sizeof(simple_to
06e0: 6b 65 6e 69 7a 65 72 29 2c 20 31 29 3b 0a 20 20  kenizer), 1);.  
06f0: 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 44  /* TODO(shess) D
0700: 65 6c 69 6d 69 74 65 72 73 20 6e 65 65 64 20 74  elimiters need t
0710: 6f 20 72 65 6d 61 69 6e 20 74 68 65 20 73 61 6d  o remain the sam
0720: 65 20 66 72 6f 6d 20 72 75 6e 20 74 6f 20 72 75  e from run to ru
0730: 6e 2c 0a 20 20 2a 2a 20 65 6c 73 65 20 77 65 20  n,.  ** else we 
0740: 6e 65 65 64 20 74 6f 20 72 65 69 6e 64 65 78 2e  need to reindex.
0750: 20 20 4f 6e 65 20 73 6f 6c 75 74 69 6f 6e 20 77    One solution w
0760: 6f 75 6c 64 20 62 65 20 61 20 6d 65 74 61 2d 74  ould be a meta-t
0770: 61 62 6c 65 20 74 6f 0a 20 20 2a 2a 20 74 72 61  able to.  ** tra
0780: 63 6b 20 73 75 63 68 20 69 6e 66 6f 72 6d 61 74  ck such informat
0790: 69 6f 6e 20 69 6e 20 74 68 65 20 64 61 74 61 62  ion in the datab
07a0: 61 73 65 2c 20 74 68 65 6e 20 77 65 27 64 20 6f  ase, then we'd o
07b0: 6e 6c 79 20 77 61 6e 74 20 74 68 69 73 0a 20 20  nly want this.  
07c0: 2a 2a 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f  ** information o
07d0: 6e 20 74 68 65 20 69 6e 69 74 69 61 6c 20 63 72  n the initial cr
07e0: 65 61 74 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  eate..  */.  if(
07f0: 20 61 72 67 63 3e 31 20 29 7b 0a 20 20 20 20 69   argc>1 ){.    i
0800: 6e 74 20 69 2c 20 6e 20 3d 20 73 74 72 6c 65 6e  nt i, n = strlen
0810: 28 61 72 67 76 5b 31 5d 29 3b 0a 20 20 20 20 66  (argv[1]);.    f
0820: 6f 72 28 69 3d 30 3b 20 69 3c 6e 3b 20 69 2b 2b  or(i=0; i<n; i++
0830: 29 7b 0a 20 20 20 20 20 20 75 6e 73 69 67 6e 65  ){.      unsigne
0840: 64 20 63 68 61 72 20 63 68 20 3d 20 61 72 67 76  d char ch = argv
0850: 5b 31 5d 5b 69 5d 3b 0a 20 20 20 20 20 20 2f 2a  [1][i];.      /*
0860: 20 57 65 20 65 78 70 6c 69 63 69 74 6c 79 20 64   We explicitly d
0870: 6f 6e 27 74 20 73 75 70 70 6f 72 74 20 55 54 46  on't support UTF
0880: 2d 38 20 64 65 6c 69 6d 69 74 65 72 73 20 66 6f  -8 delimiters fo
0890: 72 20 6e 6f 77 2e 20 2a 2f 0a 20 20 20 20 20 20  r now. */.      
08a0: 69 66 28 20 63 68 3e 3d 30 78 38 30 20 29 7b 0a  if( ch>=0x80 ){.
08b0: 20 20 20 20 20 20 20 20 66 72 65 65 28 74 29 3b          free(t);
08c0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
08d0: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
08e0: 20 20 20 20 7d 0a 20 20 20 20 20 20 74 2d 3e 64      }.      t->d
08f0: 65 6c 69 6d 5b 63 68 5d 20 3d 20 31 3b 0a 20 20  elim[ch] = 1;.  
0900: 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20    }.  } else {. 
0910: 20 20 20 2f 2a 20 4d 61 72 6b 20 6e 6f 6e 2d 61     /* Mark non-a
0920: 6c 70 68 61 6e 75 6d 65 72 69 63 20 41 53 43 49  lphanumeric ASCI
0930: 49 20 63 68 61 72 61 63 74 65 72 73 20 61 73 20  I characters as 
0940: 64 65 6c 69 6d 69 74 65 72 73 20 2a 2f 0a 20 20  delimiters */.  
0950: 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72    int i;.    for
0960: 28 69 3d 31 3b 20 69 3c 30 78 38 30 3b 20 69 2b  (i=1; i<0x80; i+
0970: 2b 29 7b 0a 20 20 20 20 20 20 74 2d 3e 64 65 6c  +){.      t->del
0980: 69 6d 5b 69 5d 20 3d 20 21 69 73 61 6c 6e 75 6d  im[i] = !isalnum
0990: 28 69 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  (i);.    }.  }..
09a0: 20 20 2a 70 70 54 6f 6b 65 6e 69 7a 65 72 20 3d    *ppTokenizer =
09b0: 20 26 74 2d 3e 62 61 73 65 3b 0a 20 20 72 65 74   &t->base;.  ret
09c0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
09d0: 0a 0a 2f 2a 0a 2a 2a 20 44 65 73 74 72 6f 79 20  ../*.** Destroy 
09e0: 61 20 74 6f 6b 65 6e 69 7a 65 72 0a 2a 2f 0a 73  a tokenizer.*/.s
09f0: 74 61 74 69 63 20 69 6e 74 20 73 69 6d 70 6c 65  tatic int simple
0a00: 44 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f  Destroy(sqlite3_
0a10: 74 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 65  tokenizer *pToke
0a20: 6e 69 7a 65 72 29 7b 0a 20 20 66 72 65 65 28 70  nizer){.  free(p
0a30: 54 6f 6b 65 6e 69 7a 65 72 29 3b 0a 20 20 72 65  Tokenizer);.  re
0a40: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
0a50: 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 65 70 61 72 65  }../*.** Prepare
0a60: 20 74 6f 20 62 65 67 69 6e 20 74 6f 6b 65 6e 69   to begin tokeni
0a70: 7a 69 6e 67 20 61 20 70 61 72 74 69 63 75 6c 61  zing a particula
0a80: 72 20 73 74 72 69 6e 67 2e 20 20 54 68 65 20 69  r string.  The i
0a90: 6e 70 75 74 0a 2a 2a 20 73 74 72 69 6e 67 20 74  nput.** string t
0aa0: 6f 20 62 65 20 74 6f 6b 65 6e 69 7a 65 64 20 69  o be tokenized i
0ab0: 73 20 70 49 6e 70 75 74 5b 30 2e 2e 6e 42 79 74  s pInput[0..nByt
0ac0: 65 73 2d 31 5d 2e 20 20 41 20 63 75 72 73 6f 72  es-1].  A cursor
0ad0: 0a 2a 2a 20 75 73 65 64 20 74 6f 20 69 6e 63 72  .** used to incr
0ae0: 65 6d 65 6e 74 61 6c 6c 79 20 74 6f 6b 65 6e 69  ementally tokeni
0af0: 7a 65 20 74 68 69 73 20 73 74 72 69 6e 67 20 69  ze this string i
0b00: 73 20 72 65 74 75 72 6e 65 64 20 69 6e 20 0a 2a  s returned in .*
0b10: 2a 20 2a 70 70 43 75 72 73 6f 72 2e 0a 2a 2f 0a  * *ppCursor..*/.
0b20: 73 74 61 74 69 63 20 69 6e 74 20 73 69 6d 70 6c  static int simpl
0b30: 65 4f 70 65 6e 28 0a 20 20 73 71 6c 69 74 65 33  eOpen(.  sqlite3
0b40: 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b  _tokenizer *pTok
0b50: 65 6e 69 7a 65 72 2c 20 20 20 20 20 20 20 20 20  enizer,         
0b60: 2f 2a 20 54 68 65 20 74 6f 6b 65 6e 69 7a 65 72  /* The tokenizer
0b70: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
0b80: 20 2a 70 49 6e 70 75 74 2c 20 69 6e 74 20 6e 42   *pInput, int nB
0b90: 79 74 65 73 2c 20 20 20 20 20 20 20 20 2f 2a 20  ytes,        /* 
0ba0: 53 74 72 69 6e 67 20 74 6f 20 62 65 20 74 6f 6b  String to be tok
0bb0: 65 6e 69 7a 65 64 20 2a 2f 0a 20 20 73 71 6c 69  enized */.  sqli
0bc0: 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75  te3_tokenizer_cu
0bd0: 72 73 6f 72 20 2a 2a 70 70 43 75 72 73 6f 72 20  rsor **ppCursor 
0be0: 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 6b 65 6e     /* OUT: Token
0bf0: 69 7a 61 74 69 6f 6e 20 63 75 72 73 6f 72 20 2a  ization cursor *
0c00: 2f 0a 29 7b 0a 20 20 73 69 6d 70 6c 65 5f 74 6f  /.){.  simple_to
0c10: 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72 20 2a  kenizer_cursor *
0c20: 63 3b 0a 0a 20 20 63 20 3d 20 28 73 69 6d 70 6c  c;..  c = (simpl
0c30: 65 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73  e_tokenizer_curs
0c40: 6f 72 20 2a 29 20 6d 61 6c 6c 6f 63 28 73 69 7a  or *) malloc(siz
0c50: 65 6f 66 28 73 69 6d 70 6c 65 5f 74 6f 6b 65 6e  eof(simple_token
0c60: 69 7a 65 72 5f 63 75 72 73 6f 72 29 29 3b 0a 20  izer_cursor));. 
0c70: 20 63 2d 3e 70 49 6e 70 75 74 20 3d 20 70 49 6e   c->pInput = pIn
0c80: 70 75 74 3b 0a 20 20 69 66 28 20 70 49 6e 70 75  put;.  if( pInpu
0c90: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 63 2d 3e 6e  t==0 ){.    c->n
0ca0: 42 79 74 65 73 20 3d 20 30 3b 0a 20 20 7d 65 6c  Bytes = 0;.  }el
0cb0: 73 65 20 69 66 28 20 6e 42 79 74 65 73 3c 30 20  se if( nBytes<0 
0cc0: 29 7b 0a 20 20 20 20 63 2d 3e 6e 42 79 74 65 73  ){.    c->nBytes
0cd0: 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 70   = (int)strlen(p
0ce0: 49 6e 70 75 74 29 3b 0a 20 20 7d 65 6c 73 65 7b  Input);.  }else{
0cf0: 0a 20 20 20 20 63 2d 3e 6e 42 79 74 65 73 20 3d  .    c->nBytes =
0d00: 20 6e 42 79 74 65 73 3b 0a 20 20 7d 0a 20 20 63   nBytes;.  }.  c
0d10: 2d 3e 69 4f 66 66 73 65 74 20 3d 20 30 3b 20 20  ->iOffset = 0;  
0d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0d30: 2a 20 73 74 61 72 74 20 74 6f 6b 65 6e 69 7a 69  * start tokenizi
0d40: 6e 67 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e  ng at the beginn
0d50: 69 6e 67 20 2a 2f 0a 20 20 63 2d 3e 69 54 6f 6b  ing */.  c->iTok
0d60: 65 6e 20 3d 20 30 3b 0a 20 20 63 2d 3e 70 54 6f  en = 0;.  c->pTo
0d70: 6b 65 6e 20 3d 20 4e 55 4c 4c 3b 20 20 20 20 20  ken = NULL;     
0d80: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 6f 20            /* no 
0d90: 73 70 61 63 65 20 61 6c 6c 6f 63 61 74 65 64 2c  space allocated,
0da0: 20 79 65 74 2e 20 2a 2f 0a 20 20 63 2d 3e 6e 54   yet. */.  c->nT
0db0: 6f 6b 65 6e 41 6c 6c 6f 63 61 74 65 64 20 3d 20  okenAllocated = 
0dc0: 30 3b 0a 0a 20 20 2a 70 70 43 75 72 73 6f 72 20  0;..  *ppCursor 
0dd0: 3d 20 26 63 2d 3e 62 61 73 65 3b 0a 20 20 72 65  = &c->base;.  re
0de0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
0df0: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61  }../*.** Close a
0e00: 20 74 6f 6b 65 6e 69 7a 61 74 69 6f 6e 20 63 75   tokenization cu
0e10: 72 73 6f 72 20 70 72 65 76 69 6f 75 73 6c 79 20  rsor previously 
0e20: 6f 70 65 6e 65 64 20 62 79 20 61 20 63 61 6c 6c  opened by a call
0e30: 20 74 6f 0a 2a 2a 20 73 69 6d 70 6c 65 4f 70 65   to.** simpleOpe
0e40: 6e 28 29 20 61 62 6f 76 65 2e 0a 2a 2f 0a 73 74  n() above..*/.st
0e50: 61 74 69 63 20 69 6e 74 20 73 69 6d 70 6c 65 43  atic int simpleC
0e60: 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 74 6f 6b  lose(sqlite3_tok
0e70: 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72 20 2a 70  enizer_cursor *p
0e80: 43 75 72 73 6f 72 29 7b 0a 20 20 73 69 6d 70 6c  Cursor){.  simpl
0e90: 65 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73  e_tokenizer_curs
0ea0: 6f 72 20 2a 63 20 3d 20 28 73 69 6d 70 6c 65 5f  or *c = (simple_
0eb0: 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73 6f 72  tokenizer_cursor
0ec0: 20 2a 29 20 70 43 75 72 73 6f 72 3b 0a 20 20 66   *) pCursor;.  f
0ed0: 72 65 65 28 63 2d 3e 70 54 6f 6b 65 6e 29 3b 0a  ree(c->pToken);.
0ee0: 20 20 66 72 65 65 28 63 29 3b 0a 20 20 72 65 74    free(c);.  ret
0ef0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
0f00: 0a 0a 2f 2a 0a 2a 2a 20 45 78 74 72 61 63 74 20  ../*.** Extract 
0f10: 74 68 65 20 6e 65 78 74 20 74 6f 6b 65 6e 20 66  the next token f
0f20: 72 6f 6d 20 61 20 74 6f 6b 65 6e 69 7a 61 74 69  rom a tokenizati
0f30: 6f 6e 20 63 75 72 73 6f 72 2e 20 20 54 68 65 20  on cursor.  The 
0f40: 63 75 72 73 6f 72 20 6d 75 73 74 0a 2a 2a 20 68  cursor must.** h
0f50: 61 76 65 20 62 65 65 6e 20 6f 70 65 6e 65 64 20  ave been opened 
0f60: 62 79 20 61 20 70 72 69 6f 72 20 63 61 6c 6c 20  by a prior call 
0f70: 74 6f 20 73 69 6d 70 6c 65 4f 70 65 6e 28 29 2e  to simpleOpen().
0f80: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .*/.static int s
0f90: 69 6d 70 6c 65 4e 65 78 74 28 0a 20 20 73 71 6c  impleNext(.  sql
0fa0: 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63  ite3_tokenizer_c
0fb0: 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20  ursor *pCursor, 
0fc0: 20 2f 2a 20 43 75 72 73 6f 72 20 72 65 74 75 72   /* Cursor retur
0fd0: 6e 65 64 20 62 79 20 73 69 6d 70 6c 65 4f 70 65  ned by simpleOpe
0fe0: 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  n */.  const cha
0ff0: 72 20 2a 2a 70 70 54 6f 6b 65 6e 2c 20 20 20 20  r **ppToken,    
1000: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
1010: 54 3a 20 2a 70 70 54 6f 6b 65 6e 20 69 73 20 74  T: *ppToken is t
1020: 68 65 20 74 6f 6b 65 6e 20 74 65 78 74 20 2a 2f  he token text */
1030: 0a 20 20 69 6e 74 20 2a 70 6e 42 79 74 65 73 2c  .  int *pnBytes,
1040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1050: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e         /* OUT: N
1060: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
1070: 6e 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74  n token */.  int
1080: 20 2a 70 69 53 74 61 72 74 4f 66 66 73 65 74 2c   *piStartOffset,
1090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10a0: 20 2f 2a 20 4f 55 54 3a 20 53 74 61 72 74 69 6e   /* OUT: Startin
10b0: 67 20 6f 66 66 73 65 74 20 6f 66 20 74 6f 6b 65  g offset of toke
10c0: 6e 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 69 45 6e  n */.  int *piEn
10d0: 64 4f 66 66 73 65 74 2c 20 20 20 20 20 20 20 20  dOffset,        
10e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
10f0: 54 3a 20 45 6e 64 69 6e 67 20 6f 66 66 73 65 74  T: Ending offset
1100: 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69   of token */.  i
1110: 6e 74 20 2a 70 69 50 6f 73 69 74 69 6f 6e 20 20  nt *piPosition  
1120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1130: 20 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 73 69 74     /* OUT: Posit
1140: 69 6f 6e 20 69 6e 74 65 67 65 72 20 6f 66 20 74  ion integer of t
1150: 6f 6b 65 6e 20 2a 2f 0a 29 7b 0a 20 20 73 69 6d  oken */.){.  sim
1160: 70 6c 65 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75  ple_tokenizer_cu
1170: 72 73 6f 72 20 2a 63 20 3d 20 28 73 69 6d 70 6c  rsor *c = (simpl
1180: 65 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73  e_tokenizer_curs
1190: 6f 72 20 2a 29 20 70 43 75 72 73 6f 72 3b 0a 20  or *) pCursor;. 
11a0: 20 73 69 6d 70 6c 65 5f 74 6f 6b 65 6e 69 7a 65   simple_tokenize
11b0: 72 20 2a 74 20 3d 20 28 73 69 6d 70 6c 65 5f 74  r *t = (simple_t
11c0: 6f 6b 65 6e 69 7a 65 72 20 2a 29 20 70 43 75 72  okenizer *) pCur
11d0: 73 6f 72 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72 3b  sor->pTokenizer;
11e0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  .  unsigned char
11f0: 20 2a 70 20 3d 20 28 75 6e 73 69 67 6e 65 64 20   *p = (unsigned 
1200: 63 68 61 72 20 2a 29 63 2d 3e 70 49 6e 70 75 74  char *)c->pInput
1210: 3b 0a 0a 20 20 77 68 69 6c 65 28 20 63 2d 3e 69  ;..  while( c->i
1220: 4f 66 66 73 65 74 3c 63 2d 3e 6e 42 79 74 65 73  Offset<c->nBytes
1230: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 53 74 61   ){.    int iSta
1240: 72 74 4f 66 66 73 65 74 3b 0a 0a 20 20 20 20 2f  rtOffset;..    /
1250: 2a 20 53 63 61 6e 20 70 61 73 74 20 64 65 6c 69  * Scan past deli
1260: 6d 69 74 65 72 20 63 68 61 72 61 63 74 65 72 73  miter characters
1270: 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 63   */.    while( c
1280: 2d 3e 69 4f 66 66 73 65 74 3c 63 2d 3e 6e 42 79  ->iOffset<c->nBy
1290: 74 65 73 20 26 26 20 69 73 44 65 6c 69 6d 28 74  tes && isDelim(t
12a0: 2c 20 70 5b 63 2d 3e 69 4f 66 66 73 65 74 5d 29  , p[c->iOffset])
12b0: 20 29 7b 0a 20 20 20 20 20 20 63 2d 3e 69 4f 66   ){.      c->iOf
12c0: 66 73 65 74 2b 2b 3b 0a 20 20 20 20 7d 0a 0a 20  fset++;.    }.. 
12d0: 20 20 20 2f 2a 20 43 6f 75 6e 74 20 6e 6f 6e 2d     /* Count non-
12e0: 64 65 6c 69 6d 69 74 65 72 20 63 68 61 72 61 63  delimiter charac
12f0: 74 65 72 73 2e 20 2a 2f 0a 20 20 20 20 69 53 74  ters. */.    iSt
1300: 61 72 74 4f 66 66 73 65 74 20 3d 20 63 2d 3e 69  artOffset = c->i
1310: 4f 66 66 73 65 74 3b 0a 20 20 20 20 77 68 69 6c  Offset;.    whil
1320: 65 28 20 63 2d 3e 69 4f 66 66 73 65 74 3c 63 2d  e( c->iOffset<c-
1330: 3e 6e 42 79 74 65 73 20 26 26 20 21 69 73 44 65  >nBytes && !isDe
1340: 6c 69 6d 28 74 2c 20 70 5b 63 2d 3e 69 4f 66 66  lim(t, p[c->iOff
1350: 73 65 74 5d 29 20 29 7b 0a 20 20 20 20 20 20 63  set]) ){.      c
1360: 2d 3e 69 4f 66 66 73 65 74 2b 2b 3b 0a 20 20 20  ->iOffset++;.   
1370: 20 7d 0a 0a 20 20 20 20 69 66 28 20 63 2d 3e 69   }..    if( c->i
1380: 4f 66 66 73 65 74 3e 69 53 74 61 72 74 4f 66 66  Offset>iStartOff
1390: 73 65 74 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  set ){.      int
13a0: 20 69 2c 20 6e 20 3d 20 63 2d 3e 69 4f 66 66 73   i, n = c->iOffs
13b0: 65 74 2d 69 53 74 61 72 74 4f 66 66 73 65 74 3b  et-iStartOffset;
13c0: 0a 20 20 20 20 20 20 69 66 28 20 6e 3e 63 2d 3e  .      if( n>c->
13d0: 6e 54 6f 6b 65 6e 41 6c 6c 6f 63 61 74 65 64 20  nTokenAllocated 
13e0: 29 7b 0a 20 20 20 20 20 20 20 20 63 2d 3e 6e 54  ){.        c->nT
13f0: 6f 6b 65 6e 41 6c 6c 6f 63 61 74 65 64 20 3d 20  okenAllocated = 
1400: 6e 2b 32 30 3b 0a 20 20 20 20 20 20 20 20 63 2d  n+20;.        c-
1410: 3e 70 54 6f 6b 65 6e 20 3d 20 72 65 61 6c 6c 6f  >pToken = reallo
1420: 63 28 63 2d 3e 70 54 6f 6b 65 6e 2c 20 63 2d 3e  c(c->pToken, c->
1430: 6e 54 6f 6b 65 6e 41 6c 6c 6f 63 61 74 65 64 29  nTokenAllocated)
1440: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
1450: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 3b 20 69 2b  for(i=0; i<n; i+
1460: 2b 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 54  +){.        /* T
1470: 4f 44 4f 28 73 68 65 73 73 29 20 54 68 69 73 20  ODO(shess) This 
1480: 6e 65 65 64 73 20 65 78 70 61 6e 73 69 6f 6e 20  needs expansion 
1490: 74 6f 20 68 61 6e 64 6c 65 20 55 54 46 2d 38 0a  to handle UTF-8.
14a0: 20 20 20 20 20 20 20 20 2a 2a 20 63 61 73 65 2d          ** case-
14b0: 69 6e 73 65 6e 73 69 74 69 76 69 74 79 2e 0a 20  insensitivity.. 
14c0: 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20         */.      
14d0: 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20    unsigned char 
14e0: 63 68 20 3d 20 70 5b 69 53 74 61 72 74 4f 66 66  ch = p[iStartOff
14f0: 73 65 74 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20  set+i];.        
1500: 63 2d 3e 70 54 6f 6b 65 6e 5b 69 5d 20 3d 20 63  c->pToken[i] = c
1510: 68 3c 30 78 38 30 20 3f 20 74 6f 6c 6f 77 65 72  h<0x80 ? tolower
1520: 28 63 68 29 20 3a 20 63 68 3b 0a 20 20 20 20 20  (ch) : ch;.     
1530: 20 7d 0a 20 20 20 20 20 20 2a 70 70 54 6f 6b 65   }.      *ppToke
1540: 6e 20 3d 20 63 2d 3e 70 54 6f 6b 65 6e 3b 0a 20  n = c->pToken;. 
1550: 20 20 20 20 20 2a 70 6e 42 79 74 65 73 20 3d 20       *pnBytes = 
1560: 6e 3b 0a 20 20 20 20 20 20 2a 70 69 53 74 61 72  n;.      *piStar
1570: 74 4f 66 66 73 65 74 20 3d 20 69 53 74 61 72 74  tOffset = iStart
1580: 4f 66 66 73 65 74 3b 0a 20 20 20 20 20 20 2a 70  Offset;.      *p
1590: 69 45 6e 64 4f 66 66 73 65 74 20 3d 20 63 2d 3e  iEndOffset = c->
15a0: 69 4f 66 66 73 65 74 3b 0a 20 20 20 20 20 20 2a  iOffset;.      *
15b0: 70 69 50 6f 73 69 74 69 6f 6e 20 3d 20 63 2d 3e  piPosition = c->
15c0: 69 54 6f 6b 65 6e 2b 2b 3b 0a 0a 20 20 20 20 20  iToken++;..     
15d0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
15e0: 4b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  K;.    }.  }.  r
15f0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 44 4f 4e  eturn SQLITE_DON
1600: 45 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  E;.}../*.** The 
1610: 73 65 74 20 6f 66 20 72 6f 75 74 69 6e 65 73 20  set of routines 
1620: 74 68 61 74 20 69 6d 70 6c 65 6d 65 6e 74 20 74  that implement t
1630: 68 65 20 73 69 6d 70 6c 65 20 74 6f 6b 65 6e 69  he simple tokeni
1640: 7a 65 72 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f  zer.*/.static co
1650: 6e 73 74 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65  nst sqlite3_toke
1660: 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 73 69 6d  nizer_module sim
1670: 70 6c 65 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  pleTokenizerModu
1680: 6c 65 20 3d 20 7b 0a 20 20 30 2c 0a 20 20 73 69  le = {.  0,.  si
1690: 6d 70 6c 65 43 72 65 61 74 65 2c 0a 20 20 73 69  mpleCreate,.  si
16a0: 6d 70 6c 65 44 65 73 74 72 6f 79 2c 0a 20 20 73  mpleDestroy,.  s
16b0: 69 6d 70 6c 65 4f 70 65 6e 2c 0a 20 20 73 69 6d  impleOpen,.  sim
16c0: 70 6c 65 43 6c 6f 73 65 2c 0a 20 20 73 69 6d 70  pleClose,.  simp
16d0: 6c 65 4e 65 78 74 2c 0a 7d 3b 0a 0a 2f 2a 0a 2a  leNext,.};../*.*
16e0: 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  * Allocate a new
16f0: 20 73 69 6d 70 6c 65 20 74 6f 6b 65 6e 69 7a 65   simple tokenize
1700: 72 2e 20 20 52 65 74 75 72 6e 20 61 20 70 6f 69  r.  Return a poi
1710: 6e 74 65 72 20 74 6f 20 74 68 65 20 6e 65 77 0a  nter to the new.
1720: 2a 2a 20 74 6f 6b 65 6e 69 7a 65 72 20 69 6e 20  ** tokenizer in 
1730: 2a 70 70 4d 6f 64 75 6c 65 0a 2a 2f 0a 76 6f 69  *ppModule.*/.voi
1740: 64 20 73 71 6c 69 74 65 33 46 74 73 32 53 69 6d  d sqlite3Fts2Sim
1750: 70 6c 65 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  pleTokenizerModu
1760: 6c 65 28 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f  le(.  sqlite3_to
1770: 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 63  kenizer_module c
1780: 6f 6e 73 74 2a 2a 70 70 4d 6f 64 75 6c 65 0a 29  onst**ppModule.)
1790: 7b 0a 20 20 2a 70 70 4d 6f 64 75 6c 65 20 3d 20  {.  *ppModule = 
17a0: 26 73 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a 65 72  &simpleTokenizer
17b0: 4d 6f 64 75 6c 65 3b 0a 7d 0a 0a 23 65 6e 64 69  Module;.}..#endi
17c0: 66 20 2f 2a 20 21 64 65 66 69 6e 65 64 28 53 51  f /* !defined(SQ
17d0: 4c 49 54 45 5f 43 4f 52 45 29 20 7c 7c 20 64 65  LITE_CORE) || de
17e0: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 45 4e 41  fined(SQLITE_ENA
17f0: 42 4c 45 5f 46 54 53 32 29 20 2a 2f 0a           BLE_FTS2) */.