/ Hex Artifact Content
Login

Artifact f7739dc37500a613cc0dab8fc04d1b5577d02998:


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 63 29 20 3a 20 30  ? isspace(c) : 0
19d0: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 73  ;.}.static int s
19e0: 61 66 65 5f 74 6f 6c 6f 77 65 72 28 63 68 61 72  afe_tolower(char
19f0: 20 63 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 63   c){.  return (c
1a00: 26 30 78 38 30 29 3d 3d 30 20 3f 20 74 6f 6c 6f  &0x80)==0 ? tolo
1a10: 77 65 72 28 63 29 20 3a 20 63 3b 0a 7d 0a 73 74  wer(c) : c;.}.st
1a20: 61 74 69 63 20 69 6e 74 20 73 61 66 65 5f 69 73  atic int safe_is
1a30: 61 6c 6e 75 6d 28 63 68 61 72 20 63 29 7b 0a 20  alnum(char c){. 
1a40: 20 72 65 74 75 72 6e 20 28 63 26 30 78 38 30 29   return (c&0x80)
1a50: 3d 3d 30 20 3f 20 69 73 61 6c 6e 75 6d 28 63 29  ==0 ? isalnum(c)
1a60: 20 3a 20 30 3b 0a 7d 0a 0a 74 79 70 65 64 65 66   : 0;.}..typedef
1a70: 20 65 6e 75 6d 20 44 6f 63 4c 69 73 74 54 79 70   enum DocListTyp
1a80: 65 20 7b 0a 20 20 44 4c 5f 44 4f 43 49 44 53 2c  e {.  DL_DOCIDS,
1a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1aa0: 20 64 6f 63 69 64 73 20 6f 6e 6c 79 20 2a 2f 0a   docids only */.
1ab0: 20 20 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 2c 20    DL_POSITIONS, 
1ac0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 64 6f 63            /* doc
1ad0: 69 64 73 20 2b 20 70 6f 73 69 74 69 6f 6e 73 20  ids + positions 
1ae0: 2a 2f 0a 20 20 44 4c 5f 50 4f 53 49 54 49 4f 4e  */.  DL_POSITION
1af0: 53 5f 4f 46 46 53 45 54 53 20 20 20 20 2f 2a 20  S_OFFSETS    /* 
1b00: 64 6f 63 69 64 73 20 2b 20 70 6f 73 69 74 69 6f  docids + positio
1b10: 6e 73 20 2b 20 6f 66 66 73 65 74 73 20 2a 2f 0a  ns + offsets */.
1b20: 7d 20 44 6f 63 4c 69 73 74 54 79 70 65 3b 0a 0a  } DocListType;..
1b30: 2f 2a 0a 2a 2a 20 42 79 20 64 65 66 61 75 6c 74  /*.** By default
1b40: 2c 20 6f 6e 6c 79 20 70 6f 73 69 74 69 6f 6e 73  , only positions
1b50: 20 61 6e 64 20 6e 6f 74 20 6f 66 66 73 65 74 73   and not offsets
1b60: 20 61 72 65 20 73 74 6f 72 65 64 20 69 6e 20 74   are stored in t
1b70: 68 65 20 64 6f 63 6c 69 73 74 73 2e 0a 2a 2a 20  he doclists..** 
1b80: 54 6f 20 63 68 61 6e 67 65 20 74 68 69 73 20 73  To change this s
1b90: 6f 20 74 68 61 74 20 6f 66 66 73 65 74 73 20 61  o that offsets a
1ba0: 72 65 20 73 74 6f 72 65 64 20 74 6f 6f 2c 20 63  re stored too, c
1bb0: 6f 6d 70 69 6c 65 20 77 69 74 68 0a 2a 2a 0a 2a  ompile with.**.*
1bc0: 2a 20 20 20 20 20 20 20 20 20 20 2d 44 44 4c 5f  *          -DDL_
1bd0: 44 45 46 41 55 4c 54 3d 44 4c 5f 50 4f 53 49 54  DEFAULT=DL_POSIT
1be0: 49 4f 4e 53 5f 4f 46 46 53 45 54 53 0a 2a 2a 0a  IONS_OFFSETS.**.
1bf0: 2a 2f 0a 23 69 66 6e 64 65 66 20 44 4c 5f 44 45  */.#ifndef DL_DE
1c00: 46 41 55 4c 54 0a 23 20 64 65 66 69 6e 65 20 44  FAULT.# define D
1c10: 4c 5f 44 45 46 41 55 4c 54 20 44 4c 5f 50 4f 53  L_DEFAULT DL_POS
1c20: 49 54 49 4f 4e 53 0a 23 65 6e 64 69 66 0a 0a 74  ITIONS.#endif..t
1c30: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 44 6f  ypedef struct Do
1c40: 63 4c 69 73 74 20 7b 0a 20 20 63 68 61 72 20 2a  cList {.  char *
1c50: 70 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e 44 61  pData;.  int nDa
1c60: 74 61 3b 0a 20 20 44 6f 63 4c 69 73 74 54 79 70  ta;.  DocListTyp
1c70: 65 20 69 54 79 70 65 3b 0a 20 20 69 6e 74 20 69  e iType;.  int i
1c80: 4c 61 73 74 43 6f 6c 75 6d 6e 3b 20 20 20 20 2f  LastColumn;    /
1c90: 2a 20 74 68 65 20 6c 61 73 74 20 63 6f 6c 75 6d  * the last colum
1ca0: 6e 20 77 72 69 74 74 65 6e 20 2a 2f 0a 20 20 69  n written */.  i
1cb0: 6e 74 20 69 4c 61 73 74 50 6f 73 3b 20 20 20 20  nt iLastPos;    
1cc0: 20 20 20 2f 2a 20 74 68 65 20 6c 61 73 74 20 70     /* the last p
1cd0: 6f 73 69 74 69 6f 6e 20 77 72 69 74 74 65 6e 20  osition written 
1ce0: 2a 2f 0a 20 20 69 6e 74 20 69 4c 61 73 74 4f 66  */.  int iLastOf
1cf0: 66 73 65 74 3b 20 20 20 20 2f 2a 20 74 68 65 20  fset;    /* the 
1d00: 6c 61 73 74 20 73 74 61 72 74 20 6f 66 66 73 65  last start offse
1d10: 74 20 77 72 69 74 74 65 6e 20 2a 2f 0a 7d 20 44  t written */.} D
1d20: 6f 63 4c 69 73 74 3b 0a 0a 65 6e 75 6d 20 7b 0a  ocList;..enum {.
1d30: 20 20 50 4f 53 5f 45 4e 44 20 3d 20 30 2c 20 20    POS_END = 0,  
1d40: 20 20 20 20 20 20 2f 2a 20 65 6e 64 20 6f 66 20        /* end of 
1d50: 74 68 69 73 20 70 6f 73 69 74 69 6f 6e 20 6c 69  this position li
1d60: 73 74 20 2a 2f 0a 20 20 50 4f 53 5f 43 4f 4c 55  st */.  POS_COLU
1d70: 4d 4e 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 66  MN,         /* f
1d80: 6f 6c 6c 6f 77 65 64 20 62 79 20 6e 65 77 20 63  ollowed by new c
1d90: 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72 20 2a 2f 0a  olumn number */.
1da0: 20 20 50 4f 53 5f 42 41 53 45 0a 7d 3b 0a 0a 2f    POS_BASE.};../
1db0: 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 20 6e  * Initialize a n
1dc0: 65 77 20 44 6f 63 4c 69 73 74 20 74 6f 20 68 6f  ew DocList to ho
1dd0: 6c 64 20 74 68 65 20 67 69 76 65 6e 20 64 61 74  ld the given dat
1de0: 61 2e 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  a. */.static voi
1df0: 64 20 64 6f 63 4c 69 73 74 49 6e 69 74 28 44 6f  d docListInit(Do
1e00: 63 4c 69 73 74 20 2a 64 2c 20 44 6f 63 4c 69 73  cList *d, DocLis
1e10: 74 54 79 70 65 20 69 54 79 70 65 2c 0a 20 20 20  tType iType,.   
1e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e30: 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20       const char 
1e40: 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74  *pData, int nDat
1e50: 61 29 7b 0a 20 20 64 2d 3e 6e 44 61 74 61 20 3d  a){.  d->nData =
1e60: 20 6e 44 61 74 61 3b 0a 20 20 69 66 28 20 6e 44   nData;.  if( nD
1e70: 61 74 61 3e 30 20 29 7b 0a 20 20 20 20 64 2d 3e  ata>0 ){.    d->
1e80: 70 44 61 74 61 20 3d 20 6d 61 6c 6c 6f 63 28 6e  pData = malloc(n
1e90: 44 61 74 61 29 3b 0a 20 20 20 20 6d 65 6d 63 70  Data);.    memcp
1ea0: 79 28 64 2d 3e 70 44 61 74 61 2c 20 70 44 61 74  y(d->pData, pDat
1eb0: 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 7d 20 65  a, nData);.  } e
1ec0: 6c 73 65 20 7b 0a 20 20 20 20 64 2d 3e 70 44 61  lse {.    d->pDa
1ed0: 74 61 20 3d 20 4e 55 4c 4c 3b 0a 20 20 7d 0a 20  ta = NULL;.  }. 
1ee0: 20 64 2d 3e 69 54 79 70 65 20 3d 20 69 54 79 70   d->iType = iTyp
1ef0: 65 3b 0a 20 20 64 2d 3e 69 4c 61 73 74 43 6f 6c  e;.  d->iLastCol
1f00: 75 6d 6e 20 3d 20 30 3b 0a 20 20 64 2d 3e 69 4c  umn = 0;.  d->iL
1f10: 61 73 74 50 6f 73 20 3d 20 64 2d 3e 69 4c 61 73  astPos = d->iLas
1f20: 74 4f 66 66 73 65 74 20 3d 20 30 3b 0a 7d 0a 0a  tOffset = 0;.}..
1f30: 2f 2a 20 43 72 65 61 74 65 20 61 20 6e 65 77 20  /* Create a new 
1f40: 64 79 6e 61 6d 69 63 61 6c 6c 79 2d 61 6c 6c 6f  dynamically-allo
1f50: 63 61 74 65 64 20 44 6f 63 4c 69 73 74 2e 20 2a  cated DocList. *
1f60: 2f 0a 73 74 61 74 69 63 20 44 6f 63 4c 69 73 74  /.static DocList
1f70: 20 2a 64 6f 63 4c 69 73 74 4e 65 77 28 44 6f 63   *docListNew(Doc
1f80: 4c 69 73 74 54 79 70 65 20 69 54 79 70 65 29 7b  ListType iType){
1f90: 0a 20 20 44 6f 63 4c 69 73 74 20 2a 64 20 3d 20  .  DocList *d = 
1fa0: 28 44 6f 63 4c 69 73 74 20 2a 29 20 6d 61 6c 6c  (DocList *) mall
1fb0: 6f 63 28 73 69 7a 65 6f 66 28 44 6f 63 4c 69 73  oc(sizeof(DocLis
1fc0: 74 29 29 3b 0a 20 20 64 6f 63 4c 69 73 74 49 6e  t));.  docListIn
1fd0: 69 74 28 64 2c 20 69 54 79 70 65 2c 20 30 2c 20  it(d, iType, 0, 
1fe0: 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 64 3b 0a  0);.  return d;.
1ff0: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  }..static void d
2000: 6f 63 4c 69 73 74 44 65 73 74 72 6f 79 28 44 6f  ocListDestroy(Do
2010: 63 4c 69 73 74 20 2a 64 29 7b 0a 20 20 66 72 65  cList *d){.  fre
2020: 65 28 64 2d 3e 70 44 61 74 61 29 3b 0a 23 69 66  e(d->pData);.#if
2030: 6e 64 65 66 20 4e 44 45 42 55 47 0a 20 20 6d 65  ndef NDEBUG.  me
2040: 6d 73 65 74 28 64 2c 20 30 78 35 35 2c 20 73 69  mset(d, 0x55, si
2050: 7a 65 6f 66 28 2a 64 29 29 3b 0a 23 65 6e 64 69  zeof(*d));.#endi
2060: 66 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  f.}..static void
2070: 20 64 6f 63 4c 69 73 74 44 65 6c 65 74 65 28 44   docListDelete(D
2080: 6f 63 4c 69 73 74 20 2a 64 29 7b 0a 20 20 64 6f  ocList *d){.  do
2090: 63 4c 69 73 74 44 65 73 74 72 6f 79 28 64 29 3b  cListDestroy(d);
20a0: 0a 20 20 66 72 65 65 28 64 29 3b 0a 7d 0a 0a 73  .  free(d);.}..s
20b0: 74 61 74 69 63 20 63 68 61 72 20 2a 64 6f 63 4c  tatic char *docL
20c0: 69 73 74 45 6e 64 28 44 6f 63 4c 69 73 74 20 2a  istEnd(DocList *
20d0: 64 29 7b 0a 20 20 72 65 74 75 72 6e 20 64 2d 3e  d){.  return d->
20e0: 70 44 61 74 61 20 2b 20 64 2d 3e 6e 44 61 74 61  pData + d->nData
20f0: 3b 0a 7d 0a 0a 2f 2a 20 41 70 70 65 6e 64 20 61  ;.}../* Append a
2100: 20 76 61 72 69 6e 74 20 74 6f 20 61 20 44 6f 63   varint to a Doc
2110: 4c 69 73 74 27 73 20 64 61 74 61 2e 20 2a 2f 0a  List's data. */.
2120: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 65  static void appe
2130: 6e 64 56 61 72 69 6e 74 28 44 6f 63 4c 69 73 74  ndVarint(DocList
2140: 20 2a 64 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36   *d, sqlite_int6
2150: 34 20 69 29 7b 0a 20 20 63 68 61 72 20 63 5b 56  4 i){.  char c[V
2160: 41 52 49 4e 54 5f 4d 41 58 5d 3b 0a 20 20 69 6e  ARINT_MAX];.  in
2170: 74 20 6e 20 3d 20 70 75 74 56 61 72 69 6e 74 28  t n = putVarint(
2180: 63 2c 20 69 29 3b 0a 20 20 64 2d 3e 70 44 61 74  c, i);.  d->pDat
2190: 61 20 3d 20 72 65 61 6c 6c 6f 63 28 64 2d 3e 70  a = realloc(d->p
21a0: 44 61 74 61 2c 20 64 2d 3e 6e 44 61 74 61 20 2b  Data, d->nData +
21b0: 20 6e 29 3b 0a 20 20 6d 65 6d 63 70 79 28 64 2d   n);.  memcpy(d-
21c0: 3e 70 44 61 74 61 20 2b 20 64 2d 3e 6e 44 61 74  >pData + d->nDat
21d0: 61 2c 20 63 2c 20 6e 29 3b 0a 20 20 64 2d 3e 6e  a, c, n);.  d->n
21e0: 44 61 74 61 20 2b 3d 20 6e 3b 0a 7d 0a 0a 73 74  Data += n;.}..st
21f0: 61 74 69 63 20 76 6f 69 64 20 64 6f 63 4c 69 73  atic void docLis
2200: 74 41 64 64 44 6f 63 69 64 28 44 6f 63 4c 69 73  tAddDocid(DocLis
2210: 74 20 2a 64 2c 20 73 71 6c 69 74 65 5f 69 6e 74  t *d, sqlite_int
2220: 36 34 20 69 44 6f 63 69 64 29 7b 0a 20 20 61 70  64 iDocid){.  ap
2230: 70 65 6e 64 56 61 72 69 6e 74 28 64 2c 20 69 44  pendVarint(d, iD
2240: 6f 63 69 64 29 3b 0a 20 20 69 66 28 20 64 2d 3e  ocid);.  if( d->
2250: 69 54 79 70 65 3e 3d 44 4c 5f 50 4f 53 49 54 49  iType>=DL_POSITI
2260: 4f 4e 53 20 29 7b 0a 20 20 20 20 61 70 70 65 6e  ONS ){.    appen
2270: 64 56 61 72 69 6e 74 28 64 2c 20 50 4f 53 5f 45  dVarint(d, POS_E
2280: 4e 44 29 3b 20 20 2f 2a 20 69 6e 69 74 69 61 6c  ND);  /* initial
2290: 6c 79 20 65 6d 70 74 79 20 70 6f 73 69 74 69 6f  ly empty positio
22a0: 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 20 20 64 2d  n list */.    d-
22b0: 3e 69 4c 61 73 74 43 6f 6c 75 6d 6e 20 3d 20 30  >iLastColumn = 0
22c0: 3b 0a 20 20 20 20 64 2d 3e 69 4c 61 73 74 50 6f  ;.    d->iLastPo
22d0: 73 20 3d 20 64 2d 3e 69 4c 61 73 74 4f 66 66 73  s = d->iLastOffs
22e0: 65 74 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f  et = 0;.  }.}../
22f0: 2a 20 68 65 6c 70 65 72 20 66 75 6e 63 74 69 6f  * helper functio
2300: 6e 20 66 6f 72 20 64 6f 63 4c 69 73 74 41 64 64  n for docListAdd
2310: 50 6f 73 20 61 6e 64 20 64 6f 63 4c 69 73 74 41  Pos and docListA
2320: 64 64 50 6f 73 4f 66 66 73 65 74 20 2a 2f 0a 73  ddPosOffset */.s
2330: 74 61 74 69 63 20 76 6f 69 64 20 61 64 64 50 6f  tatic void addPo
2340: 73 28 44 6f 63 4c 69 73 74 20 2a 64 2c 20 69 6e  s(DocList *d, in
2350: 74 20 69 43 6f 6c 75 6d 6e 2c 20 69 6e 74 20 69  t iColumn, int i
2360: 50 6f 73 29 7b 0a 20 20 61 73 73 65 72 74 28 20  Pos){.  assert( 
2370: 64 2d 3e 6e 44 61 74 61 3e 30 20 29 3b 0a 20 20  d->nData>0 );.  
2380: 2d 2d 64 2d 3e 6e 44 61 74 61 3b 20 20 2f 2a 20  --d->nData;  /* 
2390: 72 65 6d 6f 76 65 20 70 72 65 76 69 6f 75 73 20  remove previous 
23a0: 74 65 72 6d 69 6e 61 74 6f 72 20 2a 2f 0a 20 20  terminator */.  
23b0: 69 66 28 20 69 43 6f 6c 75 6d 6e 21 3d 64 2d 3e  if( iColumn!=d->
23c0: 69 4c 61 73 74 43 6f 6c 75 6d 6e 20 29 7b 0a 20  iLastColumn ){. 
23d0: 20 20 20 61 73 73 65 72 74 28 20 69 43 6f 6c 75     assert( iColu
23e0: 6d 6e 3e 64 2d 3e 69 4c 61 73 74 43 6f 6c 75 6d  mn>d->iLastColum
23f0: 6e 20 29 3b 0a 20 20 20 20 61 70 70 65 6e 64 56  n );.    appendV
2400: 61 72 69 6e 74 28 64 2c 20 50 4f 53 5f 43 4f 4c  arint(d, POS_COL
2410: 55 4d 4e 29 3b 0a 20 20 20 20 61 70 70 65 6e 64  UMN);.    append
2420: 56 61 72 69 6e 74 28 64 2c 20 69 43 6f 6c 75 6d  Varint(d, iColum
2430: 6e 29 3b 0a 20 20 20 20 64 2d 3e 69 4c 61 73 74  n);.    d->iLast
2440: 43 6f 6c 75 6d 6e 20 3d 20 69 43 6f 6c 75 6d 6e  Column = iColumn
2450: 3b 0a 20 20 20 20 64 2d 3e 69 4c 61 73 74 50 6f  ;.    d->iLastPo
2460: 73 20 3d 20 64 2d 3e 69 4c 61 73 74 4f 66 66 73  s = d->iLastOffs
2470: 65 74 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 61 73  et = 0;.  }.  as
2480: 73 65 72 74 28 20 69 50 6f 73 3e 3d 64 2d 3e 69  sert( iPos>=d->i
2490: 4c 61 73 74 50 6f 73 20 29 3b 0a 20 20 61 70 70  LastPos );.  app
24a0: 65 6e 64 56 61 72 69 6e 74 28 64 2c 20 69 50 6f  endVarint(d, iPo
24b0: 73 2d 64 2d 3e 69 4c 61 73 74 50 6f 73 2b 50 4f  s-d->iLastPos+PO
24c0: 53 5f 42 41 53 45 29 3b 0a 20 20 64 2d 3e 69 4c  S_BASE);.  d->iL
24d0: 61 73 74 50 6f 73 20 3d 20 69 50 6f 73 3b 0a 7d  astPos = iPos;.}
24e0: 0a 0a 2f 2a 20 41 64 64 20 61 20 70 6f 73 69 74  ../* Add a posit
24f0: 69 6f 6e 20 74 6f 20 74 68 65 20 6c 61 73 74 20  ion to the last 
2500: 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 20 69 6e  position list in
2510: 20 61 20 64 6f 63 6c 69 73 74 2e 20 2a 2f 0a 73   a doclist. */.s
2520: 74 61 74 69 63 20 76 6f 69 64 20 64 6f 63 4c 69  tatic void docLi
2530: 73 74 41 64 64 50 6f 73 28 44 6f 63 4c 69 73 74  stAddPos(DocList
2540: 20 2a 64 2c 20 69 6e 74 20 69 43 6f 6c 75 6d 6e   *d, int iColumn
2550: 2c 20 69 6e 74 20 69 50 6f 73 29 7b 0a 20 20 61  , int iPos){.  a
2560: 73 73 65 72 74 28 20 64 2d 3e 69 54 79 70 65 3d  ssert( d->iType=
2570: 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 29 3b  =DL_POSITIONS );
2580: 0a 20 20 61 64 64 50 6f 73 28 64 2c 20 69 43 6f  .  addPos(d, iCo
2590: 6c 75 6d 6e 2c 20 69 50 6f 73 29 3b 0a 20 20 61  lumn, iPos);.  a
25a0: 70 70 65 6e 64 56 61 72 69 6e 74 28 64 2c 20 50  ppendVarint(d, P
25b0: 4f 53 5f 45 4e 44 29 3b 20 20 2f 2a 20 61 64 64  OS_END);  /* add
25c0: 20 6e 65 77 20 74 65 72 6d 69 6e 61 74 6f 72 20   new terminator 
25d0: 2a 2f 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20  */.}../*.** Add 
25e0: 61 20 70 6f 73 69 74 69 6f 6e 20 61 6e 64 20 73  a position and s
25f0: 74 61 72 74 69 6e 67 20 61 6e 64 20 65 6e 64 69  tarting and endi
2600: 6e 67 20 6f 66 66 73 65 74 73 20 74 6f 20 61 20  ng offsets to a 
2610: 64 6f 63 6c 69 73 74 2e 0a 2a 2a 0a 2a 2a 20 49  doclist..**.** I
2620: 66 20 74 68 65 20 64 6f 63 6c 69 73 74 20 69 73  f the doclist is
2630: 20 73 65 74 75 70 20 74 6f 20 68 61 6e 64 6c 65   setup to handle
2640: 20 6f 6e 6c 79 20 70 6f 73 69 74 69 6f 6e 73 2c   only positions,
2650: 20 74 68 65 6e 20 69 6e 73 65 72 74 0a 2a 2a 20   then insert.** 
2660: 74 68 65 20 70 6f 73 69 74 69 6f 6e 20 6f 6e 6c  the position onl
2670: 79 20 61 6e 64 20 69 67 6e 6f 72 65 20 74 68 65  y and ignore the
2680: 20 6f 66 66 73 65 74 73 2e 0a 2a 2f 0a 73 74 61   offsets..*/.sta
2690: 74 69 63 20 76 6f 69 64 20 64 6f 63 4c 69 73 74  tic void docList
26a0: 41 64 64 50 6f 73 4f 66 66 73 65 74 28 0a 20 20  AddPosOffset(.  
26b0: 44 6f 63 4c 69 73 74 20 2a 64 2c 20 20 20 20 20  DocList *d,     
26c0: 20 20 20 20 20 20 20 20 2f 2a 20 44 6f 63 6c 69          /* Docli
26d0: 73 74 20 75 6e 64 65 72 20 63 6f 6e 73 74 72 75  st under constru
26e0: 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 69  ction */.  int i
26f0: 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20  Column,         
2700: 20 20 20 2f 2a 20 43 6f 6c 75 6d 6e 20 74 68 65     /* Column the
2710: 20 69 6e 73 65 72 74 65 64 20 74 65 72 6d 20 69   inserted term i
2720: 73 20 70 61 72 74 20 6f 66 20 2a 2f 0a 20 20 69  s part of */.  i
2730: 6e 74 20 69 50 6f 73 2c 20 20 20 20 20 20 20 20  nt iPos,        
2740: 20 20 20 20 20 20 20 2f 2a 20 50 6f 73 69 74 69         /* Positi
2750: 6f 6e 20 6f 66 20 74 68 65 20 69 6e 73 65 72 74  on of the insert
2760: 65 64 20 74 65 72 6d 20 2a 2f 0a 20 20 69 6e 74  ed term */.  int
2770: 20 69 53 74 61 72 74 4f 66 66 73 65 74 2c 20 20   iStartOffset,  
2780: 20 20 20 20 20 2f 2a 20 53 74 61 72 74 69 6e 67       /* Starting
2790: 20 6f 66 66 73 65 74 20 6f 66 20 69 6e 73 65 72   offset of inser
27a0: 74 65 64 20 74 65 72 6d 20 2a 2f 0a 20 20 69 6e  ted term */.  in
27b0: 74 20 69 45 6e 64 4f 66 66 73 65 74 20 20 20 20  t iEndOffset    
27c0: 20 20 20 20 20 20 2f 2a 20 45 6e 64 69 6e 67 20        /* Ending 
27d0: 6f 66 66 73 65 74 20 6f 66 20 69 6e 73 65 72 74  offset of insert
27e0: 65 64 20 74 65 72 6d 20 2a 2f 0a 29 7b 0a 20 20  ed term */.){.  
27f0: 61 73 73 65 72 74 28 20 64 2d 3e 69 54 79 70 65  assert( d->iType
2800: 3e 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 29  >=DL_POSITIONS )
2810: 3b 0a 20 20 61 64 64 50 6f 73 28 64 2c 20 69 43  ;.  addPos(d, iC
2820: 6f 6c 75 6d 6e 2c 20 69 50 6f 73 29 3b 0a 20 20  olumn, iPos);.  
2830: 69 66 28 20 64 2d 3e 69 54 79 70 65 3d 3d 44 4c  if( d->iType==DL
2840: 5f 50 4f 53 49 54 49 4f 4e 53 5f 4f 46 46 53 45  _POSITIONS_OFFSE
2850: 54 53 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  TS ){.    assert
2860: 28 20 69 53 74 61 72 74 4f 66 66 73 65 74 3e 3d  ( iStartOffset>=
2870: 64 2d 3e 69 4c 61 73 74 4f 66 66 73 65 74 20 29  d->iLastOffset )
2880: 3b 0a 20 20 20 20 61 70 70 65 6e 64 56 61 72 69  ;.    appendVari
2890: 6e 74 28 64 2c 20 69 53 74 61 72 74 4f 66 66 73  nt(d, iStartOffs
28a0: 65 74 2d 64 2d 3e 69 4c 61 73 74 4f 66 66 73 65  et-d->iLastOffse
28b0: 74 29 3b 0a 20 20 20 20 64 2d 3e 69 4c 61 73 74  t);.    d->iLast
28c0: 4f 66 66 73 65 74 20 3d 20 69 53 74 61 72 74 4f  Offset = iStartO
28d0: 66 66 73 65 74 3b 0a 20 20 20 20 61 73 73 65 72  ffset;.    asser
28e0: 74 28 20 69 45 6e 64 4f 66 66 73 65 74 3e 3d 69  t( iEndOffset>=i
28f0: 53 74 61 72 74 4f 66 66 73 65 74 20 29 3b 0a 20  StartOffset );. 
2900: 20 20 20 61 70 70 65 6e 64 56 61 72 69 6e 74 28     appendVarint(
2910: 64 2c 20 69 45 6e 64 4f 66 66 73 65 74 2d 69 53  d, iEndOffset-iS
2920: 74 61 72 74 4f 66 66 73 65 74 29 3b 0a 20 20 7d  tartOffset);.  }
2930: 0a 20 20 61 70 70 65 6e 64 56 61 72 69 6e 74 28  .  appendVarint(
2940: 64 2c 20 50 4f 53 5f 45 4e 44 29 3b 20 20 2f 2a  d, POS_END);  /*
2950: 20 61 64 64 20 6e 65 77 20 74 65 72 6d 69 6e 61   add new termina
2960: 74 6f 72 20 2a 2f 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  tor */.}../*.** 
2970: 41 20 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20  A DocListReader 
2980: 6f 62 6a 65 63 74 20 69 73 20 61 20 63 75 72 73  object is a curs
2990: 6f 72 20 69 6e 74 6f 20 61 20 64 6f 63 6c 69 73  or into a doclis
29a0: 74 2e 20 20 49 6e 69 74 69 61 6c 69 7a 65 0a 2a  t.  Initialize.*
29b0: 2a 20 74 68 65 20 63 75 72 73 6f 72 20 74 6f 20  * the cursor to 
29c0: 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66  the beginning of
29d0: 20 74 68 65 20 64 6f 63 6c 69 73 74 20 62 79 20   the doclist by 
29e0: 63 61 6c 6c 69 6e 67 20 72 65 61 64 65 72 49 6e  calling readerIn
29f0: 69 74 28 29 2e 0a 2a 2a 20 54 68 65 6e 20 75 73  it()..** Then us
2a00: 65 20 72 6f 75 74 69 6e 65 73 0a 2a 2a 0a 2a 2a  e routines.**.**
2a10: 20 20 20 20 20 20 70 65 65 6b 44 6f 63 69 64 28        peekDocid(
2a20: 29 0a 2a 2a 20 20 20 20 20 20 72 65 61 64 44 6f  ).**      readDo
2a30: 63 69 64 28 29 0a 2a 2a 20 20 20 20 20 20 72 65  cid().**      re
2a40: 61 64 50 6f 73 69 74 69 6f 6e 28 29 0a 2a 2a 20  adPosition().** 
2a50: 20 20 20 20 20 73 6b 69 70 50 6f 73 69 74 69 6f       skipPositio
2a60: 6e 4c 69 73 74 28 29 0a 2a 2a 20 20 20 20 20 20  nList().**      
2a70: 61 6e 64 20 73 6f 20 66 6f 72 74 68 2e 2e 2e 0a  and so forth....
2a80: 2a 2a 0a 2a 2a 20 74 6f 20 72 65 61 64 20 69 6e  **.** to read in
2a90: 66 6f 72 6d 61 74 69 6f 6e 20 6f 75 74 20 6f 66  formation out of
2aa0: 20 74 68 65 20 64 6f 63 6c 69 73 74 2e 20 20 57   the doclist.  W
2ab0: 68 65 6e 20 77 65 20 72 65 61 63 68 20 74 68 65  hen we reach the
2ac0: 20 65 6e 64 0a 2a 2a 20 6f 66 20 74 68 65 20 64   end.** of the d
2ad0: 6f 63 6c 69 73 74 2c 20 61 74 45 6e 64 28 29 20  oclist, atEnd() 
2ae0: 72 65 74 75 72 6e 73 20 54 52 55 45 2e 0a 2a 2f  returns TRUE..*/
2af0: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
2b00: 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20 7b 0a  DocListReader {.
2b10: 20 20 44 6f 63 4c 69 73 74 20 2a 70 44 6f 63 6c    DocList *pDocl
2b20: 69 73 74 3b 20 20 2f 2a 20 54 68 65 20 64 6f 63  ist;  /* The doc
2b30: 75 6d 65 6e 74 20 6c 69 73 74 20 77 65 20 61 72  ument list we ar
2b40: 65 20 73 74 65 70 70 69 6e 67 20 74 68 72 6f 75  e stepping throu
2b50: 67 68 20 2a 2f 0a 20 20 63 68 61 72 20 2a 70 3b  gh */.  char *p;
2b60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
2b70: 6f 69 6e 74 65 72 20 74 6f 20 6e 65 78 74 20 75  ointer to next u
2b80: 6e 72 65 61 64 20 62 79 74 65 20 69 6e 20 74 68  nread byte in th
2b90: 65 20 64 6f 63 6c 69 73 74 20 2a 2f 0a 20 20 69  e doclist */.  i
2ba0: 6e 74 20 69 4c 61 73 74 43 6f 6c 75 6d 6e 3b 0a  nt iLastColumn;.
2bb0: 20 20 69 6e 74 20 69 4c 61 73 74 50 6f 73 3b 20    int iLastPos; 
2bc0: 20 2f 2a 20 74 68 65 20 6c 61 73 74 20 70 6f 73   /* the last pos
2bd0: 69 74 69 6f 6e 20 72 65 61 64 2c 20 6f 72 20 2d  ition read, or -
2be0: 31 20 77 68 65 6e 20 6e 6f 74 20 69 6e 20 61 20  1 when not in a 
2bf0: 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 20 2a 2f  position list */
2c00: 0a 7d 20 44 6f 63 4c 69 73 74 52 65 61 64 65 72  .} DocListReader
2c10: 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c  ;../*.** Initial
2c20: 69 7a 65 20 74 68 65 20 44 6f 63 4c 69 73 74 52  ize the DocListR
2c30: 65 61 64 65 72 20 72 20 74 6f 20 70 6f 69 6e 74  eader r to point
2c40: 20 74 6f 20 74 68 65 20 62 65 67 69 6e 6e 69 6e   to the beginnin
2c50: 67 20 6f 66 20 70 44 6f 63 6c 69 73 74 2e 0a 2a  g of pDoclist..*
2c60: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 72 65  /.static void re
2c70: 61 64 65 72 49 6e 69 74 28 44 6f 63 4c 69 73 74  aderInit(DocList
2c80: 52 65 61 64 65 72 20 2a 72 2c 20 44 6f 63 4c 69  Reader *r, DocLi
2c90: 73 74 20 2a 70 44 6f 63 6c 69 73 74 29 7b 0a 20  st *pDoclist){. 
2ca0: 20 72 2d 3e 70 44 6f 63 6c 69 73 74 20 3d 20 70   r->pDoclist = p
2cb0: 44 6f 63 6c 69 73 74 3b 0a 20 20 69 66 28 20 70  Doclist;.  if( p
2cc0: 44 6f 63 6c 69 73 74 21 3d 4e 55 4c 4c 20 29 7b  Doclist!=NULL ){
2cd0: 0a 20 20 20 20 72 2d 3e 70 20 3d 20 70 44 6f 63  .    r->p = pDoc
2ce0: 6c 69 73 74 2d 3e 70 44 61 74 61 3b 0a 20 20 7d  list->pData;.  }
2cf0: 0a 20 20 72 2d 3e 69 4c 61 73 74 43 6f 6c 75 6d  .  r->iLastColum
2d00: 6e 20 3d 20 2d 31 3b 0a 20 20 72 2d 3e 69 4c 61  n = -1;.  r->iLa
2d10: 73 74 50 6f 73 20 3d 20 2d 31 3b 0a 7d 0a 0a 2f  stPos = -1;.}../
2d20: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 54 52 55 45  *.** Return TRUE
2d30: 20 69 66 20 77 65 20 68 61 76 65 20 72 65 61 63   if we have reac
2d40: 68 65 64 20 74 68 65 6e 20 65 6e 64 20 6f 66 20  hed then end of 
2d50: 70 52 65 61 64 65 72 20 61 6e 64 20 74 68 65 72  pReader and ther
2d60: 65 20 69 73 0a 2a 2a 20 6e 6f 74 68 69 6e 67 20  e is.** nothing 
2d70: 65 6c 73 65 20 6c 65 66 74 20 74 6f 20 72 65 61  else left to rea
2d80: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
2d90: 20 61 74 45 6e 64 28 44 6f 63 4c 69 73 74 52 65   atEnd(DocListRe
2da0: 61 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a  ader *pReader){.
2db0: 20 20 72 65 74 75 72 6e 20 70 52 65 61 64 65 72    return pReader
2dc0: 2d 3e 70 44 6f 63 6c 69 73 74 3d 3d 30 20 7c 7c  ->pDoclist==0 ||
2dd0: 20 28 70 52 65 61 64 65 72 2d 3e 70 20 3e 3d 20   (pReader->p >= 
2de0: 64 6f 63 4c 69 73 74 45 6e 64 28 70 52 65 61 64  docListEnd(pRead
2df0: 65 72 2d 3e 70 44 6f 63 6c 69 73 74 29 29 3b 0a  er->pDoclist));.
2e00: 7d 0a 0a 2f 2a 20 50 65 65 6b 20 61 74 20 74 68  }../* Peek at th
2e10: 65 20 6e 65 78 74 20 64 6f 63 69 64 20 77 69 74  e next docid wit
2e20: 68 6f 75 74 20 61 64 76 61 6e 63 69 6e 67 20 74  hout advancing t
2e30: 68 65 20 72 65 61 64 20 70 6f 69 6e 74 65 72 2e  he read pointer.
2e40: 20 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69   .*/.static sqli
2e50: 74 65 5f 69 6e 74 36 34 20 70 65 65 6b 44 6f 63  te_int64 peekDoc
2e60: 69 64 28 44 6f 63 4c 69 73 74 52 65 61 64 65 72  id(DocListReader
2e70: 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 73 71   *pReader){.  sq
2e80: 6c 69 74 65 5f 69 6e 74 36 34 20 72 65 74 3b 0a  lite_int64 ret;.
2e90: 20 20 61 73 73 65 72 74 28 20 21 61 74 45 6e 64    assert( !atEnd
2ea0: 28 70 52 65 61 64 65 72 29 20 29 3b 0a 20 20 61  (pReader) );.  a
2eb0: 73 73 65 72 74 28 20 70 52 65 61 64 65 72 2d 3e  ssert( pReader->
2ec0: 69 4c 61 73 74 50 6f 73 3d 3d 2d 31 20 29 3b 0a  iLastPos==-1 );.
2ed0: 20 20 67 65 74 56 61 72 69 6e 74 28 70 52 65 61    getVarint(pRea
2ee0: 64 65 72 2d 3e 70 2c 20 26 72 65 74 29 3b 0a 20  der->p, &ret);. 
2ef0: 20 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a   return ret;.}..
2f00: 2f 2a 20 52 65 61 64 20 74 68 65 20 6e 65 78 74  /* Read the next
2f10: 20 64 6f 63 69 64 2e 20 20 20 53 65 65 20 61 6c   docid.   See al
2f20: 73 6f 20 6e 65 78 74 44 6f 63 69 64 28 29 2e 0a  so nextDocid()..
2f30: 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  */.static sqlite
2f40: 5f 69 6e 74 36 34 20 72 65 61 64 44 6f 63 69 64  _int64 readDocid
2f50: 28 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20 2a  (DocListReader *
2f60: 70 52 65 61 64 65 72 29 7b 0a 20 20 73 71 6c 69  pReader){.  sqli
2f70: 74 65 5f 69 6e 74 36 34 20 72 65 74 3b 0a 20 20  te_int64 ret;.  
2f80: 61 73 73 65 72 74 28 20 21 61 74 45 6e 64 28 70  assert( !atEnd(p
2f90: 52 65 61 64 65 72 29 20 29 3b 0a 20 20 61 73 73  Reader) );.  ass
2fa0: 65 72 74 28 20 70 52 65 61 64 65 72 2d 3e 69 4c  ert( pReader->iL
2fb0: 61 73 74 50 6f 73 3d 3d 2d 31 20 29 3b 0a 20 20  astPos==-1 );.  
2fc0: 70 52 65 61 64 65 72 2d 3e 70 20 2b 3d 20 67 65  pReader->p += ge
2fd0: 74 56 61 72 69 6e 74 28 70 52 65 61 64 65 72 2d  tVarint(pReader-
2fe0: 3e 70 2c 20 26 72 65 74 29 3b 0a 20 20 69 66 28  >p, &ret);.  if(
2ff0: 20 70 52 65 61 64 65 72 2d 3e 70 44 6f 63 6c 69   pReader->pDocli
3000: 73 74 2d 3e 69 54 79 70 65 3e 3d 44 4c 5f 50 4f  st->iType>=DL_PO
3010: 53 49 54 49 4f 4e 53 20 29 7b 0a 20 20 20 20 70  SITIONS ){.    p
3020: 52 65 61 64 65 72 2d 3e 69 4c 61 73 74 43 6f 6c  Reader->iLastCol
3030: 75 6d 6e 20 3d 20 30 3b 0a 20 20 20 20 70 52 65  umn = 0;.    pRe
3040: 61 64 65 72 2d 3e 69 4c 61 73 74 50 6f 73 20 3d  ader->iLastPos =
3050: 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   0;.  }.  return
3060: 20 72 65 74 3b 0a 7d 0a 0a 2f 2a 20 52 65 61 64   ret;.}../* Read
3070: 20 74 68 65 20 6e 65 78 74 20 70 6f 73 69 74 69   the next positi
3080: 6f 6e 20 61 6e 64 20 63 6f 6c 75 6d 6e 20 69 6e  on and column in
3090: 64 65 78 20 66 72 6f 6d 20 61 20 70 6f 73 69 74  dex from a posit
30a0: 69 6f 6e 20 6c 69 73 74 2e 0a 20 2a 20 52 65 74  ion list.. * Ret
30b0: 75 72 6e 73 20 74 68 65 20 70 6f 73 69 74 69 6f  urns the positio
30c0: 6e 2c 20 6f 72 20 2d 31 20 61 74 20 74 68 65 20  n, or -1 at the 
30d0: 65 6e 64 20 6f 66 20 74 68 65 20 6c 69 73 74 2e  end of the list.
30e0: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 72   */.static int r
30f0: 65 61 64 50 6f 73 69 74 69 6f 6e 28 44 6f 63 4c  eadPosition(DocL
3100: 69 73 74 52 65 61 64 65 72 20 2a 70 52 65 61 64  istReader *pRead
3110: 65 72 2c 20 69 6e 74 20 2a 69 43 6f 6c 75 6d 6e  er, int *iColumn
3120: 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e  ){.  int i;.  in
3130: 74 20 69 54 79 70 65 20 3d 20 70 52 65 61 64 65  t iType = pReade
3140: 72 2d 3e 70 44 6f 63 6c 69 73 74 2d 3e 69 54 79  r->pDoclist->iTy
3150: 70 65 3b 0a 0a 20 20 69 66 28 20 70 52 65 61 64  pe;..  if( pRead
3160: 65 72 2d 3e 69 4c 61 73 74 50 6f 73 3d 3d 2d 31  er->iLastPos==-1
3170: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 2d   ){.    return -
3180: 31 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28  1;.  }.  assert(
3190: 20 21 61 74 45 6e 64 28 70 52 65 61 64 65 72 29   !atEnd(pReader)
31a0: 20 29 3b 0a 0a 20 20 69 66 28 20 69 54 79 70 65   );..  if( iType
31b0: 3c 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 29 7b  <DL_POSITIONS ){
31c0: 0a 20 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a  .    return -1;.
31d0: 20 20 7d 0a 20 20 70 52 65 61 64 65 72 2d 3e 70    }.  pReader->p
31e0: 20 2b 3d 20 67 65 74 56 61 72 69 6e 74 33 32 28   += getVarint32(
31f0: 70 52 65 61 64 65 72 2d 3e 70 2c 20 26 69 29 3b  pReader->p, &i);
3200: 0a 20 20 69 66 28 20 69 3d 3d 50 4f 53 5f 45 4e  .  if( i==POS_EN
3210: 44 20 29 7b 0a 20 20 20 20 70 52 65 61 64 65 72  D ){.    pReader
3220: 2d 3e 69 4c 61 73 74 43 6f 6c 75 6d 6e 20 3d 20  ->iLastColumn = 
3230: 70 52 65 61 64 65 72 2d 3e 69 4c 61 73 74 50 6f  pReader->iLastPo
3240: 73 20 3d 20 2d 31 3b 0a 20 20 20 20 2a 69 43 6f  s = -1;.    *iCo
3250: 6c 75 6d 6e 20 3d 20 2d 31 3b 0a 20 20 20 20 72  lumn = -1;.    r
3260: 65 74 75 72 6e 20 2d 31 3b 0a 20 20 7d 0a 20 20  eturn -1;.  }.  
3270: 69 66 28 20 69 3d 3d 50 4f 53 5f 43 4f 4c 55 4d  if( i==POS_COLUM
3280: 4e 20 29 7b 0a 20 20 20 20 70 52 65 61 64 65 72  N ){.    pReader
3290: 2d 3e 70 20 2b 3d 20 67 65 74 56 61 72 69 6e 74  ->p += getVarint
32a0: 33 32 28 70 52 65 61 64 65 72 2d 3e 70 2c 20 26  32(pReader->p, &
32b0: 70 52 65 61 64 65 72 2d 3e 69 4c 61 73 74 43 6f  pReader->iLastCo
32c0: 6c 75 6d 6e 29 3b 0a 20 20 20 20 70 52 65 61 64  lumn);.    pRead
32d0: 65 72 2d 3e 69 4c 61 73 74 50 6f 73 20 3d 20 30  er->iLastPos = 0
32e0: 3b 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e 70  ;.    pReader->p
32f0: 20 2b 3d 20 67 65 74 56 61 72 69 6e 74 33 32 28   += getVarint32(
3300: 70 52 65 61 64 65 72 2d 3e 70 2c 20 26 69 29 3b  pReader->p, &i);
3310: 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 3e 3d  .    assert( i>=
3320: 50 4f 53 5f 42 41 53 45 20 29 3b 0a 20 20 7d 0a  POS_BASE );.  }.
3330: 20 20 70 52 65 61 64 65 72 2d 3e 69 4c 61 73 74    pReader->iLast
3340: 50 6f 73 20 2b 3d 20 28 28 69 6e 74 29 20 69 29  Pos += ((int) i)
3350: 2d 50 4f 53 5f 42 41 53 45 3b 0a 20 20 69 66 28  -POS_BASE;.  if(
3360: 20 69 54 79 70 65 3e 3d 44 4c 5f 50 4f 53 49 54   iType>=DL_POSIT
3370: 49 4f 4e 53 5f 4f 46 46 53 45 54 53 20 29 7b 0a  IONS_OFFSETS ){.
3380: 20 20 20 20 2f 2a 20 53 6b 69 70 20 6f 76 65 72      /* Skip over
3390: 20 6f 66 66 73 65 74 73 2c 20 69 67 6e 6f 72 69   offsets, ignori
33a0: 6e 67 20 74 68 65 6d 20 66 6f 72 20 6e 6f 77 2e  ng them for now.
33b0: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 53 74 61   */.    int iSta
33c0: 72 74 2c 20 69 45 6e 64 3b 0a 20 20 20 20 70 52  rt, iEnd;.    pR
33d0: 65 61 64 65 72 2d 3e 70 20 2b 3d 20 67 65 74 56  eader->p += getV
33e0: 61 72 69 6e 74 33 32 28 70 52 65 61 64 65 72 2d  arint32(pReader-
33f0: 3e 70 2c 20 26 69 53 74 61 72 74 29 3b 0a 20 20  >p, &iStart);.  
3400: 20 20 70 52 65 61 64 65 72 2d 3e 70 20 2b 3d 20    pReader->p += 
3410: 67 65 74 56 61 72 69 6e 74 33 32 28 70 52 65 61  getVarint32(pRea
3420: 64 65 72 2d 3e 70 2c 20 26 69 45 6e 64 29 3b 0a  der->p, &iEnd);.
3430: 20 20 7d 0a 20 20 2a 69 43 6f 6c 75 6d 6e 20 3d    }.  *iColumn =
3440: 20 70 52 65 61 64 65 72 2d 3e 69 4c 61 73 74 43   pReader->iLastC
3450: 6f 6c 75 6d 6e 3b 0a 20 20 72 65 74 75 72 6e 20  olumn;.  return 
3460: 70 52 65 61 64 65 72 2d 3e 69 4c 61 73 74 50 6f  pReader->iLastPo
3470: 73 3b 0a 7d 0a 0a 2f 2a 20 53 6b 69 70 20 70 61  s;.}../* Skip pa
3480: 73 74 20 74 68 65 20 65 6e 64 20 6f 66 20 61 20  st the end of a 
3490: 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 2e 20 2a  position list. *
34a0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 6b  /.static void sk
34b0: 69 70 50 6f 73 69 74 69 6f 6e 4c 69 73 74 28 44  ipPositionList(D
34c0: 6f 63 4c 69 73 74 52 65 61 64 65 72 20 2a 70 52  ocListReader *pR
34d0: 65 61 64 65 72 29 7b 0a 20 20 44 6f 63 4c 69 73  eader){.  DocLis
34e0: 74 20 2a 70 20 3d 20 70 52 65 61 64 65 72 2d 3e  t *p = pReader->
34f0: 70 44 6f 63 6c 69 73 74 3b 0a 20 20 69 66 28 20  pDoclist;.  if( 
3500: 70 20 26 26 20 70 2d 3e 69 54 79 70 65 3e 3d 44  p && p->iType>=D
3510: 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 29 7b 0a 20  L_POSITIONS ){. 
3520: 20 20 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 3b 0a     int iColumn;.
3530: 20 20 20 20 77 68 69 6c 65 28 20 72 65 61 64 50      while( readP
3540: 6f 73 69 74 69 6f 6e 28 70 52 65 61 64 65 72 2c  osition(pReader,
3550: 20 26 69 43 6f 6c 75 6d 6e 29 21 3d 2d 31 20 29   &iColumn)!=-1 )
3560: 7b 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 53 6b 69  {}.  }.}../* Ski
3570: 70 20 6f 76 65 72 20 61 20 64 6f 63 69 64 2c 20  p over a docid, 
3580: 69 6e 63 6c 75 64 69 6e 67 20 69 74 73 20 70 6f  including its po
3590: 73 69 74 69 6f 6e 20 6c 69 73 74 20 69 66 20 74  sition list if t
35a0: 68 65 20 64 6f 63 6c 69 73 74 20 68 61 73 0a 20  he doclist has. 
35b0: 2a 20 70 6f 73 69 74 69 6f 6e 73 2e 20 2a 2f 0a  * positions. */.
35c0: 73 74 61 74 69 63 20 76 6f 69 64 20 73 6b 69 70  static void skip
35d0: 44 6f 63 75 6d 65 6e 74 28 44 6f 63 4c 69 73 74  Document(DocList
35e0: 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29  Reader *pReader)
35f0: 7b 0a 20 20 72 65 61 64 44 6f 63 69 64 28 70 52  {.  readDocid(pR
3600: 65 61 64 65 72 29 3b 0a 20 20 73 6b 69 70 50 6f  eader);.  skipPo
3610: 73 69 74 69 6f 6e 4c 69 73 74 28 70 52 65 61 64  sitionList(pRead
3620: 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 53 6b 69 70 20  er);.}../* Skip 
3630: 70 61 73 74 20 61 6c 6c 20 64 6f 63 69 64 73 20  past all docids 
3640: 77 68 69 63 68 20 61 72 65 20 6c 65 73 73 20 74  which are less t
3650: 68 61 6e 20 5b 69 44 6f 63 69 64 5d 2e 20 20 52  han [iDocid].  R
3660: 65 74 75 72 6e 73 20 31 20 69 66 20 61 20 64 6f  eturns 1 if a do
3670: 63 69 64 0a 20 2a 20 6d 61 74 63 68 69 6e 67 20  cid. * matching 
3680: 5b 69 44 6f 63 69 64 5d 20 77 61 73 20 66 6f 75  [iDocid] was fou
3690: 6e 64 2e 20 20 2a 2f 0a 73 74 61 74 69 63 20 69  nd.  */.static i
36a0: 6e 74 20 73 6b 69 70 54 6f 44 6f 63 69 64 28 44  nt skipToDocid(D
36b0: 6f 63 4c 69 73 74 52 65 61 64 65 72 20 2a 70 52  ocListReader *pR
36c0: 65 61 64 65 72 2c 20 73 71 6c 69 74 65 5f 69 6e  eader, sqlite_in
36d0: 74 36 34 20 69 44 6f 63 69 64 29 7b 0a 20 20 73  t64 iDocid){.  s
36e0: 71 6c 69 74 65 5f 69 6e 74 36 34 20 64 20 3d 20  qlite_int64 d = 
36f0: 30 3b 0a 20 20 77 68 69 6c 65 28 20 21 61 74 45  0;.  while( !atE
3700: 6e 64 28 70 52 65 61 64 65 72 29 20 26 26 20 28  nd(pReader) && (
3710: 64 3d 70 65 65 6b 44 6f 63 69 64 28 70 52 65 61  d=peekDocid(pRea
3720: 64 65 72 29 29 3c 69 44 6f 63 69 64 20 29 7b 0a  der))<iDocid ){.
3730: 20 20 20 20 73 6b 69 70 44 6f 63 75 6d 65 6e 74      skipDocument
3740: 28 70 52 65 61 64 65 72 29 3b 0a 20 20 7d 0a 20  (pReader);.  }. 
3750: 20 72 65 74 75 72 6e 20 21 61 74 45 6e 64 28 70   return !atEnd(p
3760: 52 65 61 64 65 72 29 20 26 26 20 64 3d 3d 69 44  Reader) && d==iD
3770: 6f 63 69 64 3b 0a 7d 0a 0a 2f 2a 20 52 65 74 75  ocid;.}../* Retu
3780: 72 6e 20 74 68 65 20 66 69 72 73 74 20 64 6f 63  rn the first doc
3790: 75 6d 65 6e 74 20 69 6e 20 61 20 64 6f 63 75 6d  ument in a docum
37a0: 65 6e 74 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61  ent list..*/.sta
37b0: 74 69 63 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  tic sqlite_int64
37c0: 20 66 69 72 73 74 44 6f 63 69 64 28 44 6f 63 4c   firstDocid(DocL
37d0: 69 73 74 20 2a 64 29 7b 0a 20 20 44 6f 63 4c 69  ist *d){.  DocLi
37e0: 73 74 52 65 61 64 65 72 20 72 3b 0a 20 20 72 65  stReader r;.  re
37f0: 61 64 65 72 49 6e 69 74 28 26 72 2c 20 64 29 3b  aderInit(&r, d);
3800: 0a 20 20 72 65 74 75 72 6e 20 72 65 61 64 44 6f  .  return readDo
3810: 63 69 64 28 26 72 29 3b 0a 7d 0a 0a 23 69 66 64  cid(&r);.}..#ifd
3820: 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47 0a  ef SQLITE_DEBUG.
3830: 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  /*.** This routi
3840: 6e 65 20 69 73 20 75 73 65 64 20 66 6f 72 20 64  ne is used for d
3850: 65 62 75 67 67 69 6e 67 20 70 75 72 70 6f 73 65  ebugging purpose
3860: 20 6f 6e 6c 79 2e 0a 2a 2a 0a 2a 2a 20 57 72 69   only..**.** Wri
3870: 74 65 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f  te the content o
3880: 66 20 61 20 64 6f 63 6c 69 73 74 20 74 6f 20 73  f a doclist to s
3890: 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e 0a  tandard output..
38a0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
38b0: 72 69 6e 74 44 6f 63 6c 69 73 74 28 44 6f 63 4c  rintDoclist(DocL
38c0: 69 73 74 20 2a 70 29 7b 0a 20 20 44 6f 63 4c 69  ist *p){.  DocLi
38d0: 73 74 52 65 61 64 65 72 20 72 3b 0a 20 20 63 6f  stReader r;.  co
38e0: 6e 73 74 20 63 68 61 72 20 2a 7a 53 65 70 20 3d  nst char *zSep =
38f0: 20 22 22 3b 0a 0a 20 20 72 65 61 64 65 72 49 6e   "";..  readerIn
3900: 69 74 28 26 72 2c 20 70 29 3b 0a 20 20 77 68 69  it(&r, p);.  whi
3910: 6c 65 28 20 21 61 74 45 6e 64 28 26 72 29 20 29  le( !atEnd(&r) )
3920: 7b 0a 20 20 20 20 73 71 6c 69 74 65 5f 69 6e 74  {.    sqlite_int
3930: 36 34 20 64 6f 63 69 64 20 3d 20 72 65 61 64 44  64 docid = readD
3940: 6f 63 69 64 28 26 72 29 3b 0a 20 20 20 20 69 66  ocid(&r);.    if
3950: 28 20 64 6f 63 69 64 3d 3d 30 20 29 7b 0a 20 20  ( docid==0 ){.  
3960: 20 20 20 20 73 6b 69 70 50 6f 73 69 74 69 6f 6e      skipPosition
3970: 4c 69 73 74 28 26 72 29 3b 0a 20 20 20 20 20 20  List(&r);.      
3980: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a  continue;.    }.
3990: 20 20 20 20 70 72 69 6e 74 66 28 22 25 73 25 6c      printf("%s%l
39a0: 6c 64 22 2c 20 7a 53 65 70 2c 20 64 6f 63 69 64  ld", zSep, docid
39b0: 29 3b 0a 20 20 20 20 7a 53 65 70 20 3d 20 20 22  );.    zSep =  "
39c0: 2c 22 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 69  ,";.    if( p->i
39d0: 54 79 70 65 3e 3d 44 4c 5f 50 4f 53 49 54 49 4f  Type>=DL_POSITIO
39e0: 4e 53 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  NS ){.      int 
39f0: 69 50 6f 73 2c 20 69 43 6f 6c 3b 0a 20 20 20 20  iPos, iCol;.    
3a00: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44    const char *zD
3a10: 69 76 20 3d 20 22 22 3b 0a 20 20 20 20 20 20 70  iv = "";.      p
3a20: 72 69 6e 74 66 28 22 28 22 29 3b 0a 20 20 20 20  rintf("(");.    
3a30: 20 20 77 68 69 6c 65 28 20 28 69 50 6f 73 20 3d    while( (iPos =
3a40: 20 72 65 61 64 50 6f 73 69 74 69 6f 6e 28 26 72   readPosition(&r
3a50: 2c 20 26 69 43 6f 6c 29 29 3e 3d 30 20 29 7b 0a  , &iCol))>=0 ){.
3a60: 20 20 20 20 20 20 20 20 70 72 69 6e 74 66 28 22          printf("
3a70: 25 73 25 64 3a 25 64 22 2c 20 7a 44 69 76 2c 20  %s%d:%d", zDiv, 
3a80: 69 43 6f 6c 2c 20 69 50 6f 73 29 3b 0a 20 20 20  iCol, iPos);.   
3a90: 20 20 20 20 20 7a 44 69 76 20 3d 20 22 3a 22 3b       zDiv = ":";
3aa0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70  .      }.      p
3ab0: 72 69 6e 74 66 28 22 29 22 29 3b 0a 20 20 20 20  rintf(")");.    
3ac0: 7d 0a 20 20 7d 0a 20 20 70 72 69 6e 74 66 28 22  }.  }.  printf("
3ad0: 5c 6e 22 29 3b 0a 20 20 66 66 6c 75 73 68 28 73  \n");.  fflush(s
3ae0: 74 64 6f 75 74 29 3b 0a 7d 0a 23 65 6e 64 69 66  tdout);.}.#endif
3af0: 20 2f 2a 20 53 51 4c 49 54 45 5f 44 45 42 55 47   /* SQLITE_DEBUG
3b00: 20 2a 2f 0a 0a 2f 2a 20 54 72 69 6d 20 74 68 65   */../* Trim the
3b10: 20 67 69 76 65 6e 20 64 6f 63 6c 69 73 74 20 74   given doclist t
3b20: 6f 20 63 6f 6e 74 61 69 6e 20 6f 6e 6c 79 20 70  o contain only p
3b30: 6f 73 69 74 69 6f 6e 73 20 69 6e 20 63 6f 6c 75  ositions in colu
3b40: 6d 6e 0a 20 2a 20 5b 69 52 65 73 74 72 69 63 74  mn. * [iRestrict
3b50: 43 6f 6c 75 6d 6e 5d 2e 20 2a 2f 0a 73 74 61 74  Column]. */.stat
3b60: 69 63 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 52  ic void docListR
3b70: 65 73 74 72 69 63 74 43 6f 6c 75 6d 6e 28 44 6f  estrictColumn(Do
3b80: 63 4c 69 73 74 20 2a 69 6e 2c 20 69 6e 74 20 69  cList *in, int i
3b90: 52 65 73 74 72 69 63 74 43 6f 6c 75 6d 6e 29 7b  RestrictColumn){
3ba0: 0a 20 20 44 6f 63 4c 69 73 74 52 65 61 64 65 72  .  DocListReader
3bb0: 20 72 3b 0a 20 20 44 6f 63 4c 69 73 74 20 6f 75   r;.  DocList ou
3bc0: 74 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 69 6e  t;..  assert( in
3bd0: 2d 3e 69 54 79 70 65 3e 3d 44 4c 5f 50 4f 53 49  ->iType>=DL_POSI
3be0: 54 49 4f 4e 53 20 29 3b 0a 20 20 72 65 61 64 65  TIONS );.  reade
3bf0: 72 49 6e 69 74 28 26 72 2c 20 69 6e 29 3b 0a 20  rInit(&r, in);. 
3c00: 20 64 6f 63 4c 69 73 74 49 6e 69 74 28 26 6f 75   docListInit(&ou
3c10: 74 2c 20 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 2c  t, DL_POSITIONS,
3c20: 20 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 20 20 77 68   NULL, 0);..  wh
3c30: 69 6c 65 28 20 21 61 74 45 6e 64 28 26 72 29 20  ile( !atEnd(&r) 
3c40: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 5f 69 6e  ){.    sqlite_in
3c50: 74 36 34 20 69 44 6f 63 69 64 20 3d 20 72 65 61  t64 iDocid = rea
3c60: 64 44 6f 63 69 64 28 26 72 29 3b 0a 20 20 20 20  dDocid(&r);.    
3c70: 69 6e 74 20 69 50 6f 73 2c 20 69 43 6f 6c 75 6d  int iPos, iColum
3c80: 6e 3b 0a 0a 20 20 20 20 64 6f 63 4c 69 73 74 41  n;..    docListA
3c90: 64 64 44 6f 63 69 64 28 26 6f 75 74 2c 20 69 44  ddDocid(&out, iD
3ca0: 6f 63 69 64 29 3b 0a 20 20 20 20 77 68 69 6c 65  ocid);.    while
3cb0: 28 20 28 69 50 6f 73 20 3d 20 72 65 61 64 50 6f  ( (iPos = readPo
3cc0: 73 69 74 69 6f 6e 28 26 72 2c 20 26 69 43 6f 6c  sition(&r, &iCol
3cd0: 75 6d 6e 29 29 20 21 3d 20 2d 31 20 29 7b 0a 20  umn)) != -1 ){. 
3ce0: 20 20 20 20 20 69 66 28 20 69 43 6f 6c 75 6d 6e       if( iColumn
3cf0: 3d 3d 69 52 65 73 74 72 69 63 74 43 6f 6c 75 6d  ==iRestrictColum
3d00: 6e 20 29 7b 0a 20 20 20 20 20 20 20 20 64 6f 63  n ){.        doc
3d10: 4c 69 73 74 41 64 64 50 6f 73 28 26 6f 75 74 2c  ListAddPos(&out,
3d20: 20 69 43 6f 6c 75 6d 6e 2c 20 69 50 6f 73 29 3b   iColumn, iPos);
3d30: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3d40: 20 7d 0a 0a 20 20 64 6f 63 4c 69 73 74 44 65 73   }..  docListDes
3d50: 74 72 6f 79 28 69 6e 29 3b 0a 20 20 2a 69 6e 20  troy(in);.  *in 
3d60: 3d 20 6f 75 74 3b 0a 7d 0a 0a 2f 2a 20 54 72 69  = out;.}../* Tri
3d70: 6d 20 74 68 65 20 67 69 76 65 6e 20 64 6f 63 6c  m the given docl
3d80: 69 73 74 20 62 79 20 64 69 73 63 61 72 64 69 6e  ist by discardin
3d90: 67 20 61 6e 79 20 64 6f 63 69 64 73 20 77 69 74  g any docids wit
3da0: 68 6f 75 74 20 61 6e 79 20 72 65 6d 61 69 6e 69  hout any remaini
3db0: 6e 67 0a 20 2a 20 70 6f 73 69 74 69 6f 6e 73 2e  ng. * positions.
3dc0: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
3dd0: 64 6f 63 4c 69 73 74 44 69 73 63 61 72 64 45 6d  docListDiscardEm
3de0: 70 74 79 28 44 6f 63 4c 69 73 74 20 2a 69 6e 29  pty(DocList *in)
3df0: 20 7b 0a 20 20 44 6f 63 4c 69 73 74 52 65 61 64   {.  DocListRead
3e00: 65 72 20 72 3b 0a 20 20 44 6f 63 4c 69 73 74 20  er r;.  DocList 
3e10: 6f 75 74 3b 0a 0a 20 20 2f 2a 20 54 4f 44 4f 3a  out;..  /* TODO:
3e20: 20 49 74 20 77 6f 75 6c 64 20 62 65 20 6e 69 63   It would be nic
3e30: 65 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 74  e to implement t
3e40: 68 69 73 20 6f 70 65 72 61 74 69 6f 6e 20 69 6e  his operation in
3e50: 20 70 6c 61 63 65 3b 20 74 68 61 74 0a 20 20 20   place; that.   
3e60: 2a 20 63 6f 75 6c 64 20 73 61 76 65 20 61 20 73  * could save a s
3e70: 69 67 6e 69 66 69 63 61 6e 74 20 61 6d 6f 75 6e  ignificant amoun
3e80: 74 20 6f 66 20 6d 65 6d 6f 72 79 20 69 6e 20 71  t of memory in q
3e90: 75 65 72 69 65 73 20 77 69 74 68 20 6c 6f 6e 67  ueries with long
3ea0: 20 64 6f 63 6c 69 73 74 73 2e 20 2a 2f 0a 20 20   doclists. */.  
3eb0: 61 73 73 65 72 74 28 20 69 6e 2d 3e 69 54 79 70  assert( in->iTyp
3ec0: 65 3e 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20  e>=DL_POSITIONS 
3ed0: 29 3b 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28  );.  readerInit(
3ee0: 26 72 2c 20 69 6e 29 3b 0a 20 20 64 6f 63 4c 69  &r, in);.  docLi
3ef0: 73 74 49 6e 69 74 28 26 6f 75 74 2c 20 44 4c 5f  stInit(&out, DL_
3f00: 50 4f 53 49 54 49 4f 4e 53 2c 20 4e 55 4c 4c 2c  POSITIONS, NULL,
3f10: 20 30 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 21   0);..  while( !
3f20: 61 74 45 6e 64 28 26 72 29 20 29 7b 0a 20 20 20  atEnd(&r) ){.   
3f30: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 44   sqlite_int64 iD
3f40: 6f 63 69 64 20 3d 20 72 65 61 64 44 6f 63 69 64  ocid = readDocid
3f50: 28 26 72 29 3b 0a 20 20 20 20 69 6e 74 20 6d 61  (&r);.    int ma
3f60: 74 63 68 20 3d 20 30 3b 0a 20 20 20 20 69 6e 74  tch = 0;.    int
3f70: 20 69 50 6f 73 2c 20 69 43 6f 6c 75 6d 6e 3b 0a   iPos, iColumn;.
3f80: 20 20 20 20 77 68 69 6c 65 28 20 28 69 50 6f 73      while( (iPos
3f90: 20 3d 20 72 65 61 64 50 6f 73 69 74 69 6f 6e 28   = readPosition(
3fa0: 26 72 2c 20 26 69 43 6f 6c 75 6d 6e 29 29 20 21  &r, &iColumn)) !
3fb0: 3d 20 2d 31 20 29 7b 0a 20 20 20 20 20 20 69 66  = -1 ){.      if
3fc0: 28 20 21 6d 61 74 63 68 20 29 7b 0a 20 20 20 20  ( !match ){.    
3fd0: 20 20 20 20 64 6f 63 4c 69 73 74 41 64 64 44 6f      docListAddDo
3fe0: 63 69 64 28 26 6f 75 74 2c 20 69 44 6f 63 69 64  cid(&out, iDocid
3ff0: 29 3b 0a 20 20 20 20 20 20 20 20 6d 61 74 63 68  );.        match
4000: 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = 1;.      }.  
4010: 20 20 20 20 64 6f 63 4c 69 73 74 41 64 64 50 6f      docListAddPo
4020: 73 28 26 6f 75 74 2c 20 69 43 6f 6c 75 6d 6e 2c  s(&out, iColumn,
4030: 20 69 50 6f 73 29 3b 0a 20 20 20 20 7d 0a 20 20   iPos);.    }.  
4040: 7d 0a 0a 20 20 64 6f 63 4c 69 73 74 44 65 73 74  }..  docListDest
4050: 72 6f 79 28 69 6e 29 3b 0a 20 20 2a 69 6e 20 3d  roy(in);.  *in =
4060: 20 6f 75 74 3b 0a 7d 0a 0a 2f 2a 20 48 65 6c 70   out;.}../* Help
4070: 65 72 20 66 75 6e 63 74 69 6f 6e 20 66 6f 72 20  er function for 
4080: 64 6f 63 4c 69 73 74 55 70 64 61 74 65 28 29 20  docListUpdate() 
4090: 61 6e 64 20 64 6f 63 4c 69 73 74 41 63 63 75 6d  and docListAccum
40a0: 75 6c 61 74 65 28 29 2e 0a 2a 2a 20 53 70 6c 69  ulate()..** Spli
40b0: 63 65 73 20 61 20 64 6f 63 6c 69 73 74 20 65 6c  ces a doclist el
40c0: 65 6d 65 6e 74 20 69 6e 74 6f 20 74 68 65 20 64  ement into the d
40d0: 6f 63 6c 69 73 74 20 72 65 70 72 65 73 65 6e 74  oclist represent
40e0: 65 64 20 62 79 20 72 2c 0a 2a 2a 20 6c 65 61 76  ed by r,.** leav
40f0: 69 6e 67 20 72 20 70 6f 69 6e 74 69 6e 67 20 61  ing r pointing a
4100: 66 74 65 72 20 74 68 65 20 6e 65 77 6c 79 20 73  fter the newly s
4110: 70 6c 69 63 65 64 20 65 6c 65 6d 65 6e 74 2e 0a  pliced element..
4120: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  */.static void d
4130: 6f 63 4c 69 73 74 53 70 6c 69 63 65 45 6c 65 6d  ocListSpliceElem
4140: 65 6e 74 28 44 6f 63 4c 69 73 74 52 65 61 64 65  ent(DocListReade
4150: 72 20 2a 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74  r *r, sqlite_int
4160: 36 34 20 69 44 6f 63 69 64 2c 0a 20 20 20 20 20  64 iDocid,.     
4170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4180: 20 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73              cons
4190: 74 20 63 68 61 72 20 2a 70 53 6f 75 72 63 65 2c  t char *pSource,
41a0: 20 69 6e 74 20 6e 53 6f 75 72 63 65 29 7b 0a 20   int nSource){. 
41b0: 20 44 6f 63 4c 69 73 74 20 2a 64 20 3d 20 72 2d   DocList *d = r-
41c0: 3e 70 44 6f 63 6c 69 73 74 3b 0a 20 20 63 68 61  >pDoclist;.  cha
41d0: 72 20 2a 70 54 61 72 67 65 74 3b 0a 20 20 69 6e  r *pTarget;.  in
41e0: 74 20 6e 54 61 72 67 65 74 2c 20 66 6f 75 6e 64  t nTarget, found
41f0: 3b 0a 0a 20 20 66 6f 75 6e 64 20 3d 20 73 6b 69  ;..  found = ski
4200: 70 54 6f 44 6f 63 69 64 28 72 2c 20 69 44 6f 63  pToDocid(r, iDoc
4210: 69 64 29 3b 0a 0a 20 20 2f 2a 20 44 65 73 63 72  id);..  /* Descr
4220: 69 62 65 20 73 6c 69 63 65 20 69 6e 20 64 20 74  ibe slice in d t
4230: 6f 20 70 6c 61 63 65 20 70 53 6f 75 72 63 65 2f  o place pSource/
4240: 6e 53 6f 75 72 63 65 2e 20 2a 2f 0a 20 20 70 54  nSource. */.  pT
4250: 61 72 67 65 74 20 3d 20 72 2d 3e 70 3b 0a 20 20  arget = r->p;.  
4260: 69 66 28 20 66 6f 75 6e 64 20 29 7b 0a 20 20 20  if( found ){.   
4270: 20 73 6b 69 70 44 6f 63 75 6d 65 6e 74 28 72 29   skipDocument(r)
4280: 3b 0a 20 20 20 20 6e 54 61 72 67 65 74 20 3d 20  ;.    nTarget = 
4290: 72 2d 3e 70 2d 70 54 61 72 67 65 74 3b 0a 20 20  r->p-pTarget;.  
42a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 6e 54 61 72 67  }else{.    nTarg
42b0: 65 74 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f  et = 0;.  }..  /
42c0: 2a 20 54 68 65 20 73 65 6e 73 65 20 6f 66 20 74  * The sense of t
42d0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20  he following is 
42e0: 74 68 61 74 20 74 68 65 72 65 20 61 72 65 20 74  that there are t
42f0: 68 72 65 65 20 70 6f 73 73 69 62 69 6c 69 74 69  hree possibiliti
4300: 65 73 2e 0a 20 20 2a 2a 20 49 66 20 6e 54 61 72  es..  ** If nTar
4310: 67 65 74 3d 3d 6e 53 6f 75 72 63 65 2c 20 77 65  get==nSource, we
4320: 20 73 68 6f 75 6c 64 20 6e 6f 74 20 6d 6f 76 65   should not move
4330: 20 61 6e 79 20 6d 65 6d 6f 72 79 20 6e 6f 72 20   any memory nor 
4340: 72 65 61 6c 6c 6f 63 2e 0a 20 20 2a 2a 20 49 66  realloc..  ** If
4350: 20 6e 54 61 72 67 65 74 3e 6e 53 6f 75 72 63 65   nTarget>nSource
4360: 2c 20 74 72 69 6d 20 74 61 72 67 65 74 20 61 6e  , trim target an
4370: 64 20 72 65 61 6c 6c 6f 63 2e 0a 20 20 2a 2a 20  d realloc..  ** 
4380: 49 66 20 6e 54 61 72 67 65 74 3c 6e 53 6f 75 72  If nTarget<nSour
4390: 63 65 2c 20 72 65 61 6c 6c 6f 63 20 74 68 65 6e  ce, realloc then
43a0: 20 65 78 70 61 6e 64 20 74 61 72 67 65 74 2e 0a   expand target..
43b0: 20 20 2a 2f 0a 20 20 69 66 28 20 6e 54 61 72 67    */.  if( nTarg
43c0: 65 74 3e 6e 53 6f 75 72 63 65 20 29 7b 0a 20 20  et>nSource ){.  
43d0: 20 20 6d 65 6d 6d 6f 76 65 28 70 54 61 72 67 65    memmove(pTarge
43e0: 74 2b 6e 53 6f 75 72 63 65 2c 20 70 54 61 72 67  t+nSource, pTarg
43f0: 65 74 2b 6e 54 61 72 67 65 74 2c 20 64 6f 63 4c  et+nTarget, docL
4400: 69 73 74 45 6e 64 28 64 29 2d 28 70 54 61 72 67  istEnd(d)-(pTarg
4410: 65 74 2b 6e 54 61 72 67 65 74 29 29 3b 0a 20 20  et+nTarget));.  
4420: 7d 0a 20 20 69 66 28 20 6e 54 61 72 67 65 74 21  }.  if( nTarget!
4430: 3d 6e 53 6f 75 72 63 65 20 29 7b 0a 20 20 20 20  =nSource ){.    
4440: 69 6e 74 20 69 44 6f 63 6c 69 73 74 20 3d 20 70  int iDoclist = p
4450: 54 61 72 67 65 74 2d 64 2d 3e 70 44 61 74 61 3b  Target-d->pData;
4460: 0a 20 20 20 20 64 2d 3e 70 44 61 74 61 20 3d 20  .    d->pData = 
4470: 72 65 61 6c 6c 6f 63 28 64 2d 3e 70 44 61 74 61  realloc(d->pData
4480: 2c 20 64 2d 3e 6e 44 61 74 61 2b 6e 53 6f 75 72  , d->nData+nSour
4490: 63 65 2d 6e 54 61 72 67 65 74 29 3b 0a 20 20 20  ce-nTarget);.   
44a0: 20 70 54 61 72 67 65 74 20 3d 20 64 2d 3e 70 44   pTarget = d->pD
44b0: 61 74 61 2b 69 44 6f 63 6c 69 73 74 3b 0a 20 20  ata+iDoclist;.  
44c0: 7d 0a 20 20 69 66 28 20 6e 54 61 72 67 65 74 3c  }.  if( nTarget<
44d0: 6e 53 6f 75 72 63 65 20 29 7b 0a 20 20 20 20 6d  nSource ){.    m
44e0: 65 6d 6d 6f 76 65 28 70 54 61 72 67 65 74 2b 6e  emmove(pTarget+n
44f0: 53 6f 75 72 63 65 2c 20 70 54 61 72 67 65 74 2b  Source, pTarget+
4500: 6e 54 61 72 67 65 74 2c 20 64 6f 63 4c 69 73 74  nTarget, docList
4510: 45 6e 64 28 64 29 2d 28 70 54 61 72 67 65 74 2b  End(d)-(pTarget+
4520: 6e 54 61 72 67 65 74 29 29 3b 0a 20 20 7d 0a 0a  nTarget));.  }..
4530: 20 20 6d 65 6d 63 70 79 28 70 54 61 72 67 65 74    memcpy(pTarget
4540: 2c 20 70 53 6f 75 72 63 65 2c 20 6e 53 6f 75 72  , pSource, nSour
4550: 63 65 29 3b 0a 20 20 64 2d 3e 6e 44 61 74 61 20  ce);.  d->nData 
4560: 2b 3d 20 6e 53 6f 75 72 63 65 2d 6e 54 61 72 67  += nSource-nTarg
4570: 65 74 3b 0a 20 20 72 2d 3e 70 20 3d 20 70 54 61  et;.  r->p = pTa
4580: 72 67 65 74 2b 6e 53 6f 75 72 63 65 3b 0a 7d 0a  rget+nSource;.}.
4590: 0a 2f 2a 20 49 6e 73 65 72 74 2f 75 70 64 61 74  ./* Insert/updat
45a0: 65 20 70 55 70 64 61 74 65 20 69 6e 74 6f 20 74  e pUpdate into t
45b0: 68 65 20 64 6f 63 6c 69 73 74 2e 20 2a 2f 0a 73  he doclist. */.s
45c0: 74 61 74 69 63 20 76 6f 69 64 20 64 6f 63 4c 69  tatic void docLi
45d0: 73 74 55 70 64 61 74 65 28 44 6f 63 4c 69 73 74  stUpdate(DocList
45e0: 20 2a 64 2c 20 44 6f 63 4c 69 73 74 20 2a 70 55   *d, DocList *pU
45f0: 70 64 61 74 65 29 7b 0a 20 20 44 6f 63 4c 69 73  pdate){.  DocLis
4600: 74 52 65 61 64 65 72 20 72 65 61 64 65 72 3b 0a  tReader reader;.
4610: 0a 20 20 61 73 73 65 72 74 28 20 64 21 3d 4e 55  .  assert( d!=NU
4620: 4c 4c 20 26 26 20 70 55 70 64 61 74 65 21 3d 4e  LL && pUpdate!=N
4630: 55 4c 4c 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ULL );.  assert(
4640: 20 64 2d 3e 69 54 79 70 65 3d 3d 70 55 70 64 61   d->iType==pUpda
4650: 74 65 2d 3e 69 54 79 70 65 29 3b 0a 0a 20 20 72  te->iType);..  r
4660: 65 61 64 65 72 49 6e 69 74 28 26 72 65 61 64 65  eaderInit(&reade
4670: 72 2c 20 64 29 3b 0a 20 20 64 6f 63 4c 69 73 74  r, d);.  docList
4680: 53 70 6c 69 63 65 45 6c 65 6d 65 6e 74 28 26 72  SpliceElement(&r
4690: 65 61 64 65 72 2c 20 66 69 72 73 74 44 6f 63 69  eader, firstDoci
46a0: 64 28 70 55 70 64 61 74 65 29 2c 0a 20 20 20 20  d(pUpdate),.    
46b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
46c0: 20 20 20 70 55 70 64 61 74 65 2d 3e 70 44 61 74     pUpdate->pDat
46d0: 61 2c 20 70 55 70 64 61 74 65 2d 3e 6e 44 61 74  a, pUpdate->nDat
46e0: 61 29 3b 0a 7d 0a 0a 2f 2a 20 50 72 6f 70 61 67  a);.}../* Propag
46f0: 61 74 65 20 65 6c 65 6d 65 6e 74 73 20 66 72 6f  ate elements fro
4700: 6d 20 70 55 70 64 61 74 65 20 74 6f 20 70 41 63  m pUpdate to pAc
4710: 63 2c 20 6f 76 65 72 77 72 69 74 69 6e 67 20 65  c, overwriting e
4720: 6c 65 6d 65 6e 74 73 20 77 69 74 68 0a 2a 2a 20  lements with.** 
4730: 6d 61 74 63 68 69 6e 67 20 64 6f 63 69 64 73 2e  matching docids.
4740: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
4750: 64 6f 63 4c 69 73 74 41 63 63 75 6d 75 6c 61 74  docListAccumulat
4760: 65 28 44 6f 63 4c 69 73 74 20 2a 70 41 63 63 2c  e(DocList *pAcc,
4770: 20 44 6f 63 4c 69 73 74 20 2a 70 55 70 64 61 74   DocList *pUpdat
4780: 65 29 7b 0a 20 20 44 6f 63 4c 69 73 74 52 65 61  e){.  DocListRea
4790: 64 65 72 20 61 63 63 52 65 61 64 65 72 2c 20 75  der accReader, u
47a0: 70 64 61 74 65 52 65 61 64 65 72 3b 0a 0a 20 20  pdateReader;..  
47b0: 2f 2a 20 48 61 6e 64 6c 65 20 65 64 67 65 20 63  /* Handle edge c
47c0: 61 73 65 73 20 77 68 65 72 65 20 6f 6e 65 20 64  ases where one d
47d0: 6f 63 6c 69 73 74 20 69 73 20 65 6d 70 74 79 2e  oclist is empty.
47e0: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 41   */.  assert( pA
47f0: 63 63 21 3d 4e 55 4c 4c 20 29 3b 0a 20 20 69 66  cc!=NULL );.  if
4800: 28 20 70 55 70 64 61 74 65 3d 3d 4e 55 4c 4c 20  ( pUpdate==NULL 
4810: 7c 7c 20 70 55 70 64 61 74 65 2d 3e 6e 44 61 74  || pUpdate->nDat
4820: 61 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20  a==0 ) return;. 
4830: 20 69 66 28 20 70 41 63 63 2d 3e 6e 44 61 74 61   if( pAcc->nData
4840: 3d 3d 30 20 29 7b 0a 20 20 20 20 70 41 63 63 2d  ==0 ){.    pAcc-
4850: 3e 70 44 61 74 61 20 3d 20 6d 61 6c 6c 6f 63 28  >pData = malloc(
4860: 70 55 70 64 61 74 65 2d 3e 6e 44 61 74 61 29 3b  pUpdate->nData);
4870: 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 41 63 63  .    memcpy(pAcc
4880: 2d 3e 70 44 61 74 61 2c 20 70 55 70 64 61 74 65  ->pData, pUpdate
4890: 2d 3e 70 44 61 74 61 2c 20 70 55 70 64 61 74 65  ->pData, pUpdate
48a0: 2d 3e 6e 44 61 74 61 29 3b 0a 20 20 20 20 70 41  ->nData);.    pA
48b0: 63 63 2d 3e 6e 44 61 74 61 20 3d 20 70 55 70 64  cc->nData = pUpd
48c0: 61 74 65 2d 3e 6e 44 61 74 61 3b 0a 20 20 20 20  ate->nData;.    
48d0: 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 72  return;.  }..  r
48e0: 65 61 64 65 72 49 6e 69 74 28 26 61 63 63 52 65  eaderInit(&accRe
48f0: 61 64 65 72 2c 20 70 41 63 63 29 3b 0a 20 20 72  ader, pAcc);.  r
4900: 65 61 64 65 72 49 6e 69 74 28 26 75 70 64 61 74  eaderInit(&updat
4910: 65 52 65 61 64 65 72 2c 20 70 55 70 64 61 74 65  eReader, pUpdate
4920: 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 21 61 74  );..  while( !at
4930: 45 6e 64 28 26 75 70 64 61 74 65 52 65 61 64 65  End(&updateReade
4940: 72 29 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a  r) ){.    char *
4950: 70 53 6f 75 72 63 65 20 3d 20 75 70 64 61 74 65  pSource = update
4960: 52 65 61 64 65 72 2e 70 3b 0a 20 20 20 20 73 71  Reader.p;.    sq
4970: 6c 69 74 65 5f 69 6e 74 36 34 20 69 44 6f 63 69  lite_int64 iDoci
4980: 64 20 3d 20 72 65 61 64 44 6f 63 69 64 28 26 75  d = readDocid(&u
4990: 70 64 61 74 65 52 65 61 64 65 72 29 3b 0a 20 20  pdateReader);.  
49a0: 20 20 73 6b 69 70 50 6f 73 69 74 69 6f 6e 4c 69    skipPositionLi
49b0: 73 74 28 26 75 70 64 61 74 65 52 65 61 64 65 72  st(&updateReader
49c0: 29 3b 0a 20 20 20 20 64 6f 63 4c 69 73 74 53 70  );.    docListSp
49d0: 6c 69 63 65 45 6c 65 6d 65 6e 74 28 26 61 63 63  liceElement(&acc
49e0: 52 65 61 64 65 72 2c 20 69 44 6f 63 69 64 2c 20  Reader, iDocid, 
49f0: 70 53 6f 75 72 63 65 2c 20 75 70 64 61 74 65 52  pSource, updateR
4a00: 65 61 64 65 72 2e 70 2d 70 53 6f 75 72 63 65 29  eader.p-pSource)
4a10: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  ;.  }.}../*.** R
4a20: 65 61 64 20 74 68 65 20 6e 65 78 74 20 64 6f 63  ead the next doc
4a30: 69 64 20 6f 66 66 20 6f 66 20 70 49 6e 2e 20 20  id off of pIn.  
4a40: 52 65 74 75 72 6e 20 30 20 69 66 20 77 65 20 72  Return 0 if we r
4a50: 65 61 63 68 20 74 68 65 20 65 6e 64 2e 0a 2a 0a  each the end..*.
4a60: 2a 20 54 4f 44 4f 3a 20 54 68 69 73 20 61 73 73  * TODO: This ass
4a70: 75 6d 65 73 20 74 68 61 74 20 64 6f 63 69 64 73  umes that docids
4a80: 20 61 72 65 20 6e 65 76 65 72 20 30 2c 20 62 75   are never 0, bu
4a90: 74 20 74 68 65 79 20 6d 61 79 20 61 63 74 75 61  t they may actua
4aa0: 6c 6c 79 20 62 65 20 30 20 73 69 6e 63 65 0a 2a  lly be 0 since.*
4ab0: 20 75 73 65 72 73 20 63 61 6e 20 63 68 6f 6f 73   users can choos
4ac0: 65 20 64 6f 63 69 64 73 20 77 68 65 6e 20 69 6e  e docids when in
4ad0: 73 65 72 74 69 6e 67 20 69 6e 74 6f 20 61 20 66  serting into a f
4ae0: 75 6c 6c 2d 74 65 78 74 20 74 61 62 6c 65 2e 20  ull-text table. 
4af0: 20 46 69 78 20 74 68 69 73 2e 0a 2a 2f 0a 73 74   Fix this..*/.st
4b00: 61 74 69 63 20 73 71 6c 69 74 65 5f 69 6e 74 36  atic sqlite_int6
4b10: 34 20 6e 65 78 74 44 6f 63 69 64 28 44 6f 63 4c  4 nextDocid(DocL
4b20: 69 73 74 52 65 61 64 65 72 20 2a 70 49 6e 29 7b  istReader *pIn){
4b30: 0a 20 20 73 6b 69 70 50 6f 73 69 74 69 6f 6e 4c  .  skipPositionL
4b40: 69 73 74 28 70 49 6e 29 3b 0a 20 20 72 65 74 75  ist(pIn);.  retu
4b50: 72 6e 20 61 74 45 6e 64 28 70 49 6e 29 20 3f 20  rn atEnd(pIn) ? 
4b60: 30 20 3a 20 72 65 61 64 44 6f 63 69 64 28 70 49  0 : readDocid(pI
4b70: 6e 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 70 4c 65  n);.}../*.** pLe
4b80: 66 74 20 61 6e 64 20 70 52 69 67 68 74 20 61 72  ft and pRight ar
4b90: 65 20 74 77 6f 20 44 6f 63 4c 69 73 74 52 65 61  e two DocListRea
4ba0: 64 65 72 73 20 74 68 61 74 20 61 72 65 20 70 6f  ders that are po
4bb0: 69 6e 74 69 6e 67 20 74 6f 0a 2a 2a 20 70 6f 73  inting to.** pos
4bc0: 69 74 69 6f 6e 73 20 6c 69 73 74 73 20 6f 66 20  itions lists of 
4bd0: 74 68 65 20 73 61 6d 65 20 64 6f 63 75 6d 65 6e  the same documen
4be0: 74 3a 20 69 44 6f 63 69 64 2e 20 0a 2a 2a 0a 2a  t: iDocid. .**.*
4bf0: 2a 20 49 66 20 74 68 65 72 65 20 61 72 65 20 6e  * If there are n
4c00: 6f 20 69 6e 73 74 61 6e 63 65 73 20 69 6e 20 70  o instances in p
4c10: 4c 65 66 74 20 6f 72 20 70 52 69 67 68 74 20 77  Left or pRight w
4c20: 68 65 72 65 20 74 68 65 20 70 6f 73 69 74 69 6f  here the positio
4c30: 6e 0a 2a 2a 20 6f 66 20 70 4c 65 66 74 20 69 73  n.** of pLeft is
4c40: 20 6f 6e 65 20 6c 65 73 73 20 74 68 61 6e 20 74   one less than t
4c50: 68 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66 20 70  he position of p
4c60: 52 69 67 68 74 2c 20 74 68 65 6e 20 74 68 69 73  Right, then this
4c70: 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 61 64 64 73  .** routine adds
4c80: 20 6e 6f 74 68 69 6e 67 20 74 6f 20 70 4f 75 74   nothing to pOut
4c90: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65  ..**.** If there
4ca0: 20 61 72 65 20 6f 6e 65 20 6f 72 20 6d 6f 72 65   are one or more
4cb0: 20 69 6e 73 74 61 6e 63 65 73 20 77 68 65 72 65   instances where
4cc0: 20 70 6f 73 69 74 69 6f 6e 73 20 66 72 6f 6d 20   positions from 
4cd0: 70 4c 65 66 74 0a 2a 2a 20 61 72 65 20 65 78 61  pLeft.** are exa
4ce0: 63 74 6c 79 20 6f 6e 65 20 6c 65 73 73 20 74 68  ctly one less th
4cf0: 61 6e 20 70 6f 73 69 74 69 6f 6e 73 20 66 72 6f  an positions fro
4d00: 6d 20 70 52 69 67 68 74 2c 20 74 68 65 6e 20 61  m pRight, then a
4d10: 64 64 20 61 20 6e 65 77 0a 2a 2a 20 64 6f 63 75  dd a new.** docu
4d20: 6d 65 6e 74 20 72 65 63 6f 72 64 20 74 6f 20 70  ment record to p
4d30: 4f 75 74 2e 20 20 49 66 20 70 4f 75 74 20 77 61  Out.  If pOut wa
4d40: 6e 74 73 20 74 6f 20 68 6f 6c 64 20 70 6f 73 69  nts to hold posi
4d50: 74 69 6f 6e 73 2c 20 74 68 65 6e 0a 2a 2a 20 69  tions, then.** i
4d60: 6e 63 6c 75 64 65 20 74 68 65 20 70 6f 73 69 74  nclude the posit
4d70: 69 6f 6e 73 20 66 72 6f 6d 20 70 52 69 67 68 74  ions from pRight
4d80: 20 74 68 61 74 20 61 72 65 20 6f 6e 65 20 6d 6f   that are one mo
4d90: 72 65 20 74 68 61 6e 20 61 0a 2a 2a 20 70 6f 73  re than a.** pos
4da0: 69 74 69 6f 6e 20 69 6e 20 70 4c 65 66 74 2e 20  ition in pLeft. 
4db0: 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 3a   In other words:
4dc0: 20 20 70 52 69 67 68 74 2e 69 50 6f 73 3d 3d 70    pRight.iPos==p
4dd0: 4c 65 66 74 2e 69 50 6f 73 2b 31 2e 0a 2a 2a 0a  Left.iPos+1..**.
4de0: 2a 2a 20 70 4c 65 66 74 20 61 6e 64 20 70 52 69  ** pLeft and pRi
4df0: 67 68 74 20 61 72 65 20 6c 65 66 74 20 70 6f 69  ght are left poi
4e00: 6e 74 69 6e 67 20 61 74 20 74 68 65 20 6e 65 78  nting at the nex
4e10: 74 20 64 6f 63 75 6d 65 6e 74 20 72 65 63 6f 72  t document recor
4e20: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
4e30: 64 20 6d 65 72 67 65 50 6f 73 4c 69 73 74 28 0a  d mergePosList(.
4e40: 20 20 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20    DocListReader 
4e50: 2a 70 4c 65 66 74 2c 20 20 20 20 2f 2a 20 4c 65  *pLeft,    /* Le
4e60: 66 74 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74  ft position list
4e70: 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 52 65 61   */.  DocListRea
4e80: 64 65 72 20 2a 70 52 69 67 68 74 2c 20 20 20 2f  der *pRight,   /
4e90: 2a 20 52 69 67 68 74 20 70 6f 73 69 74 69 6f 6e  * Right position
4ea0: 20 6c 69 73 74 20 2a 2f 0a 20 20 73 71 6c 69 74   list */.  sqlit
4eb0: 65 5f 69 6e 74 36 34 20 69 44 6f 63 69 64 2c 20  e_int64 iDocid, 
4ec0: 20 20 20 20 2f 2a 20 54 68 65 20 64 6f 63 69 64      /* The docid
4ed0: 20 66 72 6f 6d 20 70 4c 65 66 74 20 61 6e 64 20   from pLeft and 
4ee0: 70 52 69 67 68 74 20 2a 2f 0a 20 20 44 6f 63 4c  pRight */.  DocL
4ef0: 69 73 74 20 2a 70 4f 75 74 20 20 20 20 20 20 20  ist *pOut       
4f00: 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68       /* Write th
4f10: 65 20 6d 65 72 67 65 64 20 64 6f 63 75 6d 65 6e  e merged documen
4f20: 74 20 72 65 63 6f 72 64 20 68 65 72 65 20 2a 2f  t record here */
4f30: 0a 29 7b 0a 20 20 69 6e 74 20 69 4c 65 66 74 43  .){.  int iLeftC
4f40: 6f 6c 2c 20 69 4c 65 66 74 50 6f 73 20 3d 20 72  ol, iLeftPos = r
4f50: 65 61 64 50 6f 73 69 74 69 6f 6e 28 70 4c 65 66  eadPosition(pLef
4f60: 74 2c 20 26 69 4c 65 66 74 43 6f 6c 29 3b 0a 20  t, &iLeftCol);. 
4f70: 20 69 6e 74 20 69 52 69 67 68 74 43 6f 6c 2c 20   int iRightCol, 
4f80: 69 52 69 67 68 74 50 6f 73 20 3d 20 72 65 61 64  iRightPos = read
4f90: 50 6f 73 69 74 69 6f 6e 28 70 52 69 67 68 74 2c  Position(pRight,
4fa0: 20 26 69 52 69 67 68 74 43 6f 6c 29 3b 0a 20 20   &iRightCol);.  
4fb0: 69 6e 74 20 6d 61 74 63 68 20 3d 20 30 3b 0a 0a  int match = 0;..
4fc0: 20 20 2f 2a 20 4c 6f 6f 70 20 75 6e 74 69 6c 20    /* Loop until 
4fd0: 77 65 27 76 65 20 72 65 61 63 68 65 64 20 74 68  we've reached th
4fe0: 65 20 65 6e 64 20 6f 66 20 62 6f 74 68 20 70 6f  e end of both po
4ff0: 73 69 74 69 6f 6e 20 6c 69 73 74 73 2e 20 2a 2f  sition lists. */
5000: 0a 20 20 77 68 69 6c 65 28 20 69 4c 65 66 74 50  .  while( iLeftP
5010: 6f 73 21 3d 2d 31 20 26 26 20 69 52 69 67 68 74  os!=-1 && iRight
5020: 50 6f 73 21 3d 2d 31 20 29 7b 0a 20 20 20 20 69  Pos!=-1 ){.    i
5030: 66 28 20 69 4c 65 66 74 43 6f 6c 3d 3d 69 52 69  f( iLeftCol==iRi
5040: 67 68 74 43 6f 6c 20 26 26 20 69 4c 65 66 74 50  ghtCol && iLeftP
5050: 6f 73 2b 31 3d 3d 69 52 69 67 68 74 50 6f 73 20  os+1==iRightPos 
5060: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 21 6d 61  ){.      if( !ma
5070: 74 63 68 20 29 7b 0a 20 20 20 20 20 20 20 20 64  tch ){.        d
5080: 6f 63 4c 69 73 74 41 64 64 44 6f 63 69 64 28 70  ocListAddDocid(p
5090: 4f 75 74 2c 20 69 44 6f 63 69 64 29 3b 0a 20 20  Out, iDocid);.  
50a0: 20 20 20 20 20 20 6d 61 74 63 68 20 3d 20 31 3b        match = 1;
50b0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
50c0: 66 28 20 70 4f 75 74 2d 3e 69 54 79 70 65 3e 3d  f( pOut->iType>=
50d0: 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 29 7b 0a  DL_POSITIONS ){.
50e0: 20 20 20 20 20 20 20 20 64 6f 63 4c 69 73 74 41          docListA
50f0: 64 64 50 6f 73 28 70 4f 75 74 2c 20 69 52 69 67  ddPos(pOut, iRig
5100: 68 74 43 6f 6c 2c 20 69 52 69 67 68 74 50 6f 73  htCol, iRightPos
5110: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
5120: 20 69 4c 65 66 74 50 6f 73 20 3d 20 72 65 61 64   iLeftPos = read
5130: 50 6f 73 69 74 69 6f 6e 28 70 4c 65 66 74 2c 20  Position(pLeft, 
5140: 26 69 4c 65 66 74 43 6f 6c 29 3b 0a 20 20 20 20  &iLeftCol);.    
5150: 20 20 69 52 69 67 68 74 50 6f 73 20 3d 20 72 65    iRightPos = re
5160: 61 64 50 6f 73 69 74 69 6f 6e 28 70 52 69 67 68  adPosition(pRigh
5170: 74 2c 20 26 69 52 69 67 68 74 43 6f 6c 29 3b 0a  t, &iRightCol);.
5180: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 69 52      }else if( iR
5190: 69 67 68 74 43 6f 6c 3c 69 4c 65 66 74 43 6f 6c  ightCol<iLeftCol
51a0: 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20   ||.            
51b0: 20 20 28 69 52 69 67 68 74 43 6f 6c 3d 3d 69 4c    (iRightCol==iL
51c0: 65 66 74 43 6f 6c 20 26 26 20 69 52 69 67 68 74  eftCol && iRight
51d0: 50 6f 73 3c 69 4c 65 66 74 50 6f 73 2b 31 29 20  Pos<iLeftPos+1) 
51e0: 29 7b 0a 20 20 20 20 20 20 69 52 69 67 68 74 50  ){.      iRightP
51f0: 6f 73 20 3d 20 72 65 61 64 50 6f 73 69 74 69 6f  os = readPositio
5200: 6e 28 70 52 69 67 68 74 2c 20 26 69 52 69 67 68  n(pRight, &iRigh
5210: 74 43 6f 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65  tCol);.    }else
5220: 7b 0a 20 20 20 20 20 20 69 4c 65 66 74 50 6f 73  {.      iLeftPos
5230: 20 3d 20 72 65 61 64 50 6f 73 69 74 69 6f 6e 28   = readPosition(
5240: 70 4c 65 66 74 2c 20 26 69 4c 65 66 74 43 6f 6c  pLeft, &iLeftCol
5250: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  );.    }.  }.  i
5260: 66 28 20 69 4c 65 66 74 50 6f 73 3e 3d 30 20 29  f( iLeftPos>=0 )
5270: 20 73 6b 69 70 50 6f 73 69 74 69 6f 6e 4c 69 73   skipPositionLis
5280: 74 28 70 4c 65 66 74 29 3b 0a 20 20 69 66 28 20  t(pLeft);.  if( 
5290: 69 52 69 67 68 74 50 6f 73 3e 3d 30 20 29 20 73  iRightPos>=0 ) s
52a0: 6b 69 70 50 6f 73 69 74 69 6f 6e 4c 69 73 74 28  kipPositionList(
52b0: 70 52 69 67 68 74 29 3b 0a 7d 0a 0a 2f 2a 20 57  pRight);.}../* W
52c0: 65 20 68 61 76 65 20 74 77 6f 20 64 6f 63 6c 69  e have two docli
52d0: 73 74 73 3a 20 20 70 4c 65 66 74 20 61 6e 64 20  sts:  pLeft and 
52e0: 70 52 69 67 68 74 2e 0a 2a 2a 20 57 72 69 74 65  pRight..** Write
52f0: 20 74 68 65 20 70 68 72 61 73 65 20 69 6e 74 65   the phrase inte
5300: 72 73 65 63 74 69 6f 6e 20 6f 66 20 74 68 65 73  rsection of thes
5310: 65 20 74 77 6f 20 64 6f 63 6c 69 73 74 73 20 69  e two doclists i
5320: 6e 74 6f 20 70 4f 75 74 2e 0a 2a 2a 0a 2a 2a 20  nto pOut..**.** 
5330: 41 20 70 68 72 61 73 65 20 69 6e 74 65 72 73 65  A phrase interse
5340: 63 74 69 6f 6e 20 6d 65 61 6e 73 20 74 68 61 74  ction means that
5350: 20 74 77 6f 20 64 6f 63 75 6d 65 6e 74 73 20 6f   two documents o
5360: 6e 6c 79 20 6d 61 74 63 68 0a 2a 2a 20 69 66 20  nly match.** if 
5370: 70 4c 65 66 74 2e 69 50 6f 73 2b 31 3d 3d 70 52  pLeft.iPos+1==pR
5380: 69 67 68 74 2e 69 50 6f 73 2e 0a 2a 2a 0a 2a 2a  ight.iPos..**.**
5390: 20 54 68 65 20 6f 75 74 70 75 74 20 70 4f 75 74   The output pOut
53a0: 20 6d 61 79 20 6f 72 20 6d 61 79 20 6e 6f 74 20   may or may not 
53b0: 63 6f 6e 74 61 69 6e 20 70 6f 73 69 74 69 6f 6e  contain position
53c0: 73 2e 20 20 49 66 20 70 4f 75 74 0a 2a 2a 20 64  s.  If pOut.** d
53d0: 6f 65 73 20 63 6f 6e 74 61 69 6e 20 70 6f 73 69  oes contain posi
53e0: 74 69 6f 6e 73 2c 20 74 68 65 79 20 61 72 65 20  tions, they are 
53f0: 74 68 65 20 70 6f 73 69 74 69 6f 6e 73 20 6f 66  the positions of
5400: 20 70 52 69 67 68 74 2e 0a 2a 2f 0a 73 74 61 74   pRight..*/.stat
5410: 69 63 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 50  ic void docListP
5420: 68 72 61 73 65 4d 65 72 67 65 28 0a 20 20 44 6f  hraseMerge(.  Do
5430: 63 4c 69 73 74 20 2a 70 4c 65 66 74 2c 20 20 20  cList *pLeft,   
5440: 20 2f 2a 20 44 6f 63 6c 69 73 74 20 72 65 73 75   /* Doclist resu
5450: 6c 74 69 6e 67 20 66 72 6f 6d 20 74 68 65 20 77  lting from the w
5460: 6f 72 64 73 20 6f 6e 20 74 68 65 20 6c 65 66 74  ords on the left
5470: 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70   */.  DocList *p
5480: 52 69 67 68 74 2c 20 20 20 2f 2a 20 44 6f 63 6c  Right,   /* Docl
5490: 69 73 74 20 66 6f 72 20 74 68 65 20 6e 65 78 74  ist for the next
54a0: 20 77 6f 72 64 20 74 6f 20 74 68 65 20 72 69 67   word to the rig
54b0: 68 74 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20  ht */.  DocList 
54c0: 2a 70 4f 75 74 20 20 20 20 20 20 2f 2a 20 57 72  *pOut      /* Wr
54d0: 69 74 65 20 74 68 65 20 63 6f 6d 62 69 6e 65 64  ite the combined
54e0: 20 64 6f 63 6c 69 73 74 20 68 65 72 65 20 2a 2f   doclist here */
54f0: 0a 29 7b 0a 20 20 44 6f 63 4c 69 73 74 52 65 61  .){.  DocListRea
5500: 64 65 72 20 6c 65 66 74 2c 20 72 69 67 68 74 3b  der left, right;
5510: 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  .  sqlite_int64 
5520: 64 6f 63 69 64 4c 65 66 74 2c 20 64 6f 63 69 64  docidLeft, docid
5530: 52 69 67 68 74 3b 0a 0a 20 20 72 65 61 64 65 72  Right;..  reader
5540: 49 6e 69 74 28 26 6c 65 66 74 2c 20 70 4c 65 66  Init(&left, pLef
5550: 74 29 3b 0a 20 20 72 65 61 64 65 72 49 6e 69 74  t);.  readerInit
5560: 28 26 72 69 67 68 74 2c 20 70 52 69 67 68 74 29  (&right, pRight)
5570: 3b 0a 20 20 64 6f 63 69 64 4c 65 66 74 20 3d 20  ;.  docidLeft = 
5580: 6e 65 78 74 44 6f 63 69 64 28 26 6c 65 66 74 29  nextDocid(&left)
5590: 3b 0a 20 20 64 6f 63 69 64 52 69 67 68 74 20 3d  ;.  docidRight =
55a0: 20 6e 65 78 74 44 6f 63 69 64 28 26 72 69 67 68   nextDocid(&righ
55b0: 74 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 64 6f  t);..  while( do
55c0: 63 69 64 4c 65 66 74 3e 30 20 26 26 20 64 6f 63  cidLeft>0 && doc
55d0: 69 64 52 69 67 68 74 3e 30 20 29 7b 0a 20 20 20  idRight>0 ){.   
55e0: 20 69 66 28 20 64 6f 63 69 64 4c 65 66 74 3c 64   if( docidLeft<d
55f0: 6f 63 69 64 52 69 67 68 74 20 29 7b 0a 20 20 20  ocidRight ){.   
5600: 20 20 20 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e     docidLeft = n
5610: 65 78 74 44 6f 63 69 64 28 26 6c 65 66 74 29 3b  extDocid(&left);
5620: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 64  .    }else if( d
5630: 6f 63 69 64 52 69 67 68 74 3c 64 6f 63 69 64 4c  ocidRight<docidL
5640: 65 66 74 20 29 7b 0a 20 20 20 20 20 20 64 6f 63  eft ){.      doc
5650: 69 64 52 69 67 68 74 20 3d 20 6e 65 78 74 44 6f  idRight = nextDo
5660: 63 69 64 28 26 72 69 67 68 74 29 3b 0a 20 20 20  cid(&right);.   
5670: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6d 65   }else{.      me
5680: 72 67 65 50 6f 73 4c 69 73 74 28 26 6c 65 66 74  rgePosList(&left
5690: 2c 20 26 72 69 67 68 74 2c 20 64 6f 63 69 64 4c  , &right, docidL
56a0: 65 66 74 2c 20 70 4f 75 74 29 3b 0a 20 20 20 20  eft, pOut);.    
56b0: 20 20 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65    docidLeft = ne
56c0: 78 74 44 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a  xtDocid(&left);.
56d0: 20 20 20 20 20 20 64 6f 63 69 64 52 69 67 68 74        docidRight
56e0: 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 72 69   = nextDocid(&ri
56f0: 67 68 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  ght);.    }.  }.
5700: 7d 0a 0a 2f 2a 20 57 65 20 68 61 76 65 20 74 77  }../* We have tw
5710: 6f 20 64 6f 63 6c 69 73 74 73 3a 20 20 70 4c 65  o doclists:  pLe
5720: 66 74 20 61 6e 64 20 70 52 69 67 68 74 2e 0a 2a  ft and pRight..*
5730: 2a 20 57 72 69 74 65 20 74 68 65 20 69 6e 74 65  * Write the inte
5740: 72 73 65 63 74 69 6f 6e 20 6f 66 20 74 68 65 73  rsection of thes
5750: 65 20 74 77 6f 20 64 6f 63 6c 69 73 74 73 20 69  e two doclists i
5760: 6e 74 6f 20 70 4f 75 74 2e 0a 2a 2a 20 4f 6e 6c  nto pOut..** Onl
5770: 79 20 64 6f 63 69 64 73 20 61 72 65 20 6d 61 74  y docids are mat
5780: 63 68 65 64 2e 20 20 50 6f 73 69 74 69 6f 6e 20  ched.  Position 
5790: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 73 20 69  information is i
57a0: 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68  gnored..**.** Th
57b0: 65 20 6f 75 74 70 75 74 20 70 4f 75 74 20 6e 65  e output pOut ne
57c0: 76 65 72 20 68 6f 6c 64 73 20 70 6f 73 69 74 69  ver holds positi
57d0: 6f 6e 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ons..*/.static v
57e0: 6f 69 64 20 64 6f 63 4c 69 73 74 41 6e 64 4d 65  oid docListAndMe
57f0: 72 67 65 28 0a 20 20 44 6f 63 4c 69 73 74 20 2a  rge(.  DocList *
5800: 70 4c 65 66 74 2c 20 20 20 20 2f 2a 20 44 6f 63  pLeft,    /* Doc
5810: 6c 69 73 74 20 72 65 73 75 6c 74 69 6e 67 20 66  list resulting f
5820: 72 6f 6d 20 74 68 65 20 77 6f 72 64 73 20 6f 6e  rom the words on
5830: 20 74 68 65 20 6c 65 66 74 20 2a 2f 0a 20 20 44   the left */.  D
5840: 6f 63 4c 69 73 74 20 2a 70 52 69 67 68 74 2c 20  ocList *pRight, 
5850: 20 20 2f 2a 20 44 6f 63 6c 69 73 74 20 66 6f 72    /* Doclist for
5860: 20 74 68 65 20 6e 65 78 74 20 77 6f 72 64 20 74   the next word t
5870: 6f 20 74 68 65 20 72 69 67 68 74 20 2a 2f 0a 20  o the right */. 
5880: 20 44 6f 63 4c 69 73 74 20 2a 70 4f 75 74 20 20   DocList *pOut  
5890: 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65      /* Write the
58a0: 20 63 6f 6d 62 69 6e 65 64 20 64 6f 63 6c 69 73   combined doclis
58b0: 74 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 44  t here */.){.  D
58c0: 6f 63 4c 69 73 74 52 65 61 64 65 72 20 6c 65 66  ocListReader lef
58d0: 74 2c 20 72 69 67 68 74 3b 0a 20 20 73 71 6c 69  t, right;.  sqli
58e0: 74 65 5f 69 6e 74 36 34 20 64 6f 63 69 64 4c 65  te_int64 docidLe
58f0: 66 74 2c 20 64 6f 63 69 64 52 69 67 68 74 3b 0a  ft, docidRight;.
5900: 0a 20 20 61 73 73 65 72 74 28 20 70 4f 75 74 2d  .  assert( pOut-
5910: 3e 69 54 79 70 65 3c 44 4c 5f 50 4f 53 49 54 49  >iType<DL_POSITI
5920: 4f 4e 53 20 29 3b 0a 0a 20 20 72 65 61 64 65 72  ONS );..  reader
5930: 49 6e 69 74 28 26 6c 65 66 74 2c 20 70 4c 65 66  Init(&left, pLef
5940: 74 29 3b 0a 20 20 72 65 61 64 65 72 49 6e 69 74  t);.  readerInit
5950: 28 26 72 69 67 68 74 2c 20 70 52 69 67 68 74 29  (&right, pRight)
5960: 3b 0a 20 20 64 6f 63 69 64 4c 65 66 74 20 3d 20  ;.  docidLeft = 
5970: 6e 65 78 74 44 6f 63 69 64 28 26 6c 65 66 74 29  nextDocid(&left)
5980: 3b 0a 20 20 64 6f 63 69 64 52 69 67 68 74 20 3d  ;.  docidRight =
5990: 20 6e 65 78 74 44 6f 63 69 64 28 26 72 69 67 68   nextDocid(&righ
59a0: 74 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 64 6f  t);..  while( do
59b0: 63 69 64 4c 65 66 74 3e 30 20 26 26 20 64 6f 63  cidLeft>0 && doc
59c0: 69 64 52 69 67 68 74 3e 30 20 29 7b 0a 20 20 20  idRight>0 ){.   
59d0: 20 69 66 28 20 64 6f 63 69 64 4c 65 66 74 3c 64   if( docidLeft<d
59e0: 6f 63 69 64 52 69 67 68 74 20 29 7b 0a 20 20 20  ocidRight ){.   
59f0: 20 20 20 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e     docidLeft = n
5a00: 65 78 74 44 6f 63 69 64 28 26 6c 65 66 74 29 3b  extDocid(&left);
5a10: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 64  .    }else if( d
5a20: 6f 63 69 64 52 69 67 68 74 3c 64 6f 63 69 64 4c  ocidRight<docidL
5a30: 65 66 74 20 29 7b 0a 20 20 20 20 20 20 64 6f 63  eft ){.      doc
5a40: 69 64 52 69 67 68 74 20 3d 20 6e 65 78 74 44 6f  idRight = nextDo
5a50: 63 69 64 28 26 72 69 67 68 74 29 3b 0a 20 20 20  cid(&right);.   
5a60: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 64 6f   }else{.      do
5a70: 63 4c 69 73 74 41 64 64 44 6f 63 69 64 28 70 4f  cListAddDocid(pO
5a80: 75 74 2c 20 64 6f 63 69 64 4c 65 66 74 29 3b 0a  ut, docidLeft);.
5a90: 20 20 20 20 20 20 64 6f 63 69 64 4c 65 66 74 20        docidLeft 
5aa0: 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 6c 65 66  = nextDocid(&lef
5ab0: 74 29 3b 0a 20 20 20 20 20 20 64 6f 63 69 64 52  t);.      docidR
5ac0: 69 67 68 74 20 3d 20 6e 65 78 74 44 6f 63 69 64  ight = nextDocid
5ad0: 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20 7d 0a  (&right);.    }.
5ae0: 20 20 7d 0a 7d 0a 0a 2f 2a 20 57 65 20 68 61 76    }.}../* We hav
5af0: 65 20 74 77 6f 20 64 6f 63 6c 69 73 74 73 3a 20  e two doclists: 
5b00: 20 70 4c 65 66 74 20 61 6e 64 20 70 52 69 67 68   pLeft and pRigh
5b10: 74 2e 0a 2a 2a 20 57 72 69 74 65 20 74 68 65 20  t..** Write the 
5b20: 75 6e 69 6f 6e 20 6f 66 20 74 68 65 73 65 20 74  union of these t
5b30: 77 6f 20 64 6f 63 6c 69 73 74 73 20 69 6e 74 6f  wo doclists into
5b40: 20 70 4f 75 74 2e 0a 2a 2a 20 4f 6e 6c 79 20 64   pOut..** Only d
5b50: 6f 63 69 64 73 20 61 72 65 20 6d 61 74 63 68 65  ocids are matche
5b60: 64 2e 20 20 50 6f 73 69 74 69 6f 6e 20 69 6e 66  d.  Position inf
5b70: 6f 72 6d 61 74 69 6f 6e 20 69 73 20 69 67 6e 6f  ormation is igno
5b80: 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6f  red..**.** The o
5b90: 75 74 70 75 74 20 70 4f 75 74 20 6e 65 76 65 72  utput pOut never
5ba0: 20 68 6f 6c 64 73 20 70 6f 73 69 74 69 6f 6e 73   holds positions
5bb0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
5bc0: 20 64 6f 63 4c 69 73 74 4f 72 4d 65 72 67 65 28   docListOrMerge(
5bd0: 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70 4c 65 66  .  DocList *pLef
5be0: 74 2c 20 20 20 20 2f 2a 20 44 6f 63 6c 69 73 74  t,    /* Doclist
5bf0: 20 72 65 73 75 6c 74 69 6e 67 20 66 72 6f 6d 20   resulting from 
5c00: 74 68 65 20 77 6f 72 64 73 20 6f 6e 20 74 68 65  the words on the
5c10: 20 6c 65 66 74 20 2a 2f 0a 20 20 44 6f 63 4c 69   left */.  DocLi
5c20: 73 74 20 2a 70 52 69 67 68 74 2c 20 20 20 2f 2a  st *pRight,   /*
5c30: 20 44 6f 63 6c 69 73 74 20 66 6f 72 20 74 68 65   Doclist for the
5c40: 20 6e 65 78 74 20 77 6f 72 64 20 74 6f 20 74 68   next word to th
5c50: 65 20 72 69 67 68 74 20 2a 2f 0a 20 20 44 6f 63  e right */.  Doc
5c60: 4c 69 73 74 20 2a 70 4f 75 74 20 20 20 20 20 20  List *pOut      
5c70: 2f 2a 20 57 72 69 74 65 20 74 68 65 20 63 6f 6d  /* Write the com
5c80: 62 69 6e 65 64 20 64 6f 63 6c 69 73 74 20 68 65  bined doclist he
5c90: 72 65 20 2a 2f 0a 29 7b 0a 20 20 44 6f 63 4c 69  re */.){.  DocLi
5ca0: 73 74 52 65 61 64 65 72 20 6c 65 66 74 2c 20 72  stReader left, r
5cb0: 69 67 68 74 3b 0a 20 20 73 71 6c 69 74 65 5f 69  ight;.  sqlite_i
5cc0: 6e 74 36 34 20 64 6f 63 69 64 4c 65 66 74 2c 20  nt64 docidLeft, 
5cd0: 64 6f 63 69 64 52 69 67 68 74 2c 20 70 72 69 6f  docidRight, prio
5ce0: 72 4c 65 66 74 3b 0a 0a 20 20 72 65 61 64 65 72  rLeft;..  reader
5cf0: 49 6e 69 74 28 26 6c 65 66 74 2c 20 70 4c 65 66  Init(&left, pLef
5d00: 74 29 3b 0a 20 20 72 65 61 64 65 72 49 6e 69 74  t);.  readerInit
5d10: 28 26 72 69 67 68 74 2c 20 70 52 69 67 68 74 29  (&right, pRight)
5d20: 3b 0a 20 20 64 6f 63 69 64 4c 65 66 74 20 3d 20  ;.  docidLeft = 
5d30: 6e 65 78 74 44 6f 63 69 64 28 26 6c 65 66 74 29  nextDocid(&left)
5d40: 3b 0a 20 20 64 6f 63 69 64 52 69 67 68 74 20 3d  ;.  docidRight =
5d50: 20 6e 65 78 74 44 6f 63 69 64 28 26 72 69 67 68   nextDocid(&righ
5d60: 74 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 64 6f  t);..  while( do
5d70: 63 69 64 4c 65 66 74 3e 30 20 26 26 20 64 6f 63  cidLeft>0 && doc
5d80: 69 64 52 69 67 68 74 3e 30 20 29 7b 0a 20 20 20  idRight>0 ){.   
5d90: 20 69 66 28 20 64 6f 63 69 64 4c 65 66 74 3c 3d   if( docidLeft<=
5da0: 64 6f 63 69 64 52 69 67 68 74 20 29 7b 0a 20 20  docidRight ){.  
5db0: 20 20 20 20 64 6f 63 4c 69 73 74 41 64 64 44 6f      docListAddDo
5dc0: 63 69 64 28 70 4f 75 74 2c 20 64 6f 63 69 64 4c  cid(pOut, docidL
5dd0: 65 66 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  eft);.    }else{
5de0: 0a 20 20 20 20 20 20 64 6f 63 4c 69 73 74 41 64  .      docListAd
5df0: 64 44 6f 63 69 64 28 70 4f 75 74 2c 20 64 6f 63  dDocid(pOut, doc
5e00: 69 64 52 69 67 68 74 29 3b 0a 20 20 20 20 7d 0a  idRight);.    }.
5e10: 20 20 20 20 70 72 69 6f 72 4c 65 66 74 20 3d 20      priorLeft = 
5e20: 64 6f 63 69 64 4c 65 66 74 3b 0a 20 20 20 20 69  docidLeft;.    i
5e30: 66 28 20 64 6f 63 69 64 4c 65 66 74 3c 3d 64 6f  f( docidLeft<=do
5e40: 63 69 64 52 69 67 68 74 20 29 7b 0a 20 20 20 20  cidRight ){.    
5e50: 20 20 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65    docidLeft = ne
5e60: 78 74 44 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a  xtDocid(&left);.
5e70: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 64 6f      }.    if( do
5e80: 63 69 64 52 69 67 68 74 3e 30 20 26 26 20 64 6f  cidRight>0 && do
5e90: 63 69 64 52 69 67 68 74 3c 3d 70 72 69 6f 72 4c  cidRight<=priorL
5ea0: 65 66 74 20 29 7b 0a 20 20 20 20 20 20 64 6f 63  eft ){.      doc
5eb0: 69 64 52 69 67 68 74 20 3d 20 6e 65 78 74 44 6f  idRight = nextDo
5ec0: 63 69 64 28 26 72 69 67 68 74 29 3b 0a 20 20 20  cid(&right);.   
5ed0: 20 7d 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20   }.  }.  while( 
5ee0: 64 6f 63 69 64 4c 65 66 74 3e 30 20 29 7b 0a 20  docidLeft>0 ){. 
5ef0: 20 20 20 64 6f 63 4c 69 73 74 41 64 64 44 6f 63     docListAddDoc
5f00: 69 64 28 70 4f 75 74 2c 20 64 6f 63 69 64 4c 65  id(pOut, docidLe
5f10: 66 74 29 3b 0a 20 20 20 20 64 6f 63 69 64 4c 65  ft);.    docidLe
5f20: 66 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26  ft = nextDocid(&
5f30: 6c 65 66 74 29 3b 0a 20 20 7d 0a 20 20 77 68 69  left);.  }.  whi
5f40: 6c 65 28 20 64 6f 63 69 64 52 69 67 68 74 3e 30  le( docidRight>0
5f50: 20 29 7b 0a 20 20 20 20 64 6f 63 4c 69 73 74 41   ){.    docListA
5f60: 64 64 44 6f 63 69 64 28 70 4f 75 74 2c 20 64 6f  ddDocid(pOut, do
5f70: 63 69 64 52 69 67 68 74 29 3b 0a 20 20 20 20 64  cidRight);.    d
5f80: 6f 63 69 64 52 69 67 68 74 20 3d 20 6e 65 78 74  ocidRight = next
5f90: 44 6f 63 69 64 28 26 72 69 67 68 74 29 3b 0a 20  Docid(&right);. 
5fa0: 20 7d 0a 7d 0a 0a 2f 2a 20 57 65 20 68 61 76 65   }.}../* We have
5fb0: 20 74 77 6f 20 64 6f 63 6c 69 73 74 73 3a 20 20   two doclists:  
5fc0: 70 4c 65 66 74 20 61 6e 64 20 70 52 69 67 68 74  pLeft and pRight
5fd0: 2e 0a 2a 2a 20 57 72 69 74 65 20 69 6e 74 6f 20  ..** Write into 
5fe0: 70 4f 75 74 20 61 6c 6c 20 64 6f 63 75 6d 65 6e  pOut all documen
5ff0: 74 73 20 74 68 61 74 20 6f 63 63 75 72 20 69 6e  ts that occur in
6000: 20 70 4c 65 66 74 20 62 75 74 20 6e 6f 74 0a 2a   pLeft but not.*
6010: 2a 20 69 6e 20 70 52 69 67 68 74 2e 0a 2a 2a 0a  * in pRight..**.
6020: 2a 2a 20 4f 6e 6c 79 20 64 6f 63 69 64 73 20 61  ** Only docids a
6030: 72 65 20 6d 61 74 63 68 65 64 2e 20 20 50 6f 73  re matched.  Pos
6040: 69 74 69 6f 6e 20 69 6e 66 6f 72 6d 61 74 69 6f  ition informatio
6050: 6e 20 69 73 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a  n is ignored..**
6060: 0a 2a 2a 20 54 68 65 20 6f 75 74 70 75 74 20 70  .** The output p
6070: 4f 75 74 20 6e 65 76 65 72 20 68 6f 6c 64 73 20  Out never holds 
6080: 70 6f 73 69 74 69 6f 6e 73 2e 0a 2a 2f 0a 73 74  positions..*/.st
6090: 61 74 69 63 20 76 6f 69 64 20 64 6f 63 4c 69 73  atic void docLis
60a0: 74 45 78 63 65 70 74 4d 65 72 67 65 28 0a 20 20  tExceptMerge(.  
60b0: 44 6f 63 4c 69 73 74 20 2a 70 4c 65 66 74 2c 20  DocList *pLeft, 
60c0: 20 20 20 2f 2a 20 44 6f 63 6c 69 73 74 20 72 65     /* Doclist re
60d0: 73 75 6c 74 69 6e 67 20 66 72 6f 6d 20 74 68 65  sulting from the
60e0: 20 77 6f 72 64 73 20 6f 6e 20 74 68 65 20 6c 65   words on the le
60f0: 66 74 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20  ft */.  DocList 
6100: 2a 70 52 69 67 68 74 2c 20 20 20 2f 2a 20 44 6f  *pRight,   /* Do
6110: 63 6c 69 73 74 20 66 6f 72 20 74 68 65 20 6e 65  clist for the ne
6120: 78 74 20 77 6f 72 64 20 74 6f 20 74 68 65 20 72  xt word to the r
6130: 69 67 68 74 20 2a 2f 0a 20 20 44 6f 63 4c 69 73  ight */.  DocLis
6140: 74 20 2a 70 4f 75 74 20 20 20 20 20 20 2f 2a 20  t *pOut      /* 
6150: 57 72 69 74 65 20 74 68 65 20 63 6f 6d 62 69 6e  Write the combin
6160: 65 64 20 64 6f 63 6c 69 73 74 20 68 65 72 65 20  ed doclist here 
6170: 2a 2f 0a 29 7b 0a 20 20 44 6f 63 4c 69 73 74 52  */.){.  DocListR
6180: 65 61 64 65 72 20 6c 65 66 74 2c 20 72 69 67 68  eader left, righ
6190: 74 3b 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36  t;.  sqlite_int6
61a0: 34 20 64 6f 63 69 64 4c 65 66 74 2c 20 64 6f 63  4 docidLeft, doc
61b0: 69 64 52 69 67 68 74 2c 20 70 72 69 6f 72 4c 65  idRight, priorLe
61c0: 66 74 3b 0a 0a 20 20 72 65 61 64 65 72 49 6e 69  ft;..  readerIni
61d0: 74 28 26 6c 65 66 74 2c 20 70 4c 65 66 74 29 3b  t(&left, pLeft);
61e0: 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28 26 72  .  readerInit(&r
61f0: 69 67 68 74 2c 20 70 52 69 67 68 74 29 3b 0a 20  ight, pRight);. 
6200: 20 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65 78   docidLeft = nex
6210: 74 44 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a 20  tDocid(&left);. 
6220: 20 64 6f 63 69 64 52 69 67 68 74 20 3d 20 6e 65   docidRight = ne
6230: 78 74 44 6f 63 69 64 28 26 72 69 67 68 74 29 3b  xtDocid(&right);
6240: 0a 0a 20 20 77 68 69 6c 65 28 20 64 6f 63 69 64  ..  while( docid
6250: 4c 65 66 74 3e 30 20 26 26 20 64 6f 63 69 64 52  Left>0 && docidR
6260: 69 67 68 74 3e 30 20 29 7b 0a 20 20 20 20 70 72  ight>0 ){.    pr
6270: 69 6f 72 4c 65 66 74 20 3d 20 64 6f 63 69 64 4c  iorLeft = docidL
6280: 65 66 74 3b 0a 20 20 20 20 69 66 28 20 64 6f 63  eft;.    if( doc
6290: 69 64 4c 65 66 74 3c 64 6f 63 69 64 52 69 67 68  idLeft<docidRigh
62a0: 74 20 29 7b 0a 20 20 20 20 20 20 64 6f 63 4c 69  t ){.      docLi
62b0: 73 74 41 64 64 44 6f 63 69 64 28 70 4f 75 74 2c  stAddDocid(pOut,
62c0: 20 64 6f 63 69 64 4c 65 66 74 29 3b 0a 20 20 20   docidLeft);.   
62d0: 20 7d 0a 20 20 20 20 69 66 28 20 64 6f 63 69 64   }.    if( docid
62e0: 4c 65 66 74 3c 3d 64 6f 63 69 64 52 69 67 68 74  Left<=docidRight
62f0: 20 29 7b 0a 20 20 20 20 20 20 64 6f 63 69 64 4c   ){.      docidL
6300: 65 66 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28  eft = nextDocid(
6310: 26 6c 65 66 74 29 3b 0a 20 20 20 20 7d 0a 20 20  &left);.    }.  
6320: 20 20 69 66 28 20 64 6f 63 69 64 52 69 67 68 74    if( docidRight
6330: 3e 30 20 26 26 20 64 6f 63 69 64 52 69 67 68 74  >0 && docidRight
6340: 3c 3d 70 72 69 6f 72 4c 65 66 74 20 29 7b 0a 20  <=priorLeft ){. 
6350: 20 20 20 20 20 64 6f 63 69 64 52 69 67 68 74 20       docidRight 
6360: 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 72 69 67  = nextDocid(&rig
6370: 68 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  ht);.    }.  }. 
6380: 20 77 68 69 6c 65 28 20 64 6f 63 69 64 4c 65 66   while( docidLef
6390: 74 3e 30 20 29 7b 0a 20 20 20 20 64 6f 63 4c 69  t>0 ){.    docLi
63a0: 73 74 41 64 64 44 6f 63 69 64 28 70 4f 75 74 2c  stAddDocid(pOut,
63b0: 20 64 6f 63 69 64 4c 65 66 74 29 3b 0a 20 20 20   docidLeft);.   
63c0: 20 64 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65 78   docidLeft = nex
63d0: 74 44 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a 20  tDocid(&left);. 
63e0: 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61   }.}..static cha
63f0: 72 20 2a 73 74 72 69 6e 67 5f 64 75 70 5f 6e 28  r *string_dup_n(
6400: 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 2c 20 69  const char *s, i
6410: 6e 74 20 6e 29 7b 0a 20 20 63 68 61 72 20 2a 73  nt n){.  char *s
6420: 74 72 20 3d 20 6d 61 6c 6c 6f 63 28 6e 20 2b 20  tr = malloc(n + 
6430: 31 29 3b 0a 20 20 6d 65 6d 63 70 79 28 73 74 72  1);.  memcpy(str
6440: 2c 20 73 2c 20 6e 29 3b 0a 20 20 73 74 72 5b 6e  , s, n);.  str[n
6450: 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 72 65 74 75  ] = '\0';.  retu
6460: 72 6e 20 73 74 72 3b 0a 7d 0a 0a 2f 2a 20 44 75  rn str;.}../* Du
6470: 70 6c 69 63 61 74 65 20 61 20 73 74 72 69 6e 67  plicate a string
6480: 3b 20 74 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  ; the caller mus
6490: 74 20 66 72 65 65 28 29 20 74 68 65 20 72 65 74  t free() the ret
64a0: 75 72 6e 65 64 20 73 74 72 69 6e 67 2e 0a 20 2a  urned string.. *
64b0: 20 28 57 65 20 64 6f 6e 27 74 20 75 73 65 20 73   (We don't use s
64c0: 74 72 64 75 70 28 29 20 73 69 6e 63 65 20 69 74  trdup() since it
64d0: 20 69 73 20 6e 6f 74 20 70 61 72 74 20 6f 66 20   is not part of 
64e0: 74 68 65 20 73 74 61 6e 64 61 72 64 20 43 20 6c  the standard C l
64f0: 69 62 72 61 72 79 20 61 6e 64 0a 20 2a 20 6d 61  ibrary and. * ma
6500: 79 20 6e 6f 74 20 62 65 20 61 76 61 69 6c 61 62  y not be availab
6510: 6c 65 20 65 76 65 72 79 77 68 65 72 65 2e 29 20  le everywhere.) 
6520: 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a  */.static char *
6530: 73 74 72 69 6e 67 5f 64 75 70 28 63 6f 6e 73 74  string_dup(const
6540: 20 63 68 61 72 20 2a 73 29 7b 0a 20 20 72 65 74   char *s){.  ret
6550: 75 72 6e 20 73 74 72 69 6e 67 5f 64 75 70 5f 6e  urn string_dup_n
6560: 28 73 2c 20 73 74 72 6c 65 6e 28 73 29 29 3b 0a  (s, strlen(s));.
6570: 7d 0a 0a 2f 2a 20 46 6f 72 6d 61 74 20 61 20 73  }../* Format a s
6580: 74 72 69 6e 67 2c 20 72 65 70 6c 61 63 69 6e 67  tring, replacing
6590: 20 65 61 63 68 20 6f 63 63 75 72 72 65 6e 63 65   each occurrence
65a0: 20 6f 66 20 74 68 65 20 25 20 63 68 61 72 61 63   of the % charac
65b0: 74 65 72 20 77 69 74 68 0a 20 2a 20 7a 44 62 2e  ter with. * zDb.
65c0: 7a 4e 61 6d 65 2e 20 20 54 68 69 73 20 6d 61 79  zName.  This may
65d0: 20 62 65 20 6d 6f 72 65 20 63 6f 6e 76 65 6e 69   be more conveni
65e0: 65 6e 74 20 74 68 61 6e 20 73 71 6c 69 74 65 5f  ent than sqlite_
65f0: 6d 70 72 69 6e 74 66 28 29 0a 20 2a 20 77 68 65  mprintf(). * whe
6600: 6e 20 6f 6e 65 20 73 74 72 69 6e 67 20 69 73 20  n one string is 
6610: 75 73 65 64 20 72 65 70 65 61 74 65 64 6c 79 20  used repeatedly 
6620: 69 6e 20 61 20 66 6f 72 6d 61 74 20 73 74 72 69  in a format stri
6630: 6e 67 2e 0a 20 2a 20 54 68 65 20 63 61 6c 6c 65  ng.. * The calle
6640: 72 20 6d 75 73 74 20 66 72 65 65 28 29 20 74 68  r must free() th
6650: 65 20 72 65 74 75 72 6e 65 64 20 73 74 72 69 6e  e returned strin
6660: 67 2e 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61  g. */.static cha
6670: 72 20 2a 73 74 72 69 6e 67 5f 66 6f 72 6d 61 74  r *string_format
6680: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f  (const char *zFo
6690: 72 6d 61 74 2c 0a 20 20 20 20 20 20 20 20 20 20  rmat,.          
66a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
66b0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62   const char *zDb
66c0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e  , const char *zN
66d0: 61 6d 65 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68  ame){.  const ch
66e0: 61 72 20 2a 70 3b 0a 20 20 73 69 7a 65 5f 74 20  ar *p;.  size_t 
66f0: 6c 65 6e 20 3d 20 30 3b 0a 20 20 73 69 7a 65 5f  len = 0;.  size_
6700: 74 20 6e 44 62 20 3d 20 73 74 72 6c 65 6e 28 7a  t nDb = strlen(z
6710: 44 62 29 3b 0a 20 20 73 69 7a 65 5f 74 20 6e 4e  Db);.  size_t nN
6720: 61 6d 65 20 3d 20 73 74 72 6c 65 6e 28 7a 4e 61  ame = strlen(zNa
6730: 6d 65 29 3b 0a 20 20 73 69 7a 65 5f 74 20 6e 46  me);.  size_t nF
6740: 75 6c 6c 54 61 62 6c 65 4e 61 6d 65 20 3d 20 6e  ullTableName = n
6750: 44 62 2b 31 2b 6e 4e 61 6d 65 3b 0a 20 20 63 68  Db+1+nName;.  ch
6760: 61 72 20 2a 72 65 73 75 6c 74 3b 0a 20 20 63 68  ar *result;.  ch
6770: 61 72 20 2a 72 3b 0a 0a 20 20 2f 2a 20 66 69 72  ar *r;..  /* fir
6780: 73 74 20 63 6f 6d 70 75 74 65 20 6c 65 6e 67 74  st compute lengt
6790: 68 20 6e 65 65 64 65 64 20 2a 2f 0a 20 20 66 6f  h needed */.  fo
67a0: 72 28 70 20 3d 20 7a 46 6f 72 6d 61 74 20 3b 20  r(p = zFormat ; 
67b0: 2a 70 20 3b 20 2b 2b 70 29 7b 0a 20 20 20 20 6c  *p ; ++p){.    l
67c0: 65 6e 20 2b 3d 20 28 2a 70 3d 3d 27 25 27 20 3f  en += (*p=='%' ?
67d0: 20 6e 46 75 6c 6c 54 61 62 6c 65 4e 61 6d 65 20   nFullTableName 
67e0: 3a 20 31 29 3b 0a 20 20 7d 0a 20 20 6c 65 6e 20  : 1);.  }.  len 
67f0: 2b 3d 20 31 3b 20 20 2f 2a 20 66 6f 72 20 6e 75  += 1;  /* for nu
6800: 6c 6c 20 74 65 72 6d 69 6e 61 74 6f 72 20 2a 2f  ll terminator */
6810: 0a 0a 20 20 72 20 3d 20 72 65 73 75 6c 74 20 3d  ..  r = result =
6820: 20 6d 61 6c 6c 6f 63 28 6c 65 6e 29 3b 0a 20 20   malloc(len);.  
6830: 66 6f 72 28 70 20 3d 20 7a 46 6f 72 6d 61 74 3b  for(p = zFormat;
6840: 20 2a 70 3b 20 2b 2b 70 29 7b 0a 20 20 20 20 69   *p; ++p){.    i
6850: 66 28 20 2a 70 3d 3d 27 25 27 20 29 7b 0a 20 20  f( *p=='%' ){.  
6860: 20 20 20 20 6d 65 6d 63 70 79 28 72 2c 20 7a 44      memcpy(r, zD
6870: 62 2c 20 6e 44 62 29 3b 0a 20 20 20 20 20 20 72  b, nDb);.      r
6880: 20 2b 3d 20 6e 44 62 3b 0a 20 20 20 20 20 20 2a   += nDb;.      *
6890: 72 2b 2b 20 3d 20 27 2e 27 3b 0a 20 20 20 20 20  r++ = '.';.     
68a0: 20 6d 65 6d 63 70 79 28 72 2c 20 7a 4e 61 6d 65   memcpy(r, zName
68b0: 2c 20 6e 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20  , nName);.      
68c0: 72 20 2b 3d 20 6e 4e 61 6d 65 3b 0a 20 20 20 20  r += nName;.    
68d0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 2a  } else {.      *
68e0: 72 2b 2b 20 3d 20 2a 70 3b 0a 20 20 20 20 7d 0a  r++ = *p;.    }.
68f0: 20 20 7d 0a 20 20 2a 72 2b 2b 20 3d 20 27 5c 30    }.  *r++ = '\0
6900: 27 3b 0a 20 20 61 73 73 65 72 74 28 20 72 20 3d  ';.  assert( r =
6910: 3d 20 72 65 73 75 6c 74 20 2b 20 6c 65 6e 20 29  = result + len )
6920: 3b 0a 20 20 72 65 74 75 72 6e 20 72 65 73 75 6c  ;.  return resul
6930: 74 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  t;.}..static int
6940: 20 73 71 6c 5f 65 78 65 63 28 73 71 6c 69 74 65   sql_exec(sqlite
6950: 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 63 68 61  3 *db, const cha
6960: 72 20 2a 7a 44 62 2c 20 63 6f 6e 73 74 20 63 68  r *zDb, const ch
6970: 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20 20 20 20  ar *zName,.     
6980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63                 c
6990: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d  onst char *zForm
69a0: 61 74 29 7b 0a 20 20 63 68 61 72 20 2a 7a 43 6f  at){.  char *zCo
69b0: 6d 6d 61 6e 64 20 3d 20 73 74 72 69 6e 67 5f 66  mmand = string_f
69c0: 6f 72 6d 61 74 28 7a 46 6f 72 6d 61 74 2c 20 7a  ormat(zFormat, z
69d0: 44 62 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 69 6e  Db, zName);.  in
69e0: 74 20 72 63 3b 0a 20 20 54 52 41 43 45 28 28 22  t rc;.  TRACE(("
69f0: 46 54 53 31 20 73 71 6c 3a 20 25 73 5c 6e 22 2c  FTS1 sql: %s\n",
6a00: 20 7a 43 6f 6d 6d 61 6e 64 29 29 3b 0a 20 20 72   zCommand));.  r
6a10: 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63  c = sqlite3_exec
6a20: 28 64 62 2c 20 7a 43 6f 6d 6d 61 6e 64 2c 20 4e  (db, zCommand, N
6a30: 55 4c 4c 2c 20 30 2c 20 4e 55 4c 4c 29 3b 0a 20  ULL, 0, NULL);. 
6a40: 20 66 72 65 65 28 7a 43 6f 6d 6d 61 6e 64 29 3b   free(zCommand);
6a50: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
6a60: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 71 6c 5f  .static int sql_
6a70: 70 72 65 70 61 72 65 28 73 71 6c 69 74 65 33 20  prepare(sqlite3 
6a80: 2a 64 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  *db, const char 
6a90: 2a 7a 44 62 2c 20 63 6f 6e 73 74 20 63 68 61 72  *zDb, const char
6aa0: 20 2a 7a 4e 61 6d 65 2c 0a 20 20 20 20 20 20 20   *zName,.       
6ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ac0: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 2a 70  sqlite3_stmt **p
6ad0: 70 53 74 6d 74 2c 20 63 6f 6e 73 74 20 63 68 61  pStmt, const cha
6ae0: 72 20 2a 7a 46 6f 72 6d 61 74 29 7b 0a 20 20 63  r *zFormat){.  c
6af0: 68 61 72 20 2a 7a 43 6f 6d 6d 61 6e 64 20 3d 20  har *zCommand = 
6b00: 73 74 72 69 6e 67 5f 66 6f 72 6d 61 74 28 7a 46  string_format(zF
6b10: 6f 72 6d 61 74 2c 20 7a 44 62 2c 20 7a 4e 61 6d  ormat, zDb, zNam
6b20: 65 29 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  e);.  int rc;.  
6b30: 54 52 41 43 45 28 28 22 46 54 53 31 20 70 72 65  TRACE(("FTS1 pre
6b40: 70 61 72 65 3a 20 25 73 5c 6e 22 2c 20 7a 43 6f  pare: %s\n", zCo
6b50: 6d 6d 61 6e 64 29 29 3b 0a 20 20 72 63 20 3d 20  mmand));.  rc = 
6b60: 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28  sqlite3_prepare(
6b70: 64 62 2c 20 7a 43 6f 6d 6d 61 6e 64 2c 20 2d 31  db, zCommand, -1
6b80: 2c 20 70 70 53 74 6d 74 2c 20 4e 55 4c 4c 29 3b  , ppStmt, NULL);
6b90: 0a 20 20 66 72 65 65 28 7a 43 6f 6d 6d 61 6e 64  .  free(zCommand
6ba0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
6bb0: 7d 0a 0a 2f 2a 20 65 6e 64 20 75 74 69 6c 69 74  }../* end utilit
6bc0: 79 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 0a  y functions */..
6bd0: 2f 2a 20 46 6f 72 77 61 72 64 20 72 65 66 65 72  /* Forward refer
6be0: 65 6e 63 65 20 2a 2f 0a 74 79 70 65 64 65 66 20  ence */.typedef 
6bf0: 73 74 72 75 63 74 20 66 75 6c 6c 74 65 78 74 5f  struct fulltext_
6c00: 76 74 61 62 20 66 75 6c 6c 74 65 78 74 5f 76 74  vtab fulltext_vt
6c10: 61 62 3b 0a 0a 2f 2a 20 41 20 73 69 6e 67 6c 65  ab;../* A single
6c20: 20 74 65 72 6d 20 69 6e 20 61 20 71 75 65 72 79   term in a query
6c30: 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64 20   is represented 
6c40: 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 73 20  by an instances 
6c50: 6f 66 0a 2a 2a 20 74 68 65 20 66 6f 6c 6c 6f 77  of.** the follow
6c60: 69 6e 67 20 73 74 72 75 63 74 75 72 65 2e 0a 2a  ing structure..*
6c70: 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
6c80: 20 51 75 65 72 79 54 65 72 6d 20 7b 0a 20 20 73   QueryTerm {.  s
6c90: 68 6f 72 74 20 69 6e 74 20 6e 50 68 72 61 73 65  hort int nPhrase
6ca0: 3b 20 2f 2a 20 48 6f 77 20 6d 61 6e 79 20 66 6f  ; /* How many fo
6cb0: 6c 6c 6f 77 69 6e 67 20 74 65 72 6d 73 20 61 72  llowing terms ar
6cc0: 65 20 70 61 72 74 20 6f 66 20 74 68 65 20 73 61  e part of the sa
6cd0: 6d 65 20 70 68 72 61 73 65 20 2a 2f 0a 20 20 73  me phrase */.  s
6ce0: 68 6f 72 74 20 69 6e 74 20 69 50 68 72 61 73 65  hort int iPhrase
6cf0: 3b 20 2f 2a 20 54 68 69 73 20 69 73 20 74 68 65  ; /* This is the
6d00: 20 69 2d 74 68 20 74 65 72 6d 20 6f 66 20 61 20   i-th term of a 
6d10: 70 68 72 61 73 65 2e 20 2a 2f 0a 20 20 73 68 6f  phrase. */.  sho
6d20: 72 74 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 3b 20  rt int iColumn; 
6d30: 2f 2a 20 43 6f 6c 75 6d 6e 20 6f 66 20 74 68 65  /* Column of the
6d40: 20 69 6e 64 65 78 20 74 68 61 74 20 6d 75 73 74   index that must
6d50: 20 6d 61 74 63 68 20 74 68 69 73 20 74 65 72 6d   match this term
6d60: 20 2a 2f 0a 20 20 73 69 67 6e 65 64 20 63 68 61   */.  signed cha
6d70: 72 20 69 73 4f 72 3b 20 20 2f 2a 20 74 68 69 73  r isOr;  /* this
6d80: 20 74 65 72 6d 20 69 73 20 70 72 65 63 65 64 65   term is precede
6d90: 64 20 62 79 20 22 4f 52 22 20 2a 2f 0a 20 20 73  d by "OR" */.  s
6da0: 69 67 6e 65 64 20 63 68 61 72 20 69 73 4e 6f 74  igned char isNot
6db0: 3b 20 2f 2a 20 74 68 69 73 20 74 65 72 6d 20 69  ; /* this term i
6dc0: 73 20 70 72 65 63 65 64 65 64 20 62 79 20 22 2d  s preceded by "-
6dd0: 22 20 2a 2f 0a 20 20 63 68 61 72 20 2a 70 54 65  " */.  char *pTe
6de0: 72 6d 3b 20 20 20 20 20 20 20 2f 2a 20 74 65 78  rm;       /* tex
6df0: 74 20 6f 66 20 74 68 65 20 74 65 72 6d 2e 20 20  t of the term.  
6e00: 27 5c 30 30 30 27 20 74 65 72 6d 69 6e 61 74 65  '\000' terminate
6e10: 64 2e 20 20 6d 61 6c 6c 6f 63 65 64 20 2a 2f 0a  d.  malloced */.
6e20: 20 20 69 6e 74 20 6e 54 65 72 6d 3b 20 20 20 20    int nTerm;    
6e30: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
6e40: 66 20 62 79 74 65 73 20 69 6e 20 70 54 65 72 6d  f bytes in pTerm
6e50: 5b 5d 20 2a 2f 0a 7d 20 51 75 65 72 79 54 65 72  [] */.} QueryTer
6e60: 6d 3b 0a 0a 0a 2f 2a 20 41 20 71 75 65 72 79 20  m;.../* A query 
6e70: 73 74 72 69 6e 67 20 69 73 20 70 61 72 73 65 64  string is parsed
6e80: 20 69 6e 74 6f 20 61 20 51 75 65 72 79 20 73 74   into a Query st
6e90: 72 75 63 74 75 72 65 2e 0a 20 2a 0a 20 2a 20 57  ructure.. *. * W
6ea0: 65 20 63 6f 75 6c 64 2c 20 69 6e 20 74 68 65 6f  e could, in theo
6eb0: 72 79 2c 20 61 6c 6c 6f 77 20 71 75 65 72 79 20  ry, allow query 
6ec0: 73 74 72 69 6e 67 73 20 74 6f 20 62 65 20 63 6f  strings to be co
6ed0: 6d 70 6c 69 63 61 74 65 64 0a 20 2a 20 6e 65 73  mplicated. * nes
6ee0: 74 65 64 20 65 78 70 72 65 73 73 69 6f 6e 73 20  ted expressions 
6ef0: 77 69 74 68 20 70 72 65 63 65 64 65 6e 63 65 20  with precedence 
6f00: 64 65 74 65 72 6d 69 6e 65 64 20 62 79 20 70 61  determined by pa
6f10: 72 65 6e 74 68 65 73 65 73 2e 0a 20 2a 20 42 75  rentheses.. * Bu
6f20: 74 20 6e 6f 6e 65 20 6f 66 20 74 68 65 20 6d 61  t none of the ma
6f30: 6a 6f 72 20 73 65 61 72 63 68 20 65 6e 67 69 6e  jor search engin
6f40: 65 73 20 64 6f 20 74 68 69 73 2e 20 20 28 50 65  es do this.  (Pe
6f50: 72 68 61 70 73 20 74 68 65 0a 20 2a 20 66 65 65  rhaps the. * fee
6f60: 6c 69 6e 67 20 69 73 20 74 68 61 74 20 61 6e 20  ling is that an 
6f70: 70 61 72 65 6e 74 68 65 73 69 7a 65 64 20 65 78  parenthesized ex
6f80: 70 72 65 73 73 69 6f 6e 20 69 73 20 74 77 6f 20  pression is two 
6f90: 63 6f 6d 70 6c 65 78 20 6f 66 0a 20 2a 20 61 6e  complex of. * an
6fa0: 20 69 64 65 61 20 66 6f 72 20 74 68 65 20 61 76   idea for the av
6fb0: 65 72 61 67 65 20 75 73 65 72 20 74 6f 20 67 72  erage user to gr
6fc0: 61 73 70 2e 29 20 20 54 61 6b 69 6e 67 20 6f 75  asp.)  Taking ou
6fd0: 72 20 6c 65 61 64 20 66 72 6f 6d 0a 20 2a 20 74  r lead from. * t
6fe0: 68 65 20 6d 61 6a 6f 72 20 73 65 61 72 63 68 20  he major search 
6ff0: 65 6e 67 69 6e 65 73 2c 20 77 65 20 77 69 6c 6c  engines, we will
7000: 20 61 6c 6c 6f 77 20 71 75 65 72 69 65 73 20 74   allow queries t
7010: 6f 20 62 65 20 61 20 6c 69 73 74 0a 20 2a 20 6f  o be a list. * o
7020: 66 20 74 65 72 6d 73 20 28 77 69 74 68 20 61 6e  f terms (with an
7030: 20 69 6d 70 6c 69 65 64 20 41 4e 44 20 6f 70 65   implied AND ope
7040: 72 61 74 6f 72 29 20 6f 72 20 70 68 72 61 73 65  rator) or phrase
7050: 73 20 69 6e 20 64 6f 75 62 6c 65 2d 71 75 6f 74  s in double-quot
7060: 65 73 2c 0a 20 2a 20 77 69 74 68 20 61 20 73 69  es,. * with a si
7070: 6e 67 6c 65 20 6f 70 74 69 6f 6e 61 6c 20 22 2d  ngle optional "-
7080: 22 20 62 65 66 6f 72 65 20 65 61 63 68 20 6e 6f  " before each no
7090: 6e 2d 70 68 72 61 73 65 20 74 65 72 6d 20 74 6f  n-phrase term to
70a0: 20 64 65 73 69 67 6e 61 74 65 0a 20 2a 20 6e 65   designate. * ne
70b0: 67 61 74 69 6f 6e 20 61 6e 64 20 61 6e 20 6f 70  gation and an op
70c0: 74 69 6f 6e 61 6c 20 4f 52 20 63 6f 6e 6e 65 63  tional OR connec
70d0: 74 6f 72 2e 0a 20 2a 0a 20 2a 20 4f 52 20 62 69  tor.. *. * OR bi
70e0: 6e 64 73 20 6d 6f 72 65 20 74 69 67 68 74 6c 79  nds more tightly
70f0: 20 74 68 61 6e 20 74 68 65 20 69 6d 70 6c 69 65   than the implie
7100: 64 20 41 4e 44 2c 20 77 68 69 63 68 20 69 73 20  d AND, which is 
7110: 77 68 61 74 20 74 68 65 0a 20 2a 20 6d 61 6a 6f  what the. * majo
7120: 72 20 73 65 61 72 63 68 20 65 6e 67 69 6e 65 73  r search engines
7130: 20 73 65 65 6d 20 74 6f 20 64 6f 2e 20 20 53 6f   seem to do.  So
7140: 2c 20 66 6f 72 20 65 78 61 6d 70 6c 65 3a 0a 20  , for example:. 
7150: 2a 20 0a 20 2a 20 20 20 20 5b 6f 6e 65 20 74 77  * . *    [one tw
7160: 6f 20 4f 52 20 74 68 72 65 65 5d 20 20 20 20 20  o OR three]     
7170: 3d 3d 3e 20 20 20 20 6f 6e 65 20 41 4e 44 20 28  ==>    one AND (
7180: 74 77 6f 20 4f 52 20 74 68 72 65 65 29 0a 20 2a  two OR three). *
7190: 20 20 20 20 5b 6f 6e 65 20 4f 52 20 74 77 6f 20      [one OR two 
71a0: 74 68 72 65 65 5d 20 20 20 20 20 3d 3d 3e 20 20  three]     ==>  
71b0: 20 20 28 6f 6e 65 20 4f 52 20 74 77 6f 29 20 41    (one OR two) A
71c0: 4e 44 20 74 68 72 65 65 0a 20 2a 0a 20 2a 20 41  ND three. *. * A
71d0: 20 22 2d 22 20 62 65 66 6f 72 65 20 61 20 74 65   "-" before a te
71e0: 72 6d 20 6d 61 74 63 68 65 73 20 61 6c 6c 20 65  rm matches all e
71f0: 6e 74 72 69 65 73 20 74 68 61 74 20 6c 61 63 6b  ntries that lack
7200: 20 74 68 61 74 20 74 65 72 6d 2e 0a 20 2a 20 54   that term.. * T
7210: 68 65 20 22 2d 22 20 6d 75 73 74 20 6f 63 63 75  he "-" must occu
7220: 72 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 62 65  r immediately be
7230: 66 6f 72 65 20 74 68 65 20 74 65 72 6d 20 77 69  fore the term wi
7240: 74 68 20 69 6e 20 69 6e 74 65 72 76 65 6e 69 6e  th in intervenin
7250: 67 0a 20 2a 20 73 70 61 63 65 2e 20 20 54 68 69  g. * space.  Thi
7260: 73 20 69 73 20 68 6f 77 20 74 68 65 20 73 65 61  s is how the sea
7270: 72 63 68 20 65 6e 67 69 6e 65 73 20 64 6f 20 69  rch engines do i
7280: 74 2e 0a 20 2a 0a 20 2a 20 41 20 4e 4f 54 20 74  t.. *. * A NOT t
7290: 65 72 6d 20 63 61 6e 6e 6f 74 20 62 65 20 74 68  erm cannot be th
72a0: 65 20 72 69 67 68 74 2d 68 61 6e 64 20 6f 70 65  e right-hand ope
72b0: 72 61 6e 64 20 6f 66 20 61 6e 20 4f 52 2e 20 20  rand of an OR.  
72c0: 49 66 20 74 68 69 73 0a 20 2a 20 6f 63 63 75 72  If this. * occur
72d0: 73 20 69 6e 20 74 68 65 20 71 75 65 72 79 20 73  s in the query s
72e0: 74 72 69 6e 67 2c 20 74 68 65 20 4e 4f 54 20 69  tring, the NOT i
72f0: 73 20 69 67 6e 6f 72 65 64 3a 0a 20 2a 0a 20 2a  s ignored:. *. *
7300: 20 20 20 20 5b 6f 6e 65 20 4f 52 20 2d 74 77 6f      [one OR -two
7310: 5d 20 20 20 20 20 20 20 20 20 20 3d 3d 3e 20 20  ]          ==>  
7320: 20 20 6f 6e 65 20 4f 52 20 74 77 6f 0a 20 2a 0a    one OR two. *.
7330: 20 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75   */.typedef stru
7340: 63 74 20 51 75 65 72 79 20 7b 0a 20 20 66 75 6c  ct Query {.  ful
7350: 6c 74 65 78 74 5f 76 74 61 62 20 2a 70 46 74 73  ltext_vtab *pFts
7360: 3b 20 20 2f 2a 20 54 68 65 20 66 75 6c 6c 20 74  ;  /* The full t
7370: 65 78 74 20 69 6e 64 65 78 20 2a 2f 0a 20 20 69  ext index */.  i
7380: 6e 74 20 6e 54 65 72 6d 73 3b 20 20 20 20 20 20  nt nTerms;      
7390: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
73a0: 66 20 74 65 72 6d 73 20 69 6e 20 74 68 65 20 71  f terms in the q
73b0: 75 65 72 79 20 2a 2f 0a 20 20 51 75 65 72 79 54  uery */.  QueryT
73c0: 65 72 6d 20 2a 70 54 65 72 6d 73 3b 20 20 20 20  erm *pTerms;    
73d0: 2f 2a 20 41 72 72 61 79 20 6f 66 20 74 65 72 6d  /* Array of term
73e0: 73 2e 20 20 53 70 61 63 65 20 6f 62 74 61 69 6e  s.  Space obtain
73f0: 65 64 20 66 72 6f 6d 20 6d 61 6c 6c 6f 63 28 29  ed from malloc()
7400: 20 2a 2f 0a 20 20 69 6e 74 20 6e 65 78 74 49 73   */.  int nextIs
7410: 4f 72 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 53  Or;         /* S
7420: 65 74 20 74 68 65 20 69 73 4f 72 20 66 6c 61 67  et the isOr flag
7430: 20 6f 6e 20 74 68 65 20 6e 65 78 74 20 69 6e 73   on the next ins
7440: 65 72 74 65 64 20 74 65 72 6d 20 2a 2f 0a 20 20  erted term */.  
7450: 69 6e 74 20 6e 65 78 74 43 6f 6c 75 6d 6e 3b 20  int nextColumn; 
7460: 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 77 6f        /* Next wo
7470: 72 64 20 70 61 72 73 65 64 20 6d 75 73 74 20 62  rd parsed must b
7480: 65 20 69 6e 20 74 68 69 73 20 63 6f 6c 75 6d 6e  e in this column
7490: 20 2a 2f 0a 20 20 69 6e 74 20 64 66 6c 74 43 6f   */.  int dfltCo
74a0: 6c 75 6d 6e 3b 20 20 20 20 20 20 20 2f 2a 20 54  lumn;       /* T
74b0: 68 65 20 64 65 66 61 75 6c 74 20 63 6f 6c 75 6d  he default colum
74c0: 6e 20 2a 2f 0a 7d 20 51 75 65 72 79 3b 0a 0a 0a  n */.} Query;...
74d0: 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63  /*.** An instanc
74e0: 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  e of the followi
74f0: 6e 67 20 73 74 72 75 63 74 75 72 65 20 6b 65 65  ng structure kee
7500: 70 73 20 74 72 61 63 6b 20 6f 66 20 67 65 6e 65  ps track of gene
7510: 72 61 74 65 64 0a 2a 2a 20 6d 61 74 63 68 69 6e  rated.** matchin
7520: 67 2d 77 6f 72 64 20 6f 66 66 73 65 74 20 69 6e  g-word offset in
7530: 66 6f 72 6d 61 74 69 6f 6e 20 61 6e 64 20 73 6e  formation and sn
7540: 69 70 70 65 74 73 2e 0a 2a 2f 0a 74 79 70 65 64  ippets..*/.typed
7550: 65 66 20 73 74 72 75 63 74 20 53 6e 69 70 70 65  ef struct Snippe
7560: 74 20 7b 0a 20 20 69 6e 74 20 6e 4d 61 74 63 68  t {.  int nMatch
7570: 3b 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e  ;     /* Total n
7580: 75 6d 62 65 72 20 6f 66 20 6d 61 74 63 68 65 73  umber of matches
7590: 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c 6c 6f 63   */.  int nAlloc
75a0: 3b 20 20 20 20 20 2f 2a 20 53 70 61 63 65 20 61  ;     /* Space a
75b0: 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61 4d 61  llocated for aMa
75c0: 74 63 68 5b 5d 20 2a 2f 0a 20 20 73 74 72 75 63  tch[] */.  struc
75d0: 74 20 73 6e 69 70 70 65 74 4d 61 74 63 68 20 7b  t snippetMatch {
75e0: 20 2f 2a 20 4f 6e 65 20 65 6e 74 72 79 20 66 6f   /* One entry fo
75f0: 72 20 65 61 63 68 20 6d 61 74 63 68 69 6e 67 20  r each matching 
7600: 74 65 72 6d 20 2a 2f 0a 20 20 20 20 63 68 61 72  term */.    char
7610: 20 73 6e 53 74 61 74 75 73 3b 20 20 20 20 20 20   snStatus;      
7620: 20 2f 2a 20 53 74 61 74 75 73 20 66 6c 61 67 20   /* Status flag 
7630: 66 6f 72 20 75 73 65 20 77 68 69 6c 65 20 63 6f  for use while co
7640: 6e 73 74 72 75 63 74 69 6e 67 20 73 6e 69 70 70  nstructing snipp
7650: 65 74 73 20 2a 2f 0a 20 20 20 20 73 68 6f 72 74  ets */.    short
7660: 20 69 6e 74 20 69 43 6f 6c 3b 20 20 20 20 20 20   int iCol;      
7670: 2f 2a 20 54 68 65 20 63 6f 6c 75 6d 6e 20 74 68  /* The column th
7680: 61 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  at contains the 
7690: 6d 61 74 63 68 20 2a 2f 0a 20 20 20 20 73 68 6f  match */.    sho
76a0: 72 74 20 69 6e 74 20 69 54 65 72 6d 3b 20 20 20  rt int iTerm;   
76b0: 20 20 2f 2a 20 54 68 65 20 69 6e 64 65 78 20 69    /* The index i
76c0: 6e 20 51 75 65 72 79 2e 70 54 65 72 6d 73 5b 5d  n Query.pTerms[]
76d0: 20 6f 66 20 74 68 65 20 6d 61 74 63 68 69 6e 67   of the matching
76e0: 20 74 65 72 6d 20 2a 2f 0a 20 20 20 20 73 68 6f   term */.    sho
76f0: 72 74 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20  rt int nByte;   
7700: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
7710: 79 74 65 73 20 69 6e 20 74 68 65 20 74 65 72 6d  ytes in the term
7720: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 53 74 61   */.    int iSta
7730: 72 74 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20  rt;          /* 
7740: 54 68 65 20 6f 66 66 73 65 74 20 74 6f 20 74 68  The offset to th
7750: 65 20 66 69 72 73 74 20 63 68 61 72 61 63 74 65  e first characte
7760: 72 20 6f 66 20 74 68 65 20 74 65 72 6d 20 2a 2f  r of the term */
7770: 0a 20 20 7d 20 2a 61 4d 61 74 63 68 3b 20 20 20  .  } *aMatch;   
7780: 20 20 20 2f 2a 20 50 6f 69 6e 74 73 20 74 6f 20     /* Points to 
7790: 73 70 61 63 65 20 6f 62 74 61 69 6e 65 64 20 66  space obtained f
77a0: 72 6f 6d 20 6d 61 6c 6c 6f 63 20 2a 2f 0a 20 20  rom malloc */.  
77b0: 63 68 61 72 20 2a 7a 4f 66 66 73 65 74 3b 20 20  char *zOffset;  
77c0: 2f 2a 20 54 65 78 74 20 72 65 6e 64 65 72 69 6e  /* Text renderin
77d0: 67 20 6f 66 20 61 4d 61 74 63 68 5b 5d 20 2a 2f  g of aMatch[] */
77e0: 0a 20 20 69 6e 74 20 6e 4f 66 66 73 65 74 3b 20  .  int nOffset; 
77f0: 20 20 20 2f 2a 20 73 74 72 6c 65 6e 28 7a 4f 66     /* strlen(zOf
7800: 66 73 65 74 29 20 2a 2f 0a 20 20 63 68 61 72 20  fset) */.  char 
7810: 2a 7a 53 6e 69 70 70 65 74 3b 20 2f 2a 20 53 6e  *zSnippet; /* Sn
7820: 69 70 70 65 74 20 74 65 78 74 20 2a 2f 0a 20 20  ippet text */.  
7830: 69 6e 74 20 6e 53 6e 69 70 70 65 74 3b 20 20 20  int nSnippet;   
7840: 2f 2a 20 73 74 72 6c 65 6e 28 7a 53 6e 69 70 70  /* strlen(zSnipp
7850: 65 74 29 20 2a 2f 0a 7d 20 53 6e 69 70 70 65 74  et) */.} Snippet
7860: 3b 0a 0a 0a 74 79 70 65 64 65 66 20 65 6e 75 6d  ;...typedef enum
7870: 20 51 75 65 72 79 54 79 70 65 20 7b 0a 20 20 51   QueryType {.  Q
7880: 55 45 52 59 5f 47 45 4e 45 52 49 43 2c 20 20 20  UERY_GENERIC,   
7890: 2f 2a 20 74 61 62 6c 65 20 73 63 61 6e 20 2a 2f  /* table scan */
78a0: 0a 20 20 51 55 45 52 59 5f 52 4f 57 49 44 2c 20  .  QUERY_ROWID, 
78b0: 20 20 20 20 2f 2a 20 6c 6f 6f 6b 75 70 20 62 79      /* lookup by
78c0: 20 72 6f 77 69 64 20 2a 2f 0a 20 20 51 55 45 52   rowid */.  QUER
78d0: 59 5f 46 55 4c 4c 54 45 58 54 20 20 20 2f 2a 20  Y_FULLTEXT   /* 
78e0: 51 55 45 52 59 5f 46 55 4c 4c 54 45 58 54 20 2b  QUERY_FULLTEXT +
78f0: 20 5b 69 5d 20 69 73 20 61 20 66 75 6c 6c 2d 74   [i] is a full-t
7900: 65 78 74 20 73 65 61 72 63 68 20 66 6f 72 20 63  ext search for c
7910: 6f 6c 75 6d 6e 20 69 2a 2f 0a 7d 20 51 75 65 72  olumn i*/.} Quer
7920: 79 54 79 70 65 3b 0a 0a 2f 2a 20 54 4f 44 4f 28  yType;../* TODO(
7930: 73 68 65 73 73 29 20 43 48 55 4e 4b 5f 4d 41 58  shess) CHUNK_MAX
7940: 20 63 6f 6e 74 72 6f 6c 73 20 68 6f 77 20 6d 75   controls how mu
7950: 63 68 20 64 61 74 61 20 77 65 20 61 6c 6c 6f 77  ch data we allow
7960: 20 69 6e 20 73 65 67 6d 65 6e 74 20 30 0a 2a 2a   in segment 0.**
7970: 20 62 65 66 6f 72 65 20 77 65 20 73 74 61 72 74   before we start
7980: 20 61 67 67 72 65 67 61 74 69 6e 67 20 69 6e 74   aggregating int
7990: 6f 20 6c 61 72 67 65 72 20 73 65 67 6d 65 6e 74  o larger segment
79a0: 73 2e 20 20 4c 6f 77 65 72 20 43 48 55 4e 4b 5f  s.  Lower CHUNK_
79b0: 4d 41 58 0a 2a 2a 20 6d 65 61 6e 73 20 74 68 61  MAX.** means tha
79c0: 74 20 66 6f 72 20 61 20 67 69 76 65 6e 20 69 6e  t for a given in
79d0: 70 75 74 20 77 65 20 68 61 76 65 20 6d 6f 72 65  put we have more
79e0: 20 69 6e 64 69 76 69 64 75 61 6c 20 73 65 67 6d   individual segm
79f0: 65 6e 74 73 20 70 65 72 0a 2a 2a 20 74 65 72 6d  ents per.** term
7a00: 2c 20 77 68 69 63 68 20 6d 65 61 6e 73 20 6d 6f  , which means mo
7a10: 72 65 20 72 6f 77 73 20 69 6e 20 74 68 65 20 74  re rows in the t
7a20: 61 62 6c 65 20 61 6e 64 20 61 20 62 69 67 67 65  able and a bigge
7a30: 72 20 69 6e 64 65 78 20 28 64 75 65 20 74 6f 0a  r index (due to.
7a40: 2a 2a 20 62 6f 74 68 20 6d 6f 72 65 20 72 6f 77  ** both more row
7a50: 73 20 61 6e 64 20 62 69 67 67 65 72 20 72 6f 77  s and bigger row
7a60: 69 64 73 29 2e 20 20 42 75 74 20 69 74 20 61 6c  ids).  But it al
7a70: 73 6f 20 72 65 64 75 63 65 73 20 74 68 65 20 61  so reduces the a
7a80: 76 65 72 61 67 65 0a 2a 2a 20 63 6f 73 74 20 6f  verage.** cost o
7a90: 66 20 61 64 64 69 6e 67 20 6e 65 77 20 65 6c 65  f adding new ele
7aa0: 6d 65 6e 74 73 20 74 6f 20 74 68 65 20 73 65 67  ments to the seg
7ab0: 6d 65 6e 74 20 30 20 64 6f 63 6c 69 73 74 2c 20  ment 0 doclist, 
7ac0: 61 6e 64 20 69 74 20 73 65 65 6d 73 0a 2a 2a 20  and it seems.** 
7ad0: 74 6f 20 72 65 64 75 63 65 20 74 68 65 20 6e 75  to reduce the nu
7ae0: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 72 65  mber of pages re
7af0: 61 64 20 61 6e 64 20 77 72 69 74 74 65 6e 20 64  ad and written d
7b00: 75 72 69 6e 67 20 69 6e 73 65 72 74 73 2e 20 20  uring inserts.  
7b10: 32 35 36 0a 2a 2a 20 77 61 73 20 63 68 6f 73 65  256.** was chose
7b20: 6e 20 62 79 20 6d 65 61 73 75 72 69 6e 67 20 69  n by measuring i
7b30: 6e 73 65 72 74 69 6f 6e 20 74 69 6d 65 73 20 66  nsertion times f
7b40: 6f 72 20 61 20 63 65 72 74 61 69 6e 20 69 6e 70  or a certain inp
7b50: 75 74 20 28 66 69 72 73 74 0a 2a 2a 20 31 30 6b  ut (first.** 10k
7b60: 20 64 6f 63 75 6d 65 6e 74 73 20 6f 66 20 45 6e   documents of En
7b70: 72 6f 6e 20 63 6f 72 70 75 73 29 2c 20 74 68 6f  ron corpus), tho
7b80: 75 67 68 20 69 6e 63 6c 75 64 69 6e 67 20 71 75  ugh including qu
7b90: 65 72 79 20 70 65 72 66 6f 72 6d 61 6e 63 65 0a  ery performance.
7ba0: 2a 2a 20 69 6e 20 74 68 65 20 64 65 63 69 73 69  ** in the decisi
7bb0: 6f 6e 20 6d 61 79 20 61 72 67 75 65 20 66 6f 72  on may argue for
7bc0: 20 61 20 6c 61 72 67 65 72 20 76 61 6c 75 65 2e   a larger value.
7bd0: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 43 48 55 4e  .*/.#define CHUN
7be0: 4b 5f 4d 41 58 20 32 35 36 0a 0a 74 79 70 65 64  K_MAX 256..typed
7bf0: 65 66 20 65 6e 75 6d 20 66 75 6c 6c 74 65 78 74  ef enum fulltext
7c00: 5f 73 74 61 74 65 6d 65 6e 74 20 7b 0a 20 20 43  _statement {.  C
7c10: 4f 4e 54 45 4e 54 5f 49 4e 53 45 52 54 5f 53 54  ONTENT_INSERT_ST
7c20: 4d 54 2c 0a 20 20 43 4f 4e 54 45 4e 54 5f 53 45  MT,.  CONTENT_SE
7c30: 4c 45 43 54 5f 53 54 4d 54 2c 0a 20 20 43 4f 4e  LECT_STMT,.  CON
7c40: 54 45 4e 54 5f 55 50 44 41 54 45 5f 53 54 4d 54  TENT_UPDATE_STMT
7c50: 2c 0a 20 20 43 4f 4e 54 45 4e 54 5f 44 45 4c 45  ,.  CONTENT_DELE
7c60: 54 45 5f 53 54 4d 54 2c 0a 0a 20 20 54 45 52 4d  TE_STMT,..  TERM
7c70: 5f 53 45 4c 45 43 54 5f 53 54 4d 54 2c 0a 20 20  _SELECT_STMT,.  
7c80: 54 45 52 4d 5f 53 45 4c 45 43 54 5f 41 4c 4c 5f  TERM_SELECT_ALL_
7c90: 53 54 4d 54 2c 0a 20 20 54 45 52 4d 5f 49 4e 53  STMT,.  TERM_INS
7ca0: 45 52 54 5f 53 54 4d 54 2c 0a 20 20 54 45 52 4d  ERT_STMT,.  TERM
7cb0: 5f 55 50 44 41 54 45 5f 53 54 4d 54 2c 0a 20 20  _UPDATE_STMT,.  
7cc0: 54 45 52 4d 5f 44 45 4c 45 54 45 5f 53 54 4d 54  TERM_DELETE_STMT
7cd0: 2c 0a 0a 20 20 4d 41 58 5f 53 54 4d 54 20 20 20  ,..  MAX_STMT   
7ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7cf0: 20 20 2f 2a 20 41 6c 77 61 79 73 20 61 74 20 65    /* Always at e
7d00: 6e 64 21 20 2a 2f 0a 7d 20 66 75 6c 6c 74 65 78  nd! */.} fulltex
7d10: 74 5f 73 74 61 74 65 6d 65 6e 74 3b 0a 0a 2f 2a  t_statement;../*
7d20: 20 54 68 65 73 65 20 6d 75 73 74 20 65 78 61 63   These must exac
7d30: 74 6c 79 20 6d 61 74 63 68 20 74 68 65 20 65 6e  tly match the en
7d40: 75 6d 20 61 62 6f 76 65 2e 20 2a 2f 0a 2f 2a 20  um above. */./* 
7d50: 54 4f 44 4f 28 61 64 61 6d 29 3a 20 49 73 20 74  TODO(adam): Is t
7d60: 68 65 72 65 20 73 6f 6d 65 20 72 69 73 6b 20 74  here some risk t
7d70: 68 61 74 20 61 20 73 74 61 74 65 6d 65 6e 74 20  hat a statement 
7d80: 28 69 6e 20 70 61 72 74 69 63 75 6c 61 72 2c 0a  (in particular,.
7d90: 2a 2a 20 70 54 65 72 6d 53 65 6c 65 63 74 53 74  ** pTermSelectSt
7da0: 6d 74 29 20 77 69 6c 6c 20 62 65 20 75 73 65 64  mt) will be used
7db0: 20 69 6e 20 74 77 6f 20 63 75 72 73 6f 72 73 20   in two cursors 
7dc0: 61 74 20 6f 6e 63 65 2c 20 65 2e 67 2e 20 20 69  at once, e.g.  i
7dd0: 66 20 61 0a 2a 2a 20 71 75 65 72 79 20 6a 6f 69  f a.** query joi
7de0: 6e 73 20 61 20 76 69 72 74 75 61 6c 20 74 61 62  ns a virtual tab
7df0: 6c 65 20 74 6f 20 69 74 73 65 6c 66 3f 20 20 49  le to itself?  I
7e00: 66 20 73 6f 20 70 65 72 68 61 70 73 20 77 65 20  f so perhaps we 
7e10: 73 68 6f 75 6c 64 0a 2a 2a 20 6d 6f 76 65 20 73  should.** move s
7e20: 6f 6d 65 20 6f 66 20 74 68 65 73 65 20 74 6f 20  ome of these to 
7e30: 74 68 65 20 63 75 72 73 6f 72 20 6f 62 6a 65 63  the cursor objec
7e40: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e  t..*/.static con
7e50: 73 74 20 63 68 61 72 20 2a 63 6f 6e 73 74 20 66  st char *const f
7e60: 75 6c 6c 74 65 78 74 5f 7a 53 74 61 74 65 6d 65  ulltext_zStateme
7e70: 6e 74 5b 4d 41 58 5f 53 54 4d 54 5d 20 3d 20 7b  nt[MAX_STMT] = {
7e80: 0a 20 20 2f 2a 20 43 4f 4e 54 45 4e 54 5f 49 4e  .  /* CONTENT_IN
7e90: 53 45 52 54 20 2a 2f 20 4e 55 4c 4c 2c 20 20 2f  SERT */ NULL,  /
7ea0: 2a 20 67 65 6e 65 72 61 74 65 64 20 69 6e 20 63  * generated in c
7eb0: 6f 6e 74 65 6e 74 49 6e 73 65 72 74 53 74 61 74  ontentInsertStat
7ec0: 65 6d 65 6e 74 28 29 20 2a 2f 0a 20 20 2f 2a 20  ement() */.  /* 
7ed0: 43 4f 4e 54 45 4e 54 5f 53 45 4c 45 43 54 20 2a  CONTENT_SELECT *
7ee0: 2f 20 22 73 65 6c 65 63 74 20 2a 20 66 72 6f 6d  / "select * from
7ef0: 20 25 5f 63 6f 6e 74 65 6e 74 20 77 68 65 72 65   %_content where
7f00: 20 72 6f 77 69 64 20 3d 20 3f 22 2c 0a 20 20 2f   rowid = ?",.  /
7f10: 2a 20 43 4f 4e 54 45 4e 54 5f 55 50 44 41 54 45  * CONTENT_UPDATE
7f20: 20 2a 2f 20 4e 55 4c 4c 2c 20 20 2f 2a 20 67 65   */ NULL,  /* ge
7f30: 6e 65 72 61 74 65 64 20 69 6e 20 63 6f 6e 74 65  nerated in conte
7f40: 6e 74 55 70 64 61 74 65 53 74 61 74 65 6d 65 6e  ntUpdateStatemen
7f50: 74 28 29 20 2a 2f 0a 20 20 2f 2a 20 43 4f 4e 54  t() */.  /* CONT
7f60: 45 4e 54 5f 44 45 4c 45 54 45 20 2a 2f 20 22 64  ENT_DELETE */ "d
7f70: 65 6c 65 74 65 20 66 72 6f 6d 20 25 5f 63 6f 6e  elete from %_con
7f80: 74 65 6e 74 20 77 68 65 72 65 20 72 6f 77 69 64  tent where rowid
7f90: 20 3d 20 3f 22 2c 0a 0a 20 20 2f 2a 20 54 45 52   = ?",..  /* TER
7fa0: 4d 5f 53 45 4c 45 43 54 20 2a 2f 0a 20 20 22 73  M_SELECT */.  "s
7fb0: 65 6c 65 63 74 20 72 6f 77 69 64 2c 20 64 6f 63  elect rowid, doc
7fc0: 6c 69 73 74 20 66 72 6f 6d 20 25 5f 74 65 72 6d  list from %_term
7fd0: 20 77 68 65 72 65 20 74 65 72 6d 20 3d 20 3f 20   where term = ? 
7fe0: 61 6e 64 20 73 65 67 6d 65 6e 74 20 3d 20 3f 22  and segment = ?"
7ff0: 2c 0a 20 20 2f 2a 20 54 45 52 4d 5f 53 45 4c 45  ,.  /* TERM_SELE
8000: 43 54 5f 41 4c 4c 20 2a 2f 0a 20 20 22 73 65 6c  CT_ALL */.  "sel
8010: 65 63 74 20 64 6f 63 6c 69 73 74 20 66 72 6f 6d  ect doclist from
8020: 20 25 5f 74 65 72 6d 20 77 68 65 72 65 20 74 65   %_term where te
8030: 72 6d 20 3d 20 3f 20 6f 72 64 65 72 20 62 79 20  rm = ? order by 
8040: 73 65 67 6d 65 6e 74 22 2c 0a 20 20 2f 2a 20 54  segment",.  /* T
8050: 45 52 4d 5f 49 4e 53 45 52 54 20 2a 2f 0a 20 20  ERM_INSERT */.  
8060: 22 69 6e 73 65 72 74 20 69 6e 74 6f 20 25 5f 74  "insert into %_t
8070: 65 72 6d 20 28 72 6f 77 69 64 2c 20 74 65 72 6d  erm (rowid, term
8080: 2c 20 73 65 67 6d 65 6e 74 2c 20 64 6f 63 6c 69  , segment, docli
8090: 73 74 29 20 76 61 6c 75 65 73 20 28 3f 2c 20 3f  st) values (?, ?
80a0: 2c 20 3f 2c 20 3f 29 22 2c 0a 20 20 2f 2a 20 54  , ?, ?)",.  /* T
80b0: 45 52 4d 5f 55 50 44 41 54 45 20 2a 2f 20 22 75  ERM_UPDATE */ "u
80c0: 70 64 61 74 65 20 25 5f 74 65 72 6d 20 73 65 74  pdate %_term set
80d0: 20 64 6f 63 6c 69 73 74 20 3d 20 3f 20 77 68 65   doclist = ? whe
80e0: 72 65 20 72 6f 77 69 64 20 3d 20 3f 22 2c 0a 20  re rowid = ?",. 
80f0: 20 2f 2a 20 54 45 52 4d 5f 44 45 4c 45 54 45 20   /* TERM_DELETE 
8100: 2a 2f 20 22 64 65 6c 65 74 65 20 66 72 6f 6d 20  */ "delete from 
8110: 25 5f 74 65 72 6d 20 77 68 65 72 65 20 72 6f 77  %_term where row
8120: 69 64 20 3d 20 3f 22 2c 0a 7d 3b 0a 0a 2f 2a 0a  id = ?",.};../*.
8130: 2a 2a 20 41 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  ** A connection 
8140: 74 6f 20 61 20 66 75 6c 6c 74 65 78 74 20 69 6e  to a fulltext in
8150: 64 65 78 20 69 73 20 61 6e 20 69 6e 73 74 61 6e  dex is an instan
8160: 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77  ce of the follow
8170: 69 6e 67 0a 2a 2a 20 73 74 72 75 63 74 75 72 65  ing.** structure
8180: 2e 20 20 54 68 65 20 78 43 72 65 61 74 65 20 61  .  The xCreate a
8190: 6e 64 20 78 43 6f 6e 6e 65 63 74 20 6d 65 74 68  nd xConnect meth
81a0: 6f 64 73 20 63 72 65 61 74 65 20 61 6e 20 69 6e  ods create an in
81b0: 73 74 61 6e 63 65 0a 2a 2a 20 6f 66 20 74 68 69  stance.** of thi
81c0: 73 20 73 74 72 75 63 74 75 72 65 20 61 6e 64 20  s structure and 
81d0: 78 44 65 73 74 72 6f 79 20 61 6e 64 20 78 44 69  xDestroy and xDi
81e0: 73 63 6f 6e 6e 65 63 74 20 66 72 65 65 20 74 68  sconnect free th
81f0: 61 74 20 69 6e 73 74 61 6e 63 65 2e 0a 2a 2a 20  at instance..** 
8200: 41 6c 6c 20 6f 74 68 65 72 20 6d 65 74 68 6f 64  All other method
8210: 73 20 72 65 63 65 69 76 65 20 61 20 70 6f 69 6e  s receive a poin
8220: 74 65 72 20 74 6f 20 74 68 65 20 73 74 72 75 63  ter to the struc
8230: 74 75 72 65 20 61 73 20 6f 6e 65 20 6f 66 20 74  ture as one of t
8240: 68 65 69 72 0a 2a 2a 20 61 72 67 75 6d 65 6e 74  heir.** argument
8250: 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 66 75 6c  s..*/.struct ful
8260: 6c 74 65 78 74 5f 76 74 61 62 20 7b 0a 20 20 73  ltext_vtab {.  s
8270: 71 6c 69 74 65 33 5f 76 74 61 62 20 62 61 73 65  qlite3_vtab base
8280: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
8290: 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20 75 73  /* Base class us
82a0: 65 64 20 62 79 20 53 51 4c 69 74 65 20 63 6f 72  ed by SQLite cor
82b0: 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a  e */.  sqlite3 *
82c0: 64 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  db;             
82d0: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 64          /* The d
82e0: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
82f0: 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  on */.  const ch
8300: 61 72 20 2a 7a 44 62 3b 20 20 20 20 20 20 20 20  ar *zDb;        
8310: 20 20 20 20 20 20 20 20 20 2f 2a 20 6c 6f 67 69           /* logi
8320: 63 61 6c 20 64 61 74 61 62 61 73 65 20 6e 61 6d  cal database nam
8330: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  e */.  const cha
8340: 72 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20  r *zName;       
8350: 20 20 20 20 20 20 20 20 2f 2a 20 76 69 72 74 75          /* virtu
8360: 61 6c 20 74 61 62 6c 65 20 6e 61 6d 65 20 2a 2f  al table name */
8370: 0a 20 20 69 6e 74 20 6e 43 6f 6c 75 6d 6e 3b 20  .  int nColumn; 
8380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8390: 20 20 20 20 2f 2a 20 6e 75 6d 62 65 72 20 6f 66      /* number of
83a0: 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 76 69 72 74   columns in virt
83b0: 75 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63  ual table */.  c
83c0: 68 61 72 20 2a 2a 61 7a 43 6f 6c 75 6d 6e 3b 20  har **azColumn; 
83d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
83e0: 2f 2a 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 2e  /* column names.
83f0: 20 20 6d 61 6c 6c 6f 63 65 64 20 2a 2f 0a 20 20    malloced */.  
8400: 63 68 61 72 20 2a 2a 61 7a 43 6f 6e 74 65 6e 74  char **azContent
8410: 43 6f 6c 75 6d 6e 3b 20 20 20 20 20 20 20 20 20  Column;         
8420: 20 2f 2a 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73   /* column names
8430: 20 69 6e 20 63 6f 6e 74 65 6e 74 20 74 61 62 6c   in content tabl
8440: 65 3b 20 6d 61 6c 6c 6f 63 65 64 20 2a 2f 0a 20  e; malloced */. 
8450: 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a   sqlite3_tokeniz
8460: 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 3b 20  er *pTokenizer; 
8470: 20 20 2f 2a 20 74 6f 6b 65 6e 69 7a 65 72 20 66    /* tokenizer f
8480: 6f 72 20 69 6e 73 65 72 74 73 20 61 6e 64 20 71  or inserts and q
8490: 75 65 72 69 65 73 20 2a 2f 0a 0a 20 20 2f 2a 20  ueries */..  /* 
84a0: 50 72 65 63 6f 6d 70 69 6c 65 64 20 73 74 61 74  Precompiled stat
84b0: 65 6d 65 6e 74 73 20 77 68 69 63 68 20 77 65 20  ements which we 
84c0: 6b 65 65 70 20 61 73 20 6c 6f 6e 67 20 61 73 20  keep as long as 
84d0: 74 68 65 20 74 61 62 6c 65 20 69 73 0a 20 20 2a  the table is.  *
84e0: 2a 20 6f 70 65 6e 2e 0a 20 20 2a 2f 0a 20 20 73  * open..  */.  s
84f0: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 46 75  qlite3_stmt *pFu
8500: 6c 6c 74 65 78 74 53 74 61 74 65 6d 65 6e 74 73  lltextStatements
8510: 5b 4d 41 58 5f 53 54 4d 54 5d 3b 0a 7d 3b 0a 0a  [MAX_STMT];.};..
8520: 2f 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 63  /*.** When the c
8530: 6f 72 65 20 77 61 6e 74 73 20 74 6f 20 64 6f 20  ore wants to do 
8540: 61 20 71 75 65 72 79 2c 20 69 74 20 63 72 65 61  a query, it crea
8550: 74 65 20 61 20 63 75 72 73 6f 72 20 75 73 69 6e  te a cursor usin
8560: 67 20 61 0a 2a 2a 20 63 61 6c 6c 20 74 6f 20 78  g a.** call to x
8570: 4f 70 65 6e 2e 20 20 54 68 69 73 20 73 74 72 75  Open.  This stru
8580: 63 74 75 72 65 20 69 73 20 61 6e 20 69 6e 73 74  cture is an inst
8590: 61 6e 63 65 20 6f 66 20 61 20 63 75 72 73 6f 72  ance of a cursor
85a0: 2e 20 20 49 74 0a 2a 2a 20 69 73 20 64 65 73 74  .  It.** is dest
85b0: 72 6f 79 65 64 20 62 79 20 78 43 6c 6f 73 65 2e  royed by xClose.
85c0: 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75  .*/.typedef stru
85d0: 63 74 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73  ct fulltext_curs
85e0: 6f 72 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76  or {.  sqlite3_v
85f0: 74 61 62 5f 63 75 72 73 6f 72 20 62 61 73 65 3b  tab_cursor base;
8600: 20 20 20 20 20 20 20 20 2f 2a 20 42 61 73 65 20          /* Base 
8610: 63 6c 61 73 73 20 75 73 65 64 20 62 79 20 53 51  class used by SQ
8620: 4c 69 74 65 20 63 6f 72 65 20 2a 2f 0a 20 20 51  Lite core */.  Q
8630: 75 65 72 79 54 79 70 65 20 69 43 75 72 73 6f 72  ueryType iCursor
8640: 54 79 70 65 3b 20 20 20 20 20 20 20 20 20 20 20  Type;           
8650: 2f 2a 20 43 6f 70 79 20 6f 66 20 73 71 6c 69 74  /* Copy of sqlit
8660: 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64  e3_index_info.id
8670: 78 4e 75 6d 20 2a 2f 0a 20 20 73 71 6c 69 74 65  xNum */.  sqlite
8680: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 20 20  3_stmt *pStmt;  
8690: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72             /* Pr
86a0: 65 70 61 72 65 64 20 73 74 61 74 65 6d 65 6e 74  epared statement
86b0: 20 69 6e 20 75 73 65 20 62 79 20 74 68 65 20 63   in use by the c
86c0: 75 72 73 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 65  ursor */.  int e
86d0: 6f 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  of;             
86e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
86f0: 72 75 65 20 69 66 20 61 74 20 45 6e 64 20 4f 66  rue if at End Of
8700: 20 52 65 73 75 6c 74 73 20 2a 2f 0a 20 20 51 75   Results */.  Qu
8710: 65 72 79 20 71 3b 20 20 20 20 20 20 20 20 20 20  ery q;          
8720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8730: 2a 20 50 61 72 73 65 64 20 71 75 65 72 79 20 73  * Parsed query s
8740: 74 72 69 6e 67 20 2a 2f 0a 20 20 53 6e 69 70 70  tring */.  Snipp
8750: 65 74 20 73 6e 69 70 70 65 74 3b 20 20 20 20 20  et snippet;     
8760: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
8770: 61 63 68 65 64 20 73 6e 69 70 70 65 74 20 66 6f  ached snippet fo
8780: 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 6f  r the current ro
8790: 77 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 75  w */.  int iColu
87a0: 6d 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  mn;             
87b0: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6c 75 6d          /* Colum
87c0: 6e 20 62 65 69 6e 67 20 73 65 61 72 63 68 65 64  n being searched
87d0: 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 52 65 61   */.  DocListRea
87e0: 64 65 72 20 72 65 73 75 6c 74 3b 20 20 2f 2a 20  der result;  /* 
87f0: 75 73 65 64 20 77 68 65 6e 20 69 43 75 72 73 6f  used when iCurso
8800: 72 54 79 70 65 20 3d 3d 20 51 55 45 52 59 5f 46  rType == QUERY_F
8810: 55 4c 4c 54 45 58 54 20 2a 2f 20 0a 7d 20 66 75  ULLTEXT */ .} fu
8820: 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 3b 0a 0a  lltext_cursor;..
8830: 73 74 61 74 69 63 20 73 74 72 75 63 74 20 66 75  static struct fu
8840: 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 63 75 72  lltext_vtab *cur
8850: 73 6f 72 5f 76 74 61 62 28 66 75 6c 6c 74 65 78  sor_vtab(fulltex
8860: 74 5f 63 75 72 73 6f 72 20 2a 63 29 7b 0a 20 20  t_cursor *c){.  
8870: 72 65 74 75 72 6e 20 28 66 75 6c 6c 74 65 78 74  return (fulltext
8880: 5f 76 74 61 62 20 2a 29 20 63 2d 3e 62 61 73 65  _vtab *) c->base
8890: 2e 70 56 74 61 62 3b 0a 7d 0a 0a 73 74 61 74 69  .pVtab;.}..stati
88a0: 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f  c const sqlite3_
88b0: 6d 6f 64 75 6c 65 20 66 75 6c 6c 74 65 78 74 4d  module fulltextM
88c0: 6f 64 75 6c 65 3b 20 20 20 2f 2a 20 66 6f 72 77  odule;   /* forw
88d0: 61 72 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 20  ard declaration 
88e0: 2a 2f 0a 0a 2f 2a 20 41 70 70 65 6e 64 20 61 20  */../* Append a 
88f0: 6c 69 73 74 20 6f 66 20 73 74 72 69 6e 67 73 20  list of strings 
8900: 73 65 70 61 72 61 74 65 64 20 62 79 20 63 6f 6d  separated by com
8910: 6d 61 73 20 74 6f 20 61 20 53 74 72 69 6e 67 42  mas to a StringB
8920: 75 66 66 65 72 2e 20 2a 2f 0a 73 74 61 74 69 63  uffer. */.static
8930: 20 76 6f 69 64 20 61 70 70 65 6e 64 4c 69 73 74   void appendList
8940: 28 53 74 72 69 6e 67 42 75 66 66 65 72 20 2a 73  (StringBuffer *s
8950: 62 2c 20 69 6e 74 20 6e 53 74 72 69 6e 67 2c 20  b, int nString, 
8960: 63 68 61 72 20 2a 2a 61 7a 53 74 72 69 6e 67 29  char **azString)
8970: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72  {.  int i;.  for
8980: 28 69 3d 30 3b 20 69 3c 6e 53 74 72 69 6e 67 3b  (i=0; i<nString;
8990: 20 2b 2b 69 29 7b 0a 20 20 20 20 69 66 28 20 69   ++i){.    if( i
89a0: 3e 30 20 29 20 61 70 70 65 6e 64 28 73 62 2c 20  >0 ) append(sb, 
89b0: 22 2c 20 22 29 3b 0a 20 20 20 20 61 70 70 65 6e  ", ");.    appen
89c0: 64 28 73 62 2c 20 61 7a 53 74 72 69 6e 67 5b 69  d(sb, azString[i
89d0: 5d 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 52 65  ]);.  }.}../* Re
89e0: 74 75 72 6e 20 61 20 64 79 6e 61 6d 69 63 61 6c  turn a dynamical
89f0: 6c 79 20 67 65 6e 65 72 61 74 65 64 20 73 74 61  ly generated sta
8a00: 74 65 6d 65 6e 74 20 6f 66 20 74 68 65 20 66 6f  tement of the fo
8a10: 72 6d 0a 20 2a 20 20 20 69 6e 73 65 72 74 20 69  rm. *   insert i
8a20: 6e 74 6f 20 25 5f 63 6f 6e 74 65 6e 74 20 28 72  nto %_content (r
8a30: 6f 77 69 64 2c 20 2e 2e 2e 29 20 76 61 6c 75 65  owid, ...) value
8a40: 73 20 28 3f 2c 20 2e 2e 2e 29 0a 20 2a 2f 0a 73  s (?, ...). */.s
8a50: 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72  tatic const char
8a60: 20 2a 63 6f 6e 74 65 6e 74 49 6e 73 65 72 74 53   *contentInsertS
8a70: 74 61 74 65 6d 65 6e 74 28 66 75 6c 6c 74 65 78  tatement(fulltex
8a80: 74 5f 76 74 61 62 20 2a 76 29 7b 0a 20 20 53 74  t_vtab *v){.  St
8a90: 72 69 6e 67 42 75 66 66 65 72 20 73 62 3b 0a 20  ringBuffer sb;. 
8aa0: 20 69 6e 74 20 69 3b 0a 0a 20 20 69 6e 69 74 53   int i;..  initS
8ab0: 74 72 69 6e 67 42 75 66 66 65 72 28 26 73 62 29  tringBuffer(&sb)
8ac0: 3b 0a 20 20 61 70 70 65 6e 64 28 26 73 62 2c 20  ;.  append(&sb, 
8ad0: 22 69 6e 73 65 72 74 20 69 6e 74 6f 20 25 5f 63  "insert into %_c
8ae0: 6f 6e 74 65 6e 74 20 28 72 6f 77 69 64 2c 20 22  ontent (rowid, "
8af0: 29 3b 0a 20 20 61 70 70 65 6e 64 4c 69 73 74 28  );.  appendList(
8b00: 26 73 62 2c 20 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c  &sb, v->nColumn,
8b10: 20 76 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c   v->azContentCol
8b20: 75 6d 6e 29 3b 0a 20 20 61 70 70 65 6e 64 28 26  umn);.  append(&
8b30: 73 62 2c 20 22 29 20 76 61 6c 75 65 73 20 28 3f  sb, ") values (?
8b40: 22 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  ");.  for(i=0; i
8b50: 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69  <v->nColumn; ++i
8b60: 29 0a 20 20 20 20 61 70 70 65 6e 64 28 26 73 62  ).    append(&sb
8b70: 2c 20 22 2c 20 3f 22 29 3b 0a 20 20 61 70 70 65  , ", ?");.  appe
8b80: 6e 64 28 26 73 62 2c 20 22 29 22 29 3b 0a 20 20  nd(&sb, ")");.  
8b90: 72 65 74 75 72 6e 20 73 62 2e 73 3b 0a 7d 0a 0a  return sb.s;.}..
8ba0: 2f 2a 20 52 65 74 75 72 6e 20 61 20 64 79 6e 61  /* Return a dyna
8bb0: 6d 69 63 61 6c 6c 79 20 67 65 6e 65 72 61 74 65  mically generate
8bc0: 64 20 73 74 61 74 65 6d 65 6e 74 20 6f 66 20 74  d statement of t
8bd0: 68 65 20 66 6f 72 6d 0a 20 2a 20 20 20 75 70 64  he form. *   upd
8be0: 61 74 65 20 25 5f 63 6f 6e 74 65 6e 74 20 73 65  ate %_content se
8bf0: 74 20 5b 63 6f 6c 5f 30 5d 20 3d 20 3f 2c 20 5b  t [col_0] = ?, [
8c00: 63 6f 6c 5f 31 5d 20 3d 20 3f 2c 20 2e 2e 2e 0a  col_1] = ?, ....
8c10: 20 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   *              
8c20: 20 20 20 20 20 20 77 68 65 72 65 20 72 6f 77 69        where rowi
8c30: 64 20 3d 20 3f 0a 20 2a 2f 0a 73 74 61 74 69 63  d = ?. */.static
8c40: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e   const char *con
8c50: 74 65 6e 74 55 70 64 61 74 65 53 74 61 74 65 6d  tentUpdateStatem
8c60: 65 6e 74 28 66 75 6c 6c 74 65 78 74 5f 76 74 61  ent(fulltext_vta
8c70: 62 20 2a 76 29 7b 0a 20 20 53 74 72 69 6e 67 42  b *v){.  StringB
8c80: 75 66 66 65 72 20 73 62 3b 0a 20 20 69 6e 74 20  uffer sb;.  int 
8c90: 69 3b 0a 0a 20 20 69 6e 69 74 53 74 72 69 6e 67  i;..  initString
8ca0: 42 75 66 66 65 72 28 26 73 62 29 3b 0a 20 20 61  Buffer(&sb);.  a
8cb0: 70 70 65 6e 64 28 26 73 62 2c 20 22 75 70 64 61  ppend(&sb, "upda
8cc0: 74 65 20 25 5f 63 6f 6e 74 65 6e 74 20 73 65 74  te %_content set
8cd0: 20 22 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20   ");.  for(i=0; 
8ce0: 69 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b  i<v->nColumn; ++
8cf0: 69 29 20 7b 0a 20 20 20 20 69 66 28 20 69 3e 30  i) {.    if( i>0
8d00: 20 29 7b 0a 20 20 20 20 20 20 61 70 70 65 6e 64   ){.      append
8d10: 28 26 73 62 2c 20 22 2c 20 22 29 3b 0a 20 20 20  (&sb, ", ");.   
8d20: 20 7d 0a 20 20 20 20 61 70 70 65 6e 64 28 26 73   }.    append(&s
8d30: 62 2c 20 76 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43  b, v->azContentC
8d40: 6f 6c 75 6d 6e 5b 69 5d 29 3b 0a 20 20 20 20 61  olumn[i]);.    a
8d50: 70 70 65 6e 64 28 26 73 62 2c 20 22 20 3d 20 3f  ppend(&sb, " = ?
8d60: 22 29 3b 0a 20 20 7d 0a 20 20 61 70 70 65 6e 64  ");.  }.  append
8d70: 28 26 73 62 2c 20 22 20 77 68 65 72 65 20 72 6f  (&sb, " where ro
8d80: 77 69 64 20 3d 20 3f 22 29 3b 0a 20 20 72 65 74  wid = ?");.  ret
8d90: 75 72 6e 20 73 62 2e 73 3b 0a 7d 0a 0a 2f 2a 20  urn sb.s;.}../* 
8da0: 50 75 74 73 20 61 20 66 72 65 73 68 6c 79 2d 70  Puts a freshly-p
8db0: 72 65 70 61 72 65 64 20 73 74 61 74 65 6d 65 6e  repared statemen
8dc0: 74 20 64 65 74 65 72 6d 69 6e 65 64 20 62 79 20  t determined by 
8dd0: 69 53 74 6d 74 20 69 6e 20 2a 70 70 53 74 6d 74  iStmt in *ppStmt
8de0: 2e 0a 2a 2a 20 49 66 20 74 68 65 20 69 6e 64 69  ..** If the indi
8df0: 63 61 74 65 64 20 73 74 61 74 65 6d 65 6e 74 20  cated statement 
8e00: 68 61 73 20 6e 65 76 65 72 20 62 65 65 6e 20 70  has never been p
8e10: 72 65 70 61 72 65 64 2c 20 69 74 20 69 73 20 70  repared, it is p
8e20: 72 65 70 61 72 65 64 0a 2a 2a 20 61 6e 64 20 63  repared.** and c
8e30: 61 63 68 65 64 2c 20 6f 74 68 65 72 77 69 73 65  ached, otherwise
8e40: 20 74 68 65 20 63 61 63 68 65 64 20 76 65 72 73   the cached vers
8e50: 69 6f 6e 20 69 73 20 72 65 73 65 74 2e 0a 2a 2f  ion is reset..*/
8e60: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 71 6c 5f  .static int sql_
8e70: 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 66 75  get_statement(fu
8e80: 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20  lltext_vtab *v, 
8e90: 66 75 6c 6c 74 65 78 74 5f 73 74 61 74 65 6d 65  fulltext_stateme
8ea0: 6e 74 20 69 53 74 6d 74 2c 0a 20 20 20 20 20 20  nt iStmt,.      
8eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ec0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73         sqlite3_s
8ed0: 74 6d 74 20 2a 2a 70 70 53 74 6d 74 29 7b 0a 20  tmt **ppStmt){. 
8ee0: 20 61 73 73 65 72 74 28 20 69 53 74 6d 74 3c 4d   assert( iStmt<M
8ef0: 41 58 5f 53 54 4d 54 20 29 3b 0a 20 20 69 66 28  AX_STMT );.  if(
8f00: 20 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61   v->pFulltextSta
8f10: 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 3d 3d  tements[iStmt]==
8f20: 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 63 6f 6e 73  NULL ){.    cons
8f30: 74 20 63 68 61 72 20 2a 7a 53 74 6d 74 3b 0a 20  t char *zStmt;. 
8f40: 20 20 20 69 6e 74 20 72 63 3b 0a 20 20 20 20 73     int rc;.    s
8f50: 77 69 74 63 68 28 20 69 53 74 6d 74 20 29 7b 0a  witch( iStmt ){.
8f60: 20 20 20 20 20 20 63 61 73 65 20 43 4f 4e 54 45        case CONTE
8f70: 4e 54 5f 49 4e 53 45 52 54 5f 53 54 4d 54 3a 0a  NT_INSERT_STMT:.
8f80: 20 20 20 20 20 20 20 20 7a 53 74 6d 74 20 3d 20          zStmt = 
8f90: 63 6f 6e 74 65 6e 74 49 6e 73 65 72 74 53 74 61  contentInsertSta
8fa0: 74 65 6d 65 6e 74 28 76 29 3b 20 62 72 65 61 6b  tement(v); break
8fb0: 3b 0a 20 20 20 20 20 20 63 61 73 65 20 43 4f 4e  ;.      case CON
8fc0: 54 45 4e 54 5f 55 50 44 41 54 45 5f 53 54 4d 54  TENT_UPDATE_STMT
8fd0: 3a 0a 20 20 20 20 20 20 20 20 7a 53 74 6d 74 20  :.        zStmt 
8fe0: 3d 20 63 6f 6e 74 65 6e 74 55 70 64 61 74 65 53  = contentUpdateS
8ff0: 74 61 74 65 6d 65 6e 74 28 76 29 3b 20 62 72 65  tatement(v); bre
9000: 61 6b 3b 0a 20 20 20 20 20 20 64 65 66 61 75 6c  ak;.      defaul
9010: 74 3a 0a 20 20 20 20 20 20 20 20 7a 53 74 6d 74  t:.        zStmt
9020: 20 3d 20 66 75 6c 6c 74 65 78 74 5f 7a 53 74 61   = fulltext_zSta
9030: 74 65 6d 65 6e 74 5b 69 53 74 6d 74 5d 3b 0a 20  tement[iStmt];. 
9040: 20 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73 71     }.    rc = sq
9050: 6c 5f 70 72 65 70 61 72 65 28 76 2d 3e 64 62 2c  l_prepare(v->db,
9060: 20 76 2d 3e 7a 44 62 2c 20 76 2d 3e 7a 4e 61 6d   v->zDb, v->zNam
9070: 65 2c 20 26 76 2d 3e 70 46 75 6c 6c 74 65 78 74  e, &v->pFulltext
9080: 53 74 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74  Statements[iStmt
9090: 5d 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ],.             
90a0: 20 20 20 20 20 20 20 20 20 20 20 20 7a 53 74 6d              zStm
90b0: 74 29 3b 0a 20 20 20 20 69 66 28 20 7a 53 74 6d  t);.    if( zStm
90c0: 74 20 21 3d 20 66 75 6c 6c 74 65 78 74 5f 7a 53  t != fulltext_zS
90d0: 74 61 74 65 6d 65 6e 74 5b 69 53 74 6d 74 5d 29  tatement[iStmt])
90e0: 20 66 72 65 65 28 28 76 6f 69 64 20 2a 29 20 7a   free((void *) z
90f0: 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 72  Stmt);.    if( r
9100: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
9110: 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 20 65 6c  eturn rc;.  } el
9120: 73 65 20 7b 0a 20 20 20 20 69 6e 74 20 72 63 20  se {.    int rc 
9130: 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28  = sqlite3_reset(
9140: 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74  v->pFulltextStat
9150: 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 29 3b 0a  ements[iStmt]);.
9160: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
9170: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
9180: 63 3b 0a 20 20 7d 0a 0a 20 20 2a 70 70 53 74 6d  c;.  }..  *ppStm
9190: 74 20 3d 20 76 2d 3e 70 46 75 6c 6c 74 65 78 74  t = v->pFulltext
91a0: 53 74 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74  Statements[iStmt
91b0: 5d 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  ];.  return SQLI
91c0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 53 74 65  TE_OK;.}../* Ste
91d0: 70 20 74 68 65 20 69 6e 64 69 63 61 74 65 64 20  p the indicated 
91e0: 73 74 61 74 65 6d 65 6e 74 2c 20 68 61 6e 64 6c  statement, handl
91f0: 69 6e 67 20 65 72 72 6f 72 73 20 53 51 4c 49 54  ing errors SQLIT
9200: 45 5f 42 55 53 59 20 28 62 79 0a 2a 2a 20 72 65  E_BUSY (by.** re
9210: 74 72 79 69 6e 67 29 20 61 6e 64 20 53 51 4c 49  trying) and SQLI
9220: 54 45 5f 53 43 48 45 4d 41 20 28 62 79 20 72 65  TE_SCHEMA (by re
9230: 2d 70 72 65 70 61 72 69 6e 67 20 61 6e 64 20 74  -preparing and t
9240: 72 61 6e 73 66 65 72 72 69 6e 67 0a 2a 2a 20 62  ransferring.** b
9250: 69 6e 64 69 6e 67 73 20 74 6f 20 74 68 65 20 6e  indings to the n
9260: 65 77 20 73 74 61 74 65 6d 65 6e 74 29 2e 0a 2a  ew statement)..*
9270: 2a 20 54 4f 44 4f 28 61 64 61 6d 29 3a 20 57 65  * TODO(adam): We
9280: 20 73 68 6f 75 6c 64 20 65 78 74 65 6e 64 20 74   should extend t
9290: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 73 6f 20  his function so 
92a0: 74 68 61 74 20 69 74 20 63 61 6e 20 77 6f 72 6b  that it can work
92b0: 20 77 69 74 68 0a 2a 2a 20 73 74 61 74 65 6d 65   with.** stateme
92c0: 6e 74 73 20 64 65 63 6c 61 72 65 64 20 6c 6f 63  nts declared loc
92d0: 61 6c 6c 79 2c 20 6e 6f 74 20 6f 6e 6c 79 20 67  ally, not only g
92e0: 6c 6f 62 61 6c 6c 79 20 63 61 63 68 65 64 20 73  lobally cached s
92f0: 74 61 74 65 6d 65 6e 74 73 2e 0a 2a 2f 0a 73 74  tatements..*/.st
9300: 61 74 69 63 20 69 6e 74 20 73 71 6c 5f 73 74 65  atic int sql_ste
9310: 70 5f 73 74 61 74 65 6d 65 6e 74 28 66 75 6c 6c  p_statement(full
9320: 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 66 75  text_vtab *v, fu
9330: 6c 6c 74 65 78 74 5f 73 74 61 74 65 6d 65 6e 74  lltext_statement
9340: 20 69 53 74 6d 74 2c 0a 20 20 20 20 20 20 20 20   iStmt,.        
9350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9360: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74        sqlite3_st
9370: 6d 74 20 2a 2a 70 70 53 74 6d 74 29 7b 0a 20 20  mt **ppStmt){.  
9380: 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69 74 65  int rc;.  sqlite
9390: 33 5f 73 74 6d 74 20 2a 73 20 3d 20 2a 70 70 53  3_stmt *s = *ppS
93a0: 74 6d 74 3b 0a 20 20 61 73 73 65 72 74 28 20 69  tmt;.  assert( i
93b0: 53 74 6d 74 3c 4d 41 58 5f 53 54 4d 54 20 29 3b  Stmt<MAX_STMT );
93c0: 0a 20 20 61 73 73 65 72 74 28 20 73 3d 3d 76 2d  .  assert( s==v-
93d0: 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d  >pFulltextStatem
93e0: 65 6e 74 73 5b 69 53 74 6d 74 5d 20 29 3b 0a 0a  ents[iStmt] );..
93f0: 20 20 77 68 69 6c 65 28 20 28 72 63 3d 73 71 6c    while( (rc=sql
9400: 69 74 65 33 5f 73 74 65 70 28 73 29 29 21 3d 53  ite3_step(s))!=S
9410: 51 4c 49 54 45 5f 44 4f 4e 45 20 26 26 20 72 63  QLITE_DONE && rc
9420: 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a  !=SQLITE_ROW ){.
9430: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
9440: 54 45 5f 42 55 53 59 20 29 20 63 6f 6e 74 69 6e  TE_BUSY ) contin
9450: 75 65 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  ue;.    if( rc!=
9460: 53 51 4c 49 54 45 5f 45 52 52 4f 52 20 29 20 72  SQLITE_ERROR ) r
9470: 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20 2f  eturn rc;..    /
9480: 2a 20 49 66 20 61 6e 20 53 51 4c 49 54 45 5f 53  * If an SQLITE_S
9490: 43 48 45 4d 41 20 65 72 72 6f 72 20 68 61 73 20  CHEMA error has 
94a0: 6f 63 63 75 72 72 65 64 2c 20 74 68 65 6e 20 66  occurred, then f
94b0: 69 6e 61 6c 69 7a 69 6e 67 20 74 68 69 73 0a 20  inalizing this. 
94c0: 20 20 20 20 2a 20 73 74 61 74 65 6d 65 6e 74 20      * statement 
94d0: 69 73 20 67 6f 69 6e 67 20 74 6f 20 64 65 6c 65  is going to dele
94e0: 74 65 20 74 68 65 20 66 75 6c 6c 74 65 78 74 5f  te the fulltext_
94f0: 76 74 61 62 20 73 74 72 75 63 74 75 72 65 2e 20  vtab structure. 
9500: 49 66 0a 20 20 20 20 20 2a 20 74 68 65 20 73 74  If.     * the st
9510: 61 74 65 6d 65 6e 74 20 6a 75 73 74 20 65 78 65  atement just exe
9520: 63 75 74 65 64 20 69 73 20 69 6e 20 74 68 65 20  cuted is in the 
9530: 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d 65  pFulltextStateme
9540: 6e 74 73 5b 5d 0a 20 20 20 20 20 2a 20 61 72 72  nts[].     * arr
9550: 61 79 2c 20 69 74 20 77 69 6c 6c 20 62 65 20 66  ay, it will be f
9560: 69 6e 61 6c 69 7a 65 64 20 74 77 69 63 65 2e 20  inalized twice. 
9570: 53 6f 20 72 65 6d 6f 76 65 20 69 74 20 62 65 66  So remove it bef
9580: 6f 72 65 0a 20 20 20 20 20 2a 20 63 61 6c 6c 69  ore.     * calli
9590: 6e 67 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  ng sqlite3_final
95a0: 69 7a 65 28 29 2e 0a 20 20 20 20 20 2a 2f 0a 20  ize()..     */. 
95b0: 20 20 20 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53     v->pFulltextS
95c0: 74 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d  tatements[iStmt]
95d0: 20 3d 20 4e 55 4c 4c 3b 0a 20 20 20 20 72 63 20   = NULL;.    rc 
95e0: 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69  = sqlite3_finali
95f0: 7a 65 28 73 29 3b 0a 20 20 20 20 62 72 65 61 6b  ze(s);.    break
9600: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
9610: 63 3b 0a 0a 20 65 72 72 3a 0a 20 20 73 71 6c 69  c;.. err:.  sqli
9620: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 73 29 3b  te3_finalize(s);
9630: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
9640: 0a 2f 2a 20 4c 69 6b 65 20 73 71 6c 5f 73 74 65  ./* Like sql_ste
9650: 70 5f 73 74 61 74 65 6d 65 6e 74 28 29 2c 20 62  p_statement(), b
9660: 75 74 20 63 6f 6e 76 65 72 74 20 53 51 4c 49 54  ut convert SQLIT
9670: 45 5f 44 4f 4e 45 20 74 6f 20 53 51 4c 49 54 45  E_DONE to SQLITE
9680: 5f 4f 4b 2e 0a 2a 2a 20 55 73 65 66 75 6c 20 66  _OK..** Useful f
9690: 6f 72 20 73 74 61 74 65 6d 65 6e 74 73 20 6c 69  or statements li
96a0: 6b 65 20 55 50 44 41 54 45 2c 20 77 68 65 72 65  ke UPDATE, where
96b0: 20 77 65 20 65 78 70 65 63 74 20 6e 6f 20 72 65   we expect no re
96c0: 73 75 6c 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  sults..*/.static
96d0: 20 69 6e 74 20 73 71 6c 5f 73 69 6e 67 6c 65 5f   int sql_single_
96e0: 73 74 65 70 5f 73 74 61 74 65 6d 65 6e 74 28 66  step_statement(f
96f0: 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c  ulltext_vtab *v,
9700: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
9710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9720: 20 20 20 20 20 20 66 75 6c 6c 74 65 78 74 5f 73        fulltext_s
9730: 74 61 74 65 6d 65 6e 74 20 69 53 74 6d 74 2c 0a  tatement iStmt,.
9740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9760: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d       sqlite3_stm
9770: 74 20 2a 2a 70 70 53 74 6d 74 29 7b 0a 20 20 69  t **ppStmt){.  i
9780: 6e 74 20 72 63 20 3d 20 73 71 6c 5f 73 74 65 70  nt rc = sql_step
9790: 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 69 53  _statement(v, iS
97a0: 74 6d 74 2c 20 70 70 53 74 6d 74 29 3b 0a 20 20  tmt, ppStmt);.  
97b0: 72 65 74 75 72 6e 20 28 72 63 3d 3d 53 51 4c 49  return (rc==SQLI
97c0: 54 45 5f 44 4f 4e 45 29 20 3f 20 53 51 4c 49 54  TE_DONE) ? SQLIT
97d0: 45 5f 4f 4b 20 3a 20 72 63 3b 0a 7d 0a 0a 2f 2a  E_OK : rc;.}../*
97e0: 20 69 6e 73 65 72 74 20 69 6e 74 6f 20 25 5f 63   insert into %_c
97f0: 6f 6e 74 65 6e 74 20 28 72 6f 77 69 64 2c 20 2e  ontent (rowid, .
9800: 2e 2e 29 20 76 61 6c 75 65 73 20 28 5b 72 6f 77  ..) values ([row
9810: 69 64 5d 2c 20 5b 70 56 61 6c 75 65 73 5d 29 20  id], [pValues]) 
9820: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 63 6f  */.static int co
9830: 6e 74 65 6e 74 5f 69 6e 73 65 72 74 28 66 75 6c  ntent_insert(ful
9840: 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 73  ltext_vtab *v, s
9850: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 72 6f  qlite3_value *ro
9860: 77 69 64 2c 0a 20 20 20 20 20 20 20 20 20 20 20  wid,.           
9870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
9880: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70  qlite3_value **p
9890: 56 61 6c 75 65 73 29 7b 0a 20 20 73 71 6c 69 74  Values){.  sqlit
98a0: 65 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20 69 6e  e3_stmt *s;.  in
98b0: 74 20 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20  t i;.  int rc = 
98c0: 73 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e  sql_get_statemen
98d0: 74 28 76 2c 20 43 4f 4e 54 45 4e 54 5f 49 4e 53  t(v, CONTENT_INS
98e0: 45 52 54 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20  ERT_STMT, &s);. 
98f0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
9900: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
9910: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
9920: 62 69 6e 64 5f 76 61 6c 75 65 28 73 2c 20 31 2c  bind_value(s, 1,
9930: 20 72 6f 77 69 64 29 3b 0a 20 20 69 66 28 20 72   rowid);.  if( r
9940: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
9950: 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 66 6f 72  eturn rc;..  for
9960: 28 69 3d 30 3b 20 69 3c 76 2d 3e 6e 43 6f 6c 75  (i=0; i<v->nColu
9970: 6d 6e 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 72 63  mn; ++i){.    rc
9980: 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   = sqlite3_bind_
9990: 76 61 6c 75 65 28 73 2c 20 32 2b 69 2c 20 70 56  value(s, 2+i, pV
99a0: 61 6c 75 65 73 5b 69 5d 29 3b 0a 20 20 20 20 69  alues[i]);.    i
99b0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
99c0: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
99d0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 5f  }..  return sql_
99e0: 73 69 6e 67 6c 65 5f 73 74 65 70 5f 73 74 61 74  single_step_stat
99f0: 65 6d 65 6e 74 28 76 2c 20 43 4f 4e 54 45 4e 54  ement(v, CONTENT
9a00: 5f 49 4e 53 45 52 54 5f 53 54 4d 54 2c 20 26 73  _INSERT_STMT, &s
9a10: 29 3b 0a 7d 0a 0a 2f 2a 20 75 70 64 61 74 65 20  );.}../* update 
9a20: 25 5f 63 6f 6e 74 65 6e 74 20 73 65 74 20 63 6f  %_content set co
9a30: 6c 30 20 3d 20 70 56 61 6c 75 65 73 5b 30 5d 2c  l0 = pValues[0],
9a40: 20 63 6f 6c 31 20 3d 20 70 56 61 6c 75 65 73 5b   col1 = pValues[
9a50: 31 5d 2c 20 2e 2e 2e 0a 20 2a 20 20 20 20 20 20  1], .... *      
9a60: 20 20 20 20 20 20 20 20 20 20 20 20 77 68 65 72              wher
9a70: 65 20 72 6f 77 69 64 20 3d 20 5b 69 52 6f 77 69  e rowid = [iRowi
9a80: 64 5d 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d] */.static int
9a90: 20 63 6f 6e 74 65 6e 74 5f 75 70 64 61 74 65 28   content_update(
9aa0: 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
9ab0: 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20  , sqlite3_value 
9ac0: 2a 2a 70 56 61 6c 75 65 73 2c 0a 20 20 20 20 20  **pValues,.     
9ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9ae0: 20 20 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36       sqlite_int6
9af0: 34 20 69 52 6f 77 69 64 29 7b 0a 20 20 73 71 6c  4 iRowid){.  sql
9b00: 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20  ite3_stmt *s;.  
9b10: 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72 63 20  int i;.  int rc 
9b20: 3d 20 73 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d  = sql_get_statem
9b30: 65 6e 74 28 76 2c 20 43 4f 4e 54 45 4e 54 5f 55  ent(v, CONTENT_U
9b40: 50 44 41 54 45 5f 53 54 4d 54 2c 20 26 73 29 3b  PDATE_STMT, &s);
9b50: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
9b60: 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
9b70: 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  ;..  for(i=0; i<
9b80: 76 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29  v->nColumn; ++i)
9b90: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
9ba0: 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 73 2c  e3_bind_value(s,
9bb0: 20 31 2b 69 2c 20 70 56 61 6c 75 65 73 5b 69 5d   1+i, pValues[i]
9bc0: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
9bd0: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
9be0: 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 72 63 20  n rc;.  }..  rc 
9bf0: 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69  = sqlite3_bind_i
9c00: 6e 74 36 34 28 73 2c 20 31 2b 76 2d 3e 6e 43 6f  nt64(s, 1+v->nCo
9c10: 6c 75 6d 6e 2c 20 69 52 6f 77 69 64 29 3b 0a 20  lumn, iRowid);. 
9c20: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
9c30: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
9c40: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 5f 73 69  .  return sql_si
9c50: 6e 67 6c 65 5f 73 74 65 70 5f 73 74 61 74 65 6d  ngle_step_statem
9c60: 65 6e 74 28 76 2c 20 43 4f 4e 54 45 4e 54 5f 55  ent(v, CONTENT_U
9c70: 50 44 41 54 45 5f 53 54 4d 54 2c 20 26 73 29 3b  PDATE_STMT, &s);
9c80: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
9c90: 66 72 65 65 53 74 72 69 6e 67 41 72 72 61 79 28  freeStringArray(
9ca0: 69 6e 74 20 6e 53 74 72 69 6e 67 2c 20 63 6f 6e  int nString, con
9cb0: 73 74 20 63 68 61 72 20 2a 2a 70 53 74 72 69 6e  st char **pStrin
9cc0: 67 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20  g){.  int i;..  
9cd0: 66 6f 72 20 28 69 3d 30 20 3b 20 69 20 3c 20 6e  for (i=0 ; i < n
9ce0: 53 74 72 69 6e 67 20 3b 20 2b 2b 69 29 20 7b 0a  String ; ++i) {.
9cf0: 20 20 20 20 69 66 28 20 70 53 74 72 69 6e 67 5b      if( pString[
9d00: 69 5d 21 3d 4e 55 4c 4c 20 29 20 66 72 65 65 28  i]!=NULL ) free(
9d10: 28 76 6f 69 64 20 2a 29 20 70 53 74 72 69 6e 67  (void *) pString
9d20: 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 66 72 65 65  [i]);.  }.  free
9d30: 28 28 76 6f 69 64 20 2a 29 20 70 53 74 72 69 6e  ((void *) pStrin
9d40: 67 29 3b 0a 7d 0a 0a 2f 2a 20 73 65 6c 65 63 74  g);.}../* select
9d50: 20 2a 20 66 72 6f 6d 20 25 5f 63 6f 6e 74 65 6e   * from %_conten
9d60: 74 20 77 68 65 72 65 20 72 6f 77 69 64 20 3d 20  t where rowid = 
9d70: 5b 69 52 6f 77 5d 0a 20 2a 20 54 68 65 20 63 61  [iRow]. * The ca
9d80: 6c 6c 65 72 20 6d 75 73 74 20 64 65 6c 65 74 65  ller must delete
9d90: 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 61 72   the returned ar
9da0: 72 61 79 20 61 6e 64 20 61 6c 6c 20 73 74 72 69  ray and all stri
9db0: 6e 67 73 20 69 6e 20 69 74 2e 0a 20 2a 20 6e 75  ngs in it.. * nu
9dc0: 6c 6c 20 66 69 65 6c 64 73 20 77 69 6c 6c 20 62  ll fields will b
9dd0: 65 20 4e 55 4c 4c 20 69 6e 20 74 68 65 20 72 65  e NULL in the re
9de0: 74 75 72 6e 65 64 20 61 72 72 61 79 2e 0a 20 2a  turned array.. *
9df0: 0a 20 2a 20 54 4f 44 4f 3a 20 50 65 72 68 61 70  . * TODO: Perhap
9e00: 73 20 77 65 20 73 68 6f 75 6c 64 20 72 65 74 75  s we should retu
9e10: 72 6e 20 70 6f 69 6e 74 65 72 2f 6c 65 6e 67 74  rn pointer/lengt
9e20: 68 20 73 74 72 69 6e 67 73 20 68 65 72 65 20 66  h strings here f
9e30: 6f 72 20 63 6f 6e 73 69 73 74 65 6e 63 79 0a 20  or consistency. 
9e40: 2a 20 77 69 74 68 20 6f 74 68 65 72 20 63 6f 64  * with other cod
9e50: 65 20 77 68 69 63 68 20 75 73 65 73 20 70 6f 69  e which uses poi
9e60: 6e 74 65 72 2f 6c 65 6e 67 74 68 2e 20 2a 2f 0a  nter/length. */.
9e70: 73 74 61 74 69 63 20 69 6e 74 20 63 6f 6e 74 65  static int conte
9e80: 6e 74 5f 73 65 6c 65 63 74 28 66 75 6c 6c 74 65  nt_select(fullte
9e90: 78 74 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69  xt_vtab *v, sqli
9ea0: 74 65 5f 69 6e 74 36 34 20 69 52 6f 77 2c 0a 20  te_int64 iRow,. 
9eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9ec0: 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63           const c
9ed0: 68 61 72 20 2a 2a 2a 70 56 61 6c 75 65 73 29 7b  har ***pValues){
9ee0: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
9ef0: 2a 73 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  *s;.  const char
9f00: 20 2a 2a 76 61 6c 75 65 73 3b 0a 20 20 69 6e 74   **values;.  int
9f10: 20 69 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20   i;.  int rc;.. 
9f20: 20 2a 70 56 61 6c 75 65 73 20 3d 20 4e 55 4c 4c   *pValues = NULL
9f30: 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 5f 67 65  ;..  rc = sql_ge
9f40: 74 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 43  t_statement(v, C
9f50: 4f 4e 54 45 4e 54 5f 53 45 4c 45 43 54 5f 53 54  ONTENT_SELECT_ST
9f60: 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72  MT, &s);.  if( r
9f70: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
9f80: 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20  eturn rc;..  rc 
9f90: 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69  = sqlite3_bind_i
9fa0: 6e 74 36 34 28 73 2c 20 31 2c 20 69 52 6f 77 29  nt64(s, 1, iRow)
9fb0: 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
9fc0: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
9fd0: 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 5f 73  c;..  rc = sql_s
9fe0: 74 65 70 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c  tep_statement(v,
9ff0: 20 43 4f 4e 54 45 4e 54 5f 53 45 4c 45 43 54 5f   CONTENT_SELECT_
a000: 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28  STMT, &s);.  if(
a010: 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20   rc!=SQLITE_ROW 
a020: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
a030: 76 61 6c 75 65 73 20 3d 20 28 63 6f 6e 73 74 20  values = (const 
a040: 63 68 61 72 20 2a 2a 29 20 6d 61 6c 6c 6f 63 28  char **) malloc(
a050: 76 2d 3e 6e 43 6f 6c 75 6d 6e 20 2a 20 73 69 7a  v->nColumn * siz
a060: 65 6f 66 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  eof(const char *
a070: 29 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  ));.  for(i=0; i
a080: 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69  <v->nColumn; ++i
a090: 29 7b 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74  ){.    if( sqlit
a0a0: 65 33 5f 63 6f 6c 75 6d 6e 5f 74 79 70 65 28 73  e3_column_type(s
a0b0: 2c 20 69 29 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c  , i)==SQLITE_NUL
a0c0: 4c 20 29 7b 0a 20 20 20 20 20 20 76 61 6c 75 65  L ){.      value
a0d0: 73 5b 69 5d 20 3d 20 4e 55 4c 4c 3b 0a 20 20 20  s[i] = NULL;.   
a0e0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 76 61   }else{.      va
a0f0: 6c 75 65 73 5b 69 5d 20 3d 20 73 74 72 69 6e 67  lues[i] = string
a100: 5f 64 75 70 28 28 63 68 61 72 2a 29 73 71 6c 69  _dup((char*)sqli
a110: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28  te3_column_text(
a120: 73 2c 20 69 29 29 3b 0a 20 20 20 20 7d 0a 20 20  s, i));.    }.  
a130: 7d 0a 0a 20 20 2f 2a 20 57 65 20 65 78 70 65 63  }..  /* We expec
a140: 74 20 6f 6e 6c 79 20 6f 6e 65 20 72 6f 77 2e 20  t only one row. 
a150: 20 57 65 20 6d 75 73 74 20 65 78 65 63 75 74 65   We must execute
a160: 20 61 6e 6f 74 68 65 72 20 73 71 6c 69 74 65 33   another sqlite3
a170: 5f 73 74 65 70 28 29 0a 20 20 20 2a 20 74 6f 20  _step().   * to 
a180: 63 6f 6d 70 6c 65 74 65 20 74 68 65 20 69 74 65  complete the ite
a190: 72 61 74 69 6f 6e 3b 20 6f 74 68 65 72 77 69 73  ration; otherwis
a1a0: 65 20 74 68 65 20 74 61 62 6c 65 20 77 69 6c 6c  e the table will
a1b0: 20 72 65 6d 61 69 6e 20 6c 6f 63 6b 65 64 2e 20   remain locked. 
a1c0: 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  */.  rc = sqlite
a1d0: 33 5f 73 74 65 70 28 73 29 3b 0a 20 20 69 66 28  3_step(s);.  if(
a1e0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45   rc==SQLITE_DONE
a1f0: 20 29 7b 0a 20 20 20 20 2a 70 56 61 6c 75 65 73   ){.    *pValues
a200: 20 3d 20 76 61 6c 75 65 73 3b 0a 20 20 20 20 72   = values;.    r
a210: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
a220: 0a 20 20 7d 0a 0a 20 20 66 72 65 65 53 74 72 69  .  }..  freeStri
a230: 6e 67 41 72 72 61 79 28 76 2d 3e 6e 43 6f 6c 75  ngArray(v->nColu
a240: 6d 6e 2c 20 76 61 6c 75 65 73 29 3b 0a 20 20 72  mn, values);.  r
a250: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
a260: 64 65 6c 65 74 65 20 66 72 6f 6d 20 25 5f 63 6f  delete from %_co
a270: 6e 74 65 6e 74 20 77 68 65 72 65 20 72 6f 77 69  ntent where rowi
a280: 64 20 3d 20 5b 69 52 6f 77 20 5d 20 2a 2f 0a 73  d = [iRow ] */.s
a290: 74 61 74 69 63 20 69 6e 74 20 63 6f 6e 74 65 6e  tatic int conten
a2a0: 74 5f 64 65 6c 65 74 65 28 66 75 6c 6c 74 65 78  t_delete(fulltex
a2b0: 74 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74  t_vtab *v, sqlit
a2c0: 65 5f 69 6e 74 36 34 20 69 52 6f 77 29 7b 0a 20  e_int64 iRow){. 
a2d0: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73   sqlite3_stmt *s
a2e0: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c  ;.  int rc = sql
a2f0: 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76  _get_statement(v
a300: 2c 20 43 4f 4e 54 45 4e 54 5f 44 45 4c 45 54 45  , CONTENT_DELETE
a310: 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66  _STMT, &s);.  if
a320: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
a330: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
a340: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e  rc = sqlite3_bin
a350: 64 5f 69 6e 74 36 34 28 73 2c 20 31 2c 20 69 52  d_int64(s, 1, iR
a360: 6f 77 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  ow);.  if( rc!=S
a370: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
a380: 6e 20 72 63 3b 0a 0a 20 20 72 65 74 75 72 6e 20  n rc;..  return 
a390: 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74 65 70 5f  sql_single_step_
a3a0: 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f 4e  statement(v, CON
a3b0: 54 45 4e 54 5f 44 45 4c 45 54 45 5f 53 54 4d 54  TENT_DELETE_STMT
a3c0: 2c 20 26 73 29 3b 0a 7d 0a 0a 2f 2a 20 73 65 6c  , &s);.}../* sel
a3d0: 65 63 74 20 72 6f 77 69 64 2c 20 64 6f 63 6c 69  ect rowid, docli
a3e0: 73 74 20 66 72 6f 6d 20 25 5f 74 65 72 6d 0a 20  st from %_term. 
a3f0: 2a 20 20 77 68 65 72 65 20 74 65 72 6d 20 3d 20  *  where term = 
a400: 5b 70 54 65 72 6d 5d 20 61 6e 64 20 73 65 67 6d  [pTerm] and segm
a410: 65 6e 74 20 3d 20 5b 69 53 65 67 6d 65 6e 74 5d  ent = [iSegment]
a420: 0a 20 2a 20 49 66 20 66 6f 75 6e 64 2c 20 72 65  . * If found, re
a430: 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 52 4f 57  turns SQLITE_ROW
a440: 3b 20 74 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  ; the caller mus
a450: 74 20 66 72 65 65 20 74 68 65 0a 20 2a 20 72 65  t free the. * re
a460: 74 75 72 6e 65 64 20 64 6f 63 6c 69 73 74 2e 20  turned doclist. 
a470: 20 49 66 20 6e 6f 20 72 6f 77 73 20 66 6f 75 6e   If no rows foun
a480: 64 2c 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  d, returns SQLIT
a490: 45 5f 44 4f 4e 45 2e 20 2a 2f 0a 73 74 61 74 69  E_DONE. */.stati
a4a0: 63 20 69 6e 74 20 74 65 72 6d 5f 73 65 6c 65 63  c int term_selec
a4b0: 74 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20  t(fulltext_vtab 
a4c0: 2a 76 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  *v, const char *
a4d0: 70 54 65 72 6d 2c 20 69 6e 74 20 6e 54 65 72 6d  pTerm, int nTerm
a4e0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
a4f0: 20 20 20 20 20 20 20 20 20 69 6e 74 20 69 53 65           int iSe
a500: 67 6d 65 6e 74 2c 0a 20 20 20 20 20 20 20 20 20  gment,.         
a510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
a520: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 72 6f 77 69  lite_int64 *rowi
a530: 64 2c 20 44 6f 63 4c 69 73 74 20 2a 6f 75 74 29  d, DocList *out)
a540: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  {.  sqlite3_stmt
a550: 20 2a 73 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20   *s;.  int rc = 
a560: 73 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e  sql_get_statemen
a570: 74 28 76 2c 20 54 45 52 4d 5f 53 45 4c 45 43 54  t(v, TERM_SELECT
a580: 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66  _STMT, &s);.  if
a590: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
a5a0: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
a5b0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e  rc = sqlite3_bin
a5c0: 64 5f 74 65 78 74 28 73 2c 20 31 2c 20 70 54 65  d_text(s, 1, pTe
a5d0: 72 6d 2c 20 6e 54 65 72 6d 2c 20 53 51 4c 49 54  rm, nTerm, SQLIT
a5e0: 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 69 66 28  E_STATIC);.  if(
a5f0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
a600: 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72   return rc;..  r
a610: 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
a620: 5f 69 6e 74 28 73 2c 20 32 2c 20 69 53 65 67 6d  _int(s, 2, iSegm
a630: 65 6e 74 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  ent);.  if( rc!=
a640: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
a650: 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73  rn rc;..  rc = s
a660: 71 6c 5f 73 74 65 70 5f 73 74 61 74 65 6d 65 6e  ql_step_statemen
a670: 74 28 76 2c 20 54 45 52 4d 5f 53 45 4c 45 43 54  t(v, TERM_SELECT
a680: 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66  _STMT, &s);.  if
a690: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57  ( rc!=SQLITE_ROW
a6a0: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
a6b0: 20 2a 72 6f 77 69 64 20 3d 20 73 71 6c 69 74 65   *rowid = sqlite
a6c0: 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 73  3_column_int64(s
a6d0: 2c 20 30 29 3b 0a 20 20 64 6f 63 4c 69 73 74 49  , 0);.  docListI
a6e0: 6e 69 74 28 6f 75 74 2c 20 44 4c 5f 44 45 46 41  nit(out, DL_DEFA
a6f0: 55 4c 54 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ULT,.           
a700: 20 20 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d     sqlite3_colum
a710: 6e 5f 62 6c 6f 62 28 73 2c 20 31 29 2c 20 73 71  n_blob(s, 1), sq
a720: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74  lite3_column_byt
a730: 65 73 28 73 2c 20 31 29 29 3b 0a 0a 20 20 2f 2a  es(s, 1));..  /*
a740: 20 57 65 20 65 78 70 65 63 74 20 6f 6e 6c 79 20   We expect only 
a750: 6f 6e 65 20 72 6f 77 2e 20 20 57 65 20 6d 75 73  one row.  We mus
a760: 74 20 65 78 65 63 75 74 65 20 61 6e 6f 74 68 65  t execute anothe
a770: 72 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 29  r sqlite3_step()
a780: 0a 20 20 20 2a 20 74 6f 20 63 6f 6d 70 6c 65 74  .   * to complet
a790: 65 20 74 68 65 20 69 74 65 72 61 74 69 6f 6e 3b  e the iteration;
a7a0: 20 6f 74 68 65 72 77 69 73 65 20 74 68 65 20 74   otherwise the t
a7b0: 61 62 6c 65 20 77 69 6c 6c 20 72 65 6d 61 69 6e  able will remain
a7c0: 20 6c 6f 63 6b 65 64 2e 20 2a 2f 0a 20 20 72 63   locked. */.  rc
a7d0: 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28   = sqlite3_step(
a7e0: 73 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3d  s);.  return rc=
a7f0: 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 3f 20 53  =SQLITE_DONE ? S
a800: 51 4c 49 54 45 5f 52 4f 57 20 3a 20 72 63 3b 0a  QLITE_ROW : rc;.
a810: 7d 0a 0a 2f 2a 20 4c 6f 61 64 20 74 68 65 20 73  }../* Load the s
a820: 65 67 6d 65 6e 74 20 64 6f 63 6c 69 73 74 73 20  egment doclists 
a830: 66 6f 72 20 74 65 72 6d 20 70 54 65 72 6d 20 61  for term pTerm a
a840: 6e 64 20 6d 65 72 67 65 20 74 68 65 6d 20 69 6e  nd merge them in
a850: 0a 2a 2a 20 61 70 70 72 6f 70 72 69 61 74 65 20  .** appropriate 
a860: 6f 72 64 65 72 20 69 6e 74 6f 20 6f 75 74 2e 20  order into out. 
a870: 20 52 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f   Returns SQLITE_
a880: 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  OK if successful
a890: 2e 20 20 49 66 0a 2a 2a 20 74 68 65 72 65 20 61  .  If.** there a
a8a0: 72 65 20 6e 6f 20 73 65 67 6d 65 6e 74 73 20 66  re no segments f
a8b0: 6f 72 20 70 54 65 72 6d 2c 20 73 75 63 63 65 73  or pTerm, succes
a8c0: 73 66 75 6c 6c 79 20 72 65 74 75 72 6e 73 20 61  sfully returns a
a8d0: 6e 20 65 6d 70 74 79 0a 2a 2a 20 64 6f 63 6c 69  n empty.** docli
a8e0: 73 74 20 69 6e 20 6f 75 74 2e 0a 2a 2a 0a 2a 2a  st in out..**.**
a8f0: 20 45 61 63 68 20 64 6f 63 75 6d 65 6e 74 20 63   Each document c
a900: 6f 6e 73 69 73 74 73 20 6f 66 20 31 20 6f 72 20  onsists of 1 or 
a910: 6d 6f 72 65 20 22 63 6f 6c 75 6d 6e 73 22 2e 20  more "columns". 
a920: 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 2a   The number of.*
a930: 2a 20 63 6f 6c 75 6d 6e 73 20 69 73 20 76 2d 3e  * columns is v->
a940: 6e 43 6f 6c 75 6d 6e 2e 20 20 49 66 20 69 43 6f  nColumn.  If iCo
a950: 6c 75 6d 6e 3d 3d 76 2d 3e 6e 43 6f 6c 75 6d 6e  lumn==v->nColumn
a960: 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 0a 2a 2a  , then return.**
a970: 20 70 6f 73 69 74 69 6f 6e 20 69 6e 66 6f 72 6d   position inform
a980: 61 74 69 6f 6e 20 61 62 6f 75 74 20 61 6c 6c 20  ation about all 
a990: 63 6f 6c 75 6d 6e 73 2e 20 20 49 66 20 69 43 6f  columns.  If iCo
a9a0: 6c 75 6d 6e 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c  lumn<v->nColumn,
a9b0: 0a 2a 2a 20 74 68 65 6e 20 6f 6e 6c 79 20 72 65  .** then only re
a9c0: 74 75 72 6e 20 70 6f 73 69 74 69 6f 6e 20 69 6e  turn position in
a9d0: 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20  formation about 
a9e0: 74 68 65 20 69 43 6f 6c 75 6d 6e 2d 74 68 20 63  the iColumn-th c
a9f0: 6f 6c 75 6d 6e 0a 2a 2a 20 28 77 68 65 72 65 20  olumn.** (where 
aa00: 74 68 65 20 66 69 72 73 74 20 63 6f 6c 75 6d 6e  the first column
aa10: 20 69 73 20 30 29 2e 0a 2a 2f 0a 73 74 61 74 69   is 0)..*/.stati
aa20: 63 20 69 6e 74 20 74 65 72 6d 5f 73 65 6c 65 63  c int term_selec
aa30: 74 5f 61 6c 6c 28 0a 20 20 66 75 6c 6c 74 65 78  t_all(.  fulltex
aa40: 74 5f 76 74 61 62 20 2a 76 2c 20 20 20 20 20 2f  t_vtab *v,     /
aa50: 2a 20 54 68 65 20 66 75 6c 6c 74 65 78 74 20 69  * The fulltext i
aa60: 6e 64 65 78 20 77 65 20 61 72 65 20 71 75 65 72  ndex we are quer
aa70: 79 69 6e 67 20 61 67 61 69 6e 73 74 20 2a 2f 0a  ying against */.
aa80: 20 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 2c 20 20    int iColumn,  
aa90: 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 3c 6e          /* If <n
aaa0: 43 6f 6c 75 6d 6e 2c 20 6f 6e 6c 79 20 6c 6f 6f  Column, only loo
aab0: 6b 20 61 74 20 74 68 65 20 69 43 6f 6c 75 6d 6e  k at the iColumn
aac0: 2d 74 68 20 63 6f 6c 75 6d 6e 20 2a 2f 0a 20 20  -th column */.  
aad0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65 72  const char *pTer
aae0: 6d 2c 20 20 20 20 2f 2a 20 54 68 65 20 74 65 72  m,    /* The ter
aaf0: 6d 20 77 68 6f 73 65 20 70 6f 73 74 69 6e 67 20  m whose posting 
ab00: 6c 69 73 74 73 20 77 65 20 77 61 6e 74 20 2a 2f  lists we want */
ab10: 0a 20 20 69 6e 74 20 6e 54 65 72 6d 2c 20 20 20  .  int nTerm,   
ab20: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
ab30: 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 70  er of bytes in p
ab40: 54 65 72 6d 20 2a 2f 0a 20 20 44 6f 63 4c 69 73  Term */.  DocLis
ab50: 74 20 2a 6f 75 74 20 20 20 20 20 20 20 20 20 20  t *out          
ab60: 2f 2a 20 57 72 69 74 65 20 74 68 65 20 72 65 73  /* Write the res
ab70: 75 6c 74 69 6e 67 20 64 6f 63 6c 69 73 74 20 68  ulting doclist h
ab80: 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 44 6f 63 4c  ere */.){.  DocL
ab90: 69 73 74 20 64 6f 63 6c 69 73 74 3b 0a 20 20 73  ist doclist;.  s
aba0: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a  qlite3_stmt *s;.
abb0: 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67    int rc = sql_g
abc0: 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20  et_statement(v, 
abd0: 54 45 52 4d 5f 53 45 4c 45 43 54 5f 41 4c 4c 5f  TERM_SELECT_ALL_
abe0: 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28  STMT, &s);.  if(
abf0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
ac00: 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72   return rc;..  r
ac10: 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
ac20: 5f 74 65 78 74 28 73 2c 20 31 2c 20 70 54 65 72  _text(s, 1, pTer
ac30: 6d 2c 20 6e 54 65 72 6d 2c 20 53 51 4c 49 54 45  m, nTerm, SQLITE
ac40: 5f 53 54 41 54 49 43 29 3b 0a 20 20 69 66 28 20  _STATIC);.  if( 
ac50: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
ac60: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 64 6f  return rc;..  do
ac70: 63 4c 69 73 74 49 6e 69 74 28 26 64 6f 63 6c 69  cListInit(&docli
ac80: 73 74 2c 20 44 4c 5f 44 45 46 41 55 4c 54 2c 20  st, DL_DEFAULT, 
ac90: 30 2c 20 30 29 3b 0a 0a 20 20 2f 2a 20 54 4f 44  0, 0);..  /* TOD
aca0: 4f 28 73 68 65 73 73 29 20 48 61 6e 64 6c 65 20  O(shess) Handle 
acb0: 73 63 68 65 6d 61 20 61 6e 64 20 62 75 73 79 20  schema and busy 
acc0: 65 72 72 6f 72 73 2e 20 2a 2f 0a 20 20 77 68 69  errors. */.  whi
acd0: 6c 65 28 20 28 72 63 3d 73 71 6c 5f 73 74 65 70  le( (rc=sql_step
ace0: 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 54 45  _statement(v, TE
acf0: 52 4d 5f 53 45 4c 45 43 54 5f 41 4c 4c 5f 53 54  RM_SELECT_ALL_ST
ad00: 4d 54 2c 20 26 73 29 29 3d 3d 53 51 4c 49 54 45  MT, &s))==SQLITE
ad10: 5f 52 4f 57 20 29 7b 0a 20 20 20 20 44 6f 63 4c  _ROW ){.    DocL
ad20: 69 73 74 20 6f 6c 64 3b 0a 0a 20 20 20 20 2f 2a  ist old;..    /*
ad30: 20 54 4f 44 4f 28 73 68 65 73 73 29 20 49 66 20   TODO(shess) If 
ad40: 77 65 20 70 72 6f 63 65 73 73 65 64 20 64 6f 63  we processed doc
ad50: 6c 69 73 74 73 20 66 72 6f 6d 20 6f 6c 64 65 73  lists from oldes
ad60: 74 20 74 6f 20 6e 65 77 65 73 74 2c 20 77 65 0a  t to newest, we.
ad70: 20 20 20 20 2a 2a 20 63 6f 75 6c 64 20 73 6b 69      ** could ski
ad80: 70 20 74 68 65 20 6d 61 6c 6c 6f 63 28 29 20 69  p the malloc() i
ad90: 6e 76 6f 6c 76 65 64 20 77 69 74 68 20 74 68 65  nvolved with the
ada0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 61 6c 6c 2e   following call.
adb0: 20 20 46 6f 72 0a 20 20 20 20 2a 2a 20 6e 6f 77    For.    ** now
adc0: 2c 20 49 27 64 20 72 61 74 68 65 72 20 6b 65 65  , I'd rather kee
add0: 70 20 74 68 69 73 20 6c 6f 67 69 63 20 73 69 6d  p this logic sim
ade0: 69 6c 61 72 20 74 6f 20 69 6e 64 65 78 5f 69 6e  ilar to index_in
adf0: 73 65 72 74 5f 74 65 72 6d 28 29 2e 0a 20 20 20  sert_term()..   
ae00: 20 2a 2a 20 57 65 20 63 6f 75 6c 64 20 61 64 64   ** We could add
ae10: 69 74 69 6f 6e 61 6c 6c 79 20 64 72 6f 70 20 65  itionally drop e
ae20: 6c 65 6d 65 6e 74 73 20 77 68 65 6e 20 77 65 20  lements when we 
ae30: 73 65 65 20 64 65 6c 65 74 65 73 2c 20 62 75 74  see deletes, but
ae40: 0a 20 20 20 20 2a 2a 20 74 68 61 74 20 77 6f 75  .    ** that wou
ae50: 6c 64 20 72 65 71 75 69 72 65 20 61 20 64 69 73  ld require a dis
ae60: 74 69 6e 63 74 20 76 65 72 73 69 6f 6e 20 6f 66  tinct version of
ae70: 20 64 6f 63 4c 69 73 74 41 63 63 75 6d 75 6c 61   docListAccumula
ae80: 74 65 28 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  te()..    */.   
ae90: 20 64 6f 63 4c 69 73 74 49 6e 69 74 28 26 6f 6c   docListInit(&ol
aea0: 64 2c 20 44 4c 5f 44 45 46 41 55 4c 54 2c 0a 20  d, DL_DEFAULT,. 
aeb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
aec0: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c  qlite3_column_bl
aed0: 6f 62 28 73 2c 20 30 29 2c 20 73 71 6c 69 74 65  ob(s, 0), sqlite
aee0: 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 73  3_column_bytes(s
aef0: 2c 20 30 29 29 3b 0a 0a 20 20 20 20 69 66 28 20  , 0));..    if( 
af00: 69 43 6f 6c 75 6d 6e 3c 76 2d 3e 6e 43 6f 6c 75  iColumn<v->nColu
af10: 6d 6e 20 29 7b 20 20 20 2f 2a 20 71 75 65 72 79  mn ){   /* query
af20: 69 6e 67 20 61 20 73 69 6e 67 6c 65 20 63 6f 6c  ing a single col
af30: 75 6d 6e 20 2a 2f 0a 20 20 20 20 20 20 64 6f 63  umn */.      doc
af40: 4c 69 73 74 52 65 73 74 72 69 63 74 43 6f 6c 75  ListRestrictColu
af50: 6d 6e 28 26 6f 6c 64 2c 20 69 43 6f 6c 75 6d 6e  mn(&old, iColumn
af60: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
af70: 20 64 6f 63 6c 69 73 74 20 63 6f 6e 74 61 69 6e   doclist contain
af80: 73 20 74 68 65 20 6e 65 77 65 72 20 64 61 74 61  s the newer data
af90: 2c 20 73 6f 20 77 72 69 74 65 20 69 74 20 6f 76  , so write it ov
afa0: 65 72 20 6f 6c 64 2e 20 20 54 68 65 6e 0a 20 20  er old.  Then.  
afb0: 20 20 2a 2a 20 73 74 65 61 6c 20 61 63 63 75 6d    ** steal accum
afc0: 75 6c 61 74 65 64 20 72 65 73 75 6c 74 20 66 6f  ulated result fo
afd0: 72 20 64 6f 63 6c 69 73 74 2e 0a 20 20 20 20 2a  r doclist..    *
afe0: 2f 0a 20 20 20 20 64 6f 63 4c 69 73 74 41 63 63  /.    docListAcc
aff0: 75 6d 75 6c 61 74 65 28 26 6f 6c 64 2c 20 26 64  umulate(&old, &d
b000: 6f 63 6c 69 73 74 29 3b 0a 20 20 20 20 64 6f 63  oclist);.    doc
b010: 4c 69 73 74 44 65 73 74 72 6f 79 28 26 64 6f 63  ListDestroy(&doc
b020: 6c 69 73 74 29 3b 0a 20 20 20 20 64 6f 63 6c 69  list);.    docli
b030: 73 74 20 3d 20 6f 6c 64 3b 0a 20 20 7d 0a 20 20  st = old;.  }.  
b040: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 44  if( rc!=SQLITE_D
b050: 4f 4e 45 20 29 7b 0a 20 20 20 20 64 6f 63 4c 69  ONE ){.    docLi
b060: 73 74 44 65 73 74 72 6f 79 28 26 64 6f 63 6c 69  stDestroy(&docli
b070: 73 74 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  st);.    return 
b080: 72 63 3b 0a 20 20 7d 0a 0a 20 20 64 6f 63 4c 69  rc;.  }..  docLi
b090: 73 74 44 69 73 63 61 72 64 45 6d 70 74 79 28 26  stDiscardEmpty(&
b0a0: 64 6f 63 6c 69 73 74 29 3b 0a 20 20 2a 6f 75 74  doclist);.  *out
b0b0: 20 3d 20 64 6f 63 6c 69 73 74 3b 0a 20 20 72 65   = doclist;.  re
b0c0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
b0d0: 7d 0a 0a 2f 2a 20 69 6e 73 65 72 74 20 69 6e 74  }../* insert int
b0e0: 6f 20 25 5f 74 65 72 6d 20 28 72 6f 77 69 64 2c  o %_term (rowid,
b0f0: 20 74 65 72 6d 2c 20 73 65 67 6d 65 6e 74 2c 20   term, segment, 
b100: 64 6f 63 6c 69 73 74 29 0a 20 20 20 20 20 20 20  doclist).       
b110: 20 20 20 20 20 20 20 20 76 61 6c 75 65 73 20 28          values (
b120: 5b 70 69 52 6f 77 69 64 5d 2c 20 5b 70 54 65 72  [piRowid], [pTer
b130: 6d 5d 2c 20 5b 69 53 65 67 6d 65 6e 74 5d 2c 20  m], [iSegment], 
b140: 5b 64 6f 63 6c 69 73 74 5d 29 0a 2a 2a 20 4c 65  [doclist]).** Le
b150: 74 73 20 73 71 6c 69 74 65 20 73 65 6c 65 63 74  ts sqlite select
b160: 20 72 6f 77 69 64 20 69 66 20 70 69 52 6f 77 69   rowid if piRowi
b170: 64 20 69 73 20 4e 55 4c 4c 2c 20 65 6c 73 65 20  d is NULL, else 
b180: 75 73 65 73 20 2a 70 69 52 6f 77 69 64 2e 0a 2a  uses *piRowid..*
b190: 2a 0a 2a 2a 20 4e 4f 54 45 28 73 68 65 73 73 29  *.** NOTE(shess)
b1a0: 20 70 69 52 6f 77 69 64 20 69 73 20 49 4e 2c 20   piRowid is IN, 
b1b0: 77 69 74 68 20 76 61 6c 75 65 73 20 6f 66 20 22  with values of "
b1c0: 73 70 61 63 65 20 6f 66 20 69 6e 74 36 34 22 20  space of int64" 
b1d0: 70 6c 75 73 0a 2a 2a 20 6e 75 6c 6c 2c 20 69 74  plus.** null, it
b1e0: 20 69 73 20 6e 6f 74 20 75 73 65 64 20 74 6f 20   is not used to 
b1f0: 70 61 73 73 20 64 61 74 61 20 62 61 63 6b 20 74  pass data back t
b200: 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 0a 2a 2f  o the caller..*/
b210: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 72 6d  .static int term
b220: 5f 69 6e 73 65 72 74 28 66 75 6c 6c 74 65 78 74  _insert(fulltext
b230: 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65  _vtab *v, sqlite
b240: 5f 69 6e 74 36 34 20 2a 70 69 52 6f 77 69 64 2c  _int64 *piRowid,
b250: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
b260: 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68          const ch
b270: 61 72 20 2a 70 54 65 72 6d 2c 20 69 6e 74 20 6e  ar *pTerm, int n
b280: 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20 20 20  Term,.          
b290: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74               int
b2a0: 20 69 53 65 67 6d 65 6e 74 2c 20 44 6f 63 4c 69   iSegment, DocLi
b2b0: 73 74 20 2a 64 6f 63 6c 69 73 74 29 7b 0a 20 20  st *doclist){.  
b2c0: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b  sqlite3_stmt *s;
b2d0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f  .  int rc = sql_
b2e0: 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c  get_statement(v,
b2f0: 20 54 45 52 4d 5f 49 4e 53 45 52 54 5f 53 54 4d   TERM_INSERT_STM
b300: 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63  T, &s);.  if( rc
b310: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
b320: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 69 66 28 20  turn rc;..  if( 
b330: 70 69 52 6f 77 69 64 3d 3d 4e 55 4c 4c 20 29 7b  piRowid==NULL ){
b340: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
b350: 33 5f 62 69 6e 64 5f 6e 75 6c 6c 28 73 2c 20 31  3_bind_null(s, 1
b360: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
b370: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e  rc = sqlite3_bin
b380: 64 5f 69 6e 74 36 34 28 73 2c 20 31 2c 20 2a 70  d_int64(s, 1, *p
b390: 69 52 6f 77 69 64 29 3b 0a 20 20 7d 0a 20 20 69  iRowid);.  }.  i
b3a0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
b3b0: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
b3c0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69   rc = sqlite3_bi
b3d0: 6e 64 5f 74 65 78 74 28 73 2c 20 32 2c 20 70 54  nd_text(s, 2, pT
b3e0: 65 72 6d 2c 20 6e 54 65 72 6d 2c 20 53 51 4c 49  erm, nTerm, SQLI
b3f0: 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 69 66  TE_STATIC);.  if
b400: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
b410: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
b420: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e  rc = sqlite3_bin
b430: 64 5f 69 6e 74 28 73 2c 20 33 2c 20 69 53 65 67  d_int(s, 3, iSeg
b440: 6d 65 6e 74 29 3b 0a 20 20 69 66 28 20 72 63 21  ment);.  if( rc!
b450: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
b460: 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20  urn rc;..  rc = 
b470: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 62 6c 6f  sqlite3_bind_blo
b480: 62 28 73 2c 20 34 2c 20 64 6f 63 6c 69 73 74 2d  b(s, 4, doclist-
b490: 3e 70 44 61 74 61 2c 20 64 6f 63 6c 69 73 74 2d  >pData, doclist-
b4a0: 3e 6e 44 61 74 61 2c 20 53 51 4c 49 54 45 5f 53  >nData, SQLITE_S
b4b0: 54 41 54 49 43 29 3b 0a 20 20 69 66 28 20 72 63  TATIC);.  if( rc
b4c0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
b4d0: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 65 74 75  turn rc;..  retu
b4e0: 72 6e 20 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74  rn sql_single_st
b4f0: 65 70 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20  ep_statement(v, 
b500: 54 45 52 4d 5f 49 4e 53 45 52 54 5f 53 54 4d 54  TERM_INSERT_STMT
b510: 2c 20 26 73 29 3b 0a 7d 0a 0a 2f 2a 20 75 70 64  , &s);.}../* upd
b520: 61 74 65 20 25 5f 74 65 72 6d 20 73 65 74 20 64  ate %_term set d
b530: 6f 63 6c 69 73 74 20 3d 20 5b 64 6f 63 6c 69 73  oclist = [doclis
b540: 74 5d 20 77 68 65 72 65 20 72 6f 77 69 64 20 3d  t] where rowid =
b550: 20 5b 72 6f 77 69 64 5d 20 2a 2f 0a 73 74 61 74   [rowid] */.stat
b560: 69 63 20 69 6e 74 20 74 65 72 6d 5f 75 70 64 61  ic int term_upda
b570: 74 65 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62  te(fulltext_vtab
b580: 20 2a 76 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36   *v, sqlite_int6
b590: 34 20 72 6f 77 69 64 2c 0a 20 20 20 20 20 20 20  4 rowid,.       
b5a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b5b0: 44 6f 63 4c 69 73 74 20 2a 64 6f 63 6c 69 73 74  DocList *doclist
b5c0: 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  ){.  sqlite3_stm
b5d0: 74 20 2a 73 3b 0a 20 20 69 6e 74 20 72 63 20 3d  t *s;.  int rc =
b5e0: 20 73 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65   sql_get_stateme
b5f0: 6e 74 28 76 2c 20 54 45 52 4d 5f 55 50 44 41 54  nt(v, TERM_UPDAT
b600: 45 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69  E_STMT, &s);.  i
b610: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
b620: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
b630: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69   rc = sqlite3_bi
b640: 6e 64 5f 62 6c 6f 62 28 73 2c 20 31 2c 20 64 6f  nd_blob(s, 1, do
b650: 63 6c 69 73 74 2d 3e 70 44 61 74 61 2c 20 64 6f  clist->pData, do
b660: 63 6c 69 73 74 2d 3e 6e 44 61 74 61 2c 20 53 51  clist->nData, SQ
b670: 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20  LITE_STATIC);.  
b680: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
b690: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
b6a0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62    rc = sqlite3_b
b6b0: 69 6e 64 5f 69 6e 74 36 34 28 73 2c 20 32 2c 20  ind_int64(s, 2, 
b6c0: 72 6f 77 69 64 29 3b 0a 20 20 69 66 28 20 72 63  rowid);.  if( rc
b6d0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
b6e0: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 65 74 75  turn rc;..  retu
b6f0: 72 6e 20 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74  rn sql_single_st
b700: 65 70 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20  ep_statement(v, 
b710: 54 45 52 4d 5f 55 50 44 41 54 45 5f 53 54 4d 54  TERM_UPDATE_STMT
b720: 2c 20 26 73 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  , &s);.}..static
b730: 20 69 6e 74 20 74 65 72 6d 5f 64 65 6c 65 74 65   int term_delete
b740: 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
b750: 76 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  v, sqlite_int64 
b760: 72 6f 77 69 64 29 7b 0a 20 20 73 71 6c 69 74 65  rowid){.  sqlite
b770: 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74  3_stmt *s;.  int
b780: 20 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74   rc = sql_get_st
b790: 61 74 65 6d 65 6e 74 28 76 2c 20 54 45 52 4d 5f  atement(v, TERM_
b7a0: 44 45 4c 45 54 45 5f 53 54 4d 54 2c 20 26 73 29  DELETE_STMT, &s)
b7b0: 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
b7c0: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
b7d0: 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  c;..  rc = sqlit
b7e0: 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 73 2c  e3_bind_int64(s,
b7f0: 20 31 2c 20 72 6f 77 69 64 29 3b 0a 20 20 69 66   1, rowid);.  if
b800: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
b810: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
b820: 72 65 74 75 72 6e 20 73 71 6c 5f 73 69 6e 67 6c  return sql_singl
b830: 65 5f 73 74 65 70 5f 73 74 61 74 65 6d 65 6e 74  e_step_statement
b840: 28 76 2c 20 54 45 52 4d 5f 44 45 4c 45 54 45 5f  (v, TERM_DELETE_
b850: 53 54 4d 54 2c 20 26 73 29 3b 0a 7d 0a 0a 2f 2a  STMT, &s);.}../*
b860: 0a 2a 2a 20 46 72 65 65 20 74 68 65 20 6d 65 6d  .** Free the mem
b870: 6f 72 79 20 75 73 65 64 20 74 6f 20 63 6f 6e 74  ory used to cont
b880: 61 69 6e 20 61 20 66 75 6c 6c 74 65 78 74 5f 76  ain a fulltext_v
b890: 74 61 62 20 73 74 72 75 63 74 75 72 65 2e 0a 2a  tab structure..*
b8a0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 75  /.static void fu
b8b0: 6c 6c 74 65 78 74 5f 76 74 61 62 5f 64 65 73 74  lltext_vtab_dest
b8c0: 72 6f 79 28 66 75 6c 6c 74 65 78 74 5f 76 74 61  roy(fulltext_vta
b8d0: 62 20 2a 76 29 7b 0a 20 20 69 6e 74 20 69 53 74  b *v){.  int iSt
b8e0: 6d 74 2c 20 69 3b 0a 0a 20 20 54 52 41 43 45 28  mt, i;..  TRACE(
b8f0: 28 22 46 54 53 31 20 44 65 73 74 72 6f 79 20 25  ("FTS1 Destroy %
b900: 70 5c 6e 22 2c 20 76 29 29 3b 0a 20 20 66 6f 72  p\n", v));.  for
b910: 28 20 69 53 74 6d 74 3d 30 3b 20 69 53 74 6d 74  ( iStmt=0; iStmt
b920: 3c 4d 41 58 5f 53 54 4d 54 3b 20 69 53 74 6d 74  <MAX_STMT; iStmt
b930: 2b 2b 20 29 7b 0a 20 20 20 20 69 66 28 20 76 2d  ++ ){.    if( v-
b940: 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d  >pFulltextStatem
b950: 65 6e 74 73 5b 69 53 74 6d 74 5d 21 3d 4e 55 4c  ents[iStmt]!=NUL
b960: 4c 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  L ){.      sqlit
b970: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 76 2d 3e 70  e3_finalize(v->p
b980: 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d 65 6e  FulltextStatemen
b990: 74 73 5b 69 53 74 6d 74 5d 29 3b 0a 20 20 20 20  ts[iStmt]);.    
b9a0: 20 20 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74    v->pFulltextSt
b9b0: 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 20  atements[iStmt] 
b9c0: 3d 20 4e 55 4c 4c 3b 0a 20 20 20 20 7d 0a 20 20  = NULL;.    }.  
b9d0: 7d 0a 0a 20 20 69 66 28 20 76 2d 3e 70 54 6f 6b  }..  if( v->pTok
b9e0: 65 6e 69 7a 65 72 21 3d 4e 55 4c 4c 20 29 7b 0a  enizer!=NULL ){.
b9f0: 20 20 20 20 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65      v->pTokenize
ba00: 72 2d 3e 70 4d 6f 64 75 6c 65 2d 3e 78 44 65 73  r->pModule->xDes
ba10: 74 72 6f 79 28 76 2d 3e 70 54 6f 6b 65 6e 69 7a  troy(v->pTokeniz
ba20: 65 72 29 3b 0a 20 20 20 20 76 2d 3e 70 54 6f 6b  er);.    v->pTok
ba30: 65 6e 69 7a 65 72 20 3d 20 4e 55 4c 4c 3b 0a 20  enizer = NULL;. 
ba40: 20 7d 0a 20 20 0a 20 20 66 72 65 65 28 76 2d 3e   }.  .  free(v->
ba50: 61 7a 43 6f 6c 75 6d 6e 29 3b 0a 20 20 66 6f 72  azColumn);.  for
ba60: 28 69 20 3d 20 30 3b 20 69 20 3c 20 76 2d 3e 6e  (i = 0; i < v->n
ba70: 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 20 7b 0a 20  Column; ++i) {. 
ba80: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
ba90: 76 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75  v->azContentColu
baa0: 6d 6e 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 66 72  mn[i]);.  }.  fr
bab0: 65 65 28 76 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43  ee(v->azContentC
bac0: 6f 6c 75 6d 6e 29 3b 0a 20 20 66 72 65 65 28 76  olumn);.  free(v
bad0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65  );.}../*.** Toke
bae0: 6e 20 74 79 70 65 73 20 66 6f 72 20 70 61 72 73  n types for pars
baf0: 69 6e 67 20 74 68 65 20 61 72 67 75 6d 65 6e 74  ing the argument
bb00: 73 20 74 6f 20 78 43 6f 6e 6e 65 63 74 20 6f 72  s to xConnect or
bb10: 20 78 43 72 65 61 74 65 2e 0a 2a 2f 0a 23 64 65   xCreate..*/.#de
bb20: 66 69 6e 65 20 54 4f 4b 45 4e 5f 45 4f 46 20 20  fine TOKEN_EOF  
bb30: 20 20 20 20 20 20 20 30 20 20 20 20 2f 2a 20 45         0    /* E
bb40: 6e 64 20 6f 66 20 66 69 6c 65 20 2a 2f 0a 23 64  nd of file */.#d
bb50: 65 66 69 6e 65 20 54 4f 4b 45 4e 5f 53 50 41 43  efine TOKEN_SPAC
bb60: 45 20 20 20 20 20 20 20 31 20 20 20 20 2f 2a 20  E       1    /* 
bb70: 41 6e 79 20 6b 69 6e 64 20 6f 66 20 77 68 69 74  Any kind of whit
bb80: 65 73 70 61 63 65 20 2a 2f 0a 23 64 65 66 69 6e  espace */.#defin
bb90: 65 20 54 4f 4b 45 4e 5f 49 44 20 20 20 20 20 20  e TOKEN_ID      
bba0: 20 20 20 20 32 20 20 20 20 2f 2a 20 41 6e 20 69      2    /* An i
bbb0: 64 65 6e 74 69 66 69 65 72 20 2a 2f 0a 23 64 65  dentifier */.#de
bbc0: 66 69 6e 65 20 54 4f 4b 45 4e 5f 53 54 52 49 4e  fine TOKEN_STRIN
bbd0: 47 20 20 20 20 20 20 33 20 20 20 20 2f 2a 20 41  G      3    /* A
bbe0: 20 73 74 72 69 6e 67 20 6c 69 74 65 72 61 6c 20   string literal 
bbf0: 2a 2f 0a 23 64 65 66 69 6e 65 20 54 4f 4b 45 4e  */.#define TOKEN
bc00: 5f 50 55 4e 43 54 20 20 20 20 20 20 20 34 20 20  _PUNCT       4  
bc10: 20 20 2f 2a 20 41 20 73 69 6e 67 6c 65 20 70 75    /* A single pu
bc20: 6e 63 74 75 61 74 69 6f 6e 20 63 68 61 72 61 63  nctuation charac
bc30: 74 65 72 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 66  ter */../*.** If
bc40: 20 58 20 69 73 20 61 20 63 68 61 72 61 63 74 65   X is a characte
bc50: 72 20 74 68 61 74 20 63 61 6e 20 62 65 20 75 73  r that can be us
bc60: 65 64 20 69 6e 20 61 6e 20 69 64 65 6e 74 69 66  ed in an identif
bc70: 69 65 72 20 74 68 65 6e 0a 2a 2a 20 49 64 43 68  ier then.** IdCh
bc80: 61 72 28 58 29 20 77 69 6c 6c 20 62 65 20 74 72  ar(X) will be tr
bc90: 75 65 2e 20 20 4f 74 68 65 72 77 69 73 65 20 69  ue.  Otherwise i
bca0: 74 20 69 73 20 66 61 6c 73 65 2e 0a 2a 2a 0a 2a  t is false..**.*
bcb0: 2a 20 46 6f 72 20 41 53 43 49 49 2c 20 61 6e 79  * For ASCII, any
bcc0: 20 63 68 61 72 61 63 74 65 72 20 77 69 74 68 20   character with 
bcd0: 74 68 65 20 68 69 67 68 2d 6f 72 64 65 72 20 62  the high-order b
bce0: 69 74 20 73 65 74 20 69 73 0a 2a 2a 20 61 6c 6c  it set is.** all
bcf0: 6f 77 65 64 20 69 6e 20 61 6e 20 69 64 65 6e 74  owed in an ident
bd00: 69 66 69 65 72 2e 20 20 46 6f 72 20 37 2d 62 69  ifier.  For 7-bi
bd10: 74 20 63 68 61 72 61 63 74 65 72 73 2c 20 0a 2a  t characters, .*
bd20: 2a 20 73 71 6c 69 74 65 33 49 73 49 64 43 68 61  * sqlite3IsIdCha
bd30: 72 5b 58 5d 20 6d 75 73 74 20 62 65 20 31 2e 0a  r[X] must be 1..
bd40: 2a 2a 0a 2a 2a 20 54 69 63 6b 65 74 20 23 31 30  **.** Ticket #10
bd50: 36 36 2e 20 20 74 68 65 20 53 51 4c 20 73 74 61  66.  the SQL sta
bd60: 6e 64 61 72 64 20 64 6f 65 73 20 6e 6f 74 20 61  ndard does not a
bd70: 6c 6c 6f 77 20 27 24 27 20 69 6e 20 74 68 65 0a  llow '$' in the.
bd80: 2a 2a 20 6d 69 64 64 6c 65 20 6f 66 20 69 64 65  ** middle of ide
bd90: 6e 74 66 69 65 72 73 2e 20 20 42 75 74 20 6d 61  ntfiers.  But ma
bda0: 6e 79 20 53 51 4c 20 69 6d 70 6c 65 6d 65 6e 74  ny SQL implement
bdb0: 61 74 69 6f 6e 73 20 64 6f 2e 20 0a 2a 2a 20 53  ations do. .** S
bdc0: 51 4c 69 74 65 20 77 69 6c 6c 20 61 6c 6c 6f 77  QLite will allow
bdd0: 20 27 24 27 20 69 6e 20 69 64 65 6e 74 69 66 69   '$' in identifi
bde0: 65 72 73 20 66 6f 72 20 63 6f 6d 70 61 74 69 62  ers for compatib
bdf0: 69 6c 69 74 79 2e 0a 2a 2a 20 42 75 74 20 74 68  ility..** But th
be00: 65 20 66 65 61 74 75 72 65 20 69 73 20 75 6e 64  e feature is und
be10: 6f 63 75 6d 65 6e 74 65 64 2e 0a 2a 2f 0a 73 74  ocumented..*/.st
be20: 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20  atic const char 
be30: 69 73 49 64 43 68 61 72 5b 5d 20 3d 20 7b 0a 2f  isIdChar[] = {./
be40: 2a 20 78 30 20 78 31 20 78 32 20 78 33 20 78 34  * x0 x1 x2 x3 x4
be50: 20 78 35 20 78 36 20 78 37 20 78 38 20 78 39 20   x5 x6 x7 x8 x9 
be60: 78 41 20 78 42 20 78 43 20 78 44 20 78 45 20 78  xA xB xC xD xE x
be70: 46 20 2a 2f 0a 20 20 20 20 30 2c 20 30 2c 20 30  F */.    0, 0, 0
be80: 2c 20 30 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 1, 0, 0, 0,
be90: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   0, 0, 0, 0, 0, 
bea0: 30 2c 20 30 2c 20 30 2c 20 20 2f 2a 20 32 78 20  0, 0, 0,  /* 2x 
beb0: 2a 2f 0a 20 20 20 20 31 2c 20 31 2c 20 31 2c 20  */.    1, 1, 1, 
bec0: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
bed0: 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 1, 0, 0, 0, 0,
bee0: 20 30 2c 20 30 2c 20 20 2f 2a 20 33 78 20 2a 2f   0, 0,  /* 3x */
bef0: 0a 20 20 20 20 30 2c 20 31 2c 20 31 2c 20 31 2c  .    0, 1, 1, 1,
bf00: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
bf10: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
bf20: 2c 20 31 2c 20 20 2f 2a 20 34 78 20 2a 2f 0a 20  , 1,  /* 4x */. 
bf30: 20 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31     1, 1, 1, 1, 1
bf40: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
bf50: 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   1, 0, 0, 0, 0, 
bf60: 31 2c 20 20 2f 2a 20 35 78 20 2a 2f 0a 20 20 20  1,  /* 5x */.   
bf70: 20 30 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   0, 1, 1, 1, 1, 
bf80: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
bf90: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
bfa0: 20 20 2f 2a 20 36 78 20 2a 2f 0a 20 20 20 20 31    /* 6x */.    1
bfb0: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
bfc0: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
bfd0: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20  0, 0, 0, 0, 0,  
bfe0: 2f 2a 20 37 78 20 2a 2f 0a 7d 3b 0a 23 64 65 66  /* 7x */.};.#def
bff0: 69 6e 65 20 49 64 43 68 61 72 28 43 29 20 20 28  ine IdChar(C)  (
c000: 28 28 63 3d 43 29 26 30 78 38 30 29 21 3d 30 20  ((c=C)&0x80)!=0 
c010: 7c 7c 20 28 63 3e 30 78 31 66 20 26 26 20 69 73  || (c>0x1f && is
c020: 49 64 43 68 61 72 5b 63 2d 30 78 32 30 5d 29 29  IdChar[c-0x20]))
c030: 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  .../*.** Return 
c040: 74 68 65 20 6c 65 6e 67 74 68 20 6f 66 20 74 68  the length of th
c050: 65 20 74 6f 6b 65 6e 20 74 68 61 74 20 62 65 67  e token that beg
c060: 69 6e 73 20 61 74 20 7a 5b 30 5d 2e 20 0a 2a 2a  ins at z[0]. .**
c070: 20 53 74 6f 72 65 20 74 68 65 20 74 6f 6b 65 6e   Store the token
c080: 20 74 79 70 65 20 69 6e 20 2a 74 6f 6b 65 6e 54   type in *tokenT
c090: 79 70 65 20 62 65 66 6f 72 65 20 72 65 74 75 72  ype before retur
c0a0: 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ning..*/.static 
c0b0: 69 6e 74 20 67 65 74 54 6f 6b 65 6e 28 63 6f 6e  int getToken(con
c0c0: 73 74 20 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20  st char *z, int 
c0d0: 2a 74 6f 6b 65 6e 54 79 70 65 29 7b 0a 20 20 69  *tokenType){.  i
c0e0: 6e 74 20 69 2c 20 63 3b 0a 20 20 73 77 69 74 63  nt i, c;.  switc
c0f0: 68 28 20 2a 7a 20 29 7b 0a 20 20 20 20 63 61 73  h( *z ){.    cas
c100: 65 20 30 3a 20 7b 0a 20 20 20 20 20 20 2a 74 6f  e 0: {.      *to
c110: 6b 65 6e 54 79 70 65 20 3d 20 54 4f 4b 45 4e 5f  kenType = TOKEN_
c120: 45 4f 46 3b 0a 20 20 20 20 20 20 72 65 74 75 72  EOF;.      retur
c130: 6e 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63  n 0;.    }.    c
c140: 61 73 65 20 27 20 27 3a 20 63 61 73 65 20 27 5c  ase ' ': case '\
c150: 74 27 3a 20 63 61 73 65 20 27 5c 6e 27 3a 20 63  t': case '\n': c
c160: 61 73 65 20 27 5c 66 27 3a 20 63 61 73 65 20 27  ase '\f': case '
c170: 5c 72 27 3a 20 7b 0a 20 20 20 20 20 20 66 6f 72  \r': {.      for
c180: 28 69 3d 31 3b 20 73 61 66 65 5f 69 73 73 70 61  (i=1; safe_isspa
c190: 63 65 28 7a 5b 69 5d 29 3b 20 69 2b 2b 29 7b 7d  ce(z[i]); i++){}
c1a0: 0a 20 20 20 20 20 20 2a 74 6f 6b 65 6e 54 79 70  .      *tokenTyp
c1b0: 65 20 3d 20 54 4f 4b 45 4e 5f 53 50 41 43 45 3b  e = TOKEN_SPACE;
c1c0: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 69 3b  .      return i;
c1d0: 0a 20 20 20 20 7d 0a 20 20 20 20 63 61 73 65 20  .    }.    case 
c1e0: 27 60 27 3a 0a 20 20 20 20 63 61 73 65 20 27 5c  '`':.    case '\
c1f0: 27 27 3a 0a 20 20 20 20 63 61 73 65 20 27 22 27  '':.    case '"'
c200: 3a 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 64 65  : {.      int de
c210: 6c 69 6d 20 3d 20 7a 5b 30 5d 3b 0a 20 20 20 20  lim = z[0];.    
c220: 20 20 66 6f 72 28 69 3d 31 3b 20 28 63 3d 7a 5b    for(i=1; (c=z[
c230: 69 5d 29 21 3d 30 3b 20 69 2b 2b 29 7b 0a 20 20  i])!=0; i++){.  
c240: 20 20 20 20 20 20 69 66 28 20 63 3d 3d 64 65 6c        if( c==del
c250: 69 6d 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  im ){.          
c260: 69 66 28 20 7a 5b 69 2b 31 5d 3d 3d 64 65 6c 69  if( z[i+1]==deli
c270: 6d 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  m ){.           
c280: 20 69 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20   i++;.          
c290: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20  }else{.         
c2a0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
c2b0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
c2c0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 2a 74        }.      *t
c2d0: 6f 6b 65 6e 54 79 70 65 20 3d 20 54 4f 4b 45 4e  okenType = TOKEN
c2e0: 5f 53 54 52 49 4e 47 3b 0a 20 20 20 20 20 20 72  _STRING;.      r
c2f0: 65 74 75 72 6e 20 69 20 2b 20 28 63 21 3d 30 29  eturn i + (c!=0)
c300: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 61 73 65  ;.    }.    case
c310: 20 27 5b 27 3a 20 7b 0a 20 20 20 20 20 20 66 6f   '[': {.      fo
c320: 72 28 69 3d 31 2c 20 63 3d 7a 5b 30 5d 3b 20 63  r(i=1, c=z[0]; c
c330: 21 3d 27 5d 27 20 26 26 20 28 63 3d 7a 5b 69 5d  !=']' && (c=z[i]
c340: 29 21 3d 30 3b 20 69 2b 2b 29 7b 7d 0a 20 20 20  )!=0; i++){}.   
c350: 20 20 20 2a 74 6f 6b 65 6e 54 79 70 65 20 3d 20     *tokenType = 
c360: 54 4f 4b 45 4e 5f 49 44 3b 0a 20 20 20 20 20 20  TOKEN_ID;.      
c370: 72 65 74 75 72 6e 20 69 3b 0a 20 20 20 20 7d 0a  return i;.    }.
c380: 20 20 20 20 64 65 66 61 75 6c 74 3a 20 7b 0a 20      default: {. 
c390: 20 20 20 20 20 69 66 28 20 21 49 64 43 68 61 72       if( !IdChar
c3a0: 28 2a 7a 29 20 29 7b 0a 20 20 20 20 20 20 20 20  (*z) ){.        
c3b0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
c3c0: 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 49 64       for(i=1; Id
c3d0: 43 68 61 72 28 7a 5b 69 5d 29 3b 20 69 2b 2b 29  Char(z[i]); i++)
c3e0: 7b 7d 0a 20 20 20 20 20 20 2a 74 6f 6b 65 6e 54  {}.      *tokenT
c3f0: 79 70 65 20 3d 20 54 4f 4b 45 4e 5f 49 44 3b 0a  ype = TOKEN_ID;.
c400: 20 20 20 20 20 20 72 65 74 75 72 6e 20 69 3b 0a        return i;.
c410: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 74 6f 6b      }.  }.  *tok
c420: 65 6e 54 79 70 65 20 3d 20 54 4f 4b 45 4e 5f 50  enType = TOKEN_P
c430: 55 4e 43 54 3b 0a 20 20 72 65 74 75 72 6e 20 31  UNCT;.  return 1
c440: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 20 74 6f 6b  ;.}../*.** A tok
c450: 65 6e 20 65 78 74 72 61 63 74 65 64 20 66 72 6f  en extracted fro
c460: 6d 20 61 20 73 74 72 69 6e 67 20 69 73 20 61 6e  m a string is an
c470: 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65   instance of the
c480: 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 73 74   following.** st
c490: 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 74 79 70 65  ructure..*/.type
c4a0: 64 65 66 20 73 74 72 75 63 74 20 54 6f 6b 65 6e  def struct Token
c4b0: 20 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20   {.  const char 
c4c0: 2a 7a 3b 20 20 20 20 20 20 20 2f 2a 20 50 6f 69  *z;       /* Poi
c4d0: 6e 74 65 72 20 74 6f 20 74 6f 6b 65 6e 20 74 65  nter to token te
c4e0: 78 74 2e 20 20 4e 6f 74 20 27 5c 30 30 30 27 20  xt.  Not '\000' 
c4f0: 74 65 72 6d 69 6e 61 74 65 64 20 2a 2f 0a 20 20  terminated */.  
c500: 73 68 6f 72 74 20 69 6e 74 20 6e 3b 20 20 20 20  short int n;    
c510: 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f       /* Length o
c520: 66 20 74 68 65 20 74 6f 6b 65 6e 20 74 65 78 74  f the token text
c530: 20 69 6e 20 62 79 74 65 73 2e 20 2a 2f 0a 7d 20   in bytes. */.} 
c540: 54 6f 6b 65 6e 3b 0a 0a 2f 2a 0a 2a 2a 20 47 69  Token;../*.** Gi
c550: 76 65 6e 20 61 20 69 6e 70 75 74 20 73 74 72 69  ven a input stri
c560: 6e 67 20 28 77 68 69 63 68 20 69 73 20 72 65 61  ng (which is rea
c570: 6c 6c 79 20 6f 6e 65 20 6f 66 20 74 68 65 20 61  lly one of the a
c580: 72 67 76 5b 5d 20 70 61 72 61 6d 65 74 65 72 73  rgv[] parameters
c590: 0a 2a 2a 20 70 61 73 73 65 64 20 69 6e 74 6f 20  .** passed into 
c5a0: 78 43 6f 6e 6e 65 63 74 20 6f 72 20 78 43 72 65  xConnect or xCre
c5b0: 61 74 65 29 20 73 70 6c 69 74 20 74 68 65 20 73  ate) split the s
c5c0: 74 72 69 6e 67 20 75 70 20 69 6e 74 6f 20 74 6f  tring up into to
c5d0: 6b 65 6e 73 2e 0a 2a 2a 20 52 65 74 75 72 6e 20  kens..** Return 
c5e0: 61 6e 20 61 72 72 61 79 20 6f 66 20 70 6f 69 6e  an array of poin
c5f0: 74 65 72 73 20 74 6f 20 27 5c 30 30 30 27 20 74  ters to '\000' t
c600: 65 72 6d 69 6e 61 74 65 64 20 73 74 72 69 6e 67  erminated string
c610: 73 2c 20 6f 6e 65 20 73 74 72 69 6e 67 0a 2a 2a  s, one string.**
c620: 20 66 6f 72 20 65 61 63 68 20 6e 6f 6e 2d 77 68   for each non-wh
c630: 69 74 65 73 70 61 63 65 20 74 6f 6b 65 6e 2e 0a  itespace token..
c640: 2a 2a 0a 2a 2a 20 54 68 65 20 72 65 74 75 72 6e  **.** The return
c650: 65 64 20 61 72 72 61 79 20 69 73 20 74 65 72 6d  ed array is term
c660: 69 6e 61 74 65 64 20 62 79 20 61 20 73 69 6e 67  inated by a sing
c670: 6c 65 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2e  le NULL pointer.
c680: 0a 2a 2a 0a 2a 2a 20 53 70 61 63 65 20 74 6f 20  .**.** Space to 
c690: 68 6f 6c 64 20 74 68 65 20 72 65 74 75 72 6e 65  hold the returne
c6a0: 64 20 61 72 72 61 79 20 69 73 20 6f 62 74 61 69  d array is obtai
c6b0: 6e 65 64 20 66 72 6f 6d 20 61 20 73 69 6e 67 6c  ned from a singl
c6c0: 65 0a 2a 2a 20 6d 61 6c 6c 6f 63 20 61 6e 64 20  e.** malloc and 
c6d0: 73 68 6f 75 6c 64 20 62 65 20 66 72 65 65 64 20  should be freed 
c6e0: 62 79 20 70 61 73 73 69 6e 67 20 74 68 65 20 72  by passing the r
c6f0: 65 74 75 72 6e 20 76 61 6c 75 65 20 74 6f 20 66  eturn value to f
c700: 72 65 65 28 29 2e 0a 2a 2a 20 54 68 65 20 69 6e  ree()..** The in
c710: 64 69 76 69 64 75 61 6c 20 73 74 72 69 6e 67 73  dividual strings
c720: 20 77 69 74 68 69 6e 20 74 68 65 20 74 6f 6b 65   within the toke
c730: 6e 20 6c 69 73 74 20 61 72 65 20 61 6c 6c 20 61  n list are all a
c740: 20 70 61 72 74 20 6f 66 0a 2a 2a 20 74 68 65 20   part of.** the 
c750: 73 69 6e 67 6c 65 20 6d 65 6d 6f 72 79 20 61 6c  single memory al
c760: 6c 6f 63 61 74 69 6f 6e 20 61 6e 64 20 77 69 6c  location and wil
c770: 6c 20 61 6c 6c 20 62 65 20 66 72 65 65 64 20 61  l all be freed a
c780: 74 20 6f 6e 63 65 2e 0a 2a 2f 0a 73 74 61 74 69  t once..*/.stati
c790: 63 20 63 68 61 72 20 2a 2a 74 6f 6b 65 6e 69 7a  c char **tokeniz
c7a0: 65 53 74 72 69 6e 67 28 63 6f 6e 73 74 20 63 68  eString(const ch
c7b0: 61 72 20 2a 7a 2c 20 69 6e 74 20 2a 70 6e 54 6f  ar *z, int *pnTo
c7c0: 6b 65 6e 29 7b 0a 20 20 69 6e 74 20 6e 54 6f 6b  ken){.  int nTok
c7d0: 65 6e 20 3d 20 30 3b 0a 20 20 54 6f 6b 65 6e 20  en = 0;.  Token 
c7e0: 2a 61 54 6f 6b 65 6e 20 3d 20 6d 61 6c 6c 6f 63  *aToken = malloc
c7f0: 28 20 73 74 72 6c 65 6e 28 7a 29 20 2a 20 73 69  ( strlen(z) * si
c800: 7a 65 6f 66 28 61 54 6f 6b 65 6e 5b 30 5d 29 20  zeof(aToken[0]) 
c810: 29 3b 0a 20 20 69 6e 74 20 6e 20 3d 20 31 3b 0a  );.  int n = 1;.
c820: 20 20 69 6e 74 20 65 2c 20 69 3b 0a 20 20 69 6e    int e, i;.  in
c830: 74 20 74 6f 74 61 6c 53 69 7a 65 20 3d 20 30 3b  t totalSize = 0;
c840: 0a 20 20 63 68 61 72 20 2a 2a 61 7a 54 6f 6b 65  .  char **azToke
c850: 6e 3b 0a 20 20 63 68 61 72 20 2a 7a 43 6f 70 79  n;.  char *zCopy
c860: 3b 0a 20 20 77 68 69 6c 65 28 20 6e 3e 30 20 29  ;.  while( n>0 )
c870: 7b 0a 20 20 20 20 6e 20 3d 20 67 65 74 54 6f 6b  {.    n = getTok
c880: 65 6e 28 7a 2c 20 26 65 29 3b 0a 20 20 20 20 69  en(z, &e);.    i
c890: 66 28 20 65 21 3d 54 4f 4b 45 4e 5f 53 50 41 43  f( e!=TOKEN_SPAC
c8a0: 45 20 29 7b 0a 20 20 20 20 20 20 61 54 6f 6b 65  E ){.      aToke
c8b0: 6e 5b 6e 54 6f 6b 65 6e 5d 2e 7a 20 3d 20 7a 3b  n[nToken].z = z;
c8c0: 0a 20 20 20 20 20 20 61 54 6f 6b 65 6e 5b 6e 54  .      aToken[nT
c8d0: 6f 6b 65 6e 5d 2e 6e 20 3d 20 6e 3b 0a 20 20 20  oken].n = n;.   
c8e0: 20 20 20 6e 54 6f 6b 65 6e 2b 2b 3b 0a 20 20 20     nToken++;.   
c8f0: 20 20 20 74 6f 74 61 6c 53 69 7a 65 20 2b 3d 20     totalSize += 
c900: 6e 2b 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a  n+1;.    }.    z
c910: 20 2b 3d 20 6e 3b 0a 20 20 7d 0a 20 20 61 7a 54   += n;.  }.  azT
c920: 6f 6b 65 6e 20 3d 20 28 63 68 61 72 2a 2a 29 6d  oken = (char**)m
c930: 61 6c 6c 6f 63 28 20 6e 54 6f 6b 65 6e 2a 73 69  alloc( nToken*si
c940: 7a 65 6f 66 28 63 68 61 72 2a 29 20 2b 20 74 6f  zeof(char*) + to
c950: 74 61 6c 53 69 7a 65 20 29 3b 0a 20 20 7a 43 6f  talSize );.  zCo
c960: 70 79 20 3d 20 28 63 68 61 72 2a 29 26 61 7a 54  py = (char*)&azT
c970: 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 5d 3b 0a 20 20  oken[nToken];.  
c980: 6e 54 6f 6b 65 6e 2d 2d 3b 0a 20 20 66 6f 72 28  nToken--;.  for(
c990: 69 3d 30 3b 20 69 3c 6e 54 6f 6b 65 6e 3b 20 69  i=0; i<nToken; i
c9a0: 2b 2b 29 7b 0a 20 20 20 20 61 7a 54 6f 6b 65 6e  ++){.    azToken
c9b0: 5b 69 5d 20 3d 20 7a 43 6f 70 79 3b 0a 20 20 20  [i] = zCopy;.   
c9c0: 20 6e 20 3d 20 61 54 6f 6b 65 6e 5b 69 5d 2e 6e   n = aToken[i].n
c9d0: 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 7a 43 6f  ;.    memcpy(zCo
c9e0: 70 79 2c 20 61 54 6f 6b 65 6e 5b 69 5d 2e 7a 2c  py, aToken[i].z,
c9f0: 20 6e 29 3b 0a 20 20 20 20 7a 43 6f 70 79 5b 6e   n);.    zCopy[n
ca00: 5d 20 3d 20 30 3b 0a 20 20 20 20 7a 43 6f 70 79  ] = 0;.    zCopy
ca10: 20 2b 3d 20 6e 2b 31 3b 0a 20 20 7d 0a 20 20 61   += n+1;.  }.  a
ca20: 7a 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 5d 20 3d  zToken[nToken] =
ca30: 20 30 3b 0a 20 20 66 72 65 65 28 61 54 6f 6b 65   0;.  free(aToke
ca40: 6e 29 3b 0a 20 20 2a 70 6e 54 6f 6b 65 6e 20 3d  n);.  *pnToken =
ca50: 20 6e 54 6f 6b 65 6e 3b 0a 20 20 72 65 74 75 72   nToken;.  retur
ca60: 6e 20 61 7a 54 6f 6b 65 6e 3b 0a 7d 0a 0a 2f 2a  n azToken;.}../*
ca70: 0a 2a 2a 20 43 6f 6e 76 65 72 74 20 61 6e 20 53  .** Convert an S
ca80: 51 4c 2d 73 74 79 6c 65 20 71 75 6f 74 65 64 20  QL-style quoted 
ca90: 73 74 72 69 6e 67 20 69 6e 74 6f 20 61 20 6e 6f  string into a no
caa0: 72 6d 61 6c 20 73 74 72 69 6e 67 20 62 79 20 72  rmal string by r
cab0: 65 6d 6f 76 69 6e 67 0a 2a 2a 20 74 68 65 20 71  emoving.** the q
cac0: 75 6f 74 65 20 63 68 61 72 61 63 74 65 72 73 2e  uote characters.
cad0: 20 20 54 68 65 20 63 6f 6e 76 65 72 73 69 6f 6e    The conversion
cae0: 20 69 73 20 64 6f 6e 65 20 69 6e 2d 70 6c 61 63   is done in-plac
caf0: 65 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 69 6e  e.  If the.** in
cb00: 70 75 74 20 64 6f 65 73 20 6e 6f 74 20 62 65 67  put does not beg
cb10: 69 6e 20 77 69 74 68 20 61 20 71 75 6f 74 65 20  in with a quote 
cb20: 63 68 61 72 61 63 74 65 72 2c 20 74 68 65 6e 20  character, then 
cb30: 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20  this routine.** 
cb40: 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a  is a no-op..**.*
cb50: 2a 20 45 78 61 6d 70 6c 65 73 3a 0a 2a 2a 0a 2a  * Examples:.**.*
cb60: 2a 20 20 20 20 20 22 61 62 63 22 20 20 20 62 65  *     "abc"   be
cb70: 63 6f 6d 65 73 20 20 20 61 62 63 0a 2a 2a 20 20  comes   abc.**  
cb80: 20 20 20 27 78 79 7a 27 20 20 20 62 65 63 6f 6d     'xyz'   becom
cb90: 65 73 20 20 20 78 79 7a 0a 2a 2a 20 20 20 20 20  es   xyz.**     
cba0: 5b 70 71 72 5d 20 20 20 62 65 63 6f 6d 65 73 20  [pqr]   becomes 
cbb0: 20 20 70 71 72 0a 2a 2a 20 20 20 20 20 60 6d 6e    pqr.**     `mn
cbc0: 6f 60 20 20 20 62 65 63 6f 6d 65 73 20 20 20 6d  o`   becomes   m
cbd0: 6e 6f 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  no.*/.static voi
cbe0: 64 20 64 65 71 75 6f 74 65 53 74 72 69 6e 67 28  d dequoteString(
cbf0: 63 68 61 72 20 2a 7a 29 7b 0a 20 20 69 6e 74 20  char *z){.  int 
cc00: 71 75 6f 74 65 3b 0a 20 20 69 6e 74 20 69 2c 20  quote;.  int i, 
cc10: 6a 3b 0a 20 20 69 66 28 20 7a 3d 3d 30 20 29 20  j;.  if( z==0 ) 
cc20: 72 65 74 75 72 6e 3b 0a 20 20 71 75 6f 74 65 20  return;.  quote 
cc30: 3d 20 7a 5b 30 5d 3b 0a 20 20 73 77 69 74 63 68  = z[0];.  switch
cc40: 28 20 71 75 6f 74 65 20 29 7b 0a 20 20 20 20 63  ( quote ){.    c
cc50: 61 73 65 20 27 5c 27 27 3a 20 20 62 72 65 61 6b  ase '\'':  break
cc60: 3b 0a 20 20 20 20 63 61 73 65 20 27 22 27 3a 20  ;.    case '"': 
cc70: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73    break;.    cas
cc80: 65 20 27 60 27 3a 20 20 20 62 72 65 61 6b 3b 20  e '`':   break; 
cc90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
cca0: 2a 20 46 6f 72 20 4d 79 53 51 4c 20 63 6f 6d 70  * For MySQL comp
ccb0: 61 74 69 62 69 6c 69 74 79 20 2a 2f 0a 20 20 20  atibility */.   
ccc0: 20 63 61 73 65 20 27 5b 27 3a 20 20 20 71 75 6f   case '[':   quo
ccd0: 74 65 20 3d 20 27 5d 27 3b 20 20 62 72 65 61 6b  te = ']';  break
cce0: 3b 20 20 2f 2a 20 46 6f 72 20 4d 53 20 53 71 6c  ;  /* For MS Sql
ccf0: 53 65 72 76 65 72 20 63 6f 6d 70 61 74 69 62 69  Server compatibi
cd00: 6c 69 74 79 20 2a 2f 0a 20 20 20 20 64 65 66 61  lity */.    defa
cd10: 75 6c 74 3a 20 20 20 20 72 65 74 75 72 6e 3b 0a  ult:    return;.
cd20: 20 20 7d 0a 20 20 66 6f 72 28 69 3d 31 2c 20 6a    }.  for(i=1, j
cd30: 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a  =0; z[i]; i++){.
cd40: 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 71 75      if( z[i]==qu
cd50: 6f 74 65 20 29 7b 0a 20 20 20 20 20 20 69 66 28  ote ){.      if(
cd60: 20 7a 5b 69 2b 31 5d 3d 3d 71 75 6f 74 65 20 29   z[i+1]==quote )
cd70: 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b 2b 5d  {.        z[j++]
cd80: 20 3d 20 71 75 6f 74 65 3b 0a 20 20 20 20 20 20   = quote;.      
cd90: 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 7d 65 6c    i++;.      }el
cda0: 73 65 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b  se{.        z[j+
cdb0: 2b 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  +] = 0;.        
cdc0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
cdd0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
cde0: 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a 20  z[j++] = z[i];. 
cdf0: 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a     }.  }.}../*.*
ce00: 2a 20 54 68 65 20 69 6e 70 75 74 20 61 7a 49 6e  * The input azIn
ce10: 20 69 73 20 61 20 4e 55 4c 4c 2d 74 65 72 6d 69   is a NULL-termi
ce20: 6e 61 74 65 64 20 6c 69 73 74 20 6f 66 20 74 6f  nated list of to
ce30: 6b 65 6e 73 2e 20 20 52 65 6d 6f 76 65 20 74 68  kens.  Remove th
ce40: 65 20 66 69 72 73 74 0a 2a 2a 20 74 6f 6b 65 6e  e first.** token
ce50: 20 61 6e 64 20 61 6c 6c 20 70 75 6e 63 74 75 61   and all punctua
ce60: 74 69 6f 6e 20 74 6f 6b 65 6e 73 2e 20 20 52 65  tion tokens.  Re
ce70: 6d 6f 76 65 20 74 68 65 20 71 75 6f 74 65 73 20  move the quotes 
ce80: 66 72 6f 6d 0a 2a 2a 20 61 72 6f 75 6e 64 20 73  from.** around s
ce90: 74 72 69 6e 67 20 6c 69 74 65 72 61 6c 20 74 6f  tring literal to
cea0: 6b 65 6e 73 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d  kens..**.** Exam
ceb0: 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 69  ple:.**.**     i
cec0: 6e 70 75 74 3a 20 20 20 20 20 20 74 6f 6b 65 6e  nput:      token
ced0: 69 7a 65 20 63 68 69 6e 65 73 65 20 28 20 27 73  ize chinese ( 's
cee0: 69 6d 70 6c 69 66 65 64 27 20 2c 20 27 6d 69 78  implifed' , 'mix
cef0: 65 64 27 20 29 0a 2a 2a 20 20 20 20 20 6f 75 74  ed' ).**     out
cf00: 70 75 74 3a 20 20 20 20 20 63 68 69 6e 65 73 65  put:     chinese
cf10: 20 73 69 6d 70 6c 69 66 65 64 20 6d 69 78 65 64   simplifed mixed
cf20: 0a 2a 2a 0a 2a 2a 20 41 6e 6f 74 68 65 72 20 65  .**.** Another e
cf30: 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20  xample:.**.**   
cf40: 20 20 69 6e 70 75 74 3a 20 20 20 20 20 20 64 65    input:      de
cf50: 6c 69 6d 69 74 65 72 73 20 28 20 27 5b 27 20 2c  limiters ( '[' ,
cf60: 20 27 5d 27 20 2c 20 27 2e 2e 2e 27 20 29 0a 2a   ']' , '...' ).*
cf70: 2a 20 20 20 20 20 6f 75 74 70 75 74 3a 20 20 20  *     output:   
cf80: 20 20 5b 20 5d 20 2e 2e 2e 0a 2a 2f 0a 73 74 61    [ ] ....*/.sta
cf90: 74 69 63 20 76 6f 69 64 20 74 6f 6b 65 6e 4c 69  tic void tokenLi
cfa0: 73 74 54 6f 49 64 4c 69 73 74 28 63 68 61 72 20  stToIdList(char 
cfb0: 2a 2a 61 7a 49 6e 29 7b 0a 20 20 69 6e 74 20 69  **azIn){.  int i
cfc0: 2c 20 6a 3b 0a 20 20 69 66 28 20 61 7a 49 6e 20  , j;.  if( azIn 
cfd0: 29 7b 0a 20 20 20 20 66 6f 72 28 69 3d 30 2c 20  ){.    for(i=0, 
cfe0: 6a 3d 2d 31 3b 20 61 7a 49 6e 5b 69 5d 3b 20 69  j=-1; azIn[i]; i
cff0: 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 73  ++){.      if( s
d000: 61 66 65 5f 69 73 61 6c 6e 75 6d 28 61 7a 49 6e  afe_isalnum(azIn
d010: 5b 69 5d 5b 30 5d 29 20 7c 7c 20 61 7a 49 6e 5b  [i][0]) || azIn[
d020: 69 5d 5b 31 5d 20 29 7b 0a 20 20 20 20 20 20 20  i][1] ){.       
d030: 20 64 65 71 75 6f 74 65 53 74 72 69 6e 67 28 61   dequoteString(a
d040: 7a 49 6e 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20  zIn[i]);.       
d050: 20 69 66 28 20 6a 3e 3d 30 20 29 7b 0a 20 20 20   if( j>=0 ){.   
d060: 20 20 20 20 20 20 20 61 7a 49 6e 5b 6a 5d 20 3d         azIn[j] =
d070: 20 61 7a 49 6e 5b 69 5d 3b 0a 20 20 20 20 20 20   azIn[i];.      
d080: 20 20 7d 0a 20 20 20 20 20 20 20 20 6a 2b 2b 3b    }.        j++;
d090: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
d0a0: 20 20 20 61 7a 49 6e 5b 6a 5d 20 3d 20 30 3b 0a     azIn[j] = 0;.
d0b0: 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 46 69    }.}.../*.** Fi
d0c0: 6e 64 20 74 68 65 20 66 69 72 73 74 20 61 6c 70  nd the first alp
d0d0: 68 61 6e 75 6d 65 72 69 63 20 74 6f 6b 65 6e 20  hanumeric token 
d0e0: 69 6e 20 74 68 65 20 73 74 72 69 6e 67 20 7a 49  in the string zI
d0f0: 6e 2e 20 20 4e 75 6c 6c 2d 74 65 72 6d 69 6e 61  n.  Null-termina
d100: 74 65 0a 2a 2a 20 74 68 69 73 20 74 6f 6b 65 6e  te.** this token
d110: 2e 20 20 52 65 6d 6f 76 65 20 61 6e 79 20 71 75  .  Remove any qu
d120: 6f 74 61 74 69 6f 6e 20 6d 61 72 6b 73 2e 20 20  otation marks.  
d130: 41 6e 64 20 72 65 74 75 72 6e 20 61 20 70 6f 69  And return a poi
d140: 6e 74 65 72 20 74 6f 0a 2a 2a 20 74 68 65 20 72  nter to.** the r
d150: 65 73 75 6c 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  esult..*/.static
d160: 20 63 68 61 72 20 2a 66 69 72 73 74 54 6f 6b 65   char *firstToke
d170: 6e 28 63 68 61 72 20 2a 7a 49 6e 2c 20 63 68 61  n(char *zIn, cha
d180: 72 20 2a 2a 70 7a 54 61 69 6c 29 7b 0a 20 20 69  r **pzTail){.  i
d190: 6e 74 20 6e 2c 20 74 74 79 70 65 3b 0a 20 20 77  nt n, ttype;.  w
d1a0: 68 69 6c 65 28 31 29 7b 0a 20 20 20 20 6e 20 3d  hile(1){.    n =
d1b0: 20 67 65 74 54 6f 6b 65 6e 28 7a 49 6e 2c 20 26   getToken(zIn, &
d1c0: 74 74 79 70 65 29 3b 0a 20 20 20 20 69 66 28 20  ttype);.    if( 
d1d0: 74 74 79 70 65 3d 3d 54 4f 4b 45 4e 5f 53 50 41  ttype==TOKEN_SPA
d1e0: 43 45 20 29 7b 0a 20 20 20 20 20 20 7a 49 6e 20  CE ){.      zIn 
d1f0: 2b 3d 20 6e 3b 0a 20 20 20 20 7d 65 6c 73 65 20  += n;.    }else 
d200: 69 66 28 20 74 74 79 70 65 3d 3d 54 4f 4b 45 4e  if( ttype==TOKEN
d210: 5f 45 4f 46 20 29 7b 0a 20 20 20 20 20 20 2a 70  _EOF ){.      *p
d220: 7a 54 61 69 6c 20 3d 20 7a 49 6e 3b 0a 20 20 20  zTail = zIn;.   
d230: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20     return 0;.   
d240: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a 49   }else{.      zI
d250: 6e 5b 6e 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20  n[n] = 0;.      
d260: 2a 70 7a 54 61 69 6c 20 3d 20 26 7a 49 6e 5b 31  *pzTail = &zIn[1
d270: 5d 3b 0a 20 20 20 20 20 20 64 65 71 75 6f 74 65  ];.      dequote
d280: 53 74 72 69 6e 67 28 7a 49 6e 29 3b 0a 20 20 20  String(zIn);.   
d290: 20 20 20 72 65 74 75 72 6e 20 7a 49 6e 3b 0a 20     return zIn;. 
d2a0: 20 20 20 7d 0a 20 20 7d 0a 20 20 2f 2a 4e 4f 54     }.  }.  /*NOT
d2b0: 52 45 41 43 48 45 44 2a 2f 0a 7d 0a 0a 2f 2a 20  REACHED*/.}../* 
d2c0: 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 2e 2e  Return true if..
d2d0: 2e 0a 2a 2a 0a 2a 2a 20 20 20 2a 20 20 73 20 62  ..**.**   *  s b
d2e0: 65 67 69 6e 73 20 77 69 74 68 20 74 68 65 20 73  egins with the s
d2f0: 74 72 69 6e 67 20 74 2c 20 69 67 6e 6f 72 69 6e  tring t, ignorin
d300: 67 20 63 61 73 65 0a 2a 2a 20 20 20 2a 20 20 73  g case.**   *  s
d310: 20 69 73 20 6c 6f 6e 67 65 72 20 74 68 61 6e 20   is longer than 
d320: 74 0a 2a 2a 20 20 20 2a 20 20 54 68 65 20 66 69  t.**   *  The fi
d330: 72 73 74 20 63 68 61 72 61 63 74 65 72 20 6f 66  rst character of
d340: 20 73 20 62 65 79 6f 6e 64 20 74 20 69 73 20 6e   s beyond t is n
d350: 6f 74 20 61 20 61 6c 70 68 61 6e 75 6d 65 72 69  ot a alphanumeri
d360: 63 0a 2a 2a 20 0a 2a 2a 20 49 67 6e 6f 72 65 20  c.** .** Ignore 
d370: 6c 65 61 64 69 6e 67 20 73 70 61 63 65 20 69 6e  leading space in
d380: 20 2a 73 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 70 75   *s..**.** To pu
d390: 74 20 69 74 20 61 6e 6f 74 68 65 72 20 77 61 79  t it another way
d3a0: 2c 20 72 65 74 75 72 6e 20 74 72 75 65 20 69 66  , return true if
d3b0: 20 74 68 65 20 66 69 72 73 74 20 74 6f 6b 65 6e   the first token
d3c0: 20 6f 66 0a 2a 2a 20 73 5b 5d 20 69 73 20 74 5b   of.** s[] is t[
d3d0: 5d 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  ]..*/.static int
d3e0: 20 73 74 61 72 74 73 57 69 74 68 28 63 6f 6e 73   startsWith(cons
d3f0: 74 20 63 68 61 72 20 2a 73 2c 20 63 6f 6e 73 74  t char *s, const
d400: 20 63 68 61 72 20 2a 74 29 7b 0a 20 20 77 68 69   char *t){.  whi
d410: 6c 65 28 20 73 61 66 65 5f 69 73 73 70 61 63 65  le( safe_isspace
d420: 28 2a 73 29 20 29 7b 20 73 2b 2b 3b 20 7d 0a 20  (*s) ){ s++; }. 
d430: 20 77 68 69 6c 65 28 20 2a 74 20 29 7b 0a 20 20   while( *t ){.  
d440: 20 20 69 66 28 20 73 61 66 65 5f 74 6f 6c 6f 77    if( safe_tolow
d450: 65 72 28 2a 73 2b 2b 29 21 3d 73 61 66 65 5f 74  er(*s++)!=safe_t
d460: 6f 6c 6f 77 65 72 28 2a 74 2b 2b 29 20 29 20 72  olower(*t++) ) r
d470: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 72  eturn 0;.  }.  r
d480: 65 74 75 72 6e 20 2a 73 21 3d 27 5f 27 20 26 26  eturn *s!='_' &&
d490: 20 21 73 61 66 65 5f 69 73 61 6c 6e 75 6d 28 2a   !safe_isalnum(*
d4a0: 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20  s);.}../*.** An 
d4b0: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73  instance of this
d4c0: 20 73 74 72 75 63 74 75 72 65 20 64 65 66 69 6e   structure defin
d4d0: 65 73 20 74 68 65 20 22 73 70 65 63 22 20 6f 66  es the "spec" of
d4e0: 20 61 0a 2a 2a 20 66 75 6c 6c 20 74 65 78 74 20   a.** full text 
d4f0: 69 6e 64 65 78 2e 20 20 54 68 69 73 20 73 74 72  index.  This str
d500: 75 63 74 75 72 65 20 69 73 20 70 6f 70 75 6c 61  ucture is popula
d510: 74 65 64 20 62 79 20 70 61 72 73 65 53 70 65 63  ted by parseSpec
d520: 0a 2a 2a 20 61 6e 64 20 75 73 65 20 62 79 20 66  .** and use by f
d530: 75 6c 6c 74 65 78 74 43 6f 6e 6e 65 63 74 20 61  ulltextConnect a
d540: 6e 64 20 66 75 6c 6c 74 65 78 74 43 72 65 61 74  nd fulltextCreat
d550: 65 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  e..*/.typedef st
d560: 72 75 63 74 20 54 61 62 6c 65 53 70 65 63 20 7b  ruct TableSpec {
d570: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
d580: 44 62 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4c  Db;         /* L
d590: 6f 67 69 63 61 6c 20 64 61 74 61 62 61 73 65 20  ogical database 
d5a0: 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  name */.  const 
d5b0: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20 20  char *zName;    
d5c0: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68     /* Name of th
d5d0: 65 20 66 75 6c 6c 2d 74 65 78 74 20 69 6e 64 65  e full-text inde
d5e0: 78 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 75  x */.  int nColu
d5f0: 6d 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  mn;             
d600: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c  /* Number of col
d610: 75 6d 6e 73 20 74 6f 20 62 65 20 69 6e 64 65 78  umns to be index
d620: 65 64 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61  ed */.  char **a
d630: 7a 43 6f 6c 75 6d 6e 3b 20 20 20 20 20 20 20 20  zColumn;        
d640: 20 2f 2a 20 4f 72 69 67 69 6e 61 6c 20 6e 61 6d   /* Original nam
d650: 65 73 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 74 6f  es of columns to
d660: 20 62 65 20 69 6e 64 65 78 65 64 20 2a 2f 0a 20   be indexed */. 
d670: 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6e 74 65 6e   char **azConten
d680: 74 43 6f 6c 75 6d 6e 3b 20 20 2f 2a 20 43 6f 6c  tColumn;  /* Col
d690: 75 6d 6e 20 6e 61 6d 65 73 20 66 6f 72 20 25 5f  umn names for %_
d6a0: 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 63 68 61  content */.  cha
d6b0: 72 20 2a 2a 61 7a 54 6f 6b 65 6e 69 7a 65 72 3b  r **azTokenizer;
d6c0: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
d6d0: 20 74 6f 6b 65 6e 69 7a 65 72 20 61 6e 64 20 69   tokenizer and i
d6e0: 74 73 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  ts arguments */.
d6f0: 7d 20 54 61 62 6c 65 53 70 65 63 3b 0a 0a 2f 2a  } TableSpec;../*
d700: 0a 2a 2a 20 52 65 63 6c 61 69 6d 20 61 6c 6c 20  .** Reclaim all 
d710: 6f 66 20 74 68 65 20 6d 65 6d 6f 72 79 20 75 73  of the memory us
d720: 65 64 20 62 79 20 61 20 54 61 62 6c 65 53 70 65  ed by a TableSpe
d730: 63 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  c.*/.static void
d740: 20 63 6c 65 61 72 54 61 62 6c 65 53 70 65 63 28   clearTableSpec(
d750: 54 61 62 6c 65 53 70 65 63 20 2a 70 29 20 7b 0a  TableSpec *p) {.
d760: 20 20 66 72 65 65 28 70 2d 3e 61 7a 43 6f 6c 75    free(p->azColu
d770: 6d 6e 29 3b 0a 20 20 66 72 65 65 28 70 2d 3e 61  mn);.  free(p->a
d780: 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 29 3b  zContentColumn);
d790: 0a 20 20 66 72 65 65 28 70 2d 3e 61 7a 54 6f 6b  .  free(p->azTok
d7a0: 65 6e 69 7a 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 50  enizer);.}../* P
d7b0: 61 72 73 65 20 61 20 43 52 45 41 54 45 20 56 49  arse a CREATE VI
d7c0: 52 54 55 41 4c 20 54 41 42 4c 45 20 73 74 61 74  RTUAL TABLE stat
d7d0: 65 6d 65 6e 74 2c 20 77 68 69 63 68 20 6c 6f 6f  ement, which loo
d7e0: 6b 73 20 6c 69 6b 65 20 74 68 69 73 3a 0a 20 2a  ks like this:. *
d7f0: 0a 20 2a 20 43 52 45 41 54 45 20 56 49 52 54 55  . * CREATE VIRTU
d800: 41 4c 20 54 41 42 4c 45 20 65 6d 61 69 6c 0a 20  AL TABLE email. 
d810: 2a 20 20 20 20 20 20 20 20 55 53 49 4e 47 20 66  *        USING f
d820: 74 73 31 28 73 75 62 6a 65 63 74 2c 20 62 6f 64  ts1(subject, bod
d830: 79 2c 20 74 6f 6b 65 6e 69 7a 65 20 6d 79 74 6f  y, tokenize myto
d840: 6b 65 6e 69 7a 65 72 28 6d 79 61 72 67 29 29 0a  kenizer(myarg)).
d850: 20 2a 0a 20 2a 20 57 65 20 72 65 74 75 72 6e 20   *. * We return 
d860: 70 61 72 73 65 64 20 69 6e 66 6f 72 6d 61 74 69  parsed informati
d870: 6f 6e 20 69 6e 20 61 20 54 61 62 6c 65 53 70 65  on in a TableSpe
d880: 63 20 73 74 72 75 63 74 75 72 65 2e 0a 20 2a 20  c structure.. * 
d890: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
d8a0: 70 61 72 73 65 53 70 65 63 28 54 61 62 6c 65 53  parseSpec(TableS
d8b0: 70 65 63 20 2a 70 53 70 65 63 2c 20 69 6e 74 20  pec *pSpec, int 
d8c0: 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72  argc, const char
d8d0: 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20   *const*argv,.  
d8e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d8f0: 20 20 20 63 68 61 72 2a 2a 70 7a 45 72 72 29 7b     char**pzErr){
d900: 0a 20 20 69 6e 74 20 69 2c 20 6e 3b 0a 20 20 63  .  int i, n;.  c
d910: 68 61 72 20 2a 7a 2c 20 2a 7a 44 75 6d 6d 79 3b  har *z, *zDummy;
d920: 0a 20 20 63 68 61 72 20 2a 2a 61 7a 41 72 67 3b  .  char **azArg;
d930: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
d940: 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 30 3b 20 20  Tokenizer = 0;  
d950: 20 20 2f 2a 20 61 72 67 76 5b 5d 20 65 6e 74 72    /* argv[] entr
d960: 79 20 64 65 73 63 72 69 62 69 6e 67 20 74 68 65  y describing the
d970: 20 74 6f 6b 65 6e 69 7a 65 72 20 2a 2f 0a 0a 20   tokenizer */.. 
d980: 20 61 73 73 65 72 74 28 20 61 72 67 63 3e 3d 33   assert( argc>=3
d990: 20 29 3b 0a 20 20 2f 2a 20 43 75 72 72 65 6e 74   );.  /* Current
d9a0: 20 69 6e 74 65 72 66 61 63 65 3a 0a 20 20 2a 2a   interface:.  **
d9b0: 20 61 72 67 76 5b 30 5d 20 2d 20 6d 6f 64 75 6c   argv[0] - modul
d9c0: 65 20 6e 61 6d 65 0a 20 20 2a 2a 20 61 72 67 76  e name.  ** argv
d9d0: 5b 31 5d 20 2d 20 64 61 74 61 62 61 73 65 20 6e  [1] - database n
d9e0: 61 6d 65 0a 20 20 2a 2a 20 61 72 67 76 5b 32 5d  ame.  ** argv[2]
d9f0: 20 2d 20 74 61 62 6c 65 20 6e 61 6d 65 0a 20 20   - table name.  
da00: 2a 2a 20 61 72 67 76 5b 33 2e 2e 5d 20 2d 20 63  ** argv[3..] - c
da10: 6f 6c 75 6d 6e 73 2c 20 6f 70 74 69 6f 6e 61 6c  olumns, optional
da20: 6c 79 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 74  ly followed by t
da30: 6f 6b 65 6e 69 7a 65 72 20 73 70 65 63 69 66 69  okenizer specifi
da40: 63 61 74 69 6f 6e 0a 20 20 2a 2a 20 20 20 20 20  cation.  **     
da50: 20 20 20 20 20 20 20 20 61 6e 64 20 73 6e 69 70          and snip
da60: 70 65 74 20 64 65 6c 69 6d 69 74 65 72 73 20 73  pet delimiters s
da70: 70 65 63 69 66 69 63 61 74 69 6f 6e 2e 0a 20 20  pecification..  
da80: 2a 2f 0a 0a 20 20 2f 2a 20 4d 61 6b 65 20 61 20  */..  /* Make a 
da90: 63 6f 70 79 20 6f 66 20 74 68 65 20 63 6f 6d 70  copy of the comp
daa0: 6c 65 74 65 20 61 72 67 76 5b 5d 5b 5d 20 61 72  lete argv[][] ar
dab0: 72 61 79 20 69 6e 20 61 20 73 69 6e 67 6c 65 20  ray in a single 
dac0: 61 6c 6c 6f 63 61 74 69 6f 6e 2e 0a 20 20 2a 2a  allocation..  **
dad0: 20 54 68 65 20 61 72 67 76 5b 5d 5b 5d 20 61 72   The argv[][] ar
dae0: 72 61 79 20 69 73 20 72 65 61 64 2d 6f 6e 6c 79  ray is read-only
daf0: 20 61 6e 64 20 74 72 61 6e 73 69 65 6e 74 2e 20   and transient. 
db00: 20 57 65 20 63 61 6e 20 77 72 69 74 65 20 74 6f   We can write to
db10: 20 74 68 65 0a 20 20 2a 2a 20 63 6f 70 79 20 69   the.  ** copy i
db20: 6e 20 6f 72 64 65 72 20 74 6f 20 6d 6f 64 69 66  n order to modif
db30: 79 20 74 68 69 6e 67 73 20 61 6e 64 20 74 68 65  y things and the
db40: 20 63 6f 70 79 20 69 73 20 70 65 72 73 69 73 74   copy is persist
db50: 65 6e 74 2e 0a 20 20 2a 2f 0a 20 20 6d 65 6d 73  ent..  */.  mems
db60: 65 74 28 70 53 70 65 63 2c 20 30 2c 20 73 69 7a  et(pSpec, 0, siz
db70: 65 6f 66 28 2a 70 53 70 65 63 29 29 3b 0a 20 20  eof(*pSpec));.  
db80: 66 6f 72 28 69 3d 6e 3d 30 3b 20 69 3c 61 72 67  for(i=n=0; i<arg
db90: 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 6e 20 2b  c; i++){.    n +
dba0: 3d 20 73 74 72 6c 65 6e 28 61 72 67 76 5b 69 5d  = strlen(argv[i]
dbb0: 29 20 2b 20 31 3b 0a 20 20 7d 0a 20 20 61 7a 41  ) + 1;.  }.  azA
dbc0: 72 67 20 3d 20 6d 61 6c 6c 6f 63 28 20 73 69 7a  rg = malloc( siz
dbd0: 65 6f 66 28 63 68 61 72 2a 29 2a 61 72 67 63 20  eof(char*)*argc 
dbe0: 2b 20 6e 20 29 3b 0a 20 20 69 66 28 20 61 7a 41  + n );.  if( azA
dbf0: 72 67 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  rg==0 ){.    ret
dc00: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
dc10: 3b 0a 20 20 7d 0a 20 20 7a 20 3d 20 28 63 68 61  ;.  }.  z = (cha
dc20: 72 2a 29 26 61 7a 41 72 67 5b 61 72 67 63 5d 3b  r*)&azArg[argc];
dc30: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 61 72  .  for(i=0; i<ar
dc40: 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 61 7a  gc; i++){.    az
dc50: 41 72 67 5b 69 5d 20 3d 20 7a 3b 0a 20 20 20 20  Arg[i] = z;.    
dc60: 73 74 72 63 70 79 28 7a 2c 20 61 72 67 76 5b 69  strcpy(z, argv[i
dc70: 5d 29 3b 0a 20 20 20 20 7a 20 2b 3d 20 73 74 72  ]);.    z += str
dc80: 6c 65 6e 28 7a 29 2b 31 3b 0a 20 20 7d 0a 0a 20  len(z)+1;.  }.. 
dc90: 20 2f 2a 20 49 64 65 6e 74 69 66 79 20 74 68 65   /* Identify the
dca0: 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 61 6e   column names an
dcb0: 64 20 74 68 65 20 74 6f 6b 65 6e 69 7a 65 72 20  d the tokenizer 
dcc0: 61 6e 64 20 64 65 6c 69 6d 69 74 65 72 20 61 72  and delimiter ar
dcd0: 67 75 6d 65 6e 74 73 0a 20 20 2a 2a 20 69 6e 20  guments.  ** in 
dce0: 74 68 65 20 61 72 67 76 5b 5d 5b 5d 20 61 72 72  the argv[][] arr
dcf0: 61 79 2e 0a 20 20 2a 2f 0a 20 20 70 53 70 65 63  ay..  */.  pSpec
dd00: 2d 3e 7a 44 62 20 3d 20 61 7a 41 72 67 5b 31 5d  ->zDb = azArg[1]
dd10: 3b 0a 20 20 70 53 70 65 63 2d 3e 7a 4e 61 6d 65  ;.  pSpec->zName
dd20: 20 3d 20 61 7a 41 72 67 5b 32 5d 3b 0a 20 20 70   = azArg[2];.  p
dd30: 53 70 65 63 2d 3e 6e 43 6f 6c 75 6d 6e 20 3d 20  Spec->nColumn = 
dd40: 30 3b 0a 20 20 70 53 70 65 63 2d 3e 61 7a 43 6f  0;.  pSpec->azCo
dd50: 6c 75 6d 6e 20 3d 20 61 7a 41 72 67 3b 0a 20 20  lumn = azArg;.  
dd60: 7a 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 22 74 6f  zTokenizer = "to
dd70: 6b 65 6e 69 7a 65 20 73 69 6d 70 6c 65 22 3b 0a  kenize simple";.
dd80: 20 20 66 6f 72 28 69 3d 33 3b 20 69 3c 61 72 67    for(i=3; i<arg
dd90: 63 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 69 66 28  c; ++i){.    if(
dda0: 20 73 74 61 72 74 73 57 69 74 68 28 61 7a 41 72   startsWith(azAr
ddb0: 67 5b 69 5d 2c 22 74 6f 6b 65 6e 69 7a 65 22 29  g[i],"tokenize")
ddc0: 20 29 7b 0a 20 20 20 20 20 20 7a 54 6f 6b 65 6e   ){.      zToken
ddd0: 69 7a 65 72 20 3d 20 61 7a 41 72 67 5b 69 5d 3b  izer = azArg[i];
dde0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
ddf0: 20 20 7a 20 3d 20 61 7a 41 72 67 5b 70 53 70 65    z = azArg[pSpe
de00: 63 2d 3e 6e 43 6f 6c 75 6d 6e 5d 20 3d 20 66 69  c->nColumn] = fi
de10: 72 73 74 54 6f 6b 65 6e 28 61 7a 41 72 67 5b 69  rstToken(azArg[i
de20: 5d 2c 20 26 7a 44 75 6d 6d 79 29 3b 0a 20 20 20  ], &zDummy);.   
de30: 20 20 20 70 53 70 65 63 2d 3e 6e 43 6f 6c 75 6d     pSpec->nColum
de40: 6e 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  n++;.    }.  }. 
de50: 20 69 66 28 20 70 53 70 65 63 2d 3e 6e 43 6f 6c   if( pSpec->nCol
de60: 75 6d 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 61 7a  umn==0 ){.    az
de70: 41 72 67 5b 30 5d 20 3d 20 22 63 6f 6e 74 65 6e  Arg[0] = "conten
de80: 74 22 3b 0a 20 20 20 20 70 53 70 65 63 2d 3e 6e  t";.    pSpec->n
de90: 43 6f 6c 75 6d 6e 20 3d 20 31 3b 0a 20 20 7d 0a  Column = 1;.  }.
dea0: 0a 20 20 2f 2a 0a 20 20 2a 2a 20 43 6f 6e 73 74  .  /*.  ** Const
deb0: 72 75 63 74 20 74 68 65 20 6c 69 73 74 20 6f 66  ruct the list of
dec0: 20 63 6f 6e 74 65 6e 74 20 63 6f 6c 75 6d 6e 20   content column 
ded0: 6e 61 6d 65 73 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  names..  **.  **
dee0: 20 45 61 63 68 20 63 6f 6e 74 65 6e 74 20 63 6f   Each content co
def0: 6c 75 6d 6e 20 6e 61 6d 65 20 77 69 6c 6c 20 62  lumn name will b
df00: 65 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 63 4e  e of the form cN
df10: 4e 41 41 41 41 0a 20 20 2a 2a 20 77 68 65 72 65  NAAAA.  ** where
df20: 20 4e 4e 20 69 73 20 74 68 65 20 63 6f 6c 75 6d   NN is the colum
df30: 6e 20 6e 75 6d 62 65 72 20 61 6e 64 20 41 41 41  n number and AAA
df40: 41 20 69 73 20 74 68 65 20 73 61 6e 69 74 69 7a  A is the sanitiz
df50: 65 64 0a 20 20 2a 2a 20 63 6f 6c 75 6d 6e 20 6e  ed.  ** column n
df60: 61 6d 65 2e 20 20 22 73 61 6e 69 74 69 7a 65 64  ame.  "sanitized
df70: 22 20 6d 65 61 6e 73 20 74 68 61 74 20 73 70 65  " means that spe
df80: 63 69 61 6c 20 63 68 61 72 61 63 74 65 72 73 20  cial characters 
df90: 61 72 65 0a 20 20 2a 2a 20 63 6f 6e 76 65 72 74  are.  ** convert
dfa0: 65 64 20 74 6f 20 22 5f 22 2e 20 20 54 68 65 20  ed to "_".  The 
dfb0: 63 4e 4e 20 70 72 65 66 69 78 20 67 75 61 72 61  cNN prefix guara
dfc0: 6e 74 65 65 73 20 74 68 61 74 20 61 6c 6c 20 63  ntees that all c
dfd0: 6f 6c 75 6d 6e 0a 20 20 2a 2a 20 6e 61 6d 65 73  olumn.  ** names
dfe0: 20 61 72 65 20 75 6e 69 71 75 65 2e 0a 20 20 2a   are unique..  *
dff0: 2a 0a 20 20 2a 2a 20 54 68 65 20 41 41 41 41 20  *.  ** The AAAA 
e000: 73 75 66 66 69 78 20 69 73 20 6e 6f 74 20 73 74  suffix is not st
e010: 72 69 63 74 6c 79 20 6e 65 63 65 73 73 61 72 79  rictly necessary
e020: 2e 20 20 49 74 20 69 73 20 69 6e 63 6c 75 64 65  .  It is include
e030: 64 0a 20 20 2a 2a 20 66 6f 72 20 74 68 65 20 63  d.  ** for the c
e040: 6f 6e 76 65 6e 69 65 6e 63 65 20 6f 66 20 70 65  onvenience of pe
e050: 6f 70 6c 65 20 77 68 6f 20 6d 69 67 68 74 20 65  ople who might e
e060: 78 61 6d 69 6e 65 20 74 68 65 20 67 65 6e 65 72  xamine the gener
e070: 61 74 65 64 0a 20 20 2a 2a 20 25 5f 63 6f 6e 74  ated.  ** %_cont
e080: 65 6e 74 20 74 61 62 6c 65 20 61 6e 64 20 77 6f  ent table and wo
e090: 6e 64 65 72 20 77 68 61 74 20 74 68 65 20 63 6f  nder what the co
e0a0: 6c 75 6d 6e 73 20 61 72 65 20 75 73 65 64 20 66  lumns are used f
e0b0: 6f 72 2e 0a 20 20 2a 2f 0a 20 20 70 53 70 65 63  or..  */.  pSpec
e0c0: 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d  ->azContentColum
e0d0: 6e 20 3d 20 6d 61 6c 6c 6f 63 28 20 70 53 70 65  n = malloc( pSpe
e0e0: 63 2d 3e 6e 43 6f 6c 75 6d 6e 20 2a 20 73 69 7a  c->nColumn * siz
e0f0: 65 6f 66 28 63 68 61 72 20 2a 29 20 29 3b 0a 20  eof(char *) );. 
e100: 20 69 66 28 20 70 53 70 65 63 2d 3e 61 7a 43 6f   if( pSpec->azCo
e110: 6e 74 65 6e 74 43 6f 6c 75 6d 6e 3d 3d 30 20 29  ntentColumn==0 )
e120: 7b 0a 20 20 20 20 63 6c 65 61 72 54 61 62 6c 65  {.    clearTable
e130: 53 70 65 63 28 70 53 70 65 63 29 3b 0a 20 20 20  Spec(pSpec);.   
e140: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
e150: 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 66 6f 72 28  OMEM;.  }.  for(
e160: 69 3d 30 3b 20 69 3c 70 53 70 65 63 2d 3e 6e 43  i=0; i<pSpec->nC
e170: 6f 6c 75 6d 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20  olumn; i++){.   
e180: 20 63 68 61 72 20 2a 70 3b 0a 20 20 20 20 70 53   char *p;.    pS
e190: 70 65 63 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f  pec->azContentCo
e1a0: 6c 75 6d 6e 5b 69 5d 20 3d 20 73 71 6c 69 74 65  lumn[i] = sqlite
e1b0: 33 5f 6d 70 72 69 6e 74 66 28 22 63 25 64 25 73  3_mprintf("c%d%s
e1c0: 22 2c 20 69 2c 20 61 7a 41 72 67 5b 69 5d 29 3b  ", i, azArg[i]);
e1d0: 0a 20 20 20 20 66 6f 72 20 28 70 20 3d 20 70 53  .    for (p = pS
e1e0: 70 65 63 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f  pec->azContentCo
e1f0: 6c 75 6d 6e 5b 69 5d 3b 20 2a 70 20 3b 20 2b 2b  lumn[i]; *p ; ++
e200: 70 29 20 7b 0a 20 20 20 20 20 20 69 66 28 20 21  p) {.      if( !
e210: 73 61 66 65 5f 69 73 61 6c 6e 75 6d 28 2a 70 29  safe_isalnum(*p)
e220: 20 29 20 2a 70 20 3d 20 27 5f 27 3b 0a 20 20 20   ) *p = '_';.   
e230: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 0a 20 20 2a   }.  }..  /*.  *
e240: 2a 20 50 61 72 73 65 20 74 68 65 20 74 6f 6b 65  * Parse the toke
e250: 6e 69 7a 65 72 20 73 70 65 63 69 66 69 63 61 74  nizer specificat
e260: 69 6f 6e 20 73 74 72 69 6e 67 2e 0a 20 20 2a 2f  ion string..  */
e270: 0a 20 20 70 53 70 65 63 2d 3e 61 7a 54 6f 6b 65  .  pSpec->azToke
e280: 6e 69 7a 65 72 20 3d 20 74 6f 6b 65 6e 69 7a 65  nizer = tokenize
e290: 53 74 72 69 6e 67 28 7a 54 6f 6b 65 6e 69 7a 65  String(zTokenize
e2a0: 72 2c 20 26 6e 29 3b 0a 20 20 74 6f 6b 65 6e 4c  r, &n);.  tokenL
e2b0: 69 73 74 54 6f 49 64 4c 69 73 74 28 70 53 70 65  istToIdList(pSpe
e2c0: 63 2d 3e 61 7a 54 6f 6b 65 6e 69 7a 65 72 29 3b  c->azTokenizer);
e2d0: 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ..  return SQLIT
e2e0: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47  E_OK;.}../*.** G
e2f0: 65 6e 65 72 61 74 65 20 61 20 43 52 45 41 54 45  enerate a CREATE
e300: 20 54 41 42 4c 45 20 73 74 61 74 65 6d 65 6e 74   TABLE statement
e310: 20 74 68 61 74 20 64 65 73 63 72 69 62 65 73 20   that describes 
e320: 74 68 65 20 73 63 68 65 6d 61 20 6f 66 0a 2a 2a  the schema of.**
e330: 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62   the virtual tab
e340: 6c 65 2e 20 20 52 65 74 75 72 6e 20 61 20 70 6f  le.  Return a po
e350: 69 6e 74 65 72 20 74 6f 20 74 68 69 73 20 73 63  inter to this sc
e360: 68 65 6d 61 20 73 74 72 69 6e 67 2e 0a 2a 2a 0a  hema string..**.
e370: 2a 2a 20 53 70 61 63 65 20 69 73 20 6f 62 74 61  ** Space is obta
e380: 69 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65  ined from sqlite
e390: 33 5f 6d 70 72 69 6e 74 66 28 29 20 61 6e 64 20  3_mprintf() and 
e3a0: 73 68 6f 75 6c 64 20 62 65 20 66 72 65 65 64 0a  should be freed.
e3b0: 2a 2a 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33  ** using sqlite3
e3c0: 5f 66 72 65 65 28 29 2e 0a 2a 2f 0a 73 74 61 74  _free()..*/.stat
e3d0: 69 63 20 63 68 61 72 20 2a 66 75 6c 6c 74 65 78  ic char *fulltex
e3e0: 74 53 63 68 65 6d 61 28 0a 20 20 69 6e 74 20 6e  tSchema(.  int n
e3f0: 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20  Column,         
e400: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
e410: 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 2a 2f  er of columns */
e420: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  .  const char *c
e430: 6f 6e 73 74 2a 20 61 7a 43 6f 6c 75 6d 6e 2c 20  onst* azColumn, 
e440: 20 2f 2a 20 4c 69 73 74 20 6f 66 20 63 6f 6c 75   /* List of colu
e450: 6d 6e 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  mns */.  const c
e460: 68 61 72 20 2a 7a 54 61 62 6c 65 4e 61 6d 65 20  har *zTableName 
e470: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
e480: 66 20 74 68 65 20 74 61 62 6c 65 20 2a 2f 0a 29  f the table */.)
e490: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 68 61  {.  int i;.  cha
e4a0: 72 20 2a 7a 53 63 68 65 6d 61 2c 20 2a 7a 4e 65  r *zSchema, *zNe
e4b0: 78 74 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  xt;.  const char
e4c0: 20 2a 7a 53 65 70 20 3d 20 22 28 22 3b 0a 20 20   *zSep = "(";.  
e4d0: 7a 53 63 68 65 6d 61 20 3d 20 73 71 6c 69 74 65  zSchema = sqlite
e4e0: 33 5f 6d 70 72 69 6e 74 66 28 22 43 52 45 41 54  3_mprintf("CREAT
e4f0: 45 20 54 41 42 4c 45 20 78 22 29 3b 0a 20 20 66  E TABLE x");.  f
e500: 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 75 6d  or(i=0; i<nColum
e510: 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 7a 4e 65  n; i++){.    zNe
e520: 78 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  xt = sqlite3_mpr
e530: 69 6e 74 66 28 22 25 73 25 73 25 51 22 2c 20 7a  intf("%s%s%Q", z
e540: 53 63 68 65 6d 61 2c 20 7a 53 65 70 2c 20 61 7a  Schema, zSep, az
e550: 43 6f 6c 75 6d 6e 5b 69 5d 29 3b 0a 20 20 20 20  Column[i]);.    
e560: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 63  sqlite3_free(zSc
e570: 68 65 6d 61 29 3b 0a 20 20 20 20 7a 53 63 68 65  hema);.    zSche
e580: 6d 61 20 3d 20 7a 4e 65 78 74 3b 0a 20 20 20 20  ma = zNext;.    
e590: 7a 53 65 70 20 3d 20 22 2c 22 3b 0a 20 20 7d 0a  zSep = ",";.  }.
e5a0: 20 20 7a 4e 65 78 74 20 3d 20 73 71 6c 69 74 65    zNext = sqlite
e5b0: 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 2c 25 51  3_mprintf("%s,%Q
e5c0: 29 22 2c 20 7a 53 63 68 65 6d 61 2c 20 7a 54 61  )", zSchema, zTa
e5d0: 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 73 71 6c 69  bleName);.  sqli
e5e0: 74 65 33 5f 66 72 65 65 28 7a 53 63 68 65 6d 61  te3_free(zSchema
e5f0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a 4e 65 78  );.  return zNex
e600: 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42 75 69 6c  t;.}../*.** Buil
e610: 64 20 61 20 6e 65 77 20 73 71 6c 69 74 65 33 5f  d a new sqlite3_
e620: 76 74 61 62 20 73 74 72 75 63 74 75 72 65 20 74  vtab structure t
e630: 68 61 74 20 77 69 6c 6c 20 64 65 73 63 72 69 62  hat will describ
e640: 65 20 74 68 65 0a 2a 2a 20 66 75 6c 6c 74 65 78  e the.** fulltex
e650: 74 20 69 6e 64 65 78 20 64 65 66 69 6e 65 64 20  t index defined 
e660: 62 79 20 73 70 65 63 2e 0a 2a 2f 0a 73 74 61 74  by spec..*/.stat
e670: 69 63 20 69 6e 74 20 63 6f 6e 73 74 72 75 63 74  ic int construct
e680: 56 74 61 62 28 0a 20 20 73 71 6c 69 74 65 33 20  Vtab(.  sqlite3 
e690: 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  *db,            
e6a0: 20 20 2f 2a 20 54 68 65 20 53 51 4c 69 74 65 20    /* The SQLite 
e6b0: 64 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74  database connect
e6c0: 69 6f 6e 20 2a 2f 0a 20 20 54 61 62 6c 65 53 70  ion */.  TableSp
e6d0: 65 63 20 2a 73 70 65 63 2c 20 20 20 20 20 20 20  ec *spec,       
e6e0: 20 20 20 2f 2a 20 50 61 72 73 65 64 20 73 70 65     /* Parsed spe
e6f0: 63 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 72  c information fr
e700: 6f 6d 20 70 61 72 73 65 53 70 65 63 28 29 20 2a  om parseSpec() *
e710: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  /.  sqlite3_vtab
e720: 20 2a 2a 70 70 56 54 61 62 2c 20 20 20 20 2f 2a   **ppVTab,    /*
e730: 20 57 72 69 74 65 20 74 68 65 20 72 65 73 75 6c   Write the resul
e740: 74 69 6e 67 20 76 74 61 62 20 73 74 72 75 63 74  ting vtab struct
e750: 75 72 65 20 68 65 72 65 20 2a 2f 0a 20 20 63 68  ure here */.  ch
e760: 61 72 20 2a 2a 70 7a 45 72 72 20 20 20 20 20 20  ar **pzErr      
e770: 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65          /* Write
e780: 20 61 6e 79 20 65 72 72 6f 72 20 6d 65 73 73 61   any error messa
e790: 67 65 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20  ge here */.){.  
e7a0: 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 6e 3b  int rc;.  int n;
e7b0: 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62  .  fulltext_vtab
e7c0: 20 2a 76 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74   *v = 0;.  const
e7d0: 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a   sqlite3_tokeniz
e7e0: 65 72 5f 6d 6f 64 75 6c 65 20 2a 6d 20 3d 20 4e  er_module *m = N
e7f0: 55 4c 4c 3b 0a 20 20 63 68 61 72 20 2a 73 63 68  ULL;.  char *sch
e800: 65 6d 61 3b 0a 0a 20 20 76 20 3d 20 28 66 75 6c  ema;..  v = (ful
e810: 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 20 6d 61  ltext_vtab *) ma
e820: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 66 75 6c 6c  lloc(sizeof(full
e830: 74 65 78 74 5f 76 74 61 62 29 29 3b 0a 20 20 69  text_vtab));.  i
e840: 66 28 20 76 3d 3d 30 20 29 20 72 65 74 75 72 6e  f( v==0 ) return
e850: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
e860: 20 6d 65 6d 73 65 74 28 76 2c 20 30 2c 20 73 69   memset(v, 0, si
e870: 7a 65 6f 66 28 2a 76 29 29 3b 0a 20 20 2f 2a 20  zeof(*v));.  /* 
e880: 73 71 6c 69 74 65 20 77 69 6c 6c 20 69 6e 69 74  sqlite will init
e890: 69 61 6c 69 7a 65 20 76 2d 3e 62 61 73 65 20 2a  ialize v->base *
e8a0: 2f 0a 20 20 76 2d 3e 64 62 20 3d 20 64 62 3b 0a  /.  v->db = db;.
e8b0: 20 20 76 2d 3e 7a 44 62 20 3d 20 73 70 65 63 2d    v->zDb = spec-
e8c0: 3e 7a 44 62 3b 20 20 20 20 20 20 20 2f 2a 20 46  >zDb;       /* F
e8d0: 72 65 65 64 20 77 68 65 6e 20 61 7a 43 6f 6c 75  reed when azColu
e8e0: 6d 6e 20 69 73 20 66 72 65 65 64 20 2a 2f 0a 20  mn is freed */. 
e8f0: 20 76 2d 3e 7a 4e 61 6d 65 20 3d 20 73 70 65 63   v->zName = spec
e900: 2d 3e 7a 4e 61 6d 65 3b 20 20 20 2f 2a 20 46 72  ->zName;   /* Fr
e910: 65 65 64 20 77 68 65 6e 20 61 7a 43 6f 6c 75 6d  eed when azColum
e920: 6e 20 69 73 20 66 72 65 65 64 20 2a 2f 0a 20 20  n is freed */.  
e930: 76 2d 3e 6e 43 6f 6c 75 6d 6e 20 3d 20 73 70 65  v->nColumn = spe
e940: 63 2d 3e 6e 43 6f 6c 75 6d 6e 3b 0a 20 20 76 2d  c->nColumn;.  v-
e950: 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e  >azContentColumn
e960: 20 3d 20 73 70 65 63 2d 3e 61 7a 43 6f 6e 74 65   = spec->azConte
e970: 6e 74 43 6f 6c 75 6d 6e 3b 0a 20 20 73 70 65 63  ntColumn;.  spec
e980: 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d  ->azContentColum
e990: 6e 20 3d 20 30 3b 0a 20 20 76 2d 3e 61 7a 43 6f  n = 0;.  v->azCo
e9a0: 6c 75 6d 6e 20 3d 20 73 70 65 63 2d 3e 61 7a 43  lumn = spec->azC
e9b0: 6f 6c 75 6d 6e 3b 0a 20 20 73 70 65 63 2d 3e 61  olumn;.  spec->a
e9c0: 7a 43 6f 6c 75 6d 6e 20 3d 20 30 3b 0a 0a 20 20  zColumn = 0;..  
e9d0: 69 66 28 20 73 70 65 63 2d 3e 61 7a 54 6f 6b 65  if( spec->azToke
e9e0: 6e 69 7a 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20  nizer==0 ){.    
e9f0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
ea00: 4d 45 4d 3b 0a 20 20 7d 0a 20 20 2f 2a 20 54 4f  MEM;.  }.  /* TO
ea10: 44 4f 28 73 68 65 73 73 29 20 46 6f 72 20 6e 6f  DO(shess) For no
ea20: 77 2c 20 61 64 64 20 6e 65 77 20 74 6f 6b 65 6e  w, add new token
ea30: 69 7a 65 72 73 20 61 73 20 65 6c 73 65 20 69 66  izers as else if
ea40: 20 63 6c 61 75 73 65 73 2e 20 2a 2f 0a 20 20 69   clauses. */.  i
ea50: 66 28 20 73 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e  f( spec->azToken
ea60: 69 7a 65 72 5b 30 5d 3d 3d 30 20 7c 7c 20 73 74  izer[0]==0 || st
ea70: 61 72 74 73 57 69 74 68 28 73 70 65 63 2d 3e 61  artsWith(spec->a
ea80: 7a 54 6f 6b 65 6e 69 7a 65 72 5b 30 5d 2c 20 22  zTokenizer[0], "
ea90: 73 69 6d 70 6c 65 22 29 20 29 7b 0a 20 20 20 20  simple") ){.    
eaa0: 73 71 6c 69 74 65 33 46 74 73 31 53 69 6d 70 6c  sqlite3Fts1Simpl
eab0: 65 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65  eTokenizerModule
eac0: 28 26 6d 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66  (&m);.  }else if
ead0: 28 20 73 74 61 72 74 73 57 69 74 68 28 73 70 65  ( startsWith(spe
eae0: 63 2d 3e 61 7a 54 6f 6b 65 6e 69 7a 65 72 5b 30  c->azTokenizer[0
eaf0: 5d 2c 20 22 70 6f 72 74 65 72 22 29 20 29 7b 0a  ], "porter") ){.
eb00: 20 20 20 20 73 71 6c 69 74 65 33 46 74 73 31 50      sqlite3Fts1P
eb10: 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 4d 6f  orterTokenizerMo
eb20: 64 75 6c 65 28 26 6d 29 3b 0a 20 20 7d 65 6c 73  dule(&m);.  }els
eb30: 65 7b 0a 20 20 20 20 2a 70 7a 45 72 72 20 3d 20  e{.    *pzErr = 
eb40: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
eb50: 22 75 6e 6b 6e 6f 77 6e 20 74 6f 6b 65 6e 69 7a  "unknown tokeniz
eb60: 65 72 3a 20 25 73 22 2c 20 73 70 65 63 2d 3e 61  er: %s", spec->a
eb70: 7a 54 6f 6b 65 6e 69 7a 65 72 5b 30 5d 29 3b 0a  zTokenizer[0]);.
eb80: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
eb90: 45 52 52 4f 52 3b 0a 20 20 20 20 67 6f 74 6f 20  ERROR;.    goto 
eba0: 65 72 72 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 6e  err;.  }.  for(n
ebb0: 3d 30 3b 20 73 70 65 63 2d 3e 61 7a 54 6f 6b 65  =0; spec->azToke
ebc0: 6e 69 7a 65 72 5b 6e 5d 3b 20 6e 2b 2b 29 7b 7d  nizer[n]; n++){}
ebd0: 0a 20 20 69 66 28 20 6e 20 29 7b 0a 20 20 20 20  .  if( n ){.    
ebe0: 72 63 20 3d 20 6d 2d 3e 78 43 72 65 61 74 65 28  rc = m->xCreate(
ebf0: 6e 2d 31 2c 20 28 63 6f 6e 73 74 20 63 68 61 72  n-1, (const char
ec00: 2a 63 6f 6e 73 74 2a 29 26 73 70 65 63 2d 3e 61  *const*)&spec->a
ec10: 7a 54 6f 6b 65 6e 69 7a 65 72 5b 31 5d 2c 0a 20  zTokenizer[1],. 
ec20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ec30: 20 20 20 26 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65     &v->pTokenize
ec40: 72 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  r);.  }else{.   
ec50: 20 72 63 20 3d 20 6d 2d 3e 78 43 72 65 61 74 65   rc = m->xCreate
ec60: 28 30 2c 20 30 2c 20 26 76 2d 3e 70 54 6f 6b 65  (0, 0, &v->pToke
ec70: 6e 69 7a 65 72 29 3b 0a 20 20 7d 0a 20 20 69 66  nizer);.  }.  if
ec80: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
ec90: 29 20 67 6f 74 6f 20 65 72 72 3b 0a 20 20 76 2d  ) goto err;.  v-
eca0: 3e 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e 70 4d 6f  >pTokenizer->pMo
ecb0: 64 75 6c 65 20 3d 20 6d 3b 0a 0a 20 20 2f 2a 20  dule = m;..  /* 
ecc0: 54 4f 44 4f 3a 20 76 65 72 69 66 79 20 74 68 65  TODO: verify the
ecd0: 20 65 78 69 73 74 65 6e 63 65 20 6f 66 20 62 61   existence of ba
ece0: 63 6b 69 6e 67 20 74 61 62 6c 65 73 20 66 6f 6f  cking tables foo
ecf0: 5f 63 6f 6e 74 65 6e 74 2c 20 66 6f 6f 5f 74 65  _content, foo_te
ed00: 72 6d 20 2a 2f 0a 0a 20 20 73 63 68 65 6d 61 20  rm */..  schema 
ed10: 3d 20 66 75 6c 6c 74 65 78 74 53 63 68 65 6d 61  = fulltextSchema
ed20: 28 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 28 63 6f  (v->nColumn, (co
ed30: 6e 73 74 20 63 68 61 72 2a 63 6f 6e 73 74 2a 29  nst char*const*)
ed40: 76 2d 3e 61 7a 43 6f 6c 75 6d 6e 2c 0a 20 20 20  v->azColumn,.   
ed50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ed60: 20 20 20 20 20 20 20 73 70 65 63 2d 3e 7a 4e 61         spec->zNa
ed70: 6d 65 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69  me);.  rc = sqli
ed80: 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62  te3_declare_vtab
ed90: 28 64 62 2c 20 73 63 68 65 6d 61 29 3b 0a 20 20  (db, schema);.  
eda0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 73 63 68  sqlite3_free(sch
edb0: 65 6d 61 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  ema);.  if( rc!=
edc0: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f  SQLITE_OK ) goto
edd0: 20 65 72 72 3b 0a 0a 20 20 6d 65 6d 73 65 74 28   err;..  memset(
ede0: 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74  v->pFulltextStat
edf0: 65 6d 65 6e 74 73 2c 20 30 2c 20 73 69 7a 65 6f  ements, 0, sizeo
ee00: 66 28 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74  f(v->pFulltextSt
ee10: 61 74 65 6d 65 6e 74 73 29 29 3b 0a 0a 20 20 2a  atements));..  *
ee20: 70 70 56 54 61 62 20 3d 20 26 76 2d 3e 62 61 73  ppVTab = &v->bas
ee30: 65 3b 0a 20 20 54 52 41 43 45 28 28 22 46 54 53  e;.  TRACE(("FTS
ee40: 31 20 43 6f 6e 6e 65 63 74 20 25 70 5c 6e 22 2c  1 Connect %p\n",
ee50: 20 76 29 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20   v));..  return 
ee60: 72 63 3b 0a 0a 65 72 72 3a 0a 20 20 66 75 6c 6c  rc;..err:.  full
ee70: 74 65 78 74 5f 76 74 61 62 5f 64 65 73 74 72 6f  text_vtab_destro
ee80: 79 28 76 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  y(v);.  return r
ee90: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
eea0: 20 66 75 6c 6c 74 65 78 74 43 6f 6e 6e 65 63 74   fulltextConnect
eeb0: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
eec0: 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20  .  void *pAux,. 
eed0: 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74   int argc, const
eee0: 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67   char *const*arg
eef0: 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  v,.  sqlite3_vta
ef00: 62 20 2a 2a 70 70 56 54 61 62 2c 0a 20 20 63 68  b **ppVTab,.  ch
ef10: 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20  ar **pzErr.){.  
ef20: 54 61 62 6c 65 53 70 65 63 20 73 70 65 63 3b 0a  TableSpec spec;.
ef30: 20 20 69 6e 74 20 72 63 20 3d 20 70 61 72 73 65    int rc = parse
ef40: 53 70 65 63 28 26 73 70 65 63 2c 20 61 72 67 63  Spec(&spec, argc
ef50: 2c 20 61 72 67 76 2c 20 70 7a 45 72 72 29 3b 0a  , argv, pzErr);.
ef60: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
ef70: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
ef80: 0a 0a 20 20 72 63 20 3d 20 63 6f 6e 73 74 72 75  ..  rc = constru
ef90: 63 74 56 74 61 62 28 64 62 2c 20 26 73 70 65 63  ctVtab(db, &spec
efa0: 2c 20 70 70 56 54 61 62 2c 20 70 7a 45 72 72 29  , ppVTab, pzErr)
efb0: 3b 0a 20 20 63 6c 65 61 72 54 61 62 6c 65 53 70  ;.  clearTableSp
efc0: 65 63 28 26 73 70 65 63 29 3b 0a 20 20 72 65 74  ec(&spec);.  ret
efd0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 20 20 2f 2a 20  urn rc;.}..  /* 
efe0: 54 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61  The %_content ta
eff0: 62 6c 65 20 68 6f 6c 64 73 20 74 68 65 20 74 65  ble holds the te
f000: 78 74 20 6f 66 20 65 61 63 68 20 64 6f 63 75 6d  xt of each docum
f010: 65 6e 74 2c 20 77 69 74 68 0a 20 20 2a 2a 20 74  ent, with.  ** t
f020: 68 65 20 72 6f 77 69 64 20 75 73 65 64 20 61 73  he rowid used as
f030: 20 74 68 65 20 64 6f 63 69 64 2e 0a 20 20 2a 2a   the docid..  **
f040: 0a 20 20 2a 2a 20 54 68 65 20 25 5f 74 65 72 6d  .  ** The %_term
f050: 20 74 61 62 6c 65 20 6d 61 70 73 20 65 61 63 68   table maps each
f060: 20 74 65 72 6d 20 74 6f 20 61 20 64 6f 63 75 6d   term to a docum
f070: 65 6e 74 20 6c 69 73 74 20 62 6c 6f 62 0a 20 20  ent list blob.  
f080: 2a 2a 20 63 6f 6e 74 61 69 6e 69 6e 67 20 65 6c  ** containing el
f090: 65 6d 65 6e 74 73 20 73 6f 72 74 65 64 20 62 79  ements sorted by
f0a0: 20 61 73 63 65 6e 64 69 6e 67 20 64 6f 63 69 64   ascending docid
f0b0: 2c 20 65 61 63 68 20 65 6c 65 6d 65 6e 74 0a 20  , each element. 
f0c0: 20 2a 2a 20 65 6e 63 6f 64 65 64 20 61 73 3a 0a   ** encoded as:.
f0d0: 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 64 6f 63 69    **.  **   doci
f0e0: 64 20 76 61 72 69 6e 74 2d 65 6e 63 6f 64 65 64  d varint-encoded
f0f0: 0a 20 20 2a 2a 20 20 20 74 6f 6b 65 6e 20 65 6c  .  **   token el
f100: 65 6d 65 6e 74 73 3a 0a 20 20 2a 2a 20 20 20 20  ements:.  **    
f110: 20 70 6f 73 69 74 69 6f 6e 2b 31 20 76 61 72 69   position+1 vari
f120: 6e 74 2d 65 6e 63 6f 64 65 64 20 61 73 20 64 65  nt-encoded as de
f130: 6c 74 61 20 66 72 6f 6d 20 70 72 65 76 69 6f 75  lta from previou
f140: 73 20 70 6f 73 69 74 69 6f 6e 0a 20 20 2a 2a 20  s position.  ** 
f150: 20 20 20 20 73 74 61 72 74 20 6f 66 66 73 65 74      start offset
f160: 20 76 61 72 69 6e 74 2d 65 6e 63 6f 64 65 64 20   varint-encoded 
f170: 61 73 20 64 65 6c 74 61 20 66 72 6f 6d 20 70 72  as delta from pr
f180: 65 76 69 6f 75 73 20 73 74 61 72 74 20 6f 66 66  evious start off
f190: 73 65 74 0a 20 20 2a 2a 20 20 20 20 20 65 6e 64  set.  **     end
f1a0: 20 6f 66 66 73 65 74 20 76 61 72 69 6e 74 2d 65   offset varint-e
f1b0: 6e 63 6f 64 65 64 20 61 73 20 64 65 6c 74 61 20  ncoded as delta 
f1c0: 66 72 6f 6d 20 73 74 61 72 74 20 6f 66 66 73 65  from start offse
f1d0: 74 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 20  t.  **.  ** The 
f1e0: 73 65 6e 74 69 6e 65 6c 20 70 6f 73 69 74 69 6f  sentinel positio
f1f0: 6e 20 6f 66 20 30 20 69 6e 64 69 63 61 74 65 73  n of 0 indicates
f200: 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
f210: 74 6f 6b 65 6e 20 6c 69 73 74 2e 0a 20 20 2a 2a  token list..  **
f220: 0a 20 20 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c  .  ** Additional
f230: 6c 79 2c 20 64 6f 63 6c 69 73 74 20 62 6c 6f 62  ly, doclist blob
f240: 73 20 61 72 65 20 63 68 75 6e 6b 65 64 20 69 6e  s are chunked in
f250: 74 6f 20 6d 75 6c 74 69 70 6c 65 20 73 65 67 6d  to multiple segm
f260: 65 6e 74 73 2c 0a 20 20 2a 2a 20 75 73 69 6e 67  ents,.  ** using
f270: 20 73 65 67 6d 65 6e 74 20 74 6f 20 6f 72 64 65   segment to orde
f280: 72 20 74 68 65 20 73 65 67 6d 65 6e 74 73 2e 20  r the segments. 
f290: 20 4e 65 77 20 65 6c 65 6d 65 6e 74 73 20 61 72   New elements ar
f2a0: 65 20 61 64 64 65 64 20 74 6f 0a 20 20 2a 2a 20  e added to.  ** 
f2b0: 74 68 65 20 73 65 67 6d 65 6e 74 20 61 74 20 73  the segment at s
f2c0: 65 67 6d 65 6e 74 20 30 2c 20 75 6e 74 69 6c 20  egment 0, until 
f2d0: 69 74 20 65 78 63 65 65 64 73 20 43 48 55 4e 4b  it exceeds CHUNK
f2e0: 5f 4d 41 58 2e 20 20 54 68 65 6e 0a 20 20 2a 2a  _MAX.  Then.  **
f2f0: 20 73 65 67 6d 65 6e 74 20 30 20 69 73 20 64 65   segment 0 is de
f300: 6c 65 74 65 64 2c 20 61 6e 64 20 74 68 65 20 64  leted, and the d
f310: 6f 63 6c 69 73 74 20 69 73 20 69 6e 73 65 72 74  oclist is insert
f320: 65 64 20 61 74 20 73 65 67 6d 65 6e 74 20 31 2e  ed at segment 1.
f330: 0a 20 20 2a 2a 20 49 66 20 74 68 65 72 65 20 69  .  ** If there i
f340: 73 20 61 6c 72 65 61 64 79 20 61 20 64 6f 63 6c  s already a docl
f350: 69 73 74 20 61 74 20 73 65 67 6d 65 6e 74 20 31  ist at segment 1
f360: 2c 20 74 68 65 20 73 65 67 6d 65 6e 74 20 30 20  , the segment 0 
f370: 64 6f 63 6c 69 73 74 0a 20 20 2a 2a 20 69 73 20  doclist.  ** is 
f380: 6d 65 72 67 65 64 20 77 69 74 68 20 69 74 2c 20  merged with it, 
f390: 74 68 65 20 73 65 67 6d 65 6e 74 20 31 20 64 6f  the segment 1 do
f3a0: 63 6c 69 73 74 20 69 73 20 64 65 6c 65 74 65 64  clist is deleted
f3b0: 2c 20 61 6e 64 20 74 68 65 0a 20 20 2a 2a 20 6d  , and the.  ** m
f3c0: 65 72 67 65 64 20 64 6f 63 6c 69 73 74 20 69 73  erged doclist is
f3d0: 20 69 6e 73 65 72 74 65 64 20 61 74 20 73 65 67   inserted at seg
f3e0: 6d 65 6e 74 20 32 2c 20 72 65 70 65 61 74 69 6e  ment 2, repeatin
f3f0: 67 20 74 68 6f 73 65 0a 20 20 2a 2a 20 6f 70 65  g those.  ** ope
f400: 72 61 74 69 6f 6e 73 20 75 6e 74 69 6c 20 61 6e  rations until an
f410: 20 69 6e 73 65 72 74 20 73 75 63 63 65 65 64 73   insert succeeds
f420: 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 53 69 6e 63  ..  **.  ** Sinc
f430: 65 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65  e this structure
f440: 20 64 6f 65 73 6e 27 74 20 61 6c 6c 6f 77 20 75   doesn't allow u
f450: 73 20 74 6f 20 75 70 64 61 74 65 20 65 6c 65 6d  s to update elem
f460: 65 6e 74 73 20 69 6e 20 70 6c 61 63 65 0a 20 20  ents in place.  
f470: 2a 2a 20 69 6e 20 63 61 73 65 20 6f 66 20 64 65  ** in case of de
f480: 6c 65 74 69 6f 6e 20 6f 72 20 75 70 64 61 74 65  letion or update
f490: 2c 20 74 68 65 73 65 20 61 72 65 20 73 69 6d 70  , these are simp
f4a0: 6c 79 20 77 72 69 74 74 65 6e 20 74 6f 0a 20 20  ly written to.  
f4b0: 2a 2a 20 73 65 67 6d 65 6e 74 20 30 20 28 77 69  ** segment 0 (wi
f4c0: 74 68 20 61 6e 20 65 6d 70 74 79 20 74 6f 6b 65  th an empty toke
f4d0: 6e 20 6c 69 73 74 20 69 6e 20 63 61 73 65 20 6f  n list in case o
f4e0: 66 20 64 65 6c 65 74 69 6f 6e 29 2c 20 77 69 74  f deletion), wit
f4f0: 68 0a 20 20 2a 2a 20 64 6f 63 4c 69 73 74 41 63  h.  ** docListAc
f500: 63 75 6d 75 6c 61 74 65 28 29 20 74 61 6b 69 6e  cumulate() takin
f510: 67 20 63 61 72 65 20 74 6f 20 72 65 74 61 69 6e  g care to retain
f520: 20 6c 6f 77 65 72 2d 73 65 67 6d 65 6e 74 0a 20   lower-segment. 
f530: 20 2a 2a 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20   ** information 
f540: 69 6e 20 70 72 65 66 65 72 65 6e 63 65 20 74 6f  in preference to
f550: 20 68 69 67 68 65 72 2d 73 65 67 6d 65 6e 74 20   higher-segment 
f560: 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 0a 20 20 2a  information..  *
f570: 2f 0a 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73  /.  /* TODO(shes
f580: 73 29 20 50 72 6f 76 69 64 65 20 61 20 56 41 43  s) Provide a VAC
f590: 55 55 4d 20 74 79 70 65 20 6f 70 65 72 61 74 69  UUM type operati
f5a0: 6f 6e 20 77 68 69 63 68 20 62 6f 74 68 20 72 65  on which both re
f5b0: 6d 6f 76 65 73 0a 20 20 2a 2a 20 64 65 6c 65 74  moves.  ** delet
f5c0: 65 64 20 65 6c 65 6d 65 6e 74 73 20 77 68 69 63  ed elements whic
f5d0: 68 20 61 72 65 20 6e 6f 20 6c 6f 6e 67 65 72 20  h are no longer 
f5e0: 6e 65 63 65 73 73 61 72 79 2c 20 61 6e 64 20 64  necessary, and d
f5f0: 75 70 6c 69 63 61 74 65 64 0a 20 20 2a 2a 20 65  uplicated.  ** e
f600: 6c 65 6d 65 6e 74 73 2e 20 20 49 20 73 75 73 70  lements.  I susp
f610: 65 63 74 20 74 68 69 73 20 77 69 6c 6c 20 70 72  ect this will pr
f620: 6f 62 61 62 6c 79 20 6e 6f 74 20 62 65 20 6e 65  obably not be ne
f630: 63 65 73 73 61 72 79 20 69 6e 0a 20 20 2a 2a 20  cessary in.  ** 
f640: 70 72 61 63 74 69 63 65 2c 20 74 68 6f 75 67 68  practice, though
f650: 2e 0a 20 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ..  */.static in
f660: 74 20 66 75 6c 6c 74 65 78 74 43 72 65 61 74 65  t fulltextCreate
f670: 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 76 6f  (sqlite3 *db, vo
f680: 69 64 20 2a 70 41 75 78 2c 0a 20 20 20 20 20 20  id *pAux,.      
f690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f6a0: 20 20 20 20 69 6e 74 20 61 72 67 63 2c 20 63 6f      int argc, co
f6b0: 6e 73 74 20 63 68 61 72 20 2a 20 63 6f 6e 73 74  nst char * const
f6c0: 20 2a 61 72 67 76 2c 0a 20 20 20 20 20 20 20 20   *argv,.        
f6d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f6e0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
f6f0: 2a 70 70 56 54 61 62 2c 20 63 68 61 72 20 2a 2a  *ppVTab, char **
f700: 70 7a 45 72 72 29 7b 0a 20 20 69 6e 74 20 72 63  pzErr){.  int rc
f710: 3b 0a 20 20 54 61 62 6c 65 53 70 65 63 20 73 70  ;.  TableSpec sp
f720: 65 63 3b 0a 20 20 53 74 72 69 6e 67 42 75 66 66  ec;.  StringBuff
f730: 65 72 20 73 63 68 65 6d 61 3b 0a 20 20 54 52 41  er schema;.  TRA
f740: 43 45 28 28 22 46 54 53 31 20 43 72 65 61 74 65  CE(("FTS1 Create
f750: 5c 6e 22 29 29 3b 0a 0a 20 20 72 63 20 3d 20 70  \n"));..  rc = p
f760: 61 72 73 65 53 70 65 63 28 26 73 70 65 63 2c 20  arseSpec(&spec, 
f770: 61 72 67 63 2c 20 61 72 67 76 2c 20 70 7a 45 72  argc, argv, pzEr
f780: 72 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  r);.  if( rc!=SQ
f790: 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
f7a0: 20 72 63 3b 0a 0a 20 20 69 6e 69 74 53 74 72 69   rc;..  initStri
f7b0: 6e 67 42 75 66 66 65 72 28 26 73 63 68 65 6d 61  ngBuffer(&schema
f7c0: 29 3b 0a 20 20 61 70 70 65 6e 64 28 26 73 63 68  );.  append(&sch
f7d0: 65 6d 61 2c 20 22 43 52 45 41 54 45 20 54 41 42  ema, "CREATE TAB
f7e0: 4c 45 20 25 5f 63 6f 6e 74 65 6e 74 28 22 29 3b  LE %_content(");
f7f0: 0a 20 20 61 70 70 65 6e 64 4c 69 73 74 28 26 73  .  appendList(&s
f800: 63 68 65 6d 61 2c 20 73 70 65 63 2e 6e 43 6f 6c  chema, spec.nCol
f810: 75 6d 6e 2c 20 73 70 65 63 2e 61 7a 43 6f 6e 74  umn, spec.azCont
f820: 65 6e 74 43 6f 6c 75 6d 6e 29 3b 0a 20 20 61 70  entColumn);.  ap
f830: 70 65 6e 64 28 26 73 63 68 65 6d 61 2c 20 22 29  pend(&schema, ")
f840: 22 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 5f 65  ");.  rc = sql_e
f850: 78 65 63 28 64 62 2c 20 73 70 65 63 2e 7a 44 62  xec(db, spec.zDb
f860: 2c 20 73 70 65 63 2e 7a 4e 61 6d 65 2c 20 73 63  , spec.zName, sc
f870: 68 65 6d 61 2e 73 29 3b 0a 20 20 66 72 65 65 28  hema.s);.  free(
f880: 73 63 68 65 6d 61 2e 73 29 3b 0a 20 20 69 66 28  schema.s);.  if(
f890: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
f8a0: 20 67 6f 74 6f 20 6f 75 74 3b 0a 0a 20 20 72 63   goto out;..  rc
f8b0: 20 3d 20 73 71 6c 5f 65 78 65 63 28 64 62 2c 20   = sql_exec(db, 
f8c0: 73 70 65 63 2e 7a 44 62 2c 20 73 70 65 63 2e 7a  spec.zDb, spec.z
f8d0: 4e 61 6d 65 2c 0a 20 20 20 20 22 63 72 65 61 74  Name,.    "creat
f8e0: 65 20 74 61 62 6c 65 20 25 5f 74 65 72 6d 28 74  e table %_term(t
f8f0: 65 72 6d 20 74 65 78 74 2c 20 73 65 67 6d 65 6e  erm text, segmen
f900: 74 20 69 6e 74 65 67 65 72 2c 20 64 6f 63 6c 69  t integer, docli
f910: 73 74 20 62 6c 6f 62 2c 20 22 0a 20 20 20 20 20  st blob, ".     
f920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f930: 20 20 20 22 70 72 69 6d 61 72 79 20 6b 65 79 28     "primary key(
f940: 74 65 72 6d 2c 20 73 65 67 6d 65 6e 74 29 29 3b  term, segment));
f950: 22 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  ");.  if( rc!=SQ
f960: 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 6f  LITE_OK ) goto o
f970: 75 74 3b 0a 0a 20 20 72 63 20 3d 20 63 6f 6e 73  ut;..  rc = cons
f980: 74 72 75 63 74 56 74 61 62 28 64 62 2c 20 26 73  tructVtab(db, &s
f990: 70 65 63 2c 20 70 70 56 54 61 62 2c 20 70 7a 45  pec, ppVTab, pzE
f9a0: 72 72 29 3b 0a 0a 6f 75 74 3a 0a 20 20 63 6c 65  rr);..out:.  cle
f9b0: 61 72 54 61 62 6c 65 53 70 65 63 28 26 73 70 65  arTableSpec(&spe
f9c0: 63 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  c);.  return rc;
f9d0: 0a 7d 0a 0a 2f 2a 20 44 65 63 69 64 65 20 68 6f  .}../* Decide ho
f9e0: 77 20 74 6f 20 68 61 6e 64 6c 65 20 61 6e 20 53  w to handle an S
f9f0: 51 4c 20 71 75 65 72 79 2e 20 2a 2f 0a 73 74 61  QL query. */.sta
fa00: 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74  tic int fulltext
fa10: 42 65 73 74 49 6e 64 65 78 28 73 71 6c 69 74 65  BestIndex(sqlite
fa20: 33 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20 73  3_vtab *pVTab, s
fa30: 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66  qlite3_index_inf
fa40: 6f 20 2a 70 49 6e 66 6f 29 7b 0a 20 20 69 6e 74  o *pInfo){.  int
fa50: 20 69 3b 0a 20 20 54 52 41 43 45 28 28 22 46 54   i;.  TRACE(("FT
fa60: 53 31 20 42 65 73 74 49 6e 64 65 78 5c 6e 22 29  S1 BestIndex\n")
fa70: 29 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  );..  for(i=0; i
fa80: 3c 70 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61  <pInfo->nConstra
fa90: 69 6e 74 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 63  int; ++i){.    c
faa0: 6f 6e 73 74 20 73 74 72 75 63 74 20 73 71 6c 69  onst struct sqli
fab0: 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72  te3_index_constr
fac0: 61 69 6e 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e  aint *pConstrain
fad0: 74 3b 0a 20 20 20 20 70 43 6f 6e 73 74 72 61 69  t;.    pConstrai
fae0: 6e 74 20 3d 20 26 70 49 6e 66 6f 2d 3e 61 43 6f  nt = &pInfo->aCo
faf0: 6e 73 74 72 61 69 6e 74 5b 69 5d 3b 0a 20 20 20  nstraint[i];.   
fb00: 20 69 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74   if( pConstraint
fb10: 2d 3e 75 73 61 62 6c 65 20 29 20 7b 0a 20 20 20  ->usable ) {.   
fb20: 20 20 20 69 66 28 20 70 43 6f 6e 73 74 72 61 69     if( pConstrai
fb30: 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 2d 31 20  nt->iColumn==-1 
fb40: 26 26 0a 20 20 20 20 20 20 20 20 20 20 70 43 6f  &&.          pCo
fb50: 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 3d 3d 53 51  nstraint->op==SQ
fb60: 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54  LITE_INDEX_CONST
fb70: 52 41 49 4e 54 5f 45 51 20 29 7b 0a 20 20 20 20  RAINT_EQ ){.    
fb80: 20 20 20 20 70 49 6e 66 6f 2d 3e 69 64 78 4e 75      pInfo->idxNu
fb90: 6d 20 3d 20 51 55 45 52 59 5f 52 4f 57 49 44 3b  m = QUERY_ROWID;
fba0: 20 20 20 20 20 20 2f 2a 20 6c 6f 6f 6b 75 70 20        /* lookup 
fbb0: 62 79 20 72 6f 77 69 64 20 2a 2f 0a 20 20 20 20  by rowid */.    
fbc0: 20 20 20 20 54 52 41 43 45 28 28 22 46 54 53 31      TRACE(("FTS1
fbd0: 20 51 55 45 52 59 5f 52 4f 57 49 44 5c 6e 22 29   QUERY_ROWID\n")
fbe0: 29 3b 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20  );.      } else 
fbf0: 69 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d  if( pConstraint-
fc00: 3e 69 43 6f 6c 75 6d 6e 3e 3d 30 20 26 26 0a 20  >iColumn>=0 &&. 
fc10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fc20: 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 3d  pConstraint->op=
fc30: 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f  =SQLITE_INDEX_CO
fc40: 4e 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 20 29  NSTRAINT_MATCH )
fc50: 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 66 75 6c  {.        /* ful
fc60: 6c 2d 74 65 78 74 20 73 65 61 72 63 68 20 2a 2f  l-text search */
fc70: 0a 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e  .        pInfo->
fc80: 69 64 78 4e 75 6d 20 3d 20 51 55 45 52 59 5f 46  idxNum = QUERY_F
fc90: 55 4c 4c 54 45 58 54 20 2b 20 70 43 6f 6e 73 74  ULLTEXT + pConst
fca0: 72 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a  raint->iColumn;.
fcb0: 20 20 20 20 20 20 20 20 54 52 41 43 45 28 28 22          TRACE(("
fcc0: 46 54 53 31 20 51 55 45 52 59 5f 46 55 4c 4c 54  FTS1 QUERY_FULLT
fcd0: 45 58 54 20 25 64 5c 6e 22 2c 20 70 43 6f 6e 73  EXT %d\n", pCons
fce0: 74 72 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 29  traint->iColumn)
fcf0: 29 3b 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20  );.      } else 
fd00: 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20 20 20 20  continue;..     
fd10: 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61   pInfo->aConstra
fd20: 69 6e 74 55 73 61 67 65 5b 69 5d 2e 61 72 67 76  intUsage[i].argv
fd30: 49 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20 20 20  Index = 1;.     
fd40: 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61   pInfo->aConstra
fd50: 69 6e 74 55 73 61 67 65 5b 69 5d 2e 6f 6d 69 74  intUsage[i].omit
fd60: 20 3d 20 31 3b 0a 0a 20 20 20 20 20 20 2f 2a 20   = 1;..      /* 
fd70: 41 6e 20 61 72 62 69 74 72 61 72 79 20 76 61 6c  An arbitrary val
fd80: 75 65 20 66 6f 72 20 6e 6f 77 2e 0a 20 20 20 20  ue for now..    
fd90: 20 20 20 2a 20 54 4f 44 4f 3a 20 50 65 72 68 61     * TODO: Perha
fda0: 70 73 20 72 6f 77 69 64 20 6d 61 74 63 68 65 73  ps rowid matches
fdb0: 20 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e 73 69   should be consi
fdc0: 64 65 72 65 64 20 63 68 65 61 70 65 72 20 74 68  dered cheaper th
fdd0: 61 6e 0a 20 20 20 20 20 20 20 2a 20 66 75 6c 6c  an.       * full
fde0: 2d 74 65 78 74 20 73 65 61 72 63 68 65 73 2e 20  -text searches. 
fdf0: 2a 2f 0a 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e  */.      pInfo->
fe00: 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20  estimatedCost = 
fe10: 31 2e 30 3b 20 20 20 0a 0a 20 20 20 20 20 20 72  1.0;   ..      r
fe20: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
fe30: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 49 6e  .    }.  }.  pIn
fe40: 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 51 55 45  fo->idxNum = QUE
fe50: 52 59 5f 47 45 4e 45 52 49 43 3b 0a 20 20 72 65  RY_GENERIC;.  re
fe60: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
fe70: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75  }..static int fu
fe80: 6c 6c 74 65 78 74 44 69 73 63 6f 6e 6e 65 63 74  lltextDisconnect
fe90: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
fea0: 56 54 61 62 29 7b 0a 20 20 54 52 41 43 45 28 28  VTab){.  TRACE((
feb0: 22 46 54 53 31 20 44 69 73 63 6f 6e 6e 65 63 74  "FTS1 Disconnect
fec0: 20 25 70 5c 6e 22 2c 20 70 56 54 61 62 29 29 3b   %p\n", pVTab));
fed0: 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62  .  fulltext_vtab
fee0: 5f 64 65 73 74 72 6f 79 28 28 66 75 6c 6c 74 65  _destroy((fullte
fef0: 78 74 5f 76 74 61 62 20 2a 29 70 56 54 61 62 29  xt_vtab *)pVTab)
ff00: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
ff10: 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  E_OK;.}..static 
ff20: 69 6e 74 20 66 75 6c 6c 74 65 78 74 44 65 73 74  int fulltextDest
ff30: 72 6f 79 28 73 71 6c 69 74 65 33 5f 76 74 61 62  roy(sqlite3_vtab
ff40: 20 2a 70 56 54 61 62 29 7b 0a 20 20 66 75 6c 6c   *pVTab){.  full
ff50: 74 65 78 74 5f 76 74 61 62 20 2a 76 20 3d 20 28  text_vtab *v = (
ff60: 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29  fulltext_vtab *)
ff70: 70 56 54 61 62 3b 0a 20 20 69 6e 74 20 72 63 3b  pVTab;.  int rc;
ff80: 0a 0a 20 20 54 52 41 43 45 28 28 22 46 54 53 31  ..  TRACE(("FTS1
ff90: 20 44 65 73 74 72 6f 79 20 25 70 5c 6e 22 2c 20   Destroy %p\n", 
ffa0: 70 56 54 61 62 29 29 3b 0a 20 20 72 63 20 3d 20  pVTab));.  rc = 
ffb0: 73 71 6c 5f 65 78 65 63 28 76 2d 3e 64 62 2c 20  sql_exec(v->db, 
ffc0: 76 2d 3e 7a 44 62 2c 20 76 2d 3e 7a 4e 61 6d 65  v->zDb, v->zName
ffd0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
ffe0: 20 20 22 64 72 6f 70 20 74 61 62 6c 65 20 69 66    "drop table if
fff0: 20 65 78 69 73 74 73 20 25 5f 63 6f 6e 74 65 6e   exists %_conten
10000 74 3b 22 0a 20 20 20 20 20 20 20 20 20 20 20 20  t;".            
10010 20 20 20 20 22 64 72 6f 70 20 74 61 62 6c 65 20      "drop table 
10020 69 66 20 65 78 69 73 74 73 20 25 5f 74 65 72 6d  if exists %_term
10030 3b 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ;".             
10040 20 20 20 29 3b 0a 20 20 69 66 28 20 72 63 21 3d     );.  if( rc!=
10050 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
10060 72 6e 20 72 63 3b 0a 0a 20 20 66 75 6c 6c 74 65  rn rc;..  fullte
10070 78 74 5f 76 74 61 62 5f 64 65 73 74 72 6f 79 28  xt_vtab_destroy(
10080 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
10090 29 70 56 54 61 62 29 3b 0a 20 20 72 65 74 75 72  )pVTab);.  retur
100a0 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
100b0 73 74 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 74  static int fullt
100c0 65 78 74 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f  extOpen(sqlite3_
100d0 76 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71 6c  vtab *pVTab, sql
100e0 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
100f0 20 2a 2a 70 70 43 75 72 73 6f 72 29 7b 0a 20 20   **ppCursor){.  
10100 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20  fulltext_cursor 
10110 2a 63 3b 0a 0a 20 20 63 20 3d 20 28 66 75 6c 6c  *c;..  c = (full
10120 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 29 20 63  text_cursor *) c
10130 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 66 75 6c  alloc(sizeof(ful
10140 6c 74 65 78 74 5f 63 75 72 73 6f 72 29 2c 20 31  ltext_cursor), 1
10150 29 3b 0a 20 20 2f 2a 20 73 71 6c 69 74 65 20 77  );.  /* sqlite w
10160 69 6c 6c 20 69 6e 69 74 69 61 6c 69 7a 65 20 63  ill initialize c
10170 2d 3e 62 61 73 65 20 2a 2f 0a 20 20 2a 70 70 43  ->base */.  *ppC
10180 75 72 73 6f 72 20 3d 20 26 63 2d 3e 62 61 73 65  ursor = &c->base
10190 3b 0a 20 20 54 52 41 43 45 28 28 22 46 54 53 31  ;.  TRACE(("FTS1
101a0 20 4f 70 65 6e 20 25 70 3a 20 25 70 5c 6e 22 2c   Open %p: %p\n",
101b0 20 70 56 54 61 62 2c 20 63 29 29 3b 0a 0a 20 20   pVTab, c));..  
101c0 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
101d0 3b 0a 7d 0a 0a 0a 2f 2a 20 46 72 65 65 20 61 6c  ;.}.../* Free al
101e0 6c 20 6f 66 20 74 68 65 20 64 79 6e 61 6d 69 63  l of the dynamic
101f0 61 6c 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d  ally allocated m
10200 65 6d 6f 72 79 20 68 65 6c 64 20 62 79 20 2a 71  emory held by *q
10210 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
10220 71 75 65 72 79 43 6c 65 61 72 28 51 75 65 72 79  queryClear(Query
10230 20 2a 71 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20   *q){.  int i;. 
10240 20 66 6f 72 28 69 20 3d 20 30 3b 20 69 20 3c 20   for(i = 0; i < 
10250 71 2d 3e 6e 54 65 72 6d 73 3b 20 2b 2b 69 29 7b  q->nTerms; ++i){
10260 0a 20 20 20 20 66 72 65 65 28 71 2d 3e 70 54 65  .    free(q->pTe
10270 72 6d 73 5b 69 5d 2e 70 54 65 72 6d 29 3b 0a 20  rms[i].pTerm);. 
10280 20 7d 0a 20 20 66 72 65 65 28 71 2d 3e 70 54 65   }.  free(q->pTe
10290 72 6d 73 29 3b 0a 20 20 6d 65 6d 73 65 74 28 71  rms);.  memset(q
102a0 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a 71 29 29  , 0, sizeof(*q))
102b0 3b 0a 7d 0a 0a 2f 2a 20 46 72 65 65 20 61 6c 6c  ;.}../* Free all
102c0 20 6f 66 20 74 68 65 20 64 79 6e 61 6d 69 63 61   of the dynamica
102d0 6c 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65  lly allocated me
102e0 6d 6f 72 79 20 68 65 6c 64 20 62 79 20 74 68 65  mory held by the
102f0 0a 2a 2a 20 53 6e 69 70 70 65 74 0a 2a 2f 0a 73  .** Snippet.*/.s
10300 74 61 74 69 63 20 76 6f 69 64 20 73 6e 69 70 70  tatic void snipp
10310 65 74 43 6c 65 61 72 28 53 6e 69 70 70 65 74 20  etClear(Snippet 
10320 2a 70 29 7b 0a 20 20 66 72 65 65 28 70 2d 3e 61  *p){.  free(p->a
10330 4d 61 74 63 68 29 3b 0a 20 20 66 72 65 65 28 70  Match);.  free(p
10340 2d 3e 7a 4f 66 66 73 65 74 29 3b 0a 20 20 66 72  ->zOffset);.  fr
10350 65 65 28 70 2d 3e 7a 53 6e 69 70 70 65 74 29 3b  ee(p->zSnippet);
10360 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20  .  memset(p, 0, 
10370 73 69 7a 65 6f 66 28 2a 70 29 29 3b 0a 7d 0a 2f  sizeof(*p));.}./
10380 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 61 20 73 69  *.** Append a si
10390 6e 67 6c 65 20 65 6e 74 72 79 20 74 6f 20 74 68  ngle entry to th
103a0 65 20 70 2d 3e 61 4d 61 74 63 68 5b 5d 20 6c 6f  e p->aMatch[] lo
103b0 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  g..*/.static voi
103c0 64 20 73 6e 69 70 70 65 74 41 70 70 65 6e 64 4d  d snippetAppendM
103d0 61 74 63 68 28 0a 20 20 53 6e 69 70 70 65 74 20  atch(.  Snippet 
103e0 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  *p,             
103f0 20 20 2f 2a 20 41 70 70 65 6e 64 20 74 68 65 20    /* Append the 
10400 65 6e 74 72 79 20 74 6f 20 74 68 69 73 20 73 6e  entry to this sn
10410 69 70 70 65 74 20 2a 2f 0a 20 20 69 6e 74 20 69  ippet */.  int i
10420 43 6f 6c 2c 20 69 6e 74 20 69 54 65 72 6d 2c 20  Col, int iTerm, 
10430 20 20 20 20 20 2f 2a 20 54 68 65 20 63 6f 6c 75       /* The colu
10440 6d 6e 20 61 6e 64 20 71 75 65 72 79 20 74 65 72  mn and query ter
10450 6d 20 2a 2f 0a 20 20 69 6e 74 20 69 53 74 61 72  m */.  int iStar
10460 74 2c 20 69 6e 74 20 6e 42 79 74 65 20 20 20 20  t, int nByte    
10470 20 2f 2a 20 4f 66 66 73 65 74 20 61 6e 64 20 73   /* Offset and s
10480 69 7a 65 20 6f 66 20 74 68 65 20 6d 61 74 63 68  ize of the match
10490 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a   */.){.  int i;.
104a0 20 20 73 74 72 75 63 74 20 73 6e 69 70 70 65 74    struct snippet
104b0 4d 61 74 63 68 20 2a 70 4d 61 74 63 68 3b 0a 20  Match *pMatch;. 
104c0 20 69 66 28 20 70 2d 3e 6e 4d 61 74 63 68 2b 31   if( p->nMatch+1
104d0 3e 3d 70 2d 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20  >=p->nAlloc ){. 
104e0 20 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 70     p->nAlloc = p
104f0 2d 3e 6e 41 6c 6c 6f 63 2a 32 20 2b 20 31 30 3b  ->nAlloc*2 + 10;
10500 0a 20 20 20 20 70 2d 3e 61 4d 61 74 63 68 20 3d  .    p->aMatch =
10510 20 72 65 61 6c 6c 6f 63 28 70 2d 3e 61 4d 61 74   realloc(p->aMat
10520 63 68 2c 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 73 69  ch, p->nAlloc*si
10530 7a 65 6f 66 28 70 2d 3e 61 4d 61 74 63 68 5b 30  zeof(p->aMatch[0
10540 5d 29 20 29 3b 0a 20 20 20 20 69 66 28 20 70 2d  ]) );.    if( p-
10550 3e 61 4d 61 74 63 68 3d 3d 30 20 29 7b 0a 20 20  >aMatch==0 ){.  
10560 20 20 20 20 70 2d 3e 6e 4d 61 74 63 68 20 3d 20      p->nMatch = 
10570 30 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c  0;.      p->nAll
10580 6f 63 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 65  oc = 0;.      re
10590 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  turn;.    }.  }.
105a0 20 20 69 20 3d 20 70 2d 3e 6e 4d 61 74 63 68 2b    i = p->nMatch+
105b0 2b 3b 0a 20 20 70 4d 61 74 63 68 20 3d 20 26 70  +;.  pMatch = &p
105c0 2d 3e 61 4d 61 74 63 68 5b 69 5d 3b 0a 20 20 70  ->aMatch[i];.  p
105d0 4d 61 74 63 68 2d 3e 69 43 6f 6c 20 3d 20 69 43  Match->iCol = iC
105e0 6f 6c 3b 0a 20 20 70 4d 61 74 63 68 2d 3e 69 54  ol;.  pMatch->iT
105f0 65 72 6d 20 3d 20 69 54 65 72 6d 3b 0a 20 20 70  erm = iTerm;.  p
10600 4d 61 74 63 68 2d 3e 69 53 74 61 72 74 20 3d 20  Match->iStart = 
10610 69 53 74 61 72 74 3b 0a 20 20 70 4d 61 74 63 68  iStart;.  pMatch
10620 2d 3e 6e 42 79 74 65 20 3d 20 6e 42 79 74 65 3b  ->nByte = nByte;
10630 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 69 7a 69 6e 67  .}../*.** Sizing
10640 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 6f 72   information for
10650 20 74 68 65 20 63 69 72 63 75 6c 61 72 20 62 75   the circular bu
10660 66 66 65 72 20 75 73 65 64 20 69 6e 20 73 6e 69  ffer used in sni
10670 70 70 65 74 4f 66 66 73 65 74 73 4f 66 43 6f 6c  ppetOffsetsOfCol
10680 75 6d 6e 28 29 0a 2a 2f 0a 23 64 65 66 69 6e 65  umn().*/.#define
10690 20 46 54 53 31 5f 52 4f 54 4f 52 5f 53 5a 20 20   FTS1_ROTOR_SZ  
106a0 20 28 33 32 29 0a 23 64 65 66 69 6e 65 20 46 54   (32).#define FT
106b0 53 31 5f 52 4f 54 4f 52 5f 4d 41 53 4b 20 28 46  S1_ROTOR_MASK (F
106c0 54 53 31 5f 52 4f 54 4f 52 5f 53 5a 2d 31 29 0a  TS1_ROTOR_SZ-1).
106d0 0a 2f 2a 0a 2a 2a 20 41 64 64 20 65 6e 74 72 69  ./*.** Add entri
106e0 65 73 20 74 6f 20 70 53 6e 69 70 70 65 74 2d 3e  es to pSnippet->
106f0 61 4d 61 74 63 68 5b 5d 20 66 6f 72 20 65 76 65  aMatch[] for eve
10700 72 79 20 6d 61 74 63 68 20 74 68 61 74 20 6f 63  ry match that oc
10710 63 75 72 73 20 61 67 61 69 6e 73 74 0a 2a 2a 20  curs against.** 
10720 64 6f 63 75 6d 65 6e 74 20 7a 44 6f 63 5b 30 2e  document zDoc[0.
10730 2e 6e 44 6f 63 2d 31 5d 20 77 68 69 63 68 20 69  .nDoc-1] which i
10740 73 20 73 74 6f 72 65 64 20 69 6e 20 63 6f 6c 75  s stored in colu
10750 6d 6e 20 69 43 6f 6c 75 6d 6e 2e 0a 2a 2f 0a 73  mn iColumn..*/.s
10760 74 61 74 69 63 20 76 6f 69 64 20 73 6e 69 70 70  tatic void snipp
10770 65 74 4f 66 66 73 65 74 73 4f 66 43 6f 6c 75 6d  etOffsetsOfColum
10780 6e 28 0a 20 20 51 75 65 72 79 20 2a 70 51 75 65  n(.  Query *pQue
10790 72 79 2c 0a 20 20 53 6e 69 70 70 65 74 20 2a 70  ry,.  Snippet *p
107a0 53 6e 69 70 70 65 74 2c 0a 20 20 69 6e 74 20 69  Snippet,.  int i
107b0 43 6f 6c 75 6d 6e 2c 0a 20 20 63 6f 6e 73 74 20  Column,.  const 
107c0 63 68 61 72 20 2a 7a 44 6f 63 2c 0a 20 20 69 6e  char *zDoc,.  in
107d0 74 20 6e 44 6f 63 0a 29 7b 0a 20 20 63 6f 6e 73  t nDoc.){.  cons
107e0 74 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69  t sqlite3_tokeni
107f0 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a 70 54 4d 6f  zer_module *pTMo
10800 64 75 6c 65 3b 20 20 2f 2a 20 54 68 65 20 74 6f  dule;  /* The to
10810 6b 65 6e 69 7a 65 72 20 6d 6f 64 75 6c 65 20 2a  kenizer module *
10820 2f 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65  /.  sqlite3_toke
10830 6e 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65  nizer *pTokenize
10840 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  r;             /
10850 2a 20 54 68 65 20 73 70 65 63 69 66 69 63 20 74  * The specific t
10860 6f 6b 65 6e 69 7a 65 72 20 2a 2f 0a 20 20 73 71  okenizer */.  sq
10870 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f  lite3_tokenizer_
10880 63 75 72 73 6f 72 20 2a 70 54 43 75 72 73 6f 72  cursor *pTCursor
10890 3b 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 6b 65  ;        /* Toke
108a0 6e 69 7a 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a  nizer cursor */.
108b0 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20    fulltext_vtab 
108c0 2a 70 56 74 61 62 3b 20 20 20 20 20 20 20 20 20  *pVtab;         
108d0 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 66 75         /* The fu
108e0 6c 6c 20 74 65 78 74 20 69 6e 64 65 78 20 2a 2f  ll text index */
108f0 0a 20 20 69 6e 74 20 6e 43 6f 6c 75 6d 6e 3b 20  .  int nColumn; 
10900 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10910 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
10920 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
10930 74 68 65 20 69 6e 64 65 78 20 2a 2f 0a 20 20 63  the index */.  c
10940 6f 6e 73 74 20 51 75 65 72 79 54 65 72 6d 20 2a  onst QueryTerm *
10950 61 54 65 72 6d 3b 20 20 20 20 20 20 20 20 20 20  aTerm;          
10960 20 20 20 20 2f 2a 20 51 75 65 72 79 20 73 74 72      /* Query str
10970 69 6e 67 20 74 65 72 6d 73 20 2a 2f 0a 20 20 69  ing terms */.  i
10980 6e 74 20 6e 54 65 72 6d 3b 20 20 20 20 20 20 20  nt nTerm;       
10990 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
109a0 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
109b0 20 71 75 65 72 79 20 73 74 72 69 6e 67 20 74 65   query string te
109c0 72 6d 73 20 2a 2f 20 20 0a 20 20 69 6e 74 20 69  rms */  .  int i
109d0 2c 20 6a 3b 20 20 20 20 20 20 20 20 20 20 20 20  , j;            
109e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
109f0 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 73  /* Loop counters
10a00 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20 20   */.  int rc;   
10a10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10a20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
10a30 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 75  turn code */.  u
10a40 6e 73 69 67 6e 65 64 20 69 6e 74 20 6d 61 74 63  nsigned int matc
10a50 68 2c 20 70 72 65 76 4d 61 74 63 68 3b 20 20 20  h, prevMatch;   
10a60 20 20 20 20 2f 2a 20 50 68 72 61 73 65 20 73 65      /* Phrase se
10a70 61 72 63 68 20 62 69 74 6d 61 73 6b 73 20 2a 2f  arch bitmasks */
10a80 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
10a90 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20 20 20  Token;          
10aa0 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
10ab0 74 6f 6b 65 6e 20 66 72 6f 6d 20 74 68 65 20 74  token from the t
10ac0 6f 6b 65 6e 69 7a 65 72 20 2a 2f 0a 20 20 69 6e  okenizer */.  in
10ad0 74 20 6e 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20  t nToken;       
10ae0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10af0 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 7a 54     /* Size of zT
10b00 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 42  oken */.  int iB
10b10 65 67 69 6e 2c 20 69 45 6e 64 2c 20 69 50 6f 73  egin, iEnd, iPos
10b20 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
10b30 2a 20 4f 66 66 73 65 74 73 20 6f 66 20 62 65 67  * Offsets of beg
10b40 69 6e 6e 69 6e 67 20 61 6e 64 20 65 6e 64 20 2a  inning and end *
10b50 2f 0a 0a 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c  /..  /* The foll
10b60 6f 77 69 6e 67 20 76 61 72 69 61 62 6c 65 73 20  owing variables 
10b70 6b 65 65 70 20 61 20 63 69 72 63 75 6c 61 72 20  keep a circular 
10b80 62 75 66 66 65 72 20 6f 66 20 74 68 65 20 6c 61  buffer of the la
10b90 73 74 0a 20 20 2a 2a 20 66 65 77 20 74 6f 6b 65  st.  ** few toke
10ba0 6e 73 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  ns */.  unsigned
10bb0 20 69 6e 74 20 69 52 6f 74 6f 72 20 3d 20 30 3b   int iRotor = 0;
10bc0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
10bd0 49 6e 64 65 78 20 6f 66 20 63 75 72 72 65 6e 74  Index of current
10be0 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20   token */.  int 
10bf0 69 52 6f 74 6f 72 42 65 67 69 6e 5b 46 54 53 31  iRotorBegin[FTS1
10c00 5f 52 4f 54 4f 52 5f 53 5a 5d 3b 20 20 20 20 20  _ROTOR_SZ];     
10c10 20 2f 2a 20 42 65 67 69 6e 6e 69 6e 67 20 6f 66   /* Beginning of
10c20 66 73 65 74 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f  fset of token */
10c30 0a 20 20 69 6e 74 20 69 52 6f 74 6f 72 4c 65 6e  .  int iRotorLen
10c40 5b 46 54 53 31 5f 52 4f 54 4f 52 5f 53 5a 5d 3b  [FTS1_ROTOR_SZ];
10c50 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74          /* Lengt
10c60 68 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 0a 20  h of token */.. 
10c70 20 70 56 74 61 62 20 3d 20 70 51 75 65 72 79 2d   pVtab = pQuery-
10c80 3e 70 46 74 73 3b 0a 20 20 6e 43 6f 6c 75 6d 6e  >pFts;.  nColumn
10c90 20 3d 20 70 56 74 61 62 2d 3e 6e 43 6f 6c 75 6d   = pVtab->nColum
10ca0 6e 3b 0a 20 20 70 54 6f 6b 65 6e 69 7a 65 72 20  n;.  pTokenizer 
10cb0 3d 20 70 56 74 61 62 2d 3e 70 54 6f 6b 65 6e 69  = pVtab->pTokeni
10cc0 7a 65 72 3b 0a 20 20 70 54 4d 6f 64 75 6c 65 20  zer;.  pTModule 
10cd0 3d 20 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e 70 4d  = pTokenizer->pM
10ce0 6f 64 75 6c 65 3b 0a 20 20 72 63 20 3d 20 70 54  odule;.  rc = pT
10cf0 4d 6f 64 75 6c 65 2d 3e 78 4f 70 65 6e 28 70 54  Module->xOpen(pT
10d00 6f 6b 65 6e 69 7a 65 72 2c 20 7a 44 6f 63 2c 20  okenizer, zDoc, 
10d10 6e 44 6f 63 2c 20 26 70 54 43 75 72 73 6f 72 29  nDoc, &pTCursor)
10d20 3b 0a 20 20 69 66 28 20 72 63 20 29 20 72 65 74  ;.  if( rc ) ret
10d30 75 72 6e 3b 0a 20 20 70 54 43 75 72 73 6f 72 2d  urn;.  pTCursor-
10d40 3e 70 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 70 54  >pTokenizer = pT
10d50 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20 61 54 65 72  okenizer;.  aTer
10d60 6d 20 3d 20 70 51 75 65 72 79 2d 3e 70 54 65 72  m = pQuery->pTer
10d70 6d 73 3b 0a 20 20 6e 54 65 72 6d 20 3d 20 70 51  ms;.  nTerm = pQ
10d80 75 65 72 79 2d 3e 6e 54 65 72 6d 73 3b 0a 20 20  uery->nTerms;.  
10d90 69 66 28 20 6e 54 65 72 6d 3e 3d 46 54 53 31 5f  if( nTerm>=FTS1_
10da0 52 4f 54 4f 52 5f 53 5a 20 29 7b 0a 20 20 20 20  ROTOR_SZ ){.    
10db0 6e 54 65 72 6d 20 3d 20 46 54 53 31 5f 52 4f 54  nTerm = FTS1_ROT
10dc0 4f 52 5f 53 5a 20 2d 20 31 3b 0a 20 20 7d 0a 20  OR_SZ - 1;.  }. 
10dd0 20 70 72 65 76 4d 61 74 63 68 20 3d 20 30 3b 0a   prevMatch = 0;.
10de0 20 20 77 68 69 6c 65 28 31 29 7b 0a 20 20 20 20    while(1){.    
10df0 72 63 20 3d 20 70 54 4d 6f 64 75 6c 65 2d 3e 78  rc = pTModule->x
10e00 4e 65 78 74 28 70 54 43 75 72 73 6f 72 2c 20 26  Next(pTCursor, &
10e10 7a 54 6f 6b 65 6e 2c 20 26 6e 54 6f 6b 65 6e 2c  zToken, &nToken,
10e20 20 26 69 42 65 67 69 6e 2c 20 26 69 45 6e 64 2c   &iBegin, &iEnd,
10e30 20 26 69 50 6f 73 29 3b 0a 20 20 20 20 69 66 28   &iPos);.    if(
10e40 20 72 63 20 29 20 62 72 65 61 6b 3b 0a 20 20 20   rc ) break;.   
10e50 20 69 52 6f 74 6f 72 42 65 67 69 6e 5b 69 52 6f   iRotorBegin[iRo
10e60 74 6f 72 26 46 54 53 31 5f 52 4f 54 4f 52 5f 4d  tor&FTS1_ROTOR_M
10e70 41 53 4b 5d 20 3d 20 69 42 65 67 69 6e 3b 0a 20  ASK] = iBegin;. 
10e80 20 20 20 69 52 6f 74 6f 72 4c 65 6e 5b 69 52 6f     iRotorLen[iRo
10e90 74 6f 72 26 46 54 53 31 5f 52 4f 54 4f 52 5f 4d  tor&FTS1_ROTOR_M
10ea0 41 53 4b 5d 20 3d 20 69 45 6e 64 2d 69 42 65 67  ASK] = iEnd-iBeg
10eb0 69 6e 3b 0a 20 20 20 20 6d 61 74 63 68 20 3d 20  in;.    match = 
10ec0 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  0;.    for(i=0; 
10ed0 69 3c 6e 54 65 72 6d 3b 20 69 2b 2b 29 7b 0a 20  i<nTerm; i++){. 
10ee0 20 20 20 20 20 69 6e 74 20 69 43 6f 6c 3b 0a 20       int iCol;. 
10ef0 20 20 20 20 20 69 43 6f 6c 20 3d 20 61 54 65 72       iCol = aTer
10f00 6d 5b 69 5d 2e 69 43 6f 6c 75 6d 6e 3b 0a 20 20  m[i].iColumn;.  
10f10 20 20 20 20 69 66 28 20 69 43 6f 6c 3e 3d 30 20      if( iCol>=0 
10f20 26 26 20 69 43 6f 6c 3c 6e 43 6f 6c 75 6d 6e 20  && iCol<nColumn 
10f30 26 26 20 69 43 6f 6c 21 3d 69 43 6f 6c 75 6d 6e  && iCol!=iColumn
10f40 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20   ) continue;.   
10f50 20 20 20 69 66 28 20 61 54 65 72 6d 5b 69 5d 2e     if( aTerm[i].
10f60 6e 54 65 72 6d 21 3d 6e 54 6f 6b 65 6e 20 29 20  nTerm!=nToken ) 
10f70 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
10f80 69 66 28 20 6d 65 6d 63 6d 70 28 61 54 65 72 6d  if( memcmp(aTerm
10f90 5b 69 5d 2e 70 54 65 72 6d 2c 20 7a 54 6f 6b 65  [i].pTerm, zToke
10fa0 6e 2c 20 6e 54 6f 6b 65 6e 29 20 29 20 63 6f 6e  n, nToken) ) con
10fb0 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 69 66 28  tinue;.      if(
10fc0 20 61 54 65 72 6d 5b 69 5d 2e 69 50 68 72 61 73   aTerm[i].iPhras
10fd0 65 3e 31 20 26 26 20 28 70 72 65 76 4d 61 74 63  e>1 && (prevMatc
10fe0 68 20 26 20 28 31 3c 3c 69 29 29 3d 3d 30 20 29  h & (1<<i))==0 )
10ff0 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20   continue;.     
11000 20 6d 61 74 63 68 20 7c 3d 20 31 3c 3c 69 3b 0a   match |= 1<<i;.
11010 20 20 20 20 20 20 69 66 28 20 69 3d 3d 6e 54 65        if( i==nTe
11020 72 6d 2d 31 20 7c 7c 20 61 54 65 72 6d 5b 69 2b  rm-1 || aTerm[i+
11030 31 5d 2e 69 50 68 72 61 73 65 3d 3d 31 20 29 7b  1].iPhrase==1 ){
11040 0a 20 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 61  .        for(j=a
11050 54 65 72 6d 5b 69 5d 2e 69 50 68 72 61 73 65 2d  Term[i].iPhrase-
11060 31 3b 20 6a 3e 3d 30 3b 20 6a 2d 2d 29 7b 0a 20  1; j>=0; j--){. 
11070 20 20 20 20 20 20 20 20 20 69 6e 74 20 6b 20 3d           int k =
11080 20 28 69 52 6f 74 6f 72 2d 6a 29 20 26 20 46 54   (iRotor-j) & FT
11090 53 31 5f 52 4f 54 4f 52 5f 4d 41 53 4b 3b 0a 20  S1_ROTOR_MASK;. 
110a0 20 20 20 20 20 20 20 20 20 73 6e 69 70 70 65 74           snippet
110b0 41 70 70 65 6e 64 4d 61 74 63 68 28 70 53 6e 69  AppendMatch(pSni
110c0 70 70 65 74 2c 20 69 43 6f 6c 75 6d 6e 2c 20 69  ppet, iColumn, i
110d0 2d 6a 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  -j,.            
110e0 20 20 20 20 69 52 6f 74 6f 72 42 65 67 69 6e 5b      iRotorBegin[
110f0 6b 5d 2c 20 69 52 6f 74 6f 72 4c 65 6e 5b 6b 5d  k], iRotorLen[k]
11100 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
11110 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70     }.    }.    p
11120 72 65 76 4d 61 74 63 68 20 3d 20 6d 61 74 63 68  revMatch = match
11130 3c 3c 31 3b 0a 20 20 20 20 69 52 6f 74 6f 72 2b  <<1;.    iRotor+
11140 2b 3b 0a 20 20 7d 0a 20 20 70 54 4d 6f 64 75 6c  +;.  }.  pTModul
11150 65 2d 3e 78 43 6c 6f 73 65 28 70 54 43 75 72 73  e->xClose(pTCurs
11160 6f 72 29 3b 20 20 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  or);  .}.../*.**
11170 20 43 6f 6d 70 75 74 65 20 61 6c 6c 20 6f 66 66   Compute all off
11180 73 65 74 73 20 66 6f 72 20 74 68 65 20 63 75 72  sets for the cur
11190 72 65 6e 74 20 72 6f 77 20 6f 66 20 74 68 65 20  rent row of the 
111a0 71 75 65 72 79 2e 20 20 0a 2a 2a 20 49 66 20 74  query.  .** If t
111b0 68 65 20 6f 66 66 73 65 74 73 20 68 61 76 65 20  he offsets have 
111c0 61 6c 72 65 61 64 79 20 62 65 65 6e 20 63 6f 6d  already been com
111d0 70 75 74 65 64 2c 20 74 68 69 73 20 72 6f 75 74  puted, this rout
111e0 69 6e 65 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a  ine is a no-op..
111f0 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  */.static void s
11200 6e 69 70 70 65 74 41 6c 6c 4f 66 66 73 65 74 73  nippetAllOffsets
11210 28 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72  (fulltext_cursor
11220 20 2a 70 29 7b 0a 20 20 69 6e 74 20 6e 43 6f 6c   *p){.  int nCol
11230 75 6d 6e 3b 0a 20 20 69 6e 74 20 69 43 6f 6c 75  umn;.  int iColu
11240 6d 6e 2c 20 69 3b 0a 20 20 69 6e 74 20 69 46 69  mn, i;.  int iFi
11250 72 73 74 2c 20 69 4c 61 73 74 3b 0a 20 20 66 75  rst, iLast;.  fu
11260 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 70 46 74  lltext_vtab *pFt
11270 73 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 73 6e 69  s;..  if( p->sni
11280 70 70 65 74 2e 6e 4d 61 74 63 68 20 29 20 72 65  ppet.nMatch ) re
11290 74 75 72 6e 3b 0a 20 20 69 66 28 20 70 2d 3e 71  turn;.  if( p->q
112a0 2e 6e 54 65 72 6d 73 3d 3d 30 20 29 20 72 65 74  .nTerms==0 ) ret
112b0 75 72 6e 3b 0a 20 20 70 46 74 73 20 3d 20 70 2d  urn;.  pFts = p-
112c0 3e 71 2e 70 46 74 73 3b 0a 20 20 6e 43 6f 6c 75  >q.pFts;.  nColu
112d0 6d 6e 20 3d 20 70 46 74 73 2d 3e 6e 43 6f 6c 75  mn = pFts->nColu
112e0 6d 6e 3b 0a 20 20 69 43 6f 6c 75 6d 6e 20 3d 20  mn;.  iColumn = 
112f0 70 2d 3e 69 43 75 72 73 6f 72 54 79 70 65 20 2d  p->iCursorType -
11300 20 51 55 45 52 59 5f 46 55 4c 4c 54 45 58 54 3b   QUERY_FULLTEXT;
11310 0a 20 20 69 66 28 20 69 43 6f 6c 75 6d 6e 3c 30  .  if( iColumn<0
11320 20 7c 7c 20 69 43 6f 6c 75 6d 6e 3e 3d 6e 43 6f   || iColumn>=nCo
11330 6c 75 6d 6e 20 29 7b 0a 20 20 20 20 69 46 69 72  lumn ){.    iFir
11340 73 74 20 3d 20 30 3b 0a 20 20 20 20 69 4c 61 73  st = 0;.    iLas
11350 74 20 3d 20 6e 43 6f 6c 75 6d 6e 2d 31 3b 0a 20  t = nColumn-1;. 
11360 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 46 69 72   }else{.    iFir
11370 73 74 20 3d 20 69 43 6f 6c 75 6d 6e 3b 0a 20 20  st = iColumn;.  
11380 20 20 69 4c 61 73 74 20 3d 20 69 43 6f 6c 75 6d    iLast = iColum
11390 6e 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d 69  n;.  }.  for(i=i
113a0 46 69 72 73 74 3b 20 69 3c 3d 69 4c 61 73 74 3b  First; i<=iLast;
113b0 20 69 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74   i++){.    const
113c0 20 63 68 61 72 20 2a 7a 44 6f 63 3b 0a 20 20 20   char *zDoc;.   
113d0 20 69 6e 74 20 6e 44 6f 63 3b 0a 20 20 20 20 7a   int nDoc;.    z
113e0 44 6f 63 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  Doc = (const cha
113f0 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  r*)sqlite3_colum
11400 6e 5f 74 65 78 74 28 70 2d 3e 70 53 74 6d 74 2c  n_text(p->pStmt,
11410 20 69 2b 31 29 3b 0a 20 20 20 20 6e 44 6f 63 20   i+1);.    nDoc 
11420 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
11430 5f 62 79 74 65 73 28 70 2d 3e 70 53 74 6d 74 2c  _bytes(p->pStmt,
11440 20 69 2b 31 29 3b 0a 20 20 20 20 73 6e 69 70 70   i+1);.    snipp
11450 65 74 4f 66 66 73 65 74 73 4f 66 43 6f 6c 75 6d  etOffsetsOfColum
11460 6e 28 26 70 2d 3e 71 2c 20 26 70 2d 3e 73 6e 69  n(&p->q, &p->sni
11470 70 70 65 74 2c 20 69 2c 20 7a 44 6f 63 2c 20 6e  ppet, i, zDoc, n
11480 44 6f 63 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  Doc);.  }.}../*.
11490 2a 2a 20 43 6f 6e 76 65 72 74 20 74 68 65 20 69  ** Convert the i
114a0 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e 20 74 68  nformation in th
114b0 65 20 61 4d 61 74 63 68 5b 5d 20 61 72 72 61 79  e aMatch[] array
114c0 20 6f 66 20 74 68 65 20 73 6e 69 70 70 65 74 0a   of the snippet.
114d0 2a 2a 20 69 6e 74 6f 20 74 68 65 20 73 74 72 69  ** into the stri
114e0 6e 67 20 7a 4f 66 66 73 65 74 5b 30 2e 2e 6e 4f  ng zOffset[0..nO
114f0 66 66 73 65 74 2d 31 5d 2e 0a 2a 2f 0a 73 74 61  ffset-1]..*/.sta
11500 74 69 63 20 76 6f 69 64 20 73 6e 69 70 70 65 74  tic void snippet
11510 4f 66 66 73 65 74 54 65 78 74 28 53 6e 69 70 70  OffsetText(Snipp
11520 65 74 20 2a 70 29 7b 0a 20 20 69 6e 74 20 69 3b  et *p){.  int i;
11530 0a 20 20 69 6e 74 20 63 6e 74 20 3d 20 30 3b 0a  .  int cnt = 0;.
11540 20 20 53 74 72 69 6e 67 42 75 66 66 65 72 20 73    StringBuffer s
11550 62 3b 0a 20 20 63 68 61 72 20 7a 42 75 66 5b 32  b;.  char zBuf[2
11560 30 30 5d 3b 0a 20 20 69 66 28 20 70 2d 3e 7a 4f  00];.  if( p->zO
11570 66 66 73 65 74 20 29 20 72 65 74 75 72 6e 3b 0a  ffset ) return;.
11580 20 20 69 6e 69 74 53 74 72 69 6e 67 42 75 66 66    initStringBuff
11590 65 72 28 26 73 62 29 3b 0a 20 20 66 6f 72 28 69  er(&sb);.  for(i
115a0 3d 30 3b 20 69 3c 70 2d 3e 6e 4d 61 74 63 68 3b  =0; i<p->nMatch;
115b0 20 69 2b 2b 29 7b 0a 20 20 20 20 73 74 72 75 63   i++){.    struc
115c0 74 20 73 6e 69 70 70 65 74 4d 61 74 63 68 20 2a  t snippetMatch *
115d0 70 4d 61 74 63 68 20 3d 20 26 70 2d 3e 61 4d 61  pMatch = &p->aMa
115e0 74 63 68 5b 69 5d 3b 0a 20 20 20 20 7a 42 75 66  tch[i];.    zBuf
115f0 5b 30 5d 20 3d 20 27 20 27 3b 0a 20 20 20 20 73  [0] = ' ';.    s
11600 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 28  qlite3_snprintf(
11610 73 69 7a 65 6f 66 28 7a 42 75 66 29 2d 31 2c 20  sizeof(zBuf)-1, 
11620 26 7a 42 75 66 5b 63 6e 74 3e 30 5d 2c 20 22 25  &zBuf[cnt>0], "%
11630 64 20 25 64 20 25 64 20 25 64 22 2c 0a 20 20 20  d %d %d %d",.   
11640 20 20 20 20 20 70 4d 61 74 63 68 2d 3e 69 43 6f       pMatch->iCo
11650 6c 2c 20 70 4d 61 74 63 68 2d 3e 69 54 65 72 6d  l, pMatch->iTerm
11660 2c 20 70 4d 61 74 63 68 2d 3e 69 53 74 61 72 74  , pMatch->iStart
11670 2c 20 70 4d 61 74 63 68 2d 3e 6e 42 79 74 65 29  , pMatch->nByte)
11680 3b 0a 20 20 20 20 61 70 70 65 6e 64 28 26 73 62  ;.    append(&sb
11690 2c 20 7a 42 75 66 29 3b 0a 20 20 20 20 63 6e 74  , zBuf);.    cnt
116a0 2b 2b 3b 0a 20 20 7d 0a 20 20 70 2d 3e 7a 4f 66  ++;.  }.  p->zOf
116b0 66 73 65 74 20 3d 20 73 62 2e 73 3b 0a 20 20 70  fset = sb.s;.  p
116c0 2d 3e 6e 4f 66 66 73 65 74 20 3d 20 73 62 2e 6c  ->nOffset = sb.l
116d0 65 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 7a 44 6f  en;.}../*.** zDo
116e0 63 5b 30 2e 2e 6e 44 6f 63 2d 31 5d 20 69 73 20  c[0..nDoc-1] is 
116f0 70 68 72 61 73 65 20 6f 66 20 74 65 78 74 2e 20  phrase of text. 
11700 20 61 4d 61 74 63 68 5b 30 2e 2e 6e 4d 61 74 63   aMatch[0..nMatc
11710 68 2d 31 5d 20 61 72 65 20 61 20 73 65 74 0a 2a  h-1] are a set.*
11720 2a 20 6f 66 20 6d 61 74 63 68 69 6e 67 20 77 6f  * of matching wo
11730 72 64 73 20 73 6f 6d 65 20 6f 66 20 77 68 69 63  rds some of whic
11740 68 20 6d 69 67 68 74 20 62 65 20 69 6e 20 7a 44  h might be in zD
11750 6f 63 2e 20 20 7a 44 6f 63 20 69 73 20 63 6f 6c  oc.  zDoc is col
11760 75 6d 6e 0a 2a 2a 20 6e 75 6d 62 65 72 20 69 43  umn.** number iC
11770 6f 6c 2e 0a 2a 2a 0a 2a 2a 20 69 42 72 65 61 6b  ol..**.** iBreak
11780 20 69 73 20 73 75 67 67 65 73 74 65 64 20 73 70   is suggested sp
11790 6f 74 20 69 6e 20 7a 44 6f 63 20 77 68 65 72 65  ot in zDoc where
117a0 20 77 65 20 63 6f 75 6c 64 20 62 65 67 69 6e 20   we could begin 
117b0 6f 72 20 65 6e 64 20 61 6e 0a 2a 2a 20 65 78 63  or end an.** exc
117c0 65 72 70 74 2e 20 20 52 65 74 75 72 6e 20 61 20  erpt.  Return a 
117d0 76 61 6c 75 65 20 73 69 6d 69 6c 61 72 20 74 6f  value similar to
117e0 20 69 42 72 65 61 6b 20 62 75 74 20 70 6f 73 73   iBreak but poss
117f0 69 62 6c 79 20 61 64 6a 75 73 74 65 64 0a 2a 2a  ibly adjusted.**
11800 20 74 6f 20 62 65 20 61 20 6c 69 74 74 6c 65 20   to be a little 
11810 6c 65 66 74 20 6f 72 20 72 69 67 68 74 20 73 6f  left or right so
11820 20 74 68 61 74 20 74 68 65 20 62 72 65 61 6b 20   that the break 
11830 70 6f 69 6e 74 20 69 73 20 62 65 74 74 65 72 2e  point is better.
11840 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
11850 6f 72 64 42 6f 75 6e 64 61 72 79 28 0a 20 20 69  ordBoundary(.  i
11860 6e 74 20 69 42 72 65 61 6b 2c 20 20 20 20 20 20  nt iBreak,      
11870 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
11880 54 68 65 20 73 75 67 67 65 73 74 65 64 20 62 72  The suggested br
11890 65 61 6b 20 70 6f 69 6e 74 20 2a 2f 0a 20 20 63  eak point */.  c
118a0 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 6f 63 2c  onst char *zDoc,
118b0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
118c0 44 6f 63 75 6d 65 6e 74 20 74 65 78 74 20 2a 2f  Document text */
118d0 0a 20 20 69 6e 74 20 6e 44 6f 63 2c 20 20 20 20  .  int nDoc,    
118e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
118f0 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
11900 74 65 73 20 69 6e 20 7a 44 6f 63 5b 5d 20 2a 2f  tes in zDoc[] */
11910 0a 20 20 73 74 72 75 63 74 20 73 6e 69 70 70 65  .  struct snippe
11920 74 4d 61 74 63 68 20 2a 61 4d 61 74 63 68 2c 20  tMatch *aMatch, 
11930 20 2f 2a 20 4d 61 74 63 68 69 6e 67 20 77 6f 72   /* Matching wor
11940 64 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 61 74  ds */.  int nMat
11950 63 68 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ch,             
11960 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
11970 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 61 4d  of entries in aM
11980 61 74 63 68 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20  atch[] */.  int 
11990 69 43 6f 6c 20 20 20 20 20 20 20 20 20 20 20 20  iCol            
119a0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
119b0 20 63 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72 20 66   column number f
119c0 6f 72 20 7a 44 6f 63 5b 5d 20 2a 2f 0a 29 7b 0a  or zDoc[] */.){.
119d0 20 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 69    int i;.  if( i
119e0 42 72 65 61 6b 3c 3d 31 30 20 29 7b 0a 20 20 20  Break<=10 ){.   
119f0 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20   return 0;.  }. 
11a00 20 69 66 28 20 69 42 72 65 61 6b 3e 3d 6e 44 6f   if( iBreak>=nDo
11a10 63 2d 31 30 20 29 7b 0a 20 20 20 20 72 65 74 75  c-10 ){.    retu
11a20 72 6e 20 6e 44 6f 63 3b 0a 20 20 7d 0a 20 20 66  rn nDoc;.  }.  f
11a30 6f 72 28 69 3d 30 3b 20 69 3c 6e 4d 61 74 63 68  or(i=0; i<nMatch
11a40 20 26 26 20 61 4d 61 74 63 68 5b 69 5d 2e 69 43   && aMatch[i].iC
11a50 6f 6c 3c 69 43 6f 6c 3b 20 69 2b 2b 29 7b 7d 0a  ol<iCol; i++){}.
11a60 20 20 77 68 69 6c 65 28 20 69 3c 6e 4d 61 74 63    while( i<nMatc
11a70 68 20 26 26 20 61 4d 61 74 63 68 5b 69 5d 2e 69  h && aMatch[i].i
11a80 53 74 61 72 74 2b 61 4d 61 74 63 68 5b 69 5d 2e  Start+aMatch[i].
11a90 6e 42 79 74 65 3c 69 42 72 65 61 6b 20 29 7b 20  nByte<iBreak ){ 
11aa0 69 2b 2b 3b 20 7d 0a 20 20 69 66 28 20 69 3c 6e  i++; }.  if( i<n
11ab0 4d 61 74 63 68 20 29 7b 0a 20 20 20 20 69 66 28  Match ){.    if(
11ac0 20 61 4d 61 74 63 68 5b 69 5d 2e 69 53 74 61 72   aMatch[i].iStar
11ad0 74 3c 69 42 72 65 61 6b 2b 31 30 20 29 7b 0a 20  t<iBreak+10 ){. 
11ae0 20 20 20 20 20 72 65 74 75 72 6e 20 61 4d 61 74       return aMat
11af0 63 68 5b 69 5d 2e 69 53 74 61 72 74 3b 0a 20 20  ch[i].iStart;.  
11b00 20 20 7d 0a 20 20 20 20 69 66 28 20 69 3e 30 20    }.    if( i>0 
11b10 26 26 20 61 4d 61 74 63 68 5b 69 2d 31 5d 2e 69  && aMatch[i-1].i
11b20 53 74 61 72 74 2b 61 4d 61 74 63 68 5b 69 2d 31  Start+aMatch[i-1
11b30 5d 2e 6e 42 79 74 65 3e 3d 69 42 72 65 61 6b 20  ].nByte>=iBreak 
11b40 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
11b50 61 4d 61 74 63 68 5b 69 2d 31 5d 2e 69 53 74 61  aMatch[i-1].iSta
11b60 72 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  rt;.    }.  }.  
11b70 66 6f 72 28 69 3d 31 3b 20 69 3c 3d 31 30 3b 20  for(i=1; i<=10; 
11b80 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 73 61  i++){.    if( sa
11b90 66 65 5f 69 73 73 70 61 63 65 28 7a 44 6f 63 5b  fe_isspace(zDoc[
11ba0 69 42 72 65 61 6b 2d 69 5d 29 20 29 7b 0a 20 20  iBreak-i]) ){.  
11bb0 20 20 20 20 72 65 74 75 72 6e 20 69 42 72 65 61      return iBrea
11bc0 6b 20 2d 20 69 20 2b 20 31 3b 0a 20 20 20 20 7d  k - i + 1;.    }
11bd0 0a 20 20 20 20 69 66 28 20 73 61 66 65 5f 69 73  .    if( safe_is
11be0 73 70 61 63 65 28 7a 44 6f 63 5b 69 42 72 65 61  space(zDoc[iBrea
11bf0 6b 2b 69 5d 29 20 29 7b 0a 20 20 20 20 20 20 72  k+i]) ){.      r
11c00 65 74 75 72 6e 20 69 42 72 65 61 6b 20 2b 20 69  eturn iBreak + i
11c10 20 2b 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   + 1;.    }.  }.
11c20 20 20 72 65 74 75 72 6e 20 69 42 72 65 61 6b 3b    return iBreak;
11c30 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65  .}../*.** If the
11c40 20 53 74 72 69 6e 67 42 75 66 66 65 72 20 64 6f   StringBuffer do
11c50 65 73 20 6e 6f 74 20 65 6e 64 20 69 6e 20 77 68  es not end in wh
11c60 69 74 65 20 73 70 61 63 65 2c 20 61 64 64 20 61  ite space, add a
11c70 20 73 69 6e 67 6c 65 0a 2a 2a 20 73 70 61 63 65   single.** space
11c80 20 63 68 61 72 61 63 74 65 72 20 74 6f 20 74 68   character to th
11c90 65 20 65 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  e end..*/.static
11ca0 20 76 6f 69 64 20 61 70 70 65 6e 64 57 68 69 74   void appendWhit
11cb0 65 53 70 61 63 65 28 53 74 72 69 6e 67 42 75 66  eSpace(StringBuf
11cc0 66 65 72 20 2a 70 29 7b 0a 20 20 69 66 28 20 70  fer *p){.  if( p
11cd0 2d 3e 6c 65 6e 3d 3d 30 20 29 20 72 65 74 75 72  ->len==0 ) retur
11ce0 6e 3b 0a 20 20 69 66 28 20 73 61 66 65 5f 69 73  n;.  if( safe_is
11cf0 73 70 61 63 65 28 70 2d 3e 73 5b 70 2d 3e 6c 65  space(p->s[p->le
11d00 6e 2d 31 5d 29 20 29 20 72 65 74 75 72 6e 3b 0a  n-1]) ) return;.
11d10 20 20 61 70 70 65 6e 64 28 70 2c 20 22 20 22 29    append(p, " ")
11d20 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76  ;.}../*.** Remov
11d30 65 20 77 68 69 74 65 20 73 70 61 63 65 20 66 72  e white space fr
11d40 6f 6d 20 74 65 68 20 65 6e 64 20 6f 66 20 74 68  om teh end of th
11d50 65 20 53 74 72 69 6e 67 42 75 66 66 65 72 0a 2a  e StringBuffer.*
11d60 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 72  /.static void tr
11d70 69 6d 57 68 69 74 65 53 70 61 63 65 28 53 74 72  imWhiteSpace(Str
11d80 69 6e 67 42 75 66 66 65 72 20 2a 70 29 7b 0a 20  ingBuffer *p){. 
11d90 20 77 68 69 6c 65 28 20 70 2d 3e 6c 65 6e 3e 30   while( p->len>0
11da0 20 26 26 20 73 61 66 65 5f 69 73 73 70 61 63 65   && safe_isspace
11db0 28 70 2d 3e 73 5b 70 2d 3e 6c 65 6e 2d 31 5d 29  (p->s[p->len-1])
11dc0 20 29 7b 0a 20 20 20 20 70 2d 3e 6c 65 6e 2d 2d   ){.    p->len--
11dd0 3b 0a 20 20 7d 0a 7d 0a 0a 0a 0a 2f 2a 0a 2a 2a  ;.  }.}..../*.**
11de0 20 41 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73 20   Allowed values 
11df0 66 6f 72 20 53 6e 69 70 70 65 74 2e 61 4d 61 74  for Snippet.aMat
11e00 63 68 5b 5d 2e 73 6e 53 74 61 74 75 73 0a 2a 2f  ch[].snStatus.*/
11e10 0a 23 64 65 66 69 6e 65 20 53 4e 49 50 50 45 54  .#define SNIPPET
11e20 5f 49 47 4e 4f 52 45 20 20 30 20 20 20 2f 2a 20  _IGNORE  0   /* 
11e30 49 74 20 69 73 20 6f 6b 20 74 6f 20 6f 6d 69 74  It is ok to omit
11e40 20 74 68 69 73 20 6d 61 74 63 68 20 66 72 6f 6d   this match from
11e50 20 74 68 65 20 73 6e 69 70 70 65 74 20 2a 2f 0a   the snippet */.
11e60 23 64 65 66 69 6e 65 20 53 4e 49 50 50 45 54 5f  #define SNIPPET_
11e70 44 45 53 49 52 45 44 20 31 20 20 20 2f 2a 20 57  DESIRED 1   /* W
11e80 65 20 77 61 6e 74 20 74 6f 20 69 6e 63 6c 75 64  e want to includ
11e90 65 20 74 68 69 73 20 6d 61 74 63 68 20 69 6e 20  e this match in 
11ea0 74 68 65 20 73 6e 69 70 70 65 74 20 2a 2f 0a 0a  the snippet */..
11eb0 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20 74  /*.** Generate t
11ec0 68 65 20 74 65 78 74 20 6f 66 20 61 20 73 6e 69  he text of a sni
11ed0 70 70 65 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ppet..*/.static 
11ee0 76 6f 69 64 20 73 6e 69 70 70 65 74 54 65 78 74  void snippetText
11ef0 28 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72  (.  fulltext_cur
11f00 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 20 20  sor *pCursor,   
11f10 2f 2a 20 54 68 65 20 63 75 72 73 6f 72 20 77 65  /* The cursor we
11f20 20 6e 65 65 64 20 74 68 65 20 73 6e 69 70 70 65   need the snippe
11f30 74 20 66 6f 72 20 2a 2f 0a 20 20 63 6f 6e 73 74  t for */.  const
11f40 20 63 68 61 72 20 2a 7a 53 74 61 72 74 4d 61 72   char *zStartMar
11f50 6b 2c 20 20 20 20 20 2f 2a 20 4d 61 72 6b 75 70  k,     /* Markup
11f60 20 74 6f 20 61 70 70 65 61 72 20 62 65 66 6f 72   to appear befor
11f70 65 20 65 61 63 68 20 6d 61 74 63 68 20 2a 2f 0a  e each match */.
11f80 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45    const char *zE
11f90 6e 64 4d 61 72 6b 2c 20 20 20 20 20 20 20 2f 2a  ndMark,       /*
11fa0 20 4d 61 72 6b 75 70 20 74 6f 20 61 70 70 65 61   Markup to appea
11fb0 72 20 61 66 74 65 72 20 65 61 63 68 20 6d 61 74  r after each mat
11fc0 63 68 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ch */.  const ch
11fd0 61 72 20 2a 7a 45 6c 6c 69 70 73 69 73 20 20 20  ar *zEllipsis   
11fe0 20 20 20 20 2f 2a 20 45 6c 6c 69 70 73 69 73 20      /* Ellipsis 
11ff0 6d 61 72 6b 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  mark */.){.  int
12000 20 69 2c 20 6a 3b 0a 20 20 73 74 72 75 63 74 20   i, j;.  struct 
12010 73 6e 69 70 70 65 74 4d 61 74 63 68 20 2a 61 4d  snippetMatch *aM
12020 61 74 63 68 3b 0a 20 20 69 6e 74 20 6e 4d 61 74  atch;.  int nMat
12030 63 68 3b 0a 20 20 69 6e 74 20 6e 44 65 73 69 72  ch;.  int nDesir
12040 65 64 3b 0a 20 20 53 74 72 69 6e 67 42 75 66 66  ed;.  StringBuff
12050 65 72 20 73 62 3b 0a 20 20 69 6e 74 20 74 61 69  er sb;.  int tai
12060 6c 43 6f 6c 3b 0a 20 20 69 6e 74 20 74 61 69 6c  lCol;.  int tail
12070 4f 66 66 73 65 74 3b 0a 20 20 69 6e 74 20 69 43  Offset;.  int iC
12080 6f 6c 3b 0a 20 20 69 6e 74 20 6e 44 6f 63 3b 0a  ol;.  int nDoc;.
12090 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44    const char *zD
120a0 6f 63 3b 0a 20 20 69 6e 74 20 69 53 74 61 72 74  oc;.  int iStart
120b0 2c 20 69 45 6e 64 3b 0a 20 20 69 6e 74 20 74 61  , iEnd;.  int ta
120c0 69 6c 45 6c 6c 69 70 73 69 73 20 3d 20 30 3b 0a  ilEllipsis = 0;.
120d0 20 20 69 6e 74 20 69 4d 61 74 63 68 3b 0a 20 20    int iMatch;.  
120e0 0a 0a 20 20 66 72 65 65 28 70 43 75 72 73 6f 72  ..  free(pCursor
120f0 2d 3e 73 6e 69 70 70 65 74 2e 7a 53 6e 69 70 70  ->snippet.zSnipp
12100 65 74 29 3b 0a 20 20 70 43 75 72 73 6f 72 2d 3e  et);.  pCursor->
12110 73 6e 69 70 70 65 74 2e 7a 53 6e 69 70 70 65 74  snippet.zSnippet
12120 20 3d 20 30 3b 0a 20 20 61 4d 61 74 63 68 20 3d   = 0;.  aMatch =
12130 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65   pCursor->snippe
12140 74 2e 61 4d 61 74 63 68 3b 0a 20 20 6e 4d 61 74  t.aMatch;.  nMat
12150 63 68 20 3d 20 70 43 75 72 73 6f 72 2d 3e 73 6e  ch = pCursor->sn
12160 69 70 70 65 74 2e 6e 4d 61 74 63 68 3b 0a 20 20  ippet.nMatch;.  
12170 69 6e 69 74 53 74 72 69 6e 67 42 75 66 66 65 72  initStringBuffer
12180 28 26 73 62 29 3b 0a 0a 20 20 66 6f 72 28 69 3d  (&sb);..  for(i=
12190 30 3b 20 69 3c 6e 4d 61 74 63 68 3b 20 69 2b 2b  0; i<nMatch; i++
121a0 29 7b 0a 20 20 20 20 61 4d 61 74 63 68 5b 69 5d  ){.    aMatch[i]
121b0 2e 73 6e 53 74 61 74 75 73 20 3d 20 53 4e 49 50  .snStatus = SNIP
121c0 50 45 54 5f 49 47 4e 4f 52 45 3b 0a 20 20 7d 0a  PET_IGNORE;.  }.
121d0 20 20 6e 44 65 73 69 72 65 64 20 3d 20 30 3b 0a    nDesired = 0;.
121e0 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 43 75    for(i=0; i<pCu
121f0 72 73 6f 72 2d 3e 71 2e 6e 54 65 72 6d 73 3b 20  rsor->q.nTerms; 
12200 69 2b 2b 29 7b 0a 20 20 20 20 66 6f 72 28 6a 3d  i++){.    for(j=
12210 30 3b 20 6a 3c 6e 4d 61 74 63 68 3b 20 6a 2b 2b  0; j<nMatch; j++
12220 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 4d 61  ){.      if( aMa
12230 74 63 68 5b 6a 5d 2e 69 54 65 72 6d 3d 3d 69 20  tch[j].iTerm==i 
12240 29 7b 0a 20 20 20 20 20 20 20 20 61 4d 61 74 63  ){.        aMatc
12250 68 5b 6a 5d 2e 73 6e 53 74 61 74 75 73 20 3d 20  h[j].snStatus = 
12260 53 4e 49 50 50 45 54 5f 44 45 53 49 52 45 44 3b  SNIPPET_DESIRED;
12270 0a 20 20 20 20 20 20 20 20 6e 44 65 73 69 72 65  .        nDesire
12280 64 2b 2b 3b 0a 20 20 20 20 20 20 20 20 62 72 65  d++;.        bre
12290 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
122a0 7d 0a 20 20 7d 0a 0a 20 20 69 4d 61 74 63 68 20  }.  }..  iMatch 
122b0 3d 20 30 3b 0a 20 20 74 61 69 6c 43 6f 6c 20 3d  = 0;.  tailCol =
122c0 20 2d 31 3b 0a 20 20 74 61 69 6c 4f 66 66 73 65   -1;.  tailOffse
122d0 74 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30  t = 0;.  for(i=0
122e0 3b 20 69 3c 6e 4d 61 74 63 68 20 26 26 20 6e 44  ; i<nMatch && nD
122f0 65 73 69 72 65 64 3e 30 3b 20 69 2b 2b 29 7b 0a  esired>0; i++){.
12300 20 20 20 20 69 66 28 20 61 4d 61 74 63 68 5b 69      if( aMatch[i
12310 5d 2e 73 6e 53 74 61 74 75 73 21 3d 53 4e 49 50  ].snStatus!=SNIP
12320 50 45 54 5f 44 45 53 49 52 45 44 20 29 20 63 6f  PET_DESIRED ) co
12330 6e 74 69 6e 75 65 3b 0a 20 20 20 20 6e 44 65 73  ntinue;.    nDes
12340 69 72 65 64 2d 2d 3b 0a 20 20 20 20 69 43 6f 6c  ired--;.    iCol
12350 20 3d 20 61 4d 61 74 63 68 5b 69 5d 2e 69 43 6f   = aMatch[i].iCo
12360 6c 3b 0a 20 20 20 20 7a 44 6f 63 20 3d 20 28 63  l;.    zDoc = (c
12370 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74  onst char*)sqlit
12380 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70  e3_column_text(p
12390 43 75 72 73 6f 72 2d 3e 70 53 74 6d 74 2c 20 69  Cursor->pStmt, i
123a0 43 6f 6c 2b 31 29 3b 0a 20 20 20 20 6e 44 6f 63  Col+1);.    nDoc
123b0 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
123c0 6e 5f 62 79 74 65 73 28 70 43 75 72 73 6f 72 2d  n_bytes(pCursor-
123d0 3e 70 53 74 6d 74 2c 20 69 43 6f 6c 2b 31 29 3b  >pStmt, iCol+1);
123e0 0a 20 20 20 20 69 53 74 61 72 74 20 3d 20 61 4d  .    iStart = aM
123f0 61 74 63 68 5b 69 5d 2e 69 53 74 61 72 74 20 2d  atch[i].iStart -
12400 20 34 30 3b 0a 20 20 20 20 69 53 74 61 72 74 20   40;.    iStart 
12410 3d 20 77 6f 72 64 42 6f 75 6e 64 61 72 79 28 69  = wordBoundary(i
12420 53 74 61 72 74 2c 20 7a 44 6f 63 2c 20 6e 44 6f  Start, zDoc, nDo
12430 63 2c 20 61 4d 61 74 63 68 2c 20 6e 4d 61 74 63  c, aMatch, nMatc
12440 68 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20 69 66  h, iCol);.    if
12450 28 20 69 53 74 61 72 74 3c 3d 31 30 20 29 7b 0a  ( iStart<=10 ){.
12460 20 20 20 20 20 20 69 53 74 61 72 74 20 3d 20 30        iStart = 0
12470 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
12480 69 43 6f 6c 3d 3d 74 61 69 6c 43 6f 6c 20 26 26  iCol==tailCol &&
12490 20 69 53 74 61 72 74 3c 3d 74 61 69 6c 4f 66 66   iStart<=tailOff
124a0 73 65 74 2b 32 30 20 29 7b 0a 20 20 20 20 20 20  set+20 ){.      
124b0 69 53 74 61 72 74 20 3d 20 74 61 69 6c 4f 66 66  iStart = tailOff
124c0 73 65 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  set;.    }.    i
124d0 66 28 20 28 69 43 6f 6c 21 3d 74 61 69 6c 43 6f  f( (iCol!=tailCo
124e0 6c 20 26 26 20 74 61 69 6c 43 6f 6c 3e 3d 30 29  l && tailCol>=0)
124f0 20 7c 7c 20 69 53 74 61 72 74 21 3d 74 61 69 6c   || iStart!=tail
12500 4f 66 66 73 65 74 20 29 7b 0a 20 20 20 20 20 20  Offset ){.      
12510 74 72 69 6d 57 68 69 74 65 53 70 61 63 65 28 26  trimWhiteSpace(&
12520 73 62 29 3b 0a 20 20 20 20 20 20 61 70 70 65 6e  sb);.      appen
12530 64 57 68 69 74 65 53 70 61 63 65 28 26 73 62 29  dWhiteSpace(&sb)
12540 3b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 28 26  ;.      append(&
12550 73 62 2c 20 7a 45 6c 6c 69 70 73 69 73 29 3b 0a  sb, zEllipsis);.
12560 20 20 20 20 20 20 61 70 70 65 6e 64 57 68 69 74        appendWhit
12570 65 53 70 61 63 65 28 26 73 62 29 3b 0a 20 20 20  eSpace(&sb);.   
12580 20 7d 0a 20 20 20 20 69 45 6e 64 20 3d 20 61 4d   }.    iEnd = aM
12590 61 74 63 68 5b 69 5d 2e 69 53 74 61 72 74 20 2b  atch[i].iStart +
125a0 20 61 4d 61 74 63 68 5b 69 5d 2e 6e 42 79 74 65   aMatch[i].nByte
125b0 20 2b 20 34 30 3b 0a 20 20 20 20 69 45 6e 64 20   + 40;.    iEnd 
125c0 3d 20 77 6f 72 64 42 6f 75 6e 64 61 72 79 28 69  = wordBoundary(i
125d0 45 6e 64 2c 20 7a 44 6f 63 2c 20 6e 44 6f 63 2c  End, zDoc, nDoc,
125e0 20 61 4d 61 74 63 68 2c 20 6e 4d 61 74 63 68 2c   aMatch, nMatch,
125f0 20 69 43 6f 6c 29 3b 0a 20 20 20 20 69 66 28 20   iCol);.    if( 
12600 69 45 6e 64 3e 3d 6e 44 6f 63 2d 31 30 20 29 7b  iEnd>=nDoc-10 ){
12610 0a 20 20 20 20 20 20 69 45 6e 64 20 3d 20 6e 44  .      iEnd = nD
12620 6f 63 3b 0a 20 20 20 20 20 20 74 61 69 6c 45 6c  oc;.      tailEl
12630 6c 69 70 73 69 73 20 3d 20 30 3b 0a 20 20 20 20  lipsis = 0;.    
12640 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 74 61 69  }else{.      tai
12650 6c 45 6c 6c 69 70 73 69 73 20 3d 20 31 3b 0a 20  lEllipsis = 1;. 
12660 20 20 20 7d 0a 20 20 20 20 77 68 69 6c 65 28 20     }.    while( 
12670 69 4d 61 74 63 68 3c 6e 4d 61 74 63 68 20 26 26  iMatch<nMatch &&
12680 20 61 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e   aMatch[iMatch].
12690 69 43 6f 6c 3c 69 43 6f 6c 20 29 7b 20 69 4d 61  iCol<iCol ){ iMa
126a0 74 63 68 2b 2b 3b 20 7d 0a 20 20 20 20 77 68 69  tch++; }.    whi
126b0 6c 65 28 20 69 53 74 61 72 74 3c 69 45 6e 64 20  le( iStart<iEnd 
126c0 29 7b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  ){.      while( 
126d0 69 4d 61 74 63 68 3c 6e 4d 61 74 63 68 20 26 26  iMatch<nMatch &&
126e0 20 61 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e   aMatch[iMatch].
126f0 69 53 74 61 72 74 3c 69 53 74 61 72 74 0a 20 20  iStart<iStart.  
12700 20 20 20 20 20 20 20 20 20 20 20 26 26 20 61 4d             && aM
12710 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69 43 6f  atch[iMatch].iCo
12720 6c 3c 3d 69 43 6f 6c 20 29 7b 0a 20 20 20 20 20  l<=iCol ){.     
12730 20 20 20 69 4d 61 74 63 68 2b 2b 3b 0a 20 20 20     iMatch++;.   
12740 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 69     }.      if( i
12750 4d 61 74 63 68 3c 6e 4d 61 74 63 68 20 26 26 20  Match<nMatch && 
12760 61 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69  aMatch[iMatch].i
12770 53 74 61 72 74 3c 69 45 6e 64 0a 20 20 20 20 20  Start<iEnd.     
12780 20 20 20 20 20 20 20 20 26 26 20 61 4d 61 74 63          && aMatc
12790 68 5b 69 4d 61 74 63 68 5d 2e 69 43 6f 6c 3d 3d  h[iMatch].iCol==
127a0 69 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20 20 20  iCol ){.        
127b0 6e 61 70 70 65 6e 64 28 26 73 62 2c 20 26 7a 44  nappend(&sb, &zD
127c0 6f 63 5b 69 53 74 61 72 74 5d 2c 20 61 4d 61 74  oc[iStart], aMat
127d0 63 68 5b 69 4d 61 74 63 68 5d 2e 69 53 74 61 72  ch[iMatch].iStar
127e0 74 20 2d 20 69 53 74 61 72 74 29 3b 0a 20 20 20  t - iStart);.   
127f0 20 20 20 20 20 69 53 74 61 72 74 20 3d 20 61 4d       iStart = aM
12800 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69 53 74  atch[iMatch].iSt
12810 61 72 74 3b 0a 20 20 20 20 20 20 20 20 61 70 70  art;.        app
12820 65 6e 64 28 26 73 62 2c 20 7a 53 74 61 72 74 4d  end(&sb, zStartM
12830 61 72 6b 29 3b 0a 20 20 20 20 20 20 20 20 6e 61  ark);.        na
12840 70 70 65 6e 64 28 26 73 62 2c 20 26 7a 44 6f 63  ppend(&sb, &zDoc
12850 5b 69 53 74 61 72 74 5d 2c 20 61 4d 61 74 63 68  [iStart], aMatch
12860 5b 69 4d 61 74 63 68 5d 2e 6e 42 79 74 65 29 3b  [iMatch].nByte);
12870 0a 20 20 20 20 20 20 20 20 61 70 70 65 6e 64 28  .        append(
12880 26 73 62 2c 20 7a 45 6e 64 4d 61 72 6b 29 3b 0a  &sb, zEndMark);.
12890 20 20 20 20 20 20 20 20 69 53 74 61 72 74 20 2b          iStart +
128a0 3d 20 61 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d  = aMatch[iMatch]
128b0 2e 6e 42 79 74 65 3b 0a 20 20 20 20 20 20 20 20  .nByte;.        
128c0 66 6f 72 28 6a 3d 69 4d 61 74 63 68 2b 31 3b 20  for(j=iMatch+1; 
128d0 6a 3c 6e 4d 61 74 63 68 3b 20 6a 2b 2b 29 7b 0a  j<nMatch; j++){.
128e0 20 20 20 20 20 20 20 20 20 20 69 66 28 20 61 4d            if( aM
128f0 61 74 63 68 5b 6a 5d 2e 69 54 65 72 6d 3d 3d 61  atch[j].iTerm==a
12900 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69 54  Match[iMatch].iT
12910 65 72 6d 0a 20 20 20 20 20 20 20 20 20 20 20 20  erm.            
12920 20 20 26 26 20 61 4d 61 74 63 68 5b 6a 5d 2e 73    && aMatch[j].s
12930 6e 53 74 61 74 75 73 3d 3d 53 4e 49 50 50 45 54  nStatus==SNIPPET
12940 5f 44 45 53 49 52 45 44 20 29 7b 0a 20 20 20 20  _DESIRED ){.    
12950 20 20 20 20 20 20 20 20 6e 44 65 73 69 72 65 64          nDesired
12960 2d 2d 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  --;.            
12970 61 4d 61 74 63 68 5b 6a 5d 2e 73 6e 53 74 61 74  aMatch[j].snStat
12980 75 73 20 3d 20 53 4e 49 50 50 45 54 5f 49 47 4e  us = SNIPPET_IGN
12990 4f 52 45 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  ORE;.          }
129a0 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
129b0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
129c0 6e 61 70 70 65 6e 64 28 26 73 62 2c 20 26 7a 44  nappend(&sb, &zD
129d0 6f 63 5b 69 53 74 61 72 74 5d 2c 20 69 45 6e 64  oc[iStart], iEnd
129e0 20 2d 20 69 53 74 61 72 74 29 3b 0a 20 20 20 20   - iStart);.    
129f0 20 20 20 20 69 53 74 61 72 74 20 3d 20 69 45 6e      iStart = iEn
12a00 64 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  d;.      }.    }
12a10 0a 20 20 20 20 74 61 69 6c 43 6f 6c 20 3d 20 69  .    tailCol = i
12a20 43 6f 6c 3b 0a 20 20 20 20 74 61 69 6c 4f 66 66  Col;.    tailOff
12a30 73 65 74 20 3d 20 69 45 6e 64 3b 0a 20 20 7d 0a  set = iEnd;.  }.
12a40 20 20 74 72 69 6d 57 68 69 74 65 53 70 61 63 65    trimWhiteSpace
12a50 28 26 73 62 29 3b 0a 20 20 69 66 28 20 74 61 69  (&sb);.  if( tai
12a60 6c 45 6c 6c 69 70 73 69 73 20 29 7b 0a 20 20 20  lEllipsis ){.   
12a70 20 61 70 70 65 6e 64 57 68 69 74 65 53 70 61 63   appendWhiteSpac
12a80 65 28 26 73 62 29 3b 0a 20 20 20 20 61 70 70 65  e(&sb);.    appe
12a90 6e 64 28 26 73 62 2c 20 7a 45 6c 6c 69 70 73 69  nd(&sb, zEllipsi
12aa0 73 29 3b 0a 20 20 7d 0a 20 20 70 43 75 72 73 6f  s);.  }.  pCurso
12ab0 72 2d 3e 73 6e 69 70 70 65 74 2e 7a 53 6e 69 70  r->snippet.zSnip
12ac0 70 65 74 20 3d 20 73 62 2e 73 3b 0a 20 20 70 43  pet = sb.s;.  pC
12ad0 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74 2e 6e  ursor->snippet.n
12ae0 53 6e 69 70 70 65 74 20 3d 20 73 62 2e 6c 65 6e  Snippet = sb.len
12af0 3b 20 20 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6c  ;  .}.../*.** Cl
12b00 6f 73 65 20 74 68 65 20 63 75 72 73 6f 72 2e 20  ose the cursor. 
12b10 20 46 6f 72 20 61 64 64 69 74 69 6f 6e 61 6c 20   For additional 
12b20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 73 65 65 20  information see 
12b30 74 68 65 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f  the documentatio
12b40 6e 0a 2a 2a 20 6f 6e 20 74 68 65 20 78 43 6c 6f  n.** on the xClo
12b50 73 65 20 6d 65 74 68 6f 64 20 6f 66 20 74 68 65  se method of the
12b60 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 69   virtual table i
12b70 6e 74 65 72 66 61 63 65 2e 0a 2a 2f 0a 73 74 61  nterface..*/.sta
12b80 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74  tic int fulltext
12b90 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 76 74  Close(sqlite3_vt
12ba0 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73  ab_cursor *pCurs
12bb0 6f 72 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f  or){.  fulltext_
12bc0 63 75 72 73 6f 72 20 2a 63 20 3d 20 28 66 75 6c  cursor *c = (ful
12bd0 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 29 20  ltext_cursor *) 
12be0 70 43 75 72 73 6f 72 3b 0a 20 20 54 52 41 43 45  pCursor;.  TRACE
12bf0 28 28 22 46 54 53 31 20 43 6c 6f 73 65 20 25 70  (("FTS1 Close %p
12c00 5c 6e 22 2c 20 63 29 29 3b 0a 20 20 73 71 6c 69  \n", c));.  sqli
12c10 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 63 2d 3e  te3_finalize(c->
12c20 70 53 74 6d 74 29 3b 0a 20 20 71 75 65 72 79 43  pStmt);.  queryC
12c30 6c 65 61 72 28 26 63 2d 3e 71 29 3b 0a 20 20 73  lear(&c->q);.  s
12c40 6e 69 70 70 65 74 43 6c 65 61 72 28 26 63 2d 3e  nippetClear(&c->
12c50 73 6e 69 70 70 65 74 29 3b 0a 20 20 69 66 28 20  snippet);.  if( 
12c60 63 2d 3e 72 65 73 75 6c 74 2e 70 44 6f 63 6c 69  c->result.pDocli
12c70 73 74 21 3d 4e 55 4c 4c 20 29 7b 0a 20 20 20 20  st!=NULL ){.    
12c80 64 6f 63 4c 69 73 74 44 65 6c 65 74 65 28 63 2d  docListDelete(c-
12c90 3e 72 65 73 75 6c 74 2e 70 44 6f 63 6c 69 73 74  >result.pDoclist
12ca0 29 3b 0a 20 20 7d 0a 20 20 66 72 65 65 28 63 29  );.  }.  free(c)
12cb0 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
12cc0 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  E_OK;.}..static 
12cd0 69 6e 74 20 66 75 6c 6c 74 65 78 74 4e 65 78 74  int fulltextNext
12ce0 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
12cf0 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a  rsor *pCursor){.
12d00 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f    fulltext_curso
12d10 72 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78 74  r *c = (fulltext
12d20 5f 63 75 72 73 6f 72 20 2a 29 20 70 43 75 72 73  _cursor *) pCurs
12d30 6f 72 3b 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74  or;.  sqlite_int
12d40 36 34 20 69 44 6f 63 69 64 3b 0a 20 20 69 6e 74  64 iDocid;.  int
12d50 20 72 63 3b 0a 0a 20 20 54 52 41 43 45 28 28 22   rc;..  TRACE(("
12d60 46 54 53 31 20 4e 65 78 74 20 25 70 5c 6e 22 2c  FTS1 Next %p\n",
12d70 20 70 43 75 72 73 6f 72 29 29 3b 0a 20 20 73 6e   pCursor));.  sn
12d80 69 70 70 65 74 43 6c 65 61 72 28 26 63 2d 3e 73  ippetClear(&c->s
12d90 6e 69 70 70 65 74 29 3b 0a 20 20 69 66 28 20 63  nippet);.  if( c
12da0 2d 3e 69 43 75 72 73 6f 72 54 79 70 65 20 3c 20  ->iCursorType < 
12db0 51 55 45 52 59 5f 46 55 4c 4c 54 45 58 54 20 29  QUERY_FULLTEXT )
12dc0 7b 0a 20 20 20 20 2f 2a 20 54 4f 44 4f 28 73 68  {.    /* TODO(sh
12dd0 65 73 73 29 20 48 61 6e 64 6c 65 20 53 51 4c 49  ess) Handle SQLI
12de0 54 45 5f 53 43 48 45 4d 41 20 41 4e 44 20 53 51  TE_SCHEMA AND SQ
12df0 4c 49 54 45 5f 42 55 53 59 2e 20 2a 2f 0a 20 20  LITE_BUSY. */.  
12e00 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73    rc = sqlite3_s
12e10 74 65 70 28 63 2d 3e 70 53 74 6d 74 29 3b 0a 20  tep(c->pStmt);. 
12e20 20 20 20 73 77 69 74 63 68 28 20 72 63 20 29 7b     switch( rc ){
12e30 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
12e40 54 45 5f 52 4f 57 3a 0a 20 20 20 20 20 20 20 20  TE_ROW:.        
12e50 63 2d 3e 65 6f 66 20 3d 20 30 3b 0a 20 20 20 20  c->eof = 0;.    
12e60 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
12e70 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 63 61 73 65  E_OK;.      case
12e80 20 53 51 4c 49 54 45 5f 44 4f 4e 45 3a 0a 20 20   SQLITE_DONE:.  
12e90 20 20 20 20 20 20 63 2d 3e 65 6f 66 20 3d 20 31        c->eof = 1
12ea0 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
12eb0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20   SQLITE_OK;.    
12ec0 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20    default:.     
12ed0 20 20 20 63 2d 3e 65 6f 66 20 3d 20 31 3b 0a 20     c->eof = 1;. 
12ee0 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63         return rc
12ef0 3b 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65  ;.    }.  } else
12f00 20 7b 20 20 2f 2a 20 66 75 6c 6c 2d 74 65 78 74   {  /* full-text
12f10 20 71 75 65 72 79 20 2a 2f 0a 20 20 20 20 72 63   query */.    rc
12f20 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74   = sqlite3_reset
12f30 28 63 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20  (c->pStmt);.    
12f40 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
12f50 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
12f60 20 20 20 20 69 44 6f 63 69 64 20 3d 20 6e 65 78      iDocid = nex
12f70 74 44 6f 63 69 64 28 26 63 2d 3e 72 65 73 75 6c  tDocid(&c->resul
12f80 74 29 3b 0a 20 20 20 20 69 66 28 20 69 44 6f 63  t);.    if( iDoc
12f90 69 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63  id==0 ){.      c
12fa0 2d 3e 65 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20  ->eof = 1;.     
12fb0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
12fc0 4b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63 20  K;.    }.    rc 
12fd0 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69  = sqlite3_bind_i
12fe0 6e 74 36 34 28 63 2d 3e 70 53 74 6d 74 2c 20 31  nt64(c->pStmt, 1
12ff0 2c 20 69 44 6f 63 69 64 29 3b 0a 20 20 20 20 69  , iDocid);.    i
13000 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
13010 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
13020 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29    /* TODO(shess)
13030 20 48 61 6e 64 6c 65 20 53 51 4c 49 54 45 5f 53   Handle SQLITE_S
13040 43 48 45 4d 41 20 41 4e 44 20 53 51 4c 49 54 45  CHEMA AND SQLITE
13050 5f 42 55 53 59 2e 20 2a 2f 0a 20 20 20 20 72 63  _BUSY. */.    rc
13060 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28   = sqlite3_step(
13070 63 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 69  c->pStmt);.    i
13080 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52 4f  f( rc==SQLITE_RO
13090 57 20 29 7b 20 20 20 2f 2a 20 74 68 65 20 63 61  W ){   /* the ca
130a0 73 65 20 77 65 20 65 78 70 65 63 74 20 2a 2f 0a  se we expect */.
130b0 20 20 20 20 20 20 63 2d 3e 65 6f 66 20 3d 20 30        c->eof = 0
130c0 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  ;.      return S
130d0 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a  QLITE_OK;.    }.
130e0 20 20 20 20 2f 2a 20 61 6e 20 65 72 72 6f 72 20      /* an error 
130f0 6f 63 63 75 72 72 65 64 3b 20 61 62 6f 72 74 20  occurred; abort 
13100 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  */.    return rc
13110 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 3f 20  ==SQLITE_DONE ? 
13120 53 51 4c 49 54 45 5f 45 52 52 4f 52 20 3a 20 72  SQLITE_ERROR : r
13130 63 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 20 52 65  c;.  }.}.../* Re
13140 74 75 72 6e 20 61 20 44 6f 63 4c 69 73 74 20 63  turn a DocList c
13150 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20  orresponding to 
13160 74 68 65 20 71 75 65 72 79 20 74 65 72 6d 20 2a  the query term *
13170 70 54 65 72 6d 2e 20 20 49 66 20 2a 70 54 65 72  pTerm.  If *pTer
13180 6d 0a 2a 2a 20 69 73 20 74 68 65 20 66 69 72 73  m.** is the firs
13190 74 20 74 65 72 6d 20 6f 66 20 61 20 70 68 72 61  t term of a phra
131a0 73 65 20 71 75 65 72 79 2c 20 67 6f 20 61 68 65  se query, go ahe
131b0 61 64 20 61 6e 64 20 65 76 61 6c 75 61 74 65 20  ad and evaluate 
131c0 74 68 65 20 70 68 72 61 73 65 0a 2a 2a 20 71 75  the phrase.** qu
131d0 65 72 79 20 61 6e 64 20 72 65 74 75 72 6e 20 74  ery and return t
131e0 68 65 20 64 6f 63 6c 69 73 74 20 66 6f 72 20 74  he doclist for t
131f0 68 65 20 65 6e 74 69 72 65 20 70 68 72 61 73 65  he entire phrase
13200 20 71 75 65 72 79 2e 0a 2a 2a 0a 2a 2a 20 54 68   query..**.** Th
13210 65 20 72 65 73 75 6c 74 20 69 73 20 73 74 6f 72  e result is stor
13220 65 64 20 69 6e 20 70 54 65 72 6d 2d 3e 64 6f 63  ed in pTerm->doc
13230 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  list..*/.static 
13240 69 6e 74 20 64 6f 63 4c 69 73 74 4f 66 54 65 72  int docListOfTer
13250 6d 28 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76 74  m(.  fulltext_vt
13260 61 62 20 2a 76 2c 20 20 20 20 20 2f 2a 20 54 68  ab *v,     /* Th
13270 65 20 66 75 6c 6c 20 74 65 78 74 20 69 6e 64 65  e full text inde
13280 78 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 75  x */.  int iColu
13290 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  mn,          /* 
132a0 63 6f 6c 75 6d 6e 20 74 6f 20 72 65 73 74 72 69  column to restri
132b0 63 74 20 74 6f 2e 20 20 4e 6f 20 72 65 73 74 72  ct to.  No restr
132c0 69 74 69 6f 6e 20 69 66 20 3e 3d 6e 43 6f 6c 75  ition if >=nColu
132d0 6d 6e 20 2a 2f 0a 20 20 51 75 65 72 79 54 65 72  mn */.  QueryTer
132e0 6d 20 2a 70 51 54 65 72 6d 2c 20 20 20 20 2f 2a  m *pQTerm,    /*
132f0 20 54 65 72 6d 20 77 65 20 61 72 65 20 6c 6f 6f   Term we are loo
13300 6b 69 6e 67 20 66 6f 72 2c 20 6f 72 20 31 73 74  king for, or 1st
13310 20 74 65 72 6d 20 6f 66 20 61 20 70 68 72 61 73   term of a phras
13320 65 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20 2a  e */.  DocList *
13330 2a 70 70 52 65 73 75 6c 74 20 20 20 20 2f 2a 20  *ppResult    /* 
13340 57 72 69 74 65 20 74 68 65 20 72 65 73 75 6c 74  Write the result
13350 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 44 6f   here */.){.  Do
13360 63 4c 69 73 74 20 2a 70 4c 65 66 74 2c 20 2a 70  cList *pLeft, *p
13370 52 69 67 68 74 2c 20 2a 70 4e 65 77 3b 0a 20 20  Right, *pNew;.  
13380 69 6e 74 20 69 2c 20 72 63 3b 0a 0a 20 20 70 4c  int i, rc;..  pL
13390 65 66 74 20 3d 20 64 6f 63 4c 69 73 74 4e 65 77  eft = docListNew
133a0 28 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 29 3b 0a  (DL_POSITIONS);.
133b0 20 20 72 63 20 3d 20 74 65 72 6d 5f 73 65 6c 65    rc = term_sele
133c0 63 74 5f 61 6c 6c 28 76 2c 20 69 43 6f 6c 75 6d  ct_all(v, iColum
133d0 6e 2c 20 70 51 54 65 72 6d 2d 3e 70 54 65 72 6d  n, pQTerm->pTerm
133e0 2c 20 70 51 54 65 72 6d 2d 3e 6e 54 65 72 6d 2c  , pQTerm->nTerm,
133f0 20 70 4c 65 66 74 29 3b 0a 20 20 69 66 28 20 72   pLeft);.  if( r
13400 63 20 29 7b 0a 20 20 20 20 64 6f 63 4c 69 73 74  c ){.    docList
13410 44 65 6c 65 74 65 28 70 4c 65 66 74 29 3b 0a 20  Delete(pLeft);. 
13420 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
13430 7d 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 3d  }.  for(i=1; i<=
13440 70 51 54 65 72 6d 2d 3e 6e 50 68 72 61 73 65 3b  pQTerm->nPhrase;
13450 20 69 2b 2b 29 7b 0a 20 20 20 20 70 52 69 67 68   i++){.    pRigh
13460 74 20 3d 20 64 6f 63 4c 69 73 74 4e 65 77 28 44  t = docListNew(D
13470 4c 5f 50 4f 53 49 54 49 4f 4e 53 29 3b 0a 20 20  L_POSITIONS);.  
13480 20 20 72 63 20 3d 20 74 65 72 6d 5f 73 65 6c 65    rc = term_sele
13490 63 74 5f 61 6c 6c 28 76 2c 20 69 43 6f 6c 75 6d  ct_all(v, iColum
134a0 6e 2c 20 70 51 54 65 72 6d 5b 69 5d 2e 70 54 65  n, pQTerm[i].pTe
134b0 72 6d 2c 20 70 51 54 65 72 6d 5b 69 5d 2e 6e 54  rm, pQTerm[i].nT
134c0 65 72 6d 2c 20 70 52 69 67 68 74 29 3b 0a 20 20  erm, pRight);.  
134d0 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20    if( rc ){.    
134e0 20 20 64 6f 63 4c 69 73 74 44 65 6c 65 74 65 28    docListDelete(
134f0 70 4c 65 66 74 29 3b 0a 20 20 20 20 20 20 72 65  pLeft);.      re
13500 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20  turn rc;.    }. 
13510 20 20 20 70 4e 65 77 20 3d 20 64 6f 63 4c 69 73     pNew = docLis
13520 74 4e 65 77 28 69 3c 70 51 54 65 72 6d 2d 3e 6e  tNew(i<pQTerm->n
13530 50 68 72 61 73 65 20 3f 20 44 4c 5f 50 4f 53 49  Phrase ? DL_POSI
13540 54 49 4f 4e 53 20 3a 20 44 4c 5f 44 4f 43 49 44  TIONS : DL_DOCID
13550 53 29 3b 0a 20 20 20 20 64 6f 63 4c 69 73 74 50  S);.    docListP
13560 68 72 61 73 65 4d 65 72 67 65 28 70 4c 65 66 74  hraseMerge(pLeft
13570 2c 20 70 52 69 67 68 74 2c 20 70 4e 65 77 29 3b  , pRight, pNew);
13580 0a 20 20 20 20 64 6f 63 4c 69 73 74 44 65 6c 65  .    docListDele
13590 74 65 28 70 4c 65 66 74 29 3b 0a 20 20 20 20 64  te(pLeft);.    d
135a0 6f 63 4c 69 73 74 44 65 6c 65 74 65 28 70 52 69  ocListDelete(pRi
135b0 67 68 74 29 3b 0a 20 20 20 20 70 4c 65 66 74 20  ght);.    pLeft 
135c0 3d 20 70 4e 65 77 3b 0a 20 20 7d 0a 20 20 2a 70  = pNew;.  }.  *p
135d0 70 52 65 73 75 6c 74 20 3d 20 70 4c 65 66 74 3b  pResult = pLeft;
135e0 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
135f0 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 41 64 64 20 61  _OK;.}../* Add a
13600 20 6e 65 77 20 74 65 72 6d 20 70 54 65 72 6d 5b   new term pTerm[
13610 30 2e 2e 6e 54 65 72 6d 2d 31 5d 20 74 6f 20 74  0..nTerm-1] to t
13620 68 65 20 71 75 65 72 79 20 2a 71 2e 0a 2a 2f 0a  he query *q..*/.
13630 73 74 61 74 69 63 20 76 6f 69 64 20 71 75 65 72  static void quer
13640 79 41 64 64 28 51 75 65 72 79 20 2a 71 2c 20 63  yAdd(Query *q, c
13650 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65 72 6d  onst char *pTerm
13660 2c 20 69 6e 74 20 6e 54 65 72 6d 29 7b 0a 20 20  , int nTerm){.  
13670 51 75 65 72 79 54 65 72 6d 20 2a 74 3b 0a 20 20  QueryTerm *t;.  
13680 2b 2b 71 2d 3e 6e 54 65 72 6d 73 3b 0a 20 20 71  ++q->nTerms;.  q
13690 2d 3e 70 54 65 72 6d 73 20 3d 20 72 65 61 6c 6c  ->pTerms = reall
136a0 6f 63 28 71 2d 3e 70 54 65 72 6d 73 2c 20 71 2d  oc(q->pTerms, q-
136b0 3e 6e 54 65 72 6d 73 20 2a 20 73 69 7a 65 6f 66  >nTerms * sizeof
136c0 28 71 2d 3e 70 54 65 72 6d 73 5b 30 5d 29 29 3b  (q->pTerms[0]));
136d0 0a 20 20 69 66 28 20 71 2d 3e 70 54 65 72 6d 73  .  if( q->pTerms
136e0 3d 3d 30 20 29 7b 0a 20 20 20 20 71 2d 3e 6e 54  ==0 ){.    q->nT
136f0 65 72 6d 73 20 3d 20 30 3b 0a 20 20 20 20 72 65  erms = 0;.    re
13700 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 74 20 3d 20  turn;.  }.  t = 
13710 26 71 2d 3e 70 54 65 72 6d 73 5b 71 2d 3e 6e 54  &q->pTerms[q->nT
13720 65 72 6d 73 20 2d 20 31 5d 3b 0a 20 20 6d 65 6d  erms - 1];.  mem
13730 73 65 74 28 74 2c 20 30 2c 20 73 69 7a 65 6f 66  set(t, 0, sizeof
13740 28 2a 74 29 29 3b 0a 20 20 74 2d 3e 70 54 65 72  (*t));.  t->pTer
13750 6d 20 3d 20 6d 61 6c 6c 6f 63 28 6e 54 65 72 6d  m = malloc(nTerm
13760 2b 31 29 3b 0a 20 20 6d 65 6d 63 70 79 28 74 2d  +1);.  memcpy(t-
13770 3e 70 54 65 72 6d 2c 20 70 54 65 72 6d 2c 20 6e  >pTerm, pTerm, n
13780 54 65 72 6d 29 3b 0a 20 20 74 2d 3e 70 54 65 72  Term);.  t->pTer
13790 6d 5b 6e 54 65 72 6d 5d 20 3d 20 30 3b 0a 20 20  m[nTerm] = 0;.  
137a0 74 2d 3e 6e 54 65 72 6d 20 3d 20 6e 54 65 72 6d  t->nTerm = nTerm
137b0 3b 0a 20 20 74 2d 3e 69 73 4f 72 20 3d 20 71 2d  ;.  t->isOr = q-
137c0 3e 6e 65 78 74 49 73 4f 72 3b 0a 20 20 71 2d 3e  >nextIsOr;.  q->
137d0 6e 65 78 74 49 73 4f 72 20 3d 20 30 3b 0a 20 20  nextIsOr = 0;.  
137e0 74 2d 3e 69 43 6f 6c 75 6d 6e 20 3d 20 71 2d 3e  t->iColumn = q->
137f0 6e 65 78 74 43 6f 6c 75 6d 6e 3b 0a 20 20 71 2d  nextColumn;.  q-
13800 3e 6e 65 78 74 43 6f 6c 75 6d 6e 20 3d 20 71 2d  >nextColumn = q-
13810 3e 64 66 6c 74 43 6f 6c 75 6d 6e 3b 0a 7d 0a 0a  >dfltColumn;.}..
13820 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 6f 20 73  /*.** Check to s
13830 65 65 20 69 66 20 74 68 65 20 73 74 72 69 6e 67  ee if the string
13840 20 7a 54 6f 6b 65 6e 5b 30 2e 2e 2e 6e 54 6f 6b   zToken[0...nTok
13850 65 6e 2d 31 5d 20 6d 61 74 63 68 65 73 20 61 6e  en-1] matches an
13860 79 0a 2a 2a 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65  y.** column name
13870 20 69 6e 20 74 68 65 20 76 69 72 74 75 61 6c 20   in the virtual 
13880 74 61 62 6c 65 2e 20 20 20 49 66 20 69 74 20 64  table.   If it d
13890 6f 65 73 2c 0a 2a 2a 20 72 65 74 75 72 6e 20 74  oes,.** return t
138a0 68 65 20 7a 65 72 6f 2d 69 6e 64 65 78 65 64 20  he zero-indexed 
138b0 63 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72 2e 20 20  column number.  
138c0 49 66 20 6e 6f 74 2c 20 72 65 74 75 72 6e 20 2d  If not, return -
138d0 31 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  1..*/.static int
138e0 20 63 68 65 63 6b 43 6f 6c 75 6d 6e 53 70 65 63   checkColumnSpec
138f0 69 66 69 65 72 28 0a 20 20 66 75 6c 6c 74 65 78  ifier(.  fulltex
13900 74 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20 20  t_vtab *pVtab,  
13910 20 20 2f 2a 20 54 68 65 20 76 69 72 74 75 61 6c    /* The virtual
13920 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73   table */.  cons
13930 74 20 63 68 61 72 20 2a 7a 54 6f 6b 65 6e 2c 20  t char *zToken, 
13940 20 20 20 20 20 2f 2a 20 54 65 78 74 20 6f 66 20       /* Text of 
13950 74 68 65 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69  the token */.  i
13960 6e 74 20 6e 54 6f 6b 65 6e 20 20 20 20 20 20 20  nt nToken       
13970 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
13980 72 20 6f 66 20 63 68 61 72 61 63 74 65 72 73 20  r of characters 
13990 69 6e 20 74 68 65 20 74 6f 6b 65 6e 20 2a 2f 0a  in the token */.
139a0 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f  ){.  int i;.  fo
139b0 72 28 69 3d 30 3b 20 69 3c 70 56 74 61 62 2d 3e  r(i=0; i<pVtab->
139c0 6e 43 6f 6c 75 6d 6e 3b 20 69 2b 2b 29 7b 0a 20  nColumn; i++){. 
139d0 20 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 70 56     if( memcmp(pV
139e0 74 61 62 2d 3e 61 7a 43 6f 6c 75 6d 6e 5b 69 5d  tab->azColumn[i]
139f0 2c 20 7a 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e  , zToken, nToken
13a00 29 3d 3d 30 0a 20 20 20 20 20 20 20 20 26 26 20  )==0.        && 
13a10 70 56 74 61 62 2d 3e 61 7a 43 6f 6c 75 6d 6e 5b  pVtab->azColumn[
13a20 69 5d 5b 6e 54 6f 6b 65 6e 5d 3d 3d 30 20 29 7b  i][nToken]==0 ){
13a30 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 69 3b  .      return i;
13a40 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
13a50 75 72 6e 20 2d 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn -1;.}../*.**
13a60 20 50 61 72 73 65 20 74 68 65 20 74 65 78 74 20   Parse the text 
13a70 61 74 20 70 53 65 67 6d 65 6e 74 5b 30 2e 2e 6e  at pSegment[0..n
13a80 53 65 67 6d 65 6e 74 2d 31 5d 2e 20 20 41 64 64  Segment-1].  Add
13a90 20 61 64 64 69 74 69 6f 6e 61 6c 20 74 65 72 6d   additional term
13aa0 73 0a 2a 2a 20 74 6f 20 74 68 65 20 71 75 65 72  s.** to the quer
13ab0 79 20 62 65 69 6e 67 20 61 73 73 65 6d 62 6c 69  y being assembli
13ac0 65 64 20 69 6e 20 70 51 75 65 72 79 2e 0a 2a 2a  ed in pQuery..**
13ad0 0a 2a 2a 20 69 6e 50 68 72 61 73 65 20 69 73 20  .** inPhrase is 
13ae0 74 72 75 65 20 69 66 20 70 53 65 67 6d 65 6e 74  true if pSegment
13af0 5b 30 2e 2e 6e 53 65 67 65 6d 65 6e 74 2d 31 5d  [0..nSegement-1]
13b00 20 69 73 20 63 6f 6e 74 61 69 6e 65 64 20 77 69   is contained wi
13b10 74 68 69 6e 0a 2a 2a 20 64 6f 75 62 6c 65 2d 71  thin.** double-q
13b20 75 6f 74 65 73 2e 20 20 49 66 20 69 6e 50 68 72  uotes.  If inPhr
13b30 61 73 65 20 69 73 20 74 72 75 65 2c 20 74 68 65  ase is true, the
13b40 6e 20 74 68 65 20 66 69 72 73 74 20 74 65 72 6d  n the first term
13b50 0a 2a 2a 20 69 73 20 6d 61 72 6b 65 64 20 77 69  .** is marked wi
13b60 74 68 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  th the number of
13b70 20 74 65 72 6d 73 20 69 6e 20 74 68 65 20 70 68   terms in the ph
13b80 72 61 73 65 20 6c 65 73 73 20 6f 6e 65 20 61 6e  rase less one an
13b90 64 0a 2a 2a 20 4f 52 20 61 6e 64 20 22 2d 22 20  d.** OR and "-" 
13ba0 73 79 6e 74 61 78 20 69 73 20 69 67 6e 6f 72 65  syntax is ignore
13bb0 64 2e 20 20 49 66 20 69 6e 50 68 72 61 73 65 20  d.  If inPhrase 
13bc0 69 73 20 66 61 6c 73 65 2c 20 74 68 65 6e 20 65  is false, then e
13bd0 76 65 72 79 0a 2a 2a 20 74 65 72 6d 20 66 6f 75  very.** term fou
13be0 6e 64 20 69 73 20 6d 61 72 6b 65 64 20 77 69 74  nd is marked wit
13bf0 68 20 6e 50 68 72 61 73 65 3d 30 20 61 6e 64 20  h nPhrase=0 and 
13c00 4f 52 20 61 6e 64 20 22 2d 22 20 73 79 6e 74 61  OR and "-" synta
13c10 78 20 69 73 20 73 69 67 6e 69 66 69 63 61 6e 74  x is significant
13c20 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
13c30 74 6f 6b 65 6e 69 7a 65 53 65 67 6d 65 6e 74 28  tokenizeSegment(
13c40 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  .  sqlite3_token
13c50 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72  izer *pTokenizer
13c60 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68  ,          /* Th
13c70 65 20 74 6f 6b 65 6e 69 7a 65 72 20 74 6f 20 75  e tokenizer to u
13c80 73 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  se */.  const ch
13c90 61 72 20 2a 70 53 65 67 6d 65 6e 74 2c 20 69 6e  ar *pSegment, in
13ca0 74 20 6e 53 65 67 6d 65 6e 74 2c 20 20 20 20 20  t nSegment,     
13cb0 2f 2a 20 51 75 65 72 79 20 65 78 70 72 65 73 73  /* Query express
13cc0 69 6f 6e 20 62 65 69 6e 67 20 70 61 72 73 65 64  ion being parsed
13cd0 20 2a 2f 0a 20 20 69 6e 74 20 69 6e 50 68 72 61   */.  int inPhra
13ce0 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  se,             
13cf0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
13d00 20 54 72 75 65 20 69 66 20 77 69 74 68 69 6e 20   True if within 
13d10 22 2e 2e 2e 22 20 2a 2f 0a 20 20 51 75 65 72 79  "..." */.  Query
13d20 20 2a 70 51 75 65 72 79 20 20 20 20 20 20 20 20   *pQuery        
13d30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13d40 20 20 20 2f 2a 20 41 70 70 65 6e 64 20 72 65 73     /* Append res
13d50 75 6c 74 73 20 68 65 72 65 20 2a 2f 0a 29 7b 0a  ults here */.){.
13d60 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f    const sqlite3_
13d70 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65  tokenizer_module
13d80 20 2a 70 4d 6f 64 75 6c 65 20 3d 20 70 54 6f 6b   *pModule = pTok
13d90 65 6e 69 7a 65 72 2d 3e 70 4d 6f 64 75 6c 65 3b  enizer->pModule;
13da0 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  .  sqlite3_token
13db0 69 7a 65 72 5f 63 75 72 73 6f 72 20 2a 70 43 75  izer_cursor *pCu
13dc0 72 73 6f 72 3b 0a 20 20 69 6e 74 20 66 69 72 73  rsor;.  int firs
13dd0 74 49 6e 64 65 78 20 3d 20 70 51 75 65 72 79 2d  tIndex = pQuery-
13de0 3e 6e 54 65 72 6d 73 3b 0a 20 20 69 6e 74 20 69  >nTerms;.  int i
13df0 43 6f 6c 3b 0a 20 20 69 6e 74 20 6e 54 65 72 6d  Col;.  int nTerm
13e00 20 3d 20 31 3b 0a 20 20 0a 20 20 69 6e 74 20 72   = 1;.  .  int r
13e10 63 20 3d 20 70 4d 6f 64 75 6c 65 2d 3e 78 4f 70  c = pModule->xOp
13e20 65 6e 28 70 54 6f 6b 65 6e 69 7a 65 72 2c 20 70  en(pTokenizer, p
13e30 53 65 67 6d 65 6e 74 2c 20 6e 53 65 67 6d 65 6e  Segment, nSegmen
13e40 74 2c 20 26 70 43 75 72 73 6f 72 29 3b 0a 20 20  t, &pCursor);.  
13e50 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
13e60 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
13e70 20 70 43 75 72 73 6f 72 2d 3e 70 54 6f 6b 65 6e   pCursor->pToken
13e80 69 7a 65 72 20 3d 20 70 54 6f 6b 65 6e 69 7a 65  izer = pTokenize
13e90 72 3b 0a 0a 20 20 77 68 69 6c 65 28 20 31 20 29  r;..  while( 1 )
13ea0 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  {.    const char
13eb0 20 2a 70 54 6f 6b 65 6e 3b 0a 20 20 20 20 69 6e   *pToken;.    in
13ec0 74 20 6e 54 6f 6b 65 6e 2c 20 69 42 65 67 69 6e  t nToken, iBegin
13ed0 2c 20 69 45 6e 64 2c 20 69 50 6f 73 3b 0a 0a 20  , iEnd, iPos;.. 
13ee0 20 20 20 72 63 20 3d 20 70 4d 6f 64 75 6c 65 2d     rc = pModule-
13ef0 3e 78 4e 65 78 74 28 70 43 75 72 73 6f 72 2c 0a  >xNext(pCursor,.
13f00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13f10 20 20 20 20 20 20 20 20 26 70 54 6f 6b 65 6e 2c          &pToken,
13f20 20 26 6e 54 6f 6b 65 6e 2c 0a 20 20 20 20 20 20   &nToken,.      
13f30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13f40 20 20 26 69 42 65 67 69 6e 2c 20 26 69 45 6e 64    &iBegin, &iEnd
13f50 2c 20 26 69 50 6f 73 29 3b 0a 20 20 20 20 69 66  , &iPos);.    if
13f60 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
13f70 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 69 66 28  ) break;.    if(
13f80 20 21 69 6e 50 68 72 61 73 65 20 26 26 0a 20 20   !inPhrase &&.  
13f90 20 20 20 20 20 20 70 53 65 67 6d 65 6e 74 5b 69        pSegment[i
13fa0 45 6e 64 5d 3d 3d 27 3a 27 20 26 26 0a 20 20 20  End]==':' &&.   
13fb0 20 20 20 20 20 20 28 69 43 6f 6c 20 3d 20 63 68        (iCol = ch
13fc0 65 63 6b 43 6f 6c 75 6d 6e 53 70 65 63 69 66 69  eckColumnSpecifi
13fd0 65 72 28 70 51 75 65 72 79 2d 3e 70 46 74 73 2c  er(pQuery->pFts,
13fe0 20 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 29   pToken, nToken)
13ff0 29 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 51  )>=0 ){.      pQ
14000 75 65 72 79 2d 3e 6e 65 78 74 43 6f 6c 75 6d 6e  uery->nextColumn
14010 20 3d 20 69 43 6f 6c 3b 0a 20 20 20 20 20 20 63   = iCol;.      c
14020 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 20  ontinue;.    }. 
14030 20 20 20 69 66 28 20 21 69 6e 50 68 72 61 73 65     if( !inPhrase
14040 20 26 26 20 70 51 75 65 72 79 2d 3e 6e 54 65 72   && pQuery->nTer
14050 6d 73 3e 30 20 26 26 20 6e 54 6f 6b 65 6e 3d 3d  ms>0 && nToken==
14060 32 0a 20 20 20 20 20 20 20 20 20 26 26 20 70 53  2.         && pS
14070 65 67 6d 65 6e 74 5b 69 42 65 67 69 6e 5d 3d 3d  egment[iBegin]==
14080 27 4f 27 20 26 26 20 70 53 65 67 6d 65 6e 74 5b  'O' && pSegment[
14090 69 42 65 67 69 6e 2b 31 5d 3d 3d 27 52 27 20 29  iBegin+1]=='R' )
140a0 7b 0a 20 20 20 20 20 20 70 51 75 65 72 79 2d 3e  {.      pQuery->
140b0 6e 65 78 74 49 73 4f 72 20 3d 20 31 3b 0a 20 20  nextIsOr = 1;.  
140c0 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20      continue;.  
140d0 20 20 7d 0a 20 20 20 20 71 75 65 72 79 41 64 64    }.    queryAdd
140e0 28 70 51 75 65 72 79 2c 20 70 54 6f 6b 65 6e 2c  (pQuery, pToken,
140f0 20 6e 54 6f 6b 65 6e 29 3b 0a 20 20 20 20 69 66   nToken);.    if
14100 28 20 21 69 6e 50 68 72 61 73 65 20 26 26 20 69  ( !inPhrase && i
14110 42 65 67 69 6e 3e 30 20 26 26 20 70 53 65 67 6d  Begin>0 && pSegm
14120 65 6e 74 5b 69 42 65 67 69 6e 2d 31 5d 3d 3d 27  ent[iBegin-1]=='
14130 2d 27 20 29 7b 0a 20 20 20 20 20 20 70 51 75 65  -' ){.      pQue
14140 72 79 2d 3e 70 54 65 72 6d 73 5b 70 51 75 65 72  ry->pTerms[pQuer
14150 79 2d 3e 6e 54 65 72 6d 73 2d 31 5d 2e 69 73 4e  y->nTerms-1].isN
14160 6f 74 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20  ot = 1;.    }.  
14170 20 20 70 51 75 65 72 79 2d 3e 70 54 65 72 6d 73    pQuery->pTerms
14180 5b 70 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73 2d  [pQuery->nTerms-
14190 31 5d 2e 69 50 68 72 61 73 65 20 3d 20 6e 54 65  1].iPhrase = nTe
141a0 72 6d 3b 0a 20 20 20 20 69 66 28 20 69 6e 50 68  rm;.    if( inPh
141b0 72 61 73 65 20 29 7b 0a 20 20 20 20 20 20 6e 54  rase ){.      nT
141c0 65 72 6d 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d  erm++;.    }.  }
141d0 0a 0a 20 20 69 66 28 20 69 6e 50 68 72 61 73 65  ..  if( inPhrase
141e0 20 26 26 20 70 51 75 65 72 79 2d 3e 6e 54 65 72   && pQuery->nTer
141f0 6d 73 3e 66 69 72 73 74 49 6e 64 65 78 20 29 7b  ms>firstIndex ){
14200 0a 20 20 20 20 70 51 75 65 72 79 2d 3e 70 54 65  .    pQuery->pTe
14210 72 6d 73 5b 66 69 72 73 74 49 6e 64 65 78 5d 2e  rms[firstIndex].
14220 6e 50 68 72 61 73 65 20 3d 20 70 51 75 65 72 79  nPhrase = pQuery
14230 2d 3e 6e 54 65 72 6d 73 20 2d 20 66 69 72 73 74  ->nTerms - first
14240 49 6e 64 65 78 20 2d 20 31 3b 0a 20 20 7d 0a 0a  Index - 1;.  }..
14250 20 20 72 65 74 75 72 6e 20 70 4d 6f 64 75 6c 65    return pModule
14260 2d 3e 78 43 6c 6f 73 65 28 70 43 75 72 73 6f 72  ->xClose(pCursor
14270 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 72 73 65 20 61  );.}../* Parse a
14280 20 71 75 65 72 79 20 73 74 72 69 6e 67 2c 20 79   query string, y
14290 69 65 6c 64 69 6e 67 20 61 20 51 75 65 72 79 20  ielding a Query 
142a0 6f 62 6a 65 63 74 20 70 51 75 65 72 79 2e 0a 2a  object pQuery..*
142b0 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 69 6e 67  *.** The calling
142c0 20 66 75 6e 63 74 69 6f 6e 20 77 69 6c 6c 20 6e   function will n
142d0 65 65 64 20 74 6f 20 71 75 65 72 79 43 6c 65 61  eed to queryClea
142e0 72 28 29 20 74 6f 20 63 6c 65 61 6e 20 75 70 0a  r() to clean up.
142f0 2a 2a 20 74 68 65 20 64 79 6e 61 6d 69 63 61 6c  ** the dynamical
14300 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d  ly allocated mem
14310 6f 72 79 20 68 65 6c 64 20 62 79 20 70 51 75 65  ory held by pQue
14320 72 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ry..*/.static in
14330 74 20 70 61 72 73 65 51 75 65 72 79 28 0a 20 20  t parseQuery(.  
14340 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
14350 2c 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20  ,        /* The 
14360 66 75 6c 6c 74 65 78 74 20 69 6e 64 65 78 20 2a  fulltext index *
14370 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
14380 7a 49 6e 70 75 74 2c 20 20 20 20 20 20 2f 2a 20  zInput,      /* 
14390 49 6e 70 75 74 20 74 65 78 74 20 6f 66 20 74 68  Input text of th
143a0 65 20 71 75 65 72 79 20 73 74 72 69 6e 67 20 2a  e query string *
143b0 2f 0a 20 20 69 6e 74 20 6e 49 6e 70 75 74 2c 20  /.  int nInput, 
143c0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
143d0 53 69 7a 65 20 6f 66 20 74 68 65 20 69 6e 70 75  Size of the inpu
143e0 74 20 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74 20  t text */.  int 
143f0 64 66 6c 74 43 6f 6c 75 6d 6e 2c 20 20 20 20 20  dfltColumn,     
14400 20 20 20 20 20 2f 2a 20 44 65 66 61 75 6c 74 20       /* Default 
14410 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65 20 69 6e  column of the in
14420 64 65 78 20 74 6f 20 6d 61 74 63 68 20 61 67 61  dex to match aga
14430 69 6e 73 74 20 2a 2f 0a 20 20 51 75 65 72 79 20  inst */.  Query 
14440 2a 70 51 75 65 72 79 20 20 20 20 20 20 20 20 20  *pQuery         
14450 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20     /* Write the 
14460 70 61 72 73 65 20 72 65 73 75 6c 74 73 20 68 65  parse results he
14470 72 65 2e 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  re. */.){.  int 
14480 69 49 6e 70 75 74 2c 20 69 6e 50 68 72 61 73 65  iInput, inPhrase
14490 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 7a 49 6e   = 0;..  if( zIn
144a0 70 75 74 3d 3d 30 20 29 20 6e 49 6e 70 75 74 20  put==0 ) nInput 
144b0 3d 20 30 3b 0a 20 20 69 66 28 20 6e 49 6e 70 75  = 0;.  if( nInpu
144c0 74 3c 30 20 29 20 6e 49 6e 70 75 74 20 3d 20 73  t<0 ) nInput = s
144d0 74 72 6c 65 6e 28 7a 49 6e 70 75 74 29 3b 0a 20  trlen(zInput);. 
144e0 20 70 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73 20   pQuery->nTerms 
144f0 3d 20 30 3b 0a 20 20 70 51 75 65 72 79 2d 3e 70  = 0;.  pQuery->p
14500 54 65 72 6d 73 20 3d 20 4e 55 4c 4c 3b 0a 20 20  Terms = NULL;.  
14510 70 51 75 65 72 79 2d 3e 6e 65 78 74 49 73 4f 72  pQuery->nextIsOr
14520 20 3d 20 30 3b 0a 20 20 70 51 75 65 72 79 2d 3e   = 0;.  pQuery->
14530 6e 65 78 74 43 6f 6c 75 6d 6e 20 3d 20 64 66 6c  nextColumn = dfl
14540 74 43 6f 6c 75 6d 6e 3b 0a 20 20 70 51 75 65 72  tColumn;.  pQuer
14550 79 2d 3e 64 66 6c 74 43 6f 6c 75 6d 6e 20 3d 20  y->dfltColumn = 
14560 64 66 6c 74 43 6f 6c 75 6d 6e 3b 0a 20 20 70 51  dfltColumn;.  pQ
14570 75 65 72 79 2d 3e 70 46 74 73 20 3d 20 76 3b 0a  uery->pFts = v;.
14580 0a 20 20 66 6f 72 28 69 49 6e 70 75 74 3d 30 3b  .  for(iInput=0;
14590 20 69 49 6e 70 75 74 3c 6e 49 6e 70 75 74 3b 20   iInput<nInput; 
145a0 2b 2b 69 49 6e 70 75 74 29 7b 0a 20 20 20 20 69  ++iInput){.    i
145b0 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d  nt i;.    for(i=
145c0 69 49 6e 70 75 74 3b 20 69 3c 6e 49 6e 70 75 74  iInput; i<nInput
145d0 20 26 26 20 7a 49 6e 70 75 74 5b 69 5d 21 3d 27   && zInput[i]!='
145e0 22 27 3b 20 2b 2b 69 29 7b 7d 0a 20 20 20 20 69  "'; ++i){}.    i
145f0 66 28 20 69 3e 69 49 6e 70 75 74 20 29 7b 0a 20  f( i>iInput ){. 
14600 20 20 20 20 20 74 6f 6b 65 6e 69 7a 65 53 65 67       tokenizeSeg
14610 6d 65 6e 74 28 76 2d 3e 70 54 6f 6b 65 6e 69 7a  ment(v->pTokeniz
14620 65 72 2c 20 7a 49 6e 70 75 74 2b 69 49 6e 70 75  er, zInput+iInpu
14630 74 2c 20 69 2d 69 49 6e 70 75 74 2c 20 69 6e 50  t, i-iInput, inP
14640 68 72 61 73 65 2c 0a 20 20 20 20 20 20 20 20 20  hrase,.         
14650 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 51                pQ
14660 75 65 72 79 29 3b 0a 20 20 20 20 7d 0a 20 20 20  uery);.    }.   
14670 20 69 49 6e 70 75 74 20 3d 20 69 3b 0a 20 20 20   iInput = i;.   
14680 20 69 66 28 20 69 3c 6e 49 6e 70 75 74 20 29 7b   if( i<nInput ){
14690 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 7a  .      assert( z
146a0 49 6e 70 75 74 5b 69 5d 3d 3d 27 22 27 20 29 3b  Input[i]=='"' );
146b0 0a 20 20 20 20 20 20 69 6e 50 68 72 61 73 65 20  .      inPhrase 
146c0 3d 20 21 69 6e 50 68 72 61 73 65 3b 0a 20 20 20  = !inPhrase;.   
146d0 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 6e   }.  }..  if( in
146e0 50 68 72 61 73 65 20 29 7b 0a 20 20 20 20 2f 2a  Phrase ){.    /*
146f0 20 75 6e 6d 61 74 63 68 65 64 20 71 75 6f 74 65   unmatched quote
14700 20 2a 2f 0a 20 20 20 20 71 75 65 72 79 43 6c 65   */.    queryCle
14710 61 72 28 70 51 75 65 72 79 29 3b 0a 20 20 20 20  ar(pQuery);.    
14720 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
14730 52 4f 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ROR;.  }.  retur
14740 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
14750 2f 2a 20 50 65 72 66 6f 72 6d 20 61 20 66 75 6c  /* Perform a ful
14760 6c 2d 74 65 78 74 20 71 75 65 72 79 20 75 73 69  l-text query usi
14770 6e 67 20 74 68 65 20 73 65 61 72 63 68 20 65 78  ng the search ex
14780 70 72 65 73 73 69 6f 6e 20 69 6e 0a 2a 2a 20 7a  pression in.** z
14790 49 6e 70 75 74 5b 30 2e 2e 6e 49 6e 70 75 74 2d  Input[0..nInput-
147a0 31 5d 2e 20 20 52 65 74 75 72 6e 20 61 20 6c 69  1].  Return a li
147b0 73 74 20 6f 66 20 6d 61 74 63 68 69 6e 67 20 64  st of matching d
147c0 6f 63 75 6d 65 6e 74 73 0a 2a 2a 20 69 6e 20 70  ocuments.** in p
147d0 52 65 73 75 6c 74 2e 0a 2a 2a 0a 2a 2a 20 51 75  Result..**.** Qu
147e0 65 72 69 65 73 20 6d 75 73 74 20 6d 61 74 63 68  eries must match
147f0 20 63 6f 6c 75 6d 6e 20 69 43 6f 6c 75 6d 6e 2e   column iColumn.
14800 20 20 4f 72 20 69 66 20 69 43 6f 6c 75 6d 6e 3e    Or if iColumn>
14810 3d 6e 43 6f 6c 75 6d 6e 0a 2a 2a 20 74 68 65 79  =nColumn.** they
14820 20 61 72 65 20 61 6c 6c 6f 77 65 64 20 74 6f 20   are allowed to 
14830 6d 61 74 63 68 20 61 67 61 69 6e 73 74 20 61 6e  match against an
14840 79 20 63 6f 6c 75 6d 6e 2e 0a 2a 2f 0a 73 74 61  y column..*/.sta
14850 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74  tic int fulltext
14860 51 75 65 72 79 28 0a 20 20 66 75 6c 6c 74 65 78  Query(.  fulltex
14870 74 5f 76 74 61 62 20 2a 76 2c 20 20 20 20 20 20  t_vtab *v,      
14880 2f 2a 20 54 68 65 20 66 75 6c 6c 20 74 65 78 74  /* The full text
14890 20 69 6e 64 65 78 20 2a 2f 0a 20 20 69 6e 74 20   index */.  int 
148a0 69 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20  iColumn,        
148b0 20 20 20 2f 2a 20 4d 61 74 63 68 20 61 67 61 69     /* Match agai
148c0 6e 73 74 20 74 68 69 73 20 63 6f 6c 75 6d 6e 20  nst this column 
148d0 62 79 20 64 65 66 61 75 6c 74 20 2a 2f 0a 20 20  by default */.  
148e0 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 6e 70  const char *zInp
148f0 75 74 2c 20 20 20 20 2f 2a 20 54 68 65 20 71 75  ut,    /* The qu
14900 65 72 79 20 73 74 72 69 6e 67 20 2a 2f 0a 20 20  ery string */.  
14910 69 6e 74 20 6e 49 6e 70 75 74 2c 20 20 20 20 20  int nInput,     
14920 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
14930 20 6f 66 20 62 79 74 65 73 20 69 6e 20 7a 49 6e   of bytes in zIn
14940 70 75 74 5b 5d 20 2a 2f 0a 20 20 44 6f 63 4c 69  put[] */.  DocLi
14950 73 74 20 2a 2a 70 52 65 73 75 6c 74 2c 20 20 20  st **pResult,   
14960 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 72    /* Write the r
14970 65 73 75 6c 74 20 64 6f 63 6c 69 73 74 20 68 65  esult doclist he
14980 72 65 20 2a 2f 0a 20 20 51 75 65 72 79 20 2a 70  re */.  Query *p
14990 51 75 65 72 79 20 20 20 20 20 20 20 20 20 20 2f  Query          /
149a0 2a 20 50 75 74 20 70 61 72 73 65 64 20 71 75 65  * Put parsed que
149b0 72 79 20 73 74 72 69 6e 67 20 68 65 72 65 20 2a  ry string here *
149c0 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 2c 20 69 4e  /.){.  int i, iN
149d0 65 78 74 2c 20 72 63 3b 0a 20 20 44 6f 63 4c 69  ext, rc;.  DocLi
149e0 73 74 20 2a 70 4c 65 66 74 20 3d 20 4e 55 4c 4c  st *pLeft = NULL
149f0 3b 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70 52 69  ;.  DocList *pRi
14a00 67 68 74 2c 20 2a 70 4e 65 77 2c 20 2a 70 4f 72  ght, *pNew, *pOr
14a10 3b 0a 20 20 69 6e 74 20 6e 4e 6f 74 20 3d 20 30  ;.  int nNot = 0
14a20 3b 0a 20 20 51 75 65 72 79 54 65 72 6d 20 2a 61  ;.  QueryTerm *a
14a30 54 65 72 6d 3b 0a 0a 20 20 72 63 20 3d 20 70 61  Term;..  rc = pa
14a40 72 73 65 51 75 65 72 79 28 76 2c 20 7a 49 6e 70  rseQuery(v, zInp
14a50 75 74 2c 20 6e 49 6e 70 75 74 2c 20 69 43 6f 6c  ut, nInput, iCol
14a60 75 6d 6e 2c 20 70 51 75 65 72 79 29 3b 0a 20 20  umn, pQuery);.  
14a70 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
14a80 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
14a90 20 20 2f 2a 20 4d 65 72 67 65 20 41 4e 44 20 74    /* Merge AND t
14aa0 65 72 6d 73 2e 20 2a 2f 0a 20 20 61 54 65 72 6d  erms. */.  aTerm
14ab0 20 3d 20 70 51 75 65 72 79 2d 3e 70 54 65 72 6d   = pQuery->pTerm
14ac0 73 3b 0a 20 20 66 6f 72 28 69 20 3d 20 30 3b 20  s;.  for(i = 0; 
14ad0 69 3c 70 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73  i<pQuery->nTerms
14ae0 3b 20 69 3d 69 4e 65 78 74 29 7b 0a 20 20 20 20  ; i=iNext){.    
14af0 69 66 28 20 61 54 65 72 6d 5b 69 5d 2e 69 73 4e  if( aTerm[i].isN
14b00 6f 74 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 48  ot ){.      /* H
14b10 61 6e 64 6c 65 20 61 6c 6c 20 4e 4f 54 20 74 65  andle all NOT te
14b20 72 6d 73 20 69 6e 20 61 20 73 65 70 61 72 61 74  rms in a separat
14b30 65 20 70 61 73 73 20 2a 2f 0a 20 20 20 20 20 20  e pass */.      
14b40 6e 4e 6f 74 2b 2b 3b 0a 20 20 20 20 20 20 69 4e  nNot++;.      iN
14b50 65 78 74 20 3d 20 69 20 2b 20 61 54 65 72 6d 5b  ext = i + aTerm[
14b60 69 5d 2e 6e 50 68 72 61 73 65 2b 31 3b 0a 20 20  i].nPhrase+1;.  
14b70 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20      continue;.  
14b80 20 20 7d 0a 20 20 20 20 69 4e 65 78 74 20 3d 20    }.    iNext = 
14b90 69 20 2b 20 61 54 65 72 6d 5b 69 5d 2e 6e 50 68  i + aTerm[i].nPh
14ba0 72 61 73 65 20 2b 20 31 3b 0a 20 20 20 20 72 63  rase + 1;.    rc
14bb0 20 3d 20 64 6f 63 4c 69 73 74 4f 66 54 65 72 6d   = docListOfTerm
14bc0 28 76 2c 20 61 54 65 72 6d 5b 69 5d 2e 69 43 6f  (v, aTerm[i].iCo
14bd0 6c 75 6d 6e 2c 20 26 61 54 65 72 6d 5b 69 5d 2c  lumn, &aTerm[i],
14be0 20 26 70 52 69 67 68 74 29 3b 0a 20 20 20 20 69   &pRight);.    i
14bf0 66 28 20 72 63 20 29 7b 0a 20 20 20 20 20 20 71  f( rc ){.      q
14c00 75 65 72 79 43 6c 65 61 72 28 70 51 75 65 72 79  ueryClear(pQuery
14c10 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  );.      return 
14c20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 77 68  rc;.    }.    wh
14c30 69 6c 65 28 20 69 4e 65 78 74 3c 70 51 75 65 72  ile( iNext<pQuer
14c40 79 2d 3e 6e 54 65 72 6d 73 20 26 26 20 61 54 65  y->nTerms && aTe
14c50 72 6d 5b 69 4e 65 78 74 5d 2e 69 73 4f 72 20 29  rm[iNext].isOr )
14c60 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 64 6f 63  {.      rc = doc
14c70 4c 69 73 74 4f 66 54 65 72 6d 28 76 2c 20 61 54  ListOfTerm(v, aT
14c80 65 72 6d 5b 69 4e 65 78 74 5d 2e 69 43 6f 6c 75  erm[iNext].iColu
14c90 6d 6e 2c 20 26 61 54 65 72 6d 5b 69 4e 65 78 74  mn, &aTerm[iNext
14ca0 5d 2c 20 26 70 4f 72 29 3b 0a 20 20 20 20 20 20  ], &pOr);.      
14cb0 69 4e 65 78 74 20 2b 3d 20 61 54 65 72 6d 5b 69  iNext += aTerm[i
14cc0 4e 65 78 74 5d 2e 6e 50 68 72 61 73 65 20 2b 20  Next].nPhrase + 
14cd0 31 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 20  1;.      if( rc 
14ce0 29 7b 0a 20 20 20 20 20 20 20 20 71 75 65 72 79  ){.        query
14cf0 43 6c 65 61 72 28 70 51 75 65 72 79 29 3b 0a 20  Clear(pQuery);. 
14d00 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63         return rc
14d10 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
14d20 70 4e 65 77 20 3d 20 64 6f 63 4c 69 73 74 4e 65  pNew = docListNe
14d30 77 28 44 4c 5f 44 4f 43 49 44 53 29 3b 0a 20 20  w(DL_DOCIDS);.  
14d40 20 20 20 20 64 6f 63 4c 69 73 74 4f 72 4d 65 72      docListOrMer
14d50 67 65 28 70 52 69 67 68 74 2c 20 70 4f 72 2c 20  ge(pRight, pOr, 
14d60 70 4e 65 77 29 3b 0a 20 20 20 20 20 20 64 6f 63  pNew);.      doc
14d70 4c 69 73 74 44 65 6c 65 74 65 28 70 52 69 67 68  ListDelete(pRigh
14d80 74 29 3b 0a 20 20 20 20 20 20 64 6f 63 4c 69 73  t);.      docLis
14d90 74 44 65 6c 65 74 65 28 70 4f 72 29 3b 0a 20 20  tDelete(pOr);.  
14da0 20 20 20 20 70 52 69 67 68 74 20 3d 20 70 4e 65      pRight = pNe
14db0 77 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  w;.    }.    if(
14dc0 20 70 4c 65 66 74 3d 3d 30 20 29 7b 0a 20 20 20   pLeft==0 ){.   
14dd0 20 20 20 70 4c 65 66 74 20 3d 20 70 52 69 67 68     pLeft = pRigh
14de0 74 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  t;.    }else{.  
14df0 20 20 20 20 70 4e 65 77 20 3d 20 64 6f 63 4c 69      pNew = docLi
14e00 73 74 4e 65 77 28 44 4c 5f 44 4f 43 49 44 53 29  stNew(DL_DOCIDS)
14e10 3b 0a 20 20 20 20 20 20 64 6f 63 4c 69 73 74 41  ;.      docListA
14e20 6e 64 4d 65 72 67 65 28 70 4c 65 66 74 2c 20 70  ndMerge(pLeft, p
14e30 52 69 67 68 74 2c 20 70 4e 65 77 29 3b 0a 20 20  Right, pNew);.  
14e40 20 20 20 20 64 6f 63 4c 69 73 74 44 65 6c 65 74      docListDelet
14e50 65 28 70 52 69 67 68 74 29 3b 0a 20 20 20 20 20  e(pRight);.     
14e60 20 64 6f 63 4c 69 73 74 44 65 6c 65 74 65 28 70   docListDelete(p
14e70 4c 65 66 74 29 3b 0a 20 20 20 20 20 20 70 4c 65  Left);.      pLe
14e80 66 74 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 7d  ft = pNew;.    }
14e90 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6e 4e 6f 74  .  }..  if( nNot
14ea0 20 26 26 20 70 4c 65 66 74 3d 3d 30 20 29 7b 0a   && pLeft==0 ){.
14eb0 20 20 20 20 2f 2a 20 57 65 20 64 6f 20 6e 6f 74      /* We do not
14ec0 20 79 65 74 20 6b 6e 6f 77 20 68 6f 77 20 74 6f   yet know how to
14ed0 20 68 61 6e 64 6c 65 20 61 20 71 75 65 72 79 20   handle a query 
14ee0 6f 66 20 6f 6e 6c 79 20 4e 4f 54 20 74 65 72 6d  of only NOT term
14ef0 73 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20  s */.    return 
14f00 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
14f10 7d 0a 0a 20 20 2f 2a 20 44 6f 20 74 68 65 20 45  }..  /* Do the E
14f20 58 43 45 50 54 20 74 65 72 6d 73 20 2a 2f 0a 20  XCEPT terms */. 
14f30 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 51 75 65   for(i=0; i<pQue
14f40 72 79 2d 3e 6e 54 65 72 6d 73 3b 20 20 69 20 2b  ry->nTerms;  i +
14f50 3d 20 61 54 65 72 6d 5b 69 5d 2e 6e 50 68 72 61  = aTerm[i].nPhra
14f60 73 65 20 2b 20 31 29 7b 0a 20 20 20 20 69 66 28  se + 1){.    if(
14f70 20 21 61 54 65 72 6d 5b 69 5d 2e 69 73 4e 6f 74   !aTerm[i].isNot
14f80 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20   ) continue;.   
14f90 20 72 63 20 3d 20 64 6f 63 4c 69 73 74 4f 66 54   rc = docListOfT
14fa0 65 72 6d 28 76 2c 20 61 54 65 72 6d 5b 69 5d 2e  erm(v, aTerm[i].
14fb0 69 43 6f 6c 75 6d 6e 2c 20 26 61 54 65 72 6d 5b  iColumn, &aTerm[
14fc0 69 5d 2c 20 26 70 52 69 67 68 74 29 3b 0a 20 20  i], &pRight);.  
14fd0 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20    if( rc ){.    
14fe0 20 20 71 75 65 72 79 43 6c 65 61 72 28 70 51 75    queryClear(pQu
14ff0 65 72 79 29 3b 0a 20 20 20 20 20 20 64 6f 63 4c  ery);.      docL
15000 69 73 74 44 65 6c 65 74 65 28 70 4c 65 66 74 29  istDelete(pLeft)
15010 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72  ;.      return r
15020 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 4e 65  c;.    }.    pNe
15030 77 20 3d 20 64 6f 63 4c 69 73 74 4e 65 77 28 44  w = docListNew(D
15040 4c 5f 44 4f 43 49 44 53 29 3b 0a 20 20 20 20 64  L_DOCIDS);.    d
15050 6f 63 4c 69 73 74 45 78 63 65 70 74 4d 65 72 67  ocListExceptMerg
15060 65 28 70 4c 65 66 74 2c 20 70 52 69 67 68 74 2c  e(pLeft, pRight,
15070 20 70 4e 65 77 29 3b 0a 20 20 20 20 64 6f 63 4c   pNew);.    docL
15080 69 73 74 44 65 6c 65 74 65 28 70 52 69 67 68 74  istDelete(pRight
15090 29 3b 0a 20 20 20 20 64 6f 63 4c 69 73 74 44 65  );.    docListDe
150a0 6c 65 74 65 28 70 4c 65 66 74 29 3b 0a 20 20 20  lete(pLeft);.   
150b0 20 70 4c 65 66 74 20 3d 20 70 4e 65 77 3b 0a 20   pLeft = pNew;. 
150c0 20 7d 0a 0a 20 20 2a 70 52 65 73 75 6c 74 20 3d   }..  *pResult =
150d0 20 70 4c 65 66 74 3b 0a 20 20 72 65 74 75 72 6e   pLeft;.  return
150e0 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
150f0 69 73 20 69 73 20 74 68 65 20 78 46 69 6c 74 65  is is the xFilte
15100 72 20 69 6e 74 65 72 66 61 63 65 20 66 6f 72 20  r interface for 
15110 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c  the virtual tabl
15120 65 2e 20 20 53 65 65 0a 2a 2a 20 74 68 65 20 76  e.  See.** the v
15130 69 72 74 75 61 6c 20 74 61 62 6c 65 20 78 46 69  irtual table xFi
15140 6c 74 65 72 20 6d 65 74 68 6f 64 20 64 6f 63 75  lter method docu
15150 6d 65 6e 74 61 74 69 6f 6e 20 66 6f 72 20 61 64  mentation for ad
15160 64 69 74 69 6f 6e 61 6c 0a 2a 2a 20 69 6e 66 6f  ditional.** info
15170 72 6d 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49  rmation..**.** I
15180 66 20 69 64 78 4e 75 6d 3d 3d 51 55 45 52 59 5f  f idxNum==QUERY_
15190 47 45 4e 45 52 49 43 20 74 68 65 6e 20 64 6f 20  GENERIC then do 
151a0 61 20 66 75 6c 6c 20 74 61 62 6c 65 20 73 63 61  a full table sca
151b0 6e 20 61 67 61 69 6e 73 74 0a 2a 2a 20 74 68 65  n against.** the
151c0 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65   %_content table
151d0 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 69 64 78 4e 75  ..**.** If idxNu
151e0 6d 3d 3d 51 55 45 52 59 5f 52 4f 57 49 44 20 74  m==QUERY_ROWID t
151f0 68 65 6e 20 64 6f 20 61 20 72 6f 77 69 64 20 6c  hen do a rowid l
15200 6f 6f 6b 75 70 20 66 6f 72 20 61 20 73 69 6e 67  ookup for a sing
15210 6c 65 20 65 6e 74 72 79 0a 2a 2a 20 69 6e 20 74  le entry.** in t
15220 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62  he %_content tab
15230 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 69 64 78  le..**.** If idx
15240 4e 75 6d 3e 3d 51 55 45 52 59 5f 46 55 4c 4c 54  Num>=QUERY_FULLT
15250 45 58 54 20 74 68 65 6e 20 75 73 65 20 74 68 65  EXT then use the
15260 20 66 75 6c 6c 20 74 65 78 74 20 69 6e 64 65 78   full text index
15270 2e 20 20 54 68 65 0a 2a 2a 20 63 6f 6c 75 6d 6e  .  The.** column
15280 20 6f 6e 20 74 68 65 20 6c 65 66 74 2d 68 61 6e   on the left-han
15290 64 20 73 69 64 65 20 6f 66 20 74 68 65 20 4d 41  d side of the MA
152a0 54 43 48 20 6f 70 65 72 61 74 6f 72 20 69 73 20  TCH operator is 
152b0 63 6f 6c 75 6d 6e 0a 2a 2a 20 6e 75 6d 62 65 72  column.** number
152c0 20 69 64 78 4e 75 6d 2d 51 55 45 52 59 5f 46 55   idxNum-QUERY_FU
152d0 4c 4c 54 45 58 54 2c 20 30 20 69 6e 64 65 78 65  LLTEXT, 0 indexe
152e0 64 2e 20 20 61 72 67 76 5b 30 5d 20 69 73 20 74  d.  argv[0] is t
152f0 68 65 20 72 69 67 68 74 2d 68 61 6e 64 0a 2a 2a  he right-hand.**
15300 20 73 69 64 65 20 6f 66 20 74 68 65 20 4d 41 54   side of the MAT
15310 43 48 20 6f 70 65 72 61 74 6f 72 2e 0a 2a 2f 0a  CH operator..*/.
15320 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 55  /* TODO(shess) U
15330 70 67 72 61 64 65 20 74 68 65 20 63 75 72 73 6f  pgrade the curso
15340 72 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e  r initialization
15350 20 61 6e 64 20 64 65 73 74 72 75 63 74 69 6f 6e   and destruction
15360 20 74 6f 0a 2a 2a 20 61 63 63 6f 75 6e 74 20 66   to.** account f
15370 6f 72 20 66 75 6c 6c 74 65 78 74 46 69 6c 74 65  or fulltextFilte
15380 72 28 29 20 62 65 69 6e 67 20 63 61 6c 6c 65 64  r() being called
15390 20 6d 75 6c 74 69 70 6c 65 20 74 69 6d 65 73 20   multiple times 
153a0 6f 6e 20 74 68 65 0a 2a 2a 20 73 61 6d 65 20 63  on the.** same c
153b0 75 72 73 6f 72 2e 20 20 54 68 65 20 63 75 72 72  ursor.  The curr
153c0 65 6e 74 20 73 6f 6c 75 74 69 6f 6e 20 69 73 20  ent solution is 
153d0 76 65 72 79 20 66 72 61 67 69 6c 65 2e 20 20 41  very fragile.  A
153e0 70 70 6c 79 20 66 69 78 20 74 6f 0a 2a 2a 20 66  pply fix to.** f
153f0 74 73 32 20 61 73 20 61 70 70 72 6f 70 72 69 61  ts2 as appropria
15400 74 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  te..*/.static in
15410 74 20 66 75 6c 6c 74 65 78 74 46 69 6c 74 65 72  t fulltextFilter
15420 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  (.  sqlite3_vtab
15430 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72  _cursor *pCursor
15440 2c 20 20 20 20 20 2f 2a 20 54 68 65 20 63 75 72  ,     /* The cur
15450 73 6f 72 20 75 73 65 64 20 66 6f 72 20 74 68 69  sor used for thi
15460 73 20 71 75 65 72 79 20 2a 2f 0a 20 20 69 6e 74  s query */.  int
15470 20 69 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63   idxNum, const c
15480 68 61 72 20 2a 69 64 78 53 74 72 2c 20 20 20 2f  har *idxStr,   /
15490 2a 20 57 68 69 63 68 20 69 6e 64 65 78 69 6e 67  * Which indexing
154a0 20 73 63 68 65 6d 65 20 74 6f 20 75 73 65 20 2a   scheme to use *
154b0 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 73 71  /.  int argc, sq
154c0 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72  lite3_value **ar
154d0 67 76 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e  gv    /* Argumen
154e0 74 73 20 66 6f 72 20 74 68 65 20 69 6e 64 65 78  ts for the index
154f0 69 6e 67 20 73 63 68 65 6d 65 20 2a 2f 0a 29 7b  ing scheme */.){
15500 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73  .  fulltext_curs
15510 6f 72 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78  or *c = (fulltex
15520 74 5f 63 75 72 73 6f 72 20 2a 29 20 70 43 75 72  t_cursor *) pCur
15530 73 6f 72 3b 0a 20 20 66 75 6c 6c 74 65 78 74 5f  sor;.  fulltext_
15540 76 74 61 62 20 2a 76 20 3d 20 63 75 72 73 6f 72  vtab *v = cursor
15550 5f 76 74 61 62 28 63 29 3b 0a 20 20 69 6e 74 20  _vtab(c);.  int 
15560 72 63 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c  rc;.  char *zSql
15570 3b 0a 0a 20 20 54 52 41 43 45 28 28 22 46 54 53  ;..  TRACE(("FTS
15580 31 20 46 69 6c 74 65 72 20 25 70 5c 6e 22 2c 70  1 Filter %p\n",p
15590 43 75 72 73 6f 72 29 29 3b 0a 0a 20 20 7a 53 71  Cursor));..  zSq
155a0 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  l = sqlite3_mpri
155b0 6e 74 66 28 22 73 65 6c 65 63 74 20 72 6f 77 69  ntf("select rowi
155c0 64 2c 20 2a 20 66 72 6f 6d 20 25 25 5f 63 6f 6e  d, * from %%_con
155d0 74 65 6e 74 20 25 73 22 2c 0a 20 20 20 20 20 20  tent %s",.      
155e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
155f0 20 20 20 20 69 64 78 4e 75 6d 3d 3d 51 55 45 52      idxNum==QUER
15600 59 5f 47 45 4e 45 52 49 43 20 3f 20 22 22 20 3a  Y_GENERIC ? "" :
15610 20 22 77 68 65 72 65 20 72 6f 77 69 64 3d 3f 22   "where rowid=?"
15620 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e  );.  sqlite3_fin
15630 61 6c 69 7a 65 28 63 2d 3e 70 53 74 6d 74 29 3b  alize(c->pStmt);
15640 0a 20 20 72 63 20 3d 20 73 71 6c 5f 70 72 65 70  .  rc = sql_prep
15650 61 72 65 28 76 2d 3e 64 62 2c 20 76 2d 3e 7a 44  are(v->db, v->zD
15660 62 2c 20 76 2d 3e 7a 4e 61 6d 65 2c 20 26 63 2d  b, v->zName, &c-
15670 3e 70 53 74 6d 74 2c 20 7a 53 71 6c 29 3b 0a 20  >pStmt, zSql);. 
15680 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53   sqlite3_free(zS
15690 71 6c 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  ql);.  if( rc!=S
156a0 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
156b0 6e 20 72 63 3b 0a 0a 20 20 63 2d 3e 69 43 75 72  n rc;..  c->iCur
156c0 73 6f 72 54 79 70 65 20 3d 20 69 64 78 4e 75 6d  sorType = idxNum
156d0 3b 0a 20 20 73 77 69 74 63 68 28 20 69 64 78 4e  ;.  switch( idxN
156e0 75 6d 20 29 7b 0a 20 20 20 20 63 61 73 65 20 51  um ){.    case Q
156f0 55 45 52 59 5f 47 45 4e 45 52 49 43 3a 0a 20 20  UERY_GENERIC:.  
15700 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20      break;..    
15710 63 61 73 65 20 51 55 45 52 59 5f 52 4f 57 49 44  case QUERY_ROWID
15720 3a 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  :.      rc = sql
15730 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28  ite3_bind_int64(
15740 63 2d 3e 70 53 74 6d 74 2c 20 31 2c 20 73 71 6c  c->pStmt, 1, sql
15750 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36 34  ite3_value_int64
15760 28 61 72 67 76 5b 30 5d 29 29 3b 0a 20 20 20 20  (argv[0]));.    
15770 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
15780 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
15790 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20  .      break;.. 
157a0 20 20 20 64 65 66 61 75 6c 74 3a 20 20 20 2f 2a     default:   /*
157b0 20 66 75 6c 6c 2d 74 65 78 74 20 73 65 61 72 63   full-text searc
157c0 68 20 2a 2f 0a 20 20 20 20 7b 0a 20 20 20 20 20  h */.    {.     
157d0 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 51 75   const char *zQu
157e0 65 72 79 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  ery = (const cha
157f0 72 20 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  r *)sqlite3_valu
15800 65 5f 74 65 78 74 28 61 72 67 76 5b 30 5d 29 3b  e_text(argv[0]);
15810 0a 20 20 20 20 20 20 44 6f 63 4c 69 73 74 20 2a  .      DocList *
15820 70 52 65 73 75 6c 74 3b 0a 20 20 20 20 20 20 61  pResult;.      a
15830 73 73 65 72 74 28 20 69 64 78 4e 75 6d 3c 3d 51  ssert( idxNum<=Q
15840 55 45 52 59 5f 46 55 4c 4c 54 45 58 54 2b 76 2d  UERY_FULLTEXT+v-
15850 3e 6e 43 6f 6c 75 6d 6e 29 3b 0a 20 20 20 20 20  >nColumn);.     
15860 20 61 73 73 65 72 74 28 20 61 72 67 63 3d 3d 31   assert( argc==1
15870 20 29 3b 0a 20 20 20 20 20 20 71 75 65 72 79 43   );.      queryC
15880 6c 65 61 72 28 26 63 2d 3e 71 29 3b 0a 20 20 20  lear(&c->q);.   
15890 20 20 20 72 63 20 3d 20 66 75 6c 6c 74 65 78 74     rc = fulltext
158a0 51 75 65 72 79 28 76 2c 20 69 64 78 4e 75 6d 2d  Query(v, idxNum-
158b0 51 55 45 52 59 5f 46 55 4c 4c 54 45 58 54 2c 20  QUERY_FULLTEXT, 
158c0 7a 51 75 65 72 79 2c 20 2d 31 2c 20 26 70 52 65  zQuery, -1, &pRe
158d0 73 75 6c 74 2c 20 26 63 2d 3e 71 29 3b 0a 20 20  sult, &c->q);.  
158e0 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
158f0 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
15900 63 3b 0a 20 20 20 20 20 20 69 66 28 20 63 2d 3e  c;.      if( c->
15910 72 65 73 75 6c 74 2e 70 44 6f 63 6c 69 73 74 21  result.pDoclist!
15920 3d 4e 55 4c 4c 20 29 20 64 6f 63 4c 69 73 74 44  =NULL ) docListD
15930 65 6c 65 74 65 28 63 2d 3e 72 65 73 75 6c 74 2e  elete(c->result.
15940 70 44 6f 63 6c 69 73 74 29 3b 0a 20 20 20 20 20  pDoclist);.     
15950 20 72 65 61 64 65 72 49 6e 69 74 28 26 63 2d 3e   readerInit(&c->
15960 72 65 73 75 6c 74 2c 20 70 52 65 73 75 6c 74 29  result, pResult)
15970 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
15980 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
15990 72 6e 20 66 75 6c 6c 74 65 78 74 4e 65 78 74 28  rn fulltextNext(
159a0 70 43 75 72 73 6f 72 29 3b 0a 7d 0a 0a 2f 2a 20  pCursor);.}../* 
159b0 54 68 69 73 20 69 73 20 74 68 65 20 78 45 6f 66  This is the xEof
159c0 20 6d 65 74 68 6f 64 20 6f 66 20 74 68 65 20 76   method of the v
159d0 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20 54  irtual table.  T
159e0 68 65 20 53 51 4c 69 74 65 20 63 6f 72 65 0a 2a  he SQLite core.*
159f0 2a 20 63 61 6c 6c 73 20 74 68 69 73 20 72 6f 75  * calls this rou
15a00 74 69 6e 65 20 74 6f 20 66 69 6e 64 20 6f 75 74  tine to find out
15a10 20 69 66 20 69 74 20 68 61 73 20 72 65 61 63 68   if it has reach
15a20 65 64 20 74 68 65 20 65 6e 64 20 6f 66 0a 2a 2a  ed the end of.**
15a30 20 61 20 71 75 65 72 79 27 73 20 72 65 73 75 6c   a query's resul
15a40 74 73 20 73 65 74 2e 0a 2a 2f 0a 73 74 61 74 69  ts set..*/.stati
15a50 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 45 6f  c int fulltextEo
15a60 66 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  f(sqlite3_vtab_c
15a70 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b  ursor *pCursor){
15a80 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73  .  fulltext_curs
15a90 6f 72 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78  or *c = (fulltex
15aa0 74 5f 63 75 72 73 6f 72 20 2a 29 20 70 43 75 72  t_cursor *) pCur
15ab0 73 6f 72 3b 0a 20 20 72 65 74 75 72 6e 20 63 2d  sor;.  return c-
15ac0 3e 65 6f 66 3b 0a 7d 0a 0a 2f 2a 20 54 68 69 73  >eof;.}../* This
15ad0 20 69 73 20 74 68 65 20 78 43 6f 6c 75 6d 6e 20   is the xColumn 
15ae0 6d 65 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69  method of the vi
15af0 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68  rtual table.  Th
15b00 65 20 53 51 4c 69 74 65 0a 2a 2a 20 63 6f 72 65  e SQLite.** core
15b10 20 63 61 6c 6c 73 20 74 68 69 73 20 6d 65 74 68   calls this meth
15b20 6f 64 20 64 75 72 69 6e 67 20 61 20 71 75 65 72  od during a quer
15b30 79 20 77 68 65 6e 20 69 74 20 6e 65 65 64 73 20  y when it needs 
15b40 74 68 65 20 76 61 6c 75 65 0a 2a 2a 20 6f 66 20  the value.** of 
15b50 61 20 63 6f 6c 75 6d 6e 20 66 72 6f 6d 20 74 68  a column from th
15b60 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e  e virtual table.
15b70 20 20 54 68 69 73 20 6d 65 74 68 6f 64 20 6e 65    This method ne
15b80 65 64 73 20 74 6f 20 75 73 65 0a 2a 2a 20 6f 6e  eds to use.** on
15b90 65 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  e of the sqlite3
15ba0 5f 72 65 73 75 6c 74 5f 2a 28 29 20 72 6f 75 74  _result_*() rout
15bb0 69 6e 65 73 20 74 6f 20 73 74 6f 72 65 20 74 68  ines to store th
15bc0 65 20 72 65 71 75 65 73 74 65 64 0a 2a 2a 20 76  e requested.** v
15bd0 61 6c 75 65 20 62 61 63 6b 20 69 6e 20 74 68 65  alue back in the
15be0 20 70 43 6f 6e 74 65 78 74 2e 0a 2a 2f 0a 73 74   pContext..*/.st
15bf0 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78  atic int fulltex
15c00 74 43 6f 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f  tColumn(sqlite3_
15c10 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75  vtab_cursor *pCu
15c20 72 73 6f 72 2c 0a 20 20 20 20 20 20 20 20 20 20  rsor,.          
15c30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15c40 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
15c50 2a 70 43 6f 6e 74 65 78 74 2c 20 69 6e 74 20 69  *pContext, int i
15c60 64 78 43 6f 6c 29 7b 0a 20 20 66 75 6c 6c 74 65  dxCol){.  fullte
15c70 78 74 5f 63 75 72 73 6f 72 20 2a 63 20 3d 20 28  xt_cursor *c = (
15c80 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20  fulltext_cursor 
15c90 2a 29 20 70 43 75 72 73 6f 72 3b 0a 20 20 66 75  *) pCursor;.  fu
15ca0 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 20 3d  lltext_vtab *v =
15cb0 20 63 75 72 73 6f 72 5f 76 74 61 62 28 63 29 3b   cursor_vtab(c);
15cc0 0a 0a 20 20 69 66 28 20 69 64 78 43 6f 6c 3c 76  ..  if( idxCol<v
15cd0 2d 3e 6e 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20  ->nColumn ){.   
15ce0 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
15cf0 70 56 61 6c 20 3d 20 73 71 6c 69 74 65 33 5f 63  pVal = sqlite3_c
15d00 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 63 2d 3e 70  olumn_value(c->p
15d10 53 74 6d 74 2c 20 69 64 78 43 6f 6c 2b 31 29 3b  Stmt, idxCol+1);
15d20 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
15d30 75 6c 74 5f 76 61 6c 75 65 28 70 43 6f 6e 74 65  ult_value(pConte
15d40 78 74 2c 20 70 56 61 6c 29 3b 0a 20 20 7d 65 6c  xt, pVal);.  }el
15d50 73 65 20 69 66 28 20 69 64 78 43 6f 6c 3d 3d 76  se if( idxCol==v
15d60 2d 3e 6e 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20  ->nColumn ){.   
15d70 20 2f 2a 20 54 68 65 20 65 78 74 72 61 20 63 6f   /* The extra co
15d80 6c 75 6d 6e 20 77 68 6f 73 65 20 6e 61 6d 65 20  lumn whose name 
15d90 69 73 20 74 68 65 20 73 61 6d 65 20 61 73 20 74  is the same as t
15da0 68 65 20 74 61 62 6c 65 2e 0a 20 20 20 20 2a 2a  he table..    **
15db0 20 52 65 74 75 72 6e 20 61 20 62 6c 6f 62 20 77   Return a blob w
15dc0 68 69 63 68 20 69 73 20 61 20 70 6f 69 6e 74 65  hich is a pointe
15dd0 72 20 74 6f 20 74 68 65 20 63 75 72 73 6f 72 0a  r to the cursor.
15de0 20 20 20 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74      */.    sqlit
15df0 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28 70  e3_result_blob(p
15e00 43 6f 6e 74 65 78 74 2c 20 26 63 2c 20 73 69 7a  Context, &c, siz
15e10 65 6f 66 28 63 29 2c 20 53 51 4c 49 54 45 5f 54  eof(c), SQLITE_T
15e20 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 20  RANSIENT);.  }. 
15e30 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
15e40 4b 3b 0a 7d 0a 0a 2f 2a 20 54 68 69 73 20 69 73  K;.}../* This is
15e50 20 74 68 65 20 78 52 6f 77 69 64 20 6d 65 74 68   the xRowid meth
15e60 6f 64 2e 20 20 54 68 65 20 53 51 4c 69 74 65 20  od.  The SQLite 
15e70 63 6f 72 65 20 63 61 6c 6c 73 20 74 68 69 73 20  core calls this 
15e80 72 6f 75 74 69 6e 65 20 74 6f 0a 2a 2a 20 72 65  routine to.** re
15e90 74 72 69 76 65 20 74 68 65 20 72 6f 77 69 64 20  trive the rowid 
15ea0 66 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74 20  for the current 
15eb0 72 6f 77 20 6f 66 20 74 68 65 20 72 65 73 75 6c  row of the resul
15ec0 74 20 73 65 74 2e 20 20 54 68 65 0a 2a 2a 20 72  t set.  The.** r
15ed0 6f 77 69 64 20 73 68 6f 75 6c 64 20 62 65 20 77  owid should be w
15ee0 72 69 74 74 65 6e 20 74 6f 20 2a 70 52 6f 77 69  ritten to *pRowi
15ef0 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
15f00 20 66 75 6c 6c 74 65 78 74 52 6f 77 69 64 28 73   fulltextRowid(s
15f10 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
15f20 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 73 71 6c  or *pCursor, sql
15f30 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69  ite_int64 *pRowi
15f40 64 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63  d){.  fulltext_c
15f50 75 72 73 6f 72 20 2a 63 20 3d 20 28 66 75 6c 6c  ursor *c = (full
15f60 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 29 20 70  text_cursor *) p
15f70 43 75 72 73 6f 72 3b 0a 0a 20 20 2a 70 52 6f 77  Cursor;..  *pRow
15f80 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c  id = sqlite3_col
15f90 75 6d 6e 5f 69 6e 74 36 34 28 63 2d 3e 70 53 74  umn_int64(c->pSt
15fa0 6d 74 2c 20 30 29 3b 0a 20 20 72 65 74 75 72 6e  mt, 0);.  return
15fb0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
15fc0 2a 20 41 64 64 20 61 6c 6c 20 74 65 72 6d 73 20  * Add all terms 
15fd0 69 6e 20 5b 7a 54 65 78 74 5d 20 74 6f 20 74 68  in [zText] to th
15fe0 65 20 67 69 76 65 6e 20 68 61 73 68 20 74 61 62  e given hash tab
15ff0 6c 65 2e 20 20 49 66 20 5b 69 43 6f 6c 75 6d 6e  le.  If [iColumn
16000 5d 20 3e 20 30 2c 0a 20 2a 20 77 65 20 61 6c 73  ] > 0,. * we als
16010 6f 20 73 74 6f 72 65 20 70 6f 73 69 74 69 6f 6e  o store position
16020 73 20 61 6e 64 20 6f 66 66 73 65 74 73 20 69 6e  s and offsets in
16030 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
16040 75 73 69 6e 67 20 74 68 65 20 67 69 76 65 6e 0a  using the given.
16050 20 2a 20 63 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72   * column number
16060 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
16070 62 75 69 6c 64 54 65 72 6d 73 28 66 75 6c 6c 74  buildTerms(fullt
16080 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 66 74 73  ext_vtab *v, fts
16090 31 48 61 73 68 20 2a 74 65 72 6d 73 2c 20 73 71  1Hash *terms, sq
160a0 6c 69 74 65 5f 69 6e 74 36 34 20 69 44 6f 63 69  lite_int64 iDoci
160b0 64 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  d,.             
160c0 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63           const c
160d0 68 61 72 20 2a 7a 54 65 78 74 2c 20 69 6e 74 20  har *zText, int 
160e0 69 43 6f 6c 75 6d 6e 29 7b 0a 20 20 73 71 6c 69  iColumn){.  sqli
160f0 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a 70  te3_tokenizer *p
16100 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 76 2d 3e 70  Tokenizer = v->p
16110 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20 73 71 6c  Tokenizer;.  sql
16120 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63  ite3_tokenizer_c
16130 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 3b 0a  ursor *pCursor;.
16140 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54    const char *pT
16150 6f 6b 65 6e 3b 0a 20 20 69 6e 74 20 6e 54 6f 6b  oken;.  int nTok
16160 65 6e 42 79 74 65 73 3b 0a 20 20 69 6e 74 20 69  enBytes;.  int i
16170 53 74 61 72 74 4f 66 66 73 65 74 2c 20 69 45 6e  StartOffset, iEn
16180 64 4f 66 66 73 65 74 2c 20 69 50 6f 73 69 74 69  dOffset, iPositi
16190 6f 6e 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20  on;.  int rc;.. 
161a0 20 72 63 20 3d 20 70 54 6f 6b 65 6e 69 7a 65 72   rc = pTokenizer
161b0 2d 3e 70 4d 6f 64 75 6c 65 2d 3e 78 4f 70 65 6e  ->pModule->xOpen
161c0 28 70 54 6f 6b 65 6e 69 7a 65 72 2c 20 7a 54 65  (pTokenizer, zTe
161d0 78 74 2c 20 2d 31 2c 20 26 70 43 75 72 73 6f 72  xt, -1, &pCursor
161e0 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
161f0 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
16200 72 63 3b 0a 0a 20 20 70 43 75 72 73 6f 72 2d 3e  rc;..  pCursor->
16210 70 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 70 54 6f  pTokenizer = pTo
16220 6b 65 6e 69 7a 65 72 3b 0a 20 20 77 68 69 6c 65  kenizer;.  while
16230 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 70 54 6f  ( SQLITE_OK==pTo
16240 6b 65 6e 69 7a 65 72 2d 3e 70 4d 6f 64 75 6c 65  kenizer->pModule
16250 2d 3e 78 4e 65 78 74 28 70 43 75 72 73 6f 72 2c  ->xNext(pCursor,
16260 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
16270 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16280 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16290 26 70 54 6f 6b 65 6e 2c 20 26 6e 54 6f 6b 65 6e  &pToken, &nToken
162a0 42 79 74 65 73 2c 0a 20 20 20 20 20 20 20 20 20  Bytes,.         
162b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
162c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
162d0 20 20 20 20 20 20 26 69 53 74 61 72 74 4f 66 66        &iStartOff
162e0 73 65 74 2c 20 26 69 45 6e 64 4f 66 66 73 65 74  set, &iEndOffset
162f0 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
16300 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16310 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16320 20 26 69 50 6f 73 69 74 69 6f 6e 29 20 29 7b 0a   &iPosition) ){.
16330 20 20 20 20 44 6f 63 4c 69 73 74 20 2a 70 3b 0a      DocList *p;.
16340 0a 20 20 20 20 2f 2a 20 50 6f 73 69 74 69 6f 6e  .    /* Position
16350 73 20 63 61 6e 27 74 20 62 65 20 6e 65 67 61 74  s can't be negat
16360 69 76 65 3b 20 77 65 20 75 73 65 20 2d 31 20 61  ive; we use -1 a
16370 73 20 61 20 74 65 72 6d 69 6e 61 74 6f 72 20 69  s a terminator i
16380 6e 74 65 72 6e 61 6c 6c 79 2e 20 2a 2f 0a 20 20  nternally. */.  
16390 20 20 69 66 28 20 69 50 6f 73 69 74 69 6f 6e 3c    if( iPosition<
163a0 30 20 29 7b 0a 20 20 20 20 20 20 70 54 6f 6b 65  0 ){.      pToke
163b0 6e 69 7a 65 72 2d 3e 70 4d 6f 64 75 6c 65 2d 3e  nizer->pModule->
163c0 78 43 6c 6f 73 65 28 70 43 75 72 73 6f 72 29 3b  xClose(pCursor);
163d0 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
163e0 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20  LITE_ERROR;.    
163f0 7d 0a 0a 20 20 20 20 70 20 3d 20 66 74 73 31 48  }..    p = fts1H
16400 61 73 68 46 69 6e 64 28 74 65 72 6d 73 2c 20 70  ashFind(terms, p
16410 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 42 79 74  Token, nTokenByt
16420 65 73 29 3b 0a 20 20 20 20 69 66 28 20 70 3d 3d  es);.    if( p==
16430 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 20 20 70 20  NULL ){.      p 
16440 3d 20 64 6f 63 4c 69 73 74 4e 65 77 28 44 4c 5f  = docListNew(DL_
16450 44 45 46 41 55 4c 54 29 3b 0a 20 20 20 20 20 20  DEFAULT);.      
16460 64 6f 63 4c 69 73 74 41 64 64 44 6f 63 69 64 28  docListAddDocid(
16470 70 2c 20 69 44 6f 63 69 64 29 3b 0a 20 20 20 20  p, iDocid);.    
16480 20 20 66 74 73 31 48 61 73 68 49 6e 73 65 72 74    fts1HashInsert
16490 28 74 65 72 6d 73 2c 20 70 54 6f 6b 65 6e 2c 20  (terms, pToken, 
164a0 6e 54 6f 6b 65 6e 42 79 74 65 73 2c 20 70 29 3b  nTokenBytes, p);
164b0 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 69  .    }.    if( i
164c0 43 6f 6c 75 6d 6e 3e 3d 30 20 29 7b 0a 20 20 20  Column>=0 ){.   
164d0 20 20 20 64 6f 63 4c 69 73 74 41 64 64 50 6f 73     docListAddPos
164e0 4f 66 66 73 65 74 28 70 2c 20 69 43 6f 6c 75 6d  Offset(p, iColum
164f0 6e 2c 20 69 50 6f 73 69 74 69 6f 6e 2c 20 69 53  n, iPosition, iS
16500 74 61 72 74 4f 66 66 73 65 74 2c 20 69 45 6e 64  tartOffset, iEnd
16510 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 7d 0a 20  Offset);.    }. 
16520 20 7d 0a 0a 20 20 2f 2a 20 54 4f 44 4f 28 73 68   }..  /* TODO(sh
16530 65 73 73 29 20 43 68 65 63 6b 20 72 65 74 75 72  ess) Check retur
16540 6e 3f 20 20 53 68 6f 75 6c 64 20 74 68 69 73 20  n?  Should this 
16550 62 65 20 61 62 6c 65 20 74 6f 20 63 61 75 73 65  be able to cause
16560 20 65 72 72 6f 72 73 20 61 74 0a 20 20 2a 2a 20   errors at.  ** 
16570 74 68 69 73 20 70 6f 69 6e 74 3f 20 20 41 63 74  this point?  Act
16580 75 61 6c 6c 79 2c 20 73 61 6d 65 20 71 75 65 73  ually, same ques
16590 74 69 6f 6e 20 61 62 6f 75 74 20 73 71 6c 69 74  tion about sqlit
165a0 65 33 5f 66 69 6e 61 6c 69 7a 65 28 29 2c 0a 20  e3_finalize(),. 
165b0 20 2a 2a 20 74 68 6f 75 67 68 20 6f 6e 65 20 63   ** though one c
165c0 6f 75 6c 64 20 61 72 67 75 65 20 74 68 61 74 20  ould argue that 
165d0 66 61 69 6c 75 72 65 20 74 68 65 72 65 20 6d 65  failure there me
165e0 61 6e 73 20 74 68 61 74 20 74 68 65 20 64 61 74  ans that the dat
165f0 61 20 69 73 0a 20 20 2a 2a 20 6e 6f 74 20 64 75  a is.  ** not du
16600 72 61 62 6c 65 2e 20 20 2a 70 6f 6e 64 65 72 2a  rable.  *ponder*
16610 0a 20 20 2a 2f 0a 20 20 70 54 6f 6b 65 6e 69 7a  .  */.  pTokeniz
16620 65 72 2d 3e 70 4d 6f 64 75 6c 65 2d 3e 78 43 6c  er->pModule->xCl
16630 6f 73 65 28 70 43 75 72 73 6f 72 29 3b 0a 20 20  ose(pCursor);.  
16640 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
16650 20 55 70 64 61 74 65 20 74 68 65 20 25 5f 74 65   Update the %_te
16660 72 6d 73 20 74 61 62 6c 65 20 74 6f 20 6d 61 70  rms table to map
16670 20 74 68 65 20 74 65 72 6d 20 5b 70 54 65 72 6d   the term [pTerm
16680 5d 20 74 6f 20 74 68 65 20 67 69 76 65 6e 20 72  ] to the given r
16690 6f 77 69 64 2e 20 2a 2f 0a 73 74 61 74 69 63 20  owid. */.static 
166a0 69 6e 74 20 69 6e 64 65 78 5f 69 6e 73 65 72 74  int index_insert
166b0 5f 74 65 72 6d 28 66 75 6c 6c 74 65 78 74 5f 76  _term(fulltext_v
166c0 74 61 62 20 2a 76 2c 20 63 6f 6e 73 74 20 63 68  tab *v, const ch
166d0 61 72 20 2a 70 54 65 72 6d 2c 20 69 6e 74 20 6e  ar *pTerm, int n
166e0 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20 20 20  Term,.          
166f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16700 20 20 20 44 6f 63 4c 69 73 74 20 2a 64 29 7b 0a     DocList *d){.
16710 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69    sqlite_int64 i
16720 49 6e 64 65 78 52 6f 77 3b 0a 20 20 44 6f 63 4c  IndexRow;.  DocL
16730 69 73 74 20 64 6f 63 6c 69 73 74 3b 0a 20 20 69  ist doclist;.  i
16740 6e 74 20 69 53 65 67 6d 65 6e 74 20 3d 20 30 2c  nt iSegment = 0,
16750 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 74 65 72   rc;..  rc = ter
16760 6d 5f 73 65 6c 65 63 74 28 76 2c 20 70 54 65 72  m_select(v, pTer
16770 6d 2c 20 6e 54 65 72 6d 2c 20 69 53 65 67 6d 65  m, nTerm, iSegme
16780 6e 74 2c 20 26 69 49 6e 64 65 78 52 6f 77 2c 20  nt, &iIndexRow, 
16790 26 64 6f 63 6c 69 73 74 29 3b 0a 20 20 69 66 28  &doclist);.  if(
167a0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45   rc==SQLITE_DONE
167b0 20 29 7b 0a 20 20 20 20 64 6f 63 4c 69 73 74 49   ){.    docListI
167c0 6e 69 74 28 26 64 6f 63 6c 69 73 74 2c 20 44 4c  nit(&doclist, DL
167d0 5f 44 45 46 41 55 4c 54 2c 20 30 2c 20 30 29 3b  _DEFAULT, 0, 0);
167e0 0a 20 20 20 20 64 6f 63 4c 69 73 74 55 70 64 61  .    docListUpda
167f0 74 65 28 26 64 6f 63 6c 69 73 74 2c 20 64 29 3b  te(&doclist, d);
16800 0a 20 20 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65  .    /* TODO(she
16810 73 73 29 20 43 6f 6e 73 69 64 65 72 20 6c 65 6e  ss) Consider len
16820 67 74 68 28 64 6f 63 6c 69 73 74 29 3e 43 48 55  gth(doclist)>CHU
16830 4e 4b 5f 4d 41 58 3f 20 2a 2f 0a 20 20 20 20 72  NK_MAX? */.    r
16840 63 20 3d 20 74 65 72 6d 5f 69 6e 73 65 72 74 28  c = term_insert(
16850 76 2c 20 4e 55 4c 4c 2c 20 70 54 65 72 6d 2c 20  v, NULL, pTerm, 
16860 6e 54 65 72 6d 2c 20 69 53 65 67 6d 65 6e 74 2c  nTerm, iSegment,
16870 20 26 64 6f 63 6c 69 73 74 29 3b 0a 20 20 20 20   &doclist);.    
16880 67 6f 74 6f 20 65 72 72 3b 0a 20 20 7d 0a 20 20  goto err;.  }.  
16890 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 52  if( rc!=SQLITE_R
168a0 4f 57 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  OW ) return SQLI
168b0 54 45 5f 45 52 52 4f 52 3b 0a 0a 20 20 64 6f 63  TE_ERROR;..  doc
168c0 4c 69 73 74 55 70 64 61 74 65 28 26 64 6f 63 6c  ListUpdate(&docl
168d0 69 73 74 2c 20 64 29 3b 0a 20 20 69 66 28 20 64  ist, d);.  if( d
168e0 6f 63 6c 69 73 74 2e 6e 44 61 74 61 3c 3d 43 48  oclist.nData<=CH
168f0 55 4e 4b 5f 4d 41 58 20 29 7b 0a 20 20 20 20 72  UNK_MAX ){.    r
16900 63 20 3d 20 74 65 72 6d 5f 75 70 64 61 74 65 28  c = term_update(
16910 76 2c 20 69 49 6e 64 65 78 52 6f 77 2c 20 26 64  v, iIndexRow, &d
16920 6f 63 6c 69 73 74 29 3b 0a 20 20 20 20 67 6f 74  oclist);.    got
16930 6f 20 65 72 72 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  o err;.  }..  /*
16940 20 44 6f 63 6c 69 73 74 20 64 6f 65 73 6e 27 74   Doclist doesn't
16950 20 66 69 74 2c 20 64 65 6c 65 74 65 20 77 68 61   fit, delete wha
16960 74 27 73 20 74 68 65 72 65 2c 20 61 6e 64 20 61  t's there, and a
16970 63 63 75 6d 75 6c 61 74 65 0a 20 20 2a 2a 20 66  ccumulate.  ** f
16980 6f 72 77 61 72 64 2e 0a 20 20 2a 2f 0a 20 20 72  orward..  */.  r
16990 63 20 3d 20 74 65 72 6d 5f 64 65 6c 65 74 65 28  c = term_delete(
169a0 76 2c 20 69 49 6e 64 65 78 52 6f 77 29 3b 0a 20  v, iIndexRow);. 
169b0 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
169c0 4f 4b 20 29 20 67 6f 74 6f 20 65 72 72 3b 0a 0a  OK ) goto err;..
169d0 20 20 2f 2a 20 54 72 79 20 74 6f 20 69 6e 73 65    /* Try to inse
169e0 72 74 20 74 68 65 20 64 6f 63 6c 69 73 74 20 69  rt the doclist i
169f0 6e 74 6f 20 61 20 68 69 67 68 65 72 20 73 65 67  nto a higher seg
16a00 6d 65 6e 74 20 62 75 63 6b 65 74 2e 20 20 4f 6e  ment bucket.  On
16a10 0a 20 20 2a 2a 20 66 61 69 6c 75 72 65 2c 20 61  .  ** failure, a
16a20 63 63 75 6d 75 6c 61 74 65 20 65 78 69 73 74 69  ccumulate existi
16a30 6e 67 20 64 6f 63 6c 69 73 74 20 77 69 74 68 20  ng doclist with 
16a40 74 68 65 20 64 6f 63 6c 69 73 74 20 66 72 6f 6d  the doclist from
16a50 20 74 68 61 74 0a 20 20 2a 2a 20 62 75 63 6b 65   that.  ** bucke
16a60 74 2c 20 61 6e 64 20 70 75 74 20 72 65 73 75 6c  t, and put resul
16a70 74 73 20 69 6e 20 74 68 65 20 6e 65 78 74 20 62  ts in the next b
16a80 75 63 6b 65 74 2e 0a 20 20 2a 2f 0a 20 20 69 53  ucket..  */.  iS
16a90 65 67 6d 65 6e 74 2b 2b 3b 0a 20 20 77 68 69 6c  egment++;.  whil
16aa0 65 28 20 28 72 63 3d 74 65 72 6d 5f 69 6e 73 65  e( (rc=term_inse
16ab0 72 74 28 76 2c 20 26 69 49 6e 64 65 78 52 6f 77  rt(v, &iIndexRow
16ac0 2c 20 70 54 65 72 6d 2c 20 6e 54 65 72 6d 2c 20  , pTerm, nTerm, 
16ad0 69 53 65 67 6d 65 6e 74 2c 0a 20 20 20 20 20 20  iSegment,.      
16ae0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16af0 20 20 20 26 64 6f 63 6c 69 73 74 29 29 21 3d 53     &doclist))!=S
16b00 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
16b10 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 53 65  sqlite_int64 iSe
16b20 67 6d 65 6e 74 52 6f 77 3b 0a 20 20 20 20 44 6f  gmentRow;.    Do
16b30 63 4c 69 73 74 20 6f 6c 64 3b 0a 20 20 20 20 69  cList old;.    i
16b40 6e 74 20 72 63 32 3b 0a 0a 20 20 20 20 2f 2a 20  nt rc2;..    /* 
16b50 52 65 74 61 69 6e 20 6f 6c 64 20 65 72 72 6f 72  Retain old error
16b60 20 69 6e 20 63 61 73 65 20 74 68 65 20 74 65 72   in case the ter
16b70 6d 5f 69 6e 73 65 72 74 28 29 20 65 72 72 6f 72  m_insert() error
16b80 20 77 61 73 20 72 65 61 6c 6c 79 20 61 6e 0a 20   was really an. 
16b90 20 20 20 2a 2a 20 65 72 72 6f 72 20 72 61 74 68     ** error rath
16ba0 65 72 20 74 68 61 6e 20 61 20 62 6f 75 6e 63 65  er than a bounce
16bb0 64 20 69 6e 73 65 72 74 2e 0a 20 20 20 20 2a 2f  d insert..    */
16bc0 0a 20 20 20 20 72 63 32 20 3d 20 74 65 72 6d 5f  .    rc2 = term_
16bd0 73 65 6c 65 63 74 28 76 2c 20 70 54 65 72 6d 2c  select(v, pTerm,
16be0 20 6e 54 65 72 6d 2c 20 69 53 65 67 6d 65 6e 74   nTerm, iSegment
16bf0 2c 20 26 69 53 65 67 6d 65 6e 74 52 6f 77 2c 20  , &iSegmentRow, 
16c00 26 6f 6c 64 29 3b 0a 20 20 20 20 69 66 28 20 72  &old);.    if( r
16c10 63 32 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  c2!=SQLITE_ROW )
16c20 20 67 6f 74 6f 20 65 72 72 3b 0a 0a 20 20 20 20   goto err;..    
16c30 72 63 20 3d 20 74 65 72 6d 5f 64 65 6c 65 74 65  rc = term_delete
16c40 28 76 2c 20 69 53 65 67 6d 65 6e 74 52 6f 77 29  (v, iSegmentRow)
16c50 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
16c60 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 65  LITE_OK ) goto e
16c70 72 72 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 75 73  rr;..    /* Reus
16c80 69 6e 67 20 6c 6f 77 65 73 74 2d 6e 75 6d 62 65  ing lowest-numbe
16c90 72 20 64 65 6c 65 74 65 64 20 72 6f 77 20 6b 65  r deleted row ke
16ca0 65 70 73 20 74 68 65 20 69 6e 64 65 78 20 73 6d  eps the index sm
16cb0 61 6c 6c 65 72 2e 20 2a 2f 0a 20 20 20 20 69 66  aller. */.    if
16cc0 28 20 69 53 65 67 6d 65 6e 74 52 6f 77 3c 69 49  ( iSegmentRow<iI
16cd0 6e 64 65 78 52 6f 77 20 29 20 69 49 6e 64 65 78  ndexRow ) iIndex
16ce0 52 6f 77 20 3d 20 69 53 65 67 6d 65 6e 74 52 6f  Row = iSegmentRo
16cf0 77 3b 0a 0a 20 20 20 20 2f 2a 20 64 6f 63 6c 69  w;..    /* docli
16d00 73 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  st contains the 
16d10 6e 65 77 65 72 20 64 61 74 61 2c 20 73 6f 20 61  newer data, so a
16d20 63 63 75 6d 75 6c 61 74 65 20 69 74 20 6f 76 65  ccumulate it ove
16d30 72 20 6f 6c 64 2e 0a 20 20 20 20 2a 2a 20 54 68  r old..    ** Th
16d40 65 6e 20 73 74 65 61 6c 20 61 63 63 75 6d 75 6c  en steal accumul
16d50 61 74 65 64 20 64 61 74 61 20 66 6f 72 20 64 6f  ated data for do
16d60 63 6c 69 73 74 2e 0a 20 20 20 20 2a 2f 0a 20 20  clist..    */.  
16d70 20 20 64 6f 63 4c 69 73 74 41 63 63 75 6d 75 6c    docListAccumul
16d80 61 74 65 28 26 6f 6c 64 2c 20 26 64 6f 63 6c 69  ate(&old, &docli
16d90 73 74 29 3b 0a 20 20 20 20 64 6f 63 4c 69 73 74  st);.    docList
16da0 44 65 73 74 72 6f 79 28 26 64 6f 63 6c 69 73 74  Destroy(&doclist
16db0 29 3b 0a 20 20 20 20 64 6f 63 6c 69 73 74 20 3d  );.    doclist =
16dc0 20 6f 6c 64 3b 0a 0a 20 20 20 20 69 53 65 67 6d   old;..    iSegm
16dd0 65 6e 74 2b 2b 3b 0a 20 20 7d 0a 0a 20 65 72 72  ent++;.  }.. err
16de0 3a 0a 20 20 64 6f 63 4c 69 73 74 44 65 73 74 72  :.  docListDestr
16df0 6f 79 28 26 64 6f 63 6c 69 73 74 29 3b 0a 20 20  oy(&doclist);.  
16e00 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
16e10 20 41 64 64 20 64 6f 63 6c 69 73 74 73 20 66 6f   Add doclists fo
16e20 72 20 61 6c 6c 20 74 65 72 6d 73 20 69 6e 20 5b  r all terms in [
16e30 70 56 61 6c 75 65 73 5d 20 74 6f 20 74 68 65 20  pValues] to the 
16e40 68 61 73 68 20 74 61 62 6c 65 20 5b 74 65 72 6d  hash table [term
16e50 73 5d 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  s]. */.static in
16e60 74 20 69 6e 73 65 72 74 54 65 72 6d 73 28 66 75  t insertTerms(fu
16e70 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20  lltext_vtab *v, 
16e80 66 74 73 31 48 61 73 68 20 2a 74 65 72 6d 73 2c  fts1Hash *terms,
16e90 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 52   sqlite_int64 iR
16ea0 6f 77 69 64 2c 0a 20 20 20 20 20 20 20 20 20 20  owid,.          
16eb0 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61        sqlite3_va
16ec0 6c 75 65 20 2a 2a 70 56 61 6c 75 65 73 29 7b 0a  lue **pValues){.
16ed0 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69    int i;.  for(i
16ee0 20 3d 20 30 3b 20 69 20 3c 20 76 2d 3e 6e 43 6f   = 0; i < v->nCo
16ef0 6c 75 6d 6e 20 3b 20 2b 2b 69 29 7b 0a 20 20 20  lumn ; ++i){.   
16f00 20 63 68 61 72 20 2a 7a 54 65 78 74 20 3d 20 28   char *zText = (
16f10 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61  char*)sqlite3_va
16f20 6c 75 65 5f 74 65 78 74 28 70 56 61 6c 75 65 73  lue_text(pValues
16f30 5b 69 5d 29 3b 0a 20 20 20 20 69 6e 74 20 72 63  [i]);.    int rc
16f40 20 3d 20 62 75 69 6c 64 54 65 72 6d 73 28 76 2c   = buildTerms(v,
16f50 20 74 65 72 6d 73 2c 20 69 52 6f 77 69 64 2c 20   terms, iRowid, 
16f60 7a 54 65 78 74 2c 20 69 29 3b 0a 20 20 20 20 69  zText, i);.    i
16f70 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
16f80 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
16f90 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  }.  return SQLIT
16fa0 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 41 64 64 20  E_OK;.}../* Add 
16fb0 65 6d 70 74 79 20 64 6f 63 6c 69 73 74 73 20 66  empty doclists f
16fc0 6f 72 20 61 6c 6c 20 74 65 72 6d 73 20 69 6e 20  or all terms in 
16fd0 74 68 65 20 67 69 76 65 6e 20 72 6f 77 27 73 20  the given row's 
16fe0 63 6f 6e 74 65 6e 74 20 74 6f 20 74 68 65 20 68  content to the h
16ff0 61 73 68 0a 20 2a 20 74 61 62 6c 65 20 5b 70 54  ash. * table [pT
17000 65 72 6d 73 5d 2e 20 2a 2f 0a 73 74 61 74 69 63  erms]. */.static
17010 20 69 6e 74 20 64 65 6c 65 74 65 54 65 72 6d 73   int deleteTerms
17020 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
17030 76 2c 20 66 74 73 31 48 61 73 68 20 2a 70 54 65  v, fts1Hash *pTe
17040 72 6d 73 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36  rms, sqlite_int6
17050 34 20 69 52 6f 77 69 64 29 7b 0a 20 20 63 6f 6e  4 iRowid){.  con
17060 73 74 20 63 68 61 72 20 2a 2a 70 56 61 6c 75 65  st char **pValue
17070 73 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69  s;.  int i;..  i
17080 6e 74 20 72 63 20 3d 20 63 6f 6e 74 65 6e 74 5f  nt rc = content_
17090 73 65 6c 65 63 74 28 76 2c 20 69 52 6f 77 69 64  select(v, iRowid
170a0 2c 20 26 70 56 61 6c 75 65 73 29 3b 0a 20 20 69  , &pValues);.  i
170b0 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
170c0 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
170d0 20 66 6f 72 28 69 20 3d 20 30 20 3b 20 69 20 3c   for(i = 0 ; i <
170e0 20 76 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69   v->nColumn; ++i
170f0 29 20 7b 0a 20 20 20 20 72 63 20 3d 20 62 75 69  ) {.    rc = bui
17100 6c 64 54 65 72 6d 73 28 76 2c 20 70 54 65 72 6d  ldTerms(v, pTerm
17110 73 2c 20 69 52 6f 77 69 64 2c 20 70 56 61 6c 75  s, iRowid, pValu
17120 65 73 5b 69 5d 2c 20 2d 31 29 3b 0a 20 20 20 20  es[i], -1);.    
17130 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
17140 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a  K ) break;.  }..
17150 20 20 66 72 65 65 53 74 72 69 6e 67 41 72 72 61    freeStringArra
17160 79 28 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 70 56  y(v->nColumn, pV
17170 61 6c 75 65 73 29 3b 0a 20 20 72 65 74 75 72 6e  alues);.  return
17180 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
17190 2a 20 49 6e 73 65 72 74 20 61 20 72 6f 77 20 69  * Insert a row i
171a0 6e 74 6f 20 74 68 65 20 25 5f 63 6f 6e 74 65 6e  nto the %_conten
171b0 74 20 74 61 62 6c 65 3b 20 73 65 74 20 2a 70 69  t table; set *pi
171c0 52 6f 77 69 64 20 74 6f 20 62 65 20 74 68 65 20  Rowid to be the 
171d0 49 44 20 6f 66 20 74 68 65 0a 20 2a 20 6e 65 77  ID of the. * new
171e0 20 72 6f 77 2e 20 20 46 69 6c 6c 20 5b 70 54 65   row.  Fill [pTe
171f0 72 6d 73 5d 20 77 69 74 68 20 6e 65 77 20 64 6f  rms] with new do
17200 63 6c 69 73 74 73 20 66 6f 72 20 74 68 65 20 25  clists for the %
17210 5f 74 65 72 6d 20 74 61 62 6c 65 2e 20 2a 2f 0a  _term table. */.
17220 73 74 61 74 69 63 20 69 6e 74 20 69 6e 64 65 78  static int index
17230 5f 69 6e 73 65 72 74 28 66 75 6c 6c 74 65 78 74  _insert(fulltext
17240 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65  _vtab *v, sqlite
17250 33 5f 76 61 6c 75 65 20 2a 70 52 65 71 75 65 73  3_value *pReques
17260 74 52 6f 77 69 64 2c 0a 20 20 20 20 20 20 20 20  tRowid,.        
17270 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17280 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
17290 70 56 61 6c 75 65 73 2c 0a 20 20 20 20 20 20 20  pValues,.       
172a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
172b0 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70   sqlite_int64 *p
172c0 69 52 6f 77 69 64 2c 20 66 74 73 31 48 61 73 68  iRowid, fts1Hash
172d0 20 2a 70 54 65 72 6d 73 29 7b 0a 20 20 69 6e 74   *pTerms){.  int
172e0 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 63 6f 6e   rc;..  rc = con
172f0 74 65 6e 74 5f 69 6e 73 65 72 74 28 76 2c 20 70  tent_insert(v, p
17300 52 65 71 75 65 73 74 52 6f 77 69 64 2c 20 70 56  RequestRowid, pV
17310 61 6c 75 65 73 29 3b 20 20 2f 2a 20 65 78 65 63  alues);  /* exec
17320 75 74 65 20 61 6e 20 53 51 4c 20 49 4e 53 45 52  ute an SQL INSER
17330 54 20 2a 2f 0a 20 20 69 66 28 20 72 63 21 3d 53  T */.  if( rc!=S
17340 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
17350 6e 20 72 63 3b 0a 20 20 2a 70 69 52 6f 77 69 64  n rc;.  *piRowid
17360 20 3d 20 73 71 6c 69 74 65 33 5f 6c 61 73 74 5f   = sqlite3_last_
17370 69 6e 73 65 72 74 5f 72 6f 77 69 64 28 76 2d 3e  insert_rowid(v->
17380 64 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 69 6e  db);.  return in
17390 73 65 72 74 54 65 72 6d 73 28 76 2c 20 70 54 65  sertTerms(v, pTe
173a0 72 6d 73 2c 20 2a 70 69 52 6f 77 69 64 2c 20 70  rms, *piRowid, p
173b0 56 61 6c 75 65 73 29 3b 0a 7d 0a 0a 2f 2a 20 44  Values);.}../* D
173c0 65 6c 65 74 65 20 61 20 72 6f 77 20 66 72 6f 6d  elete a row from
173d0 20 74 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74   the %_content t
173e0 61 62 6c 65 3b 20 66 69 6c 6c 20 5b 70 54 65 72  able; fill [pTer
173f0 6d 73 5d 20 77 69 74 68 20 65 6d 70 74 79 20 64  ms] with empty d
17400 6f 63 6c 69 73 74 73 0a 20 2a 20 74 6f 20 62 65  oclists. * to be
17410 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20   written to the 
17420 25 5f 74 65 72 6d 20 74 61 62 6c 65 2e 20 2a 2f  %_term table. */
17430 0a 73 74 61 74 69 63 20 69 6e 74 20 69 6e 64 65  .static int inde
17440 78 5f 64 65 6c 65 74 65 28 66 75 6c 6c 74 65 78  x_delete(fulltex
17450 74 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74  t_vtab *v, sqlit
17460 65 5f 69 6e 74 36 34 20 69 52 6f 77 2c 20 66 74  e_int64 iRow, ft
17470 73 31 48 61 73 68 20 2a 70 54 65 72 6d 73 29 7b  s1Hash *pTerms){
17480 0a 20 20 69 6e 74 20 72 63 20 3d 20 64 65 6c 65  .  int rc = dele
17490 74 65 54 65 72 6d 73 28 76 2c 20 70 54 65 72 6d  teTerms(v, pTerm
174a0 73 2c 20 69 52 6f 77 29 3b 0a 20 20 69 66 28 20  s, iRow);.  if( 
174b0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
174c0 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 72 65 74  return rc;.  ret
174d0 75 72 6e 20 63 6f 6e 74 65 6e 74 5f 64 65 6c 65  urn content_dele
174e0 74 65 28 76 2c 20 69 52 6f 77 29 3b 20 20 2f 2a  te(v, iRow);  /*
174f0 20 65 78 65 63 75 74 65 20 61 6e 20 53 51 4c 20   execute an SQL 
17500 44 45 4c 45 54 45 20 2a 2f 0a 7d 0a 0a 2f 2a 20  DELETE */.}../* 
17510 55 70 64 61 74 65 20 61 20 72 6f 77 20 69 6e 20  Update a row in 
17520 74 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61  the %_content ta
17530 62 6c 65 3b 20 66 69 6c 6c 20 5b 70 54 65 72 6d  ble; fill [pTerm
17540 73 5d 20 77 69 74 68 20 6e 65 77 20 64 6f 63 6c  s] with new docl
17550 69 73 74 73 20 66 6f 72 20 74 68 65 0a 20 2a 20  ists for the. * 
17560 25 5f 74 65 72 6d 20 74 61 62 6c 65 2e 20 2a 2f  %_term table. */
17570 0a 73 74 61 74 69 63 20 69 6e 74 20 69 6e 64 65  .static int inde
17580 78 5f 75 70 64 61 74 65 28 66 75 6c 6c 74 65 78  x_update(fulltex
17590 74 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74  t_vtab *v, sqlit
175a0 65 5f 69 6e 74 36 34 20 69 52 6f 77 2c 0a 20 20  e_int64 iRow,.  
175b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
175c0 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61        sqlite3_va
175d0 6c 75 65 20 2a 2a 70 56 61 6c 75 65 73 2c 20 66  lue **pValues, f
175e0 74 73 31 48 61 73 68 20 2a 70 54 65 72 6d 73 29  ts1Hash *pTerms)
175f0 7b 0a 20 20 2f 2a 20 47 65 6e 65 72 61 74 65 20  {.  /* Generate 
17600 61 6e 20 65 6d 70 74 79 20 64 6f 63 6c 69 73 74  an empty doclist
17610 20 66 6f 72 20 65 61 63 68 20 74 65 72 6d 20 74   for each term t
17620 68 61 74 20 70 72 65 76 69 6f 75 73 6c 79 20 61  hat previously a
17630 70 70 65 61 72 65 64 20 69 6e 20 74 68 69 73 0a  ppeared in this.
17640 20 20 20 2a 20 72 6f 77 2e 20 2a 2f 0a 20 20 69     * row. */.  i
17650 6e 74 20 72 63 20 3d 20 64 65 6c 65 74 65 54 65  nt rc = deleteTe
17660 72 6d 73 28 76 2c 20 70 54 65 72 6d 73 2c 20 69  rms(v, pTerms, i
17670 52 6f 77 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  Row);.  if( rc!=
17680 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
17690 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 63  rn rc;..  rc = c
176a0 6f 6e 74 65 6e 74 5f 75 70 64 61 74 65 28 76 2c  ontent_update(v,
176b0 20 70 56 61 6c 75 65 73 2c 20 69 52 6f 77 29 3b   pValues, iRow);
176c0 20 20 2f 2a 20 65 78 65 63 75 74 65 20 61 6e 20    /* execute an 
176d0 53 51 4c 20 55 50 44 41 54 45 20 2a 2f 0a 20 20  SQL UPDATE */.  
176e0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
176f0 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
17700 20 20 2f 2a 20 4e 6f 77 20 61 64 64 20 70 6f 73    /* Now add pos
17710 69 74 69 6f 6e 73 20 66 6f 72 20 74 65 72 6d 73  itions for terms
17720 20 77 68 69 63 68 20 61 70 70 65 61 72 20 69 6e   which appear in
17730 20 74 68 65 20 75 70 64 61 74 65 64 20 72 6f 77   the updated row
17740 2e 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20 69 6e  . */.  return in
17750 73 65 72 74 54 65 72 6d 73 28 76 2c 20 70 54 65  sertTerms(v, pTe
17760 72 6d 73 2c 20 69 52 6f 77 2c 20 70 56 61 6c 75  rms, iRow, pValu
17770 65 73 29 3b 0a 7d 0a 0a 2f 2a 20 54 68 69 73 20  es);.}../* This 
17780 66 75 6e 63 74 69 6f 6e 20 69 6d 70 6c 65 6d 65  function impleme
17790 6e 74 73 20 74 68 65 20 78 55 70 64 61 74 65 20  nts the xUpdate 
177a0 63 61 6c 6c 62 61 63 6b 3b 20 69 74 20 69 73 20  callback; it is 
177b0 74 68 65 20 74 6f 70 2d 6c 65 76 65 6c 20 65 6e  the top-level en
177c0 74 72 79 0a 20 2a 20 70 6f 69 6e 74 20 66 6f 72  try. * point for
177d0 20 69 6e 73 65 72 74 69 6e 67 2c 20 64 65 6c 65   inserting, dele
177e0 74 69 6e 67 20 6f 72 20 75 70 64 61 74 69 6e 67  ting or updating
177f0 20 61 20 72 6f 77 20 69 6e 20 61 20 66 75 6c 6c   a row in a full
17800 2d 74 65 78 74 20 74 61 62 6c 65 2e 20 2a 2f 0a  -text table. */.
17810 73 74 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 74  static int fullt
17820 65 78 74 55 70 64 61 74 65 28 73 71 6c 69 74 65  extUpdate(sqlite
17830 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20 69  3_vtab *pVtab, i
17840 6e 74 20 6e 41 72 67 2c 20 73 71 6c 69 74 65 33  nt nArg, sqlite3
17850 5f 76 61 6c 75 65 20 2a 2a 70 70 41 72 67 2c 0a  _value **ppArg,.
17860 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17870 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20     sqlite_int64 
17880 2a 70 52 6f 77 69 64 29 7b 0a 20 20 66 75 6c 6c  *pRowid){.  full
17890 74 65 78 74 5f 76 74 61 62 20 2a 76 20 3d 20 28  text_vtab *v = (
178a0 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29  fulltext_vtab *)
178b0 20 70 56 74 61 62 3b 0a 20 20 66 74 73 31 48 61   pVtab;.  fts1Ha
178c0 73 68 20 74 65 72 6d 73 3b 20 20 20 2f 2a 20 6d  sh terms;   /* m
178d0 61 70 73 20 74 65 72 6d 20 73 74 72 69 6e 67 20  aps term string 
178e0 2d 3e 20 50 6f 73 4c 69 73 74 20 2a 2f 0a 20 20  -> PosList */.  
178f0 69 6e 74 20 72 63 3b 0a 20 20 66 74 73 31 48 61  int rc;.  fts1Ha
17900 73 68 45 6c 65 6d 20 2a 65 3b 0a 0a 20 20 54 52  shElem *e;..  TR
17910 41 43 45 28 28 22 46 54 53 31 20 55 70 64 61 74  ACE(("FTS1 Updat
17920 65 20 25 70 5c 6e 22 2c 20 70 56 74 61 62 29 29  e %p\n", pVtab))
17930 3b 0a 20 20 0a 20 20 66 74 73 31 48 61 73 68 49  ;.  .  fts1HashI
17940 6e 69 74 28 26 74 65 72 6d 73 2c 20 46 54 53 31  nit(&terms, FTS1
17950 5f 48 41 53 48 5f 53 54 52 49 4e 47 2c 20 31 29  _HASH_STRING, 1)
17960 3b 0a 0a 20 20 69 66 28 20 6e 41 72 67 3c 32 20  ;..  if( nArg<2 
17970 29 7b 0a 20 20 20 20 72 63 20 3d 20 69 6e 64 65  ){.    rc = inde
17980 78 5f 64 65 6c 65 74 65 28 76 2c 20 73 71 6c 69  x_delete(v, sqli
17990 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28  te3_value_int64(
179a0 70 70 41 72 67 5b 30 5d 29 2c 20 26 74 65 72 6d  ppArg[0]), &term
179b0 73 29 3b 0a 20 20 7d 20 65 6c 73 65 20 69 66 28  s);.  } else if(
179c0 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
179d0 79 70 65 28 70 70 41 72 67 5b 30 5d 29 20 21 3d  ype(ppArg[0]) !=
179e0 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a   SQLITE_NULL ){.
179f0 20 20 20 20 2f 2a 20 41 6e 20 75 70 64 61 74 65      /* An update
17a00 3a 0a 20 20 20 20 20 2a 20 70 70 41 72 67 5b 30  :.     * ppArg[0
17a10 5d 20 3d 20 6f 6c 64 20 72 6f 77 69 64 0a 20 20  ] = old rowid.  
17a20 20 20 20 2a 20 70 70 41 72 67 5b 31 5d 20 3d 20     * ppArg[1] = 
17a30 6e 65 77 20 72 6f 77 69 64 0a 20 20 20 20 20 2a  new rowid.     *
17a40 20 70 70 41 72 67 5b 32 2e 2e 32 2b 76 2d 3e 6e   ppArg[2..2+v->n
17a50 43 6f 6c 75 6d 6e 2d 31 5d 20 3d 20 76 61 6c 75  Column-1] = valu
17a60 65 73 0a 20 20 20 20 20 2a 20 70 70 41 72 67 5b  es.     * ppArg[
17a70 32 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e 5d 20 3d 20  2+v->nColumn] = 
17a80 76 61 6c 75 65 20 66 6f 72 20 6d 61 67 69 63 20  value for magic 
17a90 63 6f 6c 75 6d 6e 20 28 77 65 20 69 67 6e 6f 72  column (we ignor
17aa0 65 20 74 68 69 73 29 0a 20 20 20 20 20 2a 2f 0a  e this).     */.
17ab0 20 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34      sqlite_int64
17ac0 20 72 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33   rowid = sqlite3
17ad0 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 70 70 41  _value_int64(ppA
17ae0 72 67 5b 30 5d 29 3b 0a 20 20 20 20 69 66 28 20  rg[0]);.    if( 
17af0 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
17b00 70 65 28 70 70 41 72 67 5b 31 5d 29 20 21 3d 20  pe(ppArg[1]) != 
17b10 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 7c  SQLITE_INTEGER |
17b20 7c 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  |.      sqlite3_
17b30 76 61 6c 75 65 5f 69 6e 74 36 34 28 70 70 41 72  value_int64(ppAr
17b40 67 5b 31 5d 29 20 21 3d 20 72 6f 77 69 64 20 29  g[1]) != rowid )
17b50 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
17b60 49 54 45 5f 45 52 52 4f 52 3b 20 20 2f 2a 20 77  ITE_ERROR;  /* w
17b70 65 20 64 6f 6e 27 74 20 61 6c 6c 6f 77 20 63 68  e don't allow ch
17b80 61 6e 67 69 6e 67 20 74 68 65 20 72 6f 77 69 64  anging the rowid
17b90 20 2a 2f 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b   */.    } else {
17ba0 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6e  .      assert( n
17bb0 41 72 67 3d 3d 32 2b 76 2d 3e 6e 43 6f 6c 75 6d  Arg==2+v->nColum
17bc0 6e 2b 31 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  n+1);.      rc =
17bd0 20 69 6e 64 65 78 5f 75 70 64 61 74 65 28 76 2c   index_update(v,
17be0 20 72 6f 77 69 64 2c 20 26 70 70 41 72 67 5b 32   rowid, &ppArg[2
17bf0 5d 2c 20 26 74 65 72 6d 73 29 3b 0a 20 20 20 20  ], &terms);.    
17c00 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20  }.  } else {.   
17c10 20 2f 2a 20 41 6e 20 69 6e 73 65 72 74 3a 0a 20   /* An insert:. 
17c20 20 20 20 20 2a 20 70 70 41 72 67 5b 31 5d 20 3d      * ppArg[1] =
17c30 20 72 65 71 75 65 73 74 65 64 20 72 6f 77 69 64   requested rowid
17c40 0a 20 20 20 20 20 2a 20 70 70 41 72 67 5b 32 2e  .     * ppArg[2.
17c50 2e 32 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e 2d 31 5d  .2+v->nColumn-1]
17c60 20 3d 20 76 61 6c 75 65 73 0a 20 20 20 20 20 2a   = values.     *
17c70 20 70 70 41 72 67 5b 32 2b 76 2d 3e 6e 43 6f 6c   ppArg[2+v->nCol
17c80 75 6d 6e 5d 20 3d 20 76 61 6c 75 65 20 66 6f 72  umn] = value for
17c90 20 6d 61 67 69 63 20 63 6f 6c 75 6d 6e 20 28 77   magic column (w
17ca0 65 20 69 67 6e 6f 72 65 20 74 68 69 73 29 0a 20  e ignore this). 
17cb0 20 20 20 20 2a 2f 0a 20 20 20 20 61 73 73 65 72      */.    asser
17cc0 74 28 20 6e 41 72 67 3d 3d 32 2b 76 2d 3e 6e 43  t( nArg==2+v->nC
17cd0 6f 6c 75 6d 6e 2b 31 29 3b 0a 20 20 20 20 72 63  olumn+1);.    rc
17ce0 20 3d 20 69 6e 64 65 78 5f 69 6e 73 65 72 74 28   = index_insert(
17cf0 76 2c 20 70 70 41 72 67 5b 31 5d 2c 20 26 70 70  v, ppArg[1], &pp
17d00 41 72 67 5b 32 5d 2c 20 70 52 6f 77 69 64 2c 20  Arg[2], pRowid, 
17d10 26 74 65 72 6d 73 29 3b 0a 20 20 7d 0a 0a 20 20  &terms);.  }..  
17d20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
17d30 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 57 72 69 74  K ){.    /* Writ
17d40 65 20 75 70 64 61 74 65 64 20 64 6f 63 6c 69 73  e updated doclis
17d50 74 73 20 74 6f 20 64 69 73 6b 2e 20 2a 2f 0a 20  ts to disk. */. 
17d60 20 20 20 66 6f 72 28 65 3d 66 74 73 31 48 61 73     for(e=fts1Has
17d70 68 46 69 72 73 74 28 26 74 65 72 6d 73 29 3b 20  hFirst(&terms); 
17d80 65 3b 20 65 3d 66 74 73 31 48 61 73 68 4e 65 78  e; e=fts1HashNex
17d90 74 28 65 29 29 7b 0a 20 20 20 20 20 20 44 6f 63  t(e)){.      Doc
17da0 4c 69 73 74 20 2a 70 20 3d 20 66 74 73 31 48 61  List *p = fts1Ha
17db0 73 68 44 61 74 61 28 65 29 3b 0a 20 20 20 20 20  shData(e);.     
17dc0 20 72 63 20 3d 20 69 6e 64 65 78 5f 69 6e 73 65   rc = index_inse
17dd0 72 74 5f 74 65 72 6d 28 76 2c 20 66 74 73 31 48  rt_term(v, fts1H
17de0 61 73 68 4b 65 79 28 65 29 2c 20 66 74 73 31 48  ashKey(e), fts1H
17df0 61 73 68 4b 65 79 73 69 7a 65 28 65 29 2c 20 70  ashKeysize(e), p
17e00 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
17e10 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65  =SQLITE_OK ) bre
17e20 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  ak;.    }.  }.. 
17e30 20 2f 2a 20 63 6c 65 61 6e 20 75 70 20 2a 2f 0a   /* clean up */.
17e40 20 20 66 6f 72 28 65 3d 66 74 73 31 48 61 73 68    for(e=fts1Hash
17e50 46 69 72 73 74 28 26 74 65 72 6d 73 29 3b 20 65  First(&terms); e
17e60 3b 20 65 3d 66 74 73 31 48 61 73 68 4e 65 78 74  ; e=fts1HashNext
17e70 28 65 29 29 7b 0a 20 20 20 20 44 6f 63 4c 69 73  (e)){.    DocLis
17e80 74 20 2a 70 20 3d 20 66 74 73 31 48 61 73 68 44  t *p = fts1HashD
17e90 61 74 61 28 65 29 3b 0a 20 20 20 20 64 6f 63 4c  ata(e);.    docL
17ea0 69 73 74 44 65 6c 65 74 65 28 70 29 3b 0a 20 20  istDelete(p);.  
17eb0 7d 0a 20 20 66 74 73 31 48 61 73 68 43 6c 65 61  }.  fts1HashClea
17ec0 72 28 26 74 65 72 6d 73 29 3b 0a 0a 20 20 72 65  r(&terms);..  re
17ed0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
17ee0 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
17ef0 20 6f 66 20 74 68 65 20 73 6e 69 70 70 65 74 28   of the snippet(
17f00 29 20 66 75 6e 63 74 69 6f 6e 20 66 6f 72 20 46  ) function for F
17f10 54 53 31 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  TS1.*/.static vo
17f20 69 64 20 73 6e 69 70 70 65 74 46 75 6e 63 28 0a  id snippetFunc(.
17f30 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78    sqlite3_contex
17f40 74 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69  t *pContext,.  i
17f50 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 74  nt argc,.  sqlit
17f60 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a  e3_value **argv.
17f70 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75  ){.  fulltext_cu
17f80 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 3b 0a 20  rsor *pCursor;. 
17f90 20 69 66 28 20 61 72 67 63 3c 31 20 29 20 72 65   if( argc<1 ) re
17fa0 74 75 72 6e 3b 0a 20 20 69 66 28 20 73 71 6c 69  turn;.  if( sqli
17fb0 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61  te3_value_type(a
17fc0 72 67 76 5b 30 5d 29 21 3d 53 51 4c 49 54 45 5f  rgv[0])!=SQLITE_
17fd0 42 4c 4f 42 20 7c 7c 0a 20 20 20 20 20 20 73 71  BLOB ||.      sq
17fe0 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65  lite3_value_byte
17ff0 73 28 61 72 67 76 5b 30 5d 29 21 3d 73 69 7a 65  s(argv[0])!=size
18000 6f 66 28 70 43 75 72 73 6f 72 29 20 29 7b 0a 20  of(pCursor) ){. 
18010 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
18020 74 5f 65 72 72 6f 72 28 70 43 6f 6e 74 65 78 74  t_error(pContext
18030 2c 20 22 69 6c 6c 65 67 61 6c 20 66 69 72 73 74  , "illegal first
18040 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 68 74 6d   argument to htm
18050 6c 5f 73 6e 69 70 70 65 74 22 2c 2d 31 29 3b 0a  l_snippet",-1);.
18060 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 63 6f 6e    }else{.    con
18070 73 74 20 63 68 61 72 20 2a 7a 53 74 61 72 74 20  st char *zStart 
18080 3d 20 22 3c 62 3e 22 3b 0a 20 20 20 20 63 6f 6e  = "<b>";.    con
18090 73 74 20 63 68 61 72 20 2a 7a 45 6e 64 20 3d 20  st char *zEnd = 
180a0 22 3c 2f 62 3e 22 3b 0a 20 20 20 20 63 6f 6e 73  "</b>";.    cons
180b0 74 20 63 68 61 72 20 2a 7a 45 6c 6c 69 70 73 69  t char *zEllipsi
180c0 73 20 3d 20 22 3c 62 3e 2e 2e 2e 3c 2f 62 3e 22  s = "<b>...</b>"
180d0 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 43  ;.    memcpy(&pC
180e0 75 72 73 6f 72 2c 20 73 71 6c 69 74 65 33 5f 76  ursor, sqlite3_v
180f0 61 6c 75 65 5f 62 6c 6f 62 28 61 72 67 76 5b 30  alue_blob(argv[0
18100 5d 29 2c 20 73 69 7a 65 6f 66 28 70 43 75 72 73  ]), sizeof(pCurs
18110 6f 72 29 29 3b 0a 20 20 20 20 69 66 28 20 61 72  or));.    if( ar
18120 67 63 3e 3d 32 20 29 7b 0a 20 20 20 20 20 20 7a  gc>=2 ){.      z
18130 53 74 61 72 74 20 3d 20 28 63 6f 6e 73 74 20 63  Start = (const c
18140 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  har*)sqlite3_val
18150 75 65 5f 74 65 78 74 28 61 72 67 76 5b 31 5d 29  ue_text(argv[1])
18160 3b 0a 20 20 20 20 20 20 69 66 28 20 61 72 67 63  ;.      if( argc
18170 3e 3d 33 20 29 7b 0a 20 20 20 20 20 20 20 20 7a  >=3 ){.        z
18180 45 6e 64 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  End = (const cha
18190 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  r*)sqlite3_value
181a0 5f 74 65 78 74 28 61 72 67 76 5b 32 5d 29 3b 0a  _text(argv[2]);.
181b0 20 20 20 20 20 20 20 20 69 66 28 20 61 72 67 63          if( argc
181c0 3e 3d 34 20 29 7b 0a 20 20 20 20 20 20 20 20 20  >=4 ){.         
181d0 20 7a 45 6c 6c 69 70 73 69 73 20 3d 20 28 63 6f   zEllipsis = (co
181e0 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65  nst char*)sqlite
181f0 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67  3_value_text(arg
18200 76 5b 33 5d 29 3b 0a 20 20 20 20 20 20 20 20 7d  v[3]);.        }
18210 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
18220 20 20 20 73 6e 69 70 70 65 74 41 6c 6c 4f 66 66     snippetAllOff
18230 73 65 74 73 28 70 43 75 72 73 6f 72 29 3b 0a 20  sets(pCursor);. 
18240 20 20 20 73 6e 69 70 70 65 74 54 65 78 74 28 70     snippetText(p
18250 43 75 72 73 6f 72 2c 20 7a 53 74 61 72 74 2c 20  Cursor, zStart, 
18260 7a 45 6e 64 2c 20 7a 45 6c 6c 69 70 73 69 73 29  zEnd, zEllipsis)
18270 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65  ;.    sqlite3_re
18280 73 75 6c 74 5f 74 65 78 74 28 70 43 6f 6e 74 65  sult_text(pConte
18290 78 74 2c 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69  xt, pCursor->sni
182a0 70 70 65 74 2e 7a 53 6e 69 70 70 65 74 2c 0a 20  ppet.zSnippet,. 
182b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
182c0 20 20 20 20 20 20 20 70 43 75 72 73 6f 72 2d 3e         pCursor->
182d0 73 6e 69 70 70 65 74 2e 6e 53 6e 69 70 70 65 74  snippet.nSnippet
182e0 2c 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29  , SQLITE_STATIC)
182f0 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  ;.  }.}../*.** I
18300 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
18310 20 74 68 65 20 6f 66 66 73 65 74 73 28 29 20 66   the offsets() f
18320 75 6e 63 74 69 6f 6e 20 66 6f 72 20 46 54 53 31  unction for FTS1
18330 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
18340 73 6e 69 70 70 65 74 4f 66 66 73 65 74 73 46 75  snippetOffsetsFu
18350 6e 63 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f  nc(.  sqlite3_co
18360 6e 74 65 78 74 20 2a 70 43 6f 6e 74 65 78 74 2c  ntext *pContext,
18370 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 73  .  int argc,.  s
18380 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
18390 72 67 76 0a 29 7b 0a 20 20 66 75 6c 6c 74 65 78  rgv.){.  fulltex
183a0 74 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f  t_cursor *pCurso
183b0 72 3b 0a 20 20 69 66 28 20 61 72 67 63 3c 31 20  r;.  if( argc<1 
183c0 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20  ) return;.  if( 
183d0 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
183e0 70 65 28 61 72 67 76 5b 30 5d 29 21 3d 53 51 4c  pe(argv[0])!=SQL
183f0 49 54 45 5f 42 4c 4f 42 20 7c 7c 0a 20 20 20 20  ITE_BLOB ||.    
18400 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f    sqlite3_value_
18410 62 79 74 65 73 28 61 72 67 76 5b 30 5d 29 21 3d  bytes(argv[0])!=
18420 73 69 7a 65 6f 66 28 70 43 75 72 73 6f 72 29 20  sizeof(pCursor) 
18430 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  ){.    sqlite3_r
18440 65 73 75 6c 74 5f 65 72 72 6f 72 28 70 43 6f 6e  esult_error(pCon
18450 74 65 78 74 2c 20 22 69 6c 6c 65 67 61 6c 20 66  text, "illegal f
18460 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74 6f  irst argument to
18470 20 6f 66 66 73 65 74 73 22 2c 2d 31 29 3b 0a 20   offsets",-1);. 
18480 20 7d 65 6c 73 65 7b 0a 20 20 20 20 6d 65 6d 63   }else{.    memc
18490 70 79 28 26 70 43 75 72 73 6f 72 2c 20 73 71 6c  py(&pCursor, sql
184a0 69 74 65 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28  ite3_value_blob(
184b0 61 72 67 76 5b 30 5d 29 2c 20 73 69 7a 65 6f 66  argv[0]), sizeof
184c0 28 70 43 75 72 73 6f 72 29 29 3b 0a 20 20 20 20  (pCursor));.    
184d0 73 6e 69 70 70 65 74 41 6c 6c 4f 66 66 73 65 74  snippetAllOffset
184e0 73 28 70 43 75 72 73 6f 72 29 3b 0a 20 20 20 20  s(pCursor);.    
184f0 73 6e 69 70 70 65 74 4f 66 66 73 65 74 54 65 78  snippetOffsetTex
18500 74 28 26 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70  t(&pCursor->snip
18510 70 65 74 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  pet);.    sqlite
18520 33 5f 72 65 73 75 6c 74 5f 74 65 78 74 28 70 43  3_result_text(pC
18530 6f 6e 74 65 78 74 2c 0a 20 20 20 20 20 20 20 20  ontext,.        
18540 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18550 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74  pCursor->snippet
18560 2e 7a 4f 66 66 73 65 74 2c 20 70 43 75 72 73 6f  .zOffset, pCurso
18570 72 2d 3e 73 6e 69 70 70 65 74 2e 6e 4f 66 66 73  r->snippet.nOffs
18580 65 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  et,.            
18590 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
185a0 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 7d 0a  TE_STATIC);.  }.
185b0 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  }../*.** This ro
185c0 75 74 69 6e 65 20 69 6d 70 6c 65 6d 65 6e 74 73  utine implements
185d0 20 74 68 65 20 78 46 69 6e 64 46 75 6e 63 74 69   the xFindFuncti
185e0 6f 6e 20 6d 65 74 68 6f 64 20 66 6f 72 20 74 68  on method for th
185f0 65 20 46 54 53 31 0a 2a 2a 20 76 69 72 74 75 61  e FTS1.** virtua
18600 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74  l table..*/.stat
18610 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 46  ic int fulltextF
18620 69 6e 64 46 75 6e 63 74 69 6f 6e 28 0a 20 20 73  indFunction(.  s
18630 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
18640 61 62 2c 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a  ab,.  int nArg,.
18650 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e    const char *zN
18660 61 6d 65 2c 0a 20 20 76 6f 69 64 20 28 2a 2a 70  ame,.  void (**p
18670 78 46 75 6e 63 29 28 73 71 6c 69 74 65 33 5f 63  xFunc)(sqlite3_c
18680 6f 6e 74 65 78 74 2a 2c 69 6e 74 2c 73 71 6c 69  ontext*,int,sqli
18690 74 65 33 5f 76 61 6c 75 65 2a 2a 29 2c 0a 20 20  te3_value**),.  
186a0 76 6f 69 64 20 2a 2a 70 70 41 72 67 0a 29 7b 0a  void **ppArg.){.
186b0 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 4e 61    if( strcmp(zNa
186c0 6d 65 2c 22 73 6e 69 70 70 65 74 22 29 3d 3d 30  me,"snippet")==0
186d0 20 29 7b 0a 20 20 20 20 2a 70 78 46 75 6e 63 20   ){.    *pxFunc 
186e0 3d 20 73 6e 69 70 70 65 74 46 75 6e 63 3b 0a 20  = snippetFunc;. 
186f0 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d     return 1;.  }
18700 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28  else if( strcmp(
18710 7a 4e 61 6d 65 2c 22 6f 66 66 73 65 74 73 22 29  zName,"offsets")
18720 3d 3d 30 20 29 7b 0a 20 20 20 20 2a 70 78 46 75  ==0 ){.    *pxFu
18730 6e 63 20 3d 20 73 6e 69 70 70 65 74 4f 66 66 73  nc = snippetOffs
18740 65 74 73 46 75 6e 63 3b 0a 20 20 20 20 72 65 74  etsFunc;.    ret
18750 75 72 6e 20 31 3b 0a 20 20 7d 0a 20 20 72 65 74  urn 1;.  }.  ret
18760 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 0;.}../*.** 
18770 52 65 6e 61 6d 65 20 61 6e 20 66 74 73 31 20 74  Rename an fts1 t
18780 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  able..*/.static 
18790 69 6e 74 20 66 75 6c 6c 74 65 78 74 52 65 6e 61  int fulltextRena
187a0 6d 65 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  me(.  sqlite3_vt
187b0 61 62 20 2a 70 56 74 61 62 2c 0a 20 20 63 6f 6e  ab *pVtab,.  con
187c0 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 0a 29  st char *zName.)
187d0 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61  {.  fulltext_vta
187e0 62 20 2a 70 20 3d 20 28 66 75 6c 6c 74 65 78 74  b *p = (fulltext
187f0 5f 76 74 61 62 20 2a 29 70 56 74 61 62 3b 0a 20  _vtab *)pVtab;. 
18800 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
18810 5f 4e 4f 4d 45 4d 3b 0a 20 20 63 68 61 72 20 2a  _NOMEM;.  char *
18820 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d  zSql = sqlite3_m
18830 70 72 69 6e 74 66 28 0a 20 20 20 20 22 41 4c 54  printf(.    "ALT
18840 45 52 20 54 41 42 4c 45 20 25 51 2e 27 25 71 5f  ER TABLE %Q.'%q_
18850 63 6f 6e 74 65 6e 74 27 20 20 52 45 4e 41 4d 45  content'  RENAME
18860 20 54 4f 20 27 25 71 5f 63 6f 6e 74 65 6e 74 27   TO '%q_content'
18870 3b 22 0a 20 20 20 20 22 41 4c 54 45 52 20 54 41  ;".    "ALTER TA
18880 42 4c 45 20 25 51 2e 27 25 71 5f 74 65 72 6d 27  BLE %Q.'%q_term'
18890 20 52 45 4e 41 4d 45 20 54 4f 20 27 25 71 5f 74   RENAME TO '%q_t
188a0 65 72 6d 27 3b 22 0a 20 20 20 20 2c 20 70 2d 3e  erm';".    , p->
188b0 7a 44 62 2c 20 70 2d 3e 7a 4e 61 6d 65 2c 20 7a  zDb, p->zName, z
188c0 4e 61 6d 65 0a 20 20 20 20 2c 20 70 2d 3e 7a 44  Name.    , p->zD
188d0 62 2c 20 70 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61  b, p->zName, zNa
188e0 6d 65 0a 20 20 29 3b 0a 20 20 69 66 28 20 7a 53  me.  );.  if( zS
188f0 71 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  ql ){.    rc = s
18900 71 6c 69 74 65 33 5f 65 78 65 63 28 70 2d 3e 64  qlite3_exec(p->d
18910 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30  b, zSql, 0, 0, 0
18920 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
18930 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 20  ree(zSql);.  }. 
18940 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
18950 74 61 74 69 63 20 63 6f 6e 73 74 20 73 71 6c 69  tatic const sqli
18960 74 65 33 5f 6d 6f 64 75 6c 65 20 66 75 6c 6c 74  te3_module fullt
18970 65 78 74 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20  extModule = {.  
18980 2f 2a 20 69 56 65 72 73 69 6f 6e 20 20 20 20 20  /* iVersion     
18990 20 2a 2f 20 30 2c 0a 20 20 2f 2a 20 78 43 72 65   */ 0,.  /* xCre
189a0 61 74 65 20 20 20 20 20 20 20 2a 2f 20 66 75 6c  ate       */ ful
189b0 6c 74 65 78 74 43 72 65 61 74 65 2c 0a 20 20 2f  ltextCreate,.  /
189c0 2a 20 78 43 6f 6e 6e 65 63 74 20 20 20 20 20 20  * xConnect      
189d0 2a 2f 20 66 75 6c 6c 74 65 78 74 43 6f 6e 6e 65  */ fulltextConne
189e0 63 74 2c 0a 20 20 2f 2a 20 78 42 65 73 74 49 6e  ct,.  /* xBestIn
189f0 64 65 78 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65  dex    */ fullte
18a00 78 74 42 65 73 74 49 6e 64 65 78 2c 0a 20 20 2f  xtBestIndex,.  /
18a10 2a 20 78 44 69 73 63 6f 6e 6e 65 63 74 20 20 20  * xDisconnect   
18a20 2a 2f 20 66 75 6c 6c 74 65 78 74 44 69 73 63 6f  */ fulltextDisco
18a30 6e 6e 65 63 74 2c 0a 20 20 2f 2a 20 78 44 65 73  nnect,.  /* xDes
18a40 74 72 6f 79 20 20 20 20 20 20 2a 2f 20 66 75 6c  troy      */ ful
18a50 6c 74 65 78 74 44 65 73 74 72 6f 79 2c 0a 20 20  ltextDestroy,.  
18a60 2f 2a 20 78 4f 70 65 6e 20 20 20 20 20 20 20 20  /* xOpen        
18a70 20 2a 2f 20 66 75 6c 6c 74 65 78 74 4f 70 65 6e   */ fulltextOpen
18a80 2c 0a 20 20 2f 2a 20 78 43 6c 6f 73 65 20 20 20  ,.  /* xClose   
18a90 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74       */ fulltext
18aa0 43 6c 6f 73 65 2c 0a 20 20 2f 2a 20 78 46 69 6c  Close,.  /* xFil
18ab0 74 65 72 20 20 20 20 20 20 20 2a 2f 20 66 75 6c  ter       */ ful
18ac0 6c 74 65 78 74 46 69 6c 74 65 72 2c 0a 20 20 2f  ltextFilter,.  /
18ad0 2a 20 78 4e 65 78 74 20 20 20 20 20 20 20 20 20  * xNext         
18ae0 2a 2f 20 66 75 6c 6c 74 65 78 74 4e 65 78 74 2c  */ fulltextNext,
18af0 0a 20 20 2f 2a 20 78 45 6f 66 20 20 20 20 20 20  .  /* xEof      
18b00 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74 45      */ fulltextE
18b10 6f 66 2c 0a 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e  of,.  /* xColumn
18b20 20 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65         */ fullte
18b30 78 74 43 6f 6c 75 6d 6e 2c 0a 20 20 2f 2a 20 78  xtColumn,.  /* x
18b40 52 6f 77 69 64 20 20 20 20 20 20 20 20 2a 2f 20  Rowid        */ 
18b50 66 75 6c 6c 74 65 78 74 52 6f 77 69 64 2c 0a 20  fulltextRowid,. 
18b60 20 2f 2a 20 78 55 70 64 61 74 65 20 20 20 20 20   /* xUpdate     
18b70 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74 55 70 64    */ fulltextUpd
18b80 61 74 65 2c 0a 20 20 2f 2a 20 78 42 65 67 69 6e  ate,.  /* xBegin
18b90 20 20 20 20 20 20 20 20 2a 2f 20 30 2c 20 0a 20          */ 0, . 
18ba0 20 2f 2a 20 78 53 79 6e 63 20 20 20 20 20 20 20   /* xSync       
18bb0 20 20 2a 2f 20 30 2c 0a 20 20 2f 2a 20 78 43 6f    */ 0,.  /* xCo
18bc0 6d 6d 69 74 20 20 20 20 20 20 20 2a 2f 20 30 2c  mmit       */ 0,
18bd0 0a 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20  .  /* xRollback 
18be0 20 20 20 20 2a 2f 20 30 2c 0a 20 20 2f 2a 20 78      */ 0,.  /* x
18bf0 46 69 6e 64 46 75 6e 63 74 69 6f 6e 20 2a 2f 20  FindFunction */ 
18c00 66 75 6c 6c 74 65 78 74 46 69 6e 64 46 75 6e 63  fulltextFindFunc
18c10 74 69 6f 6e 2c 0a 20 20 2f 2a 20 78 52 65 6e 61  tion,.  /* xRena
18c20 6d 65 20 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c  me       */ full
18c30 74 65 78 74 52 65 6e 61 6d 65 2c 0a 7d 3b 0a 0a  textRename,.};..
18c40 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73 31 49  int sqlite3Fts1I
18c50 6e 69 74 28 73 71 6c 69 74 65 33 20 2a 64 62 29  nit(sqlite3 *db)
18c60 7b 0a 20 20 73 71 6c 69 74 65 33 5f 6f 76 65 72  {.  sqlite3_over
18c70 6c 6f 61 64 5f 66 75 6e 63 74 69 6f 6e 28 64 62  load_function(db
18c80 2c 20 22 73 6e 69 70 70 65 74 22 2c 20 2d 31 29  , "snippet", -1)
18c90 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6f 76 65 72  ;.  sqlite3_over
18ca0 6c 6f 61 64 5f 66 75 6e 63 74 69 6f 6e 28 64 62  load_function(db
18cb0 2c 20 22 6f 66 66 73 65 74 73 22 2c 20 2d 31 29  , "offsets", -1)
18cc0 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ;.  return sqlit
18cd0 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65  e3_create_module
18ce0 28 64 62 2c 20 22 66 74 73 31 22 2c 20 26 66 75  (db, "fts1", &fu
18cf0 6c 6c 74 65 78 74 4d 6f 64 75 6c 65 2c 20 30 29  lltextModule, 0)
18d00 3b 0a 7d 0a 0a 23 69 66 20 21 53 51 4c 49 54 45  ;.}..#if !SQLITE
18d10 5f 43 4f 52 45 0a 23 69 66 64 65 66 20 5f 57 49  _CORE.#ifdef _WI
18d20 4e 33 32 0a 5f 5f 64 65 63 6c 73 70 65 63 28 64  N32.__declspec(d
18d30 6c 6c 65 78 70 6f 72 74 29 0a 23 65 6e 64 69 66  llexport).#endif
18d40 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 66 74 73  .int sqlite3_fts
18d50 31 5f 69 6e 69 74 28 73 71 6c 69 74 65 33 20 2a  1_init(sqlite3 *
18d60 64 62 2c 20 63 68 61 72 20 2a 2a 70 7a 45 72 72  db, char **pzErr
18d70 4d 73 67 2c 0a 20 20 20 20 20 20 20 20 20 20 20  Msg,.           
18d80 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74             const
18d90 20 73 71 6c 69 74 65 33 5f 61 70 69 5f 72 6f 75   sqlite3_api_rou
18da0 74 69 6e 65 73 20 2a 70 41 70 69 29 7b 0a 20 20  tines *pApi){.  
18db0 53 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e  SQLITE_EXTENSION
18dc0 5f 49 4e 49 54 32 28 70 41 70 69 29 0a 20 20 72  _INIT2(pApi).  r
18dd0 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73  eturn sqlite3Fts
18de0 31 49 6e 69 74 28 64 62 29 3b 0a 7d 0a 23 65 6e  1Init(db);.}.#en
18df0 64 69 66 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 21  dif..#endif /* !
18e00 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 43  defined(SQLITE_C
18e10 4f 52 45 29 20 7c 7c 20 64 65 66 69 6e 65 64 28  ORE) || defined(
18e20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54  SQLITE_ENABLE_FT
18e30 53 31 29 20 2a 2f 0a                             S1) */.