/ Hex Artifact Content
Login

Artifact a39f7d21c2994d27c959ef9c3505c81542c81432:


0000: 2f 2a 20 66 74 73 31 20 68 61 73 20 61 20 64 65  /* fts1 has a de
0010: 73 69 67 6e 20 66 6c 61 77 20 77 68 69 63 68 20  sign flaw which 
0020: 63 61 6e 20 6c 65 61 64 20 74 6f 20 64 61 74 61  can lead to data
0030: 62 61 73 65 20 63 6f 72 72 75 70 74 69 6f 6e 20  base corruption 
0040: 28 73 65 65 0a 2a 2a 20 62 65 6c 6f 77 29 2e 20  (see.** below). 
0050: 20 49 74 20 69 73 20 72 65 63 6f 6d 6d 65 6e 64   It is recommend
0060: 65 64 20 6e 6f 74 20 74 6f 20 75 73 65 20 69 74  ed not to use it
0070: 20 61 6e 79 20 6c 6f 6e 67 65 72 2c 20 69 6e 73   any longer, ins
0080: 74 65 61 64 20 75 73 65 0a 2a 2a 20 66 74 73 33  tead use.** fts3
0090: 20 28 6f 72 20 68 69 67 68 65 72 29 2e 20 20 49   (or higher).  I
00a0: 66 20 79 6f 75 20 62 65 6c 69 65 76 65 20 74 68  f you believe th
00b0: 61 74 20 79 6f 75 72 20 75 73 65 20 6f 66 20 66  at your use of f
00c0: 74 73 31 20 69 73 20 73 61 66 65 2c 0a 2a 2a 20  ts1 is safe,.** 
00d0: 61 64 64 20 2d 44 53 51 4c 49 54 45 5f 45 4e 41  add -DSQLITE_ENA
00e0: 42 4c 45 5f 42 52 4f 4b 45 4e 5f 46 54 53 31 3d  BLE_BROKEN_FTS1=
00f0: 31 20 74 6f 20 79 6f 75 72 20 43 46 4c 41 47 53  1 to your CFLAGS
0100: 2e 0a 2a 2f 0a 23 69 66 20 28 21 64 65 66 69 6e  ..*/.#if (!defin
0110: 65 64 28 53 51 4c 49 54 45 5f 43 4f 52 45 29 20  ed(SQLITE_CORE) 
0120: 7c 7c 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  || defined(SQLIT
0130: 45 5f 45 4e 41 42 4c 45 5f 46 54 53 31 29 29 20  E_ENABLE_FTS1)) 
0140: 5c 0a 20 20 20 20 20 20 20 20 26 26 20 21 64 65  \.        && !de
0150: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 45 4e 41  fined(SQLITE_ENA
0160: 42 4c 45 5f 42 52 4f 4b 45 4e 5f 46 54 53 31 29  BLE_BROKEN_FTS1)
0170: 0a 23 65 72 72 6f 72 20 66 74 73 31 20 68 61 73  .#error fts1 has
0180: 20 61 20 64 65 73 69 67 6e 20 66 6c 61 77 20 61   a design flaw a
0190: 6e 64 20 68 61 73 20 62 65 65 6e 20 64 65 70 72  nd has been depr
01a0: 65 63 61 74 65 64 2e 0a 23 65 6e 64 69 66 0a 2f  ecated..#endif./
01b0: 2a 20 54 68 65 20 66 6c 61 77 20 69 73 20 74 68  * The flaw is th
01c0: 61 74 20 66 74 73 31 20 75 73 65 73 20 74 68 65  at fts1 uses the
01d0: 20 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65 27 73   content table's
01e0: 20 75 6e 61 6c 69 61 73 65 64 20 72 6f 77 69 64   unaliased rowid
01f0: 20 61 73 0a 2a 2a 20 74 68 65 20 75 6e 69 71 75   as.** the uniqu
0200: 65 20 64 6f 63 69 64 2e 20 20 66 74 73 31 20 65  e docid.  fts1 e
0210: 6d 62 65 64 73 20 74 68 65 20 72 6f 77 69 64 20  mbeds the rowid 
0220: 69 6e 20 74 68 65 20 69 6e 64 65 78 20 69 74 20  in the index it 
0230: 62 75 69 6c 64 73 2c 0a 2a 2a 20 61 6e 64 20 65  builds,.** and e
0240: 78 70 65 63 74 73 20 74 68 65 20 72 6f 77 69 64  xpects the rowid
0250: 20 74 6f 20 6e 6f 74 20 63 68 61 6e 67 65 2e 20   to not change. 
0260: 20 54 68 65 20 53 51 4c 69 74 65 20 56 41 43 55   The SQLite VACU
0270: 55 4d 20 6f 70 65 72 61 74 69 6f 6e 0a 2a 2a 20  UM operation.** 
0280: 77 69 6c 6c 20 72 65 6e 75 6d 62 65 72 20 73 75  will renumber su
0290: 63 68 20 72 6f 77 69 64 73 2c 20 74 68 65 72 65  ch rowids, there
02a0: 62 79 20 62 72 65 61 6b 69 6e 67 20 66 74 73 31  by breaking fts1
02b0: 2e 20 20 49 66 20 79 6f 75 20 61 72 65 20 75 73  .  If you are us
02c0: 69 6e 67 0a 2a 2a 20 66 74 73 31 20 69 6e 20 61  ing.** fts1 in a
02d0: 20 73 79 73 74 65 6d 20 77 68 69 63 68 20 68 61   system which ha
02e0: 73 20 64 69 73 61 62 6c 65 64 20 56 41 43 55 55  s disabled VACUU
02f0: 4d 2c 20 74 68 65 6e 20 79 6f 75 20 63 61 6e 20  M, then you can 
0300: 63 6f 6e 74 69 6e 75 65 0a 2a 2a 20 74 6f 20 75  continue.** to u
0310: 73 65 20 69 74 20 73 61 66 65 6c 79 2e 20 20 4e  se it safely.  N
0320: 6f 74 65 20 74 68 61 74 20 50 52 41 47 4d 41 20  ote that PRAGMA 
0330: 61 75 74 6f 5f 76 61 63 75 75 6d 20 64 6f 65 73  auto_vacuum does
0340: 20 4e 4f 54 20 64 69 73 61 62 6c 65 0a 2a 2a 20   NOT disable.** 
0350: 56 41 43 55 55 4d 2c 20 74 68 6f 75 67 68 20 73  VACUUM, though s
0360: 79 73 74 65 6d 73 20 75 73 69 6e 67 20 61 75 74  ystems using aut
0370: 6f 5f 76 61 63 75 75 6d 20 61 72 65 20 75 6e 6c  o_vacuum are unl
0380: 69 6b 65 6c 79 20 74 6f 20 69 6e 76 6f 6b 65 0a  ikely to invoke.
0390: 2a 2a 20 56 41 43 55 55 4d 2e 0a 2a 2a 0a 2a 2a  ** VACUUM..**.**
03a0: 20 66 74 73 31 20 73 68 6f 75 6c 64 20 62 65 20   fts1 should be 
03b0: 73 61 66 65 20 65 76 65 6e 20 61 63 72 6f 73 73  safe even across
03c0: 20 56 41 43 55 55 4d 20 69 66 20 79 6f 75 20 6f   VACUUM if you o
03d0: 6e 6c 79 20 69 6e 73 65 72 74 20 64 6f 63 75 6d  nly insert docum
03e0: 65 6e 74 73 0a 2a 2a 20 61 6e 64 20 6e 65 76 65  ents.** and neve
03f0: 72 20 64 65 6c 65 74 65 2e 0a 2a 2f 0a 0a 2f 2a  r delete..*/../*
0400: 20 54 68 65 20 61 75 74 68 6f 72 20 64 69 73 63   The author disc
0410: 6c 61 69 6d 73 20 63 6f 70 79 72 69 67 68 74 20  laims copyright 
0420: 74 6f 20 74 68 69 73 20 73 6f 75 72 63 65 20 63  to this source c
0430: 6f 64 65 2e 0a 20 2a 0a 20 2a 20 54 68 69 73 20  ode.. *. * This 
0440: 69 73 20 61 6e 20 53 51 4c 69 74 65 20 6d 6f 64  is an SQLite mod
0450: 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 69 6e 67  ule implementing
0460: 20 66 75 6c 6c 2d 74 65 78 74 20 73 65 61 72 63   full-text searc
0470: 68 2e 0a 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68  h.. */../*.** Th
0480: 65 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20 66  e code in this f
0490: 69 6c 65 20 69 73 20 6f 6e 6c 79 20 63 6f 6d 70  ile is only comp
04a0: 69 6c 65 64 20 69 66 3a 0a 2a 2a 0a 2a 2a 20 20  iled if:.**.**  
04b0: 20 20 20 2a 20 54 68 65 20 46 54 53 31 20 6d 6f     * The FTS1 mo
04c0: 64 75 6c 65 20 69 73 20 62 65 69 6e 67 20 62 75  dule is being bu
04d0: 69 6c 74 20 61 73 20 61 6e 20 65 78 74 65 6e 73  ilt as an extens
04e0: 69 6f 6e 0a 2a 2a 20 20 20 20 20 20 20 28 69 6e  ion.**       (in
04f0: 20 77 68 69 63 68 20 63 61 73 65 20 53 51 4c 49   which case SQLI
0500: 54 45 5f 43 4f 52 45 20 69 73 20 6e 6f 74 20 64  TE_CORE is not d
0510: 65 66 69 6e 65 64 29 2c 20 6f 72 0a 2a 2a 0a 2a  efined), or.**.*
0520: 2a 20 20 20 20 20 2a 20 54 68 65 20 46 54 53 31  *     * The FTS1
0530: 20 6d 6f 64 75 6c 65 20 69 73 20 62 65 69 6e 67   module is being
0540: 20 62 75 69 6c 74 20 69 6e 74 6f 20 74 68 65 20   built into the 
0550: 63 6f 72 65 20 6f 66 0a 2a 2a 20 20 20 20 20 20  core of.**      
0560: 20 53 51 4c 69 74 65 20 28 69 6e 20 77 68 69 63   SQLite (in whic
0570: 68 20 63 61 73 65 20 53 51 4c 49 54 45 5f 45 4e  h case SQLITE_EN
0580: 41 42 4c 45 5f 46 54 53 31 20 69 73 20 64 65 66  ABLE_FTS1 is def
0590: 69 6e 65 64 29 2e 0a 2a 2f 0a 23 69 66 20 21 64  ined)..*/.#if !d
05a0: 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 43 4f  efined(SQLITE_CO
05b0: 52 45 29 20 7c 7c 20 64 65 66 69 6e 65 64 28 53  RE) || defined(S
05c0: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53  QLITE_ENABLE_FTS
05d0: 31 29 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28  1)..#if defined(
05e0: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54  SQLITE_ENABLE_FT
05f0: 53 31 29 20 26 26 20 21 64 65 66 69 6e 65 64 28  S1) && !defined(
0600: 53 51 4c 49 54 45 5f 43 4f 52 45 29 0a 23 20 64  SQLITE_CORE).# d
0610: 65 66 69 6e 65 20 53 51 4c 49 54 45 5f 43 4f 52  efine SQLITE_COR
0620: 45 20 31 0a 23 65 6e 64 69 66 0a 0a 23 69 6e 63  E 1.#endif..#inc
0630: 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a  lude <assert.h>.
0640: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
0650: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
0660: 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  dio.h>.#include 
0670: 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c  <string.h>.#incl
0680: 75 64 65 20 3c 63 74 79 70 65 2e 68 3e 0a 0a 23  ude <ctype.h>..#
0690: 69 6e 63 6c 75 64 65 20 22 66 74 73 31 2e 68 22  include "fts1.h"
06a0: 0a 23 69 6e 63 6c 75 64 65 20 22 66 74 73 31 5f  .#include "fts1_
06b0: 68 61 73 68 2e 68 22 0a 23 69 6e 63 6c 75 64 65  hash.h".#include
06c0: 20 22 66 74 73 31 5f 74 6f 6b 65 6e 69 7a 65 72   "fts1_tokenizer
06d0: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 73 71  .h".#include "sq
06e0: 6c 69 74 65 33 2e 68 22 0a 23 69 6e 63 6c 75 64  lite3.h".#includ
06f0: 65 20 22 73 71 6c 69 74 65 33 65 78 74 2e 68 22  e "sqlite3ext.h"
0700: 0a 53 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f  .SQLITE_EXTENSIO
0710: 4e 5f 49 4e 49 54 31 0a 0a 0a 23 69 66 20 30 0a  N_INIT1...#if 0.
0720: 23 20 64 65 66 69 6e 65 20 54 52 41 43 45 28 41  # define TRACE(A
0730: 29 20 20 70 72 69 6e 74 66 20 41 3b 20 66 66 6c  )  printf A; ffl
0740: 75 73 68 28 73 74 64 6f 75 74 29 0a 23 65 6c 73  ush(stdout).#els
0750: 65 0a 23 20 64 65 66 69 6e 65 20 54 52 41 43 45  e.# define TRACE
0760: 28 41 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 75  (A).#endif../* u
0770: 74 69 6c 69 74 79 20 66 75 6e 63 74 69 6f 6e 73  tility functions
0780: 20 2a 2f 0a 0a 74 79 70 65 64 65 66 20 73 74 72   */..typedef str
0790: 75 63 74 20 53 74 72 69 6e 67 42 75 66 66 65 72  uct StringBuffer
07a0: 20 7b 0a 20 20 69 6e 74 20 6c 65 6e 3b 20 20 20   {.  int len;   
07b0: 20 20 20 2f 2a 20 6c 65 6e 67 74 68 2c 20 6e 6f     /* length, no
07c0: 74 20 69 6e 63 6c 75 64 69 6e 67 20 6e 75 6c 6c  t including null
07d0: 20 74 65 72 6d 69 6e 61 74 6f 72 20 2a 2f 0a 20   terminator */. 
07e0: 20 69 6e 74 20 61 6c 6c 6f 63 65 64 3b 20 20 2f   int alloced;  /
07f0: 2a 20 53 70 61 63 65 20 61 6c 6c 6f 63 61 74 65  * Space allocate
0800: 64 20 66 6f 72 20 73 5b 5d 20 2a 2f 20 0a 20 20  d for s[] */ .  
0810: 63 68 61 72 20 2a 73 3b 20 20 20 20 20 20 2f 2a  char *s;      /*
0820: 20 43 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65 20   Content of the 
0830: 73 74 72 69 6e 67 20 2a 2f 0a 7d 20 53 74 72 69  string */.} Stri
0840: 6e 67 42 75 66 66 65 72 3b 0a 0a 73 74 61 74 69  ngBuffer;..stati
0850: 63 20 76 6f 69 64 20 69 6e 69 74 53 74 72 69 6e  c void initStrin
0860: 67 42 75 66 66 65 72 28 53 74 72 69 6e 67 42 75  gBuffer(StringBu
0870: 66 66 65 72 20 2a 73 62 29 7b 0a 20 20 73 62 2d  ffer *sb){.  sb-
0880: 3e 6c 65 6e 20 3d 20 30 3b 0a 20 20 73 62 2d 3e  >len = 0;.  sb->
0890: 61 6c 6c 6f 63 65 64 20 3d 20 31 30 30 3b 0a 20  alloced = 100;. 
08a0: 20 73 62 2d 3e 73 20 3d 20 6d 61 6c 6c 6f 63 28   sb->s = malloc(
08b0: 31 30 30 29 3b 0a 20 20 73 62 2d 3e 73 5b 30 5d  100);.  sb->s[0]
08c0: 20 3d 20 27 5c 30 27 3b 0a 7d 0a 0a 73 74 61 74   = '\0';.}..stat
08d0: 69 63 20 76 6f 69 64 20 6e 61 70 70 65 6e 64 28  ic void nappend(
08e0: 53 74 72 69 6e 67 42 75 66 66 65 72 20 2a 73 62  StringBuffer *sb
08f0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46  , const char *zF
0900: 72 6f 6d 2c 20 69 6e 74 20 6e 46 72 6f 6d 29 7b  rom, int nFrom){
0910: 0a 20 20 69 66 28 20 73 62 2d 3e 6c 65 6e 20 2b  .  if( sb->len +
0920: 20 6e 46 72 6f 6d 20 3e 3d 20 73 62 2d 3e 61 6c   nFrom >= sb->al
0930: 6c 6f 63 65 64 20 29 7b 0a 20 20 20 20 73 62 2d  loced ){.    sb-
0940: 3e 61 6c 6c 6f 63 65 64 20 3d 20 73 62 2d 3e 6c  >alloced = sb->l
0950: 65 6e 20 2b 20 6e 46 72 6f 6d 20 2b 20 31 30 30  en + nFrom + 100
0960: 3b 0a 20 20 20 20 73 62 2d 3e 73 20 3d 20 72 65  ;.    sb->s = re
0970: 61 6c 6c 6f 63 28 73 62 2d 3e 73 2c 20 73 62 2d  alloc(sb->s, sb-
0980: 3e 61 6c 6c 6f 63 65 64 2b 31 29 3b 0a 20 20 20  >alloced+1);.   
0990: 20 69 66 28 20 73 62 2d 3e 73 3d 3d 30 20 29 7b   if( sb->s==0 ){
09a0: 0a 20 20 20 20 20 20 69 6e 69 74 53 74 72 69 6e  .      initStrin
09b0: 67 42 75 66 66 65 72 28 73 62 29 3b 0a 20 20 20  gBuffer(sb);.   
09c0: 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 7d     return;.    }
09d0: 0a 20 20 7d 0a 20 20 6d 65 6d 63 70 79 28 73 62  .  }.  memcpy(sb
09e0: 2d 3e 73 20 2b 20 73 62 2d 3e 6c 65 6e 2c 20 7a  ->s + sb->len, z
09f0: 46 72 6f 6d 2c 20 6e 46 72 6f 6d 29 3b 0a 20 20  From, nFrom);.  
0a00: 73 62 2d 3e 6c 65 6e 20 2b 3d 20 6e 46 72 6f 6d  sb->len += nFrom
0a10: 3b 0a 20 20 73 62 2d 3e 73 5b 73 62 2d 3e 6c 65  ;.  sb->s[sb->le
0a20: 6e 5d 20 3d 20 30 3b 0a 7d 0a 73 74 61 74 69 63  n] = 0;.}.static
0a30: 20 76 6f 69 64 20 61 70 70 65 6e 64 28 53 74 72   void append(Str
0a40: 69 6e 67 42 75 66 66 65 72 20 2a 73 62 2c 20 63  ingBuffer *sb, c
0a50: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 72 6f 6d  onst char *zFrom
0a60: 29 7b 0a 20 20 6e 61 70 70 65 6e 64 28 73 62 2c  ){.  nappend(sb,
0a70: 20 7a 46 72 6f 6d 2c 20 73 74 72 6c 65 6e 28 7a   zFrom, strlen(z
0a80: 46 72 6f 6d 29 29 3b 0a 7d 0a 0a 2f 2a 20 57 65  From));.}../* We
0a90: 20 65 6e 63 6f 64 65 20 76 61 72 69 61 62 6c 65   encode variable
0aa0: 2d 6c 65 6e 67 74 68 20 69 6e 74 65 67 65 72 73  -length integers
0ab0: 20 69 6e 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61   in little-endia
0ac0: 6e 20 6f 72 64 65 72 20 75 73 69 6e 67 20 73 65  n order using se
0ad0: 76 65 6e 20 62 69 74 73 0a 20 2a 20 70 65 72 20  ven bits. * per 
0ae0: 62 79 74 65 20 61 73 20 66 6f 6c 6c 6f 77 73 3a  byte as follows:
0af0: 0a 2a 2a 0a 2a 2a 20 4b 45 59 3a 0a 2a 2a 20 20  .**.** KEY:.**  
0b00: 20 20 20 20 20 20 20 41 20 3d 20 30 78 78 78 78         A = 0xxxx
0b10: 78 78 78 20 20 20 20 37 20 62 69 74 73 20 6f 66  xxx    7 bits of
0b20: 20 64 61 74 61 20 61 6e 64 20 6f 6e 65 20 66 6c   data and one fl
0b30: 61 67 20 62 69 74 0a 2a 2a 20 20 20 20 20 20 20  ag bit.**       
0b40: 20 20 42 20 3d 20 31 78 78 78 78 78 78 78 20 20    B = 1xxxxxxx  
0b50: 20 20 37 20 62 69 74 73 20 6f 66 20 64 61 74 61    7 bits of data
0b60: 20 61 6e 64 20 6f 6e 65 20 66 6c 61 67 20 62 69   and one flag bi
0b70: 74 0a 2a 2a 0a 2a 2a 20 20 37 20 62 69 74 73 20  t.**.**  7 bits 
0b80: 2d 20 41 0a 2a 2a 20 31 34 20 62 69 74 73 20 2d  - A.** 14 bits -
0b90: 20 42 41 0a 2a 2a 20 32 31 20 62 69 74 73 20 2d   BA.** 21 bits -
0ba0: 20 42 42 41 0a 2a 2a 20 61 6e 64 20 73 6f 20 6f   BBA.** and so o
0bb0: 6e 2e 0a 2a 2f 0a 0a 2f 2a 20 57 65 20 6d 61 79  n..*/../* We may
0bc0: 20 6e 65 65 64 20 75 70 20 74 6f 20 56 41 52 49   need up to VARI
0bd0: 4e 54 5f 4d 41 58 20 62 79 74 65 73 20 74 6f 20  NT_MAX bytes to 
0be0: 73 74 6f 72 65 20 61 6e 20 65 6e 63 6f 64 65 64  store an encoded
0bf0: 20 36 34 2d 62 69 74 20 69 6e 74 65 67 65 72 2e   64-bit integer.
0c00: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 56 41 52 49   */.#define VARI
0c10: 4e 54 5f 4d 41 58 20 31 30 0a 0a 2f 2a 20 57 72  NT_MAX 10../* Wr
0c20: 69 74 65 20 61 20 36 34 2d 62 69 74 20 76 61 72  ite a 64-bit var
0c30: 69 61 62 6c 65 2d 6c 65 6e 67 74 68 20 69 6e 74  iable-length int
0c40: 65 67 65 72 20 74 6f 20 6d 65 6d 6f 72 79 20 73  eger to memory s
0c50: 74 61 72 74 69 6e 67 20 61 74 20 70 5b 30 5d 2e  tarting at p[0].
0c60: 0a 20 2a 20 54 68 65 20 6c 65 6e 67 74 68 20 6f  . * The length o
0c70: 66 20 64 61 74 61 20 77 72 69 74 74 65 6e 20 77  f data written w
0c80: 69 6c 6c 20 62 65 20 62 65 74 77 65 65 6e 20 31  ill be between 1
0c90: 20 61 6e 64 20 56 41 52 49 4e 54 5f 4d 41 58 20   and VARINT_MAX 
0ca0: 62 79 74 65 73 2e 0a 20 2a 20 54 68 65 20 6e 75  bytes.. * The nu
0cb0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 77 72  mber of bytes wr
0cc0: 69 74 74 65 6e 20 69 73 20 72 65 74 75 72 6e 65  itten is returne
0cd0: 64 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d. */.static int
0ce0: 20 70 75 74 56 61 72 69 6e 74 28 63 68 61 72 20   putVarint(char 
0cf0: 2a 70 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  *p, sqlite_int64
0d00: 20 76 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20   v){.  unsigned 
0d10: 63 68 61 72 20 2a 71 20 3d 20 28 75 6e 73 69 67  char *q = (unsig
0d20: 6e 65 64 20 63 68 61 72 20 2a 29 20 70 3b 0a 20  ned char *) p;. 
0d30: 20 73 71 6c 69 74 65 5f 75 69 6e 74 36 34 20 76   sqlite_uint64 v
0d40: 75 20 3d 20 76 3b 0a 20 20 64 6f 7b 0a 20 20 20  u = v;.  do{.   
0d50: 20 2a 71 2b 2b 20 3d 20 28 75 6e 73 69 67 6e 65   *q++ = (unsigne
0d60: 64 20 63 68 61 72 29 20 28 28 76 75 20 26 20 30  d char) ((vu & 0
0d70: 78 37 66 29 20 7c 20 30 78 38 30 29 3b 0a 20 20  x7f) | 0x80);.  
0d80: 20 20 76 75 20 3e 3e 3d 20 37 3b 0a 20 20 7d 77    vu >>= 7;.  }w
0d90: 68 69 6c 65 28 20 76 75 21 3d 30 20 29 3b 0a 20  hile( vu!=0 );. 
0da0: 20 71 5b 2d 31 5d 20 26 3d 20 30 78 37 66 3b 20   q[-1] &= 0x7f; 
0db0: 20 2f 2a 20 74 75 72 6e 20 6f 66 66 20 68 69 67   /* turn off hig
0dc0: 68 20 62 69 74 20 69 6e 20 66 69 6e 61 6c 20 62  h bit in final b
0dd0: 79 74 65 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  yte */.  assert(
0de0: 20 71 20 2d 20 28 75 6e 73 69 67 6e 65 64 20 63   q - (unsigned c
0df0: 68 61 72 20 2a 29 70 20 3c 3d 20 56 41 52 49 4e  har *)p <= VARIN
0e00: 54 5f 4d 41 58 20 29 3b 0a 20 20 72 65 74 75 72  T_MAX );.  retur
0e10: 6e 20 28 69 6e 74 29 20 28 71 20 2d 20 28 75 6e  n (int) (q - (un
0e20: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29 70 29  signed char *)p)
0e30: 3b 0a 7d 0a 0a 2f 2a 20 52 65 61 64 20 61 20 36  ;.}../* Read a 6
0e40: 34 2d 62 69 74 20 76 61 72 69 61 62 6c 65 2d 6c  4-bit variable-l
0e50: 65 6e 67 74 68 20 69 6e 74 65 67 65 72 20 66 72  ength integer fr
0e60: 6f 6d 20 6d 65 6d 6f 72 79 20 73 74 61 72 74 69  om memory starti
0e70: 6e 67 20 61 74 20 70 5b 30 5d 2e 0a 20 2a 20 52  ng at p[0].. * R
0e80: 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72  eturn the number
0e90: 20 6f 66 20 62 79 74 65 73 20 72 65 61 64 2c 20   of bytes read, 
0ea0: 6f 72 20 30 20 6f 6e 20 65 72 72 6f 72 2e 0a 20  or 0 on error.. 
0eb0: 2a 20 54 68 65 20 76 61 6c 75 65 20 69 73 20 73  * The value is s
0ec0: 74 6f 72 65 64 20 69 6e 20 2a 76 2e 20 2a 2f 0a  tored in *v. */.
0ed0: 73 74 61 74 69 63 20 69 6e 74 20 67 65 74 56 61  static int getVa
0ee0: 72 69 6e 74 28 63 6f 6e 73 74 20 63 68 61 72 20  rint(const char 
0ef0: 2a 70 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  *p, sqlite_int64
0f00: 20 2a 76 29 7b 0a 20 20 63 6f 6e 73 74 20 75 6e   *v){.  const un
0f10: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 71 20 3d  signed char *q =
0f20: 20 28 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64   (const unsigned
0f30: 20 63 68 61 72 20 2a 29 20 70 3b 0a 20 20 73 71   char *) p;.  sq
0f40: 6c 69 74 65 5f 75 69 6e 74 36 34 20 78 20 3d 20  lite_uint64 x = 
0f50: 30 2c 20 79 20 3d 20 31 3b 0a 20 20 77 68 69 6c  0, y = 1;.  whil
0f60: 65 28 20 28 2a 71 20 26 20 30 78 38 30 29 20 3d  e( (*q & 0x80) =
0f70: 3d 20 30 78 38 30 20 29 7b 0a 20 20 20 20 78 20  = 0x80 ){.    x 
0f80: 2b 3d 20 79 20 2a 20 28 2a 71 2b 2b 20 26 20 30  += y * (*q++ & 0
0f90: 78 37 66 29 3b 0a 20 20 20 20 79 20 3c 3c 3d 20  x7f);.    y <<= 
0fa0: 37 3b 0a 20 20 20 20 69 66 28 20 71 20 2d 20 28  7;.    if( q - (
0fb0: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29  unsigned char *)
0fc0: 70 20 3e 3d 20 56 41 52 49 4e 54 5f 4d 41 58 20  p >= VARINT_MAX 
0fd0: 29 7b 20 20 2f 2a 20 62 61 64 20 64 61 74 61 20  ){  /* bad data 
0fe0: 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  */.      assert(
0ff0: 20 30 20 29 3b 0a 20 20 20 20 20 20 72 65 74 75   0 );.      retu
1000: 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  rn 0;.    }.  }.
1010: 20 20 78 20 2b 3d 20 79 20 2a 20 28 2a 71 2b 2b    x += y * (*q++
1020: 29 3b 0a 20 20 2a 76 20 3d 20 28 73 71 6c 69 74  );.  *v = (sqlit
1030: 65 5f 69 6e 74 36 34 29 20 78 3b 0a 20 20 72 65  e_int64) x;.  re
1040: 74 75 72 6e 20 28 69 6e 74 29 20 28 71 20 2d 20  turn (int) (q - 
1050: 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a  (unsigned char *
1060: 29 70 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  )p);.}..static i
1070: 6e 74 20 67 65 74 56 61 72 69 6e 74 33 32 28 63  nt getVarint32(c
1080: 6f 6e 73 74 20 63 68 61 72 20 2a 70 2c 20 69 6e  onst char *p, in
1090: 74 20 2a 70 69 29 7b 0a 20 73 71 6c 69 74 65 5f  t *pi){. sqlite_
10a0: 69 6e 74 36 34 20 69 3b 0a 20 69 6e 74 20 72 65  int64 i;. int re
10b0: 74 20 3d 20 67 65 74 56 61 72 69 6e 74 28 70 2c  t = getVarint(p,
10c0: 20 26 69 29 3b 0a 20 2a 70 69 20 3d 20 28 69 6e   &i);. *pi = (in
10d0: 74 29 20 69 3b 0a 20 61 73 73 65 72 74 28 20 2a  t) i;. assert( *
10e0: 70 69 3d 3d 69 20 29 3b 0a 20 72 65 74 75 72 6e  pi==i );. return
10f0: 20 72 65 74 3b 0a 7d 0a 0a 2f 2a 2a 2a 20 44 6f   ret;.}../*** Do
1100: 63 75 6d 65 6e 74 20 6c 69 73 74 73 20 2a 2a 2a  cument lists ***
1110: 0a 20 2a 0a 20 2a 20 41 20 64 6f 63 75 6d 65 6e  . *. * A documen
1120: 74 20 6c 69 73 74 20 68 6f 6c 64 73 20 61 20 73  t list holds a s
1130: 6f 72 74 65 64 20 6c 69 73 74 20 6f 66 20 76 61  orted list of va
1140: 72 69 6e 74 2d 65 6e 63 6f 64 65 64 20 64 6f 63  rint-encoded doc
1150: 75 6d 65 6e 74 20 49 44 73 2e 0a 20 2a 0a 20 2a  ument IDs.. *. *
1160: 20 41 20 64 6f 63 6c 69 73 74 20 77 69 74 68 20   A doclist with 
1170: 74 79 70 65 20 44 4c 5f 50 4f 53 49 54 49 4f 4e  type DL_POSITION
1180: 53 5f 4f 46 46 53 45 54 53 20 69 73 20 73 74 6f  S_OFFSETS is sto
1190: 72 65 64 20 6c 69 6b 65 20 74 68 69 73 3a 0a 20  red like this:. 
11a0: 2a 0a 20 2a 20 61 72 72 61 79 20 7b 0a 20 2a 20  *. * array {. * 
11b0: 20 20 76 61 72 69 6e 74 20 64 6f 63 69 64 3b 0a    varint docid;.
11c0: 20 2a 20 20 20 61 72 72 61 79 20 7b 0a 20 2a 20   *   array {. * 
11d0: 20 20 20 20 76 61 72 69 6e 74 20 70 6f 73 69 74      varint posit
11e0: 69 6f 6e 3b 20 20 20 20 20 28 64 65 6c 74 61 20  ion;     (delta 
11f0: 66 72 6f 6d 20 70 72 65 76 69 6f 75 73 20 70 6f  from previous po
1200: 73 69 74 69 6f 6e 20 70 6c 75 73 20 50 4f 53 5f  sition plus POS_
1210: 42 41 53 45 29 0a 20 2a 20 20 20 20 20 76 61 72  BASE). *     var
1220: 69 6e 74 20 73 74 61 72 74 4f 66 66 73 65 74 3b  int startOffset;
1230: 20 20 28 64 65 6c 74 61 20 66 72 6f 6d 20 70 72    (delta from pr
1240: 65 76 69 6f 75 73 20 73 74 61 72 74 4f 66 66 73  evious startOffs
1250: 65 74 29 0a 20 2a 20 20 20 20 20 76 61 72 69 6e  et). *     varin
1260: 74 20 65 6e 64 4f 66 66 73 65 74 3b 20 20 20 20  t endOffset;    
1270: 28 64 65 6c 74 61 20 66 72 6f 6d 20 73 74 61 72  (delta from star
1280: 74 4f 66 66 73 65 74 29 0a 20 2a 20 20 20 7d 0a  tOffset). *   }.
1290: 20 2a 20 7d 0a 20 2a 0a 20 2a 20 48 65 72 65 2c   * }. *. * Here,
12a0: 20 61 72 72 61 79 20 7b 20 58 20 7d 20 6d 65 61   array { X } mea
12b0: 6e 73 20 7a 65 72 6f 20 6f 72 20 6d 6f 72 65 20  ns zero or more 
12c0: 6f 63 63 75 72 72 65 6e 63 65 73 20 6f 66 20 58  occurrences of X
12d0: 2c 20 61 64 6a 61 63 65 6e 74 20 69 6e 20 6d 65  , adjacent in me
12e0: 6d 6f 72 79 2e 0a 20 2a 0a 20 2a 20 41 20 70 6f  mory.. *. * A po
12f0: 73 69 74 69 6f 6e 20 6c 69 73 74 20 6d 61 79 20  sition list may 
1300: 68 6f 6c 64 20 70 6f 73 69 74 69 6f 6e 73 20 66  hold positions f
1310: 6f 72 20 74 65 78 74 20 69 6e 20 6d 75 6c 74 69  or text in multi
1320: 70 6c 65 20 63 6f 6c 75 6d 6e 73 2e 20 20 41 20  ple columns.  A 
1330: 70 6f 73 69 74 69 6f 6e 0a 20 2a 20 50 4f 53 5f  position. * POS_
1340: 43 4f 4c 55 4d 4e 20 69 73 20 66 6f 6c 6c 6f 77  COLUMN is follow
1350: 65 64 20 62 79 20 61 20 76 61 72 69 6e 74 20 63  ed by a varint c
1360: 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 69 6e  ontaining the in
1370: 64 65 78 20 6f 66 20 74 68 65 20 63 6f 6c 75 6d  dex of the colum
1380: 6e 20 66 6f 72 0a 20 2a 20 66 6f 6c 6c 6f 77 69  n for. * followi
1390: 6e 67 20 70 6f 73 69 74 69 6f 6e 73 20 69 6e 20  ng positions in 
13a0: 74 68 65 20 6c 69 73 74 2e 20 20 41 6e 79 20 70  the list.  Any p
13b0: 6f 73 69 74 69 6f 6e 73 20 61 70 70 65 61 72 69  ositions appeari
13c0: 6e 67 20 62 65 66 6f 72 65 20 61 6e 79 0a 20 2a  ng before any. *
13d0: 20 6f 63 63 75 72 72 65 6e 63 65 73 20 6f 66 20   occurrences of 
13e0: 50 4f 53 5f 43 4f 4c 55 4d 4e 20 61 72 65 20 66  POS_COLUMN are f
13f0: 6f 72 20 63 6f 6c 75 6d 6e 20 30 2e 0a 20 2a 0a  or column 0.. *.
1400: 20 2a 20 41 20 64 6f 63 6c 69 73 74 20 77 69 74   * A doclist wit
1410: 68 20 74 79 70 65 20 44 4c 5f 50 4f 53 49 54 49  h type DL_POSITI
1420: 4f 4e 53 20 69 73 20 6c 69 6b 65 20 74 68 65 20  ONS is like the 
1430: 61 62 6f 76 65 2c 20 62 75 74 20 68 6f 6c 64 73  above, but holds
1440: 20 6f 6e 6c 79 20 64 6f 63 69 64 73 0a 20 2a 20   only docids. * 
1450: 61 6e 64 20 70 6f 73 69 74 69 6f 6e 73 20 77 69  and positions wi
1460: 74 68 6f 75 74 20 6f 66 66 73 65 74 20 69 6e 66  thout offset inf
1470: 6f 72 6d 61 74 69 6f 6e 2e 0a 20 2a 0a 20 2a 20  ormation.. *. * 
1480: 41 20 64 6f 63 6c 69 73 74 20 77 69 74 68 20 74  A doclist with t
1490: 79 70 65 20 44 4c 5f 44 4f 43 49 44 53 20 69 73  ype DL_DOCIDS is
14a0: 20 6c 69 6b 65 20 74 68 65 20 61 62 6f 76 65 2c   like the above,
14b0: 20 62 75 74 20 68 6f 6c 64 73 20 6f 6e 6c 79 20   but holds only 
14c0: 64 6f 63 69 64 73 0a 20 2a 20 77 69 74 68 6f 75  docids. * withou
14d0: 74 20 70 6f 73 69 74 69 6f 6e 73 20 6f 72 20 6f  t positions or o
14e0: 66 66 73 65 74 20 69 6e 66 6f 72 6d 61 74 69 6f  ffset informatio
14f0: 6e 2e 0a 20 2a 0a 20 2a 20 4f 6e 20 64 69 73 6b  n.. *. * On disk
1500: 2c 20 65 76 65 72 79 20 64 6f 63 75 6d 65 6e 74  , every document
1510: 20 6c 69 73 74 20 68 61 73 20 70 6f 73 69 74 69   list has positi
1520: 6f 6e 73 20 61 6e 64 20 6f 66 66 73 65 74 73 2c  ons and offsets,
1530: 20 73 6f 20 77 65 20 64 6f 6e 27 74 20 62 6f 74   so we don't bot
1540: 68 65 72 0a 20 2a 20 74 6f 20 73 65 72 69 61 6c  her. * to serial
1550: 69 7a 65 20 61 20 64 6f 63 6c 69 73 74 27 73 20  ize a doclist's 
1560: 74 79 70 65 2e 0a 20 2a 20 0a 20 2a 20 57 65 20  type.. * . * We 
1570: 64 6f 6e 27 74 20 79 65 74 20 64 65 6c 74 61 2d  don't yet delta-
1580: 65 6e 63 6f 64 65 20 64 6f 63 75 6d 65 6e 74 20  encode document 
1590: 49 44 73 3b 20 64 6f 69 6e 67 20 73 6f 20 77 69  IDs; doing so wi
15a0: 6c 6c 20 70 72 6f 62 61 62 6c 79 20 62 65 20 61  ll probably be a
15b0: 0a 20 2a 20 6d 6f 64 65 73 74 20 77 69 6e 2e 0a  . * modest win..
15c0: 20 2a 0a 20 2a 20 4e 4f 54 45 28 73 68 65 73 73   *. * NOTE(shess
15d0: 29 20 49 27 76 65 20 74 68 6f 75 67 68 74 20 6f  ) I've thought o
15e0: 66 20 61 20 73 6c 69 67 68 74 6c 79 20 28 31 25  f a slightly (1%
15f0: 29 20 62 65 74 74 65 72 20 6f 66 66 73 65 74 20  ) better offset 
1600: 65 6e 63 6f 64 69 6e 67 2e 0a 20 2a 20 41 66 74  encoding.. * Aft
1610: 65 72 20 74 68 65 20 66 69 72 73 74 20 6f 66 66  er the first off
1620: 73 65 74 2c 20 65 73 74 69 6d 61 74 65 20 74 68  set, estimate th
1630: 65 20 6e 65 78 74 20 6f 66 66 73 65 74 20 62 79  e next offset by
1640: 20 75 73 69 6e 67 20 74 68 65 0a 20 2a 20 63 75   using the. * cu
1650: 72 72 65 6e 74 20 74 6f 6b 65 6e 20 70 6f 73 69  rrent token posi
1660: 74 69 6f 6e 20 61 6e 64 20 74 68 65 20 70 72 65  tion and the pre
1670: 76 69 6f 75 73 20 74 6f 6b 65 6e 20 70 6f 73 69  vious token posi
1680: 74 69 6f 6e 20 61 6e 64 20 6f 66 66 73 65 74 2c  tion and offset,
1690: 0a 20 2a 20 6f 66 66 73 65 74 20 74 6f 20 68 61  . * offset to ha
16a0: 6e 64 6c 65 20 73 6f 6d 65 20 76 61 72 69 61 6e  ndle some varian
16b0: 63 65 2e 20 20 53 6f 20 74 68 65 20 65 73 74 69  ce.  So the esti
16c0: 6d 61 74 65 20 77 6f 75 6c 64 20 62 65 0a 20 2a  mate would be. *
16d0: 20 28 69 50 6f 73 69 74 69 6f 6e 2a 77 2d 3e 69   (iPosition*w->i
16e0: 53 74 61 72 74 4f 66 66 73 65 74 2f 77 2d 3e 69  StartOffset/w->i
16f0: 50 6f 73 69 74 69 6f 6e 2d 36 34 29 2c 20 77 68  Position-64), wh
1700: 69 63 68 20 69 73 20 64 65 6c 74 61 2d 65 6e 63  ich is delta-enc
1710: 6f 64 65 64 0a 20 2a 20 61 73 20 6e 6f 72 6d 61  oded. * as norma
1720: 6c 2e 20 20 4f 66 66 73 65 74 73 20 6d 6f 72 65  l.  Offsets more
1730: 20 74 68 61 6e 20 36 34 20 63 68 61 72 73 20 66   than 64 chars f
1740: 72 6f 6d 20 74 68 65 20 65 73 74 69 6d 61 74 65  rom the estimate
1750: 20 61 72 65 0a 20 2a 20 65 6e 63 6f 64 65 64 20   are. * encoded 
1760: 61 73 20 74 68 65 20 64 65 6c 74 61 20 74 6f 20  as the delta to 
1770: 74 68 65 20 70 72 65 76 69 6f 75 73 20 73 74 61  the previous sta
1780: 72 74 20 6f 66 66 73 65 74 20 2b 20 31 32 38 2e  rt offset + 128.
1790: 20 20 41 6e 0a 20 2a 20 61 64 64 69 74 69 6f 6e    An. * addition
17a0: 61 6c 20 74 69 6e 79 20 69 6e 63 72 65 6d 65 6e  al tiny incremen
17b0: 74 20 63 61 6e 20 62 65 20 67 61 69 6e 65 64 20  t can be gained 
17c0: 62 79 20 75 73 69 6e 67 20 74 68 65 20 65 6e 64  by using the end
17d0: 20 6f 66 66 73 65 74 20 6f 66 0a 20 2a 20 74 68   offset of. * th
17e0: 65 20 70 72 65 76 69 6f 75 73 20 74 6f 6b 65 6e  e previous token
17f0: 20 74 6f 20 6d 61 6b 65 20 74 68 65 20 65 73 74   to make the est
1800: 69 6d 61 74 65 20 61 20 74 69 6e 79 20 62 69 74  imate a tiny bit
1810: 20 6d 6f 72 65 20 70 72 65 63 69 73 65 2e 0a 2a   more precise..*
1820: 2f 0a 0a 2f 2a 20 49 74 20 69 73 20 6e 6f 74 20  /../* It is not 
1830: 73 61 66 65 20 74 6f 20 63 61 6c 6c 20 69 73 73  safe to call iss
1840: 70 61 63 65 28 29 2c 20 74 6f 6c 6f 77 65 72 28  pace(), tolower(
1850: 29 2c 20 6f 72 20 69 73 61 6c 6e 75 6d 28 29 20  ), or isalnum() 
1860: 6f 6e 0a 2a 2a 20 68 69 2d 62 69 74 2d 73 65 74  on.** hi-bit-set
1870: 20 63 68 61 72 61 63 74 65 72 73 2e 20 20 54 68   characters.  Th
1880: 69 73 20 69 73 20 74 68 65 20 73 61 6d 65 20 73  is is the same s
1890: 6f 6c 75 74 69 6f 6e 20 75 73 65 64 20 69 6e 20  olution used in 
18a0: 74 68 65 0a 2a 2a 20 74 6f 6b 65 6e 69 7a 65 72  the.** tokenizer
18b0: 2e 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f 28 73 68 65  ..*/./* TODO(she
18c0: 73 73 29 20 54 68 65 20 73 6e 69 70 70 65 74 2d  ss) The snippet-
18d0: 67 65 6e 65 72 61 74 69 6f 6e 20 63 6f 64 65 20  generation code 
18e0: 73 68 6f 75 6c 64 20 62 65 20 75 73 69 6e 67 20  should be using 
18f0: 74 68 65 0a 2a 2a 20 74 6f 6b 65 6e 69 7a 65 72  the.** tokenizer
1900: 2d 67 65 6e 65 72 61 74 65 64 20 74 6f 6b 65 6e  -generated token
1910: 73 20 72 61 74 68 65 72 20 74 68 61 6e 20 64 6f  s rather than do
1920: 69 6e 67 20 69 74 73 20 6f 77 6e 20 6c 6f 63 61  ing its own loca
1930: 6c 0a 2a 2a 20 74 6f 6b 65 6e 69 7a 61 74 69 6f  l.** tokenizatio
1940: 6e 2e 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f 28 73 68  n..*/./* TODO(sh
1950: 65 73 73 29 20 49 73 20 5f 5f 69 73 61 73 63 69  ess) Is __isasci
1960: 69 28 29 20 61 20 70 6f 72 74 61 62 6c 65 20 76  i() a portable v
1970: 65 72 73 69 6f 6e 20 6f 66 20 28 63 26 30 78 38  ersion of (c&0x8
1980: 30 29 3d 3d 30 3f 20 2a 2f 0a 73 74 61 74 69 63  0)==0? */.static
1990: 20 69 6e 74 20 73 61 66 65 5f 69 73 73 70 61 63   int safe_isspac
19a0: 65 28 63 68 61 72 20 63 29 7b 0a 20 20 72 65 74  e(char c){.  ret
19b0: 75 72 6e 20 28 63 26 30 78 38 30 29 3d 3d 30 20  urn (c&0x80)==0 
19c0: 3f 20 69 73 73 70 61 63 65 28 28 75 6e 73 69 67  ? isspace((unsig
19d0: 6e 65 64 20 63 68 61 72 29 63 29 20 3a 20 30 3b  ned char)c) : 0;
19e0: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 73 61  .}.static int sa
19f0: 66 65 5f 74 6f 6c 6f 77 65 72 28 63 68 61 72 20  fe_tolower(char 
1a00: 63 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 63 26  c){.  return (c&
1a10: 30 78 38 30 29 3d 3d 30 20 3f 20 74 6f 6c 6f 77  0x80)==0 ? tolow
1a20: 65 72 28 28 75 6e 73 69 67 6e 65 64 20 63 68 61  er((unsigned cha
1a30: 72 29 63 29 20 3a 20 63 3b 0a 7d 0a 73 74 61 74  r)c) : c;.}.stat
1a40: 69 63 20 69 6e 74 20 73 61 66 65 5f 69 73 61 6c  ic int safe_isal
1a50: 6e 75 6d 28 63 68 61 72 20 63 29 7b 0a 20 20 72  num(char c){.  r
1a60: 65 74 75 72 6e 20 28 63 26 30 78 38 30 29 3d 3d  eturn (c&0x80)==
1a70: 30 20 3f 20 69 73 61 6c 6e 75 6d 28 28 75 6e 73  0 ? isalnum((uns
1a80: 69 67 6e 65 64 20 63 68 61 72 29 63 29 20 3a 20  igned char)c) : 
1a90: 30 3b 0a 7d 0a 0a 74 79 70 65 64 65 66 20 65 6e  0;.}..typedef en
1aa0: 75 6d 20 44 6f 63 4c 69 73 74 54 79 70 65 20 7b  um DocListType {
1ab0: 0a 20 20 44 4c 5f 44 4f 43 49 44 53 2c 20 20 20  .  DL_DOCIDS,   
1ac0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 64 6f             /* do
1ad0: 63 69 64 73 20 6f 6e 6c 79 20 2a 2f 0a 20 20 44  cids only */.  D
1ae0: 4c 5f 50 4f 53 49 54 49 4f 4e 53 2c 20 20 20 20  L_POSITIONS,    
1af0: 20 20 20 20 20 20 20 2f 2a 20 64 6f 63 69 64 73         /* docids
1b00: 20 2b 20 70 6f 73 69 74 69 6f 6e 73 20 2a 2f 0a   + positions */.
1b10: 20 20 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 5f 4f    DL_POSITIONS_O
1b20: 46 46 53 45 54 53 20 20 20 20 2f 2a 20 64 6f 63  FFSETS    /* doc
1b30: 69 64 73 20 2b 20 70 6f 73 69 74 69 6f 6e 73 20  ids + positions 
1b40: 2b 20 6f 66 66 73 65 74 73 20 2a 2f 0a 7d 20 44  + offsets */.} D
1b50: 6f 63 4c 69 73 74 54 79 70 65 3b 0a 0a 2f 2a 0a  ocListType;../*.
1b60: 2a 2a 20 42 79 20 64 65 66 61 75 6c 74 2c 20 6f  ** By default, o
1b70: 6e 6c 79 20 70 6f 73 69 74 69 6f 6e 73 20 61 6e  nly positions an
1b80: 64 20 6e 6f 74 20 6f 66 66 73 65 74 73 20 61 72  d not offsets ar
1b90: 65 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20  e stored in the 
1ba0: 64 6f 63 6c 69 73 74 73 2e 0a 2a 2a 20 54 6f 20  doclists..** To 
1bb0: 63 68 61 6e 67 65 20 74 68 69 73 20 73 6f 20 74  change this so t
1bc0: 68 61 74 20 6f 66 66 73 65 74 73 20 61 72 65 20  hat offsets are 
1bd0: 73 74 6f 72 65 64 20 74 6f 6f 2c 20 63 6f 6d 70  stored too, comp
1be0: 69 6c 65 20 77 69 74 68 0a 2a 2a 0a 2a 2a 20 20  ile with.**.**  
1bf0: 20 20 20 20 20 20 20 20 2d 44 44 4c 5f 44 45 46          -DDL_DEF
1c00: 41 55 4c 54 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e  AULT=DL_POSITION
1c10: 53 5f 4f 46 46 53 45 54 53 0a 2a 2a 0a 2a 2f 0a  S_OFFSETS.**.*/.
1c20: 23 69 66 6e 64 65 66 20 44 4c 5f 44 45 46 41 55  #ifndef DL_DEFAU
1c30: 4c 54 0a 23 20 64 65 66 69 6e 65 20 44 4c 5f 44  LT.# define DL_D
1c40: 45 46 41 55 4c 54 20 44 4c 5f 50 4f 53 49 54 49  EFAULT DL_POSITI
1c50: 4f 4e 53 0a 23 65 6e 64 69 66 0a 0a 74 79 70 65  ONS.#endif..type
1c60: 64 65 66 20 73 74 72 75 63 74 20 44 6f 63 4c 69  def struct DocLi
1c70: 73 74 20 7b 0a 20 20 63 68 61 72 20 2a 70 44 61  st {.  char *pDa
1c80: 74 61 3b 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b  ta;.  int nData;
1c90: 0a 20 20 44 6f 63 4c 69 73 74 54 79 70 65 20 69  .  DocListType i
1ca0: 54 79 70 65 3b 0a 20 20 69 6e 74 20 69 4c 61 73  Type;.  int iLas
1cb0: 74 43 6f 6c 75 6d 6e 3b 20 20 20 20 2f 2a 20 74  tColumn;    /* t
1cc0: 68 65 20 6c 61 73 74 20 63 6f 6c 75 6d 6e 20 77  he last column w
1cd0: 72 69 74 74 65 6e 20 2a 2f 0a 20 20 69 6e 74 20  ritten */.  int 
1ce0: 69 4c 61 73 74 50 6f 73 3b 20 20 20 20 20 20 20  iLastPos;       
1cf0: 2f 2a 20 74 68 65 20 6c 61 73 74 20 70 6f 73 69  /* the last posi
1d00: 74 69 6f 6e 20 77 72 69 74 74 65 6e 20 2a 2f 0a  tion written */.
1d10: 20 20 69 6e 74 20 69 4c 61 73 74 4f 66 66 73 65    int iLastOffse
1d20: 74 3b 20 20 20 20 2f 2a 20 74 68 65 20 6c 61 73  t;    /* the las
1d30: 74 20 73 74 61 72 74 20 6f 66 66 73 65 74 20 77  t start offset w
1d40: 72 69 74 74 65 6e 20 2a 2f 0a 7d 20 44 6f 63 4c  ritten */.} DocL
1d50: 69 73 74 3b 0a 0a 65 6e 75 6d 20 7b 0a 20 20 50  ist;..enum {.  P
1d60: 4f 53 5f 45 4e 44 20 3d 20 30 2c 20 20 20 20 20  OS_END = 0,     
1d70: 20 20 20 2f 2a 20 65 6e 64 20 6f 66 20 74 68 69     /* end of thi
1d80: 73 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 20  s position list 
1d90: 2a 2f 0a 20 20 50 4f 53 5f 43 4f 4c 55 4d 4e 2c  */.  POS_COLUMN,
1da0: 20 20 20 20 20 20 20 20 20 2f 2a 20 66 6f 6c 6c           /* foll
1db0: 6f 77 65 64 20 62 79 20 6e 65 77 20 63 6f 6c 75  owed by new colu
1dc0: 6d 6e 20 6e 75 6d 62 65 72 20 2a 2f 0a 20 20 50  mn number */.  P
1dd0: 4f 53 5f 42 41 53 45 0a 7d 3b 0a 0a 2f 2a 20 49  OS_BASE.};../* I
1de0: 6e 69 74 69 61 6c 69 7a 65 20 61 20 6e 65 77 20  nitialize a new 
1df0: 44 6f 63 4c 69 73 74 20 74 6f 20 68 6f 6c 64 20  DocList to hold 
1e00: 74 68 65 20 67 69 76 65 6e 20 64 61 74 61 2e 20  the given data. 
1e10: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  */.static void d
1e20: 6f 63 4c 69 73 74 49 6e 69 74 28 44 6f 63 4c 69  ocListInit(DocLi
1e30: 73 74 20 2a 64 2c 20 44 6f 63 4c 69 73 74 54 79  st *d, DocListTy
1e40: 70 65 20 69 54 79 70 65 2c 0a 20 20 20 20 20 20  pe iType,.      
1e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e60: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 44    const char *pD
1e70: 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 29 7b  ata, int nData){
1e80: 0a 20 20 64 2d 3e 6e 44 61 74 61 20 3d 20 6e 44  .  d->nData = nD
1e90: 61 74 61 3b 0a 20 20 69 66 28 20 6e 44 61 74 61  ata;.  if( nData
1ea0: 3e 30 20 29 7b 0a 20 20 20 20 64 2d 3e 70 44 61  >0 ){.    d->pDa
1eb0: 74 61 20 3d 20 6d 61 6c 6c 6f 63 28 6e 44 61 74  ta = malloc(nDat
1ec0: 61 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 64  a);.    memcpy(d
1ed0: 2d 3e 70 44 61 74 61 2c 20 70 44 61 74 61 2c 20  ->pData, pData, 
1ee0: 6e 44 61 74 61 29 3b 0a 20 20 7d 20 65 6c 73 65  nData);.  } else
1ef0: 20 7b 0a 20 20 20 20 64 2d 3e 70 44 61 74 61 20   {.    d->pData 
1f00: 3d 20 4e 55 4c 4c 3b 0a 20 20 7d 0a 20 20 64 2d  = NULL;.  }.  d-
1f10: 3e 69 54 79 70 65 20 3d 20 69 54 79 70 65 3b 0a  >iType = iType;.
1f20: 20 20 64 2d 3e 69 4c 61 73 74 43 6f 6c 75 6d 6e    d->iLastColumn
1f30: 20 3d 20 30 3b 0a 20 20 64 2d 3e 69 4c 61 73 74   = 0;.  d->iLast
1f40: 50 6f 73 20 3d 20 64 2d 3e 69 4c 61 73 74 4f 66  Pos = d->iLastOf
1f50: 66 73 65 74 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 20  fset = 0;.}../* 
1f60: 43 72 65 61 74 65 20 61 20 6e 65 77 20 64 79 6e  Create a new dyn
1f70: 61 6d 69 63 61 6c 6c 79 2d 61 6c 6c 6f 63 61 74  amically-allocat
1f80: 65 64 20 44 6f 63 4c 69 73 74 2e 20 2a 2f 0a 73  ed DocList. */.s
1f90: 74 61 74 69 63 20 44 6f 63 4c 69 73 74 20 2a 64  tatic DocList *d
1fa0: 6f 63 4c 69 73 74 4e 65 77 28 44 6f 63 4c 69 73  ocListNew(DocLis
1fb0: 74 54 79 70 65 20 69 54 79 70 65 29 7b 0a 20 20  tType iType){.  
1fc0: 44 6f 63 4c 69 73 74 20 2a 64 20 3d 20 28 44 6f  DocList *d = (Do
1fd0: 63 4c 69 73 74 20 2a 29 20 6d 61 6c 6c 6f 63 28  cList *) malloc(
1fe0: 73 69 7a 65 6f 66 28 44 6f 63 4c 69 73 74 29 29  sizeof(DocList))
1ff0: 3b 0a 20 20 64 6f 63 4c 69 73 74 49 6e 69 74 28  ;.  docListInit(
2000: 64 2c 20 69 54 79 70 65 2c 20 30 2c 20 30 29 3b  d, iType, 0, 0);
2010: 0a 20 20 72 65 74 75 72 6e 20 64 3b 0a 7d 0a 0a  .  return d;.}..
2020: 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f 63 4c  static void docL
2030: 69 73 74 44 65 73 74 72 6f 79 28 44 6f 63 4c 69  istDestroy(DocLi
2040: 73 74 20 2a 64 29 7b 0a 20 20 66 72 65 65 28 64  st *d){.  free(d
2050: 2d 3e 70 44 61 74 61 29 3b 0a 23 69 66 6e 64 65  ->pData);.#ifnde
2060: 66 20 4e 44 45 42 55 47 0a 20 20 6d 65 6d 73 65  f NDEBUG.  memse
2070: 74 28 64 2c 20 30 78 35 35 2c 20 73 69 7a 65 6f  t(d, 0x55, sizeo
2080: 66 28 2a 64 29 29 3b 0a 23 65 6e 64 69 66 0a 7d  f(*d));.#endif.}
2090: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f  ..static void do
20a0: 63 4c 69 73 74 44 65 6c 65 74 65 28 44 6f 63 4c  cListDelete(DocL
20b0: 69 73 74 20 2a 64 29 7b 0a 20 20 64 6f 63 4c 69  ist *d){.  docLi
20c0: 73 74 44 65 73 74 72 6f 79 28 64 29 3b 0a 20 20  stDestroy(d);.  
20d0: 66 72 65 65 28 64 29 3b 0a 7d 0a 0a 73 74 61 74  free(d);.}..stat
20e0: 69 63 20 63 68 61 72 20 2a 64 6f 63 4c 69 73 74  ic char *docList
20f0: 45 6e 64 28 44 6f 63 4c 69 73 74 20 2a 64 29 7b  End(DocList *d){
2100: 0a 20 20 72 65 74 75 72 6e 20 64 2d 3e 70 44 61  .  return d->pDa
2110: 74 61 20 2b 20 64 2d 3e 6e 44 61 74 61 3b 0a 7d  ta + d->nData;.}
2120: 0a 0a 2f 2a 20 41 70 70 65 6e 64 20 61 20 76 61  ../* Append a va
2130: 72 69 6e 74 20 74 6f 20 61 20 44 6f 63 4c 69 73  rint to a DocLis
2140: 74 27 73 20 64 61 74 61 2e 20 2a 2f 0a 73 74 61  t's data. */.sta
2150: 74 69 63 20 76 6f 69 64 20 61 70 70 65 6e 64 56  tic void appendV
2160: 61 72 69 6e 74 28 44 6f 63 4c 69 73 74 20 2a 64  arint(DocList *d
2170: 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69  , sqlite_int64 i
2180: 29 7b 0a 20 20 63 68 61 72 20 63 5b 56 41 52 49  ){.  char c[VARI
2190: 4e 54 5f 4d 41 58 5d 3b 0a 20 20 69 6e 74 20 6e  NT_MAX];.  int n
21a0: 20 3d 20 70 75 74 56 61 72 69 6e 74 28 63 2c 20   = putVarint(c, 
21b0: 69 29 3b 0a 20 20 64 2d 3e 70 44 61 74 61 20 3d  i);.  d->pData =
21c0: 20 72 65 61 6c 6c 6f 63 28 64 2d 3e 70 44 61 74   realloc(d->pDat
21d0: 61 2c 20 64 2d 3e 6e 44 61 74 61 20 2b 20 6e 29  a, d->nData + n)
21e0: 3b 0a 20 20 6d 65 6d 63 70 79 28 64 2d 3e 70 44  ;.  memcpy(d->pD
21f0: 61 74 61 20 2b 20 64 2d 3e 6e 44 61 74 61 2c 20  ata + d->nData, 
2200: 63 2c 20 6e 29 3b 0a 20 20 64 2d 3e 6e 44 61 74  c, n);.  d->nDat
2210: 61 20 2b 3d 20 6e 3b 0a 7d 0a 0a 73 74 61 74 69  a += n;.}..stati
2220: 63 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 41 64  c void docListAd
2230: 64 44 6f 63 69 64 28 44 6f 63 4c 69 73 74 20 2a  dDocid(DocList *
2240: 64 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  d, sqlite_int64 
2250: 69 44 6f 63 69 64 29 7b 0a 20 20 61 70 70 65 6e  iDocid){.  appen
2260: 64 56 61 72 69 6e 74 28 64 2c 20 69 44 6f 63 69  dVarint(d, iDoci
2270: 64 29 3b 0a 20 20 69 66 28 20 64 2d 3e 69 54 79  d);.  if( d->iTy
2280: 70 65 3e 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e 53  pe>=DL_POSITIONS
2290: 20 29 7b 0a 20 20 20 20 61 70 70 65 6e 64 56 61   ){.    appendVa
22a0: 72 69 6e 74 28 64 2c 20 50 4f 53 5f 45 4e 44 29  rint(d, POS_END)
22b0: 3b 20 20 2f 2a 20 69 6e 69 74 69 61 6c 6c 79 20  ;  /* initially 
22c0: 65 6d 70 74 79 20 70 6f 73 69 74 69 6f 6e 20 6c  empty position l
22d0: 69 73 74 20 2a 2f 0a 20 20 20 20 64 2d 3e 69 4c  ist */.    d->iL
22e0: 61 73 74 43 6f 6c 75 6d 6e 20 3d 20 30 3b 0a 20  astColumn = 0;. 
22f0: 20 20 20 64 2d 3e 69 4c 61 73 74 50 6f 73 20 3d     d->iLastPos =
2300: 20 64 2d 3e 69 4c 61 73 74 4f 66 66 73 65 74 20   d->iLastOffset 
2310: 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 68  = 0;.  }.}../* h
2320: 65 6c 70 65 72 20 66 75 6e 63 74 69 6f 6e 20 66  elper function f
2330: 6f 72 20 64 6f 63 4c 69 73 74 41 64 64 50 6f 73  or docListAddPos
2340: 20 61 6e 64 20 64 6f 63 4c 69 73 74 41 64 64 50   and docListAddP
2350: 6f 73 4f 66 66 73 65 74 20 2a 2f 0a 73 74 61 74  osOffset */.stat
2360: 69 63 20 76 6f 69 64 20 61 64 64 50 6f 73 28 44  ic void addPos(D
2370: 6f 63 4c 69 73 74 20 2a 64 2c 20 69 6e 74 20 69  ocList *d, int i
2380: 43 6f 6c 75 6d 6e 2c 20 69 6e 74 20 69 50 6f 73  Column, int iPos
2390: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 64 2d 3e  ){.  assert( d->
23a0: 6e 44 61 74 61 3e 30 20 29 3b 0a 20 20 2d 2d 64  nData>0 );.  --d
23b0: 2d 3e 6e 44 61 74 61 3b 20 20 2f 2a 20 72 65 6d  ->nData;  /* rem
23c0: 6f 76 65 20 70 72 65 76 69 6f 75 73 20 74 65 72  ove previous ter
23d0: 6d 69 6e 61 74 6f 72 20 2a 2f 0a 20 20 69 66 28  minator */.  if(
23e0: 20 69 43 6f 6c 75 6d 6e 21 3d 64 2d 3e 69 4c 61   iColumn!=d->iLa
23f0: 73 74 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20  stColumn ){.    
2400: 61 73 73 65 72 74 28 20 69 43 6f 6c 75 6d 6e 3e  assert( iColumn>
2410: 64 2d 3e 69 4c 61 73 74 43 6f 6c 75 6d 6e 20 29  d->iLastColumn )
2420: 3b 0a 20 20 20 20 61 70 70 65 6e 64 56 61 72 69  ;.    appendVari
2430: 6e 74 28 64 2c 20 50 4f 53 5f 43 4f 4c 55 4d 4e  nt(d, POS_COLUMN
2440: 29 3b 0a 20 20 20 20 61 70 70 65 6e 64 56 61 72  );.    appendVar
2450: 69 6e 74 28 64 2c 20 69 43 6f 6c 75 6d 6e 29 3b  int(d, iColumn);
2460: 0a 20 20 20 20 64 2d 3e 69 4c 61 73 74 43 6f 6c  .    d->iLastCol
2470: 75 6d 6e 20 3d 20 69 43 6f 6c 75 6d 6e 3b 0a 20  umn = iColumn;. 
2480: 20 20 20 64 2d 3e 69 4c 61 73 74 50 6f 73 20 3d     d->iLastPos =
2490: 20 64 2d 3e 69 4c 61 73 74 4f 66 66 73 65 74 20   d->iLastOffset 
24a0: 3d 20 30 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72  = 0;.  }.  asser
24b0: 74 28 20 69 50 6f 73 3e 3d 64 2d 3e 69 4c 61 73  t( iPos>=d->iLas
24c0: 74 50 6f 73 20 29 3b 0a 20 20 61 70 70 65 6e 64  tPos );.  append
24d0: 56 61 72 69 6e 74 28 64 2c 20 69 50 6f 73 2d 64  Varint(d, iPos-d
24e0: 2d 3e 69 4c 61 73 74 50 6f 73 2b 50 4f 53 5f 42  ->iLastPos+POS_B
24f0: 41 53 45 29 3b 0a 20 20 64 2d 3e 69 4c 61 73 74  ASE);.  d->iLast
2500: 50 6f 73 20 3d 20 69 50 6f 73 3b 0a 7d 0a 0a 2f  Pos = iPos;.}../
2510: 2a 20 41 64 64 20 61 20 70 6f 73 69 74 69 6f 6e  * Add a position
2520: 20 74 6f 20 74 68 65 20 6c 61 73 74 20 70 6f 73   to the last pos
2530: 69 74 69 6f 6e 20 6c 69 73 74 20 69 6e 20 61 20  ition list in a 
2540: 64 6f 63 6c 69 73 74 2e 20 2a 2f 0a 73 74 61 74  doclist. */.stat
2550: 69 63 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 41  ic void docListA
2560: 64 64 50 6f 73 28 44 6f 63 4c 69 73 74 20 2a 64  ddPos(DocList *d
2570: 2c 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 2c 20 69  , int iColumn, i
2580: 6e 74 20 69 50 6f 73 29 7b 0a 20 20 61 73 73 65  nt iPos){.  asse
2590: 72 74 28 20 64 2d 3e 69 54 79 70 65 3d 3d 44 4c  rt( d->iType==DL
25a0: 5f 50 4f 53 49 54 49 4f 4e 53 20 29 3b 0a 20 20  _POSITIONS );.  
25b0: 61 64 64 50 6f 73 28 64 2c 20 69 43 6f 6c 75 6d  addPos(d, iColum
25c0: 6e 2c 20 69 50 6f 73 29 3b 0a 20 20 61 70 70 65  n, iPos);.  appe
25d0: 6e 64 56 61 72 69 6e 74 28 64 2c 20 50 4f 53 5f  ndVarint(d, POS_
25e0: 45 4e 44 29 3b 20 20 2f 2a 20 61 64 64 20 6e 65  END);  /* add ne
25f0: 77 20 74 65 72 6d 69 6e 61 74 6f 72 20 2a 2f 0a  w terminator */.
2600: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 70  }../*.** Add a p
2610: 6f 73 69 74 69 6f 6e 20 61 6e 64 20 73 74 61 72  osition and star
2620: 74 69 6e 67 20 61 6e 64 20 65 6e 64 69 6e 67 20  ting and ending 
2630: 6f 66 66 73 65 74 73 20 74 6f 20 61 20 64 6f 63  offsets to a doc
2640: 6c 69 73 74 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  list..**.** If t
2650: 68 65 20 64 6f 63 6c 69 73 74 20 69 73 20 73 65  he doclist is se
2660: 74 75 70 20 74 6f 20 68 61 6e 64 6c 65 20 6f 6e  tup to handle on
2670: 6c 79 20 70 6f 73 69 74 69 6f 6e 73 2c 20 74 68  ly positions, th
2680: 65 6e 20 69 6e 73 65 72 74 0a 2a 2a 20 74 68 65  en insert.** the
2690: 20 70 6f 73 69 74 69 6f 6e 20 6f 6e 6c 79 20 61   position only a
26a0: 6e 64 20 69 67 6e 6f 72 65 20 74 68 65 20 6f 66  nd ignore the of
26b0: 66 73 65 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  fsets..*/.static
26c0: 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 41 64 64   void docListAdd
26d0: 50 6f 73 4f 66 66 73 65 74 28 0a 20 20 44 6f 63  PosOffset(.  Doc
26e0: 4c 69 73 74 20 2a 64 2c 20 20 20 20 20 20 20 20  List *d,        
26f0: 20 20 20 20 20 2f 2a 20 44 6f 63 6c 69 73 74 20       /* Doclist 
2700: 75 6e 64 65 72 20 63 6f 6e 73 74 72 75 63 74 69  under constructi
2710: 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c  on */.  int iCol
2720: 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  umn,            
2730: 2f 2a 20 43 6f 6c 75 6d 6e 20 74 68 65 20 69 6e  /* Column the in
2740: 73 65 72 74 65 64 20 74 65 72 6d 20 69 73 20 70  serted term is p
2750: 61 72 74 20 6f 66 20 2a 2f 0a 20 20 69 6e 74 20  art of */.  int 
2760: 69 50 6f 73 2c 20 20 20 20 20 20 20 20 20 20 20  iPos,           
2770: 20 20 20 20 2f 2a 20 50 6f 73 69 74 69 6f 6e 20      /* Position 
2780: 6f 66 20 74 68 65 20 69 6e 73 65 72 74 65 64 20  of the inserted 
2790: 74 65 72 6d 20 2a 2f 0a 20 20 69 6e 74 20 69 53  term */.  int iS
27a0: 74 61 72 74 4f 66 66 73 65 74 2c 20 20 20 20 20  tartOffset,     
27b0: 20 20 2f 2a 20 53 74 61 72 74 69 6e 67 20 6f 66    /* Starting of
27c0: 66 73 65 74 20 6f 66 20 69 6e 73 65 72 74 65 64  fset of inserted
27d0: 20 74 65 72 6d 20 2a 2f 0a 20 20 69 6e 74 20 69   term */.  int i
27e0: 45 6e 64 4f 66 66 73 65 74 20 20 20 20 20 20 20  EndOffset       
27f0: 20 20 20 2f 2a 20 45 6e 64 69 6e 67 20 6f 66 66     /* Ending off
2800: 73 65 74 20 6f 66 20 69 6e 73 65 72 74 65 64 20  set of inserted 
2810: 74 65 72 6d 20 2a 2f 0a 29 7b 0a 20 20 61 73 73  term */.){.  ass
2820: 65 72 74 28 20 64 2d 3e 69 54 79 70 65 3e 3d 44  ert( d->iType>=D
2830: 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 29 3b 0a 20  L_POSITIONS );. 
2840: 20 61 64 64 50 6f 73 28 64 2c 20 69 43 6f 6c 75   addPos(d, iColu
2850: 6d 6e 2c 20 69 50 6f 73 29 3b 0a 20 20 69 66 28  mn, iPos);.  if(
2860: 20 64 2d 3e 69 54 79 70 65 3d 3d 44 4c 5f 50 4f   d->iType==DL_PO
2870: 53 49 54 49 4f 4e 53 5f 4f 46 46 53 45 54 53 20  SITIONS_OFFSETS 
2880: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 69  ){.    assert( i
2890: 53 74 61 72 74 4f 66 66 73 65 74 3e 3d 64 2d 3e  StartOffset>=d->
28a0: 69 4c 61 73 74 4f 66 66 73 65 74 20 29 3b 0a 20  iLastOffset );. 
28b0: 20 20 20 61 70 70 65 6e 64 56 61 72 69 6e 74 28     appendVarint(
28c0: 64 2c 20 69 53 74 61 72 74 4f 66 66 73 65 74 2d  d, iStartOffset-
28d0: 64 2d 3e 69 4c 61 73 74 4f 66 66 73 65 74 29 3b  d->iLastOffset);
28e0: 0a 20 20 20 20 64 2d 3e 69 4c 61 73 74 4f 66 66  .    d->iLastOff
28f0: 73 65 74 20 3d 20 69 53 74 61 72 74 4f 66 66 73  set = iStartOffs
2900: 65 74 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  et;.    assert( 
2910: 69 45 6e 64 4f 66 66 73 65 74 3e 3d 69 53 74 61  iEndOffset>=iSta
2920: 72 74 4f 66 66 73 65 74 20 29 3b 0a 20 20 20 20  rtOffset );.    
2930: 61 70 70 65 6e 64 56 61 72 69 6e 74 28 64 2c 20  appendVarint(d, 
2940: 69 45 6e 64 4f 66 66 73 65 74 2d 69 53 74 61 72  iEndOffset-iStar
2950: 74 4f 66 66 73 65 74 29 3b 0a 20 20 7d 0a 20 20  tOffset);.  }.  
2960: 61 70 70 65 6e 64 56 61 72 69 6e 74 28 64 2c 20  appendVarint(d, 
2970: 50 4f 53 5f 45 4e 44 29 3b 20 20 2f 2a 20 61 64  POS_END);  /* ad
2980: 64 20 6e 65 77 20 74 65 72 6d 69 6e 61 74 6f 72  d new terminator
2990: 20 2a 2f 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 20 44   */.}../*.** A D
29a0: 6f 63 4c 69 73 74 52 65 61 64 65 72 20 6f 62 6a  ocListReader obj
29b0: 65 63 74 20 69 73 20 61 20 63 75 72 73 6f 72 20  ect is a cursor 
29c0: 69 6e 74 6f 20 61 20 64 6f 63 6c 69 73 74 2e 20  into a doclist. 
29d0: 20 49 6e 69 74 69 61 6c 69 7a 65 0a 2a 2a 20 74   Initialize.** t
29e0: 68 65 20 63 75 72 73 6f 72 20 74 6f 20 74 68 65  he cursor to the
29f0: 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68   beginning of th
2a00: 65 20 64 6f 63 6c 69 73 74 20 62 79 20 63 61 6c  e doclist by cal
2a10: 6c 69 6e 67 20 72 65 61 64 65 72 49 6e 69 74 28  ling readerInit(
2a20: 29 2e 0a 2a 2a 20 54 68 65 6e 20 75 73 65 20 72  )..** Then use r
2a30: 6f 75 74 69 6e 65 73 0a 2a 2a 0a 2a 2a 20 20 20  outines.**.**   
2a40: 20 20 20 70 65 65 6b 44 6f 63 69 64 28 29 0a 2a     peekDocid().*
2a50: 2a 20 20 20 20 20 20 72 65 61 64 44 6f 63 69 64  *      readDocid
2a60: 28 29 0a 2a 2a 20 20 20 20 20 20 72 65 61 64 50  ().**      readP
2a70: 6f 73 69 74 69 6f 6e 28 29 0a 2a 2a 20 20 20 20  osition().**    
2a80: 20 20 73 6b 69 70 50 6f 73 69 74 69 6f 6e 4c 69    skipPositionLi
2a90: 73 74 28 29 0a 2a 2a 20 20 20 20 20 20 61 6e 64  st().**      and
2aa0: 20 73 6f 20 66 6f 72 74 68 2e 2e 2e 0a 2a 2a 0a   so forth....**.
2ab0: 2a 2a 20 74 6f 20 72 65 61 64 20 69 6e 66 6f 72  ** to read infor
2ac0: 6d 61 74 69 6f 6e 20 6f 75 74 20 6f 66 20 74 68  mation out of th
2ad0: 65 20 64 6f 63 6c 69 73 74 2e 20 20 57 68 65 6e  e doclist.  When
2ae0: 20 77 65 20 72 65 61 63 68 20 74 68 65 20 65 6e   we reach the en
2af0: 64 0a 2a 2a 20 6f 66 20 74 68 65 20 64 6f 63 6c  d.** of the docl
2b00: 69 73 74 2c 20 61 74 45 6e 64 28 29 20 72 65 74  ist, atEnd() ret
2b10: 75 72 6e 73 20 54 52 55 45 2e 0a 2a 2f 0a 74 79  urns TRUE..*/.ty
2b20: 70 65 64 65 66 20 73 74 72 75 63 74 20 44 6f 63  pedef struct Doc
2b30: 4c 69 73 74 52 65 61 64 65 72 20 7b 0a 20 20 44  ListReader {.  D
2b40: 6f 63 4c 69 73 74 20 2a 70 44 6f 63 6c 69 73 74  ocList *pDoclist
2b50: 3b 20 20 2f 2a 20 54 68 65 20 64 6f 63 75 6d 65  ;  /* The docume
2b60: 6e 74 20 6c 69 73 74 20 77 65 20 61 72 65 20 73  nt list we are s
2b70: 74 65 70 70 69 6e 67 20 74 68 72 6f 75 67 68 20  tepping through 
2b80: 2a 2f 0a 20 20 63 68 61 72 20 2a 70 3b 20 20 20  */.  char *p;   
2b90: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
2ba0: 74 65 72 20 74 6f 20 6e 65 78 74 20 75 6e 72 65  ter to next unre
2bb0: 61 64 20 62 79 74 65 20 69 6e 20 74 68 65 20 64  ad byte in the d
2bc0: 6f 63 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20  oclist */.  int 
2bd0: 69 4c 61 73 74 43 6f 6c 75 6d 6e 3b 0a 20 20 69  iLastColumn;.  i
2be0: 6e 74 20 69 4c 61 73 74 50 6f 73 3b 20 20 2f 2a  nt iLastPos;  /*
2bf0: 20 74 68 65 20 6c 61 73 74 20 70 6f 73 69 74 69   the last positi
2c00: 6f 6e 20 72 65 61 64 2c 20 6f 72 20 2d 31 20 77  on read, or -1 w
2c10: 68 65 6e 20 6e 6f 74 20 69 6e 20 61 20 70 6f 73  hen not in a pos
2c20: 69 74 69 6f 6e 20 6c 69 73 74 20 2a 2f 0a 7d 20  ition list */.} 
2c30: 44 6f 63 4c 69 73 74 52 65 61 64 65 72 3b 0a 0a  DocListReader;..
2c40: 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65  /*.** Initialize
2c50: 20 74 68 65 20 44 6f 63 4c 69 73 74 52 65 61 64   the DocListRead
2c60: 65 72 20 72 20 74 6f 20 70 6f 69 6e 74 20 74 6f  er r to point to
2c70: 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f   the beginning o
2c80: 66 20 70 44 6f 63 6c 69 73 74 2e 0a 2a 2f 0a 73  f pDoclist..*/.s
2c90: 74 61 74 69 63 20 76 6f 69 64 20 72 65 61 64 65  tatic void reade
2ca0: 72 49 6e 69 74 28 44 6f 63 4c 69 73 74 52 65 61  rInit(DocListRea
2cb0: 64 65 72 20 2a 72 2c 20 44 6f 63 4c 69 73 74 20  der *r, DocList 
2cc0: 2a 70 44 6f 63 6c 69 73 74 29 7b 0a 20 20 72 2d  *pDoclist){.  r-
2cd0: 3e 70 44 6f 63 6c 69 73 74 20 3d 20 70 44 6f 63  >pDoclist = pDoc
2ce0: 6c 69 73 74 3b 0a 20 20 69 66 28 20 70 44 6f 63  list;.  if( pDoc
2cf0: 6c 69 73 74 21 3d 4e 55 4c 4c 20 29 7b 0a 20 20  list!=NULL ){.  
2d00: 20 20 72 2d 3e 70 20 3d 20 70 44 6f 63 6c 69 73    r->p = pDoclis
2d10: 74 2d 3e 70 44 61 74 61 3b 0a 20 20 7d 0a 20 20  t->pData;.  }.  
2d20: 72 2d 3e 69 4c 61 73 74 43 6f 6c 75 6d 6e 20 3d  r->iLastColumn =
2d30: 20 2d 31 3b 0a 20 20 72 2d 3e 69 4c 61 73 74 50   -1;.  r->iLastP
2d40: 6f 73 20 3d 20 2d 31 3b 0a 7d 0a 0a 2f 2a 0a 2a  os = -1;.}../*.*
2d50: 2a 20 52 65 74 75 72 6e 20 54 52 55 45 20 69 66  * Return TRUE if
2d60: 20 77 65 20 68 61 76 65 20 72 65 61 63 68 65 64   we have reached
2d70: 20 74 68 65 6e 20 65 6e 64 20 6f 66 20 70 52 65   then end of pRe
2d80: 61 64 65 72 20 61 6e 64 20 74 68 65 72 65 20 69  ader and there i
2d90: 73 0a 2a 2a 20 6e 6f 74 68 69 6e 67 20 65 6c 73  s.** nothing els
2da0: 65 20 6c 65 66 74 20 74 6f 20 72 65 61 64 2e 0a  e left to read..
2db0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 74  */.static int at
2dc0: 45 6e 64 28 44 6f 63 4c 69 73 74 52 65 61 64 65  End(DocListReade
2dd0: 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 72  r *pReader){.  r
2de0: 65 74 75 72 6e 20 70 52 65 61 64 65 72 2d 3e 70  eturn pReader->p
2df0: 44 6f 63 6c 69 73 74 3d 3d 30 20 7c 7c 20 28 70  Doclist==0 || (p
2e00: 52 65 61 64 65 72 2d 3e 70 20 3e 3d 20 64 6f 63  Reader->p >= doc
2e10: 4c 69 73 74 45 6e 64 28 70 52 65 61 64 65 72 2d  ListEnd(pReader-
2e20: 3e 70 44 6f 63 6c 69 73 74 29 29 3b 0a 7d 0a 0a  >pDoclist));.}..
2e30: 2f 2a 20 50 65 65 6b 20 61 74 20 74 68 65 20 6e  /* Peek at the n
2e40: 65 78 74 20 64 6f 63 69 64 20 77 69 74 68 6f 75  ext docid withou
2e50: 74 20 61 64 76 61 6e 63 69 6e 67 20 74 68 65 20  t advancing the 
2e60: 72 65 61 64 20 70 6f 69 6e 74 65 72 2e 20 0a 2a  read pointer. .*
2e70: 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 5f  /.static sqlite_
2e80: 69 6e 74 36 34 20 70 65 65 6b 44 6f 63 69 64 28  int64 peekDocid(
2e90: 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20 2a 70  DocListReader *p
2ea0: 52 65 61 64 65 72 29 7b 0a 20 20 73 71 6c 69 74  Reader){.  sqlit
2eb0: 65 5f 69 6e 74 36 34 20 72 65 74 3b 0a 20 20 61  e_int64 ret;.  a
2ec0: 73 73 65 72 74 28 20 21 61 74 45 6e 64 28 70 52  ssert( !atEnd(pR
2ed0: 65 61 64 65 72 29 20 29 3b 0a 20 20 61 73 73 65  eader) );.  asse
2ee0: 72 74 28 20 70 52 65 61 64 65 72 2d 3e 69 4c 61  rt( pReader->iLa
2ef0: 73 74 50 6f 73 3d 3d 2d 31 20 29 3b 0a 20 20 67  stPos==-1 );.  g
2f00: 65 74 56 61 72 69 6e 74 28 70 52 65 61 64 65 72  etVarint(pReader
2f10: 2d 3e 70 2c 20 26 72 65 74 29 3b 0a 20 20 72 65  ->p, &ret);.  re
2f20: 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 2f 2a 20  turn ret;.}../* 
2f30: 52 65 61 64 20 74 68 65 20 6e 65 78 74 20 64 6f  Read the next do
2f40: 63 69 64 2e 20 20 20 53 65 65 20 61 6c 73 6f 20  cid.   See also 
2f50: 6e 65 78 74 44 6f 63 69 64 28 29 2e 0a 2a 2f 0a  nextDocid()..*/.
2f60: 73 74 61 74 69 63 20 73 71 6c 69 74 65 5f 69 6e  static sqlite_in
2f70: 74 36 34 20 72 65 61 64 44 6f 63 69 64 28 44 6f  t64 readDocid(Do
2f80: 63 4c 69 73 74 52 65 61 64 65 72 20 2a 70 52 65  cListReader *pRe
2f90: 61 64 65 72 29 7b 0a 20 20 73 71 6c 69 74 65 5f  ader){.  sqlite_
2fa0: 69 6e 74 36 34 20 72 65 74 3b 0a 20 20 61 73 73  int64 ret;.  ass
2fb0: 65 72 74 28 20 21 61 74 45 6e 64 28 70 52 65 61  ert( !atEnd(pRea
2fc0: 64 65 72 29 20 29 3b 0a 20 20 61 73 73 65 72 74  der) );.  assert
2fd0: 28 20 70 52 65 61 64 65 72 2d 3e 69 4c 61 73 74  ( pReader->iLast
2fe0: 50 6f 73 3d 3d 2d 31 20 29 3b 0a 20 20 70 52 65  Pos==-1 );.  pRe
2ff0: 61 64 65 72 2d 3e 70 20 2b 3d 20 67 65 74 56 61  ader->p += getVa
3000: 72 69 6e 74 28 70 52 65 61 64 65 72 2d 3e 70 2c  rint(pReader->p,
3010: 20 26 72 65 74 29 3b 0a 20 20 69 66 28 20 70 52   &ret);.  if( pR
3020: 65 61 64 65 72 2d 3e 70 44 6f 63 6c 69 73 74 2d  eader->pDoclist-
3030: 3e 69 54 79 70 65 3e 3d 44 4c 5f 50 4f 53 49 54  >iType>=DL_POSIT
3040: 49 4f 4e 53 20 29 7b 0a 20 20 20 20 70 52 65 61  IONS ){.    pRea
3050: 64 65 72 2d 3e 69 4c 61 73 74 43 6f 6c 75 6d 6e  der->iLastColumn
3060: 20 3d 20 30 3b 0a 20 20 20 20 70 52 65 61 64 65   = 0;.    pReade
3070: 72 2d 3e 69 4c 61 73 74 50 6f 73 20 3d 20 30 3b  r->iLastPos = 0;
3080: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 65  .  }.  return re
3090: 74 3b 0a 7d 0a 0a 2f 2a 20 52 65 61 64 20 74 68  t;.}../* Read th
30a0: 65 20 6e 65 78 74 20 70 6f 73 69 74 69 6f 6e 20  e next position 
30b0: 61 6e 64 20 63 6f 6c 75 6d 6e 20 69 6e 64 65 78  and column index
30c0: 20 66 72 6f 6d 20 61 20 70 6f 73 69 74 69 6f 6e   from a position
30d0: 20 6c 69 73 74 2e 0a 20 2a 20 52 65 74 75 72 6e   list.. * Return
30e0: 73 20 74 68 65 20 70 6f 73 69 74 69 6f 6e 2c 20  s the position, 
30f0: 6f 72 20 2d 31 20 61 74 20 74 68 65 20 65 6e 64  or -1 at the end
3100: 20 6f 66 20 74 68 65 20 6c 69 73 74 2e 20 2a 2f   of the list. */
3110: 0a 73 74 61 74 69 63 20 69 6e 74 20 72 65 61 64  .static int read
3120: 50 6f 73 69 74 69 6f 6e 28 44 6f 63 4c 69 73 74  Position(DocList
3130: 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 2c  Reader *pReader,
3140: 20 69 6e 74 20 2a 69 43 6f 6c 75 6d 6e 29 7b 0a   int *iColumn){.
3150: 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 69    int i;.  int i
3160: 54 79 70 65 20 3d 20 70 52 65 61 64 65 72 2d 3e  Type = pReader->
3170: 70 44 6f 63 6c 69 73 74 2d 3e 69 54 79 70 65 3b  pDoclist->iType;
3180: 0a 0a 20 20 69 66 28 20 70 52 65 61 64 65 72 2d  ..  if( pReader-
3190: 3e 69 4c 61 73 74 50 6f 73 3d 3d 2d 31 20 29 7b  >iLastPos==-1 ){
31a0: 0a 20 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a  .    return -1;.
31b0: 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20 21 61    }.  assert( !a
31c0: 74 45 6e 64 28 70 52 65 61 64 65 72 29 20 29 3b  tEnd(pReader) );
31d0: 0a 0a 20 20 69 66 28 20 69 54 79 70 65 3c 44 4c  ..  if( iType<DL
31e0: 5f 50 4f 53 49 54 49 4f 4e 53 20 29 7b 0a 20 20  _POSITIONS ){.  
31f0: 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 7d    return -1;.  }
3200: 0a 20 20 70 52 65 61 64 65 72 2d 3e 70 20 2b 3d  .  pReader->p +=
3210: 20 67 65 74 56 61 72 69 6e 74 33 32 28 70 52 65   getVarint32(pRe
3220: 61 64 65 72 2d 3e 70 2c 20 26 69 29 3b 0a 20 20  ader->p, &i);.  
3230: 69 66 28 20 69 3d 3d 50 4f 53 5f 45 4e 44 20 29  if( i==POS_END )
3240: 7b 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e 69  {.    pReader->i
3250: 4c 61 73 74 43 6f 6c 75 6d 6e 20 3d 20 70 52 65  LastColumn = pRe
3260: 61 64 65 72 2d 3e 69 4c 61 73 74 50 6f 73 20 3d  ader->iLastPos =
3270: 20 2d 31 3b 0a 20 20 20 20 2a 69 43 6f 6c 75 6d   -1;.    *iColum
3280: 6e 20 3d 20 2d 31 3b 0a 20 20 20 20 72 65 74 75  n = -1;.    retu
3290: 72 6e 20 2d 31 3b 0a 20 20 7d 0a 20 20 69 66 28  rn -1;.  }.  if(
32a0: 20 69 3d 3d 50 4f 53 5f 43 4f 4c 55 4d 4e 20 29   i==POS_COLUMN )
32b0: 7b 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e 70  {.    pReader->p
32c0: 20 2b 3d 20 67 65 74 56 61 72 69 6e 74 33 32 28   += getVarint32(
32d0: 70 52 65 61 64 65 72 2d 3e 70 2c 20 26 70 52 65  pReader->p, &pRe
32e0: 61 64 65 72 2d 3e 69 4c 61 73 74 43 6f 6c 75 6d  ader->iLastColum
32f0: 6e 29 3b 0a 20 20 20 20 70 52 65 61 64 65 72 2d  n);.    pReader-
3300: 3e 69 4c 61 73 74 50 6f 73 20 3d 20 30 3b 0a 20  >iLastPos = 0;. 
3310: 20 20 20 70 52 65 61 64 65 72 2d 3e 70 20 2b 3d     pReader->p +=
3320: 20 67 65 74 56 61 72 69 6e 74 33 32 28 70 52 65   getVarint32(pRe
3330: 61 64 65 72 2d 3e 70 2c 20 26 69 29 3b 0a 20 20  ader->p, &i);.  
3340: 20 20 61 73 73 65 72 74 28 20 69 3e 3d 50 4f 53    assert( i>=POS
3350: 5f 42 41 53 45 20 29 3b 0a 20 20 7d 0a 20 20 70  _BASE );.  }.  p
3360: 52 65 61 64 65 72 2d 3e 69 4c 61 73 74 50 6f 73  Reader->iLastPos
3370: 20 2b 3d 20 28 28 69 6e 74 29 20 69 29 2d 50 4f   += ((int) i)-PO
3380: 53 5f 42 41 53 45 3b 0a 20 20 69 66 28 20 69 54  S_BASE;.  if( iT
3390: 79 70 65 3e 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e  ype>=DL_POSITION
33a0: 53 5f 4f 46 46 53 45 54 53 20 29 7b 0a 20 20 20  S_OFFSETS ){.   
33b0: 20 2f 2a 20 53 6b 69 70 20 6f 76 65 72 20 6f 66   /* Skip over of
33c0: 66 73 65 74 73 2c 20 69 67 6e 6f 72 69 6e 67 20  fsets, ignoring 
33d0: 74 68 65 6d 20 66 6f 72 20 6e 6f 77 2e 20 2a 2f  them for now. */
33e0: 0a 20 20 20 20 69 6e 74 20 69 53 74 61 72 74 2c  .    int iStart,
33f0: 20 69 45 6e 64 3b 0a 20 20 20 20 70 52 65 61 64   iEnd;.    pRead
3400: 65 72 2d 3e 70 20 2b 3d 20 67 65 74 56 61 72 69  er->p += getVari
3410: 6e 74 33 32 28 70 52 65 61 64 65 72 2d 3e 70 2c  nt32(pReader->p,
3420: 20 26 69 53 74 61 72 74 29 3b 0a 20 20 20 20 70   &iStart);.    p
3430: 52 65 61 64 65 72 2d 3e 70 20 2b 3d 20 67 65 74  Reader->p += get
3440: 56 61 72 69 6e 74 33 32 28 70 52 65 61 64 65 72  Varint32(pReader
3450: 2d 3e 70 2c 20 26 69 45 6e 64 29 3b 0a 20 20 7d  ->p, &iEnd);.  }
3460: 0a 20 20 2a 69 43 6f 6c 75 6d 6e 20 3d 20 70 52  .  *iColumn = pR
3470: 65 61 64 65 72 2d 3e 69 4c 61 73 74 43 6f 6c 75  eader->iLastColu
3480: 6d 6e 3b 0a 20 20 72 65 74 75 72 6e 20 70 52 65  mn;.  return pRe
3490: 61 64 65 72 2d 3e 69 4c 61 73 74 50 6f 73 3b 0a  ader->iLastPos;.
34a0: 7d 0a 0a 2f 2a 20 53 6b 69 70 20 70 61 73 74 20  }../* Skip past 
34b0: 74 68 65 20 65 6e 64 20 6f 66 20 61 20 70 6f 73  the end of a pos
34c0: 69 74 69 6f 6e 20 6c 69 73 74 2e 20 2a 2f 0a 73  ition list. */.s
34d0: 74 61 74 69 63 20 76 6f 69 64 20 73 6b 69 70 50  tatic void skipP
34e0: 6f 73 69 74 69 6f 6e 4c 69 73 74 28 44 6f 63 4c  ositionList(DocL
34f0: 69 73 74 52 65 61 64 65 72 20 2a 70 52 65 61 64  istReader *pRead
3500: 65 72 29 7b 0a 20 20 44 6f 63 4c 69 73 74 20 2a  er){.  DocList *
3510: 70 20 3d 20 70 52 65 61 64 65 72 2d 3e 70 44 6f  p = pReader->pDo
3520: 63 6c 69 73 74 3b 0a 20 20 69 66 28 20 70 20 26  clist;.  if( p &
3530: 26 20 70 2d 3e 69 54 79 70 65 3e 3d 44 4c 5f 50  & p->iType>=DL_P
3540: 4f 53 49 54 49 4f 4e 53 20 29 7b 0a 20 20 20 20  OSITIONS ){.    
3550: 69 6e 74 20 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20  int iColumn;.   
3560: 20 77 68 69 6c 65 28 20 72 65 61 64 50 6f 73 69   while( readPosi
3570: 74 69 6f 6e 28 70 52 65 61 64 65 72 2c 20 26 69  tion(pReader, &i
3580: 43 6f 6c 75 6d 6e 29 21 3d 2d 31 20 29 7b 7d 0a  Column)!=-1 ){}.
3590: 20 20 7d 0a 7d 0a 0a 2f 2a 20 53 6b 69 70 20 6f    }.}../* Skip o
35a0: 76 65 72 20 61 20 64 6f 63 69 64 2c 20 69 6e 63  ver a docid, inc
35b0: 6c 75 64 69 6e 67 20 69 74 73 20 70 6f 73 69 74  luding its posit
35c0: 69 6f 6e 20 6c 69 73 74 20 69 66 20 74 68 65 20  ion list if the 
35d0: 64 6f 63 6c 69 73 74 20 68 61 73 0a 20 2a 20 70  doclist has. * p
35e0: 6f 73 69 74 69 6f 6e 73 2e 20 2a 2f 0a 73 74 61  ositions. */.sta
35f0: 74 69 63 20 76 6f 69 64 20 73 6b 69 70 44 6f 63  tic void skipDoc
3600: 75 6d 65 6e 74 28 44 6f 63 4c 69 73 74 52 65 61  ument(DocListRea
3610: 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20  der *pReader){. 
3620: 20 72 65 61 64 44 6f 63 69 64 28 70 52 65 61 64   readDocid(pRead
3630: 65 72 29 3b 0a 20 20 73 6b 69 70 50 6f 73 69 74  er);.  skipPosit
3640: 69 6f 6e 4c 69 73 74 28 70 52 65 61 64 65 72 29  ionList(pReader)
3650: 3b 0a 7d 0a 0a 2f 2a 20 53 6b 69 70 20 70 61 73  ;.}../* Skip pas
3660: 74 20 61 6c 6c 20 64 6f 63 69 64 73 20 77 68 69  t all docids whi
3670: 63 68 20 61 72 65 20 6c 65 73 73 20 74 68 61 6e  ch are less than
3680: 20 5b 69 44 6f 63 69 64 5d 2e 20 20 52 65 74 75   [iDocid].  Retu
3690: 72 6e 73 20 31 20 69 66 20 61 20 64 6f 63 69 64  rns 1 if a docid
36a0: 0a 20 2a 20 6d 61 74 63 68 69 6e 67 20 5b 69 44  . * matching [iD
36b0: 6f 63 69 64 5d 20 77 61 73 20 66 6f 75 6e 64 2e  ocid] was found.
36c0: 20 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20    */.static int 
36d0: 73 6b 69 70 54 6f 44 6f 63 69 64 28 44 6f 63 4c  skipToDocid(DocL
36e0: 69 73 74 52 65 61 64 65 72 20 2a 70 52 65 61 64  istReader *pRead
36f0: 65 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  er, sqlite_int64
3700: 20 69 44 6f 63 69 64 29 7b 0a 20 20 73 71 6c 69   iDocid){.  sqli
3710: 74 65 5f 69 6e 74 36 34 20 64 20 3d 20 30 3b 0a  te_int64 d = 0;.
3720: 20 20 77 68 69 6c 65 28 20 21 61 74 45 6e 64 28    while( !atEnd(
3730: 70 52 65 61 64 65 72 29 20 26 26 20 28 64 3d 70  pReader) && (d=p
3740: 65 65 6b 44 6f 63 69 64 28 70 52 65 61 64 65 72  eekDocid(pReader
3750: 29 29 3c 69 44 6f 63 69 64 20 29 7b 0a 20 20 20  ))<iDocid ){.   
3760: 20 73 6b 69 70 44 6f 63 75 6d 65 6e 74 28 70 52   skipDocument(pR
3770: 65 61 64 65 72 29 3b 0a 20 20 7d 0a 20 20 72 65  eader);.  }.  re
3780: 74 75 72 6e 20 21 61 74 45 6e 64 28 70 52 65 61  turn !atEnd(pRea
3790: 64 65 72 29 20 26 26 20 64 3d 3d 69 44 6f 63 69  der) && d==iDoci
37a0: 64 3b 0a 7d 0a 0a 2f 2a 20 52 65 74 75 72 6e 20  d;.}../* Return 
37b0: 74 68 65 20 66 69 72 73 74 20 64 6f 63 75 6d 65  the first docume
37c0: 6e 74 20 69 6e 20 61 20 64 6f 63 75 6d 65 6e 74  nt in a document
37d0: 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63   list..*/.static
37e0: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 66 69   sqlite_int64 fi
37f0: 72 73 74 44 6f 63 69 64 28 44 6f 63 4c 69 73 74  rstDocid(DocList
3800: 20 2a 64 29 7b 0a 20 20 44 6f 63 4c 69 73 74 52   *d){.  DocListR
3810: 65 61 64 65 72 20 72 3b 0a 20 20 72 65 61 64 65  eader r;.  reade
3820: 72 49 6e 69 74 28 26 72 2c 20 64 29 3b 0a 20 20  rInit(&r, d);.  
3830: 72 65 74 75 72 6e 20 72 65 61 64 44 6f 63 69 64  return readDocid
3840: 28 26 72 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20  (&r);.}..#ifdef 
3850: 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 2f 2a 0a  SQLITE_DEBUG./*.
3860: 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
3870: 69 73 20 75 73 65 64 20 66 6f 72 20 64 65 62 75  is used for debu
3880: 67 67 69 6e 67 20 70 75 72 70 6f 73 65 20 6f 6e  gging purpose on
3890: 6c 79 2e 0a 2a 2a 0a 2a 2a 20 57 72 69 74 65 20  ly..**.** Write 
38a0: 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  the content of a
38b0: 20 64 6f 63 6c 69 73 74 20 74 6f 20 73 74 61 6e   doclist to stan
38c0: 64 61 72 64 20 6f 75 74 70 75 74 2e 0a 2a 2f 0a  dard output..*/.
38d0: 73 74 61 74 69 63 20 76 6f 69 64 20 70 72 69 6e  static void prin
38e0: 74 44 6f 63 6c 69 73 74 28 44 6f 63 4c 69 73 74  tDoclist(DocList
38f0: 20 2a 70 29 7b 0a 20 20 44 6f 63 4c 69 73 74 52   *p){.  DocListR
3900: 65 61 64 65 72 20 72 3b 0a 20 20 63 6f 6e 73 74  eader r;.  const
3910: 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20 22 22   char *zSep = ""
3920: 3b 0a 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28  ;..  readerInit(
3930: 26 72 2c 20 70 29 3b 0a 20 20 77 68 69 6c 65 28  &r, p);.  while(
3940: 20 21 61 74 45 6e 64 28 26 72 29 20 29 7b 0a 20   !atEnd(&r) ){. 
3950: 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20     sqlite_int64 
3960: 64 6f 63 69 64 20 3d 20 72 65 61 64 44 6f 63 69  docid = readDoci
3970: 64 28 26 72 29 3b 0a 20 20 20 20 69 66 28 20 64  d(&r);.    if( d
3980: 6f 63 69 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20  ocid==0 ){.     
3990: 20 73 6b 69 70 50 6f 73 69 74 69 6f 6e 4c 69 73   skipPositionLis
39a0: 74 28 26 72 29 3b 0a 20 20 20 20 20 20 63 6f 6e  t(&r);.      con
39b0: 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 20 20 20  tinue;.    }.   
39c0: 20 70 72 69 6e 74 66 28 22 25 73 25 6c 6c 64 22   printf("%s%lld"
39d0: 2c 20 7a 53 65 70 2c 20 64 6f 63 69 64 29 3b 0a  , zSep, docid);.
39e0: 20 20 20 20 7a 53 65 70 20 3d 20 20 22 2c 22 3b      zSep =  ",";
39f0: 0a 20 20 20 20 69 66 28 20 70 2d 3e 69 54 79 70  .    if( p->iTyp
3a00: 65 3e 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20  e>=DL_POSITIONS 
3a10: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 50 6f  ){.      int iPo
3a20: 73 2c 20 69 43 6f 6c 3b 0a 20 20 20 20 20 20 63  s, iCol;.      c
3a30: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 69 76 20  onst char *zDiv 
3a40: 3d 20 22 22 3b 0a 20 20 20 20 20 20 70 72 69 6e  = "";.      prin
3a50: 74 66 28 22 28 22 29 3b 0a 20 20 20 20 20 20 77  tf("(");.      w
3a60: 68 69 6c 65 28 20 28 69 50 6f 73 20 3d 20 72 65  hile( (iPos = re
3a70: 61 64 50 6f 73 69 74 69 6f 6e 28 26 72 2c 20 26  adPosition(&r, &
3a80: 69 43 6f 6c 29 29 3e 3d 30 20 29 7b 0a 20 20 20  iCol))>=0 ){.   
3a90: 20 20 20 20 20 70 72 69 6e 74 66 28 22 25 73 25       printf("%s%
3aa0: 64 3a 25 64 22 2c 20 7a 44 69 76 2c 20 69 43 6f  d:%d", zDiv, iCo
3ab0: 6c 2c 20 69 50 6f 73 29 3b 0a 20 20 20 20 20 20  l, iPos);.      
3ac0: 20 20 7a 44 69 76 20 3d 20 22 3a 22 3b 0a 20 20    zDiv = ":";.  
3ad0: 20 20 20 20 7d 0a 20 20 20 20 20 20 70 72 69 6e      }.      prin
3ae0: 74 66 28 22 29 22 29 3b 0a 20 20 20 20 7d 0a 20  tf(")");.    }. 
3af0: 20 7d 0a 20 20 70 72 69 6e 74 66 28 22 5c 6e 22   }.  printf("\n"
3b00: 29 3b 0a 20 20 66 66 6c 75 73 68 28 73 74 64 6f  );.  fflush(stdo
3b10: 75 74 29 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a  ut);.}.#endif /*
3b20: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 20 2a 2f   SQLITE_DEBUG */
3b30: 0a 0a 2f 2a 20 54 72 69 6d 20 74 68 65 20 67 69  ../* Trim the gi
3b40: 76 65 6e 20 64 6f 63 6c 69 73 74 20 74 6f 20 63  ven doclist to c
3b50: 6f 6e 74 61 69 6e 20 6f 6e 6c 79 20 70 6f 73 69  ontain only posi
3b60: 74 69 6f 6e 73 20 69 6e 20 63 6f 6c 75 6d 6e 0a  tions in column.
3b70: 20 2a 20 5b 69 52 65 73 74 72 69 63 74 43 6f 6c   * [iRestrictCol
3b80: 75 6d 6e 5d 2e 20 2a 2f 0a 73 74 61 74 69 63 20  umn]. */.static 
3b90: 76 6f 69 64 20 64 6f 63 4c 69 73 74 52 65 73 74  void docListRest
3ba0: 72 69 63 74 43 6f 6c 75 6d 6e 28 44 6f 63 4c 69  rictColumn(DocLi
3bb0: 73 74 20 2a 69 6e 2c 20 69 6e 74 20 69 52 65 73  st *in, int iRes
3bc0: 74 72 69 63 74 43 6f 6c 75 6d 6e 29 7b 0a 20 20  trictColumn){.  
3bd0: 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20 72 3b  DocListReader r;
3be0: 0a 20 20 44 6f 63 4c 69 73 74 20 6f 75 74 3b 0a  .  DocList out;.
3bf0: 0a 20 20 61 73 73 65 72 74 28 20 69 6e 2d 3e 69  .  assert( in->i
3c00: 54 79 70 65 3e 3d 44 4c 5f 50 4f 53 49 54 49 4f  Type>=DL_POSITIO
3c10: 4e 53 20 29 3b 0a 20 20 72 65 61 64 65 72 49 6e  NS );.  readerIn
3c20: 69 74 28 26 72 2c 20 69 6e 29 3b 0a 20 20 64 6f  it(&r, in);.  do
3c30: 63 4c 69 73 74 49 6e 69 74 28 26 6f 75 74 2c 20  cListInit(&out, 
3c40: 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 2c 20 4e 55  DL_POSITIONS, NU
3c50: 4c 4c 2c 20 30 29 3b 0a 0a 20 20 77 68 69 6c 65  LL, 0);..  while
3c60: 28 20 21 61 74 45 6e 64 28 26 72 29 20 29 7b 0a  ( !atEnd(&r) ){.
3c70: 20 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34      sqlite_int64
3c80: 20 69 44 6f 63 69 64 20 3d 20 72 65 61 64 44 6f   iDocid = readDo
3c90: 63 69 64 28 26 72 29 3b 0a 20 20 20 20 69 6e 74  cid(&r);.    int
3ca0: 20 69 50 6f 73 2c 20 69 43 6f 6c 75 6d 6e 3b 0a   iPos, iColumn;.
3cb0: 0a 20 20 20 20 64 6f 63 4c 69 73 74 41 64 64 44  .    docListAddD
3cc0: 6f 63 69 64 28 26 6f 75 74 2c 20 69 44 6f 63 69  ocid(&out, iDoci
3cd0: 64 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28  d);.    while( (
3ce0: 69 50 6f 73 20 3d 20 72 65 61 64 50 6f 73 69 74  iPos = readPosit
3cf0: 69 6f 6e 28 26 72 2c 20 26 69 43 6f 6c 75 6d 6e  ion(&r, &iColumn
3d00: 29 29 20 21 3d 20 2d 31 20 29 7b 0a 20 20 20 20  )) != -1 ){.    
3d10: 20 20 69 66 28 20 69 43 6f 6c 75 6d 6e 3d 3d 69    if( iColumn==i
3d20: 52 65 73 74 72 69 63 74 43 6f 6c 75 6d 6e 20 29  RestrictColumn )
3d30: 7b 0a 20 20 20 20 20 20 20 20 64 6f 63 4c 69 73  {.        docLis
3d40: 74 41 64 64 50 6f 73 28 26 6f 75 74 2c 20 69 43  tAddPos(&out, iC
3d50: 6f 6c 75 6d 6e 2c 20 69 50 6f 73 29 3b 0a 20 20  olumn, iPos);.  
3d60: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
3d70: 0a 20 20 64 6f 63 4c 69 73 74 44 65 73 74 72 6f  .  docListDestro
3d80: 79 28 69 6e 29 3b 0a 20 20 2a 69 6e 20 3d 20 6f  y(in);.  *in = o
3d90: 75 74 3b 0a 7d 0a 0a 2f 2a 20 54 72 69 6d 20 74  ut;.}../* Trim t
3da0: 68 65 20 67 69 76 65 6e 20 64 6f 63 6c 69 73 74  he given doclist
3db0: 20 62 79 20 64 69 73 63 61 72 64 69 6e 67 20 61   by discarding a
3dc0: 6e 79 20 64 6f 63 69 64 73 20 77 69 74 68 6f 75  ny docids withou
3dd0: 74 20 61 6e 79 20 72 65 6d 61 69 6e 69 6e 67 0a  t any remaining.
3de0: 20 2a 20 70 6f 73 69 74 69 6f 6e 73 2e 20 2a 2f   * positions. */
3df0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f 63  .static void doc
3e00: 4c 69 73 74 44 69 73 63 61 72 64 45 6d 70 74 79  ListDiscardEmpty
3e10: 28 44 6f 63 4c 69 73 74 20 2a 69 6e 29 20 7b 0a  (DocList *in) {.
3e20: 20 20 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20    DocListReader 
3e30: 72 3b 0a 20 20 44 6f 63 4c 69 73 74 20 6f 75 74  r;.  DocList out
3e40: 3b 0a 0a 20 20 2f 2a 20 54 4f 44 4f 3a 20 49 74  ;..  /* TODO: It
3e50: 20 77 6f 75 6c 64 20 62 65 20 6e 69 63 65 20 74   would be nice t
3e60: 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 74 68 69 73  o implement this
3e70: 20 6f 70 65 72 61 74 69 6f 6e 20 69 6e 20 70 6c   operation in pl
3e80: 61 63 65 3b 20 74 68 61 74 0a 20 20 20 2a 20 63  ace; that.   * c
3e90: 6f 75 6c 64 20 73 61 76 65 20 61 20 73 69 67 6e  ould save a sign
3ea0: 69 66 69 63 61 6e 74 20 61 6d 6f 75 6e 74 20 6f  ificant amount o
3eb0: 66 20 6d 65 6d 6f 72 79 20 69 6e 20 71 75 65 72  f memory in quer
3ec0: 69 65 73 20 77 69 74 68 20 6c 6f 6e 67 20 64 6f  ies with long do
3ed0: 63 6c 69 73 74 73 2e 20 2a 2f 0a 20 20 61 73 73  clists. */.  ass
3ee0: 65 72 74 28 20 69 6e 2d 3e 69 54 79 70 65 3e 3d  ert( in->iType>=
3ef0: 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 29 3b 0a  DL_POSITIONS );.
3f00: 20 20 72 65 61 64 65 72 49 6e 69 74 28 26 72 2c    readerInit(&r,
3f10: 20 69 6e 29 3b 0a 20 20 64 6f 63 4c 69 73 74 49   in);.  docListI
3f20: 6e 69 74 28 26 6f 75 74 2c 20 44 4c 5f 50 4f 53  nit(&out, DL_POS
3f30: 49 54 49 4f 4e 53 2c 20 4e 55 4c 4c 2c 20 30 29  ITIONS, NULL, 0)
3f40: 3b 0a 0a 20 20 77 68 69 6c 65 28 20 21 61 74 45  ;..  while( !atE
3f50: 6e 64 28 26 72 29 20 29 7b 0a 20 20 20 20 73 71  nd(&r) ){.    sq
3f60: 6c 69 74 65 5f 69 6e 74 36 34 20 69 44 6f 63 69  lite_int64 iDoci
3f70: 64 20 3d 20 72 65 61 64 44 6f 63 69 64 28 26 72  d = readDocid(&r
3f80: 29 3b 0a 20 20 20 20 69 6e 74 20 6d 61 74 63 68  );.    int match
3f90: 20 3d 20 30 3b 0a 20 20 20 20 69 6e 74 20 69 50   = 0;.    int iP
3fa0: 6f 73 2c 20 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20  os, iColumn;.   
3fb0: 20 77 68 69 6c 65 28 20 28 69 50 6f 73 20 3d 20   while( (iPos = 
3fc0: 72 65 61 64 50 6f 73 69 74 69 6f 6e 28 26 72 2c  readPosition(&r,
3fd0: 20 26 69 43 6f 6c 75 6d 6e 29 29 20 21 3d 20 2d   &iColumn)) != -
3fe0: 31 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 21  1 ){.      if( !
3ff0: 6d 61 74 63 68 20 29 7b 0a 20 20 20 20 20 20 20  match ){.       
4000: 20 64 6f 63 4c 69 73 74 41 64 64 44 6f 63 69 64   docListAddDocid
4010: 28 26 6f 75 74 2c 20 69 44 6f 63 69 64 29 3b 0a  (&out, iDocid);.
4020: 20 20 20 20 20 20 20 20 6d 61 74 63 68 20 3d 20          match = 
4030: 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  1;.      }.     
4040: 20 64 6f 63 4c 69 73 74 41 64 64 50 6f 73 28 26   docListAddPos(&
4050: 6f 75 74 2c 20 69 43 6f 6c 75 6d 6e 2c 20 69 50  out, iColumn, iP
4060: 6f 73 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  os);.    }.  }..
4070: 20 20 64 6f 63 4c 69 73 74 44 65 73 74 72 6f 79    docListDestroy
4080: 28 69 6e 29 3b 0a 20 20 2a 69 6e 20 3d 20 6f 75  (in);.  *in = ou
4090: 74 3b 0a 7d 0a 0a 2f 2a 20 48 65 6c 70 65 72 20  t;.}../* Helper 
40a0: 66 75 6e 63 74 69 6f 6e 20 66 6f 72 20 64 6f 63  function for doc
40b0: 4c 69 73 74 55 70 64 61 74 65 28 29 20 61 6e 64  ListUpdate() and
40c0: 20 64 6f 63 4c 69 73 74 41 63 63 75 6d 75 6c 61   docListAccumula
40d0: 74 65 28 29 2e 0a 2a 2a 20 53 70 6c 69 63 65 73  te()..** Splices
40e0: 20 61 20 64 6f 63 6c 69 73 74 20 65 6c 65 6d 65   a doclist eleme
40f0: 6e 74 20 69 6e 74 6f 20 74 68 65 20 64 6f 63 6c  nt into the docl
4100: 69 73 74 20 72 65 70 72 65 73 65 6e 74 65 64 20  ist represented 
4110: 62 79 20 72 2c 0a 2a 2a 20 6c 65 61 76 69 6e 67  by r,.** leaving
4120: 20 72 20 70 6f 69 6e 74 69 6e 67 20 61 66 74 65   r pointing afte
4130: 72 20 74 68 65 20 6e 65 77 6c 79 20 73 70 6c 69  r the newly spli
4140: 63 65 64 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2f 0a  ced element..*/.
4150: 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f 63 4c  static void docL
4160: 69 73 74 53 70 6c 69 63 65 45 6c 65 6d 65 6e 74  istSpliceElement
4170: 28 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20 2a  (DocListReader *
4180: 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  r, sqlite_int64 
4190: 69 44 6f 63 69 64 2c 0a 20 20 20 20 20 20 20 20  iDocid,.        
41a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
41b0: 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63           const c
41c0: 68 61 72 20 2a 70 53 6f 75 72 63 65 2c 20 69 6e  har *pSource, in
41d0: 74 20 6e 53 6f 75 72 63 65 29 7b 0a 20 20 44 6f  t nSource){.  Do
41e0: 63 4c 69 73 74 20 2a 64 20 3d 20 72 2d 3e 70 44  cList *d = r->pD
41f0: 6f 63 6c 69 73 74 3b 0a 20 20 63 68 61 72 20 2a  oclist;.  char *
4200: 70 54 61 72 67 65 74 3b 0a 20 20 69 6e 74 20 6e  pTarget;.  int n
4210: 54 61 72 67 65 74 2c 20 66 6f 75 6e 64 3b 0a 0a  Target, found;..
4220: 20 20 66 6f 75 6e 64 20 3d 20 73 6b 69 70 54 6f    found = skipTo
4230: 44 6f 63 69 64 28 72 2c 20 69 44 6f 63 69 64 29  Docid(r, iDocid)
4240: 3b 0a 0a 20 20 2f 2a 20 44 65 73 63 72 69 62 65  ;..  /* Describe
4250: 20 73 6c 69 63 65 20 69 6e 20 64 20 74 6f 20 70   slice in d to p
4260: 6c 61 63 65 20 70 53 6f 75 72 63 65 2f 6e 53 6f  lace pSource/nSo
4270: 75 72 63 65 2e 20 2a 2f 0a 20 20 70 54 61 72 67  urce. */.  pTarg
4280: 65 74 20 3d 20 72 2d 3e 70 3b 0a 20 20 69 66 28  et = r->p;.  if(
4290: 20 66 6f 75 6e 64 20 29 7b 0a 20 20 20 20 73 6b   found ){.    sk
42a0: 69 70 44 6f 63 75 6d 65 6e 74 28 72 29 3b 0a 20  ipDocument(r);. 
42b0: 20 20 20 6e 54 61 72 67 65 74 20 3d 20 72 2d 3e     nTarget = r->
42c0: 70 2d 70 54 61 72 67 65 74 3b 0a 20 20 7d 65 6c  p-pTarget;.  }el
42d0: 73 65 7b 0a 20 20 20 20 6e 54 61 72 67 65 74 20  se{.    nTarget 
42e0: 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54  = 0;.  }..  /* T
42f0: 68 65 20 73 65 6e 73 65 20 6f 66 20 74 68 65 20  he sense of the 
4300: 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 74 68 61  following is tha
4310: 74 20 74 68 65 72 65 20 61 72 65 20 74 68 72 65  t there are thre
4320: 65 20 70 6f 73 73 69 62 69 6c 69 74 69 65 73 2e  e possibilities.
4330: 0a 20 20 2a 2a 20 49 66 20 6e 54 61 72 67 65 74  .  ** If nTarget
4340: 3d 3d 6e 53 6f 75 72 63 65 2c 20 77 65 20 73 68  ==nSource, we sh
4350: 6f 75 6c 64 20 6e 6f 74 20 6d 6f 76 65 20 61 6e  ould not move an
4360: 79 20 6d 65 6d 6f 72 79 20 6e 6f 72 20 72 65 61  y memory nor rea
4370: 6c 6c 6f 63 2e 0a 20 20 2a 2a 20 49 66 20 6e 54  lloc..  ** If nT
4380: 61 72 67 65 74 3e 6e 53 6f 75 72 63 65 2c 20 74  arget>nSource, t
4390: 72 69 6d 20 74 61 72 67 65 74 20 61 6e 64 20 72  rim target and r
43a0: 65 61 6c 6c 6f 63 2e 0a 20 20 2a 2a 20 49 66 20  ealloc..  ** If 
43b0: 6e 54 61 72 67 65 74 3c 6e 53 6f 75 72 63 65 2c  nTarget<nSource,
43c0: 20 72 65 61 6c 6c 6f 63 20 74 68 65 6e 20 65 78   realloc then ex
43d0: 70 61 6e 64 20 74 61 72 67 65 74 2e 0a 20 20 2a  pand target..  *
43e0: 2f 0a 20 20 69 66 28 20 6e 54 61 72 67 65 74 3e  /.  if( nTarget>
43f0: 6e 53 6f 75 72 63 65 20 29 7b 0a 20 20 20 20 6d  nSource ){.    m
4400: 65 6d 6d 6f 76 65 28 70 54 61 72 67 65 74 2b 6e  emmove(pTarget+n
4410: 53 6f 75 72 63 65 2c 20 70 54 61 72 67 65 74 2b  Source, pTarget+
4420: 6e 54 61 72 67 65 74 2c 20 64 6f 63 4c 69 73 74  nTarget, docList
4430: 45 6e 64 28 64 29 2d 28 70 54 61 72 67 65 74 2b  End(d)-(pTarget+
4440: 6e 54 61 72 67 65 74 29 29 3b 0a 20 20 7d 0a 20  nTarget));.  }. 
4450: 20 69 66 28 20 6e 54 61 72 67 65 74 21 3d 6e 53   if( nTarget!=nS
4460: 6f 75 72 63 65 20 29 7b 0a 20 20 20 20 69 6e 74  ource ){.    int
4470: 20 69 44 6f 63 6c 69 73 74 20 3d 20 70 54 61 72   iDoclist = pTar
4480: 67 65 74 2d 64 2d 3e 70 44 61 74 61 3b 0a 20 20  get-d->pData;.  
4490: 20 20 64 2d 3e 70 44 61 74 61 20 3d 20 72 65 61    d->pData = rea
44a0: 6c 6c 6f 63 28 64 2d 3e 70 44 61 74 61 2c 20 64  lloc(d->pData, d
44b0: 2d 3e 6e 44 61 74 61 2b 6e 53 6f 75 72 63 65 2d  ->nData+nSource-
44c0: 6e 54 61 72 67 65 74 29 3b 0a 20 20 20 20 70 54  nTarget);.    pT
44d0: 61 72 67 65 74 20 3d 20 64 2d 3e 70 44 61 74 61  arget = d->pData
44e0: 2b 69 44 6f 63 6c 69 73 74 3b 0a 20 20 7d 0a 20  +iDoclist;.  }. 
44f0: 20 69 66 28 20 6e 54 61 72 67 65 74 3c 6e 53 6f   if( nTarget<nSo
4500: 75 72 63 65 20 29 7b 0a 20 20 20 20 6d 65 6d 6d  urce ){.    memm
4510: 6f 76 65 28 70 54 61 72 67 65 74 2b 6e 53 6f 75  ove(pTarget+nSou
4520: 72 63 65 2c 20 70 54 61 72 67 65 74 2b 6e 54 61  rce, pTarget+nTa
4530: 72 67 65 74 2c 20 64 6f 63 4c 69 73 74 45 6e 64  rget, docListEnd
4540: 28 64 29 2d 28 70 54 61 72 67 65 74 2b 6e 54 61  (d)-(pTarget+nTa
4550: 72 67 65 74 29 29 3b 0a 20 20 7d 0a 0a 20 20 6d  rget));.  }..  m
4560: 65 6d 63 70 79 28 70 54 61 72 67 65 74 2c 20 70  emcpy(pTarget, p
4570: 53 6f 75 72 63 65 2c 20 6e 53 6f 75 72 63 65 29  Source, nSource)
4580: 3b 0a 20 20 64 2d 3e 6e 44 61 74 61 20 2b 3d 20  ;.  d->nData += 
4590: 6e 53 6f 75 72 63 65 2d 6e 54 61 72 67 65 74 3b  nSource-nTarget;
45a0: 0a 20 20 72 2d 3e 70 20 3d 20 70 54 61 72 67 65  .  r->p = pTarge
45b0: 74 2b 6e 53 6f 75 72 63 65 3b 0a 7d 0a 0a 2f 2a  t+nSource;.}../*
45c0: 20 49 6e 73 65 72 74 2f 75 70 64 61 74 65 20 70   Insert/update p
45d0: 55 70 64 61 74 65 20 69 6e 74 6f 20 74 68 65 20  Update into the 
45e0: 64 6f 63 6c 69 73 74 2e 20 2a 2f 0a 73 74 61 74  doclist. */.stat
45f0: 69 63 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 55  ic void docListU
4600: 70 64 61 74 65 28 44 6f 63 4c 69 73 74 20 2a 64  pdate(DocList *d
4610: 2c 20 44 6f 63 4c 69 73 74 20 2a 70 55 70 64 61  , DocList *pUpda
4620: 74 65 29 7b 0a 20 20 44 6f 63 4c 69 73 74 52 65  te){.  DocListRe
4630: 61 64 65 72 20 72 65 61 64 65 72 3b 0a 0a 20 20  ader reader;..  
4640: 61 73 73 65 72 74 28 20 64 21 3d 4e 55 4c 4c 20  assert( d!=NULL 
4650: 26 26 20 70 55 70 64 61 74 65 21 3d 4e 55 4c 4c  && pUpdate!=NULL
4660: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 64 2d   );.  assert( d-
4670: 3e 69 54 79 70 65 3d 3d 70 55 70 64 61 74 65 2d  >iType==pUpdate-
4680: 3e 69 54 79 70 65 29 3b 0a 0a 20 20 72 65 61 64  >iType);..  read
4690: 65 72 49 6e 69 74 28 26 72 65 61 64 65 72 2c 20  erInit(&reader, 
46a0: 64 29 3b 0a 20 20 64 6f 63 4c 69 73 74 53 70 6c  d);.  docListSpl
46b0: 69 63 65 45 6c 65 6d 65 6e 74 28 26 72 65 61 64  iceElement(&read
46c0: 65 72 2c 20 66 69 72 73 74 44 6f 63 69 64 28 70  er, firstDocid(p
46d0: 55 70 64 61 74 65 29 2c 0a 20 20 20 20 20 20 20  Update),.       
46e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
46f0: 70 55 70 64 61 74 65 2d 3e 70 44 61 74 61 2c 20  pUpdate->pData, 
4700: 70 55 70 64 61 74 65 2d 3e 6e 44 61 74 61 29 3b  pUpdate->nData);
4710: 0a 7d 0a 0a 2f 2a 20 50 72 6f 70 61 67 61 74 65  .}../* Propagate
4720: 20 65 6c 65 6d 65 6e 74 73 20 66 72 6f 6d 20 70   elements from p
4730: 55 70 64 61 74 65 20 74 6f 20 70 41 63 63 2c 20  Update to pAcc, 
4740: 6f 76 65 72 77 72 69 74 69 6e 67 20 65 6c 65 6d  overwriting elem
4750: 65 6e 74 73 20 77 69 74 68 0a 2a 2a 20 6d 61 74  ents with.** mat
4760: 63 68 69 6e 67 20 64 6f 63 69 64 73 2e 0a 2a 2f  ching docids..*/
4770: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f 63  .static void doc
4780: 4c 69 73 74 41 63 63 75 6d 75 6c 61 74 65 28 44  ListAccumulate(D
4790: 6f 63 4c 69 73 74 20 2a 70 41 63 63 2c 20 44 6f  ocList *pAcc, Do
47a0: 63 4c 69 73 74 20 2a 70 55 70 64 61 74 65 29 7b  cList *pUpdate){
47b0: 0a 20 20 44 6f 63 4c 69 73 74 52 65 61 64 65 72  .  DocListReader
47c0: 20 61 63 63 52 65 61 64 65 72 2c 20 75 70 64 61   accReader, upda
47d0: 74 65 52 65 61 64 65 72 3b 0a 0a 20 20 2f 2a 20  teReader;..  /* 
47e0: 48 61 6e 64 6c 65 20 65 64 67 65 20 63 61 73 65  Handle edge case
47f0: 73 20 77 68 65 72 65 20 6f 6e 65 20 64 6f 63 6c  s where one docl
4800: 69 73 74 20 69 73 20 65 6d 70 74 79 2e 20 2a 2f  ist is empty. */
4810: 0a 20 20 61 73 73 65 72 74 28 20 70 41 63 63 21  .  assert( pAcc!
4820: 3d 4e 55 4c 4c 20 29 3b 0a 20 20 69 66 28 20 70  =NULL );.  if( p
4830: 55 70 64 61 74 65 3d 3d 4e 55 4c 4c 20 7c 7c 20  Update==NULL || 
4840: 70 55 70 64 61 74 65 2d 3e 6e 44 61 74 61 3d 3d  pUpdate->nData==
4850: 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66  0 ) return;.  if
4860: 28 20 70 41 63 63 2d 3e 6e 44 61 74 61 3d 3d 30  ( pAcc->nData==0
4870: 20 29 7b 0a 20 20 20 20 70 41 63 63 2d 3e 70 44   ){.    pAcc->pD
4880: 61 74 61 20 3d 20 6d 61 6c 6c 6f 63 28 70 55 70  ata = malloc(pUp
4890: 64 61 74 65 2d 3e 6e 44 61 74 61 29 3b 0a 20 20  date->nData);.  
48a0: 20 20 6d 65 6d 63 70 79 28 70 41 63 63 2d 3e 70    memcpy(pAcc->p
48b0: 44 61 74 61 2c 20 70 55 70 64 61 74 65 2d 3e 70  Data, pUpdate->p
48c0: 44 61 74 61 2c 20 70 55 70 64 61 74 65 2d 3e 6e  Data, pUpdate->n
48d0: 44 61 74 61 29 3b 0a 20 20 20 20 70 41 63 63 2d  Data);.    pAcc-
48e0: 3e 6e 44 61 74 61 20 3d 20 70 55 70 64 61 74 65  >nData = pUpdate
48f0: 2d 3e 6e 44 61 74 61 3b 0a 20 20 20 20 72 65 74  ->nData;.    ret
4900: 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 72 65 61 64  urn;.  }..  read
4910: 65 72 49 6e 69 74 28 26 61 63 63 52 65 61 64 65  erInit(&accReade
4920: 72 2c 20 70 41 63 63 29 3b 0a 20 20 72 65 61 64  r, pAcc);.  read
4930: 65 72 49 6e 69 74 28 26 75 70 64 61 74 65 52 65  erInit(&updateRe
4940: 61 64 65 72 2c 20 70 55 70 64 61 74 65 29 3b 0a  ader, pUpdate);.
4950: 0a 20 20 77 68 69 6c 65 28 20 21 61 74 45 6e 64  .  while( !atEnd
4960: 28 26 75 70 64 61 74 65 52 65 61 64 65 72 29 20  (&updateReader) 
4970: 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 70 53 6f  ){.    char *pSo
4980: 75 72 63 65 20 3d 20 75 70 64 61 74 65 52 65 61  urce = updateRea
4990: 64 65 72 2e 70 3b 0a 20 20 20 20 73 71 6c 69 74  der.p;.    sqlit
49a0: 65 5f 69 6e 74 36 34 20 69 44 6f 63 69 64 20 3d  e_int64 iDocid =
49b0: 20 72 65 61 64 44 6f 63 69 64 28 26 75 70 64 61   readDocid(&upda
49c0: 74 65 52 65 61 64 65 72 29 3b 0a 20 20 20 20 73  teReader);.    s
49d0: 6b 69 70 50 6f 73 69 74 69 6f 6e 4c 69 73 74 28  kipPositionList(
49e0: 26 75 70 64 61 74 65 52 65 61 64 65 72 29 3b 0a  &updateReader);.
49f0: 20 20 20 20 64 6f 63 4c 69 73 74 53 70 6c 69 63      docListSplic
4a00: 65 45 6c 65 6d 65 6e 74 28 26 61 63 63 52 65 61  eElement(&accRea
4a10: 64 65 72 2c 20 69 44 6f 63 69 64 2c 20 70 53 6f  der, iDocid, pSo
4a20: 75 72 63 65 2c 20 75 70 64 61 74 65 52 65 61 64  urce, updateRead
4a30: 65 72 2e 70 2d 70 53 6f 75 72 63 65 29 3b 0a 20  er.p-pSource);. 
4a40: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64   }.}../*.** Read
4a50: 20 74 68 65 20 6e 65 78 74 20 64 6f 63 69 64 20   the next docid 
4a60: 6f 66 66 20 6f 66 20 70 49 6e 2e 20 20 52 65 74  off of pIn.  Ret
4a70: 75 72 6e 20 30 20 69 66 20 77 65 20 72 65 61 63  urn 0 if we reac
4a80: 68 20 74 68 65 20 65 6e 64 2e 0a 2a 0a 2a 20 54  h the end..*.* T
4a90: 4f 44 4f 3a 20 54 68 69 73 20 61 73 73 75 6d 65  ODO: This assume
4aa0: 73 20 74 68 61 74 20 64 6f 63 69 64 73 20 61 72  s that docids ar
4ab0: 65 20 6e 65 76 65 72 20 30 2c 20 62 75 74 20 74  e never 0, but t
4ac0: 68 65 79 20 6d 61 79 20 61 63 74 75 61 6c 6c 79  hey may actually
4ad0: 20 62 65 20 30 20 73 69 6e 63 65 0a 2a 20 75 73   be 0 since.* us
4ae0: 65 72 73 20 63 61 6e 20 63 68 6f 6f 73 65 20 64  ers can choose d
4af0: 6f 63 69 64 73 20 77 68 65 6e 20 69 6e 73 65 72  ocids when inser
4b00: 74 69 6e 67 20 69 6e 74 6f 20 61 20 66 75 6c 6c  ting into a full
4b10: 2d 74 65 78 74 20 74 61 62 6c 65 2e 20 20 46 69  -text table.  Fi
4b20: 78 20 74 68 69 73 2e 0a 2a 2f 0a 73 74 61 74 69  x this..*/.stati
4b30: 63 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 6e  c sqlite_int64 n
4b40: 65 78 74 44 6f 63 69 64 28 44 6f 63 4c 69 73 74  extDocid(DocList
4b50: 52 65 61 64 65 72 20 2a 70 49 6e 29 7b 0a 20 20  Reader *pIn){.  
4b60: 73 6b 69 70 50 6f 73 69 74 69 6f 6e 4c 69 73 74  skipPositionList
4b70: 28 70 49 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20  (pIn);.  return 
4b80: 61 74 45 6e 64 28 70 49 6e 29 20 3f 20 30 20 3a  atEnd(pIn) ? 0 :
4b90: 20 72 65 61 64 44 6f 63 69 64 28 70 49 6e 29 3b   readDocid(pIn);
4ba0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 70 4c 65 66 74 20  .}../*.** pLeft 
4bb0: 61 6e 64 20 70 52 69 67 68 74 20 61 72 65 20 74  and pRight are t
4bc0: 77 6f 20 44 6f 63 4c 69 73 74 52 65 61 64 65 72  wo DocListReader
4bd0: 73 20 74 68 61 74 20 61 72 65 20 70 6f 69 6e 74  s that are point
4be0: 69 6e 67 20 74 6f 0a 2a 2a 20 70 6f 73 69 74 69  ing to.** positi
4bf0: 6f 6e 73 20 6c 69 73 74 73 20 6f 66 20 74 68 65  ons lists of the
4c00: 20 73 61 6d 65 20 64 6f 63 75 6d 65 6e 74 3a 20   same document: 
4c10: 69 44 6f 63 69 64 2e 20 0a 2a 2a 0a 2a 2a 20 49  iDocid. .**.** I
4c20: 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 69  f there are no i
4c30: 6e 73 74 61 6e 63 65 73 20 69 6e 20 70 4c 65 66  nstances in pLef
4c40: 74 20 6f 72 20 70 52 69 67 68 74 20 77 68 65 72  t or pRight wher
4c50: 65 20 74 68 65 20 70 6f 73 69 74 69 6f 6e 0a 2a  e the position.*
4c60: 2a 20 6f 66 20 70 4c 65 66 74 20 69 73 20 6f 6e  * of pLeft is on
4c70: 65 20 6c 65 73 73 20 74 68 61 6e 20 74 68 65 20  e less than the 
4c80: 70 6f 73 69 74 69 6f 6e 20 6f 66 20 70 52 69 67  position of pRig
4c90: 68 74 2c 20 74 68 65 6e 20 74 68 69 73 0a 2a 2a  ht, then this.**
4ca0: 20 72 6f 75 74 69 6e 65 20 61 64 64 73 20 6e 6f   routine adds no
4cb0: 74 68 69 6e 67 20 74 6f 20 70 4f 75 74 2e 0a 2a  thing to pOut..*
4cc0: 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61 72  *.** If there ar
4cd0: 65 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 69 6e  e one or more in
4ce0: 73 74 61 6e 63 65 73 20 77 68 65 72 65 20 70 6f  stances where po
4cf0: 73 69 74 69 6f 6e 73 20 66 72 6f 6d 20 70 4c 65  sitions from pLe
4d00: 66 74 0a 2a 2a 20 61 72 65 20 65 78 61 63 74 6c  ft.** are exactl
4d10: 79 20 6f 6e 65 20 6c 65 73 73 20 74 68 61 6e 20  y one less than 
4d20: 70 6f 73 69 74 69 6f 6e 73 20 66 72 6f 6d 20 70  positions from p
4d30: 52 69 67 68 74 2c 20 74 68 65 6e 20 61 64 64 20  Right, then add 
4d40: 61 20 6e 65 77 0a 2a 2a 20 64 6f 63 75 6d 65 6e  a new.** documen
4d50: 74 20 72 65 63 6f 72 64 20 74 6f 20 70 4f 75 74  t record to pOut
4d60: 2e 20 20 49 66 20 70 4f 75 74 20 77 61 6e 74 73  .  If pOut wants
4d70: 20 74 6f 20 68 6f 6c 64 20 70 6f 73 69 74 69 6f   to hold positio
4d80: 6e 73 2c 20 74 68 65 6e 0a 2a 2a 20 69 6e 63 6c  ns, then.** incl
4d90: 75 64 65 20 74 68 65 20 70 6f 73 69 74 69 6f 6e  ude the position
4da0: 73 20 66 72 6f 6d 20 70 52 69 67 68 74 20 74 68  s from pRight th
4db0: 61 74 20 61 72 65 20 6f 6e 65 20 6d 6f 72 65 20  at are one more 
4dc0: 74 68 61 6e 20 61 0a 2a 2a 20 70 6f 73 69 74 69  than a.** positi
4dd0: 6f 6e 20 69 6e 20 70 4c 65 66 74 2e 20 20 49 6e  on in pLeft.  In
4de0: 20 6f 74 68 65 72 20 77 6f 72 64 73 3a 20 20 70   other words:  p
4df0: 52 69 67 68 74 2e 69 50 6f 73 3d 3d 70 4c 65 66  Right.iPos==pLef
4e00: 74 2e 69 50 6f 73 2b 31 2e 0a 2a 2a 0a 2a 2a 20  t.iPos+1..**.** 
4e10: 70 4c 65 66 74 20 61 6e 64 20 70 52 69 67 68 74  pLeft and pRight
4e20: 20 61 72 65 20 6c 65 66 74 20 70 6f 69 6e 74 69   are left pointi
4e30: 6e 67 20 61 74 20 74 68 65 20 6e 65 78 74 20 64  ng at the next d
4e40: 6f 63 75 6d 65 6e 74 20 72 65 63 6f 72 64 2e 0a  ocument record..
4e50: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d  */.static void m
4e60: 65 72 67 65 50 6f 73 4c 69 73 74 28 0a 20 20 44  ergePosList(.  D
4e70: 6f 63 4c 69 73 74 52 65 61 64 65 72 20 2a 70 4c  ocListReader *pL
4e80: 65 66 74 2c 20 20 20 20 2f 2a 20 4c 65 66 74 20  eft,    /* Left 
4e90: 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 20 2a 2f  position list */
4ea0: 0a 20 20 44 6f 63 4c 69 73 74 52 65 61 64 65 72  .  DocListReader
4eb0: 20 2a 70 52 69 67 68 74 2c 20 20 20 2f 2a 20 52   *pRight,   /* R
4ec0: 69 67 68 74 20 70 6f 73 69 74 69 6f 6e 20 6c 69  ight position li
4ed0: 73 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 5f 69  st */.  sqlite_i
4ee0: 6e 74 36 34 20 69 44 6f 63 69 64 2c 20 20 20 20  nt64 iDocid,    
4ef0: 20 2f 2a 20 54 68 65 20 64 6f 63 69 64 20 66 72   /* The docid fr
4f00: 6f 6d 20 70 4c 65 66 74 20 61 6e 64 20 70 52 69  om pLeft and pRi
4f10: 67 68 74 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74  ght */.  DocList
4f20: 20 2a 70 4f 75 74 20 20 20 20 20 20 20 20 20 20   *pOut          
4f30: 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 6d    /* Write the m
4f40: 65 72 67 65 64 20 64 6f 63 75 6d 65 6e 74 20 72  erged document r
4f50: 65 63 6f 72 64 20 68 65 72 65 20 2a 2f 0a 29 7b  ecord here */.){
4f60: 0a 20 20 69 6e 74 20 69 4c 65 66 74 43 6f 6c 2c  .  int iLeftCol,
4f70: 20 69 4c 65 66 74 50 6f 73 20 3d 20 72 65 61 64   iLeftPos = read
4f80: 50 6f 73 69 74 69 6f 6e 28 70 4c 65 66 74 2c 20  Position(pLeft, 
4f90: 26 69 4c 65 66 74 43 6f 6c 29 3b 0a 20 20 69 6e  &iLeftCol);.  in
4fa0: 74 20 69 52 69 67 68 74 43 6f 6c 2c 20 69 52 69  t iRightCol, iRi
4fb0: 67 68 74 50 6f 73 20 3d 20 72 65 61 64 50 6f 73  ghtPos = readPos
4fc0: 69 74 69 6f 6e 28 70 52 69 67 68 74 2c 20 26 69  ition(pRight, &i
4fd0: 52 69 67 68 74 43 6f 6c 29 3b 0a 20 20 69 6e 74  RightCol);.  int
4fe0: 20 6d 61 74 63 68 20 3d 20 30 3b 0a 0a 20 20 2f   match = 0;..  /
4ff0: 2a 20 4c 6f 6f 70 20 75 6e 74 69 6c 20 77 65 27  * Loop until we'
5000: 76 65 20 72 65 61 63 68 65 64 20 74 68 65 20 65  ve reached the e
5010: 6e 64 20 6f 66 20 62 6f 74 68 20 70 6f 73 69 74  nd of both posit
5020: 69 6f 6e 20 6c 69 73 74 73 2e 20 2a 2f 0a 20 20  ion lists. */.  
5030: 77 68 69 6c 65 28 20 69 4c 65 66 74 50 6f 73 21  while( iLeftPos!
5040: 3d 2d 31 20 26 26 20 69 52 69 67 68 74 50 6f 73  =-1 && iRightPos
5050: 21 3d 2d 31 20 29 7b 0a 20 20 20 20 69 66 28 20  !=-1 ){.    if( 
5060: 69 4c 65 66 74 43 6f 6c 3d 3d 69 52 69 67 68 74  iLeftCol==iRight
5070: 43 6f 6c 20 26 26 20 69 4c 65 66 74 50 6f 73 2b  Col && iLeftPos+
5080: 31 3d 3d 69 52 69 67 68 74 50 6f 73 20 29 7b 0a  1==iRightPos ){.
5090: 20 20 20 20 20 20 69 66 28 20 21 6d 61 74 63 68        if( !match
50a0: 20 29 7b 0a 20 20 20 20 20 20 20 20 64 6f 63 4c   ){.        docL
50b0: 69 73 74 41 64 64 44 6f 63 69 64 28 70 4f 75 74  istAddDocid(pOut
50c0: 2c 20 69 44 6f 63 69 64 29 3b 0a 20 20 20 20 20  , iDocid);.     
50d0: 20 20 20 6d 61 74 63 68 20 3d 20 31 3b 0a 20 20     match = 1;.  
50e0: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
50f0: 70 4f 75 74 2d 3e 69 54 79 70 65 3e 3d 44 4c 5f  pOut->iType>=DL_
5100: 50 4f 53 49 54 49 4f 4e 53 20 29 7b 0a 20 20 20  POSITIONS ){.   
5110: 20 20 20 20 20 64 6f 63 4c 69 73 74 41 64 64 50       docListAddP
5120: 6f 73 28 70 4f 75 74 2c 20 69 52 69 67 68 74 43  os(pOut, iRightC
5130: 6f 6c 2c 20 69 52 69 67 68 74 50 6f 73 29 3b 0a  ol, iRightPos);.
5140: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 4c        }.      iL
5150: 65 66 74 50 6f 73 20 3d 20 72 65 61 64 50 6f 73  eftPos = readPos
5160: 69 74 69 6f 6e 28 70 4c 65 66 74 2c 20 26 69 4c  ition(pLeft, &iL
5170: 65 66 74 43 6f 6c 29 3b 0a 20 20 20 20 20 20 69  eftCol);.      i
5180: 52 69 67 68 74 50 6f 73 20 3d 20 72 65 61 64 50  RightPos = readP
5190: 6f 73 69 74 69 6f 6e 28 70 52 69 67 68 74 2c 20  osition(pRight, 
51a0: 26 69 52 69 67 68 74 43 6f 6c 29 3b 0a 20 20 20  &iRightCol);.   
51b0: 20 7d 65 6c 73 65 20 69 66 28 20 69 52 69 67 68   }else if( iRigh
51c0: 74 43 6f 6c 3c 69 4c 65 66 74 43 6f 6c 20 7c 7c  tCol<iLeftCol ||
51d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 28  .              (
51e0: 69 52 69 67 68 74 43 6f 6c 3d 3d 69 4c 65 66 74  iRightCol==iLeft
51f0: 43 6f 6c 20 26 26 20 69 52 69 67 68 74 50 6f 73  Col && iRightPos
5200: 3c 69 4c 65 66 74 50 6f 73 2b 31 29 20 29 7b 0a  <iLeftPos+1) ){.
5210: 20 20 20 20 20 20 69 52 69 67 68 74 50 6f 73 20        iRightPos 
5220: 3d 20 72 65 61 64 50 6f 73 69 74 69 6f 6e 28 70  = readPosition(p
5230: 52 69 67 68 74 2c 20 26 69 52 69 67 68 74 43 6f  Right, &iRightCo
5240: 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  l);.    }else{. 
5250: 20 20 20 20 20 69 4c 65 66 74 50 6f 73 20 3d 20       iLeftPos = 
5260: 72 65 61 64 50 6f 73 69 74 69 6f 6e 28 70 4c 65  readPosition(pLe
5270: 66 74 2c 20 26 69 4c 65 66 74 43 6f 6c 29 3b 0a  ft, &iLeftCol);.
5280: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20      }.  }.  if( 
5290: 69 4c 65 66 74 50 6f 73 3e 3d 30 20 29 20 73 6b  iLeftPos>=0 ) sk
52a0: 69 70 50 6f 73 69 74 69 6f 6e 4c 69 73 74 28 70  ipPositionList(p
52b0: 4c 65 66 74 29 3b 0a 20 20 69 66 28 20 69 52 69  Left);.  if( iRi
52c0: 67 68 74 50 6f 73 3e 3d 30 20 29 20 73 6b 69 70  ghtPos>=0 ) skip
52d0: 50 6f 73 69 74 69 6f 6e 4c 69 73 74 28 70 52 69  PositionList(pRi
52e0: 67 68 74 29 3b 0a 7d 0a 0a 2f 2a 20 57 65 20 68  ght);.}../* We h
52f0: 61 76 65 20 74 77 6f 20 64 6f 63 6c 69 73 74 73  ave two doclists
5300: 3a 20 20 70 4c 65 66 74 20 61 6e 64 20 70 52 69  :  pLeft and pRi
5310: 67 68 74 2e 0a 2a 2a 20 57 72 69 74 65 20 74 68  ght..** Write th
5320: 65 20 70 68 72 61 73 65 20 69 6e 74 65 72 73 65  e phrase interse
5330: 63 74 69 6f 6e 20 6f 66 20 74 68 65 73 65 20 74  ction of these t
5340: 77 6f 20 64 6f 63 6c 69 73 74 73 20 69 6e 74 6f  wo doclists into
5350: 20 70 4f 75 74 2e 0a 2a 2a 0a 2a 2a 20 41 20 70   pOut..**.** A p
5360: 68 72 61 73 65 20 69 6e 74 65 72 73 65 63 74 69  hrase intersecti
5370: 6f 6e 20 6d 65 61 6e 73 20 74 68 61 74 20 74 77  on means that tw
5380: 6f 20 64 6f 63 75 6d 65 6e 74 73 20 6f 6e 6c 79  o documents only
5390: 20 6d 61 74 63 68 0a 2a 2a 20 69 66 20 70 4c 65   match.** if pLe
53a0: 66 74 2e 69 50 6f 73 2b 31 3d 3d 70 52 69 67 68  ft.iPos+1==pRigh
53b0: 74 2e 69 50 6f 73 2e 0a 2a 2a 0a 2a 2a 20 54 68  t.iPos..**.** Th
53c0: 65 20 6f 75 74 70 75 74 20 70 4f 75 74 20 6d 61  e output pOut ma
53d0: 79 20 6f 72 20 6d 61 79 20 6e 6f 74 20 63 6f 6e  y or may not con
53e0: 74 61 69 6e 20 70 6f 73 69 74 69 6f 6e 73 2e 20  tain positions. 
53f0: 20 49 66 20 70 4f 75 74 0a 2a 2a 20 64 6f 65 73   If pOut.** does
5400: 20 63 6f 6e 74 61 69 6e 20 70 6f 73 69 74 69 6f   contain positio
5410: 6e 73 2c 20 74 68 65 79 20 61 72 65 20 74 68 65  ns, they are the
5420: 20 70 6f 73 69 74 69 6f 6e 73 20 6f 66 20 70 52   positions of pR
5430: 69 67 68 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ight..*/.static 
5440: 76 6f 69 64 20 64 6f 63 4c 69 73 74 50 68 72 61  void docListPhra
5450: 73 65 4d 65 72 67 65 28 0a 20 20 44 6f 63 4c 69  seMerge(.  DocLi
5460: 73 74 20 2a 70 4c 65 66 74 2c 20 20 20 20 2f 2a  st *pLeft,    /*
5470: 20 44 6f 63 6c 69 73 74 20 72 65 73 75 6c 74 69   Doclist resulti
5480: 6e 67 20 66 72 6f 6d 20 74 68 65 20 77 6f 72 64  ng from the word
5490: 73 20 6f 6e 20 74 68 65 20 6c 65 66 74 20 2a 2f  s on the left */
54a0: 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70 52 69 67  .  DocList *pRig
54b0: 68 74 2c 20 20 20 2f 2a 20 44 6f 63 6c 69 73 74  ht,   /* Doclist
54c0: 20 66 6f 72 20 74 68 65 20 6e 65 78 74 20 77 6f   for the next wo
54d0: 72 64 20 74 6f 20 74 68 65 20 72 69 67 68 74 20  rd to the right 
54e0: 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70 4f  */.  DocList *pO
54f0: 75 74 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65  ut      /* Write
5500: 20 74 68 65 20 63 6f 6d 62 69 6e 65 64 20 64 6f   the combined do
5510: 63 6c 69 73 74 20 68 65 72 65 20 2a 2f 0a 29 7b  clist here */.){
5520: 0a 20 20 44 6f 63 4c 69 73 74 52 65 61 64 65 72  .  DocListReader
5530: 20 6c 65 66 74 2c 20 72 69 67 68 74 3b 0a 20 20   left, right;.  
5540: 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 64 6f 63  sqlite_int64 doc
5550: 69 64 4c 65 66 74 2c 20 64 6f 63 69 64 52 69 67  idLeft, docidRig
5560: 68 74 3b 0a 0a 20 20 72 65 61 64 65 72 49 6e 69  ht;..  readerIni
5570: 74 28 26 6c 65 66 74 2c 20 70 4c 65 66 74 29 3b  t(&left, pLeft);
5580: 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28 26 72  .  readerInit(&r
5590: 69 67 68 74 2c 20 70 52 69 67 68 74 29 3b 0a 20  ight, pRight);. 
55a0: 20 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65 78   docidLeft = nex
55b0: 74 44 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a 20  tDocid(&left);. 
55c0: 20 64 6f 63 69 64 52 69 67 68 74 20 3d 20 6e 65   docidRight = ne
55d0: 78 74 44 6f 63 69 64 28 26 72 69 67 68 74 29 3b  xtDocid(&right);
55e0: 0a 0a 20 20 77 68 69 6c 65 28 20 64 6f 63 69 64  ..  while( docid
55f0: 4c 65 66 74 3e 30 20 26 26 20 64 6f 63 69 64 52  Left>0 && docidR
5600: 69 67 68 74 3e 30 20 29 7b 0a 20 20 20 20 69 66  ight>0 ){.    if
5610: 28 20 64 6f 63 69 64 4c 65 66 74 3c 64 6f 63 69  ( docidLeft<doci
5620: 64 52 69 67 68 74 20 29 7b 0a 20 20 20 20 20 20  dRight ){.      
5630: 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65 78 74  docidLeft = next
5640: 44 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a 20 20  Docid(&left);.  
5650: 20 20 7d 65 6c 73 65 20 69 66 28 20 64 6f 63 69    }else if( doci
5660: 64 52 69 67 68 74 3c 64 6f 63 69 64 4c 65 66 74  dRight<docidLeft
5670: 20 29 7b 0a 20 20 20 20 20 20 64 6f 63 69 64 52   ){.      docidR
5680: 69 67 68 74 20 3d 20 6e 65 78 74 44 6f 63 69 64  ight = nextDocid
5690: 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20 7d 65  (&right);.    }e
56a0: 6c 73 65 7b 0a 20 20 20 20 20 20 6d 65 72 67 65  lse{.      merge
56b0: 50 6f 73 4c 69 73 74 28 26 6c 65 66 74 2c 20 26  PosList(&left, &
56c0: 72 69 67 68 74 2c 20 64 6f 63 69 64 4c 65 66 74  right, docidLeft
56d0: 2c 20 70 4f 75 74 29 3b 0a 20 20 20 20 20 20 64  , pOut);.      d
56e0: 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65 78 74 44  ocidLeft = nextD
56f0: 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a 20 20 20  ocid(&left);.   
5700: 20 20 20 64 6f 63 69 64 52 69 67 68 74 20 3d 20     docidRight = 
5710: 6e 65 78 74 44 6f 63 69 64 28 26 72 69 67 68 74  nextDocid(&right
5720: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a  );.    }.  }.}..
5730: 2f 2a 20 57 65 20 68 61 76 65 20 74 77 6f 20 64  /* We have two d
5740: 6f 63 6c 69 73 74 73 3a 20 20 70 4c 65 66 74 20  oclists:  pLeft 
5750: 61 6e 64 20 70 52 69 67 68 74 2e 0a 2a 2a 20 57  and pRight..** W
5760: 72 69 74 65 20 74 68 65 20 69 6e 74 65 72 73 65  rite the interse
5770: 63 74 69 6f 6e 20 6f 66 20 74 68 65 73 65 20 74  ction of these t
5780: 77 6f 20 64 6f 63 6c 69 73 74 73 20 69 6e 74 6f  wo doclists into
5790: 20 70 4f 75 74 2e 0a 2a 2a 20 4f 6e 6c 79 20 64   pOut..** Only d
57a0: 6f 63 69 64 73 20 61 72 65 20 6d 61 74 63 68 65  ocids are matche
57b0: 64 2e 20 20 50 6f 73 69 74 69 6f 6e 20 69 6e 66  d.  Position inf
57c0: 6f 72 6d 61 74 69 6f 6e 20 69 73 20 69 67 6e 6f  ormation is igno
57d0: 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6f  red..**.** The o
57e0: 75 74 70 75 74 20 70 4f 75 74 20 6e 65 76 65 72  utput pOut never
57f0: 20 68 6f 6c 64 73 20 70 6f 73 69 74 69 6f 6e 73   holds positions
5800: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
5810: 20 64 6f 63 4c 69 73 74 41 6e 64 4d 65 72 67 65   docListAndMerge
5820: 28 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70 4c 65  (.  DocList *pLe
5830: 66 74 2c 20 20 20 20 2f 2a 20 44 6f 63 6c 69 73  ft,    /* Doclis
5840: 74 20 72 65 73 75 6c 74 69 6e 67 20 66 72 6f 6d  t resulting from
5850: 20 74 68 65 20 77 6f 72 64 73 20 6f 6e 20 74 68   the words on th
5860: 65 20 6c 65 66 74 20 2a 2f 0a 20 20 44 6f 63 4c  e left */.  DocL
5870: 69 73 74 20 2a 70 52 69 67 68 74 2c 20 20 20 2f  ist *pRight,   /
5880: 2a 20 44 6f 63 6c 69 73 74 20 66 6f 72 20 74 68  * Doclist for th
5890: 65 20 6e 65 78 74 20 77 6f 72 64 20 74 6f 20 74  e next word to t
58a0: 68 65 20 72 69 67 68 74 20 2a 2f 0a 20 20 44 6f  he right */.  Do
58b0: 63 4c 69 73 74 20 2a 70 4f 75 74 20 20 20 20 20  cList *pOut     
58c0: 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 63 6f   /* Write the co
58d0: 6d 62 69 6e 65 64 20 64 6f 63 6c 69 73 74 20 68  mbined doclist h
58e0: 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 44 6f 63 4c  ere */.){.  DocL
58f0: 69 73 74 52 65 61 64 65 72 20 6c 65 66 74 2c 20  istReader left, 
5900: 72 69 67 68 74 3b 0a 20 20 73 71 6c 69 74 65 5f  right;.  sqlite_
5910: 69 6e 74 36 34 20 64 6f 63 69 64 4c 65 66 74 2c  int64 docidLeft,
5920: 20 64 6f 63 69 64 52 69 67 68 74 3b 0a 0a 20 20   docidRight;..  
5930: 61 73 73 65 72 74 28 20 70 4f 75 74 2d 3e 69 54  assert( pOut->iT
5940: 79 70 65 3c 44 4c 5f 50 4f 53 49 54 49 4f 4e 53  ype<DL_POSITIONS
5950: 20 29 3b 0a 0a 20 20 72 65 61 64 65 72 49 6e 69   );..  readerIni
5960: 74 28 26 6c 65 66 74 2c 20 70 4c 65 66 74 29 3b  t(&left, pLeft);
5970: 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28 26 72  .  readerInit(&r
5980: 69 67 68 74 2c 20 70 52 69 67 68 74 29 3b 0a 20  ight, pRight);. 
5990: 20 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65 78   docidLeft = nex
59a0: 74 44 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a 20  tDocid(&left);. 
59b0: 20 64 6f 63 69 64 52 69 67 68 74 20 3d 20 6e 65   docidRight = ne
59c0: 78 74 44 6f 63 69 64 28 26 72 69 67 68 74 29 3b  xtDocid(&right);
59d0: 0a 0a 20 20 77 68 69 6c 65 28 20 64 6f 63 69 64  ..  while( docid
59e0: 4c 65 66 74 3e 30 20 26 26 20 64 6f 63 69 64 52  Left>0 && docidR
59f0: 69 67 68 74 3e 30 20 29 7b 0a 20 20 20 20 69 66  ight>0 ){.    if
5a00: 28 20 64 6f 63 69 64 4c 65 66 74 3c 64 6f 63 69  ( docidLeft<doci
5a10: 64 52 69 67 68 74 20 29 7b 0a 20 20 20 20 20 20  dRight ){.      
5a20: 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65 78 74  docidLeft = next
5a30: 44 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a 20 20  Docid(&left);.  
5a40: 20 20 7d 65 6c 73 65 20 69 66 28 20 64 6f 63 69    }else if( doci
5a50: 64 52 69 67 68 74 3c 64 6f 63 69 64 4c 65 66 74  dRight<docidLeft
5a60: 20 29 7b 0a 20 20 20 20 20 20 64 6f 63 69 64 52   ){.      docidR
5a70: 69 67 68 74 20 3d 20 6e 65 78 74 44 6f 63 69 64  ight = nextDocid
5a80: 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20 7d 65  (&right);.    }e
5a90: 6c 73 65 7b 0a 20 20 20 20 20 20 64 6f 63 4c 69  lse{.      docLi
5aa0: 73 74 41 64 64 44 6f 63 69 64 28 70 4f 75 74 2c  stAddDocid(pOut,
5ab0: 20 64 6f 63 69 64 4c 65 66 74 29 3b 0a 20 20 20   docidLeft);.   
5ac0: 20 20 20 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e     docidLeft = n
5ad0: 65 78 74 44 6f 63 69 64 28 26 6c 65 66 74 29 3b  extDocid(&left);
5ae0: 0a 20 20 20 20 20 20 64 6f 63 69 64 52 69 67 68  .      docidRigh
5af0: 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 72  t = nextDocid(&r
5b00: 69 67 68 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  ight);.    }.  }
5b10: 0a 7d 0a 0a 2f 2a 20 57 65 20 68 61 76 65 20 74  .}../* We have t
5b20: 77 6f 20 64 6f 63 6c 69 73 74 73 3a 20 20 70 4c  wo doclists:  pL
5b30: 65 66 74 20 61 6e 64 20 70 52 69 67 68 74 2e 0a  eft and pRight..
5b40: 2a 2a 20 57 72 69 74 65 20 74 68 65 20 75 6e 69  ** Write the uni
5b50: 6f 6e 20 6f 66 20 74 68 65 73 65 20 74 77 6f 20  on of these two 
5b60: 64 6f 63 6c 69 73 74 73 20 69 6e 74 6f 20 70 4f  doclists into pO
5b70: 75 74 2e 0a 2a 2a 20 4f 6e 6c 79 20 64 6f 63 69  ut..** Only doci
5b80: 64 73 20 61 72 65 20 6d 61 74 63 68 65 64 2e 20  ds are matched. 
5b90: 20 50 6f 73 69 74 69 6f 6e 20 69 6e 66 6f 72 6d   Position inform
5ba0: 61 74 69 6f 6e 20 69 73 20 69 67 6e 6f 72 65 64  ation is ignored
5bb0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6f 75 74 70  ..**.** The outp
5bc0: 75 74 20 70 4f 75 74 20 6e 65 76 65 72 20 68 6f  ut pOut never ho
5bd0: 6c 64 73 20 70 6f 73 69 74 69 6f 6e 73 2e 0a 2a  lds positions..*
5be0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f  /.static void do
5bf0: 63 4c 69 73 74 4f 72 4d 65 72 67 65 28 0a 20 20  cListOrMerge(.  
5c00: 44 6f 63 4c 69 73 74 20 2a 70 4c 65 66 74 2c 20  DocList *pLeft, 
5c10: 20 20 20 2f 2a 20 44 6f 63 6c 69 73 74 20 72 65     /* Doclist re
5c20: 73 75 6c 74 69 6e 67 20 66 72 6f 6d 20 74 68 65  sulting from the
5c30: 20 77 6f 72 64 73 20 6f 6e 20 74 68 65 20 6c 65   words on the le
5c40: 66 74 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20  ft */.  DocList 
5c50: 2a 70 52 69 67 68 74 2c 20 20 20 2f 2a 20 44 6f  *pRight,   /* Do
5c60: 63 6c 69 73 74 20 66 6f 72 20 74 68 65 20 6e 65  clist for the ne
5c70: 78 74 20 77 6f 72 64 20 74 6f 20 74 68 65 20 72  xt word to the r
5c80: 69 67 68 74 20 2a 2f 0a 20 20 44 6f 63 4c 69 73  ight */.  DocLis
5c90: 74 20 2a 70 4f 75 74 20 20 20 20 20 20 2f 2a 20  t *pOut      /* 
5ca0: 57 72 69 74 65 20 74 68 65 20 63 6f 6d 62 69 6e  Write the combin
5cb0: 65 64 20 64 6f 63 6c 69 73 74 20 68 65 72 65 20  ed doclist here 
5cc0: 2a 2f 0a 29 7b 0a 20 20 44 6f 63 4c 69 73 74 52  */.){.  DocListR
5cd0: 65 61 64 65 72 20 6c 65 66 74 2c 20 72 69 67 68  eader left, righ
5ce0: 74 3b 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36  t;.  sqlite_int6
5cf0: 34 20 64 6f 63 69 64 4c 65 66 74 2c 20 64 6f 63  4 docidLeft, doc
5d00: 69 64 52 69 67 68 74 2c 20 70 72 69 6f 72 4c 65  idRight, priorLe
5d10: 66 74 3b 0a 0a 20 20 72 65 61 64 65 72 49 6e 69  ft;..  readerIni
5d20: 74 28 26 6c 65 66 74 2c 20 70 4c 65 66 74 29 3b  t(&left, pLeft);
5d30: 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28 26 72  .  readerInit(&r
5d40: 69 67 68 74 2c 20 70 52 69 67 68 74 29 3b 0a 20  ight, pRight);. 
5d50: 20 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65 78   docidLeft = nex
5d60: 74 44 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a 20  tDocid(&left);. 
5d70: 20 64 6f 63 69 64 52 69 67 68 74 20 3d 20 6e 65   docidRight = ne
5d80: 78 74 44 6f 63 69 64 28 26 72 69 67 68 74 29 3b  xtDocid(&right);
5d90: 0a 0a 20 20 77 68 69 6c 65 28 20 64 6f 63 69 64  ..  while( docid
5da0: 4c 65 66 74 3e 30 20 26 26 20 64 6f 63 69 64 52  Left>0 && docidR
5db0: 69 67 68 74 3e 30 20 29 7b 0a 20 20 20 20 69 66  ight>0 ){.    if
5dc0: 28 20 64 6f 63 69 64 4c 65 66 74 3c 3d 64 6f 63  ( docidLeft<=doc
5dd0: 69 64 52 69 67 68 74 20 29 7b 0a 20 20 20 20 20  idRight ){.     
5de0: 20 64 6f 63 4c 69 73 74 41 64 64 44 6f 63 69 64   docListAddDocid
5df0: 28 70 4f 75 74 2c 20 64 6f 63 69 64 4c 65 66 74  (pOut, docidLeft
5e00: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
5e10: 20 20 20 20 64 6f 63 4c 69 73 74 41 64 64 44 6f      docListAddDo
5e20: 63 69 64 28 70 4f 75 74 2c 20 64 6f 63 69 64 52  cid(pOut, docidR
5e30: 69 67 68 74 29 3b 0a 20 20 20 20 7d 0a 20 20 20  ight);.    }.   
5e40: 20 70 72 69 6f 72 4c 65 66 74 20 3d 20 64 6f 63   priorLeft = doc
5e50: 69 64 4c 65 66 74 3b 0a 20 20 20 20 69 66 28 20  idLeft;.    if( 
5e60: 64 6f 63 69 64 4c 65 66 74 3c 3d 64 6f 63 69 64  docidLeft<=docid
5e70: 52 69 67 68 74 20 29 7b 0a 20 20 20 20 20 20 64  Right ){.      d
5e80: 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65 78 74 44  ocidLeft = nextD
5e90: 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a 20 20 20  ocid(&left);.   
5ea0: 20 7d 0a 20 20 20 20 69 66 28 20 64 6f 63 69 64   }.    if( docid
5eb0: 52 69 67 68 74 3e 30 20 26 26 20 64 6f 63 69 64  Right>0 && docid
5ec0: 52 69 67 68 74 3c 3d 70 72 69 6f 72 4c 65 66 74  Right<=priorLeft
5ed0: 20 29 7b 0a 20 20 20 20 20 20 64 6f 63 69 64 52   ){.      docidR
5ee0: 69 67 68 74 20 3d 20 6e 65 78 74 44 6f 63 69 64  ight = nextDocid
5ef0: 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20 7d 0a  (&right);.    }.
5f00: 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 64 6f 63    }.  while( doc
5f10: 69 64 4c 65 66 74 3e 30 20 29 7b 0a 20 20 20 20  idLeft>0 ){.    
5f20: 64 6f 63 4c 69 73 74 41 64 64 44 6f 63 69 64 28  docListAddDocid(
5f30: 70 4f 75 74 2c 20 64 6f 63 69 64 4c 65 66 74 29  pOut, docidLeft)
5f40: 3b 0a 20 20 20 20 64 6f 63 69 64 4c 65 66 74 20  ;.    docidLeft 
5f50: 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 6c 65 66  = nextDocid(&lef
5f60: 74 29 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28  t);.  }.  while(
5f70: 20 64 6f 63 69 64 52 69 67 68 74 3e 30 20 29 7b   docidRight>0 ){
5f80: 0a 20 20 20 20 64 6f 63 4c 69 73 74 41 64 64 44  .    docListAddD
5f90: 6f 63 69 64 28 70 4f 75 74 2c 20 64 6f 63 69 64  ocid(pOut, docid
5fa0: 52 69 67 68 74 29 3b 0a 20 20 20 20 64 6f 63 69  Right);.    doci
5fb0: 64 52 69 67 68 74 20 3d 20 6e 65 78 74 44 6f 63  dRight = nextDoc
5fc0: 69 64 28 26 72 69 67 68 74 29 3b 0a 20 20 7d 0a  id(&right);.  }.
5fd0: 7d 0a 0a 2f 2a 20 57 65 20 68 61 76 65 20 74 77  }../* We have tw
5fe0: 6f 20 64 6f 63 6c 69 73 74 73 3a 20 20 70 4c 65  o doclists:  pLe
5ff0: 66 74 20 61 6e 64 20 70 52 69 67 68 74 2e 0a 2a  ft and pRight..*
6000: 2a 20 57 72 69 74 65 20 69 6e 74 6f 20 70 4f 75  * Write into pOu
6010: 74 20 61 6c 6c 20 64 6f 63 75 6d 65 6e 74 73 20  t all documents 
6020: 74 68 61 74 20 6f 63 63 75 72 20 69 6e 20 70 4c  that occur in pL
6030: 65 66 74 20 62 75 74 20 6e 6f 74 0a 2a 2a 20 69  eft but not.** i
6040: 6e 20 70 52 69 67 68 74 2e 0a 2a 2a 0a 2a 2a 20  n pRight..**.** 
6050: 4f 6e 6c 79 20 64 6f 63 69 64 73 20 61 72 65 20  Only docids are 
6060: 6d 61 74 63 68 65 64 2e 20 20 50 6f 73 69 74 69  matched.  Positi
6070: 6f 6e 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69  on information i
6080: 73 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a  s ignored..**.**
6090: 20 54 68 65 20 6f 75 74 70 75 74 20 70 4f 75 74   The output pOut
60a0: 20 6e 65 76 65 72 20 68 6f 6c 64 73 20 70 6f 73   never holds pos
60b0: 69 74 69 6f 6e 73 2e 0a 2a 2f 0a 73 74 61 74 69  itions..*/.stati
60c0: 63 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 45 78  c void docListEx
60d0: 63 65 70 74 4d 65 72 67 65 28 0a 20 20 44 6f 63  ceptMerge(.  Doc
60e0: 4c 69 73 74 20 2a 70 4c 65 66 74 2c 20 20 20 20  List *pLeft,    
60f0: 2f 2a 20 44 6f 63 6c 69 73 74 20 72 65 73 75 6c  /* Doclist resul
6100: 74 69 6e 67 20 66 72 6f 6d 20 74 68 65 20 77 6f  ting from the wo
6110: 72 64 73 20 6f 6e 20 74 68 65 20 6c 65 66 74 20  rds on the left 
6120: 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70 52  */.  DocList *pR
6130: 69 67 68 74 2c 20 20 20 2f 2a 20 44 6f 63 6c 69  ight,   /* Docli
6140: 73 74 20 66 6f 72 20 74 68 65 20 6e 65 78 74 20  st for the next 
6150: 77 6f 72 64 20 74 6f 20 74 68 65 20 72 69 67 68  word to the righ
6160: 74 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20 2a  t */.  DocList *
6170: 70 4f 75 74 20 20 20 20 20 20 2f 2a 20 57 72 69  pOut      /* Wri
6180: 74 65 20 74 68 65 20 63 6f 6d 62 69 6e 65 64 20  te the combined 
6190: 64 6f 63 6c 69 73 74 20 68 65 72 65 20 2a 2f 0a  doclist here */.
61a0: 29 7b 0a 20 20 44 6f 63 4c 69 73 74 52 65 61 64  ){.  DocListRead
61b0: 65 72 20 6c 65 66 74 2c 20 72 69 67 68 74 3b 0a  er left, right;.
61c0: 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 64    sqlite_int64 d
61d0: 6f 63 69 64 4c 65 66 74 2c 20 64 6f 63 69 64 52  ocidLeft, docidR
61e0: 69 67 68 74 2c 20 70 72 69 6f 72 4c 65 66 74 3b  ight, priorLeft;
61f0: 0a 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28 26  ..  readerInit(&
6200: 6c 65 66 74 2c 20 70 4c 65 66 74 29 3b 0a 20 20  left, pLeft);.  
6210: 72 65 61 64 65 72 49 6e 69 74 28 26 72 69 67 68  readerInit(&righ
6220: 74 2c 20 70 52 69 67 68 74 29 3b 0a 20 20 64 6f  t, pRight);.  do
6230: 63 69 64 4c 65 66 74 20 3d 20 6e 65 78 74 44 6f  cidLeft = nextDo
6240: 63 69 64 28 26 6c 65 66 74 29 3b 0a 20 20 64 6f  cid(&left);.  do
6250: 63 69 64 52 69 67 68 74 20 3d 20 6e 65 78 74 44  cidRight = nextD
6260: 6f 63 69 64 28 26 72 69 67 68 74 29 3b 0a 0a 20  ocid(&right);.. 
6270: 20 77 68 69 6c 65 28 20 64 6f 63 69 64 4c 65 66   while( docidLef
6280: 74 3e 30 20 26 26 20 64 6f 63 69 64 52 69 67 68  t>0 && docidRigh
6290: 74 3e 30 20 29 7b 0a 20 20 20 20 70 72 69 6f 72  t>0 ){.    prior
62a0: 4c 65 66 74 20 3d 20 64 6f 63 69 64 4c 65 66 74  Left = docidLeft
62b0: 3b 0a 20 20 20 20 69 66 28 20 64 6f 63 69 64 4c  ;.    if( docidL
62c0: 65 66 74 3c 64 6f 63 69 64 52 69 67 68 74 20 29  eft<docidRight )
62d0: 7b 0a 20 20 20 20 20 20 64 6f 63 4c 69 73 74 41  {.      docListA
62e0: 64 64 44 6f 63 69 64 28 70 4f 75 74 2c 20 64 6f  ddDocid(pOut, do
62f0: 63 69 64 4c 65 66 74 29 3b 0a 20 20 20 20 7d 0a  cidLeft);.    }.
6300: 20 20 20 20 69 66 28 20 64 6f 63 69 64 4c 65 66      if( docidLef
6310: 74 3c 3d 64 6f 63 69 64 52 69 67 68 74 20 29 7b  t<=docidRight ){
6320: 0a 20 20 20 20 20 20 64 6f 63 69 64 4c 65 66 74  .      docidLeft
6330: 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 6c 65   = nextDocid(&le
6340: 66 74 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  ft);.    }.    i
6350: 66 28 20 64 6f 63 69 64 52 69 67 68 74 3e 30 20  f( docidRight>0 
6360: 26 26 20 64 6f 63 69 64 52 69 67 68 74 3c 3d 70  && docidRight<=p
6370: 72 69 6f 72 4c 65 66 74 20 29 7b 0a 20 20 20 20  riorLeft ){.    
6380: 20 20 64 6f 63 69 64 52 69 67 68 74 20 3d 20 6e    docidRight = n
6390: 65 78 74 44 6f 63 69 64 28 26 72 69 67 68 74 29  extDocid(&right)
63a0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68  ;.    }.  }.  wh
63b0: 69 6c 65 28 20 64 6f 63 69 64 4c 65 66 74 3e 30  ile( docidLeft>0
63c0: 20 29 7b 0a 20 20 20 20 64 6f 63 4c 69 73 74 41   ){.    docListA
63d0: 64 64 44 6f 63 69 64 28 70 4f 75 74 2c 20 64 6f  ddDocid(pOut, do
63e0: 63 69 64 4c 65 66 74 29 3b 0a 20 20 20 20 64 6f  cidLeft);.    do
63f0: 63 69 64 4c 65 66 74 20 3d 20 6e 65 78 74 44 6f  cidLeft = nextDo
6400: 63 69 64 28 26 6c 65 66 74 29 3b 0a 20 20 7d 0a  cid(&left);.  }.
6410: 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a  }..static char *
6420: 73 74 72 69 6e 67 5f 64 75 70 5f 6e 28 63 6f 6e  string_dup_n(con
6430: 73 74 20 63 68 61 72 20 2a 73 2c 20 69 6e 74 20  st char *s, int 
6440: 6e 29 7b 0a 20 20 63 68 61 72 20 2a 73 74 72 20  n){.  char *str 
6450: 3d 20 6d 61 6c 6c 6f 63 28 6e 20 2b 20 31 29 3b  = malloc(n + 1);
6460: 0a 20 20 6d 65 6d 63 70 79 28 73 74 72 2c 20 73  .  memcpy(str, s
6470: 2c 20 6e 29 3b 0a 20 20 73 74 72 5b 6e 5d 20 3d  , n);.  str[n] =
6480: 20 27 5c 30 27 3b 0a 20 20 72 65 74 75 72 6e 20   '\0';.  return 
6490: 73 74 72 3b 0a 7d 0a 0a 2f 2a 20 44 75 70 6c 69  str;.}../* Dupli
64a0: 63 61 74 65 20 61 20 73 74 72 69 6e 67 3b 20 74  cate a string; t
64b0: 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 66  he caller must f
64c0: 72 65 65 28 29 20 74 68 65 20 72 65 74 75 72 6e  ree() the return
64d0: 65 64 20 73 74 72 69 6e 67 2e 0a 20 2a 20 28 57  ed string.. * (W
64e0: 65 20 64 6f 6e 27 74 20 75 73 65 20 73 74 72 64  e don't use strd
64f0: 75 70 28 29 20 73 69 6e 63 65 20 69 74 20 69 73  up() since it is
6500: 20 6e 6f 74 20 70 61 72 74 20 6f 66 20 74 68 65   not part of the
6510: 20 73 74 61 6e 64 61 72 64 20 43 20 6c 69 62 72   standard C libr
6520: 61 72 79 20 61 6e 64 0a 20 2a 20 6d 61 79 20 6e  ary and. * may n
6530: 6f 74 20 62 65 20 61 76 61 69 6c 61 62 6c 65 20  ot be available 
6540: 65 76 65 72 79 77 68 65 72 65 2e 29 20 2a 2f 0a  everywhere.) */.
6550: 73 74 61 74 69 63 20 63 68 61 72 20 2a 73 74 72  static char *str
6560: 69 6e 67 5f 64 75 70 28 63 6f 6e 73 74 20 63 68  ing_dup(const ch
6570: 61 72 20 2a 73 29 7b 0a 20 20 72 65 74 75 72 6e  ar *s){.  return
6580: 20 73 74 72 69 6e 67 5f 64 75 70 5f 6e 28 73 2c   string_dup_n(s,
6590: 20 73 74 72 6c 65 6e 28 73 29 29 3b 0a 7d 0a 0a   strlen(s));.}..
65a0: 2f 2a 20 46 6f 72 6d 61 74 20 61 20 73 74 72 69  /* Format a stri
65b0: 6e 67 2c 20 72 65 70 6c 61 63 69 6e 67 20 65 61  ng, replacing ea
65c0: 63 68 20 6f 63 63 75 72 72 65 6e 63 65 20 6f 66  ch occurrence of
65d0: 20 74 68 65 20 25 20 63 68 61 72 61 63 74 65 72   the % character
65e0: 20 77 69 74 68 0a 20 2a 20 7a 44 62 2e 7a 4e 61   with. * zDb.zNa
65f0: 6d 65 2e 20 20 54 68 69 73 20 6d 61 79 20 62 65  me.  This may be
6600: 20 6d 6f 72 65 20 63 6f 6e 76 65 6e 69 65 6e 74   more convenient
6610: 20 74 68 61 6e 20 73 71 6c 69 74 65 5f 6d 70 72   than sqlite_mpr
6620: 69 6e 74 66 28 29 0a 20 2a 20 77 68 65 6e 20 6f  intf(). * when o
6630: 6e 65 20 73 74 72 69 6e 67 20 69 73 20 75 73 65  ne string is use
6640: 64 20 72 65 70 65 61 74 65 64 6c 79 20 69 6e 20  d repeatedly in 
6650: 61 20 66 6f 72 6d 61 74 20 73 74 72 69 6e 67 2e  a format string.
6660: 0a 20 2a 20 54 68 65 20 63 61 6c 6c 65 72 20 6d  . * The caller m
6670: 75 73 74 20 66 72 65 65 28 29 20 74 68 65 20 72  ust free() the r
6680: 65 74 75 72 6e 65 64 20 73 74 72 69 6e 67 2e 20  eturned string. 
6690: 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a  */.static char *
66a0: 73 74 72 69 6e 67 5f 66 6f 72 6d 61 74 28 63 6f  string_format(co
66b0: 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61  nst char *zForma
66c0: 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  t,.             
66d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63 6f                co
66e0: 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 2c 20 63  nst char *zDb, c
66f0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
6700: 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  ){.  const char 
6710: 2a 70 3b 0a 20 20 73 69 7a 65 5f 74 20 6c 65 6e  *p;.  size_t len
6720: 20 3d 20 30 3b 0a 20 20 73 69 7a 65 5f 74 20 6e   = 0;.  size_t n
6730: 44 62 20 3d 20 73 74 72 6c 65 6e 28 7a 44 62 29  Db = strlen(zDb)
6740: 3b 0a 20 20 73 69 7a 65 5f 74 20 6e 4e 61 6d 65  ;.  size_t nName
6750: 20 3d 20 73 74 72 6c 65 6e 28 7a 4e 61 6d 65 29   = strlen(zName)
6760: 3b 0a 20 20 73 69 7a 65 5f 74 20 6e 46 75 6c 6c  ;.  size_t nFull
6770: 54 61 62 6c 65 4e 61 6d 65 20 3d 20 6e 44 62 2b  TableName = nDb+
6780: 31 2b 6e 4e 61 6d 65 3b 0a 20 20 63 68 61 72 20  1+nName;.  char 
6790: 2a 72 65 73 75 6c 74 3b 0a 20 20 63 68 61 72 20  *result;.  char 
67a0: 2a 72 3b 0a 0a 20 20 2f 2a 20 66 69 72 73 74 20  *r;..  /* first 
67b0: 63 6f 6d 70 75 74 65 20 6c 65 6e 67 74 68 20 6e  compute length n
67c0: 65 65 64 65 64 20 2a 2f 0a 20 20 66 6f 72 28 70  eeded */.  for(p
67d0: 20 3d 20 7a 46 6f 72 6d 61 74 20 3b 20 2a 70 20   = zFormat ; *p 
67e0: 3b 20 2b 2b 70 29 7b 0a 20 20 20 20 6c 65 6e 20  ; ++p){.    len 
67f0: 2b 3d 20 28 2a 70 3d 3d 27 25 27 20 3f 20 6e 46  += (*p=='%' ? nF
6800: 75 6c 6c 54 61 62 6c 65 4e 61 6d 65 20 3a 20 31  ullTableName : 1
6810: 29 3b 0a 20 20 7d 0a 20 20 6c 65 6e 20 2b 3d 20  );.  }.  len += 
6820: 31 3b 20 20 2f 2a 20 66 6f 72 20 6e 75 6c 6c 20  1;  /* for null 
6830: 74 65 72 6d 69 6e 61 74 6f 72 20 2a 2f 0a 0a 20  terminator */.. 
6840: 20 72 20 3d 20 72 65 73 75 6c 74 20 3d 20 6d 61   r = result = ma
6850: 6c 6c 6f 63 28 6c 65 6e 29 3b 0a 20 20 66 6f 72  lloc(len);.  for
6860: 28 70 20 3d 20 7a 46 6f 72 6d 61 74 3b 20 2a 70  (p = zFormat; *p
6870: 3b 20 2b 2b 70 29 7b 0a 20 20 20 20 69 66 28 20  ; ++p){.    if( 
6880: 2a 70 3d 3d 27 25 27 20 29 7b 0a 20 20 20 20 20  *p=='%' ){.     
6890: 20 6d 65 6d 63 70 79 28 72 2c 20 7a 44 62 2c 20   memcpy(r, zDb, 
68a0: 6e 44 62 29 3b 0a 20 20 20 20 20 20 72 20 2b 3d  nDb);.      r +=
68b0: 20 6e 44 62 3b 0a 20 20 20 20 20 20 2a 72 2b 2b   nDb;.      *r++
68c0: 20 3d 20 27 2e 27 3b 0a 20 20 20 20 20 20 6d 65   = '.';.      me
68d0: 6d 63 70 79 28 72 2c 20 7a 4e 61 6d 65 2c 20 6e  mcpy(r, zName, n
68e0: 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 72 20 2b  Name);.      r +
68f0: 3d 20 6e 4e 61 6d 65 3b 0a 20 20 20 20 7d 20 65  = nName;.    } e
6900: 6c 73 65 20 7b 0a 20 20 20 20 20 20 2a 72 2b 2b  lse {.      *r++
6910: 20 3d 20 2a 70 3b 0a 20 20 20 20 7d 0a 20 20 7d   = *p;.    }.  }
6920: 0a 20 20 2a 72 2b 2b 20 3d 20 27 5c 30 27 3b 0a  .  *r++ = '\0';.
6930: 20 20 61 73 73 65 72 74 28 20 72 20 3d 3d 20 72    assert( r == r
6940: 65 73 75 6c 74 20 2b 20 6c 65 6e 20 29 3b 0a 20  esult + len );. 
6950: 20 72 65 74 75 72 6e 20 72 65 73 75 6c 74 3b 0a   return result;.
6960: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73 71  }..static int sq
6970: 6c 5f 65 78 65 63 28 73 71 6c 69 74 65 33 20 2a  l_exec(sqlite3 *
6980: 64 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  db, const char *
6990: 7a 44 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  zDb, const char 
69a0: 2a 7a 4e 61 6d 65 2c 0a 20 20 20 20 20 20 20 20  *zName,.        
69b0: 20 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73              cons
69c0: 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 29  t char *zFormat)
69d0: 7b 0a 20 20 63 68 61 72 20 2a 7a 43 6f 6d 6d 61  {.  char *zComma
69e0: 6e 64 20 3d 20 73 74 72 69 6e 67 5f 66 6f 72 6d  nd = string_form
69f0: 61 74 28 7a 46 6f 72 6d 61 74 2c 20 7a 44 62 2c  at(zFormat, zDb,
6a00: 20 7a 4e 61 6d 65 29 3b 0a 20 20 69 6e 74 20 72   zName);.  int r
6a10: 63 3b 0a 20 20 54 52 41 43 45 28 28 22 46 54 53  c;.  TRACE(("FTS
6a20: 31 20 73 71 6c 3a 20 25 73 5c 6e 22 2c 20 7a 43  1 sql: %s\n", zC
6a30: 6f 6d 6d 61 6e 64 29 29 3b 0a 20 20 72 63 20 3d  ommand));.  rc =
6a40: 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62   sqlite3_exec(db
6a50: 2c 20 7a 43 6f 6d 6d 61 6e 64 2c 20 4e 55 4c 4c  , zCommand, NULL
6a60: 2c 20 30 2c 20 4e 55 4c 4c 29 3b 0a 20 20 66 72  , 0, NULL);.  fr
6a70: 65 65 28 7a 43 6f 6d 6d 61 6e 64 29 3b 0a 20 20  ee(zCommand);.  
6a80: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
6a90: 61 74 69 63 20 69 6e 74 20 73 71 6c 5f 70 72 65  atic int sql_pre
6aa0: 70 61 72 65 28 73 71 6c 69 74 65 33 20 2a 64 62  pare(sqlite3 *db
6ab0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44  , const char *zD
6ac0: 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  b, const char *z
6ad0: 4e 61 6d 65 2c 0a 20 20 20 20 20 20 20 20 20 20  Name,.          
6ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c               sql
6af0: 69 74 65 33 5f 73 74 6d 74 20 2a 2a 70 70 53 74  ite3_stmt **ppSt
6b00: 6d 74 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  mt, const char *
6b10: 7a 46 6f 72 6d 61 74 29 7b 0a 20 20 63 68 61 72  zFormat){.  char
6b20: 20 2a 7a 43 6f 6d 6d 61 6e 64 20 3d 20 73 74 72   *zCommand = str
6b30: 69 6e 67 5f 66 6f 72 6d 61 74 28 7a 46 6f 72 6d  ing_format(zForm
6b40: 61 74 2c 20 7a 44 62 2c 20 7a 4e 61 6d 65 29 3b  at, zDb, zName);
6b50: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 54 52 41  .  int rc;.  TRA
6b60: 43 45 28 28 22 46 54 53 31 20 70 72 65 70 61 72  CE(("FTS1 prepar
6b70: 65 3a 20 25 73 5c 6e 22 2c 20 7a 43 6f 6d 6d 61  e: %s\n", zComma
6b80: 6e 64 29 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c  nd));.  rc = sql
6b90: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
6ba0: 20 7a 43 6f 6d 6d 61 6e 64 2c 20 2d 31 2c 20 70   zCommand, -1, p
6bb0: 70 53 74 6d 74 2c 20 4e 55 4c 4c 29 3b 0a 20 20  pStmt, NULL);.  
6bc0: 66 72 65 65 28 7a 43 6f 6d 6d 61 6e 64 29 3b 0a  free(zCommand);.
6bd0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
6be0: 2f 2a 20 65 6e 64 20 75 74 69 6c 69 74 79 20 66  /* end utility f
6bf0: 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 0a 2f 2a 20  unctions */../* 
6c00: 46 6f 72 77 61 72 64 20 72 65 66 65 72 65 6e 63  Forward referenc
6c10: 65 20 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72  e */.typedef str
6c20: 75 63 74 20 66 75 6c 6c 74 65 78 74 5f 76 74 61  uct fulltext_vta
6c30: 62 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 3b  b fulltext_vtab;
6c40: 0a 0a 2f 2a 20 41 20 73 69 6e 67 6c 65 20 74 65  ../* A single te
6c50: 72 6d 20 69 6e 20 61 20 71 75 65 72 79 20 69 73  rm in a query is
6c60: 20 72 65 70 72 65 73 65 6e 74 65 64 20 62 79 20   represented by 
6c70: 61 6e 20 69 6e 73 74 61 6e 63 65 73 20 6f 66 0a  an instances of.
6c80: 2a 2a 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ** the following
6c90: 20 73 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 74   structure..*/.t
6ca0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 51 75  ypedef struct Qu
6cb0: 65 72 79 54 65 72 6d 20 7b 0a 20 20 73 68 6f 72  eryTerm {.  shor
6cc0: 74 20 69 6e 74 20 6e 50 68 72 61 73 65 3b 20 2f  t int nPhrase; /
6cd0: 2a 20 48 6f 77 20 6d 61 6e 79 20 66 6f 6c 6c 6f  * How many follo
6ce0: 77 69 6e 67 20 74 65 72 6d 73 20 61 72 65 20 70  wing terms are p
6cf0: 61 72 74 20 6f 66 20 74 68 65 20 73 61 6d 65 20  art of the same 
6d00: 70 68 72 61 73 65 20 2a 2f 0a 20 20 73 68 6f 72  phrase */.  shor
6d10: 74 20 69 6e 74 20 69 50 68 72 61 73 65 3b 20 2f  t int iPhrase; /
6d20: 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 69 2d  * This is the i-
6d30: 74 68 20 74 65 72 6d 20 6f 66 20 61 20 70 68 72  th term of a phr
6d40: 61 73 65 2e 20 2a 2f 0a 20 20 73 68 6f 72 74 20  ase. */.  short 
6d50: 69 6e 74 20 69 43 6f 6c 75 6d 6e 3b 20 2f 2a 20  int iColumn; /* 
6d60: 43 6f 6c 75 6d 6e 20 6f 66 20 74 68 65 20 69 6e  Column of the in
6d70: 64 65 78 20 74 68 61 74 20 6d 75 73 74 20 6d 61  dex that must ma
6d80: 74 63 68 20 74 68 69 73 20 74 65 72 6d 20 2a 2f  tch this term */
6d90: 0a 20 20 73 69 67 6e 65 64 20 63 68 61 72 20 69  .  signed char i
6da0: 73 4f 72 3b 20 20 2f 2a 20 74 68 69 73 20 74 65  sOr;  /* this te
6db0: 72 6d 20 69 73 20 70 72 65 63 65 64 65 64 20 62  rm is preceded b
6dc0: 79 20 22 4f 52 22 20 2a 2f 0a 20 20 73 69 67 6e  y "OR" */.  sign
6dd0: 65 64 20 63 68 61 72 20 69 73 4e 6f 74 3b 20 2f  ed char isNot; /
6de0: 2a 20 74 68 69 73 20 74 65 72 6d 20 69 73 20 70  * this term is p
6df0: 72 65 63 65 64 65 64 20 62 79 20 22 2d 22 20 2a  receded by "-" *
6e00: 2f 0a 20 20 63 68 61 72 20 2a 70 54 65 72 6d 3b  /.  char *pTerm;
6e10: 20 20 20 20 20 20 20 2f 2a 20 74 65 78 74 20 6f         /* text o
6e20: 66 20 74 68 65 20 74 65 72 6d 2e 20 20 27 5c 30  f the term.  '\0
6e30: 30 30 27 20 74 65 72 6d 69 6e 61 74 65 64 2e 20  00' terminated. 
6e40: 20 6d 61 6c 6c 6f 63 65 64 20 2a 2f 0a 20 20 69   malloced */.  i
6e50: 6e 74 20 6e 54 65 72 6d 3b 20 20 20 20 20 20 20  nt nTerm;       
6e60: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
6e70: 79 74 65 73 20 69 6e 20 70 54 65 72 6d 5b 5d 20  ytes in pTerm[] 
6e80: 2a 2f 0a 7d 20 51 75 65 72 79 54 65 72 6d 3b 0a  */.} QueryTerm;.
6e90: 0a 0a 2f 2a 20 41 20 71 75 65 72 79 20 73 74 72  ../* A query str
6ea0: 69 6e 67 20 69 73 20 70 61 72 73 65 64 20 69 6e  ing is parsed in
6eb0: 74 6f 20 61 20 51 75 65 72 79 20 73 74 72 75 63  to a Query struc
6ec0: 74 75 72 65 2e 0a 20 2a 0a 20 2a 20 57 65 20 63  ture.. *. * We c
6ed0: 6f 75 6c 64 2c 20 69 6e 20 74 68 65 6f 72 79 2c  ould, in theory,
6ee0: 20 61 6c 6c 6f 77 20 71 75 65 72 79 20 73 74 72   allow query str
6ef0: 69 6e 67 73 20 74 6f 20 62 65 20 63 6f 6d 70 6c  ings to be compl
6f00: 69 63 61 74 65 64 0a 20 2a 20 6e 65 73 74 65 64  icated. * nested
6f10: 20 65 78 70 72 65 73 73 69 6f 6e 73 20 77 69 74   expressions wit
6f20: 68 20 70 72 65 63 65 64 65 6e 63 65 20 64 65 74  h precedence det
6f30: 65 72 6d 69 6e 65 64 20 62 79 20 70 61 72 65 6e  ermined by paren
6f40: 74 68 65 73 65 73 2e 0a 20 2a 20 42 75 74 20 6e  theses.. * But n
6f50: 6f 6e 65 20 6f 66 20 74 68 65 20 6d 61 6a 6f 72  one of the major
6f60: 20 73 65 61 72 63 68 20 65 6e 67 69 6e 65 73 20   search engines 
6f70: 64 6f 20 74 68 69 73 2e 20 20 28 50 65 72 68 61  do this.  (Perha
6f80: 70 73 20 74 68 65 0a 20 2a 20 66 65 65 6c 69 6e  ps the. * feelin
6f90: 67 20 69 73 20 74 68 61 74 20 61 6e 20 70 61 72  g is that an par
6fa0: 65 6e 74 68 65 73 69 7a 65 64 20 65 78 70 72 65  enthesized expre
6fb0: 73 73 69 6f 6e 20 69 73 20 74 77 6f 20 63 6f 6d  ssion is two com
6fc0: 70 6c 65 78 20 6f 66 0a 20 2a 20 61 6e 20 69 64  plex of. * an id
6fd0: 65 61 20 66 6f 72 20 74 68 65 20 61 76 65 72 61  ea for the avera
6fe0: 67 65 20 75 73 65 72 20 74 6f 20 67 72 61 73 70  ge user to grasp
6ff0: 2e 29 20 20 54 61 6b 69 6e 67 20 6f 75 72 20 6c  .)  Taking our l
7000: 65 61 64 20 66 72 6f 6d 0a 20 2a 20 74 68 65 20  ead from. * the 
7010: 6d 61 6a 6f 72 20 73 65 61 72 63 68 20 65 6e 67  major search eng
7020: 69 6e 65 73 2c 20 77 65 20 77 69 6c 6c 20 61 6c  ines, we will al
7030: 6c 6f 77 20 71 75 65 72 69 65 73 20 74 6f 20 62  low queries to b
7040: 65 20 61 20 6c 69 73 74 0a 20 2a 20 6f 66 20 74  e a list. * of t
7050: 65 72 6d 73 20 28 77 69 74 68 20 61 6e 20 69 6d  erms (with an im
7060: 70 6c 69 65 64 20 41 4e 44 20 6f 70 65 72 61 74  plied AND operat
7070: 6f 72 29 20 6f 72 20 70 68 72 61 73 65 73 20 69  or) or phrases i
7080: 6e 20 64 6f 75 62 6c 65 2d 71 75 6f 74 65 73 2c  n double-quotes,
7090: 0a 20 2a 20 77 69 74 68 20 61 20 73 69 6e 67 6c  . * with a singl
70a0: 65 20 6f 70 74 69 6f 6e 61 6c 20 22 2d 22 20 62  e optional "-" b
70b0: 65 66 6f 72 65 20 65 61 63 68 20 6e 6f 6e 2d 70  efore each non-p
70c0: 68 72 61 73 65 20 74 65 72 6d 20 74 6f 20 64 65  hrase term to de
70d0: 73 69 67 6e 61 74 65 0a 20 2a 20 6e 65 67 61 74  signate. * negat
70e0: 69 6f 6e 20 61 6e 64 20 61 6e 20 6f 70 74 69 6f  ion and an optio
70f0: 6e 61 6c 20 4f 52 20 63 6f 6e 6e 65 63 74 6f 72  nal OR connector
7100: 2e 0a 20 2a 0a 20 2a 20 4f 52 20 62 69 6e 64 73  .. *. * OR binds
7110: 20 6d 6f 72 65 20 74 69 67 68 74 6c 79 20 74 68   more tightly th
7120: 61 6e 20 74 68 65 20 69 6d 70 6c 69 65 64 20 41  an the implied A
7130: 4e 44 2c 20 77 68 69 63 68 20 69 73 20 77 68 61  ND, which is wha
7140: 74 20 74 68 65 0a 20 2a 20 6d 61 6a 6f 72 20 73  t the. * major s
7150: 65 61 72 63 68 20 65 6e 67 69 6e 65 73 20 73 65  earch engines se
7160: 65 6d 20 74 6f 20 64 6f 2e 20 20 53 6f 2c 20 66  em to do.  So, f
7170: 6f 72 20 65 78 61 6d 70 6c 65 3a 0a 20 2a 20 0a  or example:. * .
7180: 20 2a 20 20 20 20 5b 6f 6e 65 20 74 77 6f 20 4f   *    [one two O
7190: 52 20 74 68 72 65 65 5d 20 20 20 20 20 3d 3d 3e  R three]     ==>
71a0: 20 20 20 20 6f 6e 65 20 41 4e 44 20 28 74 77 6f      one AND (two
71b0: 20 4f 52 20 74 68 72 65 65 29 0a 20 2a 20 20 20   OR three). *   
71c0: 20 5b 6f 6e 65 20 4f 52 20 74 77 6f 20 74 68 72   [one OR two thr
71d0: 65 65 5d 20 20 20 20 20 3d 3d 3e 20 20 20 20 28  ee]     ==>    (
71e0: 6f 6e 65 20 4f 52 20 74 77 6f 29 20 41 4e 44 20  one OR two) AND 
71f0: 74 68 72 65 65 0a 20 2a 0a 20 2a 20 41 20 22 2d  three. *. * A "-
7200: 22 20 62 65 66 6f 72 65 20 61 20 74 65 72 6d 20  " before a term 
7210: 6d 61 74 63 68 65 73 20 61 6c 6c 20 65 6e 74 72  matches all entr
7220: 69 65 73 20 74 68 61 74 20 6c 61 63 6b 20 74 68  ies that lack th
7230: 61 74 20 74 65 72 6d 2e 0a 20 2a 20 54 68 65 20  at term.. * The 
7240: 22 2d 22 20 6d 75 73 74 20 6f 63 63 75 72 20 69  "-" must occur i
7250: 6d 6d 65 64 69 61 74 65 6c 79 20 62 65 66 6f 72  mmediately befor
7260: 65 20 74 68 65 20 74 65 72 6d 20 77 69 74 68 20  e the term with 
7270: 69 6e 20 69 6e 74 65 72 76 65 6e 69 6e 67 0a 20  in intervening. 
7280: 2a 20 73 70 61 63 65 2e 20 20 54 68 69 73 20 69  * space.  This i
7290: 73 20 68 6f 77 20 74 68 65 20 73 65 61 72 63 68  s how the search
72a0: 20 65 6e 67 69 6e 65 73 20 64 6f 20 69 74 2e 0a   engines do it..
72b0: 20 2a 0a 20 2a 20 41 20 4e 4f 54 20 74 65 72 6d   *. * A NOT term
72c0: 20 63 61 6e 6e 6f 74 20 62 65 20 74 68 65 20 72   cannot be the r
72d0: 69 67 68 74 2d 68 61 6e 64 20 6f 70 65 72 61 6e  ight-hand operan
72e0: 64 20 6f 66 20 61 6e 20 4f 52 2e 20 20 49 66 20  d of an OR.  If 
72f0: 74 68 69 73 0a 20 2a 20 6f 63 63 75 72 73 20 69  this. * occurs i
7300: 6e 20 74 68 65 20 71 75 65 72 79 20 73 74 72 69  n the query stri
7310: 6e 67 2c 20 74 68 65 20 4e 4f 54 20 69 73 20 69  ng, the NOT is i
7320: 67 6e 6f 72 65 64 3a 0a 20 2a 0a 20 2a 20 20 20  gnored:. *. *   
7330: 20 5b 6f 6e 65 20 4f 52 20 2d 74 77 6f 5d 20 20   [one OR -two]  
7340: 20 20 20 20 20 20 20 20 3d 3d 3e 20 20 20 20 6f          ==>    o
7350: 6e 65 20 4f 52 20 74 77 6f 0a 20 2a 0a 20 2a 2f  ne OR two. *. */
7360: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
7370: 51 75 65 72 79 20 7b 0a 20 20 66 75 6c 6c 74 65  Query {.  fullte
7380: 78 74 5f 76 74 61 62 20 2a 70 46 74 73 3b 20 20  xt_vtab *pFts;  
7390: 2f 2a 20 54 68 65 20 66 75 6c 6c 20 74 65 78 74  /* The full text
73a0: 20 69 6e 64 65 78 20 2a 2f 0a 20 20 69 6e 74 20   index */.  int 
73b0: 6e 54 65 72 6d 73 3b 20 20 20 20 20 20 20 20 20  nTerms;         
73c0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 74    /* Number of t
73d0: 65 72 6d 73 20 69 6e 20 74 68 65 20 71 75 65 72  erms in the quer
73e0: 79 20 2a 2f 0a 20 20 51 75 65 72 79 54 65 72 6d  y */.  QueryTerm
73f0: 20 2a 70 54 65 72 6d 73 3b 20 20 20 20 2f 2a 20   *pTerms;    /* 
7400: 41 72 72 61 79 20 6f 66 20 74 65 72 6d 73 2e 20  Array of terms. 
7410: 20 53 70 61 63 65 20 6f 62 74 61 69 6e 65 64 20   Space obtained 
7420: 66 72 6f 6d 20 6d 61 6c 6c 6f 63 28 29 20 2a 2f  from malloc() */
7430: 0a 20 20 69 6e 74 20 6e 65 78 74 49 73 4f 72 3b  .  int nextIsOr;
7440: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20           /* Set 
7450: 74 68 65 20 69 73 4f 72 20 66 6c 61 67 20 6f 6e  the isOr flag on
7460: 20 74 68 65 20 6e 65 78 74 20 69 6e 73 65 72 74   the next insert
7470: 65 64 20 74 65 72 6d 20 2a 2f 0a 20 20 69 6e 74  ed term */.  int
7480: 20 6e 65 78 74 43 6f 6c 75 6d 6e 3b 20 20 20 20   nextColumn;    
7490: 20 20 20 2f 2a 20 4e 65 78 74 20 77 6f 72 64 20     /* Next word 
74a0: 70 61 72 73 65 64 20 6d 75 73 74 20 62 65 20 69  parsed must be i
74b0: 6e 20 74 68 69 73 20 63 6f 6c 75 6d 6e 20 2a 2f  n this column */
74c0: 0a 20 20 69 6e 74 20 64 66 6c 74 43 6f 6c 75 6d  .  int dfltColum
74d0: 6e 3b 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20  n;       /* The 
74e0: 64 65 66 61 75 6c 74 20 63 6f 6c 75 6d 6e 20 2a  default column *
74f0: 2f 0a 7d 20 51 75 65 72 79 3b 0a 0a 0a 2f 2a 0a  /.} Query;.../*.
7500: 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f  ** An instance o
7510: 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
7520: 73 74 72 75 63 74 75 72 65 20 6b 65 65 70 73 20  structure keeps 
7530: 74 72 61 63 6b 20 6f 66 20 67 65 6e 65 72 61 74  track of generat
7540: 65 64 0a 2a 2a 20 6d 61 74 63 68 69 6e 67 2d 77  ed.** matching-w
7550: 6f 72 64 20 6f 66 66 73 65 74 20 69 6e 66 6f 72  ord offset infor
7560: 6d 61 74 69 6f 6e 20 61 6e 64 20 73 6e 69 70 70  mation and snipp
7570: 65 74 73 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20  ets..*/.typedef 
7580: 73 74 72 75 63 74 20 53 6e 69 70 70 65 74 20 7b  struct Snippet {
7590: 0a 20 20 69 6e 74 20 6e 4d 61 74 63 68 3b 20 20  .  int nMatch;  
75a0: 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62     /* Total numb
75b0: 65 72 20 6f 66 20 6d 61 74 63 68 65 73 20 2a 2f  er of matches */
75c0: 0a 20 20 69 6e 74 20 6e 41 6c 6c 6f 63 3b 20 20  .  int nAlloc;  
75d0: 20 20 20 2f 2a 20 53 70 61 63 65 20 61 6c 6c 6f     /* Space allo
75e0: 63 61 74 65 64 20 66 6f 72 20 61 4d 61 74 63 68  cated for aMatch
75f0: 5b 5d 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 73  [] */.  struct s
7600: 6e 69 70 70 65 74 4d 61 74 63 68 20 7b 20 2f 2a  nippetMatch { /*
7610: 20 4f 6e 65 20 65 6e 74 72 79 20 66 6f 72 20 65   One entry for e
7620: 61 63 68 20 6d 61 74 63 68 69 6e 67 20 74 65 72  ach matching ter
7630: 6d 20 2a 2f 0a 20 20 20 20 63 68 61 72 20 73 6e  m */.    char sn
7640: 53 74 61 74 75 73 3b 20 20 20 20 20 20 20 2f 2a  Status;       /*
7650: 20 53 74 61 74 75 73 20 66 6c 61 67 20 66 6f 72   Status flag for
7660: 20 75 73 65 20 77 68 69 6c 65 20 63 6f 6e 73 74   use while const
7670: 72 75 63 74 69 6e 67 20 73 6e 69 70 70 65 74 73  ructing snippets
7680: 20 2a 2f 0a 20 20 20 20 73 68 6f 72 74 20 69 6e   */.    short in
7690: 74 20 69 43 6f 6c 3b 20 20 20 20 20 20 2f 2a 20  t iCol;      /* 
76a0: 54 68 65 20 63 6f 6c 75 6d 6e 20 74 68 61 74 20  The column that 
76b0: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 6d 61 74  contains the mat
76c0: 63 68 20 2a 2f 0a 20 20 20 20 73 68 6f 72 74 20  ch */.    short 
76d0: 69 6e 74 20 69 54 65 72 6d 3b 20 20 20 20 20 2f  int iTerm;     /
76e0: 2a 20 54 68 65 20 69 6e 64 65 78 20 69 6e 20 51  * The index in Q
76f0: 75 65 72 79 2e 70 54 65 72 6d 73 5b 5d 20 6f 66  uery.pTerms[] of
7700: 20 74 68 65 20 6d 61 74 63 68 69 6e 67 20 74 65   the matching te
7710: 72 6d 20 2a 2f 0a 20 20 20 20 73 68 6f 72 74 20  rm */.    short 
7720: 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20 2f  int nByte;     /
7730: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
7740: 73 20 69 6e 20 74 68 65 20 74 65 72 6d 20 2a 2f  s in the term */
7750: 0a 20 20 20 20 69 6e 74 20 69 53 74 61 72 74 3b  .    int iStart;
7760: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
7770: 20 6f 66 66 73 65 74 20 74 6f 20 74 68 65 20 66   offset to the f
7780: 69 72 73 74 20 63 68 61 72 61 63 74 65 72 20 6f  irst character o
7790: 66 20 74 68 65 20 74 65 72 6d 20 2a 2f 0a 20 20  f the term */.  
77a0: 7d 20 2a 61 4d 61 74 63 68 3b 20 20 20 20 20 20  } *aMatch;      
77b0: 2f 2a 20 50 6f 69 6e 74 73 20 74 6f 20 73 70 61  /* Points to spa
77c0: 63 65 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d  ce obtained from
77d0: 20 6d 61 6c 6c 6f 63 20 2a 2f 0a 20 20 63 68 61   malloc */.  cha
77e0: 72 20 2a 7a 4f 66 66 73 65 74 3b 20 20 2f 2a 20  r *zOffset;  /* 
77f0: 54 65 78 74 20 72 65 6e 64 65 72 69 6e 67 20 6f  Text rendering o
7800: 66 20 61 4d 61 74 63 68 5b 5d 20 2a 2f 0a 20 20  f aMatch[] */.  
7810: 69 6e 74 20 6e 4f 66 66 73 65 74 3b 20 20 20 20  int nOffset;    
7820: 2f 2a 20 73 74 72 6c 65 6e 28 7a 4f 66 66 73 65  /* strlen(zOffse
7830: 74 29 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 53  t) */.  char *zS
7840: 6e 69 70 70 65 74 3b 20 2f 2a 20 53 6e 69 70 70  nippet; /* Snipp
7850: 65 74 20 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74  et text */.  int
7860: 20 6e 53 6e 69 70 70 65 74 3b 20 20 20 2f 2a 20   nSnippet;   /* 
7870: 73 74 72 6c 65 6e 28 7a 53 6e 69 70 70 65 74 29  strlen(zSnippet)
7880: 20 2a 2f 0a 7d 20 53 6e 69 70 70 65 74 3b 0a 0a   */.} Snippet;..
7890: 0a 74 79 70 65 64 65 66 20 65 6e 75 6d 20 51 75  .typedef enum Qu
78a0: 65 72 79 54 79 70 65 20 7b 0a 20 20 51 55 45 52  eryType {.  QUER
78b0: 59 5f 47 45 4e 45 52 49 43 2c 20 20 20 2f 2a 20  Y_GENERIC,   /* 
78c0: 74 61 62 6c 65 20 73 63 61 6e 20 2a 2f 0a 20 20  table scan */.  
78d0: 51 55 45 52 59 5f 52 4f 57 49 44 2c 20 20 20 20  QUERY_ROWID,    
78e0: 20 2f 2a 20 6c 6f 6f 6b 75 70 20 62 79 20 72 6f   /* lookup by ro
78f0: 77 69 64 20 2a 2f 0a 20 20 51 55 45 52 59 5f 46  wid */.  QUERY_F
7900: 55 4c 4c 54 45 58 54 20 20 20 2f 2a 20 51 55 45  ULLTEXT   /* QUE
7910: 52 59 5f 46 55 4c 4c 54 45 58 54 20 2b 20 5b 69  RY_FULLTEXT + [i
7920: 5d 20 69 73 20 61 20 66 75 6c 6c 2d 74 65 78 74  ] is a full-text
7930: 20 73 65 61 72 63 68 20 66 6f 72 20 63 6f 6c 75   search for colu
7940: 6d 6e 20 69 2a 2f 0a 7d 20 51 75 65 72 79 54 79  mn i*/.} QueryTy
7950: 70 65 3b 0a 0a 2f 2a 20 54 4f 44 4f 28 73 68 65  pe;../* TODO(she
7960: 73 73 29 20 43 48 55 4e 4b 5f 4d 41 58 20 63 6f  ss) CHUNK_MAX co
7970: 6e 74 72 6f 6c 73 20 68 6f 77 20 6d 75 63 68 20  ntrols how much 
7980: 64 61 74 61 20 77 65 20 61 6c 6c 6f 77 20 69 6e  data we allow in
7990: 20 73 65 67 6d 65 6e 74 20 30 0a 2a 2a 20 62 65   segment 0.** be
79a0: 66 6f 72 65 20 77 65 20 73 74 61 72 74 20 61 67  fore we start ag
79b0: 67 72 65 67 61 74 69 6e 67 20 69 6e 74 6f 20 6c  gregating into l
79c0: 61 72 67 65 72 20 73 65 67 6d 65 6e 74 73 2e 20  arger segments. 
79d0: 20 4c 6f 77 65 72 20 43 48 55 4e 4b 5f 4d 41 58   Lower CHUNK_MAX
79e0: 0a 2a 2a 20 6d 65 61 6e 73 20 74 68 61 74 20 66  .** means that f
79f0: 6f 72 20 61 20 67 69 76 65 6e 20 69 6e 70 75 74  or a given input
7a00: 20 77 65 20 68 61 76 65 20 6d 6f 72 65 20 69 6e   we have more in
7a10: 64 69 76 69 64 75 61 6c 20 73 65 67 6d 65 6e 74  dividual segment
7a20: 73 20 70 65 72 0a 2a 2a 20 74 65 72 6d 2c 20 77  s per.** term, w
7a30: 68 69 63 68 20 6d 65 61 6e 73 20 6d 6f 72 65 20  hich means more 
7a40: 72 6f 77 73 20 69 6e 20 74 68 65 20 74 61 62 6c  rows in the tabl
7a50: 65 20 61 6e 64 20 61 20 62 69 67 67 65 72 20 69  e and a bigger i
7a60: 6e 64 65 78 20 28 64 75 65 20 74 6f 0a 2a 2a 20  ndex (due to.** 
7a70: 62 6f 74 68 20 6d 6f 72 65 20 72 6f 77 73 20 61  both more rows a
7a80: 6e 64 20 62 69 67 67 65 72 20 72 6f 77 69 64 73  nd bigger rowids
7a90: 29 2e 20 20 42 75 74 20 69 74 20 61 6c 73 6f 20  ).  But it also 
7aa0: 72 65 64 75 63 65 73 20 74 68 65 20 61 76 65 72  reduces the aver
7ab0: 61 67 65 0a 2a 2a 20 63 6f 73 74 20 6f 66 20 61  age.** cost of a
7ac0: 64 64 69 6e 67 20 6e 65 77 20 65 6c 65 6d 65 6e  dding new elemen
7ad0: 74 73 20 74 6f 20 74 68 65 20 73 65 67 6d 65 6e  ts to the segmen
7ae0: 74 20 30 20 64 6f 63 6c 69 73 74 2c 20 61 6e 64  t 0 doclist, and
7af0: 20 69 74 20 73 65 65 6d 73 0a 2a 2a 20 74 6f 20   it seems.** to 
7b00: 72 65 64 75 63 65 20 74 68 65 20 6e 75 6d 62 65  reduce the numbe
7b10: 72 20 6f 66 20 70 61 67 65 73 20 72 65 61 64 20  r of pages read 
7b20: 61 6e 64 20 77 72 69 74 74 65 6e 20 64 75 72 69  and written duri
7b30: 6e 67 20 69 6e 73 65 72 74 73 2e 20 20 32 35 36  ng inserts.  256
7b40: 0a 2a 2a 20 77 61 73 20 63 68 6f 73 65 6e 20 62  .** was chosen b
7b50: 79 20 6d 65 61 73 75 72 69 6e 67 20 69 6e 73 65  y measuring inse
7b60: 72 74 69 6f 6e 20 74 69 6d 65 73 20 66 6f 72 20  rtion times for 
7b70: 61 20 63 65 72 74 61 69 6e 20 69 6e 70 75 74 20  a certain input 
7b80: 28 66 69 72 73 74 0a 2a 2a 20 31 30 6b 20 64 6f  (first.** 10k do
7b90: 63 75 6d 65 6e 74 73 20 6f 66 20 45 6e 72 6f 6e  cuments of Enron
7ba0: 20 63 6f 72 70 75 73 29 2c 20 74 68 6f 75 67 68   corpus), though
7bb0: 20 69 6e 63 6c 75 64 69 6e 67 20 71 75 65 72 79   including query
7bc0: 20 70 65 72 66 6f 72 6d 61 6e 63 65 0a 2a 2a 20   performance.** 
7bd0: 69 6e 20 74 68 65 20 64 65 63 69 73 69 6f 6e 20  in the decision 
7be0: 6d 61 79 20 61 72 67 75 65 20 66 6f 72 20 61 20  may argue for a 
7bf0: 6c 61 72 67 65 72 20 76 61 6c 75 65 2e 0a 2a 2f  larger value..*/
7c00: 0a 23 64 65 66 69 6e 65 20 43 48 55 4e 4b 5f 4d  .#define CHUNK_M
7c10: 41 58 20 32 35 36 0a 0a 74 79 70 65 64 65 66 20  AX 256..typedef 
7c20: 65 6e 75 6d 20 66 75 6c 6c 74 65 78 74 5f 73 74  enum fulltext_st
7c30: 61 74 65 6d 65 6e 74 20 7b 0a 20 20 43 4f 4e 54  atement {.  CONT
7c40: 45 4e 54 5f 49 4e 53 45 52 54 5f 53 54 4d 54 2c  ENT_INSERT_STMT,
7c50: 0a 20 20 43 4f 4e 54 45 4e 54 5f 53 45 4c 45 43  .  CONTENT_SELEC
7c60: 54 5f 53 54 4d 54 2c 0a 20 20 43 4f 4e 54 45 4e  T_STMT,.  CONTEN
7c70: 54 5f 55 50 44 41 54 45 5f 53 54 4d 54 2c 0a 20  T_UPDATE_STMT,. 
7c80: 20 43 4f 4e 54 45 4e 54 5f 44 45 4c 45 54 45 5f   CONTENT_DELETE_
7c90: 53 54 4d 54 2c 0a 0a 20 20 54 45 52 4d 5f 53 45  STMT,..  TERM_SE
7ca0: 4c 45 43 54 5f 53 54 4d 54 2c 0a 20 20 54 45 52  LECT_STMT,.  TER
7cb0: 4d 5f 53 45 4c 45 43 54 5f 41 4c 4c 5f 53 54 4d  M_SELECT_ALL_STM
7cc0: 54 2c 0a 20 20 54 45 52 4d 5f 49 4e 53 45 52 54  T,.  TERM_INSERT
7cd0: 5f 53 54 4d 54 2c 0a 20 20 54 45 52 4d 5f 55 50  _STMT,.  TERM_UP
7ce0: 44 41 54 45 5f 53 54 4d 54 2c 0a 20 20 54 45 52  DATE_STMT,.  TER
7cf0: 4d 5f 44 45 4c 45 54 45 5f 53 54 4d 54 2c 0a 0a  M_DELETE_STMT,..
7d00: 20 20 4d 41 58 5f 53 54 4d 54 20 20 20 20 20 20    MAX_STMT      
7d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7d20: 2a 20 41 6c 77 61 79 73 20 61 74 20 65 6e 64 21  * Always at end!
7d30: 20 2a 2f 0a 7d 20 66 75 6c 6c 74 65 78 74 5f 73   */.} fulltext_s
7d40: 74 61 74 65 6d 65 6e 74 3b 0a 0a 2f 2a 20 54 68  tatement;../* Th
7d50: 65 73 65 20 6d 75 73 74 20 65 78 61 63 74 6c 79  ese must exactly
7d60: 20 6d 61 74 63 68 20 74 68 65 20 65 6e 75 6d 20   match the enum 
7d70: 61 62 6f 76 65 2e 20 2a 2f 0a 2f 2a 20 54 4f 44  above. */./* TOD
7d80: 4f 28 61 64 61 6d 29 3a 20 49 73 20 74 68 65 72  O(adam): Is ther
7d90: 65 20 73 6f 6d 65 20 72 69 73 6b 20 74 68 61 74  e some risk that
7da0: 20 61 20 73 74 61 74 65 6d 65 6e 74 20 28 69 6e   a statement (in
7db0: 20 70 61 72 74 69 63 75 6c 61 72 2c 0a 2a 2a 20   particular,.** 
7dc0: 70 54 65 72 6d 53 65 6c 65 63 74 53 74 6d 74 29  pTermSelectStmt)
7dd0: 20 77 69 6c 6c 20 62 65 20 75 73 65 64 20 69 6e   will be used in
7de0: 20 74 77 6f 20 63 75 72 73 6f 72 73 20 61 74 20   two cursors at 
7df0: 6f 6e 63 65 2c 20 65 2e 67 2e 20 20 69 66 20 61  once, e.g.  if a
7e00: 0a 2a 2a 20 71 75 65 72 79 20 6a 6f 69 6e 73 20  .** query joins 
7e10: 61 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  a virtual table 
7e20: 74 6f 20 69 74 73 65 6c 66 3f 20 20 49 66 20 73  to itself?  If s
7e30: 6f 20 70 65 72 68 61 70 73 20 77 65 20 73 68 6f  o perhaps we sho
7e40: 75 6c 64 0a 2a 2a 20 6d 6f 76 65 20 73 6f 6d 65  uld.** move some
7e50: 20 6f 66 20 74 68 65 73 65 20 74 6f 20 74 68 65   of these to the
7e60: 20 63 75 72 73 6f 72 20 6f 62 6a 65 63 74 2e 0a   cursor object..
7e70: 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20  */.static const 
7e80: 63 68 61 72 20 2a 63 6f 6e 73 74 20 66 75 6c 6c  char *const full
7e90: 74 65 78 74 5f 7a 53 74 61 74 65 6d 65 6e 74 5b  text_zStatement[
7ea0: 4d 41 58 5f 53 54 4d 54 5d 20 3d 20 7b 0a 20 20  MAX_STMT] = {.  
7eb0: 2f 2a 20 43 4f 4e 54 45 4e 54 5f 49 4e 53 45 52  /* CONTENT_INSER
7ec0: 54 20 2a 2f 20 4e 55 4c 4c 2c 20 20 2f 2a 20 67  T */ NULL,  /* g
7ed0: 65 6e 65 72 61 74 65 64 20 69 6e 20 63 6f 6e 74  enerated in cont
7ee0: 65 6e 74 49 6e 73 65 72 74 53 74 61 74 65 6d 65  entInsertStateme
7ef0: 6e 74 28 29 20 2a 2f 0a 20 20 2f 2a 20 43 4f 4e  nt() */.  /* CON
7f00: 54 45 4e 54 5f 53 45 4c 45 43 54 20 2a 2f 20 22  TENT_SELECT */ "
7f10: 73 65 6c 65 63 74 20 2a 20 66 72 6f 6d 20 25 5f  select * from %_
7f20: 63 6f 6e 74 65 6e 74 20 77 68 65 72 65 20 72 6f  content where ro
7f30: 77 69 64 20 3d 20 3f 22 2c 0a 20 20 2f 2a 20 43  wid = ?",.  /* C
7f40: 4f 4e 54 45 4e 54 5f 55 50 44 41 54 45 20 2a 2f  ONTENT_UPDATE */
7f50: 20 4e 55 4c 4c 2c 20 20 2f 2a 20 67 65 6e 65 72   NULL,  /* gener
7f60: 61 74 65 64 20 69 6e 20 63 6f 6e 74 65 6e 74 55  ated in contentU
7f70: 70 64 61 74 65 53 74 61 74 65 6d 65 6e 74 28 29  pdateStatement()
7f80: 20 2a 2f 0a 20 20 2f 2a 20 43 4f 4e 54 45 4e 54   */.  /* CONTENT
7f90: 5f 44 45 4c 45 54 45 20 2a 2f 20 22 64 65 6c 65  _DELETE */ "dele
7fa0: 74 65 20 66 72 6f 6d 20 25 5f 63 6f 6e 74 65 6e  te from %_conten
7fb0: 74 20 77 68 65 72 65 20 72 6f 77 69 64 20 3d 20  t where rowid = 
7fc0: 3f 22 2c 0a 0a 20 20 2f 2a 20 54 45 52 4d 5f 53  ?",..  /* TERM_S
7fd0: 45 4c 45 43 54 20 2a 2f 0a 20 20 22 73 65 6c 65  ELECT */.  "sele
7fe0: 63 74 20 72 6f 77 69 64 2c 20 64 6f 63 6c 69 73  ct rowid, doclis
7ff0: 74 20 66 72 6f 6d 20 25 5f 74 65 72 6d 20 77 68  t from %_term wh
8000: 65 72 65 20 74 65 72 6d 20 3d 20 3f 20 61 6e 64  ere term = ? and
8010: 20 73 65 67 6d 65 6e 74 20 3d 20 3f 22 2c 0a 20   segment = ?",. 
8020: 20 2f 2a 20 54 45 52 4d 5f 53 45 4c 45 43 54 5f   /* TERM_SELECT_
8030: 41 4c 4c 20 2a 2f 0a 20 20 22 73 65 6c 65 63 74  ALL */.  "select
8040: 20 64 6f 63 6c 69 73 74 20 66 72 6f 6d 20 25 5f   doclist from %_
8050: 74 65 72 6d 20 77 68 65 72 65 20 74 65 72 6d 20  term where term 
8060: 3d 20 3f 20 6f 72 64 65 72 20 62 79 20 73 65 67  = ? order by seg
8070: 6d 65 6e 74 22 2c 0a 20 20 2f 2a 20 54 45 52 4d  ment",.  /* TERM
8080: 5f 49 4e 53 45 52 54 20 2a 2f 0a 20 20 22 69 6e  _INSERT */.  "in
8090: 73 65 72 74 20 69 6e 74 6f 20 25 5f 74 65 72 6d  sert into %_term
80a0: 20 28 72 6f 77 69 64 2c 20 74 65 72 6d 2c 20 73   (rowid, term, s
80b0: 65 67 6d 65 6e 74 2c 20 64 6f 63 6c 69 73 74 29  egment, doclist)
80c0: 20 76 61 6c 75 65 73 20 28 3f 2c 20 3f 2c 20 3f   values (?, ?, ?
80d0: 2c 20 3f 29 22 2c 0a 20 20 2f 2a 20 54 45 52 4d  , ?)",.  /* TERM
80e0: 5f 55 50 44 41 54 45 20 2a 2f 20 22 75 70 64 61  _UPDATE */ "upda
80f0: 74 65 20 25 5f 74 65 72 6d 20 73 65 74 20 64 6f  te %_term set do
8100: 63 6c 69 73 74 20 3d 20 3f 20 77 68 65 72 65 20  clist = ? where 
8110: 72 6f 77 69 64 20 3d 20 3f 22 2c 0a 20 20 2f 2a  rowid = ?",.  /*
8120: 20 54 45 52 4d 5f 44 45 4c 45 54 45 20 2a 2f 20   TERM_DELETE */ 
8130: 22 64 65 6c 65 74 65 20 66 72 6f 6d 20 25 5f 74  "delete from %_t
8140: 65 72 6d 20 77 68 65 72 65 20 72 6f 77 69 64 20  erm where rowid 
8150: 3d 20 3f 22 2c 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  = ?",.};../*.** 
8160: 41 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20  A connection to 
8170: 61 20 66 75 6c 6c 74 65 78 74 20 69 6e 64 65 78  a fulltext index
8180: 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   is an instance 
8190: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
81a0: 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 2e 20 20  .** structure.  
81b0: 54 68 65 20 78 43 72 65 61 74 65 20 61 6e 64 20  The xCreate and 
81c0: 78 43 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 73  xConnect methods
81d0: 20 63 72 65 61 74 65 20 61 6e 20 69 6e 73 74 61   create an insta
81e0: 6e 63 65 0a 2a 2a 20 6f 66 20 74 68 69 73 20 73  nce.** of this s
81f0: 74 72 75 63 74 75 72 65 20 61 6e 64 20 78 44 65  tructure and xDe
8200: 73 74 72 6f 79 20 61 6e 64 20 78 44 69 73 63 6f  stroy and xDisco
8210: 6e 6e 65 63 74 20 66 72 65 65 20 74 68 61 74 20  nnect free that 
8220: 69 6e 73 74 61 6e 63 65 2e 0a 2a 2a 20 41 6c 6c  instance..** All
8230: 20 6f 74 68 65 72 20 6d 65 74 68 6f 64 73 20 72   other methods r
8240: 65 63 65 69 76 65 20 61 20 70 6f 69 6e 74 65 72  eceive a pointer
8250: 20 74 6f 20 74 68 65 20 73 74 72 75 63 74 75 72   to the structur
8260: 65 20 61 73 20 6f 6e 65 20 6f 66 20 74 68 65 69  e as one of thei
8270: 72 0a 2a 2a 20 61 72 67 75 6d 65 6e 74 73 2e 0a  r.** arguments..
8280: 2a 2f 0a 73 74 72 75 63 74 20 66 75 6c 6c 74 65  */.struct fullte
8290: 78 74 5f 76 74 61 62 20 7b 0a 20 20 73 71 6c 69  xt_vtab {.  sqli
82a0: 74 65 33 5f 76 74 61 62 20 62 61 73 65 3b 20 20  te3_vtab base;  
82b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
82c0: 42 61 73 65 20 63 6c 61 73 73 20 75 73 65 64 20  Base class used 
82d0: 62 79 20 53 51 4c 69 74 65 20 63 6f 72 65 20 2a  by SQLite core *
82e0: 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b  /.  sqlite3 *db;
82f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8300: 20 20 20 20 20 2f 2a 20 54 68 65 20 64 61 74 61       /* The data
8310: 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  base connection 
8320: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
8330: 2a 7a 44 62 3b 20 20 20 20 20 20 20 20 20 20 20  *zDb;           
8340: 20 20 20 20 20 20 2f 2a 20 6c 6f 67 69 63 61 6c        /* logical
8350: 20 64 61 74 61 62 61 73 65 20 6e 61 6d 65 20 2a   database name *
8360: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
8370: 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  zName;          
8380: 20 20 20 20 20 2f 2a 20 76 69 72 74 75 61 6c 20       /* virtual 
8390: 74 61 62 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20  table name */.  
83a0: 69 6e 74 20 6e 43 6f 6c 75 6d 6e 3b 20 20 20 20  int nColumn;    
83b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
83c0: 20 2f 2a 20 6e 75 6d 62 65 72 20 6f 66 20 63 6f   /* number of co
83d0: 6c 75 6d 6e 73 20 69 6e 20 76 69 72 74 75 61 6c  lumns in virtual
83e0: 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63 68 61 72   table */.  char
83f0: 20 2a 2a 61 7a 43 6f 6c 75 6d 6e 3b 20 20 20 20   **azColumn;    
8400: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8410: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 2e 20 20 6d  column names.  m
8420: 61 6c 6c 6f 63 65 64 20 2a 2f 0a 20 20 63 68 61  alloced */.  cha
8430: 72 20 2a 2a 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c  r **azContentCol
8440: 75 6d 6e 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  umn;          /*
8450: 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 69 6e   column names in
8460: 20 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65 3b 20   content table; 
8470: 6d 61 6c 6c 6f 63 65 64 20 2a 2f 0a 20 20 73 71  malloced */.  sq
8480: 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 20  lite3_tokenizer 
8490: 2a 70 54 6f 6b 65 6e 69 7a 65 72 3b 20 20 20 2f  *pTokenizer;   /
84a0: 2a 20 74 6f 6b 65 6e 69 7a 65 72 20 66 6f 72 20  * tokenizer for 
84b0: 69 6e 73 65 72 74 73 20 61 6e 64 20 71 75 65 72  inserts and quer
84c0: 69 65 73 20 2a 2f 0a 0a 20 20 2f 2a 20 50 72 65  ies */..  /* Pre
84d0: 63 6f 6d 70 69 6c 65 64 20 73 74 61 74 65 6d 65  compiled stateme
84e0: 6e 74 73 20 77 68 69 63 68 20 77 65 20 6b 65 65  nts which we kee
84f0: 70 20 61 73 20 6c 6f 6e 67 20 61 73 20 74 68 65  p as long as the
8500: 20 74 61 62 6c 65 20 69 73 0a 20 20 2a 2a 20 6f   table is.  ** o
8510: 70 65 6e 2e 0a 20 20 2a 2f 0a 20 20 73 71 6c 69  pen..  */.  sqli
8520: 74 65 33 5f 73 74 6d 74 20 2a 70 46 75 6c 6c 74  te3_stmt *pFullt
8530: 65 78 74 53 74 61 74 65 6d 65 6e 74 73 5b 4d 41  extStatements[MA
8540: 58 5f 53 54 4d 54 5d 3b 0a 7d 3b 0a 0a 2f 2a 0a  X_STMT];.};../*.
8550: 2a 2a 20 57 68 65 6e 20 74 68 65 20 63 6f 72 65  ** When the core
8560: 20 77 61 6e 74 73 20 74 6f 20 64 6f 20 61 20 71   wants to do a q
8570: 75 65 72 79 2c 20 69 74 20 63 72 65 61 74 65 20  uery, it create 
8580: 61 20 63 75 72 73 6f 72 20 75 73 69 6e 67 20 61  a cursor using a
8590: 0a 2a 2a 20 63 61 6c 6c 20 74 6f 20 78 4f 70 65  .** call to xOpe
85a0: 6e 2e 20 20 54 68 69 73 20 73 74 72 75 63 74 75  n.  This structu
85b0: 72 65 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63  re is an instanc
85c0: 65 20 6f 66 20 61 20 63 75 72 73 6f 72 2e 20 20  e of a cursor.  
85d0: 49 74 0a 2a 2a 20 69 73 20 64 65 73 74 72 6f 79  It.** is destroy
85e0: 65 64 20 62 79 20 78 43 6c 6f 73 65 2e 0a 2a 2f  ed by xClose..*/
85f0: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
8600: 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20  fulltext_cursor 
8610: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  {.  sqlite3_vtab
8620: 5f 63 75 72 73 6f 72 20 62 61 73 65 3b 20 20 20  _cursor base;   
8630: 20 20 20 20 20 2f 2a 20 42 61 73 65 20 63 6c 61       /* Base cla
8640: 73 73 20 75 73 65 64 20 62 79 20 53 51 4c 69 74  ss used by SQLit
8650: 65 20 63 6f 72 65 20 2a 2f 0a 20 20 51 75 65 72  e core */.  Quer
8660: 79 54 79 70 65 20 69 43 75 72 73 6f 72 54 79 70  yType iCursorTyp
8670: 65 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  e;           /* 
8680: 43 6f 70 79 20 6f 66 20 73 71 6c 69 74 65 33 5f  Copy of sqlite3_
8690: 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78 4e 75  index_info.idxNu
86a0: 6d 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73  m */.  sqlite3_s
86b0: 74 6d 74 20 2a 70 53 74 6d 74 3b 20 20 20 20 20  tmt *pStmt;     
86c0: 20 20 20 20 20 20 20 20 2f 2a 20 50 72 65 70 61          /* Prepa
86d0: 72 65 64 20 73 74 61 74 65 6d 65 6e 74 20 69 6e  red statement in
86e0: 20 75 73 65 20 62 79 20 74 68 65 20 63 75 72 73   use by the curs
86f0: 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 65 6f 66 3b  or */.  int eof;
8700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8710: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
8720: 20 69 66 20 61 74 20 45 6e 64 20 4f 66 20 52 65   if at End Of Re
8730: 73 75 6c 74 73 20 2a 2f 0a 20 20 51 75 65 72 79  sults */.  Query
8740: 20 71 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   q;             
8750: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
8760: 61 72 73 65 64 20 71 75 65 72 79 20 73 74 72 69  arsed query stri
8770: 6e 67 20 2a 2f 0a 20 20 53 6e 69 70 70 65 74 20  ng */.  Snippet 
8780: 73 6e 69 70 70 65 74 3b 20 20 20 20 20 20 20 20  snippet;        
8790: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 63 68           /* Cach
87a0: 65 64 20 73 6e 69 70 70 65 74 20 66 6f 72 20 74  ed snippet for t
87b0: 68 65 20 63 75 72 72 65 6e 74 20 72 6f 77 20 2a  he current row *
87c0: 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 3b  /.  int iColumn;
87d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
87e0: 20 20 20 20 20 2f 2a 20 43 6f 6c 75 6d 6e 20 62       /* Column b
87f0: 65 69 6e 67 20 73 65 61 72 63 68 65 64 20 2a 2f  eing searched */
8800: 0a 20 20 44 6f 63 4c 69 73 74 52 65 61 64 65 72  .  DocListReader
8810: 20 72 65 73 75 6c 74 3b 20 20 2f 2a 20 75 73 65   result;  /* use
8820: 64 20 77 68 65 6e 20 69 43 75 72 73 6f 72 54 79  d when iCursorTy
8830: 70 65 20 3d 3d 20 51 55 45 52 59 5f 46 55 4c 4c  pe == QUERY_FULL
8840: 54 45 58 54 20 2a 2f 20 0a 7d 20 66 75 6c 6c 74  TEXT */ .} fullt
8850: 65 78 74 5f 63 75 72 73 6f 72 3b 0a 0a 73 74 61  ext_cursor;..sta
8860: 74 69 63 20 73 74 72 75 63 74 20 66 75 6c 6c 74  tic struct fullt
8870: 65 78 74 5f 76 74 61 62 20 2a 63 75 72 73 6f 72  ext_vtab *cursor
8880: 5f 76 74 61 62 28 66 75 6c 6c 74 65 78 74 5f 63  _vtab(fulltext_c
8890: 75 72 73 6f 72 20 2a 63 29 7b 0a 20 20 72 65 74  ursor *c){.  ret
88a0: 75 72 6e 20 28 66 75 6c 6c 74 65 78 74 5f 76 74  urn (fulltext_vt
88b0: 61 62 20 2a 29 20 63 2d 3e 62 61 73 65 2e 70 56  ab *) c->base.pV
88c0: 74 61 62 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63  tab;.}..static c
88d0: 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 6d 6f 64  onst sqlite3_mod
88e0: 75 6c 65 20 66 75 6c 6c 74 65 78 74 4d 6f 64 75  ule fulltextModu
88f0: 6c 65 3b 20 20 20 2f 2a 20 66 6f 72 77 61 72 64  le;   /* forward
8900: 20 64 65 63 6c 61 72 61 74 69 6f 6e 20 2a 2f 0a   declaration */.
8910: 0a 2f 2a 20 41 70 70 65 6e 64 20 61 20 6c 69 73  ./* Append a lis
8920: 74 20 6f 66 20 73 74 72 69 6e 67 73 20 73 65 70  t of strings sep
8930: 61 72 61 74 65 64 20 62 79 20 63 6f 6d 6d 61 73  arated by commas
8940: 20 74 6f 20 61 20 53 74 72 69 6e 67 42 75 66 66   to a StringBuff
8950: 65 72 2e 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  er. */.static vo
8960: 69 64 20 61 70 70 65 6e 64 4c 69 73 74 28 53 74  id appendList(St
8970: 72 69 6e 67 42 75 66 66 65 72 20 2a 73 62 2c 20  ringBuffer *sb, 
8980: 69 6e 74 20 6e 53 74 72 69 6e 67 2c 20 63 68 61  int nString, cha
8990: 72 20 2a 2a 61 7a 53 74 72 69 6e 67 29 7b 0a 20  r **azString){. 
89a0: 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d   int i;.  for(i=
89b0: 30 3b 20 69 3c 6e 53 74 72 69 6e 67 3b 20 2b 2b  0; i<nString; ++
89c0: 69 29 7b 0a 20 20 20 20 69 66 28 20 69 3e 30 20  i){.    if( i>0 
89d0: 29 20 61 70 70 65 6e 64 28 73 62 2c 20 22 2c 20  ) append(sb, ", 
89e0: 22 29 3b 0a 20 20 20 20 61 70 70 65 6e 64 28 73  ");.    append(s
89f0: 62 2c 20 61 7a 53 74 72 69 6e 67 5b 69 5d 29 3b  b, azString[i]);
8a00: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 52 65 74 75 72  .  }.}../* Retur
8a10: 6e 20 61 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20  n a dynamically 
8a20: 67 65 6e 65 72 61 74 65 64 20 73 74 61 74 65 6d  generated statem
8a30: 65 6e 74 20 6f 66 20 74 68 65 20 66 6f 72 6d 0a  ent of the form.
8a40: 20 2a 20 20 20 69 6e 73 65 72 74 20 69 6e 74 6f   *   insert into
8a50: 20 25 5f 63 6f 6e 74 65 6e 74 20 28 72 6f 77 69   %_content (rowi
8a60: 64 2c 20 2e 2e 2e 29 20 76 61 6c 75 65 73 20 28  d, ...) values (
8a70: 3f 2c 20 2e 2e 2e 29 0a 20 2a 2f 0a 73 74 61 74  ?, ...). */.stat
8a80: 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  ic const char *c
8a90: 6f 6e 74 65 6e 74 49 6e 73 65 72 74 53 74 61 74  ontentInsertStat
8aa0: 65 6d 65 6e 74 28 66 75 6c 6c 74 65 78 74 5f 76  ement(fulltext_v
8ab0: 74 61 62 20 2a 76 29 7b 0a 20 20 53 74 72 69 6e  tab *v){.  Strin
8ac0: 67 42 75 66 66 65 72 20 73 62 3b 0a 20 20 69 6e  gBuffer sb;.  in
8ad0: 74 20 69 3b 0a 0a 20 20 69 6e 69 74 53 74 72 69  t i;..  initStri
8ae0: 6e 67 42 75 66 66 65 72 28 26 73 62 29 3b 0a 20  ngBuffer(&sb);. 
8af0: 20 61 70 70 65 6e 64 28 26 73 62 2c 20 22 69 6e   append(&sb, "in
8b00: 73 65 72 74 20 69 6e 74 6f 20 25 5f 63 6f 6e 74  sert into %_cont
8b10: 65 6e 74 20 28 72 6f 77 69 64 2c 20 22 29 3b 0a  ent (rowid, ");.
8b20: 20 20 61 70 70 65 6e 64 4c 69 73 74 28 26 73 62    appendList(&sb
8b30: 2c 20 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 76 2d  , v->nColumn, v-
8b40: 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e  >azContentColumn
8b50: 29 3b 0a 20 20 61 70 70 65 6e 64 28 26 73 62 2c  );.  append(&sb,
8b60: 20 22 29 20 76 61 6c 75 65 73 20 28 3f 22 29 3b   ") values (?");
8b70: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 76 2d  .  for(i=0; i<v-
8b80: 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 0a 20  >nColumn; ++i). 
8b90: 20 20 20 61 70 70 65 6e 64 28 26 73 62 2c 20 22     append(&sb, "
8ba0: 2c 20 3f 22 29 3b 0a 20 20 61 70 70 65 6e 64 28  , ?");.  append(
8bb0: 26 73 62 2c 20 22 29 22 29 3b 0a 20 20 72 65 74  &sb, ")");.  ret
8bc0: 75 72 6e 20 73 62 2e 73 3b 0a 7d 0a 0a 2f 2a 20  urn sb.s;.}../* 
8bd0: 52 65 74 75 72 6e 20 61 20 64 79 6e 61 6d 69 63  Return a dynamic
8be0: 61 6c 6c 79 20 67 65 6e 65 72 61 74 65 64 20 73  ally generated s
8bf0: 74 61 74 65 6d 65 6e 74 20 6f 66 20 74 68 65 20  tatement of the 
8c00: 66 6f 72 6d 0a 20 2a 20 20 20 75 70 64 61 74 65  form. *   update
8c10: 20 25 5f 63 6f 6e 74 65 6e 74 20 73 65 74 20 5b   %_content set [
8c20: 63 6f 6c 5f 30 5d 20 3d 20 3f 2c 20 5b 63 6f 6c  col_0] = ?, [col
8c30: 5f 31 5d 20 3d 20 3f 2c 20 2e 2e 2e 0a 20 2a 20  _1] = ?, .... * 
8c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8c50: 20 20 20 77 68 65 72 65 20 72 6f 77 69 64 20 3d     where rowid =
8c60: 20 3f 0a 20 2a 2f 0a 73 74 61 74 69 63 20 63 6f   ?. */.static co
8c70: 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e 74 65 6e  nst char *conten
8c80: 74 55 70 64 61 74 65 53 74 61 74 65 6d 65 6e 74  tUpdateStatement
8c90: 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
8ca0: 76 29 7b 0a 20 20 53 74 72 69 6e 67 42 75 66 66  v){.  StringBuff
8cb0: 65 72 20 73 62 3b 0a 20 20 69 6e 74 20 69 3b 0a  er sb;.  int i;.
8cc0: 0a 20 20 69 6e 69 74 53 74 72 69 6e 67 42 75 66  .  initStringBuf
8cd0: 66 65 72 28 26 73 62 29 3b 0a 20 20 61 70 70 65  fer(&sb);.  appe
8ce0: 6e 64 28 26 73 62 2c 20 22 75 70 64 61 74 65 20  nd(&sb, "update 
8cf0: 25 5f 63 6f 6e 74 65 6e 74 20 73 65 74 20 22 29  %_content set ")
8d00: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 76  ;.  for(i=0; i<v
8d10: 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 20  ->nColumn; ++i) 
8d20: 7b 0a 20 20 20 20 69 66 28 20 69 3e 30 20 29 7b  {.    if( i>0 ){
8d30: 0a 20 20 20 20 20 20 61 70 70 65 6e 64 28 26 73  .      append(&s
8d40: 62 2c 20 22 2c 20 22 29 3b 0a 20 20 20 20 7d 0a  b, ", ");.    }.
8d50: 20 20 20 20 61 70 70 65 6e 64 28 26 73 62 2c 20      append(&sb, 
8d60: 76 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75  v->azContentColu
8d70: 6d 6e 5b 69 5d 29 3b 0a 20 20 20 20 61 70 70 65  mn[i]);.    appe
8d80: 6e 64 28 26 73 62 2c 20 22 20 3d 20 3f 22 29 3b  nd(&sb, " = ?");
8d90: 0a 20 20 7d 0a 20 20 61 70 70 65 6e 64 28 26 73  .  }.  append(&s
8da0: 62 2c 20 22 20 77 68 65 72 65 20 72 6f 77 69 64  b, " where rowid
8db0: 20 3d 20 3f 22 29 3b 0a 20 20 72 65 74 75 72 6e   = ?");.  return
8dc0: 20 73 62 2e 73 3b 0a 7d 0a 0a 2f 2a 20 50 75 74   sb.s;.}../* Put
8dd0: 73 20 61 20 66 72 65 73 68 6c 79 2d 70 72 65 70  s a freshly-prep
8de0: 61 72 65 64 20 73 74 61 74 65 6d 65 6e 74 20 64  ared statement d
8df0: 65 74 65 72 6d 69 6e 65 64 20 62 79 20 69 53 74  etermined by iSt
8e00: 6d 74 20 69 6e 20 2a 70 70 53 74 6d 74 2e 0a 2a  mt in *ppStmt..*
8e10: 2a 20 49 66 20 74 68 65 20 69 6e 64 69 63 61 74  * If the indicat
8e20: 65 64 20 73 74 61 74 65 6d 65 6e 74 20 68 61 73  ed statement has
8e30: 20 6e 65 76 65 72 20 62 65 65 6e 20 70 72 65 70   never been prep
8e40: 61 72 65 64 2c 20 69 74 20 69 73 20 70 72 65 70  ared, it is prep
8e50: 61 72 65 64 0a 2a 2a 20 61 6e 64 20 63 61 63 68  ared.** and cach
8e60: 65 64 2c 20 6f 74 68 65 72 77 69 73 65 20 74 68  ed, otherwise th
8e70: 65 20 63 61 63 68 65 64 20 76 65 72 73 69 6f 6e  e cached version
8e80: 20 69 73 20 72 65 73 65 74 2e 0a 2a 2f 0a 73 74   is reset..*/.st
8e90: 61 74 69 63 20 69 6e 74 20 73 71 6c 5f 67 65 74  atic int sql_get
8ea0: 5f 73 74 61 74 65 6d 65 6e 74 28 66 75 6c 6c 74  _statement(fullt
8eb0: 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 66 75 6c  ext_vtab *v, ful
8ec0: 6c 74 65 78 74 5f 73 74 61 74 65 6d 65 6e 74 20  ltext_statement 
8ed0: 69 53 74 6d 74 2c 0a 20 20 20 20 20 20 20 20 20  iStmt,.         
8ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ef0: 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74      sqlite3_stmt
8f00: 20 2a 2a 70 70 53 74 6d 74 29 7b 0a 20 20 61 73   **ppStmt){.  as
8f10: 73 65 72 74 28 20 69 53 74 6d 74 3c 4d 41 58 5f  sert( iStmt<MAX_
8f20: 53 54 4d 54 20 29 3b 0a 20 20 69 66 28 20 76 2d  STMT );.  if( v-
8f30: 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d  >pFulltextStatem
8f40: 65 6e 74 73 5b 69 53 74 6d 74 5d 3d 3d 4e 55 4c  ents[iStmt]==NUL
8f50: 4c 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63  L ){.    const c
8f60: 68 61 72 20 2a 7a 53 74 6d 74 3b 0a 20 20 20 20  har *zStmt;.    
8f70: 69 6e 74 20 72 63 3b 0a 20 20 20 20 73 77 69 74  int rc;.    swit
8f80: 63 68 28 20 69 53 74 6d 74 20 29 7b 0a 20 20 20  ch( iStmt ){.   
8f90: 20 20 20 63 61 73 65 20 43 4f 4e 54 45 4e 54 5f     case CONTENT_
8fa0: 49 4e 53 45 52 54 5f 53 54 4d 54 3a 0a 20 20 20  INSERT_STMT:.   
8fb0: 20 20 20 20 20 7a 53 74 6d 74 20 3d 20 63 6f 6e       zStmt = con
8fc0: 74 65 6e 74 49 6e 73 65 72 74 53 74 61 74 65 6d  tentInsertStatem
8fd0: 65 6e 74 28 76 29 3b 20 62 72 65 61 6b 3b 0a 20  ent(v); break;. 
8fe0: 20 20 20 20 20 63 61 73 65 20 43 4f 4e 54 45 4e       case CONTEN
8ff0: 54 5f 55 50 44 41 54 45 5f 53 54 4d 54 3a 0a 20  T_UPDATE_STMT:. 
9000: 20 20 20 20 20 20 20 7a 53 74 6d 74 20 3d 20 63         zStmt = c
9010: 6f 6e 74 65 6e 74 55 70 64 61 74 65 53 74 61 74  ontentUpdateStat
9020: 65 6d 65 6e 74 28 76 29 3b 20 62 72 65 61 6b 3b  ement(v); break;
9030: 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74 3a 0a  .      default:.
9040: 20 20 20 20 20 20 20 20 7a 53 74 6d 74 20 3d 20          zStmt = 
9050: 66 75 6c 6c 74 65 78 74 5f 7a 53 74 61 74 65 6d  fulltext_zStatem
9060: 65 6e 74 5b 69 53 74 6d 74 5d 3b 0a 20 20 20 20  ent[iStmt];.    
9070: 7d 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 5f 70  }.    rc = sql_p
9080: 72 65 70 61 72 65 28 76 2d 3e 64 62 2c 20 76 2d  repare(v->db, v-
9090: 3e 7a 44 62 2c 20 76 2d 3e 7a 4e 61 6d 65 2c 20  >zDb, v->zName, 
90a0: 26 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61  &v->pFulltextSta
90b0: 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 2c 0a  tements[iStmt],.
90c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
90d0: 20 20 20 20 20 20 20 20 20 7a 53 74 6d 74 29 3b           zStmt);
90e0: 0a 20 20 20 20 69 66 28 20 7a 53 74 6d 74 20 21  .    if( zStmt !
90f0: 3d 20 66 75 6c 6c 74 65 78 74 5f 7a 53 74 61 74  = fulltext_zStat
9100: 65 6d 65 6e 74 5b 69 53 74 6d 74 5d 29 20 66 72  ement[iStmt]) fr
9110: 65 65 28 28 76 6f 69 64 20 2a 29 20 7a 53 74 6d  ee((void *) zStm
9120: 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  t);.    if( rc!=
9130: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
9140: 72 6e 20 72 63 3b 0a 20 20 7d 20 65 6c 73 65 20  rn rc;.  } else 
9150: 7b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20 73  {.    int rc = s
9160: 71 6c 69 74 65 33 5f 72 65 73 65 74 28 76 2d 3e  qlite3_reset(v->
9170: 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d 65  pFulltextStateme
9180: 6e 74 73 5b 69 53 74 6d 74 5d 29 3b 0a 20 20 20  nts[iStmt]);.   
9190: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
91a0: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
91b0: 20 20 7d 0a 0a 20 20 2a 70 70 53 74 6d 74 20 3d    }..  *ppStmt =
91c0: 20 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61   v->pFulltextSta
91d0: 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 3b 0a  tements[iStmt];.
91e0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
91f0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 53 74 65 70 20 74  OK;.}../* Step t
9200: 68 65 20 69 6e 64 69 63 61 74 65 64 20 73 74 61  he indicated sta
9210: 74 65 6d 65 6e 74 2c 20 68 61 6e 64 6c 69 6e 67  tement, handling
9220: 20 65 72 72 6f 72 73 20 53 51 4c 49 54 45 5f 42   errors SQLITE_B
9230: 55 53 59 20 28 62 79 0a 2a 2a 20 72 65 74 72 79  USY (by.** retry
9240: 69 6e 67 29 20 61 6e 64 20 53 51 4c 49 54 45 5f  ing) and SQLITE_
9250: 53 43 48 45 4d 41 20 28 62 79 20 72 65 2d 70 72  SCHEMA (by re-pr
9260: 65 70 61 72 69 6e 67 20 61 6e 64 20 74 72 61 6e  eparing and tran
9270: 73 66 65 72 72 69 6e 67 0a 2a 2a 20 62 69 6e 64  sferring.** bind
9280: 69 6e 67 73 20 74 6f 20 74 68 65 20 6e 65 77 20  ings to the new 
9290: 73 74 61 74 65 6d 65 6e 74 29 2e 0a 2a 2a 20 54  statement)..** T
92a0: 4f 44 4f 28 61 64 61 6d 29 3a 20 57 65 20 73 68  ODO(adam): We sh
92b0: 6f 75 6c 64 20 65 78 74 65 6e 64 20 74 68 69 73  ould extend this
92c0: 20 66 75 6e 63 74 69 6f 6e 20 73 6f 20 74 68 61   function so tha
92d0: 74 20 69 74 20 63 61 6e 20 77 6f 72 6b 20 77 69  t it can work wi
92e0: 74 68 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74 73  th.** statements
92f0: 20 64 65 63 6c 61 72 65 64 20 6c 6f 63 61 6c 6c   declared locall
9300: 79 2c 20 6e 6f 74 20 6f 6e 6c 79 20 67 6c 6f 62  y, not only glob
9310: 61 6c 6c 79 20 63 61 63 68 65 64 20 73 74 61 74  ally cached stat
9320: 65 6d 65 6e 74 73 2e 0a 2a 2f 0a 73 74 61 74 69  ements..*/.stati
9330: 63 20 69 6e 74 20 73 71 6c 5f 73 74 65 70 5f 73  c int sql_step_s
9340: 74 61 74 65 6d 65 6e 74 28 66 75 6c 6c 74 65 78  tatement(fulltex
9350: 74 5f 76 74 61 62 20 2a 76 2c 20 66 75 6c 6c 74  t_vtab *v, fullt
9360: 65 78 74 5f 73 74 61 74 65 6d 65 6e 74 20 69 53  ext_statement iS
9370: 74 6d 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20  tmt,.           
9380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9390: 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20     sqlite3_stmt 
93a0: 2a 2a 70 70 53 74 6d 74 29 7b 0a 20 20 69 6e 74  **ppStmt){.  int
93b0: 20 72 63 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73   rc;.  sqlite3_s
93c0: 74 6d 74 20 2a 73 20 3d 20 2a 70 70 53 74 6d 74  tmt *s = *ppStmt
93d0: 3b 0a 20 20 61 73 73 65 72 74 28 20 69 53 74 6d  ;.  assert( iStm
93e0: 74 3c 4d 41 58 5f 53 54 4d 54 20 29 3b 0a 20 20  t<MAX_STMT );.  
93f0: 61 73 73 65 72 74 28 20 73 3d 3d 76 2d 3e 70 46  assert( s==v->pF
9400: 75 6c 6c 74 65 78 74 53 74 61 74 65 6d 65 6e 74  ulltextStatement
9410: 73 5b 69 53 74 6d 74 5d 20 29 3b 0a 0a 20 20 77  s[iStmt] );..  w
9420: 68 69 6c 65 28 20 28 72 63 3d 73 71 6c 69 74 65  hile( (rc=sqlite
9430: 33 5f 73 74 65 70 28 73 29 29 21 3d 53 51 4c 49  3_step(s))!=SQLI
9440: 54 45 5f 44 4f 4e 45 20 26 26 20 72 63 21 3d 53  TE_DONE && rc!=S
9450: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
9460: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
9470: 42 55 53 59 20 29 20 63 6f 6e 74 69 6e 75 65 3b  BUSY ) continue;
9480: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
9490: 49 54 45 5f 45 52 52 4f 52 20 29 20 72 65 74 75  ITE_ERROR ) retu
94a0: 72 6e 20 72 63 3b 0a 0a 20 20 20 20 2f 2a 20 49  rn rc;..    /* I
94b0: 66 20 61 6e 20 53 51 4c 49 54 45 5f 53 43 48 45  f an SQLITE_SCHE
94c0: 4d 41 20 65 72 72 6f 72 20 68 61 73 20 6f 63 63  MA error has occ
94d0: 75 72 72 65 64 2c 20 74 68 65 6e 20 66 69 6e 61  urred, then fina
94e0: 6c 69 7a 69 6e 67 20 74 68 69 73 0a 20 20 20 20  lizing this.    
94f0: 20 2a 20 73 74 61 74 65 6d 65 6e 74 20 69 73 20   * statement is 
9500: 67 6f 69 6e 67 20 74 6f 20 64 65 6c 65 74 65 20  going to delete 
9510: 74 68 65 20 66 75 6c 6c 74 65 78 74 5f 76 74 61  the fulltext_vta
9520: 62 20 73 74 72 75 63 74 75 72 65 2e 20 49 66 0a  b structure. If.
9530: 20 20 20 20 20 2a 20 74 68 65 20 73 74 61 74 65       * the state
9540: 6d 65 6e 74 20 6a 75 73 74 20 65 78 65 63 75 74  ment just execut
9550: 65 64 20 69 73 20 69 6e 20 74 68 65 20 70 46 75  ed is in the pFu
9560: 6c 6c 74 65 78 74 53 74 61 74 65 6d 65 6e 74 73  lltextStatements
9570: 5b 5d 0a 20 20 20 20 20 2a 20 61 72 72 61 79 2c  [].     * array,
9580: 20 69 74 20 77 69 6c 6c 20 62 65 20 66 69 6e 61   it will be fina
9590: 6c 69 7a 65 64 20 74 77 69 63 65 2e 20 53 6f 20  lized twice. So 
95a0: 72 65 6d 6f 76 65 20 69 74 20 62 65 66 6f 72 65  remove it before
95b0: 0a 20 20 20 20 20 2a 20 63 61 6c 6c 69 6e 67 20  .     * calling 
95c0: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
95d0: 28 29 2e 0a 20 20 20 20 20 2a 2f 0a 20 20 20 20  ()..     */.    
95e0: 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74  v->pFulltextStat
95f0: 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 20 3d 20  ements[iStmt] = 
9600: 4e 55 4c 4c 3b 0a 20 20 20 20 72 63 20 3d 20 73  NULL;.    rc = s
9610: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
9620: 73 29 3b 0a 20 20 20 20 62 72 65 61 6b 3b 0a 20  s);.    break;. 
9630: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
9640: 0a 20 65 72 72 3a 0a 20 20 73 71 6c 69 74 65 33  . err:.  sqlite3
9650: 5f 66 69 6e 61 6c 69 7a 65 28 73 29 3b 0a 20 20  _finalize(s);.  
9660: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
9670: 20 4c 69 6b 65 20 73 71 6c 5f 73 74 65 70 5f 73   Like sql_step_s
9680: 74 61 74 65 6d 65 6e 74 28 29 2c 20 62 75 74 20  tatement(), but 
9690: 63 6f 6e 76 65 72 74 20 53 51 4c 49 54 45 5f 44  convert SQLITE_D
96a0: 4f 4e 45 20 74 6f 20 53 51 4c 49 54 45 5f 4f 4b  ONE to SQLITE_OK
96b0: 2e 0a 2a 2a 20 55 73 65 66 75 6c 20 66 6f 72 20  ..** Useful for 
96c0: 73 74 61 74 65 6d 65 6e 74 73 20 6c 69 6b 65 20  statements like 
96d0: 55 50 44 41 54 45 2c 20 77 68 65 72 65 20 77 65  UPDATE, where we
96e0: 20 65 78 70 65 63 74 20 6e 6f 20 72 65 73 75 6c   expect no resul
96f0: 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ts..*/.static in
9700: 74 20 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74 65  t sql_single_ste
9710: 70 5f 73 74 61 74 65 6d 65 6e 74 28 66 75 6c 6c  p_statement(full
9720: 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 0a 20 20  text_vtab *v,.  
9730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9750: 20 20 20 66 75 6c 6c 74 65 78 74 5f 73 74 61 74     fulltext_stat
9760: 65 6d 65 6e 74 20 69 53 74 6d 74 2c 0a 20 20 20  ement iStmt,.   
9770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9790: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
97a0: 2a 70 70 53 74 6d 74 29 7b 0a 20 20 69 6e 74 20  *ppStmt){.  int 
97b0: 72 63 20 3d 20 73 71 6c 5f 73 74 65 70 5f 73 74  rc = sql_step_st
97c0: 61 74 65 6d 65 6e 74 28 76 2c 20 69 53 74 6d 74  atement(v, iStmt
97d0: 2c 20 70 70 53 74 6d 74 29 3b 0a 20 20 72 65 74  , ppStmt);.  ret
97e0: 75 72 6e 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f  urn (rc==SQLITE_
97f0: 44 4f 4e 45 29 20 3f 20 53 51 4c 49 54 45 5f 4f  DONE) ? SQLITE_O
9800: 4b 20 3a 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 69 6e  K : rc;.}../* in
9810: 73 65 72 74 20 69 6e 74 6f 20 25 5f 63 6f 6e 74  sert into %_cont
9820: 65 6e 74 20 28 72 6f 77 69 64 2c 20 2e 2e 2e 29  ent (rowid, ...)
9830: 20 76 61 6c 75 65 73 20 28 5b 72 6f 77 69 64 5d   values ([rowid]
9840: 2c 20 5b 70 56 61 6c 75 65 73 5d 29 20 2a 2f 0a  , [pValues]) */.
9850: 73 74 61 74 69 63 20 69 6e 74 20 63 6f 6e 74 65  static int conte
9860: 6e 74 5f 69 6e 73 65 72 74 28 66 75 6c 6c 74 65  nt_insert(fullte
9870: 78 74 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69  xt_vtab *v, sqli
9880: 74 65 33 5f 76 61 6c 75 65 20 2a 72 6f 77 69 64  te3_value *rowid
9890: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
98a0: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
98b0: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70 56 61 6c  te3_value **pVal
98c0: 75 65 73 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  ues){.  sqlite3_
98d0: 73 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74 20 69  stmt *s;.  int i
98e0: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c  ;.  int rc = sql
98f0: 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76  _get_statement(v
9900: 2c 20 43 4f 4e 54 45 4e 54 5f 49 4e 53 45 52 54  , CONTENT_INSERT
9910: 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66  _STMT, &s);.  if
9920: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
9930: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
9940: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e  rc = sqlite3_bin
9950: 64 5f 76 61 6c 75 65 28 73 2c 20 31 2c 20 72 6f  d_value(s, 1, ro
9960: 77 69 64 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  wid);.  if( rc!=
9970: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
9980: 72 6e 20 72 63 3b 0a 0a 20 20 66 6f 72 28 69 3d  rn rc;..  for(i=
9990: 30 3b 20 69 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 3b  0; i<v->nColumn;
99a0: 20 2b 2b 69 29 7b 0a 20 20 20 20 72 63 20 3d 20   ++i){.    rc = 
99b0: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c  sqlite3_bind_val
99c0: 75 65 28 73 2c 20 32 2b 69 2c 20 70 56 61 6c 75  ue(s, 2+i, pValu
99d0: 65 73 5b 69 5d 29 3b 0a 20 20 20 20 69 66 28 20  es[i]);.    if( 
99e0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
99f0: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a  return rc;.  }..
9a00: 20 20 72 65 74 75 72 6e 20 73 71 6c 5f 73 69 6e    return sql_sin
9a10: 67 6c 65 5f 73 74 65 70 5f 73 74 61 74 65 6d 65  gle_step_stateme
9a20: 6e 74 28 76 2c 20 43 4f 4e 54 45 4e 54 5f 49 4e  nt(v, CONTENT_IN
9a30: 53 45 52 54 5f 53 54 4d 54 2c 20 26 73 29 3b 0a  SERT_STMT, &s);.
9a40: 7d 0a 0a 2f 2a 20 75 70 64 61 74 65 20 25 5f 63  }../* update %_c
9a50: 6f 6e 74 65 6e 74 20 73 65 74 20 63 6f 6c 30 20  ontent set col0 
9a60: 3d 20 70 56 61 6c 75 65 73 5b 30 5d 2c 20 63 6f  = pValues[0], co
9a70: 6c 31 20 3d 20 70 56 61 6c 75 65 73 5b 31 5d 2c  l1 = pValues[1],
9a80: 20 2e 2e 2e 0a 20 2a 20 20 20 20 20 20 20 20 20   .... *         
9a90: 20 20 20 20 20 20 20 20 20 77 68 65 72 65 20 72           where r
9aa0: 6f 77 69 64 20 3d 20 5b 69 52 6f 77 69 64 5d 20  owid = [iRowid] 
9ab0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 63 6f  */.static int co
9ac0: 6e 74 65 6e 74 5f 75 70 64 61 74 65 28 66 75 6c  ntent_update(ful
9ad0: 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 73  ltext_vtab *v, s
9ae0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70  qlite3_value **p
9af0: 56 61 6c 75 65 73 2c 0a 20 20 20 20 20 20 20 20  Values,.        
9b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9b10: 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69    sqlite_int64 i
9b20: 52 6f 77 69 64 29 7b 0a 20 20 73 71 6c 69 74 65  Rowid){.  sqlite
9b30: 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74  3_stmt *s;.  int
9b40: 20 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73   i;.  int rc = s
9b50: 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74  ql_get_statement
9b60: 28 76 2c 20 43 4f 4e 54 45 4e 54 5f 55 50 44 41  (v, CONTENT_UPDA
9b70: 54 45 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20  TE_STMT, &s);.  
9b80: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
9b90: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
9ba0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 76 2d 3e    for(i=0; i<v->
9bb0: 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 7b 0a 20  nColumn; ++i){. 
9bc0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
9bd0: 62 69 6e 64 5f 76 61 6c 75 65 28 73 2c 20 31 2b  bind_value(s, 1+
9be0: 69 2c 20 70 56 61 6c 75 65 73 5b 69 5d 29 3b 0a  i, pValues[i]);.
9bf0: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
9c00: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
9c10: 63 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 73  c;.  }..  rc = s
9c20: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36  qlite3_bind_int6
9c30: 34 28 73 2c 20 31 2b 76 2d 3e 6e 43 6f 6c 75 6d  4(s, 1+v->nColum
9c40: 6e 2c 20 69 52 6f 77 69 64 29 3b 0a 20 20 69 66  n, iRowid);.  if
9c50: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
9c60: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
9c70: 72 65 74 75 72 6e 20 73 71 6c 5f 73 69 6e 67 6c  return sql_singl
9c80: 65 5f 73 74 65 70 5f 73 74 61 74 65 6d 65 6e 74  e_step_statement
9c90: 28 76 2c 20 43 4f 4e 54 45 4e 54 5f 55 50 44 41  (v, CONTENT_UPDA
9ca0: 54 45 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 7d 0a  TE_STMT, &s);.}.
9cb0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 72 65  .static void fre
9cc0: 65 53 74 72 69 6e 67 41 72 72 61 79 28 69 6e 74  eStringArray(int
9cd0: 20 6e 53 74 72 69 6e 67 2c 20 63 6f 6e 73 74 20   nString, const 
9ce0: 63 68 61 72 20 2a 2a 70 53 74 72 69 6e 67 29 7b  char **pString){
9cf0: 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 66 6f 72  .  int i;..  for
9d00: 20 28 69 3d 30 20 3b 20 69 20 3c 20 6e 53 74 72   (i=0 ; i < nStr
9d10: 69 6e 67 20 3b 20 2b 2b 69 29 20 7b 0a 20 20 20  ing ; ++i) {.   
9d20: 20 69 66 28 20 70 53 74 72 69 6e 67 5b 69 5d 21   if( pString[i]!
9d30: 3d 4e 55 4c 4c 20 29 20 66 72 65 65 28 28 76 6f  =NULL ) free((vo
9d40: 69 64 20 2a 29 20 70 53 74 72 69 6e 67 5b 69 5d  id *) pString[i]
9d50: 29 3b 0a 20 20 7d 0a 20 20 66 72 65 65 28 28 76  );.  }.  free((v
9d60: 6f 69 64 20 2a 29 20 70 53 74 72 69 6e 67 29 3b  oid *) pString);
9d70: 0a 7d 0a 0a 2f 2a 20 73 65 6c 65 63 74 20 2a 20  .}../* select * 
9d80: 66 72 6f 6d 20 25 5f 63 6f 6e 74 65 6e 74 20 77  from %_content w
9d90: 68 65 72 65 20 72 6f 77 69 64 20 3d 20 5b 69 52  here rowid = [iR
9da0: 6f 77 5d 0a 20 2a 20 54 68 65 20 63 61 6c 6c 65  ow]. * The calle
9db0: 72 20 6d 75 73 74 20 64 65 6c 65 74 65 20 74 68  r must delete th
9dc0: 65 20 72 65 74 75 72 6e 65 64 20 61 72 72 61 79  e returned array
9dd0: 20 61 6e 64 20 61 6c 6c 20 73 74 72 69 6e 67 73   and all strings
9de0: 20 69 6e 20 69 74 2e 0a 20 2a 20 6e 75 6c 6c 20   in it.. * null 
9df0: 66 69 65 6c 64 73 20 77 69 6c 6c 20 62 65 20 4e  fields will be N
9e00: 55 4c 4c 20 69 6e 20 74 68 65 20 72 65 74 75 72  ULL in the retur
9e10: 6e 65 64 20 61 72 72 61 79 2e 0a 20 2a 0a 20 2a  ned array.. *. *
9e20: 20 54 4f 44 4f 3a 20 50 65 72 68 61 70 73 20 77   TODO: Perhaps w
9e30: 65 20 73 68 6f 75 6c 64 20 72 65 74 75 72 6e 20  e should return 
9e40: 70 6f 69 6e 74 65 72 2f 6c 65 6e 67 74 68 20 73  pointer/length s
9e50: 74 72 69 6e 67 73 20 68 65 72 65 20 66 6f 72 20  trings here for 
9e60: 63 6f 6e 73 69 73 74 65 6e 63 79 0a 20 2a 20 77  consistency. * w
9e70: 69 74 68 20 6f 74 68 65 72 20 63 6f 64 65 20 77  ith other code w
9e80: 68 69 63 68 20 75 73 65 73 20 70 6f 69 6e 74 65  hich uses pointe
9e90: 72 2f 6c 65 6e 67 74 68 2e 20 2a 2f 0a 73 74 61  r/length. */.sta
9ea0: 74 69 63 20 69 6e 74 20 63 6f 6e 74 65 6e 74 5f  tic int content_
9eb0: 73 65 6c 65 63 74 28 66 75 6c 6c 74 65 78 74 5f  select(fulltext_
9ec0: 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f  vtab *v, sqlite_
9ed0: 69 6e 74 36 34 20 69 52 6f 77 2c 0a 20 20 20 20  int64 iRow,.    
9ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9ef0: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
9f00: 20 2a 2a 2a 70 56 61 6c 75 65 73 29 7b 0a 20 20   ***pValues){.  
9f10: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b  sqlite3_stmt *s;
9f20: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a  .  const char **
9f30: 76 61 6c 75 65 73 3b 0a 20 20 69 6e 74 20 69 3b  values;.  int i;
9f40: 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 2a 70  .  int rc;..  *p
9f50: 56 61 6c 75 65 73 20 3d 20 4e 55 4c 4c 3b 0a 0a  Values = NULL;..
9f60: 20 20 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73    rc = sql_get_s
9f70: 74 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f 4e 54  tatement(v, CONT
9f80: 45 4e 54 5f 53 45 4c 45 43 54 5f 53 54 4d 54 2c  ENT_SELECT_STMT,
9f90: 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63 21 3d   &s);.  if( rc!=
9fa0: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
9fb0: 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73  rn rc;..  rc = s
9fc0: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36  qlite3_bind_int6
9fd0: 34 28 73 2c 20 31 2c 20 69 52 6f 77 29 3b 0a 20  4(s, 1, iRow);. 
9fe0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
9ff0: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
a000: 0a 20 20 72 63 20 3d 20 73 71 6c 5f 73 74 65 70  .  rc = sql_step
a010: 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f  _statement(v, CO
a020: 4e 54 45 4e 54 5f 53 45 4c 45 43 54 5f 53 54 4d  NTENT_SELECT_STM
a030: 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63  T, &s);.  if( rc
a040: 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 20 72  !=SQLITE_ROW ) r
a050: 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 76 61 6c  eturn rc;..  val
a060: 75 65 73 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  ues = (const cha
a070: 72 20 2a 2a 29 20 6d 61 6c 6c 6f 63 28 76 2d 3e  r **) malloc(v->
a080: 6e 43 6f 6c 75 6d 6e 20 2a 20 73 69 7a 65 6f 66  nColumn * sizeof
a090: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 29 3b  (const char *));
a0a0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 76 2d  .  for(i=0; i<v-
a0b0: 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 7b 0a  >nColumn; ++i){.
a0c0: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
a0d0: 63 6f 6c 75 6d 6e 5f 74 79 70 65 28 73 2c 20 69  column_type(s, i
a0e0: 29 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29  )==SQLITE_NULL )
a0f0: 7b 0a 20 20 20 20 20 20 76 61 6c 75 65 73 5b 69  {.      values[i
a100: 5d 20 3d 20 4e 55 4c 4c 3b 0a 20 20 20 20 7d 65  ] = NULL;.    }e
a110: 6c 73 65 7b 0a 20 20 20 20 20 20 76 61 6c 75 65  lse{.      value
a120: 73 5b 69 5d 20 3d 20 73 74 72 69 6e 67 5f 64 75  s[i] = string_du
a130: 70 28 28 63 68 61 72 2a 29 73 71 6c 69 74 65 33  p((char*)sqlite3
a140: 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 73 2c 20  _column_text(s, 
a150: 69 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  i));.    }.  }..
a160: 20 20 2f 2a 20 57 65 20 65 78 70 65 63 74 20 6f    /* We expect o
a170: 6e 6c 79 20 6f 6e 65 20 72 6f 77 2e 20 20 57 65  nly one row.  We
a180: 20 6d 75 73 74 20 65 78 65 63 75 74 65 20 61 6e   must execute an
a190: 6f 74 68 65 72 20 73 71 6c 69 74 65 33 5f 73 74  other sqlite3_st
a1a0: 65 70 28 29 0a 20 20 20 2a 20 74 6f 20 63 6f 6d  ep().   * to com
a1b0: 70 6c 65 74 65 20 74 68 65 20 69 74 65 72 61 74  plete the iterat
a1c0: 69 6f 6e 3b 20 6f 74 68 65 72 77 69 73 65 20 74  ion; otherwise t
a1d0: 68 65 20 74 61 62 6c 65 20 77 69 6c 6c 20 72 65  he table will re
a1e0: 6d 61 69 6e 20 6c 6f 63 6b 65 64 2e 20 2a 2f 0a  main locked. */.
a1f0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73    rc = sqlite3_s
a200: 74 65 70 28 73 29 3b 0a 20 20 69 66 28 20 72 63  tep(s);.  if( rc
a210: 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29 7b  ==SQLITE_DONE ){
a220: 0a 20 20 20 20 2a 70 56 61 6c 75 65 73 20 3d 20  .    *pValues = 
a230: 76 61 6c 75 65 73 3b 0a 20 20 20 20 72 65 74 75  values;.    retu
a240: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20  rn SQLITE_OK;.  
a250: 7d 0a 0a 20 20 66 72 65 65 53 74 72 69 6e 67 41  }..  freeStringA
a260: 72 72 61 79 28 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c  rray(v->nColumn,
a270: 20 76 61 6c 75 65 73 29 3b 0a 20 20 72 65 74 75   values);.  retu
a280: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 64 65 6c  rn rc;.}../* del
a290: 65 74 65 20 66 72 6f 6d 20 25 5f 63 6f 6e 74 65  ete from %_conte
a2a0: 6e 74 20 77 68 65 72 65 20 72 6f 77 69 64 20 3d  nt where rowid =
a2b0: 20 5b 69 52 6f 77 20 5d 20 2a 2f 0a 73 74 61 74   [iRow ] */.stat
a2c0: 69 63 20 69 6e 74 20 63 6f 6e 74 65 6e 74 5f 64  ic int content_d
a2d0: 65 6c 65 74 65 28 66 75 6c 6c 74 65 78 74 5f 76  elete(fulltext_v
a2e0: 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f 69  tab *v, sqlite_i
a2f0: 6e 74 36 34 20 69 52 6f 77 29 7b 0a 20 20 73 71  nt64 iRow){.  sq
a300: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a 20  lite3_stmt *s;. 
a310: 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67 65   int rc = sql_ge
a320: 74 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 43  t_statement(v, C
a330: 4f 4e 54 45 4e 54 5f 44 45 4c 45 54 45 5f 53 54  ONTENT_DELETE_ST
a340: 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72  MT, &s);.  if( r
a350: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
a360: 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20  eturn rc;..  rc 
a370: 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69  = sqlite3_bind_i
a380: 6e 74 36 34 28 73 2c 20 31 2c 20 69 52 6f 77 29  nt64(s, 1, iRow)
a390: 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
a3a0: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
a3b0: 63 3b 0a 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  c;..  return sql
a3c0: 5f 73 69 6e 67 6c 65 5f 73 74 65 70 5f 73 74 61  _single_step_sta
a3d0: 74 65 6d 65 6e 74 28 76 2c 20 43 4f 4e 54 45 4e  tement(v, CONTEN
a3e0: 54 5f 44 45 4c 45 54 45 5f 53 54 4d 54 2c 20 26  T_DELETE_STMT, &
a3f0: 73 29 3b 0a 7d 0a 0a 2f 2a 20 73 65 6c 65 63 74  s);.}../* select
a400: 20 72 6f 77 69 64 2c 20 64 6f 63 6c 69 73 74 20   rowid, doclist 
a410: 66 72 6f 6d 20 25 5f 74 65 72 6d 0a 20 2a 20 20  from %_term. *  
a420: 77 68 65 72 65 20 74 65 72 6d 20 3d 20 5b 70 54  where term = [pT
a430: 65 72 6d 5d 20 61 6e 64 20 73 65 67 6d 65 6e 74  erm] and segment
a440: 20 3d 20 5b 69 53 65 67 6d 65 6e 74 5d 0a 20 2a   = [iSegment]. *
a450: 20 49 66 20 66 6f 75 6e 64 2c 20 72 65 74 75 72   If found, retur
a460: 6e 73 20 53 51 4c 49 54 45 5f 52 4f 57 3b 20 74  ns SQLITE_ROW; t
a470: 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 66  he caller must f
a480: 72 65 65 20 74 68 65 0a 20 2a 20 72 65 74 75 72  ree the. * retur
a490: 6e 65 64 20 64 6f 63 6c 69 73 74 2e 20 20 49 66  ned doclist.  If
a4a0: 20 6e 6f 20 72 6f 77 73 20 66 6f 75 6e 64 2c 20   no rows found, 
a4b0: 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 44  returns SQLITE_D
a4c0: 4f 4e 45 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69  ONE. */.static i
a4d0: 6e 74 20 74 65 72 6d 5f 73 65 6c 65 63 74 28 66  nt term_select(f
a4e0: 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c  ulltext_vtab *v,
a4f0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65   const char *pTe
a500: 72 6d 2c 20 69 6e 74 20 6e 54 65 72 6d 2c 0a 20  rm, int nTerm,. 
a510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a520: 20 20 20 20 20 20 69 6e 74 20 69 53 65 67 6d 65        int iSegme
a530: 6e 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  nt,.            
a540: 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
a550: 65 5f 69 6e 74 36 34 20 2a 72 6f 77 69 64 2c 20  e_int64 *rowid, 
a560: 44 6f 63 4c 69 73 74 20 2a 6f 75 74 29 7b 0a 20  DocList *out){. 
a570: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73   sqlite3_stmt *s
a580: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c  ;.  int rc = sql
a590: 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76  _get_statement(v
a5a0: 2c 20 54 45 52 4d 5f 53 45 4c 45 43 54 5f 53 54  , TERM_SELECT_ST
a5b0: 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72  MT, &s);.  if( r
a5c0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
a5d0: 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20  eturn rc;..  rc 
a5e0: 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74  = sqlite3_bind_t
a5f0: 65 78 74 28 73 2c 20 31 2c 20 70 54 65 72 6d 2c  ext(s, 1, pTerm,
a600: 20 6e 54 65 72 6d 2c 20 53 51 4c 49 54 45 5f 53   nTerm, SQLITE_S
a610: 54 41 54 49 43 29 3b 0a 20 20 69 66 28 20 72 63  TATIC);.  if( rc
a620: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
a630: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d  turn rc;..  rc =
a640: 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e   sqlite3_bind_in
a650: 74 28 73 2c 20 32 2c 20 69 53 65 67 6d 65 6e 74  t(s, 2, iSegment
a660: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
a670: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
a680: 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 5f  rc;..  rc = sql_
a690: 73 74 65 70 5f 73 74 61 74 65 6d 65 6e 74 28 76  step_statement(v
a6a0: 2c 20 54 45 52 4d 5f 53 45 4c 45 43 54 5f 53 54  , TERM_SELECT_ST
a6b0: 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72  MT, &s);.  if( r
a6c0: 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 20  c!=SQLITE_ROW ) 
a6d0: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 2a 72  return rc;..  *r
a6e0: 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 63  owid = sqlite3_c
a6f0: 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 73 2c 20 30  olumn_int64(s, 0
a700: 29 3b 0a 20 20 64 6f 63 4c 69 73 74 49 6e 69 74  );.  docListInit
a710: 28 6f 75 74 2c 20 44 4c 5f 44 45 46 41 55 4c 54  (out, DL_DEFAULT
a720: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
a730: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62  sqlite3_column_b
a740: 6c 6f 62 28 73 2c 20 31 29 2c 20 73 71 6c 69 74  lob(s, 1), sqlit
a750: 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28  e3_column_bytes(
a760: 73 2c 20 31 29 29 3b 0a 0a 20 20 2f 2a 20 57 65  s, 1));..  /* We
a770: 20 65 78 70 65 63 74 20 6f 6e 6c 79 20 6f 6e 65   expect only one
a780: 20 72 6f 77 2e 20 20 57 65 20 6d 75 73 74 20 65   row.  We must e
a790: 78 65 63 75 74 65 20 61 6e 6f 74 68 65 72 20 73  xecute another s
a7a0: 71 6c 69 74 65 33 5f 73 74 65 70 28 29 0a 20 20  qlite3_step().  
a7b0: 20 2a 20 74 6f 20 63 6f 6d 70 6c 65 74 65 20 74   * to complete t
a7c0: 68 65 20 69 74 65 72 61 74 69 6f 6e 3b 20 6f 74  he iteration; ot
a7d0: 68 65 72 77 69 73 65 20 74 68 65 20 74 61 62 6c  herwise the tabl
a7e0: 65 20 77 69 6c 6c 20 72 65 6d 61 69 6e 20 6c 6f  e will remain lo
a7f0: 63 6b 65 64 2e 20 2a 2f 0a 20 20 72 63 20 3d 20  cked. */.  rc = 
a800: 73 71 6c 69 74 65 33 5f 73 74 65 70 28 73 29 3b  sqlite3_step(s);
a810: 0a 20 20 72 65 74 75 72 6e 20 72 63 3d 3d 53 51  .  return rc==SQ
a820: 4c 49 54 45 5f 44 4f 4e 45 20 3f 20 53 51 4c 49  LITE_DONE ? SQLI
a830: 54 45 5f 52 4f 57 20 3a 20 72 63 3b 0a 7d 0a 0a  TE_ROW : rc;.}..
a840: 2f 2a 20 4c 6f 61 64 20 74 68 65 20 73 65 67 6d  /* Load the segm
a850: 65 6e 74 20 64 6f 63 6c 69 73 74 73 20 66 6f 72  ent doclists for
a860: 20 74 65 72 6d 20 70 54 65 72 6d 20 61 6e 64 20   term pTerm and 
a870: 6d 65 72 67 65 20 74 68 65 6d 20 69 6e 0a 2a 2a  merge them in.**
a880: 20 61 70 70 72 6f 70 72 69 61 74 65 20 6f 72 64   appropriate ord
a890: 65 72 20 69 6e 74 6f 20 6f 75 74 2e 20 20 52 65  er into out.  Re
a8a0: 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b 20  turns SQLITE_OK 
a8b0: 69 66 20 73 75 63 63 65 73 73 66 75 6c 2e 20 20  if successful.  
a8c0: 49 66 0a 2a 2a 20 74 68 65 72 65 20 61 72 65 20  If.** there are 
a8d0: 6e 6f 20 73 65 67 6d 65 6e 74 73 20 66 6f 72 20  no segments for 
a8e0: 70 54 65 72 6d 2c 20 73 75 63 63 65 73 73 66 75  pTerm, successfu
a8f0: 6c 6c 79 20 72 65 74 75 72 6e 73 20 61 6e 20 65  lly returns an e
a900: 6d 70 74 79 0a 2a 2a 20 64 6f 63 6c 69 73 74 20  mpty.** doclist 
a910: 69 6e 20 6f 75 74 2e 0a 2a 2a 0a 2a 2a 20 45 61  in out..**.** Ea
a920: 63 68 20 64 6f 63 75 6d 65 6e 74 20 63 6f 6e 73  ch document cons
a930: 69 73 74 73 20 6f 66 20 31 20 6f 72 20 6d 6f 72  ists of 1 or mor
a940: 65 20 22 63 6f 6c 75 6d 6e 73 22 2e 20 20 54 68  e "columns".  Th
a950: 65 20 6e 75 6d 62 65 72 20 6f 66 0a 2a 2a 20 63  e number of.** c
a960: 6f 6c 75 6d 6e 73 20 69 73 20 76 2d 3e 6e 43 6f  olumns is v->nCo
a970: 6c 75 6d 6e 2e 20 20 49 66 20 69 43 6f 6c 75 6d  lumn.  If iColum
a980: 6e 3d 3d 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 74  n==v->nColumn, t
a990: 68 65 6e 20 72 65 74 75 72 6e 0a 2a 2a 20 70 6f  hen return.** po
a9a0: 73 69 74 69 6f 6e 20 69 6e 66 6f 72 6d 61 74 69  sition informati
a9b0: 6f 6e 20 61 62 6f 75 74 20 61 6c 6c 20 63 6f 6c  on about all col
a9c0: 75 6d 6e 73 2e 20 20 49 66 20 69 43 6f 6c 75 6d  umns.  If iColum
a9d0: 6e 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 0a 2a 2a  n<v->nColumn,.**
a9e0: 20 74 68 65 6e 20 6f 6e 6c 79 20 72 65 74 75 72   then only retur
a9f0: 6e 20 70 6f 73 69 74 69 6f 6e 20 69 6e 66 6f 72  n position infor
aa00: 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 74 68 65  mation about the
aa10: 20 69 43 6f 6c 75 6d 6e 2d 74 68 20 63 6f 6c 75   iColumn-th colu
aa20: 6d 6e 0a 2a 2a 20 28 77 68 65 72 65 20 74 68 65  mn.** (where the
aa30: 20 66 69 72 73 74 20 63 6f 6c 75 6d 6e 20 69 73   first column is
aa40: 20 30 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69   0)..*/.static i
aa50: 6e 74 20 74 65 72 6d 5f 73 65 6c 65 63 74 5f 61  nt term_select_a
aa60: 6c 6c 28 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76  ll(.  fulltext_v
aa70: 74 61 62 20 2a 76 2c 20 20 20 20 20 2f 2a 20 54  tab *v,     /* T
aa80: 68 65 20 66 75 6c 6c 74 65 78 74 20 69 6e 64 65  he fulltext inde
aa90: 78 20 77 65 20 61 72 65 20 71 75 65 72 79 69 6e  x we are queryin
aaa0: 67 20 61 67 61 69 6e 73 74 20 2a 2f 0a 20 20 69  g against */.  i
aab0: 6e 74 20 69 43 6f 6c 75 6d 6e 2c 20 20 20 20 20  nt iColumn,     
aac0: 20 20 20 20 20 2f 2a 20 49 66 20 3c 6e 43 6f 6c       /* If <nCol
aad0: 75 6d 6e 2c 20 6f 6e 6c 79 20 6c 6f 6f 6b 20 61  umn, only look a
aae0: 74 20 74 68 65 20 69 43 6f 6c 75 6d 6e 2d 74 68  t the iColumn-th
aaf0: 20 63 6f 6c 75 6d 6e 20 2a 2f 0a 20 20 63 6f 6e   column */.  con
ab00: 73 74 20 63 68 61 72 20 2a 70 54 65 72 6d 2c 20  st char *pTerm, 
ab10: 20 20 20 2f 2a 20 54 68 65 20 74 65 72 6d 20 77     /* The term w
ab20: 68 6f 73 65 20 70 6f 73 74 69 6e 67 20 6c 69 73  hose posting lis
ab30: 74 73 20 77 65 20 77 61 6e 74 20 2a 2f 0a 20 20  ts we want */.  
ab40: 69 6e 74 20 6e 54 65 72 6d 2c 20 20 20 20 20 20  int nTerm,      
ab50: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
ab60: 6f 66 20 62 79 74 65 73 20 69 6e 20 70 54 65 72  of bytes in pTer
ab70: 6d 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20 2a  m */.  DocList *
ab80: 6f 75 74 20 20 20 20 20 20 20 20 20 20 2f 2a 20  out          /* 
ab90: 57 72 69 74 65 20 74 68 65 20 72 65 73 75 6c 74  Write the result
aba0: 69 6e 67 20 64 6f 63 6c 69 73 74 20 68 65 72 65  ing doclist here
abb0: 20 2a 2f 0a 29 7b 0a 20 20 44 6f 63 4c 69 73 74   */.){.  DocList
abc0: 20 64 6f 63 6c 69 73 74 3b 0a 20 20 73 71 6c 69   doclist;.  sqli
abd0: 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20 69  te3_stmt *s;.  i
abe0: 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f  nt rc = sql_get_
abf0: 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 54 45 52  statement(v, TER
ac00: 4d 5f 53 45 4c 45 43 54 5f 41 4c 4c 5f 53 54 4d  M_SELECT_ALL_STM
ac10: 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63  T, &s);.  if( rc
ac20: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
ac30: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d  turn rc;..  rc =
ac40: 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65   sqlite3_bind_te
ac50: 78 74 28 73 2c 20 31 2c 20 70 54 65 72 6d 2c 20  xt(s, 1, pTerm, 
ac60: 6e 54 65 72 6d 2c 20 53 51 4c 49 54 45 5f 53 54  nTerm, SQLITE_ST
ac70: 41 54 49 43 29 3b 0a 20 20 69 66 28 20 72 63 21  ATIC);.  if( rc!
ac80: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
ac90: 75 72 6e 20 72 63 3b 0a 0a 20 20 64 6f 63 4c 69  urn rc;..  docLi
aca0: 73 74 49 6e 69 74 28 26 64 6f 63 6c 69 73 74 2c  stInit(&doclist,
acb0: 20 44 4c 5f 44 45 46 41 55 4c 54 2c 20 30 2c 20   DL_DEFAULT, 0, 
acc0: 30 29 3b 0a 0a 20 20 2f 2a 20 54 4f 44 4f 28 73  0);..  /* TODO(s
acd0: 68 65 73 73 29 20 48 61 6e 64 6c 65 20 73 63 68  hess) Handle sch
ace0: 65 6d 61 20 61 6e 64 20 62 75 73 79 20 65 72 72  ema and busy err
acf0: 6f 72 73 2e 20 2a 2f 0a 20 20 77 68 69 6c 65 28  ors. */.  while(
ad00: 20 28 72 63 3d 73 71 6c 5f 73 74 65 70 5f 73 74   (rc=sql_step_st
ad10: 61 74 65 6d 65 6e 74 28 76 2c 20 54 45 52 4d 5f  atement(v, TERM_
ad20: 53 45 4c 45 43 54 5f 41 4c 4c 5f 53 54 4d 54 2c  SELECT_ALL_STMT,
ad30: 20 26 73 29 29 3d 3d 53 51 4c 49 54 45 5f 52 4f   &s))==SQLITE_RO
ad40: 57 20 29 7b 0a 20 20 20 20 44 6f 63 4c 69 73 74  W ){.    DocList
ad50: 20 6f 6c 64 3b 0a 0a 20 20 20 20 2f 2a 20 54 4f   old;..    /* TO
ad60: 44 4f 28 73 68 65 73 73 29 20 49 66 20 77 65 20  DO(shess) If we 
ad70: 70 72 6f 63 65 73 73 65 64 20 64 6f 63 6c 69 73  processed doclis
ad80: 74 73 20 66 72 6f 6d 20 6f 6c 64 65 73 74 20 74  ts from oldest t
ad90: 6f 20 6e 65 77 65 73 74 2c 20 77 65 0a 20 20 20  o newest, we.   
ada0: 20 2a 2a 20 63 6f 75 6c 64 20 73 6b 69 70 20 74   ** could skip t
adb0: 68 65 20 6d 61 6c 6c 6f 63 28 29 20 69 6e 76 6f  he malloc() invo
adc0: 6c 76 65 64 20 77 69 74 68 20 74 68 65 20 66 6f  lved with the fo
add0: 6c 6c 6f 77 69 6e 67 20 63 61 6c 6c 2e 20 20 46  llowing call.  F
ade0: 6f 72 0a 20 20 20 20 2a 2a 20 6e 6f 77 2c 20 49  or.    ** now, I
adf0: 27 64 20 72 61 74 68 65 72 20 6b 65 65 70 20 74  'd rather keep t
ae00: 68 69 73 20 6c 6f 67 69 63 20 73 69 6d 69 6c 61  his logic simila
ae10: 72 20 74 6f 20 69 6e 64 65 78 5f 69 6e 73 65 72  r to index_inser
ae20: 74 5f 74 65 72 6d 28 29 2e 0a 20 20 20 20 2a 2a  t_term()..    **
ae30: 20 57 65 20 63 6f 75 6c 64 20 61 64 64 69 74 69   We could additi
ae40: 6f 6e 61 6c 6c 79 20 64 72 6f 70 20 65 6c 65 6d  onally drop elem
ae50: 65 6e 74 73 20 77 68 65 6e 20 77 65 20 73 65 65  ents when we see
ae60: 20 64 65 6c 65 74 65 73 2c 20 62 75 74 0a 20 20   deletes, but.  
ae70: 20 20 2a 2a 20 74 68 61 74 20 77 6f 75 6c 64 20    ** that would 
ae80: 72 65 71 75 69 72 65 20 61 20 64 69 73 74 69 6e  require a distin
ae90: 63 74 20 76 65 72 73 69 6f 6e 20 6f 66 20 64 6f  ct version of do
aea0: 63 4c 69 73 74 41 63 63 75 6d 75 6c 61 74 65 28  cListAccumulate(
aeb0: 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 64 6f  )..    */.    do
aec0: 63 4c 69 73 74 49 6e 69 74 28 26 6f 6c 64 2c 20  cListInit(&old, 
aed0: 44 4c 5f 44 45 46 41 55 4c 54 2c 0a 20 20 20 20  DL_DEFAULT,.    
aee0: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
aef0: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28  te3_column_blob(
af00: 73 2c 20 30 29 2c 20 73 71 6c 69 74 65 33 5f 63  s, 0), sqlite3_c
af10: 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 73 2c 20 30  olumn_bytes(s, 0
af20: 29 29 3b 0a 0a 20 20 20 20 69 66 28 20 69 43 6f  ));..    if( iCo
af30: 6c 75 6d 6e 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 20  lumn<v->nColumn 
af40: 29 7b 20 20 20 2f 2a 20 71 75 65 72 79 69 6e 67  ){   /* querying
af50: 20 61 20 73 69 6e 67 6c 65 20 63 6f 6c 75 6d 6e   a single column
af60: 20 2a 2f 0a 20 20 20 20 20 20 64 6f 63 4c 69 73   */.      docLis
af70: 74 52 65 73 74 72 69 63 74 43 6f 6c 75 6d 6e 28  tRestrictColumn(
af80: 26 6f 6c 64 2c 20 69 43 6f 6c 75 6d 6e 29 3b 0a  &old, iColumn);.
af90: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 64 6f      }..    /* do
afa0: 63 6c 69 73 74 20 63 6f 6e 74 61 69 6e 73 20 74  clist contains t
afb0: 68 65 20 6e 65 77 65 72 20 64 61 74 61 2c 20 73  he newer data, s
afc0: 6f 20 77 72 69 74 65 20 69 74 20 6f 76 65 72 20  o write it over 
afd0: 6f 6c 64 2e 20 20 54 68 65 6e 0a 20 20 20 20 2a  old.  Then.    *
afe0: 2a 20 73 74 65 61 6c 20 61 63 63 75 6d 75 6c 61  * steal accumula
aff0: 74 65 64 20 72 65 73 75 6c 74 20 66 6f 72 20 64  ted result for d
b000: 6f 63 6c 69 73 74 2e 0a 20 20 20 20 2a 2f 0a 20  oclist..    */. 
b010: 20 20 20 64 6f 63 4c 69 73 74 41 63 63 75 6d 75     docListAccumu
b020: 6c 61 74 65 28 26 6f 6c 64 2c 20 26 64 6f 63 6c  late(&old, &docl
b030: 69 73 74 29 3b 0a 20 20 20 20 64 6f 63 4c 69 73  ist);.    docLis
b040: 74 44 65 73 74 72 6f 79 28 26 64 6f 63 6c 69 73  tDestroy(&doclis
b050: 74 29 3b 0a 20 20 20 20 64 6f 63 6c 69 73 74 20  t);.    doclist 
b060: 3d 20 6f 6c 64 3b 0a 20 20 7d 0a 20 20 69 66 28  = old;.  }.  if(
b070: 20 72 63 21 3d 53 51 4c 49 54 45 5f 44 4f 4e 45   rc!=SQLITE_DONE
b080: 20 29 7b 0a 20 20 20 20 64 6f 63 4c 69 73 74 44   ){.    docListD
b090: 65 73 74 72 6f 79 28 26 64 6f 63 6c 69 73 74 29  estroy(&doclist)
b0a0: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  ;.    return rc;
b0b0: 0a 20 20 7d 0a 0a 20 20 64 6f 63 4c 69 73 74 44  .  }..  docListD
b0c0: 69 73 63 61 72 64 45 6d 70 74 79 28 26 64 6f 63  iscardEmpty(&doc
b0d0: 6c 69 73 74 29 3b 0a 20 20 2a 6f 75 74 20 3d 20  list);.  *out = 
b0e0: 64 6f 63 6c 69 73 74 3b 0a 20 20 72 65 74 75 72  doclist;.  retur
b0f0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
b100: 2f 2a 20 69 6e 73 65 72 74 20 69 6e 74 6f 20 25  /* insert into %
b110: 5f 74 65 72 6d 20 28 72 6f 77 69 64 2c 20 74 65  _term (rowid, te
b120: 72 6d 2c 20 73 65 67 6d 65 6e 74 2c 20 64 6f 63  rm, segment, doc
b130: 6c 69 73 74 29 0a 20 20 20 20 20 20 20 20 20 20  list).          
b140: 20 20 20 20 20 76 61 6c 75 65 73 20 28 5b 70 69       values ([pi
b150: 52 6f 77 69 64 5d 2c 20 5b 70 54 65 72 6d 5d 2c  Rowid], [pTerm],
b160: 20 5b 69 53 65 67 6d 65 6e 74 5d 2c 20 5b 64 6f   [iSegment], [do
b170: 63 6c 69 73 74 5d 29 0a 2a 2a 20 4c 65 74 73 20  clist]).** Lets 
b180: 73 71 6c 69 74 65 20 73 65 6c 65 63 74 20 72 6f  sqlite select ro
b190: 77 69 64 20 69 66 20 70 69 52 6f 77 69 64 20 69  wid if piRowid i
b1a0: 73 20 4e 55 4c 4c 2c 20 65 6c 73 65 20 75 73 65  s NULL, else use
b1b0: 73 20 2a 70 69 52 6f 77 69 64 2e 0a 2a 2a 0a 2a  s *piRowid..**.*
b1c0: 2a 20 4e 4f 54 45 28 73 68 65 73 73 29 20 70 69  * NOTE(shess) pi
b1d0: 52 6f 77 69 64 20 69 73 20 49 4e 2c 20 77 69 74  Rowid is IN, wit
b1e0: 68 20 76 61 6c 75 65 73 20 6f 66 20 22 73 70 61  h values of "spa
b1f0: 63 65 20 6f 66 20 69 6e 74 36 34 22 20 70 6c 75  ce of int64" plu
b200: 73 0a 2a 2a 20 6e 75 6c 6c 2c 20 69 74 20 69 73  s.** null, it is
b210: 20 6e 6f 74 20 75 73 65 64 20 74 6f 20 70 61 73   not used to pas
b220: 73 20 64 61 74 61 20 62 61 63 6b 20 74 6f 20 74  s data back to t
b230: 68 65 20 63 61 6c 6c 65 72 2e 0a 2a 2f 0a 73 74  he caller..*/.st
b240: 61 74 69 63 20 69 6e 74 20 74 65 72 6d 5f 69 6e  atic int term_in
b250: 73 65 72 74 28 66 75 6c 6c 74 65 78 74 5f 76 74  sert(fulltext_vt
b260: 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f 69 6e  ab *v, sqlite_in
b270: 74 36 34 20 2a 70 69 52 6f 77 69 64 2c 0a 20 20  t64 *piRowid,.  
b280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b290: 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20       const char 
b2a0: 2a 70 54 65 72 6d 2c 20 69 6e 74 20 6e 54 65 72  *pTerm, int nTer
b2b0: 6d 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  m,.             
b2c0: 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 69 53            int iS
b2d0: 65 67 6d 65 6e 74 2c 20 44 6f 63 4c 69 73 74 20  egment, DocList 
b2e0: 2a 64 6f 63 6c 69 73 74 29 7b 0a 20 20 73 71 6c  *doclist){.  sql
b2f0: 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20  ite3_stmt *s;.  
b300: 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67 65 74  int rc = sql_get
b310: 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 54 45  _statement(v, TE
b320: 52 4d 5f 49 4e 53 45 52 54 5f 53 54 4d 54 2c 20  RM_INSERT_STMT, 
b330: 26 73 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  &s);.  if( rc!=S
b340: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
b350: 6e 20 72 63 3b 0a 0a 20 20 69 66 28 20 70 69 52  n rc;..  if( piR
b360: 6f 77 69 64 3d 3d 4e 55 4c 4c 20 29 7b 0a 20 20  owid==NULL ){.  
b370: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62    rc = sqlite3_b
b380: 69 6e 64 5f 6e 75 6c 6c 28 73 2c 20 31 29 3b 0a  ind_null(s, 1);.
b390: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20    }else{.    rc 
b3a0: 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69  = sqlite3_bind_i
b3b0: 6e 74 36 34 28 73 2c 20 31 2c 20 2a 70 69 52 6f  nt64(s, 1, *piRo
b3c0: 77 69 64 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  wid);.  }.  if( 
b3d0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
b3e0: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63  return rc;..  rc
b3f0: 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   = sqlite3_bind_
b400: 74 65 78 74 28 73 2c 20 32 2c 20 70 54 65 72 6d  text(s, 2, pTerm
b410: 2c 20 6e 54 65 72 6d 2c 20 53 51 4c 49 54 45 5f  , nTerm, SQLITE_
b420: 53 54 41 54 49 43 29 3b 0a 20 20 69 66 28 20 72  STATIC);.  if( r
b430: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
b440: 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20  eturn rc;..  rc 
b450: 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69  = sqlite3_bind_i
b460: 6e 74 28 73 2c 20 33 2c 20 69 53 65 67 6d 65 6e  nt(s, 3, iSegmen
b470: 74 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  t);.  if( rc!=SQ
b480: 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
b490: 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c   rc;..  rc = sql
b4a0: 69 74 65 33 5f 62 69 6e 64 5f 62 6c 6f 62 28 73  ite3_bind_blob(s
b4b0: 2c 20 34 2c 20 64 6f 63 6c 69 73 74 2d 3e 70 44  , 4, doclist->pD
b4c0: 61 74 61 2c 20 64 6f 63 6c 69 73 74 2d 3e 6e 44  ata, doclist->nD
b4d0: 61 74 61 2c 20 53 51 4c 49 54 45 5f 53 54 41 54  ata, SQLITE_STAT
b4e0: 49 43 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  IC);.  if( rc!=S
b4f0: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
b500: 6e 20 72 63 3b 0a 0a 20 20 72 65 74 75 72 6e 20  n rc;..  return 
b510: 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74 65 70 5f  sql_single_step_
b520: 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 54 45 52  statement(v, TER
b530: 4d 5f 49 4e 53 45 52 54 5f 53 54 4d 54 2c 20 26  M_INSERT_STMT, &
b540: 73 29 3b 0a 7d 0a 0a 2f 2a 20 75 70 64 61 74 65  s);.}../* update
b550: 20 25 5f 74 65 72 6d 20 73 65 74 20 64 6f 63 6c   %_term set docl
b560: 69 73 74 20 3d 20 5b 64 6f 63 6c 69 73 74 5d 20  ist = [doclist] 
b570: 77 68 65 72 65 20 72 6f 77 69 64 20 3d 20 5b 72  where rowid = [r
b580: 6f 77 69 64 5d 20 2a 2f 0a 73 74 61 74 69 63 20  owid] */.static 
b590: 69 6e 74 20 74 65 72 6d 5f 75 70 64 61 74 65 28  int term_update(
b5a0: 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
b5b0: 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 72  , sqlite_int64 r
b5c0: 6f 77 69 64 2c 0a 20 20 20 20 20 20 20 20 20 20  owid,.          
b5d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 44 6f 63               Doc
b5e0: 4c 69 73 74 20 2a 64 6f 63 6c 69 73 74 29 7b 0a  List *doclist){.
b5f0: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
b600: 73 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71  s;.  int rc = sq
b610: 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28  l_get_statement(
b620: 76 2c 20 54 45 52 4d 5f 55 50 44 41 54 45 5f 53  v, TERM_UPDATE_S
b630: 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20  TMT, &s);.  if( 
b640: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
b650: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63  return rc;..  rc
b660: 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   = sqlite3_bind_
b670: 62 6c 6f 62 28 73 2c 20 31 2c 20 64 6f 63 6c 69  blob(s, 1, docli
b680: 73 74 2d 3e 70 44 61 74 61 2c 20 64 6f 63 6c 69  st->pData, docli
b690: 73 74 2d 3e 6e 44 61 74 61 2c 20 53 51 4c 49 54  st->nData, SQLIT
b6a0: 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 69 66 28  E_STATIC);.  if(
b6b0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
b6c0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72   return rc;..  r
b6d0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
b6e0: 5f 69 6e 74 36 34 28 73 2c 20 32 2c 20 72 6f 77  _int64(s, 2, row
b6f0: 69 64 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  id);.  if( rc!=S
b700: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
b710: 6e 20 72 63 3b 0a 0a 20 20 72 65 74 75 72 6e 20  n rc;..  return 
b720: 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74 65 70 5f  sql_single_step_
b730: 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 54 45 52  statement(v, TER
b740: 4d 5f 55 50 44 41 54 45 5f 53 54 4d 54 2c 20 26  M_UPDATE_STMT, &
b750: 73 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  s);.}..static in
b760: 74 20 74 65 72 6d 5f 64 65 6c 65 74 65 28 66 75  t term_delete(fu
b770: 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20  lltext_vtab *v, 
b780: 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 72 6f 77  sqlite_int64 row
b790: 69 64 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73  id){.  sqlite3_s
b7a0: 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74 20 72 63  tmt *s;.  int rc
b7b0: 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74 61 74 65   = sql_get_state
b7c0: 6d 65 6e 74 28 76 2c 20 54 45 52 4d 5f 44 45 4c  ment(v, TERM_DEL
b7d0: 45 54 45 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20  ETE_STMT, &s);. 
b7e0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
b7f0: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
b800: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
b810: 62 69 6e 64 5f 69 6e 74 36 34 28 73 2c 20 31 2c  bind_int64(s, 1,
b820: 20 72 6f 77 69 64 29 3b 0a 20 20 69 66 28 20 72   rowid);.  if( r
b830: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
b840: 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 65 74  eturn rc;..  ret
b850: 75 72 6e 20 73 71 6c 5f 73 69 6e 67 6c 65 5f 73  urn sql_single_s
b860: 74 65 70 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c  tep_statement(v,
b870: 20 54 45 52 4d 5f 44 45 4c 45 54 45 5f 53 54 4d   TERM_DELETE_STM
b880: 54 2c 20 26 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  T, &s);.}../*.**
b890: 20 46 72 65 65 20 74 68 65 20 6d 65 6d 6f 72 79   Free the memory
b8a0: 20 75 73 65 64 20 74 6f 20 63 6f 6e 74 61 69 6e   used to contain
b8b0: 20 61 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62   a fulltext_vtab
b8c0: 20 73 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 73   structure..*/.s
b8d0: 74 61 74 69 63 20 76 6f 69 64 20 66 75 6c 6c 74  tatic void fullt
b8e0: 65 78 74 5f 76 74 61 62 5f 64 65 73 74 72 6f 79  ext_vtab_destroy
b8f0: 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
b900: 76 29 7b 0a 20 20 69 6e 74 20 69 53 74 6d 74 2c  v){.  int iStmt,
b910: 20 69 3b 0a 0a 20 20 54 52 41 43 45 28 28 22 46   i;..  TRACE(("F
b920: 54 53 31 20 44 65 73 74 72 6f 79 20 25 70 5c 6e  TS1 Destroy %p\n
b930: 22 2c 20 76 29 29 3b 0a 20 20 66 6f 72 28 20 69  ", v));.  for( i
b940: 53 74 6d 74 3d 30 3b 20 69 53 74 6d 74 3c 4d 41  Stmt=0; iStmt<MA
b950: 58 5f 53 54 4d 54 3b 20 69 53 74 6d 74 2b 2b 20  X_STMT; iStmt++ 
b960: 29 7b 0a 20 20 20 20 69 66 28 20 76 2d 3e 70 46  ){.    if( v->pF
b970: 75 6c 6c 74 65 78 74 53 74 61 74 65 6d 65 6e 74  ulltextStatement
b980: 73 5b 69 53 74 6d 74 5d 21 3d 4e 55 4c 4c 20 29  s[iStmt]!=NULL )
b990: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
b9a0: 66 69 6e 61 6c 69 7a 65 28 76 2d 3e 70 46 75 6c  finalize(v->pFul
b9b0: 6c 74 65 78 74 53 74 61 74 65 6d 65 6e 74 73 5b  ltextStatements[
b9c0: 69 53 74 6d 74 5d 29 3b 0a 20 20 20 20 20 20 76  iStmt]);.      v
b9d0: 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65  ->pFulltextState
b9e0: 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 20 3d 20 4e  ments[iStmt] = N
b9f0: 55 4c 4c 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ULL;.    }.  }..
ba00: 20 20 69 66 28 20 76 2d 3e 70 54 6f 6b 65 6e 69    if( v->pTokeni
ba10: 7a 65 72 21 3d 4e 55 4c 4c 20 29 7b 0a 20 20 20  zer!=NULL ){.   
ba20: 20 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e   v->pTokenizer->
ba30: 70 4d 6f 64 75 6c 65 2d 3e 78 44 65 73 74 72 6f  pModule->xDestro
ba40: 79 28 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72 29  y(v->pTokenizer)
ba50: 3b 0a 20 20 20 20 76 2d 3e 70 54 6f 6b 65 6e 69  ;.    v->pTokeni
ba60: 7a 65 72 20 3d 20 4e 55 4c 4c 3b 0a 20 20 7d 0a  zer = NULL;.  }.
ba70: 20 20 0a 20 20 66 72 65 65 28 76 2d 3e 61 7a 43    .  free(v->azC
ba80: 6f 6c 75 6d 6e 29 3b 0a 20 20 66 6f 72 28 69 20  olumn);.  for(i 
ba90: 3d 20 30 3b 20 69 20 3c 20 76 2d 3e 6e 43 6f 6c  = 0; i < v->nCol
baa0: 75 6d 6e 3b 20 2b 2b 69 29 20 7b 0a 20 20 20 20  umn; ++i) {.    
bab0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 76 2d 3e  sqlite3_free(v->
bac0: 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 5b  azContentColumn[
bad0: 69 5d 29 3b 0a 20 20 7d 0a 20 20 66 72 65 65 28  i]);.  }.  free(
bae0: 76 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75  v->azContentColu
baf0: 6d 6e 29 3b 0a 20 20 66 72 65 65 28 76 29 3b 0a  mn);.  free(v);.
bb00: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e 20 74  }../*.** Token t
bb10: 79 70 65 73 20 66 6f 72 20 70 61 72 73 69 6e 67  ypes for parsing
bb20: 20 74 68 65 20 61 72 67 75 6d 65 6e 74 73 20 74   the arguments t
bb30: 6f 20 78 43 6f 6e 6e 65 63 74 20 6f 72 20 78 43  o xConnect or xC
bb40: 72 65 61 74 65 2e 0a 2a 2f 0a 23 64 65 66 69 6e  reate..*/.#defin
bb50: 65 20 54 4f 4b 45 4e 5f 45 4f 46 20 20 20 20 20  e TOKEN_EOF     
bb60: 20 20 20 20 30 20 20 20 20 2f 2a 20 45 6e 64 20      0    /* End 
bb70: 6f 66 20 66 69 6c 65 20 2a 2f 0a 23 64 65 66 69  of file */.#defi
bb80: 6e 65 20 54 4f 4b 45 4e 5f 53 50 41 43 45 20 20  ne TOKEN_SPACE  
bb90: 20 20 20 20 20 31 20 20 20 20 2f 2a 20 41 6e 79       1    /* Any
bba0: 20 6b 69 6e 64 20 6f 66 20 77 68 69 74 65 73 70   kind of whitesp
bbb0: 61 63 65 20 2a 2f 0a 23 64 65 66 69 6e 65 20 54  ace */.#define T
bbc0: 4f 4b 45 4e 5f 49 44 20 20 20 20 20 20 20 20 20  OKEN_ID         
bbd0: 20 32 20 20 20 20 2f 2a 20 41 6e 20 69 64 65 6e   2    /* An iden
bbe0: 74 69 66 69 65 72 20 2a 2f 0a 23 64 65 66 69 6e  tifier */.#defin
bbf0: 65 20 54 4f 4b 45 4e 5f 53 54 52 49 4e 47 20 20  e TOKEN_STRING  
bc00: 20 20 20 20 33 20 20 20 20 2f 2a 20 41 20 73 74      3    /* A st
bc10: 72 69 6e 67 20 6c 69 74 65 72 61 6c 20 2a 2f 0a  ring literal */.
bc20: 23 64 65 66 69 6e 65 20 54 4f 4b 45 4e 5f 50 55  #define TOKEN_PU
bc30: 4e 43 54 20 20 20 20 20 20 20 34 20 20 20 20 2f  NCT       4    /
bc40: 2a 20 41 20 73 69 6e 67 6c 65 20 70 75 6e 63 74  * A single punct
bc50: 75 61 74 69 6f 6e 20 63 68 61 72 61 63 74 65 72  uation character
bc60: 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 58 20   */../*.** If X 
bc70: 69 73 20 61 20 63 68 61 72 61 63 74 65 72 20 74  is a character t
bc80: 68 61 74 20 63 61 6e 20 62 65 20 75 73 65 64 20  hat can be used 
bc90: 69 6e 20 61 6e 20 69 64 65 6e 74 69 66 69 65 72  in an identifier
bca0: 20 74 68 65 6e 0a 2a 2a 20 49 64 43 68 61 72 28   then.** IdChar(
bcb0: 58 29 20 77 69 6c 6c 20 62 65 20 74 72 75 65 2e  X) will be true.
bcc0: 20 20 4f 74 68 65 72 77 69 73 65 20 69 74 20 69    Otherwise it i
bcd0: 73 20 66 61 6c 73 65 2e 0a 2a 2a 0a 2a 2a 20 46  s false..**.** F
bce0: 6f 72 20 41 53 43 49 49 2c 20 61 6e 79 20 63 68  or ASCII, any ch
bcf0: 61 72 61 63 74 65 72 20 77 69 74 68 20 74 68 65  aracter with the
bd00: 20 68 69 67 68 2d 6f 72 64 65 72 20 62 69 74 20   high-order bit 
bd10: 73 65 74 20 69 73 0a 2a 2a 20 61 6c 6c 6f 77 65  set is.** allowe
bd20: 64 20 69 6e 20 61 6e 20 69 64 65 6e 74 69 66 69  d in an identifi
bd30: 65 72 2e 20 20 46 6f 72 20 37 2d 62 69 74 20 63  er.  For 7-bit c
bd40: 68 61 72 61 63 74 65 72 73 2c 20 0a 2a 2a 20 73  haracters, .** s
bd50: 71 6c 69 74 65 33 49 73 49 64 43 68 61 72 5b 58  qlite3IsIdChar[X
bd60: 5d 20 6d 75 73 74 20 62 65 20 31 2e 0a 2a 2a 0a  ] must be 1..**.
bd70: 2a 2a 20 54 69 63 6b 65 74 20 23 31 30 36 36 2e  ** Ticket #1066.
bd80: 20 20 74 68 65 20 53 51 4c 20 73 74 61 6e 64 61    the SQL standa
bd90: 72 64 20 64 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f  rd does not allo
bda0: 77 20 27 24 27 20 69 6e 20 74 68 65 0a 2a 2a 20  w '$' in the.** 
bdb0: 6d 69 64 64 6c 65 20 6f 66 20 69 64 65 6e 74 66  middle of identf
bdc0: 69 65 72 73 2e 20 20 42 75 74 20 6d 61 6e 79 20  iers.  But many 
bdd0: 53 51 4c 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  SQL implementati
bde0: 6f 6e 73 20 64 6f 2e 20 0a 2a 2a 20 53 51 4c 69  ons do. .** SQLi
bdf0: 74 65 20 77 69 6c 6c 20 61 6c 6c 6f 77 20 27 24  te will allow '$
be00: 27 20 69 6e 20 69 64 65 6e 74 69 66 69 65 72 73  ' in identifiers
be10: 20 66 6f 72 20 63 6f 6d 70 61 74 69 62 69 6c 69   for compatibili
be20: 74 79 2e 0a 2a 2a 20 42 75 74 20 74 68 65 20 66  ty..** But the f
be30: 65 61 74 75 72 65 20 69 73 20 75 6e 64 6f 63 75  eature is undocu
be40: 6d 65 6e 74 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  mented..*/.stati
be50: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 69 73 49  c const char isI
be60: 64 43 68 61 72 5b 5d 20 3d 20 7b 0a 2f 2a 20 78  dChar[] = {./* x
be70: 30 20 78 31 20 78 32 20 78 33 20 78 34 20 78 35  0 x1 x2 x3 x4 x5
be80: 20 78 36 20 78 37 20 78 38 20 78 39 20 78 41 20   x6 x7 x8 x9 xA 
be90: 78 42 20 78 43 20 78 44 20 78 45 20 78 46 20 2a  xB xC xD xE xF *
bea0: 2f 0a 20 20 20 20 30 2c 20 30 2c 20 30 2c 20 30  /.    0, 0, 0, 0
beb0: 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 1, 0, 0, 0, 0,
bec0: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   0, 0, 0, 0, 0, 
bed0: 30 2c 20 30 2c 20 20 2f 2a 20 32 78 20 2a 2f 0a  0, 0,  /* 2x */.
bee0: 20 20 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20      1, 1, 1, 1, 
bef0: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
bf00: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
bf10: 20 30 2c 20 20 2f 2a 20 33 78 20 2a 2f 0a 20 20   0,  /* 3x */.  
bf20: 20 20 30 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c    0, 1, 1, 1, 1,
bf30: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
bf40: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
bf50: 2c 20 20 2f 2a 20 34 78 20 2a 2f 0a 20 20 20 20  ,  /* 4x */.    
bf60: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
bf70: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
bf80: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 31 2c 20   0, 0, 0, 0, 1, 
bf90: 20 2f 2a 20 35 78 20 2a 2f 0a 20 20 20 20 30 2c   /* 5x */.    0,
bfa0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
bfb0: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
bfc0: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 20 2f  , 1, 1, 1, 1,  /
bfd0: 2a 20 36 78 20 2a 2f 0a 20 20 20 20 31 2c 20 31  * 6x */.    1, 1
bfe0: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
bff0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 30 2c 20   1, 1, 1, 1, 0, 
c000: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 2f 2a 20  0, 0, 0, 0,  /* 
c010: 37 78 20 2a 2f 0a 7d 3b 0a 23 64 65 66 69 6e 65  7x */.};.#define
c020: 20 49 64 43 68 61 72 28 43 29 20 20 28 28 28 63   IdChar(C)  (((c
c030: 3d 43 29 26 30 78 38 30 29 21 3d 30 20 7c 7c 20  =C)&0x80)!=0 || 
c040: 28 63 3e 30 78 31 66 20 26 26 20 69 73 49 64 43  (c>0x1f && isIdC
c050: 68 61 72 5b 63 2d 30 78 32 30 5d 29 29 0a 0a 0a  har[c-0x20]))...
c060: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
c070: 20 6c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 74   length of the t
c080: 6f 6b 65 6e 20 74 68 61 74 20 62 65 67 69 6e 73  oken that begins
c090: 20 61 74 20 7a 5b 30 5d 2e 20 0a 2a 2a 20 53 74   at z[0]. .** St
c0a0: 6f 72 65 20 74 68 65 20 74 6f 6b 65 6e 20 74 79  ore the token ty
c0b0: 70 65 20 69 6e 20 2a 74 6f 6b 65 6e 54 79 70 65  pe in *tokenType
c0c0: 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
c0d0: 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  g..*/.static int
c0e0: 20 67 65 74 54 6f 6b 65 6e 28 63 6f 6e 73 74 20   getToken(const 
c0f0: 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 2a 74 6f  char *z, int *to
c100: 6b 65 6e 54 79 70 65 29 7b 0a 20 20 69 6e 74 20  kenType){.  int 
c110: 69 2c 20 63 3b 0a 20 20 73 77 69 74 63 68 28 20  i, c;.  switch( 
c120: 2a 7a 20 29 7b 0a 20 20 20 20 63 61 73 65 20 30  *z ){.    case 0
c130: 3a 20 7b 0a 20 20 20 20 20 20 2a 74 6f 6b 65 6e  : {.      *token
c140: 54 79 70 65 20 3d 20 54 4f 4b 45 4e 5f 45 4f 46  Type = TOKEN_EOF
c150: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 30  ;.      return 0
c160: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 61 73 65  ;.    }.    case
c170: 20 27 20 27 3a 20 63 61 73 65 20 27 5c 74 27 3a   ' ': case '\t':
c180: 20 63 61 73 65 20 27 5c 6e 27 3a 20 63 61 73 65   case '\n': case
c190: 20 27 5c 66 27 3a 20 63 61 73 65 20 27 5c 72 27   '\f': case '\r'
c1a0: 3a 20 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d  : {.      for(i=
c1b0: 31 3b 20 73 61 66 65 5f 69 73 73 70 61 63 65 28  1; safe_isspace(
c1c0: 7a 5b 69 5d 29 3b 20 69 2b 2b 29 7b 7d 0a 20 20  z[i]); i++){}.  
c1d0: 20 20 20 20 2a 74 6f 6b 65 6e 54 79 70 65 20 3d      *tokenType =
c1e0: 20 54 4f 4b 45 4e 5f 53 50 41 43 45 3b 0a 20 20   TOKEN_SPACE;.  
c1f0: 20 20 20 20 72 65 74 75 72 6e 20 69 3b 0a 20 20      return i;.  
c200: 20 20 7d 0a 20 20 20 20 63 61 73 65 20 27 60 27    }.    case '`'
c210: 3a 0a 20 20 20 20 63 61 73 65 20 27 5c 27 27 3a  :.    case '\'':
c220: 0a 20 20 20 20 63 61 73 65 20 27 22 27 3a 20 7b  .    case '"': {
c230: 0a 20 20 20 20 20 20 69 6e 74 20 64 65 6c 69 6d  .      int delim
c240: 20 3d 20 7a 5b 30 5d 3b 0a 20 20 20 20 20 20 66   = z[0];.      f
c250: 6f 72 28 69 3d 31 3b 20 28 63 3d 7a 5b 69 5d 29  or(i=1; (c=z[i])
c260: 21 3d 30 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  !=0; i++){.     
c270: 20 20 20 69 66 28 20 63 3d 3d 64 65 6c 69 6d 20     if( c==delim 
c280: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  ){.          if(
c290: 20 7a 5b 69 2b 31 5d 3d 3d 64 65 6c 69 6d 20 29   z[i+1]==delim )
c2a0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 2b  {.            i+
c2b0: 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c  +;.          }el
c2c0: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  se{.            
c2d0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20  break;.         
c2e0: 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
c2f0: 20 20 20 7d 0a 20 20 20 20 20 20 2a 74 6f 6b 65     }.      *toke
c300: 6e 54 79 70 65 20 3d 20 54 4f 4b 45 4e 5f 53 54  nType = TOKEN_ST
c310: 52 49 4e 47 3b 0a 20 20 20 20 20 20 72 65 74 75  RING;.      retu
c320: 72 6e 20 69 20 2b 20 28 63 21 3d 30 29 3b 0a 20  rn i + (c!=0);. 
c330: 20 20 20 7d 0a 20 20 20 20 63 61 73 65 20 27 5b     }.    case '[
c340: 27 3a 20 7b 0a 20 20 20 20 20 20 66 6f 72 28 69  ': {.      for(i
c350: 3d 31 2c 20 63 3d 7a 5b 30 5d 3b 20 63 21 3d 27  =1, c=z[0]; c!='
c360: 5d 27 20 26 26 20 28 63 3d 7a 5b 69 5d 29 21 3d  ]' && (c=z[i])!=
c370: 30 3b 20 69 2b 2b 29 7b 7d 0a 20 20 20 20 20 20  0; i++){}.      
c380: 2a 74 6f 6b 65 6e 54 79 70 65 20 3d 20 54 4f 4b  *tokenType = TOK
c390: 45 4e 5f 49 44 3b 0a 20 20 20 20 20 20 72 65 74  EN_ID;.      ret
c3a0: 75 72 6e 20 69 3b 0a 20 20 20 20 7d 0a 20 20 20  urn i;.    }.   
c3b0: 20 64 65 66 61 75 6c 74 3a 20 7b 0a 20 20 20 20   default: {.    
c3c0: 20 20 69 66 28 20 21 49 64 43 68 61 72 28 2a 7a    if( !IdChar(*z
c3d0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 62 72 65  ) ){.        bre
c3e0: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
c3f0: 20 20 66 6f 72 28 69 3d 31 3b 20 49 64 43 68 61    for(i=1; IdCha
c400: 72 28 7a 5b 69 5d 29 3b 20 69 2b 2b 29 7b 7d 0a  r(z[i]); i++){}.
c410: 20 20 20 20 20 20 2a 74 6f 6b 65 6e 54 79 70 65        *tokenType
c420: 20 3d 20 54 4f 4b 45 4e 5f 49 44 3b 0a 20 20 20   = TOKEN_ID;.   
c430: 20 20 20 72 65 74 75 72 6e 20 69 3b 0a 20 20 20     return i;.   
c440: 20 7d 0a 20 20 7d 0a 20 20 2a 74 6f 6b 65 6e 54   }.  }.  *tokenT
c450: 79 70 65 20 3d 20 54 4f 4b 45 4e 5f 50 55 4e 43  ype = TOKEN_PUNC
c460: 54 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d  T;.  return 1;.}
c470: 0a 0a 2f 2a 0a 2a 2a 20 41 20 74 6f 6b 65 6e 20  ../*.** A token 
c480: 65 78 74 72 61 63 74 65 64 20 66 72 6f 6d 20 61  extracted from a
c490: 20 73 74 72 69 6e 67 20 69 73 20 61 6e 20 69 6e   string is an in
c4a0: 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f  stance of the fo
c4b0: 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 73 74 72 75 63  llowing.** struc
c4c0: 74 75 72 65 2e 0a 2a 2f 0a 74 79 70 65 64 65 66  ture..*/.typedef
c4d0: 20 73 74 72 75 63 74 20 54 6f 6b 65 6e 20 7b 0a   struct Token {.
c4e0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 3b    const char *z;
c4f0: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
c500: 72 20 74 6f 20 74 6f 6b 65 6e 20 74 65 78 74 2e  r to token text.
c510: 20 20 4e 6f 74 20 27 5c 30 30 30 27 20 74 65 72    Not '\000' ter
c520: 6d 69 6e 61 74 65 64 20 2a 2f 0a 20 20 73 68 6f  minated */.  sho
c530: 72 74 20 69 6e 74 20 6e 3b 20 20 20 20 20 20 20  rt int n;       
c540: 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 74    /* Length of t
c550: 68 65 20 74 6f 6b 65 6e 20 74 65 78 74 20 69 6e  he token text in
c560: 20 62 79 74 65 73 2e 20 2a 2f 0a 7d 20 54 6f 6b   bytes. */.} Tok
c570: 65 6e 3b 0a 0a 2f 2a 0a 2a 2a 20 47 69 76 65 6e  en;../*.** Given
c580: 20 61 20 69 6e 70 75 74 20 73 74 72 69 6e 67 20   a input string 
c590: 28 77 68 69 63 68 20 69 73 20 72 65 61 6c 6c 79  (which is really
c5a0: 20 6f 6e 65 20 6f 66 20 74 68 65 20 61 72 67 76   one of the argv
c5b0: 5b 5d 20 70 61 72 61 6d 65 74 65 72 73 0a 2a 2a  [] parameters.**
c5c0: 20 70 61 73 73 65 64 20 69 6e 74 6f 20 78 43 6f   passed into xCo
c5d0: 6e 6e 65 63 74 20 6f 72 20 78 43 72 65 61 74 65  nnect or xCreate
c5e0: 29 20 73 70 6c 69 74 20 74 68 65 20 73 74 72 69  ) split the stri
c5f0: 6e 67 20 75 70 20 69 6e 74 6f 20 74 6f 6b 65 6e  ng up into token
c600: 73 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 61 6e 20  s..** Return an 
c610: 61 72 72 61 79 20 6f 66 20 70 6f 69 6e 74 65 72  array of pointer
c620: 73 20 74 6f 20 27 5c 30 30 30 27 20 74 65 72 6d  s to '\000' term
c630: 69 6e 61 74 65 64 20 73 74 72 69 6e 67 73 2c 20  inated strings, 
c640: 6f 6e 65 20 73 74 72 69 6e 67 0a 2a 2a 20 66 6f  one string.** fo
c650: 72 20 65 61 63 68 20 6e 6f 6e 2d 77 68 69 74 65  r each non-white
c660: 73 70 61 63 65 20 74 6f 6b 65 6e 2e 0a 2a 2a 0a  space token..**.
c670: 2a 2a 20 54 68 65 20 72 65 74 75 72 6e 65 64 20  ** The returned 
c680: 61 72 72 61 79 20 69 73 20 74 65 72 6d 69 6e 61  array is termina
c690: 74 65 64 20 62 79 20 61 20 73 69 6e 67 6c 65 20  ted by a single 
c6a0: 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2e 0a 2a 2a  NULL pointer..**
c6b0: 0a 2a 2a 20 53 70 61 63 65 20 74 6f 20 68 6f 6c  .** Space to hol
c6c0: 64 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 61  d the returned a
c6d0: 72 72 61 79 20 69 73 20 6f 62 74 61 69 6e 65 64  rray is obtained
c6e0: 20 66 72 6f 6d 20 61 20 73 69 6e 67 6c 65 0a 2a   from a single.*
c6f0: 2a 20 6d 61 6c 6c 6f 63 20 61 6e 64 20 73 68 6f  * malloc and sho
c700: 75 6c 64 20 62 65 20 66 72 65 65 64 20 62 79 20  uld be freed by 
c710: 70 61 73 73 69 6e 67 20 74 68 65 20 72 65 74 75  passing the retu
c720: 72 6e 20 76 61 6c 75 65 20 74 6f 20 66 72 65 65  rn value to free
c730: 28 29 2e 0a 2a 2a 20 54 68 65 20 69 6e 64 69 76  ()..** The indiv
c740: 69 64 75 61 6c 20 73 74 72 69 6e 67 73 20 77 69  idual strings wi
c750: 74 68 69 6e 20 74 68 65 20 74 6f 6b 65 6e 20 6c  thin the token l
c760: 69 73 74 20 61 72 65 20 61 6c 6c 20 61 20 70 61  ist are all a pa
c770: 72 74 20 6f 66 0a 2a 2a 20 74 68 65 20 73 69 6e  rt of.** the sin
c780: 67 6c 65 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63  gle memory alloc
c790: 61 74 69 6f 6e 20 61 6e 64 20 77 69 6c 6c 20 61  ation and will a
c7a0: 6c 6c 20 62 65 20 66 72 65 65 64 20 61 74 20 6f  ll be freed at o
c7b0: 6e 63 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63  nce..*/.static c
c7c0: 68 61 72 20 2a 2a 74 6f 6b 65 6e 69 7a 65 53 74  har **tokenizeSt
c7d0: 72 69 6e 67 28 63 6f 6e 73 74 20 63 68 61 72 20  ring(const char 
c7e0: 2a 7a 2c 20 69 6e 74 20 2a 70 6e 54 6f 6b 65 6e  *z, int *pnToken
c7f0: 29 7b 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 20  ){.  int nToken 
c800: 3d 20 30 3b 0a 20 20 54 6f 6b 65 6e 20 2a 61 54  = 0;.  Token *aT
c810: 6f 6b 65 6e 20 3d 20 6d 61 6c 6c 6f 63 28 20 73  oken = malloc( s
c820: 74 72 6c 65 6e 28 7a 29 20 2a 20 73 69 7a 65 6f  trlen(z) * sizeo
c830: 66 28 61 54 6f 6b 65 6e 5b 30 5d 29 20 29 3b 0a  f(aToken[0]) );.
c840: 20 20 69 6e 74 20 6e 20 3d 20 31 3b 0a 20 20 69    int n = 1;.  i
c850: 6e 74 20 65 2c 20 69 3b 0a 20 20 69 6e 74 20 74  nt e, i;.  int t
c860: 6f 74 61 6c 53 69 7a 65 20 3d 20 30 3b 0a 20 20  otalSize = 0;.  
c870: 63 68 61 72 20 2a 2a 61 7a 54 6f 6b 65 6e 3b 0a  char **azToken;.
c880: 20 20 63 68 61 72 20 2a 7a 43 6f 70 79 3b 0a 20    char *zCopy;. 
c890: 20 77 68 69 6c 65 28 20 6e 3e 30 20 29 7b 0a 20   while( n>0 ){. 
c8a0: 20 20 20 6e 20 3d 20 67 65 74 54 6f 6b 65 6e 28     n = getToken(
c8b0: 7a 2c 20 26 65 29 3b 0a 20 20 20 20 69 66 28 20  z, &e);.    if( 
c8c0: 65 21 3d 54 4f 4b 45 4e 5f 53 50 41 43 45 20 29  e!=TOKEN_SPACE )
c8d0: 7b 0a 20 20 20 20 20 20 61 54 6f 6b 65 6e 5b 6e  {.      aToken[n
c8e0: 54 6f 6b 65 6e 5d 2e 7a 20 3d 20 7a 3b 0a 20 20  Token].z = z;.  
c8f0: 20 20 20 20 61 54 6f 6b 65 6e 5b 6e 54 6f 6b 65      aToken[nToke
c900: 6e 5d 2e 6e 20 3d 20 6e 3b 0a 20 20 20 20 20 20  n].n = n;.      
c910: 6e 54 6f 6b 65 6e 2b 2b 3b 0a 20 20 20 20 20 20  nToken++;.      
c920: 74 6f 74 61 6c 53 69 7a 65 20 2b 3d 20 6e 2b 31  totalSize += n+1
c930: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a 20 2b 3d  ;.    }.    z +=
c940: 20 6e 3b 0a 20 20 7d 0a 20 20 61 7a 54 6f 6b 65   n;.  }.  azToke
c950: 6e 20 3d 20 28 63 68 61 72 2a 2a 29 6d 61 6c 6c  n = (char**)mall
c960: 6f 63 28 20 6e 54 6f 6b 65 6e 2a 73 69 7a 65 6f  oc( nToken*sizeo
c970: 66 28 63 68 61 72 2a 29 20 2b 20 74 6f 74 61 6c  f(char*) + total
c980: 53 69 7a 65 20 29 3b 0a 20 20 7a 43 6f 70 79 20  Size );.  zCopy 
c990: 3d 20 28 63 68 61 72 2a 29 26 61 7a 54 6f 6b 65  = (char*)&azToke
c9a0: 6e 5b 6e 54 6f 6b 65 6e 5d 3b 0a 20 20 6e 54 6f  n[nToken];.  nTo
c9b0: 6b 65 6e 2d 2d 3b 0a 20 20 66 6f 72 28 69 3d 30  ken--;.  for(i=0
c9c0: 3b 20 69 3c 6e 54 6f 6b 65 6e 3b 20 69 2b 2b 29  ; i<nToken; i++)
c9d0: 7b 0a 20 20 20 20 61 7a 54 6f 6b 65 6e 5b 69 5d  {.    azToken[i]
c9e0: 20 3d 20 7a 43 6f 70 79 3b 0a 20 20 20 20 6e 20   = zCopy;.    n 
c9f0: 3d 20 61 54 6f 6b 65 6e 5b 69 5d 2e 6e 3b 0a 20  = aToken[i].n;. 
ca00: 20 20 20 6d 65 6d 63 70 79 28 7a 43 6f 70 79 2c     memcpy(zCopy,
ca10: 20 61 54 6f 6b 65 6e 5b 69 5d 2e 7a 2c 20 6e 29   aToken[i].z, n)
ca20: 3b 0a 20 20 20 20 7a 43 6f 70 79 5b 6e 5d 20 3d  ;.    zCopy[n] =
ca30: 20 30 3b 0a 20 20 20 20 7a 43 6f 70 79 20 2b 3d   0;.    zCopy +=
ca40: 20 6e 2b 31 3b 0a 20 20 7d 0a 20 20 61 7a 54 6f   n+1;.  }.  azTo
ca50: 6b 65 6e 5b 6e 54 6f 6b 65 6e 5d 20 3d 20 30 3b  ken[nToken] = 0;
ca60: 0a 20 20 66 72 65 65 28 61 54 6f 6b 65 6e 29 3b  .  free(aToken);
ca70: 0a 20 20 2a 70 6e 54 6f 6b 65 6e 20 3d 20 6e 54  .  *pnToken = nT
ca80: 6f 6b 65 6e 3b 0a 20 20 72 65 74 75 72 6e 20 61  oken;.  return a
ca90: 7a 54 6f 6b 65 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  zToken;.}../*.**
caa0: 20 43 6f 6e 76 65 72 74 20 61 6e 20 53 51 4c 2d   Convert an SQL-
cab0: 73 74 79 6c 65 20 71 75 6f 74 65 64 20 73 74 72  style quoted str
cac0: 69 6e 67 20 69 6e 74 6f 20 61 20 6e 6f 72 6d 61  ing into a norma
cad0: 6c 20 73 74 72 69 6e 67 20 62 79 20 72 65 6d 6f  l string by remo
cae0: 76 69 6e 67 0a 2a 2a 20 74 68 65 20 71 75 6f 74  ving.** the quot
caf0: 65 20 63 68 61 72 61 63 74 65 72 73 2e 20 20 54  e characters.  T
cb00: 68 65 20 63 6f 6e 76 65 72 73 69 6f 6e 20 69 73  he conversion is
cb10: 20 64 6f 6e 65 20 69 6e 2d 70 6c 61 63 65 2e 20   done in-place. 
cb20: 20 49 66 20 74 68 65 0a 2a 2a 20 69 6e 70 75 74   If the.** input
cb30: 20 64 6f 65 73 20 6e 6f 74 20 62 65 67 69 6e 20   does not begin 
cb40: 77 69 74 68 20 61 20 71 75 6f 74 65 20 63 68 61  with a quote cha
cb50: 72 61 63 74 65 72 2c 20 74 68 65 6e 20 74 68 69  racter, then thi
cb60: 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 69 73 20  s routine.** is 
cb70: 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 45  a no-op..**.** E
cb80: 78 61 6d 70 6c 65 73 3a 0a 2a 2a 0a 2a 2a 20 20  xamples:.**.**  
cb90: 20 20 20 22 61 62 63 22 20 20 20 62 65 63 6f 6d     "abc"   becom
cba0: 65 73 20 20 20 61 62 63 0a 2a 2a 20 20 20 20 20  es   abc.**     
cbb0: 27 78 79 7a 27 20 20 20 62 65 63 6f 6d 65 73 20  'xyz'   becomes 
cbc0: 20 20 78 79 7a 0a 2a 2a 20 20 20 20 20 5b 70 71    xyz.**     [pq
cbd0: 72 5d 20 20 20 62 65 63 6f 6d 65 73 20 20 20 70  r]   becomes   p
cbe0: 71 72 0a 2a 2a 20 20 20 20 20 60 6d 6e 6f 60 20  qr.**     `mno` 
cbf0: 20 20 62 65 63 6f 6d 65 73 20 20 20 6d 6e 6f 0a    becomes   mno.
cc00: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  */.static void d
cc10: 65 71 75 6f 74 65 53 74 72 69 6e 67 28 63 68 61  equoteString(cha
cc20: 72 20 2a 7a 29 7b 0a 20 20 69 6e 74 20 71 75 6f  r *z){.  int quo
cc30: 74 65 3b 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 0a  te;.  int i, j;.
cc40: 20 20 69 66 28 20 7a 3d 3d 30 20 29 20 72 65 74    if( z==0 ) ret
cc50: 75 72 6e 3b 0a 20 20 71 75 6f 74 65 20 3d 20 7a  urn;.  quote = z
cc60: 5b 30 5d 3b 0a 20 20 73 77 69 74 63 68 28 20 71  [0];.  switch( q
cc70: 75 6f 74 65 20 29 7b 0a 20 20 20 20 63 61 73 65  uote ){.    case
cc80: 20 27 5c 27 27 3a 20 20 62 72 65 61 6b 3b 0a 20   '\'':  break;. 
cc90: 20 20 20 63 61 73 65 20 27 22 27 3a 20 20 20 62     case '"':   b
cca0: 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 27  reak;.    case '
ccb0: 60 27 3a 20 20 20 62 72 65 61 6b 3b 20 20 20 20  `':   break;    
ccc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
ccd0: 6f 72 20 4d 79 53 51 4c 20 63 6f 6d 70 61 74 69  or MySQL compati
cce0: 62 69 6c 69 74 79 20 2a 2f 0a 20 20 20 20 63 61  bility */.    ca
ccf0: 73 65 20 27 5b 27 3a 20 20 20 71 75 6f 74 65 20  se '[':   quote 
cd00: 3d 20 27 5d 27 3b 20 20 62 72 65 61 6b 3b 20 20  = ']';  break;  
cd10: 2f 2a 20 46 6f 72 20 4d 53 20 53 71 6c 53 65 72  /* For MS SqlSer
cd20: 76 65 72 20 63 6f 6d 70 61 74 69 62 69 6c 69 74  ver compatibilit
cd30: 79 20 2a 2f 0a 20 20 20 20 64 65 66 61 75 6c 74  y */.    default
cd40: 3a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d  :    return;.  }
cd50: 0a 20 20 66 6f 72 28 69 3d 31 2c 20 6a 3d 30 3b  .  for(i=1, j=0;
cd60: 20 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20   z[i]; i++){.   
cd70: 20 69 66 28 20 7a 5b 69 5d 3d 3d 71 75 6f 74 65   if( z[i]==quote
cd80: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 7a 5b   ){.      if( z[
cd90: 69 2b 31 5d 3d 3d 71 75 6f 74 65 20 29 7b 0a 20  i+1]==quote ){. 
cda0: 20 20 20 20 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20         z[j++] = 
cdb0: 71 75 6f 74 65 3b 0a 20 20 20 20 20 20 20 20 69  quote;.        i
cdc0: 2b 2b 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  ++;.      }else{
cdd0: 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b 2b 5d 20  .        z[j++] 
cde0: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 62 72 65  = 0;.        bre
cdf0: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
ce00: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a 5b 6a  }else{.      z[j
ce10: 2b 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a 20 20 20 20  ++] = z[i];.    
ce20: 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  }.  }.}../*.** T
ce30: 68 65 20 69 6e 70 75 74 20 61 7a 49 6e 20 69 73  he input azIn is
ce40: 20 61 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74   a NULL-terminat
ce50: 65 64 20 6c 69 73 74 20 6f 66 20 74 6f 6b 65 6e  ed list of token
ce60: 73 2e 20 20 52 65 6d 6f 76 65 20 74 68 65 20 66  s.  Remove the f
ce70: 69 72 73 74 0a 2a 2a 20 74 6f 6b 65 6e 20 61 6e  irst.** token an
ce80: 64 20 61 6c 6c 20 70 75 6e 63 74 75 61 74 69 6f  d all punctuatio
ce90: 6e 20 74 6f 6b 65 6e 73 2e 20 20 52 65 6d 6f 76  n tokens.  Remov
cea0: 65 20 74 68 65 20 71 75 6f 74 65 73 20 66 72 6f  e the quotes fro
ceb0: 6d 0a 2a 2a 20 61 72 6f 75 6e 64 20 73 74 72 69  m.** around stri
cec0: 6e 67 20 6c 69 74 65 72 61 6c 20 74 6f 6b 65 6e  ng literal token
ced0: 73 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65  s..**.** Example
cee0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 69 6e 70 75  :.**.**     inpu
cef0: 74 3a 20 20 20 20 20 20 74 6f 6b 65 6e 69 7a 65  t:      tokenize
cf00: 20 63 68 69 6e 65 73 65 20 28 20 27 73 69 6d 70   chinese ( 'simp
cf10: 6c 69 66 65 64 27 20 2c 20 27 6d 69 78 65 64 27  lifed' , 'mixed'
cf20: 20 29 0a 2a 2a 20 20 20 20 20 6f 75 74 70 75 74   ).**     output
cf30: 3a 20 20 20 20 20 63 68 69 6e 65 73 65 20 73 69  :     chinese si
cf40: 6d 70 6c 69 66 65 64 20 6d 69 78 65 64 0a 2a 2a  mplifed mixed.**
cf50: 0a 2a 2a 20 41 6e 6f 74 68 65 72 20 65 78 61 6d  .** Another exam
cf60: 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 69  ple:.**.**     i
cf70: 6e 70 75 74 3a 20 20 20 20 20 20 64 65 6c 69 6d  nput:      delim
cf80: 69 74 65 72 73 20 28 20 27 5b 27 20 2c 20 27 5d  iters ( '[' , ']
cf90: 27 20 2c 20 27 2e 2e 2e 27 20 29 0a 2a 2a 20 20  ' , '...' ).**  
cfa0: 20 20 20 6f 75 74 70 75 74 3a 20 20 20 20 20 5b     output:     [
cfb0: 20 5d 20 2e 2e 2e 0a 2a 2f 0a 73 74 61 74 69 63   ] ....*/.static
cfc0: 20 76 6f 69 64 20 74 6f 6b 65 6e 4c 69 73 74 54   void tokenListT
cfd0: 6f 49 64 4c 69 73 74 28 63 68 61 72 20 2a 2a 61  oIdList(char **a
cfe0: 7a 49 6e 29 7b 0a 20 20 69 6e 74 20 69 2c 20 6a  zIn){.  int i, j
cff0: 3b 0a 20 20 69 66 28 20 61 7a 49 6e 20 29 7b 0a  ;.  if( azIn ){.
d000: 20 20 20 20 66 6f 72 28 69 3d 30 2c 20 6a 3d 2d      for(i=0, j=-
d010: 31 3b 20 61 7a 49 6e 5b 69 5d 3b 20 69 2b 2b 29  1; azIn[i]; i++)
d020: 7b 0a 20 20 20 20 20 20 69 66 28 20 73 61 66 65  {.      if( safe
d030: 5f 69 73 61 6c 6e 75 6d 28 61 7a 49 6e 5b 69 5d  _isalnum(azIn[i]
d040: 5b 30 5d 29 20 7c 7c 20 61 7a 49 6e 5b 69 5d 5b  [0]) || azIn[i][
d050: 31 5d 20 29 7b 0a 20 20 20 20 20 20 20 20 64 65  1] ){.        de
d060: 71 75 6f 74 65 53 74 72 69 6e 67 28 61 7a 49 6e  quoteString(azIn
d070: 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20 20 69 66  [i]);.        if
d080: 28 20 6a 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20  ( j>=0 ){.      
d090: 20 20 20 20 61 7a 49 6e 5b 6a 5d 20 3d 20 61 7a      azIn[j] = az
d0a0: 49 6e 5b 69 5d 3b 0a 20 20 20 20 20 20 20 20 7d  In[i];.        }
d0b0: 0a 20 20 20 20 20 20 20 20 6a 2b 2b 3b 0a 20 20  .        j++;.  
d0c0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
d0d0: 61 7a 49 6e 5b 6a 5d 20 3d 20 30 3b 0a 20 20 7d  azIn[j] = 0;.  }
d0e0: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 64 20  .}.../*.** Find 
d0f0: 74 68 65 20 66 69 72 73 74 20 61 6c 70 68 61 6e  the first alphan
d100: 75 6d 65 72 69 63 20 74 6f 6b 65 6e 20 69 6e 20  umeric token in 
d110: 74 68 65 20 73 74 72 69 6e 67 20 7a 49 6e 2e 20  the string zIn. 
d120: 20 4e 75 6c 6c 2d 74 65 72 6d 69 6e 61 74 65 0a   Null-terminate.
d130: 2a 2a 20 74 68 69 73 20 74 6f 6b 65 6e 2e 20 20  ** this token.  
d140: 52 65 6d 6f 76 65 20 61 6e 79 20 71 75 6f 74 61  Remove any quota
d150: 74 69 6f 6e 20 6d 61 72 6b 73 2e 20 20 41 6e 64  tion marks.  And
d160: 20 72 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65   return a pointe
d170: 72 20 74 6f 0a 2a 2a 20 74 68 65 20 72 65 73 75  r to.** the resu
d180: 6c 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68  lt..*/.static ch
d190: 61 72 20 2a 66 69 72 73 74 54 6f 6b 65 6e 28 63  ar *firstToken(c
d1a0: 68 61 72 20 2a 7a 49 6e 2c 20 63 68 61 72 20 2a  har *zIn, char *
d1b0: 2a 70 7a 54 61 69 6c 29 7b 0a 20 20 69 6e 74 20  *pzTail){.  int 
d1c0: 6e 2c 20 74 74 79 70 65 3b 0a 20 20 77 68 69 6c  n, ttype;.  whil
d1d0: 65 28 31 29 7b 0a 20 20 20 20 6e 20 3d 20 67 65  e(1){.    n = ge
d1e0: 74 54 6f 6b 65 6e 28 7a 49 6e 2c 20 26 74 74 79  tToken(zIn, &tty
d1f0: 70 65 29 3b 0a 20 20 20 20 69 66 28 20 74 74 79  pe);.    if( tty
d200: 70 65 3d 3d 54 4f 4b 45 4e 5f 53 50 41 43 45 20  pe==TOKEN_SPACE 
d210: 29 7b 0a 20 20 20 20 20 20 7a 49 6e 20 2b 3d 20  ){.      zIn += 
d220: 6e 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  n;.    }else if(
d230: 20 74 74 79 70 65 3d 3d 54 4f 4b 45 4e 5f 45 4f   ttype==TOKEN_EO
d240: 46 20 29 7b 0a 20 20 20 20 20 20 2a 70 7a 54 61  F ){.      *pzTa
d250: 69 6c 20 3d 20 7a 49 6e 3b 0a 20 20 20 20 20 20  il = zIn;.      
d260: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 65  return 0;.    }e
d270: 6c 73 65 7b 0a 20 20 20 20 20 20 7a 49 6e 5b 6e  lse{.      zIn[n
d280: 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 2a 70 7a  ] = 0;.      *pz
d290: 54 61 69 6c 20 3d 20 26 7a 49 6e 5b 31 5d 3b 0a  Tail = &zIn[1];.
d2a0: 20 20 20 20 20 20 64 65 71 75 6f 74 65 53 74 72        dequoteStr
d2b0: 69 6e 67 28 7a 49 6e 29 3b 0a 20 20 20 20 20 20  ing(zIn);.      
d2c0: 72 65 74 75 72 6e 20 7a 49 6e 3b 0a 20 20 20 20  return zIn;.    
d2d0: 7d 0a 20 20 7d 0a 20 20 2f 2a 4e 4f 54 52 45 41  }.  }.  /*NOTREA
d2e0: 43 48 45 44 2a 2f 0a 7d 0a 0a 2f 2a 20 52 65 74  CHED*/.}../* Ret
d2f0: 75 72 6e 20 74 72 75 65 20 69 66 2e 2e 2e 0a 2a  urn true if....*
d300: 2a 0a 2a 2a 20 20 20 2a 20 20 73 20 62 65 67 69  *.**   *  s begi
d310: 6e 73 20 77 69 74 68 20 74 68 65 20 73 74 72 69  ns with the stri
d320: 6e 67 20 74 2c 20 69 67 6e 6f 72 69 6e 67 20 63  ng t, ignoring c
d330: 61 73 65 0a 2a 2a 20 20 20 2a 20 20 73 20 69 73  ase.**   *  s is
d340: 20 6c 6f 6e 67 65 72 20 74 68 61 6e 20 74 0a 2a   longer than t.*
d350: 2a 20 20 20 2a 20 20 54 68 65 20 66 69 72 73 74  *   *  The first
d360: 20 63 68 61 72 61 63 74 65 72 20 6f 66 20 73 20   character of s 
d370: 62 65 79 6f 6e 64 20 74 20 69 73 20 6e 6f 74 20  beyond t is not 
d380: 61 20 61 6c 70 68 61 6e 75 6d 65 72 69 63 0a 2a  a alphanumeric.*
d390: 2a 20 0a 2a 2a 20 49 67 6e 6f 72 65 20 6c 65 61  * .** Ignore lea
d3a0: 64 69 6e 67 20 73 70 61 63 65 20 69 6e 20 2a 73  ding space in *s
d3b0: 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 70 75 74 20 69  ..**.** To put i
d3c0: 74 20 61 6e 6f 74 68 65 72 20 77 61 79 2c 20 72  t another way, r
d3d0: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 74 68  eturn true if th
d3e0: 65 20 66 69 72 73 74 20 74 6f 6b 65 6e 20 6f 66  e first token of
d3f0: 0a 2a 2a 20 73 5b 5d 20 69 73 20 74 5b 5d 2e 0a  .** s[] is t[]..
d400: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 74  */.static int st
d410: 61 72 74 73 57 69 74 68 28 63 6f 6e 73 74 20 63  artsWith(const c
d420: 68 61 72 20 2a 73 2c 20 63 6f 6e 73 74 20 63 68  har *s, const ch
d430: 61 72 20 2a 74 29 7b 0a 20 20 77 68 69 6c 65 28  ar *t){.  while(
d440: 20 73 61 66 65 5f 69 73 73 70 61 63 65 28 2a 73   safe_isspace(*s
d450: 29 20 29 7b 20 73 2b 2b 3b 20 7d 0a 20 20 77 68  ) ){ s++; }.  wh
d460: 69 6c 65 28 20 2a 74 20 29 7b 0a 20 20 20 20 69  ile( *t ){.    i
d470: 66 28 20 73 61 66 65 5f 74 6f 6c 6f 77 65 72 28  f( safe_tolower(
d480: 2a 73 2b 2b 29 21 3d 73 61 66 65 5f 74 6f 6c 6f  *s++)!=safe_tolo
d490: 77 65 72 28 2a 74 2b 2b 29 20 29 20 72 65 74 75  wer(*t++) ) retu
d4a0: 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75  rn 0;.  }.  retu
d4b0: 72 6e 20 2a 73 21 3d 27 5f 27 20 26 26 20 21 73  rn *s!='_' && !s
d4c0: 61 66 65 5f 69 73 61 6c 6e 75 6d 28 2a 73 29 3b  afe_isalnum(*s);
d4d0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73  .}../*.** An ins
d4e0: 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 73 74  tance of this st
d4f0: 72 75 63 74 75 72 65 20 64 65 66 69 6e 65 73 20  ructure defines 
d500: 74 68 65 20 22 73 70 65 63 22 20 6f 66 20 61 0a  the "spec" of a.
d510: 2a 2a 20 66 75 6c 6c 20 74 65 78 74 20 69 6e 64  ** full text ind
d520: 65 78 2e 20 20 54 68 69 73 20 73 74 72 75 63 74  ex.  This struct
d530: 75 72 65 20 69 73 20 70 6f 70 75 6c 61 74 65 64  ure is populated
d540: 20 62 79 20 70 61 72 73 65 53 70 65 63 0a 2a 2a   by parseSpec.**
d550: 20 61 6e 64 20 75 73 65 20 62 79 20 66 75 6c 6c   and use by full
d560: 74 65 78 74 43 6f 6e 6e 65 63 74 20 61 6e 64 20  textConnect and 
d570: 66 75 6c 6c 74 65 78 74 43 72 65 61 74 65 2e 0a  fulltextCreate..
d580: 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  */.typedef struc
d590: 74 20 54 61 62 6c 65 53 70 65 63 20 7b 0a 20 20  t TableSpec {.  
d5a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 3b  const char *zDb;
d5b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 67 69           /* Logi
d5c0: 63 61 6c 20 64 61 74 61 62 61 73 65 20 6e 61 6d  cal database nam
d5d0: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  e */.  const cha
d5e0: 72 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20  r *zName;       
d5f0: 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 66  /* Name of the f
d600: 75 6c 6c 2d 74 65 78 74 20 69 6e 64 65 78 20 2a  ull-text index *
d610: 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 75 6d 6e 3b  /.  int nColumn;
d620: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
d630: 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e  Number of column
d640: 73 20 74 6f 20 62 65 20 69 6e 64 65 78 65 64 20  s to be indexed 
d650: 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61 7a 43 6f  */.  char **azCo
d660: 6c 75 6d 6e 3b 20 20 20 20 20 20 20 20 20 2f 2a  lumn;         /*
d670: 20 4f 72 69 67 69 6e 61 6c 20 6e 61 6d 65 73 20   Original names 
d680: 6f 66 20 63 6f 6c 75 6d 6e 73 20 74 6f 20 62 65  of columns to be
d690: 20 69 6e 64 65 78 65 64 20 2a 2f 0a 20 20 63 68   indexed */.  ch
d6a0: 61 72 20 2a 2a 61 7a 43 6f 6e 74 65 6e 74 43 6f  ar **azContentCo
d6b0: 6c 75 6d 6e 3b 20 20 2f 2a 20 43 6f 6c 75 6d 6e  lumn;  /* Column
d6c0: 20 6e 61 6d 65 73 20 66 6f 72 20 25 5f 63 6f 6e   names for %_con
d6d0: 74 65 6e 74 20 2a 2f 0a 20 20 63 68 61 72 20 2a  tent */.  char *
d6e0: 2a 61 7a 54 6f 6b 65 6e 69 7a 65 72 3b 20 20 20  *azTokenizer;   
d6f0: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 6f     /* Name of to
d700: 6b 65 6e 69 7a 65 72 20 61 6e 64 20 69 74 73 20  kenizer and its 
d710: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 7d 20 54  arguments */.} T
d720: 61 62 6c 65 53 70 65 63 3b 0a 0a 2f 2a 0a 2a 2a  ableSpec;../*.**
d730: 20 52 65 63 6c 61 69 6d 20 61 6c 6c 20 6f 66 20   Reclaim all of 
d740: 74 68 65 20 6d 65 6d 6f 72 79 20 75 73 65 64 20  the memory used 
d750: 62 79 20 61 20 54 61 62 6c 65 53 70 65 63 0a 2a  by a TableSpec.*
d760: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 63 6c  /.static void cl
d770: 65 61 72 54 61 62 6c 65 53 70 65 63 28 54 61 62  earTableSpec(Tab
d780: 6c 65 53 70 65 63 20 2a 70 29 20 7b 0a 20 20 66  leSpec *p) {.  f
d790: 72 65 65 28 70 2d 3e 61 7a 43 6f 6c 75 6d 6e 29  ree(p->azColumn)
d7a0: 3b 0a 20 20 66 72 65 65 28 70 2d 3e 61 7a 43 6f  ;.  free(p->azCo
d7b0: 6e 74 65 6e 74 43 6f 6c 75 6d 6e 29 3b 0a 20 20  ntentColumn);.  
d7c0: 66 72 65 65 28 70 2d 3e 61 7a 54 6f 6b 65 6e 69  free(p->azTokeni
d7d0: 7a 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 72 73  zer);.}../* Pars
d7e0: 65 20 61 20 43 52 45 41 54 45 20 56 49 52 54 55  e a CREATE VIRTU
d7f0: 41 4c 20 54 41 42 4c 45 20 73 74 61 74 65 6d 65  AL TABLE stateme
d800: 6e 74 2c 20 77 68 69 63 68 20 6c 6f 6f 6b 73 20  nt, which looks 
d810: 6c 69 6b 65 20 74 68 69 73 3a 0a 20 2a 0a 20 2a  like this:. *. *
d820: 20 43 52 45 41 54 45 20 56 49 52 54 55 41 4c 20   CREATE VIRTUAL 
d830: 54 41 42 4c 45 20 65 6d 61 69 6c 0a 20 2a 20 20  TABLE email. *  
d840: 20 20 20 20 20 20 55 53 49 4e 47 20 66 74 73 31        USING fts1
d850: 28 73 75 62 6a 65 63 74 2c 20 62 6f 64 79 2c 20  (subject, body, 
d860: 74 6f 6b 65 6e 69 7a 65 20 6d 79 74 6f 6b 65 6e  tokenize mytoken
d870: 69 7a 65 72 28 6d 79 61 72 67 29 29 0a 20 2a 0a  izer(myarg)). *.
d880: 20 2a 20 57 65 20 72 65 74 75 72 6e 20 70 61 72   * We return par
d890: 73 65 64 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  sed information 
d8a0: 69 6e 20 61 20 54 61 62 6c 65 53 70 65 63 20 73  in a TableSpec s
d8b0: 74 72 75 63 74 75 72 65 2e 0a 20 2a 20 0a 20 2a  tructure.. * . *
d8c0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 61 72  /.static int par
d8d0: 73 65 53 70 65 63 28 54 61 62 6c 65 53 70 65 63  seSpec(TableSpec
d8e0: 20 2a 70 53 70 65 63 2c 20 69 6e 74 20 61 72 67   *pSpec, int arg
d8f0: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  c, const char *c
d900: 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 20 20 20  onst*argv,.     
d910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d920: 63 68 61 72 2a 2a 70 7a 45 72 72 29 7b 0a 20 20  char**pzErr){.  
d930: 69 6e 74 20 69 2c 20 6e 3b 0a 20 20 63 68 61 72  int i, n;.  char
d940: 20 2a 7a 2c 20 2a 7a 44 75 6d 6d 79 3b 0a 20 20   *z, *zDummy;.  
d950: 63 68 61 72 20 2a 2a 61 7a 41 72 67 3b 0a 20 20  char **azArg;.  
d960: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 6f 6b  const char *zTok
d970: 65 6e 69 7a 65 72 20 3d 20 30 3b 20 20 20 20 2f  enizer = 0;    /
d980: 2a 20 61 72 67 76 5b 5d 20 65 6e 74 72 79 20 64  * argv[] entry d
d990: 65 73 63 72 69 62 69 6e 67 20 74 68 65 20 74 6f  escribing the to
d9a0: 6b 65 6e 69 7a 65 72 20 2a 2f 0a 0a 20 20 61 73  kenizer */..  as
d9b0: 73 65 72 74 28 20 61 72 67 63 3e 3d 33 20 29 3b  sert( argc>=3 );
d9c0: 0a 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e  .  /* Current in
d9d0: 74 65 72 66 61 63 65 3a 0a 20 20 2a 2a 20 61 72  terface:.  ** ar
d9e0: 67 76 5b 30 5d 20 2d 20 6d 6f 64 75 6c 65 20 6e  gv[0] - module n
d9f0: 61 6d 65 0a 20 20 2a 2a 20 61 72 67 76 5b 31 5d  ame.  ** argv[1]
da00: 20 2d 20 64 61 74 61 62 61 73 65 20 6e 61 6d 65   - database name
da10: 0a 20 20 2a 2a 20 61 72 67 76 5b 32 5d 20 2d 20  .  ** argv[2] - 
da20: 74 61 62 6c 65 20 6e 61 6d 65 0a 20 20 2a 2a 20  table name.  ** 
da30: 61 72 67 76 5b 33 2e 2e 5d 20 2d 20 63 6f 6c 75  argv[3..] - colu
da40: 6d 6e 73 2c 20 6f 70 74 69 6f 6e 61 6c 6c 79 20  mns, optionally 
da50: 66 6f 6c 6c 6f 77 65 64 20 62 79 20 74 6f 6b 65  followed by toke
da60: 6e 69 7a 65 72 20 73 70 65 63 69 66 69 63 61 74  nizer specificat
da70: 69 6f 6e 0a 20 20 2a 2a 20 20 20 20 20 20 20 20  ion.  **        
da80: 20 20 20 20 20 61 6e 64 20 73 6e 69 70 70 65 74       and snippet
da90: 20 64 65 6c 69 6d 69 74 65 72 73 20 73 70 65 63   delimiters spec
daa0: 69 66 69 63 61 74 69 6f 6e 2e 0a 20 20 2a 2f 0a  ification..  */.
dab0: 0a 20 20 2f 2a 20 4d 61 6b 65 20 61 20 63 6f 70  .  /* Make a cop
dac0: 79 20 6f 66 20 74 68 65 20 63 6f 6d 70 6c 65 74  y of the complet
dad0: 65 20 61 72 67 76 5b 5d 5b 5d 20 61 72 72 61 79  e argv[][] array
dae0: 20 69 6e 20 61 20 73 69 6e 67 6c 65 20 61 6c 6c   in a single all
daf0: 6f 63 61 74 69 6f 6e 2e 0a 20 20 2a 2a 20 54 68  ocation..  ** Th
db00: 65 20 61 72 67 76 5b 5d 5b 5d 20 61 72 72 61 79  e argv[][] array
db10: 20 69 73 20 72 65 61 64 2d 6f 6e 6c 79 20 61 6e   is read-only an
db20: 64 20 74 72 61 6e 73 69 65 6e 74 2e 20 20 57 65  d transient.  We
db30: 20 63 61 6e 20 77 72 69 74 65 20 74 6f 20 74 68   can write to th
db40: 65 0a 20 20 2a 2a 20 63 6f 70 79 20 69 6e 20 6f  e.  ** copy in o
db50: 72 64 65 72 20 74 6f 20 6d 6f 64 69 66 79 20 74  rder to modify t
db60: 68 69 6e 67 73 20 61 6e 64 20 74 68 65 20 63 6f  hings and the co
db70: 70 79 20 69 73 20 70 65 72 73 69 73 74 65 6e 74  py is persistent
db80: 2e 0a 20 20 2a 2f 0a 20 20 6d 65 6d 73 65 74 28  ..  */.  memset(
db90: 70 53 70 65 63 2c 20 30 2c 20 73 69 7a 65 6f 66  pSpec, 0, sizeof
dba0: 28 2a 70 53 70 65 63 29 29 3b 0a 20 20 66 6f 72  (*pSpec));.  for
dbb0: 28 69 3d 6e 3d 30 3b 20 69 3c 61 72 67 63 3b 20  (i=n=0; i<argc; 
dbc0: 69 2b 2b 29 7b 0a 20 20 20 20 6e 20 2b 3d 20 73  i++){.    n += s
dbd0: 74 72 6c 65 6e 28 61 72 67 76 5b 69 5d 29 20 2b  trlen(argv[i]) +
dbe0: 20 31 3b 0a 20 20 7d 0a 20 20 61 7a 41 72 67 20   1;.  }.  azArg 
dbf0: 3d 20 6d 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66  = malloc( sizeof
dc00: 28 63 68 61 72 2a 29 2a 61 72 67 63 20 2b 20 6e  (char*)*argc + n
dc10: 20 29 3b 0a 20 20 69 66 28 20 61 7a 41 72 67 3d   );.  if( azArg=
dc20: 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  =0 ){.    return
dc30: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
dc40: 20 7d 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a 29   }.  z = (char*)
dc50: 26 61 7a 41 72 67 5b 61 72 67 63 5d 3b 0a 20 20  &azArg[argc];.  
dc60: 66 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b  for(i=0; i<argc;
dc70: 20 69 2b 2b 29 7b 0a 20 20 20 20 61 7a 41 72 67   i++){.    azArg
dc80: 5b 69 5d 20 3d 20 7a 3b 0a 20 20 20 20 73 74 72  [i] = z;.    str
dc90: 63 70 79 28 7a 2c 20 61 72 67 76 5b 69 5d 29 3b  cpy(z, argv[i]);
dca0: 0a 20 20 20 20 7a 20 2b 3d 20 73 74 72 6c 65 6e  .    z += strlen
dcb0: 28 7a 29 2b 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  (z)+1;.  }..  /*
dcc0: 20 49 64 65 6e 74 69 66 79 20 74 68 65 20 63 6f   Identify the co
dcd0: 6c 75 6d 6e 20 6e 61 6d 65 73 20 61 6e 64 20 74  lumn names and t
dce0: 68 65 20 74 6f 6b 65 6e 69 7a 65 72 20 61 6e 64  he tokenizer and
dcf0: 20 64 65 6c 69 6d 69 74 65 72 20 61 72 67 75 6d   delimiter argum
dd00: 65 6e 74 73 0a 20 20 2a 2a 20 69 6e 20 74 68 65  ents.  ** in the
dd10: 20 61 72 67 76 5b 5d 5b 5d 20 61 72 72 61 79 2e   argv[][] array.
dd20: 0a 20 20 2a 2f 0a 20 20 70 53 70 65 63 2d 3e 7a  .  */.  pSpec->z
dd30: 44 62 20 3d 20 61 7a 41 72 67 5b 31 5d 3b 0a 20  Db = azArg[1];. 
dd40: 20 70 53 70 65 63 2d 3e 7a 4e 61 6d 65 20 3d 20   pSpec->zName = 
dd50: 61 7a 41 72 67 5b 32 5d 3b 0a 20 20 70 53 70 65  azArg[2];.  pSpe
dd60: 63 2d 3e 6e 43 6f 6c 75 6d 6e 20 3d 20 30 3b 0a  c->nColumn = 0;.
dd70: 20 20 70 53 70 65 63 2d 3e 61 7a 43 6f 6c 75 6d    pSpec->azColum
dd80: 6e 20 3d 20 61 7a 41 72 67 3b 0a 20 20 7a 54 6f  n = azArg;.  zTo
dd90: 6b 65 6e 69 7a 65 72 20 3d 20 22 74 6f 6b 65 6e  kenizer = "token
dda0: 69 7a 65 20 73 69 6d 70 6c 65 22 3b 0a 20 20 66  ize simple";.  f
ddb0: 6f 72 28 69 3d 33 3b 20 69 3c 61 72 67 63 3b 20  or(i=3; i<argc; 
ddc0: 2b 2b 69 29 7b 0a 20 20 20 20 69 66 28 20 73 74  ++i){.    if( st
ddd0: 61 72 74 73 57 69 74 68 28 61 7a 41 72 67 5b 69  artsWith(azArg[i
dde0: 5d 2c 22 74 6f 6b 65 6e 69 7a 65 22 29 20 29 7b  ],"tokenize") ){
ddf0: 0a 20 20 20 20 20 20 7a 54 6f 6b 65 6e 69 7a 65  .      zTokenize
de00: 72 20 3d 20 61 7a 41 72 67 5b 69 5d 3b 0a 20 20  r = azArg[i];.  
de10: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a    }else{.      z
de20: 20 3d 20 61 7a 41 72 67 5b 70 53 70 65 63 2d 3e   = azArg[pSpec->
de30: 6e 43 6f 6c 75 6d 6e 5d 20 3d 20 66 69 72 73 74  nColumn] = first
de40: 54 6f 6b 65 6e 28 61 7a 41 72 67 5b 69 5d 2c 20  Token(azArg[i], 
de50: 26 7a 44 75 6d 6d 79 29 3b 0a 20 20 20 20 20 20  &zDummy);.      
de60: 70 53 70 65 63 2d 3e 6e 43 6f 6c 75 6d 6e 2b 2b  pSpec->nColumn++
de70: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ;.    }.  }.  if
de80: 28 20 70 53 70 65 63 2d 3e 6e 43 6f 6c 75 6d 6e  ( pSpec->nColumn
de90: 3d 3d 30 20 29 7b 0a 20 20 20 20 61 7a 41 72 67  ==0 ){.    azArg
dea0: 5b 30 5d 20 3d 20 22 63 6f 6e 74 65 6e 74 22 3b  [0] = "content";
deb0: 0a 20 20 20 20 70 53 70 65 63 2d 3e 6e 43 6f 6c  .    pSpec->nCol
dec0: 75 6d 6e 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20  umn = 1;.  }..  
ded0: 2f 2a 0a 20 20 2a 2a 20 43 6f 6e 73 74 72 75 63  /*.  ** Construc
dee0: 74 20 74 68 65 20 6c 69 73 74 20 6f 66 20 63 6f  t the list of co
def0: 6e 74 65 6e 74 20 63 6f 6c 75 6d 6e 20 6e 61 6d  ntent column nam
df00: 65 73 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 45 61  es..  **.  ** Ea
df10: 63 68 20 63 6f 6e 74 65 6e 74 20 63 6f 6c 75 6d  ch content colum
df20: 6e 20 6e 61 6d 65 20 77 69 6c 6c 20 62 65 20 6f  n name will be o
df30: 66 20 74 68 65 20 66 6f 72 6d 20 63 4e 4e 41 41  f the form cNNAA
df40: 41 41 0a 20 20 2a 2a 20 77 68 65 72 65 20 4e 4e  AA.  ** where NN
df50: 20 69 73 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e   is the column n
df60: 75 6d 62 65 72 20 61 6e 64 20 41 41 41 41 20 69  umber and AAAA i
df70: 73 20 74 68 65 20 73 61 6e 69 74 69 7a 65 64 0a  s the sanitized.
df80: 20 20 2a 2a 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65    ** column name
df90: 2e 20 20 22 73 61 6e 69 74 69 7a 65 64 22 20 6d  .  "sanitized" m
dfa0: 65 61 6e 73 20 74 68 61 74 20 73 70 65 63 69 61  eans that specia
dfb0: 6c 20 63 68 61 72 61 63 74 65 72 73 20 61 72 65  l characters are
dfc0: 0a 20 20 2a 2a 20 63 6f 6e 76 65 72 74 65 64 20  .  ** converted 
dfd0: 74 6f 20 22 5f 22 2e 20 20 54 68 65 20 63 4e 4e  to "_".  The cNN
dfe0: 20 70 72 65 66 69 78 20 67 75 61 72 61 6e 74 65   prefix guarante
dff0: 65 73 20 74 68 61 74 20 61 6c 6c 20 63 6f 6c 75  es that all colu
e000: 6d 6e 0a 20 20 2a 2a 20 6e 61 6d 65 73 20 61 72  mn.  ** names ar
e010: 65 20 75 6e 69 71 75 65 2e 0a 20 20 2a 2a 0a 20  e unique..  **. 
e020: 20 2a 2a 20 54 68 65 20 41 41 41 41 20 73 75 66   ** The AAAA suf
e030: 66 69 78 20 69 73 20 6e 6f 74 20 73 74 72 69 63  fix is not stric
e040: 74 6c 79 20 6e 65 63 65 73 73 61 72 79 2e 20 20  tly necessary.  
e050: 49 74 20 69 73 20 69 6e 63 6c 75 64 65 64 0a 20  It is included. 
e060: 20 2a 2a 20 66 6f 72 20 74 68 65 20 63 6f 6e 76   ** for the conv
e070: 65 6e 69 65 6e 63 65 20 6f 66 20 70 65 6f 70 6c  enience of peopl
e080: 65 20 77 68 6f 20 6d 69 67 68 74 20 65 78 61 6d  e who might exam
e090: 69 6e 65 20 74 68 65 20 67 65 6e 65 72 61 74 65  ine the generate
e0a0: 64 0a 20 20 2a 2a 20 25 5f 63 6f 6e 74 65 6e 74  d.  ** %_content
e0b0: 20 74 61 62 6c 65 20 61 6e 64 20 77 6f 6e 64 65   table and wonde
e0c0: 72 20 77 68 61 74 20 74 68 65 20 63 6f 6c 75 6d  r what the colum
e0d0: 6e 73 20 61 72 65 20 75 73 65 64 20 66 6f 72 2e  ns are used for.
e0e0: 0a 20 20 2a 2f 0a 20 20 70 53 70 65 63 2d 3e 61  .  */.  pSpec->a
e0f0: 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 20 3d  zContentColumn =
e100: 20 6d 61 6c 6c 6f 63 28 20 70 53 70 65 63 2d 3e   malloc( pSpec->
e110: 6e 43 6f 6c 75 6d 6e 20 2a 20 73 69 7a 65 6f 66  nColumn * sizeof
e120: 28 63 68 61 72 20 2a 29 20 29 3b 0a 20 20 69 66  (char *) );.  if
e130: 28 20 70 53 70 65 63 2d 3e 61 7a 43 6f 6e 74 65  ( pSpec->azConte
e140: 6e 74 43 6f 6c 75 6d 6e 3d 3d 30 20 29 7b 0a 20  ntColumn==0 ){. 
e150: 20 20 20 63 6c 65 61 72 54 61 62 6c 65 53 70 65     clearTableSpe
e160: 63 28 70 53 70 65 63 29 3b 0a 20 20 20 20 72 65  c(pSpec);.    re
e170: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
e180: 4d 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d 30  M;.  }.  for(i=0
e190: 3b 20 69 3c 70 53 70 65 63 2d 3e 6e 43 6f 6c 75  ; i<pSpec->nColu
e1a0: 6d 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 63 68  mn; i++){.    ch
e1b0: 61 72 20 2a 70 3b 0a 20 20 20 20 70 53 70 65 63  ar *p;.    pSpec
e1c0: 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d  ->azContentColum
e1d0: 6e 5b 69 5d 20 3d 20 73 71 6c 69 74 65 33 5f 6d  n[i] = sqlite3_m
e1e0: 70 72 69 6e 74 66 28 22 63 25 64 25 73 22 2c 20  printf("c%d%s", 
e1f0: 69 2c 20 61 7a 41 72 67 5b 69 5d 29 3b 0a 20 20  i, azArg[i]);.  
e200: 20 20 66 6f 72 20 28 70 20 3d 20 70 53 70 65 63    for (p = pSpec
e210: 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d  ->azContentColum
e220: 6e 5b 69 5d 3b 20 2a 70 20 3b 20 2b 2b 70 29 20  n[i]; *p ; ++p) 
e230: 7b 0a 20 20 20 20 20 20 69 66 28 20 21 73 61 66  {.      if( !saf
e240: 65 5f 69 73 61 6c 6e 75 6d 28 2a 70 29 20 29 20  e_isalnum(*p) ) 
e250: 2a 70 20 3d 20 27 5f 27 3b 0a 20 20 20 20 7d 0a  *p = '_';.    }.
e260: 20 20 7d 0a 0a 20 20 2f 2a 0a 20 20 2a 2a 20 50    }..  /*.  ** P
e270: 61 72 73 65 20 74 68 65 20 74 6f 6b 65 6e 69 7a  arse the tokeniz
e280: 65 72 20 73 70 65 63 69 66 69 63 61 74 69 6f 6e  er specification
e290: 20 73 74 72 69 6e 67 2e 0a 20 20 2a 2f 0a 20 20   string..  */.  
e2a0: 70 53 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e 69 7a  pSpec->azTokeniz
e2b0: 65 72 20 3d 20 74 6f 6b 65 6e 69 7a 65 53 74 72  er = tokenizeStr
e2c0: 69 6e 67 28 7a 54 6f 6b 65 6e 69 7a 65 72 2c 20  ing(zTokenizer, 
e2d0: 26 6e 29 3b 0a 20 20 74 6f 6b 65 6e 4c 69 73 74  &n);.  tokenList
e2e0: 54 6f 49 64 4c 69 73 74 28 70 53 70 65 63 2d 3e  ToIdList(pSpec->
e2f0: 61 7a 54 6f 6b 65 6e 69 7a 65 72 29 3b 0a 0a 20  azTokenizer);.. 
e300: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
e310: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65  K;.}../*.** Gene
e320: 72 61 74 65 20 61 20 43 52 45 41 54 45 20 54 41  rate a CREATE TA
e330: 42 4c 45 20 73 74 61 74 65 6d 65 6e 74 20 74 68  BLE statement th
e340: 61 74 20 64 65 73 63 72 69 62 65 73 20 74 68 65  at describes the
e350: 20 73 63 68 65 6d 61 20 6f 66 0a 2a 2a 20 74 68   schema of.** th
e360: 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e  e virtual table.
e370: 20 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74    Return a point
e380: 65 72 20 74 6f 20 74 68 69 73 20 73 63 68 65 6d  er to this schem
e390: 61 20 73 74 72 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20  a string..**.** 
e3a0: 53 70 61 63 65 20 69 73 20 6f 62 74 61 69 6e 65  Space is obtaine
e3b0: 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 5f 6d  d from sqlite3_m
e3c0: 70 72 69 6e 74 66 28 29 20 61 6e 64 20 73 68 6f  printf() and sho
e3d0: 75 6c 64 20 62 65 20 66 72 65 65 64 0a 2a 2a 20  uld be freed.** 
e3e0: 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 66 72  using sqlite3_fr
e3f0: 65 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ee()..*/.static 
e400: 63 68 61 72 20 2a 66 75 6c 6c 74 65 78 74 53 63  char *fulltextSc
e410: 68 65 6d 61 28 0a 20 20 69 6e 74 20 6e 43 6f 6c  hema(.  int nCol
e420: 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  umn,            
e430: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
e440: 6f 66 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20  of columns */.  
e450: 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e 73  const char *cons
e460: 74 2a 20 61 7a 43 6f 6c 75 6d 6e 2c 20 20 2f 2a  t* azColumn,  /*
e470: 20 4c 69 73 74 20 6f 66 20 63 6f 6c 75 6d 6e 73   List of columns
e480: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
e490: 20 2a 7a 54 61 62 6c 65 4e 61 6d 65 20 20 20 20   *zTableName    
e4a0: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74      /* Name of t
e4b0: 68 65 20 74 61 62 6c 65 20 2a 2f 0a 29 7b 0a 20  he table */.){. 
e4c0: 20 69 6e 74 20 69 3b 0a 20 20 63 68 61 72 20 2a   int i;.  char *
e4d0: 7a 53 63 68 65 6d 61 2c 20 2a 7a 4e 65 78 74 3b  zSchema, *zNext;
e4e0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
e4f0: 53 65 70 20 3d 20 22 28 22 3b 0a 20 20 7a 53 63  Sep = "(";.  zSc
e500: 68 65 6d 61 20 3d 20 73 71 6c 69 74 65 33 5f 6d  hema = sqlite3_m
e510: 70 72 69 6e 74 66 28 22 43 52 45 41 54 45 20 54  printf("CREATE T
e520: 41 42 4c 45 20 78 22 29 3b 0a 20 20 66 6f 72 28  ABLE x");.  for(
e530: 69 3d 30 3b 20 69 3c 6e 43 6f 6c 75 6d 6e 3b 20  i=0; i<nColumn; 
e540: 69 2b 2b 29 7b 0a 20 20 20 20 7a 4e 65 78 74 20  i++){.    zNext 
e550: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
e560: 66 28 22 25 73 25 73 25 51 22 2c 20 7a 53 63 68  f("%s%s%Q", zSch
e570: 65 6d 61 2c 20 7a 53 65 70 2c 20 61 7a 43 6f 6c  ema, zSep, azCol
e580: 75 6d 6e 5b 69 5d 29 3b 0a 20 20 20 20 73 71 6c  umn[i]);.    sql
e590: 69 74 65 33 5f 66 72 65 65 28 7a 53 63 68 65 6d  ite3_free(zSchem
e5a0: 61 29 3b 0a 20 20 20 20 7a 53 63 68 65 6d 61 20  a);.    zSchema 
e5b0: 3d 20 7a 4e 65 78 74 3b 0a 20 20 20 20 7a 53 65  = zNext;.    zSe
e5c0: 70 20 3d 20 22 2c 22 3b 0a 20 20 7d 0a 20 20 7a  p = ",";.  }.  z
e5d0: 4e 65 78 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d  Next = sqlite3_m
e5e0: 70 72 69 6e 74 66 28 22 25 73 2c 25 51 29 22 2c  printf("%s,%Q)",
e5f0: 20 7a 53 63 68 65 6d 61 2c 20 7a 54 61 62 6c 65   zSchema, zTable
e600: 4e 61 6d 65 29 3b 0a 20 20 73 71 6c 69 74 65 33  Name);.  sqlite3
e610: 5f 66 72 65 65 28 7a 53 63 68 65 6d 61 29 3b 0a  _free(zSchema);.
e620: 20 20 72 65 74 75 72 6e 20 7a 4e 65 78 74 3b 0a    return zNext;.
e630: 7d 0a 0a 2f 2a 0a 2a 2a 20 42 75 69 6c 64 20 61  }../*.** Build a
e640: 20 6e 65 77 20 73 71 6c 69 74 65 33 5f 76 74 61   new sqlite3_vta
e650: 62 20 73 74 72 75 63 74 75 72 65 20 74 68 61 74  b structure that
e660: 20 77 69 6c 6c 20 64 65 73 63 72 69 62 65 20 74   will describe t
e670: 68 65 0a 2a 2a 20 66 75 6c 6c 74 65 78 74 20 69  he.** fulltext i
e680: 6e 64 65 78 20 64 65 66 69 6e 65 64 20 62 79 20  ndex defined by 
e690: 73 70 65 63 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  spec..*/.static 
e6a0: 69 6e 74 20 63 6f 6e 73 74 72 75 63 74 56 74 61  int constructVta
e6b0: 62 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  b(.  sqlite3 *db
e6c0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
e6d0: 2a 20 54 68 65 20 53 51 4c 69 74 65 20 64 61 74  * The SQLite dat
e6e0: 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e  abase connection
e6f0: 20 2a 2f 0a 20 20 54 61 62 6c 65 53 70 65 63 20   */.  TableSpec 
e700: 2a 73 70 65 63 2c 20 20 20 20 20 20 20 20 20 20  *spec,          
e710: 2f 2a 20 50 61 72 73 65 64 20 73 70 65 63 20 69  /* Parsed spec i
e720: 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 72 6f 6d 20  nformation from 
e730: 70 61 72 73 65 53 70 65 63 28 29 20 2a 2f 0a 20  parseSpec() */. 
e740: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a   sqlite3_vtab **
e750: 70 70 56 54 61 62 2c 20 20 20 20 2f 2a 20 57 72  ppVTab,    /* Wr
e760: 69 74 65 20 74 68 65 20 72 65 73 75 6c 74 69 6e  ite the resultin
e770: 67 20 76 74 61 62 20 73 74 72 75 63 74 75 72 65  g vtab structure
e780: 20 68 65 72 65 20 2a 2f 0a 20 20 63 68 61 72 20   here */.  char 
e790: 2a 2a 70 7a 45 72 72 20 20 20 20 20 20 20 20 20  **pzErr         
e7a0: 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 61 6e       /* Write an
e7b0: 79 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 20  y error message 
e7c0: 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  here */.){.  int
e7d0: 20 72 63 3b 0a 20 20 69 6e 74 20 6e 3b 0a 20 20   rc;.  int n;.  
e7e0: 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
e7f0: 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20 73 71   = 0;.  const sq
e800: 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f  lite3_tokenizer_
e810: 6d 6f 64 75 6c 65 20 2a 6d 20 3d 20 4e 55 4c 4c  module *m = NULL
e820: 3b 0a 20 20 63 68 61 72 20 2a 73 63 68 65 6d 61  ;.  char *schema
e830: 3b 0a 0a 20 20 76 20 3d 20 28 66 75 6c 6c 74 65  ;..  v = (fullte
e840: 78 74 5f 76 74 61 62 20 2a 29 20 6d 61 6c 6c 6f  xt_vtab *) mallo
e850: 63 28 73 69 7a 65 6f 66 28 66 75 6c 6c 74 65 78  c(sizeof(fulltex
e860: 74 5f 76 74 61 62 29 29 3b 0a 20 20 69 66 28 20  t_vtab));.  if( 
e870: 76 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  v==0 ) return SQ
e880: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65  LITE_NOMEM;.  me
e890: 6d 73 65 74 28 76 2c 20 30 2c 20 73 69 7a 65 6f  mset(v, 0, sizeo
e8a0: 66 28 2a 76 29 29 3b 0a 20 20 2f 2a 20 73 71 6c  f(*v));.  /* sql
e8b0: 69 74 65 20 77 69 6c 6c 20 69 6e 69 74 69 61 6c  ite will initial
e8c0: 69 7a 65 20 76 2d 3e 62 61 73 65 20 2a 2f 0a 20  ize v->base */. 
e8d0: 20 76 2d 3e 64 62 20 3d 20 64 62 3b 0a 20 20 76   v->db = db;.  v
e8e0: 2d 3e 7a 44 62 20 3d 20 73 70 65 63 2d 3e 7a 44  ->zDb = spec->zD
e8f0: 62 3b 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65  b;       /* Free
e900: 64 20 77 68 65 6e 20 61 7a 43 6f 6c 75 6d 6e 20  d when azColumn 
e910: 69 73 20 66 72 65 65 64 20 2a 2f 0a 20 20 76 2d  is freed */.  v-
e920: 3e 7a 4e 61 6d 65 20 3d 20 73 70 65 63 2d 3e 7a  >zName = spec->z
e930: 4e 61 6d 65 3b 20 20 20 2f 2a 20 46 72 65 65 64  Name;   /* Freed
e940: 20 77 68 65 6e 20 61 7a 43 6f 6c 75 6d 6e 20 69   when azColumn i
e950: 73 20 66 72 65 65 64 20 2a 2f 0a 20 20 76 2d 3e  s freed */.  v->
e960: 6e 43 6f 6c 75 6d 6e 20 3d 20 73 70 65 63 2d 3e  nColumn = spec->
e970: 6e 43 6f 6c 75 6d 6e 3b 0a 20 20 76 2d 3e 61 7a  nColumn;.  v->az
e980: 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 20 3d 20  ContentColumn = 
e990: 73 70 65 63 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43  spec->azContentC
e9a0: 6f 6c 75 6d 6e 3b 0a 20 20 73 70 65 63 2d 3e 61  olumn;.  spec->a
e9b0: 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 20 3d  zContentColumn =
e9c0: 20 30 3b 0a 20 20 76 2d 3e 61 7a 43 6f 6c 75 6d   0;.  v->azColum
e9d0: 6e 20 3d 20 73 70 65 63 2d 3e 61 7a 43 6f 6c 75  n = spec->azColu
e9e0: 6d 6e 3b 0a 20 20 73 70 65 63 2d 3e 61 7a 43 6f  mn;.  spec->azCo
e9f0: 6c 75 6d 6e 20 3d 20 30 3b 0a 0a 20 20 69 66 28  lumn = 0;..  if(
ea00: 20 73 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e 69 7a   spec->azTokeniz
ea10: 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  er==0 ){.    ret
ea20: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
ea30: 3b 0a 20 20 7d 0a 20 20 2f 2a 20 54 4f 44 4f 28  ;.  }.  /* TODO(
ea40: 73 68 65 73 73 29 20 46 6f 72 20 6e 6f 77 2c 20  shess) For now, 
ea50: 61 64 64 20 6e 65 77 20 74 6f 6b 65 6e 69 7a 65  add new tokenize
ea60: 72 73 20 61 73 20 65 6c 73 65 20 69 66 20 63 6c  rs as else if cl
ea70: 61 75 73 65 73 2e 20 2a 2f 0a 20 20 69 66 28 20  auses. */.  if( 
ea80: 73 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e 69 7a 65  spec->azTokenize
ea90: 72 5b 30 5d 3d 3d 30 20 7c 7c 20 73 74 61 72 74  r[0]==0 || start
eaa0: 73 57 69 74 68 28 73 70 65 63 2d 3e 61 7a 54 6f  sWith(spec->azTo
eab0: 6b 65 6e 69 7a 65 72 5b 30 5d 2c 20 22 73 69 6d  kenizer[0], "sim
eac0: 70 6c 65 22 29 20 29 7b 0a 20 20 20 20 73 71 6c  ple") ){.    sql
ead0: 69 74 65 33 46 74 73 31 53 69 6d 70 6c 65 54 6f  ite3Fts1SimpleTo
eae0: 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 28 26 6d  kenizerModule(&m
eaf0: 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 73  );.  }else if( s
eb00: 74 61 72 74 73 57 69 74 68 28 73 70 65 63 2d 3e  tartsWith(spec->
eb10: 61 7a 54 6f 6b 65 6e 69 7a 65 72 5b 30 5d 2c 20  azTokenizer[0], 
eb20: 22 70 6f 72 74 65 72 22 29 20 29 7b 0a 20 20 20  "porter") ){.   
eb30: 20 73 71 6c 69 74 65 33 46 74 73 31 50 6f 72 74   sqlite3Fts1Port
eb40: 65 72 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c  erTokenizerModul
eb50: 65 28 26 6d 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  e(&m);.  }else{.
eb60: 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c      *pzErr = sql
eb70: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 75 6e  ite3_mprintf("un
eb80: 6b 6e 6f 77 6e 20 74 6f 6b 65 6e 69 7a 65 72 3a  known tokenizer:
eb90: 20 25 73 22 2c 20 73 70 65 63 2d 3e 61 7a 54 6f   %s", spec->azTo
eba0: 6b 65 6e 69 7a 65 72 5b 30 5d 29 3b 0a 20 20 20  kenizer[0]);.   
ebb0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52   rc = SQLITE_ERR
ebc0: 4f 52 3b 0a 20 20 20 20 67 6f 74 6f 20 65 72 72  OR;.    goto err
ebd0: 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 6e 3d 30 3b  ;.  }.  for(n=0;
ebe0: 20 73 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e 69 7a   spec->azTokeniz
ebf0: 65 72 5b 6e 5d 3b 20 6e 2b 2b 29 7b 7d 0a 20 20  er[n]; n++){}.  
ec00: 69 66 28 20 6e 20 29 7b 0a 20 20 20 20 72 63 20  if( n ){.    rc 
ec10: 3d 20 6d 2d 3e 78 43 72 65 61 74 65 28 6e 2d 31  = m->xCreate(n-1
ec20: 2c 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 63 6f  , (const char*co
ec30: 6e 73 74 2a 29 26 73 70 65 63 2d 3e 61 7a 54 6f  nst*)&spec->azTo
ec40: 6b 65 6e 69 7a 65 72 5b 31 5d 2c 0a 20 20 20 20  kenizer[1],.    
ec50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ec60: 26 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72 29 3b  &v->pTokenizer);
ec70: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63  .  }else{.    rc
ec80: 20 3d 20 6d 2d 3e 78 43 72 65 61 74 65 28 30 2c   = m->xCreate(0,
ec90: 20 30 2c 20 26 76 2d 3e 70 54 6f 6b 65 6e 69 7a   0, &v->pTokeniz
eca0: 65 72 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72  er);.  }.  if( r
ecb0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67  c!=SQLITE_OK ) g
ecc0: 6f 74 6f 20 65 72 72 3b 0a 20 20 76 2d 3e 70 54  oto err;.  v->pT
ecd0: 6f 6b 65 6e 69 7a 65 72 2d 3e 70 4d 6f 64 75 6c  okenizer->pModul
ece0: 65 20 3d 20 6d 3b 0a 0a 20 20 2f 2a 20 54 4f 44  e = m;..  /* TOD
ecf0: 4f 3a 20 76 65 72 69 66 79 20 74 68 65 20 65 78  O: verify the ex
ed00: 69 73 74 65 6e 63 65 20 6f 66 20 62 61 63 6b 69  istence of backi
ed10: 6e 67 20 74 61 62 6c 65 73 20 66 6f 6f 5f 63 6f  ng tables foo_co
ed20: 6e 74 65 6e 74 2c 20 66 6f 6f 5f 74 65 72 6d 20  ntent, foo_term 
ed30: 2a 2f 0a 0a 20 20 73 63 68 65 6d 61 20 3d 20 66  */..  schema = f
ed40: 75 6c 6c 74 65 78 74 53 63 68 65 6d 61 28 76 2d  ulltextSchema(v-
ed50: 3e 6e 43 6f 6c 75 6d 6e 2c 20 28 63 6f 6e 73 74  >nColumn, (const
ed60: 20 63 68 61 72 2a 63 6f 6e 73 74 2a 29 76 2d 3e   char*const*)v->
ed70: 61 7a 43 6f 6c 75 6d 6e 2c 0a 20 20 20 20 20 20  azColumn,.      
ed80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ed90: 20 20 20 20 73 70 65 63 2d 3e 7a 4e 61 6d 65 29      spec->zName)
eda0: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
edb0: 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 64 62  _declare_vtab(db
edc0: 2c 20 73 63 68 65 6d 61 29 3b 0a 20 20 73 71 6c  , schema);.  sql
edd0: 69 74 65 33 5f 66 72 65 65 28 73 63 68 65 6d 61  ite3_free(schema
ede0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
edf0: 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 65 72  ITE_OK ) goto er
ee00: 72 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 76 2d 3e  r;..  memset(v->
ee10: 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d 65  pFulltextStateme
ee20: 6e 74 73 2c 20 30 2c 20 73 69 7a 65 6f 66 28 76  nts, 0, sizeof(v
ee30: 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65  ->pFulltextState
ee40: 6d 65 6e 74 73 29 29 3b 0a 0a 20 20 2a 70 70 56  ments));..  *ppV
ee50: 54 61 62 20 3d 20 26 76 2d 3e 62 61 73 65 3b 0a  Tab = &v->base;.
ee60: 20 20 54 52 41 43 45 28 28 22 46 54 53 31 20 43    TRACE(("FTS1 C
ee70: 6f 6e 6e 65 63 74 20 25 70 5c 6e 22 2c 20 76 29  onnect %p\n", v)
ee80: 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  );..  return rc;
ee90: 0a 0a 65 72 72 3a 0a 20 20 66 75 6c 6c 74 65 78  ..err:.  fulltex
eea0: 74 5f 76 74 61 62 5f 64 65 73 74 72 6f 79 28 76  t_vtab_destroy(v
eeb0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
eec0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75  }..static int fu
eed0: 6c 6c 74 65 78 74 43 6f 6e 6e 65 63 74 28 0a 20  lltextConnect(. 
eee0: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
eef0: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
ef00: 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68  t argc, const ch
ef10: 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a  ar *const*argv,.
ef20: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
ef30: 2a 70 70 56 54 61 62 2c 0a 20 20 63 68 61 72 20  *ppVTab,.  char 
ef40: 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 54 61 62  **pzErr.){.  Tab
ef50: 6c 65 53 70 65 63 20 73 70 65 63 3b 0a 20 20 69  leSpec spec;.  i
ef60: 6e 74 20 72 63 20 3d 20 70 61 72 73 65 53 70 65  nt rc = parseSpe
ef70: 63 28 26 73 70 65 63 2c 20 61 72 67 63 2c 20 61  c(&spec, argc, a
ef80: 72 67 76 2c 20 70 7a 45 72 72 29 3b 0a 20 20 69  rgv, pzErr);.  i
ef90: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
efa0: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
efb0: 20 72 63 20 3d 20 63 6f 6e 73 74 72 75 63 74 56   rc = constructV
efc0: 74 61 62 28 64 62 2c 20 26 73 70 65 63 2c 20 70  tab(db, &spec, p
efd0: 70 56 54 61 62 2c 20 70 7a 45 72 72 29 3b 0a 20  pVTab, pzErr);. 
efe0: 20 63 6c 65 61 72 54 61 62 6c 65 53 70 65 63 28   clearTableSpec(
eff0: 26 73 70 65 63 29 3b 0a 20 20 72 65 74 75 72 6e  &spec);.  return
f000: 20 72 63 3b 0a 7d 0a 0a 20 20 2f 2a 20 54 68 65   rc;.}..  /* The
f010: 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65   %_content table
f020: 20 68 6f 6c 64 73 20 74 68 65 20 74 65 78 74 20   holds the text 
f030: 6f 66 20 65 61 63 68 20 64 6f 63 75 6d 65 6e 74  of each document
f040: 2c 20 77 69 74 68 0a 20 20 2a 2a 20 74 68 65 20  , with.  ** the 
f050: 72 6f 77 69 64 20 75 73 65 64 20 61 73 20 74 68  rowid used as th
f060: 65 20 64 6f 63 69 64 2e 0a 20 20 2a 2a 0a 20 20  e docid..  **.  
f070: 2a 2a 20 54 68 65 20 25 5f 74 65 72 6d 20 74 61  ** The %_term ta
f080: 62 6c 65 20 6d 61 70 73 20 65 61 63 68 20 74 65  ble maps each te
f090: 72 6d 20 74 6f 20 61 20 64 6f 63 75 6d 65 6e 74  rm to a document
f0a0: 20 6c 69 73 74 20 62 6c 6f 62 0a 20 20 2a 2a 20   list blob.  ** 
f0b0: 63 6f 6e 74 61 69 6e 69 6e 67 20 65 6c 65 6d 65  containing eleme
f0c0: 6e 74 73 20 73 6f 72 74 65 64 20 62 79 20 61 73  nts sorted by as
f0d0: 63 65 6e 64 69 6e 67 20 64 6f 63 69 64 2c 20 65  cending docid, e
f0e0: 61 63 68 20 65 6c 65 6d 65 6e 74 0a 20 20 2a 2a  ach element.  **
f0f0: 20 65 6e 63 6f 64 65 64 20 61 73 3a 0a 20 20 2a   encoded as:.  *
f100: 2a 0a 20 20 2a 2a 20 20 20 64 6f 63 69 64 20 76  *.  **   docid v
f110: 61 72 69 6e 74 2d 65 6e 63 6f 64 65 64 0a 20 20  arint-encoded.  
f120: 2a 2a 20 20 20 74 6f 6b 65 6e 20 65 6c 65 6d 65  **   token eleme
f130: 6e 74 73 3a 0a 20 20 2a 2a 20 20 20 20 20 70 6f  nts:.  **     po
f140: 73 69 74 69 6f 6e 2b 31 20 76 61 72 69 6e 74 2d  sition+1 varint-
f150: 65 6e 63 6f 64 65 64 20 61 73 20 64 65 6c 74 61  encoded as delta
f160: 20 66 72 6f 6d 20 70 72 65 76 69 6f 75 73 20 70   from previous p
f170: 6f 73 69 74 69 6f 6e 0a 20 20 2a 2a 20 20 20 20  osition.  **    
f180: 20 73 74 61 72 74 20 6f 66 66 73 65 74 20 76 61   start offset va
f190: 72 69 6e 74 2d 65 6e 63 6f 64 65 64 20 61 73 20  rint-encoded as 
f1a0: 64 65 6c 74 61 20 66 72 6f 6d 20 70 72 65 76 69  delta from previ
f1b0: 6f 75 73 20 73 74 61 72 74 20 6f 66 66 73 65 74  ous start offset
f1c0: 0a 20 20 2a 2a 20 20 20 20 20 65 6e 64 20 6f 66  .  **     end of
f1d0: 66 73 65 74 20 76 61 72 69 6e 74 2d 65 6e 63 6f  fset varint-enco
f1e0: 64 65 64 20 61 73 20 64 65 6c 74 61 20 66 72 6f  ded as delta fro
f1f0: 6d 20 73 74 61 72 74 20 6f 66 66 73 65 74 0a 20  m start offset. 
f200: 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 20 73 65 6e   **.  ** The sen
f210: 74 69 6e 65 6c 20 70 6f 73 69 74 69 6f 6e 20 6f  tinel position o
f220: 66 20 30 20 69 6e 64 69 63 61 74 65 73 20 74 68  f 0 indicates th
f230: 65 20 65 6e 64 20 6f 66 20 74 68 65 20 74 6f 6b  e end of the tok
f240: 65 6e 20 6c 69 73 74 2e 0a 20 20 2a 2a 0a 20 20  en list..  **.  
f250: 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c 6c 79 2c  ** Additionally,
f260: 20 64 6f 63 6c 69 73 74 20 62 6c 6f 62 73 20 61   doclist blobs a
f270: 72 65 20 63 68 75 6e 6b 65 64 20 69 6e 74 6f 20  re chunked into 
f280: 6d 75 6c 74 69 70 6c 65 20 73 65 67 6d 65 6e 74  multiple segment
f290: 73 2c 0a 20 20 2a 2a 20 75 73 69 6e 67 20 73 65  s,.  ** using se
f2a0: 67 6d 65 6e 74 20 74 6f 20 6f 72 64 65 72 20 74  gment to order t
f2b0: 68 65 20 73 65 67 6d 65 6e 74 73 2e 20 20 4e 65  he segments.  Ne
f2c0: 77 20 65 6c 65 6d 65 6e 74 73 20 61 72 65 20 61  w elements are a
f2d0: 64 64 65 64 20 74 6f 0a 20 20 2a 2a 20 74 68 65  dded to.  ** the
f2e0: 20 73 65 67 6d 65 6e 74 20 61 74 20 73 65 67 6d   segment at segm
f2f0: 65 6e 74 20 30 2c 20 75 6e 74 69 6c 20 69 74 20  ent 0, until it 
f300: 65 78 63 65 65 64 73 20 43 48 55 4e 4b 5f 4d 41  exceeds CHUNK_MA
f310: 58 2e 20 20 54 68 65 6e 0a 20 20 2a 2a 20 73 65  X.  Then.  ** se
f320: 67 6d 65 6e 74 20 30 20 69 73 20 64 65 6c 65 74  gment 0 is delet
f330: 65 64 2c 20 61 6e 64 20 74 68 65 20 64 6f 63 6c  ed, and the docl
f340: 69 73 74 20 69 73 20 69 6e 73 65 72 74 65 64 20  ist is inserted 
f350: 61 74 20 73 65 67 6d 65 6e 74 20 31 2e 0a 20 20  at segment 1..  
f360: 2a 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 61  ** If there is a
f370: 6c 72 65 61 64 79 20 61 20 64 6f 63 6c 69 73 74  lready a doclist
f380: 20 61 74 20 73 65 67 6d 65 6e 74 20 31 2c 20 74   at segment 1, t
f390: 68 65 20 73 65 67 6d 65 6e 74 20 30 20 64 6f 63  he segment 0 doc
f3a0: 6c 69 73 74 0a 20 20 2a 2a 20 69 73 20 6d 65 72  list.  ** is mer
f3b0: 67 65 64 20 77 69 74 68 20 69 74 2c 20 74 68 65  ged with it, the
f3c0: 20 73 65 67 6d 65 6e 74 20 31 20 64 6f 63 6c 69   segment 1 docli
f3d0: 73 74 20 69 73 20 64 65 6c 65 74 65 64 2c 20 61  st is deleted, a
f3e0: 6e 64 20 74 68 65 0a 20 20 2a 2a 20 6d 65 72 67  nd the.  ** merg
f3f0: 65 64 20 64 6f 63 6c 69 73 74 20 69 73 20 69 6e  ed doclist is in
f400: 73 65 72 74 65 64 20 61 74 20 73 65 67 6d 65 6e  serted at segmen
f410: 74 20 32 2c 20 72 65 70 65 61 74 69 6e 67 20 74  t 2, repeating t
f420: 68 6f 73 65 0a 20 20 2a 2a 20 6f 70 65 72 61 74  hose.  ** operat
f430: 69 6f 6e 73 20 75 6e 74 69 6c 20 61 6e 20 69 6e  ions until an in
f440: 73 65 72 74 20 73 75 63 63 65 65 64 73 2e 0a 20  sert succeeds.. 
f450: 20 2a 2a 0a 20 20 2a 2a 20 53 69 6e 63 65 20 74   **.  ** Since t
f460: 68 69 73 20 73 74 72 75 63 74 75 72 65 20 64 6f  his structure do
f470: 65 73 6e 27 74 20 61 6c 6c 6f 77 20 75 73 20 74  esn't allow us t
f480: 6f 20 75 70 64 61 74 65 20 65 6c 65 6d 65 6e 74  o update element
f490: 73 20 69 6e 20 70 6c 61 63 65 0a 20 20 2a 2a 20  s in place.  ** 
f4a0: 69 6e 20 63 61 73 65 20 6f 66 20 64 65 6c 65 74  in case of delet
f4b0: 69 6f 6e 20 6f 72 20 75 70 64 61 74 65 2c 20 74  ion or update, t
f4c0: 68 65 73 65 20 61 72 65 20 73 69 6d 70 6c 79 20  hese are simply 
f4d0: 77 72 69 74 74 65 6e 20 74 6f 0a 20 20 2a 2a 20  written to.  ** 
f4e0: 73 65 67 6d 65 6e 74 20 30 20 28 77 69 74 68 20  segment 0 (with 
f4f0: 61 6e 20 65 6d 70 74 79 20 74 6f 6b 65 6e 20 6c  an empty token l
f500: 69 73 74 20 69 6e 20 63 61 73 65 20 6f 66 20 64  ist in case of d
f510: 65 6c 65 74 69 6f 6e 29 2c 20 77 69 74 68 0a 20  eletion), with. 
f520: 20 2a 2a 20 64 6f 63 4c 69 73 74 41 63 63 75 6d   ** docListAccum
f530: 75 6c 61 74 65 28 29 20 74 61 6b 69 6e 67 20 63  ulate() taking c
f540: 61 72 65 20 74 6f 20 72 65 74 61 69 6e 20 6c 6f  are to retain lo
f550: 77 65 72 2d 73 65 67 6d 65 6e 74 0a 20 20 2a 2a  wer-segment.  **
f560: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e 20   information in 
f570: 70 72 65 66 65 72 65 6e 63 65 20 74 6f 20 68 69  preference to hi
f580: 67 68 65 72 2d 73 65 67 6d 65 6e 74 20 69 6e 66  gher-segment inf
f590: 6f 72 6d 61 74 69 6f 6e 2e 0a 20 20 2a 2f 0a 20  ormation..  */. 
f5a0: 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20   /* TODO(shess) 
f5b0: 50 72 6f 76 69 64 65 20 61 20 56 41 43 55 55 4d  Provide a VACUUM
f5c0: 20 74 79 70 65 20 6f 70 65 72 61 74 69 6f 6e 20   type operation 
f5d0: 77 68 69 63 68 20 62 6f 74 68 20 72 65 6d 6f 76  which both remov
f5e0: 65 73 0a 20 20 2a 2a 20 64 65 6c 65 74 65 64 20  es.  ** deleted 
f5f0: 65 6c 65 6d 65 6e 74 73 20 77 68 69 63 68 20 61  elements which a
f600: 72 65 20 6e 6f 20 6c 6f 6e 67 65 72 20 6e 65 63  re no longer nec
f610: 65 73 73 61 72 79 2c 20 61 6e 64 20 64 75 70 6c  essary, and dupl
f620: 69 63 61 74 65 64 0a 20 20 2a 2a 20 65 6c 65 6d  icated.  ** elem
f630: 65 6e 74 73 2e 20 20 49 20 73 75 73 70 65 63 74  ents.  I suspect
f640: 20 74 68 69 73 20 77 69 6c 6c 20 70 72 6f 62 61   this will proba
f650: 62 6c 79 20 6e 6f 74 20 62 65 20 6e 65 63 65 73  bly not be neces
f660: 73 61 72 79 20 69 6e 0a 20 20 2a 2a 20 70 72 61  sary in.  ** pra
f670: 63 74 69 63 65 2c 20 74 68 6f 75 67 68 2e 0a 20  ctice, though.. 
f680: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66   */.static int f
f690: 75 6c 6c 74 65 78 74 43 72 65 61 74 65 28 73 71  ulltextCreate(sq
f6a0: 6c 69 74 65 33 20 2a 64 62 2c 20 76 6f 69 64 20  lite3 *db, void 
f6b0: 2a 70 41 75 78 2c 0a 20 20 20 20 20 20 20 20 20  *pAux,.         
f6c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f6d0: 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74   int argc, const
f6e0: 20 63 68 61 72 20 2a 20 63 6f 6e 73 74 20 2a 61   char * const *a
f6f0: 72 67 76 2c 0a 20 20 20 20 20 20 20 20 20 20 20  rgv,.           
f700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
f710: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70  qlite3_vtab **pp
f720: 56 54 61 62 2c 20 63 68 61 72 20 2a 2a 70 7a 45  VTab, char **pzE
f730: 72 72 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  rr){.  int rc;. 
f740: 20 54 61 62 6c 65 53 70 65 63 20 73 70 65 63 3b   TableSpec spec;
f750: 0a 20 20 53 74 72 69 6e 67 42 75 66 66 65 72 20  .  StringBuffer 
f760: 73 63 68 65 6d 61 3b 0a 20 20 54 52 41 43 45 28  schema;.  TRACE(
f770: 28 22 46 54 53 31 20 43 72 65 61 74 65 5c 6e 22  ("FTS1 Create\n"
f780: 29 29 3b 0a 0a 20 20 72 63 20 3d 20 70 61 72 73  ));..  rc = pars
f790: 65 53 70 65 63 28 26 73 70 65 63 2c 20 61 72 67  eSpec(&spec, arg
f7a0: 63 2c 20 61 72 67 76 2c 20 70 7a 45 72 72 29 3b  c, argv, pzErr);
f7b0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
f7c0: 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
f7d0: 3b 0a 0a 20 20 69 6e 69 74 53 74 72 69 6e 67 42  ;..  initStringB
f7e0: 75 66 66 65 72 28 26 73 63 68 65 6d 61 29 3b 0a  uffer(&schema);.
f7f0: 20 20 61 70 70 65 6e 64 28 26 73 63 68 65 6d 61    append(&schema
f800: 2c 20 22 43 52 45 41 54 45 20 54 41 42 4c 45 20  , "CREATE TABLE 
f810: 25 5f 63 6f 6e 74 65 6e 74 28 22 29 3b 0a 20 20  %_content(");.  
f820: 61 70 70 65 6e 64 4c 69 73 74 28 26 73 63 68 65  appendList(&sche
f830: 6d 61 2c 20 73 70 65 63 2e 6e 43 6f 6c 75 6d 6e  ma, spec.nColumn
f840: 2c 20 73 70 65 63 2e 61 7a 43 6f 6e 74 65 6e 74  , spec.azContent
f850: 43 6f 6c 75 6d 6e 29 3b 0a 20 20 61 70 70 65 6e  Column);.  appen
f860: 64 28 26 73 63 68 65 6d 61 2c 20 22 29 22 29 3b  d(&schema, ")");
f870: 0a 20 20 72 63 20 3d 20 73 71 6c 5f 65 78 65 63  .  rc = sql_exec
f880: 28 64 62 2c 20 73 70 65 63 2e 7a 44 62 2c 20 73  (db, spec.zDb, s
f890: 70 65 63 2e 7a 4e 61 6d 65 2c 20 73 63 68 65 6d  pec.zName, schem
f8a0: 61 2e 73 29 3b 0a 20 20 66 72 65 65 28 73 63 68  a.s);.  free(sch
f8b0: 65 6d 61 2e 73 29 3b 0a 20 20 69 66 28 20 72 63  ema.s);.  if( rc
f8c0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f  !=SQLITE_OK ) go
f8d0: 74 6f 20 6f 75 74 3b 0a 0a 20 20 72 63 20 3d 20  to out;..  rc = 
f8e0: 73 71 6c 5f 65 78 65 63 28 64 62 2c 20 73 70 65  sql_exec(db, spe
f8f0: 63 2e 7a 44 62 2c 20 73 70 65 63 2e 7a 4e 61 6d  c.zDb, spec.zNam
f900: 65 2c 0a 20 20 20 20 22 63 72 65 61 74 65 20 74  e,.    "create t
f910: 61 62 6c 65 20 25 5f 74 65 72 6d 28 74 65 72 6d  able %_term(term
f920: 20 74 65 78 74 2c 20 73 65 67 6d 65 6e 74 20 69   text, segment i
f930: 6e 74 65 67 65 72 2c 20 64 6f 63 6c 69 73 74 20  nteger, doclist 
f940: 62 6c 6f 62 2c 20 22 0a 20 20 20 20 20 20 20 20  blob, ".        
f950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f960: 22 70 72 69 6d 61 72 79 20 6b 65 79 28 74 65 72  "primary key(ter
f970: 6d 2c 20 73 65 67 6d 65 6e 74 29 29 3b 22 29 3b  m, segment));");
f980: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
f990: 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 6f 75 74 3b  E_OK ) goto out;
f9a0: 0a 0a 20 20 72 63 20 3d 20 63 6f 6e 73 74 72 75  ..  rc = constru
f9b0: 63 74 56 74 61 62 28 64 62 2c 20 26 73 70 65 63  ctVtab(db, &spec
f9c0: 2c 20 70 70 56 54 61 62 2c 20 70 7a 45 72 72 29  , ppVTab, pzErr)
f9d0: 3b 0a 0a 6f 75 74 3a 0a 20 20 63 6c 65 61 72 54  ;..out:.  clearT
f9e0: 61 62 6c 65 53 70 65 63 28 26 73 70 65 63 29 3b  ableSpec(&spec);
f9f0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
fa00: 0a 2f 2a 20 44 65 63 69 64 65 20 68 6f 77 20 74  ./* Decide how t
fa10: 6f 20 68 61 6e 64 6c 65 20 61 6e 20 53 51 4c 20  o handle an SQL 
fa20: 71 75 65 72 79 2e 20 2a 2f 0a 73 74 61 74 69 63  query. */.static
fa30: 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 42 65 73   int fulltextBes
fa40: 74 49 6e 64 65 78 28 73 71 6c 69 74 65 33 5f 76  tIndex(sqlite3_v
fa50: 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71 6c 69  tab *pVTab, sqli
fa60: 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a  te3_index_info *
fa70: 70 49 6e 66 6f 29 7b 0a 20 20 69 6e 74 20 69 3b  pInfo){.  int i;
fa80: 0a 20 20 54 52 41 43 45 28 28 22 46 54 53 31 20  .  TRACE(("FTS1 
fa90: 42 65 73 74 49 6e 64 65 78 5c 6e 22 29 29 3b 0a  BestIndex\n"));.
faa0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 49  .  for(i=0; i<pI
fab0: 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74  nfo->nConstraint
fac0: 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 63 6f 6e 73  ; ++i){.    cons
fad0: 74 20 73 74 72 75 63 74 20 73 71 6c 69 74 65 33  t struct sqlite3
fae0: 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e  _index_constrain
faf0: 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e 74 3b 0a  t *pConstraint;.
fb00: 20 20 20 20 70 43 6f 6e 73 74 72 61 69 6e 74 20      pConstraint 
fb10: 3d 20 26 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  = &pInfo->aConst
fb20: 72 61 69 6e 74 5b 69 5d 3b 0a 20 20 20 20 69 66  raint[i];.    if
fb30: 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 75  ( pConstraint->u
fb40: 73 61 62 6c 65 20 29 20 7b 0a 20 20 20 20 20 20  sable ) {.      
fb50: 69 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d  if( pConstraint-
fb60: 3e 69 43 6f 6c 75 6d 6e 3d 3d 2d 31 20 26 26 0a  >iColumn==-1 &&.
fb70: 20 20 20 20 20 20 20 20 20 20 70 43 6f 6e 73 74            pConst
fb80: 72 61 69 6e 74 2d 3e 6f 70 3d 3d 53 51 4c 49 54  raint->op==SQLIT
fb90: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49  E_INDEX_CONSTRAI
fba0: 4e 54 5f 45 51 20 29 7b 0a 20 20 20 20 20 20 20  NT_EQ ){.       
fbb0: 20 70 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d   pInfo->idxNum =
fbc0: 20 51 55 45 52 59 5f 52 4f 57 49 44 3b 20 20 20   QUERY_ROWID;   
fbd0: 20 20 20 2f 2a 20 6c 6f 6f 6b 75 70 20 62 79 20     /* lookup by 
fbe0: 72 6f 77 69 64 20 2a 2f 0a 20 20 20 20 20 20 20  rowid */.       
fbf0: 20 54 52 41 43 45 28 28 22 46 54 53 31 20 51 55   TRACE(("FTS1 QU
fc00: 45 52 59 5f 52 4f 57 49 44 5c 6e 22 29 29 3b 0a  ERY_ROWID\n"));.
fc10: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 69 66 28        } else if(
fc20: 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 69 43   pConstraint->iC
fc30: 6f 6c 75 6d 6e 3e 3d 30 20 26 26 0a 20 20 20 20  olumn>=0 &&.    
fc40: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 43 6f               pCo
fc50: 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 3d 3d 53 51  nstraint->op==SQ
fc60: 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54  LITE_INDEX_CONST
fc70: 52 41 49 4e 54 5f 4d 41 54 43 48 20 29 7b 0a 20  RAINT_MATCH ){. 
fc80: 20 20 20 20 20 20 20 2f 2a 20 66 75 6c 6c 2d 74         /* full-t
fc90: 65 78 74 20 73 65 61 72 63 68 20 2a 2f 0a 20 20  ext search */.  
fca0: 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 69 64 78        pInfo->idx
fcb0: 4e 75 6d 20 3d 20 51 55 45 52 59 5f 46 55 4c 4c  Num = QUERY_FULL
fcc0: 54 45 58 54 20 2b 20 70 43 6f 6e 73 74 72 61 69  TEXT + pConstrai
fcd0: 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20  nt->iColumn;.   
fce0: 20 20 20 20 20 54 52 41 43 45 28 28 22 46 54 53       TRACE(("FTS
fcf0: 31 20 51 55 45 52 59 5f 46 55 4c 4c 54 45 58 54  1 QUERY_FULLTEXT
fd00: 20 25 64 5c 6e 22 2c 20 70 43 6f 6e 73 74 72 61   %d\n", pConstra
fd10: 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 29 29 3b 0a  int->iColumn));.
fd20: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 63 6f 6e        } else con
fd30: 74 69 6e 75 65 3b 0a 0a 20 20 20 20 20 20 70 49  tinue;..      pI
fd40: 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74  nfo->aConstraint
fd50: 55 73 61 67 65 5b 69 5d 2e 61 72 67 76 49 6e 64  Usage[i].argvInd
fd60: 65 78 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 49  ex = 1;.      pI
fd70: 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74  nfo->aConstraint
fd80: 55 73 61 67 65 5b 69 5d 2e 6f 6d 69 74 20 3d 20  Usage[i].omit = 
fd90: 31 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 41 6e 20  1;..      /* An 
fda0: 61 72 62 69 74 72 61 72 79 20 76 61 6c 75 65 20  arbitrary value 
fdb0: 66 6f 72 20 6e 6f 77 2e 0a 20 20 20 20 20 20 20  for now..       
fdc0: 2a 20 54 4f 44 4f 3a 20 50 65 72 68 61 70 73 20  * TODO: Perhaps 
fdd0: 72 6f 77 69 64 20 6d 61 74 63 68 65 73 20 73 68  rowid matches sh
fde0: 6f 75 6c 64 20 62 65 20 63 6f 6e 73 69 64 65 72  ould be consider
fdf0: 65 64 20 63 68 65 61 70 65 72 20 74 68 61 6e 0a  ed cheaper than.
fe00: 20 20 20 20 20 20 20 2a 20 66 75 6c 6c 2d 74 65         * full-te
fe10: 78 74 20 73 65 61 72 63 68 65 73 2e 20 2a 2f 0a  xt searches. */.
fe20: 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 65 73 74        pInfo->est
fe30: 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 2e 30  imatedCost = 1.0
fe40: 3b 20 20 20 0a 0a 20 20 20 20 20 20 72 65 74 75  ;   ..      retu
fe50: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20  rn SQLITE_OK;.  
fe60: 20 20 7d 0a 20 20 7d 0a 20 20 70 49 6e 66 6f 2d    }.  }.  pInfo-
fe70: 3e 69 64 78 4e 75 6d 20 3d 20 51 55 45 52 59 5f  >idxNum = QUERY_
fe80: 47 45 4e 45 52 49 43 3b 0a 20 20 72 65 74 75 72  GENERIC;.  retur
fe90: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
fea0: 73 74 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 74  static int fullt
feb0: 65 78 74 44 69 73 63 6f 6e 6e 65 63 74 28 73 71  extDisconnect(sq
fec0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61  lite3_vtab *pVTa
fed0: 62 29 7b 0a 20 20 54 52 41 43 45 28 28 22 46 54  b){.  TRACE(("FT
fee0: 53 31 20 44 69 73 63 6f 6e 6e 65 63 74 20 25 70  S1 Disconnect %p
fef0: 5c 6e 22 2c 20 70 56 54 61 62 29 29 3b 0a 20 20  \n", pVTab));.  
ff00: 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 5f 64 65  fulltext_vtab_de
ff10: 73 74 72 6f 79 28 28 66 75 6c 6c 74 65 78 74 5f  stroy((fulltext_
ff20: 76 74 61 62 20 2a 29 70 56 54 61 62 29 3b 0a 20  vtab *)pVTab);. 
ff30: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
ff40: 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  K;.}..static int
ff50: 20 66 75 6c 6c 74 65 78 74 44 65 73 74 72 6f 79   fulltextDestroy
ff60: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
ff70: 56 54 61 62 29 7b 0a 20 20 66 75 6c 6c 74 65 78  VTab){.  fulltex
ff80: 74 5f 76 74 61 62 20 2a 76 20 3d 20 28 66 75 6c  t_vtab *v = (ful
ff90: 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 70 56 54  ltext_vtab *)pVT
ffa0: 61 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20  ab;.  int rc;.. 
ffb0: 20 54 52 41 43 45 28 28 22 46 54 53 31 20 44 65   TRACE(("FTS1 De
ffc0: 73 74 72 6f 79 20 25 70 5c 6e 22 2c 20 70 56 54  stroy %p\n", pVT
ffd0: 61 62 29 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c  ab));.  rc = sql
ffe0: 5f 65 78 65 63 28 76 2d 3e 64 62 2c 20 76 2d 3e  _exec(v->db, v->
fff0: 7a 44 62 2c 20 76 2d 3e 7a 4e 61 6d 65 2c 0a 20  zDb, v->zName,. 
10000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22                 "
10010 64 72 6f 70 20 74 61 62 6c 65 20 69 66 20 65 78  drop table if ex
10020 69 73 74 73 20 25 5f 63 6f 6e 74 65 6e 74 3b 22  ists %_content;"
10030 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
10040 20 22 64 72 6f 70 20 74 61 62 6c 65 20 69 66 20   "drop table if 
10050 65 78 69 73 74 73 20 25 5f 74 65 72 6d 3b 22 0a  exists %_term;".
10060 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10070 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
10080 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
10090 72 63 3b 0a 0a 20 20 66 75 6c 6c 74 65 78 74 5f  rc;..  fulltext_
100a0 76 74 61 62 5f 64 65 73 74 72 6f 79 28 28 66 75  vtab_destroy((fu
100b0 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 70 56  lltext_vtab *)pV
100c0 54 61 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  Tab);.  return S
100d0 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61  QLITE_OK;.}..sta
100e0 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74  tic int fulltext
100f0 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  Open(sqlite3_vta
10100 62 20 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65  b *pVTab, sqlite
10110 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a  3_vtab_cursor **
10120 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 66 75 6c  ppCursor){.  ful
10130 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 63 3b  ltext_cursor *c;
10140 0a 0a 20 20 63 20 3d 20 28 66 75 6c 6c 74 65 78  ..  c = (fulltex
10150 74 5f 63 75 72 73 6f 72 20 2a 29 20 63 61 6c 6c  t_cursor *) call
10160 6f 63 28 73 69 7a 65 6f 66 28 66 75 6c 6c 74 65  oc(sizeof(fullte
10170 78 74 5f 63 75 72 73 6f 72 29 2c 20 31 29 3b 0a  xt_cursor), 1);.
10180 20 20 2f 2a 20 73 71 6c 69 74 65 20 77 69 6c 6c    /* sqlite will
10190 20 69 6e 69 74 69 61 6c 69 7a 65 20 63 2d 3e 62   initialize c->b
101a0 61 73 65 20 2a 2f 0a 20 20 2a 70 70 43 75 72 73  ase */.  *ppCurs
101b0 6f 72 20 3d 20 26 63 2d 3e 62 61 73 65 3b 0a 20  or = &c->base;. 
101c0 20 54 52 41 43 45 28 28 22 46 54 53 31 20 4f 70   TRACE(("FTS1 Op
101d0 65 6e 20 25 70 3a 20 25 70 5c 6e 22 2c 20 70 56  en %p: %p\n", pV
101e0 54 61 62 2c 20 63 29 29 3b 0a 0a 20 20 72 65 74  Tab, c));..  ret
101f0 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
10200 0a 0a 0a 2f 2a 20 46 72 65 65 20 61 6c 6c 20 6f  .../* Free all o
10210 66 20 74 68 65 20 64 79 6e 61 6d 69 63 61 6c 6c  f the dynamicall
10220 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f  y allocated memo
10230 72 79 20 68 65 6c 64 20 62 79 20 2a 71 0a 2a 2f  ry held by *q.*/
10240 0a 73 74 61 74 69 63 20 76 6f 69 64 20 71 75 65  .static void que
10250 72 79 43 6c 65 61 72 28 51 75 65 72 79 20 2a 71  ryClear(Query *q
10260 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f  ){.  int i;.  fo
10270 72 28 69 20 3d 20 30 3b 20 69 20 3c 20 71 2d 3e  r(i = 0; i < q->
10280 6e 54 65 72 6d 73 3b 20 2b 2b 69 29 7b 0a 20 20  nTerms; ++i){.  
10290 20 20 66 72 65 65 28 71 2d 3e 70 54 65 72 6d 73    free(q->pTerms
102a0 5b 69 5d 2e 70 54 65 72 6d 29 3b 0a 20 20 7d 0a  [i].pTerm);.  }.
102b0 20 20 66 72 65 65 28 71 2d 3e 70 54 65 72 6d 73    free(q->pTerms
102c0 29 3b 0a 20 20 6d 65 6d 73 65 74 28 71 2c 20 30  );.  memset(q, 0
102d0 2c 20 73 69 7a 65 6f 66 28 2a 71 29 29 3b 0a 7d  , sizeof(*q));.}
102e0 0a 0a 2f 2a 20 46 72 65 65 20 61 6c 6c 20 6f 66  ../* Free all of
102f0 20 74 68 65 20 64 79 6e 61 6d 69 63 61 6c 6c 79   the dynamically
10300 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72   allocated memor
10310 79 20 68 65 6c 64 20 62 79 20 74 68 65 0a 2a 2a  y held by the.**
10320 20 53 6e 69 70 70 65 74 0a 2a 2f 0a 73 74 61 74   Snippet.*/.stat
10330 69 63 20 76 6f 69 64 20 73 6e 69 70 70 65 74 43  ic void snippetC
10340 6c 65 61 72 28 53 6e 69 70 70 65 74 20 2a 70 29  lear(Snippet *p)
10350 7b 0a 20 20 66 72 65 65 28 70 2d 3e 61 4d 61 74  {.  free(p->aMat
10360 63 68 29 3b 0a 20 20 66 72 65 65 28 70 2d 3e 7a  ch);.  free(p->z
10370 4f 66 66 73 65 74 29 3b 0a 20 20 66 72 65 65 28  Offset);.  free(
10380 70 2d 3e 7a 53 6e 69 70 70 65 74 29 3b 0a 20 20  p->zSnippet);.  
10390 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a  memset(p, 0, siz
103a0 65 6f 66 28 2a 70 29 29 3b 0a 7d 0a 2f 2a 0a 2a  eof(*p));.}./*.*
103b0 2a 20 41 70 70 65 6e 64 20 61 20 73 69 6e 67 6c  * Append a singl
103c0 65 20 65 6e 74 72 79 20 74 6f 20 74 68 65 20 70  e entry to the p
103d0 2d 3e 61 4d 61 74 63 68 5b 5d 20 6c 6f 67 2e 0a  ->aMatch[] log..
103e0 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  */.static void s
103f0 6e 69 70 70 65 74 41 70 70 65 6e 64 4d 61 74 63  nippetAppendMatc
10400 68 28 0a 20 20 53 6e 69 70 70 65 74 20 2a 70 2c  h(.  Snippet *p,
10410 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
10420 2a 20 41 70 70 65 6e 64 20 74 68 65 20 65 6e 74  * Append the ent
10430 72 79 20 74 6f 20 74 68 69 73 20 73 6e 69 70 70  ry to this snipp
10440 65 74 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c  et */.  int iCol
10450 2c 20 69 6e 74 20 69 54 65 72 6d 2c 20 20 20 20  , int iTerm,    
10460 20 20 2f 2a 20 54 68 65 20 63 6f 6c 75 6d 6e 20    /* The column 
10470 61 6e 64 20 71 75 65 72 79 20 74 65 72 6d 20 2a  and query term *
10480 2f 0a 20 20 69 6e 74 20 69 53 74 61 72 74 2c 20  /.  int iStart, 
10490 69 6e 74 20 6e 42 79 74 65 20 20 20 20 20 2f 2a  int nByte     /*
104a0 20 4f 66 66 73 65 74 20 61 6e 64 20 73 69 7a 65   Offset and size
104b0 20 6f 66 20 74 68 65 20 6d 61 74 63 68 20 2a 2f   of the match */
104c0 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 73  .){.  int i;.  s
104d0 74 72 75 63 74 20 73 6e 69 70 70 65 74 4d 61 74  truct snippetMat
104e0 63 68 20 2a 70 4d 61 74 63 68 3b 0a 20 20 69 66  ch *pMatch;.  if
104f0 28 20 70 2d 3e 6e 4d 61 74 63 68 2b 31 3e 3d 70  ( p->nMatch+1>=p
10500 2d 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20 20 20 20  ->nAlloc ){.    
10510 70 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 70 2d 3e 6e  p->nAlloc = p->n
10520 41 6c 6c 6f 63 2a 32 20 2b 20 31 30 3b 0a 20 20  Alloc*2 + 10;.  
10530 20 20 70 2d 3e 61 4d 61 74 63 68 20 3d 20 72 65    p->aMatch = re
10540 61 6c 6c 6f 63 28 70 2d 3e 61 4d 61 74 63 68 2c  alloc(p->aMatch,
10550 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 73 69 7a 65 6f   p->nAlloc*sizeo
10560 66 28 70 2d 3e 61 4d 61 74 63 68 5b 30 5d 29 20  f(p->aMatch[0]) 
10570 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 61 4d  );.    if( p->aM
10580 61 74 63 68 3d 3d 30 20 29 7b 0a 20 20 20 20 20  atch==0 ){.     
10590 20 70 2d 3e 6e 4d 61 74 63 68 20 3d 20 30 3b 0a   p->nMatch = 0;.
105a0 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20        p->nAlloc 
105b0 3d 20 30 3b 0a 20 20 20 20 20 20 72 65 74 75 72  = 0;.      retur
105c0 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  n;.    }.  }.  i
105d0 20 3d 20 70 2d 3e 6e 4d 61 74 63 68 2b 2b 3b 0a   = p->nMatch++;.
105e0 20 20 70 4d 61 74 63 68 20 3d 20 26 70 2d 3e 61    pMatch = &p->a
105f0 4d 61 74 63 68 5b 69 5d 3b 0a 20 20 70 4d 61 74  Match[i];.  pMat
10600 63 68 2d 3e 69 43 6f 6c 20 3d 20 69 43 6f 6c 3b  ch->iCol = iCol;
10610 0a 20 20 70 4d 61 74 63 68 2d 3e 69 54 65 72 6d  .  pMatch->iTerm
10620 20 3d 20 69 54 65 72 6d 3b 0a 20 20 70 4d 61 74   = iTerm;.  pMat
10630 63 68 2d 3e 69 53 74 61 72 74 20 3d 20 69 53 74  ch->iStart = iSt
10640 61 72 74 3b 0a 20 20 70 4d 61 74 63 68 2d 3e 6e  art;.  pMatch->n
10650 42 79 74 65 20 3d 20 6e 42 79 74 65 3b 0a 7d 0a  Byte = nByte;.}.
10660 0a 2f 2a 0a 2a 2a 20 53 69 7a 69 6e 67 20 69 6e  ./*.** Sizing in
10670 66 6f 72 6d 61 74 69 6f 6e 20 66 6f 72 20 74 68  formation for th
10680 65 20 63 69 72 63 75 6c 61 72 20 62 75 66 66 65  e circular buffe
10690 72 20 75 73 65 64 20 69 6e 20 73 6e 69 70 70 65  r used in snippe
106a0 74 4f 66 66 73 65 74 73 4f 66 43 6f 6c 75 6d 6e  tOffsetsOfColumn
106b0 28 29 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54  ().*/.#define FT
106c0 53 31 5f 52 4f 54 4f 52 5f 53 5a 20 20 20 28 33  S1_ROTOR_SZ   (3
106d0 32 29 0a 23 64 65 66 69 6e 65 20 46 54 53 31 5f  2).#define FTS1_
106e0 52 4f 54 4f 52 5f 4d 41 53 4b 20 28 46 54 53 31  ROTOR_MASK (FTS1
106f0 5f 52 4f 54 4f 52 5f 53 5a 2d 31 29 0a 0a 2f 2a  _ROTOR_SZ-1)../*
10700 0a 2a 2a 20 41 64 64 20 65 6e 74 72 69 65 73 20  .** Add entries 
10710 74 6f 20 70 53 6e 69 70 70 65 74 2d 3e 61 4d 61  to pSnippet->aMa
10720 74 63 68 5b 5d 20 66 6f 72 20 65 76 65 72 79 20  tch[] for every 
10730 6d 61 74 63 68 20 74 68 61 74 20 6f 63 63 75 72  match that occur
10740 73 20 61 67 61 69 6e 73 74 0a 2a 2a 20 64 6f 63  s against.** doc
10750 75 6d 65 6e 74 20 7a 44 6f 63 5b 30 2e 2e 6e 44  ument zDoc[0..nD
10760 6f 63 2d 31 5d 20 77 68 69 63 68 20 69 73 20 73  oc-1] which is s
10770 74 6f 72 65 64 20 69 6e 20 63 6f 6c 75 6d 6e 20  tored in column 
10780 69 43 6f 6c 75 6d 6e 2e 0a 2a 2f 0a 73 74 61 74  iColumn..*/.stat
10790 69 63 20 76 6f 69 64 20 73 6e 69 70 70 65 74 4f  ic void snippetO
107a0 66 66 73 65 74 73 4f 66 43 6f 6c 75 6d 6e 28 0a  ffsetsOfColumn(.
107b0 20 20 51 75 65 72 79 20 2a 70 51 75 65 72 79 2c    Query *pQuery,
107c0 0a 20 20 53 6e 69 70 70 65 74 20 2a 70 53 6e 69  .  Snippet *pSni
107d0 70 70 65 74 2c 0a 20 20 69 6e 74 20 69 43 6f 6c  ppet,.  int iCol
107e0 75 6d 6e 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  umn,.  const cha
107f0 72 20 2a 7a 44 6f 63 2c 0a 20 20 69 6e 74 20 6e  r *zDoc,.  int n
10800 44 6f 63 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 73  Doc.){.  const s
10810 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72  qlite3_tokenizer
10820 5f 6d 6f 64 75 6c 65 20 2a 70 54 4d 6f 64 75 6c  _module *pTModul
10830 65 3b 20 20 2f 2a 20 54 68 65 20 74 6f 6b 65 6e  e;  /* The token
10840 69 7a 65 72 20 6d 6f 64 75 6c 65 20 2a 2f 0a 20  izer module */. 
10850 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a   sqlite3_tokeniz
10860 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 3b 20  er *pTokenizer; 
10870 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
10880 68 65 20 73 70 65 63 69 66 69 63 20 74 6f 6b 65  he specific toke
10890 6e 69 7a 65 72 20 2a 2f 0a 20 20 73 71 6c 69 74  nizer */.  sqlit
108a0 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72  e3_tokenizer_cur
108b0 73 6f 72 20 2a 70 54 43 75 72 73 6f 72 3b 20 20  sor *pTCursor;  
108c0 20 20 20 20 20 20 2f 2a 20 54 6f 6b 65 6e 69 7a        /* Tokeniz
108d0 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66  er cursor */.  f
108e0 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 70 56  ulltext_vtab *pV
108f0 74 61 62 3b 20 20 20 20 20 20 20 20 20 20 20 20  tab;            
10900 20 20 20 20 2f 2a 20 54 68 65 20 66 75 6c 6c 20      /* The full 
10910 74 65 78 74 20 69 6e 64 65 78 20 2a 2f 0a 20 20  text index */.  
10920 69 6e 74 20 6e 43 6f 6c 75 6d 6e 3b 20 20 20 20  int nColumn;    
10930 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10940 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
10950 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65  f columns in the
10960 20 69 6e 64 65 78 20 2a 2f 0a 20 20 63 6f 6e 73   index */.  cons
10970 74 20 51 75 65 72 79 54 65 72 6d 20 2a 61 54 65  t QueryTerm *aTe
10980 72 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rm;             
10990 20 2f 2a 20 51 75 65 72 79 20 73 74 72 69 6e 67   /* Query string
109a0 20 74 65 72 6d 73 20 2a 2f 0a 20 20 69 6e 74 20   terms */.  int 
109b0 6e 54 65 72 6d 3b 20 20 20 20 20 20 20 20 20 20  nTerm;          
109c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
109d0 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 71 75   /* Number of qu
109e0 65 72 79 20 73 74 72 69 6e 67 20 74 65 72 6d 73  ery string terms
109f0 20 2a 2f 20 20 0a 20 20 69 6e 74 20 69 2c 20 6a   */  .  int i, j
10a00 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
10a10 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
10a20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 73 20 2a 2f  Loop counters */
10a30 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
10a40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10a50 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
10a60 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 75 6e 73 69  n code */.  unsi
10a70 67 6e 65 64 20 69 6e 74 20 6d 61 74 63 68 2c 20  gned int match, 
10a80 70 72 65 76 4d 61 74 63 68 3b 20 20 20 20 20 20  prevMatch;      
10a90 20 2f 2a 20 50 68 72 61 73 65 20 73 65 61 72 63   /* Phrase searc
10aa0 68 20 62 69 74 6d 61 73 6b 73 20 2a 2f 0a 20 20  h bitmasks */.  
10ab0 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 6f 6b  const char *zTok
10ac0 65 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  en;             
10ad0 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 74 6f 6b       /* Next tok
10ae0 65 6e 20 66 72 6f 6d 20 74 68 65 20 74 6f 6b 65  en from the toke
10af0 6e 69 7a 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e  nizer */.  int n
10b00 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20 20 20  Token;          
10b10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10b20 2f 2a 20 53 69 7a 65 20 6f 66 20 7a 54 6f 6b 65  /* Size of zToke
10b30 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 42 65 67 69  n */.  int iBegi
10b40 6e 2c 20 69 45 6e 64 2c 20 69 50 6f 73 3b 20 20  n, iEnd, iPos;  
10b50 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
10b60 66 66 73 65 74 73 20 6f 66 20 62 65 67 69 6e 6e  ffsets of beginn
10b70 69 6e 67 20 61 6e 64 20 65 6e 64 20 2a 2f 0a 0a  ing and end */..
10b80 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69    /* The followi
10b90 6e 67 20 76 61 72 69 61 62 6c 65 73 20 6b 65 65  ng variables kee
10ba0 70 20 61 20 63 69 72 63 75 6c 61 72 20 62 75 66  p a circular buf
10bb0 66 65 72 20 6f 66 20 74 68 65 20 6c 61 73 74 0a  fer of the last.
10bc0 20 20 2a 2a 20 66 65 77 20 74 6f 6b 65 6e 73 20    ** few tokens 
10bd0 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
10be0 74 20 69 52 6f 74 6f 72 20 3d 20 30 3b 20 20 20  t iRotor = 0;   
10bf0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
10c00 65 78 20 6f 66 20 63 75 72 72 65 6e 74 20 74 6f  ex of current to
10c10 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 52 6f  ken */.  int iRo
10c20 74 6f 72 42 65 67 69 6e 5b 46 54 53 31 5f 52 4f  torBegin[FTS1_RO
10c30 54 4f 52 5f 53 5a 5d 3b 20 20 20 20 20 20 2f 2a  TOR_SZ];      /*
10c40 20 42 65 67 69 6e 6e 69 6e 67 20 6f 66 66 73 65   Beginning offse
10c50 74 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20  t of token */.  
10c60 69 6e 74 20 69 52 6f 74 6f 72 4c 65 6e 5b 46 54  int iRotorLen[FT
10c70 53 31 5f 52 4f 54 4f 52 5f 53 5a 5d 3b 20 20 20  S1_ROTOR_SZ];   
10c80 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f       /* Length o
10c90 66 20 74 6f 6b 65 6e 20 2a 2f 0a 0a 20 20 70 56  f token */..  pV
10ca0 74 61 62 20 3d 20 70 51 75 65 72 79 2d 3e 70 46  tab = pQuery->pF
10cb0 74 73 3b 0a 20 20 6e 43 6f 6c 75 6d 6e 20 3d 20  ts;.  nColumn = 
10cc0 70 56 74 61 62 2d 3e 6e 43 6f 6c 75 6d 6e 3b 0a  pVtab->nColumn;.
10cd0 20 20 70 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 70    pTokenizer = p
10ce0 56 74 61 62 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72  Vtab->pTokenizer
10cf0 3b 0a 20 20 70 54 4d 6f 64 75 6c 65 20 3d 20 70  ;.  pTModule = p
10d00 54 6f 6b 65 6e 69 7a 65 72 2d 3e 70 4d 6f 64 75  Tokenizer->pModu
10d10 6c 65 3b 0a 20 20 72 63 20 3d 20 70 54 4d 6f 64  le;.  rc = pTMod
10d20 75 6c 65 2d 3e 78 4f 70 65 6e 28 70 54 6f 6b 65  ule->xOpen(pToke
10d30 6e 69 7a 65 72 2c 20 7a 44 6f 63 2c 20 6e 44 6f  nizer, zDoc, nDo
10d40 63 2c 20 26 70 54 43 75 72 73 6f 72 29 3b 0a 20  c, &pTCursor);. 
10d50 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e   if( rc ) return
10d60 3b 0a 20 20 70 54 43 75 72 73 6f 72 2d 3e 70 54  ;.  pTCursor->pT
10d70 6f 6b 65 6e 69 7a 65 72 20 3d 20 70 54 6f 6b 65  okenizer = pToke
10d80 6e 69 7a 65 72 3b 0a 20 20 61 54 65 72 6d 20 3d  nizer;.  aTerm =
10d90 20 70 51 75 65 72 79 2d 3e 70 54 65 72 6d 73 3b   pQuery->pTerms;
10da0 0a 20 20 6e 54 65 72 6d 20 3d 20 70 51 75 65 72  .  nTerm = pQuer
10db0 79 2d 3e 6e 54 65 72 6d 73 3b 0a 20 20 69 66 28  y->nTerms;.  if(
10dc0 20 6e 54 65 72 6d 3e 3d 46 54 53 31 5f 52 4f 54   nTerm>=FTS1_ROT
10dd0 4f 52 5f 53 5a 20 29 7b 0a 20 20 20 20 6e 54 65  OR_SZ ){.    nTe
10de0 72 6d 20 3d 20 46 54 53 31 5f 52 4f 54 4f 52 5f  rm = FTS1_ROTOR_
10df0 53 5a 20 2d 20 31 3b 0a 20 20 7d 0a 20 20 70 72  SZ - 1;.  }.  pr
10e00 65 76 4d 61 74 63 68 20 3d 20 30 3b 0a 20 20 77  evMatch = 0;.  w
10e10 68 69 6c 65 28 31 29 7b 0a 20 20 20 20 72 63 20  hile(1){.    rc 
10e20 3d 20 70 54 4d 6f 64 75 6c 65 2d 3e 78 4e 65 78  = pTModule->xNex
10e30 74 28 70 54 43 75 72 73 6f 72 2c 20 26 7a 54 6f  t(pTCursor, &zTo
10e40 6b 65 6e 2c 20 26 6e 54 6f 6b 65 6e 2c 20 26 69  ken, &nToken, &i
10e50 42 65 67 69 6e 2c 20 26 69 45 6e 64 2c 20 26 69  Begin, &iEnd, &i
10e60 50 6f 73 29 3b 0a 20 20 20 20 69 66 28 20 72 63  Pos);.    if( rc
10e70 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 69 52   ) break;.    iR
10e80 6f 74 6f 72 42 65 67 69 6e 5b 69 52 6f 74 6f 72  otorBegin[iRotor
10e90 26 46 54 53 31 5f 52 4f 54 4f 52 5f 4d 41 53 4b  &FTS1_ROTOR_MASK
10ea0 5d 20 3d 20 69 42 65 67 69 6e 3b 0a 20 20 20 20  ] = iBegin;.    
10eb0 69 52 6f 74 6f 72 4c 65 6e 5b 69 52 6f 74 6f 72  iRotorLen[iRotor
10ec0 26 46 54 53 31 5f 52 4f 54 4f 52 5f 4d 41 53 4b  &FTS1_ROTOR_MASK
10ed0 5d 20 3d 20 69 45 6e 64 2d 69 42 65 67 69 6e 3b  ] = iEnd-iBegin;
10ee0 0a 20 20 20 20 6d 61 74 63 68 20 3d 20 30 3b 0a  .    match = 0;.
10ef0 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e      for(i=0; i<n
10f00 54 65 72 6d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Term; i++){.    
10f10 20 20 69 6e 74 20 69 43 6f 6c 3b 0a 20 20 20 20    int iCol;.    
10f20 20 20 69 43 6f 6c 20 3d 20 61 54 65 72 6d 5b 69    iCol = aTerm[i
10f30 5d 2e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 20  ].iColumn;.     
10f40 20 69 66 28 20 69 43 6f 6c 3e 3d 30 20 26 26 20   if( iCol>=0 && 
10f50 69 43 6f 6c 3c 6e 43 6f 6c 75 6d 6e 20 26 26 20  iCol<nColumn && 
10f60 69 43 6f 6c 21 3d 69 43 6f 6c 75 6d 6e 20 29 20  iCol!=iColumn ) 
10f70 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
10f80 69 66 28 20 61 54 65 72 6d 5b 69 5d 2e 6e 54 65  if( aTerm[i].nTe
10f90 72 6d 21 3d 6e 54 6f 6b 65 6e 20 29 20 63 6f 6e  rm!=nToken ) con
10fa0 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 69 66 28  tinue;.      if(
10fb0 20 6d 65 6d 63 6d 70 28 61 54 65 72 6d 5b 69 5d   memcmp(aTerm[i]
10fc0 2e 70 54 65 72 6d 2c 20 7a 54 6f 6b 65 6e 2c 20  .pTerm, zToken, 
10fd0 6e 54 6f 6b 65 6e 29 20 29 20 63 6f 6e 74 69 6e  nToken) ) contin
10fe0 75 65 3b 0a 20 20 20 20 20 20 69 66 28 20 61 54  ue;.      if( aT
10ff0 65 72 6d 5b 69 5d 2e 69 50 68 72 61 73 65 3e 31  erm[i].iPhrase>1
11000 20 26 26 20 28 70 72 65 76 4d 61 74 63 68 20 26   && (prevMatch &
11010 20 28 31 3c 3c 69 29 29 3d 3d 30 20 29 20 63 6f   (1<<i))==0 ) co
11020 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 6d 61  ntinue;.      ma
11030 74 63 68 20 7c 3d 20 31 3c 3c 69 3b 0a 20 20 20  tch |= 1<<i;.   
11040 20 20 20 69 66 28 20 69 3d 3d 6e 54 65 72 6d 2d     if( i==nTerm-
11050 31 20 7c 7c 20 61 54 65 72 6d 5b 69 2b 31 5d 2e  1 || aTerm[i+1].
11060 69 50 68 72 61 73 65 3d 3d 31 20 29 7b 0a 20 20  iPhrase==1 ){.  
11070 20 20 20 20 20 20 66 6f 72 28 6a 3d 61 54 65 72        for(j=aTer
11080 6d 5b 69 5d 2e 69 50 68 72 61 73 65 2d 31 3b 20  m[i].iPhrase-1; 
11090 6a 3e 3d 30 3b 20 6a 2d 2d 29 7b 0a 20 20 20 20  j>=0; j--){.    
110a0 20 20 20 20 20 20 69 6e 74 20 6b 20 3d 20 28 69        int k = (i
110b0 52 6f 74 6f 72 2d 6a 29 20 26 20 46 54 53 31 5f  Rotor-j) & FTS1_
110c0 52 4f 54 4f 52 5f 4d 41 53 4b 3b 0a 20 20 20 20  ROTOR_MASK;.    
110d0 20 20 20 20 20 20 73 6e 69 70 70 65 74 41 70 70        snippetApp
110e0 65 6e 64 4d 61 74 63 68 28 70 53 6e 69 70 70 65  endMatch(pSnippe
110f0 74 2c 20 69 43 6f 6c 75 6d 6e 2c 20 69 2d 6a 2c  t, iColumn, i-j,
11100 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
11110 20 69 52 6f 74 6f 72 42 65 67 69 6e 5b 6b 5d 2c   iRotorBegin[k],
11120 20 69 52 6f 74 6f 72 4c 65 6e 5b 6b 5d 29 3b 0a   iRotorLen[k]);.
11130 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
11140 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70 72 65 76  }.    }.    prev
11150 4d 61 74 63 68 20 3d 20 6d 61 74 63 68 3c 3c 31  Match = match<<1
11160 3b 0a 20 20 20 20 69 52 6f 74 6f 72 2b 2b 3b 0a  ;.    iRotor++;.
11170 20 20 7d 0a 20 20 70 54 4d 6f 64 75 6c 65 2d 3e    }.  pTModule->
11180 78 43 6c 6f 73 65 28 70 54 43 75 72 73 6f 72 29  xClose(pTCursor)
11190 3b 20 20 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6f  ;  .}.../*.** Co
111a0 6d 70 75 74 65 20 61 6c 6c 20 6f 66 66 73 65 74  mpute all offset
111b0 73 20 66 6f 72 20 74 68 65 20 63 75 72 72 65 6e  s for the curren
111c0 74 20 72 6f 77 20 6f 66 20 74 68 65 20 71 75 65  t row of the que
111d0 72 79 2e 20 20 0a 2a 2a 20 49 66 20 74 68 65 20  ry.  .** If the 
111e0 6f 66 66 73 65 74 73 20 68 61 76 65 20 61 6c 72  offsets have alr
111f0 65 61 64 79 20 62 65 65 6e 20 63 6f 6d 70 75 74  eady been comput
11200 65 64 2c 20 74 68 69 73 20 72 6f 75 74 69 6e 65  ed, this routine
11210 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a   is a no-op..*/.
11220 73 74 61 74 69 63 20 76 6f 69 64 20 73 6e 69 70  static void snip
11230 70 65 74 41 6c 6c 4f 66 66 73 65 74 73 28 66 75  petAllOffsets(fu
11240 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 70  lltext_cursor *p
11250 29 7b 0a 20 20 69 6e 74 20 6e 43 6f 6c 75 6d 6e  ){.  int nColumn
11260 3b 0a 20 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 2c  ;.  int iColumn,
11270 20 69 3b 0a 20 20 69 6e 74 20 69 46 69 72 73 74   i;.  int iFirst
11280 2c 20 69 4c 61 73 74 3b 0a 20 20 66 75 6c 6c 74  , iLast;.  fullt
11290 65 78 74 5f 76 74 61 62 20 2a 70 46 74 73 3b 0a  ext_vtab *pFts;.
112a0 0a 20 20 69 66 28 20 70 2d 3e 73 6e 69 70 70 65  .  if( p->snippe
112b0 74 2e 6e 4d 61 74 63 68 20 29 20 72 65 74 75 72  t.nMatch ) retur
112c0 6e 3b 0a 20 20 69 66 28 20 70 2d 3e 71 2e 6e 54  n;.  if( p->q.nT
112d0 65 72 6d 73 3d 3d 30 20 29 20 72 65 74 75 72 6e  erms==0 ) return
112e0 3b 0a 20 20 70 46 74 73 20 3d 20 70 2d 3e 71 2e  ;.  pFts = p->q.
112f0 70 46 74 73 3b 0a 20 20 6e 43 6f 6c 75 6d 6e 20  pFts;.  nColumn 
11300 3d 20 70 46 74 73 2d 3e 6e 43 6f 6c 75 6d 6e 3b  = pFts->nColumn;
11310 0a 20 20 69 43 6f 6c 75 6d 6e 20 3d 20 70 2d 3e  .  iColumn = p->
11320 69 43 75 72 73 6f 72 54 79 70 65 20 2d 20 51 55  iCursorType - QU
11330 45 52 59 5f 46 55 4c 4c 54 45 58 54 3b 0a 20 20  ERY_FULLTEXT;.  
11340 69 66 28 20 69 43 6f 6c 75 6d 6e 3c 30 20 7c 7c  if( iColumn<0 ||
11350 20 69 43 6f 6c 75 6d 6e 3e 3d 6e 43 6f 6c 75 6d   iColumn>=nColum
11360 6e 20 29 7b 0a 20 20 20 20 69 46 69 72 73 74 20  n ){.    iFirst 
11370 3d 20 30 3b 0a 20 20 20 20 69 4c 61 73 74 20 3d  = 0;.    iLast =
11380 20 6e 43 6f 6c 75 6d 6e 2d 31 3b 0a 20 20 7d 65   nColumn-1;.  }e
11390 6c 73 65 7b 0a 20 20 20 20 69 46 69 72 73 74 20  lse{.    iFirst 
113a0 3d 20 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 69  = iColumn;.    i
113b0 4c 61 73 74 20 3d 20 69 43 6f 6c 75 6d 6e 3b 0a  Last = iColumn;.
113c0 20 20 7d 0a 20 20 66 6f 72 28 69 3d 69 46 69 72    }.  for(i=iFir
113d0 73 74 3b 20 69 3c 3d 69 4c 61 73 74 3b 20 69 2b  st; i<=iLast; i+
113e0 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68  +){.    const ch
113f0 61 72 20 2a 7a 44 6f 63 3b 0a 20 20 20 20 69 6e  ar *zDoc;.    in
11400 74 20 6e 44 6f 63 3b 0a 20 20 20 20 7a 44 6f 63  t nDoc;.    zDoc
11410 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29   = (const char*)
11420 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
11430 65 78 74 28 70 2d 3e 70 53 74 6d 74 2c 20 69 2b  ext(p->pStmt, i+
11440 31 29 3b 0a 20 20 20 20 6e 44 6f 63 20 3d 20 73  1);.    nDoc = s
11450 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79  qlite3_column_by
11460 74 65 73 28 70 2d 3e 70 53 74 6d 74 2c 20 69 2b  tes(p->pStmt, i+
11470 31 29 3b 0a 20 20 20 20 73 6e 69 70 70 65 74 4f  1);.    snippetO
11480 66 66 73 65 74 73 4f 66 43 6f 6c 75 6d 6e 28 26  ffsetsOfColumn(&
11490 70 2d 3e 71 2c 20 26 70 2d 3e 73 6e 69 70 70 65  p->q, &p->snippe
114a0 74 2c 20 69 2c 20 7a 44 6f 63 2c 20 6e 44 6f 63  t, i, zDoc, nDoc
114b0 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
114c0 43 6f 6e 76 65 72 74 20 74 68 65 20 69 6e 66 6f  Convert the info
114d0 72 6d 61 74 69 6f 6e 20 69 6e 20 74 68 65 20 61  rmation in the a
114e0 4d 61 74 63 68 5b 5d 20 61 72 72 61 79 20 6f 66  Match[] array of
114f0 20 74 68 65 20 73 6e 69 70 70 65 74 0a 2a 2a 20   the snippet.** 
11500 69 6e 74 6f 20 74 68 65 20 73 74 72 69 6e 67 20  into the string 
11510 7a 4f 66 66 73 65 74 5b 30 2e 2e 6e 4f 66 66 73  zOffset[0..nOffs
11520 65 74 2d 31 5d 2e 0a 2a 2f 0a 73 74 61 74 69 63  et-1]..*/.static
11530 20 76 6f 69 64 20 73 6e 69 70 70 65 74 4f 66 66   void snippetOff
11540 73 65 74 54 65 78 74 28 53 6e 69 70 70 65 74 20  setText(Snippet 
11550 2a 70 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  *p){.  int i;.  
11560 69 6e 74 20 63 6e 74 20 3d 20 30 3b 0a 20 20 53  int cnt = 0;.  S
11570 74 72 69 6e 67 42 75 66 66 65 72 20 73 62 3b 0a  tringBuffer sb;.
11580 20 20 63 68 61 72 20 7a 42 75 66 5b 32 30 30 5d    char zBuf[200]
11590 3b 0a 20 20 69 66 28 20 70 2d 3e 7a 4f 66 66 73  ;.  if( p->zOffs
115a0 65 74 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69  et ) return;.  i
115b0 6e 69 74 53 74 72 69 6e 67 42 75 66 66 65 72 28  nitStringBuffer(
115c0 26 73 62 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  &sb);.  for(i=0;
115d0 20 69 3c 70 2d 3e 6e 4d 61 74 63 68 3b 20 69 2b   i<p->nMatch; i+
115e0 2b 29 7b 0a 20 20 20 20 73 74 72 75 63 74 20 73  +){.    struct s
115f0 6e 69 70 70 65 74 4d 61 74 63 68 20 2a 70 4d 61  nippetMatch *pMa
11600 74 63 68 20 3d 20 26 70 2d 3e 61 4d 61 74 63 68  tch = &p->aMatch
11610 5b 69 5d 3b 0a 20 20 20 20 7a 42 75 66 5b 30 5d  [i];.    zBuf[0]
11620 20 3d 20 27 20 27 3b 0a 20 20 20 20 73 71 6c 69   = ' ';.    sqli
11630 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a  te3_snprintf(siz
11640 65 6f 66 28 7a 42 75 66 29 2d 31 2c 20 26 7a 42  eof(zBuf)-1, &zB
11650 75 66 5b 63 6e 74 3e 30 5d 2c 20 22 25 64 20 25  uf[cnt>0], "%d %
11660 64 20 25 64 20 25 64 22 2c 0a 20 20 20 20 20 20  d %d %d",.      
11670 20 20 70 4d 61 74 63 68 2d 3e 69 43 6f 6c 2c 20    pMatch->iCol, 
11680 70 4d 61 74 63 68 2d 3e 69 54 65 72 6d 2c 20 70  pMatch->iTerm, p
11690 4d 61 74 63 68 2d 3e 69 53 74 61 72 74 2c 20 70  Match->iStart, p
116a0 4d 61 74 63 68 2d 3e 6e 42 79 74 65 29 3b 0a 20  Match->nByte);. 
116b0 20 20 20 61 70 70 65 6e 64 28 26 73 62 2c 20 7a     append(&sb, z
116c0 42 75 66 29 3b 0a 20 20 20 20 63 6e 74 2b 2b 3b  Buf);.    cnt++;
116d0 0a 20 20 7d 0a 20 20 70 2d 3e 7a 4f 66 66 73 65  .  }.  p->zOffse
116e0 74 20 3d 20 73 62 2e 73 3b 0a 20 20 70 2d 3e 6e  t = sb.s;.  p->n
116f0 4f 66 66 73 65 74 20 3d 20 73 62 2e 6c 65 6e 3b  Offset = sb.len;
11700 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 7a 44 6f 63 5b 30  .}../*.** zDoc[0
11710 2e 2e 6e 44 6f 63 2d 31 5d 20 69 73 20 70 68 72  ..nDoc-1] is phr
11720 61 73 65 20 6f 66 20 74 65 78 74 2e 20 20 61 4d  ase of text.  aM
11730 61 74 63 68 5b 30 2e 2e 6e 4d 61 74 63 68 2d 31  atch[0..nMatch-1
11740 5d 20 61 72 65 20 61 20 73 65 74 0a 2a 2a 20 6f  ] are a set.** o
11750 66 20 6d 61 74 63 68 69 6e 67 20 77 6f 72 64 73  f matching words
11760 20 73 6f 6d 65 20 6f 66 20 77 68 69 63 68 20 6d   some of which m
11770 69 67 68 74 20 62 65 20 69 6e 20 7a 44 6f 63 2e  ight be in zDoc.
11780 20 20 7a 44 6f 63 20 69 73 20 63 6f 6c 75 6d 6e    zDoc is column
11790 0a 2a 2a 20 6e 75 6d 62 65 72 20 69 43 6f 6c 2e  .** number iCol.
117a0 0a 2a 2a 0a 2a 2a 20 69 42 72 65 61 6b 20 69 73  .**.** iBreak is
117b0 20 73 75 67 67 65 73 74 65 64 20 73 70 6f 74 20   suggested spot 
117c0 69 6e 20 7a 44 6f 63 20 77 68 65 72 65 20 77 65  in zDoc where we
117d0 20 63 6f 75 6c 64 20 62 65 67 69 6e 20 6f 72 20   could begin or 
117e0 65 6e 64 20 61 6e 0a 2a 2a 20 65 78 63 65 72 70  end an.** excerp
117f0 74 2e 20 20 52 65 74 75 72 6e 20 61 20 76 61 6c  t.  Return a val
11800 75 65 20 73 69 6d 69 6c 61 72 20 74 6f 20 69 42  ue similar to iB
11810 72 65 61 6b 20 62 75 74 20 70 6f 73 73 69 62 6c  reak but possibl
11820 79 20 61 64 6a 75 73 74 65 64 0a 2a 2a 20 74 6f  y adjusted.** to
11830 20 62 65 20 61 20 6c 69 74 74 6c 65 20 6c 65 66   be a little lef
11840 74 20 6f 72 20 72 69 67 68 74 20 73 6f 20 74 68  t or right so th
11850 61 74 20 74 68 65 20 62 72 65 61 6b 20 70 6f 69  at the break poi
11860 6e 74 20 69 73 20 62 65 74 74 65 72 2e 0a 2a 2f  nt is better..*/
11870 0a 73 74 61 74 69 63 20 69 6e 74 20 77 6f 72 64  .static int word
11880 42 6f 75 6e 64 61 72 79 28 0a 20 20 69 6e 74 20  Boundary(.  int 
11890 69 42 72 65 61 6b 2c 20 20 20 20 20 20 20 20 20  iBreak,         
118a0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
118b0 20 73 75 67 67 65 73 74 65 64 20 62 72 65 61 6b   suggested break
118c0 20 70 6f 69 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73   point */.  cons
118d0 74 20 63 68 61 72 20 2a 7a 44 6f 63 2c 20 20 20  t char *zDoc,   
118e0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 6f 63            /* Doc
118f0 75 6d 65 6e 74 20 74 65 78 74 20 2a 2f 0a 20 20  ument text */.  
11900 69 6e 74 20 6e 44 6f 63 2c 20 20 20 20 20 20 20  int nDoc,       
11910 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
11920 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   Number of bytes
11930 20 69 6e 20 7a 44 6f 63 5b 5d 20 2a 2f 0a 20 20   in zDoc[] */.  
11940 73 74 72 75 63 74 20 73 6e 69 70 70 65 74 4d 61  struct snippetMa
11950 74 63 68 20 2a 61 4d 61 74 63 68 2c 20 20 2f 2a  tch *aMatch,  /*
11960 20 4d 61 74 63 68 69 6e 67 20 77 6f 72 64 73 20   Matching words 
11970 2a 2f 0a 20 20 69 6e 74 20 6e 4d 61 74 63 68 2c  */.  int nMatch,
11980 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11990 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
119a0 65 6e 74 72 69 65 73 20 69 6e 20 61 4d 61 74 63  entries in aMatc
119b0 68 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f  h[] */.  int iCo
119c0 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l               
119d0 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63 6f         /* The co
119e0 6c 75 6d 6e 20 6e 75 6d 62 65 72 20 66 6f 72 20  lumn number for 
119f0 7a 44 6f 63 5b 5d 20 2a 2f 0a 29 7b 0a 20 20 69  zDoc[] */.){.  i
11a00 6e 74 20 69 3b 0a 20 20 69 66 28 20 69 42 72 65  nt i;.  if( iBre
11a10 61 6b 3c 3d 31 30 20 29 7b 0a 20 20 20 20 72 65  ak<=10 ){.    re
11a20 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 69 66  turn 0;.  }.  if
11a30 28 20 69 42 72 65 61 6b 3e 3d 6e 44 6f 63 2d 31  ( iBreak>=nDoc-1
11a40 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  0 ){.    return 
11a50 6e 44 6f 63 3b 0a 20 20 7d 0a 20 20 66 6f 72 28  nDoc;.  }.  for(
11a60 69 3d 30 3b 20 69 3c 6e 4d 61 74 63 68 20 26 26  i=0; i<nMatch &&
11a70 20 61 4d 61 74 63 68 5b 69 5d 2e 69 43 6f 6c 3c   aMatch[i].iCol<
11a80 69 43 6f 6c 3b 20 69 2b 2b 29 7b 7d 0a 20 20 77  iCol; i++){}.  w
11a90 68 69 6c 65 28 20 69 3c 6e 4d 61 74 63 68 20 26  hile( i<nMatch &
11aa0 26 20 61 4d 61 74 63 68 5b 69 5d 2e 69 53 74 61  & aMatch[i].iSta
11ab0 72 74 2b 61 4d 61 74 63 68 5b 69 5d 2e 6e 42 79  rt+aMatch[i].nBy
11ac0 74 65 3c 69 42 72 65 61 6b 20 29 7b 20 69 2b 2b  te<iBreak ){ i++
11ad0 3b 20 7d 0a 20 20 69 66 28 20 69 3c 6e 4d 61 74  ; }.  if( i<nMat
11ae0 63 68 20 29 7b 0a 20 20 20 20 69 66 28 20 61 4d  ch ){.    if( aM
11af0 61 74 63 68 5b 69 5d 2e 69 53 74 61 72 74 3c 69  atch[i].iStart<i
11b00 42 72 65 61 6b 2b 31 30 20 29 7b 0a 20 20 20 20  Break+10 ){.    
11b10 20 20 72 65 74 75 72 6e 20 61 4d 61 74 63 68 5b    return aMatch[
11b20 69 5d 2e 69 53 74 61 72 74 3b 0a 20 20 20 20 7d  i].iStart;.    }
11b30 0a 20 20 20 20 69 66 28 20 69 3e 30 20 26 26 20  .    if( i>0 && 
11b40 61 4d 61 74 63 68 5b 69 2d 31 5d 2e 69 53 74 61  aMatch[i-1].iSta
11b50 72 74 2b 61 4d 61 74 63 68 5b 69 2d 31 5d 2e 6e  rt+aMatch[i-1].n
11b60 42 79 74 65 3e 3d 69 42 72 65 61 6b 20 29 7b 0a  Byte>=iBreak ){.
11b70 20 20 20 20 20 20 72 65 74 75 72 6e 20 61 4d 61        return aMa
11b80 74 63 68 5b 69 2d 31 5d 2e 69 53 74 61 72 74 3b  tch[i-1].iStart;
11b90 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 66 6f 72  .    }.  }.  for
11ba0 28 69 3d 31 3b 20 69 3c 3d 31 30 3b 20 69 2b 2b  (i=1; i<=10; i++
11bb0 29 7b 0a 20 20 20 20 69 66 28 20 73 61 66 65 5f  ){.    if( safe_
11bc0 69 73 73 70 61 63 65 28 7a 44 6f 63 5b 69 42 72  isspace(zDoc[iBr
11bd0 65 61 6b 2d 69 5d 29 20 29 7b 0a 20 20 20 20 20  eak-i]) ){.     
11be0 20 72 65 74 75 72 6e 20 69 42 72 65 61 6b 20 2d   return iBreak -
11bf0 20 69 20 2b 20 31 3b 0a 20 20 20 20 7d 0a 20 20   i + 1;.    }.  
11c00 20 20 69 66 28 20 73 61 66 65 5f 69 73 73 70 61    if( safe_isspa
11c10 63 65 28 7a 44 6f 63 5b 69 42 72 65 61 6b 2b 69  ce(zDoc[iBreak+i
11c20 5d 29 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75  ]) ){.      retu
11c30 72 6e 20 69 42 72 65 61 6b 20 2b 20 69 20 2b 20  rn iBreak + i + 
11c40 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  1;.    }.  }.  r
11c50 65 74 75 72 6e 20 69 42 72 65 61 6b 3b 0a 7d 0a  eturn iBreak;.}.
11c60 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 20 53 74  ./*.** If the St
11c70 72 69 6e 67 42 75 66 66 65 72 20 64 6f 65 73 20  ringBuffer does 
11c80 6e 6f 74 20 65 6e 64 20 69 6e 20 77 68 69 74 65  not end in white
11c90 20 73 70 61 63 65 2c 20 61 64 64 20 61 20 73 69   space, add a si
11ca0 6e 67 6c 65 0a 2a 2a 20 73 70 61 63 65 20 63 68  ngle.** space ch
11cb0 61 72 61 63 74 65 72 20 74 6f 20 74 68 65 20 65  aracter to the e
11cc0 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  nd..*/.static vo
11cd0 69 64 20 61 70 70 65 6e 64 57 68 69 74 65 53 70  id appendWhiteSp
11ce0 61 63 65 28 53 74 72 69 6e 67 42 75 66 66 65 72  ace(StringBuffer
11cf0 20 2a 70 29 7b 0a 20 20 69 66 28 20 70 2d 3e 6c   *p){.  if( p->l
11d00 65 6e 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a  en==0 ) return;.
11d10 20 20 69 66 28 20 73 61 66 65 5f 69 73 73 70 61    if( safe_isspa
11d20 63 65 28 70 2d 3e 73 5b 70 2d 3e 6c 65 6e 2d 31  ce(p->s[p->len-1
11d30 5d 29 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 61  ]) ) return;.  a
11d40 70 70 65 6e 64 28 70 2c 20 22 20 22 29 3b 0a 7d  ppend(p, " ");.}
11d50 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 77  ../*.** Remove w
11d60 68 69 74 65 20 73 70 61 63 65 20 66 72 6f 6d 20  hite space from 
11d70 74 65 68 20 65 6e 64 20 6f 66 20 74 68 65 20 53  teh end of the S
11d80 74 72 69 6e 67 42 75 66 66 65 72 0a 2a 2f 0a 73  tringBuffer.*/.s
11d90 74 61 74 69 63 20 76 6f 69 64 20 74 72 69 6d 57  tatic void trimW
11da0 68 69 74 65 53 70 61 63 65 28 53 74 72 69 6e 67  hiteSpace(String
11db0 42 75 66 66 65 72 20 2a 70 29 7b 0a 20 20 77 68  Buffer *p){.  wh
11dc0 69 6c 65 28 20 70 2d 3e 6c 65 6e 3e 30 20 26 26  ile( p->len>0 &&
11dd0 20 73 61 66 65 5f 69 73 73 70 61 63 65 28 70 2d   safe_isspace(p-
11de0 3e 73 5b 70 2d 3e 6c 65 6e 2d 31 5d 29 20 29 7b  >s[p->len-1]) ){
11df0 0a 20 20 20 20 70 2d 3e 6c 65 6e 2d 2d 3b 0a 20  .    p->len--;. 
11e00 20 7d 0a 7d 0a 0a 0a 0a 2f 2a 0a 2a 2a 20 41 6c   }.}..../*.** Al
11e10 6c 6f 77 65 64 20 76 61 6c 75 65 73 20 66 6f 72  lowed values for
11e20 20 53 6e 69 70 70 65 74 2e 61 4d 61 74 63 68 5b   Snippet.aMatch[
11e30 5d 2e 73 6e 53 74 61 74 75 73 0a 2a 2f 0a 23 64  ].snStatus.*/.#d
11e40 65 66 69 6e 65 20 53 4e 49 50 50 45 54 5f 49 47  efine SNIPPET_IG
11e50 4e 4f 52 45 20 20 30 20 20 20 2f 2a 20 49 74 20  NORE  0   /* It 
11e60 69 73 20 6f 6b 20 74 6f 20 6f 6d 69 74 20 74 68  is ok to omit th
11e70 69 73 20 6d 61 74 63 68 20 66 72 6f 6d 20 74 68  is match from th
11e80 65 20 73 6e 69 70 70 65 74 20 2a 2f 0a 23 64 65  e snippet */.#de
11e90 66 69 6e 65 20 53 4e 49 50 50 45 54 5f 44 45 53  fine SNIPPET_DES
11ea0 49 52 45 44 20 31 20 20 20 2f 2a 20 57 65 20 77  IRED 1   /* We w
11eb0 61 6e 74 20 74 6f 20 69 6e 63 6c 75 64 65 20 74  ant to include t
11ec0 68 69 73 20 6d 61 74 63 68 20 69 6e 20 74 68 65  his match in the
11ed0 20 73 6e 69 70 70 65 74 20 2a 2f 0a 0a 2f 2a 0a   snippet */../*.
11ee0 2a 2a 20 47 65 6e 65 72 61 74 65 20 74 68 65 20  ** Generate the 
11ef0 74 65 78 74 20 6f 66 20 61 20 73 6e 69 70 70 65  text of a snippe
11f00 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t..*/.static voi
11f10 64 20 73 6e 69 70 70 65 74 54 65 78 74 28 0a 20  d snippetText(. 
11f20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72   fulltext_cursor
11f30 20 2a 70 43 75 72 73 6f 72 2c 20 20 20 2f 2a 20   *pCursor,   /* 
11f40 54 68 65 20 63 75 72 73 6f 72 20 77 65 20 6e 65  The cursor we ne
11f50 65 64 20 74 68 65 20 73 6e 69 70 70 65 74 20 66  ed the snippet f
11f60 6f 72 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  or */.  const ch
11f70 61 72 20 2a 7a 53 74 61 72 74 4d 61 72 6b 2c 20  ar *zStartMark, 
11f80 20 20 20 20 2f 2a 20 4d 61 72 6b 75 70 20 74 6f      /* Markup to
11f90 20 61 70 70 65 61 72 20 62 65 66 6f 72 65 20 65   appear before e
11fa0 61 63 68 20 6d 61 74 63 68 20 2a 2f 0a 20 20 63  ach match */.  c
11fb0 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 6e 64 4d  onst char *zEndM
11fc0 61 72 6b 2c 20 20 20 20 20 20 20 2f 2a 20 4d 61  ark,       /* Ma
11fd0 72 6b 75 70 20 74 6f 20 61 70 70 65 61 72 20 61  rkup to appear a
11fe0 66 74 65 72 20 65 61 63 68 20 6d 61 74 63 68 20  fter each match 
11ff0 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
12000 2a 7a 45 6c 6c 69 70 73 69 73 20 20 20 20 20 20  *zEllipsis      
12010 20 2f 2a 20 45 6c 6c 69 70 73 69 73 20 6d 61 72   /* Ellipsis mar
12020 6b 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 2c  k */.){.  int i,
12030 20 6a 3b 0a 20 20 73 74 72 75 63 74 20 73 6e 69   j;.  struct sni
12040 70 70 65 74 4d 61 74 63 68 20 2a 61 4d 61 74 63  ppetMatch *aMatc
12050 68 3b 0a 20 20 69 6e 74 20 6e 4d 61 74 63 68 3b  h;.  int nMatch;
12060 0a 20 20 69 6e 74 20 6e 44 65 73 69 72 65 64 3b  .  int nDesired;
12070 0a 20 20 53 74 72 69 6e 67 42 75 66 66 65 72 20  .  StringBuffer 
12080 73 62 3b 0a 20 20 69 6e 74 20 74 61 69 6c 43 6f  sb;.  int tailCo
12090 6c 3b 0a 20 20 69 6e 74 20 74 61 69 6c 4f 66 66  l;.  int tailOff
120a0 73 65 74 3b 0a 20 20 69 6e 74 20 69 43 6f 6c 3b  set;.  int iCol;
120b0 0a 20 20 69 6e 74 20 6e 44 6f 63 3b 0a 20 20 63  .  int nDoc;.  c
120c0 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 6f 63 3b  onst char *zDoc;
120d0 0a 20 20 69 6e 74 20 69 53 74 61 72 74 2c 20 69  .  int iStart, i
120e0 45 6e 64 3b 0a 20 20 69 6e 74 20 74 61 69 6c 45  End;.  int tailE
120f0 6c 6c 69 70 73 69 73 20 3d 20 30 3b 0a 20 20 69  llipsis = 0;.  i
12100 6e 74 20 69 4d 61 74 63 68 3b 0a 20 20 0a 0a 20  nt iMatch;.  .. 
12110 20 66 72 65 65 28 70 43 75 72 73 6f 72 2d 3e 73   free(pCursor->s
12120 6e 69 70 70 65 74 2e 7a 53 6e 69 70 70 65 74 29  nippet.zSnippet)
12130 3b 0a 20 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69  ;.  pCursor->sni
12140 70 70 65 74 2e 7a 53 6e 69 70 70 65 74 20 3d 20  ppet.zSnippet = 
12150 30 3b 0a 20 20 61 4d 61 74 63 68 20 3d 20 70 43  0;.  aMatch = pC
12160 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74 2e 61  ursor->snippet.a
12170 4d 61 74 63 68 3b 0a 20 20 6e 4d 61 74 63 68 20  Match;.  nMatch 
12180 3d 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70  = pCursor->snipp
12190 65 74 2e 6e 4d 61 74 63 68 3b 0a 20 20 69 6e 69  et.nMatch;.  ini
121a0 74 53 74 72 69 6e 67 42 75 66 66 65 72 28 26 73  tStringBuffer(&s
121b0 62 29 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20  b);..  for(i=0; 
121c0 69 3c 6e 4d 61 74 63 68 3b 20 69 2b 2b 29 7b 0a  i<nMatch; i++){.
121d0 20 20 20 20 61 4d 61 74 63 68 5b 69 5d 2e 73 6e      aMatch[i].sn
121e0 53 74 61 74 75 73 20 3d 20 53 4e 49 50 50 45 54  Status = SNIPPET
121f0 5f 49 47 4e 4f 52 45 3b 0a 20 20 7d 0a 20 20 6e  _IGNORE;.  }.  n
12200 44 65 73 69 72 65 64 20 3d 20 30 3b 0a 20 20 66  Desired = 0;.  f
12210 6f 72 28 69 3d 30 3b 20 69 3c 70 43 75 72 73 6f  or(i=0; i<pCurso
12220 72 2d 3e 71 2e 6e 54 65 72 6d 73 3b 20 69 2b 2b  r->q.nTerms; i++
12230 29 7b 0a 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20  ){.    for(j=0; 
12240 6a 3c 6e 4d 61 74 63 68 3b 20 6a 2b 2b 29 7b 0a  j<nMatch; j++){.
12250 20 20 20 20 20 20 69 66 28 20 61 4d 61 74 63 68        if( aMatch
12260 5b 6a 5d 2e 69 54 65 72 6d 3d 3d 69 20 29 7b 0a  [j].iTerm==i ){.
12270 20 20 20 20 20 20 20 20 61 4d 61 74 63 68 5b 6a          aMatch[j
12280 5d 2e 73 6e 53 74 61 74 75 73 20 3d 20 53 4e 49  ].snStatus = SNI
12290 50 50 45 54 5f 44 45 53 49 52 45 44 3b 0a 20 20  PPET_DESIRED;.  
122a0 20 20 20 20 20 20 6e 44 65 73 69 72 65 64 2b 2b        nDesired++
122b0 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
122c0 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
122d0 20 7d 0a 0a 20 20 69 4d 61 74 63 68 20 3d 20 30   }..  iMatch = 0
122e0 3b 0a 20 20 74 61 69 6c 43 6f 6c 20 3d 20 2d 31  ;.  tailCol = -1
122f0 3b 0a 20 20 74 61 69 6c 4f 66 66 73 65 74 20 3d  ;.  tailOffset =
12300 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69   0;.  for(i=0; i
12310 3c 6e 4d 61 74 63 68 20 26 26 20 6e 44 65 73 69  <nMatch && nDesi
12320 72 65 64 3e 30 3b 20 69 2b 2b 29 7b 0a 20 20 20  red>0; i++){.   
12330 20 69 66 28 20 61 4d 61 74 63 68 5b 69 5d 2e 73   if( aMatch[i].s
12340 6e 53 74 61 74 75 73 21 3d 53 4e 49 50 50 45 54  nStatus!=SNIPPET
12350 5f 44 45 53 49 52 45 44 20 29 20 63 6f 6e 74 69  _DESIRED ) conti
12360 6e 75 65 3b 0a 20 20 20 20 6e 44 65 73 69 72 65  nue;.    nDesire
12370 64 2d 2d 3b 0a 20 20 20 20 69 43 6f 6c 20 3d 20  d--;.    iCol = 
12380 61 4d 61 74 63 68 5b 69 5d 2e 69 43 6f 6c 3b 0a  aMatch[i].iCol;.
12390 20 20 20 20 7a 44 6f 63 20 3d 20 28 63 6f 6e 73      zDoc = (cons
123a0 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
123b0 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 43 75 72  column_text(pCur
123c0 73 6f 72 2d 3e 70 53 74 6d 74 2c 20 69 43 6f 6c  sor->pStmt, iCol
123d0 2b 31 29 3b 0a 20 20 20 20 6e 44 6f 63 20 3d 20  +1);.    nDoc = 
123e0 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62  sqlite3_column_b
123f0 79 74 65 73 28 70 43 75 72 73 6f 72 2d 3e 70 53  ytes(pCursor->pS
12400 74 6d 74 2c 20 69 43 6f 6c 2b 31 29 3b 0a 20 20  tmt, iCol+1);.  
12410 20 20 69 53 74 61 72 74 20 3d 20 61 4d 61 74 63    iStart = aMatc
12420 68 5b 69 5d 2e 69 53 74 61 72 74 20 2d 20 34 30  h[i].iStart - 40
12430 3b 0a 20 20 20 20 69 53 74 61 72 74 20 3d 20 77  ;.    iStart = w
12440 6f 72 64 42 6f 75 6e 64 61 72 79 28 69 53 74 61  ordBoundary(iSta
12450 72 74 2c 20 7a 44 6f 63 2c 20 6e 44 6f 63 2c 20  rt, zDoc, nDoc, 
12460 61 4d 61 74 63 68 2c 20 6e 4d 61 74 63 68 2c 20  aMatch, nMatch, 
12470 69 43 6f 6c 29 3b 0a 20 20 20 20 69 66 28 20 69  iCol);.    if( i
12480 53 74 61 72 74 3c 3d 31 30 20 29 7b 0a 20 20 20  Start<=10 ){.   
12490 20 20 20 69 53 74 61 72 74 20 3d 20 30 3b 0a 20     iStart = 0;. 
124a0 20 20 20 7d 0a 20 20 20 20 69 66 28 20 69 43 6f     }.    if( iCo
124b0 6c 3d 3d 74 61 69 6c 43 6f 6c 20 26 26 20 69 53  l==tailCol && iS
124c0 74 61 72 74 3c 3d 74 61 69 6c 4f 66 66 73 65 74  tart<=tailOffset
124d0 2b 32 30 20 29 7b 0a 20 20 20 20 20 20 69 53 74  +20 ){.      iSt
124e0 61 72 74 20 3d 20 74 61 69 6c 4f 66 66 73 65 74  art = tailOffset
124f0 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
12500 28 69 43 6f 6c 21 3d 74 61 69 6c 43 6f 6c 20 26  (iCol!=tailCol &
12510 26 20 74 61 69 6c 43 6f 6c 3e 3d 30 29 20 7c 7c  & tailCol>=0) ||
12520 20 69 53 74 61 72 74 21 3d 74 61 69 6c 4f 66 66   iStart!=tailOff
12530 73 65 74 20 29 7b 0a 20 20 20 20 20 20 74 72 69  set ){.      tri
12540 6d 57 68 69 74 65 53 70 61 63 65 28 26 73 62 29  mWhiteSpace(&sb)
12550 3b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 57 68  ;.      appendWh
12560 69 74 65 53 70 61 63 65 28 26 73 62 29 3b 0a 20  iteSpace(&sb);. 
12570 20 20 20 20 20 61 70 70 65 6e 64 28 26 73 62 2c       append(&sb,
12580 20 7a 45 6c 6c 69 70 73 69 73 29 3b 0a 20 20 20   zEllipsis);.   
12590 20 20 20 61 70 70 65 6e 64 57 68 69 74 65 53 70     appendWhiteSp
125a0 61 63 65 28 26 73 62 29 3b 0a 20 20 20 20 7d 0a  ace(&sb);.    }.
125b0 20 20 20 20 69 45 6e 64 20 3d 20 61 4d 61 74 63      iEnd = aMatc
125c0 68 5b 69 5d 2e 69 53 74 61 72 74 20 2b 20 61 4d  h[i].iStart + aM
125d0 61 74 63 68 5b 69 5d 2e 6e 42 79 74 65 20 2b 20  atch[i].nByte + 
125e0 34 30 3b 0a 20 20 20 20 69 45 6e 64 20 3d 20 77  40;.    iEnd = w
125f0 6f 72 64 42 6f 75 6e 64 61 72 79 28 69 45 6e 64  ordBoundary(iEnd
12600 2c 20 7a 44 6f 63 2c 20 6e 44 6f 63 2c 20 61 4d  , zDoc, nDoc, aM
12610 61 74 63 68 2c 20 6e 4d 61 74 63 68 2c 20 69 43  atch, nMatch, iC
12620 6f 6c 29 3b 0a 20 20 20 20 69 66 28 20 69 45 6e  ol);.    if( iEn
12630 64 3e 3d 6e 44 6f 63 2d 31 30 20 29 7b 0a 20 20  d>=nDoc-10 ){.  
12640 20 20 20 20 69 45 6e 64 20 3d 20 6e 44 6f 63 3b      iEnd = nDoc;
12650 0a 20 20 20 20 20 20 74 61 69 6c 45 6c 6c 69 70  .      tailEllip
12660 73 69 73 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c  sis = 0;.    }el
12670 73 65 7b 0a 20 20 20 20 20 20 74 61 69 6c 45 6c  se{.      tailEl
12680 6c 69 70 73 69 73 20 3d 20 31 3b 0a 20 20 20 20  lipsis = 1;.    
12690 7d 0a 20 20 20 20 77 68 69 6c 65 28 20 69 4d 61  }.    while( iMa
126a0 74 63 68 3c 6e 4d 61 74 63 68 20 26 26 20 61 4d  tch<nMatch && aM
126b0 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69 43 6f  atch[iMatch].iCo
126c0 6c 3c 69 43 6f 6c 20 29 7b 20 69 4d 61 74 63 68  l<iCol ){ iMatch
126d0 2b 2b 3b 20 7d 0a 20 20 20 20 77 68 69 6c 65 28  ++; }.    while(
126e0 20 69 53 74 61 72 74 3c 69 45 6e 64 20 29 7b 0a   iStart<iEnd ){.
126f0 20 20 20 20 20 20 77 68 69 6c 65 28 20 69 4d 61        while( iMa
12700 74 63 68 3c 6e 4d 61 74 63 68 20 26 26 20 61 4d  tch<nMatch && aM
12710 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69 53 74  atch[iMatch].iSt
12720 61 72 74 3c 69 53 74 61 72 74 0a 20 20 20 20 20  art<iStart.     
12730 20 20 20 20 20 20 20 20 26 26 20 61 4d 61 74 63          && aMatc
12740 68 5b 69 4d 61 74 63 68 5d 2e 69 43 6f 6c 3c 3d  h[iMatch].iCol<=
12750 69 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20 20 20  iCol ){.        
12760 69 4d 61 74 63 68 2b 2b 3b 0a 20 20 20 20 20 20  iMatch++;.      
12770 7d 0a 20 20 20 20 20 20 69 66 28 20 69 4d 61 74  }.      if( iMat
12780 63 68 3c 6e 4d 61 74 63 68 20 26 26 20 61 4d 61  ch<nMatch && aMa
12790 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69 53 74 61  tch[iMatch].iSta
127a0 72 74 3c 69 45 6e 64 0a 20 20 20 20 20 20 20 20  rt<iEnd.        
127b0 20 20 20 20 20 26 26 20 61 4d 61 74 63 68 5b 69       && aMatch[i
127c0 4d 61 74 63 68 5d 2e 69 43 6f 6c 3d 3d 69 43 6f  Match].iCol==iCo
127d0 6c 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 61 70  l ){.        nap
127e0 70 65 6e 64 28 26 73 62 2c 20 26 7a 44 6f 63 5b  pend(&sb, &zDoc[
127f0 69 53 74 61 72 74 5d 2c 20 61 4d 61 74 63 68 5b  iStart], aMatch[
12800 69 4d 61 74 63 68 5d 2e 69 53 74 61 72 74 20 2d  iMatch].iStart -
12810 20 69 53 74 61 72 74 29 3b 0a 20 20 20 20 20 20   iStart);.      
12820 20 20 69 53 74 61 72 74 20 3d 20 61 4d 61 74 63    iStart = aMatc
12830 68 5b 69 4d 61 74 63 68 5d 2e 69 53 74 61 72 74  h[iMatch].iStart
12840 3b 0a 20 20 20 20 20 20 20 20 61 70 70 65 6e 64  ;.        append
12850 28 26 73 62 2c 20 7a 53 74 61 72 74 4d 61 72 6b  (&sb, zStartMark
12860 29 3b 0a 20 20 20 20 20 20 20 20 6e 61 70 70 65  );.        nappe
12870 6e 64 28 26 73 62 2c 20 26 7a 44 6f 63 5b 69 53  nd(&sb, &zDoc[iS
12880 74 61 72 74 5d 2c 20 61 4d 61 74 63 68 5b 69 4d  tart], aMatch[iM
12890 61 74 63 68 5d 2e 6e 42 79 74 65 29 3b 0a 20 20  atch].nByte);.  
128a0 20 20 20 20 20 20 61 70 70 65 6e 64 28 26 73 62        append(&sb
128b0 2c 20 7a 45 6e 64 4d 61 72 6b 29 3b 0a 20 20 20  , zEndMark);.   
128c0 20 20 20 20 20 69 53 74 61 72 74 20 2b 3d 20 61       iStart += a
128d0 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e 6e 42  Match[iMatch].nB
128e0 79 74 65 3b 0a 20 20 20 20 20 20 20 20 66 6f 72  yte;.        for
128f0 28 6a 3d 69 4d 61 74 63 68 2b 31 3b 20 6a 3c 6e  (j=iMatch+1; j<n
12900 4d 61 74 63 68 3b 20 6a 2b 2b 29 7b 0a 20 20 20  Match; j++){.   
12910 20 20 20 20 20 20 20 69 66 28 20 61 4d 61 74 63         if( aMatc
12920 68 5b 6a 5d 2e 69 54 65 72 6d 3d 3d 61 4d 61 74  h[j].iTerm==aMat
12930 63 68 5b 69 4d 61 74 63 68 5d 2e 69 54 65 72 6d  ch[iMatch].iTerm
12940 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26  .              &
12950 26 20 61 4d 61 74 63 68 5b 6a 5d 2e 73 6e 53 74  & aMatch[j].snSt
12960 61 74 75 73 3d 3d 53 4e 49 50 50 45 54 5f 44 45  atus==SNIPPET_DE
12970 53 49 52 45 44 20 29 7b 0a 20 20 20 20 20 20 20  SIRED ){.       
12980 20 20 20 20 20 6e 44 65 73 69 72 65 64 2d 2d 3b       nDesired--;
12990 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 4d 61  .            aMa
129a0 74 63 68 5b 6a 5d 2e 73 6e 53 74 61 74 75 73 20  tch[j].snStatus 
129b0 3d 20 53 4e 49 50 50 45 54 5f 49 47 4e 4f 52 45  = SNIPPET_IGNORE
129c0 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
129d0 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65        }.      }e
129e0 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 6e 61 70  lse{.        nap
129f0 70 65 6e 64 28 26 73 62 2c 20 26 7a 44 6f 63 5b  pend(&sb, &zDoc[
12a00 69 53 74 61 72 74 5d 2c 20 69 45 6e 64 20 2d 20  iStart], iEnd - 
12a10 69 53 74 61 72 74 29 3b 0a 20 20 20 20 20 20 20  iStart);.       
12a20 20 69 53 74 61 72 74 20 3d 20 69 45 6e 64 3b 0a   iStart = iEnd;.
12a30 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
12a40 20 20 74 61 69 6c 43 6f 6c 20 3d 20 69 43 6f 6c    tailCol = iCol
12a50 3b 0a 20 20 20 20 74 61 69 6c 4f 66 66 73 65 74  ;.    tailOffset
12a60 20 3d 20 69 45 6e 64 3b 0a 20 20 7d 0a 20 20 74   = iEnd;.  }.  t
12a70 72 69 6d 57 68 69 74 65 53 70 61 63 65 28 26 73  rimWhiteSpace(&s
12a80 62 29 3b 0a 20 20 69 66 28 20 74 61 69 6c 45 6c  b);.  if( tailEl
12a90 6c 69 70 73 69 73 20 29 7b 0a 20 20 20 20 61 70  lipsis ){.    ap
12aa0 70 65 6e 64 57 68 69 74 65 53 70 61 63 65 28 26  pendWhiteSpace(&
12ab0 73 62 29 3b 0a 20 20 20 20 61 70 70 65 6e 64 28  sb);.    append(
12ac0 26 73 62 2c 20 7a 45 6c 6c 69 70 73 69 73 29 3b  &sb, zEllipsis);
12ad0 0a 20 20 7d 0a 20 20 70 43 75 72 73 6f 72 2d 3e  .  }.  pCursor->
12ae0 73 6e 69 70 70 65 74 2e 7a 53 6e 69 70 70 65 74  snippet.zSnippet
12af0 20 3d 20 73 62 2e 73 3b 0a 20 20 70 43 75 72 73   = sb.s;.  pCurs
12b00 6f 72 2d 3e 73 6e 69 70 70 65 74 2e 6e 53 6e 69  or->snippet.nSni
12b10 70 70 65 74 20 3d 20 73 62 2e 6c 65 6e 3b 20 20  ppet = sb.len;  
12b20 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65  .}.../*.** Close
12b30 20 74 68 65 20 63 75 72 73 6f 72 2e 20 20 46 6f   the cursor.  Fo
12b40 72 20 61 64 64 69 74 69 6f 6e 61 6c 20 69 6e 66  r additional inf
12b50 6f 72 6d 61 74 69 6f 6e 20 73 65 65 20 74 68 65  ormation see the
12b60 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 0a 2a   documentation.*
12b70 2a 20 6f 6e 20 74 68 65 20 78 43 6c 6f 73 65 20  * on the xClose 
12b80 6d 65 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69  method of the vi
12b90 72 74 75 61 6c 20 74 61 62 6c 65 20 69 6e 74 65  rtual table inte
12ba0 72 66 61 63 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rface..*/.static
12bb0 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 43 6c 6f   int fulltextClo
12bc0 73 65 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  se(sqlite3_vtab_
12bd0 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29  cursor *pCursor)
12be0 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72  {.  fulltext_cur
12bf0 73 6f 72 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65  sor *c = (fullte
12c00 78 74 5f 63 75 72 73 6f 72 20 2a 29 20 70 43 75  xt_cursor *) pCu
12c10 72 73 6f 72 3b 0a 20 20 54 52 41 43 45 28 28 22  rsor;.  TRACE(("
12c20 46 54 53 31 20 43 6c 6f 73 65 20 25 70 5c 6e 22  FTS1 Close %p\n"
12c30 2c 20 63 29 29 3b 0a 20 20 73 71 6c 69 74 65 33  , c));.  sqlite3
12c40 5f 66 69 6e 61 6c 69 7a 65 28 63 2d 3e 70 53 74  _finalize(c->pSt
12c50 6d 74 29 3b 0a 20 20 71 75 65 72 79 43 6c 65 61  mt);.  queryClea
12c60 72 28 26 63 2d 3e 71 29 3b 0a 20 20 73 6e 69 70  r(&c->q);.  snip
12c70 70 65 74 43 6c 65 61 72 28 26 63 2d 3e 73 6e 69  petClear(&c->sni
12c80 70 70 65 74 29 3b 0a 20 20 69 66 28 20 63 2d 3e  ppet);.  if( c->
12c90 72 65 73 75 6c 74 2e 70 44 6f 63 6c 69 73 74 21  result.pDoclist!
12ca0 3d 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 64 6f 63  =NULL ){.    doc
12cb0 4c 69 73 74 44 65 6c 65 74 65 28 63 2d 3e 72 65  ListDelete(c->re
12cc0 73 75 6c 74 2e 70 44 6f 63 6c 69 73 74 29 3b 0a  sult.pDoclist);.
12cd0 20 20 7d 0a 20 20 66 72 65 65 28 63 29 3b 0a 20    }.  free(c);. 
12ce0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
12cf0 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  K;.}..static int
12d00 20 66 75 6c 6c 74 65 78 74 4e 65 78 74 28 73 71   fulltextNext(sq
12d10 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
12d20 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20 66  r *pCursor){.  f
12d30 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a  ulltext_cursor *
12d40 63 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f 63 75  c = (fulltext_cu
12d50 72 73 6f 72 20 2a 29 20 70 43 75 72 73 6f 72 3b  rsor *) pCursor;
12d60 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  .  sqlite_int64 
12d70 69 44 6f 63 69 64 3b 0a 20 20 69 6e 74 20 72 63  iDocid;.  int rc
12d80 3b 0a 0a 20 20 54 52 41 43 45 28 28 22 46 54 53  ;..  TRACE(("FTS
12d90 31 20 4e 65 78 74 20 25 70 5c 6e 22 2c 20 70 43  1 Next %p\n", pC
12da0 75 72 73 6f 72 29 29 3b 0a 20 20 73 6e 69 70 70  ursor));.  snipp
12db0 65 74 43 6c 65 61 72 28 26 63 2d 3e 73 6e 69 70  etClear(&c->snip
12dc0 70 65 74 29 3b 0a 20 20 69 66 28 20 63 2d 3e 69  pet);.  if( c->i
12dd0 43 75 72 73 6f 72 54 79 70 65 20 3c 20 51 55 45  CursorType < QUE
12de0 52 59 5f 46 55 4c 4c 54 45 58 54 20 29 7b 0a 20  RY_FULLTEXT ){. 
12df0 20 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73     /* TODO(shess
12e00 29 20 48 61 6e 64 6c 65 20 53 51 4c 49 54 45 5f  ) Handle SQLITE_
12e10 53 43 48 45 4d 41 20 41 4e 44 20 53 51 4c 49 54  SCHEMA AND SQLIT
12e20 45 5f 42 55 53 59 2e 20 2a 2f 0a 20 20 20 20 72  E_BUSY. */.    r
12e30 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70  c = sqlite3_step
12e40 28 63 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20  (c->pStmt);.    
12e50 73 77 69 74 63 68 28 20 72 63 20 29 7b 0a 20 20  switch( rc ){.  
12e60 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
12e70 52 4f 57 3a 0a 20 20 20 20 20 20 20 20 63 2d 3e  ROW:.        c->
12e80 65 6f 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  eof = 0;.       
12e90 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
12ea0 4b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 53 51  K;.      case SQ
12eb0 4c 49 54 45 5f 44 4f 4e 45 3a 0a 20 20 20 20 20  LITE_DONE:.     
12ec0 20 20 20 63 2d 3e 65 6f 66 20 3d 20 31 3b 0a 20     c->eof = 1;. 
12ed0 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51         return SQ
12ee0 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 64  LITE_OK;.      d
12ef0 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20  efault:.        
12f00 63 2d 3e 65 6f 66 20 3d 20 31 3b 0a 20 20 20 20  c->eof = 1;.    
12f10 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
12f20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 20     }.  } else { 
12f30 20 2f 2a 20 66 75 6c 6c 2d 74 65 78 74 20 71 75   /* full-text qu
12f40 65 72 79 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20  ery */.    rc = 
12f50 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 63 2d  sqlite3_reset(c-
12f60 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28  >pStmt);.    if(
12f70 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
12f80 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20   return rc;..   
12f90 20 69 44 6f 63 69 64 20 3d 20 6e 65 78 74 44 6f   iDocid = nextDo
12fa0 63 69 64 28 26 63 2d 3e 72 65 73 75 6c 74 29 3b  cid(&c->result);
12fb0 0a 20 20 20 20 69 66 28 20 69 44 6f 63 69 64 3d  .    if( iDocid=
12fc0 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 2d 3e 65  =0 ){.      c->e
12fd0 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20 20 72 65  of = 1;.      re
12fe0 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
12ff0 20 20 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73      }.    rc = s
13000 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36  qlite3_bind_int6
13010 34 28 63 2d 3e 70 53 74 6d 74 2c 20 31 2c 20 69  4(c->pStmt, 1, i
13020 44 6f 63 69 64 29 3b 0a 20 20 20 20 69 66 28 20  Docid);.    if( 
13030 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
13040 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 2f  return rc;.    /
13050 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 48 61  * TODO(shess) Ha
13060 6e 64 6c 65 20 53 51 4c 49 54 45 5f 53 43 48 45  ndle SQLITE_SCHE
13070 4d 41 20 41 4e 44 20 53 51 4c 49 54 45 5f 42 55  MA AND SQLITE_BU
13080 53 59 2e 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20  SY. */.    rc = 
13090 73 71 6c 69 74 65 33 5f 73 74 65 70 28 63 2d 3e  sqlite3_step(c->
130a0 70 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20  pStmt);.    if( 
130b0 72 63 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  rc==SQLITE_ROW )
130c0 7b 20 20 20 2f 2a 20 74 68 65 20 63 61 73 65 20  {   /* the case 
130d0 77 65 20 65 78 70 65 63 74 20 2a 2f 0a 20 20 20  we expect */.   
130e0 20 20 20 63 2d 3e 65 6f 66 20 3d 20 30 3b 0a 20     c->eof = 0;. 
130f0 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
13100 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 20  TE_OK;.    }.   
13110 20 2f 2a 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   /* an error occ
13120 75 72 72 65 64 3b 20 61 62 6f 72 74 20 2a 2f 0a  urred; abort */.
13130 20 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d 53      return rc==S
13140 51 4c 49 54 45 5f 44 4f 4e 45 20 3f 20 53 51 4c  QLITE_DONE ? SQL
13150 49 54 45 5f 45 52 52 4f 52 20 3a 20 72 63 3b 0a  ITE_ERROR : rc;.
13160 20 20 7d 0a 7d 0a 0a 0a 2f 2a 20 52 65 74 75 72    }.}.../* Retur
13170 6e 20 61 20 44 6f 63 4c 69 73 74 20 63 6f 72 72  n a DocList corr
13180 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 74 68 65  esponding to the
13190 20 71 75 65 72 79 20 74 65 72 6d 20 2a 70 54 65   query term *pTe
131a0 72 6d 2e 20 20 49 66 20 2a 70 54 65 72 6d 0a 2a  rm.  If *pTerm.*
131b0 2a 20 69 73 20 74 68 65 20 66 69 72 73 74 20 74  * is the first t
131c0 65 72 6d 20 6f 66 20 61 20 70 68 72 61 73 65 20  erm of a phrase 
131d0 71 75 65 72 79 2c 20 67 6f 20 61 68 65 61 64 20  query, go ahead 
131e0 61 6e 64 20 65 76 61 6c 75 61 74 65 20 74 68 65  and evaluate the
131f0 20 70 68 72 61 73 65 0a 2a 2a 20 71 75 65 72 79   phrase.** query
13200 20 61 6e 64 20 72 65 74 75 72 6e 20 74 68 65 20   and return the 
13210 64 6f 63 6c 69 73 74 20 66 6f 72 20 74 68 65 20  doclist for the 
13220 65 6e 74 69 72 65 20 70 68 72 61 73 65 20 71 75  entire phrase qu
13230 65 72 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 72  ery..**.** The r
13240 65 73 75 6c 74 20 69 73 20 73 74 6f 72 65 64 20  esult is stored 
13250 69 6e 20 70 54 65 72 6d 2d 3e 64 6f 63 6c 69 73  in pTerm->doclis
13260 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t..*/.static int
13270 20 64 6f 63 4c 69 73 74 4f 66 54 65 72 6d 28 0a   docListOfTerm(.
13280 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20    fulltext_vtab 
13290 2a 76 2c 20 20 20 20 20 2f 2a 20 54 68 65 20 66  *v,     /* The f
132a0 75 6c 6c 20 74 65 78 74 20 69 6e 64 65 78 20 2a  ull text index *
132b0 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 2c  /.  int iColumn,
132c0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 63 6f 6c            /* col
132d0 75 6d 6e 20 74 6f 20 72 65 73 74 72 69 63 74 20  umn to restrict 
132e0 74 6f 2e 20 20 4e 6f 20 72 65 73 74 72 69 74 69  to.  No restriti
132f0 6f 6e 20 69 66 20 3e 3d 6e 43 6f 6c 75 6d 6e 20  on if >=nColumn 
13300 2a 2f 0a 20 20 51 75 65 72 79 54 65 72 6d 20 2a  */.  QueryTerm *
13310 70 51 54 65 72 6d 2c 20 20 20 20 2f 2a 20 54 65  pQTerm,    /* Te
13320 72 6d 20 77 65 20 61 72 65 20 6c 6f 6f 6b 69 6e  rm we are lookin
13330 67 20 66 6f 72 2c 20 6f 72 20 31 73 74 20 74 65  g for, or 1st te
13340 72 6d 20 6f 66 20 61 20 70 68 72 61 73 65 20 2a  rm of a phrase *
13350 2f 0a 20 20 44 6f 63 4c 69 73 74 20 2a 2a 70 70  /.  DocList **pp
13360 52 65 73 75 6c 74 20 20 20 20 2f 2a 20 57 72 69  Result    /* Wri
13370 74 65 20 74 68 65 20 72 65 73 75 6c 74 20 68 65  te the result he
13380 72 65 20 2a 2f 0a 29 7b 0a 20 20 44 6f 63 4c 69  re */.){.  DocLi
13390 73 74 20 2a 70 4c 65 66 74 2c 20 2a 70 52 69 67  st *pLeft, *pRig
133a0 68 74 2c 20 2a 70 4e 65 77 3b 0a 20 20 69 6e 74  ht, *pNew;.  int
133b0 20 69 2c 20 72 63 3b 0a 0a 20 20 70 4c 65 66 74   i, rc;..  pLeft
133c0 20 3d 20 64 6f 63 4c 69 73 74 4e 65 77 28 44 4c   = docListNew(DL
133d0 5f 50 4f 53 49 54 49 4f 4e 53 29 3b 0a 20 20 72  _POSITIONS);.  r
133e0 63 20 3d 20 74 65 72 6d 5f 73 65 6c 65 63 74 5f  c = term_select_
133f0 61 6c 6c 28 76 2c 20 69 43 6f 6c 75 6d 6e 2c 20  all(v, iColumn, 
13400 70 51 54 65 72 6d 2d 3e 70 54 65 72 6d 2c 20 70  pQTerm->pTerm, p
13410 51 54 65 72 6d 2d 3e 6e 54 65 72 6d 2c 20 70 4c  QTerm->nTerm, pL
13420 65 66 74 29 3b 0a 20 20 69 66 28 20 72 63 20 29  eft);.  if( rc )
13430 7b 0a 20 20 20 20 64 6f 63 4c 69 73 74 44 65 6c  {.    docListDel
13440 65 74 65 28 70 4c 65 66 74 29 3b 0a 20 20 20 20  ete(pLeft);.    
13450 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20  return rc;.  }. 
13460 20 66 6f 72 28 69 3d 31 3b 20 69 3c 3d 70 51 54   for(i=1; i<=pQT
13470 65 72 6d 2d 3e 6e 50 68 72 61 73 65 3b 20 69 2b  erm->nPhrase; i+
13480 2b 29 7b 0a 20 20 20 20 70 52 69 67 68 74 20 3d  +){.    pRight =
13490 20 64 6f 63 4c 69 73 74 4e 65 77 28 44 4c 5f 50   docListNew(DL_P
134a0 4f 53 49 54 49 4f 4e 53 29 3b 0a 20 20 20 20 72  OSITIONS);.    r
134b0 63 20 3d 20 74 65 72 6d 5f 73 65 6c 65 63 74 5f  c = term_select_
134c0 61 6c 6c 28 76 2c 20 69 43 6f 6c 75 6d 6e 2c 20  all(v, iColumn, 
134d0 70 51 54 65 72 6d 5b 69 5d 2e 70 54 65 72 6d 2c  pQTerm[i].pTerm,
134e0 20 70 51 54 65 72 6d 5b 69 5d 2e 6e 54 65 72 6d   pQTerm[i].nTerm
134f0 2c 20 70 52 69 67 68 74 29 3b 0a 20 20 20 20 69  , pRight);.    i
13500 66 28 20 72 63 20 29 7b 0a 20 20 20 20 20 20 64  f( rc ){.      d
13510 6f 63 4c 69 73 74 44 65 6c 65 74 65 28 70 4c 65  ocListDelete(pLe
13520 66 74 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72  ft);.      retur
13530 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20  n rc;.    }.    
13540 70 4e 65 77 20 3d 20 64 6f 63 4c 69 73 74 4e 65  pNew = docListNe
13550 77 28 69 3c 70 51 54 65 72 6d 2d 3e 6e 50 68 72  w(i<pQTerm->nPhr
13560 61 73 65 20 3f 20 44 4c 5f 50 4f 53 49 54 49 4f  ase ? DL_POSITIO
13570 4e 53 20 3a 20 44 4c 5f 44 4f 43 49 44 53 29 3b  NS : DL_DOCIDS);
13580 0a 20 20 20 20 64 6f 63 4c 69 73 74 50 68 72 61  .    docListPhra
13590 73 65 4d 65 72 67 65 28 70 4c 65 66 74 2c 20 70  seMerge(pLeft, p
135a0 52 69 67 68 74 2c 20 70 4e 65 77 29 3b 0a 20 20  Right, pNew);.  
135b0 20 20 64 6f 63 4c 69 73 74 44 65 6c 65 74 65 28    docListDelete(
135c0 70 4c 65 66 74 29 3b 0a 20 20 20 20 64 6f 63 4c  pLeft);.    docL
135d0 69 73 74 44 65 6c 65 74 65 28 70 52 69 67 68 74  istDelete(pRight
135e0 29 3b 0a 20 20 20 20 70 4c 65 66 74 20 3d 20 70  );.    pLeft = p
135f0 4e 65 77 3b 0a 20 20 7d 0a 20 20 2a 70 70 52 65  New;.  }.  *ppRe
13600 73 75 6c 74 20 3d 20 70 4c 65 66 74 3b 0a 20 20  sult = pLeft;.  
13610 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
13620 3b 0a 7d 0a 0a 2f 2a 20 41 64 64 20 61 20 6e 65  ;.}../* Add a ne
13630 77 20 74 65 72 6d 20 70 54 65 72 6d 5b 30 2e 2e  w term pTerm[0..
13640 6e 54 65 72 6d 2d 31 5d 20 74 6f 20 74 68 65 20  nTerm-1] to the 
13650 71 75 65 72 79 20 2a 71 2e 0a 2a 2f 0a 73 74 61  query *q..*/.sta
13660 74 69 63 20 76 6f 69 64 20 71 75 65 72 79 41 64  tic void queryAd
13670 64 28 51 75 65 72 79 20 2a 71 2c 20 63 6f 6e 73  d(Query *q, cons
13680 74 20 63 68 61 72 20 2a 70 54 65 72 6d 2c 20 69  t char *pTerm, i
13690 6e 74 20 6e 54 65 72 6d 29 7b 0a 20 20 51 75 65  nt nTerm){.  Que
136a0 72 79 54 65 72 6d 20 2a 74 3b 0a 20 20 2b 2b 71  ryTerm *t;.  ++q
136b0 2d 3e 6e 54 65 72 6d 73 3b 0a 20 20 71 2d 3e 70  ->nTerms;.  q->p
136c0 54 65 72 6d 73 20 3d 20 72 65 61 6c 6c 6f 63 28  Terms = realloc(
136d0 71 2d 3e 70 54 65 72 6d 73 2c 20 71 2d 3e 6e 54  q->pTerms, q->nT
136e0 65 72 6d 73 20 2a 20 73 69 7a 65 6f 66 28 71 2d  erms * sizeof(q-
136f0 3e 70 54 65 72 6d 73 5b 30 5d 29 29 3b 0a 20 20  >pTerms[0]));.  
13700 69 66 28 20 71 2d 3e 70 54 65 72 6d 73 3d 3d 30  if( q->pTerms==0
13710 20 29 7b 0a 20 20 20 20 71 2d 3e 6e 54 65 72 6d   ){.    q->nTerm
13720 73 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75 72  s = 0;.    retur
13730 6e 3b 0a 20 20 7d 0a 20 20 74 20 3d 20 26 71 2d  n;.  }.  t = &q-
13740 3e 70 54 65 72 6d 73 5b 71 2d 3e 6e 54 65 72 6d  >pTerms[q->nTerm
13750 73 20 2d 20 31 5d 3b 0a 20 20 6d 65 6d 73 65 74  s - 1];.  memset
13760 28 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a 74  (t, 0, sizeof(*t
13770 29 29 3b 0a 20 20 74 2d 3e 70 54 65 72 6d 20 3d  ));.  t->pTerm =
13780 20 6d 61 6c 6c 6f 63 28 6e 54 65 72 6d 2b 31 29   malloc(nTerm+1)
13790 3b 0a 20 20 6d 65 6d 63 70 79 28 74 2d 3e 70 54  ;.  memcpy(t->pT
137a0 65 72 6d 2c 20 70 54 65 72 6d 2c 20 6e 54 65 72  erm, pTerm, nTer
137b0 6d 29 3b 0a 20 20 74 2d 3e 70 54 65 72 6d 5b 6e  m);.  t->pTerm[n
137c0 54 65 72 6d 5d 20 3d 20 30 3b 0a 20 20 74 2d 3e  Term] = 0;.  t->
137d0 6e 54 65 72 6d 20 3d 20 6e 54 65 72 6d 3b 0a 20  nTerm = nTerm;. 
137e0 20 74 2d 3e 69 73 4f 72 20 3d 20 71 2d 3e 6e 65   t->isOr = q->ne
137f0 78 74 49 73 4f 72 3b 0a 20 20 71 2d 3e 6e 65 78  xtIsOr;.  q->nex
13800 74 49 73 4f 72 20 3d 20 30 3b 0a 20 20 74 2d 3e  tIsOr = 0;.  t->
13810 69 43 6f 6c 75 6d 6e 20 3d 20 71 2d 3e 6e 65 78  iColumn = q->nex
13820 74 43 6f 6c 75 6d 6e 3b 0a 20 20 71 2d 3e 6e 65  tColumn;.  q->ne
13830 78 74 43 6f 6c 75 6d 6e 20 3d 20 71 2d 3e 64 66  xtColumn = q->df
13840 6c 74 43 6f 6c 75 6d 6e 3b 0a 7d 0a 0a 2f 2a 0a  ltColumn;.}../*.
13850 2a 2a 20 43 68 65 63 6b 20 74 6f 20 73 65 65 20  ** Check to see 
13860 69 66 20 74 68 65 20 73 74 72 69 6e 67 20 7a 54  if the string zT
13870 6f 6b 65 6e 5b 30 2e 2e 2e 6e 54 6f 6b 65 6e 2d  oken[0...nToken-
13880 31 5d 20 6d 61 74 63 68 65 73 20 61 6e 79 0a 2a  1] matches any.*
13890 2a 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 20 69 6e  * column name in
138a0 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62   the virtual tab
138b0 6c 65 2e 20 20 20 49 66 20 69 74 20 64 6f 65 73  le.   If it does
138c0 2c 0a 2a 2a 20 72 65 74 75 72 6e 20 74 68 65 20  ,.** return the 
138d0 7a 65 72 6f 2d 69 6e 64 65 78 65 64 20 63 6f 6c  zero-indexed col
138e0 75 6d 6e 20 6e 75 6d 62 65 72 2e 20 20 49 66 20  umn number.  If 
138f0 6e 6f 74 2c 20 72 65 74 75 72 6e 20 2d 31 2e 0a  not, return -1..
13900 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 63 68  */.static int ch
13910 65 63 6b 43 6f 6c 75 6d 6e 53 70 65 63 69 66 69  eckColumnSpecifi
13920 65 72 28 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76  er(.  fulltext_v
13930 74 61 62 20 2a 70 56 74 61 62 2c 20 20 20 20 2f  tab *pVtab,    /
13940 2a 20 54 68 65 20 76 69 72 74 75 61 6c 20 74 61  * The virtual ta
13950 62 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ble */.  const c
13960 68 61 72 20 2a 7a 54 6f 6b 65 6e 2c 20 20 20 20  har *zToken,    
13970 20 20 2f 2a 20 54 65 78 74 20 6f 66 20 74 68 65    /* Text of the
13980 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20   token */.  int 
13990 6e 54 6f 6b 65 6e 20 20 20 20 20 20 20 20 20 20  nToken          
139a0 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
139b0 66 20 63 68 61 72 61 63 74 65 72 73 20 69 6e 20  f characters in 
139c0 74 68 65 20 74 6f 6b 65 6e 20 2a 2f 0a 29 7b 0a  the token */.){.
139d0 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69    int i;.  for(i
139e0 3d 30 3b 20 69 3c 70 56 74 61 62 2d 3e 6e 43 6f  =0; i<pVtab->nCo
139f0 6c 75 6d 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  lumn; i++){.    
13a00 69 66 28 20 6d 65 6d 63 6d 70 28 70 56 74 61 62  if( memcmp(pVtab
13a10 2d 3e 61 7a 43 6f 6c 75 6d 6e 5b 69 5d 2c 20 7a  ->azColumn[i], z
13a20 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 29 3d 3d  Token, nToken)==
13a30 30 0a 20 20 20 20 20 20 20 20 26 26 20 70 56 74  0.        && pVt
13a40 61 62 2d 3e 61 7a 43 6f 6c 75 6d 6e 5b 69 5d 5b  ab->azColumn[i][
13a50 6e 54 6f 6b 65 6e 5d 3d 3d 30 20 29 7b 0a 20 20  nToken]==0 ){.  
13a60 20 20 20 20 72 65 74 75 72 6e 20 69 3b 0a 20 20      return i;.  
13a70 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
13a80 20 2d 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61   -1;.}../*.** Pa
13a90 72 73 65 20 74 68 65 20 74 65 78 74 20 61 74 20  rse the text at 
13aa0 70 53 65 67 6d 65 6e 74 5b 30 2e 2e 6e 53 65 67  pSegment[0..nSeg
13ab0 6d 65 6e 74 2d 31 5d 2e 20 20 41 64 64 20 61 64  ment-1].  Add ad
13ac0 64 69 74 69 6f 6e 61 6c 20 74 65 72 6d 73 0a 2a  ditional terms.*
13ad0 2a 20 74 6f 20 74 68 65 20 71 75 65 72 79 20 62  * to the query b
13ae0 65 69 6e 67 20 61 73 73 65 6d 62 6c 69 65 64 20  eing assemblied 
13af0 69 6e 20 70 51 75 65 72 79 2e 0a 2a 2a 0a 2a 2a  in pQuery..**.**
13b00 20 69 6e 50 68 72 61 73 65 20 69 73 20 74 72 75   inPhrase is tru
13b10 65 20 69 66 20 70 53 65 67 6d 65 6e 74 5b 30 2e  e if pSegment[0.
13b20 2e 6e 53 65 67 65 6d 65 6e 74 2d 31 5d 20 69 73  .nSegement-1] is
13b30 20 63 6f 6e 74 61 69 6e 65 64 20 77 69 74 68 69   contained withi
13b40 6e 0a 2a 2a 20 64 6f 75 62 6c 65 2d 71 75 6f 74  n.** double-quot
13b50 65 73 2e 20 20 49 66 20 69 6e 50 68 72 61 73 65  es.  If inPhrase
13b60 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e 20 74   is true, then t
13b70 68 65 20 66 69 72 73 74 20 74 65 72 6d 0a 2a 2a  he first term.**
13b80 20 69 73 20 6d 61 72 6b 65 64 20 77 69 74 68 20   is marked with 
13b90 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 65  the number of te
13ba0 72 6d 73 20 69 6e 20 74 68 65 20 70 68 72 61 73  rms in the phras
13bb0 65 20 6c 65 73 73 20 6f 6e 65 20 61 6e 64 0a 2a  e less one and.*
13bc0 2a 20 4f 52 20 61 6e 64 20 22 2d 22 20 73 79 6e  * OR and "-" syn
13bd0 74 61 78 20 69 73 20 69 67 6e 6f 72 65 64 2e 20  tax is ignored. 
13be0 20 49 66 20 69 6e 50 68 72 61 73 65 20 69 73 20   If inPhrase is 
13bf0 66 61 6c 73 65 2c 20 74 68 65 6e 20 65 76 65 72  false, then ever
13c00 79 0a 2a 2a 20 74 65 72 6d 20 66 6f 75 6e 64 20  y.** term found 
13c10 69 73 20 6d 61 72 6b 65 64 20 77 69 74 68 20 6e  is marked with n
13c20 50 68 72 61 73 65 3d 30 20 61 6e 64 20 4f 52 20  Phrase=0 and OR 
13c30 61 6e 64 20 22 2d 22 20 73 79 6e 74 61 78 20 69  and "-" syntax i
13c40 73 20 73 69 67 6e 69 66 69 63 61 6e 74 2e 0a 2a  s significant..*
13c50 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 6f 6b  /.static int tok
13c60 65 6e 69 7a 65 53 65 67 6d 65 6e 74 28 0a 20 20  enizeSegment(.  
13c70 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
13c80 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 2c 20 20  r *pTokenizer,  
13c90 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 74          /* The t
13ca0 6f 6b 65 6e 69 7a 65 72 20 74 6f 20 75 73 65 20  okenizer to use 
13cb0 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
13cc0 2a 70 53 65 67 6d 65 6e 74 2c 20 69 6e 74 20 6e  *pSegment, int n
13cd0 53 65 67 6d 65 6e 74 2c 20 20 20 20 20 2f 2a 20  Segment,     /* 
13ce0 51 75 65 72 79 20 65 78 70 72 65 73 73 69 6f 6e  Query expression
13cf0 20 62 65 69 6e 67 20 70 61 72 73 65 64 20 2a 2f   being parsed */
13d00 0a 20 20 69 6e 74 20 69 6e 50 68 72 61 73 65 2c  .  int inPhrase,
13d10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13d20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
13d30 75 65 20 69 66 20 77 69 74 68 69 6e 20 22 2e 2e  ue if within "..
13d40 2e 22 20 2a 2f 0a 20 20 51 75 65 72 79 20 2a 70  ." */.  Query *p
13d50 51 75 65 72 79 20 20 20 20 20 20 20 20 20 20 20  Query           
13d60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13d70 2f 2a 20 41 70 70 65 6e 64 20 72 65 73 75 6c 74  /* Append result
13d80 73 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 63  s here */.){.  c
13d90 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 74 6f 6b  onst sqlite3_tok
13da0 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a 70  enizer_module *p
13db0 4d 6f 64 75 6c 65 20 3d 20 70 54 6f 6b 65 6e 69  Module = pTokeni
13dc0 7a 65 72 2d 3e 70 4d 6f 64 75 6c 65 3b 0a 20 20  zer->pModule;.  
13dd0 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
13de0 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f  r_cursor *pCurso
13df0 72 3b 0a 20 20 69 6e 74 20 66 69 72 73 74 49 6e  r;.  int firstIn
13e00 64 65 78 20 3d 20 70 51 75 65 72 79 2d 3e 6e 54  dex = pQuery->nT
13e10 65 72 6d 73 3b 0a 20 20 69 6e 74 20 69 43 6f 6c  erms;.  int iCol
13e20 3b 0a 20 20 69 6e 74 20 6e 54 65 72 6d 20 3d 20  ;.  int nTerm = 
13e30 31 3b 0a 20 20 0a 20 20 69 6e 74 20 72 63 20 3d  1;.  .  int rc =
13e40 20 70 4d 6f 64 75 6c 65 2d 3e 78 4f 70 65 6e 28   pModule->xOpen(
13e50 70 54 6f 6b 65 6e 69 7a 65 72 2c 20 70 53 65 67  pTokenizer, pSeg
13e60 6d 65 6e 74 2c 20 6e 53 65 67 6d 65 6e 74 2c 20  ment, nSegment, 
13e70 26 70 43 75 72 73 6f 72 29 3b 0a 20 20 69 66 28  &pCursor);.  if(
13e80 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
13e90 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 70 43   return rc;.  pC
13ea0 75 72 73 6f 72 2d 3e 70 54 6f 6b 65 6e 69 7a 65  ursor->pTokenize
13eb0 72 20 3d 20 70 54 6f 6b 65 6e 69 7a 65 72 3b 0a  r = pTokenizer;.
13ec0 0a 20 20 77 68 69 6c 65 28 20 31 20 29 7b 0a 20  .  while( 1 ){. 
13ed0 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70     const char *p
13ee0 54 6f 6b 65 6e 3b 0a 20 20 20 20 69 6e 74 20 6e  Token;.    int n
13ef0 54 6f 6b 65 6e 2c 20 69 42 65 67 69 6e 2c 20 69  Token, iBegin, i
13f00 45 6e 64 2c 20 69 50 6f 73 3b 0a 0a 20 20 20 20  End, iPos;..    
13f10 72 63 20 3d 20 70 4d 6f 64 75 6c 65 2d 3e 78 4e  rc = pModule->xN
13f20 65 78 74 28 70 43 75 72 73 6f 72 2c 0a 20 20 20  ext(pCursor,.   
13f30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13f40 20 20 20 20 20 26 70 54 6f 6b 65 6e 2c 20 26 6e       &pToken, &n
13f50 54 6f 6b 65 6e 2c 0a 20 20 20 20 20 20 20 20 20  Token,.         
13f60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26                 &
13f70 69 42 65 67 69 6e 2c 20 26 69 45 6e 64 2c 20 26  iBegin, &iEnd, &
13f80 69 50 6f 73 29 3b 0a 20 20 20 20 69 66 28 20 72  iPos);.    if( r
13f90 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62  c!=SQLITE_OK ) b
13fa0 72 65 61 6b 3b 0a 20 20 20 20 69 66 28 20 21 69  reak;.    if( !i
13fb0 6e 50 68 72 61 73 65 20 26 26 0a 20 20 20 20 20  nPhrase &&.     
13fc0 20 20 20 70 53 65 67 6d 65 6e 74 5b 69 45 6e 64     pSegment[iEnd
13fd0 5d 3d 3d 27 3a 27 20 26 26 0a 20 20 20 20 20 20  ]==':' &&.      
13fe0 20 20 20 28 69 43 6f 6c 20 3d 20 63 68 65 63 6b     (iCol = check
13ff0 43 6f 6c 75 6d 6e 53 70 65 63 69 66 69 65 72 28  ColumnSpecifier(
14000 70 51 75 65 72 79 2d 3e 70 46 74 73 2c 20 70 54  pQuery->pFts, pT
14010 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 29 29 3e 3d  oken, nToken))>=
14020 30 20 29 7b 0a 20 20 20 20 20 20 70 51 75 65 72  0 ){.      pQuer
14030 79 2d 3e 6e 65 78 74 43 6f 6c 75 6d 6e 20 3d 20  y->nextColumn = 
14040 69 43 6f 6c 3b 0a 20 20 20 20 20 20 63 6f 6e 74  iCol;.      cont
14050 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20  inue;.    }.    
14060 69 66 28 20 21 69 6e 50 68 72 61 73 65 20 26 26  if( !inPhrase &&
14070 20 70 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73 3e   pQuery->nTerms>
14080 30 20 26 26 20 6e 54 6f 6b 65 6e 3d 3d 32 0a 20  0 && nToken==2. 
14090 20 20 20 20 20 20 20 20 26 26 20 70 53 65 67 6d          && pSegm
140a0 65 6e 74 5b 69 42 65 67 69 6e 5d 3d 3d 27 4f 27  ent[iBegin]=='O'
140b0 20 26 26 20 70 53 65 67 6d 65 6e 74 5b 69 42 65   && pSegment[iBe
140c0 67 69 6e 2b 31 5d 3d 3d 27 52 27 20 29 7b 0a 20  gin+1]=='R' ){. 
140d0 20 20 20 20 20 70 51 75 65 72 79 2d 3e 6e 65 78       pQuery->nex
140e0 74 49 73 4f 72 20 3d 20 31 3b 0a 20 20 20 20 20  tIsOr = 1;.     
140f0 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 7d   continue;.    }
14100 0a 20 20 20 20 71 75 65 72 79 41 64 64 28 70 51  .    queryAdd(pQ
14110 75 65 72 79 2c 20 70 54 6f 6b 65 6e 2c 20 6e 54  uery, pToken, nT
14120 6f 6b 65 6e 29 3b 0a 20 20 20 20 69 66 28 20 21  oken);.    if( !
14130 69 6e 50 68 72 61 73 65 20 26 26 20 69 42 65 67  inPhrase && iBeg
14140 69 6e 3e 30 20 26 26 20 70 53 65 67 6d 65 6e 74  in>0 && pSegment
14150 5b 69 42 65 67 69 6e 2d 31 5d 3d 3d 27 2d 27 20  [iBegin-1]=='-' 
14160 29 7b 0a 20 20 20 20 20 20 70 51 75 65 72 79 2d  ){.      pQuery-
14170 3e 70 54 65 72 6d 73 5b 70 51 75 65 72 79 2d 3e  >pTerms[pQuery->
14180 6e 54 65 72 6d 73 2d 31 5d 2e 69 73 4e 6f 74 20  nTerms-1].isNot 
14190 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  = 1;.    }.    p
141a0 51 75 65 72 79 2d 3e 70 54 65 72 6d 73 5b 70 51  Query->pTerms[pQ
141b0 75 65 72 79 2d 3e 6e 54 65 72 6d 73 2d 31 5d 2e  uery->nTerms-1].
141c0 69 50 68 72 61 73 65 20 3d 20 6e 54 65 72 6d 3b  iPhrase = nTerm;
141d0 0a 20 20 20 20 69 66 28 20 69 6e 50 68 72 61 73  .    if( inPhras
141e0 65 20 29 7b 0a 20 20 20 20 20 20 6e 54 65 72 6d  e ){.      nTerm
141f0 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  ++;.    }.  }.. 
14200 20 69 66 28 20 69 6e 50 68 72 61 73 65 20 26 26   if( inPhrase &&
14210 20 70 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73 3e   pQuery->nTerms>
14220 66 69 72 73 74 49 6e 64 65 78 20 29 7b 0a 20 20  firstIndex ){.  
14230 20 20 70 51 75 65 72 79 2d 3e 70 54 65 72 6d 73    pQuery->pTerms
14240 5b 66 69 72 73 74 49 6e 64 65 78 5d 2e 6e 50 68  [firstIndex].nPh
14250 72 61 73 65 20 3d 20 70 51 75 65 72 79 2d 3e 6e  rase = pQuery->n
14260 54 65 72 6d 73 20 2d 20 66 69 72 73 74 49 6e 64  Terms - firstInd
14270 65 78 20 2d 20 31 3b 0a 20 20 7d 0a 0a 20 20 72  ex - 1;.  }..  r
14280 65 74 75 72 6e 20 70 4d 6f 64 75 6c 65 2d 3e 78  eturn pModule->x
14290 43 6c 6f 73 65 28 70 43 75 72 73 6f 72 29 3b 0a  Close(pCursor);.
142a0 7d 0a 0a 2f 2a 20 50 61 72 73 65 20 61 20 71 75  }../* Parse a qu
142b0 65 72 79 20 73 74 72 69 6e 67 2c 20 79 69 65 6c  ery string, yiel
142c0 64 69 6e 67 20 61 20 51 75 65 72 79 20 6f 62 6a  ding a Query obj
142d0 65 63 74 20 70 51 75 65 72 79 2e 0a 2a 2a 0a 2a  ect pQuery..**.*
142e0 2a 20 54 68 65 20 63 61 6c 6c 69 6e 67 20 66 75  * The calling fu
142f0 6e 63 74 69 6f 6e 20 77 69 6c 6c 20 6e 65 65 64  nction will need
14300 20 74 6f 20 71 75 65 72 79 43 6c 65 61 72 28 29   to queryClear()
14310 20 74 6f 20 63 6c 65 61 6e 20 75 70 0a 2a 2a 20   to clean up.** 
14320 74 68 65 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20  the dynamically 
14330 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72 79  allocated memory
14340 20 68 65 6c 64 20 62 79 20 70 51 75 65 72 79 2e   held by pQuery.
14350 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70  .*/.static int p
14360 61 72 73 65 51 75 65 72 79 28 0a 20 20 66 75 6c  arseQuery(.  ful
14370 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 20  ltext_vtab *v,  
14380 20 20 20 20 20 20 2f 2a 20 54 68 65 20 66 75 6c        /* The ful
14390 6c 74 65 78 74 20 69 6e 64 65 78 20 2a 2f 0a 20  ltext index */. 
143a0 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 6e   const char *zIn
143b0 70 75 74 2c 20 20 20 20 20 20 2f 2a 20 49 6e 70  put,      /* Inp
143c0 75 74 20 74 65 78 74 20 6f 66 20 74 68 65 20 71  ut text of the q
143d0 75 65 72 79 20 73 74 72 69 6e 67 20 2a 2f 0a 20  uery string */. 
143e0 20 69 6e 74 20 6e 49 6e 70 75 74 2c 20 20 20 20   int nInput,    
143f0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
14400 65 20 6f 66 20 74 68 65 20 69 6e 70 75 74 20 74  e of the input t
14410 65 78 74 20 2a 2f 0a 20 20 69 6e 74 20 64 66 6c  ext */.  int dfl
14420 74 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20  tColumn,        
14430 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 63 6f 6c    /* Default col
14440 75 6d 6e 20 6f 66 20 74 68 65 20 69 6e 64 65 78  umn of the index
14450 20 74 6f 20 6d 61 74 63 68 20 61 67 61 69 6e 73   to match agains
14460 74 20 2a 2f 0a 20 20 51 75 65 72 79 20 2a 70 51  t */.  Query *pQ
14470 75 65 72 79 20 20 20 20 20 20 20 20 20 20 20 20  uery            
14480 2f 2a 20 57 72 69 74 65 20 74 68 65 20 70 61 72  /* Write the par
14490 73 65 20 72 65 73 75 6c 74 73 20 68 65 72 65 2e  se results here.
144a0 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 49 6e   */.){.  int iIn
144b0 70 75 74 2c 20 69 6e 50 68 72 61 73 65 20 3d 20  put, inPhrase = 
144c0 30 3b 0a 0a 20 20 69 66 28 20 7a 49 6e 70 75 74  0;..  if( zInput
144d0 3d 3d 30 20 29 20 6e 49 6e 70 75 74 20 3d 20 30  ==0 ) nInput = 0
144e0 3b 0a 20 20 69 66 28 20 6e 49 6e 70 75 74 3c 30  ;.  if( nInput<0
144f0 20 29 20 6e 49 6e 70 75 74 20 3d 20 73 74 72 6c   ) nInput = strl
14500 65 6e 28 7a 49 6e 70 75 74 29 3b 0a 20 20 70 51  en(zInput);.  pQ
14510 75 65 72 79 2d 3e 6e 54 65 72 6d 73 20 3d 20 30  uery->nTerms = 0
14520 3b 0a 20 20 70 51 75 65 72 79 2d 3e 70 54 65 72  ;.  pQuery->pTer
14530 6d 73 20 3d 20 4e 55 4c 4c 3b 0a 20 20 70 51 75  ms = NULL;.  pQu
14540 65 72 79 2d 3e 6e 65 78 74 49 73 4f 72 20 3d 20  ery->nextIsOr = 
14550 30 3b 0a 20 20 70 51 75 65 72 79 2d 3e 6e 65 78  0;.  pQuery->nex
14560 74 43 6f 6c 75 6d 6e 20 3d 20 64 66 6c 74 43 6f  tColumn = dfltCo
14570 6c 75 6d 6e 3b 0a 20 20 70 51 75 65 72 79 2d 3e  lumn;.  pQuery->
14580 64 66 6c 74 43 6f 6c 75 6d 6e 20 3d 20 64 66 6c  dfltColumn = dfl
14590 74 43 6f 6c 75 6d 6e 3b 0a 20 20 70 51 75 65 72  tColumn;.  pQuer
145a0 79 2d 3e 70 46 74 73 20 3d 20 76 3b 0a 0a 20 20  y->pFts = v;..  
145b0 66 6f 72 28 69 49 6e 70 75 74 3d 30 3b 20 69 49  for(iInput=0; iI
145c0 6e 70 75 74 3c 6e 49 6e 70 75 74 3b 20 2b 2b 69  nput<nInput; ++i
145d0 49 6e 70 75 74 29 7b 0a 20 20 20 20 69 6e 74 20  Input){.    int 
145e0 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 69 49 6e  i;.    for(i=iIn
145f0 70 75 74 3b 20 69 3c 6e 49 6e 70 75 74 20 26 26  put; i<nInput &&
14600 20 7a 49 6e 70 75 74 5b 69 5d 21 3d 27 22 27 3b   zInput[i]!='"';
14610 20 2b 2b 69 29 7b 7d 0a 20 20 20 20 69 66 28 20   ++i){}.    if( 
14620 69 3e 69 49 6e 70 75 74 20 29 7b 0a 20 20 20 20  i>iInput ){.    
14630 20 20 74 6f 6b 65 6e 69 7a 65 53 65 67 6d 65 6e    tokenizeSegmen
14640 74 28 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72 2c  t(v->pTokenizer,
14650 20 7a 49 6e 70 75 74 2b 69 49 6e 70 75 74 2c 20   zInput+iInput, 
14660 69 2d 69 49 6e 70 75 74 2c 20 69 6e 50 68 72 61  i-iInput, inPhra
14670 73 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  se,.            
14680 20 20 20 20 20 20 20 20 20 20 20 70 51 75 65 72             pQuer
14690 79 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 49  y);.    }.    iI
146a0 6e 70 75 74 20 3d 20 69 3b 0a 20 20 20 20 69 66  nput = i;.    if
146b0 28 20 69 3c 6e 49 6e 70 75 74 20 29 7b 0a 20 20  ( i<nInput ){.  
146c0 20 20 20 20 61 73 73 65 72 74 28 20 7a 49 6e 70      assert( zInp
146d0 75 74 5b 69 5d 3d 3d 27 22 27 20 29 3b 0a 20 20  ut[i]=='"' );.  
146e0 20 20 20 20 69 6e 50 68 72 61 73 65 20 3d 20 21      inPhrase = !
146f0 69 6e 50 68 72 61 73 65 3b 0a 20 20 20 20 7d 0a  inPhrase;.    }.
14700 20 20 7d 0a 0a 20 20 69 66 28 20 69 6e 50 68 72    }..  if( inPhr
14710 61 73 65 20 29 7b 0a 20 20 20 20 2f 2a 20 75 6e  ase ){.    /* un
14720 6d 61 74 63 68 65 64 20 71 75 6f 74 65 20 2a 2f  matched quote */
14730 0a 20 20 20 20 71 75 65 72 79 43 6c 65 61 72 28  .    queryClear(
14740 70 51 75 65 72 79 29 3b 0a 20 20 20 20 72 65 74  pQuery);.    ret
14750 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  urn SQLITE_ERROR
14760 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53  ;.  }.  return S
14770 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20  QLITE_OK;.}../* 
14780 50 65 72 66 6f 72 6d 20 61 20 66 75 6c 6c 2d 74  Perform a full-t
14790 65 78 74 20 71 75 65 72 79 20 75 73 69 6e 67 20  ext query using 
147a0 74 68 65 20 73 65 61 72 63 68 20 65 78 70 72 65  the search expre
147b0 73 73 69 6f 6e 20 69 6e 0a 2a 2a 20 7a 49 6e 70  ssion in.** zInp
147c0 75 74 5b 30 2e 2e 6e 49 6e 70 75 74 2d 31 5d 2e  ut[0..nInput-1].
147d0 20 20 52 65 74 75 72 6e 20 61 20 6c 69 73 74 20    Return a list 
147e0 6f 66 20 6d 61 74 63 68 69 6e 67 20 64 6f 63 75  of matching docu
147f0 6d 65 6e 74 73 0a 2a 2a 20 69 6e 20 70 52 65 73  ments.** in pRes
14800 75 6c 74 2e 0a 2a 2a 0a 2a 2a 20 51 75 65 72 69  ult..**.** Queri
14810 65 73 20 6d 75 73 74 20 6d 61 74 63 68 20 63 6f  es must match co
14820 6c 75 6d 6e 20 69 43 6f 6c 75 6d 6e 2e 20 20 4f  lumn iColumn.  O
14830 72 20 69 66 20 69 43 6f 6c 75 6d 6e 3e 3d 6e 43  r if iColumn>=nC
14840 6f 6c 75 6d 6e 0a 2a 2a 20 74 68 65 79 20 61 72  olumn.** they ar
14850 65 20 61 6c 6c 6f 77 65 64 20 74 6f 20 6d 61 74  e allowed to mat
14860 63 68 20 61 67 61 69 6e 73 74 20 61 6e 79 20 63  ch against any c
14870 6f 6c 75 6d 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  olumn..*/.static
14880 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 51 75 65   int fulltextQue
14890 72 79 28 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76  ry(.  fulltext_v
148a0 74 61 62 20 2a 76 2c 20 20 20 20 20 20 2f 2a 20  tab *v,      /* 
148b0 54 68 65 20 66 75 6c 6c 20 74 65 78 74 20 69 6e  The full text in
148c0 64 65 78 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f  dex */.  int iCo
148d0 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20  lumn,           
148e0 2f 2a 20 4d 61 74 63 68 20 61 67 61 69 6e 73 74  /* Match against
148f0 20 74 68 69 73 20 63 6f 6c 75 6d 6e 20 62 79 20   this column by 
14900 64 65 66 61 75 6c 74 20 2a 2f 0a 20 20 63 6f 6e  default */.  con
14910 73 74 20 63 68 61 72 20 2a 7a 49 6e 70 75 74 2c  st char *zInput,
14920 20 20 20 20 2f 2a 20 54 68 65 20 71 75 65 72 79      /* The query
14930 20 73 74 72 69 6e 67 20 2a 2f 0a 20 20 69 6e 74   string */.  int
14940 20 6e 49 6e 70 75 74 2c 20 20 20 20 20 20 20 20   nInput,        
14950 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
14960 20 62 79 74 65 73 20 69 6e 20 7a 49 6e 70 75 74   bytes in zInput
14970 5b 5d 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20  [] */.  DocList 
14980 2a 2a 70 52 65 73 75 6c 74 2c 20 20 20 20 20 2f  **pResult,     /
14990 2a 20 57 72 69 74 65 20 74 68 65 20 72 65 73 75  * Write the resu
149a0 6c 74 20 64 6f 63 6c 69 73 74 20 68 65 72 65 20  lt doclist here 
149b0 2a 2f 0a 20 20 51 75 65 72 79 20 2a 70 51 75 65  */.  Query *pQue
149c0 72 79 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50  ry          /* P
149d0 75 74 20 70 61 72 73 65 64 20 71 75 65 72 79 20  ut parsed query 
149e0 73 74 72 69 6e 67 20 68 65 72 65 20 2a 2f 0a 29  string here */.)
149f0 7b 0a 20 20 69 6e 74 20 69 2c 20 69 4e 65 78 74  {.  int i, iNext
14a00 2c 20 72 63 3b 0a 20 20 44 6f 63 4c 69 73 74 20  , rc;.  DocList 
14a10 2a 70 4c 65 66 74 20 3d 20 4e 55 4c 4c 3b 0a 20  *pLeft = NULL;. 
14a20 20 44 6f 63 4c 69 73 74 20 2a 70 52 69 67 68 74   DocList *pRight
14a30 2c 20 2a 70 4e 65 77 2c 20 2a 70 4f 72 3b 0a 20  , *pNew, *pOr;. 
14a40 20 69 6e 74 20 6e 4e 6f 74 20 3d 20 30 3b 0a 20   int nNot = 0;. 
14a50 20 51 75 65 72 79 54 65 72 6d 20 2a 61 54 65 72   QueryTerm *aTer
14a60 6d 3b 0a 0a 20 20 72 63 20 3d 20 70 61 72 73 65  m;..  rc = parse
14a70 51 75 65 72 79 28 76 2c 20 7a 49 6e 70 75 74 2c  Query(v, zInput,
14a80 20 6e 49 6e 70 75 74 2c 20 69 43 6f 6c 75 6d 6e   nInput, iColumn
14a90 2c 20 70 51 75 65 72 79 29 3b 0a 20 20 69 66 28  , pQuery);.  if(
14aa0 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
14ab0 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 2f   return rc;..  /
14ac0 2a 20 4d 65 72 67 65 20 41 4e 44 20 74 65 72 6d  * Merge AND term
14ad0 73 2e 20 2a 2f 0a 20 20 61 54 65 72 6d 20 3d 20  s. */.  aTerm = 
14ae0 70 51 75 65 72 79 2d 3e 70 54 65 72 6d 73 3b 0a  pQuery->pTerms;.
14af0 20 20 66 6f 72 28 69 20 3d 20 30 3b 20 69 3c 70    for(i = 0; i<p
14b00 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73 3b 20 69  Query->nTerms; i
14b10 3d 69 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28  =iNext){.    if(
14b20 20 61 54 65 72 6d 5b 69 5d 2e 69 73 4e 6f 74 20   aTerm[i].isNot 
14b30 29 7b 0a 20 20 20 20 20 20 2f 2a 20 48 61 6e 64  ){.      /* Hand
14b40 6c 65 20 61 6c 6c 20 4e 4f 54 20 74 65 72 6d 73  le all NOT terms
14b50 20 69 6e 20 61 20 73 65 70 61 72 61 74 65 20 70   in a separate p
14b60 61 73 73 20 2a 2f 0a 20 20 20 20 20 20 6e 4e 6f  ass */.      nNo
14b70 74 2b 2b 3b 0a 20 20 20 20 20 20 69 4e 65 78 74  t++;.      iNext
14b80 20 3d 20 69 20 2b 20 61 54 65 72 6d 5b 69 5d 2e   = i + aTerm[i].
14b90 6e 50 68 72 61 73 65 2b 31 3b 0a 20 20 20 20 20  nPhrase+1;.     
14ba0 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 7d   continue;.    }
14bb0 0a 20 20 20 20 69 4e 65 78 74 20 3d 20 69 20 2b  .    iNext = i +
14bc0 20 61 54 65 72 6d 5b 69 5d 2e 6e 50 68 72 61 73   aTerm[i].nPhras
14bd0 65 20 2b 20 31 3b 0a 20 20 20 20 72 63 20 3d 20  e + 1;.    rc = 
14be0 64 6f 63 4c 69 73 74 4f 66 54 65 72 6d 28 76 2c  docListOfTerm(v,
14bf0 20 61 54 65 72 6d 5b 69 5d 2e 69 43 6f 6c 75 6d   aTerm[i].iColum
14c00 6e 2c 20 26 61 54 65 72 6d 5b 69 5d 2c 20 26 70  n, &aTerm[i], &p
14c10 52 69 67 68 74 29 3b 0a 20 20 20 20 69 66 28 20  Right);.    if( 
14c20 72 63 20 29 7b 0a 20 20 20 20 20 20 71 75 65 72  rc ){.      quer
14c30 79 43 6c 65 61 72 28 70 51 75 65 72 79 29 3b 0a  yClear(pQuery);.
14c40 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
14c50 0a 20 20 20 20 7d 0a 20 20 20 20 77 68 69 6c 65  .    }.    while
14c60 28 20 69 4e 65 78 74 3c 70 51 75 65 72 79 2d 3e  ( iNext<pQuery->
14c70 6e 54 65 72 6d 73 20 26 26 20 61 54 65 72 6d 5b  nTerms && aTerm[
14c80 69 4e 65 78 74 5d 2e 69 73 4f 72 20 29 7b 0a 20  iNext].isOr ){. 
14c90 20 20 20 20 20 72 63 20 3d 20 64 6f 63 4c 69 73       rc = docLis
14ca0 74 4f 66 54 65 72 6d 28 76 2c 20 61 54 65 72 6d  tOfTerm(v, aTerm
14cb0 5b 69 4e 65 78 74 5d 2e 69 43 6f 6c 75 6d 6e 2c  [iNext].iColumn,
14cc0 20 26 61 54 65 72 6d 5b 69 4e 65 78 74 5d 2c 20   &aTerm[iNext], 
14cd0 26 70 4f 72 29 3b 0a 20 20 20 20 20 20 69 4e 65  &pOr);.      iNe
14ce0 78 74 20 2b 3d 20 61 54 65 72 6d 5b 69 4e 65 78  xt += aTerm[iNex
14cf0 74 5d 2e 6e 50 68 72 61 73 65 20 2b 20 31 3b 0a  t].nPhrase + 1;.
14d00 20 20 20 20 20 20 69 66 28 20 72 63 20 29 7b 0a        if( rc ){.
14d10 20 20 20 20 20 20 20 20 71 75 65 72 79 43 6c 65          queryCle
14d20 61 72 28 70 51 75 65 72 79 29 3b 0a 20 20 20 20  ar(pQuery);.    
14d30 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
14d40 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 4e 65       }.      pNe
14d50 77 20 3d 20 64 6f 63 4c 69 73 74 4e 65 77 28 44  w = docListNew(D
14d60 4c 5f 44 4f 43 49 44 53 29 3b 0a 20 20 20 20 20  L_DOCIDS);.     
14d70 20 64 6f 63 4c 69 73 74 4f 72 4d 65 72 67 65 28   docListOrMerge(
14d80 70 52 69 67 68 74 2c 20 70 4f 72 2c 20 70 4e 65  pRight, pOr, pNe
14d90 77 29 3b 0a 20 20 20 20 20 20 64 6f 63 4c 69 73  w);.      docLis
14da0 74 44 65 6c 65 74 65 28 70 52 69 67 68 74 29 3b  tDelete(pRight);
14db0 0a 20 20 20 20 20 20 64 6f 63 4c 69 73 74 44 65  .      docListDe
14dc0 6c 65 74 65 28 70 4f 72 29 3b 0a 20 20 20 20 20  lete(pOr);.     
14dd0 20 70 52 69 67 68 74 20 3d 20 70 4e 65 77 3b 0a   pRight = pNew;.
14de0 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 4c      }.    if( pL
14df0 65 66 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  eft==0 ){.      
14e00 70 4c 65 66 74 20 3d 20 70 52 69 67 68 74 3b 0a  pLeft = pRight;.
14e10 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
14e20 20 70 4e 65 77 20 3d 20 64 6f 63 4c 69 73 74 4e   pNew = docListN
14e30 65 77 28 44 4c 5f 44 4f 43 49 44 53 29 3b 0a 20  ew(DL_DOCIDS);. 
14e40 20 20 20 20 20 64 6f 63 4c 69 73 74 41 6e 64 4d       docListAndM
14e50 65 72 67 65 28 70 4c 65 66 74 2c 20 70 52 69 67  erge(pLeft, pRig
14e60 68 74 2c 20 70 4e 65 77 29 3b 0a 20 20 20 20 20  ht, pNew);.     
14e70 20 64 6f 63 4c 69 73 74 44 65 6c 65 74 65 28 70   docListDelete(p
14e80 52 69 67 68 74 29 3b 0a 20 20 20 20 20 20 64 6f  Right);.      do
14e90 63 4c 69 73 74 44 65 6c 65 74 65 28 70 4c 65 66  cListDelete(pLef
14ea0 74 29 3b 0a 20 20 20 20 20 20 70 4c 65 66 74 20  t);.      pLeft 
14eb0 3d 20 70 4e 65 77 3b 0a 20 20 20 20 7d 0a 20 20  = pNew;.    }.  
14ec0 7d 0a 0a 20 20 69 66 28 20 6e 4e 6f 74 20 26 26  }..  if( nNot &&
14ed0 20 70 4c 65 66 74 3d 3d 30 20 29 7b 0a 20 20 20   pLeft==0 ){.   
14ee0 20 2f 2a 20 57 65 20 64 6f 20 6e 6f 74 20 79 65   /* We do not ye
14ef0 74 20 6b 6e 6f 77 20 68 6f 77 20 74 6f 20 68 61  t know how to ha
14f00 6e 64 6c 65 20 61 20 71 75 65 72 79 20 6f 66 20  ndle a query of 
14f10 6f 6e 6c 79 20 4e 4f 54 20 74 65 72 6d 73 20 2a  only NOT terms *
14f20 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  /.    return SQL
14f30 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a  ITE_ERROR;.  }..
14f40 20 20 2f 2a 20 44 6f 20 74 68 65 20 45 58 43 45    /* Do the EXCE
14f50 50 54 20 74 65 72 6d 73 20 2a 2f 0a 20 20 66 6f  PT terms */.  fo
14f60 72 28 69 3d 30 3b 20 69 3c 70 51 75 65 72 79 2d  r(i=0; i<pQuery-
14f70 3e 6e 54 65 72 6d 73 3b 20 20 69 20 2b 3d 20 61  >nTerms;  i += a
14f80 54 65 72 6d 5b 69 5d 2e 6e 50 68 72 61 73 65 20  Term[i].nPhrase 
14f90 2b 20 31 29 7b 0a 20 20 20 20 69 66 28 20 21 61  + 1){.    if( !a
14fa0 54 65 72 6d 5b 69 5d 2e 69 73 4e 6f 74 20 29 20  Term[i].isNot ) 
14fb0 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 72 63  continue;.    rc
14fc0 20 3d 20 64 6f 63 4c 69 73 74 4f 66 54 65 72 6d   = docListOfTerm
14fd0 28 76 2c 20 61 54 65 72 6d 5b 69 5d 2e 69 43 6f  (v, aTerm[i].iCo
14fe0 6c 75 6d 6e 2c 20 26 61 54 65 72 6d 5b 69 5d 2c  lumn, &aTerm[i],
14ff0 20 26 70 52 69 67 68 74 29 3b 0a 20 20 20 20 69   &pRight);.    i
15000 66 28 20 72 63 20 29 7b 0a 20 20 20 20 20 20 71  f( rc ){.      q
15010 75 65 72 79 43 6c 65 61 72 28 70 51 75 65 72 79  ueryClear(pQuery
15020 29 3b 0a 20 20 20 20 20 20 64 6f 63 4c 69 73 74  );.      docList
15030 44 65 6c 65 74 65 28 70 4c 65 66 74 29 3b 0a 20  Delete(pLeft);. 
15040 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a       return rc;.
15050 20 20 20 20 7d 0a 20 20 20 20 70 4e 65 77 20 3d      }.    pNew =
15060 20 64 6f 63 4c 69 73 74 4e 65 77 28 44 4c 5f 44   docListNew(DL_D
15070 4f 43 49 44 53 29 3b 0a 20 20 20 20 64 6f 63 4c  OCIDS);.    docL
15080 69 73 74 45 78 63 65 70 74 4d 65 72 67 65 28 70  istExceptMerge(p
15090 4c 65 66 74 2c 20 70 52 69 67 68 74 2c 20 70 4e  Left, pRight, pN
150a0 65 77 29 3b 0a 20 20 20 20 64 6f 63 4c 69 73 74  ew);.    docList
150b0 44 65 6c 65 74 65 28 70 52 69 67 68 74 29 3b 0a  Delete(pRight);.
150c0 20 20 20 20 64 6f 63 4c 69 73 74 44 65 6c 65 74      docListDelet
150d0 65 28 70 4c 65 66 74 29 3b 0a 20 20 20 20 70 4c  e(pLeft);.    pL
150e0 65 66 74 20 3d 20 70 4e 65 77 3b 0a 20 20 7d 0a  eft = pNew;.  }.
150f0 0a 20 20 2a 70 52 65 73 75 6c 74 20 3d 20 70 4c  .  *pResult = pL
15100 65 66 74 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  eft;.  return rc
15110 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
15120 69 73 20 74 68 65 20 78 46 69 6c 74 65 72 20 69  is the xFilter i
15130 6e 74 65 72 66 61 63 65 20 66 6f 72 20 74 68 65  nterface for the
15140 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20   virtual table. 
15150 20 53 65 65 0a 2a 2a 20 74 68 65 20 76 69 72 74   See.** the virt
15160 75 61 6c 20 74 61 62 6c 65 20 78 46 69 6c 74 65  ual table xFilte
15170 72 20 6d 65 74 68 6f 64 20 64 6f 63 75 6d 65 6e  r method documen
15180 74 61 74 69 6f 6e 20 66 6f 72 20 61 64 64 69 74  tation for addit
15190 69 6f 6e 61 6c 0a 2a 2a 20 69 6e 66 6f 72 6d 61  ional.** informa
151a0 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 69  tion..**.** If i
151b0 64 78 4e 75 6d 3d 3d 51 55 45 52 59 5f 47 45 4e  dxNum==QUERY_GEN
151c0 45 52 49 43 20 74 68 65 6e 20 64 6f 20 61 20 66  ERIC then do a f
151d0 75 6c 6c 20 74 61 62 6c 65 20 73 63 61 6e 20 61  ull table scan a
151e0 67 61 69 6e 73 74 0a 2a 2a 20 74 68 65 20 25 5f  gainst.** the %_
151f0 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65 2e 0a 2a  content table..*
15200 2a 0a 2a 2a 20 49 66 20 69 64 78 4e 75 6d 3d 3d  *.** If idxNum==
15210 51 55 45 52 59 5f 52 4f 57 49 44 20 74 68 65 6e  QUERY_ROWID then
15220 20 64 6f 20 61 20 72 6f 77 69 64 20 6c 6f 6f 6b   do a rowid look
15230 75 70 20 66 6f 72 20 61 20 73 69 6e 67 6c 65 20  up for a single 
15240 65 6e 74 72 79 0a 2a 2a 20 69 6e 20 74 68 65 20  entry.** in the 
15250 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65 2e  %_content table.
15260 0a 2a 2a 0a 2a 2a 20 49 66 20 69 64 78 4e 75 6d  .**.** If idxNum
15270 3e 3d 51 55 45 52 59 5f 46 55 4c 4c 54 45 58 54  >=QUERY_FULLTEXT
15280 20 74 68 65 6e 20 75 73 65 20 74 68 65 20 66 75   then use the fu
15290 6c 6c 20 74 65 78 74 20 69 6e 64 65 78 2e 20 20  ll text index.  
152a0 54 68 65 0a 2a 2a 20 63 6f 6c 75 6d 6e 20 6f 6e  The.** column on
152b0 20 74 68 65 20 6c 65 66 74 2d 68 61 6e 64 20 73   the left-hand s
152c0 69 64 65 20 6f 66 20 74 68 65 20 4d 41 54 43 48  ide of the MATCH
152d0 20 6f 70 65 72 61 74 6f 72 20 69 73 20 63 6f 6c   operator is col
152e0 75 6d 6e 0a 2a 2a 20 6e 75 6d 62 65 72 20 69 64  umn.** number id
152f0 78 4e 75 6d 2d 51 55 45 52 59 5f 46 55 4c 4c 54  xNum-QUERY_FULLT
15300 45 58 54 2c 20 30 20 69 6e 64 65 78 65 64 2e 20  EXT, 0 indexed. 
15310 20 61 72 67 76 5b 30 5d 20 69 73 20 74 68 65 20   argv[0] is the 
15320 72 69 67 68 74 2d 68 61 6e 64 0a 2a 2a 20 73 69  right-hand.** si
15330 64 65 20 6f 66 20 74 68 65 20 4d 41 54 43 48 20  de of the MATCH 
15340 6f 70 65 72 61 74 6f 72 2e 0a 2a 2f 0a 2f 2a 20  operator..*/./* 
15350 54 4f 44 4f 28 73 68 65 73 73 29 20 55 70 67 72  TODO(shess) Upgr
15360 61 64 65 20 74 68 65 20 63 75 72 73 6f 72 20 69  ade the cursor i
15370 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 61 6e  nitialization an
15380 64 20 64 65 73 74 72 75 63 74 69 6f 6e 20 74 6f  d destruction to
15390 0a 2a 2a 20 61 63 63 6f 75 6e 74 20 66 6f 72 20  .** account for 
153a0 66 75 6c 6c 74 65 78 74 46 69 6c 74 65 72 28 29  fulltextFilter()
153b0 20 62 65 69 6e 67 20 63 61 6c 6c 65 64 20 6d 75   being called mu
153c0 6c 74 69 70 6c 65 20 74 69 6d 65 73 20 6f 6e 20  ltiple times on 
153d0 74 68 65 0a 2a 2a 20 73 61 6d 65 20 63 75 72 73  the.** same curs
153e0 6f 72 2e 20 20 54 68 65 20 63 75 72 72 65 6e 74  or.  The current
153f0 20 73 6f 6c 75 74 69 6f 6e 20 69 73 20 76 65 72   solution is ver
15400 79 20 66 72 61 67 69 6c 65 2e 20 20 41 70 70 6c  y fragile.  Appl
15410 79 20 66 69 78 20 74 6f 0a 2a 2a 20 66 74 73 32  y fix to.** fts2
15420 20 61 73 20 61 70 70 72 6f 70 72 69 61 74 65 2e   as appropriate.
15430 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
15440 75 6c 6c 74 65 78 74 46 69 6c 74 65 72 28 0a 20  ulltextFilter(. 
15450 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75   sqlite3_vtab_cu
15460 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 20  rsor *pCursor,  
15470 20 20 20 2f 2a 20 54 68 65 20 63 75 72 73 6f 72     /* The cursor
15480 20 75 73 65 64 20 66 6f 72 20 74 68 69 73 20 71   used for this q
15490 75 65 72 79 20 2a 2f 0a 20 20 69 6e 74 20 69 64  uery */.  int id
154a0 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61 72  xNum, const char
154b0 20 2a 69 64 78 53 74 72 2c 20 20 20 2f 2a 20 57   *idxStr,   /* W
154c0 68 69 63 68 20 69 6e 64 65 78 69 6e 67 20 73 63  hich indexing sc
154d0 68 65 6d 65 20 74 6f 20 75 73 65 20 2a 2f 0a 20  heme to use */. 
154e0 20 69 6e 74 20 61 72 67 63 2c 20 73 71 6c 69 74   int argc, sqlit
154f0 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 20  e3_value **argv 
15500 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 73 20     /* Arguments 
15510 66 6f 72 20 74 68 65 20 69 6e 64 65 78 69 6e 67  for the indexing
15520 20 73 63 68 65 6d 65 20 2a 2f 0a 29 7b 0a 20 20   scheme */.){.  
15530 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20  fulltext_cursor 
15540 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f 63  *c = (fulltext_c
15550 75 72 73 6f 72 20 2a 29 20 70 43 75 72 73 6f 72  ursor *) pCursor
15560 3b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61  ;.  fulltext_vta
15570 62 20 2a 76 20 3d 20 63 75 72 73 6f 72 5f 76 74  b *v = cursor_vt
15580 61 62 28 63 29 3b 0a 20 20 69 6e 74 20 72 63 3b  ab(c);.  int rc;
15590 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 0a  .  char *zSql;..
155a0 20 20 54 52 41 43 45 28 28 22 46 54 53 31 20 46    TRACE(("FTS1 F
155b0 69 6c 74 65 72 20 25 70 5c 6e 22 2c 70 43 75 72  ilter %p\n",pCur
155c0 73 6f 72 29 29 3b 0a 0a 20 20 7a 53 71 6c 20 3d  sor));..  zSql =
155d0 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
155e0 28 22 73 65 6c 65 63 74 20 72 6f 77 69 64 2c 20  ("select rowid, 
155f0 2a 20 66 72 6f 6d 20 25 25 5f 63 6f 6e 74 65 6e  * from %%_conten
15600 74 20 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20  t %s",.         
15610 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15620 20 69 64 78 4e 75 6d 3d 3d 51 55 45 52 59 5f 47   idxNum==QUERY_G
15630 45 4e 45 52 49 43 20 3f 20 22 22 20 3a 20 22 77  ENERIC ? "" : "w
15640 68 65 72 65 20 72 6f 77 69 64 3d 3f 22 29 3b 0a  here rowid=?");.
15650 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
15660 7a 65 28 63 2d 3e 70 53 74 6d 74 29 3b 0a 20 20  ze(c->pStmt);.  
15670 72 63 20 3d 20 73 71 6c 5f 70 72 65 70 61 72 65  rc = sql_prepare
15680 28 76 2d 3e 64 62 2c 20 76 2d 3e 7a 44 62 2c 20  (v->db, v->zDb, 
15690 76 2d 3e 7a 4e 61 6d 65 2c 20 26 63 2d 3e 70 53  v->zName, &c->pS
156a0 74 6d 74 2c 20 7a 53 71 6c 29 3b 0a 20 20 73 71  tmt, zSql);.  sq
156b0 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29  lite3_free(zSql)
156c0 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
156d0 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
156e0 63 3b 0a 0a 20 20 63 2d 3e 69 43 75 72 73 6f 72  c;..  c->iCursor
156f0 54 79 70 65 20 3d 20 69 64 78 4e 75 6d 3b 0a 20  Type = idxNum;. 
15700 20 73 77 69 74 63 68 28 20 69 64 78 4e 75 6d 20   switch( idxNum 
15710 29 7b 0a 20 20 20 20 63 61 73 65 20 51 55 45 52  ){.    case QUER
15720 59 5f 47 45 4e 45 52 49 43 3a 0a 20 20 20 20 20  Y_GENERIC:.     
15730 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73   break;..    cas
15740 65 20 51 55 45 52 59 5f 52 4f 57 49 44 3a 0a 20  e QUERY_ROWID:. 
15750 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
15760 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 63 2d 3e  3_bind_int64(c->
15770 70 53 74 6d 74 2c 20 31 2c 20 73 71 6c 69 74 65  pStmt, 1, sqlite
15780 33 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 61 72  3_value_int64(ar
15790 67 76 5b 30 5d 29 29 3b 0a 20 20 20 20 20 20 69  gv[0]));.      i
157a0 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
157b0 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
157c0 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20      break;..    
157d0 64 65 66 61 75 6c 74 3a 20 20 20 2f 2a 20 66 75  default:   /* fu
157e0 6c 6c 2d 74 65 78 74 20 73 65 61 72 63 68 20 2a  ll-text search *
157f0 2f 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 63 6f  /.    {.      co
15800 6e 73 74 20 63 68 61 72 20 2a 7a 51 75 65 72 79  nst char *zQuery
15810 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 20 2a   = (const char *
15820 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74  )sqlite3_value_t
15830 65 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20  ext(argv[0]);.  
15840 20 20 20 20 44 6f 63 4c 69 73 74 20 2a 70 52 65      DocList *pRe
15850 73 75 6c 74 3b 0a 20 20 20 20 20 20 61 73 73 65  sult;.      asse
15860 72 74 28 20 69 64 78 4e 75 6d 3c 3d 51 55 45 52  rt( idxNum<=QUER
15870 59 5f 46 55 4c 4c 54 45 58 54 2b 76 2d 3e 6e 43  Y_FULLTEXT+v->nC
15880 6f 6c 75 6d 6e 29 3b 0a 20 20 20 20 20 20 61 73  olumn);.      as
15890 73 65 72 74 28 20 61 72 67 63 3d 3d 31 20 29 3b  sert( argc==1 );
158a0 0a 20 20 20 20 20 20 71 75 65 72 79 43 6c 65 61  .      queryClea
158b0 72 28 26 63 2d 3e 71 29 3b 0a 20 20 20 20 20 20  r(&c->q);.      
158c0 72 63 20 3d 20 66 75 6c 6c 74 65 78 74 51 75 65  rc = fulltextQue
158d0 72 79 28 76 2c 20 69 64 78 4e 75 6d 2d 51 55 45  ry(v, idxNum-QUE
158e0 52 59 5f 46 55 4c 4c 54 45 58 54 2c 20 7a 51 75  RY_FULLTEXT, zQu
158f0 65 72 79 2c 20 2d 31 2c 20 26 70 52 65 73 75 6c  ery, -1, &pResul
15900 74 2c 20 26 63 2d 3e 71 29 3b 0a 20 20 20 20 20  t, &c->q);.     
15910 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
15920 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
15930 20 20 20 20 20 20 69 66 28 20 63 2d 3e 72 65 73        if( c->res
15940 75 6c 74 2e 70 44 6f 63 6c 69 73 74 21 3d 4e 55  ult.pDoclist!=NU
15950 4c 4c 20 29 20 64 6f 63 4c 69 73 74 44 65 6c 65  LL ) docListDele
15960 74 65 28 63 2d 3e 72 65 73 75 6c 74 2e 70 44 6f  te(c->result.pDo
15970 63 6c 69 73 74 29 3b 0a 20 20 20 20 20 20 72 65  clist);.      re
15980 61 64 65 72 49 6e 69 74 28 26 63 2d 3e 72 65 73  aderInit(&c->res
15990 75 6c 74 2c 20 70 52 65 73 75 6c 74 29 3b 0a 20  ult, pResult);. 
159a0 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
159b0 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  }.  }..  return 
159c0 66 75 6c 6c 74 65 78 74 4e 65 78 74 28 70 43 75  fulltextNext(pCu
159d0 72 73 6f 72 29 3b 0a 7d 0a 0a 2f 2a 20 54 68 69  rsor);.}../* Thi
159e0 73 20 69 73 20 74 68 65 20 78 45 6f 66 20 6d 65  s is the xEof me
159f0 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69 72 74  thod of the virt
15a00 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 65 20  ual table.  The 
15a10 53 51 4c 69 74 65 20 63 6f 72 65 0a 2a 2a 20 63  SQLite core.** c
15a20 61 6c 6c 73 20 74 68 69 73 20 72 6f 75 74 69 6e  alls this routin
15a30 65 20 74 6f 20 66 69 6e 64 20 6f 75 74 20 69 66  e to find out if
15a40 20 69 74 20 68 61 73 20 72 65 61 63 68 65 64 20   it has reached 
15a50 74 68 65 20 65 6e 64 20 6f 66 0a 2a 2a 20 61 20  the end of.** a 
15a60 71 75 65 72 79 27 73 20 72 65 73 75 6c 74 73 20  query's results 
15a70 73 65 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  set..*/.static i
15a80 6e 74 20 66 75 6c 6c 74 65 78 74 45 6f 66 28 73  nt fulltextEof(s
15a90 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
15aa0 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20  or *pCursor){.  
15ab0 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20  fulltext_cursor 
15ac0 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f 63  *c = (fulltext_c
15ad0 75 72 73 6f 72 20 2a 29 20 70 43 75 72 73 6f 72  ursor *) pCursor
15ae0 3b 0a 20 20 72 65 74 75 72 6e 20 63 2d 3e 65 6f  ;.  return c->eo
15af0 66 3b 0a 7d 0a 0a 2f 2a 20 54 68 69 73 20 69 73  f;.}../* This is
15b00 20 74 68 65 20 78 43 6f 6c 75 6d 6e 20 6d 65 74   the xColumn met
15b10 68 6f 64 20 6f 66 20 74 68 65 20 76 69 72 74 75  hod of the virtu
15b20 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 65 20 53  al table.  The S
15b30 51 4c 69 74 65 0a 2a 2a 20 63 6f 72 65 20 63 61  QLite.** core ca
15b40 6c 6c 73 20 74 68 69 73 20 6d 65 74 68 6f 64 20  lls this method 
15b50 64 75 72 69 6e 67 20 61 20 71 75 65 72 79 20 77  during a query w
15b60 68 65 6e 20 69 74 20 6e 65 65 64 73 20 74 68 65  hen it needs the
15b70 20 76 61 6c 75 65 0a 2a 2a 20 6f 66 20 61 20 63   value.** of a c
15b80 6f 6c 75 6d 6e 20 66 72 6f 6d 20 74 68 65 20 76  olumn from the v
15b90 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20 54  irtual table.  T
15ba0 68 69 73 20 6d 65 74 68 6f 64 20 6e 65 65 64 73  his method needs
15bb0 20 74 6f 20 75 73 65 0a 2a 2a 20 6f 6e 65 20 6f   to use.** one o
15bc0 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 72 65  f the sqlite3_re
15bd0 73 75 6c 74 5f 2a 28 29 20 72 6f 75 74 69 6e 65  sult_*() routine
15be0 73 20 74 6f 20 73 74 6f 72 65 20 74 68 65 20 72  s to store the r
15bf0 65 71 75 65 73 74 65 64 0a 2a 2a 20 76 61 6c 75  equested.** valu
15c00 65 20 62 61 63 6b 20 69 6e 20 74 68 65 20 70 43  e back in the pC
15c10 6f 6e 74 65 78 74 2e 0a 2a 2f 0a 73 74 61 74 69  ontext..*/.stati
15c20 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 43 6f  c int fulltextCo
15c30 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  lumn(sqlite3_vta
15c40 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f  b_cursor *pCurso
15c50 72 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  r,.             
15c60 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c               sql
15c70 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43  ite3_context *pC
15c80 6f 6e 74 65 78 74 2c 20 69 6e 74 20 69 64 78 43  ontext, int idxC
15c90 6f 6c 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f  ol){.  fulltext_
15ca0 63 75 72 73 6f 72 20 2a 63 20 3d 20 28 66 75 6c  cursor *c = (ful
15cb0 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 29 20  ltext_cursor *) 
15cc0 70 43 75 72 73 6f 72 3b 0a 20 20 66 75 6c 6c 74  pCursor;.  fullt
15cd0 65 78 74 5f 76 74 61 62 20 2a 76 20 3d 20 63 75  ext_vtab *v = cu
15ce0 72 73 6f 72 5f 76 74 61 62 28 63 29 3b 0a 0a 20  rsor_vtab(c);.. 
15cf0 20 69 66 28 20 69 64 78 43 6f 6c 3c 76 2d 3e 6e   if( idxCol<v->n
15d00 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20 73 71  Column ){.    sq
15d10 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56 61  lite3_value *pVa
15d20 6c 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  l = sqlite3_colu
15d30 6d 6e 5f 76 61 6c 75 65 28 63 2d 3e 70 53 74 6d  mn_value(c->pStm
15d40 74 2c 20 69 64 78 43 6f 6c 2b 31 29 3b 0a 20 20  t, idxCol+1);.  
15d50 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
15d60 5f 76 61 6c 75 65 28 70 43 6f 6e 74 65 78 74 2c  _value(pContext,
15d70 20 70 56 61 6c 29 3b 0a 20 20 7d 65 6c 73 65 20   pVal);.  }else 
15d80 69 66 28 20 69 64 78 43 6f 6c 3d 3d 76 2d 3e 6e  if( idxCol==v->n
15d90 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20 2f 2a  Column ){.    /*
15da0 20 54 68 65 20 65 78 74 72 61 20 63 6f 6c 75 6d   The extra colum
15db0 6e 20 77 68 6f 73 65 20 6e 61 6d 65 20 69 73 20  n whose name is 
15dc0 74 68 65 20 73 61 6d 65 20 61 73 20 74 68 65 20  the same as the 
15dd0 74 61 62 6c 65 2e 0a 20 20 20 20 2a 2a 20 52 65  table..    ** Re
15de0 74 75 72 6e 20 61 20 62 6c 6f 62 20 77 68 69 63  turn a blob whic
15df0 68 20 69 73 20 61 20 70 6f 69 6e 74 65 72 20 74  h is a pointer t
15e00 6f 20 74 68 65 20 63 75 72 73 6f 72 0a 20 20 20  o the cursor.   
15e10 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   */.    sqlite3_
15e20 72 65 73 75 6c 74 5f 62 6c 6f 62 28 70 43 6f 6e  result_blob(pCon
15e30 74 65 78 74 2c 20 26 63 2c 20 73 69 7a 65 6f 66  text, &c, sizeof
15e40 28 63 29 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e  (c), SQLITE_TRAN
15e50 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 20 20 72 65  SIENT);.  }.  re
15e60 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
15e70 7d 0a 0a 2f 2a 20 54 68 69 73 20 69 73 20 74 68  }../* This is th
15e80 65 20 78 52 6f 77 69 64 20 6d 65 74 68 6f 64 2e  e xRowid method.
15e90 20 20 54 68 65 20 53 51 4c 69 74 65 20 63 6f 72    The SQLite cor
15ea0 65 20 63 61 6c 6c 73 20 74 68 69 73 20 72 6f 75  e calls this rou
15eb0 74 69 6e 65 20 74 6f 0a 2a 2a 20 72 65 74 72 69  tine to.** retri
15ec0 76 65 20 74 68 65 20 72 6f 77 69 64 20 66 6f 72  ve the rowid for
15ed0 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 6f 77   the current row
15ee0 20 6f 66 20 74 68 65 20 72 65 73 75 6c 74 20 73   of the result s
15ef0 65 74 2e 20 20 54 68 65 0a 2a 2a 20 72 6f 77 69  et.  The.** rowi
15f00 64 20 73 68 6f 75 6c 64 20 62 65 20 77 72 69 74  d should be writ
15f10 74 65 6e 20 74 6f 20 2a 70 52 6f 77 69 64 2e 0a  ten to *pRowid..
15f20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75  */.static int fu
15f30 6c 6c 74 65 78 74 52 6f 77 69 64 28 73 71 6c 69  lltextRowid(sqli
15f40 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
15f50 2a 70 43 75 72 73 6f 72 2c 20 73 71 6c 69 74 65  *pCursor, sqlite
15f60 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 29 7b  _int64 *pRowid){
15f70 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73  .  fulltext_curs
15f80 6f 72 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78  or *c = (fulltex
15f90 74 5f 63 75 72 73 6f 72 20 2a 29 20 70 43 75 72  t_cursor *) pCur
15fa0 73 6f 72 3b 0a 0a 20 20 2a 70 52 6f 77 69 64 20  sor;..  *pRowid 
15fb0 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
15fc0 5f 69 6e 74 36 34 28 63 2d 3e 70 53 74 6d 74 2c  _int64(c->pStmt,
15fd0 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51   0);.  return SQ
15fe0 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 41  LITE_OK;.}../* A
15ff0 64 64 20 61 6c 6c 20 74 65 72 6d 73 20 69 6e 20  dd all terms in 
16000 5b 7a 54 65 78 74 5d 20 74 6f 20 74 68 65 20 67  [zText] to the g
16010 69 76 65 6e 20 68 61 73 68 20 74 61 62 6c 65 2e  iven hash table.
16020 20 20 49 66 20 5b 69 43 6f 6c 75 6d 6e 5d 20 3e    If [iColumn] >
16030 20 30 2c 0a 20 2a 20 77 65 20 61 6c 73 6f 20 73   0,. * we also s
16040 74 6f 72 65 20 70 6f 73 69 74 69 6f 6e 73 20 61  tore positions a
16050 6e 64 20 6f 66 66 73 65 74 73 20 69 6e 20 74 68  nd offsets in th
16060 65 20 68 61 73 68 20 74 61 62 6c 65 20 75 73 69  e hash table usi
16070 6e 67 20 74 68 65 20 67 69 76 65 6e 0a 20 2a 20  ng the given. * 
16080 63 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72 2e 20 2a  column number. *
16090 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 62 75 69  /.static int bui
160a0 6c 64 54 65 72 6d 73 28 66 75 6c 6c 74 65 78 74  ldTerms(fulltext
160b0 5f 76 74 61 62 20 2a 76 2c 20 66 74 73 31 48 61  _vtab *v, fts1Ha
160c0 73 68 20 2a 74 65 72 6d 73 2c 20 73 71 6c 69 74  sh *terms, sqlit
160d0 65 5f 69 6e 74 36 34 20 69 44 6f 63 69 64 2c 0a  e_int64 iDocid,.
160e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
160f0 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
16100 20 2a 7a 54 65 78 74 2c 20 69 6e 74 20 69 43 6f   *zText, int iCo
16110 6c 75 6d 6e 29 7b 0a 20 20 73 71 6c 69 74 65 33  lumn){.  sqlite3
16120 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b  _tokenizer *pTok
16130 65 6e 69 7a 65 72 20 3d 20 76 2d 3e 70 54 6f 6b  enizer = v->pTok
16140 65 6e 69 7a 65 72 3b 0a 20 20 73 71 6c 69 74 65  enizer;.  sqlite
16150 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72 73  3_tokenizer_curs
16160 6f 72 20 2a 70 43 75 72 73 6f 72 3b 0a 20 20 63  or *pCursor;.  c
16170 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 6f 6b 65  onst char *pToke
16180 6e 3b 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 42  n;.  int nTokenB
16190 79 74 65 73 3b 0a 20 20 69 6e 74 20 69 53 74 61  ytes;.  int iSta
161a0 72 74 4f 66 66 73 65 74 2c 20 69 45 6e 64 4f 66  rtOffset, iEndOf
161b0 66 73 65 74 2c 20 69 50 6f 73 69 74 69 6f 6e 3b  fset, iPosition;
161c0 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 72 63  .  int rc;..  rc
161d0 20 3d 20 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e 70   = pTokenizer->p
161e0 4d 6f 64 75 6c 65 2d 3e 78 4f 70 65 6e 28 70 54  Module->xOpen(pT
161f0 6f 6b 65 6e 69 7a 65 72 2c 20 7a 54 65 78 74 2c  okenizer, zText,
16200 20 2d 31 2c 20 26 70 43 75 72 73 6f 72 29 3b 0a   -1, &pCursor);.
16210 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
16220 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
16230 0a 0a 20 20 70 43 75 72 73 6f 72 2d 3e 70 54 6f  ..  pCursor->pTo
16240 6b 65 6e 69 7a 65 72 20 3d 20 70 54 6f 6b 65 6e  kenizer = pToken
16250 69 7a 65 72 3b 0a 20 20 77 68 69 6c 65 28 20 53  izer;.  while( S
16260 51 4c 49 54 45 5f 4f 4b 3d 3d 70 54 6f 6b 65 6e  QLITE_OK==pToken
16270 69 7a 65 72 2d 3e 70 4d 6f 64 75 6c 65 2d 3e 78  izer->pModule->x
16280 4e 65 78 74 28 70 43 75 72 73 6f 72 2c 0a 20 20  Next(pCursor,.  
16290 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
162a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
162b0 20 20 20 20 20 20 20 20 20 20 20 20 20 26 70 54               &pT
162c0 6f 6b 65 6e 2c 20 26 6e 54 6f 6b 65 6e 42 79 74  oken, &nTokenByt
162d0 65 73 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  es,.            
162e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
162f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16300 20 20 20 26 69 53 74 61 72 74 4f 66 66 73 65 74     &iStartOffset
16310 2c 20 26 69 45 6e 64 4f 66 66 73 65 74 2c 0a 20  , &iEndOffset,. 
16320 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16330 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16340 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26 69                &i
16350 50 6f 73 69 74 69 6f 6e 29 20 29 7b 0a 20 20 20  Position) ){.   
16360 20 44 6f 63 4c 69 73 74 20 2a 70 3b 0a 0a 20 20   DocList *p;..  
16370 20 20 2f 2a 20 50 6f 73 69 74 69 6f 6e 73 20 63    /* Positions c
16380 61 6e 27 74 20 62 65 20 6e 65 67 61 74 69 76 65  an't be negative
16390 3b 20 77 65 20 75 73 65 20 2d 31 20 61 73 20 61  ; we use -1 as a
163a0 20 74 65 72 6d 69 6e 61 74 6f 72 20 69 6e 74 65   terminator inte
163b0 72 6e 61 6c 6c 79 2e 20 2a 2f 0a 20 20 20 20 69  rnally. */.    i
163c0 66 28 20 69 50 6f 73 69 74 69 6f 6e 3c 30 20 29  f( iPosition<0 )
163d0 7b 0a 20 20 20 20 20 20 70 54 6f 6b 65 6e 69 7a  {.      pTokeniz
163e0 65 72 2d 3e 70 4d 6f 64 75 6c 65 2d 3e 78 43 6c  er->pModule->xCl
163f0 6f 73 65 28 70 43 75 72 73 6f 72 29 3b 0a 20 20  ose(pCursor);.  
16400 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
16410 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 0a  E_ERROR;.    }..
16420 20 20 20 20 70 20 3d 20 66 74 73 31 48 61 73 68      p = fts1Hash
16430 46 69 6e 64 28 74 65 72 6d 73 2c 20 70 54 6f 6b  Find(terms, pTok
16440 65 6e 2c 20 6e 54 6f 6b 65 6e 42 79 74 65 73 29  en, nTokenBytes)
16450 3b 0a 20 20 20 20 69 66 28 20 70 3d 3d 4e 55 4c  ;.    if( p==NUL
16460 4c 20 29 7b 0a 20 20 20 20 20 20 70 20 3d 20 64  L ){.      p = d
16470 6f 63 4c 69 73 74 4e 65 77 28 44 4c 5f 44 45 46  ocListNew(DL_DEF
16480 41 55 4c 54 29 3b 0a 20 20 20 20 20 20 64 6f 63  AULT);.      doc
16490 4c 69 73 74 41 64 64 44 6f 63 69 64 28 70 2c 20  ListAddDocid(p, 
164a0 69 44 6f 63 69 64 29 3b 0a 20 20 20 20 20 20 66  iDocid);.      f
164b0 74 73 31 48 61 73 68 49 6e 73 65 72 74 28 74 65  ts1HashInsert(te
164c0 72 6d 73 2c 20 70 54 6f 6b 65 6e 2c 20 6e 54 6f  rms, pToken, nTo
164d0 6b 65 6e 42 79 74 65 73 2c 20 70 29 3b 0a 20 20  kenBytes, p);.  
164e0 20 20 7d 0a 20 20 20 20 69 66 28 20 69 43 6f 6c    }.    if( iCol
164f0 75 6d 6e 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20  umn>=0 ){.      
16500 64 6f 63 4c 69 73 74 41 64 64 50 6f 73 4f 66 66  docListAddPosOff
16510 73 65 74 28 70 2c 20 69 43 6f 6c 75 6d 6e 2c 20  set(p, iColumn, 
16520 69 50 6f 73 69 74 69 6f 6e 2c 20 69 53 74 61 72  iPosition, iStar
16530 74 4f 66 66 73 65 74 2c 20 69 45 6e 64 4f 66 66  tOffset, iEndOff
16540 73 65 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  set);.    }.  }.
16550 0a 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73  .  /* TODO(shess
16560 29 20 43 68 65 63 6b 20 72 65 74 75 72 6e 3f 20  ) Check return? 
16570 20 53 68 6f 75 6c 64 20 74 68 69 73 20 62 65 20   Should this be 
16580 61 62 6c 65 20 74 6f 20 63 61 75 73 65 20 65 72  able to cause er
16590 72 6f 72 73 20 61 74 0a 20 20 2a 2a 20 74 68 69  rors at.  ** thi
165a0 73 20 70 6f 69 6e 74 3f 20 20 41 63 74 75 61 6c  s point?  Actual
165b0 6c 79 2c 20 73 61 6d 65 20 71 75 65 73 74 69 6f  ly, same questio
165c0 6e 20 61 62 6f 75 74 20 73 71 6c 69 74 65 33 5f  n about sqlite3_
165d0 66 69 6e 61 6c 69 7a 65 28 29 2c 0a 20 20 2a 2a  finalize(),.  **
165e0 20 74 68 6f 75 67 68 20 6f 6e 65 20 63 6f 75 6c   though one coul
165f0 64 20 61 72 67 75 65 20 74 68 61 74 20 66 61 69  d argue that fai
16600 6c 75 72 65 20 74 68 65 72 65 20 6d 65 61 6e 73  lure there means
16610 20 74 68 61 74 20 74 68 65 20 64 61 74 61 20 69   that the data i
16620 73 0a 20 20 2a 2a 20 6e 6f 74 20 64 75 72 61 62  s.  ** not durab
16630 6c 65 2e 20 20 2a 70 6f 6e 64 65 72 2a 0a 20 20  le.  *ponder*.  
16640 2a 2f 0a 20 20 70 54 6f 6b 65 6e 69 7a 65 72 2d  */.  pTokenizer-
16650 3e 70 4d 6f 64 75 6c 65 2d 3e 78 43 6c 6f 73 65  >pModule->xClose
16660 28 70 43 75 72 73 6f 72 29 3b 0a 20 20 72 65 74  (pCursor);.  ret
16670 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 55 70  urn rc;.}../* Up
16680 64 61 74 65 20 74 68 65 20 25 5f 74 65 72 6d 73  date the %_terms
16690 20 74 61 62 6c 65 20 74 6f 20 6d 61 70 20 74 68   table to map th
166a0 65 20 74 65 72 6d 20 5b 70 54 65 72 6d 5d 20 74  e term [pTerm] t
166b0 6f 20 74 68 65 20 67 69 76 65 6e 20 72 6f 77 69  o the given rowi
166c0 64 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d. */.static int
166d0 20 69 6e 64 65 78 5f 69 6e 73 65 72 74 5f 74 65   index_insert_te
166e0 72 6d 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62  rm(fulltext_vtab
166f0 20 2a 76 2c 20 63 6f 6e 73 74 20 63 68 61 72 20   *v, const char 
16700 2a 70 54 65 72 6d 2c 20 69 6e 74 20 6e 54 65 72  *pTerm, int nTer
16710 6d 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  m,.             
16720 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16730 44 6f 63 4c 69 73 74 20 2a 64 29 7b 0a 20 20 73  DocList *d){.  s
16740 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 49 6e 64  qlite_int64 iInd
16750 65 78 52 6f 77 3b 0a 20 20 44 6f 63 4c 69 73 74  exRow;.  DocList
16760 20 64 6f 63 6c 69 73 74 3b 0a 20 20 69 6e 74 20   doclist;.  int 
16770 69 53 65 67 6d 65 6e 74 20 3d 20 30 2c 20 72 63  iSegment = 0, rc
16780 3b 0a 0a 20 20 72 63 20 3d 20 74 65 72 6d 5f 73  ;..  rc = term_s
16790 65 6c 65 63 74 28 76 2c 20 70 54 65 72 6d 2c 20  elect(v, pTerm, 
167a0 6e 54 65 72 6d 2c 20 69 53 65 67 6d 65 6e 74 2c  nTerm, iSegment,
167b0 20 26 69 49 6e 64 65 78 52 6f 77 2c 20 26 64 6f   &iIndexRow, &do
167c0 63 6c 69 73 74 29 3b 0a 20 20 69 66 28 20 72 63  clist);.  if( rc
167d0 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29 7b  ==SQLITE_DONE ){
167e0 0a 20 20 20 20 64 6f 63 4c 69 73 74 49 6e 69 74  .    docListInit
167f0 28 26 64 6f 63 6c 69 73 74 2c 20 44 4c 5f 44 45  (&doclist, DL_DE
16800 46 41 55 4c 54 2c 20 30 2c 20 30 29 3b 0a 20 20  FAULT, 0, 0);.  
16810 20 20 64 6f 63 4c 69 73 74 55 70 64 61 74 65 28    docListUpdate(
16820 26 64 6f 63 6c 69 73 74 2c 20 64 29 3b 0a 20 20  &doclist, d);.  
16830 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29    /* TODO(shess)
16840 20 43 6f 6e 73 69 64 65 72 20 6c 65 6e 67 74 68   Consider length
16850 28 64 6f 63 6c 69 73 74 29 3e 43 48 55 4e 4b 5f  (doclist)>CHUNK_
16860 4d 41 58 3f 20 2a 2f 0a 20 20 20 20 72 63 20 3d  MAX? */.    rc =
16870 20 74 65 72 6d 5f 69 6e 73 65 72 74 28 76 2c 20   term_insert(v, 
16880 4e 55 4c 4c 2c 20 70 54 65 72 6d 2c 20 6e 54 65  NULL, pTerm, nTe
16890 72 6d 2c 20 69 53 65 67 6d 65 6e 74 2c 20 26 64  rm, iSegment, &d
168a0 6f 63 6c 69 73 74 29 3b 0a 20 20 20 20 67 6f 74  oclist);.    got
168b0 6f 20 65 72 72 3b 0a 20 20 7d 0a 20 20 69 66 28  o err;.  }.  if(
168c0 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20   rc!=SQLITE_ROW 
168d0 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
168e0 45 52 52 4f 52 3b 0a 0a 20 20 64 6f 63 4c 69 73  ERROR;..  docLis
168f0 74 55 70 64 61 74 65 28 26 64 6f 63 6c 69 73 74  tUpdate(&doclist
16900 2c 20 64 29 3b 0a 20 20 69 66 28 20 64 6f 63 6c  , d);.  if( docl
16910 69 73 74 2e 6e 44 61 74 61 3c 3d 43 48 55 4e 4b  ist.nData<=CHUNK
16920 5f 4d 41 58 20 29 7b 0a 20 20 20 20 72 63 20 3d  _MAX ){.    rc =
16930 20 74 65 72 6d 5f 75 70 64 61 74 65 28 76 2c 20   term_update(v, 
16940 69 49 6e 64 65 78 52 6f 77 2c 20 26 64 6f 63 6c  iIndexRow, &docl
16950 69 73 74 29 3b 0a 20 20 20 20 67 6f 74 6f 20 65  ist);.    goto e
16960 72 72 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 6f  rr;.  }..  /* Do
16970 63 6c 69 73 74 20 64 6f 65 73 6e 27 74 20 66 69  clist doesn't fi
16980 74 2c 20 64 65 6c 65 74 65 20 77 68 61 74 27 73  t, delete what's
16990 20 74 68 65 72 65 2c 20 61 6e 64 20 61 63 63 75   there, and accu
169a0 6d 75 6c 61 74 65 0a 20 20 2a 2a 20 66 6f 72 77  mulate.  ** forw
169b0 61 72 64 2e 0a 20 20 2a 2f 0a 20 20 72 63 20 3d  ard..  */.  rc =
169c0 20 74 65 72 6d 5f 64 65 6c 65 74 65 28 76 2c 20   term_delete(v, 
169d0 69 49 6e 64 65 78 52 6f 77 29 3b 0a 20 20 69 66  iIndexRow);.  if
169e0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
169f0 29 20 67 6f 74 6f 20 65 72 72 3b 0a 0a 20 20 2f  ) goto err;..  /
16a00 2a 20 54 72 79 20 74 6f 20 69 6e 73 65 72 74 20  * Try to insert 
16a10 74 68 65 20 64 6f 63 6c 69 73 74 20 69 6e 74 6f  the doclist into
16a20 20 61 20 68 69 67 68 65 72 20 73 65 67 6d 65 6e   a higher segmen
16a30 74 20 62 75 63 6b 65 74 2e 20 20 4f 6e 0a 20 20  t bucket.  On.  
16a40 2a 2a 20 66 61 69 6c 75 72 65 2c 20 61 63 63 75  ** failure, accu
16a50 6d 75 6c 61 74 65 20 65 78 69 73 74 69 6e 67 20  mulate existing 
16a60 64 6f 63 6c 69 73 74 20 77 69 74 68 20 74 68 65  doclist with the
16a70 20 64 6f 63 6c 69 73 74 20 66 72 6f 6d 20 74 68   doclist from th
16a80 61 74 0a 20 20 2a 2a 20 62 75 63 6b 65 74 2c 20  at.  ** bucket, 
16a90 61 6e 64 20 70 75 74 20 72 65 73 75 6c 74 73 20  and put results 
16aa0 69 6e 20 74 68 65 20 6e 65 78 74 20 62 75 63 6b  in the next buck
16ab0 65 74 2e 0a 20 20 2a 2f 0a 20 20 69 53 65 67 6d  et..  */.  iSegm
16ac0 65 6e 74 2b 2b 3b 0a 20 20 77 68 69 6c 65 28 20  ent++;.  while( 
16ad0 28 72 63 3d 74 65 72 6d 5f 69 6e 73 65 72 74 28  (rc=term_insert(
16ae0 76 2c 20 26 69 49 6e 64 65 78 52 6f 77 2c 20 70  v, &iIndexRow, p
16af0 54 65 72 6d 2c 20 6e 54 65 72 6d 2c 20 69 53 65  Term, nTerm, iSe
16b00 67 6d 65 6e 74 2c 0a 20 20 20 20 20 20 20 20 20  gment,.         
16b10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16b20 26 64 6f 63 6c 69 73 74 29 29 21 3d 53 51 4c 49  &doclist))!=SQLI
16b30 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c  TE_OK ){.    sql
16b40 69 74 65 5f 69 6e 74 36 34 20 69 53 65 67 6d 65  ite_int64 iSegme
16b50 6e 74 52 6f 77 3b 0a 20 20 20 20 44 6f 63 4c 69  ntRow;.    DocLi
16b60 73 74 20 6f 6c 64 3b 0a 20 20 20 20 69 6e 74 20  st old;.    int 
16b70 72 63 32 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 74  rc2;..    /* Ret
16b80 61 69 6e 20 6f 6c 64 20 65 72 72 6f 72 20 69 6e  ain old error in
16b90 20 63 61 73 65 20 74 68 65 20 74 65 72 6d 5f 69   case the term_i
16ba0 6e 73 65 72 74 28 29 20 65 72 72 6f 72 20 77 61  nsert() error wa
16bb0 73 20 72 65 61 6c 6c 79 20 61 6e 0a 20 20 20 20  s really an.    
16bc0 2a 2a 20 65 72 72 6f 72 20 72 61 74 68 65 72 20  ** error rather 
16bd0 74 68 61 6e 20 61 20 62 6f 75 6e 63 65 64 20 69  than a bounced i
16be0 6e 73 65 72 74 2e 0a 20 20 20 20 2a 2f 0a 20 20  nsert..    */.  
16bf0 20 20 72 63 32 20 3d 20 74 65 72 6d 5f 73 65 6c    rc2 = term_sel
16c00 65 63 74 28 76 2c 20 70 54 65 72 6d 2c 20 6e 54  ect(v, pTerm, nT
16c10 65 72 6d 2c 20 69 53 65 67 6d 65 6e 74 2c 20 26  erm, iSegment, &
16c20 69 53 65 67 6d 65 6e 74 52 6f 77 2c 20 26 6f 6c  iSegmentRow, &ol
16c30 64 29 3b 0a 20 20 20 20 69 66 28 20 72 63 32 21  d);.    if( rc2!
16c40 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 20 67 6f  =SQLITE_ROW ) go
16c50 74 6f 20 65 72 72 3b 0a 0a 20 20 20 20 72 63 20  to err;..    rc 
16c60 3d 20 74 65 72 6d 5f 64 65 6c 65 74 65 28 76 2c  = term_delete(v,
16c70 20 69 53 65 67 6d 65 6e 74 52 6f 77 29 3b 0a 20   iSegmentRow);. 
16c80 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
16c90 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 65 72 72 3b  E_OK ) goto err;
16ca0 0a 0a 20 20 20 20 2f 2a 20 52 65 75 73 69 6e 67  ..    /* Reusing
16cb0 20 6c 6f 77 65 73 74 2d 6e 75 6d 62 65 72 20 64   lowest-number d
16cc0 65 6c 65 74 65 64 20 72 6f 77 20 6b 65 65 70 73  eleted row keeps
16cd0 20 74 68 65 20 69 6e 64 65 78 20 73 6d 61 6c 6c   the index small
16ce0 65 72 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 69  er. */.    if( i
16cf0 53 65 67 6d 65 6e 74 52 6f 77 3c 69 49 6e 64 65  SegmentRow<iInde
16d00 78 52 6f 77 20 29 20 69 49 6e 64 65 78 52 6f 77  xRow ) iIndexRow
16d10 20 3d 20 69 53 65 67 6d 65 6e 74 52 6f 77 3b 0a   = iSegmentRow;.
16d20 0a 20 20 20 20 2f 2a 20 64 6f 63 6c 69 73 74 20  .    /* doclist 
16d30 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 6e 65 77  contains the new
16d40 65 72 20 64 61 74 61 2c 20 73 6f 20 61 63 63 75  er data, so accu
16d50 6d 75 6c 61 74 65 20 69 74 20 6f 76 65 72 20 6f  mulate it over o
16d60 6c 64 2e 0a 20 20 20 20 2a 2a 20 54 68 65 6e 20  ld..    ** Then 
16d70 73 74 65 61 6c 20 61 63 63 75 6d 75 6c 61 74 65  steal accumulate
16d80 64 20 64 61 74 61 20 66 6f 72 20 64 6f 63 6c 69  d data for docli
16d90 73 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 64  st..    */.    d
16da0 6f 63 4c 69 73 74 41 63 63 75 6d 75 6c 61 74 65  ocListAccumulate
16db0 28 26 6f 6c 64 2c 20 26 64 6f 63 6c 69 73 74 29  (&old, &doclist)
16dc0 3b 0a 20 20 20 20 64 6f 63 4c 69 73 74 44 65 73  ;.    docListDes
16dd0 74 72 6f 79 28 26 64 6f 63 6c 69 73 74 29 3b 0a  troy(&doclist);.
16de0 20 20 20 20 64 6f 63 6c 69 73 74 20 3d 20 6f 6c      doclist = ol
16df0 64 3b 0a 0a 20 20 20 20 69 53 65 67 6d 65 6e 74  d;..    iSegment
16e00 2b 2b 3b 0a 20 20 7d 0a 0a 20 65 72 72 3a 0a 20  ++;.  }.. err:. 
16e10 20 64 6f 63 4c 69 73 74 44 65 73 74 72 6f 79 28   docListDestroy(
16e20 26 64 6f 63 6c 69 73 74 29 3b 0a 20 20 72 65 74  &doclist);.  ret
16e30 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 41 64  urn rc;.}../* Ad
16e40 64 20 64 6f 63 6c 69 73 74 73 20 66 6f 72 20 61  d doclists for a
16e50 6c 6c 20 74 65 72 6d 73 20 69 6e 20 5b 70 56 61  ll terms in [pVa
16e60 6c 75 65 73 5d 20 74 6f 20 74 68 65 20 68 61 73  lues] to the has
16e70 68 20 74 61 62 6c 65 20 5b 74 65 72 6d 73 5d 2e  h table [terms].
16e80 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 69   */.static int i
16e90 6e 73 65 72 74 54 65 72 6d 73 28 66 75 6c 6c 74  nsertTerms(fullt
16ea0 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 66 74 73  ext_vtab *v, fts
16eb0 31 48 61 73 68 20 2a 74 65 72 6d 73 2c 20 73 71  1Hash *terms, sq
16ec0 6c 69 74 65 5f 69 6e 74 36 34 20 69 52 6f 77 69  lite_int64 iRowi
16ed0 64 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  d,.             
16ee0 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65     sqlite3_value
16ef0 20 2a 2a 70 56 61 6c 75 65 73 29 7b 0a 20 20 69   **pValues){.  i
16f00 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 20 3d 20  nt i;.  for(i = 
16f10 30 3b 20 69 20 3c 20 76 2d 3e 6e 43 6f 6c 75 6d  0; i < v->nColum
16f20 6e 20 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 63 68  n ; ++i){.    ch
16f30 61 72 20 2a 7a 54 65 78 74 20 3d 20 28 63 68 61  ar *zText = (cha
16f40 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  r*)sqlite3_value
16f50 5f 74 65 78 74 28 70 56 61 6c 75 65 73 5b 69 5d  _text(pValues[i]
16f60 29 3b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20  );.    int rc = 
16f70 62 75 69 6c 64 54 65 72 6d 73 28 76 2c 20 74 65  buildTerms(v, te
16f80 72 6d 73 2c 20 69 52 6f 77 69 64 2c 20 7a 54 65  rms, iRowid, zTe
16f90 78 74 2c 20 69 29 3b 0a 20 20 20 20 69 66 28 20  xt, i);.    if( 
16fa0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
16fb0 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20  return rc;.  }. 
16fc0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
16fd0 4b 3b 0a 7d 0a 0a 2f 2a 20 41 64 64 20 65 6d 70  K;.}../* Add emp
16fe0 74 79 20 64 6f 63 6c 69 73 74 73 20 66 6f 72 20  ty doclists for 
16ff0 61 6c 6c 20 74 65 72 6d 73 20 69 6e 20 74 68 65  all terms in the
17000 20 67 69 76 65 6e 20 72 6f 77 27 73 20 63 6f 6e   given row's con
17010 74 65 6e 74 20 74 6f 20 74 68 65 20 68 61 73 68  tent to the hash
17020 0a 20 2a 20 74 61 62 6c 65 20 5b 70 54 65 72 6d  . * table [pTerm
17030 73 5d 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  s]. */.static in
17040 74 20 64 65 6c 65 74 65 54 65 72 6d 73 28 66 75  t deleteTerms(fu
17050 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20  lltext_vtab *v, 
17060 66 74 73 31 48 61 73 68 20 2a 70 54 65 72 6d 73  fts1Hash *pTerms
17070 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69  , sqlite_int64 i
17080 52 6f 77 69 64 29 7b 0a 20 20 63 6f 6e 73 74 20  Rowid){.  const 
17090 63 68 61 72 20 2a 2a 70 56 61 6c 75 65 73 3b 0a  char **pValues;.
170a0 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69 6e 74 20    int i;..  int 
170b0 72 63 20 3d 20 63 6f 6e 74 65 6e 74 5f 73 65 6c  rc = content_sel
170c0 65 63 74 28 76 2c 20 69 52 6f 77 69 64 2c 20 26  ect(v, iRowid, &
170d0 70 56 61 6c 75 65 73 29 3b 0a 20 20 69 66 28 20  pValues);.  if( 
170e0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
170f0 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 66 6f  return rc;..  fo
17100 72 28 69 20 3d 20 30 20 3b 20 69 20 3c 20 76 2d  r(i = 0 ; i < v-
17110 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 20 7b  >nColumn; ++i) {
17120 0a 20 20 20 20 72 63 20 3d 20 62 75 69 6c 64 54  .    rc = buildT
17130 65 72 6d 73 28 76 2c 20 70 54 65 72 6d 73 2c 20  erms(v, pTerms, 
17140 69 52 6f 77 69 64 2c 20 70 56 61 6c 75 65 73 5b  iRowid, pValues[
17150 69 5d 2c 20 2d 31 29 3b 0a 20 20 20 20 69 66 28  i], -1);.    if(
17160 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
17170 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 66   break;.  }..  f
17180 72 65 65 53 74 72 69 6e 67 41 72 72 61 79 28 76  reeStringArray(v
17190 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 70 56 61 6c 75  ->nColumn, pValu
171a0 65 73 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  es);.  return SQ
171b0 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 49  LITE_OK;.}../* I
171c0 6e 73 65 72 74 20 61 20 72 6f 77 20 69 6e 74 6f  nsert a row into
171d0 20 74 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74   the %_content t
171e0 61 62 6c 65 3b 20 73 65 74 20 2a 70 69 52 6f 77  able; set *piRow
171f0 69 64 20 74 6f 20 62 65 20 74 68 65 20 49 44 20  id to be the ID 
17200 6f 66 20 74 68 65 0a 20 2a 20 6e 65 77 20 72 6f  of the. * new ro
17210 77 2e 20 20 46 69 6c 6c 20 5b 70 54 65 72 6d 73  w.  Fill [pTerms
17220 5d 20 77 69 74 68 20 6e 65 77 20 64 6f 63 6c 69  ] with new docli
17230 73 74 73 20 66 6f 72 20 74 68 65 20 25 5f 74 65  sts for the %_te
17240 72 6d 20 74 61 62 6c 65 2e 20 2a 2f 0a 73 74 61  rm table. */.sta
17250 74 69 63 20 69 6e 74 20 69 6e 64 65 78 5f 69 6e  tic int index_in
17260 73 65 72 74 28 66 75 6c 6c 74 65 78 74 5f 76 74  sert(fulltext_vt
17270 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 33 5f 76  ab *v, sqlite3_v
17280 61 6c 75 65 20 2a 70 52 65 71 75 65 73 74 52 6f  alue *pRequestRo
17290 77 69 64 2c 0a 20 20 20 20 20 20 20 20 20 20 20  wid,.           
172a0 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c               sql
172b0 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70 56 61  ite3_value **pVa
172c0 6c 75 65 73 2c 0a 20 20 20 20 20 20 20 20 20 20  lues,.          
172d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
172e0 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 69 52 6f  lite_int64 *piRo
172f0 77 69 64 2c 20 66 74 73 31 48 61 73 68 20 2a 70  wid, fts1Hash *p
17300 54 65 72 6d 73 29 7b 0a 20 20 69 6e 74 20 72 63  Terms){.  int rc
17310 3b 0a 0a 20 20 72 63 20 3d 20 63 6f 6e 74 65 6e  ;..  rc = conten
17320 74 5f 69 6e 73 65 72 74 28 76 2c 20 70 52 65 71  t_insert(v, pReq
17330 75 65 73 74 52 6f 77 69 64 2c 20 70 56 61 6c 75  uestRowid, pValu
17340 65 73 29 3b 20 20 2f 2a 20 65 78 65 63 75 74 65  es);  /* execute
17350 20 61 6e 20 53 51 4c 20 49 4e 53 45 52 54 20 2a   an SQL INSERT *
17360 2f 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  /.  if( rc!=SQLI
17370 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
17380 63 3b 0a 20 20 2a 70 69 52 6f 77 69 64 20 3d 20  c;.  *piRowid = 
17390 73 71 6c 69 74 65 33 5f 6c 61 73 74 5f 69 6e 73  sqlite3_last_ins
173a0 65 72 74 5f 72 6f 77 69 64 28 76 2d 3e 64 62 29  ert_rowid(v->db)
173b0 3b 0a 20 20 72 65 74 75 72 6e 20 69 6e 73 65 72  ;.  return inser
173c0 74 54 65 72 6d 73 28 76 2c 20 70 54 65 72 6d 73  tTerms(v, pTerms
173d0 2c 20 2a 70 69 52 6f 77 69 64 2c 20 70 56 61 6c  , *piRowid, pVal
173e0 75 65 73 29 3b 0a 7d 0a 0a 2f 2a 20 44 65 6c 65  ues);.}../* Dele
173f0 74 65 20 61 20 72 6f 77 20 66 72 6f 6d 20 74 68  te a row from th
17400 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62 6c  e %_content tabl
17410 65 3b 20 66 69 6c 6c 20 5b 70 54 65 72 6d 73 5d  e; fill [pTerms]
17420 20 77 69 74 68 20 65 6d 70 74 79 20 64 6f 63 6c   with empty docl
17430 69 73 74 73 0a 20 2a 20 74 6f 20 62 65 20 77 72  ists. * to be wr
17440 69 74 74 65 6e 20 74 6f 20 74 68 65 20 25 5f 74  itten to the %_t
17450 65 72 6d 20 74 61 62 6c 65 2e 20 2a 2f 0a 73 74  erm table. */.st
17460 61 74 69 63 20 69 6e 74 20 69 6e 64 65 78 5f 64  atic int index_d
17470 65 6c 65 74 65 28 66 75 6c 6c 74 65 78 74 5f 76  elete(fulltext_v
17480 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f 69  tab *v, sqlite_i
17490 6e 74 36 34 20 69 52 6f 77 2c 20 66 74 73 31 48  nt64 iRow, fts1H
174a0 61 73 68 20 2a 70 54 65 72 6d 73 29 7b 0a 20 20  ash *pTerms){.  
174b0 69 6e 74 20 72 63 20 3d 20 64 65 6c 65 74 65 54  int rc = deleteT
174c0 65 72 6d 73 28 76 2c 20 70 54 65 72 6d 73 2c 20  erms(v, pTerms, 
174d0 69 52 6f 77 29 3b 0a 20 20 69 66 28 20 72 63 21  iRow);.  if( rc!
174e0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
174f0 75 72 6e 20 72 63 3b 0a 20 20 72 65 74 75 72 6e  urn rc;.  return
17500 20 63 6f 6e 74 65 6e 74 5f 64 65 6c 65 74 65 28   content_delete(
17510 76 2c 20 69 52 6f 77 29 3b 20 20 2f 2a 20 65 78  v, iRow);  /* ex
17520 65 63 75 74 65 20 61 6e 20 53 51 4c 20 44 45 4c  ecute an SQL DEL
17530 45 54 45 20 2a 2f 0a 7d 0a 0a 2f 2a 20 55 70 64  ETE */.}../* Upd
17540 61 74 65 20 61 20 72 6f 77 20 69 6e 20 74 68 65  ate a row in the
17550 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65   %_content table
17560 3b 20 66 69 6c 6c 20 5b 70 54 65 72 6d 73 5d 20  ; fill [pTerms] 
17570 77 69 74 68 20 6e 65 77 20 64 6f 63 6c 69 73 74  with new doclist
17580 73 20 66 6f 72 20 74 68 65 0a 20 2a 20 25 5f 74  s for the. * %_t
17590 65 72 6d 20 74 61 62 6c 65 2e 20 2a 2f 0a 73 74  erm table. */.st
175a0 61 74 69 63 20 69 6e 74 20 69 6e 64 65 78 5f 75  atic int index_u
175b0 70 64 61 74 65 28 66 75 6c 6c 74 65 78 74 5f 76  pdate(fulltext_v
175c0 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f 69  tab *v, sqlite_i
175d0 6e 74 36 34 20 69 52 6f 77 2c 0a 20 20 20 20 20  nt64 iRow,.     
175e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
175f0 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65     sqlite3_value
17600 20 2a 2a 70 56 61 6c 75 65 73 2c 20 66 74 73 31   **pValues, fts1
17610 48 61 73 68 20 2a 70 54 65 72 6d 73 29 7b 0a 20  Hash *pTerms){. 
17620 20 2f 2a 20 47 65 6e 65 72 61 74 65 20 61 6e 20   /* Generate an 
17630 65 6d 70 74 79 20 64 6f 63 6c 69 73 74 20 66 6f  empty doclist fo
17640 72 20 65 61 63 68 20 74 65 72 6d 20 74 68 61 74  r each term that
17650 20 70 72 65 76 69 6f 75 73 6c 79 20 61 70 70 65   previously appe
17660 61 72 65 64 20 69 6e 20 74 68 69 73 0a 20 20 20  ared in this.   
17670 2a 20 72 6f 77 2e 20 2a 2f 0a 20 20 69 6e 74 20  * row. */.  int 
17680 72 63 20 3d 20 64 65 6c 65 74 65 54 65 72 6d 73  rc = deleteTerms
17690 28 76 2c 20 70 54 65 72 6d 73 2c 20 69 52 6f 77  (v, pTerms, iRow
176a0 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
176b0 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
176c0 72 63 3b 0a 0a 20 20 72 63 20 3d 20 63 6f 6e 74  rc;..  rc = cont
176d0 65 6e 74 5f 75 70 64 61 74 65 28 76 2c 20 70 56  ent_update(v, pV
176e0 61 6c 75 65 73 2c 20 69 52 6f 77 29 3b 20 20 2f  alues, iRow);  /
176f0 2a 20 65 78 65 63 75 74 65 20 61 6e 20 53 51 4c  * execute an SQL
17700 20 55 50 44 41 54 45 20 2a 2f 0a 20 20 69 66 28   UPDATE */.  if(
17710 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
17720 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 2f   return rc;..  /
17730 2a 20 4e 6f 77 20 61 64 64 20 70 6f 73 69 74 69  * Now add positi
17740 6f 6e 73 20 66 6f 72 20 74 65 72 6d 73 20 77 68  ons for terms wh
17750 69 63 68 20 61 70 70 65 61 72 20 69 6e 20 74 68  ich appear in th
17760 65 20 75 70 64 61 74 65 64 20 72 6f 77 2e 20 2a  e updated row. *
17770 2f 0a 20 20 72 65 74 75 72 6e 20 69 6e 73 65 72  /.  return inser
17780 74 54 65 72 6d 73 28 76 2c 20 70 54 65 72 6d 73  tTerms(v, pTerms
17790 2c 20 69 52 6f 77 2c 20 70 56 61 6c 75 65 73 29  , iRow, pValues)
177a0 3b 0a 7d 0a 0a 2f 2a 20 54 68 69 73 20 66 75 6e  ;.}../* This fun
177b0 63 74 69 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74 73  ction implements
177c0 20 74 68 65 20 78 55 70 64 61 74 65 20 63 61 6c   the xUpdate cal
177d0 6c 62 61 63 6b 3b 20 69 74 20 69 73 20 74 68 65  lback; it is the
177e0 20 74 6f 70 2d 6c 65 76 65 6c 20 65 6e 74 72 79   top-level entry
177f0 0a 20 2a 20 70 6f 69 6e 74 20 66 6f 72 20 69 6e  . * point for in
17800 73 65 72 74 69 6e 67 2c 20 64 65 6c 65 74 69 6e  serting, deletin
17810 67 20 6f 72 20 75 70 64 61 74 69 6e 67 20 61 20  g or updating a 
17820 72 6f 77 20 69 6e 20 61 20 66 75 6c 6c 2d 74 65  row in a full-te
17830 78 74 20 74 61 62 6c 65 2e 20 2a 2f 0a 73 74 61  xt table. */.sta
17840 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74  tic int fulltext
17850 55 70 64 61 74 65 28 73 71 6c 69 74 65 33 5f 76  Update(sqlite3_v
17860 74 61 62 20 2a 70 56 74 61 62 2c 20 69 6e 74 20  tab *pVtab, int 
17870 6e 41 72 67 2c 20 73 71 6c 69 74 65 33 5f 76 61  nArg, sqlite3_va
17880 6c 75 65 20 2a 2a 70 70 41 72 67 2c 0a 20 20 20  lue **ppArg,.   
17890 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
178a0 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52  sqlite_int64 *pR
178b0 6f 77 69 64 29 7b 0a 20 20 66 75 6c 6c 74 65 78  owid){.  fulltex
178c0 74 5f 76 74 61 62 20 2a 76 20 3d 20 28 66 75 6c  t_vtab *v = (ful
178d0 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 20 70 56  ltext_vtab *) pV
178e0 74 61 62 3b 0a 20 20 66 74 73 31 48 61 73 68 20  tab;.  fts1Hash 
178f0 74 65 72 6d 73 3b 20 20 20 2f 2a 20 6d 61 70 73  terms;   /* maps
17900 20 74 65 72 6d 20 73 74 72 69 6e 67 20 2d 3e 20   term string -> 
17910 50 6f 73 4c 69 73 74 20 2a 2f 0a 20 20 69 6e 74  PosList */.  int
17920 20 72 63 3b 0a 20 20 66 74 73 31 48 61 73 68 45   rc;.  fts1HashE
17930 6c 65 6d 20 2a 65 3b 0a 0a 20 20 54 52 41 43 45  lem *e;..  TRACE
17940 28 28 22 46 54 53 31 20 55 70 64 61 74 65 20 25  (("FTS1 Update %
17950 70 5c 6e 22 2c 20 70 56 74 61 62 29 29 3b 0a 20  p\n", pVtab));. 
17960 20 0a 20 20 66 74 73 31 48 61 73 68 49 6e 69 74   .  fts1HashInit
17970 28 26 74 65 72 6d 73 2c 20 46 54 53 31 5f 48 41  (&terms, FTS1_HA
17980 53 48 5f 53 54 52 49 4e 47 2c 20 31 29 3b 0a 0a  SH_STRING, 1);..
17990 20 20 69 66 28 20 6e 41 72 67 3c 32 20 29 7b 0a    if( nArg<2 ){.
179a0 20 20 20 20 72 63 20 3d 20 69 6e 64 65 78 5f 64      rc = index_d
179b0 65 6c 65 74 65 28 76 2c 20 73 71 6c 69 74 65 33  elete(v, sqlite3
179c0 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 70 70 41  _value_int64(ppA
179d0 72 67 5b 30 5d 29 2c 20 26 74 65 72 6d 73 29 3b  rg[0]), &terms);
179e0 0a 20 20 7d 20 65 6c 73 65 20 69 66 28 20 73 71  .  } else if( sq
179f0 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
17a00 28 70 70 41 72 67 5b 30 5d 29 20 21 3d 20 53 51  (ppArg[0]) != SQ
17a10 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20  LITE_NULL ){.   
17a20 20 2f 2a 20 41 6e 20 75 70 64 61 74 65 3a 0a 20   /* An update:. 
17a30 20 20 20 20 2a 20 70 70 41 72 67 5b 30 5d 20 3d      * ppArg[0] =
17a40 20 6f 6c 64 20 72 6f 77 69 64 0a 20 20 20 20 20   old rowid.     
17a50 2a 20 70 70 41 72 67 5b 31 5d 20 3d 20 6e 65 77  * ppArg[1] = new
17a60 20 72 6f 77 69 64 0a 20 20 20 20 20 2a 20 70 70   rowid.     * pp
17a70 41 72 67 5b 32 2e 2e 32 2b 76 2d 3e 6e 43 6f 6c  Arg[2..2+v->nCol
17a80 75 6d 6e 2d 31 5d 20 3d 20 76 61 6c 75 65 73 0a  umn-1] = values.
17a90 20 20 20 20 20 2a 20 70 70 41 72 67 5b 32 2b 76       * ppArg[2+v
17aa0 2d 3e 6e 43 6f 6c 75 6d 6e 5d 20 3d 20 76 61 6c  ->nColumn] = val
17ab0 75 65 20 66 6f 72 20 6d 61 67 69 63 20 63 6f 6c  ue for magic col
17ac0 75 6d 6e 20 28 77 65 20 69 67 6e 6f 72 65 20 74  umn (we ignore t
17ad0 68 69 73 29 0a 20 20 20 20 20 2a 2f 0a 20 20 20  his).     */.   
17ae0 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 72 6f   sqlite_int64 ro
17af0 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 76 61  wid = sqlite3_va
17b00 6c 75 65 5f 69 6e 74 36 34 28 70 70 41 72 67 5b  lue_int64(ppArg[
17b10 30 5d 29 3b 0a 20 20 20 20 69 66 28 20 73 71 6c  0]);.    if( sql
17b20 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
17b30 70 70 41 72 67 5b 31 5d 29 20 21 3d 20 53 51 4c  ppArg[1]) != SQL
17b40 49 54 45 5f 49 4e 54 45 47 45 52 20 7c 7c 0a 20  ITE_INTEGER ||. 
17b50 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c       sqlite3_val
17b60 75 65 5f 69 6e 74 36 34 28 70 70 41 72 67 5b 31  ue_int64(ppArg[1
17b70 5d 29 20 21 3d 20 72 6f 77 69 64 20 29 7b 0a 20  ]) != rowid ){. 
17b80 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
17b90 5f 45 52 52 4f 52 3b 20 20 2f 2a 20 77 65 20 64  _ERROR;  /* we d
17ba0 6f 6e 27 74 20 61 6c 6c 6f 77 20 63 68 61 6e 67  on't allow chang
17bb0 69 6e 67 20 74 68 65 20 72 6f 77 69 64 20 2a 2f  ing the rowid */
17bc0 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
17bd0 20 20 20 20 61 73 73 65 72 74 28 20 6e 41 72 67      assert( nArg
17be0 3d 3d 32 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e 2b 31  ==2+v->nColumn+1
17bf0 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 69 6e  );.      rc = in
17c00 64 65 78 5f 75 70 64 61 74 65 28 76 2c 20 72 6f  dex_update(v, ro
17c10 77 69 64 2c 20 26 70 70 41 72 67 5b 32 5d 2c 20  wid, &ppArg[2], 
17c20 26 74 65 72 6d 73 29 3b 0a 20 20 20 20 7d 0a 20  &terms);.    }. 
17c30 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 2f 2a   } else {.    /*
17c40 20 41 6e 20 69 6e 73 65 72 74 3a 0a 20 20 20 20   An insert:.    
17c50 20 2a 20 70 70 41 72 67 5b 31 5d 20 3d 20 72 65   * ppArg[1] = re
17c60 71 75 65 73 74 65 64 20 72 6f 77 69 64 0a 20 20  quested rowid.  
17c70 20 20 20 2a 20 70 70 41 72 67 5b 32 2e 2e 32 2b     * ppArg[2..2+
17c80 76 2d 3e 6e 43 6f 6c 75 6d 6e 2d 31 5d 20 3d 20  v->nColumn-1] = 
17c90 76 61 6c 75 65 73 0a 20 20 20 20 20 2a 20 70 70  values.     * pp
17ca0 41 72 67 5b 32 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e  Arg[2+v->nColumn
17cb0 5d 20 3d 20 76 61 6c 75 65 20 66 6f 72 20 6d 61  ] = value for ma
17cc0 67 69 63 20 63 6f 6c 75 6d 6e 20 28 77 65 20 69  gic column (we i
17cd0 67 6e 6f 72 65 20 74 68 69 73 29 0a 20 20 20 20  gnore this).    
17ce0 20 2a 2f 0a 20 20 20 20 61 73 73 65 72 74 28 20   */.    assert( 
17cf0 6e 41 72 67 3d 3d 32 2b 76 2d 3e 6e 43 6f 6c 75  nArg==2+v->nColu
17d00 6d 6e 2b 31 29 3b 0a 20 20 20 20 72 63 20 3d 20  mn+1);.    rc = 
17d10 69 6e 64 65 78 5f 69 6e 73 65 72 74 28 76 2c 20  index_insert(v, 
17d20 70 70 41 72 67 5b 31 5d 2c 20 26 70 70 41 72 67  ppArg[1], &ppArg
17d30 5b 32 5d 2c 20 70 52 6f 77 69 64 2c 20 26 74 65  [2], pRowid, &te
17d40 72 6d 73 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  rms);.  }..  if(
17d50 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
17d60 7b 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20 75  {.    /* Write u
17d70 70 64 61 74 65 64 20 64 6f 63 6c 69 73 74 73 20  pdated doclists 
17d80 74 6f 20 64 69 73 6b 2e 20 2a 2f 0a 20 20 20 20  to disk. */.    
17d90 66 6f 72 28 65 3d 66 74 73 31 48 61 73 68 46 69  for(e=fts1HashFi
17da0 72 73 74 28 26 74 65 72 6d 73 29 3b 20 65 3b 20  rst(&terms); e; 
17db0 65 3d 66 74 73 31 48 61 73 68 4e 65 78 74 28 65  e=fts1HashNext(e
17dc0 29 29 7b 0a 20 20 20 20 20 20 44 6f 63 4c 69 73  )){.      DocLis
17dd0 74 20 2a 70 20 3d 20 66 74 73 31 48 61 73 68 44  t *p = fts1HashD
17de0 61 74 61 28 65 29 3b 0a 20 20 20 20 20 20 72 63  ata(e);.      rc
17df0 20 3d 20 69 6e 64 65 78 5f 69 6e 73 65 72 74 5f   = index_insert_
17e00 74 65 72 6d 28 76 2c 20 66 74 73 31 48 61 73 68  term(v, fts1Hash
17e10 4b 65 79 28 65 29 2c 20 66 74 73 31 48 61 73 68  Key(e), fts1Hash
17e20 4b 65 79 73 69 7a 65 28 65 29 2c 20 70 29 3b 0a  Keysize(e), p);.
17e30 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
17e40 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b  LITE_OK ) break;
17e50 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
17e60 20 63 6c 65 61 6e 20 75 70 20 2a 2f 0a 20 20 66   clean up */.  f
17e70 6f 72 28 65 3d 66 74 73 31 48 61 73 68 46 69 72  or(e=fts1HashFir
17e80 73 74 28 26 74 65 72 6d 73 29 3b 20 65 3b 20 65  st(&terms); e; e
17e90 3d 66 74 73 31 48 61 73 68 4e 65 78 74 28 65 29  =fts1HashNext(e)
17ea0 29 7b 0a 20 20 20 20 44 6f 63 4c 69 73 74 20 2a  ){.    DocList *
17eb0 70 20 3d 20 66 74 73 31 48 61 73 68 44 61 74 61  p = fts1HashData
17ec0 28 65 29 3b 0a 20 20 20 20 64 6f 63 4c 69 73 74  (e);.    docList
17ed0 44 65 6c 65 74 65 28 70 29 3b 0a 20 20 7d 0a 20  Delete(p);.  }. 
17ee0 20 66 74 73 31 48 61 73 68 43 6c 65 61 72 28 26   fts1HashClear(&
17ef0 74 65 72 6d 73 29 3b 0a 0a 20 20 72 65 74 75 72  terms);..  retur
17f00 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  n rc;.}../*.** I
17f10 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
17f20 20 74 68 65 20 73 6e 69 70 70 65 74 28 29 20 66   the snippet() f
17f30 75 6e 63 74 69 6f 6e 20 66 6f 72 20 46 54 53 31  unction for FTS1
17f40 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
17f50 73 6e 69 70 70 65 74 46 75 6e 63 28 0a 20 20 73  snippetFunc(.  s
17f60 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
17f70 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20  pContext,.  int 
17f80 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argc,.  sqlite3_
17f90 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a  value **argv.){.
17fa0 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f    fulltext_curso
17fb0 72 20 2a 70 43 75 72 73 6f 72 3b 0a 20 20 69 66  r *pCursor;.  if
17fc0 28 20 61 72 67 63 3c 31 20 29 20 72 65 74 75 72  ( argc<1 ) retur
17fd0 6e 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33  n;.  if( sqlite3
17fe0 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 72 67 76  _value_type(argv
17ff0 5b 30 5d 29 21 3d 53 51 4c 49 54 45 5f 42 4c 4f  [0])!=SQLITE_BLO
18000 42 20 7c 7c 0a 20 20 20 20 20 20 73 71 6c 69 74  B ||.      sqlit
18010 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61  e3_value_bytes(a
18020 72 67 76 5b 30 5d 29 21 3d 73 69 7a 65 6f 66 28  rgv[0])!=sizeof(
18030 70 43 75 72 73 6f 72 29 20 29 7b 0a 20 20 20 20  pCursor) ){.    
18040 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65  sqlite3_result_e
18050 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 22  rror(pContext, "
18060 69 6c 6c 65 67 61 6c 20 66 69 72 73 74 20 61 72  illegal first ar
18070 67 75 6d 65 6e 74 20 74 6f 20 68 74 6d 6c 5f 73  gument to html_s
18080 6e 69 70 70 65 74 22 2c 2d 31 29 3b 0a 20 20 7d  nippet",-1);.  }
18090 65 6c 73 65 7b 0a 20 20 20 20 63 6f 6e 73 74 20  else{.    const 
180a0 63 68 61 72 20 2a 7a 53 74 61 72 74 20 3d 20 22  char *zStart = "
180b0 3c 62 3e 22 3b 0a 20 20 20 20 63 6f 6e 73 74 20  <b>";.    const 
180c0 63 68 61 72 20 2a 7a 45 6e 64 20 3d 20 22 3c 2f  char *zEnd = "</
180d0 62 3e 22 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63  b>";.    const c
180e0 68 61 72 20 2a 7a 45 6c 6c 69 70 73 69 73 20 3d  har *zEllipsis =
180f0 20 22 3c 62 3e 2e 2e 2e 3c 2f 62 3e 22 3b 0a 20   "<b>...</b>";. 
18100 20 20 20 6d 65 6d 63 70 79 28 26 70 43 75 72 73     memcpy(&pCurs
18110 6f 72 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  or, sqlite3_valu
18120 65 5f 62 6c 6f 62 28 61 72 67 76 5b 30 5d 29 2c  e_blob(argv[0]),
18130 20 73 69 7a 65 6f 66 28 70 43 75 72 73 6f 72 29   sizeof(pCursor)
18140 29 3b 0a 20 20 20 20 69 66 28 20 61 72 67 63 3e  );.    if( argc>
18150 3d 32 20 29 7b 0a 20 20 20 20 20 20 7a 53 74 61  =2 ){.      zSta
18160 72 74 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72  rt = (const char
18170 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  *)sqlite3_value_
18180 74 65 78 74 28 61 72 67 76 5b 31 5d 29 3b 0a 20  text(argv[1]);. 
18190 20 20 20 20 20 69 66 28 20 61 72 67 63 3e 3d 33       if( argc>=3
181a0 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 45 6e 64   ){.        zEnd
181b0 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29   = (const char*)
181c0 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
181d0 78 74 28 61 72 67 76 5b 32 5d 29 3b 0a 20 20 20  xt(argv[2]);.   
181e0 20 20 20 20 20 69 66 28 20 61 72 67 63 3e 3d 34       if( argc>=4
181f0 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 45   ){.          zE
18200 6c 6c 69 70 73 69 73 20 3d 20 28 63 6f 6e 73 74  llipsis = (const
18210 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76   char*)sqlite3_v
18220 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 33  alue_text(argv[3
18230 5d 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  ]);.        }.  
18240 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
18250 73 6e 69 70 70 65 74 41 6c 6c 4f 66 66 73 65 74  snippetAllOffset
18260 73 28 70 43 75 72 73 6f 72 29 3b 0a 20 20 20 20  s(pCursor);.    
18270 73 6e 69 70 70 65 74 54 65 78 74 28 70 43 75 72  snippetText(pCur
18280 73 6f 72 2c 20 7a 53 74 61 72 74 2c 20 7a 45 6e  sor, zStart, zEn
18290 64 2c 20 7a 45 6c 6c 69 70 73 69 73 29 3b 0a 20  d, zEllipsis);. 
182a0 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
182b0 74 5f 74 65 78 74 28 70 43 6f 6e 74 65 78 74 2c  t_text(pContext,
182c0 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65   pCursor->snippe
182d0 74 2e 7a 53 6e 69 70 70 65 74 2c 0a 20 20 20 20  t.zSnippet,.    
182e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
182f0 20 20 20 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69      pCursor->sni
18300 70 70 65 74 2e 6e 53 6e 69 70 70 65 74 2c 20 53  ppet.nSnippet, S
18310 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20  QLITE_STATIC);. 
18320 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c   }.}../*.** Impl
18330 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
18340 65 20 6f 66 66 73 65 74 73 28 29 20 66 75 6e 63  e offsets() func
18350 74 69 6f 6e 20 66 6f 72 20 46 54 53 31 0a 2a 2f  tion for FTS1.*/
18360 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 6e 69  .static void sni
18370 70 70 65 74 4f 66 66 73 65 74 73 46 75 6e 63 28  ppetOffsetsFunc(
18380 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65  .  sqlite3_conte
18390 78 74 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20  xt *pContext,.  
183a0 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69  int argc,.  sqli
183b0 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76  te3_value **argv
183c0 0a 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63  .){.  fulltext_c
183d0 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 3b 0a  ursor *pCursor;.
183e0 20 20 69 66 28 20 61 72 67 63 3c 31 20 29 20 72    if( argc<1 ) r
183f0 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 73 71 6c  eturn;.  if( sql
18400 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
18410 61 72 67 76 5b 30 5d 29 21 3d 53 51 4c 49 54 45  argv[0])!=SQLITE
18420 5f 42 4c 4f 42 20 7c 7c 0a 20 20 20 20 20 20 73  _BLOB ||.      s
18430 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74  qlite3_value_byt
18440 65 73 28 61 72 67 76 5b 30 5d 29 21 3d 73 69 7a  es(argv[0])!=siz
18450 65 6f 66 28 70 43 75 72 73 6f 72 29 20 29 7b 0a  eof(pCursor) ){.
18460 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
18470 6c 74 5f 65 72 72 6f 72 28 70 43 6f 6e 74 65 78  lt_error(pContex
18480 74 2c 20 22 69 6c 6c 65 67 61 6c 20 66 69 72 73  t, "illegal firs
18490 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 6f 66  t argument to of
184a0 66 73 65 74 73 22 2c 2d 31 29 3b 0a 20 20 7d 65  fsets",-1);.  }e
184b0 6c 73 65 7b 0a 20 20 20 20 6d 65 6d 63 70 79 28  lse{.    memcpy(
184c0 26 70 43 75 72 73 6f 72 2c 20 73 71 6c 69 74 65  &pCursor, sqlite
184d0 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 61 72 67  3_value_blob(arg
184e0 76 5b 30 5d 29 2c 20 73 69 7a 65 6f 66 28 70 43  v[0]), sizeof(pC
184f0 75 72 73 6f 72 29 29 3b 0a 20 20 20 20 73 6e 69  ursor));.    sni
18500 70 70 65 74 41 6c 6c 4f 66 66 73 65 74 73 28 70  ppetAllOffsets(p
18510 43 75 72 73 6f 72 29 3b 0a 20 20 20 20 73 6e 69  Cursor);.    sni
18520 70 70 65 74 4f 66 66 73 65 74 54 65 78 74 28 26  ppetOffsetText(&
18530 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74  pCursor->snippet
18540 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  );.    sqlite3_r
18550 65 73 75 6c 74 5f 74 65 78 74 28 70 43 6f 6e 74  esult_text(pCont
18560 65 78 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ext,.           
18570 20 20 20 20 20 20 20 20 20 20 20 20 20 70 43 75               pCu
18580 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74 2e 7a 4f  rsor->snippet.zO
18590 66 66 73 65 74 2c 20 70 43 75 72 73 6f 72 2d 3e  ffset, pCursor->
185a0 73 6e 69 70 70 65 74 2e 6e 4f 66 66 73 65 74 2c  snippet.nOffset,
185b0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
185c0 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
185d0 53 54 41 54 49 43 29 3b 0a 20 20 7d 0a 7d 0a 0a  STATIC);.  }.}..
185e0 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  /*.** This routi
185f0 6e 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68  ne implements th
18600 65 20 78 46 69 6e 64 46 75 6e 63 74 69 6f 6e 20  e xFindFunction 
18610 6d 65 74 68 6f 64 20 66 6f 72 20 74 68 65 20 46  method for the F
18620 54 53 31 0a 2a 2a 20 76 69 72 74 75 61 6c 20 74  TS1.** virtual t
18630 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  able..*/.static 
18640 69 6e 74 20 66 75 6c 6c 74 65 78 74 46 69 6e 64  int fulltextFind
18650 46 75 6e 63 74 69 6f 6e 28 0a 20 20 73 71 6c 69  Function(.  sqli
18660 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c  te3_vtab *pVtab,
18670 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20 63  .  int nArg,.  c
18680 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
18690 2c 0a 20 20 76 6f 69 64 20 28 2a 2a 70 78 46 75  ,.  void (**pxFu
186a0 6e 63 29 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74  nc)(sqlite3_cont
186b0 65 78 74 2a 2c 69 6e 74 2c 73 71 6c 69 74 65 33  ext*,int,sqlite3
186c0 5f 76 61 6c 75 65 2a 2a 29 2c 0a 20 20 76 6f 69  _value**),.  voi
186d0 64 20 2a 2a 70 70 41 72 67 0a 29 7b 0a 20 20 69  d **ppArg.){.  i
186e0 66 28 20 73 74 72 63 6d 70 28 7a 4e 61 6d 65 2c  f( strcmp(zName,
186f0 22 73 6e 69 70 70 65 74 22 29 3d 3d 30 20 29 7b  "snippet")==0 ){
18700 0a 20 20 20 20 2a 70 78 46 75 6e 63 20 3d 20 73  .    *pxFunc = s
18710 6e 69 70 70 65 74 46 75 6e 63 3b 0a 20 20 20 20  nippetFunc;.    
18720 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 65 6c 73  return 1;.  }els
18730 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 4e 61  e if( strcmp(zNa
18740 6d 65 2c 22 6f 66 66 73 65 74 73 22 29 3d 3d 30  me,"offsets")==0
18750 20 29 7b 0a 20 20 20 20 2a 70 78 46 75 6e 63 20   ){.    *pxFunc 
18760 3d 20 73 6e 69 70 70 65 74 4f 66 66 73 65 74 73  = snippetOffsets
18770 46 75 6e 63 3b 0a 20 20 20 20 72 65 74 75 72 6e  Func;.    return
18780 20 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   1;.  }.  return
18790 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6e   0;.}../*.** Ren
187a0 61 6d 65 20 61 6e 20 66 74 73 31 20 74 61 62 6c  ame an fts1 tabl
187b0 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
187c0 20 66 75 6c 6c 74 65 78 74 52 65 6e 61 6d 65 28   fulltextRename(
187d0 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
187e0 2a 70 56 74 61 62 2c 0a 20 20 63 6f 6e 73 74 20  *pVtab,.  const 
187f0 63 68 61 72 20 2a 7a 4e 61 6d 65 0a 29 7b 0a 20  char *zName.){. 
18800 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a   fulltext_vtab *
18810 70 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f 76 74  p = (fulltext_vt
18820 61 62 20 2a 29 70 56 74 61 62 3b 0a 20 20 69 6e  ab *)pVtab;.  in
18830 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f  t rc = SQLITE_NO
18840 4d 45 4d 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71  MEM;.  char *zSq
18850 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  l = sqlite3_mpri
18860 6e 74 66 28 0a 20 20 20 20 22 41 4c 54 45 52 20  ntf(.    "ALTER 
18870 54 41 42 4c 45 20 25 51 2e 27 25 71 5f 63 6f 6e  TABLE %Q.'%q_con
18880 74 65 6e 74 27 20 20 52 45 4e 41 4d 45 20 54 4f  tent'  RENAME TO
18890 20 27 25 71 5f 63 6f 6e 74 65 6e 74 27 3b 22 0a   '%q_content';".
188a0 20 20 20 20 22 41 4c 54 45 52 20 54 41 42 4c 45      "ALTER TABLE
188b0 20 25 51 2e 27 25 71 5f 74 65 72 6d 27 20 52 45   %Q.'%q_term' RE
188c0 4e 41 4d 45 20 54 4f 20 27 25 71 5f 74 65 72 6d  NAME TO '%q_term
188d0 27 3b 22 0a 20 20 20 20 2c 20 70 2d 3e 7a 44 62  ';".    , p->zDb
188e0 2c 20 70 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d  , p->zName, zNam
188f0 65 0a 20 20 20 20 2c 20 70 2d 3e 7a 44 62 2c 20  e.    , p->zDb, 
18900 70 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 0a  p->zName, zName.
18910 20 20 29 3b 0a 20 20 69 66 28 20 7a 53 71 6c 20    );.  if( zSql 
18920 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
18930 74 65 33 5f 65 78 65 63 28 70 2d 3e 64 62 2c 20  te3_exec(p->db, 
18940 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a  zSql, 0, 0, 0);.
18950 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
18960 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 20 20 72 65  (zSql);.  }.  re
18970 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
18980 69 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33  ic const sqlite3
18990 5f 6d 6f 64 75 6c 65 20 66 75 6c 6c 74 65 78 74  _module fulltext
189a0 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 2f 2a 20  Module = {.  /* 
189b0 69 56 65 72 73 69 6f 6e 20 20 20 20 20 20 2a 2f  iVersion      */
189c0 20 30 2c 0a 20 20 2f 2a 20 78 43 72 65 61 74 65   0,.  /* xCreate
189d0 20 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65         */ fullte
189e0 78 74 43 72 65 61 74 65 2c 0a 20 20 2f 2a 20 78  xtCreate,.  /* x
189f0 43 6f 6e 6e 65 63 74 20 20 20 20 20 20 2a 2f 20  Connect      */ 
18a00 66 75 6c 6c 74 65 78 74 43 6f 6e 6e 65 63 74 2c  fulltextConnect,
18a10 0a 20 20 2f 2a 20 78 42 65 73 74 49 6e 64 65 78  .  /* xBestIndex
18a20 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74 42      */ fulltextB
18a30 65 73 74 49 6e 64 65 78 2c 0a 20 20 2f 2a 20 78  estIndex,.  /* x
18a40 44 69 73 63 6f 6e 6e 65 63 74 20 20 20 2a 2f 20  Disconnect   */ 
18a50 66 75 6c 6c 74 65 78 74 44 69 73 63 6f 6e 6e 65  fulltextDisconne
18a60 63 74 2c 0a 20 20 2f 2a 20 78 44 65 73 74 72 6f  ct,.  /* xDestro
18a70 79 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65  y      */ fullte
18a80 78 74 44 65 73 74 72 6f 79 2c 0a 20 20 2f 2a 20  xtDestroy,.  /* 
18a90 78 4f 70 65 6e 20 20 20 20 20 20 20 20 20 2a 2f  xOpen         */
18aa0 20 66 75 6c 6c 74 65 78 74 4f 70 65 6e 2c 0a 20   fulltextOpen,. 
18ab0 20 2f 2a 20 78 43 6c 6f 73 65 20 20 20 20 20 20   /* xClose      
18ac0 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74 43 6c 6f    */ fulltextClo
18ad0 73 65 2c 0a 20 20 2f 2a 20 78 46 69 6c 74 65 72  se,.  /* xFilter
18ae0 20 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65         */ fullte
18af0 78 74 46 69 6c 74 65 72 2c 0a 20 20 2f 2a 20 78  xtFilter,.  /* x
18b00 4e 65 78 74 20 20 20 20 20 20 20 20 20 2a 2f 20  Next         */ 
18b10 66 75 6c 6c 74 65 78 74 4e 65 78 74 2c 0a 20 20  fulltextNext,.  
18b20 2f 2a 20 78 45 6f 66 20 20 20 20 20 20 20 20 20  /* xEof         
18b30 20 2a 2f 20 66 75 6c 6c 74 65 78 74 45 6f 66 2c   */ fulltextEof,
18b40 0a 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20 20 20  .  /* xColumn   
18b50 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74 43      */ fulltextC
18b60 6f 6c 75 6d 6e 2c 0a 20 20 2f 2a 20 78 52 6f 77  olumn,.  /* xRow
18b70 69 64 20 20 20 20 20 20 20 20 2a 2f 20 66 75 6c  id        */ ful
18b80 6c 74 65 78 74 52 6f 77 69 64 2c 0a 20 20 2f 2a  ltextRowid,.  /*
18b90 20 78 55 70 64 61 74 65 20 20 20 20 20 20 20 2a   xUpdate       *
18ba0 2f 20 66 75 6c 6c 74 65 78 74 55 70 64 61 74 65  / fulltextUpdate
18bb0 2c 0a 20 20 2f 2a 20 78 42 65 67 69 6e 20 20 20  ,.  /* xBegin   
18bc0 20 20 20 20 20 2a 2f 20 30 2c 20 0a 20 20 2f 2a       */ 0, .  /*
18bd0 20 78 53 79 6e 63 20 20 20 20 20 20 20 20 20 2a   xSync         *
18be0 2f 20 30 2c 0a 20 20 2f 2a 20 78 43 6f 6d 6d 69  / 0,.  /* xCommi
18bf0 74 20 20 20 20 20 20 20 2a 2f 20 30 2c 0a 20 20  t       */ 0,.  
18c00 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 20 20 20  /* xRollback    
18c10 20 2a 2f 20 30 2c 0a 20 20 2f 2a 20 78 46 69 6e   */ 0,.  /* xFin
18c20 64 46 75 6e 63 74 69 6f 6e 20 2a 2f 20 66 75 6c  dFunction */ ful
18c30 6c 74 65 78 74 46 69 6e 64 46 75 6e 63 74 69 6f  ltextFindFunctio
18c40 6e 2c 0a 20 20 2f 2a 20 78 52 65 6e 61 6d 65 20  n,.  /* xRename 
18c50 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65 78        */ fulltex
18c60 74 52 65 6e 61 6d 65 2c 0a 7d 3b 0a 0a 69 6e 74  tRename,.};..int
18c70 20 73 71 6c 69 74 65 33 46 74 73 31 49 6e 69 74   sqlite3Fts1Init
18c80 28 73 71 6c 69 74 65 33 20 2a 64 62 29 7b 0a 20  (sqlite3 *db){. 
18c90 20 73 71 6c 69 74 65 33 5f 6f 76 65 72 6c 6f 61   sqlite3_overloa
18ca0 64 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20 22  d_function(db, "
18cb0 73 6e 69 70 70 65 74 22 2c 20 2d 31 29 3b 0a 20  snippet", -1);. 
18cc0 20 73 71 6c 69 74 65 33 5f 6f 76 65 72 6c 6f 61   sqlite3_overloa
18cd0 64 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20 22  d_function(db, "
18ce0 6f 66 66 73 65 74 73 22 2c 20 2d 31 29 3b 0a 20  offsets", -1);. 
18cf0 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 5f   return sqlite3_
18d00 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 64 62  create_module(db
18d10 2c 20 22 66 74 73 31 22 2c 20 26 66 75 6c 6c 74  , "fts1", &fullt
18d20 65 78 74 4d 6f 64 75 6c 65 2c 20 30 29 3b 0a 7d  extModule, 0);.}
18d30 0a 0a 23 69 66 20 21 53 51 4c 49 54 45 5f 43 4f  ..#if !SQLITE_CO
18d40 52 45 0a 23 69 66 64 65 66 20 5f 57 49 4e 33 32  RE.#ifdef _WIN32
18d50 0a 5f 5f 64 65 63 6c 73 70 65 63 28 64 6c 6c 65  .__declspec(dlle
18d60 78 70 6f 72 74 29 0a 23 65 6e 64 69 66 0a 69 6e  xport).#endif.in
18d70 74 20 73 71 6c 69 74 65 33 5f 66 74 73 31 5f 69  t sqlite3_fts1_i
18d80 6e 69 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  nit(sqlite3 *db,
18d90 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 4d 73 67   char **pzErrMsg
18da0 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
18db0 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 73 71          const sq
18dc0 6c 69 74 65 33 5f 61 70 69 5f 72 6f 75 74 69 6e  lite3_api_routin
18dd0 65 73 20 2a 70 41 70 69 29 7b 0a 20 20 53 51 4c  es *pApi){.  SQL
18de0 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e 5f 49 4e  ITE_EXTENSION_IN
18df0 49 54 32 28 70 41 70 69 29 0a 20 20 72 65 74 75  IT2(pApi).  retu
18e00 72 6e 20 73 71 6c 69 74 65 33 46 74 73 31 49 6e  rn sqlite3Fts1In
18e10 69 74 28 64 62 29 3b 0a 7d 0a 23 65 6e 64 69 66  it(db);.}.#endif
18e20 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 21 64 65 66  ..#endif /* !def
18e30 69 6e 65 64 28 53 51 4c 49 54 45 5f 43 4f 52 45  ined(SQLITE_CORE
18e40 29 20 7c 7c 20 64 65 66 69 6e 65 64 28 53 51 4c  ) || defined(SQL
18e50 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53 31 29  ITE_ENABLE_FTS1)
18e60 20 2a 2f 0a                                       */.