/ Hex Artifact Content
Login

Artifact 0aab3cf20eefd38935c8f525494d689cb2785f1d:


0000: 2f 2a 20 54 68 65 20 61 75 74 68 6f 72 20 64 69  /* The author di
0010: 73 63 6c 61 69 6d 73 20 63 6f 70 79 72 69 67 68  sclaims copyrigh
0020: 74 20 74 6f 20 74 68 69 73 20 73 6f 75 72 63 65  t to this source
0030: 20 63 6f 64 65 2e 0a 20 2a 0a 20 2a 20 54 68 69   code.. *. * Thi
0040: 73 20 69 73 20 61 6e 20 53 51 4c 69 74 65 20 6d  s is an SQLite m
0050: 6f 64 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 69  odule implementi
0060: 6e 67 20 66 75 6c 6c 2d 74 65 78 74 20 73 65 61  ng full-text sea
0070: 72 63 68 2e 0a 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  rch.. */../*.** 
0080: 54 68 65 20 63 6f 64 65 20 69 6e 20 74 68 69 73  The code in this
0090: 20 66 69 6c 65 20 69 73 20 6f 6e 6c 79 20 63 6f   file is only co
00a0: 6d 70 69 6c 65 64 20 69 66 3a 0a 2a 2a 0a 2a 2a  mpiled if:.**.**
00b0: 20 20 20 20 20 2a 20 54 68 65 20 46 54 53 31 20       * The FTS1 
00c0: 6d 6f 64 75 6c 65 20 69 73 20 62 65 69 6e 67 20  module is being 
00d0: 62 75 69 6c 74 20 61 73 20 61 6e 20 65 78 74 65  built as an exte
00e0: 6e 73 69 6f 6e 0a 2a 2a 20 20 20 20 20 20 20 28  nsion.**       (
00f0: 69 6e 20 77 68 69 63 68 20 63 61 73 65 20 53 51  in which case SQ
0100: 4c 49 54 45 5f 43 4f 52 45 20 69 73 20 6e 6f 74  LITE_CORE is not
0110: 20 64 65 66 69 6e 65 64 29 2c 20 6f 72 0a 2a 2a   defined), or.**
0120: 0a 2a 2a 20 20 20 20 20 2a 20 54 68 65 20 46 54  .**     * The FT
0130: 53 31 20 6d 6f 64 75 6c 65 20 69 73 20 62 65 69  S1 module is bei
0140: 6e 67 20 62 75 69 6c 74 20 69 6e 74 6f 20 74 68  ng built into th
0150: 65 20 63 6f 72 65 20 6f 66 0a 2a 2a 20 20 20 20  e core of.**    
0160: 20 20 20 53 51 4c 69 74 65 20 28 69 6e 20 77 68     SQLite (in wh
0170: 69 63 68 20 63 61 73 65 20 53 51 4c 49 54 45 5f  ich case SQLITE_
0180: 45 4e 41 42 4c 45 5f 46 54 53 31 20 69 73 20 64  ENABLE_FTS1 is d
0190: 65 66 69 6e 65 64 29 2e 0a 2a 2f 0a 23 69 66 20  efined)..*/.#if 
01a0: 21 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f  !defined(SQLITE_
01b0: 43 4f 52 45 29 20 7c 7c 20 64 65 66 69 6e 65 64  CORE) || defined
01c0: 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46  (SQLITE_ENABLE_F
01d0: 54 53 31 29 0a 0a 23 69 66 20 64 65 66 69 6e 65  TS1)..#if define
01e0: 64 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  d(SQLITE_ENABLE_
01f0: 46 54 53 31 29 20 26 26 20 21 64 65 66 69 6e 65  FTS1) && !define
0200: 64 28 53 51 4c 49 54 45 5f 43 4f 52 45 29 0a 23  d(SQLITE_CORE).#
0210: 20 64 65 66 69 6e 65 20 53 51 4c 49 54 45 5f 43   define SQLITE_C
0220: 4f 52 45 20 31 0a 23 65 6e 64 69 66 0a 0a 23 69  ORE 1.#endif..#i
0230: 6e 63 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68  nclude <assert.h
0240: 3e 0a 23 69 66 20 21 64 65 66 69 6e 65 64 28 5f  >.#if !defined(_
0250: 5f 41 50 50 4c 45 5f 5f 29 0a 23 69 6e 63 6c 75  _APPLE__).#inclu
0260: 64 65 20 3c 6d 61 6c 6c 6f 63 2e 68 3e 0a 23 65  de <malloc.h>.#e
0270: 6c 73 65 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  lse.#include <st
0280: 64 6c 69 62 2e 68 3e 0a 23 65 6e 64 69 66 0a 23  dlib.h>.#endif.#
0290: 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68  include <stdio.h
02a0: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69  >.#include <stri
02b0: 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  ng.h>.#include <
02c0: 63 74 79 70 65 2e 68 3e 0a 0a 23 69 6e 63 6c 75  ctype.h>..#inclu
02d0: 64 65 20 22 66 74 73 31 2e 68 22 0a 23 69 6e 63  de "fts1.h".#inc
02e0: 6c 75 64 65 20 22 66 74 73 31 5f 68 61 73 68 2e  lude "fts1_hash.
02f0: 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 66 74 73  h".#include "fts
0300: 31 5f 74 6f 6b 65 6e 69 7a 65 72 2e 68 22 0a 23  1_tokenizer.h".#
0310: 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 33  include "sqlite3
0320: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 73 71  .h".#include "sq
0330: 6c 69 74 65 33 65 78 74 2e 68 22 0a 53 51 4c 49  lite3ext.h".SQLI
0340: 54 45 5f 45 58 54 45 4e 53 49 4f 4e 5f 49 4e 49  TE_EXTENSION_INI
0350: 54 31 0a 0a 0a 23 69 66 20 30 0a 23 20 64 65 66  T1...#if 0.# def
0360: 69 6e 65 20 54 52 41 43 45 28 41 29 20 20 70 72  ine TRACE(A)  pr
0370: 69 6e 74 66 20 41 3b 20 66 66 6c 75 73 68 28 73  intf A; fflush(s
0380: 74 64 6f 75 74 29 0a 23 65 6c 73 65 0a 23 20 64  tdout).#else.# d
0390: 65 66 69 6e 65 20 54 52 41 43 45 28 41 29 0a 23  efine TRACE(A).#
03a0: 65 6e 64 69 66 0a 0a 2f 2a 20 75 74 69 6c 69 74  endif../* utilit
03b0: 79 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 0a  y functions */..
03c0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53  typedef struct S
03d0: 74 72 69 6e 67 42 75 66 66 65 72 20 7b 0a 20 20  tringBuffer {.  
03e0: 69 6e 74 20 6c 65 6e 3b 20 20 20 20 20 20 2f 2a  int len;      /*
03f0: 20 6c 65 6e 67 74 68 2c 20 6e 6f 74 20 69 6e 63   length, not inc
0400: 6c 75 64 69 6e 67 20 6e 75 6c 6c 20 74 65 72 6d  luding null term
0410: 69 6e 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20  inator */.  int 
0420: 61 6c 6c 6f 63 65 64 3b 20 20 2f 2a 20 53 70 61  alloced;  /* Spa
0430: 63 65 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  ce allocated for
0440: 20 73 5b 5d 20 2a 2f 20 0a 20 20 63 68 61 72 20   s[] */ .  char 
0450: 2a 73 3b 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74  *s;      /* Cont
0460: 65 6e 74 20 6f 66 20 74 68 65 20 73 74 72 69 6e  ent of the strin
0470: 67 20 2a 2f 0a 7d 20 53 74 72 69 6e 67 42 75 66  g */.} StringBuf
0480: 66 65 72 3b 0a 0a 73 74 61 74 69 63 20 76 6f 69  fer;..static voi
0490: 64 20 69 6e 69 74 53 74 72 69 6e 67 42 75 66 66  d initStringBuff
04a0: 65 72 28 53 74 72 69 6e 67 42 75 66 66 65 72 20  er(StringBuffer 
04b0: 2a 73 62 29 7b 0a 20 20 73 62 2d 3e 6c 65 6e 20  *sb){.  sb->len 
04c0: 3d 20 30 3b 0a 20 20 73 62 2d 3e 61 6c 6c 6f 63  = 0;.  sb->alloc
04d0: 65 64 20 3d 20 31 30 30 3b 0a 20 20 73 62 2d 3e  ed = 100;.  sb->
04e0: 73 20 3d 20 6d 61 6c 6c 6f 63 28 31 30 30 29 3b  s = malloc(100);
04f0: 0a 20 20 73 62 2d 3e 73 5b 30 5d 20 3d 20 27 5c  .  sb->s[0] = '\
0500: 30 27 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  0';.}..static vo
0510: 69 64 20 6e 61 70 70 65 6e 64 28 53 74 72 69 6e  id nappend(Strin
0520: 67 42 75 66 66 65 72 20 2a 73 62 2c 20 63 6f 6e  gBuffer *sb, con
0530: 73 74 20 63 68 61 72 20 2a 7a 46 72 6f 6d 2c 20  st char *zFrom, 
0540: 69 6e 74 20 6e 46 72 6f 6d 29 7b 0a 20 20 69 66  int nFrom){.  if
0550: 28 20 73 62 2d 3e 6c 65 6e 20 2b 20 6e 46 72 6f  ( sb->len + nFro
0560: 6d 20 3e 3d 20 73 62 2d 3e 61 6c 6c 6f 63 65 64  m >= sb->alloced
0570: 20 29 7b 0a 20 20 20 20 73 62 2d 3e 61 6c 6c 6f   ){.    sb->allo
0580: 63 65 64 20 3d 20 73 62 2d 3e 6c 65 6e 20 2b 20  ced = sb->len + 
0590: 6e 46 72 6f 6d 20 2b 20 31 30 30 3b 0a 20 20 20  nFrom + 100;.   
05a0: 20 73 62 2d 3e 73 20 3d 20 72 65 61 6c 6c 6f 63   sb->s = realloc
05b0: 28 73 62 2d 3e 73 2c 20 73 62 2d 3e 61 6c 6c 6f  (sb->s, sb->allo
05c0: 63 65 64 2b 31 29 3b 0a 20 20 20 20 69 66 28 20  ced+1);.    if( 
05d0: 73 62 2d 3e 73 3d 3d 30 20 29 7b 0a 20 20 20 20  sb->s==0 ){.    
05e0: 20 20 69 6e 69 74 53 74 72 69 6e 67 42 75 66 66    initStringBuff
05f0: 65 72 28 73 62 29 3b 0a 20 20 20 20 20 20 72 65  er(sb);.      re
0600: 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  turn;.    }.  }.
0610: 20 20 6d 65 6d 63 70 79 28 73 62 2d 3e 73 20 2b    memcpy(sb->s +
0620: 20 73 62 2d 3e 6c 65 6e 2c 20 7a 46 72 6f 6d 2c   sb->len, zFrom,
0630: 20 6e 46 72 6f 6d 29 3b 0a 20 20 73 62 2d 3e 6c   nFrom);.  sb->l
0640: 65 6e 20 2b 3d 20 6e 46 72 6f 6d 3b 0a 20 20 73  en += nFrom;.  s
0650: 62 2d 3e 73 5b 73 62 2d 3e 6c 65 6e 5d 20 3d 20  b->s[sb->len] = 
0660: 30 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64  0;.}.static void
0670: 20 61 70 70 65 6e 64 28 53 74 72 69 6e 67 42 75   append(StringBu
0680: 66 66 65 72 20 2a 73 62 2c 20 63 6f 6e 73 74 20  ffer *sb, const 
0690: 63 68 61 72 20 2a 7a 46 72 6f 6d 29 7b 0a 20 20  char *zFrom){.  
06a0: 6e 61 70 70 65 6e 64 28 73 62 2c 20 7a 46 72 6f  nappend(sb, zFro
06b0: 6d 2c 20 73 74 72 6c 65 6e 28 7a 46 72 6f 6d 29  m, strlen(zFrom)
06c0: 29 3b 0a 7d 0a 0a 2f 2a 20 57 65 20 65 6e 63 6f  );.}../* We enco
06d0: 64 65 20 76 61 72 69 61 62 6c 65 2d 6c 65 6e 67  de variable-leng
06e0: 74 68 20 69 6e 74 65 67 65 72 73 20 69 6e 20 6c  th integers in l
06f0: 69 74 74 6c 65 2d 65 6e 64 69 61 6e 20 6f 72 64  ittle-endian ord
0700: 65 72 20 75 73 69 6e 67 20 73 65 76 65 6e 20 62  er using seven b
0710: 69 74 73 0a 20 2a 20 70 65 72 20 62 79 74 65 20  its. * per byte 
0720: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a  as follows:.**.*
0730: 2a 20 4b 45 59 3a 0a 2a 2a 20 20 20 20 20 20 20  * KEY:.**       
0740: 20 20 41 20 3d 20 30 78 78 78 78 78 78 78 20 20    A = 0xxxxxxx  
0750: 20 20 37 20 62 69 74 73 20 6f 66 20 64 61 74 61    7 bits of data
0760: 20 61 6e 64 20 6f 6e 65 20 66 6c 61 67 20 62 69   and one flag bi
0770: 74 0a 2a 2a 20 20 20 20 20 20 20 20 20 42 20 3d  t.**         B =
0780: 20 31 78 78 78 78 78 78 78 20 20 20 20 37 20 62   1xxxxxxx    7 b
0790: 69 74 73 20 6f 66 20 64 61 74 61 20 61 6e 64 20  its of data and 
07a0: 6f 6e 65 20 66 6c 61 67 20 62 69 74 0a 2a 2a 0a  one flag bit.**.
07b0: 2a 2a 20 20 37 20 62 69 74 73 20 2d 20 41 0a 2a  **  7 bits - A.*
07c0: 2a 20 31 34 20 62 69 74 73 20 2d 20 42 41 0a 2a  * 14 bits - BA.*
07d0: 2a 20 32 31 20 62 69 74 73 20 2d 20 42 42 41 0a  * 21 bits - BBA.
07e0: 2a 2a 20 61 6e 64 20 73 6f 20 6f 6e 2e 0a 2a 2f  ** and so on..*/
07f0: 0a 0a 2f 2a 20 57 65 20 6d 61 79 20 6e 65 65 64  ../* We may need
0800: 20 75 70 20 74 6f 20 56 41 52 49 4e 54 5f 4d 41   up to VARINT_MA
0810: 58 20 62 79 74 65 73 20 74 6f 20 73 74 6f 72 65  X bytes to store
0820: 20 61 6e 20 65 6e 63 6f 64 65 64 20 36 34 2d 62   an encoded 64-b
0830: 69 74 20 69 6e 74 65 67 65 72 2e 20 2a 2f 0a 23  it integer. */.#
0840: 64 65 66 69 6e 65 20 56 41 52 49 4e 54 5f 4d 41  define VARINT_MA
0850: 58 20 31 30 0a 0a 2f 2a 20 57 72 69 74 65 20 61  X 10../* Write a
0860: 20 36 34 2d 62 69 74 20 76 61 72 69 61 62 6c 65   64-bit variable
0870: 2d 6c 65 6e 67 74 68 20 69 6e 74 65 67 65 72 20  -length integer 
0880: 74 6f 20 6d 65 6d 6f 72 79 20 73 74 61 72 74 69  to memory starti
0890: 6e 67 20 61 74 20 70 5b 30 5d 2e 0a 20 2a 20 54  ng at p[0].. * T
08a0: 68 65 20 6c 65 6e 67 74 68 20 6f 66 20 64 61 74  he length of dat
08b0: 61 20 77 72 69 74 74 65 6e 20 77 69 6c 6c 20 62  a written will b
08c0: 65 20 62 65 74 77 65 65 6e 20 31 20 61 6e 64 20  e between 1 and 
08d0: 56 41 52 49 4e 54 5f 4d 41 58 20 62 79 74 65 73  VARINT_MAX bytes
08e0: 2e 0a 20 2a 20 54 68 65 20 6e 75 6d 62 65 72 20  .. * The number 
08f0: 6f 66 20 62 79 74 65 73 20 77 72 69 74 74 65 6e  of bytes written
0900: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 2a 2f   is returned. */
0910: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 75 74 56  .static int putV
0920: 61 72 69 6e 74 28 63 68 61 72 20 2a 70 2c 20 73  arint(char *p, s
0930: 71 6c 69 74 65 5f 69 6e 74 36 34 20 76 29 7b 0a  qlite_int64 v){.
0940: 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20    unsigned char 
0950: 2a 71 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63  *q = (unsigned c
0960: 68 61 72 20 2a 29 20 70 3b 0a 20 20 73 71 6c 69  har *) p;.  sqli
0970: 74 65 5f 75 69 6e 74 36 34 20 76 75 20 3d 20 76  te_uint64 vu = v
0980: 3b 0a 20 20 64 6f 7b 0a 20 20 20 20 2a 71 2b 2b  ;.  do{.    *q++
0990: 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61   = (unsigned cha
09a0: 72 29 20 28 28 76 75 20 26 20 30 78 37 66 29 20  r) ((vu & 0x7f) 
09b0: 7c 20 30 78 38 30 29 3b 0a 20 20 20 20 76 75 20  | 0x80);.    vu 
09c0: 3e 3e 3d 20 37 3b 0a 20 20 7d 77 68 69 6c 65 28  >>= 7;.  }while(
09d0: 20 76 75 21 3d 30 20 29 3b 0a 20 20 71 5b 2d 31   vu!=0 );.  q[-1
09e0: 5d 20 26 3d 20 30 78 37 66 3b 20 20 2f 2a 20 74  ] &= 0x7f;  /* t
09f0: 75 72 6e 20 6f 66 66 20 68 69 67 68 20 62 69 74  urn off high bit
0a00: 20 69 6e 20 66 69 6e 61 6c 20 62 79 74 65 20 2a   in final byte *
0a10: 2f 0a 20 20 61 73 73 65 72 74 28 20 71 20 2d 20  /.  assert( q - 
0a20: 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a  (unsigned char *
0a30: 29 70 20 3c 3d 20 56 41 52 49 4e 54 5f 4d 41 58  )p <= VARINT_MAX
0a40: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 69 6e   );.  return (in
0a50: 74 29 20 28 71 20 2d 20 28 75 6e 73 69 67 6e 65  t) (q - (unsigne
0a60: 64 20 63 68 61 72 20 2a 29 70 29 3b 0a 7d 0a 0a  d char *)p);.}..
0a70: 2f 2a 20 52 65 61 64 20 61 20 36 34 2d 62 69 74  /* Read a 64-bit
0a80: 20 76 61 72 69 61 62 6c 65 2d 6c 65 6e 67 74 68   variable-length
0a90: 20 69 6e 74 65 67 65 72 20 66 72 6f 6d 20 6d 65   integer from me
0aa0: 6d 6f 72 79 20 73 74 61 72 74 69 6e 67 20 61 74  mory starting at
0ab0: 20 70 5b 30 5d 2e 0a 20 2a 20 52 65 74 75 72 6e   p[0].. * Return
0ac0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62   the number of b
0ad0: 79 74 65 73 20 72 65 61 64 2c 20 6f 72 20 30 20  ytes read, or 0 
0ae0: 6f 6e 20 65 72 72 6f 72 2e 0a 20 2a 20 54 68 65  on error.. * The
0af0: 20 76 61 6c 75 65 20 69 73 20 73 74 6f 72 65 64   value is stored
0b00: 20 69 6e 20 2a 76 2e 20 2a 2f 0a 73 74 61 74 69   in *v. */.stati
0b10: 63 20 69 6e 74 20 67 65 74 56 61 72 69 6e 74 28  c int getVarint(
0b20: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 2c 20 73  const char *p, s
0b30: 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 76 29 7b  qlite_int64 *v){
0b40: 0a 20 20 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65  .  const unsigne
0b50: 64 20 63 68 61 72 20 2a 71 20 3d 20 28 63 6f 6e  d char *q = (con
0b60: 73 74 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  st unsigned char
0b70: 20 2a 29 20 70 3b 0a 20 20 73 71 6c 69 74 65 5f   *) p;.  sqlite_
0b80: 75 69 6e 74 36 34 20 78 20 3d 20 30 2c 20 79 20  uint64 x = 0, y 
0b90: 3d 20 31 3b 0a 20 20 77 68 69 6c 65 28 20 28 2a  = 1;.  while( (*
0ba0: 71 20 26 20 30 78 38 30 29 20 3d 3d 20 30 78 38  q & 0x80) == 0x8
0bb0: 30 20 29 7b 0a 20 20 20 20 78 20 2b 3d 20 79 20  0 ){.    x += y 
0bc0: 2a 20 28 2a 71 2b 2b 20 26 20 30 78 37 66 29 3b  * (*q++ & 0x7f);
0bd0: 0a 20 20 20 20 79 20 3c 3c 3d 20 37 3b 0a 20 20  .    y <<= 7;.  
0be0: 20 20 69 66 28 20 71 20 2d 20 28 75 6e 73 69 67    if( q - (unsig
0bf0: 6e 65 64 20 63 68 61 72 20 2a 29 70 20 3e 3d 20  ned char *)p >= 
0c00: 56 41 52 49 4e 54 5f 4d 41 58 20 29 7b 20 20 2f  VARINT_MAX ){  /
0c10: 2a 20 62 61 64 20 64 61 74 61 20 2a 2f 0a 20 20  * bad data */.  
0c20: 20 20 20 20 61 73 73 65 72 74 28 20 30 20 29 3b      assert( 0 );
0c30: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b  .      return 0;
0c40: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 78 20 2b  .    }.  }.  x +
0c50: 3d 20 79 20 2a 20 28 2a 71 2b 2b 29 3b 0a 20 20  = y * (*q++);.  
0c60: 2a 76 20 3d 20 28 73 71 6c 69 74 65 5f 69 6e 74  *v = (sqlite_int
0c70: 36 34 29 20 78 3b 0a 20 20 72 65 74 75 72 6e 20  64) x;.  return 
0c80: 28 69 6e 74 29 20 28 71 20 2d 20 28 75 6e 73 69  (int) (q - (unsi
0c90: 67 6e 65 64 20 63 68 61 72 20 2a 29 70 29 3b 0a  gned char *)p);.
0ca0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65  }..static int ge
0cb0: 74 56 61 72 69 6e 74 33 32 28 63 6f 6e 73 74 20  tVarint32(const 
0cc0: 63 68 61 72 20 2a 70 2c 20 69 6e 74 20 2a 70 69  char *p, int *pi
0cd0: 29 7b 0a 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  ){. sqlite_int64
0ce0: 20 69 3b 0a 20 69 6e 74 20 72 65 74 20 3d 20 67   i;. int ret = g
0cf0: 65 74 56 61 72 69 6e 74 28 70 2c 20 26 69 29 3b  etVarint(p, &i);
0d00: 0a 20 2a 70 69 20 3d 20 28 69 6e 74 29 20 69 3b  . *pi = (int) i;
0d10: 0a 20 61 73 73 65 72 74 28 20 2a 70 69 3d 3d 69  . assert( *pi==i
0d20: 20 29 3b 0a 20 72 65 74 75 72 6e 20 72 65 74 3b   );. return ret;
0d30: 0a 7d 0a 0a 2f 2a 2a 2a 20 44 6f 63 75 6d 65 6e  .}../*** Documen
0d40: 74 20 6c 69 73 74 73 20 2a 2a 2a 0a 20 2a 0a 20  t lists ***. *. 
0d50: 2a 20 41 20 64 6f 63 75 6d 65 6e 74 20 6c 69 73  * A document lis
0d60: 74 20 68 6f 6c 64 73 20 61 20 73 6f 72 74 65 64  t holds a sorted
0d70: 20 6c 69 73 74 20 6f 66 20 76 61 72 69 6e 74 2d   list of varint-
0d80: 65 6e 63 6f 64 65 64 20 64 6f 63 75 6d 65 6e 74  encoded document
0d90: 20 49 44 73 2e 0a 20 2a 0a 20 2a 20 41 20 64 6f   IDs.. *. * A do
0da0: 63 6c 69 73 74 20 77 69 74 68 20 74 79 70 65 20  clist with type 
0db0: 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 5f 4f 46 46  DL_POSITIONS_OFF
0dc0: 53 45 54 53 20 69 73 20 73 74 6f 72 65 64 20 6c  SETS is stored l
0dd0: 69 6b 65 20 74 68 69 73 3a 0a 20 2a 0a 20 2a 20  ike this:. *. * 
0de0: 61 72 72 61 79 20 7b 0a 20 2a 20 20 20 76 61 72  array {. *   var
0df0: 69 6e 74 20 64 6f 63 69 64 3b 0a 20 2a 20 20 20  int docid;. *   
0e00: 61 72 72 61 79 20 7b 0a 20 2a 20 20 20 20 20 76  array {. *     v
0e10: 61 72 69 6e 74 20 70 6f 73 69 74 69 6f 6e 3b 20  arint position; 
0e20: 20 20 20 20 28 64 65 6c 74 61 20 66 72 6f 6d 20      (delta from 
0e30: 70 72 65 76 69 6f 75 73 20 70 6f 73 69 74 69 6f  previous positio
0e40: 6e 20 70 6c 75 73 20 50 4f 53 5f 42 41 53 45 29  n plus POS_BASE)
0e50: 0a 20 2a 20 20 20 20 20 76 61 72 69 6e 74 20 73  . *     varint s
0e60: 74 61 72 74 4f 66 66 73 65 74 3b 20 20 28 64 65  tartOffset;  (de
0e70: 6c 74 61 20 66 72 6f 6d 20 70 72 65 76 69 6f 75  lta from previou
0e80: 73 20 73 74 61 72 74 4f 66 66 73 65 74 29 0a 20  s startOffset). 
0e90: 2a 20 20 20 20 20 76 61 72 69 6e 74 20 65 6e 64  *     varint end
0ea0: 4f 66 66 73 65 74 3b 20 20 20 20 28 64 65 6c 74  Offset;    (delt
0eb0: 61 20 66 72 6f 6d 20 73 74 61 72 74 4f 66 66 73  a from startOffs
0ec0: 65 74 29 0a 20 2a 20 20 20 7d 0a 20 2a 20 7d 0a  et). *   }. * }.
0ed0: 20 2a 0a 20 2a 20 48 65 72 65 2c 20 61 72 72 61   *. * Here, arra
0ee0: 79 20 7b 20 58 20 7d 20 6d 65 61 6e 73 20 7a 65  y { X } means ze
0ef0: 72 6f 20 6f 72 20 6d 6f 72 65 20 6f 63 63 75 72  ro or more occur
0f00: 72 65 6e 63 65 73 20 6f 66 20 58 2c 20 61 64 6a  rences of X, adj
0f10: 61 63 65 6e 74 20 69 6e 20 6d 65 6d 6f 72 79 2e  acent in memory.
0f20: 0a 20 2a 0a 20 2a 20 41 20 70 6f 73 69 74 69 6f  . *. * A positio
0f30: 6e 20 6c 69 73 74 20 6d 61 79 20 68 6f 6c 64 20  n list may hold 
0f40: 70 6f 73 69 74 69 6f 6e 73 20 66 6f 72 20 74 65  positions for te
0f50: 78 74 20 69 6e 20 6d 75 6c 74 69 70 6c 65 20 63  xt in multiple c
0f60: 6f 6c 75 6d 6e 73 2e 20 20 41 20 70 6f 73 69 74  olumns.  A posit
0f70: 69 6f 6e 0a 20 2a 20 50 4f 53 5f 43 4f 4c 55 4d  ion. * POS_COLUM
0f80: 4e 20 69 73 20 66 6f 6c 6c 6f 77 65 64 20 62 79  N is followed by
0f90: 20 61 20 76 61 72 69 6e 74 20 63 6f 6e 74 61 69   a varint contai
0fa0: 6e 69 6e 67 20 74 68 65 20 69 6e 64 65 78 20 6f  ning the index o
0fb0: 66 20 74 68 65 20 63 6f 6c 75 6d 6e 20 66 6f 72  f the column for
0fc0: 0a 20 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20 70 6f  . * following po
0fd0: 73 69 74 69 6f 6e 73 20 69 6e 20 74 68 65 20 6c  sitions in the l
0fe0: 69 73 74 2e 20 20 41 6e 79 20 70 6f 73 69 74 69  ist.  Any positi
0ff0: 6f 6e 73 20 61 70 70 65 61 72 69 6e 67 20 62 65  ons appearing be
1000: 66 6f 72 65 20 61 6e 79 0a 20 2a 20 6f 63 63 75  fore any. * occu
1010: 72 72 65 6e 63 65 73 20 6f 66 20 50 4f 53 5f 43  rrences of POS_C
1020: 4f 4c 55 4d 4e 20 61 72 65 20 66 6f 72 20 63 6f  OLUMN are for co
1030: 6c 75 6d 6e 20 30 2e 0a 20 2a 0a 20 2a 20 41 20  lumn 0.. *. * A 
1040: 64 6f 63 6c 69 73 74 20 77 69 74 68 20 74 79 70  doclist with typ
1050: 65 20 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 69  e DL_POSITIONS i
1060: 73 20 6c 69 6b 65 20 74 68 65 20 61 62 6f 76 65  s like the above
1070: 2c 20 62 75 74 20 68 6f 6c 64 73 20 6f 6e 6c 79  , but holds only
1080: 20 64 6f 63 69 64 73 0a 20 2a 20 61 6e 64 20 70   docids. * and p
1090: 6f 73 69 74 69 6f 6e 73 20 77 69 74 68 6f 75 74  ositions without
10a0: 20 6f 66 66 73 65 74 20 69 6e 66 6f 72 6d 61 74   offset informat
10b0: 69 6f 6e 2e 0a 20 2a 0a 20 2a 20 41 20 64 6f 63  ion.. *. * A doc
10c0: 6c 69 73 74 20 77 69 74 68 20 74 79 70 65 20 44  list with type D
10d0: 4c 5f 44 4f 43 49 44 53 20 69 73 20 6c 69 6b 65  L_DOCIDS is like
10e0: 20 74 68 65 20 61 62 6f 76 65 2c 20 62 75 74 20   the above, but 
10f0: 68 6f 6c 64 73 20 6f 6e 6c 79 20 64 6f 63 69 64  holds only docid
1100: 73 0a 20 2a 20 77 69 74 68 6f 75 74 20 70 6f 73  s. * without pos
1110: 69 74 69 6f 6e 73 20 6f 72 20 6f 66 66 73 65 74  itions or offset
1120: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 0a 20 2a   information.. *
1130: 0a 20 2a 20 4f 6e 20 64 69 73 6b 2c 20 65 76 65  . * On disk, eve
1140: 72 79 20 64 6f 63 75 6d 65 6e 74 20 6c 69 73 74  ry document list
1150: 20 68 61 73 20 70 6f 73 69 74 69 6f 6e 73 20 61   has positions a
1160: 6e 64 20 6f 66 66 73 65 74 73 2c 20 73 6f 20 77  nd offsets, so w
1170: 65 20 64 6f 6e 27 74 20 62 6f 74 68 65 72 0a 20  e don't bother. 
1180: 2a 20 74 6f 20 73 65 72 69 61 6c 69 7a 65 20 61  * to serialize a
1190: 20 64 6f 63 6c 69 73 74 27 73 20 74 79 70 65 2e   doclist's type.
11a0: 0a 20 2a 20 0a 20 2a 20 57 65 20 64 6f 6e 27 74  . * . * We don't
11b0: 20 79 65 74 20 64 65 6c 74 61 2d 65 6e 63 6f 64   yet delta-encod
11c0: 65 20 64 6f 63 75 6d 65 6e 74 20 49 44 73 3b 20  e document IDs; 
11d0: 64 6f 69 6e 67 20 73 6f 20 77 69 6c 6c 20 70 72  doing so will pr
11e0: 6f 62 61 62 6c 79 20 62 65 20 61 0a 20 2a 20 6d  obably be a. * m
11f0: 6f 64 65 73 74 20 77 69 6e 2e 0a 20 2a 0a 20 2a  odest win.. *. *
1200: 20 4e 4f 54 45 28 73 68 65 73 73 29 20 49 27 76   NOTE(shess) I'v
1210: 65 20 74 68 6f 75 67 68 74 20 6f 66 20 61 20 73  e thought of a s
1220: 6c 69 67 68 74 6c 79 20 28 31 25 29 20 62 65 74  lightly (1%) bet
1230: 74 65 72 20 6f 66 66 73 65 74 20 65 6e 63 6f 64  ter offset encod
1240: 69 6e 67 2e 0a 20 2a 20 41 66 74 65 72 20 74 68  ing.. * After th
1250: 65 20 66 69 72 73 74 20 6f 66 66 73 65 74 2c 20  e first offset, 
1260: 65 73 74 69 6d 61 74 65 20 74 68 65 20 6e 65 78  estimate the nex
1270: 74 20 6f 66 66 73 65 74 20 62 79 20 75 73 69 6e  t offset by usin
1280: 67 20 74 68 65 0a 20 2a 20 63 75 72 72 65 6e 74  g the. * current
1290: 20 74 6f 6b 65 6e 20 70 6f 73 69 74 69 6f 6e 20   token position 
12a0: 61 6e 64 20 74 68 65 20 70 72 65 76 69 6f 75 73  and the previous
12b0: 20 74 6f 6b 65 6e 20 70 6f 73 69 74 69 6f 6e 20   token position 
12c0: 61 6e 64 20 6f 66 66 73 65 74 2c 0a 20 2a 20 6f  and offset,. * o
12d0: 66 66 73 65 74 20 74 6f 20 68 61 6e 64 6c 65 20  ffset to handle 
12e0: 73 6f 6d 65 20 76 61 72 69 61 6e 63 65 2e 20 20  some variance.  
12f0: 53 6f 20 74 68 65 20 65 73 74 69 6d 61 74 65 20  So the estimate 
1300: 77 6f 75 6c 64 20 62 65 0a 20 2a 20 28 69 50 6f  would be. * (iPo
1310: 73 69 74 69 6f 6e 2a 77 2d 3e 69 53 74 61 72 74  sition*w->iStart
1320: 4f 66 66 73 65 74 2f 77 2d 3e 69 50 6f 73 69 74  Offset/w->iPosit
1330: 69 6f 6e 2d 36 34 29 2c 20 77 68 69 63 68 20 69  ion-64), which i
1340: 73 20 64 65 6c 74 61 2d 65 6e 63 6f 64 65 64 0a  s delta-encoded.
1350: 20 2a 20 61 73 20 6e 6f 72 6d 61 6c 2e 20 20 4f   * as normal.  O
1360: 66 66 73 65 74 73 20 6d 6f 72 65 20 74 68 61 6e  ffsets more than
1370: 20 36 34 20 63 68 61 72 73 20 66 72 6f 6d 20 74   64 chars from t
1380: 68 65 20 65 73 74 69 6d 61 74 65 20 61 72 65 0a  he estimate are.
1390: 20 2a 20 65 6e 63 6f 64 65 64 20 61 73 20 74 68   * encoded as th
13a0: 65 20 64 65 6c 74 61 20 74 6f 20 74 68 65 20 70  e delta to the p
13b0: 72 65 76 69 6f 75 73 20 73 74 61 72 74 20 6f 66  revious start of
13c0: 66 73 65 74 20 2b 20 31 32 38 2e 20 20 41 6e 0a  fset + 128.  An.
13d0: 20 2a 20 61 64 64 69 74 69 6f 6e 61 6c 20 74 69   * additional ti
13e0: 6e 79 20 69 6e 63 72 65 6d 65 6e 74 20 63 61 6e  ny increment can
13f0: 20 62 65 20 67 61 69 6e 65 64 20 62 79 20 75 73   be gained by us
1400: 69 6e 67 20 74 68 65 20 65 6e 64 20 6f 66 66 73  ing the end offs
1410: 65 74 20 6f 66 0a 20 2a 20 74 68 65 20 70 72 65  et of. * the pre
1420: 76 69 6f 75 73 20 74 6f 6b 65 6e 20 74 6f 20 6d  vious token to m
1430: 61 6b 65 20 74 68 65 20 65 73 74 69 6d 61 74 65  ake the estimate
1440: 20 61 20 74 69 6e 79 20 62 69 74 20 6d 6f 72 65   a tiny bit more
1450: 20 70 72 65 63 69 73 65 2e 0a 2a 2f 0a 0a 74 79   precise..*/..ty
1460: 70 65 64 65 66 20 65 6e 75 6d 20 44 6f 63 4c 69  pedef enum DocLi
1470: 73 74 54 79 70 65 20 7b 0a 20 20 44 4c 5f 44 4f  stType {.  DL_DO
1480: 43 49 44 53 2c 20 20 20 20 20 20 20 20 20 20 20  CIDS,           
1490: 20 20 20 2f 2a 20 64 6f 63 69 64 73 20 6f 6e 6c     /* docids onl
14a0: 79 20 2a 2f 0a 20 20 44 4c 5f 50 4f 53 49 54 49  y */.  DL_POSITI
14b0: 4f 4e 53 2c 20 20 20 20 20 20 20 20 20 20 20 2f  ONS,           /
14c0: 2a 20 64 6f 63 69 64 73 20 2b 20 70 6f 73 69 74  * docids + posit
14d0: 69 6f 6e 73 20 2a 2f 0a 20 20 44 4c 5f 50 4f 53  ions */.  DL_POS
14e0: 49 54 49 4f 4e 53 5f 4f 46 46 53 45 54 53 20 20  ITIONS_OFFSETS  
14f0: 20 20 2f 2a 20 64 6f 63 69 64 73 20 2b 20 70 6f    /* docids + po
1500: 73 69 74 69 6f 6e 73 20 2b 20 6f 66 66 73 65 74  sitions + offset
1510: 73 20 2a 2f 0a 7d 20 44 6f 63 4c 69 73 74 54 79  s */.} DocListTy
1520: 70 65 3b 0a 0a 2f 2a 0a 2a 2a 20 42 79 20 64 65  pe;../*.** By de
1530: 66 61 75 6c 74 2c 20 6f 6e 6c 79 20 70 6f 73 69  fault, only posi
1540: 74 69 6f 6e 73 20 61 6e 64 20 6e 6f 74 20 6f 66  tions and not of
1550: 66 73 65 74 73 20 61 72 65 20 73 74 6f 72 65 64  fsets are stored
1560: 20 69 6e 20 74 68 65 20 64 6f 63 6c 69 73 74 73   in the doclists
1570: 2e 0a 2a 2a 20 54 6f 20 63 68 61 6e 67 65 20 74  ..** To change t
1580: 68 69 73 20 73 6f 20 74 68 61 74 20 6f 66 66 73  his so that offs
1590: 65 74 73 20 61 72 65 20 73 74 6f 72 65 64 20 74  ets are stored t
15a0: 6f 6f 2c 20 63 6f 6d 70 69 6c 65 20 77 69 74 68  oo, compile with
15b0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  .**.**          
15c0: 2d 44 44 4c 5f 44 45 46 41 55 4c 54 3d 44 4c 5f  -DDL_DEFAULT=DL_
15d0: 50 4f 53 49 54 49 4f 4e 53 5f 4f 46 46 53 45 54  POSITIONS_OFFSET
15e0: 53 0a 2a 2a 0a 2a 2f 0a 23 69 66 6e 64 65 66 20  S.**.*/.#ifndef 
15f0: 44 4c 5f 44 45 46 41 55 4c 54 0a 23 20 64 65 66  DL_DEFAULT.# def
1600: 69 6e 65 20 44 4c 5f 44 45 46 41 55 4c 54 20 44  ine DL_DEFAULT D
1610: 4c 5f 50 4f 53 49 54 49 4f 4e 53 0a 23 65 6e 64  L_POSITIONS.#end
1620: 69 66 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75  if..typedef stru
1630: 63 74 20 44 6f 63 4c 69 73 74 20 7b 0a 20 20 63  ct DocList {.  c
1640: 68 61 72 20 2a 70 44 61 74 61 3b 0a 20 20 69 6e  har *pData;.  in
1650: 74 20 6e 44 61 74 61 3b 0a 20 20 44 6f 63 4c 69  t nData;.  DocLi
1660: 73 74 54 79 70 65 20 69 54 79 70 65 3b 0a 20 20  stType iType;.  
1670: 69 6e 74 20 69 4c 61 73 74 43 6f 6c 75 6d 6e 3b  int iLastColumn;
1680: 20 20 20 20 2f 2a 20 74 68 65 20 6c 61 73 74 20      /* the last 
1690: 63 6f 6c 75 6d 6e 20 77 72 69 74 74 65 6e 20 2a  column written *
16a0: 2f 0a 20 20 69 6e 74 20 69 4c 61 73 74 50 6f 73  /.  int iLastPos
16b0: 3b 20 20 20 20 20 20 20 2f 2a 20 74 68 65 20 6c  ;       /* the l
16c0: 61 73 74 20 70 6f 73 69 74 69 6f 6e 20 77 72 69  ast position wri
16d0: 74 74 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 4c  tten */.  int iL
16e0: 61 73 74 4f 66 66 73 65 74 3b 20 20 20 20 2f 2a  astOffset;    /*
16f0: 20 74 68 65 20 6c 61 73 74 20 73 74 61 72 74 20   the last start 
1700: 6f 66 66 73 65 74 20 77 72 69 74 74 65 6e 20 2a  offset written *
1710: 2f 0a 7d 20 44 6f 63 4c 69 73 74 3b 0a 0a 65 6e  /.} DocList;..en
1720: 75 6d 20 7b 0a 20 20 50 4f 53 5f 45 4e 44 20 3d  um {.  POS_END =
1730: 20 30 2c 20 20 20 20 20 20 20 20 2f 2a 20 65 6e   0,        /* en
1740: 64 20 6f 66 20 74 68 69 73 20 70 6f 73 69 74 69  d of this positi
1750: 6f 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 50 4f 53  on list */.  POS
1760: 5f 43 4f 4c 55 4d 4e 2c 20 20 20 20 20 20 20 20  _COLUMN,        
1770: 20 2f 2a 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20   /* followed by 
1780: 6e 65 77 20 63 6f 6c 75 6d 6e 20 6e 75 6d 62 65  new column numbe
1790: 72 20 2a 2f 0a 20 20 50 4f 53 5f 42 41 53 45 0a  r */.  POS_BASE.
17a0: 7d 3b 0a 0a 2f 2a 20 49 6e 69 74 69 61 6c 69 7a  };../* Initializ
17b0: 65 20 61 20 6e 65 77 20 44 6f 63 4c 69 73 74 20  e a new DocList 
17c0: 74 6f 20 68 6f 6c 64 20 74 68 65 20 67 69 76 65  to hold the give
17d0: 6e 20 64 61 74 61 2e 20 2a 2f 0a 73 74 61 74 69  n data. */.stati
17e0: 63 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 49 6e  c void docListIn
17f0: 69 74 28 44 6f 63 4c 69 73 74 20 2a 64 2c 20 44  it(DocList *d, D
1800: 6f 63 4c 69 73 74 54 79 70 65 20 69 54 79 70 65  ocListType iType
1810: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
1820: 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20            const 
1830: 63 68 61 72 20 2a 70 44 61 74 61 2c 20 69 6e 74  char *pData, int
1840: 20 6e 44 61 74 61 29 7b 0a 20 20 64 2d 3e 6e 44   nData){.  d->nD
1850: 61 74 61 20 3d 20 6e 44 61 74 61 3b 0a 20 20 69  ata = nData;.  i
1860: 66 28 20 6e 44 61 74 61 3e 30 20 29 7b 0a 20 20  f( nData>0 ){.  
1870: 20 20 64 2d 3e 70 44 61 74 61 20 3d 20 6d 61 6c    d->pData = mal
1880: 6c 6f 63 28 6e 44 61 74 61 29 3b 0a 20 20 20 20  loc(nData);.    
1890: 6d 65 6d 63 70 79 28 64 2d 3e 70 44 61 74 61 2c  memcpy(d->pData,
18a0: 20 70 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a   pData, nData);.
18b0: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 64    } else {.    d
18c0: 2d 3e 70 44 61 74 61 20 3d 20 4e 55 4c 4c 3b 0a  ->pData = NULL;.
18d0: 20 20 7d 0a 20 20 64 2d 3e 69 54 79 70 65 20 3d    }.  d->iType =
18e0: 20 69 54 79 70 65 3b 0a 20 20 64 2d 3e 69 4c 61   iType;.  d->iLa
18f0: 73 74 43 6f 6c 75 6d 6e 20 3d 20 30 3b 0a 20 20  stColumn = 0;.  
1900: 64 2d 3e 69 4c 61 73 74 50 6f 73 20 3d 20 64 2d  d->iLastPos = d-
1910: 3e 69 4c 61 73 74 4f 66 66 73 65 74 20 3d 20 30  >iLastOffset = 0
1920: 3b 0a 7d 0a 0a 2f 2a 20 43 72 65 61 74 65 20 61  ;.}../* Create a
1930: 20 6e 65 77 20 64 79 6e 61 6d 69 63 61 6c 6c 79   new dynamically
1940: 2d 61 6c 6c 6f 63 61 74 65 64 20 44 6f 63 4c 69  -allocated DocLi
1950: 73 74 2e 20 2a 2f 0a 73 74 61 74 69 63 20 44 6f  st. */.static Do
1960: 63 4c 69 73 74 20 2a 64 6f 63 4c 69 73 74 4e 65  cList *docListNe
1970: 77 28 44 6f 63 4c 69 73 74 54 79 70 65 20 69 54  w(DocListType iT
1980: 79 70 65 29 7b 0a 20 20 44 6f 63 4c 69 73 74 20  ype){.  DocList 
1990: 2a 64 20 3d 20 28 44 6f 63 4c 69 73 74 20 2a 29  *d = (DocList *)
19a0: 20 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 44   malloc(sizeof(D
19b0: 6f 63 4c 69 73 74 29 29 3b 0a 20 20 64 6f 63 4c  ocList));.  docL
19c0: 69 73 74 49 6e 69 74 28 64 2c 20 69 54 79 70 65  istInit(d, iType
19d0: 2c 20 30 2c 20 30 29 3b 0a 20 20 72 65 74 75 72  , 0, 0);.  retur
19e0: 6e 20 64 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  n d;.}..static v
19f0: 6f 69 64 20 64 6f 63 4c 69 73 74 44 65 73 74 72  oid docListDestr
1a00: 6f 79 28 44 6f 63 4c 69 73 74 20 2a 64 29 7b 0a  oy(DocList *d){.
1a10: 20 20 66 72 65 65 28 64 2d 3e 70 44 61 74 61 29    free(d->pData)
1a20: 3b 0a 23 69 66 6e 64 65 66 20 4e 44 45 42 55 47  ;.#ifndef NDEBUG
1a30: 0a 20 20 6d 65 6d 73 65 74 28 64 2c 20 30 78 35  .  memset(d, 0x5
1a40: 35 2c 20 73 69 7a 65 6f 66 28 2a 64 29 29 3b 0a  5, sizeof(*d));.
1a50: 23 65 6e 64 69 66 0a 7d 0a 0a 73 74 61 74 69 63  #endif.}..static
1a60: 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 44 65 6c   void docListDel
1a70: 65 74 65 28 44 6f 63 4c 69 73 74 20 2a 64 29 7b  ete(DocList *d){
1a80: 0a 20 20 64 6f 63 4c 69 73 74 44 65 73 74 72 6f  .  docListDestro
1a90: 79 28 64 29 3b 0a 20 20 66 72 65 65 28 64 29 3b  y(d);.  free(d);
1aa0: 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20  .}..static char 
1ab0: 2a 64 6f 63 4c 69 73 74 45 6e 64 28 44 6f 63 4c  *docListEnd(DocL
1ac0: 69 73 74 20 2a 64 29 7b 0a 20 20 72 65 74 75 72  ist *d){.  retur
1ad0: 6e 20 64 2d 3e 70 44 61 74 61 20 2b 20 64 2d 3e  n d->pData + d->
1ae0: 6e 44 61 74 61 3b 0a 7d 0a 0a 2f 2a 20 41 70 70  nData;.}../* App
1af0: 65 6e 64 20 61 20 76 61 72 69 6e 74 20 74 6f 20  end a varint to 
1b00: 61 20 44 6f 63 4c 69 73 74 27 73 20 64 61 74 61  a DocList's data
1b10: 2e 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  . */.static void
1b20: 20 61 70 70 65 6e 64 56 61 72 69 6e 74 28 44 6f   appendVarint(Do
1b30: 63 4c 69 73 74 20 2a 64 2c 20 73 71 6c 69 74 65  cList *d, sqlite
1b40: 5f 69 6e 74 36 34 20 69 29 7b 0a 20 20 63 68 61  _int64 i){.  cha
1b50: 72 20 63 5b 56 41 52 49 4e 54 5f 4d 41 58 5d 3b  r c[VARINT_MAX];
1b60: 0a 20 20 69 6e 74 20 6e 20 3d 20 70 75 74 56 61  .  int n = putVa
1b70: 72 69 6e 74 28 63 2c 20 69 29 3b 0a 20 20 64 2d  rint(c, i);.  d-
1b80: 3e 70 44 61 74 61 20 3d 20 72 65 61 6c 6c 6f 63  >pData = realloc
1b90: 28 64 2d 3e 70 44 61 74 61 2c 20 64 2d 3e 6e 44  (d->pData, d->nD
1ba0: 61 74 61 20 2b 20 6e 29 3b 0a 20 20 6d 65 6d 63  ata + n);.  memc
1bb0: 70 79 28 64 2d 3e 70 44 61 74 61 20 2b 20 64 2d  py(d->pData + d-
1bc0: 3e 6e 44 61 74 61 2c 20 63 2c 20 6e 29 3b 0a 20  >nData, c, n);. 
1bd0: 20 64 2d 3e 6e 44 61 74 61 20 2b 3d 20 6e 3b 0a   d->nData += n;.
1be0: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  }..static void d
1bf0: 6f 63 4c 69 73 74 41 64 64 44 6f 63 69 64 28 44  ocListAddDocid(D
1c00: 6f 63 4c 69 73 74 20 2a 64 2c 20 73 71 6c 69 74  ocList *d, sqlit
1c10: 65 5f 69 6e 74 36 34 20 69 44 6f 63 69 64 29 7b  e_int64 iDocid){
1c20: 0a 20 20 61 70 70 65 6e 64 56 61 72 69 6e 74 28  .  appendVarint(
1c30: 64 2c 20 69 44 6f 63 69 64 29 3b 0a 20 20 69 66  d, iDocid);.  if
1c40: 28 20 64 2d 3e 69 54 79 70 65 3e 3d 44 4c 5f 50  ( d->iType>=DL_P
1c50: 4f 53 49 54 49 4f 4e 53 20 29 7b 0a 20 20 20 20  OSITIONS ){.    
1c60: 61 70 70 65 6e 64 56 61 72 69 6e 74 28 64 2c 20  appendVarint(d, 
1c70: 50 4f 53 5f 45 4e 44 29 3b 20 20 2f 2a 20 69 6e  POS_END);  /* in
1c80: 69 74 69 61 6c 6c 79 20 65 6d 70 74 79 20 70 6f  itially empty po
1c90: 73 69 74 69 6f 6e 20 6c 69 73 74 20 2a 2f 0a 20  sition list */. 
1ca0: 20 20 20 64 2d 3e 69 4c 61 73 74 43 6f 6c 75 6d     d->iLastColum
1cb0: 6e 20 3d 20 30 3b 0a 20 20 20 20 64 2d 3e 69 4c  n = 0;.    d->iL
1cc0: 61 73 74 50 6f 73 20 3d 20 64 2d 3e 69 4c 61 73  astPos = d->iLas
1cd0: 74 4f 66 66 73 65 74 20 3d 20 30 3b 0a 20 20 7d  tOffset = 0;.  }
1ce0: 0a 7d 0a 0a 2f 2a 20 68 65 6c 70 65 72 20 66 75  .}../* helper fu
1cf0: 6e 63 74 69 6f 6e 20 66 6f 72 20 64 6f 63 4c 69  nction for docLi
1d00: 73 74 41 64 64 50 6f 73 20 61 6e 64 20 64 6f 63  stAddPos and doc
1d10: 4c 69 73 74 41 64 64 50 6f 73 4f 66 66 73 65 74  ListAddPosOffset
1d20: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
1d30: 61 64 64 50 6f 73 28 44 6f 63 4c 69 73 74 20 2a  addPos(DocList *
1d40: 64 2c 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 2c 20  d, int iColumn, 
1d50: 69 6e 74 20 69 50 6f 73 29 7b 0a 20 20 61 73 73  int iPos){.  ass
1d60: 65 72 74 28 20 64 2d 3e 6e 44 61 74 61 3e 30 20  ert( d->nData>0 
1d70: 29 3b 0a 20 20 2d 2d 64 2d 3e 6e 44 61 74 61 3b  );.  --d->nData;
1d80: 20 20 2f 2a 20 72 65 6d 6f 76 65 20 70 72 65 76    /* remove prev
1d90: 69 6f 75 73 20 74 65 72 6d 69 6e 61 74 6f 72 20  ious terminator 
1da0: 2a 2f 0a 20 20 69 66 28 20 69 43 6f 6c 75 6d 6e  */.  if( iColumn
1db0: 21 3d 64 2d 3e 69 4c 61 73 74 43 6f 6c 75 6d 6e  !=d->iLastColumn
1dc0: 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20   ){.    assert( 
1dd0: 69 43 6f 6c 75 6d 6e 3e 64 2d 3e 69 4c 61 73 74  iColumn>d->iLast
1de0: 43 6f 6c 75 6d 6e 20 29 3b 0a 20 20 20 20 61 70  Column );.    ap
1df0: 70 65 6e 64 56 61 72 69 6e 74 28 64 2c 20 50 4f  pendVarint(d, PO
1e00: 53 5f 43 4f 4c 55 4d 4e 29 3b 0a 20 20 20 20 61  S_COLUMN);.    a
1e10: 70 70 65 6e 64 56 61 72 69 6e 74 28 64 2c 20 69  ppendVarint(d, i
1e20: 43 6f 6c 75 6d 6e 29 3b 0a 20 20 20 20 64 2d 3e  Column);.    d->
1e30: 69 4c 61 73 74 43 6f 6c 75 6d 6e 20 3d 20 69 43  iLastColumn = iC
1e40: 6f 6c 75 6d 6e 3b 0a 20 20 20 20 64 2d 3e 69 4c  olumn;.    d->iL
1e50: 61 73 74 50 6f 73 20 3d 20 64 2d 3e 69 4c 61 73  astPos = d->iLas
1e60: 74 4f 66 66 73 65 74 20 3d 20 30 3b 0a 20 20 7d  tOffset = 0;.  }
1e70: 0a 20 20 61 73 73 65 72 74 28 20 69 50 6f 73 3e  .  assert( iPos>
1e80: 3d 64 2d 3e 69 4c 61 73 74 50 6f 73 20 29 3b 0a  =d->iLastPos );.
1e90: 20 20 61 70 70 65 6e 64 56 61 72 69 6e 74 28 64    appendVarint(d
1ea0: 2c 20 69 50 6f 73 2d 64 2d 3e 69 4c 61 73 74 50  , iPos-d->iLastP
1eb0: 6f 73 2b 50 4f 53 5f 42 41 53 45 29 3b 0a 20 20  os+POS_BASE);.  
1ec0: 64 2d 3e 69 4c 61 73 74 50 6f 73 20 3d 20 69 50  d->iLastPos = iP
1ed0: 6f 73 3b 0a 7d 0a 0a 2f 2a 20 41 64 64 20 61 20  os;.}../* Add a 
1ee0: 70 6f 73 69 74 69 6f 6e 20 74 6f 20 74 68 65 20  position to the 
1ef0: 6c 61 73 74 20 70 6f 73 69 74 69 6f 6e 20 6c 69  last position li
1f00: 73 74 20 69 6e 20 61 20 64 6f 63 6c 69 73 74 2e  st in a doclist.
1f10: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
1f20: 64 6f 63 4c 69 73 74 41 64 64 50 6f 73 28 44 6f  docListAddPos(Do
1f30: 63 4c 69 73 74 20 2a 64 2c 20 69 6e 74 20 69 43  cList *d, int iC
1f40: 6f 6c 75 6d 6e 2c 20 69 6e 74 20 69 50 6f 73 29  olumn, int iPos)
1f50: 7b 0a 20 20 61 73 73 65 72 74 28 20 64 2d 3e 69  {.  assert( d->i
1f60: 54 79 70 65 3d 3d 44 4c 5f 50 4f 53 49 54 49 4f  Type==DL_POSITIO
1f70: 4e 53 20 29 3b 0a 20 20 61 64 64 50 6f 73 28 64  NS );.  addPos(d
1f80: 2c 20 69 43 6f 6c 75 6d 6e 2c 20 69 50 6f 73 29  , iColumn, iPos)
1f90: 3b 0a 20 20 61 70 70 65 6e 64 56 61 72 69 6e 74  ;.  appendVarint
1fa0: 28 64 2c 20 50 4f 53 5f 45 4e 44 29 3b 20 20 2f  (d, POS_END);  /
1fb0: 2a 20 61 64 64 20 6e 65 77 20 74 65 72 6d 69 6e  * add new termin
1fc0: 61 74 6f 72 20 2a 2f 0a 7d 0a 0a 2f 2a 0a 2a 2a  ator */.}../*.**
1fd0: 20 41 64 64 20 61 20 70 6f 73 69 74 69 6f 6e 20   Add a position 
1fe0: 61 6e 64 20 73 74 61 72 74 69 6e 67 20 61 6e 64  and starting and
1ff0: 20 65 6e 64 69 6e 67 20 6f 66 66 73 65 74 73 20   ending offsets 
2000: 74 6f 20 61 20 64 6f 63 6c 69 73 74 2e 0a 2a 2a  to a doclist..**
2010: 0a 2a 2a 20 49 66 20 74 68 65 20 64 6f 63 6c 69  .** If the docli
2020: 73 74 20 69 73 20 73 65 74 75 70 20 74 6f 20 68  st is setup to h
2030: 61 6e 64 6c 65 20 6f 6e 6c 79 20 70 6f 73 69 74  andle only posit
2040: 69 6f 6e 73 2c 20 74 68 65 6e 20 69 6e 73 65 72  ions, then inser
2050: 74 0a 2a 2a 20 74 68 65 20 70 6f 73 69 74 69 6f  t.** the positio
2060: 6e 20 6f 6e 6c 79 20 61 6e 64 20 69 67 6e 6f 72  n only and ignor
2070: 65 20 74 68 65 20 6f 66 66 73 65 74 73 2e 0a 2a  e the offsets..*
2080: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f  /.static void do
2090: 63 4c 69 73 74 41 64 64 50 6f 73 4f 66 66 73 65  cListAddPosOffse
20a0: 74 28 0a 20 20 44 6f 63 4c 69 73 74 20 2a 64 2c  t(.  DocList *d,
20b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
20c0: 44 6f 63 6c 69 73 74 20 75 6e 64 65 72 20 63 6f  Doclist under co
20d0: 6e 73 74 72 75 63 74 69 6f 6e 20 2a 2f 0a 20 20  nstruction */.  
20e0: 69 6e 74 20 69 43 6f 6c 75 6d 6e 2c 20 20 20 20  int iColumn,    
20f0: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6c 75 6d          /* Colum
2100: 6e 20 74 68 65 20 69 6e 73 65 72 74 65 64 20 74  n the inserted t
2110: 65 72 6d 20 69 73 20 70 61 72 74 20 6f 66 20 2a  erm is part of *
2120: 2f 0a 20 20 69 6e 74 20 69 50 6f 73 2c 20 20 20  /.  int iPos,   
2130: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
2140: 6f 73 69 74 69 6f 6e 20 6f 66 20 74 68 65 20 69  osition of the i
2150: 6e 73 65 72 74 65 64 20 74 65 72 6d 20 2a 2f 0a  nserted term */.
2160: 20 20 69 6e 74 20 69 53 74 61 72 74 4f 66 66 73    int iStartOffs
2170: 65 74 2c 20 20 20 20 20 20 20 2f 2a 20 53 74 61  et,       /* Sta
2180: 72 74 69 6e 67 20 6f 66 66 73 65 74 20 6f 66 20  rting offset of 
2190: 69 6e 73 65 72 74 65 64 20 74 65 72 6d 20 2a 2f  inserted term */
21a0: 0a 20 20 69 6e 74 20 69 45 6e 64 4f 66 66 73 65  .  int iEndOffse
21b0: 74 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45 6e  t          /* En
21c0: 64 69 6e 67 20 6f 66 66 73 65 74 20 6f 66 20 69  ding offset of i
21d0: 6e 73 65 72 74 65 64 20 74 65 72 6d 20 2a 2f 0a  nserted term */.
21e0: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 64 2d 3e  ){.  assert( d->
21f0: 69 54 79 70 65 3e 3d 44 4c 5f 50 4f 53 49 54 49  iType>=DL_POSITI
2200: 4f 4e 53 20 29 3b 0a 20 20 61 64 64 50 6f 73 28  ONS );.  addPos(
2210: 64 2c 20 69 43 6f 6c 75 6d 6e 2c 20 69 50 6f 73  d, iColumn, iPos
2220: 29 3b 0a 20 20 69 66 28 20 64 2d 3e 69 54 79 70  );.  if( d->iTyp
2230: 65 3d 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 5f  e==DL_POSITIONS_
2240: 4f 46 46 53 45 54 53 20 29 7b 0a 20 20 20 20 61  OFFSETS ){.    a
2250: 73 73 65 72 74 28 20 69 53 74 61 72 74 4f 66 66  ssert( iStartOff
2260: 73 65 74 3e 3d 64 2d 3e 69 4c 61 73 74 4f 66 66  set>=d->iLastOff
2270: 73 65 74 20 29 3b 0a 20 20 20 20 61 70 70 65 6e  set );.    appen
2280: 64 56 61 72 69 6e 74 28 64 2c 20 69 53 74 61 72  dVarint(d, iStar
2290: 74 4f 66 66 73 65 74 2d 64 2d 3e 69 4c 61 73 74  tOffset-d->iLast
22a0: 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 64 2d 3e  Offset);.    d->
22b0: 69 4c 61 73 74 4f 66 66 73 65 74 20 3d 20 69 53  iLastOffset = iS
22c0: 74 61 72 74 4f 66 66 73 65 74 3b 0a 20 20 20 20  tartOffset;.    
22d0: 61 73 73 65 72 74 28 20 69 45 6e 64 4f 66 66 73  assert( iEndOffs
22e0: 65 74 3e 3d 69 53 74 61 72 74 4f 66 66 73 65 74  et>=iStartOffset
22f0: 20 29 3b 0a 20 20 20 20 61 70 70 65 6e 64 56 61   );.    appendVa
2300: 72 69 6e 74 28 64 2c 20 69 45 6e 64 4f 66 66 73  rint(d, iEndOffs
2310: 65 74 2d 69 53 74 61 72 74 4f 66 66 73 65 74 29  et-iStartOffset)
2320: 3b 0a 20 20 7d 0a 20 20 61 70 70 65 6e 64 56 61  ;.  }.  appendVa
2330: 72 69 6e 74 28 64 2c 20 50 4f 53 5f 45 4e 44 29  rint(d, POS_END)
2340: 3b 20 20 2f 2a 20 61 64 64 20 6e 65 77 20 74 65  ;  /* add new te
2350: 72 6d 69 6e 61 74 6f 72 20 2a 2f 0a 7d 0a 0a 2f  rminator */.}../
2360: 2a 0a 2a 2a 20 41 20 44 6f 63 4c 69 73 74 52 65  *.** A DocListRe
2370: 61 64 65 72 20 6f 62 6a 65 63 74 20 69 73 20 61  ader object is a
2380: 20 63 75 72 73 6f 72 20 69 6e 74 6f 20 61 20 64   cursor into a d
2390: 6f 63 6c 69 73 74 2e 20 20 49 6e 69 74 69 61 6c  oclist.  Initial
23a0: 69 7a 65 0a 2a 2a 20 74 68 65 20 63 75 72 73 6f  ize.** the curso
23b0: 72 20 74 6f 20 74 68 65 20 62 65 67 69 6e 6e 69  r to the beginni
23c0: 6e 67 20 6f 66 20 74 68 65 20 64 6f 63 6c 69 73  ng of the doclis
23d0: 74 20 62 79 20 63 61 6c 6c 69 6e 67 20 72 65 61  t by calling rea
23e0: 64 65 72 49 6e 69 74 28 29 2e 0a 2a 2a 20 54 68  derInit()..** Th
23f0: 65 6e 20 75 73 65 20 72 6f 75 74 69 6e 65 73 0a  en use routines.
2400: 2a 2a 0a 2a 2a 20 20 20 20 20 20 70 65 65 6b 44  **.**      peekD
2410: 6f 63 69 64 28 29 0a 2a 2a 20 20 20 20 20 20 72  ocid().**      r
2420: 65 61 64 44 6f 63 69 64 28 29 0a 2a 2a 20 20 20  eadDocid().**   
2430: 20 20 20 72 65 61 64 50 6f 73 69 74 69 6f 6e 28     readPosition(
2440: 29 0a 2a 2a 20 20 20 20 20 20 73 6b 69 70 50 6f  ).**      skipPo
2450: 73 69 74 69 6f 6e 4c 69 73 74 28 29 0a 2a 2a 20  sitionList().** 
2460: 20 20 20 20 20 61 6e 64 20 73 6f 20 66 6f 72 74       and so fort
2470: 68 2e 2e 2e 0a 2a 2a 0a 2a 2a 20 74 6f 20 72 65  h....**.** to re
2480: 61 64 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f  ad information o
2490: 75 74 20 6f 66 20 74 68 65 20 64 6f 63 6c 69 73  ut of the doclis
24a0: 74 2e 20 20 57 68 65 6e 20 77 65 20 72 65 61 63  t.  When we reac
24b0: 68 20 74 68 65 20 65 6e 64 0a 2a 2a 20 6f 66 20  h the end.** of 
24c0: 74 68 65 20 64 6f 63 6c 69 73 74 2c 20 61 74 45  the doclist, atE
24d0: 6e 64 28 29 20 72 65 74 75 72 6e 73 20 54 52 55  nd() returns TRU
24e0: 45 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  E..*/.typedef st
24f0: 72 75 63 74 20 44 6f 63 4c 69 73 74 52 65 61 64  ruct DocListRead
2500: 65 72 20 7b 0a 20 20 44 6f 63 4c 69 73 74 20 2a  er {.  DocList *
2510: 70 44 6f 63 6c 69 73 74 3b 20 20 2f 2a 20 54 68  pDoclist;  /* Th
2520: 65 20 64 6f 63 75 6d 65 6e 74 20 6c 69 73 74 20  e document list 
2530: 77 65 20 61 72 65 20 73 74 65 70 70 69 6e 67 20  we are stepping 
2540: 74 68 72 6f 75 67 68 20 2a 2f 0a 20 20 63 68 61  through */.  cha
2550: 72 20 2a 70 3b 20 20 20 20 20 20 20 20 20 20 20  r *p;           
2560: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 6e   /* Pointer to n
2570: 65 78 74 20 75 6e 72 65 61 64 20 62 79 74 65 20  ext unread byte 
2580: 69 6e 20 74 68 65 20 64 6f 63 6c 69 73 74 20 2a  in the doclist *
2590: 2f 0a 20 20 69 6e 74 20 69 4c 61 73 74 43 6f 6c  /.  int iLastCol
25a0: 75 6d 6e 3b 0a 20 20 69 6e 74 20 69 4c 61 73 74  umn;.  int iLast
25b0: 50 6f 73 3b 20 20 2f 2a 20 74 68 65 20 6c 61 73  Pos;  /* the las
25c0: 74 20 70 6f 73 69 74 69 6f 6e 20 72 65 61 64 2c  t position read,
25d0: 20 6f 72 20 2d 31 20 77 68 65 6e 20 6e 6f 74 20   or -1 when not 
25e0: 69 6e 20 61 20 70 6f 73 69 74 69 6f 6e 20 6c 69  in a position li
25f0: 73 74 20 2a 2f 0a 7d 20 44 6f 63 4c 69 73 74 52  st */.} DocListR
2600: 65 61 64 65 72 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6e  eader;../*.** In
2610: 69 74 69 61 6c 69 7a 65 20 74 68 65 20 44 6f 63  itialize the Doc
2620: 4c 69 73 74 52 65 61 64 65 72 20 72 20 74 6f 20  ListReader r to 
2630: 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 62 65 67  point to the beg
2640: 69 6e 6e 69 6e 67 20 6f 66 20 70 44 6f 63 6c 69  inning of pDocli
2650: 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  st..*/.static vo
2660: 69 64 20 72 65 61 64 65 72 49 6e 69 74 28 44 6f  id readerInit(Do
2670: 63 4c 69 73 74 52 65 61 64 65 72 20 2a 72 2c 20  cListReader *r, 
2680: 44 6f 63 4c 69 73 74 20 2a 70 44 6f 63 6c 69 73  DocList *pDoclis
2690: 74 29 7b 0a 20 20 72 2d 3e 70 44 6f 63 6c 69 73  t){.  r->pDoclis
26a0: 74 20 3d 20 70 44 6f 63 6c 69 73 74 3b 0a 20 20  t = pDoclist;.  
26b0: 69 66 28 20 70 44 6f 63 6c 69 73 74 21 3d 4e 55  if( pDoclist!=NU
26c0: 4c 4c 20 29 7b 0a 20 20 20 20 72 2d 3e 70 20 3d  LL ){.    r->p =
26d0: 20 70 44 6f 63 6c 69 73 74 2d 3e 70 44 61 74 61   pDoclist->pData
26e0: 3b 0a 20 20 7d 0a 20 20 72 2d 3e 69 4c 61 73 74  ;.  }.  r->iLast
26f0: 43 6f 6c 75 6d 6e 20 3d 20 2d 31 3b 0a 20 20 72  Column = -1;.  r
2700: 2d 3e 69 4c 61 73 74 50 6f 73 20 3d 20 2d 31 3b  ->iLastPos = -1;
2710: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
2720: 20 54 52 55 45 20 69 66 20 77 65 20 68 61 76 65   TRUE if we have
2730: 20 72 65 61 63 68 65 64 20 74 68 65 6e 20 65 6e   reached then en
2740: 64 20 6f 66 20 70 52 65 61 64 65 72 20 61 6e 64  d of pReader and
2750: 20 74 68 65 72 65 20 69 73 0a 2a 2a 20 6e 6f 74   there is.** not
2760: 68 69 6e 67 20 65 6c 73 65 20 6c 65 66 74 20 74  hing else left t
2770: 6f 20 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69  o read..*/.stati
2780: 63 20 69 6e 74 20 61 74 45 6e 64 28 44 6f 63 4c  c int atEnd(DocL
2790: 69 73 74 52 65 61 64 65 72 20 2a 70 52 65 61 64  istReader *pRead
27a0: 65 72 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 52  er){.  return pR
27b0: 65 61 64 65 72 2d 3e 70 44 6f 63 6c 69 73 74 3d  eader->pDoclist=
27c0: 3d 30 20 7c 7c 20 28 70 52 65 61 64 65 72 2d 3e  =0 || (pReader->
27d0: 70 20 3e 3d 20 64 6f 63 4c 69 73 74 45 6e 64 28  p >= docListEnd(
27e0: 70 52 65 61 64 65 72 2d 3e 70 44 6f 63 6c 69 73  pReader->pDoclis
27f0: 74 29 29 3b 0a 7d 0a 0a 2f 2a 20 50 65 65 6b 20  t));.}../* Peek 
2800: 61 74 20 74 68 65 20 6e 65 78 74 20 64 6f 63 69  at the next doci
2810: 64 20 77 69 74 68 6f 75 74 20 61 64 76 61 6e 63  d without advanc
2820: 69 6e 67 20 74 68 65 20 72 65 61 64 20 70 6f 69  ing the read poi
2830: 6e 74 65 72 2e 20 0a 2a 2f 0a 73 74 61 74 69 63  nter. .*/.static
2840: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 70 65   sqlite_int64 pe
2850: 65 6b 44 6f 63 69 64 28 44 6f 63 4c 69 73 74 52  ekDocid(DocListR
2860: 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b  eader *pReader){
2870: 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  .  sqlite_int64 
2880: 72 65 74 3b 0a 20 20 61 73 73 65 72 74 28 20 21  ret;.  assert( !
2890: 61 74 45 6e 64 28 70 52 65 61 64 65 72 29 20 29  atEnd(pReader) )
28a0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 52 65 61  ;.  assert( pRea
28b0: 64 65 72 2d 3e 69 4c 61 73 74 50 6f 73 3d 3d 2d  der->iLastPos==-
28c0: 31 20 29 3b 0a 20 20 67 65 74 56 61 72 69 6e 74  1 );.  getVarint
28d0: 28 70 52 65 61 64 65 72 2d 3e 70 2c 20 26 72 65  (pReader->p, &re
28e0: 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 65 74  t);.  return ret
28f0: 3b 0a 7d 0a 0a 2f 2a 20 52 65 61 64 20 74 68 65  ;.}../* Read the
2900: 20 6e 65 78 74 20 64 6f 63 69 64 2e 20 20 20 53   next docid.   S
2910: 65 65 20 61 6c 73 6f 20 6e 65 78 74 44 6f 63 69  ee also nextDoci
2920: 64 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73  d()..*/.static s
2930: 71 6c 69 74 65 5f 69 6e 74 36 34 20 72 65 61 64  qlite_int64 read
2940: 44 6f 63 69 64 28 44 6f 63 4c 69 73 74 52 65 61  Docid(DocListRea
2950: 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20  der *pReader){. 
2960: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 72 65   sqlite_int64 re
2970: 74 3b 0a 20 20 61 73 73 65 72 74 28 20 21 61 74  t;.  assert( !at
2980: 45 6e 64 28 70 52 65 61 64 65 72 29 20 29 3b 0a  End(pReader) );.
2990: 20 20 61 73 73 65 72 74 28 20 70 52 65 61 64 65    assert( pReade
29a0: 72 2d 3e 69 4c 61 73 74 50 6f 73 3d 3d 2d 31 20  r->iLastPos==-1 
29b0: 29 3b 0a 20 20 70 52 65 61 64 65 72 2d 3e 70 20  );.  pReader->p 
29c0: 2b 3d 20 67 65 74 56 61 72 69 6e 74 28 70 52 65  += getVarint(pRe
29d0: 61 64 65 72 2d 3e 70 2c 20 26 72 65 74 29 3b 0a  ader->p, &ret);.
29e0: 20 20 69 66 28 20 70 52 65 61 64 65 72 2d 3e 70    if( pReader->p
29f0: 44 6f 63 6c 69 73 74 2d 3e 69 54 79 70 65 3e 3d  Doclist->iType>=
2a00: 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 29 7b 0a  DL_POSITIONS ){.
2a10: 20 20 20 20 70 52 65 61 64 65 72 2d 3e 69 4c 61      pReader->iLa
2a20: 73 74 43 6f 6c 75 6d 6e 20 3d 20 30 3b 0a 20 20  stColumn = 0;.  
2a30: 20 20 70 52 65 61 64 65 72 2d 3e 69 4c 61 73 74    pReader->iLast
2a40: 50 6f 73 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72  Pos = 0;.  }.  r
2a50: 65 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 2f 2a  eturn ret;.}../*
2a60: 20 52 65 61 64 20 74 68 65 20 6e 65 78 74 20 70   Read the next p
2a70: 6f 73 69 74 69 6f 6e 20 61 6e 64 20 63 6f 6c 75  osition and colu
2a80: 6d 6e 20 69 6e 64 65 78 20 66 72 6f 6d 20 61 20  mn index from a 
2a90: 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 2e 0a 20  position list.. 
2aa0: 2a 20 52 65 74 75 72 6e 73 20 74 68 65 20 70 6f  * Returns the po
2ab0: 73 69 74 69 6f 6e 2c 20 6f 72 20 2d 31 20 61 74  sition, or -1 at
2ac0: 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
2ad0: 6c 69 73 74 2e 20 2a 2f 0a 73 74 61 74 69 63 20  list. */.static 
2ae0: 69 6e 74 20 72 65 61 64 50 6f 73 69 74 69 6f 6e  int readPosition
2af0: 28 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20 2a  (DocListReader *
2b00: 70 52 65 61 64 65 72 2c 20 69 6e 74 20 2a 69 43  pReader, int *iC
2b10: 6f 6c 75 6d 6e 29 7b 0a 20 20 69 6e 74 20 69 3b  olumn){.  int i;
2b20: 0a 20 20 69 6e 74 20 69 54 79 70 65 20 3d 20 70  .  int iType = p
2b30: 52 65 61 64 65 72 2d 3e 70 44 6f 63 6c 69 73 74  Reader->pDoclist
2b40: 2d 3e 69 54 79 70 65 3b 0a 0a 20 20 69 66 28 20  ->iType;..  if( 
2b50: 70 52 65 61 64 65 72 2d 3e 69 4c 61 73 74 50 6f  pReader->iLastPo
2b60: 73 3d 3d 2d 31 20 29 7b 0a 20 20 20 20 72 65 74  s==-1 ){.    ret
2b70: 75 72 6e 20 2d 31 3b 0a 20 20 7d 0a 20 20 61 73  urn -1;.  }.  as
2b80: 73 65 72 74 28 20 21 61 74 45 6e 64 28 70 52 65  sert( !atEnd(pRe
2b90: 61 64 65 72 29 20 29 3b 0a 0a 20 20 69 66 28 20  ader) );..  if( 
2ba0: 69 54 79 70 65 3c 44 4c 5f 50 4f 53 49 54 49 4f  iType<DL_POSITIO
2bb0: 4e 53 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  NS ){.    return
2bc0: 20 2d 31 3b 0a 20 20 7d 0a 20 20 70 52 65 61 64   -1;.  }.  pRead
2bd0: 65 72 2d 3e 70 20 2b 3d 20 67 65 74 56 61 72 69  er->p += getVari
2be0: 6e 74 33 32 28 70 52 65 61 64 65 72 2d 3e 70 2c  nt32(pReader->p,
2bf0: 20 26 69 29 3b 0a 20 20 69 66 28 20 69 3d 3d 50   &i);.  if( i==P
2c00: 4f 53 5f 45 4e 44 20 29 7b 0a 20 20 20 20 70 52  OS_END ){.    pR
2c10: 65 61 64 65 72 2d 3e 69 4c 61 73 74 43 6f 6c 75  eader->iLastColu
2c20: 6d 6e 20 3d 20 70 52 65 61 64 65 72 2d 3e 69 4c  mn = pReader->iL
2c30: 61 73 74 50 6f 73 20 3d 20 2d 31 3b 0a 20 20 20  astPos = -1;.   
2c40: 20 2a 69 43 6f 6c 75 6d 6e 20 3d 20 2d 31 3b 0a   *iColumn = -1;.
2c50: 20 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20      return -1;. 
2c60: 20 7d 0a 20 20 69 66 28 20 69 3d 3d 50 4f 53 5f   }.  if( i==POS_
2c70: 43 4f 4c 55 4d 4e 20 29 7b 0a 20 20 20 20 70 52  COLUMN ){.    pR
2c80: 65 61 64 65 72 2d 3e 70 20 2b 3d 20 67 65 74 56  eader->p += getV
2c90: 61 72 69 6e 74 33 32 28 70 52 65 61 64 65 72 2d  arint32(pReader-
2ca0: 3e 70 2c 20 26 70 52 65 61 64 65 72 2d 3e 69 4c  >p, &pReader->iL
2cb0: 61 73 74 43 6f 6c 75 6d 6e 29 3b 0a 20 20 20 20  astColumn);.    
2cc0: 70 52 65 61 64 65 72 2d 3e 69 4c 61 73 74 50 6f  pReader->iLastPo
2cd0: 73 20 3d 20 30 3b 0a 20 20 20 20 70 52 65 61 64  s = 0;.    pRead
2ce0: 65 72 2d 3e 70 20 2b 3d 20 67 65 74 56 61 72 69  er->p += getVari
2cf0: 6e 74 33 32 28 70 52 65 61 64 65 72 2d 3e 70 2c  nt32(pReader->p,
2d00: 20 26 69 29 3b 0a 20 20 20 20 61 73 73 65 72 74   &i);.    assert
2d10: 28 20 69 3e 3d 50 4f 53 5f 42 41 53 45 20 29 3b  ( i>=POS_BASE );
2d20: 0a 20 20 7d 0a 20 20 70 52 65 61 64 65 72 2d 3e  .  }.  pReader->
2d30: 69 4c 61 73 74 50 6f 73 20 2b 3d 20 28 28 69 6e  iLastPos += ((in
2d40: 74 29 20 69 29 2d 50 4f 53 5f 42 41 53 45 3b 0a  t) i)-POS_BASE;.
2d50: 20 20 69 66 28 20 69 54 79 70 65 3e 3d 44 4c 5f    if( iType>=DL_
2d60: 50 4f 53 49 54 49 4f 4e 53 5f 4f 46 46 53 45 54  POSITIONS_OFFSET
2d70: 53 20 29 7b 0a 20 20 20 20 2f 2a 20 53 6b 69 70  S ){.    /* Skip
2d80: 20 6f 76 65 72 20 6f 66 66 73 65 74 73 2c 20 69   over offsets, i
2d90: 67 6e 6f 72 69 6e 67 20 74 68 65 6d 20 66 6f 72  gnoring them for
2da0: 20 6e 6f 77 2e 20 2a 2f 0a 20 20 20 20 69 6e 74   now. */.    int
2db0: 20 69 53 74 61 72 74 2c 20 69 45 6e 64 3b 0a 20   iStart, iEnd;. 
2dc0: 20 20 20 70 52 65 61 64 65 72 2d 3e 70 20 2b 3d     pReader->p +=
2dd0: 20 67 65 74 56 61 72 69 6e 74 33 32 28 70 52 65   getVarint32(pRe
2de0: 61 64 65 72 2d 3e 70 2c 20 26 69 53 74 61 72 74  ader->p, &iStart
2df0: 29 3b 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e  );.    pReader->
2e00: 70 20 2b 3d 20 67 65 74 56 61 72 69 6e 74 33 32  p += getVarint32
2e10: 28 70 52 65 61 64 65 72 2d 3e 70 2c 20 26 69 45  (pReader->p, &iE
2e20: 6e 64 29 3b 0a 20 20 7d 0a 20 20 2a 69 43 6f 6c  nd);.  }.  *iCol
2e30: 75 6d 6e 20 3d 20 70 52 65 61 64 65 72 2d 3e 69  umn = pReader->i
2e40: 4c 61 73 74 43 6f 6c 75 6d 6e 3b 0a 20 20 72 65  LastColumn;.  re
2e50: 74 75 72 6e 20 70 52 65 61 64 65 72 2d 3e 69 4c  turn pReader->iL
2e60: 61 73 74 50 6f 73 3b 0a 7d 0a 0a 2f 2a 20 53 6b  astPos;.}../* Sk
2e70: 69 70 20 70 61 73 74 20 74 68 65 20 65 6e 64 20  ip past the end 
2e80: 6f 66 20 61 20 70 6f 73 69 74 69 6f 6e 20 6c 69  of a position li
2e90: 73 74 2e 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  st. */.static vo
2ea0: 69 64 20 73 6b 69 70 50 6f 73 69 74 69 6f 6e 4c  id skipPositionL
2eb0: 69 73 74 28 44 6f 63 4c 69 73 74 52 65 61 64 65  ist(DocListReade
2ec0: 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 44  r *pReader){.  D
2ed0: 6f 63 4c 69 73 74 20 2a 70 20 3d 20 70 52 65 61  ocList *p = pRea
2ee0: 64 65 72 2d 3e 70 44 6f 63 6c 69 73 74 3b 0a 20  der->pDoclist;. 
2ef0: 20 69 66 28 20 70 20 26 26 20 70 2d 3e 69 54 79   if( p && p->iTy
2f00: 70 65 3e 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e 53  pe>=DL_POSITIONS
2f10: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c   ){.    int iCol
2f20: 75 6d 6e 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  umn;.    while( 
2f30: 72 65 61 64 50 6f 73 69 74 69 6f 6e 28 70 52 65  readPosition(pRe
2f40: 61 64 65 72 2c 20 26 69 43 6f 6c 75 6d 6e 29 21  ader, &iColumn)!
2f50: 3d 2d 31 20 29 7b 7d 0a 20 20 7d 0a 7d 0a 0a 2f  =-1 ){}.  }.}../
2f60: 2a 20 53 6b 69 70 20 6f 76 65 72 20 61 20 64 6f  * Skip over a do
2f70: 63 69 64 2c 20 69 6e 63 6c 75 64 69 6e 67 20 69  cid, including i
2f80: 74 73 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74  ts position list
2f90: 20 69 66 20 74 68 65 20 64 6f 63 6c 69 73 74 20   if the doclist 
2fa0: 68 61 73 0a 20 2a 20 70 6f 73 69 74 69 6f 6e 73  has. * positions
2fb0: 2e 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  . */.static void
2fc0: 20 73 6b 69 70 44 6f 63 75 6d 65 6e 74 28 44 6f   skipDocument(Do
2fd0: 63 4c 69 73 74 52 65 61 64 65 72 20 2a 70 52 65  cListReader *pRe
2fe0: 61 64 65 72 29 7b 0a 20 20 72 65 61 64 44 6f 63  ader){.  readDoc
2ff0: 69 64 28 70 52 65 61 64 65 72 29 3b 0a 20 20 73  id(pReader);.  s
3000: 6b 69 70 50 6f 73 69 74 69 6f 6e 4c 69 73 74 28  kipPositionList(
3010: 70 52 65 61 64 65 72 29 3b 0a 7d 0a 0a 2f 2a 20  pReader);.}../* 
3020: 53 6b 69 70 20 70 61 73 74 20 61 6c 6c 20 64 6f  Skip past all do
3030: 63 69 64 73 20 77 68 69 63 68 20 61 72 65 20 6c  cids which are l
3040: 65 73 73 20 74 68 61 6e 20 5b 69 44 6f 63 69 64  ess than [iDocid
3050: 5d 2e 20 20 52 65 74 75 72 6e 73 20 31 20 69 66  ].  Returns 1 if
3060: 20 61 20 64 6f 63 69 64 0a 20 2a 20 6d 61 74 63   a docid. * matc
3070: 68 69 6e 67 20 5b 69 44 6f 63 69 64 5d 20 77 61  hing [iDocid] wa
3080: 73 20 66 6f 75 6e 64 2e 20 20 2a 2f 0a 73 74 61  s found.  */.sta
3090: 74 69 63 20 69 6e 74 20 73 6b 69 70 54 6f 44 6f  tic int skipToDo
30a0: 63 69 64 28 44 6f 63 4c 69 73 74 52 65 61 64 65  cid(DocListReade
30b0: 72 20 2a 70 52 65 61 64 65 72 2c 20 73 71 6c 69  r *pReader, sqli
30c0: 74 65 5f 69 6e 74 36 34 20 69 44 6f 63 69 64 29  te_int64 iDocid)
30d0: 7b 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  {.  sqlite_int64
30e0: 20 64 20 3d 20 30 3b 0a 20 20 77 68 69 6c 65 28   d = 0;.  while(
30f0: 20 21 61 74 45 6e 64 28 70 52 65 61 64 65 72 29   !atEnd(pReader)
3100: 20 26 26 20 28 64 3d 70 65 65 6b 44 6f 63 69 64   && (d=peekDocid
3110: 28 70 52 65 61 64 65 72 29 29 3c 69 44 6f 63 69  (pReader))<iDoci
3120: 64 20 29 7b 0a 20 20 20 20 73 6b 69 70 44 6f 63  d ){.    skipDoc
3130: 75 6d 65 6e 74 28 70 52 65 61 64 65 72 29 3b 0a  ument(pReader);.
3140: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 21 61 74    }.  return !at
3150: 45 6e 64 28 70 52 65 61 64 65 72 29 20 26 26 20  End(pReader) && 
3160: 64 3d 3d 69 44 6f 63 69 64 3b 0a 7d 0a 0a 2f 2a  d==iDocid;.}../*
3170: 20 52 65 74 75 72 6e 20 74 68 65 20 66 69 72 73   Return the firs
3180: 74 20 64 6f 63 75 6d 65 6e 74 20 69 6e 20 61 20  t document in a 
3190: 64 6f 63 75 6d 65 6e 74 20 6c 69 73 74 2e 0a 2a  document list..*
31a0: 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 5f  /.static sqlite_
31b0: 69 6e 74 36 34 20 66 69 72 73 74 44 6f 63 69 64  int64 firstDocid
31c0: 28 44 6f 63 4c 69 73 74 20 2a 64 29 7b 0a 20 20  (DocList *d){.  
31d0: 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20 72 3b  DocListReader r;
31e0: 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28 26 72  .  readerInit(&r
31f0: 2c 20 64 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  , d);.  return r
3200: 65 61 64 44 6f 63 69 64 28 26 72 29 3b 0a 7d 0a  eadDocid(&r);.}.
3210: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44  .#ifdef SQLITE_D
3220: 45 42 55 47 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  EBUG./*.** This 
3230: 72 6f 75 74 69 6e 65 20 69 73 20 75 73 65 64 20  routine is used 
3240: 66 6f 72 20 64 65 62 75 67 67 69 6e 67 20 70 75  for debugging pu
3250: 72 70 6f 73 65 20 6f 6e 6c 79 2e 0a 2a 2a 0a 2a  rpose only..**.*
3260: 2a 20 57 72 69 74 65 20 74 68 65 20 63 6f 6e 74  * Write the cont
3270: 65 6e 74 20 6f 66 20 61 20 64 6f 63 6c 69 73 74  ent of a doclist
3280: 20 74 6f 20 73 74 61 6e 64 61 72 64 20 6f 75 74   to standard out
3290: 70 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  put..*/.static v
32a0: 6f 69 64 20 70 72 69 6e 74 44 6f 63 6c 69 73 74  oid printDoclist
32b0: 28 44 6f 63 4c 69 73 74 20 2a 70 29 7b 0a 20 20  (DocList *p){.  
32c0: 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20 72 3b  DocListReader r;
32d0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
32e0: 53 65 70 20 3d 20 22 22 3b 0a 0a 20 20 72 65 61  Sep = "";..  rea
32f0: 64 65 72 49 6e 69 74 28 26 72 2c 20 70 29 3b 0a  derInit(&r, p);.
3300: 20 20 77 68 69 6c 65 28 20 21 61 74 45 6e 64 28    while( !atEnd(
3310: 26 72 29 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  &r) ){.    sqlit
3320: 65 5f 69 6e 74 36 34 20 64 6f 63 69 64 20 3d 20  e_int64 docid = 
3330: 72 65 61 64 44 6f 63 69 64 28 26 72 29 3b 0a 20  readDocid(&r);. 
3340: 20 20 20 69 66 28 20 64 6f 63 69 64 3d 3d 30 20     if( docid==0 
3350: 29 7b 0a 20 20 20 20 20 20 73 6b 69 70 50 6f 73  ){.      skipPos
3360: 69 74 69 6f 6e 4c 69 73 74 28 26 72 29 3b 0a 20  itionList(&r);. 
3370: 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20       continue;. 
3380: 20 20 20 7d 0a 20 20 20 20 70 72 69 6e 74 66 28     }.    printf(
3390: 22 25 73 25 6c 6c 64 22 2c 20 7a 53 65 70 2c 20  "%s%lld", zSep, 
33a0: 64 6f 63 69 64 29 3b 0a 20 20 20 20 7a 53 65 70  docid);.    zSep
33b0: 20 3d 20 20 22 2c 22 3b 0a 20 20 20 20 69 66 28   =  ",";.    if(
33c0: 20 70 2d 3e 69 54 79 70 65 3e 3d 44 4c 5f 50 4f   p->iType>=DL_PO
33d0: 53 49 54 49 4f 4e 53 20 29 7b 0a 20 20 20 20 20  SITIONS ){.     
33e0: 20 69 6e 74 20 69 50 6f 73 2c 20 69 43 6f 6c 3b   int iPos, iCol;
33f0: 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61  .      const cha
3400: 72 20 2a 7a 44 69 76 20 3d 20 22 22 3b 0a 20 20  r *zDiv = "";.  
3410: 20 20 20 20 70 72 69 6e 74 66 28 22 28 22 29 3b      printf("(");
3420: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 28 69  .      while( (i
3430: 50 6f 73 20 3d 20 72 65 61 64 50 6f 73 69 74 69  Pos = readPositi
3440: 6f 6e 28 26 72 2c 20 26 69 43 6f 6c 29 29 3e 3d  on(&r, &iCol))>=
3450: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 70 72 69  0 ){.        pri
3460: 6e 74 66 28 22 25 73 25 64 3a 25 64 22 2c 20 7a  ntf("%s%d:%d", z
3470: 44 69 76 2c 20 69 43 6f 6c 2c 20 69 50 6f 73 29  Div, iCol, iPos)
3480: 3b 0a 20 20 20 20 20 20 20 20 7a 44 69 76 20 3d  ;.        zDiv =
3490: 20 22 3a 22 3b 0a 20 20 20 20 20 20 7d 0a 20 20   ":";.      }.  
34a0: 20 20 20 20 70 72 69 6e 74 66 28 22 29 22 29 3b      printf(")");
34b0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 72 69  .    }.  }.  pri
34c0: 6e 74 66 28 22 5c 6e 22 29 3b 0a 20 20 66 66 6c  ntf("\n");.  ffl
34d0: 75 73 68 28 73 74 64 6f 75 74 29 3b 0a 7d 0a 23  ush(stdout);.}.#
34e0: 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f  endif /* SQLITE_
34f0: 44 45 42 55 47 20 2a 2f 0a 0a 2f 2a 20 54 72 69  DEBUG */../* Tri
3500: 6d 20 74 68 65 20 67 69 76 65 6e 20 64 6f 63 6c  m the given docl
3510: 69 73 74 20 74 6f 20 63 6f 6e 74 61 69 6e 20 6f  ist to contain o
3520: 6e 6c 79 20 70 6f 73 69 74 69 6f 6e 73 20 69 6e  nly positions in
3530: 20 63 6f 6c 75 6d 6e 0a 20 2a 20 5b 69 52 65 73   column. * [iRes
3540: 74 72 69 63 74 43 6f 6c 75 6d 6e 5d 2e 20 2a 2f  trictColumn]. */
3550: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f 63  .static void doc
3560: 4c 69 73 74 52 65 73 74 72 69 63 74 43 6f 6c 75  ListRestrictColu
3570: 6d 6e 28 44 6f 63 4c 69 73 74 20 2a 69 6e 2c 20  mn(DocList *in, 
3580: 69 6e 74 20 69 52 65 73 74 72 69 63 74 43 6f 6c  int iRestrictCol
3590: 75 6d 6e 29 7b 0a 20 20 44 6f 63 4c 69 73 74 52  umn){.  DocListR
35a0: 65 61 64 65 72 20 72 3b 0a 20 20 44 6f 63 4c 69  eader r;.  DocLi
35b0: 73 74 20 6f 75 74 3b 0a 0a 20 20 61 73 73 65 72  st out;..  asser
35c0: 74 28 20 69 6e 2d 3e 69 54 79 70 65 3e 3d 44 4c  t( in->iType>=DL
35d0: 5f 50 4f 53 49 54 49 4f 4e 53 20 29 3b 0a 20 20  _POSITIONS );.  
35e0: 72 65 61 64 65 72 49 6e 69 74 28 26 72 2c 20 69  readerInit(&r, i
35f0: 6e 29 3b 0a 20 20 64 6f 63 4c 69 73 74 49 6e 69  n);.  docListIni
3600: 74 28 26 6f 75 74 2c 20 44 4c 5f 50 4f 53 49 54  t(&out, DL_POSIT
3610: 49 4f 4e 53 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a  IONS, NULL, 0);.
3620: 0a 20 20 77 68 69 6c 65 28 20 21 61 74 45 6e 64  .  while( !atEnd
3630: 28 26 72 29 20 29 7b 0a 20 20 20 20 73 71 6c 69  (&r) ){.    sqli
3640: 74 65 5f 69 6e 74 36 34 20 69 44 6f 63 69 64 20  te_int64 iDocid 
3650: 3d 20 72 65 61 64 44 6f 63 69 64 28 26 72 29 3b  = readDocid(&r);
3660: 0a 20 20 20 20 69 6e 74 20 69 50 6f 73 2c 20 69  .    int iPos, i
3670: 43 6f 6c 75 6d 6e 3b 0a 0a 20 20 20 20 64 6f 63  Column;..    doc
3680: 4c 69 73 74 41 64 64 44 6f 63 69 64 28 26 6f 75  ListAddDocid(&ou
3690: 74 2c 20 69 44 6f 63 69 64 29 3b 0a 20 20 20 20  t, iDocid);.    
36a0: 77 68 69 6c 65 28 20 28 69 50 6f 73 20 3d 20 72  while( (iPos = r
36b0: 65 61 64 50 6f 73 69 74 69 6f 6e 28 26 72 2c 20  eadPosition(&r, 
36c0: 26 69 43 6f 6c 75 6d 6e 29 29 20 21 3d 20 2d 31  &iColumn)) != -1
36d0: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 69 43   ){.      if( iC
36e0: 6f 6c 75 6d 6e 3d 3d 69 52 65 73 74 72 69 63 74  olumn==iRestrict
36f0: 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20 20 20  Column ){.      
3700: 20 20 64 6f 63 4c 69 73 74 41 64 64 50 6f 73 28    docListAddPos(
3710: 26 6f 75 74 2c 20 69 43 6f 6c 75 6d 6e 2c 20 69  &out, iColumn, i
3720: 50 6f 73 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  Pos);.      }.  
3730: 20 20 7d 0a 20 20 7d 0a 0a 20 20 64 6f 63 4c 69    }.  }..  docLi
3740: 73 74 44 65 73 74 72 6f 79 28 69 6e 29 3b 0a 20  stDestroy(in);. 
3750: 20 2a 69 6e 20 3d 20 6f 75 74 3b 0a 7d 0a 0a 2f   *in = out;.}../
3760: 2a 20 54 72 69 6d 20 74 68 65 20 67 69 76 65 6e  * Trim the given
3770: 20 64 6f 63 6c 69 73 74 20 62 79 20 64 69 73 63   doclist by disc
3780: 61 72 64 69 6e 67 20 61 6e 79 20 64 6f 63 69 64  arding any docid
3790: 73 20 77 69 74 68 6f 75 74 20 61 6e 79 20 72 65  s without any re
37a0: 6d 61 69 6e 69 6e 67 0a 20 2a 20 70 6f 73 69 74  maining. * posit
37b0: 69 6f 6e 73 2e 20 2a 2f 0a 73 74 61 74 69 63 20  ions. */.static 
37c0: 76 6f 69 64 20 64 6f 63 4c 69 73 74 44 69 73 63  void docListDisc
37d0: 61 72 64 45 6d 70 74 79 28 44 6f 63 4c 69 73 74  ardEmpty(DocList
37e0: 20 2a 69 6e 29 20 7b 0a 20 20 44 6f 63 4c 69 73   *in) {.  DocLis
37f0: 74 52 65 61 64 65 72 20 72 3b 0a 20 20 44 6f 63  tReader r;.  Doc
3800: 4c 69 73 74 20 6f 75 74 3b 0a 0a 20 20 2f 2a 20  List out;..  /* 
3810: 54 4f 44 4f 3a 20 49 74 20 77 6f 75 6c 64 20 62  TODO: It would b
3820: 65 20 6e 69 63 65 20 74 6f 20 69 6d 70 6c 65 6d  e nice to implem
3830: 65 6e 74 20 74 68 69 73 20 6f 70 65 72 61 74 69  ent this operati
3840: 6f 6e 20 69 6e 20 70 6c 61 63 65 3b 20 74 68 61  on in place; tha
3850: 74 0a 20 20 20 2a 20 63 6f 75 6c 64 20 73 61 76  t.   * could sav
3860: 65 20 61 20 73 69 67 6e 69 66 69 63 61 6e 74 20  e a significant 
3870: 61 6d 6f 75 6e 74 20 6f 66 20 6d 65 6d 6f 72 79  amount of memory
3880: 20 69 6e 20 71 75 65 72 69 65 73 20 77 69 74 68   in queries with
3890: 20 6c 6f 6e 67 20 64 6f 63 6c 69 73 74 73 2e 20   long doclists. 
38a0: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 69 6e 2d  */.  assert( in-
38b0: 3e 69 54 79 70 65 3e 3d 44 4c 5f 50 4f 53 49 54  >iType>=DL_POSIT
38c0: 49 4f 4e 53 20 29 3b 0a 20 20 72 65 61 64 65 72  IONS );.  reader
38d0: 49 6e 69 74 28 26 72 2c 20 69 6e 29 3b 0a 20 20  Init(&r, in);.  
38e0: 64 6f 63 4c 69 73 74 49 6e 69 74 28 26 6f 75 74  docListInit(&out
38f0: 2c 20 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 2c 20  , DL_POSITIONS, 
3900: 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 20 20 77 68 69  NULL, 0);..  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 69 44 6f 63 69 64 20 3d 20 72 65 61 64  64 iDocid = read
3940: 44 6f 63 69 64 28 26 72 29 3b 0a 20 20 20 20 69  Docid(&r);.    i
3950: 6e 74 20 6d 61 74 63 68 20 3d 20 30 3b 0a 20 20  nt match = 0;.  
3960: 20 20 69 6e 74 20 69 50 6f 73 2c 20 69 43 6f 6c    int iPos, iCol
3970: 75 6d 6e 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  umn;.    while( 
3980: 28 69 50 6f 73 20 3d 20 72 65 61 64 50 6f 73 69  (iPos = readPosi
3990: 74 69 6f 6e 28 26 72 2c 20 26 69 43 6f 6c 75 6d  tion(&r, &iColum
39a0: 6e 29 29 20 21 3d 20 2d 31 20 29 7b 0a 20 20 20  n)) != -1 ){.   
39b0: 20 20 20 69 66 28 20 21 6d 61 74 63 68 20 29 7b     if( !match ){
39c0: 0a 20 20 20 20 20 20 20 20 64 6f 63 4c 69 73 74  .        docList
39d0: 41 64 64 44 6f 63 69 64 28 26 6f 75 74 2c 20 69  AddDocid(&out, i
39e0: 44 6f 63 69 64 29 3b 0a 20 20 20 20 20 20 20 20  Docid);.        
39f0: 6d 61 74 63 68 20 3d 20 31 3b 0a 20 20 20 20 20  match = 1;.     
3a00: 20 7d 0a 20 20 20 20 20 20 64 6f 63 4c 69 73 74   }.      docList
3a10: 41 64 64 50 6f 73 28 26 6f 75 74 2c 20 69 43 6f  AddPos(&out, iCo
3a20: 6c 75 6d 6e 2c 20 69 50 6f 73 29 3b 0a 20 20 20  lumn, iPos);.   
3a30: 20 7d 0a 20 20 7d 0a 0a 20 20 64 6f 63 4c 69 73   }.  }..  docLis
3a40: 74 44 65 73 74 72 6f 79 28 69 6e 29 3b 0a 20 20  tDestroy(in);.  
3a50: 2a 69 6e 20 3d 20 6f 75 74 3b 0a 7d 0a 0a 2f 2a  *in = out;.}../*
3a60: 20 48 65 6c 70 65 72 20 66 75 6e 63 74 69 6f 6e   Helper function
3a70: 20 66 6f 72 20 64 6f 63 4c 69 73 74 55 70 64 61   for docListUpda
3a80: 74 65 28 29 20 61 6e 64 20 64 6f 63 4c 69 73 74  te() and docList
3a90: 41 63 63 75 6d 75 6c 61 74 65 28 29 2e 0a 2a 2a  Accumulate()..**
3aa0: 20 53 70 6c 69 63 65 73 20 61 20 64 6f 63 6c 69   Splices a docli
3ab0: 73 74 20 65 6c 65 6d 65 6e 74 20 69 6e 74 6f 20  st element into 
3ac0: 74 68 65 20 64 6f 63 6c 69 73 74 20 72 65 70 72  the doclist repr
3ad0: 65 73 65 6e 74 65 64 20 62 79 20 72 2c 0a 2a 2a  esented by r,.**
3ae0: 20 6c 65 61 76 69 6e 67 20 72 20 70 6f 69 6e 74   leaving r point
3af0: 69 6e 67 20 61 66 74 65 72 20 74 68 65 20 6e 65  ing after the ne
3b00: 77 6c 79 20 73 70 6c 69 63 65 64 20 65 6c 65 6d  wly spliced elem
3b10: 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ent..*/.static v
3b20: 6f 69 64 20 64 6f 63 4c 69 73 74 53 70 6c 69 63  oid docListSplic
3b30: 65 45 6c 65 6d 65 6e 74 28 44 6f 63 4c 69 73 74  eElement(DocList
3b40: 52 65 61 64 65 72 20 2a 72 2c 20 73 71 6c 69 74  Reader *r, sqlit
3b50: 65 5f 69 6e 74 36 34 20 69 44 6f 63 69 64 2c 0a  e_int64 iDocid,.
3b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3b80: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 53 6f   const char *pSo
3b90: 75 72 63 65 2c 20 69 6e 74 20 6e 53 6f 75 72 63  urce, int nSourc
3ba0: 65 29 7b 0a 20 20 44 6f 63 4c 69 73 74 20 2a 64  e){.  DocList *d
3bb0: 20 3d 20 72 2d 3e 70 44 6f 63 6c 69 73 74 3b 0a   = r->pDoclist;.
3bc0: 20 20 63 68 61 72 20 2a 70 54 61 72 67 65 74 3b    char *pTarget;
3bd0: 0a 20 20 69 6e 74 20 6e 54 61 72 67 65 74 2c 20  .  int nTarget, 
3be0: 66 6f 75 6e 64 3b 0a 0a 20 20 66 6f 75 6e 64 20  found;..  found 
3bf0: 3d 20 73 6b 69 70 54 6f 44 6f 63 69 64 28 72 2c  = skipToDocid(r,
3c00: 20 69 44 6f 63 69 64 29 3b 0a 0a 20 20 2f 2a 20   iDocid);..  /* 
3c10: 44 65 73 63 72 69 62 65 20 73 6c 69 63 65 20 69  Describe slice i
3c20: 6e 20 64 20 74 6f 20 70 6c 61 63 65 20 70 53 6f  n d to place pSo
3c30: 75 72 63 65 2f 6e 53 6f 75 72 63 65 2e 20 2a 2f  urce/nSource. */
3c40: 0a 20 20 70 54 61 72 67 65 74 20 3d 20 72 2d 3e  .  pTarget = r->
3c50: 70 3b 0a 20 20 69 66 28 20 66 6f 75 6e 64 20 29  p;.  if( found )
3c60: 7b 0a 20 20 20 20 73 6b 69 70 44 6f 63 75 6d 65  {.    skipDocume
3c70: 6e 74 28 72 29 3b 0a 20 20 20 20 6e 54 61 72 67  nt(r);.    nTarg
3c80: 65 74 20 3d 20 72 2d 3e 70 2d 70 54 61 72 67 65  et = r->p-pTarge
3c90: 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  t;.  }else{.    
3ca0: 6e 54 61 72 67 65 74 20 3d 20 30 3b 0a 20 20 7d  nTarget = 0;.  }
3cb0: 0a 0a 20 20 2f 2a 20 54 68 65 20 73 65 6e 73 65  ..  /* The sense
3cc0: 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   of the followin
3cd0: 67 20 69 73 20 74 68 61 74 20 74 68 65 72 65 20  g is that there 
3ce0: 61 72 65 20 74 68 72 65 65 20 70 6f 73 73 69 62  are three possib
3cf0: 69 6c 69 74 69 65 73 2e 0a 20 20 2a 2a 20 49 66  ilities..  ** If
3d00: 20 6e 54 61 72 67 65 74 3d 3d 6e 53 6f 75 72 63   nTarget==nSourc
3d10: 65 2c 20 77 65 20 73 68 6f 75 6c 64 20 6e 6f 74  e, we should not
3d20: 20 6d 6f 76 65 20 61 6e 79 20 6d 65 6d 6f 72 79   move any memory
3d30: 20 6e 6f 72 20 72 65 61 6c 6c 6f 63 2e 0a 20 20   nor realloc..  
3d40: 2a 2a 20 49 66 20 6e 54 61 72 67 65 74 3e 6e 53  ** If nTarget>nS
3d50: 6f 75 72 63 65 2c 20 74 72 69 6d 20 74 61 72 67  ource, trim targ
3d60: 65 74 20 61 6e 64 20 72 65 61 6c 6c 6f 63 2e 0a  et and realloc..
3d70: 20 20 2a 2a 20 49 66 20 6e 54 61 72 67 65 74 3c    ** If nTarget<
3d80: 6e 53 6f 75 72 63 65 2c 20 72 65 61 6c 6c 6f 63  nSource, realloc
3d90: 20 74 68 65 6e 20 65 78 70 61 6e 64 20 74 61 72   then expand tar
3da0: 67 65 74 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  get..  */.  if( 
3db0: 6e 54 61 72 67 65 74 3e 6e 53 6f 75 72 63 65 20  nTarget>nSource 
3dc0: 29 7b 0a 20 20 20 20 6d 65 6d 6d 6f 76 65 28 70  ){.    memmove(p
3dd0: 54 61 72 67 65 74 2b 6e 53 6f 75 72 63 65 2c 20  Target+nSource, 
3de0: 70 54 61 72 67 65 74 2b 6e 54 61 72 67 65 74 2c  pTarget+nTarget,
3df0: 20 64 6f 63 4c 69 73 74 45 6e 64 28 64 29 2d 28   docListEnd(d)-(
3e00: 70 54 61 72 67 65 74 2b 6e 54 61 72 67 65 74 29  pTarget+nTarget)
3e10: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 6e 54 61  );.  }.  if( nTa
3e20: 72 67 65 74 21 3d 6e 53 6f 75 72 63 65 20 29 7b  rget!=nSource ){
3e30: 0a 20 20 20 20 69 6e 74 20 69 44 6f 63 6c 69 73  .    int iDoclis
3e40: 74 20 3d 20 70 54 61 72 67 65 74 2d 64 2d 3e 70  t = pTarget-d->p
3e50: 44 61 74 61 3b 0a 20 20 20 20 64 2d 3e 70 44 61  Data;.    d->pDa
3e60: 74 61 20 3d 20 72 65 61 6c 6c 6f 63 28 64 2d 3e  ta = realloc(d->
3e70: 70 44 61 74 61 2c 20 64 2d 3e 6e 44 61 74 61 2b  pData, d->nData+
3e80: 6e 53 6f 75 72 63 65 2d 6e 54 61 72 67 65 74 29  nSource-nTarget)
3e90: 3b 0a 20 20 20 20 70 54 61 72 67 65 74 20 3d 20  ;.    pTarget = 
3ea0: 64 2d 3e 70 44 61 74 61 2b 69 44 6f 63 6c 69 73  d->pData+iDoclis
3eb0: 74 3b 0a 20 20 7d 0a 20 20 69 66 28 20 6e 54 61  t;.  }.  if( nTa
3ec0: 72 67 65 74 3c 6e 53 6f 75 72 63 65 20 29 7b 0a  rget<nSource ){.
3ed0: 20 20 20 20 6d 65 6d 6d 6f 76 65 28 70 54 61 72      memmove(pTar
3ee0: 67 65 74 2b 6e 53 6f 75 72 63 65 2c 20 70 54 61  get+nSource, pTa
3ef0: 72 67 65 74 2b 6e 54 61 72 67 65 74 2c 20 64 6f  rget+nTarget, do
3f00: 63 4c 69 73 74 45 6e 64 28 64 29 2d 28 70 54 61  cListEnd(d)-(pTa
3f10: 72 67 65 74 2b 6e 54 61 72 67 65 74 29 29 3b 0a  rget+nTarget));.
3f20: 20 20 7d 0a 0a 20 20 6d 65 6d 63 70 79 28 70 54    }..  memcpy(pT
3f30: 61 72 67 65 74 2c 20 70 53 6f 75 72 63 65 2c 20  arget, pSource, 
3f40: 6e 53 6f 75 72 63 65 29 3b 0a 20 20 64 2d 3e 6e  nSource);.  d->n
3f50: 44 61 74 61 20 2b 3d 20 6e 53 6f 75 72 63 65 2d  Data += nSource-
3f60: 6e 54 61 72 67 65 74 3b 0a 20 20 72 2d 3e 70 20  nTarget;.  r->p 
3f70: 3d 20 70 54 61 72 67 65 74 2b 6e 53 6f 75 72 63  = pTarget+nSourc
3f80: 65 3b 0a 7d 0a 0a 2f 2a 20 49 6e 73 65 72 74 2f  e;.}../* Insert/
3f90: 75 70 64 61 74 65 20 70 55 70 64 61 74 65 20 69  update pUpdate i
3fa0: 6e 74 6f 20 74 68 65 20 64 6f 63 6c 69 73 74 2e  nto the doclist.
3fb0: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
3fc0: 64 6f 63 4c 69 73 74 55 70 64 61 74 65 28 44 6f  docListUpdate(Do
3fd0: 63 4c 69 73 74 20 2a 64 2c 20 44 6f 63 4c 69 73  cList *d, DocLis
3fe0: 74 20 2a 70 55 70 64 61 74 65 29 7b 0a 20 20 44  t *pUpdate){.  D
3ff0: 6f 63 4c 69 73 74 52 65 61 64 65 72 20 72 65 61  ocListReader rea
4000: 64 65 72 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  der;..  assert( 
4010: 64 21 3d 4e 55 4c 4c 20 26 26 20 70 55 70 64 61  d!=NULL && pUpda
4020: 74 65 21 3d 4e 55 4c 4c 20 29 3b 0a 20 20 61 73  te!=NULL );.  as
4030: 73 65 72 74 28 20 64 2d 3e 69 54 79 70 65 3d 3d  sert( d->iType==
4040: 70 55 70 64 61 74 65 2d 3e 69 54 79 70 65 29 3b  pUpdate->iType);
4050: 0a 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28 26  ..  readerInit(&
4060: 72 65 61 64 65 72 2c 20 64 29 3b 0a 20 20 64 6f  reader, d);.  do
4070: 63 4c 69 73 74 53 70 6c 69 63 65 45 6c 65 6d 65  cListSpliceEleme
4080: 6e 74 28 26 72 65 61 64 65 72 2c 20 66 69 72 73  nt(&reader, firs
4090: 74 44 6f 63 69 64 28 70 55 70 64 61 74 65 29 2c  tDocid(pUpdate),
40a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
40b0: 20 20 20 20 20 20 20 20 70 55 70 64 61 74 65 2d          pUpdate-
40c0: 3e 70 44 61 74 61 2c 20 70 55 70 64 61 74 65 2d  >pData, pUpdate-
40d0: 3e 6e 44 61 74 61 29 3b 0a 7d 0a 0a 2f 2a 20 50  >nData);.}../* P
40e0: 72 6f 70 61 67 61 74 65 20 65 6c 65 6d 65 6e 74  ropagate element
40f0: 73 20 66 72 6f 6d 20 70 55 70 64 61 74 65 20 74  s from pUpdate t
4100: 6f 20 70 41 63 63 2c 20 6f 76 65 72 77 72 69 74  o pAcc, overwrit
4110: 69 6e 67 20 65 6c 65 6d 65 6e 74 73 20 77 69 74  ing elements wit
4120: 68 0a 2a 2a 20 6d 61 74 63 68 69 6e 67 20 64 6f  h.** matching do
4130: 63 69 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  cids..*/.static 
4140: 76 6f 69 64 20 64 6f 63 4c 69 73 74 41 63 63 75  void docListAccu
4150: 6d 75 6c 61 74 65 28 44 6f 63 4c 69 73 74 20 2a  mulate(DocList *
4160: 70 41 63 63 2c 20 44 6f 63 4c 69 73 74 20 2a 70  pAcc, DocList *p
4170: 55 70 64 61 74 65 29 7b 0a 20 20 44 6f 63 4c 69  Update){.  DocLi
4180: 73 74 52 65 61 64 65 72 20 61 63 63 52 65 61 64  stReader accRead
4190: 65 72 2c 20 75 70 64 61 74 65 52 65 61 64 65 72  er, updateReader
41a0: 3b 0a 0a 20 20 2f 2a 20 48 61 6e 64 6c 65 20 65  ;..  /* Handle e
41b0: 64 67 65 20 63 61 73 65 73 20 77 68 65 72 65 20  dge cases where 
41c0: 6f 6e 65 20 64 6f 63 6c 69 73 74 20 69 73 20 65  one doclist is e
41d0: 6d 70 74 79 2e 20 2a 2f 0a 20 20 61 73 73 65 72  mpty. */.  asser
41e0: 74 28 20 70 41 63 63 21 3d 4e 55 4c 4c 20 29 3b  t( pAcc!=NULL );
41f0: 0a 20 20 69 66 28 20 70 55 70 64 61 74 65 3d 3d  .  if( pUpdate==
4200: 4e 55 4c 4c 20 7c 7c 20 70 55 70 64 61 74 65 2d  NULL || pUpdate-
4210: 3e 6e 44 61 74 61 3d 3d 30 20 29 20 72 65 74 75  >nData==0 ) retu
4220: 72 6e 3b 0a 20 20 69 66 28 20 70 41 63 63 2d 3e  rn;.  if( pAcc->
4230: 6e 44 61 74 61 3d 3d 30 20 29 7b 0a 20 20 20 20  nData==0 ){.    
4240: 70 41 63 63 2d 3e 70 44 61 74 61 20 3d 20 6d 61  pAcc->pData = ma
4250: 6c 6c 6f 63 28 70 55 70 64 61 74 65 2d 3e 6e 44  lloc(pUpdate->nD
4260: 61 74 61 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79  ata);.    memcpy
4270: 28 70 41 63 63 2d 3e 70 44 61 74 61 2c 20 70 55  (pAcc->pData, pU
4280: 70 64 61 74 65 2d 3e 70 44 61 74 61 2c 20 70 55  pdate->pData, pU
4290: 70 64 61 74 65 2d 3e 6e 44 61 74 61 29 3b 0a 20  pdate->nData);. 
42a0: 20 20 20 70 41 63 63 2d 3e 6e 44 61 74 61 20 3d     pAcc->nData =
42b0: 20 70 55 70 64 61 74 65 2d 3e 6e 44 61 74 61 3b   pUpdate->nData;
42c0: 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d  .    return;.  }
42d0: 0a 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28 26  ..  readerInit(&
42e0: 61 63 63 52 65 61 64 65 72 2c 20 70 41 63 63 29  accReader, pAcc)
42f0: 3b 0a 20 20 72 65 61 64 65 72 49 6e 69 74 28 26  ;.  readerInit(&
4300: 75 70 64 61 74 65 52 65 61 64 65 72 2c 20 70 55  updateReader, pU
4310: 70 64 61 74 65 29 3b 0a 0a 20 20 77 68 69 6c 65  pdate);..  while
4320: 28 20 21 61 74 45 6e 64 28 26 75 70 64 61 74 65  ( !atEnd(&update
4330: 52 65 61 64 65 72 29 20 29 7b 0a 20 20 20 20 63  Reader) ){.    c
4340: 68 61 72 20 2a 70 53 6f 75 72 63 65 20 3d 20 75  har *pSource = u
4350: 70 64 61 74 65 52 65 61 64 65 72 2e 70 3b 0a 20  pdateReader.p;. 
4360: 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20     sqlite_int64 
4370: 69 44 6f 63 69 64 20 3d 20 72 65 61 64 44 6f 63  iDocid = readDoc
4380: 69 64 28 26 75 70 64 61 74 65 52 65 61 64 65 72  id(&updateReader
4390: 29 3b 0a 20 20 20 20 73 6b 69 70 50 6f 73 69 74  );.    skipPosit
43a0: 69 6f 6e 4c 69 73 74 28 26 75 70 64 61 74 65 52  ionList(&updateR
43b0: 65 61 64 65 72 29 3b 0a 20 20 20 20 64 6f 63 4c  eader);.    docL
43c0: 69 73 74 53 70 6c 69 63 65 45 6c 65 6d 65 6e 74  istSpliceElement
43d0: 28 26 61 63 63 52 65 61 64 65 72 2c 20 69 44 6f  (&accReader, iDo
43e0: 63 69 64 2c 20 70 53 6f 75 72 63 65 2c 20 75 70  cid, pSource, up
43f0: 64 61 74 65 52 65 61 64 65 72 2e 70 2d 70 53 6f  dateReader.p-pSo
4400: 75 72 63 65 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  urce);.  }.}../*
4410: 0a 2a 2a 20 52 65 61 64 20 74 68 65 20 6e 65 78  .** Read the nex
4420: 74 20 64 6f 63 69 64 20 6f 66 66 20 6f 66 20 70  t docid off of p
4430: 49 6e 2e 20 20 52 65 74 75 72 6e 20 30 20 69 66  In.  Return 0 if
4440: 20 77 65 20 72 65 61 63 68 20 74 68 65 20 65 6e   we reach the en
4450: 64 2e 0a 2a 0a 2a 20 54 4f 44 4f 3a 20 54 68 69  d..*.* TODO: Thi
4460: 73 20 61 73 73 75 6d 65 73 20 74 68 61 74 20 64  s assumes that d
4470: 6f 63 69 64 73 20 61 72 65 20 6e 65 76 65 72 20  ocids are never 
4480: 30 2c 20 62 75 74 20 74 68 65 79 20 6d 61 79 20  0, but they may 
4490: 61 63 74 75 61 6c 6c 79 20 62 65 20 30 20 73 69  actually be 0 si
44a0: 6e 63 65 0a 2a 20 75 73 65 72 73 20 63 61 6e 20  nce.* users can 
44b0: 63 68 6f 6f 73 65 20 64 6f 63 69 64 73 20 77 68  choose docids wh
44c0: 65 6e 20 69 6e 73 65 72 74 69 6e 67 20 69 6e 74  en inserting int
44d0: 6f 20 61 20 66 75 6c 6c 2d 74 65 78 74 20 74 61  o a full-text ta
44e0: 62 6c 65 2e 20 20 46 69 78 20 74 68 69 73 2e 0a  ble.  Fix this..
44f0: 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  */.static sqlite
4500: 5f 69 6e 74 36 34 20 6e 65 78 74 44 6f 63 69 64  _int64 nextDocid
4510: 28 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20 2a  (DocListReader *
4520: 70 49 6e 29 7b 0a 20 20 73 6b 69 70 50 6f 73 69  pIn){.  skipPosi
4530: 74 69 6f 6e 4c 69 73 74 28 70 49 6e 29 3b 0a 20  tionList(pIn);. 
4540: 20 72 65 74 75 72 6e 20 61 74 45 6e 64 28 70 49   return atEnd(pI
4550: 6e 29 20 3f 20 30 20 3a 20 72 65 61 64 44 6f 63  n) ? 0 : readDoc
4560: 69 64 28 70 49 6e 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  id(pIn);.}../*.*
4570: 2a 20 70 4c 65 66 74 20 61 6e 64 20 70 52 69 67  * pLeft and pRig
4580: 68 74 20 61 72 65 20 74 77 6f 20 44 6f 63 4c 69  ht are two DocLi
4590: 73 74 52 65 61 64 65 72 73 20 74 68 61 74 20 61  stReaders that a
45a0: 72 65 20 70 6f 69 6e 74 69 6e 67 20 74 6f 0a 2a  re pointing to.*
45b0: 2a 20 70 6f 73 69 74 69 6f 6e 73 20 6c 69 73 74  * positions list
45c0: 73 20 6f 66 20 74 68 65 20 73 61 6d 65 20 64 6f  s of the same do
45d0: 63 75 6d 65 6e 74 3a 20 69 44 6f 63 69 64 2e 20  cument: iDocid. 
45e0: 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20  .**.** If there 
45f0: 61 72 65 20 6e 6f 20 69 6e 73 74 61 6e 63 65 73  are no instances
4600: 20 69 6e 20 70 4c 65 66 74 20 6f 72 20 70 52 69   in pLeft or pRi
4610: 67 68 74 20 77 68 65 72 65 20 74 68 65 20 70 6f  ght where the po
4620: 73 69 74 69 6f 6e 0a 2a 2a 20 6f 66 20 70 4c 65  sition.** of pLe
4630: 66 74 20 69 73 20 6f 6e 65 20 6c 65 73 73 20 74  ft is one less t
4640: 68 61 6e 20 74 68 65 20 70 6f 73 69 74 69 6f 6e  han the position
4650: 20 6f 66 20 70 52 69 67 68 74 2c 20 74 68 65 6e   of pRight, then
4660: 20 74 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65   this.** routine
4670: 20 61 64 64 73 20 6e 6f 74 68 69 6e 67 20 74 6f   adds nothing to
4680: 20 70 4f 75 74 2e 0a 2a 2a 0a 2a 2a 20 49 66 20   pOut..**.** If 
4690: 74 68 65 72 65 20 61 72 65 20 6f 6e 65 20 6f 72  there are one or
46a0: 20 6d 6f 72 65 20 69 6e 73 74 61 6e 63 65 73 20   more instances 
46b0: 77 68 65 72 65 20 70 6f 73 69 74 69 6f 6e 73 20  where positions 
46c0: 66 72 6f 6d 20 70 4c 65 66 74 0a 2a 2a 20 61 72  from pLeft.** ar
46d0: 65 20 65 78 61 63 74 6c 79 20 6f 6e 65 20 6c 65  e exactly one le
46e0: 73 73 20 74 68 61 6e 20 70 6f 73 69 74 69 6f 6e  ss than position
46f0: 73 20 66 72 6f 6d 20 70 52 69 67 68 74 2c 20 74  s from pRight, t
4700: 68 65 6e 20 61 64 64 20 61 20 6e 65 77 0a 2a 2a  hen add a new.**
4710: 20 64 6f 63 75 6d 65 6e 74 20 72 65 63 6f 72 64   document record
4720: 20 74 6f 20 70 4f 75 74 2e 20 20 49 66 20 70 4f   to pOut.  If pO
4730: 75 74 20 77 61 6e 74 73 20 74 6f 20 68 6f 6c 64  ut wants to hold
4740: 20 70 6f 73 69 74 69 6f 6e 73 2c 20 74 68 65 6e   positions, then
4750: 0a 2a 2a 20 69 6e 63 6c 75 64 65 20 74 68 65 20  .** include the 
4760: 70 6f 73 69 74 69 6f 6e 73 20 66 72 6f 6d 20 70  positions from p
4770: 52 69 67 68 74 20 74 68 61 74 20 61 72 65 20 6f  Right that are o
4780: 6e 65 20 6d 6f 72 65 20 74 68 61 6e 20 61 0a 2a  ne more than a.*
4790: 2a 20 70 6f 73 69 74 69 6f 6e 20 69 6e 20 70 4c  * position in pL
47a0: 65 66 74 2e 20 20 49 6e 20 6f 74 68 65 72 20 77  eft.  In other w
47b0: 6f 72 64 73 3a 20 20 70 52 69 67 68 74 2e 69 50  ords:  pRight.iP
47c0: 6f 73 3d 3d 70 4c 65 66 74 2e 69 50 6f 73 2b 31  os==pLeft.iPos+1
47d0: 2e 0a 2a 2a 0a 2a 2a 20 70 4c 65 66 74 20 61 6e  ..**.** pLeft an
47e0: 64 20 70 52 69 67 68 74 20 61 72 65 20 6c 65 66  d pRight are lef
47f0: 74 20 70 6f 69 6e 74 69 6e 67 20 61 74 20 74 68  t pointing at th
4800: 65 20 6e 65 78 74 20 64 6f 63 75 6d 65 6e 74 20  e next document 
4810: 72 65 63 6f 72 64 2e 0a 2a 2f 0a 73 74 61 74 69  record..*/.stati
4820: 63 20 76 6f 69 64 20 6d 65 72 67 65 50 6f 73 4c  c void mergePosL
4830: 69 73 74 28 0a 20 20 44 6f 63 4c 69 73 74 52 65  ist(.  DocListRe
4840: 61 64 65 72 20 2a 70 4c 65 66 74 2c 20 20 20 20  ader *pLeft,    
4850: 2f 2a 20 4c 65 66 74 20 70 6f 73 69 74 69 6f 6e  /* Left position
4860: 20 6c 69 73 74 20 2a 2f 0a 20 20 44 6f 63 4c 69   list */.  DocLi
4870: 73 74 52 65 61 64 65 72 20 2a 70 52 69 67 68 74  stReader *pRight
4880: 2c 20 20 20 2f 2a 20 52 69 67 68 74 20 70 6f 73  ,   /* Right pos
4890: 69 74 69 6f 6e 20 6c 69 73 74 20 2a 2f 0a 20 20  ition list */.  
48a0: 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 44 6f  sqlite_int64 iDo
48b0: 63 69 64 2c 20 20 20 20 20 2f 2a 20 54 68 65 20  cid,     /* The 
48c0: 64 6f 63 69 64 20 66 72 6f 6d 20 70 4c 65 66 74  docid from pLeft
48d0: 20 61 6e 64 20 70 52 69 67 68 74 20 2a 2f 0a 20   and pRight */. 
48e0: 20 44 6f 63 4c 69 73 74 20 2a 70 4f 75 74 20 20   DocList *pOut  
48f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69            /* Wri
4900: 74 65 20 74 68 65 20 6d 65 72 67 65 64 20 64 6f  te the merged do
4910: 63 75 6d 65 6e 74 20 72 65 63 6f 72 64 20 68 65  cument record he
4920: 72 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69  re */.){.  int i
4930: 4c 65 66 74 43 6f 6c 2c 20 69 4c 65 66 74 50 6f  LeftCol, iLeftPo
4940: 73 20 3d 20 72 65 61 64 50 6f 73 69 74 69 6f 6e  s = readPosition
4950: 28 70 4c 65 66 74 2c 20 26 69 4c 65 66 74 43 6f  (pLeft, &iLeftCo
4960: 6c 29 3b 0a 20 20 69 6e 74 20 69 52 69 67 68 74  l);.  int iRight
4970: 43 6f 6c 2c 20 69 52 69 67 68 74 50 6f 73 20 3d  Col, iRightPos =
4980: 20 72 65 61 64 50 6f 73 69 74 69 6f 6e 28 70 52   readPosition(pR
4990: 69 67 68 74 2c 20 26 69 52 69 67 68 74 43 6f 6c  ight, &iRightCol
49a0: 29 3b 0a 20 20 69 6e 74 20 6d 61 74 63 68 20 3d  );.  int match =
49b0: 20 30 3b 0a 0a 20 20 2f 2a 20 4c 6f 6f 70 20 75   0;..  /* Loop u
49c0: 6e 74 69 6c 20 77 65 27 76 65 20 72 65 61 63 68  ntil we've reach
49d0: 65 64 20 74 68 65 20 65 6e 64 20 6f 66 20 62 6f  ed the end of bo
49e0: 74 68 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74  th position list
49f0: 73 2e 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 69  s. */.  while( i
4a00: 4c 65 66 74 50 6f 73 21 3d 2d 31 20 26 26 20 69  LeftPos!=-1 && i
4a10: 52 69 67 68 74 50 6f 73 21 3d 2d 31 20 29 7b 0a  RightPos!=-1 ){.
4a20: 20 20 20 20 69 66 28 20 69 4c 65 66 74 43 6f 6c      if( iLeftCol
4a30: 3d 3d 69 52 69 67 68 74 43 6f 6c 20 26 26 20 69  ==iRightCol && i
4a40: 4c 65 66 74 50 6f 73 2b 31 3d 3d 69 52 69 67 68  LeftPos+1==iRigh
4a50: 74 50 6f 73 20 29 7b 0a 20 20 20 20 20 20 69 66  tPos ){.      if
4a60: 28 20 21 6d 61 74 63 68 20 29 7b 0a 20 20 20 20  ( !match ){.    
4a70: 20 20 20 20 64 6f 63 4c 69 73 74 41 64 64 44 6f      docListAddDo
4a80: 63 69 64 28 70 4f 75 74 2c 20 69 44 6f 63 69 64  cid(pOut, iDocid
4a90: 29 3b 0a 20 20 20 20 20 20 20 20 6d 61 74 63 68  );.        match
4aa0: 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = 1;.      }.  
4ab0: 20 20 20 20 69 66 28 20 70 4f 75 74 2d 3e 69 54      if( pOut->iT
4ac0: 79 70 65 3e 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e  ype>=DL_POSITION
4ad0: 53 20 29 7b 0a 20 20 20 20 20 20 20 20 64 6f 63  S ){.        doc
4ae0: 4c 69 73 74 41 64 64 50 6f 73 28 70 4f 75 74 2c  ListAddPos(pOut,
4af0: 20 69 52 69 67 68 74 43 6f 6c 2c 20 69 52 69 67   iRightCol, iRig
4b00: 68 74 50 6f 73 29 3b 0a 20 20 20 20 20 20 7d 0a  htPos);.      }.
4b10: 20 20 20 20 20 20 69 4c 65 66 74 50 6f 73 20 3d        iLeftPos =
4b20: 20 72 65 61 64 50 6f 73 69 74 69 6f 6e 28 70 4c   readPosition(pL
4b30: 65 66 74 2c 20 26 69 4c 65 66 74 43 6f 6c 29 3b  eft, &iLeftCol);
4b40: 0a 20 20 20 20 20 20 69 52 69 67 68 74 50 6f 73  .      iRightPos
4b50: 20 3d 20 72 65 61 64 50 6f 73 69 74 69 6f 6e 28   = readPosition(
4b60: 70 52 69 67 68 74 2c 20 26 69 52 69 67 68 74 43  pRight, &iRightC
4b70: 6f 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  ol);.    }else i
4b80: 66 28 20 69 52 69 67 68 74 43 6f 6c 3c 69 4c 65  f( iRightCol<iLe
4b90: 66 74 43 6f 6c 20 7c 7c 0a 20 20 20 20 20 20 20  ftCol ||.       
4ba0: 20 20 20 20 20 20 20 28 69 52 69 67 68 74 43 6f         (iRightCo
4bb0: 6c 3d 3d 69 4c 65 66 74 43 6f 6c 20 26 26 20 69  l==iLeftCol && i
4bc0: 52 69 67 68 74 50 6f 73 3c 69 4c 65 66 74 50 6f  RightPos<iLeftPo
4bd0: 73 2b 31 29 20 29 7b 0a 20 20 20 20 20 20 69 52  s+1) ){.      iR
4be0: 69 67 68 74 50 6f 73 20 3d 20 72 65 61 64 50 6f  ightPos = readPo
4bf0: 73 69 74 69 6f 6e 28 70 52 69 67 68 74 2c 20 26  sition(pRight, &
4c00: 69 52 69 67 68 74 43 6f 6c 29 3b 0a 20 20 20 20  iRightCol);.    
4c10: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 4c 65  }else{.      iLe
4c20: 66 74 50 6f 73 20 3d 20 72 65 61 64 50 6f 73 69  ftPos = readPosi
4c30: 74 69 6f 6e 28 70 4c 65 66 74 2c 20 26 69 4c 65  tion(pLeft, &iLe
4c40: 66 74 43 6f 6c 29 3b 0a 20 20 20 20 7d 0a 20 20  ftCol);.    }.  
4c50: 7d 0a 20 20 69 66 28 20 69 4c 65 66 74 50 6f 73  }.  if( iLeftPos
4c60: 3e 3d 30 20 29 20 73 6b 69 70 50 6f 73 69 74 69  >=0 ) skipPositi
4c70: 6f 6e 4c 69 73 74 28 70 4c 65 66 74 29 3b 0a 20  onList(pLeft);. 
4c80: 20 69 66 28 20 69 52 69 67 68 74 50 6f 73 3e 3d   if( iRightPos>=
4c90: 30 20 29 20 73 6b 69 70 50 6f 73 69 74 69 6f 6e  0 ) skipPosition
4ca0: 4c 69 73 74 28 70 52 69 67 68 74 29 3b 0a 7d 0a  List(pRight);.}.
4cb0: 0a 2f 2a 20 57 65 20 68 61 76 65 20 74 77 6f 20  ./* We have two 
4cc0: 64 6f 63 6c 69 73 74 73 3a 20 20 70 4c 65 66 74  doclists:  pLeft
4cd0: 20 61 6e 64 20 70 52 69 67 68 74 2e 0a 2a 2a 20   and pRight..** 
4ce0: 57 72 69 74 65 20 74 68 65 20 70 68 72 61 73 65  Write the phrase
4cf0: 20 69 6e 74 65 72 73 65 63 74 69 6f 6e 20 6f 66   intersection of
4d00: 20 74 68 65 73 65 20 74 77 6f 20 64 6f 63 6c 69   these two docli
4d10: 73 74 73 20 69 6e 74 6f 20 70 4f 75 74 2e 0a 2a  sts into pOut..*
4d20: 2a 0a 2a 2a 20 41 20 70 68 72 61 73 65 20 69 6e  *.** A phrase in
4d30: 74 65 72 73 65 63 74 69 6f 6e 20 6d 65 61 6e 73  tersection means
4d40: 20 74 68 61 74 20 74 77 6f 20 64 6f 63 75 6d 65   that two docume
4d50: 6e 74 73 20 6f 6e 6c 79 20 6d 61 74 63 68 0a 2a  nts only match.*
4d60: 2a 20 69 66 20 70 4c 65 66 74 2e 69 50 6f 73 2b  * if pLeft.iPos+
4d70: 31 3d 3d 70 52 69 67 68 74 2e 69 50 6f 73 2e 0a  1==pRight.iPos..
4d80: 2a 2a 0a 2a 2a 20 54 68 65 20 6f 75 74 70 75 74  **.** The output
4d90: 20 70 4f 75 74 20 6d 61 79 20 6f 72 20 6d 61 79   pOut may or may
4da0: 20 6e 6f 74 20 63 6f 6e 74 61 69 6e 20 70 6f 73   not contain pos
4db0: 69 74 69 6f 6e 73 2e 20 20 49 66 20 70 4f 75 74  itions.  If pOut
4dc0: 0a 2a 2a 20 64 6f 65 73 20 63 6f 6e 74 61 69 6e  .** does contain
4dd0: 20 70 6f 73 69 74 69 6f 6e 73 2c 20 74 68 65 79   positions, they
4de0: 20 61 72 65 20 74 68 65 20 70 6f 73 69 74 69 6f   are the positio
4df0: 6e 73 20 6f 66 20 70 52 69 67 68 74 2e 0a 2a 2f  ns of pRight..*/
4e00: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f 63  .static void doc
4e10: 4c 69 73 74 50 68 72 61 73 65 4d 65 72 67 65 28  ListPhraseMerge(
4e20: 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70 4c 65 66  .  DocList *pLef
4e30: 74 2c 20 20 20 20 2f 2a 20 44 6f 63 6c 69 73 74  t,    /* Doclist
4e40: 20 72 65 73 75 6c 74 69 6e 67 20 66 72 6f 6d 20   resulting from 
4e50: 74 68 65 20 77 6f 72 64 73 20 6f 6e 20 74 68 65  the words on the
4e60: 20 6c 65 66 74 20 2a 2f 0a 20 20 44 6f 63 4c 69   left */.  DocLi
4e70: 73 74 20 2a 70 52 69 67 68 74 2c 20 20 20 2f 2a  st *pRight,   /*
4e80: 20 44 6f 63 6c 69 73 74 20 66 6f 72 20 74 68 65   Doclist for the
4e90: 20 6e 65 78 74 20 77 6f 72 64 20 74 6f 20 74 68   next word to th
4ea0: 65 20 72 69 67 68 74 20 2a 2f 0a 20 20 44 6f 63  e right */.  Doc
4eb0: 4c 69 73 74 20 2a 70 4f 75 74 20 20 20 20 20 20  List *pOut      
4ec0: 2f 2a 20 57 72 69 74 65 20 74 68 65 20 63 6f 6d  /* Write the com
4ed0: 62 69 6e 65 64 20 64 6f 63 6c 69 73 74 20 68 65  bined doclist he
4ee0: 72 65 20 2a 2f 0a 29 7b 0a 20 20 44 6f 63 4c 69  re */.){.  DocLi
4ef0: 73 74 52 65 61 64 65 72 20 6c 65 66 74 2c 20 72  stReader left, r
4f00: 69 67 68 74 3b 0a 20 20 73 71 6c 69 74 65 5f 69  ight;.  sqlite_i
4f10: 6e 74 36 34 20 64 6f 63 69 64 4c 65 66 74 2c 20  nt64 docidLeft, 
4f20: 64 6f 63 69 64 52 69 67 68 74 3b 0a 0a 20 20 72  docidRight;..  r
4f30: 65 61 64 65 72 49 6e 69 74 28 26 6c 65 66 74 2c  eaderInit(&left,
4f40: 20 70 4c 65 66 74 29 3b 0a 20 20 72 65 61 64 65   pLeft);.  reade
4f50: 72 49 6e 69 74 28 26 72 69 67 68 74 2c 20 70 52  rInit(&right, pR
4f60: 69 67 68 74 29 3b 0a 20 20 64 6f 63 69 64 4c 65  ight);.  docidLe
4f70: 66 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26  ft = nextDocid(&
4f80: 6c 65 66 74 29 3b 0a 20 20 64 6f 63 69 64 52 69  left);.  docidRi
4f90: 67 68 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28  ght = nextDocid(
4fa0: 26 72 69 67 68 74 29 3b 0a 0a 20 20 77 68 69 6c  &right);..  whil
4fb0: 65 28 20 64 6f 63 69 64 4c 65 66 74 3e 30 20 26  e( docidLeft>0 &
4fc0: 26 20 64 6f 63 69 64 52 69 67 68 74 3e 30 20 29  & docidRight>0 )
4fd0: 7b 0a 20 20 20 20 69 66 28 20 64 6f 63 69 64 4c  {.    if( docidL
4fe0: 65 66 74 3c 64 6f 63 69 64 52 69 67 68 74 20 29  eft<docidRight )
4ff0: 7b 0a 20 20 20 20 20 20 64 6f 63 69 64 4c 65 66  {.      docidLef
5000: 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 6c  t = nextDocid(&l
5010: 65 66 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20  eft);.    }else 
5020: 69 66 28 20 64 6f 63 69 64 52 69 67 68 74 3c 64  if( docidRight<d
5030: 6f 63 69 64 4c 65 66 74 20 29 7b 0a 20 20 20 20  ocidLeft ){.    
5040: 20 20 64 6f 63 69 64 52 69 67 68 74 20 3d 20 6e    docidRight = n
5050: 65 78 74 44 6f 63 69 64 28 26 72 69 67 68 74 29  extDocid(&right)
5060: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
5070: 20 20 20 6d 65 72 67 65 50 6f 73 4c 69 73 74 28     mergePosList(
5080: 26 6c 65 66 74 2c 20 26 72 69 67 68 74 2c 20 64  &left, &right, d
5090: 6f 63 69 64 4c 65 66 74 2c 20 70 4f 75 74 29 3b  ocidLeft, pOut);
50a0: 0a 20 20 20 20 20 20 64 6f 63 69 64 4c 65 66 74  .      docidLeft
50b0: 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 6c 65   = nextDocid(&le
50c0: 66 74 29 3b 0a 20 20 20 20 20 20 64 6f 63 69 64  ft);.      docid
50d0: 52 69 67 68 74 20 3d 20 6e 65 78 74 44 6f 63 69  Right = nextDoci
50e0: 64 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20 7d  d(&right);.    }
50f0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 57 65 20 68 61  .  }.}../* We ha
5100: 76 65 20 74 77 6f 20 64 6f 63 6c 69 73 74 73 3a  ve two doclists:
5110: 20 20 70 4c 65 66 74 20 61 6e 64 20 70 52 69 67    pLeft and pRig
5120: 68 74 2e 0a 2a 2a 20 57 72 69 74 65 20 74 68 65  ht..** Write the
5130: 20 69 6e 74 65 72 73 65 63 74 69 6f 6e 20 6f 66   intersection of
5140: 20 74 68 65 73 65 20 74 77 6f 20 64 6f 63 6c 69   these two docli
5150: 73 74 73 20 69 6e 74 6f 20 70 4f 75 74 2e 0a 2a  sts into pOut..*
5160: 2a 20 4f 6e 6c 79 20 64 6f 63 69 64 73 20 61 72  * Only docids ar
5170: 65 20 6d 61 74 63 68 65 64 2e 20 20 50 6f 73 69  e matched.  Posi
5180: 74 69 6f 6e 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  tion information
5190: 20 69 73 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a 0a   is ignored..**.
51a0: 2a 2a 20 54 68 65 20 6f 75 74 70 75 74 20 70 4f  ** The output pO
51b0: 75 74 20 6e 65 76 65 72 20 68 6f 6c 64 73 20 70  ut never holds p
51c0: 6f 73 69 74 69 6f 6e 73 2e 0a 2a 2f 0a 73 74 61  ositions..*/.sta
51d0: 74 69 63 20 76 6f 69 64 20 64 6f 63 4c 69 73 74  tic void docList
51e0: 41 6e 64 4d 65 72 67 65 28 0a 20 20 44 6f 63 4c  AndMerge(.  DocL
51f0: 69 73 74 20 2a 70 4c 65 66 74 2c 20 20 20 20 2f  ist *pLeft,    /
5200: 2a 20 44 6f 63 6c 69 73 74 20 72 65 73 75 6c 74  * Doclist result
5210: 69 6e 67 20 66 72 6f 6d 20 74 68 65 20 77 6f 72  ing from the wor
5220: 64 73 20 6f 6e 20 74 68 65 20 6c 65 66 74 20 2a  ds on the left *
5230: 2f 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70 52 69  /.  DocList *pRi
5240: 67 68 74 2c 20 20 20 2f 2a 20 44 6f 63 6c 69 73  ght,   /* Doclis
5250: 74 20 66 6f 72 20 74 68 65 20 6e 65 78 74 20 77  t for the next w
5260: 6f 72 64 20 74 6f 20 74 68 65 20 72 69 67 68 74  ord to the right
5270: 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70   */.  DocList *p
5280: 4f 75 74 20 20 20 20 20 20 2f 2a 20 57 72 69 74  Out      /* Writ
5290: 65 20 74 68 65 20 63 6f 6d 62 69 6e 65 64 20 64  e the combined d
52a0: 6f 63 6c 69 73 74 20 68 65 72 65 20 2a 2f 0a 29  oclist here */.)
52b0: 7b 0a 20 20 44 6f 63 4c 69 73 74 52 65 61 64 65  {.  DocListReade
52c0: 72 20 6c 65 66 74 2c 20 72 69 67 68 74 3b 0a 20  r left, right;. 
52d0: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 64 6f   sqlite_int64 do
52e0: 63 69 64 4c 65 66 74 2c 20 64 6f 63 69 64 52 69  cidLeft, docidRi
52f0: 67 68 74 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  ght;..  assert( 
5300: 70 4f 75 74 2d 3e 69 54 79 70 65 3c 44 4c 5f 50  pOut->iType<DL_P
5310: 4f 53 49 54 49 4f 4e 53 20 29 3b 0a 0a 20 20 72  OSITIONS );..  r
5320: 65 61 64 65 72 49 6e 69 74 28 26 6c 65 66 74 2c  eaderInit(&left,
5330: 20 70 4c 65 66 74 29 3b 0a 20 20 72 65 61 64 65   pLeft);.  reade
5340: 72 49 6e 69 74 28 26 72 69 67 68 74 2c 20 70 52  rInit(&right, pR
5350: 69 67 68 74 29 3b 0a 20 20 64 6f 63 69 64 4c 65  ight);.  docidLe
5360: 66 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26  ft = nextDocid(&
5370: 6c 65 66 74 29 3b 0a 20 20 64 6f 63 69 64 52 69  left);.  docidRi
5380: 67 68 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28  ght = nextDocid(
5390: 26 72 69 67 68 74 29 3b 0a 0a 20 20 77 68 69 6c  &right);..  whil
53a0: 65 28 20 64 6f 63 69 64 4c 65 66 74 3e 30 20 26  e( docidLeft>0 &
53b0: 26 20 64 6f 63 69 64 52 69 67 68 74 3e 30 20 29  & docidRight>0 )
53c0: 7b 0a 20 20 20 20 69 66 28 20 64 6f 63 69 64 4c  {.    if( docidL
53d0: 65 66 74 3c 64 6f 63 69 64 52 69 67 68 74 20 29  eft<docidRight )
53e0: 7b 0a 20 20 20 20 20 20 64 6f 63 69 64 4c 65 66  {.      docidLef
53f0: 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 6c  t = nextDocid(&l
5400: 65 66 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20  eft);.    }else 
5410: 69 66 28 20 64 6f 63 69 64 52 69 67 68 74 3c 64  if( docidRight<d
5420: 6f 63 69 64 4c 65 66 74 20 29 7b 0a 20 20 20 20  ocidLeft ){.    
5430: 20 20 64 6f 63 69 64 52 69 67 68 74 20 3d 20 6e    docidRight = n
5440: 65 78 74 44 6f 63 69 64 28 26 72 69 67 68 74 29  extDocid(&right)
5450: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
5460: 20 20 20 64 6f 63 4c 69 73 74 41 64 64 44 6f 63     docListAddDoc
5470: 69 64 28 70 4f 75 74 2c 20 64 6f 63 69 64 4c 65  id(pOut, docidLe
5480: 66 74 29 3b 0a 20 20 20 20 20 20 64 6f 63 69 64  ft);.      docid
5490: 4c 65 66 74 20 3d 20 6e 65 78 74 44 6f 63 69 64  Left = nextDocid
54a0: 28 26 6c 65 66 74 29 3b 0a 20 20 20 20 20 20 64  (&left);.      d
54b0: 6f 63 69 64 52 69 67 68 74 20 3d 20 6e 65 78 74  ocidRight = next
54c0: 44 6f 63 69 64 28 26 72 69 67 68 74 29 3b 0a 20  Docid(&right);. 
54d0: 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 57     }.  }.}../* W
54e0: 65 20 68 61 76 65 20 74 77 6f 20 64 6f 63 6c 69  e have two docli
54f0: 73 74 73 3a 20 20 70 4c 65 66 74 20 61 6e 64 20  sts:  pLeft and 
5500: 70 52 69 67 68 74 2e 0a 2a 2a 20 57 72 69 74 65  pRight..** Write
5510: 20 74 68 65 20 75 6e 69 6f 6e 20 6f 66 20 74 68   the union of th
5520: 65 73 65 20 74 77 6f 20 64 6f 63 6c 69 73 74 73  ese two doclists
5530: 20 69 6e 74 6f 20 70 4f 75 74 2e 0a 2a 2a 20 4f   into pOut..** O
5540: 6e 6c 79 20 64 6f 63 69 64 73 20 61 72 65 20 6d  nly docids are m
5550: 61 74 63 68 65 64 2e 20 20 50 6f 73 69 74 69 6f  atched.  Positio
5560: 6e 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 73  n information is
5570: 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20   ignored..**.** 
5580: 54 68 65 20 6f 75 74 70 75 74 20 70 4f 75 74 20  The output pOut 
5590: 6e 65 76 65 72 20 68 6f 6c 64 73 20 70 6f 73 69  never holds posi
55a0: 74 69 6f 6e 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  tions..*/.static
55b0: 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 4f 72 4d   void docListOrM
55c0: 65 72 67 65 28 0a 20 20 44 6f 63 4c 69 73 74 20  erge(.  DocList 
55d0: 2a 70 4c 65 66 74 2c 20 20 20 20 2f 2a 20 44 6f  *pLeft,    /* Do
55e0: 63 6c 69 73 74 20 72 65 73 75 6c 74 69 6e 67 20  clist resulting 
55f0: 66 72 6f 6d 20 74 68 65 20 77 6f 72 64 73 20 6f  from the words o
5600: 6e 20 74 68 65 20 6c 65 66 74 20 2a 2f 0a 20 20  n the left */.  
5610: 44 6f 63 4c 69 73 74 20 2a 70 52 69 67 68 74 2c  DocList *pRight,
5620: 20 20 20 2f 2a 20 44 6f 63 6c 69 73 74 20 66 6f     /* Doclist fo
5630: 72 20 74 68 65 20 6e 65 78 74 20 77 6f 72 64 20  r the next word 
5640: 74 6f 20 74 68 65 20 72 69 67 68 74 20 2a 2f 0a  to the right */.
5650: 20 20 44 6f 63 4c 69 73 74 20 2a 70 4f 75 74 20    DocList *pOut 
5660: 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68       /* Write th
5670: 65 20 63 6f 6d 62 69 6e 65 64 20 64 6f 63 6c 69  e combined docli
5680: 73 74 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20  st here */.){.  
5690: 44 6f 63 4c 69 73 74 52 65 61 64 65 72 20 6c 65  DocListReader le
56a0: 66 74 2c 20 72 69 67 68 74 3b 0a 20 20 73 71 6c  ft, right;.  sql
56b0: 69 74 65 5f 69 6e 74 36 34 20 64 6f 63 69 64 4c  ite_int64 docidL
56c0: 65 66 74 2c 20 64 6f 63 69 64 52 69 67 68 74 2c  eft, docidRight,
56d0: 20 70 72 69 6f 72 4c 65 66 74 3b 0a 0a 20 20 72   priorLeft;..  r
56e0: 65 61 64 65 72 49 6e 69 74 28 26 6c 65 66 74 2c  eaderInit(&left,
56f0: 20 70 4c 65 66 74 29 3b 0a 20 20 72 65 61 64 65   pLeft);.  reade
5700: 72 49 6e 69 74 28 26 72 69 67 68 74 2c 20 70 52  rInit(&right, pR
5710: 69 67 68 74 29 3b 0a 20 20 64 6f 63 69 64 4c 65  ight);.  docidLe
5720: 66 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26  ft = nextDocid(&
5730: 6c 65 66 74 29 3b 0a 20 20 64 6f 63 69 64 52 69  left);.  docidRi
5740: 67 68 74 20 3d 20 6e 65 78 74 44 6f 63 69 64 28  ght = nextDocid(
5750: 26 72 69 67 68 74 29 3b 0a 0a 20 20 77 68 69 6c  &right);..  whil
5760: 65 28 20 64 6f 63 69 64 4c 65 66 74 3e 30 20 26  e( docidLeft>0 &
5770: 26 20 64 6f 63 69 64 52 69 67 68 74 3e 30 20 29  & docidRight>0 )
5780: 7b 0a 20 20 20 20 69 66 28 20 64 6f 63 69 64 4c  {.    if( docidL
5790: 65 66 74 3c 3d 64 6f 63 69 64 52 69 67 68 74 20  eft<=docidRight 
57a0: 29 7b 0a 20 20 20 20 20 20 64 6f 63 4c 69 73 74  ){.      docList
57b0: 41 64 64 44 6f 63 69 64 28 70 4f 75 74 2c 20 64  AddDocid(pOut, d
57c0: 6f 63 69 64 4c 65 66 74 29 3b 0a 20 20 20 20 7d  ocidLeft);.    }
57d0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 64 6f 63 4c  else{.      docL
57e0: 69 73 74 41 64 64 44 6f 63 69 64 28 70 4f 75 74  istAddDocid(pOut
57f0: 2c 20 64 6f 63 69 64 52 69 67 68 74 29 3b 0a 20  , docidRight);. 
5800: 20 20 20 7d 0a 20 20 20 20 70 72 69 6f 72 4c 65     }.    priorLe
5810: 66 74 20 3d 20 64 6f 63 69 64 4c 65 66 74 3b 0a  ft = docidLeft;.
5820: 20 20 20 20 69 66 28 20 64 6f 63 69 64 4c 65 66      if( docidLef
5830: 74 3c 3d 64 6f 63 69 64 52 69 67 68 74 20 29 7b  t<=docidRight ){
5840: 0a 20 20 20 20 20 20 64 6f 63 69 64 4c 65 66 74  .      docidLeft
5850: 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 6c 65   = nextDocid(&le
5860: 66 74 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  ft);.    }.    i
5870: 66 28 20 64 6f 63 69 64 52 69 67 68 74 3e 30 20  f( docidRight>0 
5880: 26 26 20 64 6f 63 69 64 52 69 67 68 74 3c 3d 70  && docidRight<=p
5890: 72 69 6f 72 4c 65 66 74 20 29 7b 0a 20 20 20 20  riorLeft ){.    
58a0: 20 20 64 6f 63 69 64 52 69 67 68 74 20 3d 20 6e    docidRight = n
58b0: 65 78 74 44 6f 63 69 64 28 26 72 69 67 68 74 29  extDocid(&right)
58c0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68  ;.    }.  }.  wh
58d0: 69 6c 65 28 20 64 6f 63 69 64 4c 65 66 74 3e 30  ile( docidLeft>0
58e0: 20 29 7b 0a 20 20 20 20 64 6f 63 4c 69 73 74 41   ){.    docListA
58f0: 64 64 44 6f 63 69 64 28 70 4f 75 74 2c 20 64 6f  ddDocid(pOut, do
5900: 63 69 64 4c 65 66 74 29 3b 0a 20 20 20 20 64 6f  cidLeft);.    do
5910: 63 69 64 4c 65 66 74 20 3d 20 6e 65 78 74 44 6f  cidLeft = nextDo
5920: 63 69 64 28 26 6c 65 66 74 29 3b 0a 20 20 7d 0a  cid(&left);.  }.
5930: 20 20 77 68 69 6c 65 28 20 64 6f 63 69 64 52 69    while( docidRi
5940: 67 68 74 3e 30 20 29 7b 0a 20 20 20 20 64 6f 63  ght>0 ){.    doc
5950: 4c 69 73 74 41 64 64 44 6f 63 69 64 28 70 4f 75  ListAddDocid(pOu
5960: 74 2c 20 64 6f 63 69 64 52 69 67 68 74 29 3b 0a  t, docidRight);.
5970: 20 20 20 20 64 6f 63 69 64 52 69 67 68 74 20 3d      docidRight =
5980: 20 6e 65 78 74 44 6f 63 69 64 28 26 72 69 67 68   nextDocid(&righ
5990: 74 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 57 65  t);.  }.}../* We
59a0: 20 68 61 76 65 20 74 77 6f 20 64 6f 63 6c 69 73   have two doclis
59b0: 74 73 3a 20 20 70 4c 65 66 74 20 61 6e 64 20 70  ts:  pLeft and p
59c0: 52 69 67 68 74 2e 0a 2a 2a 20 57 72 69 74 65 20  Right..** Write 
59d0: 69 6e 74 6f 20 70 4f 75 74 20 61 6c 6c 20 64 6f  into pOut all do
59e0: 63 75 6d 65 6e 74 73 20 74 68 61 74 20 6f 63 63  cuments that occ
59f0: 75 72 20 69 6e 20 70 4c 65 66 74 20 62 75 74 20  ur in pLeft but 
5a00: 6e 6f 74 0a 2a 2a 20 69 6e 20 70 52 69 67 68 74  not.** in pRight
5a10: 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 6c 79 20 64 6f 63  ..**.** Only doc
5a20: 69 64 73 20 61 72 65 20 6d 61 74 63 68 65 64 2e  ids are matched.
5a30: 20 20 50 6f 73 69 74 69 6f 6e 20 69 6e 66 6f 72    Position infor
5a40: 6d 61 74 69 6f 6e 20 69 73 20 69 67 6e 6f 72 65  mation is ignore
5a50: 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6f 75 74  d..**.** The out
5a60: 70 75 74 20 70 4f 75 74 20 6e 65 76 65 72 20 68  put pOut never h
5a70: 6f 6c 64 73 20 70 6f 73 69 74 69 6f 6e 73 2e 0a  olds positions..
5a80: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  */.static void d
5a90: 6f 63 4c 69 73 74 45 78 63 65 70 74 4d 65 72 67  ocListExceptMerg
5aa0: 65 28 0a 20 20 44 6f 63 4c 69 73 74 20 2a 70 4c  e(.  DocList *pL
5ab0: 65 66 74 2c 20 20 20 20 2f 2a 20 44 6f 63 6c 69  eft,    /* Docli
5ac0: 73 74 20 72 65 73 75 6c 74 69 6e 67 20 66 72 6f  st resulting fro
5ad0: 6d 20 74 68 65 20 77 6f 72 64 73 20 6f 6e 20 74  m the words on t
5ae0: 68 65 20 6c 65 66 74 20 2a 2f 0a 20 20 44 6f 63  he left */.  Doc
5af0: 4c 69 73 74 20 2a 70 52 69 67 68 74 2c 20 20 20  List *pRight,   
5b00: 2f 2a 20 44 6f 63 6c 69 73 74 20 66 6f 72 20 74  /* Doclist for t
5b10: 68 65 20 6e 65 78 74 20 77 6f 72 64 20 74 6f 20  he next word to 
5b20: 74 68 65 20 72 69 67 68 74 20 2a 2f 0a 20 20 44  the right */.  D
5b30: 6f 63 4c 69 73 74 20 2a 70 4f 75 74 20 20 20 20  ocList *pOut    
5b40: 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 63    /* Write the c
5b50: 6f 6d 62 69 6e 65 64 20 64 6f 63 6c 69 73 74 20  ombined doclist 
5b60: 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 44 6f 63  here */.){.  Doc
5b70: 4c 69 73 74 52 65 61 64 65 72 20 6c 65 66 74 2c  ListReader left,
5b80: 20 72 69 67 68 74 3b 0a 20 20 73 71 6c 69 74 65   right;.  sqlite
5b90: 5f 69 6e 74 36 34 20 64 6f 63 69 64 4c 65 66 74  _int64 docidLeft
5ba0: 2c 20 64 6f 63 69 64 52 69 67 68 74 2c 20 70 72  , docidRight, pr
5bb0: 69 6f 72 4c 65 66 74 3b 0a 0a 20 20 72 65 61 64  iorLeft;..  read
5bc0: 65 72 49 6e 69 74 28 26 6c 65 66 74 2c 20 70 4c  erInit(&left, pL
5bd0: 65 66 74 29 3b 0a 20 20 72 65 61 64 65 72 49 6e  eft);.  readerIn
5be0: 69 74 28 26 72 69 67 68 74 2c 20 70 52 69 67 68  it(&right, pRigh
5bf0: 74 29 3b 0a 20 20 64 6f 63 69 64 4c 65 66 74 20  t);.  docidLeft 
5c00: 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 6c 65 66  = nextDocid(&lef
5c10: 74 29 3b 0a 20 20 64 6f 63 69 64 52 69 67 68 74  t);.  docidRight
5c20: 20 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 72 69   = nextDocid(&ri
5c30: 67 68 74 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20  ght);..  while( 
5c40: 64 6f 63 69 64 4c 65 66 74 3e 30 20 26 26 20 64  docidLeft>0 && d
5c50: 6f 63 69 64 52 69 67 68 74 3e 30 20 29 7b 0a 20  ocidRight>0 ){. 
5c60: 20 20 20 70 72 69 6f 72 4c 65 66 74 20 3d 20 64     priorLeft = d
5c70: 6f 63 69 64 4c 65 66 74 3b 0a 20 20 20 20 69 66  ocidLeft;.    if
5c80: 28 20 64 6f 63 69 64 4c 65 66 74 3c 64 6f 63 69  ( docidLeft<doci
5c90: 64 52 69 67 68 74 20 29 7b 0a 20 20 20 20 20 20  dRight ){.      
5ca0: 64 6f 63 4c 69 73 74 41 64 64 44 6f 63 69 64 28  docListAddDocid(
5cb0: 70 4f 75 74 2c 20 64 6f 63 69 64 4c 65 66 74 29  pOut, docidLeft)
5cc0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
5cd0: 64 6f 63 69 64 4c 65 66 74 3c 3d 64 6f 63 69 64  docidLeft<=docid
5ce0: 52 69 67 68 74 20 29 7b 0a 20 20 20 20 20 20 64  Right ){.      d
5cf0: 6f 63 69 64 4c 65 66 74 20 3d 20 6e 65 78 74 44  ocidLeft = nextD
5d00: 6f 63 69 64 28 26 6c 65 66 74 29 3b 0a 20 20 20  ocid(&left);.   
5d10: 20 7d 0a 20 20 20 20 69 66 28 20 64 6f 63 69 64   }.    if( docid
5d20: 52 69 67 68 74 3e 30 20 26 26 20 64 6f 63 69 64  Right>0 && docid
5d30: 52 69 67 68 74 3c 3d 70 72 69 6f 72 4c 65 66 74  Right<=priorLeft
5d40: 20 29 7b 0a 20 20 20 20 20 20 64 6f 63 69 64 52   ){.      docidR
5d50: 69 67 68 74 20 3d 20 6e 65 78 74 44 6f 63 69 64  ight = nextDocid
5d60: 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20 7d 0a  (&right);.    }.
5d70: 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 64 6f 63    }.  while( doc
5d80: 69 64 4c 65 66 74 3e 30 20 29 7b 0a 20 20 20 20  idLeft>0 ){.    
5d90: 64 6f 63 4c 69 73 74 41 64 64 44 6f 63 69 64 28  docListAddDocid(
5da0: 70 4f 75 74 2c 20 64 6f 63 69 64 4c 65 66 74 29  pOut, docidLeft)
5db0: 3b 0a 20 20 20 20 64 6f 63 69 64 4c 65 66 74 20  ;.    docidLeft 
5dc0: 3d 20 6e 65 78 74 44 6f 63 69 64 28 26 6c 65 66  = nextDocid(&lef
5dd0: 74 29 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69  t);.  }.}..stati
5de0: 63 20 63 68 61 72 20 2a 73 74 72 69 6e 67 5f 64  c char *string_d
5df0: 75 70 5f 6e 28 63 6f 6e 73 74 20 63 68 61 72 20  up_n(const char 
5e00: 2a 73 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 63 68  *s, int n){.  ch
5e10: 61 72 20 2a 73 74 72 20 3d 20 6d 61 6c 6c 6f 63  ar *str = malloc
5e20: 28 6e 20 2b 20 31 29 3b 0a 20 20 6d 65 6d 63 70  (n + 1);.  memcp
5e30: 79 28 73 74 72 2c 20 73 2c 20 6e 29 3b 0a 20 20  y(str, s, n);.  
5e40: 73 74 72 5b 6e 5d 20 3d 20 27 5c 30 27 3b 0a 20  str[n] = '\0';. 
5e50: 20 72 65 74 75 72 6e 20 73 74 72 3b 0a 7d 0a 0a   return str;.}..
5e60: 2f 2a 20 44 75 70 6c 69 63 61 74 65 20 61 20 73  /* Duplicate a s
5e70: 74 72 69 6e 67 3b 20 74 68 65 20 63 61 6c 6c 65  tring; the calle
5e80: 72 20 6d 75 73 74 20 66 72 65 65 28 29 20 74 68  r must free() th
5e90: 65 20 72 65 74 75 72 6e 65 64 20 73 74 72 69 6e  e returned strin
5ea0: 67 2e 0a 20 2a 20 28 57 65 20 64 6f 6e 27 74 20  g.. * (We don't 
5eb0: 75 73 65 20 73 74 72 64 75 70 28 29 20 73 69 6e  use strdup() sin
5ec0: 63 65 20 69 74 27 73 20 6e 6f 74 20 70 61 72 74  ce it's not part
5ed0: 20 6f 66 20 74 68 65 20 73 74 61 6e 64 61 72 64   of the standard
5ee0: 20 43 20 6c 69 62 72 61 72 79 20 61 6e 64 0a 20   C library and. 
5ef0: 2a 20 6d 61 79 20 6e 6f 74 20 62 65 20 61 76 61  * may not be ava
5f00: 69 6c 61 62 6c 65 20 65 76 65 72 79 77 68 65 72  ilable everywher
5f10: 65 2e 29 20 2a 2f 0a 73 74 61 74 69 63 20 63 68  e.) */.static ch
5f20: 61 72 20 2a 73 74 72 69 6e 67 5f 64 75 70 28 63  ar *string_dup(c
5f30: 6f 6e 73 74 20 63 68 61 72 20 2a 73 29 7b 0a 20  onst char *s){. 
5f40: 20 72 65 74 75 72 6e 20 73 74 72 69 6e 67 5f 64   return string_d
5f50: 75 70 5f 6e 28 73 2c 20 73 74 72 6c 65 6e 28 73  up_n(s, strlen(s
5f60: 29 29 3b 0a 7d 0a 0a 2f 2a 20 46 6f 72 6d 61 74  ));.}../* Format
5f70: 20 61 20 73 74 72 69 6e 67 2c 20 72 65 70 6c 61   a string, repla
5f80: 63 69 6e 67 20 65 61 63 68 20 6f 63 63 75 72 72  cing each occurr
5f90: 65 6e 63 65 20 6f 66 20 74 68 65 20 25 20 63 68  ence of the % ch
5fa0: 61 72 61 63 74 65 72 20 77 69 74 68 0a 20 2a 20  aracter with. * 
5fb0: 7a 44 62 2e 7a 4e 61 6d 65 2e 20 20 54 68 69 73  zDb.zName.  This
5fc0: 20 6d 61 79 20 62 65 20 6d 6f 72 65 20 63 6f 6e   may be more con
5fd0: 76 65 6e 69 65 6e 74 20 74 68 61 6e 20 73 71 6c  venient than sql
5fe0: 69 74 65 5f 6d 70 72 69 6e 74 66 28 29 0a 20 2a  ite_mprintf(). *
5ff0: 20 77 68 65 6e 20 6f 6e 65 20 73 74 72 69 6e 67   when one string
6000: 20 69 73 20 75 73 65 64 20 72 65 70 65 61 74 65   is used repeate
6010: 64 6c 79 20 69 6e 20 61 20 66 6f 72 6d 61 74 20  dly in a format 
6020: 73 74 72 69 6e 67 2e 0a 20 2a 20 54 68 65 20 63  string.. * The c
6030: 61 6c 6c 65 72 20 6d 75 73 74 20 66 72 65 65 28  aller must free(
6040: 29 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 73  ) the returned s
6050: 74 72 69 6e 67 2e 20 2a 2f 0a 73 74 61 74 69 63  tring. */.static
6060: 20 63 68 61 72 20 2a 73 74 72 69 6e 67 5f 66 6f   char *string_fo
6070: 72 6d 61 74 28 63 6f 6e 73 74 20 63 68 61 72 20  rmat(const char 
6080: 2a 7a 46 6f 72 6d 61 74 2c 0a 20 20 20 20 20 20  *zFormat,.      
6090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60a0: 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20       const char 
60b0: 2a 7a 44 62 2c 20 63 6f 6e 73 74 20 63 68 61 72  *zDb, const char
60c0: 20 2a 7a 4e 61 6d 65 29 7b 0a 20 20 63 6f 6e 73   *zName){.  cons
60d0: 74 20 63 68 61 72 20 2a 70 3b 0a 20 20 73 69 7a  t char *p;.  siz
60e0: 65 5f 74 20 6c 65 6e 20 3d 20 30 3b 0a 20 20 73  e_t len = 0;.  s
60f0: 69 7a 65 5f 74 20 6e 44 62 20 3d 20 73 74 72 6c  ize_t nDb = strl
6100: 65 6e 28 7a 44 62 29 3b 0a 20 20 73 69 7a 65 5f  en(zDb);.  size_
6110: 74 20 6e 4e 61 6d 65 20 3d 20 73 74 72 6c 65 6e  t nName = strlen
6120: 28 7a 4e 61 6d 65 29 3b 0a 20 20 73 69 7a 65 5f  (zName);.  size_
6130: 74 20 6e 46 75 6c 6c 54 61 62 6c 65 4e 61 6d 65  t nFullTableName
6140: 20 3d 20 6e 44 62 2b 31 2b 6e 4e 61 6d 65 3b 0a   = nDb+1+nName;.
6150: 20 20 63 68 61 72 20 2a 72 65 73 75 6c 74 3b 0a    char *result;.
6160: 20 20 63 68 61 72 20 2a 72 3b 0a 0a 20 20 2f 2a    char *r;..  /*
6170: 20 66 69 72 73 74 20 63 6f 6d 70 75 74 65 20 6c   first compute l
6180: 65 6e 67 74 68 20 6e 65 65 64 65 64 20 2a 2f 0a  ength needed */.
6190: 20 20 66 6f 72 28 70 20 3d 20 7a 46 6f 72 6d 61    for(p = zForma
61a0: 74 20 3b 20 2a 70 20 3b 20 2b 2b 70 29 7b 0a 20  t ; *p ; ++p){. 
61b0: 20 20 20 6c 65 6e 20 2b 3d 20 28 2a 70 3d 3d 27     len += (*p=='
61c0: 25 27 20 3f 20 6e 46 75 6c 6c 54 61 62 6c 65 4e  %' ? nFullTableN
61d0: 61 6d 65 20 3a 20 31 29 3b 0a 20 20 7d 0a 20 20  ame : 1);.  }.  
61e0: 6c 65 6e 20 2b 3d 20 31 3b 20 20 2f 2a 20 66 6f  len += 1;  /* fo
61f0: 72 20 6e 75 6c 6c 20 74 65 72 6d 69 6e 61 74 6f  r null terminato
6200: 72 20 2a 2f 0a 0a 20 20 72 20 3d 20 72 65 73 75  r */..  r = resu
6210: 6c 74 20 3d 20 6d 61 6c 6c 6f 63 28 6c 65 6e 29  lt = malloc(len)
6220: 3b 0a 20 20 66 6f 72 28 70 20 3d 20 7a 46 6f 72  ;.  for(p = zFor
6230: 6d 61 74 3b 20 2a 70 3b 20 2b 2b 70 29 7b 0a 20  mat; *p; ++p){. 
6240: 20 20 20 69 66 28 20 2a 70 3d 3d 27 25 27 20 29     if( *p=='%' )
6250: 7b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 72  {.      memcpy(r
6260: 2c 20 7a 44 62 2c 20 6e 44 62 29 3b 0a 20 20 20  , zDb, nDb);.   
6270: 20 20 20 72 20 2b 3d 20 6e 44 62 3b 0a 20 20 20     r += nDb;.   
6280: 20 20 20 2a 72 2b 2b 20 3d 20 27 2e 27 3b 0a 20     *r++ = '.';. 
6290: 20 20 20 20 20 6d 65 6d 63 70 79 28 72 2c 20 7a       memcpy(r, z
62a0: 4e 61 6d 65 2c 20 6e 4e 61 6d 65 29 3b 0a 20 20  Name, nName);.  
62b0: 20 20 20 20 72 20 2b 3d 20 6e 4e 61 6d 65 3b 0a      r += nName;.
62c0: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
62d0: 20 20 20 2a 72 2b 2b 20 3d 20 2a 70 3b 0a 20 20     *r++ = *p;.  
62e0: 20 20 7d 0a 20 20 7d 0a 20 20 2a 72 2b 2b 20 3d    }.  }.  *r++ =
62f0: 20 27 5c 30 27 3b 0a 20 20 61 73 73 65 72 74 28   '\0';.  assert(
6300: 20 72 20 3d 3d 20 72 65 73 75 6c 74 20 2b 20 6c   r == result + l
6310: 65 6e 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  en );.  return r
6320: 65 73 75 6c 74 3b 0a 7d 0a 0a 73 74 61 74 69 63  esult;.}..static
6330: 20 69 6e 74 20 73 71 6c 5f 65 78 65 63 28 73 71   int sql_exec(sq
6340: 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74  lite3 *db, const
6350: 20 63 68 61 72 20 2a 7a 44 62 2c 20 63 6f 6e 73   char *zDb, cons
6360: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20  t char *zName,. 
6370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6380: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
6390: 46 6f 72 6d 61 74 29 7b 0a 20 20 63 68 61 72 20  Format){.  char 
63a0: 2a 7a 43 6f 6d 6d 61 6e 64 20 3d 20 73 74 72 69  *zCommand = stri
63b0: 6e 67 5f 66 6f 72 6d 61 74 28 7a 46 6f 72 6d 61  ng_format(zForma
63c0: 74 2c 20 7a 44 62 2c 20 7a 4e 61 6d 65 29 3b 0a  t, zDb, zName);.
63d0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 54 52 41 43    int rc;.  TRAC
63e0: 45 28 28 22 46 54 53 31 20 73 71 6c 3a 20 25 73  E(("FTS1 sql: %s
63f0: 5c 6e 22 2c 20 7a 43 6f 6d 6d 61 6e 64 29 29 3b  \n", zCommand));
6400: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
6410: 65 78 65 63 28 64 62 2c 20 7a 43 6f 6d 6d 61 6e  exec(db, zComman
6420: 64 2c 20 4e 55 4c 4c 2c 20 30 2c 20 4e 55 4c 4c  d, NULL, 0, NULL
6430: 29 3b 0a 20 20 66 72 65 65 28 7a 43 6f 6d 6d 61  );.  free(zComma
6440: 6e 64 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  nd);.  return rc
6450: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
6460: 73 71 6c 5f 70 72 65 70 61 72 65 28 73 71 6c 69  sql_prepare(sqli
6470: 74 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 63  te3 *db, const c
6480: 68 61 72 20 2a 7a 44 62 2c 20 63 6f 6e 73 74 20  har *zDb, const 
6490: 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20 20  char *zName,.   
64a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
64b0: 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74      sqlite3_stmt
64c0: 20 2a 2a 70 70 53 74 6d 74 2c 20 63 6f 6e 73 74   **ppStmt, const
64d0: 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 29 7b   char *zFormat){
64e0: 0a 20 20 63 68 61 72 20 2a 7a 43 6f 6d 6d 61 6e  .  char *zComman
64f0: 64 20 3d 20 73 74 72 69 6e 67 5f 66 6f 72 6d 61  d = string_forma
6500: 74 28 7a 46 6f 72 6d 61 74 2c 20 7a 44 62 2c 20  t(zFormat, zDb, 
6510: 7a 4e 61 6d 65 29 3b 0a 20 20 69 6e 74 20 72 63  zName);.  int rc
6520: 3b 0a 20 20 54 52 41 43 45 28 28 22 46 54 53 31  ;.  TRACE(("FTS1
6530: 20 70 72 65 70 61 72 65 3a 20 25 73 5c 6e 22 2c   prepare: %s\n",
6540: 20 7a 43 6f 6d 6d 61 6e 64 29 29 3b 0a 20 20 72   zCommand));.  r
6550: 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
6560: 61 72 65 28 64 62 2c 20 7a 43 6f 6d 6d 61 6e 64  are(db, zCommand
6570: 2c 20 2d 31 2c 20 70 70 53 74 6d 74 2c 20 4e 55  , -1, ppStmt, NU
6580: 4c 4c 29 3b 0a 20 20 66 72 65 65 28 7a 43 6f 6d  LL);.  free(zCom
6590: 6d 61 6e 64 29 3b 0a 20 20 72 65 74 75 72 6e 20  mand);.  return 
65a0: 72 63 3b 0a 7d 0a 0a 2f 2a 20 65 6e 64 20 75 74  rc;.}../* end ut
65b0: 69 6c 69 74 79 20 66 75 6e 63 74 69 6f 6e 73 20  ility functions 
65c0: 2a 2f 0a 0a 2f 2a 20 46 6f 72 77 61 72 64 20 72  */../* Forward r
65d0: 65 66 65 72 65 6e 63 65 20 2a 2f 0a 74 79 70 65  eference */.type
65e0: 64 65 66 20 73 74 72 75 63 74 20 66 75 6c 6c 74  def struct fullt
65f0: 65 78 74 5f 76 74 61 62 20 66 75 6c 6c 74 65 78  ext_vtab fulltex
6600: 74 5f 76 74 61 62 3b 0a 0a 2f 2a 20 41 20 73 69  t_vtab;../* A si
6610: 6e 67 6c 65 20 74 65 72 6d 20 69 6e 20 61 20 71  ngle term in a q
6620: 75 65 72 79 20 69 73 20 72 65 70 72 65 73 65 6e  uery is represen
6630: 74 65 64 20 62 79 20 61 6e 20 69 6e 73 74 61 6e  ted by an instan
6640: 63 65 73 20 6f 66 0a 2a 2a 20 74 68 65 20 66 6f  ces of.** the fo
6650: 6c 6c 6f 77 69 6e 67 20 73 74 72 75 63 74 75 72  llowing structur
6660: 65 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  e..*/.typedef st
6670: 72 75 63 74 20 51 75 65 72 79 54 65 72 6d 20 7b  ruct QueryTerm {
6680: 0a 20 20 73 68 6f 72 74 20 69 6e 74 20 6e 50 68  .  short int nPh
6690: 72 61 73 65 3b 20 2f 2a 20 48 6f 77 20 6d 61 6e  rase; /* How man
66a0: 79 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 65 72 6d  y following term
66b0: 73 20 61 72 65 20 70 61 72 74 20 6f 66 20 74 68  s are part of th
66c0: 65 20 73 61 6d 65 20 70 68 72 61 73 65 20 2a 2f  e same phrase */
66d0: 0a 20 20 73 68 6f 72 74 20 69 6e 74 20 69 50 68  .  short int iPh
66e0: 72 61 73 65 3b 20 2f 2a 20 54 68 69 73 20 69 73  rase; /* This is
66f0: 20 74 68 65 20 69 2d 74 68 20 74 65 72 6d 20 6f   the i-th term o
6700: 66 20 61 20 70 68 72 61 73 65 2e 20 2a 2f 0a 20  f a phrase. */. 
6710: 20 73 68 6f 72 74 20 69 6e 74 20 69 43 6f 6c 75   short int iColu
6720: 6d 6e 3b 20 2f 2a 20 43 6f 6c 75 6d 6e 20 6f 66  mn; /* Column of
6730: 20 74 68 65 20 69 6e 64 65 78 20 74 68 61 74 20   the index that 
6740: 6d 75 73 74 20 6d 61 74 63 68 20 74 68 69 73 20  must match this 
6750: 74 65 72 6d 20 2a 2f 0a 20 20 73 69 67 6e 65 64  term */.  signed
6760: 20 63 68 61 72 20 69 73 4f 72 3b 20 20 2f 2a 20   char isOr;  /* 
6770: 74 68 69 73 20 74 65 72 6d 20 69 73 20 70 72 65  this term is pre
6780: 63 65 64 65 64 20 62 79 20 22 4f 52 22 20 2a 2f  ceded by "OR" */
6790: 0a 20 20 73 69 67 6e 65 64 20 63 68 61 72 20 69  .  signed char i
67a0: 73 4e 6f 74 3b 20 2f 2a 20 74 68 69 73 20 74 65  sNot; /* this te
67b0: 72 6d 20 69 73 20 70 72 65 63 65 64 65 64 20 62  rm is preceded b
67c0: 79 20 22 2d 22 20 2a 2f 0a 20 20 63 68 61 72 20  y "-" */.  char 
67d0: 2a 70 54 65 72 6d 3b 20 20 20 20 20 20 20 2f 2a  *pTerm;       /*
67e0: 20 74 65 78 74 20 6f 66 20 74 68 65 20 74 65 72   text of the ter
67f0: 6d 2e 20 20 27 5c 30 30 30 27 20 74 65 72 6d 69  m.  '\000' termi
6800: 6e 61 74 65 64 2e 20 20 6d 61 6c 6c 6f 63 65 64  nated.  malloced
6810: 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 65 72 6d 3b   */.  int nTerm;
6820: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
6830: 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 70  er of bytes in p
6840: 54 65 72 6d 5b 5d 20 2a 2f 0a 7d 20 51 75 65 72  Term[] */.} Quer
6850: 79 54 65 72 6d 3b 0a 0a 0a 2f 2a 20 41 20 71 75  yTerm;.../* A qu
6860: 65 72 79 20 73 74 72 69 6e 67 20 69 73 20 70 61  ery string is pa
6870: 72 73 65 64 20 69 6e 74 6f 20 61 20 51 75 65 72  rsed into a Quer
6880: 79 20 73 74 72 75 63 74 75 72 65 2e 0a 20 2a 0a  y structure.. *.
6890: 20 2a 20 57 65 20 63 6f 75 6c 64 2c 20 69 6e 20   * We could, in 
68a0: 74 68 65 6f 72 79 2c 20 61 6c 6c 6f 77 20 71 75  theory, allow qu
68b0: 65 72 79 20 73 74 72 69 6e 67 73 20 74 6f 20 62  ery strings to b
68c0: 65 20 63 6f 6d 70 6c 69 63 61 74 65 64 0a 20 2a  e complicated. *
68d0: 20 6e 65 73 74 65 64 20 65 78 70 72 65 73 73 69   nested expressi
68e0: 6f 6e 73 20 77 69 74 68 20 70 72 65 63 65 64 65  ons with precede
68f0: 6e 63 65 20 64 65 74 65 72 6d 69 6e 65 64 20 62  nce determined b
6900: 79 20 70 61 72 65 6e 74 68 65 73 65 73 2e 0a 20  y parentheses.. 
6910: 2a 20 42 75 74 20 6e 6f 6e 65 20 6f 66 20 74 68  * But none of th
6920: 65 20 6d 61 6a 6f 72 20 73 65 61 72 63 68 20 65  e major search e
6930: 6e 67 69 6e 65 73 20 64 6f 20 74 68 69 73 2e 20  ngines do this. 
6940: 20 28 50 65 72 68 61 70 73 20 74 68 65 0a 20 2a   (Perhaps the. *
6950: 20 66 65 65 6c 69 6e 67 20 69 73 20 74 68 61 74   feeling is that
6960: 20 61 6e 20 70 61 72 65 6e 74 68 65 73 69 7a 65   an parenthesize
6970: 64 20 65 78 70 72 65 73 73 69 6f 6e 20 69 73 20  d expression is 
6980: 74 77 6f 20 63 6f 6d 70 6c 65 78 20 6f 66 0a 20  two complex of. 
6990: 2a 20 61 6e 20 69 64 65 61 20 66 6f 72 20 74 68  * an idea for th
69a0: 65 20 61 76 65 72 61 67 65 20 75 73 65 72 20 74  e average user t
69b0: 6f 20 67 72 61 73 70 2e 29 20 20 54 61 6b 69 6e  o grasp.)  Takin
69c0: 67 20 6f 75 72 20 6c 65 61 64 20 66 72 6f 6d 0a  g our lead from.
69d0: 20 2a 20 74 68 65 20 6d 61 6a 6f 72 20 73 65 61   * the major sea
69e0: 72 63 68 20 65 6e 67 69 6e 65 73 2c 20 77 65 20  rch engines, we 
69f0: 77 69 6c 6c 20 61 6c 6c 6f 77 20 71 75 65 72 69  will allow queri
6a00: 65 73 20 74 6f 20 62 65 20 61 20 6c 69 73 74 0a  es to be a list.
6a10: 20 2a 20 6f 66 20 74 65 72 6d 73 20 28 77 69 74   * of terms (wit
6a20: 68 20 61 6e 20 69 6d 70 6c 69 65 64 20 41 4e 44  h an implied AND
6a30: 20 6f 70 65 72 61 74 6f 72 29 20 6f 72 20 70 68   operator) or ph
6a40: 72 61 73 65 73 20 69 6e 20 64 6f 75 62 6c 65 2d  rases in double-
6a50: 71 75 6f 74 65 73 2c 0a 20 2a 20 77 69 74 68 20  quotes,. * with 
6a60: 61 20 73 69 6e 67 6c 65 20 6f 70 74 69 6f 6e 61  a single optiona
6a70: 6c 20 22 2d 22 20 62 65 66 6f 72 65 20 65 61 63  l "-" before eac
6a80: 68 20 6e 6f 6e 2d 70 68 72 61 73 65 20 74 65 72  h non-phrase ter
6a90: 6d 20 74 6f 20 64 65 73 69 67 6e 61 74 65 0a 20  m to designate. 
6aa0: 2a 20 6e 65 67 61 74 69 6f 6e 20 61 6e 64 20 61  * negation and a
6ab0: 6e 20 6f 70 74 69 6f 6e 61 6c 20 4f 52 20 63 6f  n optional OR co
6ac0: 6e 6e 65 63 74 6f 72 2e 0a 20 2a 0a 20 2a 20 4f  nnector.. *. * O
6ad0: 52 20 62 69 6e 64 73 20 6d 6f 72 65 20 74 69 67  R binds more tig
6ae0: 68 74 6c 79 20 74 68 61 6e 20 74 68 65 20 69 6d  htly than the im
6af0: 70 6c 69 65 64 20 41 4e 44 2c 20 77 68 69 63 68  plied AND, which
6b00: 20 69 73 20 77 68 61 74 20 74 68 65 0a 20 2a 20   is what the. * 
6b10: 6d 61 6a 6f 72 20 73 65 61 72 63 68 20 65 6e 67  major search eng
6b20: 69 6e 65 73 20 73 65 65 6d 20 74 6f 20 64 6f 2e  ines seem to do.
6b30: 20 20 53 6f 2c 20 66 6f 72 20 65 78 61 6d 70 6c    So, for exampl
6b40: 65 3a 0a 20 2a 20 0a 20 2a 20 20 20 20 5b 6f 6e  e:. * . *    [on
6b50: 65 20 74 77 6f 20 4f 52 20 74 68 72 65 65 5d 20  e two OR three] 
6b60: 20 20 20 20 3d 3d 3e 20 20 20 20 6f 6e 65 20 41      ==>    one A
6b70: 4e 44 20 28 74 77 6f 20 4f 52 20 74 68 72 65 65  ND (two OR three
6b80: 29 0a 20 2a 20 20 20 20 5b 6f 6e 65 20 4f 52 20  ). *    [one OR 
6b90: 74 77 6f 20 74 68 72 65 65 5d 20 20 20 20 20 3d  two three]     =
6ba0: 3d 3e 20 20 20 20 28 6f 6e 65 20 4f 52 20 74 77  =>    (one OR tw
6bb0: 6f 29 20 41 4e 44 20 74 68 72 65 65 0a 20 2a 0a  o) AND three. *.
6bc0: 20 2a 20 41 20 22 2d 22 20 62 65 66 6f 72 65 20   * A "-" before 
6bd0: 61 20 74 65 72 6d 20 6d 61 74 63 68 65 73 20 61  a term matches a
6be0: 6c 6c 20 65 6e 74 72 69 65 73 20 74 68 61 74 20  ll entries that 
6bf0: 6c 61 63 6b 20 74 68 61 74 20 74 65 72 6d 2e 0a  lack that term..
6c00: 20 2a 20 54 68 65 20 22 2d 22 20 6d 75 73 74 20   * The "-" must 
6c10: 6f 63 63 75 72 20 69 6d 6d 65 64 69 61 74 65 6c  occur immediatel
6c20: 79 20 62 65 66 6f 72 65 20 74 68 65 20 74 65 72  y before the ter
6c30: 6d 20 77 69 74 68 20 69 6e 20 69 6e 74 65 72 76  m with in interv
6c40: 65 6e 69 6e 67 0a 20 2a 20 73 70 61 63 65 2e 20  ening. * space. 
6c50: 20 54 68 69 73 20 69 73 20 68 6f 77 20 74 68 65   This is how the
6c60: 20 73 65 61 72 63 68 20 65 6e 67 69 6e 65 73 20   search engines 
6c70: 64 6f 20 69 74 2e 0a 20 2a 0a 20 2a 20 41 20 4e  do it.. *. * A N
6c80: 4f 54 20 74 65 72 6d 20 63 61 6e 6e 6f 74 20 62  OT term cannot b
6c90: 65 20 74 68 65 20 72 69 67 68 74 2d 68 61 6e 64  e the right-hand
6ca0: 20 6f 70 65 72 61 6e 64 20 6f 66 20 61 6e 20 4f   operand of an O
6cb0: 52 2e 20 20 49 66 20 74 68 69 73 0a 20 2a 20 6f  R.  If this. * o
6cc0: 63 63 75 72 73 20 69 6e 20 74 68 65 20 71 75 65  ccurs in the que
6cd0: 72 79 20 73 74 72 69 6e 67 2c 20 74 68 65 20 4e  ry string, the N
6ce0: 4f 54 20 69 73 20 69 67 6e 6f 72 65 64 3a 0a 20  OT is ignored:. 
6cf0: 2a 0a 20 2a 20 20 20 20 5b 6f 6e 65 20 4f 52 20  *. *    [one OR 
6d00: 2d 74 77 6f 5d 20 20 20 20 20 20 20 20 20 20 3d  -two]          =
6d10: 3d 3e 20 20 20 20 6f 6e 65 20 4f 52 20 74 77 6f  =>    one OR two
6d20: 0a 20 2a 0a 20 2a 2f 0a 74 79 70 65 64 65 66 20  . *. */.typedef 
6d30: 73 74 72 75 63 74 20 51 75 65 72 79 20 7b 0a 20  struct Query {. 
6d40: 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a   fulltext_vtab *
6d50: 70 46 74 73 3b 20 20 2f 2a 20 54 68 65 20 66 75  pFts;  /* The fu
6d60: 6c 6c 20 74 65 78 74 20 69 6e 64 65 78 20 2a 2f  ll text index */
6d70: 0a 20 20 69 6e 74 20 6e 54 65 72 6d 73 3b 20 20  .  int nTerms;  
6d80: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
6d90: 65 72 20 6f 66 20 74 65 72 6d 73 20 69 6e 20 74  er of terms in t
6da0: 68 65 20 71 75 65 72 79 20 2a 2f 0a 20 20 51 75  he query */.  Qu
6db0: 65 72 79 54 65 72 6d 20 2a 70 54 65 72 6d 73 3b  eryTerm *pTerms;
6dc0: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20      /* Array of 
6dd0: 74 65 72 6d 73 2e 20 20 53 70 61 63 65 20 6f 62  terms.  Space ob
6de0: 74 61 69 6e 65 64 20 66 72 6f 6d 20 6d 61 6c 6c  tained from mall
6df0: 6f 63 28 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 65  oc() */.  int ne
6e00: 78 74 49 73 4f 72 3b 20 20 20 20 20 20 20 20 20  xtIsOr;         
6e10: 2f 2a 20 53 65 74 20 74 68 65 20 69 73 4f 72 20  /* Set the isOr 
6e20: 66 6c 61 67 20 6f 6e 20 74 68 65 20 6e 65 78 74  flag on the next
6e30: 20 69 6e 73 65 72 74 65 64 20 74 65 72 6d 20 2a   inserted term *
6e40: 2f 0a 20 20 69 6e 74 20 6e 65 78 74 43 6f 6c 75  /.  int nextColu
6e50: 6d 6e 3b 20 20 20 20 20 20 20 2f 2a 20 4e 65 78  mn;       /* Nex
6e60: 74 20 77 6f 72 64 20 70 61 72 73 65 64 20 6d 75  t word parsed mu
6e70: 73 74 20 62 65 20 69 6e 20 74 68 69 73 20 63 6f  st be in this co
6e80: 6c 75 6d 6e 20 2a 2f 0a 20 20 69 6e 74 20 64 66  lumn */.  int df
6e90: 6c 74 43 6f 6c 75 6d 6e 3b 20 20 20 20 20 20 20  ltColumn;       
6ea0: 2f 2a 20 54 68 65 20 64 65 66 61 75 6c 74 20 63  /* The default c
6eb0: 6f 6c 75 6d 6e 20 2a 2f 0a 7d 20 51 75 65 72 79  olumn */.} Query
6ec0: 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73  ;.../*.** An ins
6ed0: 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c  tance of the fol
6ee0: 6c 6f 77 69 6e 67 20 73 74 72 75 63 74 75 72 65  lowing structure
6ef0: 20 6b 65 65 70 73 20 74 72 61 63 6b 20 6f 66 20   keeps track of 
6f00: 67 65 6e 65 72 61 74 65 64 0a 2a 2a 20 6d 61 74  generated.** mat
6f10: 63 68 69 6e 67 2d 77 6f 72 64 20 6f 66 66 73 65  ching-word offse
6f20: 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 6e  t information an
6f30: 64 20 73 6e 69 70 70 65 74 73 2e 0a 2a 2f 0a 74  d snippets..*/.t
6f40: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 53 6e  ypedef struct Sn
6f50: 69 70 70 65 74 20 7b 0a 20 20 69 6e 74 20 6e 4d  ippet {.  int nM
6f60: 61 74 63 68 3b 20 20 20 20 20 2f 2a 20 54 6f 74  atch;     /* Tot
6f70: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 6d 61 74  al number of mat
6f80: 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 41  ches */.  int nA
6f90: 6c 6c 6f 63 3b 20 20 20 20 20 2f 2a 20 53 70 61  lloc;     /* Spa
6fa0: 63 65 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  ce allocated for
6fb0: 20 61 4d 61 74 63 68 5b 5d 20 2a 2f 0a 20 20 73   aMatch[] */.  s
6fc0: 74 72 75 63 74 20 73 6e 69 70 70 65 74 4d 61 74  truct snippetMat
6fd0: 63 68 20 7b 20 2f 2a 20 4f 6e 65 20 65 6e 74 72  ch { /* One entr
6fe0: 79 20 66 6f 72 20 65 61 63 68 20 6d 61 74 63 68  y for each match
6ff0: 69 6e 67 20 74 65 72 6d 20 2a 2f 0a 20 20 20 20  ing term */.    
7000: 63 68 61 72 20 73 6e 53 74 61 74 75 73 3b 20 20  char snStatus;  
7010: 20 20 20 20 20 2f 2a 20 53 74 61 74 75 73 20 66       /* Status f
7020: 6c 61 67 20 66 6f 72 20 75 73 65 20 77 68 69 6c  lag for use whil
7030: 65 20 63 6f 6e 73 74 72 75 63 74 69 6e 67 20 73  e constructing s
7040: 6e 69 70 70 65 74 73 20 2a 2f 0a 20 20 20 20 73  nippets */.    s
7050: 68 6f 72 74 20 69 6e 74 20 69 43 6f 6c 3b 20 20  hort int iCol;  
7060: 20 20 20 20 2f 2a 20 54 68 65 20 63 6f 6c 75 6d      /* The colum
7070: 6e 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  n that contains 
7080: 74 68 65 20 6d 61 74 63 68 20 2a 2f 0a 20 20 20  the match */.   
7090: 20 73 68 6f 72 74 20 69 6e 74 20 69 54 65 72 6d   short int iTerm
70a0: 3b 20 20 20 20 20 2f 2a 20 54 68 65 20 69 6e 64  ;     /* The ind
70b0: 65 78 20 69 6e 20 51 75 65 72 79 2e 70 54 65 72  ex in Query.pTer
70c0: 6d 73 5b 5d 20 6f 66 20 74 68 65 20 6d 61 74 63  ms[] of the matc
70d0: 68 69 6e 67 20 74 65 72 6d 20 2a 2f 0a 20 20 20  hing term */.   
70e0: 20 73 68 6f 72 74 20 69 6e 74 20 6e 42 79 74 65   short int nByte
70f0: 3b 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20  ;     /* Number 
7100: 6f 66 20 62 79 74 65 73 20 69 6e 20 74 68 65 20  of bytes in the 
7110: 74 65 72 6d 20 2a 2f 0a 20 20 20 20 69 6e 74 20  term */.    int 
7120: 69 53 74 61 72 74 3b 20 20 20 20 20 20 20 20 20  iStart;         
7130: 20 2f 2a 20 54 68 65 20 6f 66 66 73 65 74 20 74   /* The offset t
7140: 6f 20 74 68 65 20 66 69 72 73 74 20 63 68 61 72  o the first char
7150: 61 63 74 65 72 20 6f 66 20 74 68 65 20 74 65 72  acter of the ter
7160: 6d 20 2a 2f 0a 20 20 7d 20 2a 61 4d 61 74 63 68  m */.  } *aMatch
7170: 3b 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 73  ;      /* Points
7180: 20 74 6f 20 73 70 61 63 65 20 6f 62 74 61 69 6e   to space obtain
7190: 65 64 20 66 72 6f 6d 20 6d 61 6c 6c 6f 63 20 2a  ed from malloc *
71a0: 2f 0a 20 20 63 68 61 72 20 2a 7a 4f 66 66 73 65  /.  char *zOffse
71b0: 74 3b 20 20 2f 2a 20 54 65 78 74 20 72 65 6e 64  t;  /* Text rend
71c0: 65 72 69 6e 67 20 6f 66 20 61 4d 61 74 63 68 5b  ering of aMatch[
71d0: 5d 20 2a 2f 0a 20 20 69 6e 74 20 6e 4f 66 66 73  ] */.  int nOffs
71e0: 65 74 3b 20 20 20 20 2f 2a 20 73 74 72 6c 65 6e  et;    /* strlen
71f0: 28 7a 4f 66 66 73 65 74 29 20 2a 2f 0a 20 20 63  (zOffset) */.  c
7200: 68 61 72 20 2a 7a 53 6e 69 70 70 65 74 3b 20 2f  har *zSnippet; /
7210: 2a 20 53 6e 69 70 70 65 74 20 74 65 78 74 20 2a  * Snippet text *
7220: 2f 0a 20 20 69 6e 74 20 6e 53 6e 69 70 70 65 74  /.  int nSnippet
7230: 3b 20 20 20 2f 2a 20 73 74 72 6c 65 6e 28 7a 53  ;   /* strlen(zS
7240: 6e 69 70 70 65 74 29 20 2a 2f 0a 7d 20 53 6e 69  nippet) */.} Sni
7250: 70 70 65 74 3b 0a 0a 0a 74 79 70 65 64 65 66 20  ppet;...typedef 
7260: 65 6e 75 6d 20 51 75 65 72 79 54 79 70 65 20 7b  enum QueryType {
7270: 0a 20 20 51 55 45 52 59 5f 47 45 4e 45 52 49 43  .  QUERY_GENERIC
7280: 2c 20 20 20 2f 2a 20 74 61 62 6c 65 20 73 63 61  ,   /* table sca
7290: 6e 20 2a 2f 0a 20 20 51 55 45 52 59 5f 52 4f 57  n */.  QUERY_ROW
72a0: 49 44 2c 20 20 20 20 20 2f 2a 20 6c 6f 6f 6b 75  ID,     /* looku
72b0: 70 20 62 79 20 72 6f 77 69 64 20 2a 2f 0a 20 20  p by rowid */.  
72c0: 51 55 45 52 59 5f 46 55 4c 4c 54 45 58 54 20 20  QUERY_FULLTEXT  
72d0: 20 2f 2a 20 51 55 45 52 59 5f 46 55 4c 4c 54 45   /* QUERY_FULLTE
72e0: 58 54 20 2b 20 5b 69 5d 20 69 73 20 61 20 66 75  XT + [i] is a fu
72f0: 6c 6c 2d 74 65 78 74 20 73 65 61 72 63 68 20 66  ll-text search f
7300: 6f 72 20 63 6f 6c 75 6d 6e 20 69 2a 2f 0a 7d 20  or column i*/.} 
7310: 51 75 65 72 79 54 79 70 65 3b 0a 0a 2f 2a 20 54  QueryType;../* T
7320: 4f 44 4f 28 73 68 65 73 73 29 20 43 48 55 4e 4b  ODO(shess) CHUNK
7330: 5f 4d 41 58 20 63 6f 6e 74 72 6f 6c 73 20 68 6f  _MAX controls ho
7340: 77 20 6d 75 63 68 20 64 61 74 61 20 77 65 20 61  w much data we a
7350: 6c 6c 6f 77 20 69 6e 20 73 65 67 6d 65 6e 74 20  llow in segment 
7360: 30 0a 2a 2a 20 62 65 66 6f 72 65 20 77 65 20 73  0.** before we s
7370: 74 61 72 74 20 61 67 67 72 65 67 61 74 69 6e 67  tart aggregating
7380: 20 69 6e 74 6f 20 6c 61 72 67 65 72 20 73 65 67   into larger seg
7390: 6d 65 6e 74 73 2e 20 20 4c 6f 77 65 72 20 43 48  ments.  Lower CH
73a0: 55 4e 4b 5f 4d 41 58 0a 2a 2a 20 6d 65 61 6e 73  UNK_MAX.** means
73b0: 20 74 68 61 74 20 66 6f 72 20 61 20 67 69 76 65   that for a give
73c0: 6e 20 69 6e 70 75 74 20 77 65 20 68 61 76 65 20  n input we have 
73d0: 6d 6f 72 65 20 69 6e 64 69 76 69 64 75 61 6c 20  more individual 
73e0: 73 65 67 6d 65 6e 74 73 20 70 65 72 0a 2a 2a 20  segments per.** 
73f0: 74 65 72 6d 2c 20 77 68 69 63 68 20 6d 65 61 6e  term, which mean
7400: 73 20 6d 6f 72 65 20 72 6f 77 73 20 69 6e 20 74  s more rows in t
7410: 68 65 20 74 61 62 6c 65 20 61 6e 64 20 61 20 62  he table and a b
7420: 69 67 67 65 72 20 69 6e 64 65 78 20 28 64 75 65  igger index (due
7430: 20 74 6f 0a 2a 2a 20 62 6f 74 68 20 6d 6f 72 65   to.** both more
7440: 20 72 6f 77 73 20 61 6e 64 20 62 69 67 67 65 72   rows and bigger
7450: 20 72 6f 77 69 64 73 29 2e 20 20 42 75 74 20 69   rowids).  But i
7460: 74 20 61 6c 73 6f 20 72 65 64 75 63 65 73 20 74  t also reduces t
7470: 68 65 20 61 76 65 72 61 67 65 0a 2a 2a 20 63 6f  he average.** co
7480: 73 74 20 6f 66 20 61 64 64 69 6e 67 20 6e 65 77  st of adding new
7490: 20 65 6c 65 6d 65 6e 74 73 20 74 6f 20 74 68 65   elements to the
74a0: 20 73 65 67 6d 65 6e 74 20 30 20 64 6f 63 6c 69   segment 0 docli
74b0: 73 74 2c 20 61 6e 64 20 69 74 20 73 65 65 6d 73  st, and it seems
74c0: 0a 2a 2a 20 74 6f 20 72 65 64 75 63 65 20 74 68  .** to reduce th
74d0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  e number of page
74e0: 73 20 72 65 61 64 20 61 6e 64 20 77 72 69 74 74  s read and writt
74f0: 65 6e 20 64 75 72 69 6e 67 20 69 6e 73 65 72 74  en during insert
7500: 73 2e 20 20 32 35 36 0a 2a 2a 20 77 61 73 20 63  s.  256.** was c
7510: 68 6f 73 65 6e 20 62 79 20 6d 65 61 73 75 72 69  hosen by measuri
7520: 6e 67 20 69 6e 73 65 72 74 69 6f 6e 20 74 69 6d  ng insertion tim
7530: 65 73 20 66 6f 72 20 61 20 63 65 72 74 61 69 6e  es for a certain
7540: 20 69 6e 70 75 74 20 28 66 69 72 73 74 0a 2a 2a   input (first.**
7550: 20 31 30 6b 20 64 6f 63 75 6d 65 6e 74 73 20 6f   10k documents o
7560: 66 20 45 6e 72 6f 6e 20 63 6f 72 70 75 73 29 2c  f Enron corpus),
7570: 20 74 68 6f 75 67 68 20 69 6e 63 6c 75 64 69 6e   though includin
7580: 67 20 71 75 65 72 79 20 70 65 72 66 6f 72 6d 61  g query performa
7590: 6e 63 65 0a 2a 2a 20 69 6e 20 74 68 65 20 64 65  nce.** in the de
75a0: 63 69 73 69 6f 6e 20 6d 61 79 20 61 72 67 75 65  cision may argue
75b0: 20 66 6f 72 20 61 20 6c 61 72 67 65 72 20 76 61   for a larger va
75c0: 6c 75 65 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  lue..*/.#define 
75d0: 43 48 55 4e 4b 5f 4d 41 58 20 32 35 36 0a 0a 74  CHUNK_MAX 256..t
75e0: 79 70 65 64 65 66 20 65 6e 75 6d 20 66 75 6c 6c  ypedef enum full
75f0: 74 65 78 74 5f 73 74 61 74 65 6d 65 6e 74 20 7b  text_statement {
7600: 0a 20 20 43 4f 4e 54 45 4e 54 5f 49 4e 53 45 52  .  CONTENT_INSER
7610: 54 5f 53 54 4d 54 2c 0a 20 20 43 4f 4e 54 45 4e  T_STMT,.  CONTEN
7620: 54 5f 53 45 4c 45 43 54 5f 53 54 4d 54 2c 0a 20  T_SELECT_STMT,. 
7630: 20 43 4f 4e 54 45 4e 54 5f 55 50 44 41 54 45 5f   CONTENT_UPDATE_
7640: 53 54 4d 54 2c 0a 20 20 43 4f 4e 54 45 4e 54 5f  STMT,.  CONTENT_
7650: 44 45 4c 45 54 45 5f 53 54 4d 54 2c 0a 0a 20 20  DELETE_STMT,..  
7660: 54 45 52 4d 5f 53 45 4c 45 43 54 5f 53 54 4d 54  TERM_SELECT_STMT
7670: 2c 0a 20 20 54 45 52 4d 5f 53 45 4c 45 43 54 5f  ,.  TERM_SELECT_
7680: 41 4c 4c 5f 53 54 4d 54 2c 0a 20 20 54 45 52 4d  ALL_STMT,.  TERM
7690: 5f 49 4e 53 45 52 54 5f 53 54 4d 54 2c 0a 20 20  _INSERT_STMT,.  
76a0: 54 45 52 4d 5f 55 50 44 41 54 45 5f 53 54 4d 54  TERM_UPDATE_STMT
76b0: 2c 0a 20 20 54 45 52 4d 5f 44 45 4c 45 54 45 5f  ,.  TERM_DELETE_
76c0: 53 54 4d 54 2c 0a 0a 20 20 4d 41 58 5f 53 54 4d  STMT,..  MAX_STM
76d0: 54 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  T               
76e0: 20 20 20 20 20 20 2f 2a 20 41 6c 77 61 79 73 20        /* Always 
76f0: 61 74 20 65 6e 64 21 20 2a 2f 0a 7d 20 66 75 6c  at end! */.} ful
7700: 6c 74 65 78 74 5f 73 74 61 74 65 6d 65 6e 74 3b  ltext_statement;
7710: 0a 0a 2f 2a 20 54 68 65 73 65 20 6d 75 73 74 20  ../* These must 
7720: 65 78 61 63 74 6c 79 20 6d 61 74 63 68 20 74 68  exactly match th
7730: 65 20 65 6e 75 6d 20 61 62 6f 76 65 2e 20 2a 2f  e enum above. */
7740: 0a 2f 2a 20 54 4f 44 4f 28 61 64 61 6d 29 3a 20  ./* TODO(adam): 
7750: 49 73 20 74 68 65 72 65 20 73 6f 6d 65 20 72 69  Is there some ri
7760: 73 6b 20 74 68 61 74 20 61 20 73 74 61 74 65 6d  sk that a statem
7770: 65 6e 74 20 28 69 6e 20 70 61 72 74 69 63 75 6c  ent (in particul
7780: 61 72 2c 0a 2a 2a 20 70 54 65 72 6d 53 65 6c 65  ar,.** pTermSele
7790: 63 74 53 74 6d 74 29 20 77 69 6c 6c 20 62 65 20  ctStmt) will be 
77a0: 75 73 65 64 20 69 6e 20 74 77 6f 20 63 75 72 73  used in two curs
77b0: 6f 72 73 20 61 74 20 6f 6e 63 65 2c 20 65 2e 67  ors at once, e.g
77c0: 2e 20 20 69 66 20 61 0a 2a 2a 20 71 75 65 72 79  .  if a.** query
77d0: 20 6a 6f 69 6e 73 20 61 20 76 69 72 74 75 61 6c   joins a virtual
77e0: 20 74 61 62 6c 65 20 74 6f 20 69 74 73 65 6c 66   table to itself
77f0: 3f 20 20 49 66 20 73 6f 20 70 65 72 68 61 70 73  ?  If so perhaps
7800: 20 77 65 20 73 68 6f 75 6c 64 0a 2a 2a 20 6d 6f   we should.** mo
7810: 76 65 20 73 6f 6d 65 20 6f 66 20 74 68 65 73 65  ve some of these
7820: 20 74 6f 20 74 68 65 20 63 75 72 73 6f 72 20 6f   to the cursor o
7830: 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  bject..*/.static
7840: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e   const char *con
7850: 73 74 20 66 75 6c 6c 74 65 78 74 5f 7a 53 74 61  st fulltext_zSta
7860: 74 65 6d 65 6e 74 5b 4d 41 58 5f 53 54 4d 54 5d  tement[MAX_STMT]
7870: 20 3d 20 7b 0a 20 20 2f 2a 20 43 4f 4e 54 45 4e   = {.  /* CONTEN
7880: 54 5f 49 4e 53 45 52 54 20 2a 2f 20 4e 55 4c 4c  T_INSERT */ NULL
7890: 2c 20 20 2f 2a 20 67 65 6e 65 72 61 74 65 64 20  ,  /* generated 
78a0: 69 6e 20 63 6f 6e 74 65 6e 74 49 6e 73 65 72 74  in contentInsert
78b0: 53 74 61 74 65 6d 65 6e 74 28 29 20 2a 2f 0a 20  Statement() */. 
78c0: 20 2f 2a 20 43 4f 4e 54 45 4e 54 5f 53 45 4c 45   /* CONTENT_SELE
78d0: 43 54 20 2a 2f 20 22 73 65 6c 65 63 74 20 2a 20  CT */ "select * 
78e0: 66 72 6f 6d 20 25 5f 63 6f 6e 74 65 6e 74 20 77  from %_content w
78f0: 68 65 72 65 20 72 6f 77 69 64 20 3d 20 3f 22 2c  here rowid = ?",
7900: 0a 20 20 2f 2a 20 43 4f 4e 54 45 4e 54 5f 55 50  .  /* CONTENT_UP
7910: 44 41 54 45 20 2a 2f 20 4e 55 4c 4c 2c 20 20 2f  DATE */ NULL,  /
7920: 2a 20 67 65 6e 65 72 61 74 65 64 20 69 6e 20 63  * generated in c
7930: 6f 6e 74 65 6e 74 55 70 64 61 74 65 53 74 61 74  ontentUpdateStat
7940: 65 6d 65 6e 74 28 29 20 2a 2f 0a 20 20 2f 2a 20  ement() */.  /* 
7950: 43 4f 4e 54 45 4e 54 5f 44 45 4c 45 54 45 20 2a  CONTENT_DELETE *
7960: 2f 20 22 64 65 6c 65 74 65 20 66 72 6f 6d 20 25  / "delete from %
7970: 5f 63 6f 6e 74 65 6e 74 20 77 68 65 72 65 20 72  _content where r
7980: 6f 77 69 64 20 3d 20 3f 22 2c 0a 0a 20 20 2f 2a  owid = ?",..  /*
7990: 20 54 45 52 4d 5f 53 45 4c 45 43 54 20 2a 2f 0a   TERM_SELECT */.
79a0: 20 20 22 73 65 6c 65 63 74 20 72 6f 77 69 64 2c    "select rowid,
79b0: 20 64 6f 63 6c 69 73 74 20 66 72 6f 6d 20 25 5f   doclist from %_
79c0: 74 65 72 6d 20 77 68 65 72 65 20 74 65 72 6d 20  term where term 
79d0: 3d 20 3f 20 61 6e 64 20 73 65 67 6d 65 6e 74 20  = ? and segment 
79e0: 3d 20 3f 22 2c 0a 20 20 2f 2a 20 54 45 52 4d 5f  = ?",.  /* TERM_
79f0: 53 45 4c 45 43 54 5f 41 4c 4c 20 2a 2f 0a 20 20  SELECT_ALL */.  
7a00: 22 73 65 6c 65 63 74 20 64 6f 63 6c 69 73 74 20  "select doclist 
7a10: 66 72 6f 6d 20 25 5f 74 65 72 6d 20 77 68 65 72  from %_term wher
7a20: 65 20 74 65 72 6d 20 3d 20 3f 20 6f 72 64 65 72  e term = ? order
7a30: 20 62 79 20 73 65 67 6d 65 6e 74 22 2c 0a 20 20   by segment",.  
7a40: 2f 2a 20 54 45 52 4d 5f 49 4e 53 45 52 54 20 2a  /* TERM_INSERT *
7a50: 2f 0a 20 20 22 69 6e 73 65 72 74 20 69 6e 74 6f  /.  "insert into
7a60: 20 25 5f 74 65 72 6d 20 28 72 6f 77 69 64 2c 20   %_term (rowid, 
7a70: 74 65 72 6d 2c 20 73 65 67 6d 65 6e 74 2c 20 64  term, segment, d
7a80: 6f 63 6c 69 73 74 29 20 76 61 6c 75 65 73 20 28  oclist) values (
7a90: 3f 2c 20 3f 2c 20 3f 2c 20 3f 29 22 2c 0a 20 20  ?, ?, ?, ?)",.  
7aa0: 2f 2a 20 54 45 52 4d 5f 55 50 44 41 54 45 20 2a  /* TERM_UPDATE *
7ab0: 2f 20 22 75 70 64 61 74 65 20 25 5f 74 65 72 6d  / "update %_term
7ac0: 20 73 65 74 20 64 6f 63 6c 69 73 74 20 3d 20 3f   set doclist = ?
7ad0: 20 77 68 65 72 65 20 72 6f 77 69 64 20 3d 20 3f   where rowid = ?
7ae0: 22 2c 0a 20 20 2f 2a 20 54 45 52 4d 5f 44 45 4c  ",.  /* TERM_DEL
7af0: 45 54 45 20 2a 2f 20 22 64 65 6c 65 74 65 20 66  ETE */ "delete f
7b00: 72 6f 6d 20 25 5f 74 65 72 6d 20 77 68 65 72 65  rom %_term where
7b10: 20 72 6f 77 69 64 20 3d 20 3f 22 2c 0a 7d 3b 0a   rowid = ?",.};.
7b20: 0a 2f 2a 0a 2a 2a 20 41 20 63 6f 6e 6e 65 63 74  ./*.** A connect
7b30: 69 6f 6e 20 74 6f 20 61 20 66 75 6c 6c 74 65 78  ion to a fulltex
7b40: 74 20 69 6e 64 65 78 20 69 73 20 61 6e 20 69 6e  t index is an in
7b50: 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f  stance of the fo
7b60: 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 73 74 72 75 63  llowing.** struc
7b70: 74 75 72 65 2e 20 20 54 68 65 20 78 43 72 65 61  ture.  The xCrea
7b80: 74 65 20 61 6e 64 20 78 43 6f 6e 6e 65 63 74 20  te and xConnect 
7b90: 6d 65 74 68 6f 64 73 20 63 72 65 61 74 65 20 61  methods create a
7ba0: 6e 20 69 6e 73 74 61 6e 63 65 0a 2a 2a 20 6f 66  n instance.** of
7bb0: 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65 20   this structure 
7bc0: 61 6e 64 20 78 44 65 73 74 72 6f 79 20 61 6e 64  and xDestroy and
7bd0: 20 78 44 69 73 63 6f 6e 6e 65 63 74 20 66 72 65   xDisconnect fre
7be0: 65 20 74 68 61 74 20 69 6e 73 74 61 6e 63 65 2e  e that instance.
7bf0: 0a 2a 2a 20 41 6c 6c 20 6f 74 68 65 72 20 6d 65  .** All other me
7c00: 74 68 6f 64 73 20 72 65 63 65 69 76 65 20 61 20  thods receive a 
7c10: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 73  pointer to the s
7c20: 74 72 75 63 74 75 72 65 20 61 73 20 6f 6e 65 20  tructure as one 
7c30: 6f 66 20 74 68 65 69 72 0a 2a 2a 20 61 72 67 75  of their.** argu
7c40: 6d 65 6e 74 73 2e 0a 2a 2f 0a 73 74 72 75 63 74  ments..*/.struct
7c50: 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 7b   fulltext_vtab {
7c60: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
7c70: 62 61 73 65 3b 20 20 20 20 20 20 20 20 20 20 20  base;           
7c80: 20 20 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73      /* Base clas
7c90: 73 20 75 73 65 64 20 62 79 20 53 51 4c 69 74 65  s used by SQLite
7ca0: 20 63 6f 72 65 20 2a 2f 0a 20 20 73 71 6c 69 74   core */.  sqlit
7cb0: 65 33 20 2a 64 62 3b 20 20 20 20 20 20 20 20 20  e3 *db;         
7cc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
7cd0: 68 65 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e  he database conn
7ce0: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73  ection */.  cons
7cf0: 74 20 63 68 61 72 20 2a 7a 44 62 3b 20 20 20 20  t char *zDb;    
7d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7d10: 6c 6f 67 69 63 61 6c 20 64 61 74 61 62 61 73 65  logical database
7d20: 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74   name */.  const
7d30: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20   char *zName;   
7d40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 76              /* v
7d50: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6e 61 6d  irtual table nam
7d60: 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 75  e */.  int nColu
7d70: 6d 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  mn;             
7d80: 20 20 20 20 20 20 20 20 2f 2a 20 6e 75 6d 62 65          /* numbe
7d90: 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
7da0: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 2a 2f  virtual table */
7db0: 0a 20 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6c 75  .  char **azColu
7dc0: 6d 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  mn;             
7dd0: 20 20 20 20 2f 2a 20 63 6f 6c 75 6d 6e 20 6e 61      /* column na
7de0: 6d 65 73 2e 20 20 6d 61 6c 6c 6f 63 65 64 20 2a  mes.  malloced *
7df0: 2f 0a 20 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6e  /.  char **azCon
7e00: 74 65 6e 74 43 6f 6c 75 6d 6e 3b 20 20 20 20 20  tentColumn;     
7e10: 20 20 20 20 20 2f 2a 20 63 6f 6c 75 6d 6e 20 6e       /* column n
7e20: 61 6d 65 73 20 69 6e 20 63 6f 6e 74 65 6e 74 20  ames in content 
7e30: 74 61 62 6c 65 3b 20 6d 61 6c 6c 6f 63 65 64 20  table; malloced 
7e40: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b  */.  sqlite3_tok
7e50: 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a  enizer *pTokeniz
7e60: 65 72 3b 20 20 20 2f 2a 20 74 6f 6b 65 6e 69 7a  er;   /* tokeniz
7e70: 65 72 20 66 6f 72 20 69 6e 73 65 72 74 73 20 61  er for inserts a
7e80: 6e 64 20 71 75 65 72 69 65 73 20 2a 2f 0a 0a 20  nd queries */.. 
7e90: 20 2f 2a 20 50 72 65 63 6f 6d 70 69 6c 65 64 20   /* Precompiled 
7ea0: 73 74 61 74 65 6d 65 6e 74 73 20 77 68 69 63 68  statements which
7eb0: 20 77 65 20 6b 65 65 70 20 61 73 20 6c 6f 6e 67   we keep as long
7ec0: 20 61 73 20 74 68 65 20 74 61 62 6c 65 20 69 73   as the table is
7ed0: 0a 20 20 2a 2a 20 6f 70 65 6e 2e 0a 20 20 2a 2f  .  ** open..  */
7ee0: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
7ef0: 2a 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d  *pFulltextStatem
7f00: 65 6e 74 73 5b 4d 41 58 5f 53 54 4d 54 5d 3b 0a  ents[MAX_STMT];.
7f10: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 57 68 65 6e 20 74  };../*.** When t
7f20: 68 65 20 63 6f 72 65 20 77 61 6e 74 73 20 74 6f  he core wants to
7f30: 20 64 6f 20 61 20 71 75 65 72 79 2c 20 69 74 20   do a query, it 
7f40: 63 72 65 61 74 65 20 61 20 63 75 72 73 6f 72 20  create a cursor 
7f50: 75 73 69 6e 67 20 61 0a 2a 2a 20 63 61 6c 6c 20  using a.** call 
7f60: 74 6f 20 78 4f 70 65 6e 2e 20 20 54 68 69 73 20  to xOpen.  This 
7f70: 73 74 72 75 63 74 75 72 65 20 69 73 20 61 6e 20  structure is an 
7f80: 69 6e 73 74 61 6e 63 65 20 6f 66 20 61 20 63 75  instance of a cu
7f90: 72 73 6f 72 2e 20 20 49 74 0a 2a 2a 20 69 73 20  rsor.  It.** is 
7fa0: 64 65 73 74 72 6f 79 65 64 20 62 79 20 78 43 6c  destroyed by xCl
7fb0: 6f 73 65 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20  ose..*/.typedef 
7fc0: 73 74 72 75 63 74 20 66 75 6c 6c 74 65 78 74 5f  struct fulltext_
7fd0: 63 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c 69 74  cursor {.  sqlit
7fe0: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 62  e3_vtab_cursor b
7ff0: 61 73 65 3b 20 20 20 20 20 20 20 20 2f 2a 20 42  ase;        /* B
8000: 61 73 65 20 63 6c 61 73 73 20 75 73 65 64 20 62  ase class used b
8010: 79 20 53 51 4c 69 74 65 20 63 6f 72 65 20 2a 2f  y SQLite core */
8020: 0a 20 20 51 75 65 72 79 54 79 70 65 20 69 43 75  .  QueryType iCu
8030: 72 73 6f 72 54 79 70 65 3b 20 20 20 20 20 20 20  rsorType;       
8040: 20 20 20 20 2f 2a 20 43 6f 70 79 20 6f 66 20 73      /* Copy of s
8050: 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66  qlite3_index_inf
8060: 6f 2e 69 64 78 4e 75 6d 20 2a 2f 0a 20 20 73 71  o.idxNum */.  sq
8070: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
8080: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  t;             /
8090: 2a 20 50 72 65 70 61 72 65 64 20 73 74 61 74 65  * Prepared state
80a0: 6d 65 6e 74 20 69 6e 20 75 73 65 20 62 79 20 74  ment in use by t
80b0: 68 65 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 69  he cursor */.  i
80c0: 6e 74 20 65 6f 66 3b 20 20 20 20 20 20 20 20 20  nt eof;         
80d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
80e0: 2f 2a 20 54 72 75 65 20 69 66 20 61 74 20 45 6e  /* True if at En
80f0: 64 20 4f 66 20 52 65 73 75 6c 74 73 20 2a 2f 0a  d Of Results */.
8100: 20 20 51 75 65 72 79 20 71 3b 20 20 20 20 20 20    Query q;      
8110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8120: 20 20 20 2f 2a 20 50 61 72 73 65 64 20 71 75 65     /* Parsed que
8130: 72 79 20 73 74 72 69 6e 67 20 2a 2f 0a 20 20 53  ry string */.  S
8140: 6e 69 70 70 65 74 20 73 6e 69 70 70 65 74 3b 20  nippet snippet; 
8150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8160: 2f 2a 20 43 61 63 68 65 64 20 73 6e 69 70 70 65  /* Cached snippe
8170: 74 20 66 6f 72 20 74 68 65 20 63 75 72 72 65 6e  t for the curren
8180: 74 20 72 6f 77 20 2a 2f 0a 20 20 69 6e 74 20 69  t row */.  int i
8190: 43 6f 6c 75 6d 6e 3b 20 20 20 20 20 20 20 20 20  Column;         
81a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
81b0: 6f 6c 75 6d 6e 20 62 65 69 6e 67 20 73 65 61 72  olumn being sear
81c0: 63 68 65 64 20 2a 2f 0a 20 20 44 6f 63 4c 69 73  ched */.  DocLis
81d0: 74 52 65 61 64 65 72 20 72 65 73 75 6c 74 3b 20  tReader result; 
81e0: 20 2f 2a 20 75 73 65 64 20 77 68 65 6e 20 69 43   /* used when iC
81f0: 75 72 73 6f 72 54 79 70 65 20 3d 3d 20 51 55 45  ursorType == QUE
8200: 52 59 5f 46 55 4c 4c 54 45 58 54 20 2a 2f 20 0a  RY_FULLTEXT */ .
8210: 7d 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f  } fulltext_curso
8220: 72 3b 0a 0a 73 74 61 74 69 63 20 73 74 72 75 63  r;..static struc
8230: 74 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20  t fulltext_vtab 
8240: 2a 63 75 72 73 6f 72 5f 76 74 61 62 28 66 75 6c  *cursor_vtab(ful
8250: 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 63 29  ltext_cursor *c)
8260: 7b 0a 20 20 72 65 74 75 72 6e 20 28 66 75 6c 6c  {.  return (full
8270: 74 65 78 74 5f 76 74 61 62 20 2a 29 20 63 2d 3e  text_vtab *) c->
8280: 62 61 73 65 2e 70 56 74 61 62 3b 0a 7d 0a 0a 73  base.pVtab;.}..s
8290: 74 61 74 69 63 20 63 6f 6e 73 74 20 73 71 6c 69  tatic const sqli
82a0: 74 65 33 5f 6d 6f 64 75 6c 65 20 66 75 6c 6c 74  te3_module fullt
82b0: 65 78 74 4d 6f 64 75 6c 65 3b 20 20 20 2f 2a 20  extModule;   /* 
82c0: 66 6f 72 77 61 72 64 20 64 65 63 6c 61 72 61 74  forward declarat
82d0: 69 6f 6e 20 2a 2f 0a 0a 2f 2a 20 41 70 70 65 6e  ion */../* Appen
82e0: 64 20 61 20 6c 69 73 74 20 6f 66 20 73 74 72 69  d a list of stri
82f0: 6e 67 73 20 73 65 70 61 72 61 74 65 64 20 62 79  ngs separated by
8300: 20 63 6f 6d 6d 61 73 20 74 6f 20 61 20 53 74 72   commas to a Str
8310: 69 6e 67 42 75 66 66 65 72 2e 20 2a 2f 0a 73 74  ingBuffer. */.st
8320: 61 74 69 63 20 76 6f 69 64 20 61 70 70 65 6e 64  atic void append
8330: 4c 69 73 74 28 53 74 72 69 6e 67 42 75 66 66 65  List(StringBuffe
8340: 72 20 2a 73 62 2c 20 69 6e 74 20 6e 53 74 72 69  r *sb, int nStri
8350: 6e 67 2c 20 63 68 61 72 20 2a 2a 61 7a 53 74 72  ng, char **azStr
8360: 69 6e 67 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  ing){.  int i;. 
8370: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 53 74 72   for(i=0; i<nStr
8380: 69 6e 67 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 69  ing; ++i){.    i
8390: 66 28 20 69 3e 30 20 29 20 61 70 70 65 6e 64 28  f( i>0 ) append(
83a0: 73 62 2c 20 22 2c 20 22 29 3b 0a 20 20 20 20 61  sb, ", ");.    a
83b0: 70 70 65 6e 64 28 73 62 2c 20 61 7a 53 74 72 69  ppend(sb, azStri
83c0: 6e 67 5b 69 5d 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  ng[i]);.  }.}../
83d0: 2a 20 52 65 74 75 72 6e 20 61 20 64 79 6e 61 6d  * Return a dynam
83e0: 69 63 61 6c 6c 79 20 67 65 6e 65 72 61 74 65 64  ically generated
83f0: 20 73 74 61 74 65 6d 65 6e 74 20 6f 66 20 74 68   statement of th
8400: 65 20 66 6f 72 6d 0a 20 2a 20 20 20 69 6e 73 65  e form. *   inse
8410: 72 74 20 69 6e 74 6f 20 25 5f 63 6f 6e 74 65 6e  rt into %_conten
8420: 74 20 28 72 6f 77 69 64 2c 20 2e 2e 2e 29 20 76  t (rowid, ...) v
8430: 61 6c 75 65 73 20 28 3f 2c 20 2e 2e 2e 29 0a 20  alues (?, ...). 
8440: 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20  */.static const 
8450: 63 68 61 72 20 2a 63 6f 6e 74 65 6e 74 49 6e 73  char *contentIns
8460: 65 72 74 53 74 61 74 65 6d 65 6e 74 28 66 75 6c  ertStatement(ful
8470: 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 29 7b 0a  ltext_vtab *v){.
8480: 20 20 53 74 72 69 6e 67 42 75 66 66 65 72 20 73    StringBuffer s
8490: 62 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69  b;.  int i;..  i
84a0: 6e 69 74 53 74 72 69 6e 67 42 75 66 66 65 72 28  nitStringBuffer(
84b0: 26 73 62 29 3b 0a 20 20 61 70 70 65 6e 64 28 26  &sb);.  append(&
84c0: 73 62 2c 20 22 69 6e 73 65 72 74 20 69 6e 74 6f  sb, "insert into
84d0: 20 25 5f 63 6f 6e 74 65 6e 74 20 28 72 6f 77 69   %_content (rowi
84e0: 64 2c 20 22 29 3b 0a 20 20 61 70 70 65 6e 64 4c  d, ");.  appendL
84f0: 69 73 74 28 26 73 62 2c 20 76 2d 3e 6e 43 6f 6c  ist(&sb, v->nCol
8500: 75 6d 6e 2c 20 76 2d 3e 61 7a 43 6f 6e 74 65 6e  umn, v->azConten
8510: 74 43 6f 6c 75 6d 6e 29 3b 0a 20 20 61 70 70 65  tColumn);.  appe
8520: 6e 64 28 26 73 62 2c 20 22 29 20 76 61 6c 75 65  nd(&sb, ") value
8530: 73 20 28 3f 22 29 3b 0a 20 20 66 6f 72 28 69 3d  s (?");.  for(i=
8540: 30 3b 20 69 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 3b  0; i<v->nColumn;
8550: 20 2b 2b 69 29 0a 20 20 20 20 61 70 70 65 6e 64   ++i).    append
8560: 28 26 73 62 2c 20 22 2c 20 3f 22 29 3b 0a 20 20  (&sb, ", ?");.  
8570: 61 70 70 65 6e 64 28 26 73 62 2c 20 22 29 22 29  append(&sb, ")")
8580: 3b 0a 20 20 72 65 74 75 72 6e 20 73 62 2e 73 3b  ;.  return sb.s;
8590: 0a 7d 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 61 20  .}../* Return a 
85a0: 64 79 6e 61 6d 69 63 61 6c 6c 79 20 67 65 6e 65  dynamically gene
85b0: 72 61 74 65 64 20 73 74 61 74 65 6d 65 6e 74 20  rated statement 
85c0: 6f 66 20 74 68 65 20 66 6f 72 6d 0a 20 2a 20 20  of the form. *  
85d0: 20 75 70 64 61 74 65 20 25 5f 63 6f 6e 74 65 6e   update %_conten
85e0: 74 20 73 65 74 20 5b 63 6f 6c 5f 30 5d 20 3d 20  t set [col_0] = 
85f0: 3f 2c 20 5b 63 6f 6c 5f 31 5d 20 3d 20 3f 2c 20  ?, [col_1] = ?, 
8600: 2e 2e 2e 0a 20 2a 20 20 20 20 20 20 20 20 20 20  .... *          
8610: 20 20 20 20 20 20 20 20 20 20 77 68 65 72 65 20            where 
8620: 72 6f 77 69 64 20 3d 20 3f 0a 20 2a 2f 0a 73 74  rowid = ?. */.st
8630: 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20  atic const char 
8640: 2a 63 6f 6e 74 65 6e 74 55 70 64 61 74 65 53 74  *contentUpdateSt
8650: 61 74 65 6d 65 6e 74 28 66 75 6c 6c 74 65 78 74  atement(fulltext
8660: 5f 76 74 61 62 20 2a 76 29 7b 0a 20 20 53 74 72  _vtab *v){.  Str
8670: 69 6e 67 42 75 66 66 65 72 20 73 62 3b 0a 20 20  ingBuffer sb;.  
8680: 69 6e 74 20 69 3b 0a 0a 20 20 69 6e 69 74 53 74  int i;..  initSt
8690: 72 69 6e 67 42 75 66 66 65 72 28 26 73 62 29 3b  ringBuffer(&sb);
86a0: 0a 20 20 61 70 70 65 6e 64 28 26 73 62 2c 20 22  .  append(&sb, "
86b0: 75 70 64 61 74 65 20 25 5f 63 6f 6e 74 65 6e 74  update %_content
86c0: 20 73 65 74 20 22 29 3b 0a 20 20 66 6f 72 28 69   set ");.  for(i
86d0: 3d 30 3b 20 69 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e  =0; i<v->nColumn
86e0: 3b 20 2b 2b 69 29 20 7b 0a 20 20 20 20 69 66 28  ; ++i) {.    if(
86f0: 20 69 3e 30 20 29 7b 0a 20 20 20 20 20 20 61 70   i>0 ){.      ap
8700: 70 65 6e 64 28 26 73 62 2c 20 22 2c 20 22 29 3b  pend(&sb, ", ");
8710: 0a 20 20 20 20 7d 0a 20 20 20 20 61 70 70 65 6e  .    }.    appen
8720: 64 28 26 73 62 2c 20 76 2d 3e 61 7a 43 6f 6e 74  d(&sb, v->azCont
8730: 65 6e 74 43 6f 6c 75 6d 6e 5b 69 5d 29 3b 0a 20  entColumn[i]);. 
8740: 20 20 20 61 70 70 65 6e 64 28 26 73 62 2c 20 22     append(&sb, "
8750: 20 3d 20 3f 22 29 3b 0a 20 20 7d 0a 20 20 61 70   = ?");.  }.  ap
8760: 70 65 6e 64 28 26 73 62 2c 20 22 20 77 68 65 72  pend(&sb, " wher
8770: 65 20 72 6f 77 69 64 20 3d 20 3f 22 29 3b 0a 20  e rowid = ?");. 
8780: 20 72 65 74 75 72 6e 20 73 62 2e 73 3b 0a 7d 0a   return sb.s;.}.
8790: 0a 2f 2a 20 50 75 74 73 20 61 20 66 72 65 73 68  ./* Puts a fresh
87a0: 6c 79 2d 70 72 65 70 61 72 65 64 20 73 74 61 74  ly-prepared stat
87b0: 65 6d 65 6e 74 20 64 65 74 65 72 6d 69 6e 65 64  ement determined
87c0: 20 62 79 20 69 53 74 6d 74 20 69 6e 20 2a 70 70   by iStmt in *pp
87d0: 53 74 6d 74 2e 0a 2a 2a 20 49 66 20 74 68 65 20  Stmt..** If the 
87e0: 69 6e 64 69 63 61 74 65 64 20 73 74 61 74 65 6d  indicated statem
87f0: 65 6e 74 20 68 61 73 20 6e 65 76 65 72 20 62 65  ent has never be
8800: 65 6e 20 70 72 65 70 61 72 65 64 2c 20 69 74 20  en prepared, it 
8810: 69 73 20 70 72 65 70 61 72 65 64 0a 2a 2a 20 61  is prepared.** a
8820: 6e 64 20 63 61 63 68 65 64 2c 20 6f 74 68 65 72  nd cached, other
8830: 77 69 73 65 20 74 68 65 20 63 61 63 68 65 64 20  wise the cached 
8840: 76 65 72 73 69 6f 6e 20 69 73 20 72 65 73 65 74  version is reset
8850: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
8860: 73 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e  sql_get_statemen
8870: 74 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20  t(fulltext_vtab 
8880: 2a 76 2c 20 66 75 6c 6c 74 65 78 74 5f 73 74 61  *v, fulltext_sta
8890: 74 65 6d 65 6e 74 20 69 53 74 6d 74 2c 0a 20 20  tement iStmt,.  
88a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
88b0: 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
88c0: 65 33 5f 73 74 6d 74 20 2a 2a 70 70 53 74 6d 74  e3_stmt **ppStmt
88d0: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69 53 74  ){.  assert( iSt
88e0: 6d 74 3c 4d 41 58 5f 53 54 4d 54 20 29 3b 0a 20  mt<MAX_STMT );. 
88f0: 20 69 66 28 20 76 2d 3e 70 46 75 6c 6c 74 65 78   if( v->pFulltex
8900: 74 53 74 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d  tStatements[iStm
8910: 74 5d 3d 3d 4e 55 4c 4c 20 29 7b 0a 20 20 20 20  t]==NULL ){.    
8920: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 6d  const char *zStm
8930: 74 3b 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a 20  t;.    int rc;. 
8940: 20 20 20 73 77 69 74 63 68 28 20 69 53 74 6d 74     switch( iStmt
8950: 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65 20 43   ){.      case C
8960: 4f 4e 54 45 4e 54 5f 49 4e 53 45 52 54 5f 53 54  ONTENT_INSERT_ST
8970: 4d 54 3a 0a 20 20 20 20 20 20 20 20 7a 53 74 6d  MT:.        zStm
8980: 74 20 3d 20 63 6f 6e 74 65 6e 74 49 6e 73 65 72  t = contentInser
8990: 74 53 74 61 74 65 6d 65 6e 74 28 76 29 3b 20 62  tStatement(v); b
89a0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65  reak;.      case
89b0: 20 43 4f 4e 54 45 4e 54 5f 55 50 44 41 54 45 5f   CONTENT_UPDATE_
89c0: 53 54 4d 54 3a 0a 20 20 20 20 20 20 20 20 7a 53  STMT:.        zS
89d0: 74 6d 74 20 3d 20 63 6f 6e 74 65 6e 74 55 70 64  tmt = contentUpd
89e0: 61 74 65 53 74 61 74 65 6d 65 6e 74 28 76 29 3b  ateStatement(v);
89f0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 64 65   break;.      de
8a00: 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20 7a  fault:.        z
8a10: 53 74 6d 74 20 3d 20 66 75 6c 6c 74 65 78 74 5f  Stmt = fulltext_
8a20: 7a 53 74 61 74 65 6d 65 6e 74 5b 69 53 74 6d 74  zStatement[iStmt
8a30: 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63 20  ];.    }.    rc 
8a40: 3d 20 73 71 6c 5f 70 72 65 70 61 72 65 28 76 2d  = sql_prepare(v-
8a50: 3e 64 62 2c 20 76 2d 3e 7a 44 62 2c 20 76 2d 3e  >db, v->zDb, v->
8a60: 7a 4e 61 6d 65 2c 20 26 76 2d 3e 70 46 75 6c 6c  zName, &v->pFull
8a70: 74 65 78 74 53 74 61 74 65 6d 65 6e 74 73 5b 69  textStatements[i
8a80: 53 74 6d 74 5d 2c 0a 20 20 20 20 20 20 20 20 20  Stmt],.         
8a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8aa0: 7a 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20  zStmt);.    if( 
8ab0: 7a 53 74 6d 74 20 21 3d 20 66 75 6c 6c 74 65 78  zStmt != fulltex
8ac0: 74 5f 7a 53 74 61 74 65 6d 65 6e 74 5b 69 53 74  t_zStatement[iSt
8ad0: 6d 74 5d 29 20 66 72 65 65 28 28 76 6f 69 64 20  mt]) free((void 
8ae0: 2a 29 20 7a 53 74 6d 74 29 3b 0a 20 20 20 20 69  *) zStmt);.    i
8af0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
8b00: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
8b10: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 69 6e 74  } else {.    int
8b20: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65   rc = sqlite3_re
8b30: 73 65 74 28 76 2d 3e 70 46 75 6c 6c 74 65 78 74  set(v->pFulltext
8b40: 53 74 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74  Statements[iStmt
8b50: 5d 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  ]);.    if( rc!=
8b60: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
8b70: 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2a 70  rn rc;.  }..  *p
8b80: 70 53 74 6d 74 20 3d 20 76 2d 3e 70 46 75 6c 6c  pStmt = v->pFull
8b90: 74 65 78 74 53 74 61 74 65 6d 65 6e 74 73 5b 69  textStatements[i
8ba0: 53 74 6d 74 5d 3b 0a 20 20 72 65 74 75 72 6e 20  Stmt];.  return 
8bb0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
8bc0: 20 53 74 65 70 20 74 68 65 20 69 6e 64 69 63 61   Step the indica
8bd0: 74 65 64 20 73 74 61 74 65 6d 65 6e 74 2c 20 68  ted statement, h
8be0: 61 6e 64 6c 69 6e 67 20 65 72 72 6f 72 73 20 53  andling errors S
8bf0: 51 4c 49 54 45 5f 42 55 53 59 20 28 62 79 0a 2a  QLITE_BUSY (by.*
8c00: 2a 20 72 65 74 72 79 69 6e 67 29 20 61 6e 64 20  * retrying) and 
8c10: 53 51 4c 49 54 45 5f 53 43 48 45 4d 41 20 28 62  SQLITE_SCHEMA (b
8c20: 79 20 72 65 2d 70 72 65 70 61 72 69 6e 67 20 61  y re-preparing a
8c30: 6e 64 20 74 72 61 6e 73 66 65 72 72 69 6e 67 0a  nd transferring.
8c40: 2a 2a 20 62 69 6e 64 69 6e 67 73 20 74 6f 20 74  ** bindings to t
8c50: 68 65 20 6e 65 77 20 73 74 61 74 65 6d 65 6e 74  he new statement
8c60: 29 2e 0a 2a 2a 20 54 4f 44 4f 28 61 64 61 6d 29  )..** TODO(adam)
8c70: 3a 20 57 65 20 73 68 6f 75 6c 64 20 65 78 74 65  : We should exte
8c80: 6e 64 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  nd this function
8c90: 20 73 6f 20 74 68 61 74 20 69 74 20 63 61 6e 20   so that it can 
8ca0: 77 6f 72 6b 20 77 69 74 68 0a 2a 2a 20 73 74 61  work with.** sta
8cb0: 74 65 6d 65 6e 74 73 20 64 65 63 6c 61 72 65 64  tements declared
8cc0: 20 6c 6f 63 61 6c 6c 79 2c 20 6e 6f 74 20 6f 6e   locally, not on
8cd0: 6c 79 20 67 6c 6f 62 61 6c 6c 79 20 63 61 63 68  ly globally cach
8ce0: 65 64 20 73 74 61 74 65 6d 65 6e 74 73 2e 0a 2a  ed statements..*
8cf0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 71 6c  /.static int sql
8d00: 5f 73 74 65 70 5f 73 74 61 74 65 6d 65 6e 74 28  _step_statement(
8d10: 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
8d20: 2c 20 66 75 6c 6c 74 65 78 74 5f 73 74 61 74 65  , fulltext_state
8d30: 6d 65 6e 74 20 69 53 74 6d 74 2c 0a 20 20 20 20  ment iStmt,.    
8d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8d50: 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
8d60: 33 5f 73 74 6d 74 20 2a 2a 70 70 53 74 6d 74 29  3_stmt **ppStmt)
8d70: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71  {.  int rc;.  sq
8d80: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 20 3d 20  lite3_stmt *s = 
8d90: 2a 70 70 53 74 6d 74 3b 0a 20 20 61 73 73 65 72  *ppStmt;.  asser
8da0: 74 28 20 69 53 74 6d 74 3c 4d 41 58 5f 53 54 4d  t( iStmt<MAX_STM
8db0: 54 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 73  T );.  assert( s
8dc0: 3d 3d 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74  ==v->pFulltextSt
8dd0: 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 20  atements[iStmt] 
8de0: 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 28 72 63  );..  while( (rc
8df0: 3d 73 71 6c 69 74 65 33 5f 73 74 65 70 28 73 29  =sqlite3_step(s)
8e00: 29 21 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 26  )!=SQLITE_DONE &
8e10: 26 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57  & rc!=SQLITE_ROW
8e20: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
8e30: 73 74 6d 74 20 2a 70 4e 65 77 53 74 6d 74 3b 0a  stmt *pNewStmt;.
8e40: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
8e50: 49 54 45 5f 42 55 53 59 20 29 20 63 6f 6e 74 69  ITE_BUSY ) conti
8e60: 6e 75 65 3b 0a 20 20 20 20 69 66 28 20 72 63 21  nue;.    if( rc!
8e70: 3d 53 51 4c 49 54 45 5f 45 52 52 4f 52 20 29 20  =SQLITE_ERROR ) 
8e80: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20  return rc;..    
8e90: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73  rc = sqlite3_res
8ea0: 65 74 28 73 29 3b 0a 20 20 20 20 69 66 28 20 72  et(s);.    if( r
8eb0: 63 21 3d 53 51 4c 49 54 45 5f 53 43 48 45 4d 41  c!=SQLITE_SCHEMA
8ec0: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
8ed0: 5f 45 52 52 4f 52 3b 0a 0a 20 20 20 20 76 2d 3e  _ERROR;..    v->
8ee0: 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d 65  pFulltextStateme
8ef0: 6e 74 73 5b 69 53 74 6d 74 5d 20 3d 20 4e 55 4c  nts[iStmt] = NUL
8f00: 4c 3b 20 20 20 2f 2a 20 53 74 69 6c 6c 20 69 6e  L;   /* Still in
8f10: 20 73 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73   s */.    rc = s
8f20: 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74  ql_get_statement
8f30: 28 76 2c 20 69 53 74 6d 74 2c 20 26 70 4e 65 77  (v, iStmt, &pNew
8f40: 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 72  Stmt);.    if( r
8f50: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67  c!=SQLITE_OK ) g
8f60: 6f 74 6f 20 65 72 72 3b 0a 20 20 20 20 2a 70 70  oto err;.    *pp
8f70: 53 74 6d 74 20 3d 20 70 4e 65 77 53 74 6d 74 3b  Stmt = pNewStmt;
8f80: 0a 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ..    rc = sqlit
8f90: 65 33 5f 74 72 61 6e 73 66 65 72 5f 62 69 6e 64  e3_transfer_bind
8fa0: 69 6e 67 73 28 73 2c 20 70 4e 65 77 53 74 6d 74  ings(s, pNewStmt
8fb0: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
8fc0: 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20  QLITE_OK ) goto 
8fd0: 65 72 72 3b 0a 0a 20 20 20 20 72 63 20 3d 20 73  err;..    rc = s
8fe0: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
8ff0: 73 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  s);.    if( rc!=
9000: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
9010: 72 6e 20 72 63 3b 0a 20 20 20 20 73 20 3d 20 70  rn rc;.    s = p
9020: 4e 65 77 53 74 6d 74 3b 0a 20 20 7d 0a 20 20 72  NewStmt;.  }.  r
9030: 65 74 75 72 6e 20 72 63 3b 0a 0a 20 65 72 72 3a  eturn rc;.. err:
9040: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
9050: 69 7a 65 28 73 29 3b 0a 20 20 72 65 74 75 72 6e  ize(s);.  return
9060: 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 4c 69 6b 65 20   rc;.}../* Like 
9070: 73 71 6c 5f 73 74 65 70 5f 73 74 61 74 65 6d 65  sql_step_stateme
9080: 6e 74 28 29 2c 20 62 75 74 20 63 6f 6e 76 65 72  nt(), but conver
9090: 74 20 53 51 4c 49 54 45 5f 44 4f 4e 45 20 74 6f  t SQLITE_DONE to
90a0: 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2a 20 55   SQLITE_OK..** U
90b0: 73 65 66 75 6c 20 66 6f 72 20 73 74 61 74 65 6d  seful for statem
90c0: 65 6e 74 73 20 6c 69 6b 65 20 55 50 44 41 54 45  ents like UPDATE
90d0: 2c 20 77 68 65 72 65 20 77 65 20 65 78 70 65 63  , where we expec
90e0: 74 20 6e 6f 20 72 65 73 75 6c 74 73 2e 0a 2a 2f  t no results..*/
90f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 71 6c 5f  .static int sql_
9100: 73 69 6e 67 6c 65 5f 73 74 65 70 5f 73 74 61 74  single_step_stat
9110: 65 6d 65 6e 74 28 66 75 6c 6c 74 65 78 74 5f 76  ement(fulltext_v
9120: 74 61 62 20 2a 76 2c 0a 20 20 20 20 20 20 20 20  tab *v,.        
9130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9140: 20 20 20 20 20 20 20 20 20 20 20 20 20 66 75 6c               ful
9150: 6c 74 65 78 74 5f 73 74 61 74 65 6d 65 6e 74 20  ltext_statement 
9160: 69 53 74 6d 74 2c 0a 20 20 20 20 20 20 20 20 20  iStmt,.         
9170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9180: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
9190: 74 65 33 5f 73 74 6d 74 20 2a 2a 70 70 53 74 6d  te3_stmt **ppStm
91a0: 74 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73  t){.  int rc = s
91b0: 71 6c 5f 73 74 65 70 5f 73 74 61 74 65 6d 65 6e  ql_step_statemen
91c0: 74 28 76 2c 20 69 53 74 6d 74 2c 20 70 70 53 74  t(v, iStmt, ppSt
91d0: 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 72  mt);.  return (r
91e0: 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 29 20  c==SQLITE_DONE) 
91f0: 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20 72 63  ? SQLITE_OK : rc
9200: 3b 0a 7d 0a 0a 2f 2a 20 69 6e 73 65 72 74 20 69  ;.}../* insert i
9210: 6e 74 6f 20 25 5f 63 6f 6e 74 65 6e 74 20 28 72  nto %_content (r
9220: 6f 77 69 64 2c 20 2e 2e 2e 29 20 76 61 6c 75 65  owid, ...) value
9230: 73 20 28 5b 72 6f 77 69 64 5d 2c 20 5b 70 56 61  s ([rowid], [pVa
9240: 6c 75 65 73 5d 29 20 2a 2f 0a 73 74 61 74 69 63  lues]) */.static
9250: 20 69 6e 74 20 63 6f 6e 74 65 6e 74 5f 69 6e 73   int content_ins
9260: 65 72 74 28 66 75 6c 6c 74 65 78 74 5f 76 74 61  ert(fulltext_vta
9270: 62 20 2a 76 2c 20 73 71 6c 69 74 65 33 5f 76 61  b *v, sqlite3_va
9280: 6c 75 65 20 2a 72 6f 77 69 64 2c 0a 20 20 20 20  lue *rowid,.    
9290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
92a0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61        sqlite3_va
92b0: 6c 75 65 20 2a 2a 70 56 61 6c 75 65 73 29 7b 0a  lue **pValues){.
92c0: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
92d0: 73 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e  s;.  int i;.  in
92e0: 74 20 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73  t rc = sql_get_s
92f0: 74 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f 4e 54  tatement(v, CONT
9300: 45 4e 54 5f 49 4e 53 45 52 54 5f 53 54 4d 54 2c  ENT_INSERT_STMT,
9310: 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63 21 3d   &s);.  if( rc!=
9320: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
9330: 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73  rn rc;..  rc = s
9340: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75  qlite3_bind_valu
9350: 65 28 73 2c 20 31 2c 20 72 6f 77 69 64 29 3b 0a  e(s, 1, rowid);.
9360: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
9370: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
9380: 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 76  ..  for(i=0; i<v
9390: 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 7b  ->nColumn; ++i){
93a0: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
93b0: 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 73 2c 20  3_bind_value(s, 
93c0: 32 2b 69 2c 20 70 56 61 6c 75 65 73 5b 69 5d 29  2+i, pValues[i])
93d0: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
93e0: 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
93f0: 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75   rc;.  }..  retu
9400: 72 6e 20 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74  rn sql_single_st
9410: 65 70 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20  ep_statement(v, 
9420: 43 4f 4e 54 45 4e 54 5f 49 4e 53 45 52 54 5f 53  CONTENT_INSERT_S
9430: 54 4d 54 2c 20 26 73 29 3b 0a 7d 0a 0a 2f 2a 20  TMT, &s);.}../* 
9440: 75 70 64 61 74 65 20 25 5f 63 6f 6e 74 65 6e 74  update %_content
9450: 20 73 65 74 20 63 6f 6c 30 20 3d 20 70 56 61 6c   set col0 = pVal
9460: 75 65 73 5b 30 5d 2c 20 63 6f 6c 31 20 3d 20 70  ues[0], col1 = p
9470: 56 61 6c 75 65 73 5b 31 5d 2c 20 2e 2e 2e 0a 20  Values[1], .... 
9480: 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  *               
9490: 20 20 20 77 68 65 72 65 20 72 6f 77 69 64 20 3d     where rowid =
94a0: 20 5b 69 52 6f 77 69 64 5d 20 2a 2f 0a 73 74 61   [iRowid] */.sta
94b0: 74 69 63 20 69 6e 74 20 63 6f 6e 74 65 6e 74 5f  tic int content_
94c0: 75 70 64 61 74 65 28 66 75 6c 6c 74 65 78 74 5f  update(fulltext_
94d0: 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 33  vtab *v, sqlite3
94e0: 5f 76 61 6c 75 65 20 2a 2a 70 56 61 6c 75 65 73  _value **pValues
94f0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
9500: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
9510: 74 65 5f 69 6e 74 36 34 20 69 52 6f 77 69 64 29  te_int64 iRowid)
9520: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  {.  sqlite3_stmt
9530: 20 2a 73 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20   *s;.  int i;.  
9540: 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67 65 74  int rc = sql_get
9550: 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f  _statement(v, CO
9560: 4e 54 45 4e 54 5f 55 50 44 41 54 45 5f 53 54 4d  NTENT_UPDATE_STM
9570: 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63  T, &s);.  if( rc
9580: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
9590: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 66 6f 72 28  turn rc;..  for(
95a0: 69 3d 30 3b 20 69 3c 76 2d 3e 6e 43 6f 6c 75 6d  i=0; i<v->nColum
95b0: 6e 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 72 63 20  n; ++i){.    rc 
95c0: 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76  = sqlite3_bind_v
95d0: 61 6c 75 65 28 73 2c 20 31 2b 69 2c 20 70 56 61  alue(s, 1+i, pVa
95e0: 6c 75 65 73 5b 69 5d 29 3b 0a 20 20 20 20 69 66  lues[i]);.    if
95f0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
9600: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d  ) return rc;.  }
9610: 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ..  rc = sqlite3
9620: 5f 62 69 6e 64 5f 69 6e 74 36 34 28 73 2c 20 31  _bind_int64(s, 1
9630: 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 69 52 6f  +v->nColumn, iRo
9640: 77 69 64 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  wid);.  if( rc!=
9650: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
9660: 72 6e 20 72 63 3b 0a 0a 20 20 72 65 74 75 72 6e  rn rc;..  return
9670: 20 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74 65 70   sql_single_step
9680: 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f  _statement(v, CO
9690: 4e 54 45 4e 54 5f 55 50 44 41 54 45 5f 53 54 4d  NTENT_UPDATE_STM
96a0: 54 2c 20 26 73 29 3b 0a 7d 0a 0a 73 74 61 74 69  T, &s);.}..stati
96b0: 63 20 76 6f 69 64 20 66 72 65 65 53 74 72 69 6e  c void freeStrin
96c0: 67 41 72 72 61 79 28 69 6e 74 20 6e 53 74 72 69  gArray(int nStri
96d0: 6e 67 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ng, const char *
96e0: 2a 70 53 74 72 69 6e 67 29 7b 0a 20 20 69 6e 74  *pString){.  int
96f0: 20 69 3b 0a 0a 20 20 66 6f 72 20 28 69 3d 30 20   i;..  for (i=0 
9700: 3b 20 69 20 3c 20 6e 53 74 72 69 6e 67 20 3b 20  ; i < nString ; 
9710: 2b 2b 69 29 20 7b 0a 20 20 20 20 66 72 65 65 28  ++i) {.    free(
9720: 28 76 6f 69 64 20 2a 29 20 70 53 74 72 69 6e 67  (void *) pString
9730: 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 66 72 65 65  [i]);.  }.  free
9740: 28 28 76 6f 69 64 20 2a 29 20 70 53 74 72 69 6e  ((void *) pStrin
9750: 67 29 3b 0a 7d 0a 0a 2f 2a 20 73 65 6c 65 63 74  g);.}../* select
9760: 20 2a 20 66 72 6f 6d 20 25 5f 63 6f 6e 74 65 6e   * from %_conten
9770: 74 20 77 68 65 72 65 20 72 6f 77 69 64 20 3d 20  t where rowid = 
9780: 5b 69 52 6f 77 5d 0a 20 2a 20 54 68 65 20 63 61  [iRow]. * The ca
9790: 6c 6c 65 72 20 6d 75 73 74 20 64 65 6c 65 74 65  ller must delete
97a0: 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 61 72   the returned ar
97b0: 72 61 79 20 61 6e 64 20 61 6c 6c 20 73 74 72 69  ray and all stri
97c0: 6e 67 73 20 69 6e 20 69 74 2e 0a 20 2a 0a 20 2a  ngs in it.. *. *
97d0: 20 54 4f 44 4f 3a 20 50 65 72 68 61 70 73 20 77   TODO: Perhaps w
97e0: 65 20 73 68 6f 75 6c 64 20 72 65 74 75 72 6e 20  e should return 
97f0: 70 6f 69 6e 74 65 72 2f 6c 65 6e 67 74 68 20 73  pointer/length s
9800: 74 72 69 6e 67 73 20 68 65 72 65 20 66 6f 72 20  trings here for 
9810: 63 6f 6e 73 69 73 74 65 6e 63 79 0a 20 2a 20 77  consistency. * w
9820: 69 74 68 20 6f 74 68 65 72 20 63 6f 64 65 20 77  ith other code w
9830: 68 69 63 68 20 75 73 65 73 20 70 6f 69 6e 74 65  hich uses pointe
9840: 72 2f 6c 65 6e 67 74 68 2e 20 2a 2f 0a 73 74 61  r/length. */.sta
9850: 74 69 63 20 69 6e 74 20 63 6f 6e 74 65 6e 74 5f  tic int content_
9860: 73 65 6c 65 63 74 28 66 75 6c 6c 74 65 78 74 5f  select(fulltext_
9870: 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f  vtab *v, sqlite_
9880: 69 6e 74 36 34 20 69 52 6f 77 2c 0a 20 20 20 20  int64 iRow,.    
9890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
98a0: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
98b0: 20 2a 2a 2a 70 56 61 6c 75 65 73 29 7b 0a 20 20   ***pValues){.  
98c0: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b  sqlite3_stmt *s;
98d0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a  .  const char **
98e0: 76 61 6c 75 65 73 3b 0a 20 20 69 6e 74 20 69 3b  values;.  int i;
98f0: 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 2a 70  .  int rc;..  *p
9900: 56 61 6c 75 65 73 20 3d 20 4e 55 4c 4c 3b 0a 0a  Values = NULL;..
9910: 20 20 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73    rc = sql_get_s
9920: 74 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f 4e 54  tatement(v, CONT
9930: 45 4e 54 5f 53 45 4c 45 43 54 5f 53 54 4d 54 2c  ENT_SELECT_STMT,
9940: 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63 21 3d   &s);.  if( rc!=
9950: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
9960: 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73  rn rc;..  rc = s
9970: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36  qlite3_bind_int6
9980: 34 28 73 2c 20 31 2c 20 69 52 6f 77 29 3b 0a 20  4(s, 1, iRow);. 
9990: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
99a0: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
99b0: 0a 20 20 72 63 20 3d 20 73 71 6c 5f 73 74 65 70  .  rc = sql_step
99c0: 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f  _statement(v, CO
99d0: 4e 54 45 4e 54 5f 53 45 4c 45 43 54 5f 53 54 4d  NTENT_SELECT_STM
99e0: 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63  T, &s);.  if( rc
99f0: 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 20 72  !=SQLITE_ROW ) r
9a00: 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 76 61 6c  eturn rc;..  val
9a10: 75 65 73 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  ues = (const cha
9a20: 72 20 2a 2a 29 20 6d 61 6c 6c 6f 63 28 76 2d 3e  r **) malloc(v->
9a30: 6e 43 6f 6c 75 6d 6e 20 2a 20 73 69 7a 65 6f 66  nColumn * sizeof
9a40: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 29 3b  (const char *));
9a50: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 76 2d  .  for(i=0; i<v-
9a60: 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 7b 0a  >nColumn; ++i){.
9a70: 20 20 20 20 76 61 6c 75 65 73 5b 69 5d 20 3d 20      values[i] = 
9a80: 73 74 72 69 6e 67 5f 64 75 70 28 28 63 68 61 72  string_dup((char
9a90: 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  *)sqlite3_column
9aa0: 5f 74 65 78 74 28 73 2c 20 69 29 29 3b 0a 20 20  _text(s, i));.  
9ab0: 7d 0a 0a 20 20 2f 2a 20 57 65 20 65 78 70 65 63  }..  /* We expec
9ac0: 74 20 6f 6e 6c 79 20 6f 6e 65 20 72 6f 77 2e 20  t only one row. 
9ad0: 20 57 65 20 6d 75 73 74 20 65 78 65 63 75 74 65   We must execute
9ae0: 20 61 6e 6f 74 68 65 72 20 73 71 6c 69 74 65 33   another sqlite3
9af0: 5f 73 74 65 70 28 29 0a 20 20 20 2a 20 74 6f 20  _step().   * to 
9b00: 63 6f 6d 70 6c 65 74 65 20 74 68 65 20 69 74 65  complete the ite
9b10: 72 61 74 69 6f 6e 3b 20 6f 74 68 65 72 77 69 73  ration; otherwis
9b20: 65 20 74 68 65 20 74 61 62 6c 65 20 77 69 6c 6c  e the table will
9b30: 20 72 65 6d 61 69 6e 20 6c 6f 63 6b 65 64 2e 20   remain locked. 
9b40: 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  */.  rc = sqlite
9b50: 33 5f 73 74 65 70 28 73 29 3b 0a 20 20 69 66 28  3_step(s);.  if(
9b60: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45   rc==SQLITE_DONE
9b70: 20 29 7b 0a 20 20 20 20 2a 70 56 61 6c 75 65 73   ){.    *pValues
9b80: 20 3d 20 76 61 6c 75 65 73 3b 0a 20 20 20 20 72   = values;.    r
9b90: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
9ba0: 0a 20 20 7d 0a 0a 20 20 66 72 65 65 53 74 72 69  .  }..  freeStri
9bb0: 6e 67 41 72 72 61 79 28 76 2d 3e 6e 43 6f 6c 75  ngArray(v->nColu
9bc0: 6d 6e 2c 20 76 61 6c 75 65 73 29 3b 0a 20 20 72  mn, values);.  r
9bd0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
9be0: 64 65 6c 65 74 65 20 66 72 6f 6d 20 25 5f 63 6f  delete from %_co
9bf0: 6e 74 65 6e 74 20 77 68 65 72 65 20 72 6f 77 69  ntent where rowi
9c00: 64 20 3d 20 5b 69 52 6f 77 20 5d 20 2a 2f 0a 73  d = [iRow ] */.s
9c10: 74 61 74 69 63 20 69 6e 74 20 63 6f 6e 74 65 6e  tatic int conten
9c20: 74 5f 64 65 6c 65 74 65 28 66 75 6c 6c 74 65 78  t_delete(fulltex
9c30: 74 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74  t_vtab *v, sqlit
9c40: 65 5f 69 6e 74 36 34 20 69 52 6f 77 29 7b 0a 20  e_int64 iRow){. 
9c50: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73   sqlite3_stmt *s
9c60: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c  ;.  int rc = sql
9c70: 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76  _get_statement(v
9c80: 2c 20 43 4f 4e 54 45 4e 54 5f 44 45 4c 45 54 45  , CONTENT_DELETE
9c90: 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66  _STMT, &s);.  if
9ca0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
9cb0: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
9cc0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e  rc = sqlite3_bin
9cd0: 64 5f 69 6e 74 36 34 28 73 2c 20 31 2c 20 69 52  d_int64(s, 1, iR
9ce0: 6f 77 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  ow);.  if( rc!=S
9cf0: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
9d00: 6e 20 72 63 3b 0a 0a 20 20 72 65 74 75 72 6e 20  n rc;..  return 
9d10: 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74 65 70 5f  sql_single_step_
9d20: 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f 4e  statement(v, CON
9d30: 54 45 4e 54 5f 44 45 4c 45 54 45 5f 53 54 4d 54  TENT_DELETE_STMT
9d40: 2c 20 26 73 29 3b 0a 7d 0a 0a 2f 2a 20 73 65 6c  , &s);.}../* sel
9d50: 65 63 74 20 72 6f 77 69 64 2c 20 64 6f 63 6c 69  ect rowid, docli
9d60: 73 74 20 66 72 6f 6d 20 25 5f 74 65 72 6d 0a 20  st from %_term. 
9d70: 2a 20 20 77 68 65 72 65 20 74 65 72 6d 20 3d 20  *  where term = 
9d80: 5b 70 54 65 72 6d 5d 20 61 6e 64 20 73 65 67 6d  [pTerm] and segm
9d90: 65 6e 74 20 3d 20 5b 69 53 65 67 6d 65 6e 74 5d  ent = [iSegment]
9da0: 0a 20 2a 20 49 66 20 66 6f 75 6e 64 2c 20 72 65  . * If found, re
9db0: 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 52 4f 57  turns SQLITE_ROW
9dc0: 3b 20 74 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  ; the caller mus
9dd0: 74 20 66 72 65 65 20 74 68 65 0a 20 2a 20 72 65  t free the. * re
9de0: 74 75 72 6e 65 64 20 64 6f 63 6c 69 73 74 2e 20  turned doclist. 
9df0: 20 49 66 20 6e 6f 20 72 6f 77 73 20 66 6f 75 6e   If no rows foun
9e00: 64 2c 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  d, returns SQLIT
9e10: 45 5f 44 4f 4e 45 2e 20 2a 2f 0a 73 74 61 74 69  E_DONE. */.stati
9e20: 63 20 69 6e 74 20 74 65 72 6d 5f 73 65 6c 65 63  c int term_selec
9e30: 74 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20  t(fulltext_vtab 
9e40: 2a 76 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  *v, const char *
9e50: 70 54 65 72 6d 2c 20 69 6e 74 20 6e 54 65 72 6d  pTerm, int nTerm
9e60: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
9e70: 20 20 20 20 20 20 20 20 20 69 6e 74 20 69 53 65           int iSe
9e80: 67 6d 65 6e 74 2c 0a 20 20 20 20 20 20 20 20 20  gment,.         
9e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
9ea0: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 72 6f 77 69  lite_int64 *rowi
9eb0: 64 2c 20 44 6f 63 4c 69 73 74 20 2a 6f 75 74 29  d, DocList *out)
9ec0: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  {.  sqlite3_stmt
9ed0: 20 2a 73 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20   *s;.  int rc = 
9ee0: 73 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e  sql_get_statemen
9ef0: 74 28 76 2c 20 54 45 52 4d 5f 53 45 4c 45 43 54  t(v, TERM_SELECT
9f00: 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66  _STMT, &s);.  if
9f10: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
9f20: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
9f30: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e  rc = sqlite3_bin
9f40: 64 5f 74 65 78 74 28 73 2c 20 31 2c 20 70 54 65  d_text(s, 1, pTe
9f50: 72 6d 2c 20 6e 54 65 72 6d 2c 20 53 51 4c 49 54  rm, nTerm, SQLIT
9f60: 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 69 66 28  E_STATIC);.  if(
9f70: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
9f80: 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72   return rc;..  r
9f90: 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
9fa0: 5f 69 6e 74 28 73 2c 20 32 2c 20 69 53 65 67 6d  _int(s, 2, iSegm
9fb0: 65 6e 74 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  ent);.  if( rc!=
9fc0: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
9fd0: 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73  rn rc;..  rc = s
9fe0: 71 6c 5f 73 74 65 70 5f 73 74 61 74 65 6d 65 6e  ql_step_statemen
9ff0: 74 28 76 2c 20 54 45 52 4d 5f 53 45 4c 45 43 54  t(v, TERM_SELECT
a000: 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66  _STMT, &s);.  if
a010: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57  ( rc!=SQLITE_ROW
a020: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
a030: 20 2a 72 6f 77 69 64 20 3d 20 73 71 6c 69 74 65   *rowid = sqlite
a040: 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 73  3_column_int64(s
a050: 2c 20 30 29 3b 0a 20 20 64 6f 63 4c 69 73 74 49  , 0);.  docListI
a060: 6e 69 74 28 6f 75 74 2c 20 44 4c 5f 44 45 46 41  nit(out, DL_DEFA
a070: 55 4c 54 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ULT,.           
a080: 20 20 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d     sqlite3_colum
a090: 6e 5f 62 6c 6f 62 28 73 2c 20 31 29 2c 20 73 71  n_blob(s, 1), sq
a0a0: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74  lite3_column_byt
a0b0: 65 73 28 73 2c 20 31 29 29 3b 0a 0a 20 20 2f 2a  es(s, 1));..  /*
a0c0: 20 57 65 20 65 78 70 65 63 74 20 6f 6e 6c 79 20   We expect only 
a0d0: 6f 6e 65 20 72 6f 77 2e 20 20 57 65 20 6d 75 73  one row.  We mus
a0e0: 74 20 65 78 65 63 75 74 65 20 61 6e 6f 74 68 65  t execute anothe
a0f0: 72 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 29  r sqlite3_step()
a100: 0a 20 20 20 2a 20 74 6f 20 63 6f 6d 70 6c 65 74  .   * to complet
a110: 65 20 74 68 65 20 69 74 65 72 61 74 69 6f 6e 3b  e the iteration;
a120: 20 6f 74 68 65 72 77 69 73 65 20 74 68 65 20 74   otherwise the t
a130: 61 62 6c 65 20 77 69 6c 6c 20 72 65 6d 61 69 6e  able will remain
a140: 20 6c 6f 63 6b 65 64 2e 20 2a 2f 0a 20 20 72 63   locked. */.  rc
a150: 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28   = sqlite3_step(
a160: 73 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3d  s);.  return rc=
a170: 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 3f 20 53  =SQLITE_DONE ? S
a180: 51 4c 49 54 45 5f 52 4f 57 20 3a 20 72 63 3b 0a  QLITE_ROW : rc;.
a190: 7d 0a 0a 2f 2a 20 4c 6f 61 64 20 74 68 65 20 73  }../* Load the s
a1a0: 65 67 6d 65 6e 74 20 64 6f 63 6c 69 73 74 73 20  egment doclists 
a1b0: 66 6f 72 20 74 65 72 6d 20 70 54 65 72 6d 20 61  for term pTerm a
a1c0: 6e 64 20 6d 65 72 67 65 20 74 68 65 6d 20 69 6e  nd merge them in
a1d0: 0a 2a 2a 20 61 70 70 72 6f 70 72 69 61 74 65 20  .** appropriate 
a1e0: 6f 72 64 65 72 20 69 6e 74 6f 20 6f 75 74 2e 20  order into out. 
a1f0: 20 52 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f   Returns SQLITE_
a200: 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  OK if successful
a210: 2e 20 20 49 66 0a 2a 2a 20 74 68 65 72 65 20 61  .  If.** there a
a220: 72 65 20 6e 6f 20 73 65 67 6d 65 6e 74 73 20 66  re no segments f
a230: 6f 72 20 70 54 65 72 6d 2c 20 73 75 63 63 65 73  or pTerm, succes
a240: 73 66 75 6c 6c 79 20 72 65 74 75 72 6e 73 20 61  sfully returns a
a250: 6e 20 65 6d 70 74 79 0a 2a 2a 20 64 6f 63 6c 69  n empty.** docli
a260: 73 74 20 69 6e 20 6f 75 74 2e 0a 2a 2a 0a 2a 2a  st in out..**.**
a270: 20 45 61 63 68 20 64 6f 63 75 6d 65 6e 74 20 63   Each document c
a280: 6f 6e 73 69 73 74 73 20 6f 66 20 31 20 6f 72 20  onsists of 1 or 
a290: 6d 6f 72 65 20 22 63 6f 6c 75 6d 6e 73 22 2e 20  more "columns". 
a2a0: 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 2a   The number of.*
a2b0: 2a 20 63 6f 6c 75 6d 6e 73 20 69 73 20 76 2d 3e  * columns is v->
a2c0: 6e 43 6f 6c 75 6d 6e 2e 20 20 49 66 20 69 43 6f  nColumn.  If iCo
a2d0: 6c 75 6d 6e 3d 3d 76 2d 3e 6e 43 6f 6c 75 6d 6e  lumn==v->nColumn
a2e0: 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 0a 2a 2a  , then return.**
a2f0: 20 70 6f 73 69 74 69 6f 6e 20 69 6e 66 6f 72 6d   position inform
a300: 61 74 69 6f 6e 20 61 62 6f 75 74 20 61 6c 6c 20  ation about all 
a310: 63 6f 6c 75 6d 6e 73 2e 20 20 49 66 20 69 43 6f  columns.  If iCo
a320: 6c 75 6d 6e 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c  lumn<v->nColumn,
a330: 0a 2a 2a 20 74 68 65 6e 20 6f 6e 6c 79 20 72 65  .** then only re
a340: 74 75 72 6e 20 70 6f 73 69 74 69 6f 6e 20 69 6e  turn position in
a350: 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20  formation about 
a360: 74 68 65 20 69 43 6f 6c 75 6d 6e 2d 74 68 20 63  the iColumn-th c
a370: 6f 6c 75 6d 6e 0a 2a 2a 20 28 77 68 65 72 65 20  olumn.** (where 
a380: 74 68 65 20 66 69 72 73 74 20 63 6f 6c 75 6d 6e  the first column
a390: 20 69 73 20 30 29 2e 0a 2a 2f 0a 73 74 61 74 69   is 0)..*/.stati
a3a0: 63 20 69 6e 74 20 74 65 72 6d 5f 73 65 6c 65 63  c int term_selec
a3b0: 74 5f 61 6c 6c 28 0a 20 20 66 75 6c 6c 74 65 78  t_all(.  fulltex
a3c0: 74 5f 76 74 61 62 20 2a 76 2c 20 20 20 20 20 2f  t_vtab *v,     /
a3d0: 2a 20 54 68 65 20 66 75 6c 6c 74 65 78 74 20 69  * The fulltext i
a3e0: 6e 64 65 78 20 77 65 20 61 72 65 20 71 75 65 72  ndex we are quer
a3f0: 79 69 6e 67 20 61 67 61 69 6e 73 74 20 2a 2f 0a  ying against */.
a400: 20 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 2c 20 20    int iColumn,  
a410: 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 3c 6e          /* If <n
a420: 43 6f 6c 75 6d 6e 2c 20 6f 6e 6c 79 20 6c 6f 6f  Column, only loo
a430: 6b 20 61 74 20 74 68 65 20 69 43 6f 6c 75 6d 6e  k at the iColumn
a440: 2d 74 68 20 63 6f 6c 75 6d 6e 20 2a 2f 0a 20 20  -th column */.  
a450: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65 72  const char *pTer
a460: 6d 2c 20 20 20 20 2f 2a 20 54 68 65 20 74 65 72  m,    /* The ter
a470: 6d 20 77 68 6f 73 65 20 70 6f 73 74 69 6e 67 20  m whose posting 
a480: 6c 69 73 74 73 20 77 65 20 77 61 6e 74 20 2a 2f  lists we want */
a490: 0a 20 20 69 6e 74 20 6e 54 65 72 6d 2c 20 20 20  .  int nTerm,   
a4a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
a4b0: 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 70  er of bytes in p
a4c0: 54 65 72 6d 20 2a 2f 0a 20 20 44 6f 63 4c 69 73  Term */.  DocLis
a4d0: 74 20 2a 6f 75 74 20 20 20 20 20 20 20 20 20 20  t *out          
a4e0: 2f 2a 20 57 72 69 74 65 20 74 68 65 20 72 65 73  /* Write the res
a4f0: 75 6c 74 69 6e 67 20 64 6f 63 6c 69 73 74 20 68  ulting doclist h
a500: 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 44 6f 63 4c  ere */.){.  DocL
a510: 69 73 74 20 64 6f 63 6c 69 73 74 3b 0a 20 20 73  ist doclist;.  s
a520: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a  qlite3_stmt *s;.
a530: 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67    int rc = sql_g
a540: 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20  et_statement(v, 
a550: 54 45 52 4d 5f 53 45 4c 45 43 54 5f 41 4c 4c 5f  TERM_SELECT_ALL_
a560: 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28  STMT, &s);.  if(
a570: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
a580: 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72   return rc;..  r
a590: 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
a5a0: 5f 74 65 78 74 28 73 2c 20 31 2c 20 70 54 65 72  _text(s, 1, pTer
a5b0: 6d 2c 20 6e 54 65 72 6d 2c 20 53 51 4c 49 54 45  m, nTerm, SQLITE
a5c0: 5f 53 54 41 54 49 43 29 3b 0a 20 20 69 66 28 20  _STATIC);.  if( 
a5d0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
a5e0: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 64 6f  return rc;..  do
a5f0: 63 4c 69 73 74 49 6e 69 74 28 26 64 6f 63 6c 69  cListInit(&docli
a600: 73 74 2c 20 44 4c 5f 44 45 46 41 55 4c 54 2c 20  st, DL_DEFAULT, 
a610: 30 2c 20 30 29 3b 0a 0a 20 20 2f 2a 20 54 4f 44  0, 0);..  /* TOD
a620: 4f 28 73 68 65 73 73 29 20 48 61 6e 64 6c 65 20  O(shess) Handle 
a630: 73 63 68 65 6d 61 20 61 6e 64 20 62 75 73 79 20  schema and busy 
a640: 65 72 72 6f 72 73 2e 20 2a 2f 0a 20 20 77 68 69  errors. */.  whi
a650: 6c 65 28 20 28 72 63 3d 73 71 6c 5f 73 74 65 70  le( (rc=sql_step
a660: 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 54 45  _statement(v, TE
a670: 52 4d 5f 53 45 4c 45 43 54 5f 41 4c 4c 5f 53 54  RM_SELECT_ALL_ST
a680: 4d 54 2c 20 26 73 29 29 3d 3d 53 51 4c 49 54 45  MT, &s))==SQLITE
a690: 5f 52 4f 57 20 29 7b 0a 20 20 20 20 44 6f 63 4c  _ROW ){.    DocL
a6a0: 69 73 74 20 6f 6c 64 3b 0a 0a 20 20 20 20 2f 2a  ist old;..    /*
a6b0: 20 54 4f 44 4f 28 73 68 65 73 73 29 20 49 66 20   TODO(shess) If 
a6c0: 77 65 20 70 72 6f 63 65 73 73 65 64 20 64 6f 63  we processed doc
a6d0: 6c 69 73 74 73 20 66 72 6f 6d 20 6f 6c 64 65 73  lists from oldes
a6e0: 74 20 74 6f 20 6e 65 77 65 73 74 2c 20 77 65 0a  t to newest, we.
a6f0: 20 20 20 20 2a 2a 20 63 6f 75 6c 64 20 73 6b 69      ** could ski
a700: 70 20 74 68 65 20 6d 61 6c 6c 6f 63 28 29 20 69  p the malloc() i
a710: 6e 76 6f 6c 76 65 64 20 77 69 74 68 20 74 68 65  nvolved with the
a720: 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 61 6c 6c 2e   following call.
a730: 20 20 46 6f 72 0a 20 20 20 20 2a 2a 20 6e 6f 77    For.    ** now
a740: 2c 20 49 27 64 20 72 61 74 68 65 72 20 6b 65 65  , I'd rather kee
a750: 70 20 74 68 69 73 20 6c 6f 67 69 63 20 73 69 6d  p this logic sim
a760: 69 6c 61 72 20 74 6f 20 69 6e 64 65 78 5f 69 6e  ilar to index_in
a770: 73 65 72 74 5f 74 65 72 6d 28 29 2e 0a 20 20 20  sert_term()..   
a780: 20 2a 2a 20 57 65 20 63 6f 75 6c 64 20 61 64 64   ** We could add
a790: 69 74 69 6f 6e 61 6c 6c 79 20 64 72 6f 70 20 65  itionally drop e
a7a0: 6c 65 6d 65 6e 74 73 20 77 68 65 6e 20 77 65 20  lements when we 
a7b0: 73 65 65 20 64 65 6c 65 74 65 73 2c 20 62 75 74  see deletes, but
a7c0: 0a 20 20 20 20 2a 2a 20 74 68 61 74 20 77 6f 75  .    ** that wou
a7d0: 6c 64 20 72 65 71 75 69 72 65 20 61 20 64 69 73  ld require a dis
a7e0: 74 69 6e 63 74 20 76 65 72 73 69 6f 6e 20 6f 66  tinct version of
a7f0: 20 64 6f 63 4c 69 73 74 41 63 63 75 6d 75 6c 61   docListAccumula
a800: 74 65 28 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  te()..    */.   
a810: 20 64 6f 63 4c 69 73 74 49 6e 69 74 28 26 6f 6c   docListInit(&ol
a820: 64 2c 20 44 4c 5f 44 45 46 41 55 4c 54 2c 0a 20  d, DL_DEFAULT,. 
a830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
a840: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c  qlite3_column_bl
a850: 6f 62 28 73 2c 20 30 29 2c 20 73 71 6c 69 74 65  ob(s, 0), sqlite
a860: 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 73  3_column_bytes(s
a870: 2c 20 30 29 29 3b 0a 0a 20 20 20 20 69 66 28 20  , 0));..    if( 
a880: 69 43 6f 6c 75 6d 6e 3c 76 2d 3e 6e 43 6f 6c 75  iColumn<v->nColu
a890: 6d 6e 20 29 7b 20 20 20 2f 2a 20 71 75 65 72 79  mn ){   /* query
a8a0: 69 6e 67 20 61 20 73 69 6e 67 6c 65 20 63 6f 6c  ing a single col
a8b0: 75 6d 6e 20 2a 2f 0a 20 20 20 20 20 20 64 6f 63  umn */.      doc
a8c0: 4c 69 73 74 52 65 73 74 72 69 63 74 43 6f 6c 75  ListRestrictColu
a8d0: 6d 6e 28 26 6f 6c 64 2c 20 69 43 6f 6c 75 6d 6e  mn(&old, iColumn
a8e0: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
a8f0: 20 64 6f 63 6c 69 73 74 20 63 6f 6e 74 61 69 6e   doclist contain
a900: 73 20 74 68 65 20 6e 65 77 65 72 20 64 61 74 61  s the newer data
a910: 2c 20 73 6f 20 77 72 69 74 65 20 69 74 20 6f 76  , so write it ov
a920: 65 72 20 6f 6c 64 2e 20 20 54 68 65 6e 0a 20 20  er old.  Then.  
a930: 20 20 2a 2a 20 73 74 65 61 6c 20 61 63 63 75 6d    ** steal accum
a940: 75 6c 61 74 65 64 20 72 65 73 75 6c 74 20 66 6f  ulated result fo
a950: 72 20 64 6f 63 6c 69 73 74 2e 0a 20 20 20 20 2a  r doclist..    *
a960: 2f 0a 20 20 20 20 64 6f 63 4c 69 73 74 41 63 63  /.    docListAcc
a970: 75 6d 75 6c 61 74 65 28 26 6f 6c 64 2c 20 26 64  umulate(&old, &d
a980: 6f 63 6c 69 73 74 29 3b 0a 20 20 20 20 64 6f 63  oclist);.    doc
a990: 4c 69 73 74 44 65 73 74 72 6f 79 28 26 64 6f 63  ListDestroy(&doc
a9a0: 6c 69 73 74 29 3b 0a 20 20 20 20 64 6f 63 6c 69  list);.    docli
a9b0: 73 74 20 3d 20 6f 6c 64 3b 0a 20 20 7d 0a 20 20  st = old;.  }.  
a9c0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 44  if( rc!=SQLITE_D
a9d0: 4f 4e 45 20 29 7b 0a 20 20 20 20 64 6f 63 4c 69  ONE ){.    docLi
a9e0: 73 74 44 65 73 74 72 6f 79 28 26 64 6f 63 6c 69  stDestroy(&docli
a9f0: 73 74 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  st);.    return 
aa00: 72 63 3b 0a 20 20 7d 0a 0a 20 20 64 6f 63 4c 69  rc;.  }..  docLi
aa10: 73 74 44 69 73 63 61 72 64 45 6d 70 74 79 28 26  stDiscardEmpty(&
aa20: 64 6f 63 6c 69 73 74 29 3b 0a 20 20 2a 6f 75 74  doclist);.  *out
aa30: 20 3d 20 64 6f 63 6c 69 73 74 3b 0a 20 20 72 65   = doclist;.  re
aa40: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
aa50: 7d 0a 0a 2f 2a 20 69 6e 73 65 72 74 20 69 6e 74  }../* insert int
aa60: 6f 20 25 5f 74 65 72 6d 20 28 72 6f 77 69 64 2c  o %_term (rowid,
aa70: 20 74 65 72 6d 2c 20 73 65 67 6d 65 6e 74 2c 20   term, segment, 
aa80: 64 6f 63 6c 69 73 74 29 0a 20 20 20 20 20 20 20  doclist).       
aa90: 20 20 20 20 20 20 20 20 76 61 6c 75 65 73 20 28          values (
aaa0: 5b 70 69 52 6f 77 69 64 5d 2c 20 5b 70 54 65 72  [piRowid], [pTer
aab0: 6d 5d 2c 20 5b 69 53 65 67 6d 65 6e 74 5d 2c 20  m], [iSegment], 
aac0: 5b 64 6f 63 6c 69 73 74 5d 29 0a 2a 2a 20 4c 65  [doclist]).** Le
aad0: 74 73 20 73 71 6c 69 74 65 20 73 65 6c 65 63 74  ts sqlite select
aae0: 20 72 6f 77 69 64 20 69 66 20 70 69 52 6f 77 69   rowid if piRowi
aaf0: 64 20 69 73 20 4e 55 4c 4c 2c 20 65 6c 73 65 20  d is NULL, else 
ab00: 75 73 65 73 20 2a 70 69 52 6f 77 69 64 2e 0a 2a  uses *piRowid..*
ab10: 2a 0a 2a 2a 20 4e 4f 54 45 28 73 68 65 73 73 29  *.** NOTE(shess)
ab20: 20 70 69 52 6f 77 69 64 20 69 73 20 49 4e 2c 20   piRowid is IN, 
ab30: 77 69 74 68 20 76 61 6c 75 65 73 20 6f 66 20 22  with values of "
ab40: 73 70 61 63 65 20 6f 66 20 69 6e 74 36 34 22 20  space of int64" 
ab50: 70 6c 75 73 0a 2a 2a 20 6e 75 6c 6c 2c 20 69 74  plus.** null, it
ab60: 20 69 73 20 6e 6f 74 20 75 73 65 64 20 74 6f 20   is not used to 
ab70: 70 61 73 73 20 64 61 74 61 20 62 61 63 6b 20 74  pass data back t
ab80: 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 0a 2a 2f  o the caller..*/
ab90: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 72 6d  .static int term
aba0: 5f 69 6e 73 65 72 74 28 66 75 6c 6c 74 65 78 74  _insert(fulltext
abb0: 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65  _vtab *v, sqlite
abc0: 5f 69 6e 74 36 34 20 2a 70 69 52 6f 77 69 64 2c  _int64 *piRowid,
abd0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
abe0: 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68          const ch
abf0: 61 72 20 2a 70 54 65 72 6d 2c 20 69 6e 74 20 6e  ar *pTerm, int n
ac00: 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20 20 20  Term,.          
ac10: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74               int
ac20: 20 69 53 65 67 6d 65 6e 74 2c 20 44 6f 63 4c 69   iSegment, DocLi
ac30: 73 74 20 2a 64 6f 63 6c 69 73 74 29 7b 0a 20 20  st *doclist){.  
ac40: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b  sqlite3_stmt *s;
ac50: 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f  .  int rc = sql_
ac60: 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c  get_statement(v,
ac70: 20 54 45 52 4d 5f 49 4e 53 45 52 54 5f 53 54 4d   TERM_INSERT_STM
ac80: 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63  T, &s);.  if( rc
ac90: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
aca0: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 69 66 28 20  turn rc;..  if( 
acb0: 70 69 52 6f 77 69 64 3d 3d 4e 55 4c 4c 20 29 7b  piRowid==NULL ){
acc0: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
acd0: 33 5f 62 69 6e 64 5f 6e 75 6c 6c 28 73 2c 20 31  3_bind_null(s, 1
ace0: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
acf0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e  rc = sqlite3_bin
ad00: 64 5f 69 6e 74 36 34 28 73 2c 20 31 2c 20 2a 70  d_int64(s, 1, *p
ad10: 69 52 6f 77 69 64 29 3b 0a 20 20 7d 0a 20 20 69  iRowid);.  }.  i
ad20: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
ad30: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
ad40: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69   rc = sqlite3_bi
ad50: 6e 64 5f 74 65 78 74 28 73 2c 20 32 2c 20 70 54  nd_text(s, 2, pT
ad60: 65 72 6d 2c 20 6e 54 65 72 6d 2c 20 53 51 4c 49  erm, nTerm, SQLI
ad70: 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 69 66  TE_STATIC);.  if
ad80: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
ad90: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
ada0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e  rc = sqlite3_bin
adb0: 64 5f 69 6e 74 28 73 2c 20 33 2c 20 69 53 65 67  d_int(s, 3, iSeg
adc0: 6d 65 6e 74 29 3b 0a 20 20 69 66 28 20 72 63 21  ment);.  if( rc!
add0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
ade0: 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20  urn rc;..  rc = 
adf0: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 62 6c 6f  sqlite3_bind_blo
ae00: 62 28 73 2c 20 34 2c 20 64 6f 63 6c 69 73 74 2d  b(s, 4, doclist-
ae10: 3e 70 44 61 74 61 2c 20 64 6f 63 6c 69 73 74 2d  >pData, doclist-
ae20: 3e 6e 44 61 74 61 2c 20 53 51 4c 49 54 45 5f 53  >nData, SQLITE_S
ae30: 54 41 54 49 43 29 3b 0a 20 20 69 66 28 20 72 63  TATIC);.  if( rc
ae40: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
ae50: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 65 74 75  turn rc;..  retu
ae60: 72 6e 20 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74  rn sql_single_st
ae70: 65 70 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20  ep_statement(v, 
ae80: 54 45 52 4d 5f 49 4e 53 45 52 54 5f 53 54 4d 54  TERM_INSERT_STMT
ae90: 2c 20 26 73 29 3b 0a 7d 0a 0a 2f 2a 20 75 70 64  , &s);.}../* upd
aea0: 61 74 65 20 25 5f 74 65 72 6d 20 73 65 74 20 64  ate %_term set d
aeb0: 6f 63 6c 69 73 74 20 3d 20 5b 64 6f 63 6c 69 73  oclist = [doclis
aec0: 74 5d 20 77 68 65 72 65 20 72 6f 77 69 64 20 3d  t] where rowid =
aed0: 20 5b 72 6f 77 69 64 5d 20 2a 2f 0a 73 74 61 74   [rowid] */.stat
aee0: 69 63 20 69 6e 74 20 74 65 72 6d 5f 75 70 64 61  ic int term_upda
aef0: 74 65 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62  te(fulltext_vtab
af00: 20 2a 76 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36   *v, sqlite_int6
af10: 34 20 72 6f 77 69 64 2c 0a 20 20 20 20 20 20 20  4 rowid,.       
af20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
af30: 44 6f 63 4c 69 73 74 20 2a 64 6f 63 6c 69 73 74  DocList *doclist
af40: 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  ){.  sqlite3_stm
af50: 74 20 2a 73 3b 0a 20 20 69 6e 74 20 72 63 20 3d  t *s;.  int rc =
af60: 20 73 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65   sql_get_stateme
af70: 6e 74 28 76 2c 20 54 45 52 4d 5f 55 50 44 41 54  nt(v, TERM_UPDAT
af80: 45 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69  E_STMT, &s);.  i
af90: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
afa0: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
afb0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69   rc = sqlite3_bi
afc0: 6e 64 5f 62 6c 6f 62 28 73 2c 20 31 2c 20 64 6f  nd_blob(s, 1, do
afd0: 63 6c 69 73 74 2d 3e 70 44 61 74 61 2c 20 64 6f  clist->pData, do
afe0: 63 6c 69 73 74 2d 3e 6e 44 61 74 61 2c 20 53 51  clist->nData, SQ
aff0: 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20  LITE_STATIC);.  
b000: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
b010: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
b020: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62    rc = sqlite3_b
b030: 69 6e 64 5f 69 6e 74 36 34 28 73 2c 20 32 2c 20  ind_int64(s, 2, 
b040: 72 6f 77 69 64 29 3b 0a 20 20 69 66 28 20 72 63  rowid);.  if( rc
b050: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
b060: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 65 74 75  turn rc;..  retu
b070: 72 6e 20 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74  rn sql_single_st
b080: 65 70 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20  ep_statement(v, 
b090: 54 45 52 4d 5f 55 50 44 41 54 45 5f 53 54 4d 54  TERM_UPDATE_STMT
b0a0: 2c 20 26 73 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  , &s);.}..static
b0b0: 20 69 6e 74 20 74 65 72 6d 5f 64 65 6c 65 74 65   int term_delete
b0c0: 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
b0d0: 76 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  v, sqlite_int64 
b0e0: 72 6f 77 69 64 29 7b 0a 20 20 73 71 6c 69 74 65  rowid){.  sqlite
b0f0: 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74  3_stmt *s;.  int
b100: 20 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74   rc = sql_get_st
b110: 61 74 65 6d 65 6e 74 28 76 2c 20 54 45 52 4d 5f  atement(v, TERM_
b120: 44 45 4c 45 54 45 5f 53 54 4d 54 2c 20 26 73 29  DELETE_STMT, &s)
b130: 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
b140: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
b150: 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  c;..  rc = sqlit
b160: 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 73 2c  e3_bind_int64(s,
b170: 20 31 2c 20 72 6f 77 69 64 29 3b 0a 20 20 69 66   1, rowid);.  if
b180: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
b190: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
b1a0: 72 65 74 75 72 6e 20 73 71 6c 5f 73 69 6e 67 6c  return sql_singl
b1b0: 65 5f 73 74 65 70 5f 73 74 61 74 65 6d 65 6e 74  e_step_statement
b1c0: 28 76 2c 20 54 45 52 4d 5f 44 45 4c 45 54 45 5f  (v, TERM_DELETE_
b1d0: 53 54 4d 54 2c 20 26 73 29 3b 0a 7d 0a 0a 2f 2a  STMT, &s);.}../*
b1e0: 0a 2a 2a 20 46 72 65 65 20 74 68 65 20 6d 65 6d  .** Free the mem
b1f0: 6f 72 79 20 75 73 65 64 20 74 6f 20 63 6f 6e 74  ory used to cont
b200: 61 69 6e 20 61 20 66 75 6c 6c 74 65 78 74 5f 76  ain a fulltext_v
b210: 74 61 62 20 73 74 72 75 63 74 75 72 65 2e 0a 2a  tab structure..*
b220: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 75  /.static void fu
b230: 6c 6c 74 65 78 74 5f 76 74 61 62 5f 64 65 73 74  lltext_vtab_dest
b240: 72 6f 79 28 66 75 6c 6c 74 65 78 74 5f 76 74 61  roy(fulltext_vta
b250: 62 20 2a 76 29 7b 0a 20 20 69 6e 74 20 69 53 74  b *v){.  int iSt
b260: 6d 74 2c 20 69 3b 0a 0a 20 20 54 52 41 43 45 28  mt, i;..  TRACE(
b270: 28 22 46 54 53 31 20 44 65 73 74 72 6f 79 20 25  ("FTS1 Destroy %
b280: 70 5c 6e 22 2c 20 76 29 29 3b 0a 20 20 66 6f 72  p\n", v));.  for
b290: 28 20 69 53 74 6d 74 3d 30 3b 20 69 53 74 6d 74  ( iStmt=0; iStmt
b2a0: 3c 4d 41 58 5f 53 54 4d 54 3b 20 69 53 74 6d 74  <MAX_STMT; iStmt
b2b0: 2b 2b 20 29 7b 0a 20 20 20 20 69 66 28 20 76 2d  ++ ){.    if( v-
b2c0: 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d  >pFulltextStatem
b2d0: 65 6e 74 73 5b 69 53 74 6d 74 5d 21 3d 4e 55 4c  ents[iStmt]!=NUL
b2e0: 4c 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  L ){.      sqlit
b2f0: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 76 2d 3e 70  e3_finalize(v->p
b300: 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d 65 6e  FulltextStatemen
b310: 74 73 5b 69 53 74 6d 74 5d 29 3b 0a 20 20 20 20  ts[iStmt]);.    
b320: 20 20 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74    v->pFulltextSt
b330: 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 20  atements[iStmt] 
b340: 3d 20 4e 55 4c 4c 3b 0a 20 20 20 20 7d 0a 20 20  = NULL;.    }.  
b350: 7d 0a 0a 20 20 69 66 28 20 76 2d 3e 70 54 6f 6b  }..  if( v->pTok
b360: 65 6e 69 7a 65 72 21 3d 4e 55 4c 4c 20 29 7b 0a  enizer!=NULL ){.
b370: 20 20 20 20 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65      v->pTokenize
b380: 72 2d 3e 70 4d 6f 64 75 6c 65 2d 3e 78 44 65 73  r->pModule->xDes
b390: 74 72 6f 79 28 76 2d 3e 70 54 6f 6b 65 6e 69 7a  troy(v->pTokeniz
b3a0: 65 72 29 3b 0a 20 20 20 20 76 2d 3e 70 54 6f 6b  er);.    v->pTok
b3b0: 65 6e 69 7a 65 72 20 3d 20 4e 55 4c 4c 3b 0a 20  enizer = NULL;. 
b3c0: 20 7d 0a 20 20 0a 20 20 66 72 65 65 28 76 2d 3e   }.  .  free(v->
b3d0: 61 7a 43 6f 6c 75 6d 6e 29 3b 0a 20 20 66 6f 72  azColumn);.  for
b3e0: 28 69 20 3d 20 30 3b 20 69 20 3c 20 76 2d 3e 6e  (i = 0; i < v->n
b3f0: 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 20 7b 0a 20  Column; ++i) {. 
b400: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
b410: 76 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75  v->azContentColu
b420: 6d 6e 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 66 72  mn[i]);.  }.  fr
b430: 65 65 28 76 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43  ee(v->azContentC
b440: 6f 6c 75 6d 6e 29 3b 0a 20 20 66 72 65 65 28 76  olumn);.  free(v
b450: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65  );.}../*.** Toke
b460: 6e 20 74 79 70 65 73 20 66 6f 72 20 70 61 72 73  n types for pars
b470: 69 6e 67 20 74 68 65 20 61 72 67 75 6d 65 6e 74  ing the argument
b480: 73 20 74 6f 20 78 43 6f 6e 6e 65 63 74 20 6f 72  s to xConnect or
b490: 20 78 43 72 65 61 74 65 2e 0a 2a 2f 0a 23 64 65   xCreate..*/.#de
b4a0: 66 69 6e 65 20 54 4f 4b 45 4e 5f 45 4f 46 20 20  fine TOKEN_EOF  
b4b0: 20 20 20 20 20 20 20 30 20 20 20 20 2f 2a 20 45         0    /* E
b4c0: 6e 64 20 6f 66 20 66 69 6c 65 20 2a 2f 0a 23 64  nd of file */.#d
b4d0: 65 66 69 6e 65 20 54 4f 4b 45 4e 5f 53 50 41 43  efine TOKEN_SPAC
b4e0: 45 20 20 20 20 20 20 20 31 20 20 20 20 2f 2a 20  E       1    /* 
b4f0: 41 6e 79 20 6b 69 6e 64 20 6f 66 20 77 68 69 74  Any kind of whit
b500: 65 73 70 61 63 65 20 2a 2f 0a 23 64 65 66 69 6e  espace */.#defin
b510: 65 20 54 4f 4b 45 4e 5f 49 44 20 20 20 20 20 20  e TOKEN_ID      
b520: 20 20 20 20 32 20 20 20 20 2f 2a 20 41 6e 20 69      2    /* An i
b530: 64 65 6e 74 69 66 69 65 72 20 2a 2f 0a 23 64 65  dentifier */.#de
b540: 66 69 6e 65 20 54 4f 4b 45 4e 5f 53 54 52 49 4e  fine TOKEN_STRIN
b550: 47 20 20 20 20 20 20 33 20 20 20 20 2f 2a 20 41  G      3    /* A
b560: 20 73 74 72 69 6e 67 20 6c 69 74 65 72 61 6c 20   string literal 
b570: 2a 2f 0a 23 64 65 66 69 6e 65 20 54 4f 4b 45 4e  */.#define TOKEN
b580: 5f 50 55 4e 43 54 20 20 20 20 20 20 20 34 20 20  _PUNCT       4  
b590: 20 20 2f 2a 20 41 20 73 69 6e 67 6c 65 20 70 75    /* A single pu
b5a0: 6e 63 74 75 61 74 69 6f 6e 20 63 68 61 72 61 63  nctuation charac
b5b0: 74 65 72 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 66  ter */../*.** If
b5c0: 20 58 20 69 73 20 61 20 63 68 61 72 61 63 74 65   X is a characte
b5d0: 72 20 74 68 61 74 20 63 61 6e 20 62 65 20 75 73  r that can be us
b5e0: 65 64 20 69 6e 20 61 6e 20 69 64 65 6e 74 69 66  ed in an identif
b5f0: 69 65 72 20 74 68 65 6e 0a 2a 2a 20 49 64 43 68  ier then.** IdCh
b600: 61 72 28 58 29 20 77 69 6c 6c 20 62 65 20 74 72  ar(X) will be tr
b610: 75 65 2e 20 20 4f 74 68 65 72 77 69 73 65 20 69  ue.  Otherwise i
b620: 74 20 69 73 20 66 61 6c 73 65 2e 0a 2a 2a 0a 2a  t is false..**.*
b630: 2a 20 46 6f 72 20 41 53 43 49 49 2c 20 61 6e 79  * For ASCII, any
b640: 20 63 68 61 72 61 63 74 65 72 20 77 69 74 68 20   character with 
b650: 74 68 65 20 68 69 67 68 2d 6f 72 64 65 72 20 62  the high-order b
b660: 69 74 20 73 65 74 20 69 73 0a 2a 2a 20 61 6c 6c  it set is.** all
b670: 6f 77 65 64 20 69 6e 20 61 6e 20 69 64 65 6e 74  owed in an ident
b680: 69 66 69 65 72 2e 20 20 46 6f 72 20 37 2d 62 69  ifier.  For 7-bi
b690: 74 20 63 68 61 72 61 63 74 65 72 73 2c 20 0a 2a  t characters, .*
b6a0: 2a 20 73 71 6c 69 74 65 33 49 73 49 64 43 68 61  * sqlite3IsIdCha
b6b0: 72 5b 58 5d 20 6d 75 73 74 20 62 65 20 31 2e 0a  r[X] must be 1..
b6c0: 2a 2a 0a 2a 2a 20 54 69 63 6b 65 74 20 23 31 30  **.** Ticket #10
b6d0: 36 36 2e 20 20 74 68 65 20 53 51 4c 20 73 74 61  66.  the SQL sta
b6e0: 6e 64 61 72 64 20 64 6f 65 73 20 6e 6f 74 20 61  ndard does not a
b6f0: 6c 6c 6f 77 20 27 24 27 20 69 6e 20 74 68 65 0a  llow '$' in the.
b700: 2a 2a 20 6d 69 64 64 6c 65 20 6f 66 20 69 64 65  ** middle of ide
b710: 6e 74 66 69 65 72 73 2e 20 20 42 75 74 20 6d 61  ntfiers.  But ma
b720: 6e 79 20 53 51 4c 20 69 6d 70 6c 65 6d 65 6e 74  ny SQL implement
b730: 61 74 69 6f 6e 73 20 64 6f 2e 20 0a 2a 2a 20 53  ations do. .** S
b740: 51 4c 69 74 65 20 77 69 6c 6c 20 61 6c 6c 6f 77  QLite will allow
b750: 20 27 24 27 20 69 6e 20 69 64 65 6e 74 69 66 69   '$' in identifi
b760: 65 72 73 20 66 6f 72 20 63 6f 6d 70 61 74 69 62  ers for compatib
b770: 69 6c 69 74 79 2e 0a 2a 2a 20 42 75 74 20 74 68  ility..** But th
b780: 65 20 66 65 61 74 75 72 65 20 69 73 20 75 6e 64  e feature is und
b790: 6f 63 75 6d 65 6e 74 65 64 2e 0a 2a 2f 0a 73 74  ocumented..*/.st
b7a0: 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20  atic const char 
b7b0: 69 73 49 64 43 68 61 72 5b 5d 20 3d 20 7b 0a 2f  isIdChar[] = {./
b7c0: 2a 20 78 30 20 78 31 20 78 32 20 78 33 20 78 34  * x0 x1 x2 x3 x4
b7d0: 20 78 35 20 78 36 20 78 37 20 78 38 20 78 39 20   x5 x6 x7 x8 x9 
b7e0: 78 41 20 78 42 20 78 43 20 78 44 20 78 45 20 78  xA xB xC xD xE x
b7f0: 46 20 2a 2f 0a 20 20 20 20 30 2c 20 30 2c 20 30  F */.    0, 0, 0
b800: 2c 20 30 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 1, 0, 0, 0,
b810: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   0, 0, 0, 0, 0, 
b820: 30 2c 20 30 2c 20 30 2c 20 20 2f 2a 20 32 78 20  0, 0, 0,  /* 2x 
b830: 2a 2f 0a 20 20 20 20 31 2c 20 31 2c 20 31 2c 20  */.    1, 1, 1, 
b840: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
b850: 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 1, 0, 0, 0, 0,
b860: 20 30 2c 20 30 2c 20 20 2f 2a 20 33 78 20 2a 2f   0, 0,  /* 3x */
b870: 0a 20 20 20 20 30 2c 20 31 2c 20 31 2c 20 31 2c  .    0, 1, 1, 1,
b880: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
b890: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
b8a0: 2c 20 31 2c 20 20 2f 2a 20 34 78 20 2a 2f 0a 20  , 1,  /* 4x */. 
b8b0: 20 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31     1, 1, 1, 1, 1
b8c0: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
b8d0: 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   1, 0, 0, 0, 0, 
b8e0: 31 2c 20 20 2f 2a 20 35 78 20 2a 2f 0a 20 20 20  1,  /* 5x */.   
b8f0: 20 30 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   0, 1, 1, 1, 1, 
b900: 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
b910: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
b920: 20 20 2f 2a 20 36 78 20 2a 2f 0a 20 20 20 20 31    /* 6x */.    1
b930: 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
b940: 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
b950: 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20  0, 0, 0, 0, 0,  
b960: 2f 2a 20 37 78 20 2a 2f 0a 7d 3b 0a 23 64 65 66  /* 7x */.};.#def
b970: 69 6e 65 20 49 64 43 68 61 72 28 43 29 20 20 28  ine IdChar(C)  (
b980: 28 28 63 3d 43 29 26 30 78 38 30 29 21 3d 30 20  ((c=C)&0x80)!=0 
b990: 7c 7c 20 28 63 3e 30 78 31 66 20 26 26 20 69 73  || (c>0x1f && is
b9a0: 49 64 43 68 61 72 5b 63 2d 30 78 32 30 5d 29 29  IdChar[c-0x20]))
b9b0: 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  .../*.** Return 
b9c0: 74 68 65 20 6c 65 6e 67 74 68 20 6f 66 20 74 68  the length of th
b9d0: 65 20 74 6f 6b 65 6e 20 74 68 61 74 20 62 65 67  e token that beg
b9e0: 69 6e 73 20 61 74 20 7a 5b 30 5d 2e 20 0a 2a 2a  ins at z[0]. .**
b9f0: 20 53 74 6f 72 65 20 74 68 65 20 74 6f 6b 65 6e   Store the token
ba00: 20 74 79 70 65 20 69 6e 20 2a 74 6f 6b 65 6e 54   type in *tokenT
ba10: 79 70 65 20 62 65 66 6f 72 65 20 72 65 74 75 72  ype before retur
ba20: 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ning..*/.static 
ba30: 69 6e 74 20 67 65 74 54 6f 6b 65 6e 28 63 6f 6e  int getToken(con
ba40: 73 74 20 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20  st char *z, int 
ba50: 2a 74 6f 6b 65 6e 54 79 70 65 29 7b 0a 20 20 69  *tokenType){.  i
ba60: 6e 74 20 69 2c 20 63 3b 0a 20 20 73 77 69 74 63  nt i, c;.  switc
ba70: 68 28 20 2a 7a 20 29 7b 0a 20 20 20 20 63 61 73  h( *z ){.    cas
ba80: 65 20 30 3a 20 7b 0a 20 20 20 20 20 20 2a 74 6f  e 0: {.      *to
ba90: 6b 65 6e 54 79 70 65 20 3d 20 54 4f 4b 45 4e 5f  kenType = TOKEN_
baa0: 45 4f 46 3b 0a 20 20 20 20 20 20 72 65 74 75 72  EOF;.      retur
bab0: 6e 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63  n 0;.    }.    c
bac0: 61 73 65 20 27 20 27 3a 20 63 61 73 65 20 27 5c  ase ' ': case '\
bad0: 74 27 3a 20 63 61 73 65 20 27 5c 6e 27 3a 20 63  t': case '\n': c
bae0: 61 73 65 20 27 5c 66 27 3a 20 63 61 73 65 20 27  ase '\f': case '
baf0: 5c 72 27 3a 20 7b 0a 20 20 20 20 20 20 66 6f 72  \r': {.      for
bb00: 28 69 3d 31 3b 20 69 73 73 70 61 63 65 28 7a 5b  (i=1; isspace(z[
bb10: 69 5d 29 3b 20 69 2b 2b 29 7b 7d 0a 20 20 20 20  i]); i++){}.    
bb20: 20 20 2a 74 6f 6b 65 6e 54 79 70 65 20 3d 20 54    *tokenType = T
bb30: 4f 4b 45 4e 5f 53 50 41 43 45 3b 0a 20 20 20 20  OKEN_SPACE;.    
bb40: 20 20 72 65 74 75 72 6e 20 69 3b 0a 20 20 20 20    return i;.    
bb50: 7d 0a 20 20 20 20 63 61 73 65 20 27 5c 27 27 3a  }.    case '\'':
bb60: 0a 20 20 20 20 63 61 73 65 20 27 22 27 3a 20 7b  .    case '"': {
bb70: 0a 20 20 20 20 20 20 69 6e 74 20 64 65 6c 69 6d  .      int delim
bb80: 20 3d 20 7a 5b 30 5d 3b 0a 20 20 20 20 20 20 66   = z[0];.      f
bb90: 6f 72 28 69 3d 31 3b 20 28 63 3d 7a 5b 69 5d 29  or(i=1; (c=z[i])
bba0: 21 3d 30 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  !=0; i++){.     
bbb0: 20 20 20 69 66 28 20 63 3d 3d 64 65 6c 69 6d 20     if( c==delim 
bbc0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  ){.          if(
bbd0: 20 7a 5b 69 2b 31 5d 3d 3d 64 65 6c 69 6d 20 29   z[i+1]==delim )
bbe0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 2b  {.            i+
bbf0: 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c  +;.          }el
bc00: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  se{.            
bc10: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20  break;.         
bc20: 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
bc30: 20 20 20 7d 0a 20 20 20 20 20 20 2a 74 6f 6b 65     }.      *toke
bc40: 6e 54 79 70 65 20 3d 20 54 4f 4b 45 4e 5f 53 54  nType = TOKEN_ST
bc50: 52 49 4e 47 3b 0a 20 20 20 20 20 20 72 65 74 75  RING;.      retu
bc60: 72 6e 20 69 20 2b 20 28 63 21 3d 30 29 3b 0a 20  rn i + (c!=0);. 
bc70: 20 20 20 7d 0a 20 20 20 20 63 61 73 65 20 27 5b     }.    case '[
bc80: 27 3a 20 7b 0a 20 20 20 20 20 20 66 6f 72 28 69  ': {.      for(i
bc90: 3d 31 2c 20 63 3d 7a 5b 30 5d 3b 20 63 21 3d 27  =1, c=z[0]; c!='
bca0: 5d 27 20 26 26 20 28 63 3d 7a 5b 69 5d 29 21 3d  ]' && (c=z[i])!=
bcb0: 30 3b 20 69 2b 2b 29 7b 7d 0a 20 20 20 20 20 20  0; i++){}.      
bcc0: 2a 74 6f 6b 65 6e 54 79 70 65 20 3d 20 54 4f 4b  *tokenType = TOK
bcd0: 45 4e 5f 49 44 3b 0a 20 20 20 20 20 20 72 65 74  EN_ID;.      ret
bce0: 75 72 6e 20 69 3b 0a 20 20 20 20 7d 0a 20 20 20  urn i;.    }.   
bcf0: 20 64 65 66 61 75 6c 74 3a 20 7b 0a 20 20 20 20   default: {.    
bd00: 20 20 69 66 28 20 21 49 64 43 68 61 72 28 2a 7a    if( !IdChar(*z
bd10: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 62 72 65  ) ){.        bre
bd20: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
bd30: 20 20 66 6f 72 28 69 3d 31 3b 20 49 64 43 68 61    for(i=1; IdCha
bd40: 72 28 7a 5b 69 5d 29 3b 20 69 2b 2b 29 7b 7d 0a  r(z[i]); i++){}.
bd50: 20 20 20 20 20 20 2a 74 6f 6b 65 6e 54 79 70 65        *tokenType
bd60: 20 3d 20 54 4f 4b 45 4e 5f 49 44 3b 0a 20 20 20   = TOKEN_ID;.   
bd70: 20 20 20 72 65 74 75 72 6e 20 69 3b 0a 20 20 20     return i;.   
bd80: 20 7d 0a 20 20 7d 0a 20 20 2a 74 6f 6b 65 6e 54   }.  }.  *tokenT
bd90: 79 70 65 20 3d 20 54 4f 4b 45 4e 5f 50 55 4e 43  ype = TOKEN_PUNC
bda0: 54 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d  T;.  return 1;.}
bdb0: 0a 0a 2f 2a 0a 2a 2a 20 41 20 74 6f 6b 65 6e 20  ../*.** A token 
bdc0: 65 78 74 72 61 63 74 65 64 20 66 72 6f 6d 20 61  extracted from a
bdd0: 20 73 74 72 69 6e 67 20 69 73 20 61 6e 20 69 6e   string is an in
bde0: 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f  stance of the fo
bdf0: 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 73 74 72 75 63  llowing.** struc
be00: 74 75 72 65 2e 0a 2a 2f 0a 74 79 70 65 64 65 66  ture..*/.typedef
be10: 20 73 74 72 75 63 74 20 54 6f 6b 65 6e 20 7b 0a   struct Token {.
be20: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 3b    const char *z;
be30: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
be40: 72 20 74 6f 20 74 6f 6b 65 6e 20 74 65 78 74 2e  r to token text.
be50: 20 20 4e 6f 74 20 27 5c 30 30 30 27 20 74 65 72    Not '\000' ter
be60: 6d 69 6e 61 74 65 64 20 2a 2f 0a 20 20 73 68 6f  minated */.  sho
be70: 72 74 20 69 6e 74 20 6e 3b 20 20 20 20 20 20 20  rt int n;       
be80: 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 74    /* Length of t
be90: 68 65 20 74 6f 6b 65 6e 20 74 65 78 74 20 69 6e  he token text in
bea0: 20 62 79 74 65 73 2e 20 2a 2f 0a 7d 20 54 6f 6b   bytes. */.} Tok
beb0: 65 6e 3b 0a 0a 2f 2a 0a 2a 2a 20 47 69 76 65 6e  en;../*.** Given
bec0: 20 61 20 69 6e 70 75 74 20 73 74 72 69 6e 67 20   a input string 
bed0: 28 77 68 69 63 68 20 69 73 20 72 65 61 6c 6c 79  (which is really
bee0: 20 6f 6e 65 20 6f 66 20 74 68 65 20 61 72 67 76   one of the argv
bef0: 5b 5d 20 70 61 72 61 6d 65 74 65 72 73 0a 2a 2a  [] parameters.**
bf00: 20 70 61 73 73 65 64 20 69 6e 74 6f 20 78 43 6f   passed into xCo
bf10: 6e 6e 65 63 74 20 6f 72 20 78 43 72 65 61 74 65  nnect or xCreate
bf20: 29 20 73 70 6c 69 74 20 74 68 65 20 73 74 72 69  ) split the stri
bf30: 6e 67 20 75 70 20 69 6e 74 6f 20 74 6f 6b 65 6e  ng up into token
bf40: 73 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 61 6e 20  s..** Return an 
bf50: 61 72 72 61 79 20 6f 66 20 70 6f 69 6e 74 65 72  array of pointer
bf60: 73 20 74 6f 20 27 5c 30 30 30 27 20 74 65 72 6d  s to '\000' term
bf70: 69 6e 61 74 65 64 20 73 74 72 69 6e 67 73 2c 20  inated strings, 
bf80: 6f 6e 65 20 73 74 72 69 6e 67 0a 2a 2a 20 66 6f  one string.** fo
bf90: 72 20 65 61 63 68 20 6e 6f 6e 2d 77 68 69 74 65  r each non-white
bfa0: 73 70 61 63 65 20 74 6f 6b 65 6e 2e 0a 2a 2a 0a  space token..**.
bfb0: 2a 2a 20 54 68 65 20 72 65 74 75 72 6e 65 64 20  ** The returned 
bfc0: 61 72 72 61 79 20 69 73 20 74 65 72 6d 69 6e 61  array is termina
bfd0: 74 65 64 20 62 79 20 61 20 73 69 6e 67 6c 65 20  ted by a single 
bfe0: 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2e 0a 2a 2a  NULL pointer..**
bff0: 0a 2a 2a 20 53 70 61 63 65 20 74 6f 20 68 6f 6c  .** Space to hol
c000: 64 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 61  d the returned a
c010: 72 72 61 79 20 69 73 20 6f 62 74 61 69 6e 65 64  rray is obtained
c020: 20 66 72 6f 6d 20 61 20 73 69 6e 67 6c 65 0a 2a   from a single.*
c030: 2a 20 6d 61 6c 6c 6f 63 20 61 6e 64 20 73 68 6f  * malloc and sho
c040: 75 6c 64 20 62 65 20 66 72 65 65 64 20 62 79 20  uld be freed by 
c050: 70 61 73 73 69 6e 67 20 74 68 65 20 72 65 74 75  passing the retu
c060: 72 6e 20 76 61 6c 75 65 20 74 6f 20 66 72 65 65  rn value to free
c070: 28 29 2e 0a 2a 2a 20 54 68 65 20 69 6e 64 69 76  ()..** The indiv
c080: 69 64 75 61 6c 20 73 74 72 69 6e 67 73 20 77 69  idual strings wi
c090: 74 68 69 6e 20 74 68 65 20 74 6f 6b 65 6e 20 6c  thin the token l
c0a0: 69 73 74 20 61 72 65 20 61 6c 6c 20 61 20 70 61  ist are all a pa
c0b0: 72 74 20 6f 66 0a 2a 2a 20 74 68 65 20 73 69 6e  rt of.** the sin
c0c0: 67 6c 65 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63  gle memory alloc
c0d0: 61 74 69 6f 6e 20 61 6e 64 20 77 69 6c 6c 20 61  ation and will a
c0e0: 6c 6c 20 62 65 20 66 72 65 65 64 20 61 74 20 6f  ll be freed at o
c0f0: 6e 63 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63  nce..*/.static c
c100: 68 61 72 20 2a 2a 74 6f 6b 65 6e 69 7a 65 53 74  har **tokenizeSt
c110: 72 69 6e 67 28 63 6f 6e 73 74 20 63 68 61 72 20  ring(const char 
c120: 2a 7a 2c 20 69 6e 74 20 2a 70 6e 54 6f 6b 65 6e  *z, int *pnToken
c130: 29 7b 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 20  ){.  int nToken 
c140: 3d 20 30 3b 0a 20 20 54 6f 6b 65 6e 20 2a 61 54  = 0;.  Token *aT
c150: 6f 6b 65 6e 20 3d 20 6d 61 6c 6c 6f 63 28 20 73  oken = malloc( s
c160: 74 72 6c 65 6e 28 7a 29 20 2a 20 73 69 7a 65 6f  trlen(z) * sizeo
c170: 66 28 61 54 6f 6b 65 6e 5b 30 5d 29 20 29 3b 0a  f(aToken[0]) );.
c180: 20 20 69 6e 74 20 6e 20 3d 20 31 3b 0a 20 20 69    int n = 1;.  i
c190: 6e 74 20 65 2c 20 69 3b 0a 20 20 69 6e 74 20 74  nt e, i;.  int t
c1a0: 6f 74 61 6c 53 69 7a 65 20 3d 20 30 3b 0a 20 20  otalSize = 0;.  
c1b0: 63 68 61 72 20 2a 2a 61 7a 54 6f 6b 65 6e 3b 0a  char **azToken;.
c1c0: 20 20 63 68 61 72 20 2a 7a 43 6f 70 79 3b 0a 20    char *zCopy;. 
c1d0: 20 77 68 69 6c 65 28 20 6e 3e 30 20 29 7b 0a 20   while( n>0 ){. 
c1e0: 20 20 20 6e 20 3d 20 67 65 74 54 6f 6b 65 6e 28     n = getToken(
c1f0: 7a 2c 20 26 65 29 3b 0a 20 20 20 20 69 66 28 20  z, &e);.    if( 
c200: 65 21 3d 54 4f 4b 45 4e 5f 53 50 41 43 45 20 29  e!=TOKEN_SPACE )
c210: 7b 0a 20 20 20 20 20 20 61 54 6f 6b 65 6e 5b 6e  {.      aToken[n
c220: 54 6f 6b 65 6e 5d 2e 7a 20 3d 20 7a 3b 0a 20 20  Token].z = z;.  
c230: 20 20 20 20 61 54 6f 6b 65 6e 5b 6e 54 6f 6b 65      aToken[nToke
c240: 6e 5d 2e 6e 20 3d 20 6e 3b 0a 20 20 20 20 20 20  n].n = n;.      
c250: 6e 54 6f 6b 65 6e 2b 2b 3b 0a 20 20 20 20 20 20  nToken++;.      
c260: 74 6f 74 61 6c 53 69 7a 65 20 2b 3d 20 6e 2b 31  totalSize += n+1
c270: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a 20 2b 3d  ;.    }.    z +=
c280: 20 6e 3b 0a 20 20 7d 0a 20 20 61 7a 54 6f 6b 65   n;.  }.  azToke
c290: 6e 20 3d 20 28 63 68 61 72 2a 2a 29 6d 61 6c 6c  n = (char**)mall
c2a0: 6f 63 28 20 6e 54 6f 6b 65 6e 2a 73 69 7a 65 6f  oc( nToken*sizeo
c2b0: 66 28 63 68 61 72 2a 29 20 2b 20 74 6f 74 61 6c  f(char*) + total
c2c0: 53 69 7a 65 20 29 3b 0a 20 20 7a 43 6f 70 79 20  Size );.  zCopy 
c2d0: 3d 20 28 63 68 61 72 2a 29 26 61 7a 54 6f 6b 65  = (char*)&azToke
c2e0: 6e 5b 6e 54 6f 6b 65 6e 5d 3b 0a 20 20 6e 54 6f  n[nToken];.  nTo
c2f0: 6b 65 6e 2d 2d 3b 0a 20 20 66 6f 72 28 69 3d 30  ken--;.  for(i=0
c300: 3b 20 69 3c 6e 54 6f 6b 65 6e 3b 20 69 2b 2b 29  ; i<nToken; i++)
c310: 7b 0a 20 20 20 20 61 7a 54 6f 6b 65 6e 5b 69 5d  {.    azToken[i]
c320: 20 3d 20 7a 43 6f 70 79 3b 0a 20 20 20 20 6e 20   = zCopy;.    n 
c330: 3d 20 61 54 6f 6b 65 6e 5b 69 5d 2e 6e 3b 0a 20  = aToken[i].n;. 
c340: 20 20 20 6d 65 6d 63 70 79 28 7a 43 6f 70 79 2c     memcpy(zCopy,
c350: 20 61 54 6f 6b 65 6e 5b 69 5d 2e 7a 2c 20 6e 29   aToken[i].z, n)
c360: 3b 0a 20 20 20 20 7a 43 6f 70 79 5b 6e 5d 20 3d  ;.    zCopy[n] =
c370: 20 30 3b 0a 20 20 20 20 7a 43 6f 70 79 20 2b 3d   0;.    zCopy +=
c380: 20 6e 2b 31 3b 0a 20 20 7d 0a 20 20 61 7a 54 6f   n+1;.  }.  azTo
c390: 6b 65 6e 5b 6e 54 6f 6b 65 6e 5d 20 3d 20 30 3b  ken[nToken] = 0;
c3a0: 0a 20 20 66 72 65 65 28 61 54 6f 6b 65 6e 29 3b  .  free(aToken);
c3b0: 0a 20 20 2a 70 6e 54 6f 6b 65 6e 20 3d 20 6e 54  .  *pnToken = nT
c3c0: 6f 6b 65 6e 3b 0a 20 20 72 65 74 75 72 6e 20 61  oken;.  return a
c3d0: 7a 54 6f 6b 65 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  zToken;.}../*.**
c3e0: 20 43 6f 6e 76 65 72 74 20 61 6e 20 53 51 4c 2d   Convert an SQL-
c3f0: 73 74 79 6c 65 20 71 75 6f 74 65 64 20 73 74 72  style quoted str
c400: 69 6e 67 20 69 6e 74 6f 20 61 20 6e 6f 72 6d 61  ing into a norma
c410: 6c 20 73 74 72 69 6e 67 20 62 79 20 72 65 6d 6f  l string by remo
c420: 76 69 6e 67 0a 2a 2a 20 74 68 65 20 71 75 6f 74  ving.** the quot
c430: 65 20 63 68 61 72 61 63 74 65 72 73 2e 20 20 54  e characters.  T
c440: 68 65 20 63 6f 6e 76 65 72 73 69 6f 6e 20 69 73  he conversion is
c450: 20 64 6f 6e 65 20 69 6e 2d 70 6c 61 63 65 2e 20   done in-place. 
c460: 20 49 66 20 74 68 65 0a 2a 2a 20 69 6e 70 75 74   If the.** input
c470: 20 64 6f 65 73 20 6e 6f 74 20 62 65 67 69 6e 20   does not begin 
c480: 77 69 74 68 20 61 20 71 75 6f 74 65 20 63 68 61  with a quote cha
c490: 72 61 63 74 65 72 2c 20 74 68 65 6e 20 74 68 69  racter, then thi
c4a0: 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 69 73 20  s routine.** is 
c4b0: 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 45  a no-op..**.** E
c4c0: 78 61 6d 70 6c 65 73 3a 0a 2a 2a 0a 2a 2a 20 20  xamples:.**.**  
c4d0: 20 20 20 22 61 62 63 22 20 20 20 62 65 63 6f 6d     "abc"   becom
c4e0: 65 73 20 20 20 61 62 63 0a 2a 2a 20 20 20 20 20  es   abc.**     
c4f0: 27 78 79 7a 27 20 20 20 62 65 63 6f 6d 65 73 20  'xyz'   becomes 
c500: 20 20 78 79 7a 0a 2a 2a 20 20 20 20 20 5b 70 71    xyz.**     [pq
c510: 72 5d 20 20 20 62 65 63 6f 6d 65 73 20 20 20 70  r]   becomes   p
c520: 71 72 0a 2a 2a 20 20 20 20 20 60 6d 6e 6f 60 20  qr.**     `mno` 
c530: 20 20 62 65 63 6f 6d 65 73 20 20 20 6d 6e 6f 0a    becomes   mno.
c540: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  */.static void d
c550: 65 71 75 6f 74 65 53 74 72 69 6e 67 28 63 68 61  equoteString(cha
c560: 72 20 2a 7a 29 7b 0a 20 20 69 6e 74 20 71 75 6f  r *z){.  int quo
c570: 74 65 3b 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 0a  te;.  int i, j;.
c580: 20 20 69 66 28 20 7a 3d 3d 30 20 29 20 72 65 74    if( z==0 ) ret
c590: 75 72 6e 3b 0a 20 20 71 75 6f 74 65 20 3d 20 7a  urn;.  quote = z
c5a0: 5b 30 5d 3b 0a 20 20 73 77 69 74 63 68 28 20 71  [0];.  switch( q
c5b0: 75 6f 74 65 20 29 7b 0a 20 20 20 20 63 61 73 65  uote ){.    case
c5c0: 20 27 5c 27 27 3a 20 20 62 72 65 61 6b 3b 0a 20   '\'':  break;. 
c5d0: 20 20 20 63 61 73 65 20 27 22 27 3a 20 20 20 62     case '"':   b
c5e0: 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 27  reak;.    case '
c5f0: 60 27 3a 20 20 20 62 72 65 61 6b 3b 20 20 20 20  `':   break;    
c600: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
c610: 6f 72 20 4d 79 53 51 4c 20 63 6f 6d 70 61 74 69  or MySQL compati
c620: 62 69 6c 69 74 79 20 2a 2f 0a 20 20 20 20 63 61  bility */.    ca
c630: 73 65 20 27 5b 27 3a 20 20 20 71 75 6f 74 65 20  se '[':   quote 
c640: 3d 20 27 5d 27 3b 20 20 62 72 65 61 6b 3b 20 20  = ']';  break;  
c650: 2f 2a 20 46 6f 72 20 4d 53 20 53 71 6c 53 65 72  /* For MS SqlSer
c660: 76 65 72 20 63 6f 6d 70 61 74 69 62 69 6c 69 74  ver compatibilit
c670: 79 20 2a 2f 0a 20 20 20 20 64 65 66 61 75 6c 74  y */.    default
c680: 3a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d  :    return;.  }
c690: 0a 20 20 66 6f 72 28 69 3d 31 2c 20 6a 3d 30 3b  .  for(i=1, j=0;
c6a0: 20 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20   z[i]; i++){.   
c6b0: 20 69 66 28 20 7a 5b 69 5d 3d 3d 71 75 6f 74 65   if( z[i]==quote
c6c0: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 7a 5b   ){.      if( z[
c6d0: 69 2b 31 5d 3d 3d 71 75 6f 74 65 20 29 7b 0a 20  i+1]==quote ){. 
c6e0: 20 20 20 20 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20         z[j++] = 
c6f0: 71 75 6f 74 65 3b 0a 20 20 20 20 20 20 20 20 69  quote;.        i
c700: 2b 2b 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  ++;.      }else{
c710: 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b 2b 5d 20  .        z[j++] 
c720: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 62 72 65  = 0;.        bre
c730: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
c740: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a 5b 6a  }else{.      z[j
c750: 2b 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a 20 20 20 20  ++] = z[i];.    
c760: 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  }.  }.}../*.** T
c770: 68 65 20 69 6e 70 75 74 20 61 7a 49 6e 20 69 73  he input azIn is
c780: 20 61 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74   a NULL-terminat
c790: 65 64 20 6c 69 73 74 20 6f 66 20 74 6f 6b 65 6e  ed list of token
c7a0: 73 2e 20 20 52 65 6d 6f 76 65 20 74 68 65 20 66  s.  Remove the f
c7b0: 69 72 73 74 0a 2a 2a 20 74 6f 6b 65 6e 20 61 6e  irst.** token an
c7c0: 64 20 61 6c 6c 20 70 75 6e 63 74 75 61 74 69 6f  d all punctuatio
c7d0: 6e 20 74 6f 6b 65 6e 73 2e 20 20 52 65 6d 6f 76  n tokens.  Remov
c7e0: 65 20 74 68 65 20 71 75 6f 74 65 73 20 66 72 6f  e the quotes fro
c7f0: 6d 0a 2a 2a 20 61 72 6f 75 6e 64 20 73 74 72 69  m.** around stri
c800: 6e 67 20 6c 69 74 65 72 61 6c 20 74 6f 6b 65 6e  ng literal token
c810: 73 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65  s..**.** Example
c820: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 69 6e 70 75  :.**.**     inpu
c830: 74 3a 20 20 20 20 20 20 74 6f 6b 65 6e 69 7a 65  t:      tokenize
c840: 20 63 68 69 6e 65 73 65 20 28 20 27 73 69 6d 70   chinese ( 'simp
c850: 6c 69 66 65 64 27 20 2c 20 27 6d 69 78 65 64 27  lifed' , 'mixed'
c860: 20 29 0a 2a 2a 20 20 20 20 20 6f 75 74 70 75 74   ).**     output
c870: 3a 20 20 20 20 20 63 68 69 6e 65 73 65 20 73 69  :     chinese si
c880: 6d 70 6c 69 66 65 64 20 6d 69 78 65 64 0a 2a 2a  mplifed mixed.**
c890: 0a 2a 2a 20 41 6e 6f 74 68 65 72 20 65 78 61 6d  .** Another exam
c8a0: 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 69  ple:.**.**     i
c8b0: 6e 70 75 74 3a 20 20 20 20 20 20 64 65 6c 69 6d  nput:      delim
c8c0: 69 74 65 72 73 20 28 20 27 5b 27 20 2c 20 27 5d  iters ( '[' , ']
c8d0: 27 20 2c 20 27 2e 2e 2e 27 20 29 0a 2a 2a 20 20  ' , '...' ).**  
c8e0: 20 20 20 6f 75 74 70 75 74 3a 20 20 20 20 20 5b     output:     [
c8f0: 20 5d 20 2e 2e 2e 0a 2a 2f 0a 73 74 61 74 69 63   ] ....*/.static
c900: 20 76 6f 69 64 20 74 6f 6b 65 6e 4c 69 73 74 54   void tokenListT
c910: 6f 49 64 4c 69 73 74 28 63 68 61 72 20 2a 2a 61  oIdList(char **a
c920: 7a 49 6e 29 7b 0a 20 20 69 6e 74 20 69 2c 20 6a  zIn){.  int i, j
c930: 3b 0a 20 20 69 66 28 20 61 7a 49 6e 20 29 7b 0a  ;.  if( azIn ){.
c940: 20 20 20 20 66 6f 72 28 69 3d 30 2c 20 6a 3d 2d      for(i=0, j=-
c950: 31 3b 20 61 7a 49 6e 5b 69 5d 3b 20 69 2b 2b 29  1; azIn[i]; i++)
c960: 7b 0a 20 20 20 20 20 20 69 66 28 20 69 73 61 6c  {.      if( isal
c970: 6e 75 6d 28 61 7a 49 6e 5b 69 5d 5b 30 5d 29 20  num(azIn[i][0]) 
c980: 7c 7c 20 61 7a 49 6e 5b 69 5d 5b 31 5d 20 29 7b  || azIn[i][1] ){
c990: 0a 20 20 20 20 20 20 20 20 64 65 71 75 6f 74 65  .        dequote
c9a0: 53 74 72 69 6e 67 28 61 7a 49 6e 5b 69 5d 29 3b  String(azIn[i]);
c9b0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 6a 3e 3d  .        if( j>=
c9c0: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 61  0 ){.          a
c9d0: 7a 49 6e 5b 6a 5d 20 3d 20 61 7a 49 6e 5b 69 5d  zIn[j] = azIn[i]
c9e0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
c9f0: 20 20 20 20 6a 2b 2b 3b 0a 20 20 20 20 20 20 7d      j++;.      }
ca00: 0a 20 20 20 20 7d 0a 20 20 20 20 61 7a 49 6e 5b  .    }.    azIn[
ca10: 6a 5d 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 0a  j] = 0;.  }.}...
ca20: 2f 2a 0a 2a 2a 20 46 69 6e 64 20 74 68 65 20 66  /*.** Find the f
ca30: 69 72 73 74 20 61 6c 70 68 61 6e 75 6d 65 72 69  irst alphanumeri
ca40: 63 20 74 6f 6b 65 6e 20 69 6e 20 74 68 65 20 73  c token in the s
ca50: 74 72 69 6e 67 20 7a 49 6e 2e 20 20 4e 75 6c 6c  tring zIn.  Null
ca60: 2d 74 65 72 6d 69 6e 61 74 65 0a 2a 2a 20 74 68  -terminate.** th
ca70: 69 73 20 74 6f 6b 65 6e 2e 20 20 52 65 6d 6f 76  is token.  Remov
ca80: 65 20 61 6e 79 20 71 75 6f 74 61 74 69 6f 6e 20  e any quotation 
ca90: 6d 61 72 6b 73 2e 20 20 41 6e 64 20 72 65 74 75  marks.  And retu
caa0: 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 0a  rn a pointer to.
cab0: 2a 2a 20 74 68 65 20 72 65 73 75 6c 74 2e 0a 2a  ** the result..*
cac0: 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 66  /.static char *f
cad0: 69 72 73 74 54 6f 6b 65 6e 28 63 68 61 72 20 2a  irstToken(char *
cae0: 7a 49 6e 2c 20 63 68 61 72 20 2a 2a 70 7a 54 61  zIn, char **pzTa
caf0: 69 6c 29 7b 0a 20 20 69 6e 74 20 6e 2c 20 74 74  il){.  int n, tt
cb00: 79 70 65 3b 0a 20 20 77 68 69 6c 65 28 31 29 7b  ype;.  while(1){
cb10: 0a 20 20 20 20 6e 20 3d 20 67 65 74 54 6f 6b 65  .    n = getToke
cb20: 6e 28 7a 49 6e 2c 20 26 74 74 79 70 65 29 3b 0a  n(zIn, &ttype);.
cb30: 20 20 20 20 69 66 28 20 74 74 79 70 65 3d 3d 54      if( ttype==T
cb40: 4f 4b 45 4e 5f 53 50 41 43 45 20 29 7b 0a 20 20  OKEN_SPACE ){.  
cb50: 20 20 20 20 7a 49 6e 20 2b 3d 20 6e 3b 0a 20 20      zIn += n;.  
cb60: 20 20 7d 65 6c 73 65 20 69 66 28 20 74 74 79 70    }else if( ttyp
cb70: 65 3d 3d 54 4f 4b 45 4e 5f 45 4f 46 20 29 7b 0a  e==TOKEN_EOF ){.
cb80: 20 20 20 20 20 20 2a 70 7a 54 61 69 6c 20 3d 20        *pzTail = 
cb90: 7a 49 6e 3b 0a 20 20 20 20 20 20 72 65 74 75 72  zIn;.      retur
cba0: 6e 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  n 0;.    }else{.
cbb0: 20 20 20 20 20 20 7a 49 6e 5b 6e 5d 20 3d 20 30        zIn[n] = 0
cbc0: 3b 0a 20 20 20 20 20 20 2a 70 7a 54 61 69 6c 20  ;.      *pzTail 
cbd0: 3d 20 26 7a 49 6e 5b 31 5d 3b 0a 20 20 20 20 20  = &zIn[1];.     
cbe0: 20 64 65 71 75 6f 74 65 53 74 72 69 6e 67 28 7a   dequoteString(z
cbf0: 49 6e 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72  In);.      retur
cc00: 6e 20 7a 49 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d  n zIn;.    }.  }
cc10: 0a 20 20 2f 2a 4e 4f 54 52 45 41 43 48 45 44 2a  .  /*NOTREACHED*
cc20: 2f 0a 7d 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 74  /.}../* Return t
cc30: 72 75 65 20 69 66 2e 2e 2e 0a 2a 2a 0a 2a 2a 20  rue if....**.** 
cc40: 20 20 2a 20 20 73 20 62 65 67 69 6e 73 20 77 69    *  s begins wi
cc50: 74 68 20 74 68 65 20 73 74 72 69 6e 67 20 74 2c  th the string t,
cc60: 20 69 67 6e 6f 72 69 6e 67 20 63 61 73 65 0a 2a   ignoring case.*
cc70: 2a 20 20 20 2a 20 20 73 20 69 73 20 6c 6f 6e 67  *   *  s is long
cc80: 65 72 20 74 68 61 6e 20 74 0a 2a 2a 20 20 20 2a  er than t.**   *
cc90: 20 20 54 68 65 20 66 69 72 73 74 20 63 68 61 72    The first char
cca0: 61 63 74 65 72 20 6f 66 20 73 20 62 65 79 6f 6e  acter of s beyon
ccb0: 64 20 74 20 69 73 20 6e 6f 74 20 61 20 61 6c 70  d t is not a alp
ccc0: 68 61 6e 75 6d 65 72 69 63 0a 2a 2a 20 0a 2a 2a  hanumeric.** .**
ccd0: 20 49 67 6e 6f 72 65 20 6c 65 61 64 69 6e 67 20   Ignore leading 
cce0: 73 70 61 63 65 20 69 6e 20 2a 73 2e 0a 2a 2a 0a  space in *s..**.
ccf0: 2a 2a 20 54 6f 20 70 75 74 20 69 74 20 61 6e 6f  ** To put it ano
cd00: 74 68 65 72 20 77 61 79 2c 20 72 65 74 75 72 6e  ther way, return
cd10: 20 74 72 75 65 20 69 66 20 74 68 65 20 66 69 72   true if the fir
cd20: 73 74 20 74 6f 6b 65 6e 20 6f 66 0a 2a 2a 20 73  st token of.** s
cd30: 5b 5d 20 69 73 20 74 5b 5d 2e 0a 2a 2f 0a 73 74  [] is t[]..*/.st
cd40: 61 74 69 63 20 69 6e 74 20 73 74 61 72 74 73 57  atic int startsW
cd50: 69 74 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ith(const char *
cd60: 73 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 74  s, const char *t
cd70: 29 7b 0a 20 20 77 68 69 6c 65 28 20 69 73 73 70  ){.  while( issp
cd80: 61 63 65 28 2a 73 29 20 29 7b 20 73 2b 2b 3b 20  ace(*s) ){ s++; 
cd90: 7d 0a 20 20 77 68 69 6c 65 28 20 2a 74 20 29 7b  }.  while( *t ){
cda0: 0a 20 20 20 20 69 66 28 20 74 6f 6c 6f 77 65 72  .    if( tolower
cdb0: 28 2a 73 2b 2b 29 21 3d 74 6f 6c 6f 77 65 72 28  (*s++)!=tolower(
cdc0: 2a 74 2b 2b 29 20 29 20 72 65 74 75 72 6e 20 30  *t++) ) return 0
cdd0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 2a  ;.  }.  return *
cde0: 73 21 3d 27 5f 27 20 26 26 20 21 69 73 61 6c 6e  s!='_' && !isaln
cdf0: 75 6d 28 2a 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  um(*s);.}../*.**
ce00: 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   An instance of 
ce10: 74 68 69 73 20 73 74 72 75 63 74 75 72 65 20 64  this structure d
ce20: 65 66 69 6e 65 73 20 74 68 65 20 22 73 70 65 63  efines the "spec
ce30: 22 20 6f 66 20 61 0a 2a 2a 20 66 75 6c 6c 20 74  " of a.** full t
ce40: 65 78 74 20 69 6e 64 65 78 2e 20 20 54 68 69 73  ext index.  This
ce50: 20 73 74 72 75 63 74 75 72 65 20 69 73 20 70 6f   structure is po
ce60: 70 75 6c 61 74 65 64 20 62 79 20 70 61 72 73 65  pulated by parse
ce70: 53 70 65 63 0a 2a 2a 20 61 6e 64 20 75 73 65 20  Spec.** and use 
ce80: 62 79 20 66 75 6c 6c 74 65 78 74 43 6f 6e 6e 65  by fulltextConne
ce90: 63 74 20 61 6e 64 20 66 75 6c 6c 74 65 78 74 43  ct and fulltextC
cea0: 72 65 61 74 65 2e 0a 2a 2f 0a 74 79 70 65 64 65  reate..*/.typede
ceb0: 66 20 73 74 72 75 63 74 20 54 61 62 6c 65 53 70  f struct TableSp
cec0: 65 63 20 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61  ec {.  const cha
ced0: 72 20 2a 7a 44 62 3b 20 20 20 20 20 20 20 20 20  r *zDb;         
cee0: 2f 2a 20 4c 6f 67 69 63 61 6c 20 64 61 74 61 62  /* Logical datab
cef0: 61 73 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f  ase name */.  co
cf00: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b  nst char *zName;
cf10: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
cf20: 66 20 74 68 65 20 66 75 6c 6c 2d 74 65 78 74 20  f the full-text 
cf30: 69 6e 64 65 78 20 2a 2f 0a 20 20 69 6e 74 20 6e  index */.  int n
cf40: 43 6f 6c 75 6d 6e 3b 20 20 20 20 20 20 20 20 20  Column;         
cf50: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
cf60: 20 63 6f 6c 75 6d 6e 73 20 74 6f 20 62 65 20 69   columns to be i
cf70: 6e 64 65 78 65 64 20 2a 2f 0a 20 20 63 68 61 72  ndexed */.  char
cf80: 20 2a 2a 61 7a 43 6f 6c 75 6d 6e 3b 20 20 20 20   **azColumn;    
cf90: 20 20 20 20 20 2f 2a 20 4f 72 69 67 69 6e 61 6c       /* Original
cfa0: 20 6e 61 6d 65 73 20 6f 66 20 63 6f 6c 75 6d 6e   names of column
cfb0: 73 20 74 6f 20 62 65 20 69 6e 64 65 78 65 64 20  s to be indexed 
cfc0: 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61 7a 43 6f  */.  char **azCo
cfd0: 6e 74 65 6e 74 43 6f 6c 75 6d 6e 3b 20 20 2f 2a  ntentColumn;  /*
cfe0: 20 43 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 66 6f   Column names fo
cff0: 72 20 25 5f 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20  r %_content */. 
d000: 20 63 68 61 72 20 2a 2a 61 7a 54 6f 6b 65 6e 69   char **azTokeni
d010: 7a 65 72 3b 20 20 20 20 20 20 2f 2a 20 4e 61 6d  zer;      /* Nam
d020: 65 20 6f 66 20 74 6f 6b 65 6e 69 7a 65 72 20 61  e of tokenizer a
d030: 6e 64 20 69 74 73 20 61 72 67 75 6d 65 6e 74 73  nd its arguments
d040: 20 2a 2f 0a 7d 20 54 61 62 6c 65 53 70 65 63 3b   */.} TableSpec;
d050: 0a 0a 2f 2a 0a 2a 2a 20 52 65 63 6c 61 69 6d 20  ../*.** Reclaim 
d060: 61 6c 6c 20 6f 66 20 74 68 65 20 6d 65 6d 6f 72  all of the memor
d070: 79 20 75 73 65 64 20 62 79 20 61 20 54 61 62 6c  y used by a Tabl
d080: 65 53 70 65 63 0a 2a 2f 0a 73 74 61 74 69 63 20  eSpec.*/.static 
d090: 76 6f 69 64 20 63 6c 65 61 72 54 61 62 6c 65 53  void clearTableS
d0a0: 70 65 63 28 54 61 62 6c 65 53 70 65 63 20 2a 70  pec(TableSpec *p
d0b0: 29 20 7b 0a 20 20 66 72 65 65 28 70 2d 3e 61 7a  ) {.  free(p->az
d0c0: 43 6f 6c 75 6d 6e 29 3b 0a 20 20 66 72 65 65 28  Column);.  free(
d0d0: 70 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75  p->azContentColu
d0e0: 6d 6e 29 3b 0a 20 20 66 72 65 65 28 70 2d 3e 61  mn);.  free(p->a
d0f0: 7a 54 6f 6b 65 6e 69 7a 65 72 29 3b 0a 7d 0a 0a  zTokenizer);.}..
d100: 2f 2a 20 50 61 72 73 65 20 61 20 43 52 45 41 54  /* Parse a CREAT
d110: 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20  E VIRTUAL TABLE 
d120: 73 74 61 74 65 6d 65 6e 74 2c 20 77 68 69 63 68  statement, which
d130: 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20 74 68 69 73   looks like this
d140: 3a 0a 20 2a 0a 20 2a 20 43 52 45 41 54 45 20 56  :. *. * CREATE V
d150: 49 52 54 55 41 4c 20 54 41 42 4c 45 20 65 6d 61  IRTUAL TABLE ema
d160: 69 6c 0a 20 2a 20 20 20 20 20 20 20 20 55 53 49  il. *        USI
d170: 4e 47 20 66 74 73 31 28 73 75 62 6a 65 63 74 2c  NG fts1(subject,
d180: 20 62 6f 64 79 2c 20 74 6f 6b 65 6e 69 7a 65 20   body, tokenize 
d190: 6d 79 74 6f 6b 65 6e 69 7a 65 72 28 6d 79 61 72  mytokenizer(myar
d1a0: 67 29 29 0a 20 2a 0a 20 2a 20 57 65 20 72 65 74  g)). *. * We ret
d1b0: 75 72 6e 20 70 61 72 73 65 64 20 69 6e 66 6f 72  urn parsed infor
d1c0: 6d 61 74 69 6f 6e 20 69 6e 20 61 20 54 61 62 6c  mation in a Tabl
d1d0: 65 53 70 65 63 20 73 74 72 75 63 74 75 72 65 2e  eSpec structure.
d1e0: 0a 20 2a 20 0a 20 2a 2f 0a 73 74 61 74 69 63 20  . * . */.static 
d1f0: 69 6e 74 20 70 61 72 73 65 53 70 65 63 28 54 61  int parseSpec(Ta
d200: 62 6c 65 53 70 65 63 20 2a 70 53 70 65 63 2c 20  bleSpec *pSpec, 
d210: 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20  int argc, const 
d220: 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76  char *const*argv
d230: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
d240: 20 20 20 20 20 20 20 63 68 61 72 2a 2a 70 7a 45         char**pzE
d250: 72 72 29 7b 0a 20 20 69 6e 74 20 69 2c 20 6e 3b  rr){.  int i, n;
d260: 0a 20 20 63 68 61 72 20 2a 7a 2c 20 2a 7a 44 75  .  char *z, *zDu
d270: 6d 6d 79 3b 0a 20 20 63 68 61 72 20 2a 2a 61 7a  mmy;.  char **az
d280: 41 72 67 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61  Arg;.  const cha
d290: 72 20 2a 7a 54 6f 6b 65 6e 69 7a 65 72 20 3d 20  r *zTokenizer = 
d2a0: 30 3b 20 20 20 20 2f 2a 20 61 72 67 76 5b 5d 20  0;    /* argv[] 
d2b0: 65 6e 74 72 79 20 64 65 73 63 72 69 62 69 6e 67  entry describing
d2c0: 20 74 68 65 20 74 6f 6b 65 6e 69 7a 65 72 20 2a   the tokenizer *
d2d0: 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 61 72 67  /..  assert( arg
d2e0: 63 3e 3d 33 20 29 3b 0a 20 20 2f 2a 20 43 75 72  c>=3 );.  /* Cur
d2f0: 72 65 6e 74 20 69 6e 74 65 72 66 61 63 65 3a 0a  rent interface:.
d300: 20 20 2a 2a 20 61 72 67 76 5b 30 5d 20 2d 20 6d    ** argv[0] - m
d310: 6f 64 75 6c 65 20 6e 61 6d 65 0a 20 20 2a 2a 20  odule name.  ** 
d320: 61 72 67 76 5b 31 5d 20 2d 20 64 61 74 61 62 61  argv[1] - databa
d330: 73 65 20 6e 61 6d 65 0a 20 20 2a 2a 20 61 72 67  se name.  ** arg
d340: 76 5b 32 5d 20 2d 20 74 61 62 6c 65 20 6e 61 6d  v[2] - table nam
d350: 65 0a 20 20 2a 2a 20 61 72 67 76 5b 33 2e 2e 5d  e.  ** argv[3..]
d360: 20 2d 20 63 6f 6c 75 6d 6e 73 2c 20 6f 70 74 69   - columns, opti
d370: 6f 6e 61 6c 6c 79 20 66 6f 6c 6c 6f 77 65 64 20  onally followed 
d380: 62 79 20 74 6f 6b 65 6e 69 7a 65 72 20 73 70 65  by tokenizer spe
d390: 63 69 66 69 63 61 74 69 6f 6e 0a 20 20 2a 2a 20  cification.  ** 
d3a0: 20 20 20 20 20 20 20 20 20 20 20 20 61 6e 64 20              and 
d3b0: 73 6e 69 70 70 65 74 20 64 65 6c 69 6d 69 74 65  snippet delimite
d3c0: 72 73 20 73 70 65 63 69 66 69 63 61 74 69 6f 6e  rs specification
d3d0: 2e 0a 20 20 2a 2f 0a 0a 20 20 2f 2a 20 4d 61 6b  ..  */..  /* Mak
d3e0: 65 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20  e a copy of the 
d3f0: 63 6f 6d 70 6c 65 74 65 20 61 72 67 76 5b 5d 5b  complete argv[][
d400: 5d 20 61 72 72 61 79 20 69 6e 20 61 20 73 69 6e  ] array in a sin
d410: 67 6c 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 2e 0a  gle allocation..
d420: 20 20 2a 2a 20 54 68 65 20 61 72 67 76 5b 5d 5b    ** The argv[][
d430: 5d 20 61 72 72 61 79 20 69 73 20 72 65 61 64 2d  ] array is read-
d440: 6f 6e 6c 79 20 61 6e 64 20 74 72 61 6e 73 69 65  only and transie
d450: 6e 74 2e 20 20 57 65 20 63 61 6e 20 77 72 69 74  nt.  We can writ
d460: 65 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20 63 6f  e to the.  ** co
d470: 70 79 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 6d  py in order to m
d480: 6f 64 69 66 79 20 74 68 69 6e 67 73 20 61 6e 64  odify things and
d490: 20 74 68 65 20 63 6f 70 79 20 69 73 20 70 65 72   the copy is per
d4a0: 73 69 73 74 65 6e 74 2e 0a 20 20 2a 2f 0a 20 20  sistent..  */.  
d4b0: 6d 65 6d 73 65 74 28 70 53 70 65 63 2c 20 30 2c  memset(pSpec, 0,
d4c0: 20 73 69 7a 65 6f 66 28 2a 70 53 70 65 63 29 29   sizeof(*pSpec))
d4d0: 3b 0a 20 20 66 6f 72 28 69 3d 6e 3d 30 3b 20 69  ;.  for(i=n=0; i
d4e0: 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20  <argc; i++){.   
d4f0: 20 6e 20 2b 3d 20 73 74 72 6c 65 6e 28 61 72 67   n += strlen(arg
d500: 76 5b 69 5d 29 20 2b 20 31 3b 0a 20 20 7d 0a 20  v[i]) + 1;.  }. 
d510: 20 61 7a 41 72 67 20 3d 20 6d 61 6c 6c 6f 63 28   azArg = malloc(
d520: 20 73 69 7a 65 6f 66 28 63 68 61 72 2a 29 2a 61   sizeof(char*)*a
d530: 72 67 63 20 2b 20 6e 20 29 3b 0a 20 20 69 66 28  rgc + n );.  if(
d540: 20 61 7a 41 72 67 3d 3d 30 20 29 7b 0a 20 20 20   azArg==0 ){.   
d550: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
d560: 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 7a 20 3d 20  OMEM;.  }.  z = 
d570: 28 63 68 61 72 2a 29 26 61 7a 41 72 67 5b 61 72  (char*)&azArg[ar
d580: 67 63 5d 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  gc];.  for(i=0; 
d590: 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20  i<argc; i++){.  
d5a0: 20 20 61 7a 41 72 67 5b 69 5d 20 3d 20 7a 3b 0a    azArg[i] = z;.
d5b0: 20 20 20 20 73 74 72 63 70 79 28 7a 2c 20 61 72      strcpy(z, ar
d5c0: 67 76 5b 69 5d 29 3b 0a 20 20 20 20 7a 20 2b 3d  gv[i]);.    z +=
d5d0: 20 73 74 72 6c 65 6e 28 7a 29 2b 31 3b 0a 20 20   strlen(z)+1;.  
d5e0: 7d 0a 0a 20 20 2f 2a 20 49 64 65 6e 74 69 66 79  }..  /* Identify
d5f0: 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65   the column name
d600: 73 20 61 6e 64 20 74 68 65 20 74 6f 6b 65 6e 69  s and the tokeni
d610: 7a 65 72 20 61 6e 64 20 64 65 6c 69 6d 69 74 65  zer and delimite
d620: 72 20 61 72 67 75 6d 65 6e 74 73 0a 20 20 2a 2a  r arguments.  **
d630: 20 69 6e 20 74 68 65 20 61 72 67 76 5b 5d 5b 5d   in the argv[][]
d640: 20 61 72 72 61 79 2e 0a 20 20 2a 2f 0a 20 20 70   array..  */.  p
d650: 53 70 65 63 2d 3e 7a 44 62 20 3d 20 61 7a 41 72  Spec->zDb = azAr
d660: 67 5b 31 5d 3b 0a 20 20 70 53 70 65 63 2d 3e 7a  g[1];.  pSpec->z
d670: 4e 61 6d 65 20 3d 20 61 7a 41 72 67 5b 32 5d 3b  Name = azArg[2];
d680: 0a 20 20 70 53 70 65 63 2d 3e 6e 43 6f 6c 75 6d  .  pSpec->nColum
d690: 6e 20 3d 20 30 3b 0a 20 20 70 53 70 65 63 2d 3e  n = 0;.  pSpec->
d6a0: 61 7a 43 6f 6c 75 6d 6e 20 3d 20 61 7a 41 72 67  azColumn = azArg
d6b0: 3b 0a 20 20 7a 54 6f 6b 65 6e 69 7a 65 72 20 3d  ;.  zTokenizer =
d6c0: 20 22 74 6f 6b 65 6e 69 7a 65 20 73 69 6d 70 6c   "tokenize simpl
d6d0: 65 22 3b 0a 20 20 66 6f 72 28 69 3d 33 3b 20 69  e";.  for(i=3; i
d6e0: 3c 61 72 67 63 3b 20 2b 2b 69 29 7b 0a 20 20 20  <argc; ++i){.   
d6f0: 20 69 66 28 20 73 74 61 72 74 73 57 69 74 68 28   if( startsWith(
d700: 61 7a 41 72 67 5b 69 5d 2c 22 74 6f 6b 65 6e 69  azArg[i],"tokeni
d710: 7a 65 22 29 20 29 7b 0a 20 20 20 20 20 20 7a 54  ze") ){.      zT
d720: 6f 6b 65 6e 69 7a 65 72 20 3d 20 61 7a 41 72 67  okenizer = azArg
d730: 5b 69 5d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  [i];.    }else{.
d740: 20 20 20 20 20 20 7a 20 3d 20 61 7a 41 72 67 5b        z = azArg[
d750: 70 53 70 65 63 2d 3e 6e 43 6f 6c 75 6d 6e 5d 20  pSpec->nColumn] 
d760: 3d 20 66 69 72 73 74 54 6f 6b 65 6e 28 61 7a 41  = firstToken(azA
d770: 72 67 5b 69 5d 2c 20 26 7a 44 75 6d 6d 79 29 3b  rg[i], &zDummy);
d780: 0a 20 20 20 20 20 20 70 53 70 65 63 2d 3e 6e 43  .      pSpec->nC
d790: 6f 6c 75 6d 6e 2b 2b 3b 0a 20 20 20 20 7d 0a 20  olumn++;.    }. 
d7a0: 20 7d 0a 20 20 69 66 28 20 70 53 70 65 63 2d 3e   }.  if( pSpec->
d7b0: 6e 43 6f 6c 75 6d 6e 3d 3d 30 20 29 7b 0a 20 20  nColumn==0 ){.  
d7c0: 20 20 61 7a 41 72 67 5b 30 5d 20 3d 20 22 63 6f    azArg[0] = "co
d7d0: 6e 74 65 6e 74 22 3b 0a 20 20 20 20 70 53 70 65  ntent";.    pSpe
d7e0: 63 2d 3e 6e 43 6f 6c 75 6d 6e 20 3d 20 31 3b 0a  c->nColumn = 1;.
d7f0: 20 20 7d 0a 0a 20 20 2f 2a 0a 20 20 2a 2a 20 43    }..  /*.  ** C
d800: 6f 6e 73 74 72 75 63 74 20 74 68 65 20 6c 69 73  onstruct the lis
d810: 74 20 6f 66 20 63 6f 6e 74 65 6e 74 20 63 6f 6c  t of content col
d820: 75 6d 6e 20 6e 61 6d 65 73 2e 0a 20 20 2a 2a 0a  umn names..  **.
d830: 20 20 2a 2a 20 45 61 63 68 20 63 6f 6e 74 65 6e    ** Each conten
d840: 74 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 20 77 69  t column name wi
d850: 6c 6c 20 62 65 20 6f 66 20 74 68 65 20 66 6f 72  ll be of the for
d860: 6d 20 63 4e 4e 41 41 41 41 0a 20 20 2a 2a 20 77  m cNNAAAA.  ** w
d870: 68 65 72 65 20 4e 4e 20 69 73 20 74 68 65 20 63  here NN is the c
d880: 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72 20 61 6e 64  olumn number and
d890: 20 41 41 41 41 20 69 73 20 74 68 65 20 73 61 6e   AAAA is the san
d8a0: 69 74 69 7a 65 64 0a 20 20 2a 2a 20 63 6f 6c 75  itized.  ** colu
d8b0: 6d 6e 20 6e 61 6d 65 2e 20 20 22 73 61 6e 69 74  mn name.  "sanit
d8c0: 69 7a 65 64 22 20 6d 65 61 6e 73 20 74 68 61 74  ized" means that
d8d0: 20 73 70 65 63 69 61 6c 20 63 68 61 72 61 63 74   special charact
d8e0: 65 72 73 20 61 72 65 0a 20 20 2a 2a 20 63 6f 6e  ers are.  ** con
d8f0: 76 65 72 74 65 64 20 74 6f 20 22 5f 22 2e 20 20  verted to "_".  
d900: 54 68 65 20 63 4e 4e 20 70 72 65 66 69 78 20 67  The cNN prefix g
d910: 75 61 72 61 6e 74 65 65 73 20 74 68 61 74 20 61  uarantees that a
d920: 6c 6c 20 63 6f 6c 75 6d 6e 0a 20 20 2a 2a 20 6e  ll column.  ** n
d930: 61 6d 65 73 20 61 72 65 20 75 6e 69 71 75 65 2e  ames are unique.
d940: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 20 41  .  **.  ** The A
d950: 41 41 41 20 73 75 66 66 69 78 20 69 73 20 6e 6f  AAA suffix is no
d960: 74 20 73 74 72 69 63 74 6c 79 20 6e 65 63 65 73  t strictly neces
d970: 73 61 72 79 2e 20 20 49 74 20 69 73 20 69 6e 63  sary.  It is inc
d980: 6c 75 64 65 64 0a 20 20 2a 2a 20 66 6f 72 20 74  luded.  ** for t
d990: 68 65 20 63 6f 6e 76 65 6e 69 65 6e 63 65 20 6f  he convenience o
d9a0: 66 20 70 65 6f 70 6c 65 20 77 68 6f 20 6d 69 67  f people who mig
d9b0: 68 74 20 65 78 61 6d 69 6e 65 20 74 68 65 20 67  ht examine the g
d9c0: 65 6e 65 72 61 74 65 64 0a 20 20 2a 2a 20 25 5f  enerated.  ** %_
d9d0: 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65 20 61 6e  content table an
d9e0: 64 20 77 6f 6e 64 65 72 20 77 68 61 74 20 74 68  d wonder what th
d9f0: 65 20 63 6f 6c 75 6d 6e 73 20 61 72 65 20 75 73  e columns are us
da00: 65 64 20 66 6f 72 2e 0a 20 20 2a 2f 0a 20 20 70  ed for..  */.  p
da10: 53 70 65 63 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43  Spec->azContentC
da20: 6f 6c 75 6d 6e 20 3d 20 6d 61 6c 6c 6f 63 28 20  olumn = malloc( 
da30: 70 53 70 65 63 2d 3e 6e 43 6f 6c 75 6d 6e 20 2a  pSpec->nColumn *
da40: 20 73 69 7a 65 6f 66 28 63 68 61 72 20 2a 29 20   sizeof(char *) 
da50: 29 3b 0a 20 20 69 66 28 20 70 53 70 65 63 2d 3e  );.  if( pSpec->
da60: 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 3d  azContentColumn=
da70: 3d 30 20 29 7b 0a 20 20 20 20 63 6c 65 61 72 54  =0 ){.    clearT
da80: 61 62 6c 65 53 70 65 63 28 70 53 70 65 63 29 3b  ableSpec(pSpec);
da90: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
daa0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
dab0: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 53 70 65 63  for(i=0; i<pSpec
dac0: 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 69 2b 2b 29 7b  ->nColumn; i++){
dad0: 0a 20 20 20 20 63 68 61 72 20 2a 70 3b 0a 20 20  .    char *p;.  
dae0: 20 20 70 53 70 65 63 2d 3e 61 7a 43 6f 6e 74 65    pSpec->azConte
daf0: 6e 74 43 6f 6c 75 6d 6e 5b 69 5d 20 3d 20 73 71  ntColumn[i] = sq
db00: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 63  lite3_mprintf("c
db10: 25 64 25 73 22 2c 20 69 2c 20 61 7a 41 72 67 5b  %d%s", i, azArg[
db20: 69 5d 29 3b 0a 20 20 20 20 66 6f 72 20 28 70 20  i]);.    for (p 
db30: 3d 20 70 53 70 65 63 2d 3e 61 7a 43 6f 6e 74 65  = pSpec->azConte
db40: 6e 74 43 6f 6c 75 6d 6e 5b 69 5d 3b 20 2a 70 20  ntColumn[i]; *p 
db50: 3b 20 2b 2b 70 29 20 7b 0a 20 20 20 20 20 20 69  ; ++p) {.      i
db60: 66 28 20 21 69 73 61 6c 6e 75 6d 28 2a 70 29 20  f( !isalnum(*p) 
db70: 29 20 2a 70 20 3d 20 27 5f 27 3b 0a 20 20 20 20  ) *p = '_';.    
db80: 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 0a 20 20 2a 2a  }.  }..  /*.  **
db90: 20 50 61 72 73 65 20 74 68 65 20 74 6f 6b 65 6e   Parse the token
dba0: 69 7a 65 72 20 73 70 65 63 69 66 69 63 61 74 69  izer specificati
dbb0: 6f 6e 20 73 74 72 69 6e 67 2e 0a 20 20 2a 2f 0a  on string..  */.
dbc0: 20 20 70 53 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e    pSpec->azToken
dbd0: 69 7a 65 72 20 3d 20 74 6f 6b 65 6e 69 7a 65 53  izer = tokenizeS
dbe0: 74 72 69 6e 67 28 7a 54 6f 6b 65 6e 69 7a 65 72  tring(zTokenizer
dbf0: 2c 20 26 6e 29 3b 0a 20 20 74 6f 6b 65 6e 4c 69  , &n);.  tokenLi
dc00: 73 74 54 6f 49 64 4c 69 73 74 28 70 53 70 65 63  stToIdList(pSpec
dc10: 2d 3e 61 7a 54 6f 6b 65 6e 69 7a 65 72 29 3b 0a  ->azTokenizer);.
dc20: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
dc30: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47 65  _OK;.}../*.** Ge
dc40: 6e 65 72 61 74 65 20 61 20 43 52 45 41 54 45 20  nerate a CREATE 
dc50: 54 41 42 4c 45 20 73 74 61 74 65 6d 65 6e 74 20  TABLE statement 
dc60: 74 68 61 74 20 64 65 73 63 72 69 62 65 73 20 74  that describes t
dc70: 68 65 20 73 63 68 65 6d 61 20 6f 66 0a 2a 2a 20  he schema of.** 
dc80: 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c  the virtual tabl
dc90: 65 2e 20 20 52 65 74 75 72 6e 20 61 20 70 6f 69  e.  Return a poi
dca0: 6e 74 65 72 20 74 6f 20 74 68 69 73 20 73 63 68  nter to this sch
dcb0: 65 6d 61 20 73 74 72 69 6e 67 2e 0a 2a 2a 0a 2a  ema string..**.*
dcc0: 2a 20 53 70 61 63 65 20 69 73 20 6f 62 74 61 69  * Space is obtai
dcd0: 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33  ned from sqlite3
dce0: 5f 6d 70 72 69 6e 74 66 28 29 20 61 6e 64 20 73  _mprintf() and s
dcf0: 68 6f 75 6c 64 20 62 65 20 66 72 65 65 64 0a 2a  hould be freed.*
dd00: 2a 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f  * using sqlite3_
dd10: 66 72 65 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69  free()..*/.stati
dd20: 63 20 63 68 61 72 20 2a 66 75 6c 6c 74 65 78 74  c char *fulltext
dd30: 53 63 68 65 6d 61 28 0a 20 20 69 6e 74 20 6e 43  Schema(.  int nC
dd40: 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20  olumn,          
dd50: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
dd60: 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a  r of columns */.
dd70: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f    const char *co
dd80: 6e 73 74 2a 20 61 7a 43 6f 6c 75 6d 6e 2c 20 20  nst* azColumn,  
dd90: 2f 2a 20 4c 69 73 74 20 6f 66 20 63 6f 6c 75 6d  /* List of colum
dda0: 6e 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ns */.  const ch
ddb0: 61 72 20 2a 7a 54 61 62 6c 65 4e 61 6d 65 20 20  ar *zTableName  
ddc0: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
ddd0: 20 74 68 65 20 74 61 62 6c 65 20 2a 2f 0a 29 7b   the table */.){
dde0: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 68 61 72  .  int i;.  char
ddf0: 20 2a 7a 53 63 68 65 6d 61 2c 20 2a 7a 4e 65 78   *zSchema, *zNex
de00: 74 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  t;.  const char 
de10: 2a 7a 53 65 70 20 3d 20 22 28 22 3b 0a 20 20 7a  *zSep = "(";.  z
de20: 53 63 68 65 6d 61 20 3d 20 73 71 6c 69 74 65 33  Schema = sqlite3
de30: 5f 6d 70 72 69 6e 74 66 28 22 43 52 45 41 54 45  _mprintf("CREATE
de40: 20 54 41 42 4c 45 20 78 22 29 3b 0a 20 20 66 6f   TABLE x");.  fo
de50: 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 75 6d 6e  r(i=0; i<nColumn
de60: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 7a 4e 65 78  ; i++){.    zNex
de70: 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  t = sqlite3_mpri
de80: 6e 74 66 28 22 25 73 25 73 25 51 22 2c 20 7a 53  ntf("%s%s%Q", zS
de90: 63 68 65 6d 61 2c 20 7a 53 65 70 2c 20 61 7a 43  chema, zSep, azC
dea0: 6f 6c 75 6d 6e 5b 69 5d 29 3b 0a 20 20 20 20 73  olumn[i]);.    s
deb0: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 63 68  qlite3_free(zSch
dec0: 65 6d 61 29 3b 0a 20 20 20 20 7a 53 63 68 65 6d  ema);.    zSchem
ded0: 61 20 3d 20 7a 4e 65 78 74 3b 0a 20 20 20 20 7a  a = zNext;.    z
dee0: 53 65 70 20 3d 20 22 2c 22 3b 0a 20 20 7d 0a 20  Sep = ",";.  }. 
def0: 20 7a 4e 65 78 74 20 3d 20 73 71 6c 69 74 65 33   zNext = sqlite3
df00: 5f 6d 70 72 69 6e 74 66 28 22 25 73 2c 25 51 29  _mprintf("%s,%Q)
df10: 22 2c 20 7a 53 63 68 65 6d 61 2c 20 7a 54 61 62  ", zSchema, zTab
df20: 6c 65 4e 61 6d 65 29 3b 0a 20 20 73 71 6c 69 74  leName);.  sqlit
df30: 65 33 5f 66 72 65 65 28 7a 53 63 68 65 6d 61 29  e3_free(zSchema)
df40: 3b 0a 20 20 72 65 74 75 72 6e 20 7a 4e 65 78 74  ;.  return zNext
df50: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42 75 69 6c 64  ;.}../*.** Build
df60: 20 61 20 6e 65 77 20 73 71 6c 69 74 65 33 5f 76   a new sqlite3_v
df70: 74 61 62 20 73 74 72 75 63 74 75 72 65 20 74 68  tab structure th
df80: 61 74 20 77 69 6c 6c 20 64 65 73 63 72 69 62 65  at will describe
df90: 20 74 68 65 0a 2a 2a 20 66 75 6c 6c 74 65 78 74   the.** fulltext
dfa0: 20 69 6e 64 65 78 20 64 65 66 69 6e 65 64 20 62   index defined b
dfb0: 79 20 73 70 65 63 2e 0a 2a 2f 0a 73 74 61 74 69  y spec..*/.stati
dfc0: 63 20 69 6e 74 20 63 6f 6e 73 74 72 75 63 74 56  c int constructV
dfd0: 74 61 62 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  tab(.  sqlite3 *
dfe0: 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  db,             
dff0: 20 2f 2a 20 54 68 65 20 53 51 4c 69 74 65 20 64   /* The SQLite d
e000: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
e010: 6f 6e 20 2a 2f 0a 20 20 54 61 62 6c 65 53 70 65  on */.  TableSpe
e020: 63 20 2a 73 70 65 63 2c 20 20 20 20 20 20 20 20  c *spec,        
e030: 20 20 2f 2a 20 50 61 72 73 65 64 20 73 70 65 63    /* Parsed spec
e040: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 72 6f   information fro
e050: 6d 20 70 61 72 73 65 53 70 65 63 28 29 20 2a 2f  m parseSpec() */
e060: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
e070: 2a 2a 70 70 56 54 61 62 2c 20 20 20 20 2f 2a 20  **ppVTab,    /* 
e080: 57 72 69 74 65 20 74 68 65 20 72 65 73 75 6c 74  Write the result
e090: 69 6e 67 20 76 74 61 62 20 73 74 72 75 63 74 75  ing vtab structu
e0a0: 72 65 20 68 65 72 65 20 2a 2f 0a 20 20 63 68 61  re here */.  cha
e0b0: 72 20 2a 2a 70 7a 45 72 72 20 20 20 20 20 20 20  r **pzErr       
e0c0: 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20         /* Write 
e0d0: 61 6e 79 20 65 72 72 6f 72 20 6d 65 73 73 61 67  any error messag
e0e0: 65 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 69  e here */.){.  i
e0f0: 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 6e 3b 0a  nt rc;.  int n;.
e100: 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20    fulltext_vtab 
e110: 2a 76 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20  *v = 0;.  const 
e120: 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
e130: 72 5f 6d 6f 64 75 6c 65 20 2a 6d 20 3d 20 4e 55  r_module *m = NU
e140: 4c 4c 3b 0a 20 20 63 68 61 72 20 2a 73 63 68 65  LL;.  char *sche
e150: 6d 61 3b 0a 0a 20 20 76 20 3d 20 28 66 75 6c 6c  ma;..  v = (full
e160: 74 65 78 74 5f 76 74 61 62 20 2a 29 20 6d 61 6c  text_vtab *) mal
e170: 6c 6f 63 28 73 69 7a 65 6f 66 28 66 75 6c 6c 74  loc(sizeof(fullt
e180: 65 78 74 5f 76 74 61 62 29 29 3b 0a 20 20 69 66  ext_vtab));.  if
e190: 28 20 76 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  ( v==0 ) return 
e1a0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
e1b0: 6d 65 6d 73 65 74 28 76 2c 20 30 2c 20 73 69 7a  memset(v, 0, siz
e1c0: 65 6f 66 28 2a 76 29 29 3b 0a 20 20 2f 2a 20 73  eof(*v));.  /* s
e1d0: 71 6c 69 74 65 20 77 69 6c 6c 20 69 6e 69 74 69  qlite will initi
e1e0: 61 6c 69 7a 65 20 76 2d 3e 62 61 73 65 20 2a 2f  alize v->base */
e1f0: 0a 20 20 76 2d 3e 64 62 20 3d 20 64 62 3b 0a 20  .  v->db = db;. 
e200: 20 76 2d 3e 7a 44 62 20 3d 20 73 70 65 63 2d 3e   v->zDb = spec->
e210: 7a 44 62 3b 20 20 20 20 20 20 20 2f 2a 20 46 72  zDb;       /* Fr
e220: 65 65 64 20 77 68 65 6e 20 61 7a 43 6f 6c 75 6d  eed when azColum
e230: 6e 20 69 73 20 66 72 65 65 64 20 2a 2f 0a 20 20  n is freed */.  
e240: 76 2d 3e 7a 4e 61 6d 65 20 3d 20 73 70 65 63 2d  v->zName = spec-
e250: 3e 7a 4e 61 6d 65 3b 20 20 20 2f 2a 20 46 72 65  >zName;   /* Fre
e260: 65 64 20 77 68 65 6e 20 61 7a 43 6f 6c 75 6d 6e  ed when azColumn
e270: 20 69 73 20 66 72 65 65 64 20 2a 2f 0a 20 20 76   is freed */.  v
e280: 2d 3e 6e 43 6f 6c 75 6d 6e 20 3d 20 73 70 65 63  ->nColumn = spec
e290: 2d 3e 6e 43 6f 6c 75 6d 6e 3b 0a 20 20 76 2d 3e  ->nColumn;.  v->
e2a0: 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 20  azContentColumn 
e2b0: 3d 20 73 70 65 63 2d 3e 61 7a 43 6f 6e 74 65 6e  = spec->azConten
e2c0: 74 43 6f 6c 75 6d 6e 3b 0a 20 20 73 70 65 63 2d  tColumn;.  spec-
e2d0: 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e  >azContentColumn
e2e0: 20 3d 20 30 3b 0a 20 20 76 2d 3e 61 7a 43 6f 6c   = 0;.  v->azCol
e2f0: 75 6d 6e 20 3d 20 73 70 65 63 2d 3e 61 7a 43 6f  umn = spec->azCo
e300: 6c 75 6d 6e 3b 0a 20 20 73 70 65 63 2d 3e 61 7a  lumn;.  spec->az
e310: 43 6f 6c 75 6d 6e 20 3d 20 30 3b 0a 0a 20 20 69  Column = 0;..  i
e320: 66 28 20 73 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e  f( spec->azToken
e330: 69 7a 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72  izer==0 ){.    r
e340: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
e350: 45 4d 3b 0a 20 20 7d 0a 20 20 2f 2a 20 54 4f 44  EM;.  }.  /* TOD
e360: 4f 28 73 68 65 73 73 29 20 46 6f 72 20 6e 6f 77  O(shess) For now
e370: 2c 20 61 64 64 20 6e 65 77 20 74 6f 6b 65 6e 69  , add new tokeni
e380: 7a 65 72 73 20 61 73 20 65 6c 73 65 20 69 66 20  zers as else if 
e390: 63 6c 61 75 73 65 73 2e 20 2a 2f 0a 20 20 69 66  clauses. */.  if
e3a0: 28 20 73 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e 69  ( spec->azTokeni
e3b0: 7a 65 72 5b 30 5d 3d 3d 30 20 7c 7c 20 73 74 61  zer[0]==0 || sta
e3c0: 72 74 73 57 69 74 68 28 73 70 65 63 2d 3e 61 7a  rtsWith(spec->az
e3d0: 54 6f 6b 65 6e 69 7a 65 72 5b 30 5d 2c 20 22 73  Tokenizer[0], "s
e3e0: 69 6d 70 6c 65 22 29 20 29 7b 0a 20 20 20 20 73  imple") ){.    s
e3f0: 71 6c 69 74 65 33 46 74 73 31 53 69 6d 70 6c 65  qlite3Fts1Simple
e400: 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 28  TokenizerModule(
e410: 26 6d 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  &m);.  }else if(
e420: 20 73 74 61 72 74 73 57 69 74 68 28 73 70 65 63   startsWith(spec
e430: 2d 3e 61 7a 54 6f 6b 65 6e 69 7a 65 72 5b 30 5d  ->azTokenizer[0]
e440: 2c 20 22 70 6f 72 74 65 72 22 29 20 29 7b 0a 20  , "porter") ){. 
e450: 20 20 20 73 71 6c 69 74 65 33 46 74 73 31 50 6f     sqlite3Fts1Po
e460: 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64  rterTokenizerMod
e470: 75 6c 65 28 26 6d 29 3b 0a 20 20 7d 65 6c 73 65  ule(&m);.  }else
e480: 7b 0a 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73  {.    *pzErr = s
e490: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
e4a0: 75 6e 6b 6e 6f 77 6e 20 74 6f 6b 65 6e 69 7a 65  unknown tokenize
e4b0: 72 3a 20 25 73 22 2c 20 73 70 65 63 2d 3e 61 7a  r: %s", spec->az
e4c0: 54 6f 6b 65 6e 69 7a 65 72 5b 30 5d 29 3b 0a 20  Tokenizer[0]);. 
e4d0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45     rc = SQLITE_E
e4e0: 52 52 4f 52 3b 0a 20 20 20 20 67 6f 74 6f 20 65  RROR;.    goto e
e4f0: 72 72 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 6e 3d  rr;.  }.  for(n=
e500: 30 3b 20 73 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e  0; spec->azToken
e510: 69 7a 65 72 5b 6e 5d 3b 20 6e 2b 2b 29 7b 7d 0a  izer[n]; n++){}.
e520: 20 20 69 66 28 20 6e 20 29 7b 0a 20 20 20 20 72    if( n ){.    r
e530: 63 20 3d 20 6d 2d 3e 78 43 72 65 61 74 65 28 6e  c = m->xCreate(n
e540: 2d 31 2c 20 28 63 6f 6e 73 74 20 63 68 61 72 2a  -1, (const char*
e550: 63 6f 6e 73 74 2a 29 26 73 70 65 63 2d 3e 61 7a  const*)&spec->az
e560: 54 6f 6b 65 6e 69 7a 65 72 5b 31 5d 2c 0a 20 20  Tokenizer[1],.  
e570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e580: 20 20 26 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72    &v->pTokenizer
e590: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
e5a0: 72 63 20 3d 20 6d 2d 3e 78 43 72 65 61 74 65 28  rc = m->xCreate(
e5b0: 30 2c 20 30 2c 20 26 76 2d 3e 70 54 6f 6b 65 6e  0, 0, &v->pToken
e5c0: 69 7a 65 72 29 3b 0a 20 20 7d 0a 20 20 69 66 28  izer);.  }.  if(
e5d0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
e5e0: 20 67 6f 74 6f 20 65 72 72 3b 0a 20 20 76 2d 3e   goto err;.  v->
e5f0: 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e 70 4d 6f 64  pTokenizer->pMod
e600: 75 6c 65 20 3d 20 6d 3b 0a 0a 20 20 2f 2a 20 54  ule = m;..  /* T
e610: 4f 44 4f 3a 20 76 65 72 69 66 79 20 74 68 65 20  ODO: verify the 
e620: 65 78 69 73 74 65 6e 63 65 20 6f 66 20 62 61 63  existence of bac
e630: 6b 69 6e 67 20 74 61 62 6c 65 73 20 66 6f 6f 5f  king tables foo_
e640: 63 6f 6e 74 65 6e 74 2c 20 66 6f 6f 5f 74 65 72  content, foo_ter
e650: 6d 20 2a 2f 0a 0a 20 20 73 63 68 65 6d 61 20 3d  m */..  schema =
e660: 20 66 75 6c 6c 74 65 78 74 53 63 68 65 6d 61 28   fulltextSchema(
e670: 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 28 63 6f 6e  v->nColumn, (con
e680: 73 74 20 63 68 61 72 2a 63 6f 6e 73 74 2a 29 76  st char*const*)v
e690: 2d 3e 61 7a 43 6f 6c 75 6d 6e 2c 0a 20 20 20 20  ->azColumn,.    
e6a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e6b0: 20 20 20 20 20 20 73 70 65 63 2d 3e 7a 4e 61 6d        spec->zNam
e6c0: 65 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  e);.  rc = sqlit
e6d0: 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28  e3_declare_vtab(
e6e0: 64 62 2c 20 73 63 68 65 6d 61 29 3b 0a 20 20 73  db, schema);.  s
e6f0: 71 6c 69 74 65 33 5f 66 72 65 65 28 73 63 68 65  qlite3_free(sche
e700: 6d 61 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  ma);.  if( rc!=S
e710: 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20  QLITE_OK ) goto 
e720: 65 72 72 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 76  err;..  memset(v
e730: 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74 65  ->pFulltextState
e740: 6d 65 6e 74 73 2c 20 30 2c 20 73 69 7a 65 6f 66  ments, 0, sizeof
e750: 28 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61  (v->pFulltextSta
e760: 74 65 6d 65 6e 74 73 29 29 3b 0a 0a 20 20 2a 70  tements));..  *p
e770: 70 56 54 61 62 20 3d 20 26 76 2d 3e 62 61 73 65  pVTab = &v->base
e780: 3b 0a 20 20 54 52 41 43 45 28 28 22 46 54 53 31  ;.  TRACE(("FTS1
e790: 20 43 6f 6e 6e 65 63 74 20 25 70 5c 6e 22 2c 20   Connect %p\n", 
e7a0: 76 29 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72  v));..  return r
e7b0: 63 3b 0a 0a 65 72 72 3a 0a 20 20 66 75 6c 6c 74  c;..err:.  fullt
e7c0: 65 78 74 5f 76 74 61 62 5f 64 65 73 74 72 6f 79  ext_vtab_destroy
e7d0: 28 76 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  (v);.  return rc
e7e0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
e7f0: 66 75 6c 6c 74 65 78 74 43 6f 6e 6e 65 63 74 28  fulltextConnect(
e800: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a  .  sqlite3 *db,.
e810: 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20    void *pAux,.  
e820: 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20  int argc, const 
e830: 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76  char *const*argv
e840: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  ,.  sqlite3_vtab
e850: 20 2a 2a 70 70 56 54 61 62 2c 0a 20 20 63 68 61   **ppVTab,.  cha
e860: 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 54  r **pzErr.){.  T
e870: 61 62 6c 65 53 70 65 63 20 73 70 65 63 3b 0a 20  ableSpec spec;. 
e880: 20 69 6e 74 20 72 63 20 3d 20 70 61 72 73 65 53   int rc = parseS
e890: 70 65 63 28 26 73 70 65 63 2c 20 61 72 67 63 2c  pec(&spec, argc,
e8a0: 20 61 72 67 76 2c 20 70 7a 45 72 72 29 3b 0a 20   argv, pzErr);. 
e8b0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
e8c0: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
e8d0: 0a 20 20 72 63 20 3d 20 63 6f 6e 73 74 72 75 63  .  rc = construc
e8e0: 74 56 74 61 62 28 64 62 2c 20 26 73 70 65 63 2c  tVtab(db, &spec,
e8f0: 20 70 70 56 54 61 62 2c 20 70 7a 45 72 72 29 3b   ppVTab, pzErr);
e900: 0a 20 20 63 6c 65 61 72 54 61 62 6c 65 53 70 65  .  clearTableSpe
e910: 63 28 26 73 70 65 63 29 3b 0a 20 20 72 65 74 75  c(&spec);.  retu
e920: 72 6e 20 72 63 3b 0a 7d 0a 0a 20 20 2f 2a 20 54  rn rc;.}..  /* T
e930: 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62  he %_content tab
e940: 6c 65 20 68 6f 6c 64 73 20 74 68 65 20 74 65 78  le holds the tex
e950: 74 20 6f 66 20 65 61 63 68 20 64 6f 63 75 6d 65  t of each docume
e960: 6e 74 2c 20 77 69 74 68 0a 20 20 2a 2a 20 74 68  nt, with.  ** th
e970: 65 20 72 6f 77 69 64 20 75 73 65 64 20 61 73 20  e rowid used as 
e980: 74 68 65 20 64 6f 63 69 64 2e 0a 20 20 2a 2a 0a  the docid..  **.
e990: 20 20 2a 2a 20 54 68 65 20 25 5f 74 65 72 6d 20    ** The %_term 
e9a0: 74 61 62 6c 65 20 6d 61 70 73 20 65 61 63 68 20  table maps each 
e9b0: 74 65 72 6d 20 74 6f 20 61 20 64 6f 63 75 6d 65  term to a docume
e9c0: 6e 74 20 6c 69 73 74 20 62 6c 6f 62 0a 20 20 2a  nt list blob.  *
e9d0: 2a 20 63 6f 6e 74 61 69 6e 69 6e 67 20 65 6c 65  * containing ele
e9e0: 6d 65 6e 74 73 20 73 6f 72 74 65 64 20 62 79 20  ments sorted by 
e9f0: 61 73 63 65 6e 64 69 6e 67 20 64 6f 63 69 64 2c  ascending docid,
ea00: 20 65 61 63 68 20 65 6c 65 6d 65 6e 74 0a 20 20   each element.  
ea10: 2a 2a 20 65 6e 63 6f 64 65 64 20 61 73 3a 0a 20  ** encoded as:. 
ea20: 20 2a 2a 0a 20 20 2a 2a 20 20 20 64 6f 63 69 64   **.  **   docid
ea30: 20 76 61 72 69 6e 74 2d 65 6e 63 6f 64 65 64 0a   varint-encoded.
ea40: 20 20 2a 2a 20 20 20 74 6f 6b 65 6e 20 65 6c 65    **   token ele
ea50: 6d 65 6e 74 73 3a 0a 20 20 2a 2a 20 20 20 20 20  ments:.  **     
ea60: 70 6f 73 69 74 69 6f 6e 2b 31 20 76 61 72 69 6e  position+1 varin
ea70: 74 2d 65 6e 63 6f 64 65 64 20 61 73 20 64 65 6c  t-encoded as del
ea80: 74 61 20 66 72 6f 6d 20 70 72 65 76 69 6f 75 73  ta from previous
ea90: 20 70 6f 73 69 74 69 6f 6e 0a 20 20 2a 2a 20 20   position.  **  
eaa0: 20 20 20 73 74 61 72 74 20 6f 66 66 73 65 74 20     start offset 
eab0: 76 61 72 69 6e 74 2d 65 6e 63 6f 64 65 64 20 61  varint-encoded a
eac0: 73 20 64 65 6c 74 61 20 66 72 6f 6d 20 70 72 65  s delta from pre
ead0: 76 69 6f 75 73 20 73 74 61 72 74 20 6f 66 66 73  vious start offs
eae0: 65 74 0a 20 20 2a 2a 20 20 20 20 20 65 6e 64 20  et.  **     end 
eaf0: 6f 66 66 73 65 74 20 76 61 72 69 6e 74 2d 65 6e  offset varint-en
eb00: 63 6f 64 65 64 20 61 73 20 64 65 6c 74 61 20 66  coded as delta f
eb10: 72 6f 6d 20 73 74 61 72 74 20 6f 66 66 73 65 74  rom start offset
eb20: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 20 73  .  **.  ** The s
eb30: 65 6e 74 69 6e 65 6c 20 70 6f 73 69 74 69 6f 6e  entinel position
eb40: 20 6f 66 20 30 20 69 6e 64 69 63 61 74 65 73 20   of 0 indicates 
eb50: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 74  the end of the t
eb60: 6f 6b 65 6e 20 6c 69 73 74 2e 0a 20 20 2a 2a 0a  oken list..  **.
eb70: 20 20 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c 6c    ** Additionall
eb80: 79 2c 20 64 6f 63 6c 69 73 74 20 62 6c 6f 62 73  y, doclist blobs
eb90: 20 61 72 65 20 63 68 75 6e 6b 65 64 20 69 6e 74   are chunked int
eba0: 6f 20 6d 75 6c 74 69 70 6c 65 20 73 65 67 6d 65  o multiple segme
ebb0: 6e 74 73 2c 0a 20 20 2a 2a 20 75 73 69 6e 67 20  nts,.  ** using 
ebc0: 73 65 67 6d 65 6e 74 20 74 6f 20 6f 72 64 65 72  segment to order
ebd0: 20 74 68 65 20 73 65 67 6d 65 6e 74 73 2e 20 20   the segments.  
ebe0: 4e 65 77 20 65 6c 65 6d 65 6e 74 73 20 61 72 65  New elements are
ebf0: 20 61 64 64 65 64 20 74 6f 0a 20 20 2a 2a 20 74   added to.  ** t
ec00: 68 65 20 73 65 67 6d 65 6e 74 20 61 74 20 73 65  he segment at se
ec10: 67 6d 65 6e 74 20 30 2c 20 75 6e 74 69 6c 20 69  gment 0, until i
ec20: 74 20 65 78 63 65 65 64 73 20 43 48 55 4e 4b 5f  t exceeds CHUNK_
ec30: 4d 41 58 2e 20 20 54 68 65 6e 0a 20 20 2a 2a 20  MAX.  Then.  ** 
ec40: 73 65 67 6d 65 6e 74 20 30 20 69 73 20 64 65 6c  segment 0 is del
ec50: 65 74 65 64 2c 20 61 6e 64 20 74 68 65 20 64 6f  eted, and the do
ec60: 63 6c 69 73 74 20 69 73 20 69 6e 73 65 72 74 65  clist is inserte
ec70: 64 20 61 74 20 73 65 67 6d 65 6e 74 20 31 2e 0a  d at segment 1..
ec80: 20 20 2a 2a 20 49 66 20 74 68 65 72 65 20 69 73    ** If there is
ec90: 20 61 6c 72 65 61 64 79 20 61 20 64 6f 63 6c 69   already a docli
eca0: 73 74 20 61 74 20 73 65 67 6d 65 6e 74 20 31 2c  st at segment 1,
ecb0: 20 74 68 65 20 73 65 67 6d 65 6e 74 20 30 20 64   the segment 0 d
ecc0: 6f 63 6c 69 73 74 0a 20 20 2a 2a 20 69 73 20 6d  oclist.  ** is m
ecd0: 65 72 67 65 64 20 77 69 74 68 20 69 74 2c 20 74  erged with it, t
ece0: 68 65 20 73 65 67 6d 65 6e 74 20 31 20 64 6f 63  he segment 1 doc
ecf0: 6c 69 73 74 20 69 73 20 64 65 6c 65 74 65 64 2c  list is deleted,
ed00: 20 61 6e 64 20 74 68 65 0a 20 20 2a 2a 20 6d 65   and the.  ** me
ed10: 72 67 65 64 20 64 6f 63 6c 69 73 74 20 69 73 20  rged doclist is 
ed20: 69 6e 73 65 72 74 65 64 20 61 74 20 73 65 67 6d  inserted at segm
ed30: 65 6e 74 20 32 2c 20 72 65 70 65 61 74 69 6e 67  ent 2, repeating
ed40: 20 74 68 6f 73 65 0a 20 20 2a 2a 20 6f 70 65 72   those.  ** oper
ed50: 61 74 69 6f 6e 73 20 75 6e 74 69 6c 20 61 6e 20  ations until an 
ed60: 69 6e 73 65 72 74 20 73 75 63 63 65 65 64 73 2e  insert succeeds.
ed70: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 53 69 6e 63 65  .  **.  ** Since
ed80: 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65 20   this structure 
ed90: 64 6f 65 73 6e 27 74 20 61 6c 6c 6f 77 20 75 73  doesn't allow us
eda0: 20 74 6f 20 75 70 64 61 74 65 20 65 6c 65 6d 65   to update eleme
edb0: 6e 74 73 20 69 6e 20 70 6c 61 63 65 0a 20 20 2a  nts in place.  *
edc0: 2a 20 69 6e 20 63 61 73 65 20 6f 66 20 64 65 6c  * in case of del
edd0: 65 74 69 6f 6e 20 6f 72 20 75 70 64 61 74 65 2c  etion or update,
ede0: 20 74 68 65 73 65 20 61 72 65 20 73 69 6d 70 6c   these are simpl
edf0: 79 20 77 72 69 74 74 65 6e 20 74 6f 0a 20 20 2a  y written to.  *
ee00: 2a 20 73 65 67 6d 65 6e 74 20 30 20 28 77 69 74  * segment 0 (wit
ee10: 68 20 61 6e 20 65 6d 70 74 79 20 74 6f 6b 65 6e  h an empty token
ee20: 20 6c 69 73 74 20 69 6e 20 63 61 73 65 20 6f 66   list in case of
ee30: 20 64 65 6c 65 74 69 6f 6e 29 2c 20 77 69 74 68   deletion), with
ee40: 0a 20 20 2a 2a 20 64 6f 63 4c 69 73 74 41 63 63  .  ** docListAcc
ee50: 75 6d 75 6c 61 74 65 28 29 20 74 61 6b 69 6e 67  umulate() taking
ee60: 20 63 61 72 65 20 74 6f 20 72 65 74 61 69 6e 20   care to retain 
ee70: 6c 6f 77 65 72 2d 73 65 67 6d 65 6e 74 0a 20 20  lower-segment.  
ee80: 2a 2a 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69  ** information i
ee90: 6e 20 70 72 65 66 65 72 65 6e 63 65 20 74 6f 20  n preference to 
eea0: 68 69 67 68 65 72 2d 73 65 67 6d 65 6e 74 20 69  higher-segment i
eeb0: 6e 66 6f 72 6d 61 74 69 6f 6e 2e 0a 20 20 2a 2f  nformation..  */
eec0: 0a 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73  .  /* TODO(shess
eed0: 29 20 50 72 6f 76 69 64 65 20 61 20 56 41 43 55  ) Provide a VACU
eee0: 55 4d 20 74 79 70 65 20 6f 70 65 72 61 74 69 6f  UM type operatio
eef0: 6e 20 77 68 69 63 68 20 62 6f 74 68 20 72 65 6d  n which both rem
ef00: 6f 76 65 73 0a 20 20 2a 2a 20 64 65 6c 65 74 65  oves.  ** delete
ef10: 64 20 65 6c 65 6d 65 6e 74 73 20 77 68 69 63 68  d elements which
ef20: 20 61 72 65 20 6e 6f 20 6c 6f 6e 67 65 72 20 6e   are no longer n
ef30: 65 63 65 73 73 61 72 79 2c 20 61 6e 64 20 64 75  ecessary, and du
ef40: 70 6c 69 63 61 74 65 64 0a 20 20 2a 2a 20 65 6c  plicated.  ** el
ef50: 65 6d 65 6e 74 73 2e 20 20 49 20 73 75 73 70 65  ements.  I suspe
ef60: 63 74 20 74 68 69 73 20 77 69 6c 6c 20 70 72 6f  ct this will pro
ef70: 62 61 62 6c 79 20 6e 6f 74 20 62 65 20 6e 65 63  bably not be nec
ef80: 65 73 73 61 72 79 20 69 6e 0a 20 20 2a 2a 20 70  essary in.  ** p
ef90: 72 61 63 74 69 63 65 2c 20 74 68 6f 75 67 68 2e  ractice, though.
efa0: 0a 20 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  .  */.static int
efb0: 20 66 75 6c 6c 74 65 78 74 43 72 65 61 74 65 28   fulltextCreate(
efc0: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 76 6f 69  sqlite3 *db, voi
efd0: 64 20 2a 70 41 75 78 2c 0a 20 20 20 20 20 20 20  d *pAux,.       
efe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
eff0: 20 20 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e     int argc, con
f000: 73 74 20 63 68 61 72 20 2a 20 63 6f 6e 73 74 20  st char * const 
f010: 2a 61 72 67 76 2c 0a 20 20 20 20 20 20 20 20 20  *argv,.         
f020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f030: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a   sqlite3_vtab **
f040: 70 70 56 54 61 62 2c 20 63 68 61 72 20 2a 2a 70  ppVTab, char **p
f050: 7a 45 72 72 29 7b 0a 20 20 69 6e 74 20 72 63 3b  zErr){.  int rc;
f060: 0a 20 20 54 61 62 6c 65 53 70 65 63 20 73 70 65  .  TableSpec spe
f070: 63 3b 0a 20 20 53 74 72 69 6e 67 42 75 66 66 65  c;.  StringBuffe
f080: 72 20 73 63 68 65 6d 61 3b 0a 20 20 54 52 41 43  r schema;.  TRAC
f090: 45 28 28 22 46 54 53 31 20 43 72 65 61 74 65 5c  E(("FTS1 Create\
f0a0: 6e 22 29 29 3b 0a 0a 20 20 72 63 20 3d 20 70 61  n"));..  rc = pa
f0b0: 72 73 65 53 70 65 63 28 26 73 70 65 63 2c 20 61  rseSpec(&spec, a
f0c0: 72 67 63 2c 20 61 72 67 76 2c 20 70 7a 45 72 72  rgc, argv, pzErr
f0d0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
f0e0: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
f0f0: 72 63 3b 0a 0a 20 20 69 6e 69 74 53 74 72 69 6e  rc;..  initStrin
f100: 67 42 75 66 66 65 72 28 26 73 63 68 65 6d 61 29  gBuffer(&schema)
f110: 3b 0a 20 20 61 70 70 65 6e 64 28 26 73 63 68 65  ;.  append(&sche
f120: 6d 61 2c 20 22 43 52 45 41 54 45 20 54 41 42 4c  ma, "CREATE TABL
f130: 45 20 25 5f 63 6f 6e 74 65 6e 74 28 22 29 3b 0a  E %_content(");.
f140: 20 20 61 70 70 65 6e 64 4c 69 73 74 28 26 73 63    appendList(&sc
f150: 68 65 6d 61 2c 20 73 70 65 63 2e 6e 43 6f 6c 75  hema, spec.nColu
f160: 6d 6e 2c 20 73 70 65 63 2e 61 7a 43 6f 6e 74 65  mn, spec.azConte
f170: 6e 74 43 6f 6c 75 6d 6e 29 3b 0a 20 20 61 70 70  ntColumn);.  app
f180: 65 6e 64 28 26 73 63 68 65 6d 61 2c 20 22 29 22  end(&schema, ")"
f190: 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 5f 65 78  );.  rc = sql_ex
f1a0: 65 63 28 64 62 2c 20 73 70 65 63 2e 7a 44 62 2c  ec(db, spec.zDb,
f1b0: 20 73 70 65 63 2e 7a 4e 61 6d 65 2c 20 73 63 68   spec.zName, sch
f1c0: 65 6d 61 2e 73 29 3b 0a 20 20 66 72 65 65 28 73  ema.s);.  free(s
f1d0: 63 68 65 6d 61 2e 73 29 3b 0a 20 20 69 66 28 20  chema.s);.  if( 
f1e0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
f1f0: 67 6f 74 6f 20 6f 75 74 3b 0a 0a 20 20 72 63 20  goto out;..  rc 
f200: 3d 20 73 71 6c 5f 65 78 65 63 28 64 62 2c 20 73  = sql_exec(db, s
f210: 70 65 63 2e 7a 44 62 2c 20 73 70 65 63 2e 7a 4e  pec.zDb, spec.zN
f220: 61 6d 65 2c 0a 20 20 20 20 22 63 72 65 61 74 65  ame,.    "create
f230: 20 74 61 62 6c 65 20 25 5f 74 65 72 6d 28 74 65   table %_term(te
f240: 72 6d 20 74 65 78 74 2c 20 73 65 67 6d 65 6e 74  rm text, segment
f250: 20 69 6e 74 65 67 65 72 2c 20 64 6f 63 6c 69 73   integer, doclis
f260: 74 20 62 6c 6f 62 2c 20 22 0a 20 20 20 20 20 20  t blob, ".      
f270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f280: 20 20 22 70 72 69 6d 61 72 79 20 6b 65 79 28 74    "primary key(t
f290: 65 72 6d 2c 20 73 65 67 6d 65 6e 74 29 29 3b 22  erm, segment));"
f2a0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
f2b0: 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 6f 75  ITE_OK ) goto ou
f2c0: 74 3b 0a 0a 20 20 72 63 20 3d 20 63 6f 6e 73 74  t;..  rc = const
f2d0: 72 75 63 74 56 74 61 62 28 64 62 2c 20 26 73 70  ructVtab(db, &sp
f2e0: 65 63 2c 20 70 70 56 54 61 62 2c 20 70 7a 45 72  ec, ppVTab, pzEr
f2f0: 72 29 3b 0a 0a 6f 75 74 3a 0a 20 20 63 6c 65 61  r);..out:.  clea
f300: 72 54 61 62 6c 65 53 70 65 63 28 26 73 70 65 63  rTableSpec(&spec
f310: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
f320: 7d 0a 0a 2f 2a 20 44 65 63 69 64 65 20 68 6f 77  }../* Decide how
f330: 20 74 6f 20 68 61 6e 64 6c 65 20 61 6e 20 53 51   to handle an SQ
f340: 4c 20 71 75 65 72 79 2e 20 2a 2f 0a 73 74 61 74  L query. */.stat
f350: 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 42  ic int fulltextB
f360: 65 73 74 49 6e 64 65 78 28 73 71 6c 69 74 65 33  estIndex(sqlite3
f370: 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71  _vtab *pVTab, sq
f380: 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f  lite3_index_info
f390: 20 2a 70 49 6e 66 6f 29 7b 0a 20 20 69 6e 74 20   *pInfo){.  int 
f3a0: 69 3b 0a 20 20 54 52 41 43 45 28 28 22 46 54 53  i;.  TRACE(("FTS
f3b0: 31 20 42 65 73 74 49 6e 64 65 78 5c 6e 22 29 29  1 BestIndex\n"))
f3c0: 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  ;..  for(i=0; i<
f3d0: 70 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69  pInfo->nConstrai
f3e0: 6e 74 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 63 6f  nt; ++i){.    co
f3f0: 6e 73 74 20 73 74 72 75 63 74 20 73 71 6c 69 74  nst struct sqlit
f400: 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61  e3_index_constra
f410: 69 6e 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e 74  int *pConstraint
f420: 3b 0a 20 20 20 20 70 43 6f 6e 73 74 72 61 69 6e  ;.    pConstrain
f430: 74 20 3d 20 26 70 49 6e 66 6f 2d 3e 61 43 6f 6e  t = &pInfo->aCon
f440: 73 74 72 61 69 6e 74 5b 69 5d 3b 0a 20 20 20 20  straint[i];.    
f450: 69 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d  if( pConstraint-
f460: 3e 75 73 61 62 6c 65 20 29 20 7b 0a 20 20 20 20  >usable ) {.    
f470: 20 20 69 66 28 20 70 43 6f 6e 73 74 72 61 69 6e    if( pConstrain
f480: 74 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 2d 31 20 26  t->iColumn==-1 &
f490: 26 0a 20 20 20 20 20 20 20 20 20 20 70 43 6f 6e  &.          pCon
f4a0: 73 74 72 61 69 6e 74 2d 3e 6f 70 3d 3d 53 51 4c  straint->op==SQL
f4b0: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
f4c0: 41 49 4e 54 5f 45 51 20 29 7b 0a 20 20 20 20 20  AINT_EQ ){.     
f4d0: 20 20 20 70 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d     pInfo->idxNum
f4e0: 20 3d 20 51 55 45 52 59 5f 52 4f 57 49 44 3b 20   = QUERY_ROWID; 
f4f0: 20 20 20 20 20 2f 2a 20 6c 6f 6f 6b 75 70 20 62       /* lookup b
f500: 79 20 72 6f 77 69 64 20 2a 2f 0a 20 20 20 20 20  y rowid */.     
f510: 20 20 20 54 52 41 43 45 28 28 22 46 54 53 31 20     TRACE(("FTS1 
f520: 51 55 45 52 59 5f 52 4f 57 49 44 5c 6e 22 29 29  QUERY_ROWID\n"))
f530: 3b 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 69  ;.      } else i
f540: 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e  f( pConstraint->
f550: 69 43 6f 6c 75 6d 6e 3e 3d 30 20 26 26 0a 20 20  iColumn>=0 &&.  
f560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
f570: 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 3d 3d  Constraint->op==
f580: 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e  SQLITE_INDEX_CON
f590: 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 20 29 7b  STRAINT_MATCH ){
f5a0: 0a 20 20 20 20 20 20 20 20 2f 2a 20 66 75 6c 6c  .        /* full
f5b0: 2d 74 65 78 74 20 73 65 61 72 63 68 20 2a 2f 0a  -text search */.
f5c0: 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 69          pInfo->i
f5d0: 64 78 4e 75 6d 20 3d 20 51 55 45 52 59 5f 46 55  dxNum = QUERY_FU
f5e0: 4c 4c 54 45 58 54 20 2b 20 70 43 6f 6e 73 74 72  LLTEXT + pConstr
f5f0: 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20  aint->iColumn;. 
f600: 20 20 20 20 20 20 20 54 52 41 43 45 28 28 22 46         TRACE(("F
f610: 54 53 31 20 51 55 45 52 59 5f 46 55 4c 4c 54 45  TS1 QUERY_FULLTE
f620: 58 54 20 25 64 5c 6e 22 2c 20 70 43 6f 6e 73 74  XT %d\n", pConst
f630: 72 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 29 29  raint->iColumn))
f640: 3b 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 63  ;.      } else c
f650: 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20 20 20 20 20  ontinue;..      
f660: 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  pInfo->aConstrai
f670: 6e 74 55 73 61 67 65 5b 69 5d 2e 61 72 67 76 49  ntUsage[i].argvI
f680: 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20 20 20 20  ndex = 1;.      
f690: 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  pInfo->aConstrai
f6a0: 6e 74 55 73 61 67 65 5b 69 5d 2e 6f 6d 69 74 20  ntUsage[i].omit 
f6b0: 3d 20 31 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 41  = 1;..      /* A
f6c0: 6e 20 61 72 62 69 74 72 61 72 79 20 76 61 6c 75  n arbitrary valu
f6d0: 65 20 66 6f 72 20 6e 6f 77 2e 0a 20 20 20 20 20  e for now..     
f6e0: 20 20 2a 20 54 4f 44 4f 3a 20 50 65 72 68 61 70    * TODO: Perhap
f6f0: 73 20 72 6f 77 69 64 20 6d 61 74 63 68 65 73 20  s rowid matches 
f700: 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e 73 69 64  should be consid
f710: 65 72 65 64 20 63 68 65 61 70 65 72 20 74 68 61  ered cheaper tha
f720: 6e 0a 20 20 20 20 20 20 20 2a 20 66 75 6c 6c 2d  n.       * full-
f730: 74 65 78 74 20 73 65 61 72 63 68 65 73 2e 20 2a  text searches. *
f740: 2f 0a 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 65  /.      pInfo->e
f750: 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31  stimatedCost = 1
f760: 2e 30 3b 20 20 20 0a 0a 20 20 20 20 20 20 72 65  .0;   ..      re
f770: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
f780: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 49 6e 66      }.  }.  pInf
f790: 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 51 55 45 52  o->idxNum = QUER
f7a0: 59 5f 47 45 4e 45 52 49 43 3b 0a 20 20 72 65 74  Y_GENERIC;.  ret
f7b0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
f7c0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75 6c  ..static int ful
f7d0: 6c 74 65 78 74 44 69 73 63 6f 6e 6e 65 63 74 28  ltextDisconnect(
f7e0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
f7f0: 54 61 62 29 7b 0a 20 20 54 52 41 43 45 28 28 22  Tab){.  TRACE(("
f800: 46 54 53 31 20 44 69 73 63 6f 6e 6e 65 63 74 20  FTS1 Disconnect 
f810: 25 70 5c 6e 22 2c 20 70 56 54 61 62 29 29 3b 0a  %p\n", pVTab));.
f820: 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 5f    fulltext_vtab_
f830: 64 65 73 74 72 6f 79 28 28 66 75 6c 6c 74 65 78  destroy((fulltex
f840: 74 5f 76 74 61 62 20 2a 29 70 56 54 61 62 29 3b  t_vtab *)pVTab);
f850: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
f860: 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  _OK;.}..static i
f870: 6e 74 20 66 75 6c 6c 74 65 78 74 44 65 73 74 72  nt fulltextDestr
f880: 6f 79 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  oy(sqlite3_vtab 
f890: 2a 70 56 54 61 62 29 7b 0a 20 20 66 75 6c 6c 74  *pVTab){.  fullt
f8a0: 65 78 74 5f 76 74 61 62 20 2a 76 20 3d 20 28 66  ext_vtab *v = (f
f8b0: 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 70  ulltext_vtab *)p
f8c0: 56 54 61 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  VTab;.  int rc;.
f8d0: 0a 20 20 54 52 41 43 45 28 28 22 46 54 53 31 20  .  TRACE(("FTS1 
f8e0: 44 65 73 74 72 6f 79 20 25 70 5c 6e 22 2c 20 70  Destroy %p\n", p
f8f0: 56 54 61 62 29 29 3b 0a 20 20 72 63 20 3d 20 73  VTab));.  rc = s
f900: 71 6c 5f 65 78 65 63 28 76 2d 3e 64 62 2c 20 76  ql_exec(v->db, v
f910: 2d 3e 7a 44 62 2c 20 76 2d 3e 7a 4e 61 6d 65 2c  ->zDb, v->zName,
f920: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
f930: 20 22 64 72 6f 70 20 74 61 62 6c 65 20 69 66 20   "drop table if 
f940: 65 78 69 73 74 73 20 25 5f 63 6f 6e 74 65 6e 74  exists %_content
f950: 3b 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ;".             
f960: 20 20 20 22 64 72 6f 70 20 74 61 62 6c 65 20 69     "drop table i
f970: 66 20 65 78 69 73 74 73 20 25 5f 74 65 72 6d 3b  f exists %_term;
f980: 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ".              
f990: 20 20 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53    );.  if( rc!=S
f9a0: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
f9b0: 6e 20 72 63 3b 0a 0a 20 20 66 75 6c 6c 74 65 78  n rc;..  fulltex
f9c0: 74 5f 76 74 61 62 5f 64 65 73 74 72 6f 79 28 28  t_vtab_destroy((
f9d0: 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29  fulltext_vtab *)
f9e0: 70 56 54 61 62 29 3b 0a 20 20 72 65 74 75 72 6e  pVTab);.  return
f9f0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73   SQLITE_OK;.}..s
fa00: 74 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65  tatic int fullte
fa10: 78 74 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76  xtOpen(sqlite3_v
fa20: 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71 6c 69  tab *pVTab, sqli
fa30: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
fa40: 2a 2a 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 66  **ppCursor){.  f
fa50: 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a  ulltext_cursor *
fa60: 63 3b 0a 0a 20 20 63 20 3d 20 28 66 75 6c 6c 74  c;..  c = (fullt
fa70: 65 78 74 5f 63 75 72 73 6f 72 20 2a 29 20 63 61  ext_cursor *) ca
fa80: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 66 75 6c 6c  lloc(sizeof(full
fa90: 74 65 78 74 5f 63 75 72 73 6f 72 29 2c 20 31 29  text_cursor), 1)
faa0: 3b 0a 20 20 2f 2a 20 73 71 6c 69 74 65 20 77 69  ;.  /* sqlite wi
fab0: 6c 6c 20 69 6e 69 74 69 61 6c 69 7a 65 20 63 2d  ll initialize c-
fac0: 3e 62 61 73 65 20 2a 2f 0a 20 20 2a 70 70 43 75  >base */.  *ppCu
fad0: 72 73 6f 72 20 3d 20 26 63 2d 3e 62 61 73 65 3b  rsor = &c->base;
fae0: 0a 20 20 54 52 41 43 45 28 28 22 46 54 53 31 20  .  TRACE(("FTS1 
faf0: 4f 70 65 6e 20 25 70 3a 20 25 70 5c 6e 22 2c 20  Open %p: %p\n", 
fb00: 70 56 54 61 62 2c 20 63 29 29 3b 0a 0a 20 20 72  pVTab, c));..  r
fb10: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
fb20: 0a 7d 0a 0a 0a 2f 2a 20 46 72 65 65 20 61 6c 6c  .}.../* Free all
fb30: 20 6f 66 20 74 68 65 20 64 79 6e 61 6d 69 63 61   of the dynamica
fb40: 6c 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65  lly allocated me
fb50: 6d 6f 72 79 20 68 65 6c 64 20 62 79 20 2a 71 0a  mory held by *q.
fb60: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 71  */.static void q
fb70: 75 65 72 79 43 6c 65 61 72 28 51 75 65 72 79 20  ueryClear(Query 
fb80: 2a 71 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  *q){.  int i;.  
fb90: 66 6f 72 28 69 20 3d 20 30 3b 20 69 20 3c 20 71  for(i = 0; i < q
fba0: 2d 3e 6e 54 65 72 6d 73 3b 20 2b 2b 69 29 7b 0a  ->nTerms; ++i){.
fbb0: 20 20 20 20 66 72 65 65 28 71 2d 3e 70 54 65 72      free(q->pTer
fbc0: 6d 73 5b 69 5d 2e 70 54 65 72 6d 29 3b 0a 20 20  ms[i].pTerm);.  
fbd0: 7d 0a 20 20 66 72 65 65 28 71 2d 3e 70 54 65 72  }.  free(q->pTer
fbe0: 6d 73 29 3b 0a 20 20 6d 65 6d 73 65 74 28 71 2c  ms);.  memset(q,
fbf0: 20 30 2c 20 73 69 7a 65 6f 66 28 2a 71 29 29 3b   0, sizeof(*q));
fc00: 0a 7d 0a 0a 2f 2a 20 46 72 65 65 20 61 6c 6c 20  .}../* Free all 
fc10: 6f 66 20 74 68 65 20 64 79 6e 61 6d 69 63 61 6c  of the dynamical
fc20: 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d  ly allocated mem
fc30: 6f 72 79 20 68 65 6c 64 20 62 79 20 74 68 65 0a  ory held by the.
fc40: 2a 2a 20 53 6e 69 70 70 65 74 0a 2a 2f 0a 73 74  ** Snippet.*/.st
fc50: 61 74 69 63 20 76 6f 69 64 20 73 6e 69 70 70 65  atic void snippe
fc60: 74 43 6c 65 61 72 28 53 6e 69 70 70 65 74 20 2a  tClear(Snippet *
fc70: 70 29 7b 0a 20 20 66 72 65 65 28 70 2d 3e 61 4d  p){.  free(p->aM
fc80: 61 74 63 68 29 3b 0a 20 20 66 72 65 65 28 70 2d  atch);.  free(p-
fc90: 3e 7a 4f 66 66 73 65 74 29 3b 0a 20 20 66 72 65  >zOffset);.  fre
fca0: 65 28 70 2d 3e 7a 53 6e 69 70 70 65 74 29 3b 0a  e(p->zSnippet);.
fcb0: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73    memset(p, 0, s
fcc0: 69 7a 65 6f 66 28 2a 70 29 29 3b 0a 7d 0a 2f 2a  izeof(*p));.}./*
fcd0: 0a 2a 2a 20 41 70 70 65 6e 64 20 61 20 73 69 6e  .** Append a sin
fce0: 67 6c 65 20 65 6e 74 72 79 20 74 6f 20 74 68 65  gle entry to the
fcf0: 20 70 2d 3e 61 4d 61 74 63 68 5b 5d 20 6c 6f 67   p->aMatch[] log
fd00: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
fd10: 20 73 6e 69 70 70 65 74 41 70 70 65 6e 64 4d 61   snippetAppendMa
fd20: 74 63 68 28 0a 20 20 53 6e 69 70 70 65 74 20 2a  tch(.  Snippet *
fd30: 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p,              
fd40: 20 2f 2a 20 41 70 70 65 6e 64 20 74 68 65 20 65   /* Append the e
fd50: 6e 74 72 79 20 74 6f 20 74 68 69 73 20 73 6e 69  ntry to this sni
fd60: 70 70 65 74 20 2a 2f 0a 20 20 69 6e 74 20 69 43  ppet */.  int iC
fd70: 6f 6c 2c 20 69 6e 74 20 69 54 65 72 6d 2c 20 20  ol, int iTerm,  
fd80: 20 20 20 20 2f 2a 20 54 68 65 20 63 6f 6c 75 6d      /* The colum
fd90: 6e 20 61 6e 64 20 71 75 65 72 79 20 74 65 72 6d  n and query term
fda0: 20 2a 2f 0a 20 20 69 6e 74 20 69 53 74 61 72 74   */.  int iStart
fdb0: 2c 20 69 6e 74 20 6e 42 79 74 65 20 20 20 20 20  , int nByte     
fdc0: 2f 2a 20 4f 66 66 73 65 74 20 61 6e 64 20 73 69  /* Offset and si
fdd0: 7a 65 20 6f 66 20 74 68 65 20 6d 61 74 63 68 20  ze of the match 
fde0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  */.){.  int i;. 
fdf0: 20 73 74 72 75 63 74 20 73 6e 69 70 70 65 74 4d   struct snippetM
fe00: 61 74 63 68 20 2a 70 4d 61 74 63 68 3b 0a 20 20  atch *pMatch;.  
fe10: 69 66 28 20 70 2d 3e 6e 4d 61 74 63 68 2b 31 3e  if( p->nMatch+1>
fe20: 3d 70 2d 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20 20  =p->nAlloc ){.  
fe30: 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 70 2d    p->nAlloc = p-
fe40: 3e 6e 41 6c 6c 6f 63 2a 32 20 2b 20 31 30 3b 0a  >nAlloc*2 + 10;.
fe50: 20 20 20 20 70 2d 3e 61 4d 61 74 63 68 20 3d 20      p->aMatch = 
fe60: 72 65 61 6c 6c 6f 63 28 70 2d 3e 61 4d 61 74 63  realloc(p->aMatc
fe70: 68 2c 20 70 2d 3e 6e 41 6c 6c 6f 63 2a 73 69 7a  h, p->nAlloc*siz
fe80: 65 6f 66 28 70 2d 3e 61 4d 61 74 63 68 5b 30 5d  eof(p->aMatch[0]
fe90: 29 20 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e  ) );.    if( p->
fea0: 61 4d 61 74 63 68 3d 3d 30 20 29 7b 0a 20 20 20  aMatch==0 ){.   
feb0: 20 20 20 70 2d 3e 6e 4d 61 74 63 68 20 3d 20 30     p->nMatch = 0
fec0: 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c 6f  ;.      p->nAllo
fed0: 63 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 65 74  c = 0;.      ret
fee0: 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  urn;.    }.  }. 
fef0: 20 69 20 3d 20 70 2d 3e 6e 4d 61 74 63 68 2b 2b   i = p->nMatch++
ff00: 3b 0a 20 20 70 4d 61 74 63 68 20 3d 20 26 70 2d  ;.  pMatch = &p-
ff10: 3e 61 4d 61 74 63 68 5b 69 5d 3b 0a 20 20 70 4d  >aMatch[i];.  pM
ff20: 61 74 63 68 2d 3e 69 43 6f 6c 20 3d 20 69 43 6f  atch->iCol = iCo
ff30: 6c 3b 0a 20 20 70 4d 61 74 63 68 2d 3e 69 54 65  l;.  pMatch->iTe
ff40: 72 6d 20 3d 20 69 54 65 72 6d 3b 0a 20 20 70 4d  rm = iTerm;.  pM
ff50: 61 74 63 68 2d 3e 69 53 74 61 72 74 20 3d 20 69  atch->iStart = i
ff60: 53 74 61 72 74 3b 0a 20 20 70 4d 61 74 63 68 2d  Start;.  pMatch-
ff70: 3e 6e 42 79 74 65 20 3d 20 6e 42 79 74 65 3b 0a  >nByte = nByte;.
ff80: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 69 7a 69 6e 67 20  }../*.** Sizing 
ff90: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 6f 72 20  information for 
ffa0: 74 68 65 20 63 69 72 63 75 6c 61 72 20 62 75 66  the circular buf
ffb0: 66 65 72 20 75 73 65 64 20 69 6e 20 73 6e 69 70  fer used in snip
ffc0: 70 65 74 4f 66 66 73 65 74 73 4f 66 43 6f 6c 75  petOffsetsOfColu
ffd0: 6d 6e 28 29 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  mn().*/.#define 
ffe0: 46 54 53 31 5f 52 4f 54 4f 52 5f 53 5a 20 20 20  FTS1_ROTOR_SZ   
fff0: 28 33 32 29 0a 23 64 65 66 69 6e 65 20 46 54 53  (32).#define FTS
10000 31 5f 52 4f 54 4f 52 5f 4d 41 53 4b 20 28 46 54  1_ROTOR_MASK (FT
10010 53 31 5f 52 4f 54 4f 52 5f 53 5a 2d 31 29 0a 0a  S1_ROTOR_SZ-1)..
10020 2f 2a 0a 2a 2a 20 41 64 64 20 65 6e 74 72 69 65  /*.** Add entrie
10030 73 20 74 6f 20 70 53 6e 69 70 70 65 74 2d 3e 61  s to pSnippet->a
10040 4d 61 74 63 68 5b 5d 20 66 6f 72 20 65 76 65 72  Match[] for ever
10050 79 20 6d 61 74 63 68 20 74 68 61 74 20 6f 63 63  y match that occ
10060 75 72 73 20 61 67 61 69 6e 73 74 0a 2a 2a 20 64  urs against.** d
10070 6f 63 75 6d 65 6e 74 20 7a 44 6f 63 5b 30 2e 2e  ocument zDoc[0..
10080 6e 44 6f 63 2d 31 5d 20 77 68 69 63 68 20 69 73  nDoc-1] which is
10090 20 73 74 6f 72 65 64 20 69 6e 20 63 6f 6c 75 6d   stored in colum
100a0 6e 20 69 43 6f 6c 75 6d 6e 2e 0a 2a 2f 0a 73 74  n iColumn..*/.st
100b0 61 74 69 63 20 76 6f 69 64 20 73 6e 69 70 70 65  atic void snippe
100c0 74 4f 66 66 73 65 74 73 4f 66 43 6f 6c 75 6d 6e  tOffsetsOfColumn
100d0 28 0a 20 20 51 75 65 72 79 20 2a 70 51 75 65 72  (.  Query *pQuer
100e0 79 2c 0a 20 20 53 6e 69 70 70 65 74 20 2a 70 53  y,.  Snippet *pS
100f0 6e 69 70 70 65 74 2c 0a 20 20 69 6e 74 20 69 43  nippet,.  int iC
10100 6f 6c 75 6d 6e 2c 0a 20 20 63 6f 6e 73 74 20 63  olumn,.  const c
10110 68 61 72 20 2a 7a 44 6f 63 2c 0a 20 20 69 6e 74  har *zDoc,.  int
10120 20 6e 44 6f 63 0a 29 7b 0a 20 20 63 6f 6e 73 74   nDoc.){.  const
10130 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a   sqlite3_tokeniz
10140 65 72 5f 6d 6f 64 75 6c 65 20 2a 70 54 4d 6f 64  er_module *pTMod
10150 75 6c 65 3b 20 20 2f 2a 20 54 68 65 20 74 6f 6b  ule;  /* The tok
10160 65 6e 69 7a 65 72 20 6d 6f 64 75 6c 65 20 2a 2f  enizer module */
10170 0a 20 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  .  sqlite3_token
10180 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72  izer *pTokenizer
10190 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
101a0 20 54 68 65 20 73 70 65 63 69 66 69 63 20 74 6f   The specific to
101b0 6b 65 6e 69 7a 65 72 20 2a 2f 0a 20 20 73 71 6c  kenizer */.  sql
101c0 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63  ite3_tokenizer_c
101d0 75 72 73 6f 72 20 2a 70 54 43 75 72 73 6f 72 3b  ursor *pTCursor;
101e0 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 6b 65 6e          /* Token
101f0 69 7a 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20  izer cursor */. 
10200 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a   fulltext_vtab *
10210 70 56 74 61 62 3b 20 20 20 20 20 20 20 20 20 20  pVtab;          
10220 20 20 20 20 20 20 2f 2a 20 54 68 65 20 66 75 6c        /* The ful
10230 6c 20 74 65 78 74 20 69 6e 64 65 78 20 2a 2f 0a  l text index */.
10240 20 20 69 6e 74 20 6e 43 6f 6c 75 6d 6e 3b 20 20    int nColumn;  
10250 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10260 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
10270 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74   of columns in t
10280 68 65 20 69 6e 64 65 78 20 2a 2f 0a 20 20 63 6f  he index */.  co
10290 6e 73 74 20 51 75 65 72 79 54 65 72 6d 20 2a 61  nst QueryTerm *a
102a0 54 65 72 6d 3b 20 20 20 20 20 20 20 20 20 20 20  Term;           
102b0 20 20 20 2f 2a 20 51 75 65 72 79 20 73 74 72 69     /* Query stri
102c0 6e 67 20 74 65 72 6d 73 20 2a 2f 0a 20 20 69 6e  ng terms */.  in
102d0 74 20 6e 54 65 72 6d 3b 20 20 20 20 20 20 20 20  t nTerm;        
102e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
102f0 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
10300 71 75 65 72 79 20 73 74 72 69 6e 67 20 74 65 72  query string ter
10310 6d 73 20 2a 2f 20 20 0a 20 20 69 6e 74 20 69 2c  ms */  .  int i,
10320 20 6a 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   j;             
10330 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
10340 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 73 20  * Loop counters 
10350 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  */.  int rc;    
10360 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10370 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
10380 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 75 6e  urn code */.  un
10390 73 69 67 6e 65 64 20 69 6e 74 20 6d 61 74 63 68  signed int match
103a0 2c 20 70 72 65 76 4d 61 74 63 68 3b 20 20 20 20  , prevMatch;    
103b0 20 20 20 2f 2a 20 50 68 72 61 73 65 20 73 65 61     /* Phrase sea
103c0 72 63 68 20 62 69 74 6d 61 73 6b 73 20 2a 2f 0a  rch bitmasks */.
103d0 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
103e0 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20 20 20 20  oken;           
103f0 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 74         /* Next t
10400 6f 6b 65 6e 20 66 72 6f 6d 20 74 68 65 20 74 6f  oken from the to
10410 6b 65 6e 69 7a 65 72 20 2a 2f 0a 20 20 69 6e 74  kenizer */.  int
10420 20 6e 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20   nToken;        
10430 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10440 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 7a 54 6f    /* Size of zTo
10450 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 42 65  ken */.  int iBe
10460 67 69 6e 2c 20 69 45 6e 64 2c 20 69 50 6f 73 3b  gin, iEnd, iPos;
10470 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
10480 20 4f 66 66 73 65 74 73 20 6f 66 20 62 65 67 69   Offsets of begi
10490 6e 6e 69 6e 67 20 61 6e 64 20 65 6e 64 20 2a 2f  nning and end */
104a0 0a 0a 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f  ..  /* The follo
104b0 77 69 6e 67 20 76 61 72 69 61 62 6c 65 73 20 6b  wing variables k
104c0 65 65 70 20 61 20 63 69 72 63 75 6c 61 72 20 62  eep a circular b
104d0 75 66 66 65 72 20 6f 66 20 74 68 65 20 6c 61 73  uffer of the las
104e0 74 0a 20 20 2a 2a 20 66 65 77 20 74 6f 6b 65 6e  t.  ** few token
104f0 73 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  s */.  unsigned 
10500 69 6e 74 20 69 52 6f 74 6f 72 20 3d 20 30 3b 20  int iRotor = 0; 
10510 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
10520 6e 64 65 78 20 6f 66 20 63 75 72 72 65 6e 74 20  ndex of current 
10530 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69  token */.  int i
10540 52 6f 74 6f 72 42 65 67 69 6e 5b 46 54 53 31 5f  RotorBegin[FTS1_
10550 52 4f 54 4f 52 5f 53 5a 5d 3b 20 20 20 20 20 20  ROTOR_SZ];      
10560 2f 2a 20 42 65 67 69 6e 6e 69 6e 67 20 6f 66 66  /* Beginning off
10570 73 65 74 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a  set of token */.
10580 20 20 69 6e 74 20 69 52 6f 74 6f 72 4c 65 6e 5b    int iRotorLen[
10590 46 54 53 31 5f 52 4f 54 4f 52 5f 53 5a 5d 3b 20  FTS1_ROTOR_SZ]; 
105a0 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68         /* Length
105b0 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 0a 20 20   of token */..  
105c0 70 56 74 61 62 20 3d 20 70 51 75 65 72 79 2d 3e  pVtab = pQuery->
105d0 70 46 74 73 3b 0a 20 20 6e 43 6f 6c 75 6d 6e 20  pFts;.  nColumn 
105e0 3d 20 70 56 74 61 62 2d 3e 6e 43 6f 6c 75 6d 6e  = pVtab->nColumn
105f0 3b 0a 20 20 70 54 6f 6b 65 6e 69 7a 65 72 20 3d  ;.  pTokenizer =
10600 20 70 56 74 61 62 2d 3e 70 54 6f 6b 65 6e 69 7a   pVtab->pTokeniz
10610 65 72 3b 0a 20 20 70 54 4d 6f 64 75 6c 65 20 3d  er;.  pTModule =
10620 20 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e 70 4d 6f   pTokenizer->pMo
10630 64 75 6c 65 3b 0a 20 20 72 63 20 3d 20 70 54 4d  dule;.  rc = pTM
10640 6f 64 75 6c 65 2d 3e 78 4f 70 65 6e 28 70 54 6f  odule->xOpen(pTo
10650 6b 65 6e 69 7a 65 72 2c 20 7a 44 6f 63 2c 20 6e  kenizer, zDoc, n
10660 44 6f 63 2c 20 26 70 54 43 75 72 73 6f 72 29 3b  Doc, &pTCursor);
10670 0a 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75  .  if( rc ) retu
10680 72 6e 3b 0a 20 20 70 54 43 75 72 73 6f 72 2d 3e  rn;.  pTCursor->
10690 70 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 70 54 6f  pTokenizer = pTo
106a0 6b 65 6e 69 7a 65 72 3b 0a 20 20 61 54 65 72 6d  kenizer;.  aTerm
106b0 20 3d 20 70 51 75 65 72 79 2d 3e 70 54 65 72 6d   = pQuery->pTerm
106c0 73 3b 0a 20 20 6e 54 65 72 6d 20 3d 20 70 51 75  s;.  nTerm = pQu
106d0 65 72 79 2d 3e 6e 54 65 72 6d 73 3b 0a 20 20 69  ery->nTerms;.  i
106e0 66 28 20 6e 54 65 72 6d 3e 3d 46 54 53 31 5f 52  f( nTerm>=FTS1_R
106f0 4f 54 4f 52 5f 53 5a 20 29 7b 0a 20 20 20 20 6e  OTOR_SZ ){.    n
10700 54 65 72 6d 20 3d 20 46 54 53 31 5f 52 4f 54 4f  Term = FTS1_ROTO
10710 52 5f 53 5a 20 2d 20 31 3b 0a 20 20 7d 0a 20 20  R_SZ - 1;.  }.  
10720 70 72 65 76 4d 61 74 63 68 20 3d 20 30 3b 0a 20  prevMatch = 0;. 
10730 20 77 68 69 6c 65 28 31 29 7b 0a 20 20 20 20 72   while(1){.    r
10740 63 20 3d 20 70 54 4d 6f 64 75 6c 65 2d 3e 78 4e  c = pTModule->xN
10750 65 78 74 28 70 54 43 75 72 73 6f 72 2c 20 26 7a  ext(pTCursor, &z
10760 54 6f 6b 65 6e 2c 20 26 6e 54 6f 6b 65 6e 2c 20  Token, &nToken, 
10770 26 69 42 65 67 69 6e 2c 20 26 69 45 6e 64 2c 20  &iBegin, &iEnd, 
10780 26 69 50 6f 73 29 3b 0a 20 20 20 20 69 66 28 20  &iPos);.    if( 
10790 72 63 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  rc ) break;.    
107a0 69 52 6f 74 6f 72 42 65 67 69 6e 5b 69 52 6f 74  iRotorBegin[iRot
107b0 6f 72 26 46 54 53 31 5f 52 4f 54 4f 52 5f 4d 41  or&FTS1_ROTOR_MA
107c0 53 4b 5d 20 3d 20 69 42 65 67 69 6e 3b 0a 20 20  SK] = iBegin;.  
107d0 20 20 69 52 6f 74 6f 72 4c 65 6e 5b 69 52 6f 74    iRotorLen[iRot
107e0 6f 72 26 46 54 53 31 5f 52 4f 54 4f 52 5f 4d 41  or&FTS1_ROTOR_MA
107f0 53 4b 5d 20 3d 20 69 45 6e 64 2d 69 42 65 67 69  SK] = iEnd-iBegi
10800 6e 3b 0a 20 20 20 20 6d 61 74 63 68 20 3d 20 30  n;.    match = 0
10810 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
10820 3c 6e 54 65 72 6d 3b 20 69 2b 2b 29 7b 0a 20 20  <nTerm; i++){.  
10830 20 20 20 20 69 6e 74 20 69 43 6f 6c 3b 0a 20 20      int iCol;.  
10840 20 20 20 20 69 43 6f 6c 20 3d 20 61 54 65 72 6d      iCol = aTerm
10850 5b 69 5d 2e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20  [i].iColumn;.   
10860 20 20 20 69 66 28 20 69 43 6f 6c 3e 3d 30 20 26     if( iCol>=0 &
10870 26 20 69 43 6f 6c 3c 6e 43 6f 6c 75 6d 6e 20 26  & iCol<nColumn &
10880 26 20 69 43 6f 6c 21 3d 69 43 6f 6c 75 6d 6e 20  & iCol!=iColumn 
10890 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20  ) continue;.    
108a0 20 20 69 66 28 20 61 54 65 72 6d 5b 69 5d 2e 6e    if( aTerm[i].n
108b0 54 65 72 6d 21 3d 6e 54 6f 6b 65 6e 20 29 20 63  Term!=nToken ) c
108c0 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 69  ontinue;.      i
108d0 66 28 20 6d 65 6d 63 6d 70 28 61 54 65 72 6d 5b  f( memcmp(aTerm[
108e0 69 5d 2e 70 54 65 72 6d 2c 20 7a 54 6f 6b 65 6e  i].pTerm, zToken
108f0 2c 20 6e 54 6f 6b 65 6e 29 20 29 20 63 6f 6e 74  , nToken) ) cont
10900 69 6e 75 65 3b 0a 20 20 20 20 20 20 69 66 28 20  inue;.      if( 
10910 61 54 65 72 6d 5b 69 5d 2e 69 50 68 72 61 73 65  aTerm[i].iPhrase
10920 3e 31 20 26 26 20 28 70 72 65 76 4d 61 74 63 68  >1 && (prevMatch
10930 20 26 20 28 31 3c 3c 69 29 29 3d 3d 30 20 29 20   & (1<<i))==0 ) 
10940 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
10950 6d 61 74 63 68 20 7c 3d 20 31 3c 3c 69 3b 0a 20  match |= 1<<i;. 
10960 20 20 20 20 20 69 66 28 20 69 3d 3d 6e 54 65 72       if( i==nTer
10970 6d 2d 31 20 7c 7c 20 61 54 65 72 6d 5b 69 2b 31  m-1 || aTerm[i+1
10980 5d 2e 69 50 68 72 61 73 65 3d 3d 31 20 29 7b 0a  ].iPhrase==1 ){.
10990 20 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 61 54          for(j=aT
109a0 65 72 6d 5b 69 5d 2e 69 50 68 72 61 73 65 2d 31  erm[i].iPhrase-1
109b0 3b 20 6a 3e 3d 30 3b 20 6a 2d 2d 29 7b 0a 20 20  ; j>=0; j--){.  
109c0 20 20 20 20 20 20 20 20 69 6e 74 20 6b 20 3d 20          int k = 
109d0 28 69 52 6f 74 6f 72 2d 6a 29 20 26 20 46 54 53  (iRotor-j) & FTS
109e0 31 5f 52 4f 54 4f 52 5f 4d 41 53 4b 3b 0a 20 20  1_ROTOR_MASK;.  
109f0 20 20 20 20 20 20 20 20 73 6e 69 70 70 65 74 41          snippetA
10a00 70 70 65 6e 64 4d 61 74 63 68 28 70 53 6e 69 70  ppendMatch(pSnip
10a10 70 65 74 2c 20 69 43 6f 6c 75 6d 6e 2c 20 69 2d  pet, iColumn, i-
10a20 6a 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  j,.             
10a30 20 20 20 69 52 6f 74 6f 72 42 65 67 69 6e 5b 6b     iRotorBegin[k
10a40 5d 2c 20 69 52 6f 74 6f 72 4c 65 6e 5b 6b 5d 29  ], iRotorLen[k])
10a50 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
10a60 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70 72    }.    }.    pr
10a70 65 76 4d 61 74 63 68 20 3d 20 6d 61 74 63 68 3c  evMatch = match<
10a80 3c 31 3b 0a 20 20 20 20 69 52 6f 74 6f 72 2b 2b  <1;.    iRotor++
10a90 3b 0a 20 20 7d 0a 20 20 70 54 4d 6f 64 75 6c 65  ;.  }.  pTModule
10aa0 2d 3e 78 43 6c 6f 73 65 28 70 54 43 75 72 73 6f  ->xClose(pTCurso
10ab0 72 29 3b 20 20 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  r);  .}.../*.** 
10ac0 43 6f 6d 70 75 74 65 20 61 6c 6c 20 6f 66 66 73  Compute all offs
10ad0 65 74 73 20 66 6f 72 20 74 68 65 20 63 75 72 72  ets for the curr
10ae0 65 6e 74 20 72 6f 77 20 6f 66 20 74 68 65 20 71  ent row of the q
10af0 75 65 72 79 2e 20 20 0a 2a 2a 20 49 66 20 74 68  uery.  .** If th
10b00 65 20 6f 66 66 73 65 74 73 20 68 61 76 65 20 61  e offsets have a
10b10 6c 72 65 61 64 79 20 62 65 65 6e 20 63 6f 6d 70  lready been comp
10b20 75 74 65 64 2c 20 74 68 69 73 20 72 6f 75 74 69  uted, this routi
10b30 6e 65 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a  ne is a no-op..*
10b40 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 6e  /.static void sn
10b50 69 70 70 65 74 41 6c 6c 4f 66 66 73 65 74 73 28  ippetAllOffsets(
10b60 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20  fulltext_cursor 
10b70 2a 70 29 7b 0a 20 20 69 6e 74 20 6e 43 6f 6c 75  *p){.  int nColu
10b80 6d 6e 3b 0a 20 20 69 6e 74 20 69 43 6f 6c 75 6d  mn;.  int iColum
10b90 6e 2c 20 69 3b 0a 20 20 69 6e 74 20 69 46 69 72  n, i;.  int iFir
10ba0 73 74 2c 20 69 4c 61 73 74 3b 0a 20 20 66 75 6c  st, iLast;.  ful
10bb0 6c 74 65 78 74 5f 76 74 61 62 20 2a 70 46 74 73  ltext_vtab *pFts
10bc0 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 73 6e 69 70  ;..  if( p->snip
10bd0 70 65 74 2e 6e 4d 61 74 63 68 20 29 20 72 65 74  pet.nMatch ) ret
10be0 75 72 6e 3b 0a 20 20 69 66 28 20 70 2d 3e 71 2e  urn;.  if( p->q.
10bf0 6e 54 65 72 6d 73 3d 3d 30 20 29 20 72 65 74 75  nTerms==0 ) retu
10c00 72 6e 3b 0a 20 20 70 46 74 73 20 3d 20 70 2d 3e  rn;.  pFts = p->
10c10 71 2e 70 46 74 73 3b 0a 20 20 6e 43 6f 6c 75 6d  q.pFts;.  nColum
10c20 6e 20 3d 20 70 46 74 73 2d 3e 6e 43 6f 6c 75 6d  n = pFts->nColum
10c30 6e 3b 0a 20 20 69 43 6f 6c 75 6d 6e 20 3d 20 70  n;.  iColumn = p
10c40 2d 3e 69 43 75 72 73 6f 72 54 79 70 65 3b 0a 20  ->iCursorType;. 
10c50 20 69 66 28 20 69 43 6f 6c 75 6d 6e 3c 30 20 7c   if( iColumn<0 |
10c60 7c 20 69 43 6f 6c 75 6d 6e 3e 3d 6e 43 6f 6c 75  | iColumn>=nColu
10c70 6d 6e 20 29 7b 0a 20 20 20 20 69 46 69 72 73 74  mn ){.    iFirst
10c80 20 3d 20 30 3b 0a 20 20 20 20 69 4c 61 73 74 20   = 0;.    iLast 
10c90 3d 20 6e 43 6f 6c 75 6d 6e 2d 31 3b 0a 20 20 7d  = nColumn-1;.  }
10ca0 65 6c 73 65 7b 0a 20 20 20 20 69 46 69 72 73 74  else{.    iFirst
10cb0 20 3d 20 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20   = iColumn;.    
10cc0 69 4c 61 73 74 20 3d 20 69 43 6f 6c 75 6d 6e 3b  iLast = iColumn;
10cd0 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d 69 46 69  .  }.  for(i=iFi
10ce0 72 73 74 3b 20 69 3c 3d 69 4c 61 73 74 3b 20 69  rst; i<=iLast; i
10cf0 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63  ++){.    const c
10d00 68 61 72 20 2a 7a 44 6f 63 3b 0a 20 20 20 20 69  har *zDoc;.    i
10d10 6e 74 20 6e 44 6f 63 3b 0a 20 20 20 20 7a 44 6f  nt nDoc;.    zDo
10d20 63 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a  c = (const char*
10d30 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f  )sqlite3_column_
10d40 74 65 78 74 28 70 2d 3e 70 53 74 6d 74 2c 20 69  text(p->pStmt, i
10d50 2b 31 29 3b 0a 20 20 20 20 6e 44 6f 63 20 3d 20  +1);.    nDoc = 
10d60 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62  sqlite3_column_b
10d70 79 74 65 73 28 70 2d 3e 70 53 74 6d 74 2c 20 69  ytes(p->pStmt, i
10d80 2b 31 29 3b 0a 20 20 20 20 73 6e 69 70 70 65 74  +1);.    snippet
10d90 4f 66 66 73 65 74 73 4f 66 43 6f 6c 75 6d 6e 28  OffsetsOfColumn(
10da0 26 70 2d 3e 71 2c 20 26 70 2d 3e 73 6e 69 70 70  &p->q, &p->snipp
10db0 65 74 2c 20 69 2c 20 7a 44 6f 63 2c 20 6e 44 6f  et, i, zDoc, nDo
10dc0 63 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  c);.  }.}../*.**
10dd0 20 43 6f 6e 76 65 72 74 20 74 68 65 20 69 6e 66   Convert the inf
10de0 6f 72 6d 61 74 69 6f 6e 20 69 6e 20 74 68 65 20  ormation in the 
10df0 61 4d 61 74 63 68 5b 5d 20 61 72 72 61 79 20 6f  aMatch[] array o
10e00 66 20 74 68 65 20 73 6e 69 70 70 65 74 0a 2a 2a  f the snippet.**
10e10 20 69 6e 74 6f 20 74 68 65 20 73 74 72 69 6e 67   into the string
10e20 20 7a 4f 66 66 73 65 74 5b 30 2e 2e 6e 4f 66 66   zOffset[0..nOff
10e30 73 65 74 2d 31 5d 2e 0a 2a 2f 0a 73 74 61 74 69  set-1]..*/.stati
10e40 63 20 76 6f 69 64 20 73 6e 69 70 70 65 74 4f 66  c void snippetOf
10e50 66 73 65 74 54 65 78 74 28 53 6e 69 70 70 65 74  fsetText(Snippet
10e60 20 2a 70 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20   *p){.  int i;. 
10e70 20 69 6e 74 20 63 6e 74 20 3d 20 30 3b 0a 20 20   int cnt = 0;.  
10e80 53 74 72 69 6e 67 42 75 66 66 65 72 20 73 62 3b  StringBuffer sb;
10e90 0a 20 20 63 68 61 72 20 7a 42 75 66 5b 32 30 30  .  char zBuf[200
10ea0 5d 3b 0a 20 20 69 66 28 20 70 2d 3e 7a 4f 66 66  ];.  if( p->zOff
10eb0 73 65 74 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  set ) return;.  
10ec0 69 6e 69 74 53 74 72 69 6e 67 42 75 66 66 65 72  initStringBuffer
10ed0 28 26 73 62 29 3b 0a 20 20 66 6f 72 28 69 3d 30  (&sb);.  for(i=0
10ee0 3b 20 69 3c 70 2d 3e 6e 4d 61 74 63 68 3b 20 69  ; i<p->nMatch; i
10ef0 2b 2b 29 7b 0a 20 20 20 20 73 74 72 75 63 74 20  ++){.    struct 
10f00 73 6e 69 70 70 65 74 4d 61 74 63 68 20 2a 70 4d  snippetMatch *pM
10f10 61 74 63 68 20 3d 20 26 70 2d 3e 61 4d 61 74 63  atch = &p->aMatc
10f20 68 5b 69 5d 3b 0a 20 20 20 20 7a 42 75 66 5b 30  h[i];.    zBuf[0
10f30 5d 20 3d 20 27 20 27 3b 0a 20 20 20 20 73 70 72  ] = ' ';.    spr
10f40 69 6e 74 66 28 26 7a 42 75 66 5b 63 6e 74 3e 30  intf(&zBuf[cnt>0
10f50 5d 2c 20 22 25 64 20 25 64 20 25 64 20 25 64 22  ], "%d %d %d %d"
10f60 2c 20 70 4d 61 74 63 68 2d 3e 69 43 6f 6c 2c 0a  , pMatch->iCol,.
10f70 20 20 20 20 20 20 20 20 70 4d 61 74 63 68 2d 3e          pMatch->
10f80 69 54 65 72 6d 2c 20 70 4d 61 74 63 68 2d 3e 69  iTerm, pMatch->i
10f90 53 74 61 72 74 2c 20 70 4d 61 74 63 68 2d 3e 6e  Start, pMatch->n
10fa0 42 79 74 65 29 3b 0a 20 20 20 20 61 70 70 65 6e  Byte);.    appen
10fb0 64 28 26 73 62 2c 20 7a 42 75 66 29 3b 0a 20 20  d(&sb, zBuf);.  
10fc0 20 20 63 6e 74 2b 2b 3b 0a 20 20 7d 0a 20 20 70    cnt++;.  }.  p
10fd0 2d 3e 7a 4f 66 66 73 65 74 20 3d 20 73 62 2e 73  ->zOffset = sb.s
10fe0 3b 0a 20 20 70 2d 3e 6e 4f 66 66 73 65 74 20 3d  ;.  p->nOffset =
10ff0 20 73 62 2e 6c 65 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a   sb.len;.}../*.*
11000 2a 20 7a 44 6f 63 5b 30 2e 2e 6e 44 6f 63 2d 31  * zDoc[0..nDoc-1
11010 5d 20 69 73 20 70 68 72 61 73 65 20 6f 66 20 74  ] is phrase of t
11020 65 78 74 2e 20 20 61 4d 61 74 63 68 5b 30 2e 2e  ext.  aMatch[0..
11030 6e 4d 61 74 63 68 2d 31 5d 20 61 72 65 20 61 20  nMatch-1] are a 
11040 73 65 74 0a 2a 2a 20 6f 66 20 6d 61 74 63 68 69  set.** of matchi
11050 6e 67 20 77 6f 72 64 73 20 73 6f 6d 65 20 6f 66  ng words some of
11060 20 77 68 69 63 68 20 6d 69 67 68 74 20 62 65 20   which might be 
11070 69 6e 20 7a 44 6f 63 2e 20 20 7a 44 6f 63 20 69  in zDoc.  zDoc i
11080 73 20 63 6f 6c 75 6d 6e 0a 2a 2a 20 6e 75 6d 62  s column.** numb
11090 65 72 20 69 43 6f 6c 2e 0a 2a 2a 0a 2a 2a 20 69  er iCol..**.** i
110a0 42 72 65 61 6b 20 69 73 20 73 75 67 67 65 73 74  Break is suggest
110b0 65 64 20 73 70 6f 74 20 69 6e 20 7a 44 6f 63 20  ed spot in zDoc 
110c0 77 68 65 72 65 20 77 65 20 63 6f 75 6c 64 20 62  where we could b
110d0 65 67 69 6e 20 6f 72 20 65 6e 64 20 61 6e 0a 2a  egin or end an.*
110e0 2a 20 65 78 63 65 72 70 74 2e 20 20 52 65 74 75  * excerpt.  Retu
110f0 72 6e 20 61 20 76 61 6c 75 65 20 73 69 6d 69 6c  rn a value simil
11100 61 72 20 74 6f 20 69 42 72 65 61 6b 20 62 75 74  ar to iBreak but
11110 20 70 6f 73 73 69 62 6c 79 20 61 64 6a 75 73 74   possibly adjust
11120 65 64 0a 2a 2a 20 74 6f 20 62 65 20 61 20 6c 69  ed.** to be a li
11130 74 74 6c 65 20 6c 65 66 74 20 6f 72 20 72 69 67  ttle left or rig
11140 68 74 20 73 6f 20 74 68 61 74 20 74 68 65 20 62  ht so that the b
11150 72 65 61 6b 20 70 6f 69 6e 74 20 69 73 20 62 65  reak point is be
11160 74 74 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  tter..*/.static 
11170 69 6e 74 20 77 6f 72 64 42 6f 75 6e 64 61 72 79  int wordBoundary
11180 28 0a 20 20 69 6e 74 20 69 42 72 65 61 6b 2c 20  (.  int iBreak, 
11190 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
111a0 20 20 2f 2a 20 54 68 65 20 73 75 67 67 65 73 74    /* The suggest
111b0 65 64 20 62 72 65 61 6b 20 70 6f 69 6e 74 20 2a  ed break point *
111c0 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
111d0 7a 44 6f 63 2c 20 20 20 20 20 20 20 20 20 20 20  zDoc,           
111e0 20 20 2f 2a 20 44 6f 63 75 6d 65 6e 74 20 74 65    /* Document te
111f0 78 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 44 6f 63  xt */.  int nDoc
11200 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
11210 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
11220 6f 66 20 62 79 74 65 73 20 69 6e 20 7a 44 6f 63  of bytes in zDoc
11230 5b 5d 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 73  [] */.  struct s
11240 6e 69 70 70 65 74 4d 61 74 63 68 20 2a 61 4d 61  nippetMatch *aMa
11250 74 63 68 2c 20 20 2f 2a 20 4d 61 74 63 68 69 6e  tch,  /* Matchin
11260 67 20 77 6f 72 64 73 20 2a 2f 0a 20 20 69 6e 74  g words */.  int
11270 20 6e 4d 61 74 63 68 2c 20 20 20 20 20 20 20 20   nMatch,        
11280 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
11290 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20  mber of entries 
112a0 69 6e 20 61 4d 61 74 63 68 5b 5d 20 2a 2f 0a 20  in aMatch[] */. 
112b0 20 69 6e 74 20 69 43 6f 6c 20 20 20 20 20 20 20   int iCol       
112c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
112d0 2a 20 54 68 65 20 63 6f 6c 75 6d 6e 20 6e 75 6d  * The column num
112e0 62 65 72 20 66 6f 72 20 7a 44 6f 63 5b 5d 20 2a  ber for zDoc[] *
112f0 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  /.){.  int i;.  
11300 69 66 28 20 69 42 72 65 61 6b 3c 3d 31 30 20 29  if( iBreak<=10 )
11310 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  {.    return 0;.
11320 20 20 7d 0a 20 20 69 66 28 20 69 42 72 65 61 6b    }.  if( iBreak
11330 3e 3d 6e 44 6f 63 2d 31 30 20 29 7b 0a 20 20 20  >=nDoc-10 ){.   
11340 20 72 65 74 75 72 6e 20 6e 44 6f 63 3b 0a 20 20   return nDoc;.  
11350 7d 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e  }.  for(i=0; i<n
11360 4d 61 74 63 68 20 26 26 20 61 4d 61 74 63 68 5b  Match && aMatch[
11370 69 5d 2e 69 43 6f 6c 3c 69 43 6f 6c 3b 20 69 2b  i].iCol<iCol; i+
11380 2b 29 7b 7d 0a 20 20 77 68 69 6c 65 28 20 69 3c  +){}.  while( i<
11390 6e 4d 61 74 63 68 20 26 26 20 61 4d 61 74 63 68  nMatch && aMatch
113a0 5b 69 5d 2e 69 53 74 61 72 74 2b 61 4d 61 74 63  [i].iStart+aMatc
113b0 68 5b 69 5d 2e 6e 42 79 74 65 3c 69 42 72 65 61  h[i].nByte<iBrea
113c0 6b 20 29 7b 20 69 2b 2b 3b 20 7d 0a 20 20 69 66  k ){ i++; }.  if
113d0 28 20 69 3c 6e 4d 61 74 63 68 20 29 7b 0a 20 20  ( i<nMatch ){.  
113e0 20 20 69 66 28 20 61 4d 61 74 63 68 5b 69 5d 2e    if( aMatch[i].
113f0 69 53 74 61 72 74 3c 69 42 72 65 61 6b 2b 31 30  iStart<iBreak+10
11400 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
11410 20 61 4d 61 74 63 68 5b 69 5d 2e 69 53 74 61 72   aMatch[i].iStar
11420 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  t;.    }.    if(
11430 20 69 3e 30 20 26 26 20 61 4d 61 74 63 68 5b 69   i>0 && aMatch[i
11440 2d 31 5d 2e 69 53 74 61 72 74 2b 61 4d 61 74 63  -1].iStart+aMatc
11450 68 5b 69 2d 31 5d 2e 6e 42 79 74 65 3e 3d 69 42  h[i-1].nByte>=iB
11460 72 65 61 6b 20 29 7b 0a 20 20 20 20 20 20 72 65  reak ){.      re
11470 74 75 72 6e 20 61 4d 61 74 63 68 5b 69 2d 31 5d  turn aMatch[i-1]
11480 2e 69 53 74 61 72 74 3b 0a 20 20 20 20 7d 0a 20  .iStart;.    }. 
11490 20 7d 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c   }.  for(i=1; i<
114a0 3d 31 30 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69  =10; i++){.    i
114b0 66 28 20 69 73 73 70 61 63 65 28 7a 44 6f 63 5b  f( isspace(zDoc[
114c0 69 42 72 65 61 6b 2d 69 5d 29 20 29 7b 0a 20 20  iBreak-i]) ){.  
114d0 20 20 20 20 72 65 74 75 72 6e 20 69 42 72 65 61      return iBrea
114e0 6b 20 2d 20 69 20 2b 20 31 3b 0a 20 20 20 20 7d  k - i + 1;.    }
114f0 0a 20 20 20 20 69 66 28 20 69 73 73 70 61 63 65  .    if( isspace
11500 28 7a 44 6f 63 5b 69 42 72 65 61 6b 2b 69 5d 29  (zDoc[iBreak+i])
11510 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
11520 20 69 42 72 65 61 6b 20 2b 20 69 20 2b 20 31 3b   iBreak + i + 1;
11530 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
11540 75 72 6e 20 69 42 72 65 61 6b 3b 0a 7d 0a 0a 2f  urn iBreak;.}../
11550 2a 0a 2a 2a 20 49 66 20 74 68 65 20 53 74 72 69  *.** If the Stri
11560 6e 67 42 75 66 66 65 72 20 64 6f 65 73 20 6e 6f  ngBuffer does no
11570 74 20 65 6e 64 20 69 6e 20 77 68 69 74 65 20 73  t end in white s
11580 70 61 63 65 2c 20 61 64 64 20 61 20 73 69 6e 67  pace, add a sing
11590 6c 65 0a 2a 2a 20 73 70 61 63 65 20 63 68 61 72  le.** space char
115a0 61 63 74 65 72 20 74 6f 20 74 68 65 20 65 6e 64  acter to the end
115b0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
115c0 20 61 70 70 65 6e 64 57 68 69 74 65 53 70 61 63   appendWhiteSpac
115d0 65 28 53 74 72 69 6e 67 42 75 66 66 65 72 20 2a  e(StringBuffer *
115e0 70 29 7b 0a 20 20 69 66 28 20 70 2d 3e 6c 65 6e  p){.  if( p->len
115f0 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ==0 ) return;.  
11600 69 66 28 20 69 73 73 70 61 63 65 28 70 2d 3e 73  if( isspace(p->s
11610 5b 70 2d 3e 6c 65 6e 2d 31 5d 29 20 29 20 72 65  [p->len-1]) ) re
11620 74 75 72 6e 3b 0a 20 20 61 70 70 65 6e 64 28 70  turn;.  append(p
11630 2c 20 22 20 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  , " ");.}../*.**
11640 20 52 65 6d 6f 76 65 20 77 68 69 74 65 20 73 70   Remove white sp
11650 61 63 65 20 66 72 6f 6d 20 74 65 68 20 65 6e 64  ace from teh end
11660 20 6f 66 20 74 68 65 20 53 74 72 69 6e 67 42 75   of the StringBu
11670 66 66 65 72 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ffer.*/.static v
11680 6f 69 64 20 74 72 69 6d 57 68 69 74 65 53 70 61  oid trimWhiteSpa
11690 63 65 28 53 74 72 69 6e 67 42 75 66 66 65 72 20  ce(StringBuffer 
116a0 2a 70 29 7b 0a 20 20 77 68 69 6c 65 28 20 70 2d  *p){.  while( p-
116b0 3e 6c 65 6e 3e 30 20 26 26 20 69 73 73 70 61 63  >len>0 && isspac
116c0 65 28 70 2d 3e 73 5b 70 2d 3e 6c 65 6e 2d 31 5d  e(p->s[p->len-1]
116d0 29 20 29 7b 0a 20 20 20 20 70 2d 3e 6c 65 6e 2d  ) ){.    p->len-
116e0 2d 3b 0a 20 20 7d 0a 7d 0a 0a 0a 0a 2f 2a 0a 2a  -;.  }.}..../*.*
116f0 2a 20 41 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73  * Allowed values
11700 20 66 6f 72 20 53 6e 69 70 70 65 74 2e 61 4d 61   for Snippet.aMa
11710 74 63 68 5b 5d 2e 73 6e 53 74 61 74 75 73 0a 2a  tch[].snStatus.*
11720 2f 0a 23 64 65 66 69 6e 65 20 53 4e 49 50 50 45  /.#define SNIPPE
11730 54 5f 49 47 4e 4f 52 45 20 20 30 20 20 20 2f 2a  T_IGNORE  0   /*
11740 20 49 74 20 69 73 20 6f 6b 20 74 6f 20 6f 6d 69   It is ok to omi
11750 74 20 74 68 69 73 20 6d 61 74 63 68 20 66 72 6f  t this match fro
11760 6d 20 74 68 65 20 73 6e 69 70 70 65 74 20 2a 2f  m the snippet */
11770 0a 23 64 65 66 69 6e 65 20 53 4e 49 50 50 45 54  .#define SNIPPET
11780 5f 44 45 53 49 52 45 44 20 31 20 20 20 2f 2a 20  _DESIRED 1   /* 
11790 57 65 20 77 61 6e 74 20 74 6f 20 69 6e 63 6c 75  We want to inclu
117a0 64 65 20 74 68 69 73 20 6d 61 74 63 68 20 69 6e  de this match in
117b0 20 74 68 65 20 73 6e 69 70 70 65 74 20 2a 2f 0a   the snippet */.
117c0 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20  ./*.** Generate 
117d0 74 68 65 20 74 65 78 74 20 6f 66 20 61 20 73 6e  the text of a sn
117e0 69 70 70 65 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  ippet..*/.static
117f0 20 76 6f 69 64 20 73 6e 69 70 70 65 74 54 65 78   void snippetTex
11800 74 28 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75  t(.  fulltext_cu
11810 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 20  rsor *pCursor,  
11820 20 2f 2a 20 54 68 65 20 63 75 72 73 6f 72 20 77   /* The cursor w
11830 65 20 6e 65 65 64 20 74 68 65 20 73 6e 69 70 70  e need the snipp
11840 65 74 20 66 6f 72 20 2a 2f 0a 20 20 63 6f 6e 73  et for */.  cons
11850 74 20 63 68 61 72 20 2a 7a 53 74 61 72 74 4d 61  t char *zStartMa
11860 72 6b 2c 20 20 20 20 20 2f 2a 20 4d 61 72 6b 75  rk,     /* Marku
11870 70 20 74 6f 20 61 70 70 65 61 72 20 62 65 66 6f  p to appear befo
11880 72 65 20 65 61 63 68 20 6d 61 74 63 68 20 2a 2f  re each match */
11890 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
118a0 45 6e 64 4d 61 72 6b 2c 20 20 20 20 20 20 20 2f  EndMark,       /
118b0 2a 20 4d 61 72 6b 75 70 20 74 6f 20 61 70 70 65  * Markup to appe
118c0 61 72 20 61 66 74 65 72 20 65 61 63 68 20 6d 61  ar after each ma
118d0 74 63 68 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  tch */.  const c
118e0 68 61 72 20 2a 7a 45 6c 6c 69 70 73 69 73 20 20  har *zEllipsis  
118f0 20 20 20 20 20 2f 2a 20 45 6c 6c 69 70 73 69 73       /* Ellipsis
11900 20 6d 61 72 6b 20 2a 2f 0a 29 7b 0a 20 20 69 6e   mark */.){.  in
11910 74 20 69 2c 20 6a 3b 0a 20 20 73 74 72 75 63 74  t i, j;.  struct
11920 20 73 6e 69 70 70 65 74 4d 61 74 63 68 20 2a 61   snippetMatch *a
11930 4d 61 74 63 68 3b 0a 20 20 69 6e 74 20 6e 4d 61  Match;.  int nMa
11940 74 63 68 3b 0a 20 20 69 6e 74 20 6e 44 65 73 69  tch;.  int nDesi
11950 72 65 64 3b 0a 20 20 53 74 72 69 6e 67 42 75 66  red;.  StringBuf
11960 66 65 72 20 73 62 3b 0a 20 20 69 6e 74 20 74 61  fer sb;.  int ta
11970 69 6c 43 6f 6c 3b 0a 20 20 69 6e 74 20 74 61 69  ilCol;.  int tai
11980 6c 4f 66 66 73 65 74 3b 0a 20 20 69 6e 74 20 69  lOffset;.  int i
11990 43 6f 6c 3b 0a 20 20 69 6e 74 20 6e 44 6f 63 3b  Col;.  int nDoc;
119a0 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
119b0 44 6f 63 3b 0a 20 20 69 6e 74 20 69 53 74 61 72  Doc;.  int iStar
119c0 74 2c 20 69 45 6e 64 3b 0a 20 20 69 6e 74 20 74  t, iEnd;.  int t
119d0 61 69 6c 45 6c 6c 69 70 73 69 73 20 3d 20 30 3b  ailEllipsis = 0;
119e0 0a 20 20 69 6e 74 20 69 4d 61 74 63 68 3b 0a 20  .  int iMatch;. 
119f0 20 0a 0a 20 20 66 72 65 65 28 70 43 75 72 73 6f   ..  free(pCurso
11a00 72 2d 3e 73 6e 69 70 70 65 74 2e 7a 53 6e 69 70  r->snippet.zSnip
11a10 70 65 74 29 3b 0a 20 20 70 43 75 72 73 6f 72 2d  pet);.  pCursor-
11a20 3e 73 6e 69 70 70 65 74 2e 7a 53 6e 69 70 70 65  >snippet.zSnippe
11a30 74 20 3d 20 30 3b 0a 20 20 61 4d 61 74 63 68 20  t = 0;.  aMatch 
11a40 3d 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70  = pCursor->snipp
11a50 65 74 2e 61 4d 61 74 63 68 3b 0a 20 20 6e 4d 61  et.aMatch;.  nMa
11a60 74 63 68 20 3d 20 70 43 75 72 73 6f 72 2d 3e 73  tch = pCursor->s
11a70 6e 69 70 70 65 74 2e 6e 4d 61 74 63 68 3b 0a 20  nippet.nMatch;. 
11a80 20 69 6e 69 74 53 74 72 69 6e 67 42 75 66 66 65   initStringBuffe
11a90 72 28 26 73 62 29 3b 0a 0a 20 20 66 6f 72 28 69  r(&sb);..  for(i
11aa0 3d 30 3b 20 69 3c 6e 4d 61 74 63 68 3b 20 69 2b  =0; i<nMatch; i+
11ab0 2b 29 7b 0a 20 20 20 20 61 4d 61 74 63 68 5b 69  +){.    aMatch[i
11ac0 5d 2e 73 6e 53 74 61 74 75 73 20 3d 20 53 4e 49  ].snStatus = SNI
11ad0 50 50 45 54 5f 49 47 4e 4f 52 45 3b 0a 20 20 7d  PPET_IGNORE;.  }
11ae0 0a 20 20 6e 44 65 73 69 72 65 64 20 3d 20 30 3b  .  nDesired = 0;
11af0 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 43  .  for(i=0; i<pC
11b00 75 72 73 6f 72 2d 3e 71 2e 6e 54 65 72 6d 73 3b  ursor->q.nTerms;
11b10 20 69 2b 2b 29 7b 0a 20 20 20 20 66 6f 72 28 6a   i++){.    for(j
11b20 3d 30 3b 20 6a 3c 6e 4d 61 74 63 68 3b 20 6a 2b  =0; j<nMatch; j+
11b30 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 4d  +){.      if( aM
11b40 61 74 63 68 5b 6a 5d 2e 69 54 65 72 6d 3d 3d 69  atch[j].iTerm==i
11b50 20 29 7b 0a 20 20 20 20 20 20 20 20 61 4d 61 74   ){.        aMat
11b60 63 68 5b 6a 5d 2e 73 6e 53 74 61 74 75 73 20 3d  ch[j].snStatus =
11b70 20 53 4e 49 50 50 45 54 5f 44 45 53 49 52 45 44   SNIPPET_DESIRED
11b80 3b 0a 20 20 20 20 20 20 20 20 6e 44 65 73 69 72  ;.        nDesir
11b90 65 64 2b 2b 3b 0a 20 20 20 20 20 20 20 20 62 72  ed++;.        br
11ba0 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
11bb0 20 7d 0a 20 20 7d 0a 0a 20 20 69 4d 61 74 63 68   }.  }..  iMatch
11bc0 20 3d 20 30 3b 0a 20 20 74 61 69 6c 43 6f 6c 20   = 0;.  tailCol 
11bd0 3d 20 2d 31 3b 0a 20 20 74 61 69 6c 4f 66 66 73  = -1;.  tailOffs
11be0 65 74 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d  et = 0;.  for(i=
11bf0 30 3b 20 69 3c 6e 4d 61 74 63 68 20 26 26 20 6e  0; i<nMatch && n
11c00 44 65 73 69 72 65 64 3e 30 3b 20 69 2b 2b 29 7b  Desired>0; i++){
11c10 0a 20 20 20 20 69 66 28 20 61 4d 61 74 63 68 5b  .    if( aMatch[
11c20 69 5d 2e 73 6e 53 74 61 74 75 73 21 3d 53 4e 49  i].snStatus!=SNI
11c30 50 50 45 54 5f 44 45 53 49 52 45 44 20 29 20 63  PPET_DESIRED ) c
11c40 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 6e 44 65  ontinue;.    nDe
11c50 73 69 72 65 64 2d 2d 3b 0a 20 20 20 20 69 43 6f  sired--;.    iCo
11c60 6c 20 3d 20 61 4d 61 74 63 68 5b 69 5d 2e 69 43  l = aMatch[i].iC
11c70 6f 6c 3b 0a 20 20 20 20 7a 44 6f 63 20 3d 20 28  ol;.    zDoc = (
11c80 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69  const char*)sqli
11c90 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28  te3_column_text(
11ca0 70 43 75 72 73 6f 72 2d 3e 70 53 74 6d 74 2c 20  pCursor->pStmt, 
11cb0 69 43 6f 6c 2b 31 29 3b 0a 20 20 20 20 6e 44 6f  iCol+1);.    nDo
11cc0 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  c = sqlite3_colu
11cd0 6d 6e 5f 62 79 74 65 73 28 70 43 75 72 73 6f 72  mn_bytes(pCursor
11ce0 2d 3e 70 53 74 6d 74 2c 20 69 43 6f 6c 2b 31 29  ->pStmt, iCol+1)
11cf0 3b 0a 20 20 20 20 69 53 74 61 72 74 20 3d 20 61  ;.    iStart = a
11d00 4d 61 74 63 68 5b 69 5d 2e 69 53 74 61 72 74 20  Match[i].iStart 
11d10 2d 20 34 30 3b 0a 20 20 20 20 69 53 74 61 72 74  - 40;.    iStart
11d20 20 3d 20 77 6f 72 64 42 6f 75 6e 64 61 72 79 28   = wordBoundary(
11d30 69 53 74 61 72 74 2c 20 7a 44 6f 63 2c 20 6e 44  iStart, zDoc, nD
11d40 6f 63 2c 20 61 4d 61 74 63 68 2c 20 6e 4d 61 74  oc, aMatch, nMat
11d50 63 68 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20 69  ch, iCol);.    i
11d60 66 28 20 69 53 74 61 72 74 3c 3d 31 30 20 29 7b  f( iStart<=10 ){
11d70 0a 20 20 20 20 20 20 69 53 74 61 72 74 20 3d 20  .      iStart = 
11d80 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  0;.    }.    if(
11d90 20 69 43 6f 6c 3d 3d 74 61 69 6c 43 6f 6c 20 26   iCol==tailCol &
11da0 26 20 69 53 74 61 72 74 3c 3d 74 61 69 6c 4f 66  & iStart<=tailOf
11db0 66 73 65 74 2b 32 30 20 29 7b 0a 20 20 20 20 20  fset+20 ){.     
11dc0 20 69 53 74 61 72 74 20 3d 20 74 61 69 6c 4f 66   iStart = tailOf
11dd0 66 73 65 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20  fset;.    }.    
11de0 69 66 28 20 28 69 43 6f 6c 21 3d 74 61 69 6c 43  if( (iCol!=tailC
11df0 6f 6c 20 26 26 20 74 61 69 6c 43 6f 6c 3e 3d 30  ol && tailCol>=0
11e00 29 20 7c 7c 20 69 53 74 61 72 74 21 3d 74 61 69  ) || iStart!=tai
11e10 6c 4f 66 66 73 65 74 20 29 7b 0a 20 20 20 20 20  lOffset ){.     
11e20 20 74 72 69 6d 57 68 69 74 65 53 70 61 63 65 28   trimWhiteSpace(
11e30 26 73 62 29 3b 0a 20 20 20 20 20 20 61 70 70 65  &sb);.      appe
11e40 6e 64 57 68 69 74 65 53 70 61 63 65 28 26 73 62  ndWhiteSpace(&sb
11e50 29 3b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 28  );.      append(
11e60 26 73 62 2c 20 7a 45 6c 6c 69 70 73 69 73 29 3b  &sb, zEllipsis);
11e70 0a 20 20 20 20 20 20 61 70 70 65 6e 64 57 68 69  .      appendWhi
11e80 74 65 53 70 61 63 65 28 26 73 62 29 3b 0a 20 20  teSpace(&sb);.  
11e90 20 20 7d 0a 20 20 20 20 69 45 6e 64 20 3d 20 61    }.    iEnd = a
11ea0 4d 61 74 63 68 5b 69 5d 2e 69 53 74 61 72 74 20  Match[i].iStart 
11eb0 2b 20 61 4d 61 74 63 68 5b 69 5d 2e 6e 42 79 74  + aMatch[i].nByt
11ec0 65 20 2b 20 34 30 3b 0a 20 20 20 20 69 45 6e 64  e + 40;.    iEnd
11ed0 20 3d 20 77 6f 72 64 42 6f 75 6e 64 61 72 79 28   = wordBoundary(
11ee0 69 45 6e 64 2c 20 7a 44 6f 63 2c 20 6e 44 6f 63  iEnd, zDoc, nDoc
11ef0 2c 20 61 4d 61 74 63 68 2c 20 6e 4d 61 74 63 68  , aMatch, nMatch
11f00 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20 69 66 28  , iCol);.    if(
11f10 20 69 45 6e 64 3e 3d 6e 44 6f 63 2d 31 30 20 29   iEnd>=nDoc-10 )
11f20 7b 0a 20 20 20 20 20 20 69 45 6e 64 20 3d 20 6e  {.      iEnd = n
11f30 44 6f 63 3b 0a 20 20 20 20 20 20 74 61 69 6c 45  Doc;.      tailE
11f40 6c 6c 69 70 73 69 73 20 3d 20 30 3b 0a 20 20 20  llipsis = 0;.   
11f50 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 74 61   }else{.      ta
11f60 69 6c 45 6c 6c 69 70 73 69 73 20 3d 20 31 3b 0a  ilEllipsis = 1;.
11f70 20 20 20 20 7d 0a 20 20 20 20 77 68 69 6c 65 28      }.    while(
11f80 20 69 4d 61 74 63 68 3c 6e 4d 61 74 63 68 20 26   iMatch<nMatch &
11f90 26 20 61 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d  & aMatch[iMatch]
11fa0 2e 69 43 6f 6c 3c 69 43 6f 6c 20 29 7b 20 69 4d  .iCol<iCol ){ iM
11fb0 61 74 63 68 2b 2b 3b 20 7d 0a 20 20 20 20 77 68  atch++; }.    wh
11fc0 69 6c 65 28 20 69 53 74 61 72 74 3c 69 45 6e 64  ile( iStart<iEnd
11fd0 20 29 7b 0a 20 20 20 20 20 20 77 68 69 6c 65 28   ){.      while(
11fe0 20 69 4d 61 74 63 68 3c 6e 4d 61 74 63 68 20 26   iMatch<nMatch &
11ff0 26 20 61 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d  & aMatch[iMatch]
12000 2e 69 53 74 61 72 74 3c 69 53 74 61 72 74 0a 20  .iStart<iStart. 
12010 20 20 20 20 20 20 20 20 20 20 20 20 26 26 20 61              && a
12020 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69 43  Match[iMatch].iC
12030 6f 6c 3c 3d 69 43 6f 6c 20 29 7b 0a 20 20 20 20  ol<=iCol ){.    
12040 20 20 20 20 69 4d 61 74 63 68 2b 2b 3b 0a 20 20      iMatch++;.  
12050 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
12060 69 4d 61 74 63 68 3c 6e 4d 61 74 63 68 20 26 26  iMatch<nMatch &&
12070 20 61 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e   aMatch[iMatch].
12080 69 53 74 61 72 74 3c 69 45 6e 64 0a 20 20 20 20  iStart<iEnd.    
12090 20 20 20 20 20 20 20 20 20 26 26 20 61 4d 61 74           && aMat
120a0 63 68 5b 69 4d 61 74 63 68 5d 2e 69 43 6f 6c 3d  ch[iMatch].iCol=
120b0 3d 69 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20 20  =iCol ){.       
120c0 20 6e 61 70 70 65 6e 64 28 26 73 62 2c 20 26 7a   nappend(&sb, &z
120d0 44 6f 63 5b 69 53 74 61 72 74 5d 2c 20 61 4d 61  Doc[iStart], aMa
120e0 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69 53 74 61  tch[iMatch].iSta
120f0 72 74 20 2d 20 69 53 74 61 72 74 29 3b 0a 20 20  rt - iStart);.  
12100 20 20 20 20 20 20 69 53 74 61 72 74 20 3d 20 61        iStart = a
12110 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69 53  Match[iMatch].iS
12120 74 61 72 74 3b 0a 20 20 20 20 20 20 20 20 61 70  tart;.        ap
12130 70 65 6e 64 28 26 73 62 2c 20 7a 53 74 61 72 74  pend(&sb, zStart
12140 4d 61 72 6b 29 3b 0a 20 20 20 20 20 20 20 20 6e  Mark);.        n
12150 61 70 70 65 6e 64 28 26 73 62 2c 20 26 7a 44 6f  append(&sb, &zDo
12160 63 5b 69 53 74 61 72 74 5d 2c 20 61 4d 61 74 63  c[iStart], aMatc
12170 68 5b 69 4d 61 74 63 68 5d 2e 6e 42 79 74 65 29  h[iMatch].nByte)
12180 3b 0a 20 20 20 20 20 20 20 20 61 70 70 65 6e 64  ;.        append
12190 28 26 73 62 2c 20 7a 45 6e 64 4d 61 72 6b 29 3b  (&sb, zEndMark);
121a0 0a 20 20 20 20 20 20 20 20 69 53 74 61 72 74 20  .        iStart 
121b0 2b 3d 20 61 4d 61 74 63 68 5b 69 4d 61 74 63 68  += aMatch[iMatch
121c0 5d 2e 6e 42 79 74 65 3b 0a 20 20 20 20 20 20 20  ].nByte;.       
121d0 20 66 6f 72 28 6a 3d 69 4d 61 74 63 68 2b 31 3b   for(j=iMatch+1;
121e0 20 6a 3c 6e 4d 61 74 63 68 3b 20 6a 2b 2b 29 7b   j<nMatch; j++){
121f0 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 61  .          if( a
12200 4d 61 74 63 68 5b 6a 5d 2e 69 54 65 72 6d 3d 3d  Match[j].iTerm==
12210 61 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d 2e 69  aMatch[iMatch].i
12220 54 65 72 6d 0a 20 20 20 20 20 20 20 20 20 20 20  Term.           
12230 20 20 20 26 26 20 61 4d 61 74 63 68 5b 6a 5d 2e     && aMatch[j].
12240 73 6e 53 74 61 74 75 73 3d 3d 53 4e 49 50 50 45  snStatus==SNIPPE
12250 54 5f 44 45 53 49 52 45 44 20 29 7b 0a 20 20 20  T_DESIRED ){.   
12260 20 20 20 20 20 20 20 20 20 6e 44 65 73 69 72 65           nDesire
12270 64 2d 2d 3b 0a 20 20 20 20 20 20 20 20 20 20 20  d--;.           
12280 20 61 4d 61 74 63 68 5b 6a 5d 2e 73 6e 53 74 61   aMatch[j].snSta
12290 74 75 73 20 3d 20 53 4e 49 50 50 45 54 5f 49 47  tus = SNIPPET_IG
122a0 4e 4f 52 45 3b 0a 20 20 20 20 20 20 20 20 20 20  NORE;.          
122b0 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
122c0 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
122d0 20 6e 61 70 70 65 6e 64 28 26 73 62 2c 20 26 7a   nappend(&sb, &z
122e0 44 6f 63 5b 69 53 74 61 72 74 5d 2c 20 69 45 6e  Doc[iStart], iEn
122f0 64 20 2d 20 69 53 74 61 72 74 29 3b 0a 20 20 20  d - iStart);.   
12300 20 20 20 20 20 69 53 74 61 72 74 20 3d 20 69 45       iStart = iE
12310 6e 64 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  nd;.      }.    
12320 7d 0a 20 20 20 20 74 61 69 6c 43 6f 6c 20 3d 20  }.    tailCol = 
12330 69 43 6f 6c 3b 0a 20 20 20 20 74 61 69 6c 4f 66  iCol;.    tailOf
12340 66 73 65 74 20 3d 20 69 45 6e 64 3b 0a 20 20 7d  fset = iEnd;.  }
12350 0a 20 20 74 72 69 6d 57 68 69 74 65 53 70 61 63  .  trimWhiteSpac
12360 65 28 26 73 62 29 3b 0a 20 20 69 66 28 20 74 61  e(&sb);.  if( ta
12370 69 6c 45 6c 6c 69 70 73 69 73 20 29 7b 0a 20 20  ilEllipsis ){.  
12380 20 20 61 70 70 65 6e 64 57 68 69 74 65 53 70 61    appendWhiteSpa
12390 63 65 28 26 73 62 29 3b 0a 20 20 20 20 61 70 70  ce(&sb);.    app
123a0 65 6e 64 28 26 73 62 2c 20 7a 45 6c 6c 69 70 73  end(&sb, zEllips
123b0 69 73 29 3b 0a 20 20 7d 0a 20 20 70 43 75 72 73  is);.  }.  pCurs
123c0 6f 72 2d 3e 73 6e 69 70 70 65 74 2e 7a 53 6e 69  or->snippet.zSni
123d0 70 70 65 74 20 3d 20 73 62 2e 73 3b 0a 20 20 70  ppet = sb.s;.  p
123e0 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74 2e  Cursor->snippet.
123f0 6e 53 6e 69 70 70 65 74 20 3d 20 73 62 2e 6c 65  nSnippet = sb.le
12400 6e 3b 20 20 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43  n;  .}.../*.** C
12410 6c 6f 73 65 20 74 68 65 20 63 75 72 73 6f 72 2e  lose the cursor.
12420 20 20 46 6f 72 20 61 64 64 69 74 69 6f 6e 61 6c    For additional
12430 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 73 65 65   information see
12440 20 74 68 65 20 64 6f 63 75 6d 65 6e 74 61 74 69   the documentati
12450 6f 6e 0a 2a 2a 20 6f 6e 20 74 68 65 20 78 43 6c  on.** on the xCl
12460 6f 73 65 20 6d 65 74 68 6f 64 20 6f 66 20 74 68  ose method of th
12470 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  e virtual table 
12480 69 6e 74 65 72 66 61 63 65 2e 0a 2a 2f 0a 73 74  interface..*/.st
12490 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78  atic int fulltex
124a0 74 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 76  tClose(sqlite3_v
124b0 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  tab_cursor *pCur
124c0 73 6f 72 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74  sor){.  fulltext
124d0 5f 63 75 72 73 6f 72 20 2a 63 20 3d 20 28 66 75  _cursor *c = (fu
124e0 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 29  lltext_cursor *)
124f0 20 70 43 75 72 73 6f 72 3b 0a 20 20 54 52 41 43   pCursor;.  TRAC
12500 45 28 28 22 46 54 53 31 20 43 6c 6f 73 65 20 25  E(("FTS1 Close %
12510 70 5c 6e 22 2c 20 63 29 29 3b 0a 20 20 73 71 6c  p\n", c));.  sql
12520 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 63 2d  ite3_finalize(c-
12530 3e 70 53 74 6d 74 29 3b 0a 20 20 71 75 65 72 79  >pStmt);.  query
12540 43 6c 65 61 72 28 26 63 2d 3e 71 29 3b 0a 20 20  Clear(&c->q);.  
12550 73 6e 69 70 70 65 74 43 6c 65 61 72 28 26 63 2d  snippetClear(&c-
12560 3e 73 6e 69 70 70 65 74 29 3b 0a 20 20 69 66 28  >snippet);.  if(
12570 20 63 2d 3e 72 65 73 75 6c 74 2e 70 44 6f 63 6c   c->result.pDocl
12580 69 73 74 21 3d 4e 55 4c 4c 20 29 7b 0a 20 20 20  ist!=NULL ){.   
12590 20 64 6f 63 4c 69 73 74 44 65 6c 65 74 65 28 63   docListDelete(c
125a0 2d 3e 72 65 73 75 6c 74 2e 70 44 6f 63 6c 69 73  ->result.pDoclis
125b0 74 29 3b 0a 20 20 7d 0a 20 20 66 72 65 65 28 63  t);.  }.  free(c
125c0 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
125d0 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63  TE_OK;.}..static
125e0 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 4e 65 78   int fulltextNex
125f0 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  t(sqlite3_vtab_c
12600 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b  ursor *pCursor){
12610 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73  .  fulltext_curs
12620 6f 72 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78  or *c = (fulltex
12630 74 5f 63 75 72 73 6f 72 20 2a 29 20 70 43 75 72  t_cursor *) pCur
12640 73 6f 72 3b 0a 20 20 73 71 6c 69 74 65 5f 69 6e  sor;.  sqlite_in
12650 74 36 34 20 69 44 6f 63 69 64 3b 0a 20 20 69 6e  t64 iDocid;.  in
12660 74 20 72 63 3b 0a 0a 20 20 54 52 41 43 45 28 28  t rc;..  TRACE((
12670 22 46 54 53 31 20 4e 65 78 74 20 25 70 5c 6e 22  "FTS1 Next %p\n"
12680 2c 20 70 43 75 72 73 6f 72 29 29 3b 0a 20 20 73  , pCursor));.  s
12690 6e 69 70 70 65 74 43 6c 65 61 72 28 26 63 2d 3e  nippetClear(&c->
126a0 73 6e 69 70 70 65 74 29 3b 0a 20 20 69 66 28 20  snippet);.  if( 
126b0 63 2d 3e 69 43 75 72 73 6f 72 54 79 70 65 20 3c  c->iCursorType <
126c0 20 51 55 45 52 59 5f 46 55 4c 4c 54 45 58 54 20   QUERY_FULLTEXT 
126d0 29 7b 0a 20 20 20 20 2f 2a 20 54 4f 44 4f 28 73  ){.    /* TODO(s
126e0 68 65 73 73 29 20 48 61 6e 64 6c 65 20 53 51 4c  hess) Handle SQL
126f0 49 54 45 5f 53 43 48 45 4d 41 20 41 4e 44 20 53  ITE_SCHEMA AND S
12700 51 4c 49 54 45 5f 42 55 53 59 2e 20 2a 2f 0a 20  QLITE_BUSY. */. 
12710 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
12720 73 74 65 70 28 63 2d 3e 70 53 74 6d 74 29 3b 0a  step(c->pStmt);.
12730 20 20 20 20 73 77 69 74 63 68 28 20 72 63 20 29      switch( rc )
12740 7b 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c  {.      case SQL
12750 49 54 45 5f 52 4f 57 3a 0a 20 20 20 20 20 20 20  ITE_ROW:.       
12760 20 63 2d 3e 65 6f 66 20 3d 20 30 3b 0a 20 20 20   c->eof = 0;.   
12770 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
12780 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 63 61 73  TE_OK;.      cas
12790 65 20 53 51 4c 49 54 45 5f 44 4f 4e 45 3a 0a 20  e SQLITE_DONE:. 
127a0 20 20 20 20 20 20 20 63 2d 3e 65 6f 66 20 3d 20         c->eof = 
127b0 31 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  1;.        retur
127c0 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20  n SQLITE_OK;.   
127d0 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20     default:.    
127e0 20 20 20 20 63 2d 3e 65 6f 66 20 3d 20 31 3b 0a      c->eof = 1;.
127f0 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72          return r
12800 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73  c;.    }.  } els
12810 65 20 7b 20 20 2f 2a 20 66 75 6c 6c 2d 74 65 78  e {  /* full-tex
12820 74 20 71 75 65 72 79 20 2a 2f 0a 20 20 20 20 72  t query */.    r
12830 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65  c = sqlite3_rese
12840 74 28 63 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20  t(c->pStmt);.   
12850 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
12860 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
12870 0a 20 20 20 20 69 44 6f 63 69 64 20 3d 20 6e 65  .    iDocid = ne
12880 78 74 44 6f 63 69 64 28 26 63 2d 3e 72 65 73 75  xtDocid(&c->resu
12890 6c 74 29 3b 0a 20 20 20 20 69 66 28 20 69 44 6f  lt);.    if( iDo
128a0 63 69 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  cid==0 ){.      
128b0 63 2d 3e 65 6f 66 20 3d 20 31 3b 0a 20 20 20 20  c->eof = 1;.    
128c0 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
128d0 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63  OK;.    }.    rc
128e0 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   = sqlite3_bind_
128f0 69 6e 74 36 34 28 63 2d 3e 70 53 74 6d 74 2c 20  int64(c->pStmt, 
12900 31 2c 20 69 44 6f 63 69 64 29 3b 0a 20 20 20 20  1, iDocid);.    
12910 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
12920 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
12930 20 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73     /* TODO(shess
12940 29 20 48 61 6e 64 6c 65 20 53 51 4c 49 54 45 5f  ) Handle SQLITE_
12950 53 43 48 45 4d 41 20 41 4e 44 20 53 51 4c 49 54  SCHEMA AND SQLIT
12960 45 5f 42 55 53 59 2e 20 2a 2f 0a 20 20 20 20 72  E_BUSY. */.    r
12970 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70  c = sqlite3_step
12980 28 63 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20  (c->pStmt);.    
12990 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52  if( rc==SQLITE_R
129a0 4f 57 20 29 7b 20 20 20 2f 2a 20 74 68 65 20 63  OW ){   /* the c
129b0 61 73 65 20 77 65 20 65 78 70 65 63 74 20 2a 2f  ase we expect */
129c0 0a 20 20 20 20 20 20 63 2d 3e 65 6f 66 20 3d 20  .      c->eof = 
129d0 30 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  0;.      return 
129e0 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d  SQLITE_OK;.    }
129f0 0a 20 20 20 20 2f 2a 20 61 6e 20 65 72 72 6f 72  .    /* an error
12a00 20 6f 63 63 75 72 72 65 64 3b 20 61 62 6f 72 74   occurred; abort
12a10 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 72   */.    return r
12a20 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 3f  c==SQLITE_DONE ?
12a30 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 20 3a 20   SQLITE_ERROR : 
12a40 72 63 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 20 52  rc;.  }.}.../* R
12a50 65 74 75 72 6e 20 61 20 44 6f 63 4c 69 73 74 20  eturn a DocList 
12a60 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f  corresponding to
12a70 20 74 68 65 20 71 75 65 72 79 20 74 65 72 6d 20   the query term 
12a80 2a 70 54 65 72 6d 2e 20 20 49 66 20 2a 70 54 65  *pTerm.  If *pTe
12a90 72 6d 0a 2a 2a 20 69 73 20 74 68 65 20 66 69 72  rm.** is the fir
12aa0 73 74 20 74 65 72 6d 20 6f 66 20 61 20 70 68 72  st term of a phr
12ab0 61 73 65 20 71 75 65 72 79 2c 20 67 6f 20 61 68  ase query, go ah
12ac0 65 61 64 20 61 6e 64 20 65 76 61 6c 75 61 74 65  ead and evaluate
12ad0 20 74 68 65 20 70 68 72 61 73 65 0a 2a 2a 20 71   the phrase.** q
12ae0 75 65 72 79 20 61 6e 64 20 72 65 74 75 72 6e 20  uery and return 
12af0 74 68 65 20 64 6f 63 6c 69 73 74 20 66 6f 72 20  the doclist for 
12b00 74 68 65 20 65 6e 74 69 72 65 20 70 68 72 61 73  the entire phras
12b10 65 20 71 75 65 72 79 2e 0a 2a 2a 0a 2a 2a 20 54  e query..**.** T
12b20 68 65 20 72 65 73 75 6c 74 20 69 73 20 73 74 6f  he result is sto
12b30 72 65 64 20 69 6e 20 70 54 65 72 6d 2d 3e 64 6f  red in pTerm->do
12b40 63 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  clist..*/.static
12b50 20 69 6e 74 20 64 6f 63 4c 69 73 74 4f 66 54 65   int docListOfTe
12b60 72 6d 28 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76  rm(.  fulltext_v
12b70 74 61 62 20 2a 76 2c 20 20 20 20 20 2f 2a 20 54  tab *v,     /* T
12b80 68 65 20 66 75 6c 6c 20 74 65 78 74 20 69 6e 64  he full text ind
12b90 65 78 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c  ex */.  int iCol
12ba0 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  umn,          /*
12bb0 20 63 6f 6c 75 6d 6e 20 74 6f 20 72 65 73 74 72   column to restr
12bc0 69 63 74 20 74 6f 2e 20 20 4e 6f 20 72 65 73 74  ict to.  No rest
12bd0 72 69 74 69 6f 6e 20 69 66 20 3e 3d 6e 43 6f 6c  rition if >=nCol
12be0 75 6d 6e 20 2a 2f 0a 20 20 51 75 65 72 79 54 65  umn */.  QueryTe
12bf0 72 6d 20 2a 70 51 54 65 72 6d 2c 20 20 20 20 2f  rm *pQTerm,    /
12c00 2a 20 54 65 72 6d 20 77 65 20 61 72 65 20 6c 6f  * Term we are lo
12c10 6f 6b 69 6e 67 20 66 6f 72 2c 20 6f 72 20 31 73  oking for, or 1s
12c20 74 20 74 65 72 6d 20 6f 66 20 61 20 70 68 72 61  t term of a phra
12c30 73 65 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 20  se */.  DocList 
12c40 2a 2a 70 70 52 65 73 75 6c 74 20 20 20 20 2f 2a  **ppResult    /*
12c50 20 57 72 69 74 65 20 74 68 65 20 72 65 73 75 6c   Write the resul
12c60 74 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 44  t here */.){.  D
12c70 6f 63 4c 69 73 74 20 2a 70 4c 65 66 74 2c 20 2a  ocList *pLeft, *
12c80 70 52 69 67 68 74 2c 20 2a 70 4e 65 77 3b 0a 20  pRight, *pNew;. 
12c90 20 69 6e 74 20 69 2c 20 72 63 3b 0a 0a 20 20 70   int i, rc;..  p
12ca0 4c 65 66 74 20 3d 20 64 6f 63 4c 69 73 74 4e 65  Left = docListNe
12cb0 77 28 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 29 3b  w(DL_POSITIONS);
12cc0 0a 20 20 72 63 20 3d 20 74 65 72 6d 5f 73 65 6c  .  rc = term_sel
12cd0 65 63 74 5f 61 6c 6c 28 76 2c 20 69 43 6f 6c 75  ect_all(v, iColu
12ce0 6d 6e 2c 20 70 51 54 65 72 6d 2d 3e 70 54 65 72  mn, pQTerm->pTer
12cf0 6d 2c 20 70 51 54 65 72 6d 2d 3e 6e 54 65 72 6d  m, pQTerm->nTerm
12d00 2c 20 70 4c 65 66 74 29 3b 0a 20 20 69 66 28 20  , pLeft);.  if( 
12d10 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  rc ) return rc;.
12d20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 3d 70 51    for(i=1; i<=pQ
12d30 54 65 72 6d 2d 3e 6e 50 68 72 61 73 65 3b 20 69  Term->nPhrase; i
12d40 2b 2b 29 7b 0a 20 20 20 20 70 52 69 67 68 74 20  ++){.    pRight 
12d50 3d 20 64 6f 63 4c 69 73 74 4e 65 77 28 44 4c 5f  = docListNew(DL_
12d60 50 4f 53 49 54 49 4f 4e 53 29 3b 0a 20 20 20 20  POSITIONS);.    
12d70 72 63 20 3d 20 74 65 72 6d 5f 73 65 6c 65 63 74  rc = term_select
12d80 5f 61 6c 6c 28 76 2c 20 69 43 6f 6c 75 6d 6e 2c  _all(v, iColumn,
12d90 20 70 51 54 65 72 6d 5b 69 5d 2e 70 54 65 72 6d   pQTerm[i].pTerm
12da0 2c 20 70 51 54 65 72 6d 5b 69 5d 2e 6e 54 65 72  , pQTerm[i].nTer
12db0 6d 2c 20 70 52 69 67 68 74 29 3b 0a 20 20 20 20  m, pRight);.    
12dc0 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 20 20  if( rc ){.      
12dd0 64 6f 63 4c 69 73 74 44 65 6c 65 74 65 28 70 4c  docListDelete(pL
12de0 65 66 74 29 3b 0a 20 20 20 20 20 20 72 65 74 75  eft);.      retu
12df0 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20  rn rc;.    }.   
12e00 20 70 4e 65 77 20 3d 20 64 6f 63 4c 69 73 74 4e   pNew = docListN
12e10 65 77 28 69 3c 70 51 54 65 72 6d 2d 3e 6e 50 68  ew(i<pQTerm->nPh
12e20 72 61 73 65 20 3f 20 44 4c 5f 50 4f 53 49 54 49  rase ? DL_POSITI
12e30 4f 4e 53 20 3a 20 44 4c 5f 44 4f 43 49 44 53 29  ONS : DL_DOCIDS)
12e40 3b 0a 20 20 20 20 64 6f 63 4c 69 73 74 50 68 72  ;.    docListPhr
12e50 61 73 65 4d 65 72 67 65 28 70 4c 65 66 74 2c 20  aseMerge(pLeft, 
12e60 70 52 69 67 68 74 2c 20 70 4e 65 77 29 3b 0a 20  pRight, pNew);. 
12e70 20 20 20 64 6f 63 4c 69 73 74 44 65 6c 65 74 65     docListDelete
12e80 28 70 4c 65 66 74 29 3b 0a 20 20 20 20 64 6f 63  (pLeft);.    doc
12e90 4c 69 73 74 44 65 6c 65 74 65 28 70 52 69 67 68  ListDelete(pRigh
12ea0 74 29 3b 0a 20 20 20 20 70 4c 65 66 74 20 3d 20  t);.    pLeft = 
12eb0 70 4e 65 77 3b 0a 20 20 7d 0a 20 20 2a 70 70 52  pNew;.  }.  *ppR
12ec0 65 73 75 6c 74 20 3d 20 70 4c 65 66 74 3b 0a 20  esult = pLeft;. 
12ed0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
12ee0 4b 3b 0a 7d 0a 0a 2f 2a 20 41 64 64 20 61 20 6e  K;.}../* Add a n
12ef0 65 77 20 74 65 72 6d 20 70 54 65 72 6d 5b 30 2e  ew term pTerm[0.
12f00 2e 6e 54 65 72 6d 2d 31 5d 20 74 6f 20 74 68 65  .nTerm-1] to the
12f10 20 71 75 65 72 79 20 2a 71 2e 0a 2a 2f 0a 73 74   query *q..*/.st
12f20 61 74 69 63 20 76 6f 69 64 20 71 75 65 72 79 41  atic void queryA
12f30 64 64 28 51 75 65 72 79 20 2a 71 2c 20 63 6f 6e  dd(Query *q, con
12f40 73 74 20 63 68 61 72 20 2a 70 54 65 72 6d 2c 20  st char *pTerm, 
12f50 69 6e 74 20 6e 54 65 72 6d 29 7b 0a 20 20 51 75  int nTerm){.  Qu
12f60 65 72 79 54 65 72 6d 20 2a 74 3b 0a 20 20 2b 2b  eryTerm *t;.  ++
12f70 71 2d 3e 6e 54 65 72 6d 73 3b 0a 20 20 71 2d 3e  q->nTerms;.  q->
12f80 70 54 65 72 6d 73 20 3d 20 72 65 61 6c 6c 6f 63  pTerms = realloc
12f90 28 71 2d 3e 70 54 65 72 6d 73 2c 20 71 2d 3e 6e  (q->pTerms, q->n
12fa0 54 65 72 6d 73 20 2a 20 73 69 7a 65 6f 66 28 71  Terms * sizeof(q
12fb0 2d 3e 70 54 65 72 6d 73 5b 30 5d 29 29 3b 0a 20  ->pTerms[0]));. 
12fc0 20 69 66 28 20 71 2d 3e 70 54 65 72 6d 73 3d 3d   if( q->pTerms==
12fd0 30 20 29 7b 0a 20 20 20 20 71 2d 3e 6e 54 65 72  0 ){.    q->nTer
12fe0 6d 73 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75  ms = 0;.    retu
12ff0 72 6e 3b 0a 20 20 7d 0a 20 20 74 20 3d 20 26 71  rn;.  }.  t = &q
13000 2d 3e 70 54 65 72 6d 73 5b 71 2d 3e 6e 54 65 72  ->pTerms[q->nTer
13010 6d 73 20 2d 20 31 5d 3b 0a 20 20 6d 65 6d 73 65  ms - 1];.  memse
13020 74 28 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a  t(t, 0, sizeof(*
13030 74 29 29 3b 0a 20 20 74 2d 3e 70 54 65 72 6d 20  t));.  t->pTerm 
13040 3d 20 6d 61 6c 6c 6f 63 28 6e 54 65 72 6d 2b 31  = malloc(nTerm+1
13050 29 3b 0a 20 20 6d 65 6d 63 70 79 28 74 2d 3e 70  );.  memcpy(t->p
13060 54 65 72 6d 2c 20 70 54 65 72 6d 2c 20 6e 54 65  Term, pTerm, nTe
13070 72 6d 29 3b 0a 20 20 74 2d 3e 70 54 65 72 6d 5b  rm);.  t->pTerm[
13080 6e 54 65 72 6d 5d 20 3d 20 30 3b 0a 20 20 74 2d  nTerm] = 0;.  t-
13090 3e 6e 54 65 72 6d 20 3d 20 6e 54 65 72 6d 3b 0a  >nTerm = nTerm;.
130a0 20 20 74 2d 3e 69 73 4f 72 20 3d 20 71 2d 3e 6e    t->isOr = q->n
130b0 65 78 74 49 73 4f 72 3b 0a 20 20 71 2d 3e 6e 65  extIsOr;.  q->ne
130c0 78 74 49 73 4f 72 20 3d 20 30 3b 0a 20 20 74 2d  xtIsOr = 0;.  t-
130d0 3e 69 43 6f 6c 75 6d 6e 20 3d 20 71 2d 3e 6e 65  >iColumn = q->ne
130e0 78 74 43 6f 6c 75 6d 6e 3b 0a 20 20 71 2d 3e 6e  xtColumn;.  q->n
130f0 65 78 74 43 6f 6c 75 6d 6e 20 3d 20 71 2d 3e 64  extColumn = q->d
13100 66 6c 74 43 6f 6c 75 6d 6e 3b 0a 7d 0a 0a 2f 2a  fltColumn;.}../*
13110 0a 2a 2a 20 43 68 65 63 6b 20 74 6f 20 73 65 65  .** Check to see
13120 20 69 66 20 74 68 65 20 73 74 72 69 6e 67 20 7a   if the string z
13130 54 6f 6b 65 6e 5b 30 2e 2e 2e 6e 54 6f 6b 65 6e  Token[0...nToken
13140 2d 31 5d 20 6d 61 74 63 68 65 73 20 61 6e 79 0a  -1] matches any.
13150 2a 2a 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 20 69  ** column name i
13160 6e 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  n the virtual ta
13170 62 6c 65 2e 20 20 20 49 66 20 69 74 20 64 6f 65  ble.   If it doe
13180 73 2c 0a 2a 2a 20 72 65 74 75 72 6e 20 74 68 65  s,.** return the
13190 20 7a 65 72 6f 2d 69 6e 64 65 78 65 64 20 63 6f   zero-indexed co
131a0 6c 75 6d 6e 20 6e 75 6d 62 65 72 2e 20 20 49 66  lumn number.  If
131b0 20 6e 6f 74 2c 20 72 65 74 75 72 6e 20 2d 31 2e   not, return -1.
131c0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 63  .*/.static int c
131d0 68 65 63 6b 43 6f 6c 75 6d 6e 53 70 65 63 69 66  heckColumnSpecif
131e0 69 65 72 28 0a 20 20 66 75 6c 6c 74 65 78 74 5f  ier(.  fulltext_
131f0 76 74 61 62 20 2a 70 56 74 61 62 2c 20 20 20 20  vtab *pVtab,    
13200 2f 2a 20 54 68 65 20 76 69 72 74 75 61 6c 20 74  /* The virtual t
13210 61 62 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  able */.  const 
13220 63 68 61 72 20 2a 7a 54 6f 6b 65 6e 2c 20 20 20  char *zToken,   
13230 20 20 20 2f 2a 20 54 65 78 74 20 6f 66 20 74 68     /* Text of th
13240 65 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74  e token */.  int
13250 20 6e 54 6f 6b 65 6e 20 20 20 20 20 20 20 20 20   nToken         
13260 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
13270 6f 66 20 63 68 61 72 61 63 74 65 72 73 20 69 6e  of characters in
13280 20 74 68 65 20 74 6f 6b 65 6e 20 2a 2f 0a 29 7b   the token */.){
13290 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28  .  int i;.  for(
132a0 69 3d 30 3b 20 69 3c 70 56 74 61 62 2d 3e 6e 43  i=0; i<pVtab->nC
132b0 6f 6c 75 6d 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20  olumn; i++){.   
132c0 20 69 66 28 20 6d 65 6d 63 6d 70 28 70 56 74 61   if( memcmp(pVta
132d0 62 2d 3e 61 7a 43 6f 6c 75 6d 6e 5b 69 5d 2c 20  b->azColumn[i], 
132e0 7a 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 29 3d  zToken, nToken)=
132f0 3d 30 0a 20 20 20 20 20 20 20 20 26 26 20 70 56  =0.        && pV
13300 74 61 62 2d 3e 61 7a 43 6f 6c 75 6d 6e 5b 69 5d  tab->azColumn[i]
13310 5b 6e 54 6f 6b 65 6e 5d 3d 3d 30 20 29 7b 0a 20  [nToken]==0 ){. 
13320 20 20 20 20 20 72 65 74 75 72 6e 20 69 3b 0a 20       return i;. 
13330 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
13340 6e 20 2d 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50  n -1;.}../*.** P
13350 61 72 73 65 20 74 68 65 20 74 65 78 74 20 61 74  arse the text at
13360 20 70 53 65 67 6d 65 6e 74 5b 30 2e 2e 6e 53 65   pSegment[0..nSe
13370 67 6d 65 6e 74 2d 31 5d 2e 20 20 41 64 64 20 61  gment-1].  Add a
13380 64 64 69 74 69 6f 6e 61 6c 20 74 65 72 6d 73 0a  dditional terms.
13390 2a 2a 20 74 6f 20 74 68 65 20 71 75 65 72 79 20  ** to the query 
133a0 62 65 69 6e 67 20 61 73 73 65 6d 62 6c 69 65 64  being assemblied
133b0 20 69 6e 20 70 51 75 65 72 79 2e 0a 2a 2a 0a 2a   in pQuery..**.*
133c0 2a 20 69 6e 50 68 72 61 73 65 20 69 73 20 74 72  * inPhrase is tr
133d0 75 65 20 69 66 20 70 53 65 67 6d 65 6e 74 5b 30  ue if pSegment[0
133e0 2e 2e 6e 53 65 67 65 6d 65 6e 74 2d 31 5d 20 69  ..nSegement-1] i
133f0 73 20 63 6f 6e 74 61 69 6e 65 64 20 77 69 74 68  s contained with
13400 69 6e 0a 2a 2a 20 64 6f 75 62 6c 65 2d 71 75 6f  in.** double-quo
13410 74 65 73 2e 20 20 49 66 20 69 6e 50 68 72 61 73  tes.  If inPhras
13420 65 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e 20  e is true, then 
13430 74 68 65 20 66 69 72 73 74 20 74 65 72 6d 0a 2a  the first term.*
13440 2a 20 69 73 20 6d 61 72 6b 65 64 20 77 69 74 68  * is marked with
13450 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 74   the number of t
13460 65 72 6d 73 20 69 6e 20 74 68 65 20 70 68 72 61  erms in the phra
13470 73 65 20 6c 65 73 73 20 6f 6e 65 20 61 6e 64 0a  se less one and.
13480 2a 2a 20 4f 52 20 61 6e 64 20 22 2d 22 20 73 79  ** OR and "-" sy
13490 6e 74 61 78 20 69 73 20 69 67 6e 6f 72 65 64 2e  ntax is ignored.
134a0 20 20 49 66 20 69 6e 50 68 72 61 73 65 20 69 73    If inPhrase is
134b0 20 66 61 6c 73 65 2c 20 74 68 65 6e 20 65 76 65   false, then eve
134c0 72 79 0a 2a 2a 20 74 65 72 6d 20 66 6f 75 6e 64  ry.** term found
134d0 20 69 73 20 6d 61 72 6b 65 64 20 77 69 74 68 20   is marked with 
134e0 6e 50 68 72 61 73 65 3d 30 20 61 6e 64 20 4f 52  nPhrase=0 and OR
134f0 20 61 6e 64 20 22 2d 22 20 73 79 6e 74 61 78 20   and "-" syntax 
13500 69 73 20 73 69 67 6e 69 66 69 63 61 6e 74 2e 0a  is significant..
13510 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 6f  */.static int to
13520 6b 65 6e 69 7a 65 53 65 67 6d 65 6e 74 28 0a 20  kenizeSegment(. 
13530 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a   sqlite3_tokeniz
13540 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 2c 20  er *pTokenizer, 
13550 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
13560 74 6f 6b 65 6e 69 7a 65 72 20 74 6f 20 75 73 65  tokenizer to use
13570 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
13580 20 2a 70 53 65 67 6d 65 6e 74 2c 20 69 6e 74 20   *pSegment, int 
13590 6e 53 65 67 6d 65 6e 74 2c 20 20 20 20 20 2f 2a  nSegment,     /*
135a0 20 51 75 65 72 79 20 65 78 70 72 65 73 73 69 6f   Query expressio
135b0 6e 20 62 65 69 6e 67 20 70 61 72 73 65 64 20 2a  n being parsed *
135c0 2f 0a 20 20 69 6e 74 20 69 6e 50 68 72 61 73 65  /.  int inPhrase
135d0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
135e0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
135f0 72 75 65 20 69 66 20 77 69 74 68 69 6e 20 22 2e  rue if within ".
13600 2e 2e 22 20 2a 2f 0a 20 20 51 75 65 72 79 20 2a  .." */.  Query *
13610 70 51 75 65 72 79 20 20 20 20 20 20 20 20 20 20  pQuery          
13620 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13630 20 2f 2a 20 41 70 70 65 6e 64 20 72 65 73 75 6c   /* Append resul
13640 74 73 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20  ts here */.){.  
13650 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 74 6f  const sqlite3_to
13660 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 2a  kenizer_module *
13670 70 4d 6f 64 75 6c 65 20 3d 20 70 54 6f 6b 65 6e  pModule = pToken
13680 69 7a 65 72 2d 3e 70 4d 6f 64 75 6c 65 3b 0a 20  izer->pModule;. 
13690 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a   sqlite3_tokeniz
136a0 65 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73  er_cursor *pCurs
136b0 6f 72 3b 0a 20 20 69 6e 74 20 66 69 72 73 74 49  or;.  int firstI
136c0 6e 64 65 78 20 3d 20 70 51 75 65 72 79 2d 3e 6e  ndex = pQuery->n
136d0 54 65 72 6d 73 3b 0a 20 20 69 6e 74 20 69 43 6f  Terms;.  int iCo
136e0 6c 3b 0a 20 20 69 6e 74 20 6e 54 65 72 6d 20 3d  l;.  int nTerm =
136f0 20 31 3b 0a 20 20 0a 20 20 69 6e 74 20 72 63 20   1;.  .  int rc 
13700 3d 20 70 4d 6f 64 75 6c 65 2d 3e 78 4f 70 65 6e  = pModule->xOpen
13710 28 70 54 6f 6b 65 6e 69 7a 65 72 2c 20 70 53 65  (pTokenizer, pSe
13720 67 6d 65 6e 74 2c 20 6e 53 65 67 6d 65 6e 74 2c  gment, nSegment,
13730 20 26 70 43 75 72 73 6f 72 29 3b 0a 20 20 69 66   &pCursor);.  if
13740 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
13750 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 70  ) return rc;.  p
13760 43 75 72 73 6f 72 2d 3e 70 54 6f 6b 65 6e 69 7a  Cursor->pTokeniz
13770 65 72 20 3d 20 70 54 6f 6b 65 6e 69 7a 65 72 3b  er = pTokenizer;
13780 0a 0a 20 20 77 68 69 6c 65 28 20 31 20 29 7b 0a  ..  while( 1 ){.
13790 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
137a0 70 54 6f 6b 65 6e 3b 0a 20 20 20 20 69 6e 74 20  pToken;.    int 
137b0 6e 54 6f 6b 65 6e 2c 20 69 42 65 67 69 6e 2c 20  nToken, iBegin, 
137c0 69 45 6e 64 2c 20 69 50 6f 73 3b 0a 0a 20 20 20  iEnd, iPos;..   
137d0 20 72 63 20 3d 20 70 4d 6f 64 75 6c 65 2d 3e 78   rc = pModule->x
137e0 4e 65 78 74 28 70 43 75 72 73 6f 72 2c 0a 20 20  Next(pCursor,.  
137f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13800 20 20 20 20 20 20 26 70 54 6f 6b 65 6e 2c 20 26        &pToken, &
13810 6e 54 6f 6b 65 6e 2c 0a 20 20 20 20 20 20 20 20  nToken,.        
13820 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13830 26 69 42 65 67 69 6e 2c 20 26 69 45 6e 64 2c 20  &iBegin, &iEnd, 
13840 26 69 50 6f 73 29 3b 0a 20 20 20 20 69 66 28 20  &iPos);.    if( 
13850 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
13860 62 72 65 61 6b 3b 0a 20 20 20 20 69 66 28 20 21  break;.    if( !
13870 69 6e 50 68 72 61 73 65 20 26 26 0a 20 20 20 20  inPhrase &&.    
13880 20 20 20 20 70 53 65 67 6d 65 6e 74 5b 69 45 6e      pSegment[iEn
13890 64 5d 3d 3d 27 3a 27 20 26 26 0a 20 20 20 20 20  d]==':' &&.     
138a0 20 20 20 20 28 69 43 6f 6c 20 3d 20 63 68 65 63      (iCol = chec
138b0 6b 43 6f 6c 75 6d 6e 53 70 65 63 69 66 69 65 72  kColumnSpecifier
138c0 28 70 51 75 65 72 79 2d 3e 70 46 74 73 2c 20 70  (pQuery->pFts, p
138d0 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 29 29 3e  Token, nToken))>
138e0 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 51 75 65  =0 ){.      pQue
138f0 72 79 2d 3e 6e 65 78 74 43 6f 6c 75 6d 6e 20 3d  ry->nextColumn =
13900 20 69 43 6f 6c 3b 0a 20 20 20 20 20 20 63 6f 6e   iCol;.      con
13910 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 20 20 20  tinue;.    }.   
13920 20 69 66 28 20 21 69 6e 50 68 72 61 73 65 20 26   if( !inPhrase &
13930 26 20 70 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73  & pQuery->nTerms
13940 3e 30 20 26 26 20 6e 54 6f 6b 65 6e 3d 3d 32 0a  >0 && nToken==2.
13950 20 20 20 20 20 20 20 20 20 26 26 20 70 53 65 67           && pSeg
13960 6d 65 6e 74 5b 69 42 65 67 69 6e 5d 3d 3d 27 4f  ment[iBegin]=='O
13970 27 20 26 26 20 70 53 65 67 6d 65 6e 74 5b 69 42  ' && pSegment[iB
13980 65 67 69 6e 2b 31 5d 3d 3d 27 52 27 20 29 7b 0a  egin+1]=='R' ){.
13990 20 20 20 20 20 20 70 51 75 65 72 79 2d 3e 6e 65        pQuery->ne
139a0 78 74 49 73 4f 72 20 3d 20 31 3b 0a 20 20 20 20  xtIsOr = 1;.    
139b0 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20    continue;.    
139c0 7d 0a 20 20 20 20 71 75 65 72 79 41 64 64 28 70  }.    queryAdd(p
139d0 51 75 65 72 79 2c 20 70 54 6f 6b 65 6e 2c 20 6e  Query, pToken, n
139e0 54 6f 6b 65 6e 29 3b 0a 20 20 20 20 69 66 28 20  Token);.    if( 
139f0 21 69 6e 50 68 72 61 73 65 20 26 26 20 69 42 65  !inPhrase && iBe
13a00 67 69 6e 3e 30 20 26 26 20 70 53 65 67 6d 65 6e  gin>0 && pSegmen
13a10 74 5b 69 42 65 67 69 6e 2d 31 5d 3d 3d 27 2d 27  t[iBegin-1]=='-'
13a20 20 29 7b 0a 20 20 20 20 20 20 70 51 75 65 72 79   ){.      pQuery
13a30 2d 3e 70 54 65 72 6d 73 5b 70 51 75 65 72 79 2d  ->pTerms[pQuery-
13a40 3e 6e 54 65 72 6d 73 2d 31 5d 2e 69 73 4e 6f 74  >nTerms-1].isNot
13a50 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20   = 1;.    }.    
13a60 70 51 75 65 72 79 2d 3e 70 54 65 72 6d 73 5b 70  pQuery->pTerms[p
13a70 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73 2d 31 5d  Query->nTerms-1]
13a80 2e 69 50 68 72 61 73 65 20 3d 20 6e 54 65 72 6d  .iPhrase = nTerm
13a90 3b 0a 20 20 20 20 69 66 28 20 69 6e 50 68 72 61  ;.    if( inPhra
13aa0 73 65 20 29 7b 0a 20 20 20 20 20 20 6e 54 65 72  se ){.      nTer
13ab0 6d 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  m++;.    }.  }..
13ac0 20 20 69 66 28 20 69 6e 50 68 72 61 73 65 20 26    if( inPhrase &
13ad0 26 20 70 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73  & pQuery->nTerms
13ae0 3e 66 69 72 73 74 49 6e 64 65 78 20 29 7b 0a 20  >firstIndex ){. 
13af0 20 20 20 70 51 75 65 72 79 2d 3e 70 54 65 72 6d     pQuery->pTerm
13b00 73 5b 66 69 72 73 74 49 6e 64 65 78 5d 2e 6e 50  s[firstIndex].nP
13b10 68 72 61 73 65 20 3d 20 70 51 75 65 72 79 2d 3e  hrase = pQuery->
13b20 6e 54 65 72 6d 73 20 2d 20 66 69 72 73 74 49 6e  nTerms - firstIn
13b30 64 65 78 20 2d 20 31 3b 0a 20 20 7d 0a 0a 20 20  dex - 1;.  }..  
13b40 72 65 74 75 72 6e 20 70 4d 6f 64 75 6c 65 2d 3e  return pModule->
13b50 78 43 6c 6f 73 65 28 70 43 75 72 73 6f 72 29 3b  xClose(pCursor);
13b60 0a 7d 0a 0a 2f 2a 20 50 61 72 73 65 20 61 20 71  .}../* Parse a q
13b70 75 65 72 79 20 73 74 72 69 6e 67 2c 20 79 69 65  uery string, yie
13b80 6c 64 69 6e 67 20 61 20 51 75 65 72 79 20 6f 62  lding a Query ob
13b90 6a 65 63 74 20 70 51 75 65 72 79 2e 0a 2a 2a 0a  ject pQuery..**.
13ba0 2a 2a 20 54 68 65 20 63 61 6c 6c 69 6e 67 20 66  ** The calling f
13bb0 75 6e 63 74 69 6f 6e 20 77 69 6c 6c 20 6e 65 65  unction will nee
13bc0 64 20 74 6f 20 71 75 65 72 79 43 6c 65 61 72 28  d to queryClear(
13bd0 29 20 74 6f 20 63 6c 65 61 6e 20 75 70 0a 2a 2a  ) to clean up.**
13be0 20 74 68 65 20 64 79 6e 61 6d 69 63 61 6c 6c 79   the dynamically
13bf0 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72   allocated memor
13c00 79 20 68 65 6c 64 20 62 79 20 70 51 75 65 72 79  y held by pQuery
13c10 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
13c20 70 61 72 73 65 51 75 65 72 79 28 0a 20 20 66 75  parseQuery(.  fu
13c30 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20  lltext_vtab *v, 
13c40 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 66 75         /* The fu
13c50 6c 6c 74 65 78 74 20 69 6e 64 65 78 20 2a 2f 0a  lltext index */.
13c60 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49    const char *zI
13c70 6e 70 75 74 2c 20 20 20 20 20 20 2f 2a 20 49 6e  nput,      /* In
13c80 70 75 74 20 74 65 78 74 20 6f 66 20 74 68 65 20  put text of the 
13c90 71 75 65 72 79 20 73 74 72 69 6e 67 20 2a 2f 0a  query string */.
13ca0 20 20 69 6e 74 20 6e 49 6e 70 75 74 2c 20 20 20    int nInput,   
13cb0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
13cc0 7a 65 20 6f 66 20 74 68 65 20 69 6e 70 75 74 20  ze of the input 
13cd0 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74 20 64 66  text */.  int df
13ce0 6c 74 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20  ltColumn,       
13cf0 20 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 63 6f     /* Default co
13d00 6c 75 6d 6e 20 6f 66 20 74 68 65 20 69 6e 64 65  lumn of the inde
13d10 78 20 74 6f 20 6d 61 74 63 68 20 61 67 61 69 6e  x to match again
13d20 73 74 20 2a 2f 0a 20 20 51 75 65 72 79 20 2a 70  st */.  Query *p
13d30 51 75 65 72 79 20 20 20 20 20 20 20 20 20 20 20  Query           
13d40 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 70 61   /* Write the pa
13d50 72 73 65 20 72 65 73 75 6c 74 73 20 68 65 72 65  rse results here
13d60 2e 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 49  . */.){.  int iI
13d70 6e 70 75 74 2c 20 69 6e 50 68 72 61 73 65 20 3d  nput, inPhrase =
13d80 20 30 3b 0a 0a 20 20 69 66 28 20 7a 49 6e 70 75   0;..  if( zInpu
13d90 74 3d 3d 30 20 29 20 6e 49 6e 70 75 74 20 3d 20  t==0 ) nInput = 
13da0 30 3b 0a 20 20 69 66 28 20 6e 49 6e 70 75 74 3c  0;.  if( nInput<
13db0 30 20 29 20 6e 49 6e 70 75 74 20 3d 20 73 74 72  0 ) nInput = str
13dc0 6c 65 6e 28 7a 49 6e 70 75 74 29 3b 0a 20 20 70  len(zInput);.  p
13dd0 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73 20 3d 20  Query->nTerms = 
13de0 30 3b 0a 20 20 70 51 75 65 72 79 2d 3e 70 54 65  0;.  pQuery->pTe
13df0 72 6d 73 20 3d 20 4e 55 4c 4c 3b 0a 20 20 70 51  rms = NULL;.  pQ
13e00 75 65 72 79 2d 3e 6e 65 78 74 49 73 4f 72 20 3d  uery->nextIsOr =
13e10 20 30 3b 0a 20 20 70 51 75 65 72 79 2d 3e 6e 65   0;.  pQuery->ne
13e20 78 74 43 6f 6c 75 6d 6e 20 3d 20 64 66 6c 74 43  xtColumn = dfltC
13e30 6f 6c 75 6d 6e 3b 0a 20 20 70 51 75 65 72 79 2d  olumn;.  pQuery-
13e40 3e 64 66 6c 74 43 6f 6c 75 6d 6e 20 3d 20 64 66  >dfltColumn = df
13e50 6c 74 43 6f 6c 75 6d 6e 3b 0a 20 20 70 51 75 65  ltColumn;.  pQue
13e60 72 79 2d 3e 70 46 74 73 20 3d 20 76 3b 0a 0a 20  ry->pFts = v;.. 
13e70 20 66 6f 72 28 69 49 6e 70 75 74 3d 30 3b 20 69   for(iInput=0; i
13e80 49 6e 70 75 74 3c 6e 49 6e 70 75 74 3b 20 2b 2b  Input<nInput; ++
13e90 69 49 6e 70 75 74 29 7b 0a 20 20 20 20 69 6e 74  iInput){.    int
13ea0 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 69 49   i;.    for(i=iI
13eb0 6e 70 75 74 3b 20 69 3c 6e 49 6e 70 75 74 20 26  nput; i<nInput &
13ec0 26 20 7a 49 6e 70 75 74 5b 69 5d 21 3d 27 22 27  & zInput[i]!='"'
13ed0 3b 20 2b 2b 69 29 7b 7d 0a 20 20 20 20 69 66 28  ; ++i){}.    if(
13ee0 20 69 3e 69 49 6e 70 75 74 20 29 7b 0a 20 20 20   i>iInput ){.   
13ef0 20 20 20 74 6f 6b 65 6e 69 7a 65 53 65 67 6d 65     tokenizeSegme
13f00 6e 74 28 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72  nt(v->pTokenizer
13f10 2c 20 7a 49 6e 70 75 74 2b 69 49 6e 70 75 74 2c  , zInput+iInput,
13f20 20 69 2d 69 49 6e 70 75 74 2c 20 69 6e 50 68 72   i-iInput, inPhr
13f30 61 73 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ase,.           
13f40 20 20 20 20 20 20 20 20 20 20 20 20 70 51 75 65              pQue
13f50 72 79 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  ry);.    }.    i
13f60 49 6e 70 75 74 20 3d 20 69 3b 0a 20 20 20 20 69  Input = i;.    i
13f70 66 28 20 69 3c 6e 49 6e 70 75 74 20 29 7b 0a 20  f( i<nInput ){. 
13f80 20 20 20 20 20 61 73 73 65 72 74 28 20 7a 49 6e       assert( zIn
13f90 70 75 74 5b 69 5d 3d 3d 27 22 27 20 29 3b 0a 20  put[i]=='"' );. 
13fa0 20 20 20 20 20 69 6e 50 68 72 61 73 65 20 3d 20       inPhrase = 
13fb0 21 69 6e 50 68 72 61 73 65 3b 0a 20 20 20 20 7d  !inPhrase;.    }
13fc0 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 6e 50 68  .  }..  if( inPh
13fd0 72 61 73 65 20 29 7b 0a 20 20 20 20 2f 2a 20 75  rase ){.    /* u
13fe0 6e 6d 61 74 63 68 65 64 20 71 75 6f 74 65 20 2a  nmatched quote *
13ff0 2f 0a 20 20 20 20 71 75 65 72 79 43 6c 65 61 72  /.    queryClear
14000 28 70 51 75 65 72 79 29 3b 0a 20 20 20 20 72 65  (pQuery);.    re
14010 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f  turn SQLITE_ERRO
14020 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  R;.  }.  return 
14030 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
14040 20 50 65 72 66 6f 72 6d 20 61 20 66 75 6c 6c 2d   Perform a full-
14050 74 65 78 74 20 71 75 65 72 79 20 75 73 69 6e 67  text query using
14060 20 74 68 65 20 73 65 61 72 63 68 20 65 78 70 72   the search expr
14070 65 73 73 69 6f 6e 20 69 6e 0a 2a 2a 20 7a 49 6e  ession in.** zIn
14080 70 75 74 5b 30 2e 2e 6e 49 6e 70 75 74 2d 31 5d  put[0..nInput-1]
14090 2e 20 20 52 65 74 75 72 6e 20 61 20 6c 69 73 74  .  Return a list
140a0 20 6f 66 20 6d 61 74 63 68 69 6e 67 20 64 6f 63   of matching doc
140b0 75 6d 65 6e 74 73 0a 2a 2a 20 69 6e 20 70 52 65  uments.** in pRe
140c0 73 75 6c 74 2e 0a 2a 2a 0a 2a 2a 20 51 75 65 72  sult..**.** Quer
140d0 69 65 73 20 6d 75 73 74 20 6d 61 74 63 68 20 63  ies must match c
140e0 6f 6c 75 6d 6e 20 69 43 6f 6c 75 6d 6e 2e 20 20  olumn iColumn.  
140f0 4f 72 20 69 66 20 69 43 6f 6c 75 6d 6e 3e 3d 6e  Or if iColumn>=n
14100 43 6f 6c 75 6d 6e 0a 2a 2a 20 74 68 65 79 20 61  Column.** they a
14110 72 65 20 61 6c 6c 6f 77 65 64 20 74 6f 20 6d 61  re allowed to ma
14120 74 63 68 20 61 67 61 69 6e 73 74 20 61 6e 79 20  tch against any 
14130 63 6f 6c 75 6d 6e 2e 0a 2a 2f 0a 73 74 61 74 69  column..*/.stati
14140 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 51 75  c int fulltextQu
14150 65 72 79 28 0a 20 20 66 75 6c 6c 74 65 78 74 5f  ery(.  fulltext_
14160 76 74 61 62 20 2a 76 2c 20 20 20 20 20 20 2f 2a  vtab *v,      /*
14170 20 54 68 65 20 66 75 6c 6c 20 74 65 78 74 20 69   The full text i
14180 6e 64 65 78 20 2a 2f 0a 20 20 69 6e 74 20 69 43  ndex */.  int iC
14190 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20  olumn,          
141a0 20 2f 2a 20 4d 61 74 63 68 20 61 67 61 69 6e 73   /* Match agains
141b0 74 20 74 68 69 73 20 63 6f 6c 75 6d 6e 20 62 79  t this column by
141c0 20 64 65 66 61 75 6c 74 20 2a 2f 0a 20 20 63 6f   default */.  co
141d0 6e 73 74 20 63 68 61 72 20 2a 7a 49 6e 70 75 74  nst char *zInput
141e0 2c 20 20 20 20 2f 2a 20 54 68 65 20 71 75 65 72  ,    /* The quer
141f0 79 20 73 74 72 69 6e 67 20 2a 2f 0a 20 20 69 6e  y string */.  in
14200 74 20 6e 49 6e 70 75 74 2c 20 20 20 20 20 20 20  t nInput,       
14210 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
14220 66 20 62 79 74 65 73 20 69 6e 20 7a 49 6e 70 75  f bytes in zInpu
14230 74 5b 5d 20 2a 2f 0a 20 20 44 6f 63 4c 69 73 74  t[] */.  DocList
14240 20 2a 2a 70 52 65 73 75 6c 74 2c 20 20 20 20 20   **pResult,     
14250 2f 2a 20 57 72 69 74 65 20 74 68 65 20 72 65 73  /* Write the res
14260 75 6c 74 20 64 6f 63 6c 69 73 74 20 68 65 72 65  ult doclist here
14270 20 2a 2f 0a 20 20 51 75 65 72 79 20 2a 70 51 75   */.  Query *pQu
14280 65 72 79 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ery          /* 
14290 50 75 74 20 70 61 72 73 65 64 20 71 75 65 72 79  Put parsed query
142a0 20 73 74 72 69 6e 67 20 68 65 72 65 20 2a 2f 0a   string here */.
142b0 29 7b 0a 20 20 69 6e 74 20 69 2c 20 69 4e 65 78  ){.  int i, iNex
142c0 74 2c 20 72 63 3b 0a 20 20 44 6f 63 4c 69 73 74  t, rc;.  DocList
142d0 20 2a 70 4c 65 66 74 20 3d 20 4e 55 4c 4c 3b 0a   *pLeft = NULL;.
142e0 20 20 44 6f 63 4c 69 73 74 20 2a 70 52 69 67 68    DocList *pRigh
142f0 74 2c 20 2a 70 4e 65 77 2c 20 2a 70 4f 72 3b 0a  t, *pNew, *pOr;.
14300 20 20 69 6e 74 20 6e 4e 6f 74 20 3d 20 30 3b 0a    int nNot = 0;.
14310 20 20 51 75 65 72 79 54 65 72 6d 20 2a 61 54 65    QueryTerm *aTe
14320 72 6d 3b 0a 0a 20 20 72 63 20 3d 20 70 61 72 73  rm;..  rc = pars
14330 65 51 75 65 72 79 28 76 2c 20 7a 49 6e 70 75 74  eQuery(v, zInput
14340 2c 20 6e 49 6e 70 75 74 2c 20 69 43 6f 6c 75 6d  , nInput, iColum
14350 6e 2c 20 70 51 75 65 72 79 29 3b 0a 20 20 69 66  n, pQuery);.  if
14360 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
14370 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
14380 2f 2a 20 4d 65 72 67 65 20 41 4e 44 20 74 65 72  /* Merge AND ter
14390 6d 73 2e 20 2a 2f 0a 20 20 61 54 65 72 6d 20 3d  ms. */.  aTerm =
143a0 20 70 51 75 65 72 79 2d 3e 70 54 65 72 6d 73 3b   pQuery->pTerms;
143b0 0a 20 20 66 6f 72 28 69 20 3d 20 30 3b 20 69 3c  .  for(i = 0; i<
143c0 70 51 75 65 72 79 2d 3e 6e 54 65 72 6d 73 3b 20  pQuery->nTerms; 
143d0 69 3d 69 4e 65 78 74 29 7b 0a 20 20 20 20 69 66  i=iNext){.    if
143e0 28 20 61 54 65 72 6d 5b 69 5d 2e 69 73 4e 6f 74  ( aTerm[i].isNot
143f0 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 48 61 6e   ){.      /* Han
14400 64 6c 65 20 61 6c 6c 20 4e 4f 54 20 74 65 72 6d  dle all NOT term
14410 73 20 69 6e 20 61 20 73 65 70 61 72 61 74 65 20  s in a separate 
14420 70 61 73 73 20 2a 2f 0a 20 20 20 20 20 20 6e 4e  pass */.      nN
14430 6f 74 2b 2b 3b 0a 20 20 20 20 20 20 69 4e 65 78  ot++;.      iNex
14440 74 20 3d 20 69 20 2b 20 61 54 65 72 6d 5b 69 5d  t = i + aTerm[i]
14450 2e 6e 50 68 72 61 73 65 2b 31 3b 0a 20 20 20 20  .nPhrase+1;.    
14460 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20    continue;.    
14470 7d 0a 20 20 20 20 69 4e 65 78 74 20 3d 20 69 20  }.    iNext = i 
14480 2b 20 61 54 65 72 6d 5b 69 5d 2e 6e 50 68 72 61  + aTerm[i].nPhra
14490 73 65 20 2b 20 31 3b 0a 20 20 20 20 72 63 20 3d  se + 1;.    rc =
144a0 20 64 6f 63 4c 69 73 74 4f 66 54 65 72 6d 28 76   docListOfTerm(v
144b0 2c 20 61 54 65 72 6d 5b 69 5d 2e 69 43 6f 6c 75  , aTerm[i].iColu
144c0 6d 6e 2c 20 26 61 54 65 72 6d 5b 69 5d 2c 20 26  mn, &aTerm[i], &
144d0 70 52 69 67 68 74 29 3b 0a 20 20 20 20 69 66 28  pRight);.    if(
144e0 20 72 63 20 29 7b 0a 20 20 20 20 20 20 71 75 65   rc ){.      que
144f0 72 79 43 6c 65 61 72 28 70 51 75 65 72 79 29 3b  ryClear(pQuery);
14500 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63  .      return rc
14510 3b 0a 20 20 20 20 7d 0a 20 20 20 20 77 68 69 6c  ;.    }.    whil
14520 65 28 20 69 4e 65 78 74 3c 70 51 75 65 72 79 2d  e( iNext<pQuery-
14530 3e 6e 54 65 72 6d 73 20 26 26 20 61 54 65 72 6d  >nTerms && aTerm
14540 5b 69 4e 65 78 74 5d 2e 69 73 4f 72 20 29 7b 0a  [iNext].isOr ){.
14550 20 20 20 20 20 20 72 63 20 3d 20 64 6f 63 4c 69        rc = docLi
14560 73 74 4f 66 54 65 72 6d 28 76 2c 20 61 54 65 72  stOfTerm(v, aTer
14570 6d 5b 69 4e 65 78 74 5d 2e 69 43 6f 6c 75 6d 6e  m[iNext].iColumn
14580 2c 20 26 61 54 65 72 6d 5b 69 4e 65 78 74 5d 2c  , &aTerm[iNext],
14590 20 26 70 4f 72 29 3b 0a 20 20 20 20 20 20 69 4e   &pOr);.      iN
145a0 65 78 74 20 2b 3d 20 61 54 65 72 6d 5b 69 4e 65  ext += aTerm[iNe
145b0 78 74 5d 2e 6e 50 68 72 61 73 65 20 2b 20 31 3b  xt].nPhrase + 1;
145c0 0a 20 20 20 20 20 20 69 66 28 20 72 63 20 29 7b  .      if( rc ){
145d0 0a 20 20 20 20 20 20 20 20 71 75 65 72 79 43 6c  .        queryCl
145e0 65 61 72 28 70 51 75 65 72 79 29 3b 0a 20 20 20  ear(pQuery);.   
145f0 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a       return rc;.
14600 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 4e        }.      pN
14610 65 77 20 3d 20 64 6f 63 4c 69 73 74 4e 65 77 28  ew = docListNew(
14620 44 4c 5f 44 4f 43 49 44 53 29 3b 0a 20 20 20 20  DL_DOCIDS);.    
14630 20 20 64 6f 63 4c 69 73 74 4f 72 4d 65 72 67 65    docListOrMerge
14640 28 70 52 69 67 68 74 2c 20 70 4f 72 2c 20 70 4e  (pRight, pOr, pN
14650 65 77 29 3b 0a 20 20 20 20 20 20 64 6f 63 4c 69  ew);.      docLi
14660 73 74 44 65 6c 65 74 65 28 70 52 69 67 68 74 29  stDelete(pRight)
14670 3b 0a 20 20 20 20 20 20 64 6f 63 4c 69 73 74 44  ;.      docListD
14680 65 6c 65 74 65 28 70 4f 72 29 3b 0a 20 20 20 20  elete(pOr);.    
14690 20 20 70 52 69 67 68 74 20 3d 20 70 4e 65 77 3b    pRight = pNew;
146a0 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
146b0 4c 65 66 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20  Left==0 ){.     
146c0 20 70 4c 65 66 74 20 3d 20 70 52 69 67 68 74 3b   pLeft = pRight;
146d0 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
146e0 20 20 70 4e 65 77 20 3d 20 64 6f 63 4c 69 73 74    pNew = docList
146f0 4e 65 77 28 44 4c 5f 44 4f 43 49 44 53 29 3b 0a  New(DL_DOCIDS);.
14700 20 20 20 20 20 20 64 6f 63 4c 69 73 74 41 6e 64        docListAnd
14710 4d 65 72 67 65 28 70 4c 65 66 74 2c 20 70 52 69  Merge(pLeft, pRi
14720 67 68 74 2c 20 70 4e 65 77 29 3b 0a 20 20 20 20  ght, pNew);.    
14730 20 20 64 6f 63 4c 69 73 74 44 65 6c 65 74 65 28    docListDelete(
14740 70 52 69 67 68 74 29 3b 0a 20 20 20 20 20 20 64  pRight);.      d
14750 6f 63 4c 69 73 74 44 65 6c 65 74 65 28 70 4c 65  ocListDelete(pLe
14760 66 74 29 3b 0a 20 20 20 20 20 20 70 4c 65 66 74  ft);.      pLeft
14770 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 7d 0a 20   = pNew;.    }. 
14780 20 7d 0a 0a 20 20 69 66 28 20 6e 4e 6f 74 20 26   }..  if( nNot &
14790 26 20 70 4c 65 66 74 3d 3d 30 20 29 7b 0a 20 20  & pLeft==0 ){.  
147a0 20 20 2f 2a 20 57 65 20 64 6f 20 6e 6f 74 20 79    /* We do not y
147b0 65 74 20 6b 6e 6f 77 20 68 6f 77 20 74 6f 20 68  et know how to h
147c0 61 6e 64 6c 65 20 61 20 71 75 65 72 79 20 6f 66  andle a query of
147d0 20 6f 6e 6c 79 20 4e 4f 54 20 74 65 72 6d 73 20   only NOT terms 
147e0 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  */.    return SQ
147f0 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
14800 0a 20 20 2f 2a 20 44 6f 20 74 68 65 20 45 58 43  .  /* Do the EXC
14810 45 50 54 20 74 65 72 6d 73 20 2a 2f 0a 20 20 66  EPT terms */.  f
14820 6f 72 28 69 3d 30 3b 20 69 3c 70 51 75 65 72 79  or(i=0; i<pQuery
14830 2d 3e 6e 54 65 72 6d 73 3b 20 20 69 20 2b 3d 20  ->nTerms;  i += 
14840 61 54 65 72 6d 5b 69 5d 2e 6e 50 68 72 61 73 65  aTerm[i].nPhrase
14850 20 2b 20 31 29 7b 0a 20 20 20 20 69 66 28 20 21   + 1){.    if( !
14860 61 54 65 72 6d 5b 69 5d 2e 69 73 4e 6f 74 20 29  aTerm[i].isNot )
14870 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 72   continue;.    r
14880 63 20 3d 20 64 6f 63 4c 69 73 74 4f 66 54 65 72  c = docListOfTer
14890 6d 28 76 2c 20 61 54 65 72 6d 5b 69 5d 2e 69 43  m(v, aTerm[i].iC
148a0 6f 6c 75 6d 6e 2c 20 26 61 54 65 72 6d 5b 69 5d  olumn, &aTerm[i]
148b0 2c 20 26 70 52 69 67 68 74 29 3b 0a 20 20 20 20  , &pRight);.    
148c0 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 20 20  if( rc ){.      
148d0 71 75 65 72 79 43 6c 65 61 72 28 70 51 75 65 72  queryClear(pQuer
148e0 79 29 3b 0a 20 20 20 20 20 20 64 6f 63 4c 69 73  y);.      docLis
148f0 74 44 65 6c 65 74 65 28 70 4c 65 66 74 29 3b 0a  tDelete(pLeft);.
14900 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
14910 0a 20 20 20 20 7d 0a 20 20 20 20 70 4e 65 77 20  .    }.    pNew 
14920 3d 20 64 6f 63 4c 69 73 74 4e 65 77 28 44 4c 5f  = docListNew(DL_
14930 44 4f 43 49 44 53 29 3b 0a 20 20 20 20 64 6f 63  DOCIDS);.    doc
14940 4c 69 73 74 45 78 63 65 70 74 4d 65 72 67 65 28  ListExceptMerge(
14950 70 4c 65 66 74 2c 20 70 52 69 67 68 74 2c 20 70  pLeft, pRight, p
14960 4e 65 77 29 3b 0a 20 20 20 20 64 6f 63 4c 69 73  New);.    docLis
14970 74 44 65 6c 65 74 65 28 70 52 69 67 68 74 29 3b  tDelete(pRight);
14980 0a 20 20 20 20 64 6f 63 4c 69 73 74 44 65 6c 65  .    docListDele
14990 74 65 28 70 4c 65 66 74 29 3b 0a 20 20 20 20 70  te(pLeft);.    p
149a0 4c 65 66 74 20 3d 20 70 4e 65 77 3b 0a 20 20 7d  Left = pNew;.  }
149b0 0a 0a 20 20 2a 70 52 65 73 75 6c 74 20 3d 20 70  ..  *pResult = p
149c0 4c 65 66 74 3b 0a 20 20 72 65 74 75 72 6e 20 72  Left;.  return r
149d0 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  c;.}../*.** This
149e0 20 69 73 20 74 68 65 20 78 46 69 6c 74 65 72 20   is the xFilter 
149f0 69 6e 74 65 72 66 61 63 65 20 66 6f 72 20 74 68  interface for th
14a00 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e  e virtual table.
14a10 20 20 53 65 65 0a 2a 2a 20 74 68 65 20 76 69 72    See.** the vir
14a20 74 75 61 6c 20 74 61 62 6c 65 20 78 46 69 6c 74  tual table xFilt
14a30 65 72 20 6d 65 74 68 6f 64 20 64 6f 63 75 6d 65  er method docume
14a40 6e 74 61 74 69 6f 6e 20 66 6f 72 20 61 64 64 69  ntation for addi
14a50 74 69 6f 6e 61 6c 0a 2a 2a 20 69 6e 66 6f 72 6d  tional.** inform
14a60 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  ation..**.** If 
14a70 69 64 78 4e 75 6d 3d 3d 51 55 45 52 59 5f 47 45  idxNum==QUERY_GE
14a80 4e 45 52 49 43 20 74 68 65 6e 20 64 6f 20 61 20  NERIC then do a 
14a90 66 75 6c 6c 20 74 61 62 6c 65 20 73 63 61 6e 20  full table scan 
14aa0 61 67 61 69 6e 73 74 0a 2a 2a 20 74 68 65 20 25  against.** the %
14ab0 5f 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65 2e 0a  _content table..
14ac0 2a 2a 0a 2a 2a 20 49 66 20 69 64 78 4e 75 6d 3d  **.** If idxNum=
14ad0 3d 51 55 45 52 59 5f 52 4f 57 49 44 20 74 68 65  =QUERY_ROWID the
14ae0 6e 20 64 6f 20 61 20 72 6f 77 69 64 20 6c 6f 6f  n do a rowid loo
14af0 6b 75 70 20 66 6f 72 20 61 20 73 69 6e 67 6c 65  kup for a single
14b00 20 65 6e 74 72 79 0a 2a 2a 20 69 6e 20 74 68 65   entry.** in the
14b10 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65   %_content table
14b20 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 69 64 78 4e 75  ..**.** If idxNu
14b30 6d 3e 3d 51 55 45 52 59 5f 46 55 4c 4c 54 45 58  m>=QUERY_FULLTEX
14b40 54 20 74 68 65 6e 20 75 73 65 20 74 68 65 20 66  T then use the f
14b50 75 6c 6c 20 74 65 78 74 20 69 6e 64 65 78 2e 20  ull text index. 
14b60 20 54 68 65 0a 2a 2a 20 63 6f 6c 75 6d 6e 20 6f   The.** column o
14b70 6e 20 74 68 65 20 6c 65 66 74 2d 68 61 6e 64 20  n the left-hand 
14b80 73 69 64 65 20 6f 66 20 74 68 65 20 4d 41 54 43  side of the MATC
14b90 48 20 6f 70 65 72 61 74 6f 72 20 69 73 20 63 6f  H operator is co
14ba0 6c 75 6d 6e 0a 2a 2a 20 6e 75 6d 62 65 72 20 69  lumn.** number i
14bb0 64 78 4e 75 6d 2d 51 55 45 52 59 5f 46 55 4c 4c  dxNum-QUERY_FULL
14bc0 54 45 58 54 2c 20 30 20 69 6e 64 65 78 65 64 2e  TEXT, 0 indexed.
14bd0 20 20 61 72 67 76 5b 30 5d 20 69 73 20 74 68 65    argv[0] is the
14be0 20 72 69 67 68 74 2d 68 61 6e 64 0a 2a 2a 20 73   right-hand.** s
14bf0 69 64 65 20 6f 66 20 74 68 65 20 4d 41 54 43 48  ide of the MATCH
14c00 20 6f 70 65 72 61 74 6f 72 2e 0a 2a 2f 0a 2f 2a   operator..*/./*
14c10 20 54 4f 44 4f 28 73 68 65 73 73 29 20 55 70 67   TODO(shess) Upg
14c20 72 61 64 65 20 74 68 65 20 63 75 72 73 6f 72 20  rade the cursor 
14c30 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 61  initialization a
14c40 6e 64 20 64 65 73 74 72 75 63 74 69 6f 6e 20 74  nd destruction t
14c50 6f 0a 2a 2a 20 61 63 63 6f 75 6e 74 20 66 6f 72  o.** account for
14c60 20 66 75 6c 6c 74 65 78 74 46 69 6c 74 65 72 28   fulltextFilter(
14c70 29 20 62 65 69 6e 67 20 63 61 6c 6c 65 64 20 6d  ) being called m
14c80 75 6c 74 69 70 6c 65 20 74 69 6d 65 73 20 6f 6e  ultiple times on
14c90 20 74 68 65 0a 2a 2a 20 73 61 6d 65 20 63 75 72   the.** same cur
14ca0 73 6f 72 2e 20 20 54 68 65 20 63 75 72 72 65 6e  sor.  The curren
14cb0 74 20 73 6f 6c 75 74 69 6f 6e 20 69 73 20 76 65  t solution is ve
14cc0 72 79 20 66 72 61 67 69 6c 65 2e 20 20 41 70 70  ry fragile.  App
14cd0 6c 79 20 66 69 78 20 74 6f 0a 2a 2a 20 66 74 73  ly fix to.** fts
14ce0 32 20 61 73 20 61 70 70 72 6f 70 72 69 61 74 65  2 as appropriate
14cf0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
14d00 66 75 6c 6c 74 65 78 74 46 69 6c 74 65 72 28 0a  fulltextFilter(.
14d10 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63    sqlite3_vtab_c
14d20 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20  ursor *pCursor, 
14d30 20 20 20 20 2f 2a 20 54 68 65 20 63 75 72 73 6f      /* The curso
14d40 72 20 75 73 65 64 20 66 6f 72 20 74 68 69 73 20  r used for this 
14d50 71 75 65 72 79 20 2a 2f 0a 20 20 69 6e 74 20 69  query */.  int i
14d60 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61  dxNum, const cha
14d70 72 20 2a 69 64 78 53 74 72 2c 20 20 20 2f 2a 20  r *idxStr,   /* 
14d80 57 68 69 63 68 20 69 6e 64 65 78 69 6e 67 20 73  Which indexing s
14d90 63 68 65 6d 65 20 74 6f 20 75 73 65 20 2a 2f 0a  cheme to use */.
14da0 20 20 69 6e 74 20 61 72 67 63 2c 20 73 71 6c 69    int argc, sqli
14db0 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76  te3_value **argv
14dc0 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 73      /* Arguments
14dd0 20 66 6f 72 20 74 68 65 20 69 6e 64 65 78 69 6e   for the indexin
14de0 67 20 73 63 68 65 6d 65 20 2a 2f 0a 29 7b 0a 20  g scheme */.){. 
14df0 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72   fulltext_cursor
14e00 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f   *c = (fulltext_
14e10 63 75 72 73 6f 72 20 2a 29 20 70 43 75 72 73 6f  cursor *) pCurso
14e20 72 3b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76 74  r;.  fulltext_vt
14e30 61 62 20 2a 76 20 3d 20 63 75 72 73 6f 72 5f 76  ab *v = cursor_v
14e40 74 61 62 28 63 29 3b 0a 20 20 69 6e 74 20 72 63  tab(c);.  int rc
14e50 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a  ;.  char *zSql;.
14e60 0a 20 20 54 52 41 43 45 28 28 22 46 54 53 31 20  .  TRACE(("FTS1 
14e70 46 69 6c 74 65 72 20 25 70 5c 6e 22 2c 70 43 75  Filter %p\n",pCu
14e80 72 73 6f 72 29 29 3b 0a 0a 20 20 7a 53 71 6c 20  rsor));..  zSql 
14e90 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
14ea0 66 28 22 73 65 6c 65 63 74 20 72 6f 77 69 64 2c  f("select rowid,
14eb0 20 2a 20 66 72 6f 6d 20 25 25 5f 63 6f 6e 74 65   * from %%_conte
14ec0 6e 74 20 25 73 22 2c 0a 20 20 20 20 20 20 20 20  nt %s",.        
14ed0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14ee0 20 20 69 64 78 4e 75 6d 3d 3d 51 55 45 52 59 5f    idxNum==QUERY_
14ef0 47 45 4e 45 52 49 43 20 3f 20 22 22 20 3a 20 22  GENERIC ? "" : "
14f00 77 68 65 72 65 20 72 6f 77 69 64 3d 3f 22 29 3b  where rowid=?");
14f10 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
14f20 69 7a 65 28 63 2d 3e 70 53 74 6d 74 29 3b 0a 20  ize(c->pStmt);. 
14f30 20 72 63 20 3d 20 73 71 6c 5f 70 72 65 70 61 72   rc = sql_prepar
14f40 65 28 76 2d 3e 64 62 2c 20 76 2d 3e 7a 44 62 2c  e(v->db, v->zDb,
14f50 20 76 2d 3e 7a 4e 61 6d 65 2c 20 26 63 2d 3e 70   v->zName, &c->p
14f60 53 74 6d 74 2c 20 7a 53 71 6c 29 3b 0a 20 20 73  Stmt, zSql);.  s
14f70 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c  qlite3_free(zSql
14f80 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
14f90 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
14fa0 72 63 3b 0a 0a 20 20 63 2d 3e 69 43 75 72 73 6f  rc;..  c->iCurso
14fb0 72 54 79 70 65 20 3d 20 69 64 78 4e 75 6d 3b 0a  rType = idxNum;.
14fc0 20 20 73 77 69 74 63 68 28 20 69 64 78 4e 75 6d    switch( idxNum
14fd0 20 29 7b 0a 20 20 20 20 63 61 73 65 20 51 55 45   ){.    case QUE
14fe0 52 59 5f 47 45 4e 45 52 49 43 3a 0a 20 20 20 20  RY_GENERIC:.    
14ff0 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61    break;..    ca
15000 73 65 20 51 55 45 52 59 5f 52 4f 57 49 44 3a 0a  se QUERY_ROWID:.
15010 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
15020 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 63 2d  e3_bind_int64(c-
15030 3e 70 53 74 6d 74 2c 20 31 2c 20 73 71 6c 69 74  >pStmt, 1, sqlit
15040 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 61  e3_value_int64(a
15050 72 67 76 5b 30 5d 29 29 3b 0a 20 20 20 20 20 20  rgv[0]));.      
15060 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
15070 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
15080 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20       break;..   
15090 20 64 65 66 61 75 6c 74 3a 20 20 20 2f 2a 20 66   default:   /* f
150a0 75 6c 6c 2d 74 65 78 74 20 73 65 61 72 63 68 20  ull-text search 
150b0 2a 2f 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 63  */.    {.      c
150c0 6f 6e 73 74 20 63 68 61 72 20 2a 7a 51 75 65 72  onst char *zQuer
150d0 79 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 20  y = (const char 
150e0 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  *)sqlite3_value_
150f0 74 65 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20  text(argv[0]);. 
15100 20 20 20 20 20 44 6f 63 4c 69 73 74 20 2a 70 52       DocList *pR
15110 65 73 75 6c 74 3b 0a 20 20 20 20 20 20 61 73 73  esult;.      ass
15120 65 72 74 28 20 69 64 78 4e 75 6d 3c 3d 51 55 45  ert( idxNum<=QUE
15130 52 59 5f 46 55 4c 4c 54 45 58 54 2b 76 2d 3e 6e  RY_FULLTEXT+v->n
15140 43 6f 6c 75 6d 6e 29 3b 0a 20 20 20 20 20 20 61  Column);.      a
15150 73 73 65 72 74 28 20 61 72 67 63 3d 3d 31 20 29  ssert( argc==1 )
15160 3b 0a 20 20 20 20 20 20 71 75 65 72 79 43 6c 65  ;.      queryCle
15170 61 72 28 26 63 2d 3e 71 29 3b 0a 20 20 20 20 20  ar(&c->q);.     
15180 20 72 63 20 3d 20 66 75 6c 6c 74 65 78 74 51 75   rc = fulltextQu
15190 65 72 79 28 76 2c 20 69 64 78 4e 75 6d 2d 51 55  ery(v, idxNum-QU
151a0 45 52 59 5f 46 55 4c 4c 54 45 58 54 2c 20 7a 51  ERY_FULLTEXT, zQ
151b0 75 65 72 79 2c 20 2d 31 2c 20 26 70 52 65 73 75  uery, -1, &pResu
151c0 6c 74 2c 20 26 63 2d 3e 71 29 3b 0a 20 20 20 20  lt, &c->q);.    
151d0 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
151e0 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
151f0 0a 20 20 20 20 20 20 69 66 28 20 63 2d 3e 72 65  .      if( c->re
15200 73 75 6c 74 2e 70 44 6f 63 6c 69 73 74 21 3d 4e  sult.pDoclist!=N
15210 55 4c 4c 20 29 20 64 6f 63 4c 69 73 74 44 65 6c  ULL ) docListDel
15220 65 74 65 28 63 2d 3e 72 65 73 75 6c 74 2e 70 44  ete(c->result.pD
15230 6f 63 6c 69 73 74 29 3b 0a 20 20 20 20 20 20 72  oclist);.      r
15240 65 61 64 65 72 49 6e 69 74 28 26 63 2d 3e 72 65  eaderInit(&c->re
15250 73 75 6c 74 2c 20 70 52 65 73 75 6c 74 29 3b 0a  sult, pResult);.
15260 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
15270 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
15280 20 66 75 6c 6c 74 65 78 74 4e 65 78 74 28 70 43   fulltextNext(pC
15290 75 72 73 6f 72 29 3b 0a 7d 0a 0a 2f 2a 20 54 68  ursor);.}../* Th
152a0 69 73 20 69 73 20 74 68 65 20 78 45 6f 66 20 6d  is is the xEof m
152b0 65 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69 72  ethod of the vir
152c0 74 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 65  tual table.  The
152d0 20 53 51 4c 69 74 65 20 63 6f 72 65 0a 2a 2a 20   SQLite core.** 
152e0 63 61 6c 6c 73 20 74 68 69 73 20 72 6f 75 74 69  calls this routi
152f0 6e 65 20 74 6f 20 66 69 6e 64 20 6f 75 74 20 69  ne to find out i
15300 66 20 69 74 20 68 61 73 20 72 65 61 63 68 65 64  f it has reached
15310 20 74 68 65 20 65 6e 64 20 6f 66 0a 2a 2a 20 61   the end of.** a
15320 20 71 75 65 72 79 27 73 20 72 65 73 75 6c 74 73   query's results
15330 20 73 65 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20   set..*/.static 
15340 69 6e 74 20 66 75 6c 6c 74 65 78 74 45 6f 66 28  int fulltextEof(
15350 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
15360 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20  sor *pCursor){. 
15370 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72   fulltext_cursor
15380 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f   *c = (fulltext_
15390 63 75 72 73 6f 72 20 2a 29 20 70 43 75 72 73 6f  cursor *) pCurso
153a0 72 3b 0a 20 20 72 65 74 75 72 6e 20 63 2d 3e 65  r;.  return c->e
153b0 6f 66 3b 0a 7d 0a 0a 2f 2a 20 54 68 69 73 20 69  of;.}../* This i
153c0 73 20 74 68 65 20 78 43 6f 6c 75 6d 6e 20 6d 65  s the xColumn me
153d0 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69 72 74  thod of the virt
153e0 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 65 20  ual table.  The 
153f0 53 51 4c 69 74 65 0a 2a 2a 20 63 6f 72 65 20 63  SQLite.** core c
15400 61 6c 6c 73 20 74 68 69 73 20 6d 65 74 68 6f 64  alls this method
15410 20 64 75 72 69 6e 67 20 61 20 71 75 65 72 79 20   during a query 
15420 77 68 65 6e 20 69 74 20 6e 65 65 64 73 20 74 68  when it needs th
15430 65 20 76 61 6c 75 65 0a 2a 2a 20 6f 66 20 61 20  e value.** of a 
15440 63 6f 6c 75 6d 6e 20 66 72 6f 6d 20 74 68 65 20  column from the 
15450 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20  virtual table.  
15460 54 68 69 73 20 6d 65 74 68 6f 64 20 6e 65 65 64  This method need
15470 73 20 74 6f 20 75 73 65 0a 2a 2a 20 6f 6e 65 20  s to use.** one 
15480 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 72  of the sqlite3_r
15490 65 73 75 6c 74 5f 2a 28 29 20 72 6f 75 74 69 6e  esult_*() routin
154a0 65 73 20 74 6f 20 73 74 6f 72 65 20 74 68 65 20  es to store the 
154b0 72 65 71 75 65 73 74 65 64 0a 2a 2a 20 76 61 6c  requested.** val
154c0 75 65 20 62 61 63 6b 20 69 6e 20 74 68 65 20 70  ue back in the p
154d0 43 6f 6e 74 65 78 74 2e 0a 2a 2f 0a 73 74 61 74  Context..*/.stat
154e0 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 43  ic int fulltextC
154f0 6f 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74  olumn(sqlite3_vt
15500 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73  ab_cursor *pCurs
15510 6f 72 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  or,.            
15520 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
15530 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70  lite3_context *p
15540 43 6f 6e 74 65 78 74 2c 20 69 6e 74 20 69 64 78  Context, int idx
15550 43 6f 6c 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74  Col){.  fulltext
15560 5f 63 75 72 73 6f 72 20 2a 63 20 3d 20 28 66 75  _cursor *c = (fu
15570 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 29  lltext_cursor *)
15580 20 70 43 75 72 73 6f 72 3b 0a 20 20 66 75 6c 6c   pCursor;.  full
15590 74 65 78 74 5f 76 74 61 62 20 2a 76 20 3d 20 63  text_vtab *v = c
155a0 75 72 73 6f 72 5f 76 74 61 62 28 63 29 3b 0a 0a  ursor_vtab(c);..
155b0 20 20 69 66 28 20 69 64 78 43 6f 6c 3c 76 2d 3e    if( idxCol<v->
155c0 6e 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20 73  nColumn ){.    s
155d0 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56  qlite3_value *pV
155e0 61 6c 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c  al = sqlite3_col
155f0 75 6d 6e 5f 76 61 6c 75 65 28 63 2d 3e 70 53 74  umn_value(c->pSt
15600 6d 74 2c 20 69 64 78 43 6f 6c 2b 31 29 3b 0a 20  mt, idxCol+1);. 
15610 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
15620 74 5f 76 61 6c 75 65 28 70 43 6f 6e 74 65 78 74  t_value(pContext
15630 2c 20 70 56 61 6c 29 3b 0a 20 20 7d 65 6c 73 65  , pVal);.  }else
15640 20 69 66 28 20 69 64 78 43 6f 6c 3d 3d 76 2d 3e   if( idxCol==v->
15650 6e 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20 2f  nColumn ){.    /
15660 2a 20 54 68 65 20 65 78 74 72 61 20 63 6f 6c 75  * The extra colu
15670 6d 6e 20 77 68 6f 73 65 20 6e 61 6d 65 20 69 73  mn whose name is
15680 20 74 68 65 20 73 61 6d 65 20 61 73 20 74 68 65   the same as the
15690 20 74 61 62 6c 65 2e 0a 20 20 20 20 2a 2a 20 52   table..    ** R
156a0 65 74 75 72 6e 20 61 20 62 6c 6f 62 20 77 68 69  eturn a blob whi
156b0 63 68 20 69 73 20 61 20 70 6f 69 6e 74 65 72 20  ch is a pointer 
156c0 74 6f 20 74 68 65 20 63 75 72 73 6f 72 0a 20 20  to the cursor.  
156d0 20 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33    */.    sqlite3
156e0 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28 70 43 6f  _result_blob(pCo
156f0 6e 74 65 78 74 2c 20 26 63 2c 20 73 69 7a 65 6f  ntext, &c, sizeo
15700 66 28 63 29 2c 20 53 51 4c 49 54 45 5f 54 52 41  f(c), SQLITE_TRA
15710 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 20 20 72  NSIENT);.  }.  r
15720 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
15730 0a 7d 0a 0a 2f 2a 20 54 68 69 73 20 69 73 20 74  .}../* This is t
15740 68 65 20 78 52 6f 77 69 64 20 6d 65 74 68 6f 64  he xRowid method
15750 2e 20 20 54 68 65 20 53 51 4c 69 74 65 20 63 6f  .  The SQLite co
15760 72 65 20 63 61 6c 6c 73 20 74 68 69 73 20 72 6f  re calls this ro
15770 75 74 69 6e 65 20 74 6f 0a 2a 2a 20 72 65 74 72  utine to.** retr
15780 69 76 65 20 74 68 65 20 72 6f 77 69 64 20 66 6f  ive the rowid fo
15790 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 6f  r the current ro
157a0 77 20 6f 66 20 74 68 65 20 72 65 73 75 6c 74 20  w of the result 
157b0 73 65 74 2e 20 20 54 68 65 0a 2a 2a 20 72 6f 77  set.  The.** row
157c0 69 64 20 73 68 6f 75 6c 64 20 62 65 20 77 72 69  id should be wri
157d0 74 74 65 6e 20 74 6f 20 2a 70 52 6f 77 69 64 2e  tten to *pRowid.
157e0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
157f0 75 6c 6c 74 65 78 74 52 6f 77 69 64 28 73 71 6c  ulltextRowid(sql
15800 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
15810 20 2a 70 43 75 72 73 6f 72 2c 20 73 71 6c 69 74   *pCursor, sqlit
15820 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 29  e_int64 *pRowid)
15830 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72  {.  fulltext_cur
15840 73 6f 72 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65  sor *c = (fullte
15850 78 74 5f 63 75 72 73 6f 72 20 2a 29 20 70 43 75  xt_cursor *) pCu
15860 72 73 6f 72 3b 0a 0a 20 20 2a 70 52 6f 77 69 64  rsor;..  *pRowid
15870 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
15880 6e 5f 69 6e 74 36 34 28 63 2d 3e 70 53 74 6d 74  n_int64(c->pStmt
15890 2c 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  , 0);.  return S
158a0 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20  QLITE_OK;.}../* 
158b0 41 64 64 20 61 6c 6c 20 74 65 72 6d 73 20 69 6e  Add all terms in
158c0 20 5b 7a 54 65 78 74 5d 20 74 6f 20 74 68 65 20   [zText] to the 
158d0 67 69 76 65 6e 20 68 61 73 68 20 74 61 62 6c 65  given hash table
158e0 2e 20 20 49 66 20 5b 69 43 6f 6c 75 6d 6e 5d 20  .  If [iColumn] 
158f0 3e 20 30 2c 0a 20 2a 20 77 65 20 61 6c 73 6f 20  > 0,. * we also 
15900 73 74 6f 72 65 20 70 6f 73 69 74 69 6f 6e 73 20  store positions 
15910 61 6e 64 20 6f 66 66 73 65 74 73 20 69 6e 20 74  and offsets in t
15920 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 75 73  he hash table us
15930 69 6e 67 20 74 68 65 20 67 69 76 65 6e 0a 20 2a  ing the given. *
15940 20 63 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72 2e 20   column number. 
15950 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 62 75  */.static int bu
15960 69 6c 64 54 65 72 6d 73 28 66 75 6c 6c 74 65 78  ildTerms(fulltex
15970 74 5f 76 74 61 62 20 2a 76 2c 20 66 74 73 31 48  t_vtab *v, fts1H
15980 61 73 68 20 2a 74 65 72 6d 73 2c 20 73 71 6c 69  ash *terms, sqli
15990 74 65 5f 69 6e 74 36 34 20 69 44 6f 63 69 64 2c  te_int64 iDocid,
159a0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
159b0 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61         const cha
159c0 72 20 2a 7a 54 65 78 74 2c 20 69 6e 74 20 69 43  r *zText, int iC
159d0 6f 6c 75 6d 6e 29 7b 0a 20 20 73 71 6c 69 74 65  olumn){.  sqlite
159e0 33 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f  3_tokenizer *pTo
159f0 6b 65 6e 69 7a 65 72 20 3d 20 76 2d 3e 70 54 6f  kenizer = v->pTo
15a00 6b 65 6e 69 7a 65 72 3b 0a 20 20 73 71 6c 69 74  kenizer;.  sqlit
15a10 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72  e3_tokenizer_cur
15a20 73 6f 72 20 2a 70 43 75 72 73 6f 72 3b 0a 20 20  sor *pCursor;.  
15a30 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 6f 6b  const char *pTok
15a40 65 6e 3b 0a 20 20 69 6e 74 20 6e 54 6f 6b 65 6e  en;.  int nToken
15a50 42 79 74 65 73 3b 0a 20 20 69 6e 74 20 69 53 74  Bytes;.  int iSt
15a60 61 72 74 4f 66 66 73 65 74 2c 20 69 45 6e 64 4f  artOffset, iEndO
15a70 66 66 73 65 74 2c 20 69 50 6f 73 69 74 69 6f 6e  ffset, iPosition
15a80 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 72  ;.  int rc;..  r
15a90 63 20 3d 20 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e  c = pTokenizer->
15aa0 70 4d 6f 64 75 6c 65 2d 3e 78 4f 70 65 6e 28 70  pModule->xOpen(p
15ab0 54 6f 6b 65 6e 69 7a 65 72 2c 20 7a 54 65 78 74  Tokenizer, zText
15ac0 2c 20 2d 31 2c 20 26 70 43 75 72 73 6f 72 29 3b  , -1, &pCursor);
15ad0 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
15ae0 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
15af0 3b 0a 0a 20 20 70 43 75 72 73 6f 72 2d 3e 70 54  ;..  pCursor->pT
15b00 6f 6b 65 6e 69 7a 65 72 20 3d 20 70 54 6f 6b 65  okenizer = pToke
15b10 6e 69 7a 65 72 3b 0a 20 20 77 68 69 6c 65 28 20  nizer;.  while( 
15b20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 70 54 6f 6b 65  SQLITE_OK==pToke
15b30 6e 69 7a 65 72 2d 3e 70 4d 6f 64 75 6c 65 2d 3e  nizer->pModule->
15b40 78 4e 65 78 74 28 70 43 75 72 73 6f 72 2c 0a 20  xNext(pCursor,. 
15b50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15b60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15b70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26 70                &p
15b80 54 6f 6b 65 6e 2c 20 26 6e 54 6f 6b 65 6e 42 79  Token, &nTokenBy
15b90 74 65 73 2c 0a 20 20 20 20 20 20 20 20 20 20 20  tes,.           
15ba0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15bb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15bc0 20 20 20 20 26 69 53 74 61 72 74 4f 66 66 73 65      &iStartOffse
15bd0 74 2c 20 26 69 45 6e 64 4f 66 66 73 65 74 2c 0a  t, &iEndOffset,.
15be0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15bf0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15c00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26                 &
15c10 69 50 6f 73 69 74 69 6f 6e 29 20 29 7b 0a 20 20  iPosition) ){.  
15c20 20 20 44 6f 63 4c 69 73 74 20 2a 70 3b 0a 0a 20    DocList *p;.. 
15c30 20 20 20 2f 2a 20 50 6f 73 69 74 69 6f 6e 73 20     /* Positions 
15c40 63 61 6e 27 74 20 62 65 20 6e 65 67 61 74 69 76  can't be negativ
15c50 65 3b 20 77 65 20 75 73 65 20 2d 31 20 61 73 20  e; we use -1 as 
15c60 61 20 74 65 72 6d 69 6e 61 74 6f 72 20 69 6e 74  a terminator int
15c70 65 72 6e 61 6c 6c 79 2e 20 2a 2f 0a 20 20 20 20  ernally. */.    
15c80 69 66 28 20 69 50 6f 73 69 74 69 6f 6e 3c 30 20  if( iPosition<0 
15c90 29 7b 0a 20 20 20 20 20 20 70 54 6f 6b 65 6e 69  ){.      pTokeni
15ca0 7a 65 72 2d 3e 70 4d 6f 64 75 6c 65 2d 3e 78 43  zer->pModule->xC
15cb0 6c 6f 73 65 28 70 43 75 72 73 6f 72 29 3b 0a 20  lose(pCursor);. 
15cc0 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
15cd0 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a  TE_ERROR;.    }.
15ce0 0a 20 20 20 20 70 20 3d 20 66 74 73 31 48 61 73  .    p = fts1Has
15cf0 68 46 69 6e 64 28 74 65 72 6d 73 2c 20 70 54 6f  hFind(terms, pTo
15d00 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 42 79 74 65 73  ken, nTokenBytes
15d10 29 3b 0a 20 20 20 20 69 66 28 20 70 3d 3d 4e 55  );.    if( p==NU
15d20 4c 4c 20 29 7b 0a 20 20 20 20 20 20 70 20 3d 20  LL ){.      p = 
15d30 64 6f 63 4c 69 73 74 4e 65 77 28 44 4c 5f 44 45  docListNew(DL_DE
15d40 46 41 55 4c 54 29 3b 0a 20 20 20 20 20 20 64 6f  FAULT);.      do
15d50 63 4c 69 73 74 41 64 64 44 6f 63 69 64 28 70 2c  cListAddDocid(p,
15d60 20 69 44 6f 63 69 64 29 3b 0a 20 20 20 20 20 20   iDocid);.      
15d70 66 74 73 31 48 61 73 68 49 6e 73 65 72 74 28 74  fts1HashInsert(t
15d80 65 72 6d 73 2c 20 70 54 6f 6b 65 6e 2c 20 6e 54  erms, pToken, nT
15d90 6f 6b 65 6e 42 79 74 65 73 2c 20 70 29 3b 0a 20  okenBytes, p);. 
15da0 20 20 20 7d 0a 20 20 20 20 69 66 28 20 69 43 6f     }.    if( iCo
15db0 6c 75 6d 6e 3e 3d 30 20 29 7b 0a 20 20 20 20 20  lumn>=0 ){.     
15dc0 20 64 6f 63 4c 69 73 74 41 64 64 50 6f 73 4f 66   docListAddPosOf
15dd0 66 73 65 74 28 70 2c 20 69 43 6f 6c 75 6d 6e 2c  fset(p, iColumn,
15de0 20 69 50 6f 73 69 74 69 6f 6e 2c 20 69 53 74 61   iPosition, iSta
15df0 72 74 4f 66 66 73 65 74 2c 20 69 45 6e 64 4f 66  rtOffset, iEndOf
15e00 66 73 65 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  fset);.    }.  }
15e10 0a 0a 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73  ..  /* TODO(shes
15e20 73 29 20 43 68 65 63 6b 20 72 65 74 75 72 6e 3f  s) Check return?
15e30 20 20 53 68 6f 75 6c 64 20 74 68 69 73 20 62 65    Should this be
15e40 20 61 62 6c 65 20 74 6f 20 63 61 75 73 65 20 65   able to cause e
15e50 72 72 6f 72 73 20 61 74 0a 20 20 2a 2a 20 74 68  rrors at.  ** th
15e60 69 73 20 70 6f 69 6e 74 3f 20 20 41 63 74 75 61  is point?  Actua
15e70 6c 6c 79 2c 20 73 61 6d 65 20 71 75 65 73 74 69  lly, same questi
15e80 6f 6e 20 61 62 6f 75 74 20 73 71 6c 69 74 65 33  on about sqlite3
15e90 5f 66 69 6e 61 6c 69 7a 65 28 29 2c 0a 20 20 2a  _finalize(),.  *
15ea0 2a 20 74 68 6f 75 67 68 20 6f 6e 65 20 63 6f 75  * though one cou
15eb0 6c 64 20 61 72 67 75 65 20 74 68 61 74 20 66 61  ld argue that fa
15ec0 69 6c 75 72 65 20 74 68 65 72 65 20 6d 65 61 6e  ilure there mean
15ed0 73 20 74 68 61 74 20 74 68 65 20 64 61 74 61 20  s that the data 
15ee0 69 73 0a 20 20 2a 2a 20 6e 6f 74 20 64 75 72 61  is.  ** not dura
15ef0 62 6c 65 2e 20 20 2a 70 6f 6e 64 65 72 2a 0a 20  ble.  *ponder*. 
15f00 20 2a 2f 0a 20 20 70 54 6f 6b 65 6e 69 7a 65 72   */.  pTokenizer
15f10 2d 3e 70 4d 6f 64 75 6c 65 2d 3e 78 43 6c 6f 73  ->pModule->xClos
15f20 65 28 70 43 75 72 73 6f 72 29 3b 0a 20 20 72 65  e(pCursor);.  re
15f30 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 55  turn rc;.}../* U
15f40 70 64 61 74 65 20 74 68 65 20 25 5f 74 65 72 6d  pdate the %_term
15f50 73 20 74 61 62 6c 65 20 74 6f 20 6d 61 70 20 74  s table to map t
15f60 68 65 20 74 65 72 6d 20 5b 70 54 65 72 6d 5d 20  he term [pTerm] 
15f70 74 6f 20 74 68 65 20 67 69 76 65 6e 20 72 6f 77  to the given row
15f80 69 64 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  id. */.static in
15f90 74 20 69 6e 64 65 78 5f 69 6e 73 65 72 74 5f 74  t index_insert_t
15fa0 65 72 6d 28 66 75 6c 6c 74 65 78 74 5f 76 74 61  erm(fulltext_vta
15fb0 62 20 2a 76 2c 20 63 6f 6e 73 74 20 63 68 61 72  b *v, const char
15fc0 20 2a 70 54 65 72 6d 2c 20 69 6e 74 20 6e 54 65   *pTerm, int nTe
15fd0 72 6d 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  rm,.            
15fe0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15ff0 20 44 6f 63 4c 69 73 74 20 2a 64 29 7b 0a 20 20   DocList *d){.  
16000 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 49 6e  sqlite_int64 iIn
16010 64 65 78 52 6f 77 3b 0a 20 20 44 6f 63 4c 69 73  dexRow;.  DocLis
16020 74 20 64 6f 63 6c 69 73 74 3b 0a 20 20 69 6e 74  t doclist;.  int
16030 20 69 53 65 67 6d 65 6e 74 20 3d 20 30 2c 20 72   iSegment = 0, r
16040 63 3b 0a 0a 20 20 72 63 20 3d 20 74 65 72 6d 5f  c;..  rc = term_
16050 73 65 6c 65 63 74 28 76 2c 20 70 54 65 72 6d 2c  select(v, pTerm,
16060 20 6e 54 65 72 6d 2c 20 69 53 65 67 6d 65 6e 74   nTerm, iSegment
16070 2c 20 26 69 49 6e 64 65 78 52 6f 77 2c 20 26 64  , &iIndexRow, &d
16080 6f 63 6c 69 73 74 29 3b 0a 20 20 69 66 28 20 72  oclist);.  if( r
16090 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29  c==SQLITE_DONE )
160a0 7b 0a 20 20 20 20 64 6f 63 4c 69 73 74 49 6e 69  {.    docListIni
160b0 74 28 26 64 6f 63 6c 69 73 74 2c 20 44 4c 5f 44  t(&doclist, DL_D
160c0 45 46 41 55 4c 54 2c 20 30 2c 20 30 29 3b 0a 20  EFAULT, 0, 0);. 
160d0 20 20 20 64 6f 63 4c 69 73 74 55 70 64 61 74 65     docListUpdate
160e0 28 26 64 6f 63 6c 69 73 74 2c 20 64 29 3b 0a 20  (&doclist, d);. 
160f0 20 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73     /* TODO(shess
16100 29 20 43 6f 6e 73 69 64 65 72 20 6c 65 6e 67 74  ) Consider lengt
16110 68 28 64 6f 63 6c 69 73 74 29 3e 43 48 55 4e 4b  h(doclist)>CHUNK
16120 5f 4d 41 58 3f 20 2a 2f 0a 20 20 20 20 72 63 20  _MAX? */.    rc 
16130 3d 20 74 65 72 6d 5f 69 6e 73 65 72 74 28 76 2c  = term_insert(v,
16140 20 4e 55 4c 4c 2c 20 70 54 65 72 6d 2c 20 6e 54   NULL, pTerm, nT
16150 65 72 6d 2c 20 69 53 65 67 6d 65 6e 74 2c 20 26  erm, iSegment, &
16160 64 6f 63 6c 69 73 74 29 3b 0a 20 20 20 20 67 6f  doclist);.    go
16170 74 6f 20 65 72 72 3b 0a 20 20 7d 0a 20 20 69 66  to err;.  }.  if
16180 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57  ( rc!=SQLITE_ROW
16190 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
161a0 5f 45 52 52 4f 52 3b 0a 0a 20 20 64 6f 63 4c 69  _ERROR;..  docLi
161b0 73 74 55 70 64 61 74 65 28 26 64 6f 63 6c 69 73  stUpdate(&doclis
161c0 74 2c 20 64 29 3b 0a 20 20 69 66 28 20 64 6f 63  t, d);.  if( doc
161d0 6c 69 73 74 2e 6e 44 61 74 61 3c 3d 43 48 55 4e  list.nData<=CHUN
161e0 4b 5f 4d 41 58 20 29 7b 0a 20 20 20 20 72 63 20  K_MAX ){.    rc 
161f0 3d 20 74 65 72 6d 5f 75 70 64 61 74 65 28 76 2c  = term_update(v,
16200 20 69 49 6e 64 65 78 52 6f 77 2c 20 26 64 6f 63   iIndexRow, &doc
16210 6c 69 73 74 29 3b 0a 20 20 20 20 67 6f 74 6f 20  list);.    goto 
16220 65 72 72 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44  err;.  }..  /* D
16230 6f 63 6c 69 73 74 20 64 6f 65 73 6e 27 74 20 66  oclist doesn't f
16240 69 74 2c 20 64 65 6c 65 74 65 20 77 68 61 74 27  it, delete what'
16250 73 20 74 68 65 72 65 2c 20 61 6e 64 20 61 63 63  s there, and acc
16260 75 6d 75 6c 61 74 65 0a 20 20 2a 2a 20 66 6f 72  umulate.  ** for
16270 77 61 72 64 2e 0a 20 20 2a 2f 0a 20 20 72 63 20  ward..  */.  rc 
16280 3d 20 74 65 72 6d 5f 64 65 6c 65 74 65 28 76 2c  = term_delete(v,
16290 20 69 49 6e 64 65 78 52 6f 77 29 3b 0a 20 20 69   iIndexRow);.  i
162a0 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
162b0 20 29 20 67 6f 74 6f 20 65 72 72 3b 0a 0a 20 20   ) goto err;..  
162c0 2f 2a 20 54 72 79 20 74 6f 20 69 6e 73 65 72 74  /* Try to insert
162d0 20 74 68 65 20 64 6f 63 6c 69 73 74 20 69 6e 74   the doclist int
162e0 6f 20 61 20 68 69 67 68 65 72 20 73 65 67 6d 65  o a higher segme
162f0 6e 74 20 62 75 63 6b 65 74 2e 20 20 4f 6e 0a 20  nt bucket.  On. 
16300 20 2a 2a 20 66 61 69 6c 75 72 65 2c 20 61 63 63   ** failure, acc
16310 75 6d 75 6c 61 74 65 20 65 78 69 73 74 69 6e 67  umulate existing
16320 20 64 6f 63 6c 69 73 74 20 77 69 74 68 20 74 68   doclist with th
16330 65 20 64 6f 63 6c 69 73 74 20 66 72 6f 6d 20 74  e doclist from t
16340 68 61 74 0a 20 20 2a 2a 20 62 75 63 6b 65 74 2c  hat.  ** bucket,
16350 20 61 6e 64 20 70 75 74 20 72 65 73 75 6c 74 73   and put results
16360 20 69 6e 20 74 68 65 20 6e 65 78 74 20 62 75 63   in the next buc
16370 6b 65 74 2e 0a 20 20 2a 2f 0a 20 20 69 53 65 67  ket..  */.  iSeg
16380 6d 65 6e 74 2b 2b 3b 0a 20 20 77 68 69 6c 65 28  ment++;.  while(
16390 20 28 72 63 3d 74 65 72 6d 5f 69 6e 73 65 72 74   (rc=term_insert
163a0 28 76 2c 20 26 69 49 6e 64 65 78 52 6f 77 2c 20  (v, &iIndexRow, 
163b0 70 54 65 72 6d 2c 20 6e 54 65 72 6d 2c 20 69 53  pTerm, nTerm, iS
163c0 65 67 6d 65 6e 74 2c 0a 20 20 20 20 20 20 20 20  egment,.        
163d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
163e0 20 26 64 6f 63 6c 69 73 74 29 29 21 3d 53 51 4c   &doclist))!=SQL
163f0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71  ITE_OK ){.    sq
16400 6c 69 74 65 5f 69 6e 74 36 34 20 69 53 65 67 6d  lite_int64 iSegm
16410 65 6e 74 52 6f 77 3b 0a 20 20 20 20 44 6f 63 4c  entRow;.    DocL
16420 69 73 74 20 6f 6c 64 3b 0a 20 20 20 20 69 6e 74  ist old;.    int
16430 20 72 63 32 3b 0a 0a 20 20 20 20 2f 2a 20 52 65   rc2;..    /* Re
16440 74 61 69 6e 20 6f 6c 64 20 65 72 72 6f 72 20 69  tain old error i
16450 6e 20 63 61 73 65 20 74 68 65 20 74 65 72 6d 5f  n case the term_
16460 69 6e 73 65 72 74 28 29 20 65 72 72 6f 72 20 77  insert() error w
16470 61 73 20 72 65 61 6c 6c 79 20 61 6e 0a 20 20 20  as really an.   
16480 20 2a 2a 20 65 72 72 6f 72 20 72 61 74 68 65 72   ** error rather
16490 20 74 68 61 6e 20 61 20 62 6f 75 6e 63 65 64 20   than a bounced 
164a0 69 6e 73 65 72 74 2e 0a 20 20 20 20 2a 2f 0a 20  insert..    */. 
164b0 20 20 20 72 63 32 20 3d 20 74 65 72 6d 5f 73 65     rc2 = term_se
164c0 6c 65 63 74 28 76 2c 20 70 54 65 72 6d 2c 20 6e  lect(v, pTerm, n
164d0 54 65 72 6d 2c 20 69 53 65 67 6d 65 6e 74 2c 20  Term, iSegment, 
164e0 26 69 53 65 67 6d 65 6e 74 52 6f 77 2c 20 26 6f  &iSegmentRow, &o
164f0 6c 64 29 3b 0a 20 20 20 20 69 66 28 20 72 63 32  ld);.    if( rc2
16500 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 20 67  !=SQLITE_ROW ) g
16510 6f 74 6f 20 65 72 72 3b 0a 0a 20 20 20 20 72 63  oto err;..    rc
16520 20 3d 20 74 65 72 6d 5f 64 65 6c 65 74 65 28 76   = term_delete(v
16530 2c 20 69 53 65 67 6d 65 6e 74 52 6f 77 29 3b 0a  , iSegmentRow);.
16540 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
16550 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 65 72 72  TE_OK ) goto err
16560 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 75 73 69 6e  ;..    /* Reusin
16570 67 20 6c 6f 77 65 73 74 2d 6e 75 6d 62 65 72 20  g lowest-number 
16580 64 65 6c 65 74 65 64 20 72 6f 77 20 6b 65 65 70  deleted row keep
16590 73 20 74 68 65 20 69 6e 64 65 78 20 73 6d 61 6c  s the index smal
165a0 6c 65 72 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  ler. */.    if( 
165b0 69 53 65 67 6d 65 6e 74 52 6f 77 3c 69 49 6e 64  iSegmentRow<iInd
165c0 65 78 52 6f 77 20 29 20 69 49 6e 64 65 78 52 6f  exRow ) iIndexRo
165d0 77 20 3d 20 69 53 65 67 6d 65 6e 74 52 6f 77 3b  w = iSegmentRow;
165e0 0a 0a 20 20 20 20 2f 2a 20 64 6f 63 6c 69 73 74  ..    /* doclist
165f0 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 6e 65   contains the ne
16600 77 65 72 20 64 61 74 61 2c 20 73 6f 20 61 63 63  wer data, so acc
16610 75 6d 75 6c 61 74 65 20 69 74 20 6f 76 65 72 20  umulate it over 
16620 6f 6c 64 2e 0a 20 20 20 20 2a 2a 20 54 68 65 6e  old..    ** Then
16630 20 73 74 65 61 6c 20 61 63 63 75 6d 75 6c 61 74   steal accumulat
16640 65 64 20 64 61 74 61 20 66 6f 72 20 64 6f 63 6c  ed data for docl
16650 69 73 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ist..    */.    
16660 64 6f 63 4c 69 73 74 41 63 63 75 6d 75 6c 61 74  docListAccumulat
16670 65 28 26 6f 6c 64 2c 20 26 64 6f 63 6c 69 73 74  e(&old, &doclist
16680 29 3b 0a 20 20 20 20 64 6f 63 4c 69 73 74 44 65  );.    docListDe
16690 73 74 72 6f 79 28 26 64 6f 63 6c 69 73 74 29 3b  stroy(&doclist);
166a0 0a 20 20 20 20 64 6f 63 6c 69 73 74 20 3d 20 6f  .    doclist = o
166b0 6c 64 3b 0a 0a 20 20 20 20 69 53 65 67 6d 65 6e  ld;..    iSegmen
166c0 74 2b 2b 3b 0a 20 20 7d 0a 0a 20 65 72 72 3a 0a  t++;.  }.. err:.
166d0 20 20 64 6f 63 4c 69 73 74 44 65 73 74 72 6f 79    docListDestroy
166e0 28 26 64 6f 63 6c 69 73 74 29 3b 0a 20 20 72 65  (&doclist);.  re
166f0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 41  turn rc;.}../* A
16700 64 64 20 64 6f 63 6c 69 73 74 73 20 66 6f 72 20  dd doclists for 
16710 61 6c 6c 20 74 65 72 6d 73 20 69 6e 20 5b 70 56  all terms in [pV
16720 61 6c 75 65 73 5d 20 74 6f 20 74 68 65 20 68 61  alues] to the ha
16730 73 68 20 74 61 62 6c 65 20 5b 74 65 72 6d 73 5d  sh table [terms]
16740 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
16750 69 6e 73 65 72 74 54 65 72 6d 73 28 66 75 6c 6c  insertTerms(full
16760 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 66 74  text_vtab *v, ft
16770 73 31 48 61 73 68 20 2a 74 65 72 6d 73 2c 20 73  s1Hash *terms, s
16780 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 52 6f 77  qlite_int64 iRow
16790 69 64 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  id,.            
167a0 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75      sqlite3_valu
167b0 65 20 2a 2a 70 56 61 6c 75 65 73 29 7b 0a 20 20  e **pValues){.  
167c0 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 20 3d  int i;.  for(i =
167d0 20 30 3b 20 69 20 3c 20 76 2d 3e 6e 43 6f 6c 75   0; i < v->nColu
167e0 6d 6e 20 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 63  mn ; ++i){.    c
167f0 68 61 72 20 2a 7a 54 65 78 74 20 3d 20 28 63 68  har *zText = (ch
16800 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
16810 65 5f 74 65 78 74 28 70 56 61 6c 75 65 73 5b 69  e_text(pValues[i
16820 5d 29 3b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d  ]);.    int rc =
16830 20 62 75 69 6c 64 54 65 72 6d 73 28 76 2c 20 74   buildTerms(v, t
16840 65 72 6d 73 2c 20 69 52 6f 77 69 64 2c 20 7a 54  erms, iRowid, zT
16850 65 78 74 2c 20 69 29 3b 0a 20 20 20 20 69 66 28  ext, i);.    if(
16860 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
16870 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
16880 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
16890 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 41 64 64 20 65 6d  OK;.}../* Add em
168a0 70 74 79 20 64 6f 63 6c 69 73 74 73 20 66 6f 72  pty doclists for
168b0 20 61 6c 6c 20 74 65 72 6d 73 20 69 6e 20 74 68   all terms in th
168c0 65 20 67 69 76 65 6e 20 72 6f 77 27 73 20 63 6f  e given row's co
168d0 6e 74 65 6e 74 20 74 6f 20 74 68 65 20 68 61 73  ntent to the has
168e0 68 0a 20 2a 20 74 61 62 6c 65 20 5b 70 54 65 72  h. * table [pTer
168f0 6d 73 5d 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69  ms]. */.static i
16900 6e 74 20 64 65 6c 65 74 65 54 65 72 6d 73 28 66  nt deleteTerms(f
16910 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c  ulltext_vtab *v,
16920 20 66 74 73 31 48 61 73 68 20 2a 70 54 65 72 6d   fts1Hash *pTerm
16930 73 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  s, sqlite_int64 
16940 69 52 6f 77 69 64 29 7b 0a 20 20 63 6f 6e 73 74  iRowid){.  const
16950 20 63 68 61 72 20 2a 2a 70 56 61 6c 75 65 73 3b   char **pValues;
16960 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69 6e 74  .  int i;..  int
16970 20 72 63 20 3d 20 63 6f 6e 74 65 6e 74 5f 73 65   rc = content_se
16980 6c 65 63 74 28 76 2c 20 69 52 6f 77 69 64 2c 20  lect(v, iRowid, 
16990 26 70 56 61 6c 75 65 73 29 3b 0a 20 20 69 66 28  &pValues);.  if(
169a0 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
169b0 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 66   return rc;..  f
169c0 6f 72 28 69 20 3d 20 30 20 3b 20 69 20 3c 20 76  or(i = 0 ; i < v
169d0 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 20  ->nColumn; ++i) 
169e0 7b 0a 20 20 20 20 72 63 20 3d 20 62 75 69 6c 64  {.    rc = build
169f0 54 65 72 6d 73 28 76 2c 20 70 54 65 72 6d 73 2c  Terms(v, pTerms,
16a00 20 69 52 6f 77 69 64 2c 20 70 56 61 6c 75 65 73   iRowid, pValues
16a10 5b 69 5d 2c 20 2d 31 29 3b 0a 20 20 20 20 69 66  [i], -1);.    if
16a20 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
16a30 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20  ) break;.  }..  
16a40 66 72 65 65 53 74 72 69 6e 67 41 72 72 61 79 28  freeStringArray(
16a50 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 70 56 61 6c  v->nColumn, pVal
16a60 75 65 73 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  ues);.  return S
16a70 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20  QLITE_OK;.}../* 
16a80 49 6e 73 65 72 74 20 61 20 72 6f 77 20 69 6e 74  Insert a row int
16a90 6f 20 74 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20  o the %_content 
16aa0 74 61 62 6c 65 3b 20 73 65 74 20 2a 70 69 52 6f  table; set *piRo
16ab0 77 69 64 20 74 6f 20 62 65 20 74 68 65 20 49 44  wid to be the ID
16ac0 20 6f 66 20 74 68 65 0a 20 2a 20 6e 65 77 20 72   of the. * new r
16ad0 6f 77 2e 20 20 46 69 6c 6c 20 5b 70 54 65 72 6d  ow.  Fill [pTerm
16ae0 73 5d 20 77 69 74 68 20 6e 65 77 20 64 6f 63 6c  s] with new docl
16af0 69 73 74 73 20 66 6f 72 20 74 68 65 20 25 5f 74  ists for the %_t
16b00 65 72 6d 20 74 61 62 6c 65 2e 20 2a 2f 0a 73 74  erm table. */.st
16b10 61 74 69 63 20 69 6e 74 20 69 6e 64 65 78 5f 69  atic int index_i
16b20 6e 73 65 72 74 28 66 75 6c 6c 74 65 78 74 5f 76  nsert(fulltext_v
16b30 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 33 5f  tab *v, sqlite3_
16b40 76 61 6c 75 65 20 2a 70 52 65 71 75 65 73 74 52  value *pRequestR
16b50 6f 77 69 64 2c 0a 20 20 20 20 20 20 20 20 20 20  owid,.          
16b60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
16b70 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 70 56  lite3_value **pV
16b80 61 6c 75 65 73 2c 0a 20 20 20 20 20 20 20 20 20  alues,.         
16b90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
16ba0 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 69 52  qlite_int64 *piR
16bb0 6f 77 69 64 2c 20 66 74 73 31 48 61 73 68 20 2a  owid, fts1Hash *
16bc0 70 54 65 72 6d 73 29 7b 0a 20 20 69 6e 74 20 72  pTerms){.  int r
16bd0 63 3b 0a 0a 20 20 72 63 20 3d 20 63 6f 6e 74 65  c;..  rc = conte
16be0 6e 74 5f 69 6e 73 65 72 74 28 76 2c 20 70 52 65  nt_insert(v, pRe
16bf0 71 75 65 73 74 52 6f 77 69 64 2c 20 70 56 61 6c  questRowid, pVal
16c00 75 65 73 29 3b 20 20 2f 2a 20 65 78 65 63 75 74  ues);  /* execut
16c10 65 20 61 6e 20 53 51 4c 20 49 4e 53 45 52 54 20  e an SQL INSERT 
16c20 2a 2f 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  */.  if( rc!=SQL
16c30 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
16c40 72 63 3b 0a 20 20 2a 70 69 52 6f 77 69 64 20 3d  rc;.  *piRowid =
16c50 20 73 71 6c 69 74 65 33 5f 6c 61 73 74 5f 69 6e   sqlite3_last_in
16c60 73 65 72 74 5f 72 6f 77 69 64 28 76 2d 3e 64 62  sert_rowid(v->db
16c70 29 3b 0a 20 20 72 65 74 75 72 6e 20 69 6e 73 65  );.  return inse
16c80 72 74 54 65 72 6d 73 28 76 2c 20 70 54 65 72 6d  rtTerms(v, pTerm
16c90 73 2c 20 2a 70 69 52 6f 77 69 64 2c 20 70 56 61  s, *piRowid, pVa
16ca0 6c 75 65 73 29 3b 0a 7d 0a 0a 2f 2a 20 44 65 6c  lues);.}../* Del
16cb0 65 74 65 20 61 20 72 6f 77 20 66 72 6f 6d 20 74  ete a row from t
16cc0 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62  he %_content tab
16cd0 6c 65 3b 20 66 69 6c 6c 20 5b 70 54 65 72 6d 73  le; fill [pTerms
16ce0 5d 20 77 69 74 68 20 65 6d 70 74 79 20 64 6f 63  ] with empty doc
16cf0 6c 69 73 74 73 0a 20 2a 20 74 6f 20 62 65 20 77  lists. * to be w
16d00 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20 25 5f  ritten to the %_
16d10 74 65 72 6d 20 74 61 62 6c 65 2e 20 2a 2f 0a 73  term table. */.s
16d20 74 61 74 69 63 20 69 6e 74 20 69 6e 64 65 78 5f  tatic int index_
16d30 64 65 6c 65 74 65 28 66 75 6c 6c 74 65 78 74 5f  delete(fulltext_
16d40 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f  vtab *v, sqlite_
16d50 69 6e 74 36 34 20 69 52 6f 77 2c 20 66 74 73 31  int64 iRow, fts1
16d60 48 61 73 68 20 2a 70 54 65 72 6d 73 29 7b 0a 20  Hash *pTerms){. 
16d70 20 69 6e 74 20 72 63 20 3d 20 64 65 6c 65 74 65   int rc = delete
16d80 54 65 72 6d 73 28 76 2c 20 70 54 65 72 6d 73 2c  Terms(v, pTerms,
16d90 20 69 52 6f 77 29 3b 0a 20 20 69 66 28 20 72 63   iRow);.  if( rc
16da0 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
16db0 74 75 72 6e 20 72 63 3b 0a 20 20 72 65 74 75 72  turn rc;.  retur
16dc0 6e 20 63 6f 6e 74 65 6e 74 5f 64 65 6c 65 74 65  n content_delete
16dd0 28 76 2c 20 69 52 6f 77 29 3b 20 20 2f 2a 20 65  (v, iRow);  /* e
16de0 78 65 63 75 74 65 20 61 6e 20 53 51 4c 20 44 45  xecute an SQL DE
16df0 4c 45 54 45 20 2a 2f 0a 7d 0a 0a 2f 2a 20 55 70  LETE */.}../* Up
16e00 64 61 74 65 20 61 20 72 6f 77 20 69 6e 20 74 68  date a row in th
16e10 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62 6c  e %_content tabl
16e20 65 3b 20 66 69 6c 6c 20 5b 70 54 65 72 6d 73 5d  e; fill [pTerms]
16e30 20 77 69 74 68 20 6e 65 77 20 64 6f 63 6c 69 73   with new doclis
16e40 74 73 20 66 6f 72 20 74 68 65 0a 20 2a 20 25 5f  ts for the. * %_
16e50 74 65 72 6d 20 74 61 62 6c 65 2e 20 2a 2f 0a 73  term table. */.s
16e60 74 61 74 69 63 20 69 6e 74 20 69 6e 64 65 78 5f  tatic int index_
16e70 75 70 64 61 74 65 28 66 75 6c 6c 74 65 78 74 5f  update(fulltext_
16e80 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f  vtab *v, sqlite_
16e90 69 6e 74 36 34 20 69 52 6f 77 2c 0a 20 20 20 20  int64 iRow,.    
16ea0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16eb0 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75      sqlite3_valu
16ec0 65 20 2a 2a 70 56 61 6c 75 65 73 2c 20 66 74 73  e **pValues, fts
16ed0 31 48 61 73 68 20 2a 70 54 65 72 6d 73 29 7b 0a  1Hash *pTerms){.
16ee0 20 20 2f 2a 20 47 65 6e 65 72 61 74 65 20 61 6e    /* Generate an
16ef0 20 65 6d 70 74 79 20 64 6f 63 6c 69 73 74 20 66   empty doclist f
16f00 6f 72 20 65 61 63 68 20 74 65 72 6d 20 74 68 61  or each term tha
16f10 74 20 70 72 65 76 69 6f 75 73 6c 79 20 61 70 70  t previously app
16f20 65 61 72 65 64 20 69 6e 20 74 68 69 73 0a 20 20  eared in this.  
16f30 20 2a 20 72 6f 77 2e 20 2a 2f 0a 20 20 69 6e 74   * row. */.  int
16f40 20 72 63 20 3d 20 64 65 6c 65 74 65 54 65 72 6d   rc = deleteTerm
16f50 73 28 76 2c 20 70 54 65 72 6d 73 2c 20 69 52 6f  s(v, pTerms, iRo
16f60 77 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  w);.  if( rc!=SQ
16f70 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
16f80 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 63 6f 6e   rc;..  rc = con
16f90 74 65 6e 74 5f 75 70 64 61 74 65 28 76 2c 20 70  tent_update(v, p
16fa0 56 61 6c 75 65 73 2c 20 69 52 6f 77 29 3b 20 20  Values, iRow);  
16fb0 2f 2a 20 65 78 65 63 75 74 65 20 61 6e 20 53 51  /* execute an SQ
16fc0 4c 20 55 50 44 41 54 45 20 2a 2f 0a 20 20 69 66  L UPDATE */.  if
16fd0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
16fe0 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
16ff0 2f 2a 20 4e 6f 77 20 61 64 64 20 70 6f 73 69 74  /* Now add posit
17000 69 6f 6e 73 20 66 6f 72 20 74 65 72 6d 73 20 77  ions for terms w
17010 68 69 63 68 20 61 70 70 65 61 72 20 69 6e 20 74  hich appear in t
17020 68 65 20 75 70 64 61 74 65 64 20 72 6f 77 2e 20  he updated row. 
17030 2a 2f 0a 20 20 72 65 74 75 72 6e 20 69 6e 73 65  */.  return inse
17040 72 74 54 65 72 6d 73 28 76 2c 20 70 54 65 72 6d  rtTerms(v, pTerm
17050 73 2c 20 69 52 6f 77 2c 20 70 56 61 6c 75 65 73  s, iRow, pValues
17060 29 3b 0a 7d 0a 0a 2f 2a 20 54 68 69 73 20 66 75  );.}../* This fu
17070 6e 63 74 69 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74  nction implement
17080 73 20 74 68 65 20 78 55 70 64 61 74 65 20 63 61  s the xUpdate ca
17090 6c 6c 62 61 63 6b 3b 20 69 74 27 73 20 74 68 65  llback; it's the
170a0 20 74 6f 70 2d 6c 65 76 65 6c 20 65 6e 74 72 79   top-level entry
170b0 0a 20 2a 20 70 6f 69 6e 74 20 66 6f 72 20 69 6e  . * point for in
170c0 73 65 72 74 69 6e 67 2c 20 64 65 6c 65 74 69 6e  serting, deletin
170d0 67 20 6f 72 20 75 70 64 61 74 69 6e 67 20 61 20  g or updating a 
170e0 72 6f 77 20 69 6e 20 61 20 66 75 6c 6c 2d 74 65  row in a full-te
170f0 78 74 20 74 61 62 6c 65 2e 20 2a 2f 0a 73 74 61  xt table. */.sta
17100 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74  tic int fulltext
17110 55 70 64 61 74 65 28 73 71 6c 69 74 65 33 5f 76  Update(sqlite3_v
17120 74 61 62 20 2a 70 56 74 61 62 2c 20 69 6e 74 20  tab *pVtab, int 
17130 6e 41 72 67 2c 20 73 71 6c 69 74 65 33 5f 76 61  nArg, sqlite3_va
17140 6c 75 65 20 2a 2a 70 70 41 72 67 2c 0a 20 20 20  lue **ppArg,.   
17150 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17160 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52  sqlite_int64 *pR
17170 6f 77 69 64 29 7b 0a 20 20 66 75 6c 6c 74 65 78  owid){.  fulltex
17180 74 5f 76 74 61 62 20 2a 76 20 3d 20 28 66 75 6c  t_vtab *v = (ful
17190 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 20 70 56  ltext_vtab *) pV
171a0 74 61 62 3b 0a 20 20 66 74 73 31 48 61 73 68 20  tab;.  fts1Hash 
171b0 74 65 72 6d 73 3b 20 20 20 2f 2a 20 6d 61 70 73  terms;   /* maps
171c0 20 74 65 72 6d 20 73 74 72 69 6e 67 20 2d 3e 20   term string -> 
171d0 50 6f 73 4c 69 73 74 20 2a 2f 0a 20 20 69 6e 74  PosList */.  int
171e0 20 72 63 3b 0a 20 20 66 74 73 31 48 61 73 68 45   rc;.  fts1HashE
171f0 6c 65 6d 20 2a 65 3b 0a 0a 20 20 54 52 41 43 45  lem *e;..  TRACE
17200 28 28 22 46 54 53 31 20 55 70 64 61 74 65 20 25  (("FTS1 Update %
17210 70 5c 6e 22 2c 20 70 56 74 61 62 29 29 3b 0a 20  p\n", pVtab));. 
17220 20 0a 20 20 66 74 73 31 48 61 73 68 49 6e 69 74   .  fts1HashInit
17230 28 26 74 65 72 6d 73 2c 20 46 54 53 31 5f 48 41  (&terms, FTS1_HA
17240 53 48 5f 53 54 52 49 4e 47 2c 20 31 29 3b 0a 0a  SH_STRING, 1);..
17250 20 20 69 66 28 20 6e 41 72 67 3c 32 20 29 7b 0a    if( nArg<2 ){.
17260 20 20 20 20 72 63 20 3d 20 69 6e 64 65 78 5f 64      rc = index_d
17270 65 6c 65 74 65 28 76 2c 20 73 71 6c 69 74 65 33  elete(v, sqlite3
17280 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 70 70 41  _value_int64(ppA
17290 72 67 5b 30 5d 29 2c 20 26 74 65 72 6d 73 29 3b  rg[0]), &terms);
172a0 0a 20 20 7d 20 65 6c 73 65 20 69 66 28 20 73 71  .  } else if( sq
172b0 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
172c0 28 70 70 41 72 67 5b 30 5d 29 20 21 3d 20 53 51  (ppArg[0]) != SQ
172d0 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20  LITE_NULL ){.   
172e0 20 2f 2a 20 41 6e 20 75 70 64 61 74 65 3a 0a 20   /* An update:. 
172f0 20 20 20 20 2a 20 70 70 41 72 67 5b 30 5d 20 3d      * ppArg[0] =
17300 20 6f 6c 64 20 72 6f 77 69 64 0a 20 20 20 20 20   old rowid.     
17310 2a 20 70 70 41 72 67 5b 31 5d 20 3d 20 6e 65 77  * ppArg[1] = new
17320 20 72 6f 77 69 64 0a 20 20 20 20 20 2a 20 70 70   rowid.     * pp
17330 41 72 67 5b 32 2e 2e 32 2b 76 2d 3e 6e 43 6f 6c  Arg[2..2+v->nCol
17340 75 6d 6e 2d 31 5d 20 3d 20 76 61 6c 75 65 73 0a  umn-1] = values.
17350 20 20 20 20 20 2a 20 70 70 41 72 67 5b 32 2b 76       * ppArg[2+v
17360 2d 3e 6e 43 6f 6c 75 6d 6e 5d 20 3d 20 76 61 6c  ->nColumn] = val
17370 75 65 20 66 6f 72 20 6d 61 67 69 63 20 63 6f 6c  ue for magic col
17380 75 6d 6e 20 28 77 65 20 69 67 6e 6f 72 65 20 74  umn (we ignore t
17390 68 69 73 29 0a 20 20 20 20 20 2a 2f 0a 20 20 20  his).     */.   
173a0 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 72 6f   sqlite_int64 ro
173b0 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 76 61  wid = sqlite3_va
173c0 6c 75 65 5f 69 6e 74 36 34 28 70 70 41 72 67 5b  lue_int64(ppArg[
173d0 30 5d 29 3b 0a 20 20 20 20 69 66 28 20 73 71 6c  0]);.    if( sql
173e0 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
173f0 70 70 41 72 67 5b 31 5d 29 20 21 3d 20 53 51 4c  ppArg[1]) != SQL
17400 49 54 45 5f 49 4e 54 45 47 45 52 20 7c 7c 0a 20  ITE_INTEGER ||. 
17410 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c       sqlite3_val
17420 75 65 5f 69 6e 74 36 34 28 70 70 41 72 67 5b 31  ue_int64(ppArg[1
17430 5d 29 20 21 3d 20 72 6f 77 69 64 20 29 7b 0a 20  ]) != rowid ){. 
17440 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
17450 5f 45 52 52 4f 52 3b 20 20 2f 2a 20 77 65 20 64  _ERROR;  /* we d
17460 6f 6e 27 74 20 61 6c 6c 6f 77 20 63 68 61 6e 67  on't allow chang
17470 69 6e 67 20 74 68 65 20 72 6f 77 69 64 20 2a 2f  ing the rowid */
17480 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
17490 20 20 20 20 61 73 73 65 72 74 28 20 6e 41 72 67      assert( nArg
174a0 3d 3d 32 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e 2b 31  ==2+v->nColumn+1
174b0 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 69 6e  );.      rc = in
174c0 64 65 78 5f 75 70 64 61 74 65 28 76 2c 20 72 6f  dex_update(v, ro
174d0 77 69 64 2c 20 26 70 70 41 72 67 5b 32 5d 2c 20  wid, &ppArg[2], 
174e0 26 74 65 72 6d 73 29 3b 0a 20 20 20 20 7d 0a 20  &terms);.    }. 
174f0 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 2f 2a   } else {.    /*
17500 20 41 6e 20 69 6e 73 65 72 74 3a 0a 20 20 20 20   An insert:.    
17510 20 2a 20 70 70 41 72 67 5b 31 5d 20 3d 20 72 65   * ppArg[1] = re
17520 71 75 65 73 74 65 64 20 72 6f 77 69 64 0a 20 20  quested rowid.  
17530 20 20 20 2a 20 70 70 41 72 67 5b 32 2e 2e 32 2b     * ppArg[2..2+
17540 76 2d 3e 6e 43 6f 6c 75 6d 6e 2d 31 5d 20 3d 20  v->nColumn-1] = 
17550 76 61 6c 75 65 73 0a 20 20 20 20 20 2a 20 70 70  values.     * pp
17560 41 72 67 5b 32 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e  Arg[2+v->nColumn
17570 5d 20 3d 20 76 61 6c 75 65 20 66 6f 72 20 6d 61  ] = value for ma
17580 67 69 63 20 63 6f 6c 75 6d 6e 20 28 77 65 20 69  gic column (we i
17590 67 6e 6f 72 65 20 74 68 69 73 29 0a 20 20 20 20  gnore this).    
175a0 20 2a 2f 0a 20 20 20 20 61 73 73 65 72 74 28 20   */.    assert( 
175b0 6e 41 72 67 3d 3d 32 2b 76 2d 3e 6e 43 6f 6c 75  nArg==2+v->nColu
175c0 6d 6e 2b 31 29 3b 0a 20 20 20 20 72 63 20 3d 20  mn+1);.    rc = 
175d0 69 6e 64 65 78 5f 69 6e 73 65 72 74 28 76 2c 20  index_insert(v, 
175e0 70 70 41 72 67 5b 31 5d 2c 20 26 70 70 41 72 67  ppArg[1], &ppArg
175f0 5b 32 5d 2c 20 70 52 6f 77 69 64 2c 20 26 74 65  [2], pRowid, &te
17600 72 6d 73 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  rms);.  }..  if(
17610 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
17620 7b 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20 75  {.    /* Write u
17630 70 64 61 74 65 64 20 64 6f 63 6c 69 73 74 73 20  pdated doclists 
17640 74 6f 20 64 69 73 6b 2e 20 2a 2f 0a 20 20 20 20  to disk. */.    
17650 66 6f 72 28 65 3d 66 74 73 31 48 61 73 68 46 69  for(e=fts1HashFi
17660 72 73 74 28 26 74 65 72 6d 73 29 3b 20 65 3b 20  rst(&terms); e; 
17670 65 3d 66 74 73 31 48 61 73 68 4e 65 78 74 28 65  e=fts1HashNext(e
17680 29 29 7b 0a 20 20 20 20 20 20 44 6f 63 4c 69 73  )){.      DocLis
17690 74 20 2a 70 20 3d 20 66 74 73 31 48 61 73 68 44  t *p = fts1HashD
176a0 61 74 61 28 65 29 3b 0a 20 20 20 20 20 20 72 63  ata(e);.      rc
176b0 20 3d 20 69 6e 64 65 78 5f 69 6e 73 65 72 74 5f   = index_insert_
176c0 74 65 72 6d 28 76 2c 20 66 74 73 31 48 61 73 68  term(v, fts1Hash
176d0 4b 65 79 28 65 29 2c 20 66 74 73 31 48 61 73 68  Key(e), fts1Hash
176e0 4b 65 79 73 69 7a 65 28 65 29 2c 20 70 29 3b 0a  Keysize(e), p);.
176f0 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
17700 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b  LITE_OK ) break;
17710 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
17720 20 63 6c 65 61 6e 20 75 70 20 2a 2f 0a 20 20 66   clean up */.  f
17730 6f 72 28 65 3d 66 74 73 31 48 61 73 68 46 69 72  or(e=fts1HashFir
17740 73 74 28 26 74 65 72 6d 73 29 3b 20 65 3b 20 65  st(&terms); e; e
17750 3d 66 74 73 31 48 61 73 68 4e 65 78 74 28 65 29  =fts1HashNext(e)
17760 29 7b 0a 20 20 20 20 44 6f 63 4c 69 73 74 20 2a  ){.    DocList *
17770 70 20 3d 20 66 74 73 31 48 61 73 68 44 61 74 61  p = fts1HashData
17780 28 65 29 3b 0a 20 20 20 20 64 6f 63 4c 69 73 74  (e);.    docList
17790 44 65 6c 65 74 65 28 70 29 3b 0a 20 20 7d 0a 20  Delete(p);.  }. 
177a0 20 66 74 73 31 48 61 73 68 43 6c 65 61 72 28 26   fts1HashClear(&
177b0 74 65 72 6d 73 29 3b 0a 0a 20 20 72 65 74 75 72  terms);..  retur
177c0 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  n rc;.}../*.** I
177d0 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
177e0 20 74 68 65 20 73 6e 69 70 70 65 74 28 29 20 66   the snippet() f
177f0 75 6e 63 74 69 6f 6e 20 66 6f 72 20 46 54 53 31  unction for FTS1
17800 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
17810 73 6e 69 70 70 65 74 46 75 6e 63 28 0a 20 20 73  snippetFunc(.  s
17820 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
17830 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20  pContext,.  int 
17840 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argc,.  sqlite3_
17850 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a  value **argv.){.
17860 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f    fulltext_curso
17870 72 20 2a 70 43 75 72 73 6f 72 3b 0a 20 20 69 66  r *pCursor;.  if
17880 28 20 61 72 67 63 3c 31 20 29 20 72 65 74 75 72  ( argc<1 ) retur
17890 6e 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33  n;.  if( sqlite3
178a0 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 72 67 76  _value_type(argv
178b0 5b 30 5d 29 21 3d 53 51 4c 49 54 45 5f 42 4c 4f  [0])!=SQLITE_BLO
178c0 42 20 7c 7c 0a 20 20 20 20 20 20 73 71 6c 69 74  B ||.      sqlit
178d0 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61  e3_value_bytes(a
178e0 72 67 76 5b 30 5d 29 21 3d 73 69 7a 65 6f 66 28  rgv[0])!=sizeof(
178f0 70 43 75 72 73 6f 72 29 20 29 7b 0a 20 20 20 20  pCursor) ){.    
17900 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65  sqlite3_result_e
17910 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 22  rror(pContext, "
17920 69 6c 6c 65 67 61 6c 20 66 69 72 73 74 20 61 72  illegal first ar
17930 67 75 6d 65 6e 74 20 74 6f 20 68 74 6d 6c 5f 73  gument to html_s
17940 6e 69 70 70 65 74 22 2c 2d 31 29 3b 0a 20 20 7d  nippet",-1);.  }
17950 65 6c 73 65 7b 0a 20 20 20 20 63 6f 6e 73 74 20  else{.    const 
17960 63 68 61 72 20 2a 7a 53 74 61 72 74 20 3d 20 22  char *zStart = "
17970 3c 62 3e 22 3b 0a 20 20 20 20 63 6f 6e 73 74 20  <b>";.    const 
17980 63 68 61 72 20 2a 7a 45 6e 64 20 3d 20 22 3c 2f  char *zEnd = "</
17990 62 3e 22 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63  b>";.    const c
179a0 68 61 72 20 2a 7a 45 6c 6c 69 70 73 69 73 20 3d  har *zEllipsis =
179b0 20 22 3c 62 3e 2e 2e 2e 3c 2f 62 3e 22 3b 0a 20   "<b>...</b>";. 
179c0 20 20 20 6d 65 6d 63 70 79 28 26 70 43 75 72 73     memcpy(&pCurs
179d0 6f 72 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  or, sqlite3_valu
179e0 65 5f 62 6c 6f 62 28 61 72 67 76 5b 30 5d 29 2c  e_blob(argv[0]),
179f0 20 73 69 7a 65 6f 66 28 70 43 75 72 73 6f 72 29   sizeof(pCursor)
17a00 29 3b 0a 20 20 20 20 69 66 28 20 61 72 67 63 3e  );.    if( argc>
17a10 3d 32 20 29 7b 0a 20 20 20 20 20 20 7a 53 74 61  =2 ){.      zSta
17a20 72 74 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72  rt = (const char
17a30 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  *)sqlite3_value_
17a40 74 65 78 74 28 61 72 67 76 5b 31 5d 29 3b 0a 20  text(argv[1]);. 
17a50 20 20 20 20 20 69 66 28 20 61 72 67 63 3e 3d 33       if( argc>=3
17a60 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 45 6e 64   ){.        zEnd
17a70 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29   = (const char*)
17a80 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
17a90 78 74 28 61 72 67 76 5b 32 5d 29 3b 0a 20 20 20  xt(argv[2]);.   
17aa0 20 20 20 20 20 69 66 28 20 61 72 67 63 3e 3d 34       if( argc>=4
17ab0 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 45   ){.          zE
17ac0 6c 6c 69 70 73 69 73 20 3d 20 28 63 6f 6e 73 74  llipsis = (const
17ad0 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76   char*)sqlite3_v
17ae0 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 33  alue_text(argv[3
17af0 5d 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  ]);.        }.  
17b00 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
17b10 73 6e 69 70 70 65 74 41 6c 6c 4f 66 66 73 65 74  snippetAllOffset
17b20 73 28 70 43 75 72 73 6f 72 29 3b 0a 20 20 20 20  s(pCursor);.    
17b30 73 6e 69 70 70 65 74 54 65 78 74 28 70 43 75 72  snippetText(pCur
17b40 73 6f 72 2c 20 7a 53 74 61 72 74 2c 20 7a 45 6e  sor, zStart, zEn
17b50 64 2c 20 7a 45 6c 6c 69 70 73 69 73 29 3b 0a 20  d, zEllipsis);. 
17b60 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
17b70 74 5f 74 65 78 74 28 70 43 6f 6e 74 65 78 74 2c  t_text(pContext,
17b80 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65   pCursor->snippe
17b90 74 2e 7a 53 6e 69 70 70 65 74 2c 0a 20 20 20 20  t.zSnippet,.    
17ba0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17bb0 20 20 20 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69      pCursor->sni
17bc0 70 70 65 74 2e 6e 53 6e 69 70 70 65 74 2c 20 53  ppet.nSnippet, S
17bd0 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20  QLITE_STATIC);. 
17be0 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c   }.}../*.** Impl
17bf0 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
17c00 65 20 6f 66 66 73 65 74 73 28 29 20 66 75 6e 63  e offsets() func
17c10 74 69 6f 6e 20 66 6f 72 20 46 54 53 31 0a 2a 2f  tion for FTS1.*/
17c20 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 6e 69  .static void sni
17c30 70 70 65 74 4f 66 66 73 65 74 73 46 75 6e 63 28  ppetOffsetsFunc(
17c40 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65  .  sqlite3_conte
17c50 78 74 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20  xt *pContext,.  
17c60 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69  int argc,.  sqli
17c70 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76  te3_value **argv
17c80 0a 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63  .){.  fulltext_c
17c90 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 3b 0a  ursor *pCursor;.
17ca0 20 20 69 66 28 20 61 72 67 63 3c 31 20 29 20 72    if( argc<1 ) r
17cb0 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 73 71 6c  eturn;.  if( sql
17cc0 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
17cd0 61 72 67 76 5b 30 5d 29 21 3d 53 51 4c 49 54 45  argv[0])!=SQLITE
17ce0 5f 42 4c 4f 42 20 7c 7c 0a 20 20 20 20 20 20 73  _BLOB ||.      s
17cf0 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74  qlite3_value_byt
17d00 65 73 28 61 72 67 76 5b 30 5d 29 21 3d 73 69 7a  es(argv[0])!=siz
17d10 65 6f 66 28 70 43 75 72 73 6f 72 29 20 29 7b 0a  eof(pCursor) ){.
17d20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
17d30 6c 74 5f 65 72 72 6f 72 28 70 43 6f 6e 74 65 78  lt_error(pContex
17d40 74 2c 20 22 69 6c 6c 65 67 61 6c 20 66 69 72 73  t, "illegal firs
17d50 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 6f 66  t argument to of
17d60 66 73 65 74 73 22 2c 2d 31 29 3b 0a 20 20 7d 65  fsets",-1);.  }e
17d70 6c 73 65 7b 0a 20 20 20 20 6d 65 6d 63 70 79 28  lse{.    memcpy(
17d80 26 70 43 75 72 73 6f 72 2c 20 73 71 6c 69 74 65  &pCursor, sqlite
17d90 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 61 72 67  3_value_blob(arg
17da0 76 5b 30 5d 29 2c 20 73 69 7a 65 6f 66 28 70 43  v[0]), sizeof(pC
17db0 75 72 73 6f 72 29 29 3b 0a 20 20 20 20 73 6e 69  ursor));.    sni
17dc0 70 70 65 74 41 6c 6c 4f 66 66 73 65 74 73 28 70  ppetAllOffsets(p
17dd0 43 75 72 73 6f 72 29 3b 0a 20 20 20 20 73 6e 69  Cursor);.    sni
17de0 70 70 65 74 4f 66 66 73 65 74 54 65 78 74 28 26  ppetOffsetText(&
17df0 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74  pCursor->snippet
17e00 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  );.    sqlite3_r
17e10 65 73 75 6c 74 5f 74 65 78 74 28 70 43 6f 6e 74  esult_text(pCont
17e20 65 78 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ext,.           
17e30 20 20 20 20 20 20 20 20 20 20 20 20 20 70 43 75               pCu
17e40 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74 2e 7a 4f  rsor->snippet.zO
17e50 66 66 73 65 74 2c 20 70 43 75 72 73 6f 72 2d 3e  ffset, pCursor->
17e60 73 6e 69 70 70 65 74 2e 6e 4f 66 66 73 65 74 2c  snippet.nOffset,
17e70 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
17e80 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
17e90 53 54 41 54 49 43 29 3b 0a 20 20 7d 0a 7d 0a 0a  STATIC);.  }.}..
17ea0 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  /*.** This routi
17eb0 6e 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68  ne implements th
17ec0 65 20 78 46 69 6e 64 46 75 6e 63 74 69 6f 6e 20  e xFindFunction 
17ed0 6d 65 74 68 6f 64 20 66 6f 72 20 74 68 65 20 46  method for the F
17ee0 54 53 31 0a 2a 2a 20 76 69 72 74 75 61 6c 20 74  TS1.** virtual t
17ef0 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  able..*/.static 
17f00 69 6e 74 20 66 75 6c 6c 74 65 78 74 46 69 6e 64  int fulltextFind
17f10 46 75 6e 63 74 69 6f 6e 28 0a 20 20 73 71 6c 69  Function(.  sqli
17f20 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c  te3_vtab *pVtab,
17f30 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20 63  .  int nArg,.  c
17f40 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
17f50 2c 0a 20 20 76 6f 69 64 20 28 2a 2a 70 78 46 75  ,.  void (**pxFu
17f60 6e 63 29 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74  nc)(sqlite3_cont
17f70 65 78 74 2a 2c 69 6e 74 2c 73 71 6c 69 74 65 33  ext*,int,sqlite3
17f80 5f 76 61 6c 75 65 2a 2a 29 2c 0a 20 20 76 6f 69  _value**),.  voi
17f90 64 20 2a 2a 70 70 41 72 67 0a 29 7b 0a 20 20 69  d **ppArg.){.  i
17fa0 66 28 20 73 74 72 63 6d 70 28 7a 4e 61 6d 65 2c  f( strcmp(zName,
17fb0 22 73 6e 69 70 70 65 74 22 29 3d 3d 30 20 29 7b  "snippet")==0 ){
17fc0 0a 20 20 20 20 2a 70 78 46 75 6e 63 20 3d 20 73  .    *pxFunc = s
17fd0 6e 69 70 70 65 74 46 75 6e 63 3b 0a 20 20 20 20  nippetFunc;.    
17fe0 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 65 6c 73  return 1;.  }els
17ff0 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 4e 61  e if( strcmp(zNa
18000 6d 65 2c 22 6f 66 66 73 65 74 73 22 29 3d 3d 30  me,"offsets")==0
18010 20 29 7b 0a 20 20 20 20 2a 70 78 46 75 6e 63 20   ){.    *pxFunc 
18020 3d 20 73 6e 69 70 70 65 74 4f 66 66 73 65 74 73  = snippetOffsets
18030 46 75 6e 63 3b 0a 20 20 20 20 72 65 74 75 72 6e  Func;.    return
18040 20 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   1;.  }.  return
18050 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 6f   0;.}..static co
18060 6e 73 74 20 73 71 6c 69 74 65 33 5f 6d 6f 64 75  nst sqlite3_modu
18070 6c 65 20 66 75 6c 6c 74 65 78 74 4d 6f 64 75 6c  le fulltextModul
18080 65 20 3d 20 7b 0a 20 20 2f 2a 20 69 56 65 72 73  e = {.  /* iVers
18090 69 6f 6e 20 20 20 20 20 20 2a 2f 20 30 2c 0a 20  ion      */ 0,. 
180a0 20 2f 2a 20 78 43 72 65 61 74 65 20 20 20 20 20   /* xCreate     
180b0 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74 43 72 65    */ fulltextCre
180c0 61 74 65 2c 0a 20 20 2f 2a 20 78 43 6f 6e 6e 65  ate,.  /* xConne
180d0 63 74 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74  ct      */ fullt
180e0 65 78 74 43 6f 6e 6e 65 63 74 2c 0a 20 20 2f 2a  extConnect,.  /*
180f0 20 78 42 65 73 74 49 6e 64 65 78 20 20 20 20 2a   xBestIndex    *
18100 2f 20 66 75 6c 6c 74 65 78 74 42 65 73 74 49 6e  / fulltextBestIn
18110 64 65 78 2c 0a 20 20 2f 2a 20 78 44 69 73 63 6f  dex,.  /* xDisco
18120 6e 6e 65 63 74 20 20 20 2a 2f 20 66 75 6c 6c 74  nnect   */ fullt
18130 65 78 74 44 69 73 63 6f 6e 6e 65 63 74 2c 0a 20  extDisconnect,. 
18140 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 20 20 20   /* xDestroy    
18150 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74 44 65 73    */ fulltextDes
18160 74 72 6f 79 2c 0a 20 20 2f 2a 20 78 4f 70 65 6e  troy,.  /* xOpen
18170 20 20 20 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c           */ full
18180 74 65 78 74 4f 70 65 6e 2c 0a 20 20 2f 2a 20 78  textOpen,.  /* x
18190 43 6c 6f 73 65 20 20 20 20 20 20 20 20 2a 2f 20  Close        */ 
181a0 66 75 6c 6c 74 65 78 74 43 6c 6f 73 65 2c 0a 20  fulltextClose,. 
181b0 20 2f 2a 20 78 46 69 6c 74 65 72 20 20 20 20 20   /* xFilter     
181c0 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74 46 69 6c    */ fulltextFil
181d0 74 65 72 2c 0a 20 20 2f 2a 20 78 4e 65 78 74 20  ter,.  /* xNext 
181e0 20 20 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74          */ fullt
181f0 65 78 74 4e 65 78 74 2c 0a 20 20 2f 2a 20 78 45  extNext,.  /* xE
18200 6f 66 20 20 20 20 20 20 20 20 20 20 2a 2f 20 66  of          */ f
18210 75 6c 6c 74 65 78 74 45 6f 66 2c 0a 20 20 2f 2a  ulltextEof,.  /*
18220 20 78 43 6f 6c 75 6d 6e 20 20 20 20 20 20 20 2a   xColumn       *
18230 2f 20 66 75 6c 6c 74 65 78 74 43 6f 6c 75 6d 6e  / fulltextColumn
18240 2c 0a 20 20 2f 2a 20 78 52 6f 77 69 64 20 20 20  ,.  /* xRowid   
18250 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74       */ fulltext
18260 52 6f 77 69 64 2c 0a 20 20 2f 2a 20 78 55 70 64  Rowid,.  /* xUpd
18270 61 74 65 20 20 20 20 20 20 20 2a 2f 20 66 75 6c  ate       */ ful
18280 6c 74 65 78 74 55 70 64 61 74 65 2c 0a 20 20 2f  ltextUpdate,.  /
18290 2a 20 78 42 65 67 69 6e 20 20 20 20 20 20 20 20  * xBegin        
182a0 2a 2f 20 30 2c 20 0a 20 20 2f 2a 20 78 53 79 6e  */ 0, .  /* xSyn
182b0 63 20 20 20 20 20 20 20 20 20 2a 2f 20 30 2c 0a  c         */ 0,.
182c0 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20 20 20 20    /* xCommit    
182d0 20 20 20 2a 2f 20 30 2c 0a 20 20 2f 2a 20 78 52     */ 0,.  /* xR
182e0 6f 6c 6c 62 61 63 6b 20 20 20 20 20 2a 2f 20 30  ollback     */ 0
182f0 2c 0a 20 20 2f 2a 20 78 46 69 6e 64 46 75 6e 63  ,.  /* xFindFunc
18300 74 69 6f 6e 20 2a 2f 20 66 75 6c 6c 74 65 78 74  tion */ fulltext
18310 46 69 6e 64 46 75 6e 63 74 69 6f 6e 2c 0a 7d 3b  FindFunction,.};
18320 0a 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73  ..int sqlite3Fts
18330 31 49 6e 69 74 28 73 71 6c 69 74 65 33 20 2a 64  1Init(sqlite3 *d
18340 62 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 6f 76  b){.  sqlite3_ov
18350 65 72 6c 6f 61 64 5f 66 75 6e 63 74 69 6f 6e 28  erload_function(
18360 64 62 2c 20 22 73 6e 69 70 70 65 74 22 2c 20 2d  db, "snippet", -
18370 31 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6f 76  1);.  sqlite3_ov
18380 65 72 6c 6f 61 64 5f 66 75 6e 63 74 69 6f 6e 28  erload_function(
18390 64 62 2c 20 22 6f 66 66 73 65 74 73 22 2c 20 2d  db, "offsets", -
183a0 31 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  1);.  return sql
183b0 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75  ite3_create_modu
183c0 6c 65 28 64 62 2c 20 22 66 74 73 31 22 2c 20 26  le(db, "fts1", &
183d0 66 75 6c 6c 74 65 78 74 4d 6f 64 75 6c 65 2c 20  fulltextModule, 
183e0 30 29 3b 0a 7d 0a 0a 23 69 66 20 21 53 51 4c 49  0);.}..#if !SQLI
183f0 54 45 5f 43 4f 52 45 0a 69 6e 74 20 73 71 6c 69  TE_CORE.int sqli
18400 74 65 33 5f 65 78 74 65 6e 73 69 6f 6e 5f 69 6e  te3_extension_in
18410 69 74 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  it(sqlite3 *db, 
18420 63 68 61 72 20 2a 2a 70 7a 45 72 72 4d 73 67 2c  char **pzErrMsg,
18430 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
18440 20 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73              cons
18450 74 20 73 71 6c 69 74 65 33 5f 61 70 69 5f 72 6f  t sqlite3_api_ro
18460 75 74 69 6e 65 73 20 2a 70 41 70 69 29 7b 0a 20  utines *pApi){. 
18470 20 53 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f   SQLITE_EXTENSIO
18480 4e 5f 49 4e 49 54 32 28 70 41 70 69 29 0a 20 20  N_INIT2(pApi).  
18490 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74  return sqlite3Ft
184a0 73 31 49 6e 69 74 28 64 62 29 3b 0a 7d 0a 23 65  s1Init(db);.}.#e
184b0 6e 64 69 66 0a 0a 23 65 6e 64 69 66 20 2f 2a 20  ndif..#endif /* 
184c0 21 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f  !defined(SQLITE_
184d0 43 4f 52 45 29 20 7c 7c 20 64 65 66 69 6e 65 64  CORE) || defined
184e0 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46  (SQLITE_ENABLE_F
184f0 54 53 31 29 20 2a 2f 0a                          TS1) */.