/ Hex Artifact Content
Login

Artifact 35bfa67d9cd659b799b8498895fe60b1e8bd3500:


0000: 2f 2a 0a 2a 2a 20 32 30 30 36 20 4f 63 74 20 31  /*.** 2006 Oct 1
0010: 30 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  0.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 69 73 20 61 6e 20 53 51 4c 69 74 65 20 6d 6f   is an SQLite mo
0190: 64 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 69 6e  dule implementin
01a0: 67 20 66 75 6c 6c 2d 74 65 78 74 20 73 65 61 72  g full-text sear
01b0: 63 68 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68  ch..*/../*.** Th
01c0: 65 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20 66  e code in this f
01d0: 69 6c 65 20 69 73 20 6f 6e 6c 79 20 63 6f 6d 70  ile is only comp
01e0: 69 6c 65 64 20 69 66 3a 0a 2a 2a 0a 2a 2a 20 20  iled if:.**.**  
01f0: 20 20 20 2a 20 54 68 65 20 46 54 53 33 20 6d 6f     * The FTS3 mo
0200: 64 75 6c 65 20 69 73 20 62 65 69 6e 67 20 62 75  dule is being bu
0210: 69 6c 74 20 61 73 20 61 6e 20 65 78 74 65 6e 73  ilt as an extens
0220: 69 6f 6e 0a 2a 2a 20 20 20 20 20 20 20 28 69 6e  ion.**       (in
0230: 20 77 68 69 63 68 20 63 61 73 65 20 53 51 4c 49   which case SQLI
0240: 54 45 5f 43 4f 52 45 20 69 73 20 6e 6f 74 20 64  TE_CORE is not d
0250: 65 66 69 6e 65 64 29 2c 20 6f 72 0a 2a 2a 0a 2a  efined), or.**.*
0260: 2a 20 20 20 20 20 2a 20 54 68 65 20 46 54 53 33  *     * The FTS3
0270: 20 6d 6f 64 75 6c 65 20 69 73 20 62 65 69 6e 67   module is being
0280: 20 62 75 69 6c 74 20 69 6e 74 6f 20 74 68 65 20   built into the 
0290: 63 6f 72 65 20 6f 66 0a 2a 2a 20 20 20 20 20 20  core of.**      
02a0: 20 53 51 4c 69 74 65 20 28 69 6e 20 77 68 69 63   SQLite (in whic
02b0: 68 20 63 61 73 65 20 53 51 4c 49 54 45 5f 45 4e  h case SQLITE_EN
02c0: 41 42 4c 45 5f 46 54 53 33 20 69 73 20 64 65 66  ABLE_FTS3 is def
02d0: 69 6e 65 64 29 2e 0a 2a 2f 0a 0a 2f 2a 20 54 4f  ined)..*/../* TO
02e0: 44 4f 28 73 68 65 73 73 29 20 43 6f 6e 73 69 64  DO(shess) Consid
02f0: 65 72 20 65 78 70 6f 72 74 69 6e 67 20 74 68 69  er exporting thi
0300: 73 20 63 6f 6d 6d 65 6e 74 20 74 6f 20 61 6e 20  s comment to an 
0310: 48 54 4d 4c 20 66 69 6c 65 20 6f 72 20 74 68 65  HTML file or the
0320: 0a 2a 2a 20 77 69 6b 69 2e 0a 2a 2f 0a 2f 2a 20  .** wiki..*/./* 
0330: 54 68 65 20 66 75 6c 6c 2d 74 65 78 74 20 69 6e  The full-text in
0340: 64 65 78 20 69 73 20 73 74 6f 72 65 64 20 69 6e  dex is stored in
0350: 20 61 20 73 65 72 69 65 73 20 6f 66 20 62 2b 74   a series of b+t
0360: 72 65 65 20 28 2d 6c 69 6b 65 29 0a 2a 2a 20 73  ree (-like).** s
0370: 74 72 75 63 74 75 72 65 73 20 63 61 6c 6c 65 64  tructures called
0380: 20 73 65 67 6d 65 6e 74 73 20 77 68 69 63 68 20   segments which 
0390: 6d 61 70 20 74 65 72 6d 73 20 74 6f 20 64 6f 63  map terms to doc
03a0: 6c 69 73 74 73 2e 20 20 54 68 65 0a 2a 2a 20 73  lists.  The.** s
03b0: 74 72 75 63 74 75 72 65 73 20 61 72 65 20 6c 69  tructures are li
03c0: 6b 65 20 62 2b 74 72 65 65 73 20 69 6e 20 6c 61  ke b+trees in la
03d0: 79 6f 75 74 2c 20 62 75 74 20 61 72 65 20 63 6f  yout, but are co
03e0: 6e 73 74 72 75 63 74 65 64 20 66 72 6f 6d 20 74  nstructed from t
03f0: 68 65 0a 2a 2a 20 62 6f 74 74 6f 6d 20 75 70 20  he.** bottom up 
0400: 69 6e 20 6f 70 74 69 6d 61 6c 20 66 61 73 68 69  in optimal fashi
0410: 6f 6e 20 61 6e 64 20 61 72 65 20 6e 6f 74 20 75  on and are not u
0420: 70 64 61 74 61 62 6c 65 2e 20 20 53 69 6e 63 65  pdatable.  Since
0430: 20 74 72 65 65 73 0a 2a 2a 20 61 72 65 20 62 75   trees.** are bu
0440: 69 6c 74 20 66 72 6f 6d 20 74 68 65 20 62 6f 74  ilt from the bot
0450: 74 6f 6d 20 75 70 2c 20 74 68 69 6e 67 73 20 77  tom up, things w
0460: 69 6c 6c 20 62 65 20 64 65 73 63 72 69 62 65 64  ill be described
0470: 20 66 72 6f 6d 20 74 68 65 0a 2a 2a 20 62 6f 74   from the.** bot
0480: 74 6f 6d 20 75 70 2e 0a 2a 2a 0a 2a 2a 0a 2a 2a  tom up..**.**.**
0490: 2a 2a 20 56 61 72 69 6e 74 73 20 2a 2a 2a 2a 0a  ** Varints ****.
04a0: 2a 2a 20 54 68 65 20 62 61 73 69 63 20 75 6e 69  ** The basic uni
04b0: 74 20 6f 66 20 65 6e 63 6f 64 69 6e 67 20 69 73  t of encoding is
04c0: 20 61 20 76 61 72 69 61 62 6c 65 2d 6c 65 6e 67   a variable-leng
04d0: 74 68 20 69 6e 74 65 67 65 72 20 63 61 6c 6c 65  th integer calle
04e0: 64 20 61 0a 2a 2a 20 76 61 72 69 6e 74 2e 20 20  d a.** varint.  
04f0: 57 65 20 65 6e 63 6f 64 65 20 76 61 72 69 61 62  We encode variab
0500: 6c 65 2d 6c 65 6e 67 74 68 20 69 6e 74 65 67 65  le-length intege
0510: 72 73 20 69 6e 20 6c 69 74 74 6c 65 2d 65 6e 64  rs in little-end
0520: 69 61 6e 20 6f 72 64 65 72 0a 2a 2a 20 75 73 69  ian order.** usi
0530: 6e 67 20 73 65 76 65 6e 20 62 69 74 73 20 2a 20  ng seven bits * 
0540: 70 65 72 20 62 79 74 65 20 61 73 20 66 6f 6c 6c  per byte as foll
0550: 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 4b 45 59 3a 0a  ows:.**.** KEY:.
0560: 2a 2a 20 20 20 20 20 20 20 20 20 41 20 3d 20 30  **         A = 0
0570: 78 78 78 78 78 78 78 20 20 20 20 37 20 62 69 74  xxxxxxx    7 bit
0580: 73 20 6f 66 20 64 61 74 61 20 61 6e 64 20 6f 6e  s of data and on
0590: 65 20 66 6c 61 67 20 62 69 74 0a 2a 2a 20 20 20  e flag bit.**   
05a0: 20 20 20 20 20 20 42 20 3d 20 31 78 78 78 78 78        B = 1xxxxx
05b0: 78 78 20 20 20 20 37 20 62 69 74 73 20 6f 66 20  xx    7 bits of 
05c0: 64 61 74 61 20 61 6e 64 20 6f 6e 65 20 66 6c 61  data and one fla
05d0: 67 20 62 69 74 0a 2a 2a 0a 2a 2a 20 20 37 20 62  g bit.**.**  7 b
05e0: 69 74 73 20 2d 20 41 0a 2a 2a 20 31 34 20 62 69  its - A.** 14 bi
05f0: 74 73 20 2d 20 42 41 0a 2a 2a 20 32 31 20 62 69  ts - BA.** 21 bi
0600: 74 73 20 2d 20 42 42 41 0a 2a 2a 20 61 6e 64 20  ts - BBA.** and 
0610: 73 6f 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  so on..**.** Thi
0620: 73 20 69 73 20 69 64 65 6e 74 69 63 61 6c 20 74  s is identical t
0630: 6f 20 68 6f 77 20 73 71 6c 69 74 65 20 65 6e 63  o how sqlite enc
0640: 6f 64 65 73 20 76 61 72 69 6e 74 73 20 28 73 65  odes varints (se
0650: 65 20 75 74 69 6c 2e 63 29 2e 0a 2a 2a 0a 2a 2a  e util.c)..**.**
0660: 0a 2a 2a 2a 2a 20 44 6f 63 75 6d 65 6e 74 20 6c  .**** Document l
0670: 69 73 74 73 20 2a 2a 2a 2a 0a 2a 2a 20 41 20 64  ists ****.** A d
0680: 6f 63 6c 69 73 74 20 28 64 6f 63 75 6d 65 6e 74  oclist (document
0690: 20 6c 69 73 74 29 20 68 6f 6c 64 73 20 61 20 64   list) holds a d
06a0: 6f 63 69 64 2d 73 6f 72 74 65 64 20 6c 69 73 74  ocid-sorted list
06b0: 20 6f 66 20 68 69 74 73 20 66 6f 72 20 61 0a 2a   of hits for a.*
06c0: 2a 20 67 69 76 65 6e 20 74 65 72 6d 2e 20 20 44  * given term.  D
06d0: 6f 63 6c 69 73 74 73 20 68 6f 6c 64 20 64 6f 63  oclists hold doc
06e0: 69 64 73 2c 20 61 6e 64 20 63 61 6e 20 6f 70 74  ids, and can opt
06f0: 69 6f 6e 61 6c 6c 79 20 61 73 73 6f 63 69 61 74  ionally associat
0700: 65 0a 2a 2a 20 74 6f 6b 65 6e 20 70 6f 73 69 74  e.** token posit
0710: 69 6f 6e 73 20 61 6e 64 20 6f 66 66 73 65 74 73  ions and offsets
0720: 20 77 69 74 68 20 64 6f 63 69 64 73 2e 0a 2a 2a   with docids..**
0730: 0a 2a 2a 20 41 20 44 4c 5f 50 4f 53 49 54 49 4f  .** A DL_POSITIO
0740: 4e 53 5f 4f 46 46 53 45 54 53 20 64 6f 63 6c 69  NS_OFFSETS docli
0750: 73 74 20 69 73 20 73 74 6f 72 65 64 20 6c 69 6b  st is stored lik
0760: 65 20 74 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 61 72  e this:.**.** ar
0770: 72 61 79 20 7b 0a 2a 2a 20 20 20 76 61 72 69 6e  ray {.**   varin
0780: 74 20 64 6f 63 69 64 3b 0a 2a 2a 20 20 20 61 72  t docid;.**   ar
0790: 72 61 79 20 7b 20 20 20 20 20 20 20 20 20 20 20  ray {           
07a0: 20 20 20 20 20 28 70 6f 73 69 74 69 6f 6e 20 6c       (position l
07b0: 69 73 74 20 66 6f 72 20 63 6f 6c 75 6d 6e 20 30  ist for column 0
07c0: 29 0a 2a 2a 20 20 20 20 20 76 61 72 69 6e 74 20  ).**     varint 
07d0: 70 6f 73 69 74 69 6f 6e 3b 20 20 20 20 20 28 64  position;     (d
07e0: 65 6c 74 61 20 66 72 6f 6d 20 70 72 65 76 69 6f  elta from previo
07f0: 75 73 20 70 6f 73 69 74 69 6f 6e 20 70 6c 75 73  us position plus
0800: 20 50 4f 53 5f 42 41 53 45 29 0a 2a 2a 20 20 20   POS_BASE).**   
0810: 20 20 76 61 72 69 6e 74 20 73 74 61 72 74 4f 66    varint startOf
0820: 66 73 65 74 3b 20 20 28 64 65 6c 74 61 20 66 72  fset;  (delta fr
0830: 6f 6d 20 70 72 65 76 69 6f 75 73 20 73 74 61 72  om previous star
0840: 74 4f 66 66 73 65 74 29 0a 2a 2a 20 20 20 20 20  tOffset).**     
0850: 76 61 72 69 6e 74 20 65 6e 64 4f 66 66 73 65 74  varint endOffset
0860: 3b 20 20 20 20 28 64 65 6c 74 61 20 66 72 6f 6d  ;    (delta from
0870: 20 73 74 61 72 74 4f 66 66 73 65 74 29 0a 2a 2a   startOffset).**
0880: 20 20 20 7d 0a 2a 2a 20 20 20 61 72 72 61 79 20     }.**   array 
0890: 7b 0a 2a 2a 20 20 20 20 20 76 61 72 69 6e 74 20  {.**     varint 
08a0: 50 4f 53 5f 43 4f 4c 55 4d 4e 3b 20 20 20 28 6d  POS_COLUMN;   (m
08b0: 61 72 6b 73 20 73 74 61 72 74 20 6f 66 20 70 6f  arks start of po
08c0: 73 69 74 69 6f 6e 20 6c 69 73 74 20 66 6f 72 20  sition list for 
08d0: 6e 65 77 20 63 6f 6c 75 6d 6e 29 0a 2a 2a 20 20  new column).**  
08e0: 20 20 20 76 61 72 69 6e 74 20 63 6f 6c 75 6d 6e     varint column
08f0: 3b 20 20 20 20 20 20 20 28 69 6e 64 65 78 20 6f  ;       (index o
0900: 66 20 6e 65 77 20 63 6f 6c 75 6d 6e 29 0a 2a 2a  f new column).**
0910: 20 20 20 20 20 61 72 72 61 79 20 7b 0a 2a 2a 20       array {.** 
0920: 20 20 20 20 20 20 76 61 72 69 6e 74 20 70 6f 73        varint pos
0930: 69 74 69 6f 6e 3b 20 20 20 28 64 65 6c 74 61 20  ition;   (delta 
0940: 66 72 6f 6d 20 70 72 65 76 69 6f 75 73 20 70 6f  from previous po
0950: 73 69 74 69 6f 6e 20 70 6c 75 73 20 50 4f 53 5f  sition plus POS_
0960: 42 41 53 45 29 0a 2a 2a 20 20 20 20 20 20 20 76  BASE).**       v
0970: 61 72 69 6e 74 20 73 74 61 72 74 4f 66 66 73 65  arint startOffse
0980: 74 3b 28 64 65 6c 74 61 20 66 72 6f 6d 20 70 72  t;(delta from pr
0990: 65 76 69 6f 75 73 20 73 74 61 72 74 4f 66 66 73  evious startOffs
09a0: 65 74 29 0a 2a 2a 20 20 20 20 20 20 20 76 61 72  et).**       var
09b0: 69 6e 74 20 65 6e 64 4f 66 66 73 65 74 3b 20 20  int endOffset;  
09c0: 28 64 65 6c 74 61 20 66 72 6f 6d 20 73 74 61 72  (delta from star
09d0: 74 4f 66 66 73 65 74 29 0a 2a 2a 20 20 20 20 20  tOffset).**     
09e0: 7d 0a 2a 2a 20 20 20 7d 0a 2a 2a 20 20 20 76 61  }.**   }.**   va
09f0: 72 69 6e 74 20 50 4f 53 5f 45 4e 44 3b 20 20 20  rint POS_END;   
0a00: 20 20 20 20 20 28 6d 61 72 6b 73 20 65 6e 64 20       (marks end 
0a10: 6f 66 20 70 6f 73 69 74 69 6f 6e 73 20 66 6f 72  of positions for
0a20: 20 74 68 69 73 20 64 6f 63 75 6d 65 6e 74 2e 0a   this document..
0a30: 2a 2a 20 7d 0a 2a 2a 0a 2a 2a 20 48 65 72 65 2c  ** }.**.** Here,
0a40: 20 61 72 72 61 79 20 7b 20 58 20 7d 20 6d 65 61   array { X } mea
0a50: 6e 73 20 7a 65 72 6f 20 6f 72 20 6d 6f 72 65 20  ns zero or more 
0a60: 6f 63 63 75 72 72 65 6e 63 65 73 20 6f 66 20 58  occurrences of X
0a70: 2c 20 61 64 6a 61 63 65 6e 74 20 69 6e 0a 2a 2a  , adjacent in.**
0a80: 20 6d 65 6d 6f 72 79 2e 20 20 41 20 22 70 6f 73   memory.  A "pos
0a90: 69 74 69 6f 6e 22 20 69 73 20 61 6e 20 69 6e 64  ition" is an ind
0aa0: 65 78 20 6f 66 20 61 20 74 6f 6b 65 6e 20 69 6e  ex of a token in
0ab0: 20 74 68 65 20 74 6f 6b 65 6e 20 73 74 72 65 61   the token strea
0ac0: 6d 0a 2a 2a 20 67 65 6e 65 72 61 74 65 64 20 62  m.** generated b
0ad0: 79 20 74 68 65 20 74 6f 6b 65 6e 69 7a 65 72 2c  y the tokenizer,
0ae0: 20 77 68 69 6c 65 20 61 6e 20 22 6f 66 66 73 65   while an "offse
0af0: 74 22 20 69 73 20 61 20 62 79 74 65 20 6f 66 66  t" is a byte off
0b00: 73 65 74 2c 0a 2a 2a 20 62 6f 74 68 20 62 61 73  set,.** both bas
0b10: 65 64 20 61 74 20 30 2e 20 20 4e 6f 74 65 20 74  ed at 0.  Note t
0b20: 68 61 74 20 50 4f 53 5f 45 4e 44 20 61 6e 64 20  hat POS_END and 
0b30: 50 4f 53 5f 43 4f 4c 55 4d 4e 20 6f 63 63 75 72  POS_COLUMN occur
0b40: 20 69 6e 20 74 68 65 0a 2a 2a 20 73 61 6d 65 20   in the.** same 
0b50: 6c 6f 67 69 63 61 6c 20 70 6c 61 63 65 20 61 73  logical place as
0b60: 20 74 68 65 20 70 6f 73 69 74 69 6f 6e 20 65 6c   the position el
0b70: 65 6d 65 6e 74 2c 20 61 6e 64 20 61 63 74 20 61  ement, and act a
0b80: 73 20 73 65 6e 74 69 6e 61 6c 73 0a 2a 2a 20 65  s sentinals.** e
0b90: 6e 64 69 6e 67 20 61 20 70 6f 73 69 74 69 6f 6e  nding a position
0ba0: 20 6c 69 73 74 20 61 72 72 61 79 2e 0a 2a 2a 0a   list array..**.
0bb0: 2a 2a 20 41 20 44 4c 5f 50 4f 53 49 54 49 4f 4e  ** A DL_POSITION
0bc0: 53 20 64 6f 63 6c 69 73 74 20 6f 6d 69 74 73 20  S doclist omits 
0bd0: 74 68 65 20 73 74 61 72 74 4f 66 66 73 65 74 20  the startOffset 
0be0: 61 6e 64 20 65 6e 64 4f 66 66 73 65 74 0a 2a 2a  and endOffset.**
0bf0: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 20 20 41   information.  A
0c00: 20 44 4c 5f 44 4f 43 49 44 53 20 64 6f 63 6c 69   DL_DOCIDS docli
0c10: 73 74 20 6f 6d 69 74 73 20 62 6f 74 68 20 74 68  st omits both th
0c20: 65 20 70 6f 73 69 74 69 6f 6e 20 61 6e 64 0a 2a  e position and.*
0c30: 2a 20 6f 66 66 73 65 74 20 69 6e 66 6f 72 6d 61  * offset informa
0c40: 74 69 6f 6e 2c 20 62 65 63 6f 6d 69 6e 67 20 61  tion, becoming a
0c50: 6e 20 61 72 72 61 79 20 6f 66 20 76 61 72 69 6e  n array of varin
0c60: 74 2d 65 6e 63 6f 64 65 64 20 64 6f 63 69 64 73  t-encoded docids
0c70: 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 2d 64 69 73 6b 20  ..**.** On-disk 
0c80: 64 61 74 61 20 69 73 20 73 74 6f 72 65 64 20 61  data is stored a
0c90: 73 20 74 79 70 65 20 44 4c 5f 44 45 46 41 55 4c  s type DL_DEFAUL
0ca0: 54 2c 20 73 6f 20 77 65 20 64 6f 6e 27 74 20 73  T, so we don't s
0cb0: 65 72 69 61 6c 69 7a 65 0a 2a 2a 20 74 68 65 20  erialize.** the 
0cc0: 74 79 70 65 2e 20 20 44 75 65 20 74 6f 20 68 6f  type.  Due to ho
0cd0: 77 20 64 65 6c 65 74 69 6f 6e 20 69 73 20 69 6d  w deletion is im
0ce0: 70 6c 65 6d 65 6e 74 65 64 20 69 6e 20 74 68 65  plemented in the
0cf0: 20 73 65 67 6d 65 6e 74 61 74 69 6f 6e 0a 2a 2a   segmentation.**
0d00: 20 73 79 73 74 65 6d 2c 20 6f 6e 2d 64 69 73 6b   system, on-disk
0d10: 20 64 6f 63 6c 69 73 74 73 20 4d 55 53 54 20 73   doclists MUST s
0d20: 74 6f 72 65 20 61 74 20 6c 65 61 73 74 20 70 6f  tore at least po
0d30: 73 69 74 69 6f 6e 73 2e 0a 2a 2a 0a 2a 2a 0a 2a  sitions..**.**.*
0d40: 2a 2a 2a 20 53 65 67 6d 65 6e 74 20 6c 65 61 66  *** Segment leaf
0d50: 20 6e 6f 64 65 73 20 2a 2a 2a 2a 0a 2a 2a 20 53   nodes ****.** S
0d60: 65 67 6d 65 6e 74 20 6c 65 61 66 20 6e 6f 64 65  egment leaf node
0d70: 73 20 73 74 6f 72 65 20 74 65 72 6d 73 20 61 6e  s store terms an
0d80: 64 20 64 6f 63 6c 69 73 74 73 2c 20 6f 72 64 65  d doclists, orde
0d90: 72 65 64 20 62 79 20 74 65 72 6d 2e 20 20 4c 65  red by term.  Le
0da0: 61 66 0a 2a 2a 20 6e 6f 64 65 73 20 61 72 65 20  af.** nodes are 
0db0: 77 72 69 74 74 65 6e 20 75 73 69 6e 67 20 4c 65  written using Le
0dc0: 61 66 57 72 69 74 65 72 2c 20 61 6e 64 20 72 65  afWriter, and re
0dd0: 61 64 20 75 73 69 6e 67 20 4c 65 61 66 52 65 61  ad using LeafRea
0de0: 64 65 72 20 28 74 6f 0a 2a 2a 20 69 74 65 72 61  der (to.** itera
0df0: 74 65 20 74 68 72 6f 75 67 68 20 61 20 73 69 6e  te through a sin
0e00: 67 6c 65 20 6c 65 61 66 20 6e 6f 64 65 27 73 20  gle leaf node's 
0e10: 64 61 74 61 29 20 61 6e 64 20 4c 65 61 76 65 73  data) and Leaves
0e20: 52 65 61 64 65 72 20 28 74 6f 0a 2a 2a 20 69 74  Reader (to.** it
0e30: 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61 20  erate through a 
0e40: 73 65 67 6d 65 6e 74 27 73 20 65 6e 74 69 72 65  segment's entire
0e50: 20 6c 65 61 66 20 6c 61 79 65 72 29 2e 20 20 4c   leaf layer).  L
0e60: 65 61 66 20 6e 6f 64 65 73 20 68 61 76 65 0a 2a  eaf nodes have.*
0e70: 2a 20 74 68 65 20 66 6f 72 6d 61 74 3a 0a 2a 2a  * the format:.**
0e80: 0a 2a 2a 20 76 61 72 69 6e 74 20 69 48 65 69 67  .** varint iHeig
0e90: 68 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ht;             
0ea0: 28 68 65 69 67 68 74 20 66 72 6f 6d 20 6c 65 61  (height from lea
0eb0: 66 20 6c 65 76 65 6c 2c 20 61 6c 77 61 79 73 20  f level, always 
0ec0: 30 29 0a 2a 2a 20 76 61 72 69 6e 74 20 6e 54 65  0).** varint nTe
0ed0: 72 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rm;             
0ee0: 20 20 28 6c 65 6e 67 74 68 20 6f 66 20 66 69 72    (length of fir
0ef0: 73 74 20 74 65 72 6d 29 0a 2a 2a 20 63 68 61 72  st term).** char
0f00: 20 70 54 65 72 6d 5b 6e 54 65 72 6d 5d 3b 20 20   pTerm[nTerm];  
0f10: 20 20 20 20 20 20 20 20 28 63 6f 6e 74 65 6e 74          (content
0f20: 20 6f 66 20 66 69 72 73 74 20 74 65 72 6d 29 0a   of first term).
0f30: 2a 2a 20 76 61 72 69 6e 74 20 6e 44 6f 63 6c 69  ** varint nDocli
0f40: 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 28  st;            (
0f50: 6c 65 6e 67 74 68 20 6f 66 20 74 65 72 6d 27 73  length of term's
0f60: 20 61 73 73 6f 63 69 61 74 65 64 20 64 6f 63 6c   associated docl
0f70: 69 73 74 29 0a 2a 2a 20 63 68 61 72 20 70 44 6f  ist).** char pDo
0f80: 63 6c 69 73 74 5b 6e 44 6f 63 6c 69 73 74 5d 3b  clist[nDoclist];
0f90: 20 20 20 20 28 63 6f 6e 74 65 6e 74 20 6f 66 20      (content of 
0fa0: 64 6f 63 6c 69 73 74 29 0a 2a 2a 20 61 72 72 61  doclist).** arra
0fb0: 79 20 7b 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  y {.**          
0fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0fd0: 20 20 20 28 66 75 72 74 68 65 72 20 74 65 72 6d     (further term
0fe0: 73 20 61 72 65 20 64 65 6c 74 61 2d 65 6e 63 6f  s are delta-enco
0ff0: 64 65 64 29 0a 2a 2a 20 20 20 76 61 72 69 6e 74  ded).**   varint
1000: 20 6e 50 72 65 66 69 78 3b 20 20 20 20 20 20 20   nPrefix;       
1010: 20 20 20 20 28 6c 65 6e 67 74 68 20 6f 66 20 70      (length of p
1020: 72 65 66 69 78 20 73 68 61 72 65 64 20 77 69 74  refix shared wit
1030: 68 20 70 72 65 76 69 6f 75 73 20 74 65 72 6d 29  h previous term)
1040: 0a 2a 2a 20 20 20 76 61 72 69 6e 74 20 6e 53 75  .**   varint nSu
1050: 66 66 69 78 3b 20 20 20 20 20 20 20 20 20 20 20  ffix;           
1060: 28 6c 65 6e 67 74 68 20 6f 66 20 75 6e 73 68 61  (length of unsha
1070: 72 65 64 20 73 75 66 66 69 78 29 0a 2a 2a 20 20  red suffix).**  
1080: 20 63 68 61 72 20 70 54 65 72 6d 53 75 66 66 69   char pTermSuffi
1090: 78 5b 6e 53 75 66 66 69 78 5d 3b 28 75 6e 73 68  x[nSuffix];(unsh
10a0: 61 72 65 64 20 73 75 66 66 69 78 20 6f 66 20 6e  ared suffix of n
10b0: 65 78 74 20 74 65 72 6d 29 0a 2a 2a 20 20 20 76  ext term).**   v
10c0: 61 72 69 6e 74 20 6e 44 6f 63 6c 69 73 74 3b 20  arint nDoclist; 
10d0: 20 20 20 20 20 20 20 20 20 28 6c 65 6e 67 74 68           (length
10e0: 20 6f 66 20 74 65 72 6d 27 73 20 61 73 73 6f 63   of term's assoc
10f0: 69 61 74 65 64 20 64 6f 63 6c 69 73 74 29 0a 2a  iated doclist).*
1100: 2a 20 20 20 63 68 61 72 20 70 44 6f 63 6c 69 73  *   char pDoclis
1110: 74 5b 6e 44 6f 63 6c 69 73 74 5d 3b 20 20 28 63  t[nDoclist];  (c
1120: 6f 6e 74 65 6e 74 20 6f 66 20 64 6f 63 6c 69 73  ontent of doclis
1130: 74 29 0a 2a 2a 20 7d 0a 2a 2a 0a 2a 2a 20 48 65  t).** }.**.** He
1140: 72 65 2c 20 61 72 72 61 79 20 7b 20 58 20 7d 20  re, array { X } 
1150: 6d 65 61 6e 73 20 7a 65 72 6f 20 6f 72 20 6d 6f  means zero or mo
1160: 72 65 20 6f 63 63 75 72 72 65 6e 63 65 73 20 6f  re occurrences o
1170: 66 20 58 2c 20 61 64 6a 61 63 65 6e 74 20 69 6e  f X, adjacent in
1180: 0a 2a 2a 20 6d 65 6d 6f 72 79 2e 0a 2a 2a 0a 2a  .** memory..**.*
1190: 2a 20 4c 65 61 66 20 6e 6f 64 65 73 20 61 72 65  * Leaf nodes are
11a0: 20 62 72 6f 6b 65 6e 20 69 6e 74 6f 20 62 6c 6f   broken into blo
11b0: 63 6b 73 20 77 68 69 63 68 20 61 72 65 20 73 74  cks which are st
11c0: 6f 72 65 64 20 63 6f 6e 74 69 67 75 6f 75 73 6c  ored contiguousl
11d0: 79 20 69 6e 0a 2a 2a 20 74 68 65 20 25 5f 73 65  y in.** the %_se
11e0: 67 6d 65 6e 74 73 20 74 61 62 6c 65 20 69 6e 20  gments table in 
11f0: 73 6f 72 74 65 64 20 6f 72 64 65 72 2e 20 20 54  sorted order.  T
1200: 68 69 73 20 6d 65 61 6e 73 20 74 68 61 74 20 77  his means that w
1210: 68 65 6e 20 74 68 65 20 65 6e 64 0a 2a 2a 20 6f  hen the end.** o
1220: 66 20 61 20 6e 6f 64 65 20 69 73 20 72 65 61 63  f a node is reac
1230: 68 65 64 2c 20 74 68 65 20 6e 65 78 74 20 74 65  hed, the next te
1240: 72 6d 20 69 73 20 69 6e 20 74 68 65 20 6e 6f 64  rm is in the nod
1250: 65 20 77 69 74 68 20 74 68 65 20 6e 65 78 74 0a  e with the next.
1260: 2a 2a 20 67 72 65 61 74 65 72 20 6e 6f 64 65 20  ** greater node 
1270: 69 64 2e 0a 2a 2a 0a 2a 2a 20 4e 65 77 20 64 61  id..**.** New da
1280: 74 61 20 69 73 20 73 70 69 6c 6c 65 64 20 74 6f  ta is spilled to
1290: 20 61 20 6e 65 77 20 6c 65 61 66 20 6e 6f 64 65   a new leaf node
12a0: 20 77 68 65 6e 20 74 68 65 20 63 75 72 72 65 6e   when the curren
12b0: 74 20 6e 6f 64 65 0a 2a 2a 20 65 78 63 65 65 64  t node.** exceed
12c0: 73 20 4c 45 41 46 5f 4d 41 58 20 62 79 74 65 73  s LEAF_MAX bytes
12d0: 20 28 64 65 66 61 75 6c 74 20 32 30 34 38 29 2e   (default 2048).
12e0: 20 20 4e 65 77 20 64 61 74 61 20 77 68 69 63 68    New data which
12f0: 20 69 74 73 65 6c 66 20 69 73 0a 2a 2a 20 6c 61   itself is.** la
1300: 72 67 65 72 20 74 68 61 6e 20 53 54 41 4e 44 41  rger than STANDA
1310: 4c 4f 4e 45 5f 4d 49 4e 20 28 64 65 66 61 75 6c  LONE_MIN (defaul
1320: 74 20 31 30 32 34 29 20 69 73 20 70 6c 61 63 65  t 1024) is place
1330: 64 20 69 6e 20 61 20 73 74 61 6e 64 61 6c 6f 6e  d in a standalon
1340: 65 0a 2a 2a 20 6e 6f 64 65 20 28 61 20 6c 65 61  e.** node (a lea
1350: 66 20 6e 6f 64 65 20 77 69 74 68 20 61 20 73 69  f node with a si
1360: 6e 67 6c 65 20 74 65 72 6d 20 61 6e 64 20 64 6f  ngle term and do
1370: 63 6c 69 73 74 29 2e 20 20 54 68 65 20 67 6f 61  clist).  The goa
1380: 6c 20 6f 66 0a 2a 2a 20 74 68 65 73 65 20 73 65  l of.** these se
1390: 74 74 69 6e 67 73 20 69 73 20 74 6f 20 70 61 63  ttings is to pac
13a0: 6b 20 74 6f 67 65 74 68 65 72 20 67 72 6f 75 70  k together group
13b0: 73 20 6f 66 20 73 6d 61 6c 6c 20 64 6f 63 6c 69  s of small docli
13c0: 73 74 73 20 77 68 69 6c 65 0a 2a 2a 20 6d 61 6b  sts while.** mak
13d0: 69 6e 67 20 69 74 20 65 66 66 69 63 69 65 6e 74  ing it efficient
13e0: 20 74 6f 20 64 69 72 65 63 74 6c 79 20 61 63 63   to directly acc
13f0: 65 73 73 20 6c 61 72 67 65 20 64 6f 63 6c 69 73  ess large doclis
1400: 74 73 2e 20 20 54 68 65 0a 2a 2a 20 61 73 73 75  ts.  The.** assu
1410: 6d 70 74 69 6f 6e 20 69 73 20 74 68 61 74 20 6c  mption is that l
1420: 61 72 67 65 20 64 6f 63 6c 69 73 74 73 20 72 65  arge doclists re
1430: 70 72 65 73 65 6e 74 20 74 65 72 6d 73 20 77 68  present terms wh
1440: 69 63 68 20 61 72 65 20 6d 6f 72 65 0a 2a 2a 20  ich are more.** 
1450: 6c 69 6b 65 6c 79 20 74 6f 20 62 65 20 71 75 65  likely to be que
1460: 72 79 20 74 61 72 67 65 74 73 2e 0a 2a 2a 0a 2a  ry targets..**.*
1470: 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 49 74  * TODO(shess) It
1480: 20 6d 61 79 20 62 65 20 75 73 65 66 75 6c 20 66   may be useful f
1490: 6f 72 20 62 6c 6f 63 6b 69 6e 67 20 64 65 63 69  or blocking deci
14a0: 73 69 6f 6e 73 20 74 6f 20 62 65 20 6d 6f 72 65  sions to be more
14b0: 0a 2a 2a 20 64 79 6e 61 6d 69 63 2e 20 20 46 6f  .** dynamic.  Fo
14c0: 72 20 69 6e 73 74 61 6e 63 65 2c 20 69 74 20 6d  r instance, it m
14d0: 61 79 20 6d 61 6b 65 20 6d 6f 72 65 20 73 65 6e  ay make more sen
14e0: 73 65 20 74 6f 20 68 61 76 65 20 61 20 32 2e 35  se to have a 2.5
14f0: 6b 20 6c 65 61 66 0a 2a 2a 20 6e 6f 64 65 20 72  k leaf.** node r
1500: 61 74 68 65 72 20 74 68 61 6e 20 73 70 6c 69 74  ather than split
1510: 74 69 6e 67 20 69 6e 74 6f 20 32 6b 20 61 6e 64  ting into 2k and
1520: 20 2e 35 6b 20 6e 6f 64 65 73 2e 20 20 4d 79 20   .5k nodes.  My 
1530: 69 6e 74 75 69 74 69 6f 6e 20 69 73 0a 2a 2a 20  intuition is.** 
1540: 74 68 61 74 20 74 68 69 73 20 6d 69 67 68 74 20  that this might 
1550: 65 78 74 65 6e 64 20 74 68 72 6f 75 67 68 20 32  extend through 2
1560: 78 20 6f 72 20 34 78 20 74 68 65 20 70 61 67 65  x or 4x the page
1570: 73 69 7a 65 2e 0a 2a 2a 0a 2a 2a 0a 2a 2a 2a 2a  size..**.**.****
1580: 20 53 65 67 6d 65 6e 74 20 69 6e 74 65 72 69 6f   Segment interio
1590: 72 20 6e 6f 64 65 73 20 2a 2a 2a 2a 0a 2a 2a 20  r nodes ****.** 
15a0: 53 65 67 6d 65 6e 74 20 69 6e 74 65 72 69 6f 72  Segment interior
15b0: 20 6e 6f 64 65 73 20 73 74 6f 72 65 20 62 6c 6f   nodes store blo
15c0: 63 6b 69 64 73 20 66 6f 72 20 73 75 62 74 72 65  ckids for subtre
15d0: 65 20 6e 6f 64 65 73 20 61 6e 64 20 74 65 72 6d  e nodes and term
15e0: 73 0a 2a 2a 20 74 6f 20 64 65 73 63 72 69 62 65  s.** to describe
15f0: 20 77 68 61 74 20 64 61 74 61 20 69 73 20 73 74   what data is st
1600: 6f 72 65 64 20 62 79 20 74 68 65 20 65 61 63 68  ored by the each
1610: 20 73 75 62 74 72 65 65 2e 20 20 49 6e 74 65 72   subtree.  Inter
1620: 69 6f 72 0a 2a 2a 20 6e 6f 64 65 73 20 61 72 65  ior.** nodes are
1630: 20 77 72 69 74 74 65 6e 20 75 73 69 6e 67 20 49   written using I
1640: 6e 74 65 72 69 6f 72 57 72 69 74 65 72 2c 20 61  nteriorWriter, a
1650: 6e 64 20 72 65 61 64 20 75 73 69 6e 67 0a 2a 2a  nd read using.**
1660: 20 49 6e 74 65 72 69 6f 72 52 65 61 64 65 72 2e   InteriorReader.
1670: 20 20 49 6e 74 65 72 69 6f 72 57 72 69 74 65 72    InteriorWriter
1680: 73 20 61 72 65 20 63 72 65 61 74 65 64 20 61 73  s are created as
1690: 20 6e 65 65 64 65 64 20 77 68 65 6e 0a 2a 2a 20   needed when.** 
16a0: 53 65 67 6d 65 6e 74 57 72 69 74 65 72 20 63 72  SegmentWriter cr
16b0: 65 61 74 65 73 20 6e 65 77 20 6c 65 61 66 20 6e  eates new leaf n
16c0: 6f 64 65 73 2c 20 6f 72 20 77 68 65 6e 20 61 6e  odes, or when an
16d0: 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65 0a 2a   interior node.*
16e0: 2a 20 69 74 73 65 6c 66 20 67 72 6f 77 73 20 74  * itself grows t
16f0: 6f 6f 20 62 69 67 20 61 6e 64 20 6d 75 73 74 20  oo big and must 
1700: 62 65 20 73 70 6c 69 74 2e 20 20 54 68 65 20 66  be split.  The f
1710: 6f 72 6d 61 74 20 6f 66 20 69 6e 74 65 72 69 6f  ormat of interio
1720: 72 0a 2a 2a 20 6e 6f 64 65 73 3a 0a 2a 2a 0a 2a  r.** nodes:.**.*
1730: 2a 20 76 61 72 69 6e 74 20 69 48 65 69 67 68 74  * varint iHeight
1740: 3b 20 20 20 20 20 20 20 20 20 20 20 28 68 65 69  ;           (hei
1750: 67 68 74 20 66 72 6f 6d 20 6c 65 61 66 20 6c 65  ght from leaf le
1760: 76 65 6c 2c 20 61 6c 77 61 79 73 20 3e 30 29 0a  vel, always >0).
1770: 2a 2a 20 76 61 72 69 6e 74 20 69 42 6c 6f 63 6b  ** varint iBlock
1780: 69 64 3b 20 20 20 20 20 20 20 20 20 20 28 62 6c  id;          (bl
1790: 6f 63 6b 20 69 64 20 6f 66 20 6e 6f 64 65 27 73  ock id of node's
17a0: 20 6c 65 66 74 6d 6f 73 74 20 73 75 62 74 72 65   leftmost subtre
17b0: 65 29 0a 2a 2a 20 6f 70 74 69 6f 6e 61 6c 20 7b  e).** optional {
17c0: 0a 2a 2a 20 20 20 76 61 72 69 6e 74 20 6e 54 65  .**   varint nTe
17d0: 72 6d 3b 20 20 20 20 20 20 20 20 20 20 20 28 6c  rm;           (l
17e0: 65 6e 67 74 68 20 6f 66 20 66 69 72 73 74 20 74  ength of first t
17f0: 65 72 6d 29 0a 2a 2a 20 20 20 63 68 61 72 20 70  erm).**   char p
1800: 54 65 72 6d 5b 6e 54 65 72 6d 5d 3b 20 20 20 20  Term[nTerm];    
1810: 20 20 28 63 6f 6e 74 65 6e 74 20 6f 66 20 66 69    (content of fi
1820: 72 73 74 20 74 65 72 6d 29 0a 2a 2a 20 20 20 61  rst term).**   a
1830: 72 72 61 79 20 7b 0a 2a 2a 20 20 20 20 20 20 20  rray {.**       
1840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1850: 20 20 20 20 20 20 20 20 20 28 66 75 72 74 68 65           (furthe
1860: 72 20 74 65 72 6d 73 20 61 72 65 20 64 65 6c 74  r terms are delt
1870: 61 2d 65 6e 63 6f 64 65 64 29 0a 2a 2a 20 20 20  a-encoded).**   
1880: 20 20 76 61 72 69 6e 74 20 6e 50 72 65 66 69 78    varint nPrefix
1890: 3b 20 20 20 20 20 20 20 20 20 20 20 20 28 6c 65  ;            (le
18a0: 6e 67 74 68 20 6f 66 20 73 68 61 72 65 64 20 70  ngth of shared p
18b0: 72 65 66 69 78 20 77 69 74 68 20 70 72 65 76 69  refix with previ
18c0: 6f 75 73 20 74 65 72 6d 29 0a 2a 2a 20 20 20 20  ous term).**    
18d0: 20 76 61 72 69 6e 74 20 6e 53 75 66 66 69 78 3b   varint nSuffix;
18e0: 20 20 20 20 20 20 20 20 20 20 20 20 28 6c 65 6e              (len
18f0: 67 74 68 20 6f 66 20 75 6e 73 68 61 72 65 64 20  gth of unshared 
1900: 73 75 66 66 69 78 29 0a 2a 2a 20 20 20 20 20 63  suffix).**     c
1910: 68 61 72 20 70 54 65 72 6d 53 75 66 66 69 78 5b  har pTermSuffix[
1920: 6e 53 75 66 66 69 78 5d 3b 20 28 75 6e 73 68 61  nSuffix]; (unsha
1930: 72 65 64 20 73 75 66 66 69 78 20 6f 66 20 6e 65  red suffix of ne
1940: 78 74 20 74 65 72 6d 29 0a 2a 2a 20 20 20 7d 0a  xt term).**   }.
1950: 2a 2a 20 7d 0a 2a 2a 0a 2a 2a 20 48 65 72 65 2c  ** }.**.** Here,
1960: 20 6f 70 74 69 6f 6e 61 6c 20 7b 20 58 20 7d 20   optional { X } 
1970: 6d 65 61 6e 73 20 61 6e 20 6f 70 74 69 6f 6e 61  means an optiona
1980: 6c 20 65 6c 65 6d 65 6e 74 2c 20 77 68 69 6c 65  l element, while
1990: 20 61 72 72 61 79 20 7b 20 58 20 7d 0a 2a 2a 20   array { X }.** 
19a0: 6d 65 61 6e 73 20 7a 65 72 6f 20 6f 72 20 6d 6f  means zero or mo
19b0: 72 65 20 6f 63 63 75 72 72 65 6e 63 65 73 20 6f  re occurrences o
19c0: 66 20 58 2c 20 61 64 6a 61 63 65 6e 74 20 69 6e  f X, adjacent in
19d0: 20 6d 65 6d 6f 72 79 2e 0a 2a 2a 0a 2a 2a 20 41   memory..**.** A
19e0: 6e 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65 20  n interior node 
19f0: 65 6e 63 6f 64 65 73 20 6e 20 74 65 72 6d 73 20  encodes n terms 
1a00: 73 65 70 61 72 61 74 69 6e 67 20 6e 2b 31 20 73  separating n+1 s
1a10: 75 62 74 72 65 65 73 2e 20 20 54 68 65 0a 2a 2a  ubtrees.  The.**
1a20: 20 73 75 62 74 72 65 65 20 62 6c 6f 63 6b 73 20   subtree blocks 
1a30: 61 72 65 20 63 6f 6e 74 69 67 75 6f 75 73 2c 20  are contiguous, 
1a40: 73 6f 20 6f 6e 6c 79 20 74 68 65 20 66 69 72 73  so only the firs
1a50: 74 20 73 75 62 74 72 65 65 27 73 20 62 6c 6f 63  t subtree's bloc
1a60: 6b 69 64 0a 2a 2a 20 69 73 20 65 6e 63 6f 64 65  kid.** is encode
1a70: 64 2e 20 20 54 68 65 20 73 75 62 74 72 65 65 20  d.  The subtree 
1a80: 61 74 20 69 42 6c 6f 63 6b 69 64 20 77 69 6c 6c  at iBlockid will
1a90: 20 63 6f 6e 74 61 69 6e 20 61 6c 6c 20 74 65 72   contain all ter
1aa0: 6d 73 20 6c 65 73 73 0a 2a 2a 20 74 68 61 6e 20  ms less.** than 
1ab0: 74 68 65 20 66 69 72 73 74 20 74 65 72 6d 20 65  the first term e
1ac0: 6e 63 6f 64 65 64 20 28 6f 72 20 61 6c 6c 20 74  ncoded (or all t
1ad0: 65 72 6d 73 20 69 66 20 6e 6f 20 74 65 72 6d 20  erms if no term 
1ae0: 69 73 20 65 6e 63 6f 64 65 64 29 2e 0a 2a 2a 20  is encoded)..** 
1af0: 4f 74 68 65 72 77 69 73 65 2c 20 66 6f 72 20 74  Otherwise, for t
1b00: 65 72 6d 73 20 67 72 65 61 74 65 72 20 74 68 61  erms greater tha
1b10: 6e 20 6f 72 20 65 71 75 61 6c 20 74 6f 20 70 54  n or equal to pT
1b20: 65 72 6d 5b 69 5d 20 62 75 74 20 6c 65 73 73 0a  erm[i] but less.
1b30: 2a 2a 20 74 68 61 6e 20 70 54 65 72 6d 5b 69 2b  ** than pTerm[i+
1b40: 31 5d 2c 20 74 68 65 20 73 75 62 74 72 65 65 20  1], the subtree 
1b50: 66 6f 72 20 74 68 61 74 20 74 65 72 6d 20 77 69  for that term wi
1b60: 6c 6c 20 62 65 20 72 6f 6f 74 65 64 20 61 74 0a  ll be rooted at.
1b70: 2a 2a 20 69 42 6c 6f 63 6b 69 64 2b 69 2e 20 20  ** iBlockid+i.  
1b80: 49 6e 74 65 72 69 6f 72 20 6e 6f 64 65 73 20 6f  Interior nodes o
1b90: 6e 6c 79 20 73 74 6f 72 65 20 65 6e 6f 75 67 68  nly store enough
1ba0: 20 74 65 72 6d 20 64 61 74 61 20 74 6f 0a 2a 2a   term data to.**
1bb0: 20 64 69 73 74 69 6e 67 75 69 73 68 20 61 64 6a   distinguish adj
1bc0: 61 63 65 6e 74 20 63 68 69 6c 64 72 65 6e 20 28  acent children (
1bd0: 69 66 20 74 68 65 20 72 69 67 68 74 6d 6f 73 74  if the rightmost
1be0: 20 74 65 72 6d 20 6f 66 20 74 68 65 20 6c 65 66   term of the lef
1bf0: 74 0a 2a 2a 20 63 68 69 6c 64 20 69 73 20 22 73  t.** child is "s
1c00: 6f 6d 65 74 68 69 6e 67 22 2c 20 61 6e 64 20 74  omething", and t
1c10: 68 65 20 6c 65 66 74 6d 6f 73 74 20 74 65 72 6d  he leftmost term
1c20: 20 6f 66 20 74 68 65 20 72 69 67 68 74 20 63 68   of the right ch
1c30: 69 6c 64 20 69 73 0a 2a 2a 20 22 77 69 63 6b 65  ild is.** "wicke
1c40: 64 22 2c 20 6f 6e 6c 79 20 22 77 22 20 69 73 20  d", only "w" is 
1c50: 73 74 6f 72 65 64 29 2e 0a 2a 2a 0a 2a 2a 20 4e  stored)..**.** N
1c60: 65 77 20 64 61 74 61 20 69 73 20 73 70 69 6c 6c  ew data is spill
1c70: 65 64 20 74 6f 20 61 20 6e 65 77 20 69 6e 74 65  ed to a new inte
1c80: 72 69 6f 72 20 6e 6f 64 65 20 61 74 20 74 68 65  rior node at the
1c90: 20 73 61 6d 65 20 68 65 69 67 68 74 20 77 68 65   same height whe
1ca0: 6e 0a 2a 2a 20 74 68 65 20 63 75 72 72 65 6e 74  n.** the current
1cb0: 20 6e 6f 64 65 20 65 78 63 65 65 64 73 20 49 4e   node exceeds IN
1cc0: 54 45 52 49 4f 52 5f 4d 41 58 20 62 79 74 65 73  TERIOR_MAX bytes
1cd0: 20 28 64 65 66 61 75 6c 74 20 32 30 34 38 29 2e   (default 2048).
1ce0: 0a 2a 2a 20 49 4e 54 45 52 49 4f 52 5f 4d 49 4e  .** INTERIOR_MIN
1cf0: 5f 54 45 52 4d 53 20 28 64 65 66 61 75 6c 74 20  _TERMS (default 
1d00: 37 29 20 6b 65 65 70 73 20 6c 61 72 67 65 20 74  7) keeps large t
1d10: 65 72 6d 73 20 66 72 6f 6d 20 6d 6f 6e 6f 70 6f  erms from monopo
1d20: 6c 69 7a 69 6e 67 0a 2a 2a 20 69 6e 74 65 72 69  lizing.** interi
1d30: 6f 72 20 6e 6f 64 65 73 20 61 6e 64 20 6d 61 6b  or nodes and mak
1d40: 69 6e 67 20 74 68 65 20 74 72 65 65 20 74 6f 6f  ing the tree too
1d50: 20 73 6b 69 6e 6e 79 2e 20 20 54 68 65 20 69 6e   skinny.  The in
1d60: 74 65 72 69 6f 72 20 6e 6f 64 65 73 0a 2a 2a 20  terior nodes.** 
1d70: 61 74 20 61 20 67 69 76 65 6e 20 68 65 69 67 68  at a given heigh
1d80: 74 20 61 72 65 20 6e 61 74 75 72 61 6c 6c 79 20  t are naturally 
1d90: 74 72 61 63 6b 65 64 20 62 79 20 69 6e 74 65 72  tracked by inter
1da0: 69 6f 72 20 6e 6f 64 65 73 20 61 74 0a 2a 2a 20  ior nodes at.** 
1db0: 68 65 69 67 68 74 2b 31 2c 20 61 6e 64 20 73 6f  height+1, and so
1dc0: 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 0a 2a 2a 2a 2a 20   on..**.**.**** 
1dd0: 53 65 67 6d 65 6e 74 20 64 69 72 65 63 74 6f 72  Segment director
1de0: 79 20 2a 2a 2a 2a 0a 2a 2a 20 54 68 65 20 73 65  y ****.** The se
1df0: 67 6d 65 6e 74 20 64 69 72 65 63 74 6f 72 79 20  gment directory 
1e00: 69 6e 20 74 61 62 6c 65 20 25 5f 73 65 67 64 69  in table %_segdi
1e10: 72 20 73 74 6f 72 65 73 20 6d 65 74 61 2d 69 6e  r stores meta-in
1e20: 66 6f 72 6d 61 74 69 6f 6e 20 66 6f 72 0a 2a 2a  formation for.**
1e30: 20 6d 65 72 67 69 6e 67 20 61 6e 64 20 64 65 6c   merging and del
1e40: 65 74 69 6e 67 20 73 65 67 6d 65 6e 74 73 2c 20  eting segments, 
1e50: 61 6e 64 20 61 6c 73 6f 20 74 68 65 20 72 6f 6f  and also the roo
1e60: 74 20 6e 6f 64 65 20 6f 66 20 74 68 65 0a 2a 2a  t node of the.**
1e70: 20 73 65 67 6d 65 6e 74 27 73 20 74 72 65 65 2e   segment's tree.
1e80: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 72 6f 6f 74 20  .**.** The root 
1e90: 6e 6f 64 65 20 69 73 20 74 68 65 20 74 6f 70 20  node is the top 
1ea0: 6e 6f 64 65 20 6f 66 20 74 68 65 20 73 65 67 6d  node of the segm
1eb0: 65 6e 74 27 73 20 74 72 65 65 20 61 66 74 65 72  ent's tree after
1ec0: 20 65 6e 63 6f 64 69 6e 67 0a 2a 2a 20 74 68 65   encoding.** the
1ed0: 20 65 6e 74 69 72 65 20 73 65 67 6d 65 6e 74 2c   entire segment,
1ee0: 20 72 65 73 74 72 69 63 74 65 64 20 74 6f 20 52   restricted to R
1ef0: 4f 4f 54 5f 4d 41 58 20 62 79 74 65 73 20 28 64  OOT_MAX bytes (d
1f00: 65 66 61 75 6c 74 20 31 30 32 34 29 2e 0a 2a 2a  efault 1024)..**
1f10: 20 54 68 69 73 20 63 6f 75 6c 64 20 62 65 20 65   This could be e
1f20: 69 74 68 65 72 20 61 20 6c 65 61 66 20 6e 6f 64  ither a leaf nod
1f30: 65 20 6f 72 20 61 6e 20 69 6e 74 65 72 69 6f 72  e or an interior
1f40: 20 6e 6f 64 65 2e 20 20 49 66 20 74 68 65 20 74   node.  If the t
1f50: 6f 70 0a 2a 2a 20 6e 6f 64 65 20 72 65 71 75 69  op.** node requi
1f60: 72 65 73 20 6d 6f 72 65 20 74 68 61 6e 20 52 4f  res more than RO
1f70: 4f 54 5f 4d 41 58 20 62 79 74 65 73 2c 20 69 74  OT_MAX bytes, it
1f80: 20 69 73 20 66 6c 75 73 68 65 64 20 74 6f 20 25   is flushed to %
1f90: 5f 73 65 67 6d 65 6e 74 73 0a 2a 2a 20 61 6e 64  _segments.** and
1fa0: 20 61 20 6e 65 77 20 72 6f 6f 74 20 69 6e 74 65   a new root inte
1fb0: 72 69 6f 72 20 6e 6f 64 65 20 69 73 20 67 65 6e  rior node is gen
1fc0: 65 72 61 74 65 64 20 28 77 68 69 63 68 20 73 68  erated (which sh
1fd0: 6f 75 6c 64 20 61 6c 77 61 79 73 20 66 69 74 0a  ould always fit.
1fe0: 2a 2a 20 77 69 74 68 69 6e 20 52 4f 4f 54 5f 4d  ** within ROOT_M
1ff0: 41 58 20 62 65 63 61 75 73 65 20 69 74 20 6f 6e  AX because it on
2000: 6c 79 20 6e 65 65 64 73 20 73 70 61 63 65 20 66  ly needs space f
2010: 6f 72 20 32 20 76 61 72 69 6e 74 73 2c 20 74 68  or 2 varints, th
2020: 65 0a 2a 2a 20 68 65 69 67 68 74 20 61 6e 64 20  e.** height and 
2030: 74 68 65 20 62 6c 6f 63 6b 69 64 20 6f 66 20 74  the blockid of t
2040: 68 65 20 70 72 65 76 69 6f 75 73 20 72 6f 6f 74  he previous root
2050: 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6d 65 74  )..**.** The met
2060: 61 2d 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e  a-information in
2070: 20 74 68 65 20 73 65 67 6d 65 6e 74 20 64 69 72   the segment dir
2080: 65 63 74 6f 72 79 20 69 73 3a 0a 2a 2a 20 20 20  ectory is:.**   
2090: 6c 65 76 65 6c 20 20 20 20 20 20 20 20 20 20 20  level           
20a0: 20 20 20 20 2d 20 73 65 67 6d 65 6e 74 20 6c 65      - segment le
20b0: 76 65 6c 20 28 73 65 65 20 62 65 6c 6f 77 29 0a  vel (see below).
20c0: 2a 2a 20 20 20 69 64 78 20 20 20 20 20 20 20 20  **   idx        
20d0: 20 20 20 20 20 20 20 20 20 2d 20 69 6e 64 65 78           - index
20e0: 20 77 69 74 68 69 6e 20 6c 65 76 65 6c 0a 2a 2a   within level.**
20f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2100: 20 20 20 20 20 20 20 2d 20 28 6c 65 76 65 6c 2c         - (level,
2110: 69 64 78 20 75 6e 69 71 75 65 6c 79 20 69 64 65  idx uniquely ide
2120: 6e 74 69 66 79 20 61 20 73 65 67 6d 65 6e 74 29  ntify a segment)
2130: 0a 2a 2a 20 20 20 73 74 61 72 74 5f 62 6c 6f 63  .**   start_bloc
2140: 6b 20 20 20 20 20 20 20 20 20 2d 20 66 69 72 73  k         - firs
2150: 74 20 6c 65 61 66 20 6e 6f 64 65 0a 2a 2a 20 20  t leaf node.**  
2160: 20 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63   leaves_end_bloc
2170: 6b 20 20 20 20 2d 20 6c 61 73 74 20 6c 65 61 66  k    - last leaf
2180: 20 6e 6f 64 65 0a 2a 2a 20 20 20 65 6e 64 5f 62   node.**   end_b
2190: 6c 6f 63 6b 20 20 20 20 20 20 20 20 20 20 20 2d  lock           -
21a0: 20 6c 61 73 74 20 62 6c 6f 63 6b 20 28 69 6e 63   last block (inc
21b0: 6c 75 64 69 6e 67 20 69 6e 74 65 72 69 6f 72 20  luding interior 
21c0: 6e 6f 64 65 73 29 0a 2a 2a 20 20 20 72 6f 6f 74  nodes).**   root
21d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21e0: 2d 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 72 6f  - contents of ro
21f0: 6f 74 20 6e 6f 64 65 0a 2a 2a 0a 2a 2a 20 49 66  ot node.**.** If
2200: 20 74 68 65 20 72 6f 6f 74 20 6e 6f 64 65 20 69   the root node i
2210: 73 20 61 20 6c 65 61 66 20 6e 6f 64 65 2c 20 74  s a leaf node, t
2220: 68 65 6e 20 73 74 61 72 74 5f 62 6c 6f 63 6b 2c  hen start_block,
2230: 0a 2a 2a 20 6c 65 61 76 65 73 5f 65 6e 64 5f 62  .** leaves_end_b
2240: 6c 6f 63 6b 2c 20 61 6e 64 20 65 6e 64 5f 62 6c  lock, and end_bl
2250: 6f 63 6b 20 61 72 65 20 61 6c 6c 20 30 2e 0a 2a  ock are all 0..*
2260: 2a 0a 2a 2a 0a 2a 2a 2a 2a 20 53 65 67 6d 65 6e  *.**.**** Segmen
2270: 74 20 6d 65 72 67 69 6e 67 20 2a 2a 2a 2a 0a 2a  t merging ****.*
2280: 2a 20 54 6f 20 61 6d 6f 72 74 69 7a 65 20 75 70  * To amortize up
2290: 64 61 74 65 20 63 6f 73 74 73 2c 20 73 65 67 6d  date costs, segm
22a0: 65 6e 74 73 20 61 72 65 20 67 72 6f 75 70 65 64  ents are grouped
22b0: 20 69 6e 74 6f 20 6c 65 76 65 6c 73 20 61 6e 64   into levels and
22c0: 0a 2a 2a 20 6d 65 72 67 65 64 20 69 6e 20 62 61  .** merged in ba
22d0: 74 63 68 65 73 2e 20 20 45 61 63 68 20 69 6e 63  tches.  Each inc
22e0: 72 65 61 73 65 20 69 6e 20 6c 65 76 65 6c 20 72  rease in level r
22f0: 65 70 72 65 73 65 6e 74 73 20 65 78 70 6f 6e 65  epresents expone
2300: 6e 74 69 61 6c 6c 79 0a 2a 2a 20 6d 6f 72 65 20  ntially.** more 
2310: 64 6f 63 75 6d 65 6e 74 73 2e 0a 2a 2a 0a 2a 2a  documents..**.**
2320: 20 4e 65 77 20 64 6f 63 75 6d 65 6e 74 73 20 28   New documents (
2330: 61 63 74 75 61 6c 6c 79 2c 20 64 6f 63 75 6d 65  actually, docume
2340: 6e 74 20 75 70 64 61 74 65 73 29 20 61 72 65 20  nt updates) are 
2350: 74 6f 6b 65 6e 69 7a 65 64 20 61 6e 64 0a 2a 2a  tokenized and.**
2360: 20 77 72 69 74 74 65 6e 20 69 6e 64 69 76 69 64   written individ
2370: 75 61 6c 6c 79 20 28 75 73 69 6e 67 20 4c 65 61  ually (using Lea
2380: 66 57 72 69 74 65 72 29 20 74 6f 20 61 20 6c 65  fWriter) to a le
2390: 76 65 6c 20 30 20 73 65 67 6d 65 6e 74 2c 20 77  vel 0 segment, w
23a0: 69 74 68 0a 2a 2a 20 69 6e 63 72 65 6d 65 6e 74  ith.** increment
23b0: 69 6e 67 20 69 64 78 2e 20 20 57 68 65 6e 20 69  ing idx.  When i
23c0: 64 78 20 72 65 61 63 68 65 73 20 4d 45 52 47 45  dx reaches MERGE
23d0: 5f 43 4f 55 4e 54 20 28 64 65 66 61 75 6c 74 20  _COUNT (default 
23e0: 31 36 29 2c 20 61 6c 6c 0a 2a 2a 20 6c 65 76 65  16), all.** leve
23f0: 6c 20 30 20 73 65 67 6d 65 6e 74 73 20 61 72 65  l 0 segments are
2400: 20 6d 65 72 67 65 64 20 69 6e 74 6f 20 61 20 73   merged into a s
2410: 69 6e 67 6c 65 20 6c 65 76 65 6c 20 31 20 73 65  ingle level 1 se
2420: 67 6d 65 6e 74 2e 20 20 4c 65 76 65 6c 20 31 0a  gment.  Level 1.
2430: 2a 2a 20 69 73 20 70 6f 70 75 6c 61 74 65 64 20  ** is populated 
2440: 6c 69 6b 65 20 6c 65 76 65 6c 20 30 2c 20 61 6e  like level 0, an
2450: 64 20 65 76 65 6e 74 75 61 6c 6c 79 20 4d 45 52  d eventually MER
2460: 47 45 5f 43 4f 55 4e 54 20 6c 65 76 65 6c 20 31  GE_COUNT level 1
2470: 0a 2a 2a 20 73 65 67 6d 65 6e 74 73 20 61 72 65  .** segments are
2480: 20 6d 65 72 67 65 64 20 74 6f 20 61 20 73 69 6e   merged to a sin
2490: 67 6c 65 20 6c 65 76 65 6c 20 32 20 73 65 67 6d  gle level 2 segm
24a0: 65 6e 74 20 28 72 65 70 72 65 73 65 6e 74 69 6e  ent (representin
24b0: 67 0a 2a 2a 20 4d 45 52 47 45 5f 43 4f 55 4e 54  g.** MERGE_COUNT
24c0: 5e 32 20 75 70 64 61 74 65 73 29 2c 20 61 6e 64  ^2 updates), and
24d0: 20 73 6f 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41 20   so on..**.** A 
24e0: 73 65 67 6d 65 6e 74 20 6d 65 72 67 65 20 74 72  segment merge tr
24f0: 61 76 65 72 73 65 73 20 61 6c 6c 20 73 65 67 6d  averses all segm
2500: 65 6e 74 73 20 61 74 20 61 20 67 69 76 65 6e 20  ents at a given 
2510: 6c 65 76 65 6c 20 69 6e 0a 2a 2a 20 70 61 72 61  level in.** para
2520: 6c 6c 65 6c 2c 20 70 65 72 66 6f 72 6d 69 6e 67  llel, performing
2530: 20 61 20 73 74 72 61 69 67 68 74 66 6f 72 77 61   a straightforwa
2540: 72 64 20 73 6f 72 74 65 64 20 6d 65 72 67 65 2e  rd sorted merge.
2550: 20 20 53 69 6e 63 65 20 73 65 67 6d 65 6e 74 0a    Since segment.
2560: 2a 2a 20 6c 65 61 66 20 6e 6f 64 65 73 20 61 72  ** leaf nodes ar
2570: 65 20 77 72 69 74 74 65 6e 20 69 6e 20 74 6f 20  e written in to 
2580: 74 68 65 20 25 5f 73 65 67 6d 65 6e 74 73 20 74  the %_segments t
2590: 61 62 6c 65 20 69 6e 20 6f 72 64 65 72 2c 20 74  able in order, t
25a0: 68 69 73 0a 2a 2a 20 6d 65 72 67 65 20 74 72 61  his.** merge tra
25b0: 76 65 72 73 65 73 20 74 68 65 20 75 6e 64 65 72  verses the under
25c0: 6c 79 69 6e 67 20 73 71 6c 69 74 65 20 64 69 73  lying sqlite dis
25d0: 6b 20 73 74 72 75 63 74 75 72 65 73 20 65 66 66  k structures eff
25e0: 69 63 69 65 6e 74 6c 79 2e 0a 2a 2a 20 41 66 74  iciently..** Aft
25f0: 65 72 20 74 68 65 20 6d 65 72 67 65 2c 20 61 6c  er the merge, al
2600: 6c 20 73 65 67 6d 65 6e 74 20 62 6c 6f 63 6b 73  l segment blocks
2610: 20 66 72 6f 6d 20 74 68 65 20 6d 65 72 67 65 64   from the merged
2620: 20 6c 65 76 65 6c 20 61 72 65 0a 2a 2a 20 64 65   level are.** de
2630: 6c 65 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 4d 45 52  leted..**.** MER
2640: 47 45 5f 43 4f 55 4e 54 20 63 6f 6e 74 72 6f 6c  GE_COUNT control
2650: 73 20 68 6f 77 20 6f 66 74 65 6e 20 77 65 20 6d  s how often we m
2660: 65 72 67 65 20 73 65 67 6d 65 6e 74 73 2e 20 20  erge segments.  
2670: 31 36 20 73 65 65 6d 73 20 74 6f 20 62 65 0a 2a  16 seems to be.*
2680: 2a 20 73 6f 6d 65 77 68 61 74 20 6f 66 20 61 20  * somewhat of a 
2690: 73 77 65 65 74 20 73 70 6f 74 20 66 6f 72 20 69  sweet spot for i
26a0: 6e 73 65 72 74 69 6f 6e 20 70 65 72 66 6f 72 6d  nsertion perform
26b0: 61 6e 63 65 2e 20 20 33 32 20 61 6e 64 20 36 34  ance.  32 and 64
26c0: 20 73 68 6f 77 0a 2a 2a 20 76 65 72 79 20 73 69   show.** very si
26d0: 6d 69 6c 61 72 20 70 65 72 66 6f 72 6d 61 6e 63  milar performanc
26e0: 65 20 6e 75 6d 62 65 72 73 20 74 6f 20 31 36 20  e numbers to 16 
26f0: 6f 6e 20 69 6e 73 65 72 74 69 6f 6e 2c 20 74 68  on insertion, th
2700: 6f 75 67 68 20 74 68 65 79 27 72 65 0a 2a 2a 20  ough they're.** 
2710: 61 20 74 69 6e 79 20 62 69 74 20 73 6c 6f 77 65  a tiny bit slowe
2720: 72 20 28 70 65 72 68 61 70 73 20 64 75 65 20 74  r (perhaps due t
2730: 6f 20 6d 6f 72 65 20 6f 76 65 72 68 65 61 64 20  o more overhead 
2740: 69 6e 20 6d 65 72 67 65 2d 74 69 6d 65 0a 2a 2a  in merge-time.**
2750: 20 73 6f 72 74 69 6e 67 29 2e 20 20 38 20 69 73   sorting).  8 is
2760: 20 61 62 6f 75 74 20 32 30 25 20 73 6c 6f 77 65   about 20% slowe
2770: 72 20 74 68 61 6e 20 31 36 2c 20 34 20 61 62 6f  r than 16, 4 abo
2780: 75 74 20 35 30 25 20 73 6c 6f 77 65 72 20 74 68  ut 50% slower th
2790: 61 6e 0a 2a 2a 20 31 36 2c 20 32 20 61 62 6f 75  an.** 16, 2 abou
27a0: 74 20 36 36 25 20 73 6c 6f 77 65 72 20 74 68 61  t 66% slower tha
27b0: 6e 20 31 36 2e 0a 2a 2a 0a 2a 2a 20 41 74 20 71  n 16..**.** At q
27c0: 75 65 72 79 20 74 69 6d 65 2c 20 68 69 67 68 20  uery time, high 
27d0: 4d 45 52 47 45 5f 43 4f 55 4e 54 20 69 6e 63 72  MERGE_COUNT incr
27e0: 65 61 73 65 73 20 74 68 65 20 6e 75 6d 62 65 72  eases the number
27f0: 20 6f 66 20 73 65 67 6d 65 6e 74 73 0a 2a 2a 20   of segments.** 
2800: 77 68 69 63 68 20 6e 65 65 64 20 74 6f 20 62 65  which need to be
2810: 20 73 63 61 6e 6e 65 64 20 61 6e 64 20 6d 65 72   scanned and mer
2820: 67 65 64 2e 20 20 46 6f 72 20 69 6e 73 74 61 6e  ged.  For instan
2830: 63 65 2c 20 77 69 74 68 20 31 30 30 6b 20 64 6f  ce, with 100k do
2840: 63 73 0a 2a 2a 20 69 6e 73 65 72 74 65 64 3a 0a  cs.** inserted:.
2850: 2a 2a 0a 2a 2a 20 20 20 20 4d 45 52 47 45 5f 43  **.**    MERGE_C
2860: 4f 55 4e 54 20 20 20 73 65 67 6d 65 6e 74 73 0a  OUNT   segments.
2870: 2a 2a 20 20 20 20 20 20 20 31 36 20 20 20 20 20  **       16     
2880: 20 20 20 20 20 20 32 35 0a 2a 2a 20 20 20 20 20        25.**     
2890: 20 20 20 38 20 20 20 20 20 20 20 20 20 20 20 31     8           1
28a0: 32 0a 2a 2a 20 20 20 20 20 20 20 20 34 20 20 20  2.**        4   
28b0: 20 20 20 20 20 20 20 20 31 30 0a 2a 2a 20 20 20          10.**   
28c0: 20 20 20 20 20 32 20 20 20 20 20 20 20 20 20 20       2          
28d0: 20 20 36 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 61    6.**.** This a
28e0: 70 70 65 61 72 73 20 74 6f 20 68 61 76 65 20 6f  ppears to have o
28f0: 6e 6c 79 20 61 20 6d 6f 64 65 72 61 74 65 20 69  nly a moderate i
2900: 6d 70 61 63 74 20 6f 6e 20 71 75 65 72 69 65 73  mpact on queries
2910: 20 66 6f 72 20 76 65 72 79 0a 2a 2a 20 66 72 65   for very.** fre
2920: 71 75 65 6e 74 20 74 65 72 6d 73 20 28 77 68 69  quent terms (whi
2930: 63 68 20 61 72 65 20 73 6f 6d 65 77 68 61 74 20  ch are somewhat 
2940: 64 6f 6d 69 6e 61 74 65 64 20 62 79 20 73 65 67  dominated by seg
2950: 6d 65 6e 74 20 6d 65 72 67 65 0a 2a 2a 20 63 6f  ment merge.** co
2960: 73 74 73 29 2c 20 61 6e 64 20 69 6e 66 72 65 71  sts), and infreq
2970: 75 65 6e 74 20 61 6e 64 20 6e 6f 6e 2d 65 78 69  uent and non-exi
2980: 73 74 65 6e 74 20 74 65 72 6d 73 20 73 74 69 6c  stent terms stil
2990: 6c 20 73 65 65 6d 20 74 6f 20 62 65 20 66 61 73  l seem to be fas
29a0: 74 0a 2a 2a 20 65 76 65 6e 20 77 69 74 68 20 6d  t.** even with m
29b0: 61 6e 79 20 73 65 67 6d 65 6e 74 73 2e 0a 2a 2a  any segments..**
29c0: 0a 2a 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20  .** TODO(shess) 
29d0: 54 68 61 74 20 73 61 69 64 2c 20 69 74 20 77 6f  That said, it wo
29e0: 75 6c 64 20 62 65 20 6e 69 63 65 20 74 6f 20 68  uld be nice to h
29f0: 61 76 65 20 61 20 62 65 74 74 65 72 20 71 75 65  ave a better que
2a00: 72 79 2d 73 69 64 65 0a 2a 2a 20 61 72 67 75 6d  ry-side.** argum
2a10: 65 6e 74 20 66 6f 72 20 4d 45 52 47 45 5f 43 4f  ent for MERGE_CO
2a20: 55 4e 54 20 6f 66 20 31 36 2e 20 20 41 6c 73 6f  UNT of 16.  Also
2a30: 2c 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c 65  , it is possible
2a40: 2f 6c 69 6b 65 6c 79 20 74 68 61 74 0a 2a 2a 20  /likely that.** 
2a50: 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 73 20 74 6f  optimizations to
2a60: 20 74 68 69 6e 67 73 20 6c 69 6b 65 20 64 6f 63   things like doc
2a70: 6c 69 73 74 20 6d 65 72 67 69 6e 67 20 77 69 6c  list merging wil
2a80: 6c 20 73 77 69 6e 67 20 74 68 65 20 73 77 65 65  l swing the swee
2a90: 74 0a 2a 2a 20 73 70 6f 74 20 61 72 6f 75 6e 64  t.** spot around
2aa0: 2e 0a 2a 2a 0a 2a 2a 0a 2a 2a 0a 2a 2a 2a 2a 20  ..**.**.**.**** 
2ab0: 48 61 6e 64 6c 69 6e 67 20 6f 66 20 64 65 6c 65  Handling of dele
2ac0: 74 69 6f 6e 73 20 61 6e 64 20 75 70 64 61 74 65  tions and update
2ad0: 73 20 2a 2a 2a 2a 0a 2a 2a 20 53 69 6e 63 65 20  s ****.** Since 
2ae0: 77 65 27 72 65 20 75 73 69 6e 67 20 61 20 73 65  we're using a se
2af0: 67 6d 65 6e 74 65 64 20 73 74 72 75 63 74 75 72  gmented structur
2b00: 65 2c 20 77 69 74 68 20 6e 6f 20 64 6f 63 69 64  e, with no docid
2b10: 2d 6f 72 69 65 6e 74 65 64 0a 2a 2a 20 69 6e 64  -oriented.** ind
2b20: 65 78 20 69 6e 74 6f 20 74 68 65 20 74 65 72 6d  ex into the term
2b30: 20 69 6e 64 65 78 2c 20 77 65 20 63 6c 65 61 72   index, we clear
2b40: 6c 79 20 63 61 6e 6e 6f 74 20 73 69 6d 70 6c 79  ly cannot simply
2b50: 20 75 70 64 61 74 65 20 74 68 65 20 74 65 72 6d   update the term
2b60: 0a 2a 2a 20 69 6e 64 65 78 20 77 68 65 6e 20 61  .** index when a
2b70: 20 64 6f 63 75 6d 65 6e 74 20 69 73 20 64 65 6c   document is del
2b80: 65 74 65 64 20 6f 72 20 75 70 64 61 74 65 64 2e  eted or updated.
2b90: 20 20 46 6f 72 20 64 65 6c 65 74 69 6f 6e 73 2c    For deletions,
2ba0: 20 77 65 0a 2a 2a 20 77 72 69 74 65 20 61 6e 20   we.** write an 
2bb0: 65 6d 70 74 79 20 64 6f 63 6c 69 73 74 20 28 76  empty doclist (v
2bc0: 61 72 69 6e 74 28 64 6f 63 69 64 29 20 76 61 72  arint(docid) var
2bd0: 69 6e 74 28 50 4f 53 5f 45 4e 44 29 29 2c 20 66  int(POS_END)), f
2be0: 6f 72 20 75 70 64 61 74 65 73 0a 2a 2a 20 77 65  or updates.** we
2bf0: 20 73 69 6d 70 6c 79 20 77 72 69 74 65 20 74 68   simply write th
2c00: 65 20 6e 65 77 20 64 6f 63 6c 69 73 74 2e 20 20  e new doclist.  
2c10: 53 65 67 6d 65 6e 74 20 6d 65 72 67 65 73 20 6f  Segment merges o
2c20: 76 65 72 77 72 69 74 65 20 6f 6c 64 65 72 0a 2a  verwrite older.*
2c30: 2a 20 64 61 74 61 20 66 6f 72 20 61 20 70 61 72  * data for a par
2c40: 74 69 63 75 6c 61 72 20 64 6f 63 69 64 20 77 69  ticular docid wi
2c50: 74 68 20 6e 65 77 65 72 20 64 61 74 61 2c 20 73  th newer data, s
2c60: 6f 20 64 65 6c 65 74 65 73 20 6f 72 20 75 70 64  o deletes or upd
2c70: 61 74 65 73 0a 2a 2a 20 77 69 6c 6c 20 65 76 65  ates.** will eve
2c80: 6e 74 75 61 6c 6c 79 20 6f 76 65 72 74 61 6b 65  ntually overtake
2c90: 20 74 68 65 20 65 61 72 6c 69 65 72 20 64 61 74   the earlier dat
2ca0: 61 20 61 6e 64 20 6b 6e 6f 63 6b 20 69 74 20 6f  a and knock it o
2cb0: 75 74 2e 20 20 54 68 65 0a 2a 2a 20 71 75 65 72  ut.  The.** quer
2cc0: 79 20 6c 6f 67 69 63 20 6c 69 6b 65 77 69 73 65  y logic likewise
2cd0: 20 6d 65 72 67 65 73 20 64 6f 63 6c 69 73 74 73   merges doclists
2ce0: 20 73 6f 20 74 68 61 74 20 6e 65 77 65 72 20 64   so that newer d
2cf0: 61 74 61 20 6b 6e 6f 63 6b 73 20 6f 75 74 0a 2a  ata knocks out.*
2d00: 2a 20 6f 6c 64 65 72 20 64 61 74 61 2e 0a 2a 2a  * older data..**
2d10: 0a 2a 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20  .** TODO(shess) 
2d20: 50 72 6f 76 69 64 65 20 61 20 56 41 43 55 55 4d  Provide a VACUUM
2d30: 20 74 79 70 65 20 6f 70 65 72 61 74 69 6f 6e 20   type operation 
2d40: 74 6f 20 63 6c 65 61 72 20 6f 75 74 20 61 6c 6c  to clear out all
2d50: 0a 2a 2a 20 64 65 6c 65 74 69 6f 6e 73 20 61 6e  .** deletions an
2d60: 64 20 64 75 70 6c 69 63 61 74 69 6f 6e 73 2e 20  d duplications. 
2d70: 20 54 68 69 73 20 77 6f 75 6c 64 20 62 61 73 69   This would basi
2d80: 63 61 6c 6c 79 20 62 65 20 61 20 66 6f 72 63 65  cally be a force
2d90: 64 20 6d 65 72 67 65 0a 2a 2a 20 69 6e 74 6f 20  d merge.** into 
2da0: 61 20 73 69 6e 67 6c 65 20 73 65 67 6d 65 6e 74  a single segment
2db0: 2e 0a 2a 2f 0a 0a 23 69 66 20 21 64 65 66 69 6e  ..*/..#if !defin
2dc0: 65 64 28 53 51 4c 49 54 45 5f 43 4f 52 45 29 20  ed(SQLITE_CORE) 
2dd0: 7c 7c 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  || defined(SQLIT
2de0: 45 5f 45 4e 41 42 4c 45 5f 46 54 53 33 29 0a 0a  E_ENABLE_FTS3)..
2df0: 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49  #if defined(SQLI
2e00: 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53 33 29 20  TE_ENABLE_FTS3) 
2e10: 26 26 20 21 64 65 66 69 6e 65 64 28 53 51 4c 49  && !defined(SQLI
2e20: 54 45 5f 43 4f 52 45 29 0a 23 20 64 65 66 69 6e  TE_CORE).# defin
2e30: 65 20 53 51 4c 49 54 45 5f 43 4f 52 45 20 31 0a  e SQLITE_CORE 1.
2e40: 23 65 6e 64 69 66 0a 0a 23 69 6e 63 6c 75 64 65  #endif..#include
2e50: 20 3c 61 73 73 65 72 74 2e 68 3e 0a 23 69 6e 63   <assert.h>.#inc
2e60: 6c 75 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a  lude <stdlib.h>.
2e70: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e  #include <stdio.
2e80: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72  h>.#include <str
2e90: 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  ing.h>.#include 
2ea0: 3c 63 74 79 70 65 2e 68 3e 0a 0a 23 69 6e 63 6c  <ctype.h>..#incl
2eb0: 75 64 65 20 22 66 74 73 33 2e 68 22 0a 23 69 6e  ude "fts3.h".#in
2ec0: 63 6c 75 64 65 20 22 66 74 73 33 5f 65 78 70 72  clude "fts3_expr
2ed0: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 66 74  .h".#include "ft
2ee0: 73 33 5f 68 61 73 68 2e 68 22 0a 23 69 6e 63 6c  s3_hash.h".#incl
2ef0: 75 64 65 20 22 66 74 73 33 5f 74 6f 6b 65 6e 69  ude "fts3_tokeni
2f00: 7a 65 72 2e 68 22 0a 23 69 66 6e 64 65 66 20 53  zer.h".#ifndef S
2f10: 51 4c 49 54 45 5f 43 4f 52 45 20 0a 23 20 69 6e  QLITE_CORE .# in
2f20: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 33 65 78  clude "sqlite3ex
2f30: 74 2e 68 22 0a 20 20 53 51 4c 49 54 45 5f 45 58  t.h".  SQLITE_EX
2f40: 54 45 4e 53 49 4f 4e 5f 49 4e 49 54 31 0a 23 65  TENSION_INIT1.#e
2f50: 6e 64 69 66 0a 0a 0a 2f 2a 20 54 4f 44 4f 28 73  ndif.../* TODO(s
2f60: 68 65 73 73 29 20 4d 41 4e 2c 20 74 68 69 73 20  hess) MAN, this 
2f70: 74 68 69 6e 67 20 6e 65 65 64 73 20 73 6f 6d 65  thing needs some
2f80: 20 72 65 66 61 63 74 6f 72 69 6e 67 2e 20 20 41   refactoring.  A
2f90: 74 20 6d 69 6e 69 6d 75 6d 2c 20 69 74 0a 2a 2a  t minimum, it.**
2fa0: 20 77 6f 75 6c 64 20 62 65 20 6e 69 63 65 20 74   would be nice t
2fb0: 6f 20 6f 72 64 65 72 20 74 68 65 20 66 69 6c 65  o order the file
2fc0: 20 62 65 74 74 65 72 2c 20 70 65 72 68 61 70 73   better, perhaps
2fd0: 20 73 6f 6d 65 74 68 69 6e 67 20 61 6c 6f 6e 67   something along
2fe0: 20 74 68 65 0a 2a 2a 20 6c 69 6e 65 73 20 6f 66   the.** lines of
2ff0: 3a 0a 2a 2a 0a 2a 2a 20 20 2d 20 75 74 69 6c 69  :.**.**  - utili
3000: 74 79 20 66 75 6e 63 74 69 6f 6e 73 0a 2a 2a 20  ty functions.** 
3010: 20 2d 20 74 61 62 6c 65 20 73 65 74 75 70 20 66   - table setup f
3020: 75 6e 63 74 69 6f 6e 73 0a 2a 2a 20 20 2d 20 74  unctions.**  - t
3030: 61 62 6c 65 20 75 70 64 61 74 65 20 66 75 6e 63  able update func
3040: 74 69 6f 6e 73 0a 2a 2a 20 20 2d 20 74 61 62 6c  tions.**  - tabl
3050: 65 20 71 75 65 72 79 20 66 75 6e 63 74 69 6f 6e  e query function
3060: 73 0a 2a 2a 0a 2a 2a 20 50 75 74 20 74 68 65 20  s.**.** Put the 
3070: 71 75 65 72 79 20 66 75 6e 63 74 69 6f 6e 73 20  query functions 
3080: 6c 61 73 74 20 62 65 63 61 75 73 65 20 74 68 65  last because the
3090: 79 27 72 65 20 6c 69 6b 65 6c 79 20 74 6f 20 72  y're likely to r
30a0: 65 66 65 72 65 6e 63 65 0a 2a 2a 20 74 79 70 65  eference.** type
30b0: 64 65 66 73 20 6f 72 20 66 75 6e 63 74 69 6f 6e  defs or function
30c0: 73 20 66 72 6f 6d 20 74 68 65 20 74 61 62 6c 65  s from the table
30d0: 20 75 70 64 61 74 65 20 73 65 63 74 69 6f 6e 2e   update section.
30e0: 0a 2a 2f 0a 0a 23 69 66 20 30 0a 23 20 64 65 66  .*/..#if 0.# def
30f0: 69 6e 65 20 46 54 53 54 52 41 43 45 28 41 29 20  ine FTSTRACE(A) 
3100: 20 70 72 69 6e 74 66 20 41 3b 20 66 66 6c 75 73   printf A; fflus
3110: 68 28 73 74 64 6f 75 74 29 0a 23 65 6c 73 65 0a  h(stdout).#else.
3120: 23 20 64 65 66 69 6e 65 20 46 54 53 54 52 41 43  # define FTSTRAC
3130: 45 28 41 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20  E(A).#endif../* 
3140: 49 74 20 69 73 20 6e 6f 74 20 73 61 66 65 20 74  It is not safe t
3150: 6f 20 63 61 6c 6c 20 69 73 73 70 61 63 65 28 29  o call isspace()
3160: 2c 20 74 6f 6c 6f 77 65 72 28 29 2c 20 6f 72 20  , tolower(), or 
3170: 69 73 61 6c 6e 75 6d 28 29 20 6f 6e 0a 2a 2a 20  isalnum() on.** 
3180: 68 69 2d 62 69 74 2d 73 65 74 20 63 68 61 72 61  hi-bit-set chara
3190: 63 74 65 72 73 2e 20 20 54 68 69 73 20 69 73 20  cters.  This is 
31a0: 74 68 65 20 73 61 6d 65 20 73 6f 6c 75 74 69 6f  the same solutio
31b0: 6e 20 75 73 65 64 20 69 6e 20 74 68 65 0a 2a 2a  n used in the.**
31c0: 20 74 6f 6b 65 6e 69 7a 65 72 2e 0a 2a 2f 0a 2f   tokenizer..*/./
31d0: 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 54 68  * TODO(shess) Th
31e0: 65 20 73 6e 69 70 70 65 74 2d 67 65 6e 65 72 61  e snippet-genera
31f0: 74 69 6f 6e 20 63 6f 64 65 20 73 68 6f 75 6c 64  tion code should
3200: 20 62 65 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a   be using the.**
3210: 20 74 6f 6b 65 6e 69 7a 65 72 2d 67 65 6e 65 72   tokenizer-gener
3220: 61 74 65 64 20 74 6f 6b 65 6e 73 20 72 61 74 68  ated tokens rath
3230: 65 72 20 74 68 61 6e 20 64 6f 69 6e 67 20 69 74  er than doing it
3240: 73 20 6f 77 6e 20 6c 6f 63 61 6c 0a 2a 2a 20 74  s own local.** t
3250: 6f 6b 65 6e 69 7a 61 74 69 6f 6e 2e 0a 2a 2f 0a  okenization..*/.
3260: 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 49  /* TODO(shess) I
3270: 73 20 5f 5f 69 73 61 73 63 69 69 28 29 20 61 20  s __isascii() a 
3280: 70 6f 72 74 61 62 6c 65 20 76 65 72 73 69 6f 6e  portable version
3290: 20 6f 66 20 28 63 26 30 78 38 30 29 3d 3d 30 3f   of (c&0x80)==0?
32a0: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73   */.static int s
32b0: 61 66 65 5f 69 73 73 70 61 63 65 28 63 68 61 72  afe_isspace(char
32c0: 20 63 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 63   c){.  return (c
32d0: 26 30 78 38 30 29 3d 3d 30 20 3f 20 69 73 73 70  &0x80)==0 ? issp
32e0: 61 63 65 28 63 29 20 3a 20 30 3b 0a 7d 0a 73 74  ace(c) : 0;.}.st
32f0: 61 74 69 63 20 69 6e 74 20 73 61 66 65 5f 74 6f  atic int safe_to
3300: 6c 6f 77 65 72 28 63 68 61 72 20 63 29 7b 0a 20  lower(char c){. 
3310: 20 72 65 74 75 72 6e 20 28 63 26 30 78 38 30 29   return (c&0x80)
3320: 3d 3d 30 20 3f 20 74 6f 6c 6f 77 65 72 28 63 29  ==0 ? tolower(c)
3330: 20 3a 20 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69   : c;.}.static i
3340: 6e 74 20 73 61 66 65 5f 69 73 61 6c 6e 75 6d 28  nt safe_isalnum(
3350: 63 68 61 72 20 63 29 7b 0a 20 20 72 65 74 75 72  char c){.  retur
3360: 6e 20 28 63 26 30 78 38 30 29 3d 3d 30 20 3f 20  n (c&0x80)==0 ? 
3370: 69 73 61 6c 6e 75 6d 28 63 29 20 3a 20 30 3b 0a  isalnum(c) : 0;.
3380: 7d 0a 0a 74 79 70 65 64 65 66 20 65 6e 75 6d 20  }..typedef enum 
3390: 44 6f 63 4c 69 73 74 54 79 70 65 20 7b 0a 20 20  DocListType {.  
33a0: 44 4c 5f 44 4f 43 49 44 53 2c 20 20 20 20 20 20  DL_DOCIDS,      
33b0: 20 20 20 20 20 20 20 20 2f 2a 20 64 6f 63 69 64          /* docid
33c0: 73 20 6f 6e 6c 79 20 2a 2f 0a 20 20 44 4c 5f 50  s only */.  DL_P
33d0: 4f 53 49 54 49 4f 4e 53 2c 20 20 20 20 20 20 20  OSITIONS,       
33e0: 20 20 20 20 2f 2a 20 64 6f 63 69 64 73 20 2b 20      /* docids + 
33f0: 70 6f 73 69 74 69 6f 6e 73 20 2a 2f 0a 20 20 44  positions */.  D
3400: 4c 5f 50 4f 53 49 54 49 4f 4e 53 5f 4f 46 46 53  L_POSITIONS_OFFS
3410: 45 54 53 20 20 20 20 2f 2a 20 64 6f 63 69 64 73  ETS    /* docids
3420: 20 2b 20 70 6f 73 69 74 69 6f 6e 73 20 2b 20 6f   + positions + o
3430: 66 66 73 65 74 73 20 2a 2f 0a 7d 20 44 6f 63 4c  ffsets */.} DocL
3440: 69 73 74 54 79 70 65 3b 0a 0a 2f 2a 0a 2a 2a 20  istType;../*.** 
3450: 42 79 20 64 65 66 61 75 6c 74 2c 20 6f 6e 6c 79  By default, only
3460: 20 70 6f 73 69 74 69 6f 6e 73 20 61 6e 64 20 6e   positions and n
3470: 6f 74 20 6f 66 66 73 65 74 73 20 61 72 65 20 73  ot offsets are s
3480: 74 6f 72 65 64 20 69 6e 20 74 68 65 20 64 6f 63  tored in the doc
3490: 6c 69 73 74 73 2e 0a 2a 2a 20 54 6f 20 63 68 61  lists..** To cha
34a0: 6e 67 65 20 74 68 69 73 20 73 6f 20 74 68 61 74  nge this so that
34b0: 20 6f 66 66 73 65 74 73 20 61 72 65 20 73 74 6f   offsets are sto
34c0: 72 65 64 20 74 6f 6f 2c 20 63 6f 6d 70 69 6c 65  red too, compile
34d0: 20 77 69 74 68 0a 2a 2a 0a 2a 2a 20 20 20 20 20   with.**.**     
34e0: 20 20 20 20 20 2d 44 44 4c 5f 44 45 46 41 55 4c       -DDL_DEFAUL
34f0: 54 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 5f 4f  T=DL_POSITIONS_O
3500: 46 46 53 45 54 53 0a 2a 2a 0a 2a 2a 20 49 66 20  FFSETS.**.** If 
3510: 44 4c 5f 44 45 46 41 55 4c 54 20 69 73 20 73 65  DL_DEFAULT is se
3520: 74 20 74 6f 20 44 4c 5f 44 4f 43 49 44 53 2c 20  t to DL_DOCIDS, 
3530: 79 6f 75 72 20 74 61 62 6c 65 20 63 61 6e 20 6f  your table can o
3540: 6e 6c 79 20 62 65 20 69 6e 73 65 72 74 65 64 0a  nly be inserted.
3550: 2a 2a 20 69 6e 74 6f 20 28 6e 6f 20 64 65 6c 65  ** into (no dele
3560: 74 65 73 20 6f 72 20 75 70 64 61 74 65 73 29 2e  tes or updates).
3570: 0a 2a 2f 0a 23 69 66 6e 64 65 66 20 44 4c 5f 44  .*/.#ifndef DL_D
3580: 45 46 41 55 4c 54 0a 23 20 64 65 66 69 6e 65 20  EFAULT.# define 
3590: 44 4c 5f 44 45 46 41 55 4c 54 20 44 4c 5f 50 4f  DL_DEFAULT DL_PO
35a0: 53 49 54 49 4f 4e 53 0a 23 65 6e 64 69 66 0a 0a  SITIONS.#endif..
35b0: 65 6e 75 6d 20 7b 0a 20 20 50 4f 53 5f 45 4e 44  enum {.  POS_END
35c0: 20 3d 20 30 2c 20 20 20 20 20 20 20 20 2f 2a 20   = 0,        /* 
35d0: 65 6e 64 20 6f 66 20 74 68 69 73 20 70 6f 73 69  end of this posi
35e0: 74 69 6f 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 50  tion list */.  P
35f0: 4f 53 5f 43 4f 4c 55 4d 4e 2c 20 20 20 20 20 20  OS_COLUMN,      
3600: 20 20 20 2f 2a 20 66 6f 6c 6c 6f 77 65 64 20 62     /* followed b
3610: 79 20 6e 65 77 20 63 6f 6c 75 6d 6e 20 6e 75 6d  y new column num
3620: 62 65 72 20 2a 2f 0a 20 20 50 4f 53 5f 42 41 53  ber */.  POS_BAS
3630: 45 0a 7d 3b 0a 0a 2f 2a 20 4d 45 52 47 45 5f 43  E.};../* MERGE_C
3640: 4f 55 4e 54 20 63 6f 6e 74 72 6f 6c 73 20 68 6f  OUNT controls ho
3650: 77 20 6f 66 74 65 6e 20 77 65 20 6d 65 72 67 65  w often we merge
3660: 20 73 65 67 6d 65 6e 74 73 20 28 73 65 65 20 63   segments (see c
3670: 6f 6d 6d 65 6e 74 20 61 74 0a 2a 2a 20 74 6f 70  omment at.** top
3680: 20 6f 66 20 66 69 6c 65 29 2e 0a 2a 2f 0a 23 64   of file)..*/.#d
3690: 65 66 69 6e 65 20 4d 45 52 47 45 5f 43 4f 55 4e  efine MERGE_COUN
36a0: 54 20 31 36 0a 0a 2f 2a 20 75 74 69 6c 69 74 79  T 16../* utility
36b0: 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 0a 2f   functions */../
36c0: 2a 20 43 4c 45 41 52 28 29 20 61 6e 64 20 53 43  * CLEAR() and SC
36d0: 52 41 4d 42 4c 45 28 29 20 61 62 73 74 72 61 63  RAMBLE() abstrac
36e0: 74 20 6d 65 6d 73 65 74 28 29 20 6f 6e 20 61 20  t memset() on a 
36f0: 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 73 69 6e  pointer to a sin
3700: 67 6c 65 0a 2a 2a 20 72 65 63 6f 72 64 20 74 6f  gle.** record to
3710: 20 70 72 65 76 65 6e 74 20 65 72 72 6f 72 73 20   prevent errors 
3720: 6f 66 20 74 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a  of the form:.**.
3730: 2a 2a 20 6d 79 5f 66 75 6e 63 74 69 6f 6e 28 53  ** my_function(S
3740: 6f 6d 65 54 79 70 65 20 2a 62 29 7b 0a 2a 2a 20  omeType *b){.** 
3750: 20 20 6d 65 6d 73 65 74 28 62 2c 20 27 5c 30 27    memset(b, '\0'
3760: 2c 20 73 69 7a 65 6f 66 28 62 29 29 3b 20 20 2f  , sizeof(b));  /
3770: 2f 20 73 69 7a 65 6f 66 28 62 29 21 3d 73 69 7a  / sizeof(b)!=siz
3780: 65 6f 66 28 2a 62 29 0a 2a 2a 20 7d 0a 2a 2f 0a  eof(*b).** }.*/.
3790: 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 4f  /* TODO(shess) O
37a0: 62 76 69 6f 75 73 20 63 61 6e 64 69 64 61 74 65  bvious candidate
37b0: 73 20 66 6f 72 20 61 20 68 65 61 64 65 72 20 66  s for a header f
37c0: 69 6c 65 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20  ile. */.#define 
37d0: 43 4c 45 41 52 28 62 29 20 6d 65 6d 73 65 74 28  CLEAR(b) memset(
37e0: 62 2c 20 27 5c 30 27 2c 20 73 69 7a 65 6f 66 28  b, '\0', sizeof(
37f0: 2a 28 62 29 29 29 0a 0a 23 69 66 6e 64 65 66 20  *(b)))..#ifndef 
3800: 4e 44 45 42 55 47 0a 23 20 20 64 65 66 69 6e 65  NDEBUG.#  define
3810: 20 53 43 52 41 4d 42 4c 45 28 62 29 20 6d 65 6d   SCRAMBLE(b) mem
3820: 73 65 74 28 62 2c 20 30 78 35 35 2c 20 73 69 7a  set(b, 0x55, siz
3830: 65 6f 66 28 2a 28 62 29 29 29 0a 23 65 6c 73 65  eof(*(b))).#else
3840: 0a 23 20 20 64 65 66 69 6e 65 20 53 43 52 41 4d  .#  define SCRAM
3850: 42 4c 45 28 62 29 0a 23 65 6e 64 69 66 0a 0a 2f  BLE(b).#endif../
3860: 2a 20 57 65 20 6d 61 79 20 6e 65 65 64 20 75 70  * We may need up
3870: 20 74 6f 20 56 41 52 49 4e 54 5f 4d 41 58 20 62   to VARINT_MAX b
3880: 79 74 65 73 20 74 6f 20 73 74 6f 72 65 20 61 6e  ytes to store an
3890: 20 65 6e 63 6f 64 65 64 20 36 34 2d 62 69 74 20   encoded 64-bit 
38a0: 69 6e 74 65 67 65 72 2e 20 2a 2f 0a 23 64 65 66  integer. */.#def
38b0: 69 6e 65 20 56 41 52 49 4e 54 5f 4d 41 58 20 31  ine VARINT_MAX 1
38c0: 30 0a 0a 2f 2a 20 57 72 69 74 65 20 61 20 36 34  0../* Write a 64
38d0: 2d 62 69 74 20 76 61 72 69 61 62 6c 65 2d 6c 65  -bit variable-le
38e0: 6e 67 74 68 20 69 6e 74 65 67 65 72 20 74 6f 20  ngth integer to 
38f0: 6d 65 6d 6f 72 79 20 73 74 61 72 74 69 6e 67 20  memory starting 
3900: 61 74 20 70 5b 30 5d 2e 0a 20 2a 20 54 68 65 20  at p[0].. * The 
3910: 6c 65 6e 67 74 68 20 6f 66 20 64 61 74 61 20 77  length of data w
3920: 72 69 74 74 65 6e 20 77 69 6c 6c 20 62 65 20 62  ritten will be b
3930: 65 74 77 65 65 6e 20 31 20 61 6e 64 20 56 41 52  etween 1 and VAR
3940: 49 4e 54 5f 4d 41 58 20 62 79 74 65 73 2e 0a 20  INT_MAX bytes.. 
3950: 2a 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  * The number of 
3960: 62 79 74 65 73 20 77 72 69 74 74 65 6e 20 69 73  bytes written is
3970: 20 72 65 74 75 72 6e 65 64 2e 20 2a 2f 0a 73 74   returned. */.st
3980: 61 74 69 63 20 69 6e 74 20 66 74 73 33 50 75 74  atic int fts3Put
3990: 56 61 72 69 6e 74 28 63 68 61 72 20 2a 70 2c 20  Varint(char *p, 
39a0: 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 76 29 7b  sqlite_int64 v){
39b0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  .  unsigned char
39c0: 20 2a 71 20 3d 20 28 75 6e 73 69 67 6e 65 64 20   *q = (unsigned 
39d0: 63 68 61 72 20 2a 29 20 70 3b 0a 20 20 73 71 6c  char *) p;.  sql
39e0: 69 74 65 5f 75 69 6e 74 36 34 20 76 75 20 3d 20  ite_uint64 vu = 
39f0: 76 3b 0a 20 20 64 6f 7b 0a 20 20 20 20 2a 71 2b  v;.  do{.    *q+
3a00: 2b 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68  + = (unsigned ch
3a10: 61 72 29 20 28 28 76 75 20 26 20 30 78 37 66 29  ar) ((vu & 0x7f)
3a20: 20 7c 20 30 78 38 30 29 3b 0a 20 20 20 20 76 75   | 0x80);.    vu
3a30: 20 3e 3e 3d 20 37 3b 0a 20 20 7d 77 68 69 6c 65   >>= 7;.  }while
3a40: 28 20 76 75 21 3d 30 20 29 3b 0a 20 20 71 5b 2d  ( vu!=0 );.  q[-
3a50: 31 5d 20 26 3d 20 30 78 37 66 3b 20 20 2f 2a 20  1] &= 0x7f;  /* 
3a60: 74 75 72 6e 20 6f 66 66 20 68 69 67 68 20 62 69  turn off high bi
3a70: 74 20 69 6e 20 66 69 6e 61 6c 20 62 79 74 65 20  t in final byte 
3a80: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 71 20 2d  */.  assert( q -
3a90: 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20   (unsigned char 
3aa0: 2a 29 70 20 3c 3d 20 56 41 52 49 4e 54 5f 4d 41  *)p <= VARINT_MA
3ab0: 58 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 69  X );.  return (i
3ac0: 6e 74 29 20 28 71 20 2d 20 28 75 6e 73 69 67 6e  nt) (q - (unsign
3ad0: 65 64 20 63 68 61 72 20 2a 29 70 29 3b 0a 7d 0a  ed char *)p);.}.
3ae0: 0a 2f 2a 20 52 65 61 64 20 61 20 36 34 2d 62 69  ./* Read a 64-bi
3af0: 74 20 76 61 72 69 61 62 6c 65 2d 6c 65 6e 67 74  t variable-lengt
3b00: 68 20 69 6e 74 65 67 65 72 20 66 72 6f 6d 20 6d  h integer from m
3b10: 65 6d 6f 72 79 20 73 74 61 72 74 69 6e 67 20 61  emory starting a
3b20: 74 20 70 5b 30 5d 2e 0a 20 2a 20 52 65 74 75 72  t p[0].. * Retur
3b30: 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  n the number of 
3b40: 62 79 74 65 73 20 72 65 61 64 2c 20 6f 72 20 30  bytes read, or 0
3b50: 20 6f 6e 20 65 72 72 6f 72 2e 0a 20 2a 20 54 68   on error.. * Th
3b60: 65 20 76 61 6c 75 65 20 69 73 20 73 74 6f 72 65  e value is store
3b70: 64 20 69 6e 20 2a 76 2e 20 2a 2f 0a 73 74 61 74  d in *v. */.stat
3b80: 69 63 20 69 6e 74 20 66 74 73 33 47 65 74 56 61  ic int fts3GetVa
3b90: 72 69 6e 74 28 63 6f 6e 73 74 20 63 68 61 72 20  rint(const char 
3ba0: 2a 70 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  *p, sqlite_int64
3bb0: 20 2a 76 29 7b 0a 20 20 63 6f 6e 73 74 20 75 6e   *v){.  const un
3bc0: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 71 20 3d  signed char *q =
3bd0: 20 28 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64   (const unsigned
3be0: 20 63 68 61 72 20 2a 29 20 70 3b 0a 20 20 73 71   char *) p;.  sq
3bf0: 6c 69 74 65 5f 75 69 6e 74 36 34 20 78 20 3d 20  lite_uint64 x = 
3c00: 30 2c 20 79 20 3d 20 31 3b 0a 20 20 77 68 69 6c  0, y = 1;.  whil
3c10: 65 28 20 28 2a 71 20 26 20 30 78 38 30 29 20 3d  e( (*q & 0x80) =
3c20: 3d 20 30 78 38 30 20 29 7b 0a 20 20 20 20 78 20  = 0x80 ){.    x 
3c30: 2b 3d 20 79 20 2a 20 28 2a 71 2b 2b 20 26 20 30  += y * (*q++ & 0
3c40: 78 37 66 29 3b 0a 20 20 20 20 79 20 3c 3c 3d 20  x7f);.    y <<= 
3c50: 37 3b 0a 20 20 20 20 69 66 28 20 71 20 2d 20 28  7;.    if( q - (
3c60: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29  unsigned char *)
3c70: 70 20 3e 3d 20 56 41 52 49 4e 54 5f 4d 41 58 20  p >= VARINT_MAX 
3c80: 29 7b 20 20 2f 2a 20 62 61 64 20 64 61 74 61 20  ){  /* bad data 
3c90: 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  */.      assert(
3ca0: 20 30 20 29 3b 0a 20 20 20 20 20 20 72 65 74 75   0 );.      retu
3cb0: 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  rn 0;.    }.  }.
3cc0: 20 20 78 20 2b 3d 20 79 20 2a 20 28 2a 71 2b 2b    x += y * (*q++
3cd0: 29 3b 0a 20 20 2a 76 20 3d 20 28 73 71 6c 69 74  );.  *v = (sqlit
3ce0: 65 5f 69 6e 74 36 34 29 20 78 3b 0a 20 20 72 65  e_int64) x;.  re
3cf0: 74 75 72 6e 20 28 69 6e 74 29 20 28 71 20 2d 20  turn (int) (q - 
3d00: 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a  (unsigned char *
3d10: 29 70 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  )p);.}..static i
3d20: 6e 74 20 66 74 73 33 47 65 74 56 61 72 69 6e 74  nt fts3GetVarint
3d30: 33 32 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  32(const char *p
3d40: 2c 20 69 6e 74 20 2a 70 69 29 7b 0a 20 73 71 6c  , int *pi){. sql
3d50: 69 74 65 5f 69 6e 74 36 34 20 69 3b 0a 20 69 6e  ite_int64 i;. in
3d60: 74 20 72 65 74 20 3d 20 66 74 73 33 47 65 74 56  t ret = fts3GetV
3d70: 61 72 69 6e 74 28 70 2c 20 26 69 29 3b 0a 20 2a  arint(p, &i);. *
3d80: 70 69 20 3d 20 28 69 6e 74 29 20 69 3b 0a 20 61  pi = (int) i;. a
3d90: 73 73 65 72 74 28 20 2a 70 69 3d 3d 69 20 29 3b  ssert( *pi==i );
3da0: 0a 20 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d 0a  . return ret;.}.
3db0: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
3dc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3dd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3de0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3df0: 2a 2a 2a 2a 2a 2f 0a 2f 2a 20 44 61 74 61 42 75  *****/./* DataBu
3e00: 66 66 65 72 20 69 73 20 75 73 65 64 20 74 6f 20  ffer is used to 
3e10: 63 6f 6c 6c 65 63 74 20 64 61 74 61 20 69 6e 74  collect data int
3e20: 6f 20 61 20 62 75 66 66 65 72 20 69 6e 20 70 69  o a buffer in pi
3e30: 65 63 65 6d 65 61 6c 0a 2a 2a 20 66 61 73 68 69  ecemeal.** fashi
3e40: 6f 6e 2e 20 20 49 74 20 69 6d 70 6c 65 6d 65 6e  on.  It implemen
3e50: 74 73 20 74 68 65 20 75 73 75 61 6c 20 64 69 73  ts the usual dis
3e60: 74 69 6e 63 74 69 6f 6e 20 62 65 74 77 65 65 6e  tinction between
3e70: 20 61 6d 6f 75 6e 74 20 6f 66 0a 2a 2a 20 64 61   amount of.** da
3e80: 74 61 20 63 75 72 72 65 6e 74 6c 79 20 73 74 6f  ta currently sto
3e90: 72 65 64 20 28 6e 44 61 74 61 29 20 61 6e 64 20  red (nData) and 
3ea0: 62 75 66 66 65 72 20 63 61 70 61 63 69 74 79 20  buffer capacity 
3eb0: 28 6e 43 61 70 61 63 69 74 79 29 2e 0a 2a 2a 0a  (nCapacity)..**.
3ec0: 2a 2a 20 64 61 74 61 42 75 66 66 65 72 49 6e 69  ** dataBufferIni
3ed0: 74 20 2d 20 63 72 65 61 74 65 20 61 20 62 75 66  t - create a buf
3ee0: 66 65 72 20 77 69 74 68 20 67 69 76 65 6e 20 69  fer with given i
3ef0: 6e 69 74 69 61 6c 20 63 61 70 61 63 69 74 79 2e  nitial capacity.
3f00: 0a 2a 2a 20 64 61 74 61 42 75 66 66 65 72 52 65  .** dataBufferRe
3f10: 73 65 74 20 2d 20 66 6f 72 67 65 74 20 62 75 66  set - forget buf
3f20: 66 65 72 27 73 20 64 61 74 61 2c 20 72 65 74 61  fer's data, reta
3f30: 69 6e 69 6e 67 20 63 61 70 61 63 69 74 79 2e 0a  ining capacity..
3f40: 2a 2a 20 64 61 74 61 42 75 66 66 65 72 44 65 73  ** dataBufferDes
3f50: 74 72 6f 79 20 2d 20 66 72 65 65 20 62 75 66 66  troy - free buff
3f60: 65 72 27 73 20 64 61 74 61 2e 0a 2a 2a 20 64 61  er's data..** da
3f70: 74 61 42 75 66 66 65 72 53 77 61 70 20 2d 20 73  taBufferSwap - s
3f80: 77 61 70 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  wap contents of 
3f90: 74 77 6f 20 62 75 66 66 65 72 73 2e 0a 2a 2a 20  two buffers..** 
3fa0: 64 61 74 61 42 75 66 66 65 72 45 78 70 61 6e 64  dataBufferExpand
3fb0: 20 2d 20 65 78 70 61 6e 64 20 63 61 70 61 63 69   - expand capaci
3fc0: 74 79 20 77 69 74 68 6f 75 74 20 61 64 64 69 6e  ty without addin
3fd0: 67 20 64 61 74 61 2e 0a 2a 2a 20 64 61 74 61 42  g data..** dataB
3fe0: 75 66 66 65 72 41 70 70 65 6e 64 20 2d 20 61 70  ufferAppend - ap
3ff0: 70 65 6e 64 20 64 61 74 61 2e 0a 2a 2a 20 64 61  pend data..** da
4000: 74 61 42 75 66 66 65 72 41 70 70 65 6e 64 32 20  taBufferAppend2 
4010: 2d 20 61 70 70 65 6e 64 20 74 77 6f 20 70 69 65  - append two pie
4020: 63 65 73 20 6f 66 20 64 61 74 61 20 61 74 20 6f  ces of data at o
4030: 6e 63 65 2e 0a 2a 2a 20 64 61 74 61 42 75 66 66  nce..** dataBuff
4040: 65 72 52 65 70 6c 61 63 65 20 2d 20 72 65 70 6c  erReplace - repl
4050: 61 63 65 20 62 75 66 66 65 72 27 73 20 64 61 74  ace buffer's dat
4060: 61 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  a..*/.typedef st
4070: 72 75 63 74 20 44 61 74 61 42 75 66 66 65 72 20  ruct DataBuffer 
4080: 7b 0a 20 20 63 68 61 72 20 2a 70 44 61 74 61 3b  {.  char *pData;
4090: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
40a0: 6e 74 65 72 20 74 6f 20 6d 61 6c 6c 6f 63 27 65  nter to malloc'e
40b0: 64 20 62 75 66 66 65 72 2e 20 2a 2f 0a 20 20 69  d buffer. */.  i
40c0: 6e 74 20 6e 43 61 70 61 63 69 74 79 3b 20 20 20  nt nCapacity;   
40d0: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
40e0: 70 44 61 74 61 20 62 75 66 66 65 72 2e 20 2a 2f  pData buffer. */
40f0: 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b 20 20 20  .  int nData;   
4100: 20 20 20 20 20 20 20 20 20 2f 2a 20 45 6e 64 20           /* End 
4110: 6f 66 20 64 61 74 61 20 6c 6f 61 64 65 64 20 69  of data loaded i
4120: 6e 74 6f 20 70 44 61 74 61 2e 20 2a 2f 0a 7d 20  nto pData. */.} 
4130: 44 61 74 61 42 75 66 66 65 72 3b 0a 0a 73 74 61  DataBuffer;..sta
4140: 74 69 63 20 76 6f 69 64 20 64 61 74 61 42 75 66  tic void dataBuf
4150: 66 65 72 49 6e 69 74 28 44 61 74 61 42 75 66 66  ferInit(DataBuff
4160: 65 72 20 2a 70 42 75 66 66 65 72 2c 20 69 6e 74  er *pBuffer, int
4170: 20 6e 43 61 70 61 63 69 74 79 29 7b 0a 20 20 61   nCapacity){.  a
4180: 73 73 65 72 74 28 20 6e 43 61 70 61 63 69 74 79  ssert( nCapacity
4190: 3e 3d 30 20 29 3b 0a 20 20 70 42 75 66 66 65 72  >=0 );.  pBuffer
41a0: 2d 3e 6e 44 61 74 61 20 3d 20 30 3b 0a 20 20 70  ->nData = 0;.  p
41b0: 42 75 66 66 65 72 2d 3e 6e 43 61 70 61 63 69 74  Buffer->nCapacit
41c0: 79 20 3d 20 6e 43 61 70 61 63 69 74 79 3b 0a 20  y = nCapacity;. 
41d0: 20 70 42 75 66 66 65 72 2d 3e 70 44 61 74 61 20   pBuffer->pData 
41e0: 3d 20 6e 43 61 70 61 63 69 74 79 3d 3d 30 20 3f  = nCapacity==0 ?
41f0: 20 4e 55 4c 4c 20 3a 20 73 71 6c 69 74 65 33 5f   NULL : sqlite3_
4200: 6d 61 6c 6c 6f 63 28 6e 43 61 70 61 63 69 74 79  malloc(nCapacity
4210: 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64  );.}.static void
4220: 20 64 61 74 61 42 75 66 66 65 72 52 65 73 65 74   dataBufferReset
4230: 28 44 61 74 61 42 75 66 66 65 72 20 2a 70 42 75  (DataBuffer *pBu
4240: 66 66 65 72 29 7b 0a 20 20 70 42 75 66 66 65 72  ffer){.  pBuffer
4250: 2d 3e 6e 44 61 74 61 20 3d 20 30 3b 0a 7d 0a 73  ->nData = 0;.}.s
4260: 74 61 74 69 63 20 76 6f 69 64 20 64 61 74 61 42  tatic void dataB
4270: 75 66 66 65 72 44 65 73 74 72 6f 79 28 44 61 74  ufferDestroy(Dat
4280: 61 42 75 66 66 65 72 20 2a 70 42 75 66 66 65 72  aBuffer *pBuffer
4290: 29 7b 0a 20 20 69 66 28 20 70 42 75 66 66 65 72  ){.  if( pBuffer
42a0: 2d 3e 70 44 61 74 61 21 3d 4e 55 4c 4c 20 29 20  ->pData!=NULL ) 
42b0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 42 75  sqlite3_free(pBu
42c0: 66 66 65 72 2d 3e 70 44 61 74 61 29 3b 0a 20 20  ffer->pData);.  
42d0: 53 43 52 41 4d 42 4c 45 28 70 42 75 66 66 65 72  SCRAMBLE(pBuffer
42e0: 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64  );.}.static void
42f0: 20 64 61 74 61 42 75 66 66 65 72 53 77 61 70 28   dataBufferSwap(
4300: 44 61 74 61 42 75 66 66 65 72 20 2a 70 42 75 66  DataBuffer *pBuf
4310: 66 65 72 31 2c 20 44 61 74 61 42 75 66 66 65 72  fer1, DataBuffer
4320: 20 2a 70 42 75 66 66 65 72 32 29 7b 0a 20 20 44   *pBuffer2){.  D
4330: 61 74 61 42 75 66 66 65 72 20 74 6d 70 20 3d 20  ataBuffer tmp = 
4340: 2a 70 42 75 66 66 65 72 31 3b 0a 20 20 2a 70 42  *pBuffer1;.  *pB
4350: 75 66 66 65 72 31 20 3d 20 2a 70 42 75 66 66 65  uffer1 = *pBuffe
4360: 72 32 3b 0a 20 20 2a 70 42 75 66 66 65 72 32 20  r2;.  *pBuffer2 
4370: 3d 20 74 6d 70 3b 0a 7d 0a 73 74 61 74 69 63 20  = tmp;.}.static 
4380: 76 6f 69 64 20 64 61 74 61 42 75 66 66 65 72 45  void dataBufferE
4390: 78 70 61 6e 64 28 44 61 74 61 42 75 66 66 65 72  xpand(DataBuffer
43a0: 20 2a 70 42 75 66 66 65 72 2c 20 69 6e 74 20 6e   *pBuffer, int n
43b0: 41 64 64 43 61 70 61 63 69 74 79 29 7b 0a 20 20  AddCapacity){.  
43c0: 61 73 73 65 72 74 28 20 6e 41 64 64 43 61 70 61  assert( nAddCapa
43d0: 63 69 74 79 3e 30 20 29 3b 0a 20 20 2f 2a 20 54  city>0 );.  /* T
43e0: 4f 44 4f 28 73 68 65 73 73 29 20 43 6f 6e 73 69  ODO(shess) Consi
43f0: 64 65 72 20 65 78 70 61 6e 64 69 6e 67 20 6d 6f  der expanding mo
4400: 72 65 20 61 67 67 72 65 73 73 69 76 65 6c 79 2e  re aggressively.
4410: 20 20 4e 6f 74 65 20 74 68 61 74 20 74 68 65 0a    Note that the.
4420: 20 20 2a 2a 20 75 6e 64 65 72 6c 79 69 6e 67 20    ** underlying 
4430: 6d 61 6c 6c 6f 63 20 69 6d 70 6c 65 6d 65 6e 74  malloc implement
4440: 61 74 69 6f 6e 20 6d 61 79 20 74 61 6b 65 20 63  ation may take c
4450: 61 72 65 20 6f 66 20 73 75 63 68 20 74 68 69 6e  are of such thin
4460: 67 73 20 66 6f 72 0a 20 20 2a 2a 20 75 73 20 61  gs for.  ** us a
4470: 6c 72 65 61 64 79 2e 0a 20 20 2a 2f 0a 20 20 69  lready..  */.  i
4480: 66 28 20 70 42 75 66 66 65 72 2d 3e 6e 44 61 74  f( pBuffer->nDat
4490: 61 2b 6e 41 64 64 43 61 70 61 63 69 74 79 3e 70  a+nAddCapacity>p
44a0: 42 75 66 66 65 72 2d 3e 6e 43 61 70 61 63 69 74  Buffer->nCapacit
44b0: 79 20 29 7b 0a 20 20 20 20 70 42 75 66 66 65 72  y ){.    pBuffer
44c0: 2d 3e 6e 43 61 70 61 63 69 74 79 20 3d 20 70 42  ->nCapacity = pB
44d0: 75 66 66 65 72 2d 3e 6e 44 61 74 61 2b 6e 41 64  uffer->nData+nAd
44e0: 64 43 61 70 61 63 69 74 79 3b 0a 20 20 20 20 70  dCapacity;.    p
44f0: 42 75 66 66 65 72 2d 3e 70 44 61 74 61 20 3d 20  Buffer->pData = 
4500: 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63 28  sqlite3_realloc(
4510: 70 42 75 66 66 65 72 2d 3e 70 44 61 74 61 2c 20  pBuffer->pData, 
4520: 70 42 75 66 66 65 72 2d 3e 6e 43 61 70 61 63 69  pBuffer->nCapaci
4530: 74 79 29 3b 0a 20 20 7d 0a 7d 0a 73 74 61 74 69  ty);.  }.}.stati
4540: 63 20 76 6f 69 64 20 64 61 74 61 42 75 66 66 65  c void dataBuffe
4550: 72 41 70 70 65 6e 64 28 44 61 74 61 42 75 66 66  rAppend(DataBuff
4560: 65 72 20 2a 70 42 75 66 66 65 72 2c 0a 20 20 20  er *pBuffer,.   
4570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4580: 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20            const 
4590: 63 68 61 72 20 2a 70 53 6f 75 72 63 65 2c 20 69  char *pSource, i
45a0: 6e 74 20 6e 53 6f 75 72 63 65 29 7b 0a 20 20 61  nt nSource){.  a
45b0: 73 73 65 72 74 28 20 6e 53 6f 75 72 63 65 3e 30  ssert( nSource>0
45c0: 20 26 26 20 70 53 6f 75 72 63 65 21 3d 4e 55 4c   && pSource!=NUL
45d0: 4c 20 29 3b 0a 20 20 64 61 74 61 42 75 66 66 65  L );.  dataBuffe
45e0: 72 45 78 70 61 6e 64 28 70 42 75 66 66 65 72 2c  rExpand(pBuffer,
45f0: 20 6e 53 6f 75 72 63 65 29 3b 0a 20 20 6d 65 6d   nSource);.  mem
4600: 63 70 79 28 70 42 75 66 66 65 72 2d 3e 70 44 61  cpy(pBuffer->pDa
4610: 74 61 2b 70 42 75 66 66 65 72 2d 3e 6e 44 61 74  ta+pBuffer->nDat
4620: 61 2c 20 70 53 6f 75 72 63 65 2c 20 6e 53 6f 75  a, pSource, nSou
4630: 72 63 65 29 3b 0a 20 20 70 42 75 66 66 65 72 2d  rce);.  pBuffer-
4640: 3e 6e 44 61 74 61 20 2b 3d 20 6e 53 6f 75 72 63  >nData += nSourc
4650: 65 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64  e;.}.static void
4660: 20 64 61 74 61 42 75 66 66 65 72 41 70 70 65 6e   dataBufferAppen
4670: 64 32 28 44 61 74 61 42 75 66 66 65 72 20 2a 70  d2(DataBuffer *p
4680: 42 75 66 66 65 72 2c 0a 20 20 20 20 20 20 20 20  Buffer,.        
4690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
46a0: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
46b0: 20 2a 70 53 6f 75 72 63 65 31 2c 20 69 6e 74 20   *pSource1, int 
46c0: 6e 53 6f 75 72 63 65 31 2c 0a 20 20 20 20 20 20  nSource1,.      
46d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
46e0: 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68          const ch
46f0: 61 72 20 2a 70 53 6f 75 72 63 65 32 2c 20 69 6e  ar *pSource2, in
4700: 74 20 6e 53 6f 75 72 63 65 32 29 7b 0a 20 20 61  t nSource2){.  a
4710: 73 73 65 72 74 28 20 6e 53 6f 75 72 63 65 31 3e  ssert( nSource1>
4720: 30 20 26 26 20 70 53 6f 75 72 63 65 31 21 3d 4e  0 && pSource1!=N
4730: 55 4c 4c 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ULL );.  assert(
4740: 20 6e 53 6f 75 72 63 65 32 3e 30 20 26 26 20 70   nSource2>0 && p
4750: 53 6f 75 72 63 65 32 21 3d 4e 55 4c 4c 20 29 3b  Source2!=NULL );
4760: 0a 20 20 64 61 74 61 42 75 66 66 65 72 45 78 70  .  dataBufferExp
4770: 61 6e 64 28 70 42 75 66 66 65 72 2c 20 6e 53 6f  and(pBuffer, nSo
4780: 75 72 63 65 31 2b 6e 53 6f 75 72 63 65 32 29 3b  urce1+nSource2);
4790: 0a 20 20 6d 65 6d 63 70 79 28 70 42 75 66 66 65  .  memcpy(pBuffe
47a0: 72 2d 3e 70 44 61 74 61 2b 70 42 75 66 66 65 72  r->pData+pBuffer
47b0: 2d 3e 6e 44 61 74 61 2c 20 70 53 6f 75 72 63 65  ->nData, pSource
47c0: 31 2c 20 6e 53 6f 75 72 63 65 31 29 3b 0a 20 20  1, nSource1);.  
47d0: 6d 65 6d 63 70 79 28 70 42 75 66 66 65 72 2d 3e  memcpy(pBuffer->
47e0: 70 44 61 74 61 2b 70 42 75 66 66 65 72 2d 3e 6e  pData+pBuffer->n
47f0: 44 61 74 61 2b 6e 53 6f 75 72 63 65 31 2c 20 70  Data+nSource1, p
4800: 53 6f 75 72 63 65 32 2c 20 6e 53 6f 75 72 63 65  Source2, nSource
4810: 32 29 3b 0a 20 20 70 42 75 66 66 65 72 2d 3e 6e  2);.  pBuffer->n
4820: 44 61 74 61 20 2b 3d 20 6e 53 6f 75 72 63 65 31  Data += nSource1
4830: 2b 6e 53 6f 75 72 63 65 32 3b 0a 7d 0a 73 74 61  +nSource2;.}.sta
4840: 74 69 63 20 76 6f 69 64 20 64 61 74 61 42 75 66  tic void dataBuf
4850: 66 65 72 52 65 70 6c 61 63 65 28 44 61 74 61 42  ferReplace(DataB
4860: 75 66 66 65 72 20 2a 70 42 75 66 66 65 72 2c 0a  uffer *pBuffer,.
4870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63 6f                co
4890: 6e 73 74 20 63 68 61 72 20 2a 70 53 6f 75 72 63  nst char *pSourc
48a0: 65 2c 20 69 6e 74 20 6e 53 6f 75 72 63 65 29 7b  e, int nSource){
48b0: 0a 20 20 64 61 74 61 42 75 66 66 65 72 52 65 73  .  dataBufferRes
48c0: 65 74 28 70 42 75 66 66 65 72 29 3b 0a 20 20 64  et(pBuffer);.  d
48d0: 61 74 61 42 75 66 66 65 72 41 70 70 65 6e 64 28  ataBufferAppend(
48e0: 70 42 75 66 66 65 72 2c 20 70 53 6f 75 72 63 65  pBuffer, pSource
48f0: 2c 20 6e 53 6f 75 72 63 65 29 3b 0a 7d 0a 0a 2f  , nSource);.}../
4900: 2a 20 53 74 72 69 6e 67 42 75 66 66 65 72 20 69  * StringBuffer i
4910: 73 20 61 20 6e 75 6c 6c 2d 74 65 72 6d 69 6e 61  s a null-termina
4920: 74 65 64 20 76 65 72 73 69 6f 6e 20 6f 66 20 44  ted version of D
4930: 61 74 61 42 75 66 66 65 72 2e 20 2a 2f 0a 74 79  ataBuffer. */.ty
4940: 70 65 64 65 66 20 73 74 72 75 63 74 20 53 74 72  pedef struct Str
4950: 69 6e 67 42 75 66 66 65 72 20 7b 0a 20 20 44 61  ingBuffer {.  Da
4960: 74 61 42 75 66 66 65 72 20 62 3b 20 20 20 20 20  taBuffer b;     
4970: 20 20 20 20 20 20 20 2f 2a 20 49 6e 63 6c 75 64         /* Includ
4980: 65 73 20 6e 75 6c 6c 20 74 65 72 6d 69 6e 61 74  es null terminat
4990: 6f 72 2e 20 2a 2f 0a 7d 20 53 74 72 69 6e 67 42  or. */.} StringB
49a0: 75 66 66 65 72 3b 0a 0a 73 74 61 74 69 63 20 76  uffer;..static v
49b0: 6f 69 64 20 69 6e 69 74 53 74 72 69 6e 67 42 75  oid initStringBu
49c0: 66 66 65 72 28 53 74 72 69 6e 67 42 75 66 66 65  ffer(StringBuffe
49d0: 72 20 2a 73 62 29 7b 0a 20 20 64 61 74 61 42 75  r *sb){.  dataBu
49e0: 66 66 65 72 49 6e 69 74 28 26 73 62 2d 3e 62 2c  fferInit(&sb->b,
49f0: 20 31 30 30 29 3b 0a 20 20 64 61 74 61 42 75 66   100);.  dataBuf
4a00: 66 65 72 52 65 70 6c 61 63 65 28 26 73 62 2d 3e  ferReplace(&sb->
4a10: 62 2c 20 22 22 2c 20 31 29 3b 0a 7d 0a 73 74 61  b, "", 1);.}.sta
4a20: 74 69 63 20 69 6e 74 20 73 74 72 69 6e 67 42 75  tic int stringBu
4a30: 66 66 65 72 4c 65 6e 67 74 68 28 53 74 72 69 6e  fferLength(Strin
4a40: 67 42 75 66 66 65 72 20 2a 73 62 29 7b 0a 20 20  gBuffer *sb){.  
4a50: 72 65 74 75 72 6e 20 73 62 2d 3e 62 2e 6e 44 61  return sb->b.nDa
4a60: 74 61 2d 31 3b 0a 7d 0a 73 74 61 74 69 63 20 63  ta-1;.}.static c
4a70: 68 61 72 20 2a 73 74 72 69 6e 67 42 75 66 66 65  har *stringBuffe
4a80: 72 44 61 74 61 28 53 74 72 69 6e 67 42 75 66 66  rData(StringBuff
4a90: 65 72 20 2a 73 62 29 7b 0a 20 20 72 65 74 75 72  er *sb){.  retur
4aa0: 6e 20 73 62 2d 3e 62 2e 70 44 61 74 61 3b 0a 7d  n sb->b.pData;.}
4ab0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 74 72  .static void str
4ac0: 69 6e 67 42 75 66 66 65 72 44 65 73 74 72 6f 79  ingBufferDestroy
4ad0: 28 53 74 72 69 6e 67 42 75 66 66 65 72 20 2a 73  (StringBuffer *s
4ae0: 62 29 7b 0a 20 20 64 61 74 61 42 75 66 66 65 72  b){.  dataBuffer
4af0: 44 65 73 74 72 6f 79 28 26 73 62 2d 3e 62 29 3b  Destroy(&sb->b);
4b00: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
4b10: 6e 61 70 70 65 6e 64 28 53 74 72 69 6e 67 42 75  nappend(StringBu
4b20: 66 66 65 72 20 2a 73 62 2c 20 63 6f 6e 73 74 20  ffer *sb, const 
4b30: 63 68 61 72 20 2a 7a 46 72 6f 6d 2c 20 69 6e 74  char *zFrom, int
4b40: 20 6e 46 72 6f 6d 29 7b 0a 20 20 61 73 73 65 72   nFrom){.  asser
4b50: 74 28 20 73 62 2d 3e 62 2e 6e 44 61 74 61 3e 30  t( sb->b.nData>0
4b60: 20 29 3b 0a 20 20 69 66 28 20 6e 46 72 6f 6d 3e   );.  if( nFrom>
4b70: 30 20 29 7b 0a 20 20 20 20 73 62 2d 3e 62 2e 6e  0 ){.    sb->b.n
4b80: 44 61 74 61 2d 2d 3b 0a 20 20 20 20 64 61 74 61  Data--;.    data
4b90: 42 75 66 66 65 72 41 70 70 65 6e 64 32 28 26 73  BufferAppend2(&s
4ba0: 62 2d 3e 62 2c 20 7a 46 72 6f 6d 2c 20 6e 46 72  b->b, zFrom, nFr
4bb0: 6f 6d 2c 20 22 22 2c 20 31 29 3b 0a 20 20 7d 0a  om, "", 1);.  }.
4bc0: 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  }.static void ap
4bd0: 70 65 6e 64 28 53 74 72 69 6e 67 42 75 66 66 65  pend(StringBuffe
4be0: 72 20 2a 73 62 2c 20 63 6f 6e 73 74 20 63 68 61  r *sb, const cha
4bf0: 72 20 2a 7a 46 72 6f 6d 29 7b 0a 20 20 6e 61 70  r *zFrom){.  nap
4c00: 70 65 6e 64 28 73 62 2c 20 7a 46 72 6f 6d 2c 20  pend(sb, zFrom, 
4c10: 73 74 72 6c 65 6e 28 7a 46 72 6f 6d 29 29 3b 0a  strlen(zFrom));.
4c20: 7d 0a 0a 2f 2a 20 41 70 70 65 6e 64 20 61 20 6c  }../* Append a l
4c30: 69 73 74 20 6f 66 20 73 74 72 69 6e 67 73 20 73  ist of strings s
4c40: 65 70 61 72 61 74 65 64 20 62 79 20 63 6f 6d 6d  eparated by comm
4c50: 61 73 2e 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  as. */.static vo
4c60: 69 64 20 61 70 70 65 6e 64 4c 69 73 74 28 53 74  id appendList(St
4c70: 72 69 6e 67 42 75 66 66 65 72 20 2a 73 62 2c 20  ringBuffer *sb, 
4c80: 69 6e 74 20 6e 53 74 72 69 6e 67 2c 20 63 68 61  int nString, cha
4c90: 72 20 2a 2a 61 7a 53 74 72 69 6e 67 29 7b 0a 20  r **azString){. 
4ca0: 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d   int i;.  for(i=
4cb0: 30 3b 20 69 3c 6e 53 74 72 69 6e 67 3b 20 2b 2b  0; i<nString; ++
4cc0: 69 29 7b 0a 20 20 20 20 69 66 28 20 69 3e 30 20  i){.    if( i>0 
4cd0: 29 20 61 70 70 65 6e 64 28 73 62 2c 20 22 2c 20  ) append(sb, ", 
4ce0: 22 29 3b 0a 20 20 20 20 61 70 70 65 6e 64 28 73  ");.    append(s
4cf0: 62 2c 20 61 7a 53 74 72 69 6e 67 5b 69 5d 29 3b  b, azString[i]);
4d00: 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69  .  }.}..static i
4d10: 6e 74 20 65 6e 64 73 49 6e 57 68 69 74 65 53 70  nt endsInWhiteSp
4d20: 61 63 65 28 53 74 72 69 6e 67 42 75 66 66 65 72  ace(StringBuffer
4d30: 20 2a 70 29 7b 0a 20 20 72 65 74 75 72 6e 20 73   *p){.  return s
4d40: 74 72 69 6e 67 42 75 66 66 65 72 4c 65 6e 67 74  tringBufferLengt
4d50: 68 28 70 29 3e 30 20 26 26 0a 20 20 20 20 73 61  h(p)>0 &&.    sa
4d60: 66 65 5f 69 73 73 70 61 63 65 28 73 74 72 69 6e  fe_isspace(strin
4d70: 67 42 75 66 66 65 72 44 61 74 61 28 70 29 5b 73  gBufferData(p)[s
4d80: 74 72 69 6e 67 42 75 66 66 65 72 4c 65 6e 67 74  tringBufferLengt
4d90: 68 28 70 29 2d 31 5d 29 3b 0a 7d 0a 0a 2f 2a 20  h(p)-1]);.}../* 
4da0: 49 66 20 74 68 65 20 53 74 72 69 6e 67 42 75 66  If the StringBuf
4db0: 66 65 72 20 65 6e 64 73 20 69 6e 20 73 6f 6d 65  fer ends in some
4dc0: 74 68 69 6e 67 20 6f 74 68 65 72 20 74 68 61 6e  thing other than
4dd0: 20 77 68 69 74 65 20 73 70 61 63 65 2c 20 61 64   white space, ad
4de0: 64 20 61 0a 2a 2a 20 73 69 6e 67 6c 65 20 73 70  d a.** single sp
4df0: 61 63 65 20 63 68 61 72 61 63 74 65 72 20 74 6f  ace character to
4e00: 20 74 68 65 20 65 6e 64 2e 0a 2a 2f 0a 73 74 61   the end..*/.sta
4e10: 74 69 63 20 76 6f 69 64 20 61 70 70 65 6e 64 57  tic void appendW
4e20: 68 69 74 65 53 70 61 63 65 28 53 74 72 69 6e 67  hiteSpace(String
4e30: 42 75 66 66 65 72 20 2a 70 29 7b 0a 20 20 69 66  Buffer *p){.  if
4e40: 28 20 73 74 72 69 6e 67 42 75 66 66 65 72 4c 65  ( stringBufferLe
4e50: 6e 67 74 68 28 70 29 3d 3d 30 20 29 20 72 65 74  ngth(p)==0 ) ret
4e60: 75 72 6e 3b 0a 20 20 69 66 28 20 21 65 6e 64 73  urn;.  if( !ends
4e70: 49 6e 57 68 69 74 65 53 70 61 63 65 28 70 29 20  InWhiteSpace(p) 
4e80: 29 20 61 70 70 65 6e 64 28 70 2c 20 22 20 22 29  ) append(p, " ")
4e90: 3b 0a 7d 0a 0a 2f 2a 20 52 65 6d 6f 76 65 20 77  ;.}../* Remove w
4ea0: 68 69 74 65 20 73 70 61 63 65 20 66 72 6f 6d 20  hite space from 
4eb0: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 53  the end of the S
4ec0: 74 72 69 6e 67 42 75 66 66 65 72 20 2a 2f 0a 73  tringBuffer */.s
4ed0: 74 61 74 69 63 20 76 6f 69 64 20 74 72 69 6d 57  tatic void trimW
4ee0: 68 69 74 65 53 70 61 63 65 28 53 74 72 69 6e 67  hiteSpace(String
4ef0: 42 75 66 66 65 72 20 2a 70 29 7b 0a 20 20 77 68  Buffer *p){.  wh
4f00: 69 6c 65 28 20 65 6e 64 73 49 6e 57 68 69 74 65  ile( endsInWhite
4f10: 53 70 61 63 65 28 70 29 20 29 7b 0a 20 20 20 20  Space(p) ){.    
4f20: 70 2d 3e 62 2e 70 44 61 74 61 5b 2d 2d 70 2d 3e  p->b.pData[--p->
4f30: 62 2e 6e 44 61 74 61 2d 31 5d 20 3d 20 27 5c 30  b.nData-1] = '\0
4f40: 27 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a  ';.  }.}../*****
4f50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4f60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4f70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4f80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
4f90: 2f 2a 20 44 4c 52 65 61 64 65 72 20 69 73 20 75  /* DLReader is u
4fa0: 73 65 64 20 74 6f 20 72 65 61 64 20 64 6f 63 75  sed to read docu
4fb0: 6d 65 6e 74 20 65 6c 65 6d 65 6e 74 73 20 66 72  ment elements fr
4fc0: 6f 6d 20 61 20 64 6f 63 6c 69 73 74 2e 20 20 54  om a doclist.  T
4fd0: 68 65 0a 2a 2a 20 63 75 72 72 65 6e 74 20 64 6f  he.** current do
4fe0: 63 69 64 20 69 73 20 63 61 63 68 65 64 2c 20 73  cid is cached, s
4ff0: 6f 20 64 6c 72 44 6f 63 69 64 28 29 20 69 73 20  o dlrDocid() is 
5000: 66 61 73 74 2e 20 20 44 4c 52 65 61 64 65 72 20  fast.  DLReader 
5010: 64 6f 65 73 20 6e 6f 74 0a 2a 2a 20 6f 77 6e 20  does not.** own 
5020: 74 68 65 20 64 6f 63 6c 69 73 74 20 62 75 66 66  the doclist buff
5030: 65 72 2e 0a 2a 2a 0a 2a 2a 20 64 6c 72 41 74 45  er..**.** dlrAtE
5040: 6e 64 20 2d 20 74 72 75 65 20 69 66 20 74 68 65  nd - true if the
5050: 72 65 27 73 20 6e 6f 20 6d 6f 72 65 20 64 61 74  re's no more dat
5060: 61 20 74 6f 20 72 65 61 64 2e 0a 2a 2a 20 64 6c  a to read..** dl
5070: 72 44 6f 63 69 64 20 2d 20 64 6f 63 69 64 20 6f  rDocid - docid o
5080: 66 20 63 75 72 72 65 6e 74 20 64 6f 63 75 6d 65  f current docume
5090: 6e 74 2e 0a 2a 2a 20 64 6c 72 44 6f 63 44 61 74  nt..** dlrDocDat
50a0: 61 20 2d 20 64 6f 63 6c 69 73 74 20 64 61 74 61  a - doclist data
50b0: 20 66 6f 72 20 63 75 72 72 65 6e 74 20 64 6f 63   for current doc
50c0: 75 6d 65 6e 74 20 28 69 6e 63 6c 75 64 69 6e 67  ument (including
50d0: 20 64 6f 63 69 64 29 2e 0a 2a 2a 20 64 6c 72 44   docid)..** dlrD
50e0: 6f 63 44 61 74 61 42 79 74 65 73 20 2d 20 6c 65  ocDataBytes - le
50f0: 6e 67 74 68 20 6f 66 20 73 61 6d 65 2e 0a 2a 2a  ngth of same..**
5100: 20 64 6c 72 41 6c 6c 44 61 74 61 42 79 74 65 73   dlrAllDataBytes
5110: 20 2d 20 6c 65 6e 67 74 68 20 6f 66 20 61 6c 6c   - length of all
5120: 20 72 65 6d 61 69 6e 69 6e 67 20 64 61 74 61 2e   remaining data.
5130: 0a 2a 2a 20 64 6c 72 50 6f 73 44 61 74 61 20 2d  .** dlrPosData -
5140: 20 70 6f 73 69 74 69 6f 6e 20 64 61 74 61 20 66   position data f
5150: 6f 72 20 63 75 72 72 65 6e 74 20 64 6f 63 75 6d  or current docum
5160: 65 6e 74 2e 0a 2a 2a 20 64 6c 72 50 6f 73 44 61  ent..** dlrPosDa
5170: 74 61 4c 65 6e 20 2d 20 6c 65 6e 67 74 68 20 6f  taLen - length o
5180: 66 20 70 6f 73 20 64 61 74 61 20 66 6f 72 20 63  f pos data for c
5190: 75 72 72 65 6e 74 20 64 6f 63 75 6d 65 6e 74 20  urrent document 
51a0: 28 69 6e 63 6c 20 50 4f 53 5f 45 4e 44 29 2e 0a  (incl POS_END)..
51b0: 2a 2a 20 64 6c 72 53 74 65 70 20 2d 20 73 74 65  ** dlrStep - ste
51c0: 70 20 74 6f 20 63 75 72 72 65 6e 74 20 64 6f 63  p to current doc
51d0: 75 6d 65 6e 74 2e 0a 2a 2a 20 64 6c 72 49 6e 69  ument..** dlrIni
51e0: 74 20 2d 20 69 6e 69 74 69 61 6c 20 66 6f 72 20  t - initial for 
51f0: 64 6f 63 6c 69 73 74 20 6f 66 20 67 69 76 65 6e  doclist of given
5200: 20 74 79 70 65 20 61 67 61 69 6e 73 74 20 67 69   type against gi
5210: 76 65 6e 20 64 61 74 61 2e 0a 2a 2a 20 64 6c 72  ven data..** dlr
5220: 44 65 73 74 72 6f 79 20 2d 20 63 6c 65 61 6e 20  Destroy - clean 
5230: 75 70 2e 0a 2a 2a 0a 2a 2a 20 45 78 70 65 63 74  up..**.** Expect
5240: 65 64 20 75 73 61 67 65 20 69 73 20 73 6f 6d 65  ed usage is some
5250: 74 68 69 6e 67 20 6c 69 6b 65 3a 0a 2a 2a 0a 2a  thing like:.**.*
5260: 2a 20 20 20 44 4c 52 65 61 64 65 72 20 72 65 61  *   DLReader rea
5270: 64 65 72 3b 0a 2a 2a 20 20 20 64 6c 72 49 6e 69  der;.**   dlrIni
5280: 74 28 26 72 65 61 64 65 72 2c 20 70 44 61 74 61  t(&reader, pData
5290: 2c 20 6e 44 61 74 61 29 3b 0a 2a 2a 20 20 20 77  , nData);.**   w
52a0: 68 69 6c 65 28 20 21 64 6c 72 41 74 45 6e 64 28  hile( !dlrAtEnd(
52b0: 26 72 65 61 64 65 72 29 20 29 7b 0a 2a 2a 20 20  &reader) ){.**  
52c0: 20 20 20 2f 2f 20 63 61 6c 6c 73 20 74 6f 20 64     // calls to d
52d0: 6c 72 44 6f 63 69 64 28 29 20 61 6e 64 20 6b 69  lrDocid() and ki
52e0: 6e 2e 0a 2a 2a 20 20 20 20 20 64 6c 72 53 74 65  n..**     dlrSte
52f0: 70 28 26 72 65 61 64 65 72 29 3b 0a 2a 2a 20 20  p(&reader);.**  
5300: 20 7d 0a 2a 2a 20 20 20 64 6c 72 44 65 73 74 72   }.**   dlrDestr
5310: 6f 79 28 26 72 65 61 64 65 72 29 3b 0a 2a 2f 0a  oy(&reader);.*/.
5320: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 44  typedef struct D
5330: 4c 52 65 61 64 65 72 20 7b 0a 20 20 44 6f 63 4c  LReader {.  DocL
5340: 69 73 74 54 79 70 65 20 69 54 79 70 65 3b 0a 20  istType iType;. 
5350: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 44 61   const char *pDa
5360: 74 61 3b 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b  ta;.  int nData;
5370: 0a 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  ..  sqlite_int64
5380: 20 69 44 6f 63 69 64 3b 0a 20 20 69 6e 74 20 6e   iDocid;.  int n
5390: 45 6c 65 6d 65 6e 74 3b 0a 7d 20 44 4c 52 65 61  Element;.} DLRea
53a0: 64 65 72 3b 0a 0a 73 74 61 74 69 63 20 69 6e 74  der;..static int
53b0: 20 64 6c 72 41 74 45 6e 64 28 44 4c 52 65 61 64   dlrAtEnd(DLRead
53c0: 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20  er *pReader){.  
53d0: 61 73 73 65 72 74 28 20 70 52 65 61 64 65 72 2d  assert( pReader-
53e0: 3e 6e 44 61 74 61 3e 3d 30 20 29 3b 0a 20 20 72  >nData>=0 );.  r
53f0: 65 74 75 72 6e 20 70 52 65 61 64 65 72 2d 3e 6e  eturn pReader->n
5400: 44 61 74 61 3d 3d 30 3b 0a 7d 0a 73 74 61 74 69  Data==0;.}.stati
5410: 63 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 64  c sqlite_int64 d
5420: 6c 72 44 6f 63 69 64 28 44 4c 52 65 61 64 65 72  lrDocid(DLReader
5430: 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 61 73   *pReader){.  as
5440: 73 65 72 74 28 20 21 64 6c 72 41 74 45 6e 64 28  sert( !dlrAtEnd(
5450: 70 52 65 61 64 65 72 29 20 29 3b 0a 20 20 72 65  pReader) );.  re
5460: 74 75 72 6e 20 70 52 65 61 64 65 72 2d 3e 69 44  turn pReader->iD
5470: 6f 63 69 64 3b 0a 7d 0a 73 74 61 74 69 63 20 63  ocid;.}.static c
5480: 6f 6e 73 74 20 63 68 61 72 20 2a 64 6c 72 44 6f  onst char *dlrDo
5490: 63 44 61 74 61 28 44 4c 52 65 61 64 65 72 20 2a  cData(DLReader *
54a0: 70 52 65 61 64 65 72 29 7b 0a 20 20 61 73 73 65  pReader){.  asse
54b0: 72 74 28 20 21 64 6c 72 41 74 45 6e 64 28 70 52  rt( !dlrAtEnd(pR
54c0: 65 61 64 65 72 29 20 29 3b 0a 20 20 72 65 74 75  eader) );.  retu
54d0: 72 6e 20 70 52 65 61 64 65 72 2d 3e 70 44 61 74  rn pReader->pDat
54e0: 61 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  a;.}.static int 
54f0: 64 6c 72 44 6f 63 44 61 74 61 42 79 74 65 73 28  dlrDocDataBytes(
5500: 44 4c 52 65 61 64 65 72 20 2a 70 52 65 61 64 65  DLReader *pReade
5510: 72 29 7b 0a 20 20 61 73 73 65 72 74 28 20 21 64  r){.  assert( !d
5520: 6c 72 41 74 45 6e 64 28 70 52 65 61 64 65 72 29  lrAtEnd(pReader)
5530: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 52 65   );.  return pRe
5540: 61 64 65 72 2d 3e 6e 45 6c 65 6d 65 6e 74 3b 0a  ader->nElement;.
5550: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 64 6c 72  }.static int dlr
5560: 41 6c 6c 44 61 74 61 42 79 74 65 73 28 44 4c 52  AllDataBytes(DLR
5570: 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b  eader *pReader){
5580: 0a 20 20 61 73 73 65 72 74 28 20 21 64 6c 72 41  .  assert( !dlrA
5590: 74 45 6e 64 28 70 52 65 61 64 65 72 29 20 29 3b  tEnd(pReader) );
55a0: 0a 20 20 72 65 74 75 72 6e 20 70 52 65 61 64 65  .  return pReade
55b0: 72 2d 3e 6e 44 61 74 61 3b 0a 7d 0a 2f 2a 20 54  r->nData;.}./* T
55c0: 4f 44 4f 28 73 68 65 73 73 29 20 43 6f 6e 73 69  ODO(shess) Consi
55d0: 64 65 72 20 61 64 64 69 6e 67 20 61 20 66 69 65  der adding a fie
55e0: 6c 64 20 74 6f 20 74 72 61 63 6b 20 69 44 6f 63  ld to track iDoc
55f0: 69 64 20 76 61 72 69 6e 74 20 6c 65 6e 67 74 68  id varint length
5600: 0a 2a 2a 20 74 6f 20 6d 61 6b 65 20 74 68 65 73  .** to make thes
5610: 65 20 74 77 6f 20 66 75 6e 63 74 69 6f 6e 73 20  e two functions 
5620: 66 61 73 74 65 72 2e 20 20 54 68 69 73 20 6d 69  faster.  This mi
5630: 67 68 74 20 6d 61 74 74 65 72 20 28 61 20 74 69  ght matter (a ti
5640: 6e 79 20 62 69 74 29 0a 2a 2a 20 66 6f 72 20 71  ny bit).** for q
5650: 75 65 72 69 65 73 2e 0a 2a 2f 0a 73 74 61 74 69  ueries..*/.stati
5660: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 64 6c  c const char *dl
5670: 72 50 6f 73 44 61 74 61 28 44 4c 52 65 61 64 65  rPosData(DLReade
5680: 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 73  r *pReader){.  s
5690: 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 44 75 6d  qlite_int64 iDum
56a0: 6d 79 3b 0a 20 20 69 6e 74 20 6e 20 3d 20 66 74  my;.  int n = ft
56b0: 73 33 47 65 74 56 61 72 69 6e 74 28 70 52 65 61  s3GetVarint(pRea
56c0: 64 65 72 2d 3e 70 44 61 74 61 2c 20 26 69 44 75  der->pData, &iDu
56d0: 6d 6d 79 29 3b 0a 20 20 61 73 73 65 72 74 28 20  mmy);.  assert( 
56e0: 21 64 6c 72 41 74 45 6e 64 28 70 52 65 61 64 65  !dlrAtEnd(pReade
56f0: 72 29 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 70  r) );.  return p
5700: 52 65 61 64 65 72 2d 3e 70 44 61 74 61 2b 6e 3b  Reader->pData+n;
5710: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 64 6c  .}.static int dl
5720: 72 50 6f 73 44 61 74 61 4c 65 6e 28 44 4c 52 65  rPosDataLen(DLRe
5730: 61 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a  ader *pReader){.
5740: 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69    sqlite_int64 i
5750: 44 75 6d 6d 79 3b 0a 20 20 69 6e 74 20 6e 20 3d  Dummy;.  int n =
5760: 20 66 74 73 33 47 65 74 56 61 72 69 6e 74 28 70   fts3GetVarint(p
5770: 52 65 61 64 65 72 2d 3e 70 44 61 74 61 2c 20 26  Reader->pData, &
5780: 69 44 75 6d 6d 79 29 3b 0a 20 20 61 73 73 65 72  iDummy);.  asser
5790: 74 28 20 21 64 6c 72 41 74 45 6e 64 28 70 52 65  t( !dlrAtEnd(pRe
57a0: 61 64 65 72 29 20 29 3b 0a 20 20 72 65 74 75 72  ader) );.  retur
57b0: 6e 20 70 52 65 61 64 65 72 2d 3e 6e 45 6c 65 6d  n pReader->nElem
57c0: 65 6e 74 2d 6e 3b 0a 7d 0a 73 74 61 74 69 63 20  ent-n;.}.static 
57d0: 76 6f 69 64 20 64 6c 72 53 74 65 70 28 44 4c 52  void dlrStep(DLR
57e0: 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b  eader *pReader){
57f0: 0a 20 20 61 73 73 65 72 74 28 20 21 64 6c 72 41  .  assert( !dlrA
5800: 74 45 6e 64 28 70 52 65 61 64 65 72 29 20 29 3b  tEnd(pReader) );
5810: 0a 0a 20 20 2f 2a 20 53 6b 69 70 20 70 61 73 74  ..  /* Skip past
5820: 20 63 75 72 72 65 6e 74 20 64 6f 63 6c 69 73 74   current doclist
5830: 20 65 6c 65 6d 65 6e 74 2e 20 2a 2f 0a 20 20 61   element. */.  a
5840: 73 73 65 72 74 28 20 70 52 65 61 64 65 72 2d 3e  ssert( pReader->
5850: 6e 45 6c 65 6d 65 6e 74 3c 3d 70 52 65 61 64 65  nElement<=pReade
5860: 72 2d 3e 6e 44 61 74 61 20 29 3b 0a 20 20 70 52  r->nData );.  pR
5870: 65 61 64 65 72 2d 3e 70 44 61 74 61 20 2b 3d 20  eader->pData += 
5880: 70 52 65 61 64 65 72 2d 3e 6e 45 6c 65 6d 65 6e  pReader->nElemen
5890: 74 3b 0a 20 20 70 52 65 61 64 65 72 2d 3e 6e 44  t;.  pReader->nD
58a0: 61 74 61 20 2d 3d 20 70 52 65 61 64 65 72 2d 3e  ata -= pReader->
58b0: 6e 45 6c 65 6d 65 6e 74 3b 0a 0a 20 20 2f 2a 20  nElement;..  /* 
58c0: 49 66 20 74 68 65 72 65 20 69 73 20 6d 6f 72 65  If there is more
58d0: 20 64 61 74 61 2c 20 72 65 61 64 20 74 68 65 20   data, read the 
58e0: 6e 65 78 74 20 64 6f 63 6c 69 73 74 20 65 6c 65  next doclist ele
58f0: 6d 65 6e 74 2e 20 2a 2f 0a 20 20 69 66 28 20 70  ment. */.  if( p
5900: 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 21 3d 30  Reader->nData!=0
5910: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 5f 69   ){.    sqlite_i
5920: 6e 74 36 34 20 69 44 6f 63 69 64 44 65 6c 74 61  nt64 iDocidDelta
5930: 3b 0a 20 20 20 20 69 6e 74 20 69 44 75 6d 6d 79  ;.    int iDummy
5940: 2c 20 6e 20 3d 20 66 74 73 33 47 65 74 56 61 72  , n = fts3GetVar
5950: 69 6e 74 28 70 52 65 61 64 65 72 2d 3e 70 44 61  int(pReader->pDa
5960: 74 61 2c 20 26 69 44 6f 63 69 64 44 65 6c 74 61  ta, &iDocidDelta
5970: 29 3b 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e  );.    pReader->
5980: 69 44 6f 63 69 64 20 2b 3d 20 69 44 6f 63 69 64  iDocid += iDocid
5990: 44 65 6c 74 61 3b 0a 20 20 20 20 69 66 28 20 70  Delta;.    if( p
59a0: 52 65 61 64 65 72 2d 3e 69 54 79 70 65 3e 3d 44  Reader->iType>=D
59b0: 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 29 7b 0a 20  L_POSITIONS ){. 
59c0: 20 20 20 20 20 61 73 73 65 72 74 28 20 6e 3c 70       assert( n<p
59d0: 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 20 29 3b  Reader->nData );
59e0: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 31 20  .      while( 1 
59f0: 29 7b 0a 20 20 20 20 20 20 20 20 6e 20 2b 3d 20  ){.        n += 
5a00: 66 74 73 33 47 65 74 56 61 72 69 6e 74 33 32 28  fts3GetVarint32(
5a10: 70 52 65 61 64 65 72 2d 3e 70 44 61 74 61 2b 6e  pReader->pData+n
5a20: 2c 20 26 69 44 75 6d 6d 79 29 3b 0a 20 20 20 20  , &iDummy);.    
5a30: 20 20 20 20 61 73 73 65 72 74 28 20 6e 3c 3d 70      assert( n<=p
5a40: 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 20 29 3b  Reader->nData );
5a50: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 44 75  .        if( iDu
5a60: 6d 6d 79 3d 3d 50 4f 53 5f 45 4e 44 20 29 20 62  mmy==POS_END ) b
5a70: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 69 66  reak;.        if
5a80: 28 20 69 44 75 6d 6d 79 3d 3d 50 4f 53 5f 43 4f  ( iDummy==POS_CO
5a90: 4c 55 4d 4e 20 29 7b 0a 20 20 20 20 20 20 20 20  LUMN ){.        
5aa0: 20 20 6e 20 2b 3d 20 66 74 73 33 47 65 74 56 61    n += fts3GetVa
5ab0: 72 69 6e 74 33 32 28 70 52 65 61 64 65 72 2d 3e  rint32(pReader->
5ac0: 70 44 61 74 61 2b 6e 2c 20 26 69 44 75 6d 6d 79  pData+n, &iDummy
5ad0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73  );.          ass
5ae0: 65 72 74 28 20 6e 3c 70 52 65 61 64 65 72 2d 3e  ert( n<pReader->
5af0: 6e 44 61 74 61 20 29 3b 0a 20 20 20 20 20 20 20  nData );.       
5b00: 20 7d 65 6c 73 65 20 69 66 28 20 70 52 65 61 64   }else if( pRead
5b10: 65 72 2d 3e 69 54 79 70 65 3d 3d 44 4c 5f 50 4f  er->iType==DL_PO
5b20: 53 49 54 49 4f 4e 53 5f 4f 46 46 53 45 54 53 20  SITIONS_OFFSETS 
5b30: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6e 20 2b  ){.          n +
5b40: 3d 20 66 74 73 33 47 65 74 56 61 72 69 6e 74 33  = fts3GetVarint3
5b50: 32 28 70 52 65 61 64 65 72 2d 3e 70 44 61 74 61  2(pReader->pData
5b60: 2b 6e 2c 20 26 69 44 75 6d 6d 79 29 3b 0a 20 20  +n, &iDummy);.  
5b70: 20 20 20 20 20 20 20 20 6e 20 2b 3d 20 66 74 73          n += fts
5b80: 33 47 65 74 56 61 72 69 6e 74 33 32 28 70 52 65  3GetVarint32(pRe
5b90: 61 64 65 72 2d 3e 70 44 61 74 61 2b 6e 2c 20 26  ader->pData+n, &
5ba0: 69 44 75 6d 6d 79 29 3b 0a 20 20 20 20 20 20 20  iDummy);.       
5bb0: 20 20 20 61 73 73 65 72 74 28 20 6e 3c 70 52 65     assert( n<pRe
5bc0: 61 64 65 72 2d 3e 6e 44 61 74 61 20 29 3b 0a 20  ader->nData );. 
5bd0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
5be0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 52 65 61 64  .    }.    pRead
5bf0: 65 72 2d 3e 6e 45 6c 65 6d 65 6e 74 20 3d 20 6e  er->nElement = n
5c00: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 52  ;.    assert( pR
5c10: 65 61 64 65 72 2d 3e 6e 45 6c 65 6d 65 6e 74 3c  eader->nElement<
5c20: 3d 70 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 20  =pReader->nData 
5c30: 29 3b 0a 20 20 7d 0a 7d 0a 73 74 61 74 69 63 20  );.  }.}.static 
5c40: 76 6f 69 64 20 64 6c 72 49 6e 69 74 28 44 4c 52  void dlrInit(DLR
5c50: 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 2c 20  eader *pReader, 
5c60: 44 6f 63 4c 69 73 74 54 79 70 65 20 69 54 79 70  DocListType iTyp
5c70: 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e,.             
5c80: 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61         const cha
5c90: 72 20 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44  r *pData, int nD
5ca0: 61 74 61 29 7b 0a 20 20 61 73 73 65 72 74 28 20  ata){.  assert( 
5cb0: 70 44 61 74 61 21 3d 4e 55 4c 4c 20 26 26 20 6e  pData!=NULL && n
5cc0: 44 61 74 61 21 3d 30 20 29 3b 0a 20 20 70 52 65  Data!=0 );.  pRe
5cd0: 61 64 65 72 2d 3e 69 54 79 70 65 20 3d 20 69 54  ader->iType = iT
5ce0: 79 70 65 3b 0a 20 20 70 52 65 61 64 65 72 2d 3e  ype;.  pReader->
5cf0: 70 44 61 74 61 20 3d 20 70 44 61 74 61 3b 0a 20  pData = pData;. 
5d00: 20 70 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 20   pReader->nData 
5d10: 3d 20 6e 44 61 74 61 3b 0a 20 20 70 52 65 61 64  = nData;.  pRead
5d20: 65 72 2d 3e 6e 45 6c 65 6d 65 6e 74 20 3d 20 30  er->nElement = 0
5d30: 3b 0a 20 20 70 52 65 61 64 65 72 2d 3e 69 44 6f  ;.  pReader->iDo
5d40: 63 69 64 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 4c  cid = 0;..  /* L
5d50: 6f 61 64 20 74 68 65 20 66 69 72 73 74 20 65 6c  oad the first el
5d60: 65 6d 65 6e 74 27 73 20 64 61 74 61 2e 20 20 54  ement's data.  T
5d70: 68 65 72 65 20 6d 75 73 74 20 62 65 20 61 20 66  here must be a f
5d80: 69 72 73 74 20 65 6c 65 6d 65 6e 74 2e 20 2a 2f  irst element. */
5d90: 0a 20 20 64 6c 72 53 74 65 70 28 70 52 65 61 64  .  dlrStep(pRead
5da0: 65 72 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f  er);.}.static vo
5db0: 69 64 20 64 6c 72 44 65 73 74 72 6f 79 28 44 4c  id dlrDestroy(DL
5dc0: 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29  Reader *pReader)
5dd0: 7b 0a 20 20 53 43 52 41 4d 42 4c 45 28 70 52 65  {.  SCRAMBLE(pRe
5de0: 61 64 65 72 29 3b 0a 7d 0a 0a 23 69 66 6e 64 65  ader);.}..#ifnde
5df0: 66 20 4e 44 45 42 55 47 0a 2f 2a 20 56 65 72 69  f NDEBUG./* Veri
5e00: 66 79 20 74 68 61 74 20 74 68 65 20 64 6f 63 6c  fy that the docl
5e10: 69 73 74 20 63 61 6e 20 62 65 20 76 61 6c 69 64  ist can be valid
5e20: 6c 79 20 64 65 63 6f 64 65 64 2e 20 20 41 6c 73  ly decoded.  Als
5e30: 6f 20 72 65 74 75 72 6e 73 20 74 68 65 0a 2a 2a  o returns the.**
5e40: 20 6c 61 73 74 20 64 6f 63 69 64 20 66 6f 75 6e   last docid foun
5e50: 64 20 62 65 63 61 75 73 65 20 69 74 20 69 73 20  d because it is 
5e60: 63 6f 6e 76 65 6e 69 65 6e 74 20 69 6e 20 6f 74  convenient in ot
5e70: 68 65 72 20 61 73 73 65 72 74 69 6f 6e 73 20 66  her assertions f
5e80: 6f 72 0a 2a 2a 20 44 4c 57 72 69 74 65 72 2e 0a  or.** DLWriter..
5e90: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  */.static void d
5ea0: 6f 63 4c 69 73 74 56 61 6c 69 64 61 74 65 28 44  ocListValidate(D
5eb0: 6f 63 4c 69 73 74 54 79 70 65 20 69 54 79 70 65  ocListType iType
5ec0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 44  , const char *pD
5ed0: 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 2c 0a  ata, int nData,.
5ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ef0: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
5f00: 74 65 5f 69 6e 74 36 34 20 2a 70 4c 61 73 74 44  te_int64 *pLastD
5f10: 6f 63 69 64 29 7b 0a 20 20 73 71 6c 69 74 65 5f  ocid){.  sqlite_
5f20: 69 6e 74 36 34 20 69 50 72 65 76 44 6f 63 69 64  int64 iPrevDocid
5f30: 20 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28 20   = 0;.  assert( 
5f40: 6e 44 61 74 61 3e 30 20 29 3b 0a 20 20 61 73 73  nData>0 );.  ass
5f50: 65 72 74 28 20 70 44 61 74 61 21 3d 30 20 29 3b  ert( pData!=0 );
5f60: 0a 20 20 61 73 73 65 72 74 28 20 70 44 61 74 61  .  assert( pData
5f70: 2b 6e 44 61 74 61 3e 70 44 61 74 61 20 29 3b 0a  +nData>pData );.
5f80: 20 20 77 68 69 6c 65 28 20 6e 44 61 74 61 21 3d    while( nData!=
5f90: 30 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 5f  0 ){.    sqlite_
5fa0: 69 6e 74 36 34 20 69 44 6f 63 69 64 44 65 6c 74  int64 iDocidDelt
5fb0: 61 3b 0a 20 20 20 20 69 6e 74 20 6e 20 3d 20 66  a;.    int n = f
5fc0: 74 73 33 47 65 74 56 61 72 69 6e 74 28 70 44 61  ts3GetVarint(pDa
5fd0: 74 61 2c 20 26 69 44 6f 63 69 64 44 65 6c 74 61  ta, &iDocidDelta
5fe0: 29 3b 0a 20 20 20 20 69 50 72 65 76 44 6f 63 69  );.    iPrevDoci
5ff0: 64 20 2b 3d 20 69 44 6f 63 69 64 44 65 6c 74 61  d += iDocidDelta
6000: 3b 0a 20 20 20 20 69 66 28 20 69 54 79 70 65 3e  ;.    if( iType>
6010: 44 4c 5f 44 4f 43 49 44 53 20 29 7b 0a 20 20 20  DL_DOCIDS ){.   
6020: 20 20 20 69 6e 74 20 69 44 75 6d 6d 79 3b 0a 20     int iDummy;. 
6030: 20 20 20 20 20 77 68 69 6c 65 28 20 31 20 29 7b       while( 1 ){
6040: 0a 20 20 20 20 20 20 20 20 6e 20 2b 3d 20 66 74  .        n += ft
6050: 73 33 47 65 74 56 61 72 69 6e 74 33 32 28 70 44  s3GetVarint32(pD
6060: 61 74 61 2b 6e 2c 20 26 69 44 75 6d 6d 79 29 3b  ata+n, &iDummy);
6070: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 44 75  .        if( iDu
6080: 6d 6d 79 3d 3d 50 4f 53 5f 45 4e 44 20 29 20 62  mmy==POS_END ) b
6090: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 69 66  reak;.        if
60a0: 28 20 69 44 75 6d 6d 79 3d 3d 50 4f 53 5f 43 4f  ( iDummy==POS_CO
60b0: 4c 55 4d 4e 20 29 7b 0a 20 20 20 20 20 20 20 20  LUMN ){.        
60c0: 20 20 6e 20 2b 3d 20 66 74 73 33 47 65 74 56 61    n += fts3GetVa
60d0: 72 69 6e 74 33 32 28 70 44 61 74 61 2b 6e 2c 20  rint32(pData+n, 
60e0: 26 69 44 75 6d 6d 79 29 3b 0a 20 20 20 20 20 20  &iDummy);.      
60f0: 20 20 7d 65 6c 73 65 20 69 66 28 20 69 54 79 70    }else if( iTyp
6100: 65 3e 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 29  e>DL_POSITIONS )
6110: 7b 0a 20 20 20 20 20 20 20 20 20 20 6e 20 2b 3d  {.          n +=
6120: 20 66 74 73 33 47 65 74 56 61 72 69 6e 74 33 32   fts3GetVarint32
6130: 28 70 44 61 74 61 2b 6e 2c 20 26 69 44 75 6d 6d  (pData+n, &iDumm
6140: 79 29 3b 0a 20 20 20 20 20 20 20 20 20 20 6e 20  y);.          n 
6150: 2b 3d 20 66 74 73 33 47 65 74 56 61 72 69 6e 74  += fts3GetVarint
6160: 33 32 28 70 44 61 74 61 2b 6e 2c 20 26 69 44 75  32(pData+n, &iDu
6170: 6d 6d 79 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  mmy);.        }.
6180: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
6190: 6e 3c 3d 6e 44 61 74 61 20 29 3b 0a 20 20 20 20  n<=nData );.    
61a0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 61 73    }.    }.    as
61b0: 73 65 72 74 28 20 6e 3c 3d 6e 44 61 74 61 20 29  sert( n<=nData )
61c0: 3b 0a 20 20 20 20 70 44 61 74 61 20 2b 3d 20 6e  ;.    pData += n
61d0: 3b 0a 20 20 20 20 6e 44 61 74 61 20 2d 3d 20 6e  ;.    nData -= n
61e0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 4c 61 73  ;.  }.  if( pLas
61f0: 74 44 6f 63 69 64 20 29 20 2a 70 4c 61 73 74 44  tDocid ) *pLastD
6200: 6f 63 69 64 20 3d 20 69 50 72 65 76 44 6f 63 69  ocid = iPrevDoci
6210: 64 3b 0a 7d 0a 23 64 65 66 69 6e 65 20 41 53 53  d;.}.#define ASS
6220: 45 52 54 5f 56 41 4c 49 44 5f 44 4f 43 4c 49 53  ERT_VALID_DOCLIS
6230: 54 28 69 2c 20 70 2c 20 6e 2c 20 6f 29 20 64 6f  T(i, p, n, o) do
6240: 63 4c 69 73 74 56 61 6c 69 64 61 74 65 28 69 2c  cListValidate(i,
6250: 20 70 2c 20 6e 2c 20 6f 29 0a 23 65 6c 73 65 0a   p, n, o).#else.
6260: 23 64 65 66 69 6e 65 20 41 53 53 45 52 54 5f 56  #define ASSERT_V
6270: 41 4c 49 44 5f 44 4f 43 4c 49 53 54 28 69 2c 20  ALID_DOCLIST(i, 
6280: 70 2c 20 6e 2c 20 6f 29 20 61 73 73 65 72 74 28  p, n, o) assert(
6290: 20 31 20 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a 2a   1 ).#endif../**
62a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
62b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
62c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
62d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
62e0: 2a 2f 0a 2f 2a 20 44 4c 57 72 69 74 65 72 20 69  */./* DLWriter i
62f0: 73 20 75 73 65 64 20 74 6f 20 77 72 69 74 65 20  s used to write 
6300: 64 6f 63 6c 69 73 74 20 64 61 74 61 20 74 6f 20  doclist data to 
6310: 61 20 44 61 74 61 42 75 66 66 65 72 2e 20 20 44  a DataBuffer.  D
6320: 4c 57 72 69 74 65 72 0a 2a 2a 20 61 6c 77 61 79  LWriter.** alway
6330: 73 20 61 70 70 65 6e 64 73 20 74 6f 20 74 68 65  s appends to the
6340: 20 62 75 66 66 65 72 20 61 6e 64 20 64 6f 65 73   buffer and does
6350: 20 6e 6f 74 20 6f 77 6e 20 69 74 2e 0a 2a 2a 0a   not own it..**.
6360: 2a 2a 20 64 6c 77 49 6e 69 74 20 2d 20 69 6e 69  ** dlwInit - ini
6370: 74 69 61 6c 69 7a 65 20 74 6f 20 77 72 69 74 65  tialize to write
6380: 20 61 20 67 69 76 65 6e 20 74 79 70 65 20 64 6f   a given type do
6390: 63 6c 69 73 74 74 6f 20 61 20 62 75 66 66 65 72  clistto a buffer
63a0: 2e 0a 2a 2a 20 64 6c 77 44 65 73 74 72 6f 79 20  ..** dlwDestroy 
63b0: 2d 20 63 6c 65 61 72 20 74 68 65 20 77 72 69 74  - clear the writ
63c0: 65 72 27 73 20 6d 65 6d 6f 72 79 2e 20 20 44 6f  er's memory.  Do
63d0: 65 73 20 6e 6f 74 20 66 72 65 65 20 62 75 66 66  es not free buff
63e0: 65 72 2e 0a 2a 2a 20 64 6c 77 41 70 70 65 6e 64  er..** dlwAppend
63f0: 20 2d 20 61 70 70 65 6e 64 20 72 61 77 20 64 6f   - append raw do
6400: 63 6c 69 73 74 20 64 61 74 61 20 74 6f 20 62 75  clist data to bu
6410: 66 66 65 72 2e 0a 2a 2a 20 64 6c 77 43 6f 70 79  ffer..** dlwCopy
6420: 20 2d 20 63 6f 70 79 20 6e 65 78 74 20 64 6f 63   - copy next doc
6430: 6c 69 73 74 20 66 72 6f 6d 20 72 65 61 64 65 72  list from reader
6440: 20 74 6f 20 77 72 69 74 65 72 2e 0a 2a 2a 20 64   to writer..** d
6450: 6c 77 41 64 64 20 2d 20 63 6f 6e 73 74 72 75 63  lwAdd - construc
6460: 74 20 64 6f 63 6c 69 73 74 20 65 6c 65 6d 65 6e  t doclist elemen
6470: 74 20 61 6e 64 20 61 70 70 65 6e 64 20 74 6f 20  t and append to 
6480: 62 75 66 66 65 72 2e 0a 2a 2a 20 20 20 20 4f 6e  buffer..**    On
6490: 6c 79 20 61 70 70 6c 79 20 64 6c 77 41 64 64 28  ly apply dlwAdd(
64a0: 29 20 74 6f 20 44 4c 5f 44 4f 43 49 44 53 20 64  ) to DL_DOCIDS d
64b0: 6f 63 6c 69 73 74 73 20 28 65 6c 73 65 20 75 73  oclists (else us
64c0: 65 20 50 4c 57 72 69 74 65 72 29 2e 0a 2a 2f 0a  e PLWriter)..*/.
64d0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 44  typedef struct D
64e0: 4c 57 72 69 74 65 72 20 7b 0a 20 20 44 6f 63 4c  LWriter {.  DocL
64f0: 69 73 74 54 79 70 65 20 69 54 79 70 65 3b 0a 20  istType iType;. 
6500: 20 44 61 74 61 42 75 66 66 65 72 20 2a 62 3b 0a   DataBuffer *b;.
6510: 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69    sqlite_int64 i
6520: 50 72 65 76 44 6f 63 69 64 3b 0a 23 69 66 6e 64  PrevDocid;.#ifnd
6530: 65 66 20 4e 44 45 42 55 47 0a 20 20 69 6e 74 20  ef NDEBUG.  int 
6540: 68 61 73 5f 69 50 72 65 76 44 6f 63 69 64 3b 0a  has_iPrevDocid;.
6550: 23 65 6e 64 69 66 0a 7d 20 44 4c 57 72 69 74 65  #endif.} DLWrite
6560: 72 3b 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  r;..static void 
6570: 64 6c 77 49 6e 69 74 28 44 4c 57 72 69 74 65 72  dlwInit(DLWriter
6580: 20 2a 70 57 72 69 74 65 72 2c 20 44 6f 63 4c 69   *pWriter, DocLi
6590: 73 74 54 79 70 65 20 69 54 79 70 65 2c 20 44 61  stType iType, Da
65a0: 74 61 42 75 66 66 65 72 20 2a 62 29 7b 0a 20 20  taBuffer *b){.  
65b0: 70 57 72 69 74 65 72 2d 3e 62 20 3d 20 62 3b 0a  pWriter->b = b;.
65c0: 20 20 70 57 72 69 74 65 72 2d 3e 69 54 79 70 65    pWriter->iType
65d0: 20 3d 20 69 54 79 70 65 3b 0a 20 20 70 57 72 69   = iType;.  pWri
65e0: 74 65 72 2d 3e 69 50 72 65 76 44 6f 63 69 64 20  ter->iPrevDocid 
65f0: 3d 20 30 3b 0a 23 69 66 6e 64 65 66 20 4e 44 45  = 0;.#ifndef NDE
6600: 42 55 47 0a 20 20 70 57 72 69 74 65 72 2d 3e 68  BUG.  pWriter->h
6610: 61 73 5f 69 50 72 65 76 44 6f 63 69 64 20 3d 20  as_iPrevDocid = 
6620: 30 3b 0a 23 65 6e 64 69 66 0a 7d 0a 73 74 61 74  0;.#endif.}.stat
6630: 69 63 20 76 6f 69 64 20 64 6c 77 44 65 73 74 72  ic void dlwDestr
6640: 6f 79 28 44 4c 57 72 69 74 65 72 20 2a 70 57 72  oy(DLWriter *pWr
6650: 69 74 65 72 29 7b 0a 20 20 53 43 52 41 4d 42 4c  iter){.  SCRAMBL
6660: 45 28 70 57 72 69 74 65 72 29 3b 0a 7d 0a 2f 2a  E(pWriter);.}./*
6670: 20 69 46 69 72 73 74 44 6f 63 69 64 20 69 73 20   iFirstDocid is 
6680: 74 68 65 20 66 69 72 73 74 20 64 6f 63 69 64 20  the first docid 
6690: 69 6e 20 74 68 65 20 64 6f 63 6c 69 73 74 20 69  in the doclist i
66a0: 6e 20 70 44 61 74 61 2e 20 20 49 74 20 69 73 0a  n pData.  It is.
66b0: 2a 2a 20 6e 65 65 64 65 64 20 62 65 63 61 75 73  ** needed becaus
66c0: 65 20 70 44 61 74 61 20 6d 61 79 20 70 6f 69 6e  e pData may poin
66d0: 74 20 77 69 74 68 69 6e 20 61 20 6c 61 72 67 65  t within a large
66e0: 72 20 64 6f 63 6c 69 73 74 2c 20 69 6e 20 77 68  r doclist, in wh
66f0: 69 63 68 0a 2a 2a 20 63 61 73 65 20 74 68 65 20  ich.** case the 
6700: 66 69 72 73 74 20 69 74 65 6d 20 77 6f 75 6c 64  first item would
6710: 20 62 65 20 64 65 6c 74 61 2d 65 6e 63 6f 64 65   be delta-encode
6720: 64 2e 0a 2a 2a 0a 2a 2a 20 69 4c 61 73 74 44 6f  d..**.** iLastDo
6730: 63 69 64 20 69 73 20 74 68 65 20 66 69 6e 61 6c  cid is the final
6740: 20 64 6f 63 69 64 20 69 6e 20 74 68 65 20 64 6f   docid in the do
6750: 63 6c 69 73 74 20 69 6e 20 70 44 61 74 61 2e 20  clist in pData. 
6760: 20 49 74 20 69 73 0a 2a 2a 20 6e 65 65 64 65 64   It is.** needed
6770: 20 74 6f 20 63 72 65 61 74 65 20 74 68 65 20 6e   to create the n
6780: 65 77 20 69 50 72 65 76 44 6f 63 69 64 20 66 6f  ew iPrevDocid fo
6790: 72 20 66 75 74 75 72 65 20 64 65 6c 74 61 2d 65  r future delta-e
67a0: 6e 63 6f 64 69 6e 67 2e 20 20 54 68 65 0a 2a 2a  ncoding.  The.**
67b0: 20 63 6f 64 65 20 63 6f 75 6c 64 20 64 65 63 6f   code could deco
67c0: 64 65 20 74 68 65 20 70 61 73 73 65 64 20 64 6f  de the passed do
67d0: 63 6c 69 73 74 20 74 6f 20 72 65 63 72 65 61 74  clist to recreat
67e0: 65 20 69 4c 61 73 74 44 6f 63 69 64 2c 20 62 75  e iLastDocid, bu
67f0: 74 0a 2a 2a 20 74 68 65 20 6f 6e 6c 79 20 63 75  t.** the only cu
6800: 72 72 65 6e 74 20 75 73 65 72 20 28 64 6f 63 4c  rrent user (docL
6810: 69 73 74 4d 65 72 67 65 29 20 61 6c 72 65 61 64  istMerge) alread
6820: 79 20 68 61 73 20 64 65 63 6f 64 65 64 20 74 68  y has decoded th
6830: 69 73 0a 2a 2a 20 69 6e 66 6f 72 6d 61 74 69 6f  is.** informatio
6840: 6e 2e 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f 28 73 68  n..*/./* TODO(sh
6850: 65 73 73 29 20 54 68 69 73 20 68 61 73 20 62 65  ess) This has be
6860: 63 6f 6d 65 20 6a 75 73 74 20 61 20 68 65 6c 70  come just a help
6870: 65 72 20 66 6f 72 20 64 6f 63 4c 69 73 74 4d 65  er for docListMe
6880: 72 67 65 2e 0a 2a 2a 20 43 6f 6e 73 69 64 65 72  rge..** Consider
6890: 20 61 20 72 65 66 61 63 74 6f 72 20 74 6f 20 6d   a refactor to m
68a0: 61 6b 65 20 74 68 69 73 20 63 6c 65 61 6e 65 72  ake this cleaner
68b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
68c0: 20 64 6c 77 41 70 70 65 6e 64 28 44 4c 57 72 69   dlwAppend(DLWri
68d0: 74 65 72 20 2a 70 57 72 69 74 65 72 2c 0a 20 20  ter *pWriter,.  
68e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
68f0: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
6900: 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61  pData, int nData
6910: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
6920: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 5f 69          sqlite_i
6930: 6e 74 36 34 20 69 46 69 72 73 74 44 6f 63 69 64  nt64 iFirstDocid
6940: 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69  , sqlite_int64 i
6950: 4c 61 73 74 44 6f 63 69 64 29 7b 0a 20 20 73 71  LastDocid){.  sq
6960: 6c 69 74 65 5f 69 6e 74 36 34 20 69 44 6f 63 69  lite_int64 iDoci
6970: 64 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 63 5b  d = 0;.  char c[
6980: 56 41 52 49 4e 54 5f 4d 41 58 5d 3b 0a 20 20 69  VARINT_MAX];.  i
6990: 6e 74 20 6e 46 69 72 73 74 4f 6c 64 2c 20 6e 46  nt nFirstOld, nF
69a0: 69 72 73 74 4e 65 77 3b 20 20 20 20 20 2f 2a 20  irstNew;     /* 
69b0: 4f 6c 64 20 61 6e 64 20 6e 65 77 20 76 61 72 69  Old and new vari
69c0: 6e 74 20 6c 65 6e 20 6f 66 20 66 69 72 73 74 20  nt len of first 
69d0: 64 6f 63 69 64 2e 20 2a 2f 0a 23 69 66 6e 64 65  docid. */.#ifnde
69e0: 66 20 4e 44 45 42 55 47 0a 20 20 73 71 6c 69 74  f NDEBUG.  sqlit
69f0: 65 5f 69 6e 74 36 34 20 69 4c 61 73 74 44 6f 63  e_int64 iLastDoc
6a00: 69 64 44 65 6c 74 61 3b 0a 23 65 6e 64 69 66 0a  idDelta;.#endif.
6a10: 0a 20 20 2f 2a 20 52 65 63 6f 64 65 20 74 68 65  .  /* Recode the
6a20: 20 69 6e 69 74 69 61 6c 20 64 6f 63 69 64 20 61   initial docid a
6a30: 73 20 64 65 6c 74 61 20 66 72 6f 6d 20 69 50 72  s delta from iPr
6a40: 65 76 44 6f 63 69 64 2e 20 2a 2f 0a 20 20 6e 46  evDocid. */.  nF
6a50: 69 72 73 74 4f 6c 64 20 3d 20 66 74 73 33 47 65  irstOld = fts3Ge
6a60: 74 56 61 72 69 6e 74 28 70 44 61 74 61 2c 20 26  tVarint(pData, &
6a70: 69 44 6f 63 69 64 29 3b 0a 20 20 61 73 73 65 72  iDocid);.  asser
6a80: 74 28 20 6e 46 69 72 73 74 4f 6c 64 3c 6e 44 61  t( nFirstOld<nDa
6a90: 74 61 20 7c 7c 20 28 6e 46 69 72 73 74 4f 6c 64  ta || (nFirstOld
6aa0: 3d 3d 6e 44 61 74 61 20 26 26 20 70 57 72 69 74  ==nData && pWrit
6ab0: 65 72 2d 3e 69 54 79 70 65 3d 3d 44 4c 5f 44 4f  er->iType==DL_DO
6ac0: 43 49 44 53 29 20 29 3b 0a 20 20 6e 46 69 72 73  CIDS) );.  nFirs
6ad0: 74 4e 65 77 20 3d 20 66 74 73 33 50 75 74 56 61  tNew = fts3PutVa
6ae0: 72 69 6e 74 28 63 2c 20 69 46 69 72 73 74 44 6f  rint(c, iFirstDo
6af0: 63 69 64 2d 70 57 72 69 74 65 72 2d 3e 69 50 72  cid-pWriter->iPr
6b00: 65 76 44 6f 63 69 64 29 3b 0a 0a 20 20 2f 2a 20  evDocid);..  /* 
6b10: 56 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20  Verify that the 
6b20: 69 6e 63 6f 6d 69 6e 67 20 64 6f 63 6c 69 73 74  incoming doclist
6b30: 20 69 73 20 76 61 6c 69 64 20 41 4e 44 20 74 68   is valid AND th
6b40: 61 74 20 69 74 20 65 6e 64 73 20 77 69 74 68 0a  at it ends with.
6b50: 20 20 2a 2a 20 74 68 65 20 65 78 70 65 63 74 65    ** the expecte
6b60: 64 20 64 6f 63 69 64 2e 20 20 54 68 69 73 20 69  d docid.  This i
6b70: 73 20 65 73 73 65 6e 74 69 61 6c 20 62 65 63 61  s essential beca
6b80: 75 73 65 20 77 65 27 6c 6c 20 74 72 75 73 74 20  use we'll trust 
6b90: 74 68 69 73 0a 20 20 2a 2a 20 64 6f 63 69 64 20  this.  ** docid 
6ba0: 69 6e 20 66 75 74 75 72 65 20 64 65 6c 74 61 2d  in future delta-
6bb0: 65 6e 63 6f 64 69 6e 67 2e 0a 20 20 2a 2f 0a 20  encoding..  */. 
6bc0: 20 41 53 53 45 52 54 5f 56 41 4c 49 44 5f 44 4f   ASSERT_VALID_DO
6bd0: 43 4c 49 53 54 28 70 57 72 69 74 65 72 2d 3e 69  CLIST(pWriter->i
6be0: 54 79 70 65 2c 20 70 44 61 74 61 2c 20 6e 44 61  Type, pData, nDa
6bf0: 74 61 2c 20 26 69 4c 61 73 74 44 6f 63 69 64 44  ta, &iLastDocidD
6c00: 65 6c 74 61 29 3b 0a 20 20 61 73 73 65 72 74 28  elta);.  assert(
6c10: 20 69 4c 61 73 74 44 6f 63 69 64 3d 3d 69 46 69   iLastDocid==iFi
6c20: 72 73 74 44 6f 63 69 64 2d 69 44 6f 63 69 64 2b  rstDocid-iDocid+
6c30: 69 4c 61 73 74 44 6f 63 69 64 44 65 6c 74 61 20  iLastDocidDelta 
6c40: 29 3b 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20  );..  /* Append 
6c50: 72 65 63 6f 64 65 64 20 69 6e 69 74 69 61 6c 20  recoded initial 
6c60: 64 6f 63 69 64 20 61 6e 64 20 65 76 65 72 79 74  docid and everyt
6c70: 68 69 6e 67 20 65 6c 73 65 2e 20 20 52 65 73 74  hing else.  Rest
6c80: 20 6f 66 20 64 6f 63 69 64 73 0a 20 20 2a 2a 20   of docids.  ** 
6c90: 73 68 6f 75 6c 64 20 68 61 76 65 20 62 65 65 6e  should have been
6ca0: 20 64 65 6c 74 61 2d 65 6e 63 6f 64 65 64 20 66   delta-encoded f
6cb0: 72 6f 6d 20 70 72 65 76 69 6f 75 73 20 69 6e 69  rom previous ini
6cc0: 74 69 61 6c 20 64 6f 63 69 64 2e 0a 20 20 2a 2f  tial docid..  */
6cd0: 0a 20 20 69 66 28 20 6e 46 69 72 73 74 4f 6c 64  .  if( nFirstOld
6ce0: 3c 6e 44 61 74 61 20 29 7b 0a 20 20 20 20 64 61  <nData ){.    da
6cf0: 74 61 42 75 66 66 65 72 41 70 70 65 6e 64 32 28  taBufferAppend2(
6d00: 70 57 72 69 74 65 72 2d 3e 62 2c 20 63 2c 20 6e  pWriter->b, c, n
6d10: 46 69 72 73 74 4e 65 77 2c 0a 20 20 20 20 20 20  FirstNew,.      
6d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d30: 70 44 61 74 61 2b 6e 46 69 72 73 74 4f 6c 64 2c  pData+nFirstOld,
6d40: 20 6e 44 61 74 61 2d 6e 46 69 72 73 74 4f 6c 64   nData-nFirstOld
6d50: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
6d60: 64 61 74 61 42 75 66 66 65 72 41 70 70 65 6e 64  dataBufferAppend
6d70: 28 70 57 72 69 74 65 72 2d 3e 62 2c 20 63 2c 20  (pWriter->b, c, 
6d80: 6e 46 69 72 73 74 4e 65 77 29 3b 0a 20 20 7d 0a  nFirstNew);.  }.
6d90: 20 20 70 57 72 69 74 65 72 2d 3e 69 50 72 65 76    pWriter->iPrev
6da0: 44 6f 63 69 64 20 3d 20 69 4c 61 73 74 44 6f 63  Docid = iLastDoc
6db0: 69 64 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  id;.}.static voi
6dc0: 64 20 64 6c 77 43 6f 70 79 28 44 4c 57 72 69 74  d dlwCopy(DLWrit
6dd0: 65 72 20 2a 70 57 72 69 74 65 72 2c 20 44 4c 52  er *pWriter, DLR
6de0: 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b  eader *pReader){
6df0: 0a 20 20 64 6c 77 41 70 70 65 6e 64 28 70 57 72  .  dlwAppend(pWr
6e00: 69 74 65 72 2c 20 64 6c 72 44 6f 63 44 61 74 61  iter, dlrDocData
6e10: 28 70 52 65 61 64 65 72 29 2c 20 64 6c 72 44 6f  (pReader), dlrDo
6e20: 63 44 61 74 61 42 79 74 65 73 28 70 52 65 61 64  cDataBytes(pRead
6e30: 65 72 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20  er),.           
6e40: 20 64 6c 72 44 6f 63 69 64 28 70 52 65 61 64 65   dlrDocid(pReade
6e50: 72 29 2c 20 64 6c 72 44 6f 63 69 64 28 70 52 65  r), dlrDocid(pRe
6e60: 61 64 65 72 29 29 3b 0a 7d 0a 73 74 61 74 69 63  ader));.}.static
6e70: 20 76 6f 69 64 20 64 6c 77 41 64 64 28 44 4c 57   void dlwAdd(DLW
6e80: 72 69 74 65 72 20 2a 70 57 72 69 74 65 72 2c 20  riter *pWriter, 
6e90: 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 44 6f  sqlite_int64 iDo
6ea0: 63 69 64 29 7b 0a 20 20 63 68 61 72 20 63 5b 56  cid){.  char c[V
6eb0: 41 52 49 4e 54 5f 4d 41 58 5d 3b 0a 20 20 69 6e  ARINT_MAX];.  in
6ec0: 74 20 6e 20 3d 20 66 74 73 33 50 75 74 56 61 72  t n = fts3PutVar
6ed0: 69 6e 74 28 63 2c 20 69 44 6f 63 69 64 2d 70 57  int(c, iDocid-pW
6ee0: 72 69 74 65 72 2d 3e 69 50 72 65 76 44 6f 63 69  riter->iPrevDoci
6ef0: 64 29 3b 0a 0a 20 20 2f 2a 20 44 6f 63 69 64 73  d);..  /* Docids
6f00: 20 6d 75 73 74 20 61 73 63 65 6e 64 2e 20 2a 2f   must ascend. */
6f10: 0a 20 20 61 73 73 65 72 74 28 20 21 70 57 72 69  .  assert( !pWri
6f20: 74 65 72 2d 3e 68 61 73 5f 69 50 72 65 76 44 6f  ter->has_iPrevDo
6f30: 63 69 64 20 7c 7c 20 69 44 6f 63 69 64 3e 70 57  cid || iDocid>pW
6f40: 72 69 74 65 72 2d 3e 69 50 72 65 76 44 6f 63 69  riter->iPrevDoci
6f50: 64 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  d );.  assert( p
6f60: 57 72 69 74 65 72 2d 3e 69 54 79 70 65 3d 3d 44  Writer->iType==D
6f70: 4c 5f 44 4f 43 49 44 53 20 29 3b 0a 0a 20 20 64  L_DOCIDS );..  d
6f80: 61 74 61 42 75 66 66 65 72 41 70 70 65 6e 64 28  ataBufferAppend(
6f90: 70 57 72 69 74 65 72 2d 3e 62 2c 20 63 2c 20 6e  pWriter->b, c, n
6fa0: 29 3b 0a 20 20 70 57 72 69 74 65 72 2d 3e 69 50  );.  pWriter->iP
6fb0: 72 65 76 44 6f 63 69 64 20 3d 20 69 44 6f 63 69  revDocid = iDoci
6fc0: 64 3b 0a 23 69 66 6e 64 65 66 20 4e 44 45 42 55  d;.#ifndef NDEBU
6fd0: 47 0a 20 20 70 57 72 69 74 65 72 2d 3e 68 61 73  G.  pWriter->has
6fe0: 5f 69 50 72 65 76 44 6f 63 69 64 20 3d 20 31 3b  _iPrevDocid = 1;
6ff0: 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 2a 2a 2a  .#endif.}../****
7000: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7010: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7020: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7030: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
7040: 0a 2f 2a 20 50 4c 52 65 61 64 65 72 20 69 73 20  ./* PLReader is 
7050: 75 73 65 64 20 74 6f 20 72 65 61 64 20 64 61 74  used to read dat
7060: 61 20 66 72 6f 6d 20 61 20 64 6f 63 75 6d 65 6e  a from a documen
7070: 74 27 73 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73  t's position lis
7080: 74 2e 20 20 41 73 0a 2a 2a 20 74 68 65 20 63 61  t.  As.** the ca
7090: 6c 6c 65 72 20 73 74 65 70 73 20 74 68 72 6f 75  ller steps throu
70a0: 67 68 20 74 68 65 20 6c 69 73 74 2c 20 64 61 74  gh the list, dat
70b0: 61 20 69 73 20 63 61 63 68 65 64 20 73 6f 20 74  a is cached so t
70c0: 68 61 74 20 76 61 72 69 6e 74 73 0a 2a 2a 20 6f  hat varints.** o
70d0: 6e 6c 79 20 6e 65 65 64 20 74 6f 20 62 65 20 64  nly need to be d
70e0: 65 63 6f 64 65 64 20 6f 6e 63 65 2e 0a 2a 2a 0a  ecoded once..**.
70f0: 2a 2a 20 70 6c 72 49 6e 69 74 2c 20 70 6c 72 44  ** plrInit, plrD
7100: 65 73 74 72 6f 79 20 2d 20 63 72 65 61 74 65 2f  estroy - create/
7110: 64 65 73 74 72 6f 79 20 61 20 72 65 61 64 65 72  destroy a reader
7120: 2e 0a 2a 2a 20 70 6c 72 43 6f 6c 75 6d 6e 2c 20  ..** plrColumn, 
7130: 70 6c 72 50 6f 73 69 74 69 6f 6e 2c 20 70 6c 72  plrPosition, plr
7140: 53 74 61 72 74 4f 66 66 73 65 74 2c 20 70 6c 72  StartOffset, plr
7150: 45 6e 64 4f 66 66 73 65 74 20 2d 20 61 63 63 65  EndOffset - acce
7160: 73 73 6f 72 73 0a 2a 2a 20 70 6c 72 41 74 45 6e  ssors.** plrAtEn
7170: 64 20 2d 20 61 74 20 65 6e 64 20 6f 66 20 73 74  d - at end of st
7180: 72 65 61 6d 2c 20 6f 6e 6c 79 20 63 61 6c 6c 20  ream, only call 
7190: 70 6c 72 44 65 73 74 72 6f 79 20 6f 6e 63 65 20  plrDestroy once 
71a0: 74 72 75 65 2e 0a 2a 2a 20 70 6c 72 53 74 65 70  true..** plrStep
71b0: 20 2d 20 73 74 65 70 20 74 6f 20 74 68 65 20 6e   - step to the n
71c0: 65 78 74 20 65 6c 65 6d 65 6e 74 2e 0a 2a 2f 0a  ext element..*/.
71d0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 50  typedef struct P
71e0: 4c 52 65 61 64 65 72 20 7b 0a 20 20 2f 2a 20 54  LReader {.  /* T
71f0: 68 65 73 65 20 72 65 66 65 72 20 74 6f 20 74 68  hese refer to th
7200: 65 20 6e 65 78 74 20 70 6f 73 69 74 69 6f 6e 27  e next position'
7210: 73 20 64 61 74 61 2e 20 20 6e 44 61 74 61 20 77  s data.  nData w
7220: 69 6c 6c 20 72 65 61 63 68 20 30 20 77 68 65 6e  ill reach 0 when
7230: 0a 20 20 2a 2a 20 72 65 61 64 69 6e 67 20 74 68  .  ** reading th
7240: 65 20 6c 61 73 74 20 70 6f 73 69 74 69 6f 6e 2c  e last position,
7250: 20 73 6f 20 70 6c 72 53 74 65 70 28 29 20 73 69   so plrStep() si
7260: 67 6e 61 6c 73 20 45 4f 46 20 62 79 20 73 65 74  gnals EOF by set
7270: 74 69 6e 67 0a 20 20 2a 2a 20 70 44 61 74 61 20  ting.  ** pData 
7280: 74 6f 20 4e 55 4c 4c 2e 0a 20 20 2a 2f 0a 20 20  to NULL..  */.  
7290: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 44 61 74  const char *pDat
72a0: 61 3b 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a  a;.  int nData;.
72b0: 0a 20 20 44 6f 63 4c 69 73 74 54 79 70 65 20 69  .  DocListType i
72c0: 54 79 70 65 3b 0a 20 20 69 6e 74 20 69 43 6f 6c  Type;.  int iCol
72d0: 75 6d 6e 3b 20 20 20 20 20 20 20 20 20 2f 2a 20  umn;         /* 
72e0: 74 68 65 20 6c 61 73 74 20 63 6f 6c 75 6d 6e 20  the last column 
72f0: 72 65 61 64 20 2a 2f 0a 20 20 69 6e 74 20 69 50  read */.  int iP
7300: 6f 73 69 74 69 6f 6e 3b 20 20 20 20 20 20 20 2f  osition;       /
7310: 2a 20 74 68 65 20 6c 61 73 74 20 70 6f 73 69 74  * the last posit
7320: 69 6f 6e 20 72 65 61 64 20 2a 2f 0a 20 20 69 6e  ion read */.  in
7330: 74 20 69 53 74 61 72 74 4f 66 66 73 65 74 3b 20  t iStartOffset; 
7340: 20 20 20 2f 2a 20 74 68 65 20 6c 61 73 74 20 73     /* the last s
7350: 74 61 72 74 20 6f 66 66 73 65 74 20 72 65 61 64  tart offset read
7360: 20 2a 2f 0a 20 20 69 6e 74 20 69 45 6e 64 4f 66   */.  int iEndOf
7370: 66 73 65 74 3b 20 20 20 20 20 20 2f 2a 20 74 68  fset;      /* th
7380: 65 20 6c 61 73 74 20 65 6e 64 20 6f 66 66 73 65  e last end offse
7390: 74 20 72 65 61 64 20 2a 2f 0a 7d 20 50 4c 52 65  t read */.} PLRe
73a0: 61 64 65 72 3b 0a 0a 73 74 61 74 69 63 20 69 6e  ader;..static in
73b0: 74 20 70 6c 72 41 74 45 6e 64 28 50 4c 52 65 61  t plrAtEnd(PLRea
73c0: 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20  der *pReader){. 
73d0: 20 72 65 74 75 72 6e 20 70 52 65 61 64 65 72 2d   return pReader-
73e0: 3e 70 44 61 74 61 3d 3d 4e 55 4c 4c 3b 0a 7d 0a  >pData==NULL;.}.
73f0: 73 74 61 74 69 63 20 69 6e 74 20 70 6c 72 43 6f  static int plrCo
7400: 6c 75 6d 6e 28 50 4c 52 65 61 64 65 72 20 2a 70  lumn(PLReader *p
7410: 52 65 61 64 65 72 29 7b 0a 20 20 61 73 73 65 72  Reader){.  asser
7420: 74 28 20 21 70 6c 72 41 74 45 6e 64 28 70 52 65  t( !plrAtEnd(pRe
7430: 61 64 65 72 29 20 29 3b 0a 20 20 72 65 74 75 72  ader) );.  retur
7440: 6e 20 70 52 65 61 64 65 72 2d 3e 69 43 6f 6c 75  n pReader->iColu
7450: 6d 6e 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74  mn;.}.static int
7460: 20 70 6c 72 50 6f 73 69 74 69 6f 6e 28 50 4c 52   plrPosition(PLR
7470: 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b  eader *pReader){
7480: 0a 20 20 61 73 73 65 72 74 28 20 21 70 6c 72 41  .  assert( !plrA
7490: 74 45 6e 64 28 70 52 65 61 64 65 72 29 20 29 3b  tEnd(pReader) );
74a0: 0a 20 20 72 65 74 75 72 6e 20 70 52 65 61 64 65  .  return pReade
74b0: 72 2d 3e 69 50 6f 73 69 74 69 6f 6e 3b 0a 7d 0a  r->iPosition;.}.
74c0: 73 74 61 74 69 63 20 69 6e 74 20 70 6c 72 53 74  static int plrSt
74d0: 61 72 74 4f 66 66 73 65 74 28 50 4c 52 65 61 64  artOffset(PLRead
74e0: 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20  er *pReader){.  
74f0: 61 73 73 65 72 74 28 20 21 70 6c 72 41 74 45 6e  assert( !plrAtEn
7500: 64 28 70 52 65 61 64 65 72 29 20 29 3b 0a 20 20  d(pReader) );.  
7510: 72 65 74 75 72 6e 20 70 52 65 61 64 65 72 2d 3e  return pReader->
7520: 69 53 74 61 72 74 4f 66 66 73 65 74 3b 0a 7d 0a  iStartOffset;.}.
7530: 73 74 61 74 69 63 20 69 6e 74 20 70 6c 72 45 6e  static int plrEn
7540: 64 4f 66 66 73 65 74 28 50 4c 52 65 61 64 65 72  dOffset(PLReader
7550: 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 61 73   *pReader){.  as
7560: 73 65 72 74 28 20 21 70 6c 72 41 74 45 6e 64 28  sert( !plrAtEnd(
7570: 70 52 65 61 64 65 72 29 20 29 3b 0a 20 20 72 65  pReader) );.  re
7580: 74 75 72 6e 20 70 52 65 61 64 65 72 2d 3e 69 45  turn pReader->iE
7590: 6e 64 4f 66 66 73 65 74 3b 0a 7d 0a 73 74 61 74  ndOffset;.}.stat
75a0: 69 63 20 76 6f 69 64 20 70 6c 72 53 74 65 70 28  ic void plrStep(
75b0: 50 4c 52 65 61 64 65 72 20 2a 70 52 65 61 64 65  PLReader *pReade
75c0: 72 29 7b 0a 20 20 69 6e 74 20 69 2c 20 6e 3b 0a  r){.  int i, n;.
75d0: 0a 20 20 61 73 73 65 72 74 28 20 21 70 6c 72 41  .  assert( !plrA
75e0: 74 45 6e 64 28 70 52 65 61 64 65 72 29 20 29 3b  tEnd(pReader) );
75f0: 0a 0a 20 20 69 66 28 20 70 52 65 61 64 65 72 2d  ..  if( pReader-
7600: 3e 6e 44 61 74 61 3d 3d 30 20 29 7b 0a 20 20 20  >nData==0 ){.   
7610: 20 70 52 65 61 64 65 72 2d 3e 70 44 61 74 61 20   pReader->pData 
7620: 3d 20 4e 55 4c 4c 3b 0a 20 20 20 20 72 65 74 75  = NULL;.    retu
7630: 72 6e 3b 0a 20 20 7d 0a 0a 20 20 6e 20 3d 20 66  rn;.  }..  n = f
7640: 74 73 33 47 65 74 56 61 72 69 6e 74 33 32 28 70  ts3GetVarint32(p
7650: 52 65 61 64 65 72 2d 3e 70 44 61 74 61 2c 20 26  Reader->pData, &
7660: 69 29 3b 0a 20 20 69 66 28 20 69 3d 3d 50 4f 53  i);.  if( i==POS
7670: 5f 43 4f 4c 55 4d 4e 20 29 7b 0a 20 20 20 20 6e  _COLUMN ){.    n
7680: 20 2b 3d 20 66 74 73 33 47 65 74 56 61 72 69 6e   += fts3GetVarin
7690: 74 33 32 28 70 52 65 61 64 65 72 2d 3e 70 44 61  t32(pReader->pDa
76a0: 74 61 2b 6e 2c 20 26 70 52 65 61 64 65 72 2d 3e  ta+n, &pReader->
76b0: 69 43 6f 6c 75 6d 6e 29 3b 0a 20 20 20 20 70 52  iColumn);.    pR
76c0: 65 61 64 65 72 2d 3e 69 50 6f 73 69 74 69 6f 6e  eader->iPosition
76d0: 20 3d 20 30 3b 0a 20 20 20 20 70 52 65 61 64 65   = 0;.    pReade
76e0: 72 2d 3e 69 53 74 61 72 74 4f 66 66 73 65 74 20  r->iStartOffset 
76f0: 3d 20 30 3b 0a 20 20 20 20 6e 20 2b 3d 20 66 74  = 0;.    n += ft
7700: 73 33 47 65 74 56 61 72 69 6e 74 33 32 28 70 52  s3GetVarint32(pR
7710: 65 61 64 65 72 2d 3e 70 44 61 74 61 2b 6e 2c 20  eader->pData+n, 
7720: 26 69 29 3b 0a 20 20 7d 0a 20 20 2f 2a 20 53 68  &i);.  }.  /* Sh
7730: 6f 75 6c 64 20 6e 65 76 65 72 20 73 65 65 20 61  ould never see a
7740: 64 6a 61 63 65 6e 74 20 63 6f 6c 75 6d 6e 20 63  djacent column c
7750: 68 61 6e 67 65 73 2e 20 2a 2f 0a 20 20 61 73 73  hanges. */.  ass
7760: 65 72 74 28 20 69 21 3d 50 4f 53 5f 43 4f 4c 55  ert( i!=POS_COLU
7770: 4d 4e 20 29 3b 0a 0a 20 20 69 66 28 20 69 3d 3d  MN );..  if( i==
7780: 50 4f 53 5f 45 4e 44 20 29 7b 0a 20 20 20 20 70  POS_END ){.    p
7790: 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 20 3d 20  Reader->nData = 
77a0: 30 3b 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e  0;.    pReader->
77b0: 70 44 61 74 61 20 3d 20 4e 55 4c 4c 3b 0a 20 20  pData = NULL;.  
77c0: 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20    return;.  }.. 
77d0: 20 70 52 65 61 64 65 72 2d 3e 69 50 6f 73 69 74   pReader->iPosit
77e0: 69 6f 6e 20 2b 3d 20 69 2d 50 4f 53 5f 42 41 53  ion += i-POS_BAS
77f0: 45 3b 0a 20 20 69 66 28 20 70 52 65 61 64 65 72  E;.  if( pReader
7800: 2d 3e 69 54 79 70 65 3d 3d 44 4c 5f 50 4f 53 49  ->iType==DL_POSI
7810: 54 49 4f 4e 53 5f 4f 46 46 53 45 54 53 20 29 7b  TIONS_OFFSETS ){
7820: 0a 20 20 20 20 6e 20 2b 3d 20 66 74 73 33 47 65  .    n += fts3Ge
7830: 74 56 61 72 69 6e 74 33 32 28 70 52 65 61 64 65  tVarint32(pReade
7840: 72 2d 3e 70 44 61 74 61 2b 6e 2c 20 26 69 29 3b  r->pData+n, &i);
7850: 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e 69 53  .    pReader->iS
7860: 74 61 72 74 4f 66 66 73 65 74 20 2b 3d 20 69 3b  tartOffset += i;
7870: 0a 20 20 20 20 6e 20 2b 3d 20 66 74 73 33 47 65  .    n += fts3Ge
7880: 74 56 61 72 69 6e 74 33 32 28 70 52 65 61 64 65  tVarint32(pReade
7890: 72 2d 3e 70 44 61 74 61 2b 6e 2c 20 26 69 29 3b  r->pData+n, &i);
78a0: 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e 69 45  .    pReader->iE
78b0: 6e 64 4f 66 66 73 65 74 20 3d 20 70 52 65 61 64  ndOffset = pRead
78c0: 65 72 2d 3e 69 53 74 61 72 74 4f 66 66 73 65 74  er->iStartOffset
78d0: 2b 69 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74  +i;.  }.  assert
78e0: 28 20 6e 3c 3d 70 52 65 61 64 65 72 2d 3e 6e 44  ( n<=pReader->nD
78f0: 61 74 61 20 29 3b 0a 20 20 70 52 65 61 64 65 72  ata );.  pReader
7900: 2d 3e 70 44 61 74 61 20 2b 3d 20 6e 3b 0a 20 20  ->pData += n;.  
7910: 70 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 20 2d  pReader->nData -
7920: 3d 20 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  = n;.}..static v
7930: 6f 69 64 20 70 6c 72 49 6e 69 74 28 50 4c 52 65  oid plrInit(PLRe
7940: 61 64 65 72 20 2a 70 52 65 61 64 65 72 2c 20 44  ader *pReader, D
7950: 4c 52 65 61 64 65 72 20 2a 70 44 4c 52 65 61 64  LReader *pDLRead
7960: 65 72 29 7b 0a 20 20 70 52 65 61 64 65 72 2d 3e  er){.  pReader->
7970: 70 44 61 74 61 20 3d 20 64 6c 72 50 6f 73 44 61  pData = dlrPosDa
7980: 74 61 28 70 44 4c 52 65 61 64 65 72 29 3b 0a 20  ta(pDLReader);. 
7990: 20 70 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 20   pReader->nData 
79a0: 3d 20 64 6c 72 50 6f 73 44 61 74 61 4c 65 6e 28  = dlrPosDataLen(
79b0: 70 44 4c 52 65 61 64 65 72 29 3b 0a 20 20 70 52  pDLReader);.  pR
79c0: 65 61 64 65 72 2d 3e 69 54 79 70 65 20 3d 20 70  eader->iType = p
79d0: 44 4c 52 65 61 64 65 72 2d 3e 69 54 79 70 65 3b  DLReader->iType;
79e0: 0a 20 20 70 52 65 61 64 65 72 2d 3e 69 43 6f 6c  .  pReader->iCol
79f0: 75 6d 6e 20 3d 20 30 3b 0a 20 20 70 52 65 61 64  umn = 0;.  pRead
7a00: 65 72 2d 3e 69 50 6f 73 69 74 69 6f 6e 20 3d 20  er->iPosition = 
7a10: 30 3b 0a 20 20 70 52 65 61 64 65 72 2d 3e 69 53  0;.  pReader->iS
7a20: 74 61 72 74 4f 66 66 73 65 74 20 3d 20 30 3b 0a  tartOffset = 0;.
7a30: 20 20 70 52 65 61 64 65 72 2d 3e 69 45 6e 64 4f    pReader->iEndO
7a40: 66 66 73 65 74 20 3d 20 30 3b 0a 20 20 70 6c 72  ffset = 0;.  plr
7a50: 53 74 65 70 28 70 52 65 61 64 65 72 29 3b 0a 7d  Step(pReader);.}
7a60: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 6c 72  .static void plr
7a70: 44 65 73 74 72 6f 79 28 50 4c 52 65 61 64 65 72  Destroy(PLReader
7a80: 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 53 43   *pReader){.  SC
7a90: 52 41 4d 42 4c 45 28 70 52 65 61 64 65 72 29 3b  RAMBLE(pReader);
7aa0: 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .}../***********
7ab0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ac0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ad0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
7ae0: 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 20 50 4c 57  ********/./* PLW
7af0: 72 69 74 65 72 20 69 73 20 75 73 65 64 20 69 6e  riter is used in
7b00: 20 63 6f 6e 73 74 72 75 63 74 69 6e 67 20 61 20   constructing a 
7b10: 64 6f 63 75 6d 65 6e 74 27 73 20 70 6f 73 69 74  document's posit
7b20: 69 6f 6e 20 6c 69 73 74 2e 20 20 41 73 20 61 0a  ion list.  As a.
7b30: 2a 2a 20 63 6f 6e 76 65 6e 69 65 6e 63 65 2c 20  ** convenience, 
7b40: 69 66 20 69 54 79 70 65 20 69 73 20 44 4c 5f 44  if iType is DL_D
7b50: 4f 43 49 44 53 2c 20 50 4c 57 72 69 74 65 72 20  OCIDS, PLWriter 
7b60: 62 65 63 6f 6d 65 73 20 61 20 6e 6f 2d 6f 70 2e  becomes a no-op.
7b70: 0a 2a 2a 20 50 4c 57 72 69 74 65 72 20 77 72 69  .** PLWriter wri
7b80: 74 65 73 20 74 6f 20 74 68 65 20 61 73 73 6f 63  tes to the assoc
7b90: 69 61 74 65 64 20 44 4c 57 72 69 74 65 72 27 73  iated DLWriter's
7ba0: 20 62 75 66 66 65 72 2e 0a 2a 2a 0a 2a 2a 20 70   buffer..**.** p
7bb0: 6c 77 49 6e 69 74 20 2d 20 69 6e 69 74 20 66 6f  lwInit - init fo
7bc0: 72 20 77 72 69 74 69 6e 67 20 61 20 64 6f 63 75  r writing a docu
7bd0: 6d 65 6e 74 27 73 20 70 6f 73 6c 69 73 74 2e 0a  ment's poslist..
7be0: 2a 2a 20 70 6c 77 44 65 73 74 72 6f 79 20 2d 20  ** plwDestroy - 
7bf0: 63 6c 65 61 72 20 61 20 77 72 69 74 65 72 2e 0a  clear a writer..
7c00: 2a 2a 20 70 6c 77 41 64 64 20 2d 20 61 70 70 65  ** plwAdd - appe
7c10: 6e 64 20 70 6f 73 69 74 69 6f 6e 20 61 6e 64 20  nd position and 
7c20: 6f 66 66 73 65 74 20 69 6e 66 6f 72 6d 61 74 69  offset informati
7c30: 6f 6e 2e 0a 2a 2a 20 70 6c 77 43 6f 70 79 20 2d  on..** plwCopy -
7c40: 20 63 6f 70 79 20 6e 65 78 74 20 70 6f 73 69 74   copy next posit
7c50: 69 6f 6e 27 73 20 64 61 74 61 20 66 72 6f 6d 20  ion's data from 
7c60: 72 65 61 64 65 72 20 74 6f 20 77 72 69 74 65 72  reader to writer
7c70: 2e 0a 2a 2a 20 70 6c 77 54 65 72 6d 69 6e 61 74  ..** plwTerminat
7c80: 65 20 2d 20 61 64 64 20 61 6e 79 20 6e 65 63 65  e - add any nece
7c90: 73 73 61 72 79 20 64 6f 63 6c 69 73 74 20 74 65  ssary doclist te
7ca0: 72 6d 69 6e 61 74 6f 72 2e 0a 2a 2a 0a 2a 2a 20  rminator..**.** 
7cb0: 43 61 6c 6c 69 6e 67 20 70 6c 77 41 64 64 28 29  Calling plwAdd()
7cc0: 20 61 66 74 65 72 20 70 6c 77 54 65 72 6d 69 6e   after plwTermin
7cd0: 61 74 65 28 29 20 6d 61 79 20 72 65 73 75 6c 74  ate() may result
7ce0: 20 69 6e 20 61 20 63 6f 72 72 75 70 74 0a 2a 2a   in a corrupt.**
7cf0: 20 64 6f 63 6c 69 73 74 2e 0a 2a 2f 0a 2f 2a 20   doclist..*/./* 
7d00: 54 4f 44 4f 28 73 68 65 73 73 29 20 55 6e 74 69  TODO(shess) Unti
7d10: 6c 20 77 65 27 76 65 20 77 72 69 74 74 65 6e 20  l we've written 
7d20: 74 68 65 20 73 65 63 6f 6e 64 20 69 74 65 6d 2c  the second item,
7d30: 20 77 65 20 63 61 6e 20 63 61 63 68 65 20 74 68   we can cache th
7d40: 65 0a 2a 2a 20 66 69 72 73 74 20 69 74 65 6d 27  e.** first item'
7d50: 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 20 20  s information.  
7d60: 54 68 65 6e 20 77 65 27 64 20 68 61 76 65 20 74  Then we'd have t
7d70: 68 72 65 65 20 73 74 61 74 65 73 3a 0a 2a 2a 0a  hree states:.**.
7d80: 2a 2a 20 2d 20 69 6e 69 74 69 61 6c 69 7a 65 64  ** - initialized
7d90: 20 77 69 74 68 20 64 6f 63 69 64 2c 20 6e 6f 20   with docid, no 
7da0: 70 6f 73 69 74 69 6f 6e 73 2e 0a 2a 2a 20 2d 20  positions..** - 
7db0: 64 6f 63 69 64 20 61 6e 64 20 6f 6e 65 20 70 6f  docid and one po
7dc0: 73 69 74 69 6f 6e 2e 0a 2a 2a 20 2d 20 64 6f 63  sition..** - doc
7dd0: 69 64 20 61 6e 64 20 6d 75 6c 74 69 70 6c 65 20  id and multiple 
7de0: 70 6f 73 69 74 69 6f 6e 73 2e 0a 2a 2a 0a 2a 2a  positions..**.**
7df0: 20 4f 6e 6c 79 20 74 68 65 20 6c 61 73 74 20 73   Only the last s
7e00: 74 61 74 65 20 6e 65 65 64 73 20 74 6f 20 61 63  tate needs to ac
7e10: 74 75 61 6c 6c 79 20 77 72 69 74 65 20 74 6f 20  tually write to 
7e20: 64 6c 77 2d 3e 62 2c 20 77 68 69 63 68 20 77 6f  dlw->b, which wo
7e30: 75 6c 64 0a 2a 2a 20 62 65 20 61 6e 20 69 6d 70  uld.** be an imp
7e40: 72 6f 76 65 6d 65 6e 74 20 69 6e 20 74 68 65 20  rovement in the 
7e50: 44 4c 43 6f 6c 6c 65 63 74 6f 72 20 63 61 73 65  DLCollector case
7e60: 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72  ..*/.typedef str
7e70: 75 63 74 20 50 4c 57 72 69 74 65 72 20 7b 0a 20  uct PLWriter {. 
7e80: 20 44 4c 57 72 69 74 65 72 20 2a 64 6c 77 3b 0a   DLWriter *dlw;.
7e90: 0a 20 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 3b 20  .  int iColumn; 
7ea0: 20 20 20 2f 2a 20 74 68 65 20 6c 61 73 74 20 63     /* the last c
7eb0: 6f 6c 75 6d 6e 20 77 72 69 74 74 65 6e 20 2a 2f  olumn written */
7ec0: 0a 20 20 69 6e 74 20 69 50 6f 73 3b 20 20 20 20  .  int iPos;    
7ed0: 20 20 20 2f 2a 20 74 68 65 20 6c 61 73 74 20 70     /* the last p
7ee0: 6f 73 69 74 69 6f 6e 20 77 72 69 74 74 65 6e 20  osition written 
7ef0: 2a 2f 0a 20 20 69 6e 74 20 69 4f 66 66 73 65 74  */.  int iOffset
7f00: 3b 20 20 20 20 2f 2a 20 74 68 65 20 6c 61 73 74  ;    /* the last
7f10: 20 73 74 61 72 74 20 6f 66 66 73 65 74 20 77 72   start offset wr
7f20: 69 74 74 65 6e 20 2a 2f 0a 7d 20 50 4c 57 72 69  itten */.} PLWri
7f30: 74 65 72 3b 0a 0a 2f 2a 20 54 4f 44 4f 28 73 68  ter;../* TODO(sh
7f40: 65 73 73 29 20 49 6e 20 74 68 65 20 63 61 73 65  ess) In the case
7f50: 20 77 68 65 72 65 20 74 68 65 20 70 61 72 65 6e   where the paren
7f60: 74 20 69 73 20 72 65 61 64 69 6e 67 20 74 68 65  t is reading the
7f70: 73 65 20 76 61 6c 75 65 73 0a 2a 2a 20 66 72 6f  se values.** fro
7f80: 6d 20 61 20 50 4c 52 65 61 64 65 72 2c 20 77 65  m a PLReader, we
7f90: 20 63 6f 75 6c 64 20 6f 70 74 69 6d 69 7a 65 20   could optimize 
7fa0: 74 6f 20 61 20 63 6f 70 79 20 69 66 20 74 68 61  to a copy if tha
7fb0: 74 20 50 4c 52 65 61 64 65 72 20 68 61 73 0a 2a  t PLReader has.*
7fc0: 2a 20 74 68 65 20 73 61 6d 65 20 74 79 70 65 20  * the same type 
7fd0: 61 73 20 70 57 72 69 74 65 72 2e 0a 2a 2f 0a 73  as pWriter..*/.s
7fe0: 74 61 74 69 63 20 76 6f 69 64 20 70 6c 77 41 64  tatic void plwAd
7ff0: 64 28 50 4c 57 72 69 74 65 72 20 2a 70 57 72 69  d(PLWriter *pWri
8000: 74 65 72 2c 20 69 6e 74 20 69 43 6f 6c 75 6d 6e  ter, int iColumn
8010: 2c 20 69 6e 74 20 69 50 6f 73 2c 0a 20 20 20 20  , int iPos,.    
8020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
8030: 6e 74 20 69 53 74 61 72 74 4f 66 66 73 65 74 2c  nt iStartOffset,
8040: 20 69 6e 74 20 69 45 6e 64 4f 66 66 73 65 74 29   int iEndOffset)
8050: 7b 0a 20 20 2f 2a 20 57 6f 72 73 74 2d 63 61 73  {.  /* Worst-cas
8060: 65 20 73 70 61 63 65 20 66 6f 72 20 50 4f 53 5f  e space for POS_
8070: 43 4f 4c 55 4d 4e 2c 20 69 43 6f 6c 75 6d 6e 2c  COLUMN, iColumn,
8080: 20 69 50 6f 73 44 65 6c 74 61 2c 0a 20 20 2a 2a   iPosDelta,.  **
8090: 20 69 53 74 61 72 74 4f 66 66 73 65 74 44 65 6c   iStartOffsetDel
80a0: 74 61 2c 20 61 6e 64 20 69 45 6e 64 4f 66 66 73  ta, and iEndOffs
80b0: 65 74 44 65 6c 74 61 2e 0a 20 20 2a 2f 0a 20 20  etDelta..  */.  
80c0: 63 68 61 72 20 63 5b 35 2a 56 41 52 49 4e 54 5f  char c[5*VARINT_
80d0: 4d 41 58 5d 3b 0a 20 20 69 6e 74 20 6e 20 3d 20  MAX];.  int n = 
80e0: 30 3b 0a 0a 20 20 2f 2a 20 42 61 6e 20 70 6c 77  0;..  /* Ban plw
80f0: 41 64 64 28 29 20 61 66 74 65 72 20 70 6c 77 54  Add() after plwT
8100: 65 72 6d 69 6e 61 74 65 28 29 2e 20 2a 2f 0a 20  erminate(). */. 
8110: 20 61 73 73 65 72 74 28 20 70 57 72 69 74 65 72   assert( pWriter
8120: 2d 3e 69 50 6f 73 21 3d 2d 31 20 29 3b 0a 0a 20  ->iPos!=-1 );.. 
8130: 20 69 66 28 20 70 57 72 69 74 65 72 2d 3e 64 6c   if( pWriter->dl
8140: 77 2d 3e 69 54 79 70 65 3d 3d 44 4c 5f 44 4f 43  w->iType==DL_DOC
8150: 49 44 53 20 29 20 72 65 74 75 72 6e 3b 0a 0a 20  IDS ) return;.. 
8160: 20 69 66 28 20 69 43 6f 6c 75 6d 6e 21 3d 70 57   if( iColumn!=pW
8170: 72 69 74 65 72 2d 3e 69 43 6f 6c 75 6d 6e 20 29  riter->iColumn )
8180: 7b 0a 20 20 20 20 6e 20 2b 3d 20 66 74 73 33 50  {.    n += fts3P
8190: 75 74 56 61 72 69 6e 74 28 63 2b 6e 2c 20 50 4f  utVarint(c+n, PO
81a0: 53 5f 43 4f 4c 55 4d 4e 29 3b 0a 20 20 20 20 6e  S_COLUMN);.    n
81b0: 20 2b 3d 20 66 74 73 33 50 75 74 56 61 72 69 6e   += fts3PutVarin
81c0: 74 28 63 2b 6e 2c 20 69 43 6f 6c 75 6d 6e 29 3b  t(c+n, iColumn);
81d0: 0a 20 20 20 20 70 57 72 69 74 65 72 2d 3e 69 43  .    pWriter->iC
81e0: 6f 6c 75 6d 6e 20 3d 20 69 43 6f 6c 75 6d 6e 3b  olumn = iColumn;
81f0: 0a 20 20 20 20 70 57 72 69 74 65 72 2d 3e 69 50  .    pWriter->iP
8200: 6f 73 20 3d 20 30 3b 0a 20 20 20 20 70 57 72 69  os = 0;.    pWri
8210: 74 65 72 2d 3e 69 4f 66 66 73 65 74 20 3d 20 30  ter->iOffset = 0
8220: 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20  ;.  }.  assert( 
8230: 69 50 6f 73 3e 3d 70 57 72 69 74 65 72 2d 3e 69  iPos>=pWriter->i
8240: 50 6f 73 20 29 3b 0a 20 20 6e 20 2b 3d 20 66 74  Pos );.  n += ft
8250: 73 33 50 75 74 56 61 72 69 6e 74 28 63 2b 6e 2c  s3PutVarint(c+n,
8260: 20 50 4f 53 5f 42 41 53 45 2b 28 69 50 6f 73 2d   POS_BASE+(iPos-
8270: 70 57 72 69 74 65 72 2d 3e 69 50 6f 73 29 29 3b  pWriter->iPos));
8280: 0a 20 20 70 57 72 69 74 65 72 2d 3e 69 50 6f 73  .  pWriter->iPos
8290: 20 3d 20 69 50 6f 73 3b 0a 20 20 69 66 28 20 70   = iPos;.  if( p
82a0: 57 72 69 74 65 72 2d 3e 64 6c 77 2d 3e 69 54 79  Writer->dlw->iTy
82b0: 70 65 3d 3d 44 4c 5f 50 4f 53 49 54 49 4f 4e 53  pe==DL_POSITIONS
82c0: 5f 4f 46 46 53 45 54 53 20 29 7b 0a 20 20 20 20  _OFFSETS ){.    
82d0: 61 73 73 65 72 74 28 20 69 53 74 61 72 74 4f 66  assert( iStartOf
82e0: 66 73 65 74 3e 3d 70 57 72 69 74 65 72 2d 3e 69  fset>=pWriter->i
82f0: 4f 66 66 73 65 74 20 29 3b 0a 20 20 20 20 6e 20  Offset );.    n 
8300: 2b 3d 20 66 74 73 33 50 75 74 56 61 72 69 6e 74  += fts3PutVarint
8310: 28 63 2b 6e 2c 20 69 53 74 61 72 74 4f 66 66 73  (c+n, iStartOffs
8320: 65 74 2d 70 57 72 69 74 65 72 2d 3e 69 4f 66 66  et-pWriter->iOff
8330: 73 65 74 29 3b 0a 20 20 20 20 70 57 72 69 74 65  set);.    pWrite
8340: 72 2d 3e 69 4f 66 66 73 65 74 20 3d 20 69 53 74  r->iOffset = iSt
8350: 61 72 74 4f 66 66 73 65 74 3b 0a 20 20 20 20 61  artOffset;.    a
8360: 73 73 65 72 74 28 20 69 45 6e 64 4f 66 66 73 65  ssert( iEndOffse
8370: 74 3e 3d 69 53 74 61 72 74 4f 66 66 73 65 74 20  t>=iStartOffset 
8380: 29 3b 0a 20 20 20 20 6e 20 2b 3d 20 66 74 73 33  );.    n += fts3
8390: 50 75 74 56 61 72 69 6e 74 28 63 2b 6e 2c 20 69  PutVarint(c+n, i
83a0: 45 6e 64 4f 66 66 73 65 74 2d 69 53 74 61 72 74  EndOffset-iStart
83b0: 4f 66 66 73 65 74 29 3b 0a 20 20 7d 0a 20 20 64  Offset);.  }.  d
83c0: 61 74 61 42 75 66 66 65 72 41 70 70 65 6e 64 28  ataBufferAppend(
83d0: 70 57 72 69 74 65 72 2d 3e 64 6c 77 2d 3e 62 2c  pWriter->dlw->b,
83e0: 20 63 2c 20 6e 29 3b 0a 7d 0a 73 74 61 74 69 63   c, n);.}.static
83f0: 20 76 6f 69 64 20 70 6c 77 43 6f 70 79 28 50 4c   void plwCopy(PL
8400: 57 72 69 74 65 72 20 2a 70 57 72 69 74 65 72 2c  Writer *pWriter,
8410: 20 50 4c 52 65 61 64 65 72 20 2a 70 52 65 61 64   PLReader *pRead
8420: 65 72 29 7b 0a 20 20 70 6c 77 41 64 64 28 70 57  er){.  plwAdd(pW
8430: 72 69 74 65 72 2c 20 70 6c 72 43 6f 6c 75 6d 6e  riter, plrColumn
8440: 28 70 52 65 61 64 65 72 29 2c 20 70 6c 72 50 6f  (pReader), plrPo
8450: 73 69 74 69 6f 6e 28 70 52 65 61 64 65 72 29 2c  sition(pReader),
8460: 0a 20 20 20 20 20 20 20 20 20 70 6c 72 53 74 61  .         plrSta
8470: 72 74 4f 66 66 73 65 74 28 70 52 65 61 64 65 72  rtOffset(pReader
8480: 29 2c 20 70 6c 72 45 6e 64 4f 66 66 73 65 74 28  ), plrEndOffset(
8490: 70 52 65 61 64 65 72 29 29 3b 0a 7d 0a 73 74 61  pReader));.}.sta
84a0: 74 69 63 20 76 6f 69 64 20 70 6c 77 49 6e 69 74  tic void plwInit
84b0: 28 50 4c 57 72 69 74 65 72 20 2a 70 57 72 69 74  (PLWriter *pWrit
84c0: 65 72 2c 20 44 4c 57 72 69 74 65 72 20 2a 64 6c  er, DLWriter *dl
84d0: 77 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  w, sqlite_int64 
84e0: 69 44 6f 63 69 64 29 7b 0a 20 20 63 68 61 72 20  iDocid){.  char 
84f0: 63 5b 56 41 52 49 4e 54 5f 4d 41 58 5d 3b 0a 20  c[VARINT_MAX];. 
8500: 20 69 6e 74 20 6e 3b 0a 0a 20 20 70 57 72 69 74   int n;..  pWrit
8510: 65 72 2d 3e 64 6c 77 20 3d 20 64 6c 77 3b 0a 0a  er->dlw = dlw;..
8520: 20 20 2f 2a 20 44 6f 63 69 64 73 20 6d 75 73 74    /* Docids must
8530: 20 61 73 63 65 6e 64 2e 20 2a 2f 0a 20 20 61 73   ascend. */.  as
8540: 73 65 72 74 28 20 21 70 57 72 69 74 65 72 2d 3e  sert( !pWriter->
8550: 64 6c 77 2d 3e 68 61 73 5f 69 50 72 65 76 44 6f  dlw->has_iPrevDo
8560: 63 69 64 20 7c 7c 20 69 44 6f 63 69 64 3e 70 57  cid || iDocid>pW
8570: 72 69 74 65 72 2d 3e 64 6c 77 2d 3e 69 50 72 65  riter->dlw->iPre
8580: 76 44 6f 63 69 64 20 29 3b 0a 20 20 6e 20 3d 20  vDocid );.  n = 
8590: 66 74 73 33 50 75 74 56 61 72 69 6e 74 28 63 2c  fts3PutVarint(c,
85a0: 20 69 44 6f 63 69 64 2d 70 57 72 69 74 65 72 2d   iDocid-pWriter-
85b0: 3e 64 6c 77 2d 3e 69 50 72 65 76 44 6f 63 69 64  >dlw->iPrevDocid
85c0: 29 3b 0a 20 20 64 61 74 61 42 75 66 66 65 72 41  );.  dataBufferA
85d0: 70 70 65 6e 64 28 70 57 72 69 74 65 72 2d 3e 64  ppend(pWriter->d
85e0: 6c 77 2d 3e 62 2c 20 63 2c 20 6e 29 3b 0a 20 20  lw->b, c, n);.  
85f0: 70 57 72 69 74 65 72 2d 3e 64 6c 77 2d 3e 69 50  pWriter->dlw->iP
8600: 72 65 76 44 6f 63 69 64 20 3d 20 69 44 6f 63 69  revDocid = iDoci
8610: 64 3b 0a 23 69 66 6e 64 65 66 20 4e 44 45 42 55  d;.#ifndef NDEBU
8620: 47 0a 20 20 70 57 72 69 74 65 72 2d 3e 64 6c 77  G.  pWriter->dlw
8630: 2d 3e 68 61 73 5f 69 50 72 65 76 44 6f 63 69 64  ->has_iPrevDocid
8640: 20 3d 20 31 3b 0a 23 65 6e 64 69 66 0a 0a 20 20   = 1;.#endif..  
8650: 70 57 72 69 74 65 72 2d 3e 69 43 6f 6c 75 6d 6e  pWriter->iColumn
8660: 20 3d 20 30 3b 0a 20 20 70 57 72 69 74 65 72 2d   = 0;.  pWriter-
8670: 3e 69 50 6f 73 20 3d 20 30 3b 0a 20 20 70 57 72  >iPos = 0;.  pWr
8680: 69 74 65 72 2d 3e 69 4f 66 66 73 65 74 20 3d 20  iter->iOffset = 
8690: 30 3b 0a 7d 0a 2f 2a 20 54 4f 44 4f 28 73 68 65  0;.}./* TODO(she
86a0: 73 73 29 20 53 68 6f 75 6c 64 20 70 6c 77 44 65  ss) Should plwDe
86b0: 73 74 72 6f 79 28 29 20 61 6c 73 6f 20 74 65 72  stroy() also ter
86c0: 6d 69 6e 61 74 65 20 74 68 65 20 64 6f 63 6c 69  minate the docli
86d0: 73 74 3f 20 20 42 75 74 0a 2a 2a 20 74 68 65 6e  st?  But.** then
86e0: 20 70 6c 77 44 65 73 74 72 6f 79 28 29 20 77 6f   plwDestroy() wo
86f0: 75 6c 64 20 6e 6f 20 6c 6f 6e 67 65 72 20 62 65  uld no longer be
8700: 20 6a 75 73 74 20 61 20 64 65 73 74 72 75 63 74   just a destruct
8710: 6f 72 2c 20 69 74 20 77 6f 75 6c 64 0a 2a 2a 20  or, it would.** 
8720: 61 6c 73 6f 20 62 65 20 64 6f 69 6e 67 20 77 6f  also be doing wo
8730: 72 6b 2c 20 77 68 69 63 68 20 69 73 6e 27 74 20  rk, which isn't 
8740: 63 6f 6e 73 69 73 74 65 6e 74 20 77 69 74 68 20  consistent with 
8750: 74 68 65 20 6f 76 65 72 61 6c 6c 20 69 64 69 6f  the overall idio
8760: 6d 2e 0a 2a 2a 20 41 6e 6f 74 68 65 72 20 6f 70  m..** Another op
8770: 74 69 6f 6e 20 77 6f 75 6c 64 20 62 65 20 66 6f  tion would be fo
8780: 72 20 70 6c 77 41 64 64 28 29 20 74 6f 20 61 6c  r plwAdd() to al
8790: 77 61 79 73 20 61 70 70 65 6e 64 20 61 6e 79 20  ways append any 
87a0: 6e 65 63 65 73 73 61 72 79 0a 2a 2a 20 74 65 72  necessary.** ter
87b0: 6d 69 6e 61 74 6f 72 2c 20 73 6f 20 74 68 61 74  minator, so that
87c0: 20 74 68 65 20 6f 75 74 70 75 74 20 69 73 20 61   the output is a
87d0: 6c 77 61 79 73 20 63 6f 72 72 65 63 74 2e 20 20  lways correct.  
87e0: 42 75 74 20 74 68 61 74 20 77 6f 75 6c 64 0a 2a  But that would.*
87f0: 2a 20 61 64 64 20 69 6e 63 72 65 6d 65 6e 74 61  * add incrementa
8800: 6c 20 77 6f 72 6b 20 74 6f 20 74 68 65 20 63 6f  l work to the co
8810: 6d 6d 6f 6e 20 63 61 73 65 20 77 69 74 68 20 74  mmon case with t
8820: 68 65 20 6f 6e 6c 79 20 62 65 6e 65 66 69 74 20  he only benefit 
8830: 62 65 69 6e 67 0a 2a 2a 20 41 50 49 20 65 6c 65  being.** API ele
8840: 67 61 6e 63 65 2e 20 20 50 75 6e 74 20 66 6f 72  gance.  Punt for
8850: 20 6e 6f 77 2e 0a 2a 2f 0a 73 74 61 74 69 63 20   now..*/.static 
8860: 76 6f 69 64 20 70 6c 77 54 65 72 6d 69 6e 61 74  void plwTerminat
8870: 65 28 50 4c 57 72 69 74 65 72 20 2a 70 57 72 69  e(PLWriter *pWri
8880: 74 65 72 29 7b 0a 20 20 69 66 28 20 70 57 72 69  ter){.  if( pWri
8890: 74 65 72 2d 3e 64 6c 77 2d 3e 69 54 79 70 65 3e  ter->dlw->iType>
88a0: 44 4c 5f 44 4f 43 49 44 53 20 29 7b 0a 20 20 20  DL_DOCIDS ){.   
88b0: 20 63 68 61 72 20 63 5b 56 41 52 49 4e 54 5f 4d   char c[VARINT_M
88c0: 41 58 5d 3b 0a 20 20 20 20 69 6e 74 20 6e 20 3d  AX];.    int n =
88d0: 20 66 74 73 33 50 75 74 56 61 72 69 6e 74 28 63   fts3PutVarint(c
88e0: 2c 20 50 4f 53 5f 45 4e 44 29 3b 0a 20 20 20 20  , POS_END);.    
88f0: 64 61 74 61 42 75 66 66 65 72 41 70 70 65 6e 64  dataBufferAppend
8900: 28 70 57 72 69 74 65 72 2d 3e 64 6c 77 2d 3e 62  (pWriter->dlw->b
8910: 2c 20 63 2c 20 6e 29 3b 0a 20 20 7d 0a 23 69 66  , c, n);.  }.#if
8920: 6e 64 65 66 20 4e 44 45 42 55 47 0a 20 20 2f 2a  ndef NDEBUG.  /*
8930: 20 4d 61 72 6b 20 61 73 20 74 65 72 6d 69 6e 61   Mark as termina
8940: 74 65 64 20 66 6f 72 20 61 73 73 65 72 74 20 69  ted for assert i
8950: 6e 20 70 6c 77 41 64 64 28 29 2e 20 2a 2f 0a 20  n plwAdd(). */. 
8960: 20 70 57 72 69 74 65 72 2d 3e 69 50 6f 73 20 3d   pWriter->iPos =
8970: 20 2d 31 3b 0a 23 65 6e 64 69 66 0a 7d 0a 73 74   -1;.#endif.}.st
8980: 61 74 69 63 20 76 6f 69 64 20 70 6c 77 44 65 73  atic void plwDes
8990: 74 72 6f 79 28 50 4c 57 72 69 74 65 72 20 2a 70  troy(PLWriter *p
89a0: 57 72 69 74 65 72 29 7b 0a 20 20 53 43 52 41 4d  Writer){.  SCRAM
89b0: 42 4c 45 28 70 57 72 69 74 65 72 29 3b 0a 7d 0a  BLE(pWriter);.}.
89c0: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
89d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
89e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
89f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8a00: 2a 2a 2a 2a 2a 2f 0a 2f 2a 20 44 4c 43 6f 6c 6c  *****/./* DLColl
8a10: 65 63 74 6f 72 20 77 72 61 70 73 20 50 4c 57 72  ector wraps PLWr
8a20: 69 74 65 72 20 61 6e 64 20 44 4c 57 72 69 74 65  iter and DLWrite
8a30: 72 20 74 6f 20 70 72 6f 76 69 64 65 20 61 0a 2a  r to provide a.*
8a40: 2a 20 64 79 6e 61 6d 69 63 61 6c 6c 79 2d 61 6c  * dynamically-al
8a50: 6c 6f 63 61 74 65 64 20 64 6f 63 6c 69 73 74 20  located doclist 
8a60: 61 72 65 61 20 74 6f 20 75 73 65 20 64 75 72 69  area to use duri
8a70: 6e 67 20 74 6f 6b 65 6e 69 7a 61 74 69 6f 6e 2e  ng tokenization.
8a80: 0a 2a 2a 0a 2a 2a 20 64 6c 63 4e 65 77 20 2d 20  .**.** dlcNew - 
8a90: 6d 61 6c 6c 6f 63 20 75 70 20 61 6e 64 20 69 6e  malloc up and in
8aa0: 69 74 69 61 6c 69 7a 65 20 61 20 63 6f 6c 6c 65  itialize a colle
8ab0: 63 74 6f 72 2e 0a 2a 2a 20 64 6c 63 44 65 6c 65  ctor..** dlcDele
8ac0: 74 65 20 2d 20 64 65 73 74 72 6f 79 20 61 20 63  te - destroy a c
8ad0: 6f 6c 6c 65 63 74 6f 72 20 61 6e 64 20 61 6c 6c  ollector and all
8ae0: 20 63 6f 6e 74 61 69 6e 65 64 20 69 74 65 6d 73   contained items
8af0: 2e 0a 2a 2a 20 64 6c 63 41 64 64 50 6f 73 20 2d  ..** dlcAddPos -
8b00: 20 61 70 70 65 6e 64 20 70 6f 73 69 74 69 6f 6e   append position
8b10: 20 61 6e 64 20 6f 66 66 73 65 74 20 69 6e 66 6f   and offset info
8b20: 72 6d 61 74 69 6f 6e 2e 0a 2a 2a 20 64 6c 63 41  rmation..** dlcA
8b30: 64 64 44 6f 63 6c 69 73 74 20 2d 20 61 64 64 20  ddDoclist - add 
8b40: 74 68 65 20 63 6f 6c 6c 65 63 74 65 64 20 64 6f  the collected do
8b50: 63 6c 69 73 74 20 74 6f 20 74 68 65 20 67 69 76  clist to the giv
8b60: 65 6e 20 62 75 66 66 65 72 2e 0a 2a 2a 20 64 6c  en buffer..** dl
8b70: 63 4e 65 78 74 20 2d 20 74 65 72 6d 69 6e 61 74  cNext - terminat
8b80: 65 20 74 68 65 20 63 75 72 72 65 6e 74 20 64 6f  e the current do
8b90: 63 75 6d 65 6e 74 20 61 6e 64 20 6f 70 65 6e 20  cument and open 
8ba0: 61 6e 6f 74 68 65 72 2e 0a 2a 2f 0a 74 79 70 65  another..*/.type
8bb0: 64 65 66 20 73 74 72 75 63 74 20 44 4c 43 6f 6c  def struct DLCol
8bc0: 6c 65 63 74 6f 72 20 7b 0a 20 20 44 61 74 61 42  lector {.  DataB
8bd0: 75 66 66 65 72 20 62 3b 0a 20 20 44 4c 57 72 69  uffer b;.  DLWri
8be0: 74 65 72 20 64 6c 77 3b 0a 20 20 50 4c 57 72 69  ter dlw;.  PLWri
8bf0: 74 65 72 20 70 6c 77 3b 0a 7d 20 44 4c 43 6f 6c  ter plw;.} DLCol
8c00: 6c 65 63 74 6f 72 3b 0a 0a 2f 2a 20 54 4f 44 4f  lector;../* TODO
8c10: 28 73 68 65 73 73 29 20 54 68 69 73 20 63 6f 75  (shess) This cou
8c20: 6c 64 20 61 6c 73 6f 20 62 65 20 64 6f 6e 65 20  ld also be done 
8c30: 62 79 20 63 61 6c 6c 69 6e 67 20 70 6c 77 54 65  by calling plwTe
8c40: 72 6d 69 6e 61 74 65 28 29 20 61 6e 64 0a 2a 2a  rminate() and.**
8c50: 20 64 61 74 61 42 75 66 66 65 72 41 70 70 65 6e   dataBufferAppen
8c60: 64 28 29 2e 20 20 49 20 74 72 69 65 64 20 74 68  d().  I tried th
8c70: 61 74 2c 20 65 78 70 65 63 74 69 6e 67 20 6e 6f  at, expecting no
8c80: 6d 69 6e 61 6c 20 70 65 72 66 6f 72 6d 61 6e 63  minal performanc
8c90: 65 0a 2a 2a 20 64 69 66 66 65 72 65 6e 63 65 73  e.** differences
8ca0: 2c 20 62 75 74 20 69 74 20 73 65 65 6d 65 64 20  , but it seemed 
8cb0: 74 6f 20 70 72 65 74 74 79 20 72 65 6c 69 61 62  to pretty reliab
8cc0: 6c 79 20 62 65 20 77 6f 72 74 68 20 31 25 20 74  ly be worth 1% t
8cd0: 6f 20 63 6f 64 65 0a 2a 2a 20 69 74 20 74 68 69  o code.** it thi
8ce0: 73 20 77 61 79 2e 20 20 49 20 73 75 73 70 65 63  s way.  I suspec
8cf0: 74 20 69 74 20 69 73 20 74 68 65 20 69 6e 63 72  t it is the incr
8d00: 65 6d 65 6e 74 61 6c 20 6d 61 6c 6c 6f 63 20 6f  emental malloc o
8d10: 76 65 72 68 65 61 64 20 28 73 6f 6d 65 0a 2a 2a  verhead (some.**
8d20: 20 70 65 72 63 65 6e 74 61 67 65 20 6f 66 20 74   percentage of t
8d30: 68 65 20 70 6c 77 54 65 72 6d 69 6e 61 74 65 28  he plwTerminate(
8d40: 29 20 63 61 6c 6c 73 20 77 69 6c 6c 20 63 61 75  ) calls will cau
8d50: 73 65 20 61 20 72 65 61 6c 6c 6f 63 29 2c 20 73  se a realloc), s
8d60: 6f 0a 2a 2a 20 74 68 69 73 20 6d 69 67 68 74 20  o.** this might 
8d70: 62 65 20 77 6f 72 74 68 20 72 65 76 69 73 69 74  be worth revisit
8d80: 69 6e 67 20 69 66 20 74 68 65 20 44 61 74 61 42  ing if the DataB
8d90: 75 66 66 65 72 20 69 6d 70 6c 65 6d 65 6e 74 61  uffer implementa
8da0: 74 69 6f 6e 0a 2a 2a 20 63 68 61 6e 67 65 73 2e  tion.** changes.
8db0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
8dc0: 64 6c 63 41 64 64 44 6f 63 6c 69 73 74 28 44 4c  dlcAddDoclist(DL
8dd0: 43 6f 6c 6c 65 63 74 6f 72 20 2a 70 43 6f 6c 6c  Collector *pColl
8de0: 65 63 74 6f 72 2c 20 44 61 74 61 42 75 66 66 65  ector, DataBuffe
8df0: 72 20 2a 62 29 7b 0a 20 20 69 66 28 20 70 43 6f  r *b){.  if( pCo
8e00: 6c 6c 65 63 74 6f 72 2d 3e 64 6c 77 2e 69 54 79  llector->dlw.iTy
8e10: 70 65 3e 44 4c 5f 44 4f 43 49 44 53 20 29 7b 0a  pe>DL_DOCIDS ){.
8e20: 20 20 20 20 63 68 61 72 20 63 5b 56 41 52 49 4e      char c[VARIN
8e30: 54 5f 4d 41 58 5d 3b 0a 20 20 20 20 69 6e 74 20  T_MAX];.    int 
8e40: 6e 20 3d 20 66 74 73 33 50 75 74 56 61 72 69 6e  n = fts3PutVarin
8e50: 74 28 63 2c 20 50 4f 53 5f 45 4e 44 29 3b 0a 20  t(c, POS_END);. 
8e60: 20 20 20 64 61 74 61 42 75 66 66 65 72 41 70 70     dataBufferApp
8e70: 65 6e 64 32 28 62 2c 20 70 43 6f 6c 6c 65 63 74  end2(b, pCollect
8e80: 6f 72 2d 3e 62 2e 70 44 61 74 61 2c 20 70 43 6f  or->b.pData, pCo
8e90: 6c 6c 65 63 74 6f 72 2d 3e 62 2e 6e 44 61 74 61  llector->b.nData
8ea0: 2c 20 63 2c 20 6e 29 3b 0a 20 20 7d 65 6c 73 65  , c, n);.  }else
8eb0: 7b 0a 20 20 20 20 64 61 74 61 42 75 66 66 65 72  {.    dataBuffer
8ec0: 41 70 70 65 6e 64 28 62 2c 20 70 43 6f 6c 6c 65  Append(b, pColle
8ed0: 63 74 6f 72 2d 3e 62 2e 70 44 61 74 61 2c 20 70  ctor->b.pData, p
8ee0: 43 6f 6c 6c 65 63 74 6f 72 2d 3e 62 2e 6e 44 61  Collector->b.nDa
8ef0: 74 61 29 3b 0a 20 20 7d 0a 7d 0a 73 74 61 74 69  ta);.  }.}.stati
8f00: 63 20 76 6f 69 64 20 64 6c 63 4e 65 78 74 28 44  c void dlcNext(D
8f10: 4c 43 6f 6c 6c 65 63 74 6f 72 20 2a 70 43 6f 6c  LCollector *pCol
8f20: 6c 65 63 74 6f 72 2c 20 73 71 6c 69 74 65 5f 69  lector, sqlite_i
8f30: 6e 74 36 34 20 69 44 6f 63 69 64 29 7b 0a 20 20  nt64 iDocid){.  
8f40: 70 6c 77 54 65 72 6d 69 6e 61 74 65 28 26 70 43  plwTerminate(&pC
8f50: 6f 6c 6c 65 63 74 6f 72 2d 3e 70 6c 77 29 3b 0a  ollector->plw);.
8f60: 20 20 70 6c 77 44 65 73 74 72 6f 79 28 26 70 43    plwDestroy(&pC
8f70: 6f 6c 6c 65 63 74 6f 72 2d 3e 70 6c 77 29 3b 0a  ollector->plw);.
8f80: 20 20 70 6c 77 49 6e 69 74 28 26 70 43 6f 6c 6c    plwInit(&pColl
8f90: 65 63 74 6f 72 2d 3e 70 6c 77 2c 20 26 70 43 6f  ector->plw, &pCo
8fa0: 6c 6c 65 63 74 6f 72 2d 3e 64 6c 77 2c 20 69 44  llector->dlw, iD
8fb0: 6f 63 69 64 29 3b 0a 7d 0a 73 74 61 74 69 63 20  ocid);.}.static 
8fc0: 76 6f 69 64 20 64 6c 63 41 64 64 50 6f 73 28 44  void dlcAddPos(D
8fd0: 4c 43 6f 6c 6c 65 63 74 6f 72 20 2a 70 43 6f 6c  LCollector *pCol
8fe0: 6c 65 63 74 6f 72 2c 20 69 6e 74 20 69 43 6f 6c  lector, int iCol
8ff0: 75 6d 6e 2c 20 69 6e 74 20 69 50 6f 73 2c 0a 20  umn, int iPos,. 
9000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9010: 20 20 20 20 20 69 6e 74 20 69 53 74 61 72 74 4f       int iStartO
9020: 66 66 73 65 74 2c 20 69 6e 74 20 69 45 6e 64 4f  ffset, int iEndO
9030: 66 66 73 65 74 29 7b 0a 20 20 70 6c 77 41 64 64  ffset){.  plwAdd
9040: 28 26 70 43 6f 6c 6c 65 63 74 6f 72 2d 3e 70 6c  (&pCollector->pl
9050: 77 2c 20 69 43 6f 6c 75 6d 6e 2c 20 69 50 6f 73  w, iColumn, iPos
9060: 2c 20 69 53 74 61 72 74 4f 66 66 73 65 74 2c 20  , iStartOffset, 
9070: 69 45 6e 64 4f 66 66 73 65 74 29 3b 0a 7d 0a 0a  iEndOffset);.}..
9080: 73 74 61 74 69 63 20 44 4c 43 6f 6c 6c 65 63 74  static DLCollect
9090: 6f 72 20 2a 64 6c 63 4e 65 77 28 73 71 6c 69 74  or *dlcNew(sqlit
90a0: 65 5f 69 6e 74 36 34 20 69 44 6f 63 69 64 2c 20  e_int64 iDocid, 
90b0: 44 6f 63 4c 69 73 74 54 79 70 65 20 69 54 79 70  DocListType iTyp
90c0: 65 29 7b 0a 20 20 44 4c 43 6f 6c 6c 65 63 74 6f  e){.  DLCollecto
90d0: 72 20 2a 70 43 6f 6c 6c 65 63 74 6f 72 20 3d 20  r *pCollector = 
90e0: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
90f0: 69 7a 65 6f 66 28 44 4c 43 6f 6c 6c 65 63 74 6f  izeof(DLCollecto
9100: 72 29 29 3b 0a 20 20 64 61 74 61 42 75 66 66 65  r));.  dataBuffe
9110: 72 49 6e 69 74 28 26 70 43 6f 6c 6c 65 63 74 6f  rInit(&pCollecto
9120: 72 2d 3e 62 2c 20 30 29 3b 0a 20 20 64 6c 77 49  r->b, 0);.  dlwI
9130: 6e 69 74 28 26 70 43 6f 6c 6c 65 63 74 6f 72 2d  nit(&pCollector-
9140: 3e 64 6c 77 2c 20 69 54 79 70 65 2c 20 26 70 43  >dlw, iType, &pC
9150: 6f 6c 6c 65 63 74 6f 72 2d 3e 62 29 3b 0a 20 20  ollector->b);.  
9160: 70 6c 77 49 6e 69 74 28 26 70 43 6f 6c 6c 65 63  plwInit(&pCollec
9170: 74 6f 72 2d 3e 70 6c 77 2c 20 26 70 43 6f 6c 6c  tor->plw, &pColl
9180: 65 63 74 6f 72 2d 3e 64 6c 77 2c 20 69 44 6f 63  ector->dlw, iDoc
9190: 69 64 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 43  id);.  return pC
91a0: 6f 6c 6c 65 63 74 6f 72 3b 0a 7d 0a 73 74 61 74  ollector;.}.stat
91b0: 69 63 20 76 6f 69 64 20 64 6c 63 44 65 6c 65 74  ic void dlcDelet
91c0: 65 28 44 4c 43 6f 6c 6c 65 63 74 6f 72 20 2a 70  e(DLCollector *p
91d0: 43 6f 6c 6c 65 63 74 6f 72 29 7b 0a 20 20 70 6c  Collector){.  pl
91e0: 77 44 65 73 74 72 6f 79 28 26 70 43 6f 6c 6c 65  wDestroy(&pColle
91f0: 63 74 6f 72 2d 3e 70 6c 77 29 3b 0a 20 20 64 6c  ctor->plw);.  dl
9200: 77 44 65 73 74 72 6f 79 28 26 70 43 6f 6c 6c 65  wDestroy(&pColle
9210: 63 74 6f 72 2d 3e 64 6c 77 29 3b 0a 20 20 64 61  ctor->dlw);.  da
9220: 74 61 42 75 66 66 65 72 44 65 73 74 72 6f 79 28  taBufferDestroy(
9230: 26 70 43 6f 6c 6c 65 63 74 6f 72 2d 3e 62 29 3b  &pCollector->b);
9240: 0a 20 20 53 43 52 41 4d 42 4c 45 28 70 43 6f 6c  .  SCRAMBLE(pCol
9250: 6c 65 63 74 6f 72 29 3b 0a 20 20 73 71 6c 69 74  lector);.  sqlit
9260: 65 33 5f 66 72 65 65 28 70 43 6f 6c 6c 65 63 74  e3_free(pCollect
9270: 6f 72 29 3b 0a 7d 0a 0a 0a 2f 2a 20 43 6f 70 79  or);.}.../* Copy
9280: 20 74 68 65 20 64 6f 63 6c 69 73 74 20 64 61 74   the doclist dat
9290: 61 20 6f 66 20 69 54 79 70 65 20 69 6e 20 70 44  a of iType in pD
92a0: 61 74 61 2f 6e 44 61 74 61 20 69 6e 74 6f 20 2a  ata/nData into *
92b0: 6f 75 74 2c 20 74 72 69 6d 6d 69 6e 67 0a 2a 2a  out, trimming.**
92c0: 20 75 6e 6e 65 63 65 73 73 61 72 79 20 64 61 74   unnecessary dat
92d0: 61 20 61 73 20 77 65 20 67 6f 2e 20 20 4f 6e 6c  a as we go.  Onl
92e0: 79 20 63 6f 6c 75 6d 6e 73 20 6d 61 74 63 68 69  y columns matchi
92f0: 6e 67 20 69 43 6f 6c 75 6d 6e 20 61 72 65 0a 2a  ng iColumn are.*
9300: 2a 20 63 6f 70 69 65 64 2c 20 61 6c 6c 20 63 6f  * copied, all co
9310: 6c 75 6d 6e 73 20 63 6f 70 69 65 64 20 69 66 20  lumns copied if 
9320: 69 43 6f 6c 75 6d 6e 20 69 73 20 2d 31 2e 20 20  iColumn is -1.  
9330: 45 6c 65 6d 65 6e 74 73 20 77 69 74 68 20 6e 6f  Elements with no
9340: 0a 2a 2a 20 6d 61 74 63 68 69 6e 67 20 63 6f 6c  .** matching col
9350: 75 6d 6e 73 20 61 72 65 20 64 72 6f 70 70 65 64  umns are dropped
9360: 2e 20 20 54 68 65 20 6f 75 74 70 75 74 20 69 73  .  The output is
9370: 20 61 6e 20 69 4f 75 74 54 79 70 65 20 64 6f 63   an iOutType doc
9380: 6c 69 73 74 2e 0a 2a 2f 0a 2f 2a 20 4e 4f 54 45  list..*/./* NOTE
9390: 28 73 68 65 73 73 29 20 54 68 69 73 20 63 6f 64  (shess) This cod
93a0: 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20  e is only valid 
93b0: 61 66 74 65 72 20 61 6c 6c 20 64 6f 63 6c 69 73  after all doclis
93c0: 74 73 20 61 72 65 20 6d 65 72 67 65 64 2e 0a 2a  ts are merged..*
93d0: 2a 20 49 66 20 74 68 69 73 20 69 73 20 72 75 6e  * If this is run
93e0: 20 62 65 66 6f 72 65 20 6d 65 72 67 65 73 2c 20   before merges, 
93f0: 74 68 65 6e 20 64 6f 63 6c 69 73 74 20 69 74 65  then doclist ite
9400: 6d 73 20 77 68 69 63 68 20 72 65 70 72 65 73 65  ms which represe
9410: 6e 74 0a 2a 2a 20 64 65 6c 65 74 69 6f 6e 20 77  nt.** deletion w
9420: 69 6c 6c 20 62 65 20 74 72 69 6d 6d 65 64 2c 20  ill be trimmed, 
9430: 61 6e 64 20 77 69 6c 6c 20 74 68 75 73 20 6e 6f  and will thus no
9440: 74 20 65 66 66 65 63 74 20 61 20 64 65 6c 65 74  t effect a delet
9450: 69 6f 6e 0a 2a 2a 20 64 75 72 69 6e 67 20 74 68  ion.** during th
9460: 65 20 6d 65 72 67 65 2e 0a 2a 2f 0a 73 74 61 74  e merge..*/.stat
9470: 69 63 20 76 6f 69 64 20 64 6f 63 4c 69 73 74 54  ic void docListT
9480: 72 69 6d 28 44 6f 63 4c 69 73 74 54 79 70 65 20  rim(DocListType 
9490: 69 54 79 70 65 2c 20 63 6f 6e 73 74 20 63 68 61  iType, const cha
94a0: 72 20 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44  r *pData, int nD
94b0: 61 74 61 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ata,.           
94c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74               int
94d0: 20 69 43 6f 6c 75 6d 6e 2c 20 44 6f 63 4c 69 73   iColumn, DocLis
94e0: 74 54 79 70 65 20 69 4f 75 74 54 79 70 65 2c 20  tType iOutType, 
94f0: 44 61 74 61 42 75 66 66 65 72 20 2a 6f 75 74 29  DataBuffer *out)
9500: 7b 0a 20 20 44 4c 52 65 61 64 65 72 20 64 6c 52  {.  DLReader dlR
9510: 65 61 64 65 72 3b 0a 20 20 44 4c 57 72 69 74 65  eader;.  DLWrite
9520: 72 20 64 6c 57 72 69 74 65 72 3b 0a 0a 20 20 61  r dlWriter;..  a
9530: 73 73 65 72 74 28 20 69 4f 75 74 54 79 70 65 3c  ssert( iOutType<
9540: 3d 69 54 79 70 65 20 29 3b 0a 0a 20 20 64 6c 72  =iType );..  dlr
9550: 49 6e 69 74 28 26 64 6c 52 65 61 64 65 72 2c 20  Init(&dlReader, 
9560: 69 54 79 70 65 2c 20 70 44 61 74 61 2c 20 6e 44  iType, pData, nD
9570: 61 74 61 29 3b 0a 20 20 64 6c 77 49 6e 69 74 28  ata);.  dlwInit(
9580: 26 64 6c 57 72 69 74 65 72 2c 20 69 4f 75 74 54  &dlWriter, iOutT
9590: 79 70 65 2c 20 6f 75 74 29 3b 0a 0a 20 20 77 68  ype, out);..  wh
95a0: 69 6c 65 28 20 21 64 6c 72 41 74 45 6e 64 28 26  ile( !dlrAtEnd(&
95b0: 64 6c 52 65 61 64 65 72 29 20 29 7b 0a 20 20 20  dlReader) ){.   
95c0: 20 50 4c 52 65 61 64 65 72 20 70 6c 52 65 61 64   PLReader plRead
95d0: 65 72 3b 0a 20 20 20 20 50 4c 57 72 69 74 65 72  er;.    PLWriter
95e0: 20 70 6c 57 72 69 74 65 72 3b 0a 20 20 20 20 69   plWriter;.    i
95f0: 6e 74 20 6d 61 74 63 68 20 3d 20 30 3b 0a 0a 20  nt match = 0;.. 
9600: 20 20 20 70 6c 72 49 6e 69 74 28 26 70 6c 52 65     plrInit(&plRe
9610: 61 64 65 72 2c 20 26 64 6c 52 65 61 64 65 72 29  ader, &dlReader)
9620: 3b 0a 0a 20 20 20 20 77 68 69 6c 65 28 20 21 70  ;..    while( !p
9630: 6c 72 41 74 45 6e 64 28 26 70 6c 52 65 61 64 65  lrAtEnd(&plReade
9640: 72 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  r) ){.      if( 
9650: 69 43 6f 6c 75 6d 6e 3d 3d 2d 31 20 7c 7c 20 70  iColumn==-1 || p
9660: 6c 72 43 6f 6c 75 6d 6e 28 26 70 6c 52 65 61 64  lrColumn(&plRead
9670: 65 72 29 3d 3d 69 43 6f 6c 75 6d 6e 20 29 7b 0a  er)==iColumn ){.
9680: 20 20 20 20 20 20 20 20 69 66 28 20 21 6d 61 74          if( !mat
9690: 63 68 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ch ){.          
96a0: 70 6c 77 49 6e 69 74 28 26 70 6c 57 72 69 74 65  plwInit(&plWrite
96b0: 72 2c 20 26 64 6c 57 72 69 74 65 72 2c 20 64 6c  r, &dlWriter, dl
96c0: 72 44 6f 63 69 64 28 26 64 6c 52 65 61 64 65 72  rDocid(&dlReader
96d0: 29 29 3b 0a 20 20 20 20 20 20 20 20 20 20 6d 61  ));.          ma
96e0: 74 63 68 20 3d 20 31 3b 0a 20 20 20 20 20 20 20  tch = 1;.       
96f0: 20 7d 0a 20 20 20 20 20 20 20 20 70 6c 77 41 64   }.        plwAd
9700: 64 28 26 70 6c 57 72 69 74 65 72 2c 20 70 6c 72  d(&plWriter, plr
9710: 43 6f 6c 75 6d 6e 28 26 70 6c 52 65 61 64 65 72  Column(&plReader
9720: 29 2c 20 70 6c 72 50 6f 73 69 74 69 6f 6e 28 26  ), plrPosition(&
9730: 70 6c 52 65 61 64 65 72 29 2c 0a 20 20 20 20 20  plReader),.     
9740: 20 20 20 20 20 20 20 20 20 20 70 6c 72 53 74 61            plrSta
9750: 72 74 4f 66 66 73 65 74 28 26 70 6c 52 65 61 64  rtOffset(&plRead
9760: 65 72 29 2c 20 70 6c 72 45 6e 64 4f 66 66 73 65  er), plrEndOffse
9770: 74 28 26 70 6c 52 65 61 64 65 72 29 29 3b 0a 20  t(&plReader));. 
9780: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 6c 72       }.      plr
9790: 53 74 65 70 28 26 70 6c 52 65 61 64 65 72 29 3b  Step(&plReader);
97a0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 6d  .    }.    if( m
97b0: 61 74 63 68 20 29 7b 0a 20 20 20 20 20 20 70 6c  atch ){.      pl
97c0: 77 54 65 72 6d 69 6e 61 74 65 28 26 70 6c 57 72  wTerminate(&plWr
97d0: 69 74 65 72 29 3b 0a 20 20 20 20 20 20 70 6c 77  iter);.      plw
97e0: 44 65 73 74 72 6f 79 28 26 70 6c 57 72 69 74 65  Destroy(&plWrite
97f0: 72 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70  r);.    }..    p
9800: 6c 72 44 65 73 74 72 6f 79 28 26 70 6c 52 65 61  lrDestroy(&plRea
9810: 64 65 72 29 3b 0a 20 20 20 20 64 6c 72 53 74 65  der);.    dlrSte
9820: 70 28 26 64 6c 52 65 61 64 65 72 29 3b 0a 20 20  p(&dlReader);.  
9830: 7d 0a 20 20 64 6c 77 44 65 73 74 72 6f 79 28 26  }.  dlwDestroy(&
9840: 64 6c 57 72 69 74 65 72 29 3b 0a 20 20 64 6c 72  dlWriter);.  dlr
9850: 44 65 73 74 72 6f 79 28 26 64 6c 52 65 61 64 65  Destroy(&dlReade
9860: 72 29 3b 0a 7d 0a 0a 2f 2a 20 55 73 65 64 20 62  r);.}../* Used b
9870: 79 20 64 6f 63 4c 69 73 74 4d 65 72 67 65 28 29  y docListMerge()
9880: 20 74 6f 20 6b 65 65 70 20 64 6f 63 6c 69 73 74   to keep doclist
9890: 73 20 69 6e 20 74 68 65 20 61 73 63 65 6e 64 69  s in the ascendi
98a0: 6e 67 20 6f 72 64 65 72 20 62 79 0a 2a 2a 20 64  ng order by.** d
98b0: 6f 63 69 64 2c 20 74 68 65 6e 20 61 73 63 65 6e  ocid, then ascen
98c0: 64 69 6e 67 20 6f 72 64 65 72 20 62 79 20 61 67  ding order by ag
98d0: 65 20 28 73 6f 20 74 68 65 20 6e 65 77 65 73 74  e (so the newest
98e0: 20 63 6f 6d 65 73 20 66 69 72 73 74 29 2e 0a 2a   comes first)..*
98f0: 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
9900: 20 4f 72 64 65 72 65 64 44 4c 52 65 61 64 65 72   OrderedDLReader
9910: 20 7b 0a 20 20 44 4c 52 65 61 64 65 72 20 2a 70   {.  DLReader *p
9920: 52 65 61 64 65 72 3b 0a 0a 20 20 2f 2a 20 54 4f  Reader;..  /* TO
9930: 44 4f 28 73 68 65 73 73 29 20 49 66 20 77 65 20  DO(shess) If we 
9940: 61 73 73 75 6d 65 20 74 68 61 74 20 64 6f 63 4c  assume that docL
9950: 69 73 74 4d 65 72 67 65 20 70 52 65 61 64 65 72  istMerge pReader
9960: 73 20 69 73 20 6f 72 64 65 72 65 64 20 62 79 0a  s is ordered by.
9970: 20 20 2a 2a 20 61 67 65 20 28 77 68 69 63 68 20    ** age (which 
9980: 77 65 20 64 6f 29 2c 20 74 68 65 6e 20 77 65 20  we do), then we 
9990: 63 6f 75 6c 64 20 75 73 65 20 70 52 65 61 64 65  could use pReade
99a0: 72 20 63 6f 6d 70 61 72 69 73 6f 6e 73 20 74 6f  r comparisons to
99b0: 20 62 72 65 61 6b 0a 20 20 2a 2a 20 74 69 65 73   break.  ** ties
99c0: 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20 69 64 78  ..  */.  int idx
99d0: 3b 0a 7d 20 4f 72 64 65 72 65 64 44 4c 52 65 61  ;.} OrderedDLRea
99e0: 64 65 72 3b 0a 0a 2f 2a 20 4f 72 64 65 72 20 65  der;../* Order e
99f0: 6f 66 20 74 6f 20 65 6e 64 2c 20 74 68 65 6e 20  of to end, then 
9a00: 62 79 20 64 6f 63 69 64 20 61 73 63 2c 20 69 64  by docid asc, id
9a10: 78 20 64 65 73 63 2e 20 2a 2f 0a 73 74 61 74 69  x desc. */.stati
9a20: 63 20 69 6e 74 20 6f 72 64 65 72 65 64 44 4c 52  c int orderedDLR
9a30: 65 61 64 65 72 43 6d 70 28 4f 72 64 65 72 65 64  eaderCmp(Ordered
9a40: 44 4c 52 65 61 64 65 72 20 2a 72 31 2c 20 4f 72  DLReader *r1, Or
9a50: 64 65 72 65 64 44 4c 52 65 61 64 65 72 20 2a 72  deredDLReader *r
9a60: 32 29 7b 0a 20 20 69 66 28 20 64 6c 72 41 74 45  2){.  if( dlrAtE
9a70: 6e 64 28 72 31 2d 3e 70 52 65 61 64 65 72 29 20  nd(r1->pReader) 
9a80: 29 7b 0a 20 20 20 20 69 66 28 20 64 6c 72 41 74  ){.    if( dlrAt
9a90: 45 6e 64 28 72 32 2d 3e 70 52 65 61 64 65 72 29  End(r2->pReader)
9aa0: 20 29 20 72 65 74 75 72 6e 20 30 3b 20 20 2f 2a   ) return 0;  /*
9ab0: 20 42 6f 74 68 20 61 74 45 6e 64 28 29 2e 20 2a   Both atEnd(). *
9ac0: 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b 20  /.    return 1; 
9ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9af0: 4f 6e 6c 79 20 72 31 20 61 74 45 6e 64 28 29 2e  Only r1 atEnd().
9b00: 20 2a 2f 0a 20 20 7d 0a 20 20 69 66 28 20 64 6c   */.  }.  if( dl
9b10: 72 41 74 45 6e 64 28 72 32 2d 3e 70 52 65 61 64  rAtEnd(r2->pRead
9b20: 65 72 29 20 29 20 72 65 74 75 72 6e 20 2d 31 3b  er) ) return -1;
9b30: 20 20 20 2f 2a 20 4f 6e 6c 79 20 72 32 20 61 74     /* Only r2 at
9b40: 45 6e 64 28 29 2e 20 2a 2f 0a 0a 20 20 69 66 28  End(). */..  if(
9b50: 20 64 6c 72 44 6f 63 69 64 28 72 31 2d 3e 70 52   dlrDocid(r1->pR
9b60: 65 61 64 65 72 29 3c 64 6c 72 44 6f 63 69 64 28  eader)<dlrDocid(
9b70: 72 32 2d 3e 70 52 65 61 64 65 72 29 20 29 20 72  r2->pReader) ) r
9b80: 65 74 75 72 6e 20 2d 31 3b 0a 20 20 69 66 28 20  eturn -1;.  if( 
9b90: 64 6c 72 44 6f 63 69 64 28 72 31 2d 3e 70 52 65  dlrDocid(r1->pRe
9ba0: 61 64 65 72 29 3e 64 6c 72 44 6f 63 69 64 28 72  ader)>dlrDocid(r
9bb0: 32 2d 3e 70 52 65 61 64 65 72 29 20 29 20 72 65  2->pReader) ) re
9bc0: 74 75 72 6e 20 31 3b 0a 0a 20 20 2f 2a 20 44 65  turn 1;..  /* De
9bd0: 73 63 65 6e 64 69 6e 67 20 6f 6e 20 69 64 78 2e  scending on idx.
9be0: 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20 72 32 2d   */.  return r2-
9bf0: 3e 69 64 78 2d 72 31 2d 3e 69 64 78 3b 0a 7d 0a  >idx-r1->idx;.}.
9c00: 0a 2f 2a 20 42 75 62 62 6c 65 20 70 5b 30 5d 20  ./* Bubble p[0] 
9c10: 74 6f 20 61 70 70 72 6f 70 72 69 61 74 65 20 70  to appropriate p
9c20: 6c 61 63 65 20 69 6e 20 70 5b 31 2e 2e 6e 2d 31  lace in p[1..n-1
9c30: 5d 2e 20 20 41 73 73 75 6d 65 73 20 74 68 61 74  ].  Assumes that
9c40: 0a 2a 2a 20 70 5b 31 2e 2e 6e 2d 31 5d 20 69 73  .** p[1..n-1] is
9c50: 20 61 6c 72 65 61 64 79 20 73 6f 72 74 65 64 2e   already sorted.
9c60: 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f 28 73 68 65 73  .*/./* TODO(shes
9c70: 73 29 20 49 73 20 74 68 69 73 20 66 72 65 71 75  s) Is this frequ
9c80: 65 6e 74 20 65 6e 6f 75 67 68 20 74 6f 20 77 61  ent enough to wa
9c90: 72 72 61 6e 74 20 61 20 62 69 6e 61 72 79 20 73  rrant a binary s
9ca0: 65 61 72 63 68 3f 0a 2a 2a 20 42 65 66 6f 72 65  earch?.** Before
9cb0: 20 69 6d 70 6c 65 6d 65 6e 74 69 6e 67 20 74 68   implementing th
9cc0: 61 74 2c 20 69 6e 73 74 72 75 6d 65 6e 74 20 74  at, instrument t
9cd0: 68 65 20 63 6f 64 65 20 74 6f 20 63 68 65 63 6b  he code to check
9ce0: 2e 20 20 49 6e 20 6d 6f 73 74 0a 2a 2a 20 63 75  .  In most.** cu
9cf0: 72 72 65 6e 74 20 75 73 61 67 65 2c 20 49 20 65  rrent usage, I e
9d00: 78 70 65 63 74 20 74 68 61 74 20 70 5b 30 5d 20  xpect that p[0] 
9d10: 77 69 6c 6c 20 62 65 20 6c 65 73 73 20 74 68 61  will be less tha
9d20: 6e 20 70 5b 31 5d 20 61 20 76 65 72 79 0a 2a 2a  n p[1] a very.**
9d30: 20 68 69 67 68 20 70 72 6f 70 6f 72 74 69 6f 6e   high proportion
9d40: 20 6f 66 20 74 68 65 20 74 69 6d 65 2e 0a 2a 2f   of the time..*/
9d50: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6f 72 64  .static void ord
9d60: 65 72 65 64 44 4c 52 65 61 64 65 72 52 65 6f 72  eredDLReaderReor
9d70: 64 65 72 28 4f 72 64 65 72 65 64 44 4c 52 65 61  der(OrderedDLRea
9d80: 64 65 72 20 2a 70 2c 20 69 6e 74 20 6e 29 7b 0a  der *p, int n){.
9d90: 20 20 77 68 69 6c 65 28 20 6e 3e 31 20 26 26 20    while( n>1 && 
9da0: 6f 72 64 65 72 65 64 44 4c 52 65 61 64 65 72 43  orderedDLReaderC
9db0: 6d 70 28 70 2c 20 70 2b 31 29 3e 30 20 29 7b 0a  mp(p, p+1)>0 ){.
9dc0: 20 20 20 20 4f 72 64 65 72 65 64 44 4c 52 65 61      OrderedDLRea
9dd0: 64 65 72 20 74 6d 70 20 3d 20 70 5b 30 5d 3b 0a  der tmp = p[0];.
9de0: 20 20 20 20 70 5b 30 5d 20 3d 20 70 5b 31 5d 3b      p[0] = p[1];
9df0: 0a 20 20 20 20 70 5b 31 5d 20 3d 20 74 6d 70 3b  .    p[1] = tmp;
9e00: 0a 20 20 20 20 6e 2d 2d 3b 0a 20 20 20 20 70 2b  .    n--;.    p+
9e10: 2b 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 47 69 76  +;.  }.}../* Giv
9e20: 65 6e 20 61 6e 20 61 72 72 61 79 20 6f 66 20 64  en an array of d
9e30: 6f 63 6c 69 73 74 20 72 65 61 64 65 72 73 2c 20  oclist readers, 
9e40: 6d 65 72 67 65 20 74 68 65 69 72 20 64 6f 63 6c  merge their docl
9e50: 69 73 74 20 65 6c 65 6d 65 6e 74 73 0a 2a 2a 20  ist elements.** 
9e60: 69 6e 74 6f 20 6f 75 74 20 69 6e 20 73 6f 72 74  into out in sort
9e70: 65 64 20 6f 72 64 65 72 20 28 62 79 20 64 6f 63  ed order (by doc
9e80: 69 64 29 2c 20 64 72 6f 70 70 69 6e 67 20 65 6c  id), dropping el
9e90: 65 6d 65 6e 74 73 20 66 72 6f 6d 20 6f 6c 64 65  ements from olde
9ea0: 72 0a 2a 2a 20 72 65 61 64 65 72 73 20 77 68 65  r.** readers whe
9eb0: 6e 20 74 68 65 72 65 20 69 73 20 61 20 64 75 70  n there is a dup
9ec0: 6c 69 63 61 74 65 20 64 6f 63 69 64 2e 20 20 70  licate docid.  p
9ed0: 52 65 61 64 65 72 73 20 69 73 20 61 73 73 75 6d  Readers is assum
9ee0: 65 64 20 74 6f 20 62 65 0a 2a 2a 20 6f 72 64 65  ed to be.** orde
9ef0: 72 65 64 20 62 79 20 61 67 65 2c 20 6f 6c 64 65  red by age, olde
9f00: 73 74 20 66 69 72 73 74 2e 0a 2a 2f 0a 2f 2a 20  st first..*/./* 
9f10: 54 4f 44 4f 28 73 68 65 73 73 29 20 6e 52 65 61  TODO(shess) nRea
9f20: 64 65 72 73 20 6d 75 73 74 20 62 65 20 3c 3d 20  ders must be <= 
9f30: 4d 45 52 47 45 5f 43 4f 55 4e 54 2e 20 20 54 68  MERGE_COUNT.  Th
9f40: 69 73 20 73 68 6f 75 6c 64 20 70 72 6f 62 61 62  is should probab
9f50: 6c 79 0a 2a 2a 20 62 65 20 66 69 78 65 64 2e 0a  ly.** be fixed..
9f60: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  */.static void d
9f70: 6f 63 4c 69 73 74 4d 65 72 67 65 28 44 61 74 61  ocListMerge(Data
9f80: 42 75 66 66 65 72 20 2a 6f 75 74 2c 0a 20 20 20  Buffer *out,.   
9f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9fa0: 20 20 20 20 20 20 44 4c 52 65 61 64 65 72 20 2a        DLReader *
9fb0: 70 52 65 61 64 65 72 73 2c 20 69 6e 74 20 6e 52  pReaders, int nR
9fc0: 65 61 64 65 72 73 29 7b 0a 20 20 4f 72 64 65 72  eaders){.  Order
9fd0: 65 64 44 4c 52 65 61 64 65 72 20 72 65 61 64 65  edDLReader reade
9fe0: 72 73 5b 4d 45 52 47 45 5f 43 4f 55 4e 54 5d 3b  rs[MERGE_COUNT];
9ff0: 0a 20 20 44 4c 57 72 69 74 65 72 20 77 72 69 74  .  DLWriter writ
a000: 65 72 3b 0a 20 20 69 6e 74 20 69 2c 20 6e 3b 0a  er;.  int i, n;.
a010: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 53    const char *pS
a020: 74 61 72 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20  tart = 0;.  int 
a030: 6e 53 74 61 72 74 20 3d 20 30 3b 0a 20 20 73 71  nStart = 0;.  sq
a040: 6c 69 74 65 5f 69 6e 74 36 34 20 69 46 69 72 73  lite_int64 iFirs
a050: 74 44 6f 63 69 64 20 3d 20 30 2c 20 69 4c 61 73  tDocid = 0, iLas
a060: 74 44 6f 63 69 64 20 3d 20 30 3b 0a 0a 20 20 61  tDocid = 0;..  a
a070: 73 73 65 72 74 28 20 6e 52 65 61 64 65 72 73 3e  ssert( nReaders>
a080: 30 20 29 3b 0a 20 20 69 66 28 20 6e 52 65 61 64  0 );.  if( nRead
a090: 65 72 73 3d 3d 31 20 29 7b 0a 20 20 20 20 64 61  ers==1 ){.    da
a0a0: 74 61 42 75 66 66 65 72 41 70 70 65 6e 64 28 6f  taBufferAppend(o
a0b0: 75 74 2c 20 64 6c 72 44 6f 63 44 61 74 61 28 70  ut, dlrDocData(p
a0c0: 52 65 61 64 65 72 73 29 2c 20 64 6c 72 41 6c 6c  Readers), dlrAll
a0d0: 44 61 74 61 42 79 74 65 73 28 70 52 65 61 64 65  DataBytes(pReade
a0e0: 72 73 29 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  rs));.    return
a0f0: 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28  ;.  }..  assert(
a100: 20 6e 52 65 61 64 65 72 73 3c 3d 4d 45 52 47 45   nReaders<=MERGE
a110: 5f 43 4f 55 4e 54 20 29 3b 0a 20 20 6e 20 3d 20  _COUNT );.  n = 
a120: 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  0;.  for(i=0; i<
a130: 6e 52 65 61 64 65 72 73 3b 20 69 2b 2b 29 7b 0a  nReaders; i++){.
a140: 20 20 20 20 61 73 73 65 72 74 28 20 70 52 65 61      assert( pRea
a150: 64 65 72 73 5b 69 5d 2e 69 54 79 70 65 3d 3d 70  ders[i].iType==p
a160: 52 65 61 64 65 72 73 5b 30 5d 2e 69 54 79 70 65  Readers[0].iType
a170: 20 29 3b 0a 20 20 20 20 72 65 61 64 65 72 73 5b   );.    readers[
a180: 69 5d 2e 70 52 65 61 64 65 72 20 3d 20 70 52 65  i].pReader = pRe
a190: 61 64 65 72 73 2b 69 3b 0a 20 20 20 20 72 65 61  aders+i;.    rea
a1a0: 64 65 72 73 5b 69 5d 2e 69 64 78 20 3d 20 69 3b  ders[i].idx = i;
a1b0: 0a 20 20 20 20 6e 20 2b 3d 20 64 6c 72 41 6c 6c  .    n += dlrAll
a1c0: 44 61 74 61 42 79 74 65 73 28 26 70 52 65 61 64  DataBytes(&pRead
a1d0: 65 72 73 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 2f  ers[i]);.  }.  /
a1e0: 2a 20 43 6f 6e 73 65 72 76 61 74 69 76 65 6c 79  * Conservatively
a1f0: 20 73 69 7a 65 20 6f 75 74 70 75 74 20 74 6f 20   size output to 
a200: 73 75 6d 20 6f 66 20 69 6e 70 75 74 73 2e 20 20  sum of inputs.  
a210: 4f 75 74 70 75 74 20 73 68 6f 75 6c 64 20 65 6e  Output should en
a220: 64 0a 20 20 2a 2a 20 75 70 20 73 74 72 69 63 74  d.  ** up strict
a230: 6c 79 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20  ly smaller than 
a240: 69 6e 70 75 74 2e 0a 20 20 2a 2f 0a 20 20 64 61  input..  */.  da
a250: 74 61 42 75 66 66 65 72 45 78 70 61 6e 64 28 6f  taBufferExpand(o
a260: 75 74 2c 20 6e 29 3b 0a 0a 20 20 2f 2a 20 47 65  ut, n);..  /* Ge
a270: 74 20 74 68 65 20 72 65 61 64 65 72 73 20 69 6e  t the readers in
a280: 74 6f 20 73 6f 72 74 65 64 20 6f 72 64 65 72 2e  to sorted order.
a290: 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 69 2d 2d   */.  while( i--
a2a0: 3e 30 20 29 7b 0a 20 20 20 20 6f 72 64 65 72 65  >0 ){.    ordere
a2b0: 64 44 4c 52 65 61 64 65 72 52 65 6f 72 64 65 72  dDLReaderReorder
a2c0: 28 72 65 61 64 65 72 73 2b 69 2c 20 6e 52 65 61  (readers+i, nRea
a2d0: 64 65 72 73 2d 69 29 3b 0a 20 20 7d 0a 0a 20 20  ders-i);.  }..  
a2e0: 64 6c 77 49 6e 69 74 28 26 77 72 69 74 65 72 2c  dlwInit(&writer,
a2f0: 20 70 52 65 61 64 65 72 73 5b 30 5d 2e 69 54 79   pReaders[0].iTy
a300: 70 65 2c 20 6f 75 74 29 3b 0a 20 20 77 68 69 6c  pe, out);.  whil
a310: 65 28 20 21 64 6c 72 41 74 45 6e 64 28 72 65 61  e( !dlrAtEnd(rea
a320: 64 65 72 73 5b 30 5d 2e 70 52 65 61 64 65 72 29  ders[0].pReader)
a330: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 5f 69   ){.    sqlite_i
a340: 6e 74 36 34 20 69 44 6f 63 69 64 20 3d 20 64 6c  nt64 iDocid = dl
a350: 72 44 6f 63 69 64 28 72 65 61 64 65 72 73 5b 30  rDocid(readers[0
a360: 5d 2e 70 52 65 61 64 65 72 29 3b 0a 0a 20 20 20  ].pReader);..   
a370: 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20 61   /* If this is a
a380: 20 63 6f 6e 74 69 6e 75 61 74 69 6f 6e 20 6f 66   continuation of
a390: 20 74 68 65 20 63 75 72 72 65 6e 74 20 62 75 66   the current buf
a3a0: 66 65 72 20 74 6f 20 63 6f 70 79 2c 20 65 78 74  fer to copy, ext
a3b0: 65 6e 64 0a 20 20 20 20 2a 2a 20 74 68 61 74 20  end.    ** that 
a3c0: 62 75 66 66 65 72 2e 20 20 6d 65 6d 63 70 79 28  buffer.  memcpy(
a3d0: 29 20 73 65 65 6d 73 20 74 6f 20 62 65 20 6d 6f  ) seems to be mo
a3e0: 72 65 20 65 66 66 69 63 69 65 6e 74 20 69 66 20  re efficient if 
a3f0: 69 74 20 68 61 73 20 61 0a 20 20 20 20 2a 2a 20  it has a.    ** 
a400: 6c 6f 74 73 20 6f 66 20 64 61 74 61 20 74 6f 20  lots of data to 
a410: 63 6f 70 79 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  copy..    */.   
a420: 20 69 66 28 20 64 6c 72 44 6f 63 44 61 74 61 28   if( dlrDocData(
a430: 72 65 61 64 65 72 73 5b 30 5d 2e 70 52 65 61 64  readers[0].pRead
a440: 65 72 29 3d 3d 70 53 74 61 72 74 2b 6e 53 74 61  er)==pStart+nSta
a450: 72 74 20 29 7b 0a 20 20 20 20 20 20 6e 53 74 61  rt ){.      nSta
a460: 72 74 20 2b 3d 20 64 6c 72 44 6f 63 44 61 74 61  rt += dlrDocData
a470: 42 79 74 65 73 28 72 65 61 64 65 72 73 5b 30 5d  Bytes(readers[0]
a480: 2e 70 52 65 61 64 65 72 29 3b 0a 20 20 20 20 7d  .pReader);.    }
a490: 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20  else{.      if( 
a4a0: 70 53 74 61 72 74 21 3d 30 20 29 7b 0a 20 20 20  pStart!=0 ){.   
a4b0: 20 20 20 20 20 64 6c 77 41 70 70 65 6e 64 28 26       dlwAppend(&
a4c0: 77 72 69 74 65 72 2c 20 70 53 74 61 72 74 2c 20  writer, pStart, 
a4d0: 6e 53 74 61 72 74 2c 20 69 46 69 72 73 74 44 6f  nStart, iFirstDo
a4e0: 63 69 64 2c 20 69 4c 61 73 74 44 6f 63 69 64 29  cid, iLastDocid)
a4f0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
a500: 70 53 74 61 72 74 20 3d 20 64 6c 72 44 6f 63 44  pStart = dlrDocD
a510: 61 74 61 28 72 65 61 64 65 72 73 5b 30 5d 2e 70  ata(readers[0].p
a520: 52 65 61 64 65 72 29 3b 0a 20 20 20 20 20 20 6e  Reader);.      n
a530: 53 74 61 72 74 20 3d 20 64 6c 72 44 6f 63 44 61  Start = dlrDocDa
a540: 74 61 42 79 74 65 73 28 72 65 61 64 65 72 73 5b  taBytes(readers[
a550: 30 5d 2e 70 52 65 61 64 65 72 29 3b 0a 20 20 20  0].pReader);.   
a560: 20 20 20 69 46 69 72 73 74 44 6f 63 69 64 20 3d     iFirstDocid =
a570: 20 69 44 6f 63 69 64 3b 0a 20 20 20 20 7d 0a 20   iDocid;.    }. 
a580: 20 20 20 69 4c 61 73 74 44 6f 63 69 64 20 3d 20     iLastDocid = 
a590: 69 44 6f 63 69 64 3b 0a 20 20 20 20 64 6c 72 53  iDocid;.    dlrS
a5a0: 74 65 70 28 72 65 61 64 65 72 73 5b 30 5d 2e 70  tep(readers[0].p
a5b0: 52 65 61 64 65 72 29 3b 0a 0a 20 20 20 20 2f 2a  Reader);..    /*
a5c0: 20 44 72 6f 70 20 61 6c 6c 20 6f 66 20 74 68 65   Drop all of the
a5d0: 20 6f 6c 64 65 72 20 65 6c 65 6d 65 6e 74 73 20   older elements 
a5e0: 77 69 74 68 20 74 68 65 20 73 61 6d 65 20 64 6f  with the same do
a5f0: 63 69 64 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28  cid. */.    for(
a600: 69 3d 31 3b 20 69 3c 6e 52 65 61 64 65 72 73 20  i=1; i<nReaders 
a610: 26 26 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  &&.             
a620: 21 64 6c 72 41 74 45 6e 64 28 72 65 61 64 65 72  !dlrAtEnd(reader
a630: 73 5b 69 5d 2e 70 52 65 61 64 65 72 29 20 26 26  s[i].pReader) &&
a640: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 64 6c  .             dl
a650: 72 44 6f 63 69 64 28 72 65 61 64 65 72 73 5b 69  rDocid(readers[i
a660: 5d 2e 70 52 65 61 64 65 72 29 3d 3d 69 44 6f 63  ].pReader)==iDoc
a670: 69 64 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  id; i++){.      
a680: 64 6c 72 53 74 65 70 28 72 65 61 64 65 72 73 5b  dlrStep(readers[
a690: 69 5d 2e 70 52 65 61 64 65 72 29 3b 0a 20 20 20  i].pReader);.   
a6a0: 20 7d 0a 0a 20 20 20 20 2f 2a 20 47 65 74 20 74   }..    /* Get t
a6b0: 68 65 20 72 65 61 64 65 72 73 20 62 61 63 6b 20  he readers back 
a6c0: 69 6e 74 6f 20 6f 72 64 65 72 2e 20 2a 2f 0a 20  into order. */. 
a6d0: 20 20 20 77 68 69 6c 65 28 20 69 2d 2d 3e 30 20     while( i-->0 
a6e0: 29 7b 0a 20 20 20 20 20 20 6f 72 64 65 72 65 64  ){.      ordered
a6f0: 44 4c 52 65 61 64 65 72 52 65 6f 72 64 65 72 28  DLReaderReorder(
a700: 72 65 61 64 65 72 73 2b 69 2c 20 6e 52 65 61 64  readers+i, nRead
a710: 65 72 73 2d 69 29 3b 0a 20 20 20 20 7d 0a 20 20  ers-i);.    }.  
a720: 7d 0a 0a 20 20 2f 2a 20 43 6f 70 79 20 6f 76 65  }..  /* Copy ove
a730: 72 20 61 6e 79 20 72 65 6d 61 69 6e 69 6e 67 20  r any remaining 
a740: 65 6c 65 6d 65 6e 74 73 2e 20 2a 2f 0a 20 20 69  elements. */.  i
a750: 66 28 20 6e 53 74 61 72 74 3e 30 20 29 20 64 6c  f( nStart>0 ) dl
a760: 77 41 70 70 65 6e 64 28 26 77 72 69 74 65 72 2c  wAppend(&writer,
a770: 20 70 53 74 61 72 74 2c 20 6e 53 74 61 72 74 2c   pStart, nStart,
a780: 20 69 46 69 72 73 74 44 6f 63 69 64 2c 20 69 4c   iFirstDocid, iL
a790: 61 73 74 44 6f 63 69 64 29 3b 0a 20 20 64 6c 77  astDocid);.  dlw
a7a0: 44 65 73 74 72 6f 79 28 26 77 72 69 74 65 72 29  Destroy(&writer)
a7b0: 3b 0a 7d 0a 0a 2f 2a 20 48 65 6c 70 65 72 20 66  ;.}../* Helper f
a7c0: 75 6e 63 74 69 6f 6e 20 66 6f 72 20 70 6f 73 4c  unction for posL
a7d0: 69 73 74 55 6e 69 6f 6e 28 29 2e 20 20 43 6f 6d  istUnion().  Com
a7e0: 70 61 72 65 73 20 74 68 65 20 63 75 72 72 65 6e  pares the curren
a7f0: 74 20 70 6f 73 69 74 69 6f 6e 0a 2a 2a 20 62 65  t position.** be
a800: 74 77 65 65 6e 20 6c 65 66 74 20 61 6e 64 20 72  tween left and r
a810: 69 67 68 74 2c 20 72 65 74 75 72 6e 69 6e 67 20  ight, returning 
a820: 61 73 20 73 74 61 6e 64 61 72 64 20 43 20 69 64  as standard C id
a830: 69 6f 6d 20 6f 66 20 3c 30 20 69 66 0a 2a 2a 20  iom of <0 if.** 
a840: 6c 65 66 74 3c 72 69 67 68 74 2c 20 3e 30 20 69  left<right, >0 i
a850: 66 20 6c 65 66 74 3e 72 69 67 68 74 2c 20 61 6e  f left>right, an
a860: 64 20 30 20 69 66 20 6c 65 66 74 3d 3d 72 69 67  d 0 if left==rig
a870: 68 74 2e 20 20 22 45 6e 64 22 20 61 6c 77 61 79  ht.  "End" alway
a880: 73 0a 2a 2a 20 63 6f 6d 70 61 72 65 73 20 67 72  s.** compares gr
a890: 65 61 74 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  eater..*/.static
a8a0: 20 69 6e 74 20 70 6f 73 4c 69 73 74 43 6d 70 28   int posListCmp(
a8b0: 50 4c 52 65 61 64 65 72 20 2a 70 4c 65 66 74 2c  PLReader *pLeft,
a8c0: 20 50 4c 52 65 61 64 65 72 20 2a 70 52 69 67 68   PLReader *pRigh
a8d0: 74 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 4c  t){.  assert( pL
a8e0: 65 66 74 2d 3e 69 54 79 70 65 3d 3d 70 52 69 67  eft->iType==pRig
a8f0: 68 74 2d 3e 69 54 79 70 65 20 29 3b 0a 20 20 69  ht->iType );.  i
a900: 66 28 20 70 4c 65 66 74 2d 3e 69 54 79 70 65 3d  f( pLeft->iType=
a910: 3d 44 4c 5f 44 4f 43 49 44 53 20 29 20 72 65 74  =DL_DOCIDS ) ret
a920: 75 72 6e 20 30 3b 0a 0a 20 20 69 66 28 20 70 6c  urn 0;..  if( pl
a930: 72 41 74 45 6e 64 28 70 4c 65 66 74 29 20 29 20  rAtEnd(pLeft) ) 
a940: 72 65 74 75 72 6e 20 70 6c 72 41 74 45 6e 64 28  return plrAtEnd(
a950: 70 52 69 67 68 74 29 20 3f 20 30 20 3a 20 31 3b  pRight) ? 0 : 1;
a960: 0a 20 20 69 66 28 20 70 6c 72 41 74 45 6e 64 28  .  if( plrAtEnd(
a970: 70 52 69 67 68 74 29 20 29 20 72 65 74 75 72 6e  pRight) ) return
a980: 20 2d 31 3b 0a 0a 20 20 69 66 28 20 70 6c 72 43   -1;..  if( plrC
a990: 6f 6c 75 6d 6e 28 70 4c 65 66 74 29 3c 70 6c 72  olumn(pLeft)<plr
a9a0: 43 6f 6c 75 6d 6e 28 70 52 69 67 68 74 29 20 29  Column(pRight) )
a9b0: 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 69 66   return -1;.  if
a9c0: 28 20 70 6c 72 43 6f 6c 75 6d 6e 28 70 4c 65 66  ( plrColumn(pLef
a9d0: 74 29 3e 70 6c 72 43 6f 6c 75 6d 6e 28 70 52 69  t)>plrColumn(pRi
a9e0: 67 68 74 29 20 29 20 72 65 74 75 72 6e 20 31 3b  ght) ) return 1;
a9f0: 0a 0a 20 20 69 66 28 20 70 6c 72 50 6f 73 69 74  ..  if( plrPosit
aa00: 69 6f 6e 28 70 4c 65 66 74 29 3c 70 6c 72 50 6f  ion(pLeft)<plrPo
aa10: 73 69 74 69 6f 6e 28 70 52 69 67 68 74 29 20 29  sition(pRight) )
aa20: 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 69 66   return -1;.  if
aa30: 28 20 70 6c 72 50 6f 73 69 74 69 6f 6e 28 70 4c  ( plrPosition(pL
aa40: 65 66 74 29 3e 70 6c 72 50 6f 73 69 74 69 6f 6e  eft)>plrPosition
aa50: 28 70 52 69 67 68 74 29 20 29 20 72 65 74 75 72  (pRight) ) retur
aa60: 6e 20 31 3b 0a 20 20 69 66 28 20 70 4c 65 66 74  n 1;.  if( pLeft
aa70: 2d 3e 69 54 79 70 65 3d 3d 44 4c 5f 50 4f 53 49  ->iType==DL_POSI
aa80: 54 49 4f 4e 53 20 29 20 72 65 74 75 72 6e 20 30  TIONS ) return 0
aa90: 3b 0a 0a 20 20 69 66 28 20 70 6c 72 53 74 61 72  ;..  if( plrStar
aaa0: 74 4f 66 66 73 65 74 28 70 4c 65 66 74 29 3c 70  tOffset(pLeft)<p
aab0: 6c 72 53 74 61 72 74 4f 66 66 73 65 74 28 70 52  lrStartOffset(pR
aac0: 69 67 68 74 29 20 29 20 72 65 74 75 72 6e 20 2d  ight) ) return -
aad0: 31 3b 0a 20 20 69 66 28 20 70 6c 72 53 74 61 72  1;.  if( plrStar
aae0: 74 4f 66 66 73 65 74 28 70 4c 65 66 74 29 3e 70  tOffset(pLeft)>p
aaf0: 6c 72 53 74 61 72 74 4f 66 66 73 65 74 28 70 52  lrStartOffset(pR
ab00: 69 67 68 74 29 20 29 20 72 65 74 75 72 6e 20 31  ight) ) return 1
ab10: 3b 0a 0a 20 20 69 66 28 20 70 6c 72 45 6e 64 4f  ;..  if( plrEndO
ab20: 66 66 73 65 74 28 70 4c 65 66 74 29 3c 70 6c 72  ffset(pLeft)<plr
ab30: 45 6e 64 4f 66 66 73 65 74 28 70 52 69 67 68 74  EndOffset(pRight
ab40: 29 20 29 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20  ) ) return -1;. 
ab50: 20 69 66 28 20 70 6c 72 45 6e 64 4f 66 66 73 65   if( plrEndOffse
ab60: 74 28 70 4c 65 66 74 29 3e 70 6c 72 45 6e 64 4f  t(pLeft)>plrEndO
ab70: 66 66 73 65 74 28 70 52 69 67 68 74 29 20 29 20  ffset(pRight) ) 
ab80: 72 65 74 75 72 6e 20 31 3b 0a 0a 20 20 72 65 74  return 1;..  ret
ab90: 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 20 57 72 69  urn 0;.}../* Wri
aba0: 74 65 20 74 68 65 20 75 6e 69 6f 6e 20 6f 66 20  te the union of 
abb0: 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 73 20 69  position lists i
abc0: 6e 20 70 4c 65 66 74 20 61 6e 64 20 70 52 69 67  n pLeft and pRig
abd0: 68 74 20 74 6f 20 70 4f 75 74 2e 0a 2a 2a 20 22  ht to pOut..** "
abe0: 55 6e 69 6f 6e 22 20 69 6e 20 74 68 69 73 20 63  Union" in this c
abf0: 61 73 65 20 6d 65 61 6e 69 6e 67 20 22 41 6c 6c  ase meaning "All
ac00: 20 75 6e 69 71 75 65 20 70 6f 73 69 74 69 6f 6e   unique position
ac10: 20 74 75 70 6c 65 73 22 2e 20 20 53 68 6f 75 6c   tuples".  Shoul
ac20: 64 0a 2a 2a 20 77 6f 72 6b 20 77 69 74 68 20 61  d.** work with a
ac30: 6e 79 20 64 6f 63 6c 69 73 74 20 74 79 70 65 2c  ny doclist type,
ac40: 20 74 68 6f 75 67 68 20 62 6f 74 68 20 69 6e 70   though both inp
ac50: 75 74 73 20 61 6e 64 20 74 68 65 20 6f 75 74 70  uts and the outp
ac60: 75 74 0a 2a 2a 20 73 68 6f 75 6c 64 20 62 65 20  ut.** should be 
ac70: 74 68 65 20 73 61 6d 65 20 74 79 70 65 2e 0a 2a  the same type..*
ac80: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 6f  /.static void po
ac90: 73 4c 69 73 74 55 6e 69 6f 6e 28 44 4c 52 65 61  sListUnion(DLRea
aca0: 64 65 72 20 2a 70 4c 65 66 74 2c 20 44 4c 52 65  der *pLeft, DLRe
acb0: 61 64 65 72 20 2a 70 52 69 67 68 74 2c 20 44 4c  ader *pRight, DL
acc0: 57 72 69 74 65 72 20 2a 70 4f 75 74 29 7b 0a 20  Writer *pOut){. 
acd0: 20 50 4c 52 65 61 64 65 72 20 6c 65 66 74 2c 20   PLReader left, 
ace0: 72 69 67 68 74 3b 0a 20 20 50 4c 57 72 69 74 65  right;.  PLWrite
acf0: 72 20 77 72 69 74 65 72 3b 0a 0a 20 20 61 73 73  r writer;..  ass
ad00: 65 72 74 28 20 64 6c 72 44 6f 63 69 64 28 70 4c  ert( dlrDocid(pL
ad10: 65 66 74 29 3d 3d 64 6c 72 44 6f 63 69 64 28 70  eft)==dlrDocid(p
ad20: 52 69 67 68 74 29 20 29 3b 0a 20 20 61 73 73 65  Right) );.  asse
ad30: 72 74 28 20 70 4c 65 66 74 2d 3e 69 54 79 70 65  rt( pLeft->iType
ad40: 3d 3d 70 52 69 67 68 74 2d 3e 69 54 79 70 65 20  ==pRight->iType 
ad50: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 4c 65  );.  assert( pLe
ad60: 66 74 2d 3e 69 54 79 70 65 3d 3d 70 4f 75 74 2d  ft->iType==pOut-
ad70: 3e 69 54 79 70 65 20 29 3b 0a 0a 20 20 70 6c 72  >iType );..  plr
ad80: 49 6e 69 74 28 26 6c 65 66 74 2c 20 70 4c 65 66  Init(&left, pLef
ad90: 74 29 3b 0a 20 20 70 6c 72 49 6e 69 74 28 26 72  t);.  plrInit(&r
ada0: 69 67 68 74 2c 20 70 52 69 67 68 74 29 3b 0a 20  ight, pRight);. 
adb0: 20 70 6c 77 49 6e 69 74 28 26 77 72 69 74 65 72   plwInit(&writer
adc0: 2c 20 70 4f 75 74 2c 20 64 6c 72 44 6f 63 69 64  , pOut, dlrDocid
add0: 28 70 4c 65 66 74 29 29 3b 0a 0a 20 20 77 68 69  (pLeft));..  whi
ade0: 6c 65 28 20 21 70 6c 72 41 74 45 6e 64 28 26 6c  le( !plrAtEnd(&l
adf0: 65 66 74 29 20 7c 7c 20 21 70 6c 72 41 74 45 6e  eft) || !plrAtEn
ae00: 64 28 26 72 69 67 68 74 29 20 29 7b 0a 20 20 20  d(&right) ){.   
ae10: 20 69 6e 74 20 63 20 3d 20 70 6f 73 4c 69 73 74   int c = posList
ae20: 43 6d 70 28 26 6c 65 66 74 2c 20 26 72 69 67 68  Cmp(&left, &righ
ae30: 74 29 3b 0a 20 20 20 20 69 66 28 20 63 3c 30 20  t);.    if( c<0 
ae40: 29 7b 0a 20 20 20 20 20 20 70 6c 77 43 6f 70 79  ){.      plwCopy
ae50: 28 26 77 72 69 74 65 72 2c 20 26 6c 65 66 74 29  (&writer, &left)
ae60: 3b 0a 20 20 20 20 20 20 70 6c 72 53 74 65 70 28  ;.      plrStep(
ae70: 26 6c 65 66 74 29 3b 0a 20 20 20 20 7d 65 6c 73  &left);.    }els
ae80: 65 20 69 66 28 20 63 3e 30 20 29 7b 0a 20 20 20  e if( c>0 ){.   
ae90: 20 20 20 70 6c 77 43 6f 70 79 28 26 77 72 69 74     plwCopy(&writ
aea0: 65 72 2c 20 26 72 69 67 68 74 29 3b 0a 20 20 20  er, &right);.   
aeb0: 20 20 20 70 6c 72 53 74 65 70 28 26 72 69 67 68     plrStep(&righ
aec0: 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  t);.    }else{. 
aed0: 20 20 20 20 20 70 6c 77 43 6f 70 79 28 26 77 72       plwCopy(&wr
aee0: 69 74 65 72 2c 20 26 6c 65 66 74 29 3b 0a 20 20  iter, &left);.  
aef0: 20 20 20 20 70 6c 72 53 74 65 70 28 26 6c 65 66      plrStep(&lef
af00: 74 29 3b 0a 20 20 20 20 20 20 70 6c 72 53 74 65  t);.      plrSte
af10: 70 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20 7d  p(&right);.    }
af20: 0a 20 20 7d 0a 0a 20 20 70 6c 77 54 65 72 6d 69  .  }..  plwTermi
af30: 6e 61 74 65 28 26 77 72 69 74 65 72 29 3b 0a 20  nate(&writer);. 
af40: 20 70 6c 77 44 65 73 74 72 6f 79 28 26 77 72 69   plwDestroy(&wri
af50: 74 65 72 29 3b 0a 20 20 70 6c 72 44 65 73 74 72  ter);.  plrDestr
af60: 6f 79 28 26 6c 65 66 74 29 3b 0a 20 20 70 6c 72  oy(&left);.  plr
af70: 44 65 73 74 72 6f 79 28 26 72 69 67 68 74 29 3b  Destroy(&right);
af80: 0a 7d 0a 0a 2f 2a 20 57 72 69 74 65 20 74 68 65  .}../* Write the
af90: 20 75 6e 69 6f 6e 20 6f 66 20 64 6f 63 6c 69 73   union of doclis
afa0: 74 73 20 69 6e 20 70 4c 65 66 74 20 61 6e 64 20  ts in pLeft and 
afb0: 70 52 69 67 68 74 20 74 6f 20 70 4f 75 74 2e 20  pRight to pOut. 
afc0: 20 46 6f 72 0a 2a 2a 20 64 6f 63 69 64 73 20 69   For.** docids i
afd0: 6e 20 63 6f 6d 6d 6f 6e 20 62 65 74 77 65 65 6e  n common between
afe0: 20 74 68 65 20 69 6e 70 75 74 73 2c 20 74 68 65   the inputs, the
aff0: 20 75 6e 69 6f 6e 20 6f 66 20 74 68 65 20 70 6f   union of the po
b000: 73 69 74 69 6f 6e 0a 2a 2a 20 6c 69 73 74 73 20  sition.** lists 
b010: 69 73 20 77 72 69 74 74 65 6e 2e 20 20 49 6e 70  is written.  Inp
b020: 75 74 73 20 61 6e 64 20 6f 75 74 70 75 74 73 20  uts and outputs 
b030: 61 72 65 20 61 6c 77 61 79 73 20 74 79 70 65 20  are always type 
b040: 44 4c 5f 44 45 46 41 55 4c 54 2e 0a 2a 2f 0a 73  DL_DEFAULT..*/.s
b050: 74 61 74 69 63 20 76 6f 69 64 20 64 6f 63 4c 69  tatic void docLi
b060: 73 74 55 6e 69 6f 6e 28 0a 20 20 63 6f 6e 73 74  stUnion(.  const
b070: 20 63 68 61 72 20 2a 70 4c 65 66 74 2c 20 69 6e   char *pLeft, in
b080: 74 20 6e 4c 65 66 74 2c 0a 20 20 63 6f 6e 73 74  t nLeft,.  const
b090: 20 63 68 61 72 20 2a 70 52 69 67 68 74 2c 20 69   char *pRight, i
b0a0: 6e 74 20 6e 52 69 67 68 74 2c 0a 20 20 44 61 74  nt nRight,.  Dat
b0b0: 61 42 75 66 66 65 72 20 2a 70 4f 75 74 20 20 20  aBuffer *pOut   
b0c0: 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20     /* Write the 
b0d0: 63 6f 6d 62 69 6e 65 64 20 64 6f 63 6c 69 73 74  combined doclist
b0e0: 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 44 4c   here */.){.  DL
b0f0: 52 65 61 64 65 72 20 6c 65 66 74 2c 20 72 69 67  Reader left, rig
b100: 68 74 3b 0a 20 20 44 4c 57 72 69 74 65 72 20 77  ht;.  DLWriter w
b110: 72 69 74 65 72 3b 0a 0a 20 20 69 66 28 20 6e 4c  riter;..  if( nL
b120: 65 66 74 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66  eft==0 ){.    if
b130: 28 20 6e 52 69 67 68 74 21 3d 30 29 20 64 61 74  ( nRight!=0) dat
b140: 61 42 75 66 66 65 72 41 70 70 65 6e 64 28 70 4f  aBufferAppend(pO
b150: 75 74 2c 20 70 52 69 67 68 74 2c 20 6e 52 69 67  ut, pRight, nRig
b160: 68 74 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b  ht);.    return;
b170: 0a 20 20 7d 0a 20 20 69 66 28 20 6e 52 69 67 68  .  }.  if( nRigh
b180: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 64 61 74 61  t==0 ){.    data
b190: 42 75 66 66 65 72 41 70 70 65 6e 64 28 70 4f 75  BufferAppend(pOu
b1a0: 74 2c 20 70 4c 65 66 74 2c 20 6e 4c 65 66 74 29  t, pLeft, nLeft)
b1b0: 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20  ;.    return;.  
b1c0: 7d 0a 0a 20 20 64 6c 72 49 6e 69 74 28 26 6c 65  }..  dlrInit(&le
b1d0: 66 74 2c 20 44 4c 5f 44 45 46 41 55 4c 54 2c 20  ft, DL_DEFAULT, 
b1e0: 70 4c 65 66 74 2c 20 6e 4c 65 66 74 29 3b 0a 20  pLeft, nLeft);. 
b1f0: 20 64 6c 72 49 6e 69 74 28 26 72 69 67 68 74 2c   dlrInit(&right,
b200: 20 44 4c 5f 44 45 46 41 55 4c 54 2c 20 70 52 69   DL_DEFAULT, pRi
b210: 67 68 74 2c 20 6e 52 69 67 68 74 29 3b 0a 20 20  ght, nRight);.  
b220: 64 6c 77 49 6e 69 74 28 26 77 72 69 74 65 72 2c  dlwInit(&writer,
b230: 20 44 4c 5f 44 45 46 41 55 4c 54 2c 20 70 4f 75   DL_DEFAULT, pOu
b240: 74 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 21 64  t);..  while( !d
b250: 6c 72 41 74 45 6e 64 28 26 6c 65 66 74 29 20 7c  lrAtEnd(&left) |
b260: 7c 20 21 64 6c 72 41 74 45 6e 64 28 26 72 69 67  | !dlrAtEnd(&rig
b270: 68 74 29 20 29 7b 0a 20 20 20 20 69 66 28 20 64  ht) ){.    if( d
b280: 6c 72 41 74 45 6e 64 28 26 72 69 67 68 74 29 20  lrAtEnd(&right) 
b290: 29 7b 0a 20 20 20 20 20 20 64 6c 77 43 6f 70 79  ){.      dlwCopy
b2a0: 28 26 77 72 69 74 65 72 2c 20 26 6c 65 66 74 29  (&writer, &left)
b2b0: 3b 0a 20 20 20 20 20 20 64 6c 72 53 74 65 70 28  ;.      dlrStep(
b2c0: 26 6c 65 66 74 29 3b 0a 20 20 20 20 7d 65 6c 73  &left);.    }els
b2d0: 65 20 69 66 28 20 64 6c 72 41 74 45 6e 64 28 26  e if( dlrAtEnd(&
b2e0: 6c 65 66 74 29 20 29 7b 0a 20 20 20 20 20 20 64  left) ){.      d
b2f0: 6c 77 43 6f 70 79 28 26 77 72 69 74 65 72 2c 20  lwCopy(&writer, 
b300: 26 72 69 67 68 74 29 3b 0a 20 20 20 20 20 20 64  &right);.      d
b310: 6c 72 53 74 65 70 28 26 72 69 67 68 74 29 3b 0a  lrStep(&right);.
b320: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 64 6c      }else if( dl
b330: 72 44 6f 63 69 64 28 26 6c 65 66 74 29 3c 64 6c  rDocid(&left)<dl
b340: 72 44 6f 63 69 64 28 26 72 69 67 68 74 29 20 29  rDocid(&right) )
b350: 7b 0a 20 20 20 20 20 20 64 6c 77 43 6f 70 79 28  {.      dlwCopy(
b360: 26 77 72 69 74 65 72 2c 20 26 6c 65 66 74 29 3b  &writer, &left);
b370: 0a 20 20 20 20 20 20 64 6c 72 53 74 65 70 28 26  .      dlrStep(&
b380: 6c 65 66 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65  left);.    }else
b390: 20 69 66 28 20 64 6c 72 44 6f 63 69 64 28 26 6c   if( dlrDocid(&l
b3a0: 65 66 74 29 3e 64 6c 72 44 6f 63 69 64 28 26 72  eft)>dlrDocid(&r
b3b0: 69 67 68 74 29 20 29 7b 0a 20 20 20 20 20 20 64  ight) ){.      d
b3c0: 6c 77 43 6f 70 79 28 26 77 72 69 74 65 72 2c 20  lwCopy(&writer, 
b3d0: 26 72 69 67 68 74 29 3b 0a 20 20 20 20 20 20 64  &right);.      d
b3e0: 6c 72 53 74 65 70 28 26 72 69 67 68 74 29 3b 0a  lrStep(&right);.
b3f0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
b400: 20 70 6f 73 4c 69 73 74 55 6e 69 6f 6e 28 26 6c   posListUnion(&l
b410: 65 66 74 2c 20 26 72 69 67 68 74 2c 20 26 77 72  eft, &right, &wr
b420: 69 74 65 72 29 3b 0a 20 20 20 20 20 20 64 6c 72  iter);.      dlr
b430: 53 74 65 70 28 26 6c 65 66 74 29 3b 0a 20 20 20  Step(&left);.   
b440: 20 20 20 64 6c 72 53 74 65 70 28 26 72 69 67 68     dlrStep(&righ
b450: 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  t);.    }.  }.. 
b460: 20 64 6c 72 44 65 73 74 72 6f 79 28 26 6c 65 66   dlrDestroy(&lef
b470: 74 29 3b 0a 20 20 64 6c 72 44 65 73 74 72 6f 79  t);.  dlrDestroy
b480: 28 26 72 69 67 68 74 29 3b 0a 20 20 64 6c 77 44  (&right);.  dlwD
b490: 65 73 74 72 6f 79 28 26 77 72 69 74 65 72 29 3b  estroy(&writer);
b4a0: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20  .}../* .** This 
b4b0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64  function is used
b4c0: 20 61 73 20 70 61 72 74 20 6f 66 20 74 68 65 20   as part of the 
b4d0: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  implementation o
b4e0: 66 20 70 68 72 61 73 65 20 61 6e 64 0a 2a 2a 20  f phrase and.** 
b4f0: 4e 45 41 52 20 6d 61 74 63 68 69 6e 67 2e 0a 2a  NEAR matching..*
b500: 2a 0a 2a 2a 20 70 4c 65 66 74 20 61 6e 64 20 70  *.** pLeft and p
b510: 52 69 67 68 74 20 61 72 65 20 44 4c 52 65 61 64  Right are DLRead
b520: 65 72 73 20 70 6f 73 69 74 69 6f 6e 65 64 20 74  ers positioned t
b530: 6f 20 74 68 65 20 73 61 6d 65 20 64 6f 63 69 64  o the same docid
b540: 20 69 6e 0a 2a 2a 20 6c 69 73 74 73 20 6f 66 20   in.** lists of 
b550: 74 79 70 65 20 44 4c 5f 50 4f 53 49 54 49 4f 4e  type DL_POSITION
b560: 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
b570: 77 72 69 74 65 73 20 61 6e 20 65 6e 74 72 79 20  writes an entry 
b580: 74 6f 20 74 68 65 0a 2a 2a 20 44 4c 57 72 69 74  to the.** DLWrit
b590: 65 72 20 70 4f 75 74 20 66 6f 72 20 65 61 63 68  er pOut for each
b5a0: 20 70 6f 73 69 74 69 6f 6e 20 69 6e 20 70 52 69   position in pRi
b5b0: 67 68 74 20 74 68 61 74 20 69 73 20 6c 65 73 73  ght that is less
b5c0: 20 74 68 61 6e 0a 2a 2a 20 28 6e 4e 65 61 72 2b   than.** (nNear+
b5d0: 31 29 20 67 72 65 61 74 65 72 20 28 62 75 74 20  1) greater (but 
b5e0: 6e 6f 74 20 65 71 75 61 6c 20 74 6f 20 6f 72 20  not equal to or 
b5f0: 73 6d 61 6c 6c 65 72 29 20 74 68 61 6e 20 61 20  smaller) than a 
b600: 70 6f 73 69 74 69 6f 6e 20 0a 2a 2a 20 69 6e 20  position .** in 
b610: 70 4c 65 66 74 2e 20 46 6f 72 20 65 78 61 6d 70  pLeft. For examp
b620: 6c 65 2c 20 69 66 20 6e 4e 65 61 72 20 69 73 20  le, if nNear is 
b630: 30 2c 20 61 6e 64 20 74 68 65 20 70 6f 73 69 74  0, and the posit
b640: 69 6f 6e 73 20 63 6f 6e 74 61 69 6e 65 64 0a 2a  ions contained.*
b650: 2a 20 62 79 20 70 4c 65 66 74 20 61 6e 64 20 70  * by pLeft and p
b660: 52 69 67 68 74 20 61 72 65 3a 0a 2a 2a 0a 2a 2a  Right are:.**.**
b670: 20 20 20 20 70 4c 65 66 74 3a 20 20 35 20 31 30      pLeft:  5 10
b680: 20 31 35 20 32 30 0a 2a 2a 20 20 20 20 70 52 69   15 20.**    pRi
b690: 67 68 74 3a 20 36 20 20 39 20 31 37 20 32 31 0a  ght: 6  9 17 21.
b6a0: 2a 2a 0a 2a 2a 20 74 68 65 6e 20 74 68 65 20 64  **.** then the d
b6b0: 6f 63 69 64 20 69 73 20 61 64 64 65 64 20 74 6f  ocid is added to
b6c0: 20 70 4f 75 74 2e 20 49 66 20 70 4f 75 74 20 69   pOut. If pOut i
b6d0: 73 20 6f 66 20 74 79 70 65 20 44 4c 5f 50 4f 53  s of type DL_POS
b6e0: 49 54 49 4f 4e 53 2c 0a 2a 2a 20 74 68 65 6e 20  ITIONS,.** then 
b6f0: 61 20 70 6f 73 69 74 69 6f 6e 69 64 73 20 22 36  a positionids "6
b700: 22 20 61 6e 64 20 22 32 31 22 20 61 72 65 20 61  " and "21" are a
b710: 6c 73 6f 20 61 64 64 65 64 20 74 6f 20 70 4f 75  lso added to pOu
b720: 74 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 62 6f 6f 6c  t..**.** If bool
b730: 65 61 6e 20 61 72 67 75 6d 65 6e 74 20 69 73 53  ean argument isS
b740: 61 76 65 4c 65 66 74 20 69 73 20 74 72 75 65 2c  aveLeft is true,
b750: 20 74 68 65 6e 20 70 6f 73 69 74 69 6f 6e 69 64   then positionid
b760: 73 20 61 72 65 20 63 6f 70 69 65 64 0a 2a 2a 20  s are copied.** 
b770: 66 72 6f 6d 20 70 4c 65 66 74 20 69 6e 73 74 65  from pLeft inste
b780: 61 64 20 6f 66 20 70 52 69 67 68 74 2e 20 49 6e  ad of pRight. In
b790: 20 74 68 65 20 65 78 61 6d 70 6c 65 20 61 62 6f   the example abo
b7a0: 76 65 2c 20 74 68 65 20 70 6f 73 69 74 69 6f 6e  ve, the position
b7b0: 73 20 22 35 22 0a 2a 2a 20 61 6e 64 20 22 32 30  s "5".** and "20
b7c0: 22 20 77 6f 75 6c 64 20 62 65 20 61 64 64 65 64  " would be added
b7d0: 20 69 6e 73 74 65 61 64 20 6f 66 20 22 36 22 20   instead of "6" 
b7e0: 61 6e 64 20 22 32 31 22 2e 0a 2a 2f 0a 73 74 61  and "21"..*/.sta
b7f0: 74 69 63 20 76 6f 69 64 20 70 6f 73 4c 69 73 74  tic void posList
b800: 50 68 72 61 73 65 4d 65 72 67 65 28 0a 20 20 44  PhraseMerge(.  D
b810: 4c 52 65 61 64 65 72 20 2a 70 4c 65 66 74 2c 20  LReader *pLeft, 
b820: 0a 20 20 44 4c 52 65 61 64 65 72 20 2a 70 52 69  .  DLReader *pRi
b830: 67 68 74 2c 0a 20 20 69 6e 74 20 6e 4e 65 61 72  ght,.  int nNear
b840: 2c 0a 20 20 69 6e 74 20 69 73 53 61 76 65 4c 65  ,.  int isSaveLe
b850: 66 74 2c 0a 20 20 44 4c 57 72 69 74 65 72 20 2a  ft,.  DLWriter *
b860: 70 4f 75 74 0a 29 7b 0a 20 20 50 4c 52 65 61 64  pOut.){.  PLRead
b870: 65 72 20 6c 65 66 74 2c 20 72 69 67 68 74 3b 0a  er left, right;.
b880: 20 20 50 4c 57 72 69 74 65 72 20 77 72 69 74 65    PLWriter write
b890: 72 3b 0a 20 20 69 6e 74 20 6d 61 74 63 68 20 3d  r;.  int match =
b8a0: 20 30 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 64   0;..  assert( d
b8b0: 6c 72 44 6f 63 69 64 28 70 4c 65 66 74 29 3d 3d  lrDocid(pLeft)==
b8c0: 64 6c 72 44 6f 63 69 64 28 70 52 69 67 68 74 29  dlrDocid(pRight)
b8d0: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 4f   );.  assert( pO
b8e0: 75 74 2d 3e 69 54 79 70 65 21 3d 44 4c 5f 50 4f  ut->iType!=DL_PO
b8f0: 53 49 54 49 4f 4e 53 5f 4f 46 46 53 45 54 53 20  SITIONS_OFFSETS 
b900: 29 3b 0a 0a 20 20 70 6c 72 49 6e 69 74 28 26 6c  );..  plrInit(&l
b910: 65 66 74 2c 20 70 4c 65 66 74 29 3b 0a 20 20 70  eft, pLeft);.  p
b920: 6c 72 49 6e 69 74 28 26 72 69 67 68 74 2c 20 70  lrInit(&right, p
b930: 52 69 67 68 74 29 3b 0a 0a 20 20 77 68 69 6c 65  Right);..  while
b940: 28 20 21 70 6c 72 41 74 45 6e 64 28 26 6c 65 66  ( !plrAtEnd(&lef
b950: 74 29 20 26 26 20 21 70 6c 72 41 74 45 6e 64 28  t) && !plrAtEnd(
b960: 26 72 69 67 68 74 29 20 29 7b 0a 20 20 20 20 69  &right) ){.    i
b970: 66 28 20 70 6c 72 43 6f 6c 75 6d 6e 28 26 6c 65  f( plrColumn(&le
b980: 66 74 29 3c 70 6c 72 43 6f 6c 75 6d 6e 28 26 72  ft)<plrColumn(&r
b990: 69 67 68 74 29 20 29 7b 0a 20 20 20 20 20 20 70  ight) ){.      p
b9a0: 6c 72 53 74 65 70 28 26 6c 65 66 74 29 3b 0a 20  lrStep(&left);. 
b9b0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 6c 72     }else if( plr
b9c0: 43 6f 6c 75 6d 6e 28 26 6c 65 66 74 29 3e 70 6c  Column(&left)>pl
b9d0: 72 43 6f 6c 75 6d 6e 28 26 72 69 67 68 74 29 20  rColumn(&right) 
b9e0: 29 7b 0a 20 20 20 20 20 20 70 6c 72 53 74 65 70  ){.      plrStep
b9f0: 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20 7d 65  (&right);.    }e
ba00: 6c 73 65 20 69 66 28 20 70 6c 72 50 6f 73 69 74  lse if( plrPosit
ba10: 69 6f 6e 28 26 6c 65 66 74 29 3e 3d 70 6c 72 50  ion(&left)>=plrP
ba20: 6f 73 69 74 69 6f 6e 28 26 72 69 67 68 74 29 20  osition(&right) 
ba30: 29 7b 0a 20 20 20 20 20 20 70 6c 72 53 74 65 70  ){.      plrStep
ba40: 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20 7d 65  (&right);.    }e
ba50: 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20 28  lse{.      if( (
ba60: 70 6c 72 50 6f 73 69 74 69 6f 6e 28 26 72 69 67  plrPosition(&rig
ba70: 68 74 29 2d 70 6c 72 50 6f 73 69 74 69 6f 6e 28  ht)-plrPosition(
ba80: 26 6c 65 66 74 29 29 3c 3d 28 6e 4e 65 61 72 2b  &left))<=(nNear+
ba90: 31 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  1) ){.        if
baa0: 28 20 21 6d 61 74 63 68 20 29 7b 0a 20 20 20 20  ( !match ){.    
bab0: 20 20 20 20 20 20 70 6c 77 49 6e 69 74 28 26 77        plwInit(&w
bac0: 72 69 74 65 72 2c 20 70 4f 75 74 2c 20 64 6c 72  riter, pOut, dlr
bad0: 44 6f 63 69 64 28 70 4c 65 66 74 29 29 3b 0a 20  Docid(pLeft));. 
bae0: 20 20 20 20 20 20 20 20 20 6d 61 74 63 68 20 3d           match =
baf0: 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   1;.        }.  
bb00: 20 20 20 20 20 20 69 66 28 20 21 69 73 53 61 76        if( !isSav
bb10: 65 4c 65 66 74 20 29 7b 0a 20 20 20 20 20 20 20  eLeft ){.       
bb20: 20 20 20 70 6c 77 41 64 64 28 26 77 72 69 74 65     plwAdd(&write
bb30: 72 2c 20 70 6c 72 43 6f 6c 75 6d 6e 28 26 72 69  r, plrColumn(&ri
bb40: 67 68 74 29 2c 20 70 6c 72 50 6f 73 69 74 69 6f  ght), plrPositio
bb50: 6e 28 26 72 69 67 68 74 29 2c 20 30 2c 20 30 29  n(&right), 0, 0)
bb60: 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b  ;.        }else{
bb70: 0a 20 20 20 20 20 20 20 20 20 20 70 6c 77 41 64  .          plwAd
bb80: 64 28 26 77 72 69 74 65 72 2c 20 70 6c 72 43 6f  d(&writer, plrCo
bb90: 6c 75 6d 6e 28 26 6c 65 66 74 29 2c 20 70 6c 72  lumn(&left), plr
bba0: 50 6f 73 69 74 69 6f 6e 28 26 6c 65 66 74 29 2c  Position(&left),
bbb0: 20 30 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20   0, 0);.        
bbc0: 7d 0a 20 20 20 20 20 20 20 20 70 6c 72 53 74 65  }.        plrSte
bbd0: 70 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20 20  p(&right);.     
bbe0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
bbf0: 70 6c 72 53 74 65 70 28 26 6c 65 66 74 29 3b 0a  plrStep(&left);.
bc00: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
bc10: 7d 0a 0a 20 20 69 66 28 20 6d 61 74 63 68 20 29  }..  if( match )
bc20: 7b 0a 20 20 20 20 70 6c 77 54 65 72 6d 69 6e 61  {.    plwTermina
bc30: 74 65 28 26 77 72 69 74 65 72 29 3b 0a 20 20 20  te(&writer);.   
bc40: 20 70 6c 77 44 65 73 74 72 6f 79 28 26 77 72 69   plwDestroy(&wri
bc50: 74 65 72 29 3b 0a 20 20 7d 0a 0a 20 20 70 6c 72  ter);.  }..  plr
bc60: 44 65 73 74 72 6f 79 28 26 6c 65 66 74 29 3b 0a  Destroy(&left);.
bc70: 20 20 70 6c 72 44 65 73 74 72 6f 79 28 26 72 69    plrDestroy(&ri
bc80: 67 68 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  ght);.}../*.** C
bc90: 6f 6d 70 61 72 65 20 74 68 65 20 76 61 6c 75 65  ompare the value
bca0: 73 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20  s pointed to by 
bcb0: 74 68 65 20 50 4c 52 65 61 64 65 72 73 20 70 61  the PLReaders pa
bcc0: 73 73 65 64 20 61 73 20 61 72 67 75 6d 65 6e 74  ssed as argument
bcd0: 73 2e 20 0a 2a 2a 20 52 65 74 75 72 6e 20 2d 31  s. .** Return -1
bce0: 20 69 66 20 74 68 65 20 76 61 6c 75 65 20 70 6f   if the value po
bcf0: 69 6e 74 65 64 20 74 6f 20 62 79 20 70 4c 65 66  inted to by pLef
bd00: 74 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64 20  t is considered 
bd10: 6c 65 73 73 20 74 68 61 6e 0a 2a 2a 20 74 68 65  less than.** the
bd20: 20 76 61 6c 75 65 20 70 6f 69 6e 74 65 64 20 74   value pointed t
bd30: 6f 20 62 79 20 70 52 69 67 68 74 2c 20 2b 31 20  o by pRight, +1 
bd40: 69 66 20 69 74 20 69 73 20 63 6f 6e 73 69 64 65  if it is conside
bd50: 72 65 64 20 67 72 65 61 74 65 72 0a 2a 2a 20 74  red greater.** t
bd60: 68 61 6e 20 69 74 2c 20 6f 72 20 30 20 69 66 20  han it, or 0 if 
bd70: 69 74 20 69 73 20 65 71 75 61 6c 2e 20 69 2e 65  it is equal. i.e
bd80: 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 28 2a 70 4c  ..**.**     (*pL
bd90: 65 66 74 20 2d 20 2a 70 52 69 67 68 74 29 0a 2a  eft - *pRight).*
bda0: 2a 0a 2a 2a 20 41 20 50 4c 52 65 61 64 65 72 20  *.** A PLReader 
bdb0: 74 68 61 74 20 69 73 20 69 6e 20 74 68 65 20 45  that is in the E
bdc0: 4f 46 20 63 6f 6e 64 69 74 69 6f 6e 20 69 73 20  OF condition is 
bdd0: 63 6f 6e 73 69 64 65 72 65 64 20 67 72 65 61 74  considered great
bde0: 65 72 20 74 68 61 6e 0a 2a 2a 20 61 6e 79 20 6f  er than.** any o
bdf0: 74 68 65 72 2e 20 49 66 20 6e 65 69 74 68 65 72  ther. If neither
be00: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 69 6e 20   argument is in 
be10: 45 4f 46 20 73 74 61 74 65 2c 20 74 68 65 20 72  EOF state, the r
be20: 65 74 75 72 6e 20 76 61 6c 75 65 20 6f 66 0a 2a  eturn value of.*
be30: 2a 20 70 6c 72 43 6f 6c 75 6d 6e 28 29 20 69 73  * plrColumn() is
be40: 20 75 73 65 64 2e 20 49 66 20 74 68 65 20 70 6c   used. If the pl
be50: 72 43 6f 6c 75 6d 6e 28 29 20 76 61 6c 75 65 73  rColumn() values
be60: 20 61 72 65 20 65 71 75 61 6c 2c 20 74 68 65 0a   are equal, the.
be70: 2a 2a 20 63 6f 6d 70 61 72 69 73 6f 6e 20 69 73  ** comparison is
be80: 20 6f 6e 20 74 68 65 20 62 61 73 69 73 20 6f 66   on the basis of
be90: 20 70 6c 72 50 6f 73 69 74 69 6f 6e 28 29 2e 0a   plrPosition()..
bea0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 6c  */.static int pl
beb0: 72 43 6f 6d 70 61 72 65 28 50 4c 52 65 61 64 65  rCompare(PLReade
bec0: 72 20 2a 70 4c 65 66 74 2c 20 50 4c 52 65 61 64  r *pLeft, PLRead
bed0: 65 72 20 2a 70 52 69 67 68 74 29 7b 0a 20 20 61  er *pRight){.  a
bee0: 73 73 65 72 74 28 21 70 6c 72 41 74 45 6e 64 28  ssert(!plrAtEnd(
bef0: 70 4c 65 66 74 29 20 7c 7c 20 21 70 6c 72 41 74  pLeft) || !plrAt
bf00: 45 6e 64 28 70 52 69 67 68 74 29 29 3b 0a 0a 20  End(pRight));.. 
bf10: 20 69 66 28 20 70 6c 72 41 74 45 6e 64 28 70 52   if( plrAtEnd(pR
bf20: 69 67 68 74 29 20 7c 7c 20 70 6c 72 41 74 45 6e  ight) || plrAtEn
bf30: 64 28 70 4c 65 66 74 29 20 29 7b 0a 20 20 20 20  d(pLeft) ){.    
bf40: 72 65 74 75 72 6e 20 28 70 6c 72 41 74 45 6e 64  return (plrAtEnd
bf50: 28 70 52 69 67 68 74 29 20 3f 20 2d 31 20 3a 20  (pRight) ? -1 : 
bf60: 31 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 6c  1);.  }.  if( pl
bf70: 72 43 6f 6c 75 6d 6e 28 70 4c 65 66 74 29 21 3d  rColumn(pLeft)!=
bf80: 70 6c 72 43 6f 6c 75 6d 6e 28 70 52 69 67 68 74  plrColumn(pRight
bf90: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
bfa0: 28 28 70 6c 72 43 6f 6c 75 6d 6e 28 70 4c 65 66  ((plrColumn(pLef
bfb0: 74 29 3c 70 6c 72 43 6f 6c 75 6d 6e 28 70 52 69  t)<plrColumn(pRi
bfc0: 67 68 74 29 29 20 3f 20 2d 31 20 3a 20 31 29 3b  ght)) ? -1 : 1);
bfd0: 0a 20 20 7d 0a 20 20 69 66 28 20 70 6c 72 50 6f  .  }.  if( plrPo
bfe0: 73 69 74 69 6f 6e 28 70 4c 65 66 74 29 21 3d 70  sition(pLeft)!=p
bff0: 6c 72 50 6f 73 69 74 69 6f 6e 28 70 52 69 67 68  lrPosition(pRigh
c000: 74 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  t) ){.    return
c010: 20 28 28 70 6c 72 50 6f 73 69 74 69 6f 6e 28 70   ((plrPosition(p
c020: 4c 65 66 74 29 3c 70 6c 72 50 6f 73 69 74 69 6f  Left)<plrPositio
c030: 6e 28 70 52 69 67 68 74 29 29 20 3f 20 2d 31 20  n(pRight)) ? -1 
c040: 3a 20 31 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  : 1);.  }.  retu
c050: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 20 57 65 20 68  rn 0;.}../* We h
c060: 61 76 65 20 74 77 6f 20 64 6f 63 6c 69 73 74 73  ave two doclists
c070: 20 77 69 74 68 20 70 6f 73 69 74 69 6f 6e 73 3a   with positions:
c080: 20 20 70 4c 65 66 74 20 61 6e 64 20 70 52 69 67    pLeft and pRig
c090: 68 74 2e 20 44 65 70 65 6e 64 69 6e 67 0a 2a 2a  ht. Depending.**
c0a0: 20 6f 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66   on the value of
c0b0: 20 74 68 65 20 6e 4e 65 61 72 20 70 61 72 61 6d   the nNear param
c0c0: 65 74 65 72 2c 20 70 65 72 66 6f 72 6d 20 65 69  eter, perform ei
c0d0: 74 68 65 72 20 61 20 70 68 72 61 73 65 0a 2a 2a  ther a phrase.**
c0e0: 20 69 6e 74 65 72 73 65 63 74 69 6f 6e 20 28 69   intersection (i
c0f0: 66 20 6e 4e 65 61 72 3d 3d 30 29 20 6f 72 20 61  f nNear==0) or a
c100: 20 4e 45 41 52 20 69 6e 74 65 72 73 65 63 74 69   NEAR intersecti
c110: 6f 6e 20 28 69 66 20 6e 4e 65 61 72 3e 30 29 0a  on (if nNear>0).
c120: 2a 2a 20 61 6e 64 20 77 72 69 74 65 20 74 68 65  ** and write the
c130: 20 72 65 73 75 6c 74 73 20 69 6e 74 6f 20 70 4f   results into pO
c140: 75 74 2e 0a 2a 2a 0a 2a 2a 20 41 20 70 68 72 61  ut..**.** A phra
c150: 73 65 20 69 6e 74 65 72 73 65 63 74 69 6f 6e 20  se intersection 
c160: 6d 65 61 6e 73 20 74 68 61 74 20 74 77 6f 20 64  means that two d
c170: 6f 63 75 6d 65 6e 74 73 20 6f 6e 6c 79 20 6d 61  ocuments only ma
c180: 74 63 68 0a 2a 2a 20 69 66 20 70 4c 65 66 74 2e  tch.** if pLeft.
c190: 69 50 6f 73 2b 31 3d 3d 70 52 69 67 68 74 2e 69  iPos+1==pRight.i
c1a0: 50 6f 73 2e 0a 2a 2a 0a 2a 2a 20 41 20 4e 45 41  Pos..**.** A NEA
c1b0: 52 20 69 6e 74 65 72 73 65 63 74 69 6f 6e 20 6d  R intersection m
c1c0: 65 61 6e 73 20 74 68 61 74 20 74 77 6f 20 64 6f  eans that two do
c1d0: 63 75 6d 65 6e 74 73 20 6f 6e 6c 79 20 6d 61 74  cuments only mat
c1e0: 63 68 20 69 66 20 0a 2a 2a 20 28 61 62 73 28 70  ch if .** (abs(p
c1f0: 4c 65 66 74 2e 69 50 6f 73 2d 70 52 69 67 68 74  Left.iPos-pRight
c200: 2e 69 50 6f 73 29 3c 6e 4e 65 61 72 29 2e 0a 2a  .iPos)<nNear)..*
c210: 2a 0a 2a 2a 20 49 66 20 61 20 4e 45 41 52 20 69  *.** If a NEAR i
c220: 6e 74 65 72 73 65 63 74 69 6f 6e 20 69 73 20 72  ntersection is r
c230: 65 71 75 65 73 74 65 64 2c 20 74 68 65 6e 20 74  equested, then t
c240: 68 65 20 6e 50 68 72 61 73 65 20 61 72 67 75 6d  he nPhrase argum
c250: 65 6e 74 20 73 68 6f 75 6c 64 0a 2a 2a 20 62 65  ent should.** be
c260: 20 70 61 73 73 65 64 20 74 68 65 20 6e 75 6d 62   passed the numb
c270: 65 72 20 6f 66 20 74 6f 6b 65 6e 73 20 69 6e 20  er of tokens in 
c280: 74 68 65 20 74 77 6f 20 6f 70 65 72 61 6e 64 73  the two operands
c290: 20 74 6f 20 74 68 65 20 4e 45 41 52 20 6f 70 65   to the NEAR ope
c2a0: 72 61 74 6f 72 0a 2a 2a 20 63 6f 6d 62 69 6e 65  rator.** combine
c2b0: 64 2e 20 46 6f 72 20 65 78 61 6d 70 6c 65 3a 0a  d. For example:.
c2c0: 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 51 75 65 72  **.**       Quer
c2d0: 79 20 73 79 6e 74 61 78 20 20 20 20 20 20 20 20  y syntax        
c2e0: 20 20 20 20 20 20 20 6e 50 68 72 61 73 65 0a 2a         nPhrase.*
c2f0: 2a 20 20 20 20 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d  *      ---------
c300: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
c310: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 2a 2a 20 20  -----------.**  
c320: 20 20 20 20 20 22 41 20 42 20 43 22 20 4e 45 41       "A B C" NEA
c330: 52 20 22 44 20 45 22 20 20 20 20 20 20 20 20 20  R "D E"         
c340: 35 0a 2a 2a 20 20 20 20 20 20 20 41 20 4e 45 41  5.**       A NEA
c350: 52 20 42 20 20 20 20 20 20 20 20 20 20 20 20 20  R B             
c360: 20 20 20 20 20 20 32 0a 2a 2a 0a 2a 2a 20 69 54        2.**.** iT
c370: 79 70 65 20 63 6f 6e 74 72 6f 6c 73 20 74 68 65  ype controls the
c380: 20 74 79 70 65 20 6f 66 20 64 61 74 61 20 77 72   type of data wr
c390: 69 74 74 65 6e 20 74 6f 20 70 4f 75 74 2e 20 20  itten to pOut.  
c3a0: 49 66 20 69 54 79 70 65 20 69 73 0a 2a 2a 20 44  If iType is.** D
c3b0: 4c 5f 50 4f 53 49 54 49 4f 4e 53 2c 20 74 68 65  L_POSITIONS, the
c3c0: 20 70 6f 73 69 74 69 6f 6e 73 20 61 72 65 20 74   positions are t
c3d0: 68 6f 73 65 20 66 72 6f 6d 20 70 52 69 67 68 74  hose from pRight
c3e0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
c3f0: 20 64 6f 63 4c 69 73 74 50 68 72 61 73 65 4d 65   docListPhraseMe
c400: 72 67 65 28 0a 20 20 63 6f 6e 73 74 20 63 68 61  rge(.  const cha
c410: 72 20 2a 70 4c 65 66 74 2c 20 69 6e 74 20 6e 4c  r *pLeft, int nL
c420: 65 66 74 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  eft,.  const cha
c430: 72 20 2a 70 52 69 67 68 74 2c 20 69 6e 74 20 6e  r *pRight, int n
c440: 52 69 67 68 74 2c 0a 20 20 69 6e 74 20 6e 4e 65  Right,.  int nNe
c450: 61 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  ar,            /
c460: 2a 20 30 20 66 6f 72 20 61 20 70 68 72 61 73 65  * 0 for a phrase
c470: 20 6d 65 72 67 65 2c 20 6e 6f 6e 2d 7a 65 72 6f   merge, non-zero
c480: 20 66 6f 72 20 61 20 4e 45 41 52 20 6d 65 72 67   for a NEAR merg
c490: 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 68 72 61  e */.  int nPhra
c4a0: 73 65 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  se,          /* 
c4b0: 4e 75 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73  Number of tokens
c4c0: 20 69 6e 20 6c 65 66 74 2b 72 69 67 68 74 20 6f   in left+right o
c4d0: 70 65 72 61 6e 64 73 20 74 6f 20 4e 45 41 52 20  perands to NEAR 
c4e0: 2a 2f 0a 20 20 44 6f 63 4c 69 73 74 54 79 70 65  */.  DocListType
c4f0: 20 69 54 79 70 65 2c 20 20 20 20 2f 2a 20 54 79   iType,    /* Ty
c500: 70 65 20 6f 66 20 64 6f 63 6c 69 73 74 20 74 6f  pe of doclist to
c510: 20 77 72 69 74 65 20 74 6f 20 70 4f 75 74 20 2a   write to pOut *
c520: 2f 0a 20 20 44 61 74 61 42 75 66 66 65 72 20 2a  /.  DataBuffer *
c530: 70 4f 75 74 20 20 20 20 20 20 2f 2a 20 57 72 69  pOut      /* Wri
c540: 74 65 20 74 68 65 20 63 6f 6d 62 69 6e 65 64 20  te the combined 
c550: 64 6f 63 6c 69 73 74 20 68 65 72 65 20 2a 2f 0a  doclist here */.
c560: 29 7b 0a 20 20 44 4c 52 65 61 64 65 72 20 6c 65  ){.  DLReader le
c570: 66 74 2c 20 72 69 67 68 74 3b 0a 20 20 44 4c 57  ft, right;.  DLW
c580: 72 69 74 65 72 20 77 72 69 74 65 72 3b 0a 0a 20  riter writer;.. 
c590: 20 69 66 28 20 6e 4c 65 66 74 3d 3d 30 20 7c 7c   if( nLeft==0 ||
c5a0: 20 6e 52 69 67 68 74 3d 3d 30 20 29 20 72 65 74   nRight==0 ) ret
c5b0: 75 72 6e 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  urn;..  assert( 
c5c0: 69 54 79 70 65 21 3d 44 4c 5f 50 4f 53 49 54 49  iType!=DL_POSITI
c5d0: 4f 4e 53 5f 4f 46 46 53 45 54 53 20 29 3b 0a 0a  ONS_OFFSETS );..
c5e0: 20 20 64 6c 72 49 6e 69 74 28 26 6c 65 66 74 2c    dlrInit(&left,
c5f0: 20 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 2c 20 70   DL_POSITIONS, p
c600: 4c 65 66 74 2c 20 6e 4c 65 66 74 29 3b 0a 20 20  Left, nLeft);.  
c610: 64 6c 72 49 6e 69 74 28 26 72 69 67 68 74 2c 20  dlrInit(&right, 
c620: 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 2c 20 70 52  DL_POSITIONS, pR
c630: 69 67 68 74 2c 20 6e 52 69 67 68 74 29 3b 0a 20  ight, nRight);. 
c640: 20 64 6c 77 49 6e 69 74 28 26 77 72 69 74 65 72   dlwInit(&writer
c650: 2c 20 69 54 79 70 65 2c 20 70 4f 75 74 29 3b 0a  , iType, pOut);.
c660: 0a 20 20 77 68 69 6c 65 28 20 21 64 6c 72 41 74  .  while( !dlrAt
c670: 45 6e 64 28 26 6c 65 66 74 29 20 26 26 20 21 64  End(&left) && !d
c680: 6c 72 41 74 45 6e 64 28 26 72 69 67 68 74 29 20  lrAtEnd(&right) 
c690: 29 7b 0a 20 20 20 20 69 66 28 20 64 6c 72 44 6f  ){.    if( dlrDo
c6a0: 63 69 64 28 26 6c 65 66 74 29 3c 64 6c 72 44 6f  cid(&left)<dlrDo
c6b0: 63 69 64 28 26 72 69 67 68 74 29 20 29 7b 0a 20  cid(&right) ){. 
c6c0: 20 20 20 20 20 64 6c 72 53 74 65 70 28 26 6c 65       dlrStep(&le
c6d0: 66 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  ft);.    }else i
c6e0: 66 28 20 64 6c 72 44 6f 63 69 64 28 26 72 69 67  f( dlrDocid(&rig
c6f0: 68 74 29 3c 64 6c 72 44 6f 63 69 64 28 26 6c 65  ht)<dlrDocid(&le
c700: 66 74 29 20 29 7b 0a 20 20 20 20 20 20 64 6c 72  ft) ){.      dlr
c710: 53 74 65 70 28 26 72 69 67 68 74 29 3b 0a 20 20  Step(&right);.  
c720: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69    }else{.      i
c730: 66 28 20 6e 4e 65 61 72 3d 3d 30 20 29 7b 0a 20  f( nNear==0 ){. 
c740: 20 20 20 20 20 20 20 70 6f 73 4c 69 73 74 50 68         posListPh
c750: 72 61 73 65 4d 65 72 67 65 28 26 6c 65 66 74 2c  raseMerge(&left,
c760: 20 26 72 69 67 68 74 2c 20 30 2c 20 30 2c 20 26   &right, 0, 0, &
c770: 77 72 69 74 65 72 29 3b 0a 20 20 20 20 20 20 7d  writer);.      }
c780: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 2f 2a  else{.        /*
c790: 20 54 68 69 73 20 63 61 73 65 20 6f 63 63 75 72   This case occur
c7a0: 73 20 77 68 65 6e 20 74 77 6f 20 74 65 72 6d 73  s when two terms
c7b0: 20 28 73 69 6d 70 6c 65 20 74 65 72 6d 73 20 6f   (simple terms o
c7c0: 72 20 70 68 72 61 73 65 73 29 20 61 72 65 0a 20  r phrases) are. 
c7d0: 20 20 20 20 20 20 20 20 2a 20 63 6f 6e 6e 65 63          * connec
c7e0: 74 65 64 20 62 79 20 61 20 4e 45 41 52 20 6f 70  ted by a NEAR op
c7f0: 65 72 61 74 6f 72 2c 20 73 70 61 6e 20 28 6e 4e  erator, span (nN
c800: 65 61 72 2b 31 29 2e 20 69 2e 65 2e 0a 20 20 20  ear+1). i.e..   
c810: 20 20 20 20 20 20 2a 0a 20 20 20 20 20 20 20 20        *.        
c820: 20 2a 20 20 20 20 20 27 22 74 65 72 72 69 62 6c   *     '"terribl
c830: 65 20 63 6f 6d 70 61 6e 79 22 20 4e 45 41 52 20  e company" NEAR 
c840: 77 69 64 67 65 74 27 0a 20 20 20 20 20 20 20 20  widget'.        
c850: 20 2a 2f 0a 20 20 20 20 20 20 20 20 44 61 74 61   */.        Data
c860: 42 75 66 66 65 72 20 6f 6e 65 20 3d 20 7b 30 2c  Buffer one = {0,
c870: 20 30 2c 20 30 7d 3b 0a 20 20 20 20 20 20 20 20   0, 0};.        
c880: 44 61 74 61 42 75 66 66 65 72 20 74 77 6f 20 3d  DataBuffer two =
c890: 20 7b 30 2c 20 30 2c 20 30 7d 3b 0a 0a 20 20 20   {0, 0, 0};..   
c8a0: 20 20 20 20 20 44 4c 57 72 69 74 65 72 20 64 6c       DLWriter dl
c8b0: 77 72 69 74 65 72 32 3b 0a 20 20 20 20 20 20 20  writer2;.       
c8c0: 20 44 4c 52 65 61 64 65 72 20 64 72 31 20 3d 20   DLReader dr1 = 
c8d0: 7b 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 7d 3b  {0, 0, 0, 0, 0};
c8e0: 20 0a 20 20 20 20 20 20 20 20 44 4c 52 65 61 64   .        DLRead
c8f0: 65 72 20 64 72 32 20 3d 20 7b 30 2c 20 30 2c 20  er dr2 = {0, 0, 
c900: 30 2c 20 30 2c 20 30 7d 3b 0a 0a 20 20 20 20 20  0, 0, 0};..     
c910: 20 20 20 64 6c 77 49 6e 69 74 28 26 64 6c 77 72     dlwInit(&dlwr
c920: 69 74 65 72 32 2c 20 69 54 79 70 65 2c 20 26 6f  iter2, iType, &o
c930: 6e 65 29 3b 0a 20 20 20 20 20 20 20 20 70 6f 73  ne);.        pos
c940: 4c 69 73 74 50 68 72 61 73 65 4d 65 72 67 65 28  ListPhraseMerge(
c950: 26 72 69 67 68 74 2c 20 26 6c 65 66 74 2c 20 6e  &right, &left, n
c960: 4e 65 61 72 2d 33 2b 6e 50 68 72 61 73 65 2c 20  Near-3+nPhrase, 
c970: 31 2c 20 26 64 6c 77 72 69 74 65 72 32 29 3b 0a  1, &dlwriter2);.
c980: 20 20 20 20 20 20 20 20 64 6c 77 49 6e 69 74 28          dlwInit(
c990: 26 64 6c 77 72 69 74 65 72 32 2c 20 69 54 79 70  &dlwriter2, iTyp
c9a0: 65 2c 20 26 74 77 6f 29 3b 0a 20 20 20 20 20 20  e, &two);.      
c9b0: 20 20 70 6f 73 4c 69 73 74 50 68 72 61 73 65 4d    posListPhraseM
c9c0: 65 72 67 65 28 26 6c 65 66 74 2c 20 26 72 69 67  erge(&left, &rig
c9d0: 68 74 2c 20 6e 4e 65 61 72 2d 31 2c 20 30 2c 20  ht, nNear-1, 0, 
c9e0: 26 64 6c 77 72 69 74 65 72 32 29 3b 0a 0a 20 20  &dlwriter2);..  
c9f0: 20 20 20 20 20 20 69 66 28 20 6f 6e 65 2e 6e 44        if( one.nD
ca00: 61 74 61 29 20 64 6c 72 49 6e 69 74 28 26 64 72  ata) dlrInit(&dr
ca10: 31 2c 20 69 54 79 70 65 2c 20 6f 6e 65 2e 70 44  1, iType, one.pD
ca20: 61 74 61 2c 20 6f 6e 65 2e 6e 44 61 74 61 29 3b  ata, one.nData);
ca30: 0a 20 20 20 20 20 20 20 20 69 66 28 20 74 77 6f  .        if( two
ca40: 2e 6e 44 61 74 61 29 20 64 6c 72 49 6e 69 74 28  .nData) dlrInit(
ca50: 26 64 72 32 2c 20 69 54 79 70 65 2c 20 74 77 6f  &dr2, iType, two
ca60: 2e 70 44 61 74 61 2c 20 74 77 6f 2e 6e 44 61 74  .pData, two.nDat
ca70: 61 29 3b 0a 0a 20 20 20 20 20 20 20 20 69 66 28  a);..        if(
ca80: 20 21 64 6c 72 41 74 45 6e 64 28 26 64 72 31 29   !dlrAtEnd(&dr1)
ca90: 20 7c 7c 20 21 64 6c 72 41 74 45 6e 64 28 26 64   || !dlrAtEnd(&d
caa0: 72 32 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  r2) ){.         
cab0: 20 50 4c 52 65 61 64 65 72 20 70 72 31 20 3d 20   PLReader pr1 = 
cac0: 7b 30 7d 3b 0a 20 20 20 20 20 20 20 20 20 20 50  {0};.          P
cad0: 4c 52 65 61 64 65 72 20 70 72 32 20 3d 20 7b 30  LReader pr2 = {0
cae0: 7d 3b 0a 0a 20 20 20 20 20 20 20 20 20 20 50 4c  };..          PL
caf0: 57 72 69 74 65 72 20 70 6c 77 72 69 74 65 72 3b  Writer plwriter;
cb00: 0a 20 20 20 20 20 20 20 20 20 20 70 6c 77 49 6e  .          plwIn
cb10: 69 74 28 26 70 6c 77 72 69 74 65 72 2c 20 26 77  it(&plwriter, &w
cb20: 72 69 74 65 72 2c 20 64 6c 72 44 6f 63 69 64 28  riter, dlrDocid(
cb30: 64 6c 72 41 74 45 6e 64 28 26 64 72 31 29 3f 26  dlrAtEnd(&dr1)?&
cb40: 64 72 32 3a 26 64 72 31 29 29 3b 0a 0a 20 20 20  dr2:&dr1));..   
cb50: 20 20 20 20 20 20 20 69 66 28 20 6f 6e 65 2e 6e         if( one.n
cb60: 44 61 74 61 20 29 20 70 6c 72 49 6e 69 74 28 26  Data ) plrInit(&
cb70: 70 72 31 2c 20 26 64 72 31 29 3b 0a 20 20 20 20  pr1, &dr1);.    
cb80: 20 20 20 20 20 20 69 66 28 20 74 77 6f 2e 6e 44        if( two.nD
cb90: 61 74 61 20 29 20 70 6c 72 49 6e 69 74 28 26 70  ata ) plrInit(&p
cba0: 72 32 2c 20 26 64 72 32 29 3b 0a 20 20 20 20 20  r2, &dr2);.     
cbb0: 20 20 20 20 20 77 68 69 6c 65 28 20 21 70 6c 72       while( !plr
cbc0: 41 74 45 6e 64 28 26 70 72 31 29 20 7c 7c 20 21  AtEnd(&pr1) || !
cbd0: 70 6c 72 41 74 45 6e 64 28 26 70 72 32 29 20 29  plrAtEnd(&pr2) )
cbe0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 6e  {.            in
cbf0: 74 20 69 43 6f 6d 70 61 72 65 20 3d 20 70 6c 72  t iCompare = plr
cc00: 43 6f 6d 70 61 72 65 28 26 70 72 31 2c 20 26 70  Compare(&pr1, &p
cc10: 72 32 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  r2);.           
cc20: 20 73 77 69 74 63 68 28 20 69 43 6f 6d 70 61 72   switch( iCompar
cc30: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  e ){.           
cc40: 20 20 20 63 61 73 65 20 2d 31 3a 0a 20 20 20 20     case -1:.    
cc50: 20 20 20 20 20 20 20 20 20 20 20 20 70 6c 77 43              plwC
cc60: 6f 70 79 28 26 70 6c 77 72 69 74 65 72 2c 20 26  opy(&plwriter, &
cc70: 70 72 31 29 3b 0a 20 20 20 20 20 20 20 20 20 20  pr1);.          
cc80: 20 20 20 20 20 20 70 6c 72 53 74 65 70 28 26 70        plrStep(&p
cc90: 72 31 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  r1);.           
cca0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
ccb0: 20 20 20 20 20 20 20 20 20 20 63 61 73 65 20 31            case 1
ccc0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
ccd0: 20 20 70 6c 77 43 6f 70 79 28 26 70 6c 77 72 69    plwCopy(&plwri
cce0: 74 65 72 2c 20 26 70 72 32 29 3b 0a 20 20 20 20  ter, &pr2);.    
ccf0: 20 20 20 20 20 20 20 20 20 20 20 20 70 6c 72 53              plrS
cd00: 74 65 70 28 26 70 72 32 29 3b 0a 20 20 20 20 20  tep(&pr2);.     
cd10: 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b             break
cd20: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;.              
cd30: 63 61 73 65 20 30 3a 0a 20 20 20 20 20 20 20 20  case 0:.        
cd40: 20 20 20 20 20 20 20 20 70 6c 77 43 6f 70 79 28          plwCopy(
cd50: 26 70 6c 77 72 69 74 65 72 2c 20 26 70 72 31 29  &plwriter, &pr1)
cd60: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;.              
cd70: 20 20 70 6c 72 53 74 65 70 28 26 70 72 31 29 3b    plrStep(&pr1);
cd80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
cd90: 20 70 6c 72 53 74 65 70 28 26 70 72 32 29 3b 0a   plrStep(&pr2);.
cda0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cdb0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20  break;.         
cdc0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 7d     }.          }
cdd0: 0a 20 20 20 20 20 20 20 20 20 20 70 6c 77 54 65  .          plwTe
cde0: 72 6d 69 6e 61 74 65 28 26 70 6c 77 72 69 74 65  rminate(&plwrite
cdf0: 72 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  r);.        }.  
ce00: 20 20 20 20 20 20 64 61 74 61 42 75 66 66 65 72        dataBuffer
ce10: 44 65 73 74 72 6f 79 28 26 6f 6e 65 29 3b 0a 20  Destroy(&one);. 
ce20: 20 20 20 20 20 20 20 64 61 74 61 42 75 66 66 65         dataBuffe
ce30: 72 44 65 73 74 72 6f 79 28 26 74 77 6f 29 3b 0a  rDestroy(&two);.
ce40: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 64 6c        }.      dl
ce50: 72 53 74 65 70 28 26 6c 65 66 74 29 3b 0a 20 20  rStep(&left);.  
ce60: 20 20 20 20 64 6c 72 53 74 65 70 28 26 72 69 67      dlrStep(&rig
ce70: 68 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ht);.    }.  }..
ce80: 20 20 64 6c 72 44 65 73 74 72 6f 79 28 26 6c 65    dlrDestroy(&le
ce90: 66 74 29 3b 0a 20 20 64 6c 72 44 65 73 74 72 6f  ft);.  dlrDestro
cea0: 79 28 26 72 69 67 68 74 29 3b 0a 20 20 64 6c 77  y(&right);.  dlw
ceb0: 44 65 73 74 72 6f 79 28 26 77 72 69 74 65 72 29  Destroy(&writer)
cec0: 3b 0a 7d 0a 0a 2f 2a 20 57 65 20 68 61 76 65 20  ;.}../* We have 
ced0: 74 77 6f 20 44 4c 5f 44 4f 43 49 44 53 20 64 6f  two DL_DOCIDS do
cee0: 63 6c 69 73 74 73 3a 20 20 70 4c 65 66 74 20 61  clists:  pLeft a
cef0: 6e 64 20 70 52 69 67 68 74 2e 0a 2a 2a 20 57 72  nd pRight..** Wr
cf00: 69 74 65 20 74 68 65 20 69 6e 74 65 72 73 65 63  ite the intersec
cf10: 74 69 6f 6e 20 6f 66 20 74 68 65 73 65 20 74 77  tion of these tw
cf20: 6f 20 64 6f 63 6c 69 73 74 73 20 69 6e 74 6f 20  o doclists into 
cf30: 70 4f 75 74 20 61 73 20 61 0a 2a 2a 20 44 4c 5f  pOut as a.** DL_
cf40: 44 4f 43 49 44 53 20 64 6f 63 6c 69 73 74 2e 0a  DOCIDS doclist..
cf50: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  */.static void d
cf60: 6f 63 4c 69 73 74 41 6e 64 4d 65 72 67 65 28 0a  ocListAndMerge(.
cf70: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 4c    const char *pL
cf80: 65 66 74 2c 20 69 6e 74 20 6e 4c 65 66 74 2c 0a  eft, int nLeft,.
cf90: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 52    const char *pR
cfa0: 69 67 68 74 2c 20 69 6e 74 20 6e 52 69 67 68 74  ight, int nRight
cfb0: 2c 0a 20 20 44 61 74 61 42 75 66 66 65 72 20 2a  ,.  DataBuffer *
cfc0: 70 4f 75 74 20 20 20 20 20 20 2f 2a 20 57 72 69  pOut      /* Wri
cfd0: 74 65 20 74 68 65 20 63 6f 6d 62 69 6e 65 64 20  te the combined 
cfe0: 64 6f 63 6c 69 73 74 20 68 65 72 65 20 2a 2f 0a  doclist here */.
cff0: 29 7b 0a 20 20 44 4c 52 65 61 64 65 72 20 6c 65  ){.  DLReader le
d000: 66 74 2c 20 72 69 67 68 74 3b 0a 20 20 44 4c 57  ft, right;.  DLW
d010: 72 69 74 65 72 20 77 72 69 74 65 72 3b 0a 0a 20  riter writer;.. 
d020: 20 69 66 28 20 6e 4c 65 66 74 3d 3d 30 20 7c 7c   if( nLeft==0 ||
d030: 20 6e 52 69 67 68 74 3d 3d 30 20 29 20 72 65 74   nRight==0 ) ret
d040: 75 72 6e 3b 0a 0a 20 20 64 6c 72 49 6e 69 74 28  urn;..  dlrInit(
d050: 26 6c 65 66 74 2c 20 44 4c 5f 44 4f 43 49 44 53  &left, DL_DOCIDS
d060: 2c 20 70 4c 65 66 74 2c 20 6e 4c 65 66 74 29 3b  , pLeft, nLeft);
d070: 0a 20 20 64 6c 72 49 6e 69 74 28 26 72 69 67 68  .  dlrInit(&righ
d080: 74 2c 20 44 4c 5f 44 4f 43 49 44 53 2c 20 70 52  t, DL_DOCIDS, pR
d090: 69 67 68 74 2c 20 6e 52 69 67 68 74 29 3b 0a 20  ight, nRight);. 
d0a0: 20 64 6c 77 49 6e 69 74 28 26 77 72 69 74 65 72   dlwInit(&writer
d0b0: 2c 20 44 4c 5f 44 4f 43 49 44 53 2c 20 70 4f 75  , DL_DOCIDS, pOu
d0c0: 74 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 21 64  t);..  while( !d
d0d0: 6c 72 41 74 45 6e 64 28 26 6c 65 66 74 29 20 26  lrAtEnd(&left) &
d0e0: 26 20 21 64 6c 72 41 74 45 6e 64 28 26 72 69 67  & !dlrAtEnd(&rig
d0f0: 68 74 29 20 29 7b 0a 20 20 20 20 69 66 28 20 64  ht) ){.    if( d
d100: 6c 72 44 6f 63 69 64 28 26 6c 65 66 74 29 3c 64  lrDocid(&left)<d
d110: 6c 72 44 6f 63 69 64 28 26 72 69 67 68 74 29 20  lrDocid(&right) 
d120: 29 7b 0a 20 20 20 20 20 20 64 6c 72 53 74 65 70  ){.      dlrStep
d130: 28 26 6c 65 66 74 29 3b 0a 20 20 20 20 7d 65 6c  (&left);.    }el
d140: 73 65 20 69 66 28 20 64 6c 72 44 6f 63 69 64 28  se if( dlrDocid(
d150: 26 72 69 67 68 74 29 3c 64 6c 72 44 6f 63 69 64  &right)<dlrDocid
d160: 28 26 6c 65 66 74 29 20 29 7b 0a 20 20 20 20 20  (&left) ){.     
d170: 20 64 6c 72 53 74 65 70 28 26 72 69 67 68 74 29   dlrStep(&right)
d180: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
d190: 20 20 20 64 6c 77 41 64 64 28 26 77 72 69 74 65     dlwAdd(&write
d1a0: 72 2c 20 64 6c 72 44 6f 63 69 64 28 26 6c 65 66  r, dlrDocid(&lef
d1b0: 74 29 29 3b 0a 20 20 20 20 20 20 64 6c 72 53 74  t));.      dlrSt
d1c0: 65 70 28 26 6c 65 66 74 29 3b 0a 20 20 20 20 20  ep(&left);.     
d1d0: 20 64 6c 72 53 74 65 70 28 26 72 69 67 68 74 29   dlrStep(&right)
d1e0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 64  ;.    }.  }..  d
d1f0: 6c 72 44 65 73 74 72 6f 79 28 26 6c 65 66 74 29  lrDestroy(&left)
d200: 3b 0a 20 20 64 6c 72 44 65 73 74 72 6f 79 28 26  ;.  dlrDestroy(&
d210: 72 69 67 68 74 29 3b 0a 20 20 64 6c 77 44 65 73  right);.  dlwDes
d220: 74 72 6f 79 28 26 77 72 69 74 65 72 29 3b 0a 7d  troy(&writer);.}
d230: 0a 0a 2f 2a 20 57 65 20 68 61 76 65 20 74 77 6f  ../* We have two
d240: 20 44 4c 5f 44 4f 43 49 44 53 20 64 6f 63 6c 69   DL_DOCIDS docli
d250: 73 74 73 3a 20 20 70 4c 65 66 74 20 61 6e 64 20  sts:  pLeft and 
d260: 70 52 69 67 68 74 2e 0a 2a 2a 20 57 72 69 74 65  pRight..** Write
d270: 20 74 68 65 20 75 6e 69 6f 6e 20 6f 66 20 74 68   the union of th
d280: 65 73 65 20 74 77 6f 20 64 6f 63 6c 69 73 74 73  ese two doclists
d290: 20 69 6e 74 6f 20 70 4f 75 74 20 61 73 20 61 0a   into pOut as a.
d2a0: 2a 2a 20 44 4c 5f 44 4f 43 49 44 53 20 64 6f 63  ** DL_DOCIDS doc
d2b0: 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  list..*/.static 
d2c0: 76 6f 69 64 20 64 6f 63 4c 69 73 74 4f 72 4d 65  void docListOrMe
d2d0: 72 67 65 28 0a 20 20 63 6f 6e 73 74 20 63 68 61  rge(.  const cha
d2e0: 72 20 2a 70 4c 65 66 74 2c 20 69 6e 74 20 6e 4c  r *pLeft, int nL
d2f0: 65 66 74 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  eft,.  const cha
d300: 72 20 2a 70 52 69 67 68 74 2c 20 69 6e 74 20 6e  r *pRight, int n
d310: 52 69 67 68 74 2c 0a 20 20 44 61 74 61 42 75 66  Right,.  DataBuf
d320: 66 65 72 20 2a 70 4f 75 74 20 20 20 20 20 20 2f  fer *pOut      /
d330: 2a 20 57 72 69 74 65 20 74 68 65 20 63 6f 6d 62  * Write the comb
d340: 69 6e 65 64 20 64 6f 63 6c 69 73 74 20 68 65 72  ined doclist her
d350: 65 20 2a 2f 0a 29 7b 0a 20 20 44 4c 52 65 61 64  e */.){.  DLRead
d360: 65 72 20 6c 65 66 74 2c 20 72 69 67 68 74 3b 0a  er left, right;.
d370: 20 20 44 4c 57 72 69 74 65 72 20 77 72 69 74 65    DLWriter write
d380: 72 3b 0a 0a 20 20 69 66 28 20 6e 4c 65 66 74 3d  r;..  if( nLeft=
d390: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 6e 52  =0 ){.    if( nR
d3a0: 69 67 68 74 21 3d 30 20 29 20 64 61 74 61 42 75  ight!=0 ) dataBu
d3b0: 66 66 65 72 41 70 70 65 6e 64 28 70 4f 75 74 2c  fferAppend(pOut,
d3c0: 20 70 52 69 67 68 74 2c 20 6e 52 69 67 68 74 29   pRight, nRight)
d3d0: 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20  ;.    return;.  
d3e0: 7d 0a 20 20 69 66 28 20 6e 52 69 67 68 74 3d 3d  }.  if( nRight==
d3f0: 30 20 29 7b 0a 20 20 20 20 64 61 74 61 42 75 66  0 ){.    dataBuf
d400: 66 65 72 41 70 70 65 6e 64 28 70 4f 75 74 2c 20  ferAppend(pOut, 
d410: 70 4c 65 66 74 2c 20 6e 4c 65 66 74 29 3b 0a 20  pLeft, nLeft);. 
d420: 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a     return;.  }..
d430: 20 20 64 6c 72 49 6e 69 74 28 26 6c 65 66 74 2c    dlrInit(&left,
d440: 20 44 4c 5f 44 4f 43 49 44 53 2c 20 70 4c 65 66   DL_DOCIDS, pLef
d450: 74 2c 20 6e 4c 65 66 74 29 3b 0a 20 20 64 6c 72  t, nLeft);.  dlr
d460: 49 6e 69 74 28 26 72 69 67 68 74 2c 20 44 4c 5f  Init(&right, DL_
d470: 44 4f 43 49 44 53 2c 20 70 52 69 67 68 74 2c 20  DOCIDS, pRight, 
d480: 6e 52 69 67 68 74 29 3b 0a 20 20 64 6c 77 49 6e  nRight);.  dlwIn
d490: 69 74 28 26 77 72 69 74 65 72 2c 20 44 4c 5f 44  it(&writer, DL_D
d4a0: 4f 43 49 44 53 2c 20 70 4f 75 74 29 3b 0a 0a 20  OCIDS, pOut);.. 
d4b0: 20 77 68 69 6c 65 28 20 21 64 6c 72 41 74 45 6e   while( !dlrAtEn
d4c0: 64 28 26 6c 65 66 74 29 20 7c 7c 20 21 64 6c 72  d(&left) || !dlr
d4d0: 41 74 45 6e 64 28 26 72 69 67 68 74 29 20 29 7b  AtEnd(&right) ){
d4e0: 0a 20 20 20 20 69 66 28 20 64 6c 72 41 74 45 6e  .    if( dlrAtEn
d4f0: 64 28 26 72 69 67 68 74 29 20 29 7b 0a 20 20 20  d(&right) ){.   
d500: 20 20 20 64 6c 77 41 64 64 28 26 77 72 69 74 65     dlwAdd(&write
d510: 72 2c 20 64 6c 72 44 6f 63 69 64 28 26 6c 65 66  r, dlrDocid(&lef
d520: 74 29 29 3b 0a 20 20 20 20 20 20 64 6c 72 53 74  t));.      dlrSt
d530: 65 70 28 26 6c 65 66 74 29 3b 0a 20 20 20 20 7d  ep(&left);.    }
d540: 65 6c 73 65 20 69 66 28 20 64 6c 72 41 74 45 6e  else if( dlrAtEn
d550: 64 28 26 6c 65 66 74 29 20 29 7b 0a 20 20 20 20  d(&left) ){.    
d560: 20 20 64 6c 77 41 64 64 28 26 77 72 69 74 65 72    dlwAdd(&writer
d570: 2c 20 64 6c 72 44 6f 63 69 64 28 26 72 69 67 68  , dlrDocid(&righ
d580: 74 29 29 3b 0a 20 20 20 20 20 20 64 6c 72 53 74  t));.      dlrSt
d590: 65 70 28 26 72 69 67 68 74 29 3b 0a 20 20 20 20  ep(&right);.    
d5a0: 7d 65 6c 73 65 20 69 66 28 20 64 6c 72 44 6f 63  }else if( dlrDoc
d5b0: 69 64 28 26 6c 65 66 74 29 3c 64 6c 72 44 6f 63  id(&left)<dlrDoc
d5c0: 69 64 28 26 72 69 67 68 74 29 20 29 7b 0a 20 20  id(&right) ){.  
d5d0: 20 20 20 20 64 6c 77 41 64 64 28 26 77 72 69 74      dlwAdd(&writ
d5e0: 65 72 2c 20 64 6c 72 44 6f 63 69 64 28 26 6c 65  er, dlrDocid(&le
d5f0: 66 74 29 29 3b 0a 20 20 20 20 20 20 64 6c 72 53  ft));.      dlrS
d600: 74 65 70 28 26 6c 65 66 74 29 3b 0a 20 20 20 20  tep(&left);.    
d610: 7d 65 6c 73 65 20 69 66 28 20 64 6c 72 44 6f 63  }else if( dlrDoc
d620: 69 64 28 26 72 69 67 68 74 29 3c 64 6c 72 44 6f  id(&right)<dlrDo
d630: 63 69 64 28 26 6c 65 66 74 29 20 29 7b 0a 20 20  cid(&left) ){.  
d640: 20 20 20 20 64 6c 77 41 64 64 28 26 77 72 69 74      dlwAdd(&writ
d650: 65 72 2c 20 64 6c 72 44 6f 63 69 64 28 26 72 69  er, dlrDocid(&ri
d660: 67 68 74 29 29 3b 0a 20 20 20 20 20 20 64 6c 72  ght));.      dlr
d670: 53 74 65 70 28 26 72 69 67 68 74 29 3b 0a 20 20  Step(&right);.  
d680: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 64    }else{.      d
d690: 6c 77 41 64 64 28 26 77 72 69 74 65 72 2c 20 64  lwAdd(&writer, d
d6a0: 6c 72 44 6f 63 69 64 28 26 6c 65 66 74 29 29 3b  lrDocid(&left));
d6b0: 0a 20 20 20 20 20 20 64 6c 72 53 74 65 70 28 26  .      dlrStep(&
d6c0: 6c 65 66 74 29 3b 0a 20 20 20 20 20 20 64 6c 72  left);.      dlr
d6d0: 53 74 65 70 28 26 72 69 67 68 74 29 3b 0a 20 20  Step(&right);.  
d6e0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 64 6c 72 44 65    }.  }..  dlrDe
d6f0: 73 74 72 6f 79 28 26 6c 65 66 74 29 3b 0a 20 20  stroy(&left);.  
d700: 64 6c 72 44 65 73 74 72 6f 79 28 26 72 69 67 68  dlrDestroy(&righ
d710: 74 29 3b 0a 20 20 64 6c 77 44 65 73 74 72 6f 79  t);.  dlwDestroy
d720: 28 26 77 72 69 74 65 72 29 3b 0a 7d 0a 0a 2f 2a  (&writer);.}../*
d730: 20 57 65 20 68 61 76 65 20 74 77 6f 20 44 4c 5f   We have two DL_
d740: 44 4f 43 49 44 53 20 64 6f 63 6c 69 73 74 73 3a  DOCIDS doclists:
d750: 20 20 70 4c 65 66 74 20 61 6e 64 20 70 52 69 67    pLeft and pRig
d760: 68 74 2e 0a 2a 2a 20 57 72 69 74 65 20 69 6e 74  ht..** Write int
d770: 6f 20 70 4f 75 74 20 61 73 20 44 4c 5f 44 4f 43  o pOut as DL_DOC
d780: 49 44 53 20 64 6f 63 6c 69 73 74 20 63 6f 6e 74  IDS doclist cont
d790: 61 69 6e 69 6e 67 20 61 6c 6c 20 64 6f 63 75 6d  aining all docum
d7a0: 65 6e 74 73 20 74 68 61 74 0a 2a 2a 20 6f 63 63  ents that.** occ
d7b0: 75 72 20 69 6e 20 70 4c 65 66 74 20 62 75 74 20  ur in pLeft but 
d7c0: 6e 6f 74 20 69 6e 20 70 52 69 67 68 74 2e 0a 2a  not in pRight..*
d7d0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f  /.static void do
d7e0: 63 4c 69 73 74 45 78 63 65 70 74 4d 65 72 67 65  cListExceptMerge
d7f0: 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  (.  const char *
d800: 70 4c 65 66 74 2c 20 69 6e 74 20 6e 4c 65 66 74  pLeft, int nLeft
d810: 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ,.  const char *
d820: 70 52 69 67 68 74 2c 20 69 6e 74 20 6e 52 69 67  pRight, int nRig
d830: 68 74 2c 0a 20 20 44 61 74 61 42 75 66 66 65 72  ht,.  DataBuffer
d840: 20 2a 70 4f 75 74 20 20 20 20 20 20 2f 2a 20 57   *pOut      /* W
d850: 72 69 74 65 20 74 68 65 20 63 6f 6d 62 69 6e 65  rite the combine
d860: 64 20 64 6f 63 6c 69 73 74 20 68 65 72 65 20 2a  d doclist here *
d870: 2f 0a 29 7b 0a 20 20 44 4c 52 65 61 64 65 72 20  /.){.  DLReader 
d880: 6c 65 66 74 2c 20 72 69 67 68 74 3b 0a 20 20 44  left, right;.  D
d890: 4c 57 72 69 74 65 72 20 77 72 69 74 65 72 3b 0a  LWriter writer;.
d8a0: 0a 20 20 69 66 28 20 6e 4c 65 66 74 3d 3d 30 20  .  if( nLeft==0 
d8b0: 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20  ) return;.  if( 
d8c0: 6e 52 69 67 68 74 3d 3d 30 20 29 7b 0a 20 20 20  nRight==0 ){.   
d8d0: 20 64 61 74 61 42 75 66 66 65 72 41 70 70 65 6e   dataBufferAppen
d8e0: 64 28 70 4f 75 74 2c 20 70 4c 65 66 74 2c 20 6e  d(pOut, pLeft, n
d8f0: 4c 65 66 74 29 3b 0a 20 20 20 20 72 65 74 75 72  Left);.    retur
d900: 6e 3b 0a 20 20 7d 0a 0a 20 20 64 6c 72 49 6e 69  n;.  }..  dlrIni
d910: 74 28 26 6c 65 66 74 2c 20 44 4c 5f 44 4f 43 49  t(&left, DL_DOCI
d920: 44 53 2c 20 70 4c 65 66 74 2c 20 6e 4c 65 66 74  DS, pLeft, nLeft
d930: 29 3b 0a 20 20 64 6c 72 49 6e 69 74 28 26 72 69  );.  dlrInit(&ri
d940: 67 68 74 2c 20 44 4c 5f 44 4f 43 49 44 53 2c 20  ght, DL_DOCIDS, 
d950: 70 52 69 67 68 74 2c 20 6e 52 69 67 68 74 29 3b  pRight, nRight);
d960: 0a 20 20 64 6c 77 49 6e 69 74 28 26 77 72 69 74  .  dlwInit(&writ
d970: 65 72 2c 20 44 4c 5f 44 4f 43 49 44 53 2c 20 70  er, DL_DOCIDS, p
d980: 4f 75 74 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20  Out);..  while( 
d990: 21 64 6c 72 41 74 45 6e 64 28 26 6c 65 66 74 29  !dlrAtEnd(&left)
d9a0: 20 29 7b 0a 20 20 20 20 77 68 69 6c 65 28 20 21   ){.    while( !
d9b0: 64 6c 72 41 74 45 6e 64 28 26 72 69 67 68 74 29  dlrAtEnd(&right)
d9c0: 20 26 26 20 64 6c 72 44 6f 63 69 64 28 26 72 69   && dlrDocid(&ri
d9d0: 67 68 74 29 3c 64 6c 72 44 6f 63 69 64 28 26 6c  ght)<dlrDocid(&l
d9e0: 65 66 74 29 20 29 7b 0a 20 20 20 20 20 20 64 6c  eft) ){.      dl
d9f0: 72 53 74 65 70 28 26 72 69 67 68 74 29 3b 0a 20  rStep(&right);. 
da00: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 64 6c 72     }.    if( dlr
da10: 41 74 45 6e 64 28 26 72 69 67 68 74 29 20 7c 7c  AtEnd(&right) ||
da20: 20 64 6c 72 44 6f 63 69 64 28 26 6c 65 66 74 29   dlrDocid(&left)
da30: 3c 64 6c 72 44 6f 63 69 64 28 26 72 69 67 68 74  <dlrDocid(&right
da40: 29 20 29 7b 0a 20 20 20 20 20 20 64 6c 77 41 64  ) ){.      dlwAd
da50: 64 28 26 77 72 69 74 65 72 2c 20 64 6c 72 44 6f  d(&writer, dlrDo
da60: 63 69 64 28 26 6c 65 66 74 29 29 3b 0a 20 20 20  cid(&left));.   
da70: 20 7d 0a 20 20 20 20 64 6c 72 53 74 65 70 28 26   }.    dlrStep(&
da80: 6c 65 66 74 29 3b 0a 20 20 7d 0a 0a 20 20 64 6c  left);.  }..  dl
da90: 72 44 65 73 74 72 6f 79 28 26 6c 65 66 74 29 3b  rDestroy(&left);
daa0: 0a 20 20 64 6c 72 44 65 73 74 72 6f 79 28 26 72  .  dlrDestroy(&r
dab0: 69 67 68 74 29 3b 0a 20 20 64 6c 77 44 65 73 74  ight);.  dlwDest
dac0: 72 6f 79 28 26 77 72 69 74 65 72 29 3b 0a 7d 0a  roy(&writer);.}.
dad0: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 73 74  .static char *st
dae0: 72 69 6e 67 5f 64 75 70 5f 6e 28 63 6f 6e 73 74  ring_dup_n(const
daf0: 20 63 68 61 72 20 2a 73 2c 20 69 6e 74 20 6e 29   char *s, int n)
db00: 7b 0a 20 20 63 68 61 72 20 2a 73 74 72 20 3d 20  {.  char *str = 
db10: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e  sqlite3_malloc(n
db20: 20 2b 20 31 29 3b 0a 20 20 6d 65 6d 63 70 79 28   + 1);.  memcpy(
db30: 73 74 72 2c 20 73 2c 20 6e 29 3b 0a 20 20 73 74  str, s, n);.  st
db40: 72 5b 6e 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 72  r[n] = '\0';.  r
db50: 65 74 75 72 6e 20 73 74 72 3b 0a 7d 0a 0a 2f 2a  eturn str;.}../*
db60: 20 44 75 70 6c 69 63 61 74 65 20 61 20 73 74 72   Duplicate a str
db70: 69 6e 67 3b 20 74 68 65 20 63 61 6c 6c 65 72 20  ing; the caller 
db80: 6d 75 73 74 20 66 72 65 65 28 29 20 74 68 65 20  must free() the 
db90: 72 65 74 75 72 6e 65 64 20 73 74 72 69 6e 67 2e  returned string.
dba0: 0a 20 2a 20 28 57 65 20 64 6f 6e 27 74 20 75 73  . * (We don't us
dbb0: 65 20 73 74 72 64 75 70 28 29 20 73 69 6e 63 65  e strdup() since
dbc0: 20 69 74 20 69 73 20 6e 6f 74 20 70 61 72 74 20   it is not part 
dbd0: 6f 66 20 74 68 65 20 73 74 61 6e 64 61 72 64 20  of the standard 
dbe0: 43 20 6c 69 62 72 61 72 79 20 61 6e 64 0a 20 2a  C library and. *
dbf0: 20 6d 61 79 20 6e 6f 74 20 62 65 20 61 76 61 69   may not be avai
dc00: 6c 61 62 6c 65 20 65 76 65 72 79 77 68 65 72 65  lable everywhere
dc10: 2e 29 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61  .) */.static cha
dc20: 72 20 2a 73 74 72 69 6e 67 5f 64 75 70 28 63 6f  r *string_dup(co
dc30: 6e 73 74 20 63 68 61 72 20 2a 73 29 7b 0a 20 20  nst char *s){.  
dc40: 72 65 74 75 72 6e 20 73 74 72 69 6e 67 5f 64 75  return string_du
dc50: 70 5f 6e 28 73 2c 20 73 74 72 6c 65 6e 28 73 29  p_n(s, strlen(s)
dc60: 29 3b 0a 7d 0a 0a 2f 2a 20 46 6f 72 6d 61 74 20  );.}../* Format 
dc70: 61 20 73 74 72 69 6e 67 2c 20 72 65 70 6c 61 63  a string, replac
dc80: 69 6e 67 20 65 61 63 68 20 6f 63 63 75 72 72 65  ing each occurre
dc90: 6e 63 65 20 6f 66 20 74 68 65 20 25 20 63 68 61  nce of the % cha
dca0: 72 61 63 74 65 72 20 77 69 74 68 0a 20 2a 20 7a  racter with. * z
dcb0: 44 62 2e 7a 4e 61 6d 65 2e 20 20 54 68 69 73 20  Db.zName.  This 
dcc0: 6d 61 79 20 62 65 20 6d 6f 72 65 20 63 6f 6e 76  may be more conv
dcd0: 65 6e 69 65 6e 74 20 74 68 61 6e 20 73 71 6c 69  enient than sqli
dce0: 74 65 5f 6d 70 72 69 6e 74 66 28 29 0a 20 2a 20  te_mprintf(). * 
dcf0: 77 68 65 6e 20 6f 6e 65 20 73 74 72 69 6e 67 20  when one string 
dd00: 69 73 20 75 73 65 64 20 72 65 70 65 61 74 65 64  is used repeated
dd10: 6c 79 20 69 6e 20 61 20 66 6f 72 6d 61 74 20 73  ly in a format s
dd20: 74 72 69 6e 67 2e 0a 20 2a 20 54 68 65 20 63 61  tring.. * The ca
dd30: 6c 6c 65 72 20 6d 75 73 74 20 66 72 65 65 28 29  ller must free()
dd40: 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 73 74   the returned st
dd50: 72 69 6e 67 2e 20 2a 2f 0a 73 74 61 74 69 63 20  ring. */.static 
dd60: 63 68 61 72 20 2a 73 74 72 69 6e 67 5f 66 6f 72  char *string_for
dd70: 6d 61 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  mat(const char *
dd80: 7a 46 6f 72 6d 61 74 2c 0a 20 20 20 20 20 20 20  zFormat,.       
dd90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dda0: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
ddb0: 7a 44 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  zDb, const char 
ddc0: 2a 7a 4e 61 6d 65 29 7b 0a 20 20 63 6f 6e 73 74  *zName){.  const
ddd0: 20 63 68 61 72 20 2a 70 3b 0a 20 20 73 69 7a 65   char *p;.  size
dde0: 5f 74 20 6c 65 6e 20 3d 20 30 3b 0a 20 20 73 69  _t len = 0;.  si
ddf0: 7a 65 5f 74 20 6e 44 62 20 3d 20 73 74 72 6c 65  ze_t nDb = strle
de00: 6e 28 7a 44 62 29 3b 0a 20 20 73 69 7a 65 5f 74  n(zDb);.  size_t
de10: 20 6e 4e 61 6d 65 20 3d 20 73 74 72 6c 65 6e 28   nName = strlen(
de20: 7a 4e 61 6d 65 29 3b 0a 20 20 73 69 7a 65 5f 74  zName);.  size_t
de30: 20 6e 46 75 6c 6c 54 61 62 6c 65 4e 61 6d 65 20   nFullTableName 
de40: 3d 20 6e 44 62 2b 31 2b 6e 4e 61 6d 65 3b 0a 20  = nDb+1+nName;. 
de50: 20 63 68 61 72 20 2a 72 65 73 75 6c 74 3b 0a 20   char *result;. 
de60: 20 63 68 61 72 20 2a 72 3b 0a 0a 20 20 2f 2a 20   char *r;..  /* 
de70: 66 69 72 73 74 20 63 6f 6d 70 75 74 65 20 6c 65  first compute le
de80: 6e 67 74 68 20 6e 65 65 64 65 64 20 2a 2f 0a 20  ngth needed */. 
de90: 20 66 6f 72 28 70 20 3d 20 7a 46 6f 72 6d 61 74   for(p = zFormat
dea0: 20 3b 20 2a 70 20 3b 20 2b 2b 70 29 7b 0a 20 20   ; *p ; ++p){.  
deb0: 20 20 6c 65 6e 20 2b 3d 20 28 2a 70 3d 3d 27 25    len += (*p=='%
dec0: 27 20 3f 20 6e 46 75 6c 6c 54 61 62 6c 65 4e 61  ' ? nFullTableNa
ded0: 6d 65 20 3a 20 31 29 3b 0a 20 20 7d 0a 20 20 6c  me : 1);.  }.  l
dee0: 65 6e 20 2b 3d 20 31 3b 20 20 2f 2a 20 66 6f 72  en += 1;  /* for
def0: 20 6e 75 6c 6c 20 74 65 72 6d 69 6e 61 74 6f 72   null terminator
df00: 20 2a 2f 0a 0a 20 20 72 20 3d 20 72 65 73 75 6c   */..  r = resul
df10: 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  t = sqlite3_mall
df20: 6f 63 28 6c 65 6e 29 3b 0a 20 20 66 6f 72 28 70  oc(len);.  for(p
df30: 20 3d 20 7a 46 6f 72 6d 61 74 3b 20 2a 70 3b 20   = zFormat; *p; 
df40: 2b 2b 70 29 7b 0a 20 20 20 20 69 66 28 20 2a 70  ++p){.    if( *p
df50: 3d 3d 27 25 27 20 29 7b 0a 20 20 20 20 20 20 6d  =='%' ){.      m
df60: 65 6d 63 70 79 28 72 2c 20 7a 44 62 2c 20 6e 44  emcpy(r, zDb, nD
df70: 62 29 3b 0a 20 20 20 20 20 20 72 20 2b 3d 20 6e  b);.      r += n
df80: 44 62 3b 0a 20 20 20 20 20 20 2a 72 2b 2b 20 3d  Db;.      *r++ =
df90: 20 27 2e 27 3b 0a 20 20 20 20 20 20 6d 65 6d 63   '.';.      memc
dfa0: 70 79 28 72 2c 20 7a 4e 61 6d 65 2c 20 6e 4e 61  py(r, zName, nNa
dfb0: 6d 65 29 3b 0a 20 20 20 20 20 20 72 20 2b 3d 20  me);.      r += 
dfc0: 6e 4e 61 6d 65 3b 0a 20 20 20 20 7d 20 65 6c 73  nName;.    } els
dfd0: 65 20 7b 0a 20 20 20 20 20 20 2a 72 2b 2b 20 3d  e {.      *r++ =
dfe0: 20 2a 70 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20   *p;.    }.  }. 
dff0: 20 2a 72 2b 2b 20 3d 20 27 5c 30 27 3b 0a 20 20   *r++ = '\0';.  
e000: 61 73 73 65 72 74 28 20 72 20 3d 3d 20 72 65 73  assert( r == res
e010: 75 6c 74 20 2b 20 6c 65 6e 20 29 3b 0a 20 20 72  ult + len );.  r
e020: 65 74 75 72 6e 20 72 65 73 75 6c 74 3b 0a 7d 0a  eturn result;.}.
e030: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 71 6c 5f  .static int sql_
e040: 65 78 65 63 28 73 71 6c 69 74 65 33 20 2a 64 62  exec(sqlite3 *db
e050: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44  , const char *zD
e060: 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  b, const char *z
e070: 4e 61 6d 65 2c 0a 20 20 20 20 20 20 20 20 20 20  Name,.          
e080: 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20            const 
e090: 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 29 7b 0a  char *zFormat){.
e0a0: 20 20 63 68 61 72 20 2a 7a 43 6f 6d 6d 61 6e 64    char *zCommand
e0b0: 20 3d 20 73 74 72 69 6e 67 5f 66 6f 72 6d 61 74   = string_format
e0c0: 28 7a 46 6f 72 6d 61 74 2c 20 7a 44 62 2c 20 7a  (zFormat, zDb, z
e0d0: 4e 61 6d 65 29 3b 0a 20 20 69 6e 74 20 72 63 3b  Name);.  int rc;
e0e0: 0a 20 20 46 54 53 54 52 41 43 45 28 28 22 46 54  .  FTSTRACE(("FT
e0f0: 53 33 20 73 71 6c 3a 20 25 73 5c 6e 22 2c 20 7a  S3 sql: %s\n", z
e100: 43 6f 6d 6d 61 6e 64 29 29 3b 0a 20 20 72 63 20  Command));.  rc 
e110: 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64  = sqlite3_exec(d
e120: 62 2c 20 7a 43 6f 6d 6d 61 6e 64 2c 20 4e 55 4c  b, zCommand, NUL
e130: 4c 2c 20 30 2c 20 4e 55 4c 4c 29 3b 0a 20 20 73  L, 0, NULL);.  s
e140: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 43 6f 6d  qlite3_free(zCom
e150: 6d 61 6e 64 29 3b 0a 20 20 72 65 74 75 72 6e 20  mand);.  return 
e160: 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  rc;.}..static in
e170: 74 20 73 71 6c 5f 70 72 65 70 61 72 65 28 73 71  t sql_prepare(sq
e180: 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74  lite3 *db, const
e190: 20 63 68 61 72 20 2a 7a 44 62 2c 20 63 6f 6e 73   char *zDb, cons
e1a0: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20  t char *zName,. 
e1b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e1c0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74        sqlite3_st
e1d0: 6d 74 20 2a 2a 70 70 53 74 6d 74 2c 20 63 6f 6e  mt **ppStmt, con
e1e0: 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74  st char *zFormat
e1f0: 29 7b 0a 20 20 63 68 61 72 20 2a 7a 43 6f 6d 6d  ){.  char *zComm
e200: 61 6e 64 20 3d 20 73 74 72 69 6e 67 5f 66 6f 72  and = string_for
e210: 6d 61 74 28 7a 46 6f 72 6d 61 74 2c 20 7a 44 62  mat(zFormat, zDb
e220: 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 69 6e 74 20  , zName);.  int 
e230: 72 63 3b 0a 20 20 46 54 53 54 52 41 43 45 28 28  rc;.  FTSTRACE((
e240: 22 46 54 53 33 20 70 72 65 70 61 72 65 3a 20 25  "FTS3 prepare: %
e250: 73 5c 6e 22 2c 20 7a 43 6f 6d 6d 61 6e 64 29 29  s\n", zCommand))
e260: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
e270: 5f 70 72 65 70 61 72 65 5f 76 32 28 64 62 2c 20  _prepare_v2(db, 
e280: 7a 43 6f 6d 6d 61 6e 64 2c 20 2d 31 2c 20 70 70  zCommand, -1, pp
e290: 53 74 6d 74 2c 20 4e 55 4c 4c 29 3b 0a 20 20 73  Stmt, NULL);.  s
e2a0: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 43 6f 6d  qlite3_free(zCom
e2b0: 6d 61 6e 64 29 3b 0a 20 20 72 65 74 75 72 6e 20  mand);.  return 
e2c0: 72 63 3b 0a 7d 0a 0a 2f 2a 20 65 6e 64 20 75 74  rc;.}../* end ut
e2d0: 69 6c 69 74 79 20 66 75 6e 63 74 69 6f 6e 73 20  ility functions 
e2e0: 2a 2f 0a 0a 2f 2a 20 46 6f 72 77 61 72 64 20 72  */../* Forward r
e2f0: 65 66 65 72 65 6e 63 65 20 2a 2f 0a 74 79 70 65  eference */.type
e300: 64 65 66 20 73 74 72 75 63 74 20 66 75 6c 6c 74  def struct fullt
e310: 65 78 74 5f 76 74 61 62 20 66 75 6c 6c 74 65 78  ext_vtab fulltex
e320: 74 5f 76 74 61 62 3b 0a 0a 2f 2a 0a 2a 2a 20 41  t_vtab;../*.** A
e330: 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  n instance of th
e340: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 72 75  e following stru
e350: 63 74 75 72 65 20 6b 65 65 70 73 20 74 72 61 63  cture keeps trac
e360: 6b 20 6f 66 20 67 65 6e 65 72 61 74 65 64 0a 2a  k of generated.*
e370: 2a 20 6d 61 74 63 68 69 6e 67 2d 77 6f 72 64 20  * matching-word 
e380: 6f 66 66 73 65 74 20 69 6e 66 6f 72 6d 61 74 69  offset informati
e390: 6f 6e 20 61 6e 64 20 73 6e 69 70 70 65 74 73 2e  on and snippets.
e3a0: 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75  .*/.typedef stru
e3b0: 63 74 20 53 6e 69 70 70 65 74 20 7b 0a 20 20 69  ct Snippet {.  i
e3c0: 6e 74 20 6e 4d 61 74 63 68 3b 20 20 20 20 20 2f  nt nMatch;     /
e3d0: 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  * Total number o
e3e0: 66 20 6d 61 74 63 68 65 73 20 2a 2f 0a 20 20 69  f matches */.  i
e3f0: 6e 74 20 6e 41 6c 6c 6f 63 3b 20 20 20 20 20 2f  nt nAlloc;     /
e400: 2a 20 53 70 61 63 65 20 61 6c 6c 6f 63 61 74 65  * Space allocate
e410: 64 20 66 6f 72 20 61 4d 61 74 63 68 5b 5d 20 2a  d for aMatch[] *
e420: 2f 0a 20 20 73 74 72 75 63 74 20 73 6e 69 70 70  /.  struct snipp
e430: 65 74 4d 61 74 63 68 20 7b 20 2f 2a 20 4f 6e 65  etMatch { /* One
e440: 20 65 6e 74 72 79 20 66 6f 72 20 65 61 63 68 20   entry for each 
e450: 6d 61 74 63 68 69 6e 67 20 74 65 72 6d 20 2a 2f  matching term */
e460: 0a 20 20 20 20 63 68 61 72 20 73 6e 53 74 61 74  .    char snStat
e470: 75 73 3b 20 20 20 20 20 20 20 2f 2a 20 53 74 61  us;       /* Sta
e480: 74 75 73 20 66 6c 61 67 20 66 6f 72 20 75 73 65  tus flag for use
e490: 20 77 68 69 6c 65 20 63 6f 6e 73 74 72 75 63 74   while construct
e4a0: 69 6e 67 20 73 6e 69 70 70 65 74 73 20 2a 2f 0a  ing snippets */.
e4b0: 20 20 20 20 73 68 6f 72 74 20 69 6e 74 20 69 43      short int iC
e4c0: 6f 6c 3b 20 20 20 20 20 20 2f 2a 20 54 68 65 20  ol;      /* The 
e4d0: 63 6f 6c 75 6d 6e 20 74 68 61 74 20 63 6f 6e 74  column that cont
e4e0: 61 69 6e 73 20 74 68 65 20 6d 61 74 63 68 20 2a  ains the match *
e4f0: 2f 0a 20 20 20 20 73 68 6f 72 74 20 69 6e 74 20  /.    short int 
e500: 69 54 65 72 6d 3b 20 20 20 20 20 2f 2a 20 54 68  iTerm;     /* Th
e510: 65 20 69 6e 64 65 78 20 69 6e 20 51 75 65 72 79  e index in Query
e520: 2e 70 54 65 72 6d 73 5b 5d 20 6f 66 20 74 68 65  .pTerms[] of the
e530: 20 6d 61 74 63 68 69 6e 67 20 74 65 72 6d 20 2a   matching term *
e540: 2f 0a 20 20 20 20 69 6e 74 20 69 54 6f 6b 65 6e  /.    int iToken
e550: 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68  ;          /* Th
e560: 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 6d  e index of the m
e570: 61 74 63 68 69 6e 67 20 64 6f 63 75 6d 65 6e 74  atching document
e580: 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 20 20 73 68   token */.    sh
e590: 6f 72 74 20 69 6e 74 20 6e 42 79 74 65 3b 20 20  ort int nByte;  
e5a0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
e5b0: 62 79 74 65 73 20 69 6e 20 74 68 65 20 74 65 72  bytes in the ter
e5c0: 6d 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 53 74  m */.    int iSt
e5d0: 61 72 74 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  art;          /*
e5e0: 20 54 68 65 20 6f 66 66 73 65 74 20 74 6f 20 74   The offset to t
e5f0: 68 65 20 66 69 72 73 74 20 63 68 61 72 61 63 74  he first charact
e600: 65 72 20 6f 66 20 74 68 65 20 74 65 72 6d 20 2a  er of the term *
e610: 2f 0a 20 20 7d 20 2a 61 4d 61 74 63 68 3b 20 20  /.  } *aMatch;  
e620: 20 20 20 20 2f 2a 20 50 6f 69 6e 74 73 20 74 6f      /* Points to
e630: 20 73 70 61 63 65 20 6f 62 74 61 69 6e 65 64 20   space obtained 
e640: 66 72 6f 6d 20 6d 61 6c 6c 6f 63 20 2a 2f 0a 20  from malloc */. 
e650: 20 63 68 61 72 20 2a 7a 4f 66 66 73 65 74 3b 20   char *zOffset; 
e660: 20 2f 2a 20 54 65 78 74 20 72 65 6e 64 65 72 69   /* Text renderi
e670: 6e 67 20 6f 66 20 61 4d 61 74 63 68 5b 5d 20 2a  ng of aMatch[] *
e680: 2f 0a 20 20 69 6e 74 20 6e 4f 66 66 73 65 74 3b  /.  int nOffset;
e690: 20 20 20 20 2f 2a 20 73 74 72 6c 65 6e 28 7a 4f      /* strlen(zO
e6a0: 66 66 73 65 74 29 20 2a 2f 0a 20 20 63 68 61 72  ffset) */.  char
e6b0: 20 2a 7a 53 6e 69 70 70 65 74 3b 20 2f 2a 20 53   *zSnippet; /* S
e6c0: 6e 69 70 70 65 74 20 74 65 78 74 20 2a 2f 0a 20  nippet text */. 
e6d0: 20 69 6e 74 20 6e 53 6e 69 70 70 65 74 3b 20 20   int nSnippet;  
e6e0: 20 2f 2a 20 73 74 72 6c 65 6e 28 7a 53 6e 69 70   /* strlen(zSnip
e6f0: 70 65 74 29 20 2a 2f 0a 7d 20 53 6e 69 70 70 65  pet) */.} Snippe
e700: 74 3b 0a 0a 0a 74 79 70 65 64 65 66 20 65 6e 75  t;...typedef enu
e710: 6d 20 51 75 65 72 79 54 79 70 65 20 7b 0a 20 20  m QueryType {.  
e720: 51 55 45 52 59 5f 47 45 4e 45 52 49 43 2c 20 20  QUERY_GENERIC,  
e730: 20 2f 2a 20 74 61 62 6c 65 20 73 63 61 6e 20 2a   /* table scan *
e740: 2f 0a 20 20 51 55 45 52 59 5f 44 4f 43 49 44 2c  /.  QUERY_DOCID,
e750: 20 20 20 20 20 2f 2a 20 6c 6f 6f 6b 75 70 20 62       /* lookup b
e760: 79 20 64 6f 63 69 64 20 2a 2f 0a 20 20 51 55 45  y docid */.  QUE
e770: 52 59 5f 46 55 4c 4c 54 45 58 54 20 20 20 2f 2a  RY_FULLTEXT   /*
e780: 20 51 55 45 52 59 5f 46 55 4c 4c 54 45 58 54 20   QUERY_FULLTEXT 
e790: 2b 20 5b 69 5d 20 69 73 20 61 20 66 75 6c 6c 2d  + [i] is a full-
e7a0: 74 65 78 74 20 73 65 61 72 63 68 20 66 6f 72 20  text search for 
e7b0: 63 6f 6c 75 6d 6e 20 69 2a 2f 0a 7d 20 51 75 65  column i*/.} Que
e7c0: 72 79 54 79 70 65 3b 0a 0a 74 79 70 65 64 65 66  ryType;..typedef
e7d0: 20 65 6e 75 6d 20 66 75 6c 6c 74 65 78 74 5f 73   enum fulltext_s
e7e0: 74 61 74 65 6d 65 6e 74 20 7b 0a 20 20 43 4f 4e  tatement {.  CON
e7f0: 54 45 4e 54 5f 49 4e 53 45 52 54 5f 53 54 4d 54  TENT_INSERT_STMT
e800: 2c 0a 20 20 43 4f 4e 54 45 4e 54 5f 53 45 4c 45  ,.  CONTENT_SELE
e810: 43 54 5f 53 54 4d 54 2c 0a 20 20 43 4f 4e 54 45  CT_STMT,.  CONTE
e820: 4e 54 5f 55 50 44 41 54 45 5f 53 54 4d 54 2c 0a  NT_UPDATE_STMT,.
e830: 20 20 43 4f 4e 54 45 4e 54 5f 44 45 4c 45 54 45    CONTENT_DELETE
e840: 5f 53 54 4d 54 2c 0a 20 20 43 4f 4e 54 45 4e 54  _STMT,.  CONTENT
e850: 5f 45 58 49 53 54 53 5f 53 54 4d 54 2c 0a 0a 20  _EXISTS_STMT,.. 
e860: 20 42 4c 4f 43 4b 5f 49 4e 53 45 52 54 5f 53 54   BLOCK_INSERT_ST
e870: 4d 54 2c 0a 20 20 42 4c 4f 43 4b 5f 53 45 4c 45  MT,.  BLOCK_SELE
e880: 43 54 5f 53 54 4d 54 2c 0a 20 20 42 4c 4f 43 4b  CT_STMT,.  BLOCK
e890: 5f 44 45 4c 45 54 45 5f 53 54 4d 54 2c 0a 20 20  _DELETE_STMT,.  
e8a0: 42 4c 4f 43 4b 5f 44 45 4c 45 54 45 5f 41 4c 4c  BLOCK_DELETE_ALL
e8b0: 5f 53 54 4d 54 2c 0a 0a 20 20 53 45 47 44 49 52  _STMT,..  SEGDIR
e8c0: 5f 4d 41 58 5f 49 4e 44 45 58 5f 53 54 4d 54 2c  _MAX_INDEX_STMT,
e8d0: 0a 20 20 53 45 47 44 49 52 5f 53 45 54 5f 53 54  .  SEGDIR_SET_ST
e8e0: 4d 54 2c 0a 20 20 53 45 47 44 49 52 5f 53 45 4c  MT,.  SEGDIR_SEL
e8f0: 45 43 54 5f 4c 45 56 45 4c 5f 53 54 4d 54 2c 0a  ECT_LEVEL_STMT,.
e900: 20 20 53 45 47 44 49 52 5f 53 50 41 4e 5f 53 54    SEGDIR_SPAN_ST
e910: 4d 54 2c 0a 20 20 53 45 47 44 49 52 5f 44 45 4c  MT,.  SEGDIR_DEL
e920: 45 54 45 5f 53 54 4d 54 2c 0a 20 20 53 45 47 44  ETE_STMT,.  SEGD
e930: 49 52 5f 53 45 4c 45 43 54 5f 53 45 47 4d 45 4e  IR_SELECT_SEGMEN
e940: 54 5f 53 54 4d 54 2c 0a 20 20 53 45 47 44 49 52  T_STMT,.  SEGDIR
e950: 5f 53 45 4c 45 43 54 5f 41 4c 4c 5f 53 54 4d 54  _SELECT_ALL_STMT
e960: 2c 0a 20 20 53 45 47 44 49 52 5f 44 45 4c 45 54  ,.  SEGDIR_DELET
e970: 45 5f 41 4c 4c 5f 53 54 4d 54 2c 0a 20 20 53 45  E_ALL_STMT,.  SE
e980: 47 44 49 52 5f 43 4f 55 4e 54 5f 53 54 4d 54 2c  GDIR_COUNT_STMT,
e990: 0a 0a 20 20 4d 41 58 5f 53 54 4d 54 20 20 20 20  ..  MAX_STMT    
e9a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e9b0: 20 2f 2a 20 41 6c 77 61 79 73 20 61 74 20 65 6e   /* Always at en
e9c0: 64 21 20 2a 2f 0a 7d 20 66 75 6c 6c 74 65 78 74  d! */.} fulltext
e9d0: 5f 73 74 61 74 65 6d 65 6e 74 3b 0a 0a 2f 2a 20  _statement;../* 
e9e0: 54 68 65 73 65 20 6d 75 73 74 20 65 78 61 63 74  These must exact
e9f0: 6c 79 20 6d 61 74 63 68 20 74 68 65 20 65 6e 75  ly match the enu
ea00: 6d 20 61 62 6f 76 65 2e 20 2a 2f 0a 2f 2a 20 54  m above. */./* T
ea10: 4f 44 4f 28 73 68 65 73 73 29 3a 20 49 73 20 74  ODO(shess): Is t
ea20: 68 65 72 65 20 73 6f 6d 65 20 72 69 73 6b 20 74  here some risk t
ea30: 68 61 74 20 61 20 73 74 61 74 65 6d 65 6e 74 20  hat a statement 
ea40: 77 69 6c 6c 20 62 65 20 75 73 65 64 20 69 6e 20  will be used in 
ea50: 74 77 6f 0a 2a 2a 20 63 75 72 73 6f 72 73 20 61  two.** cursors a
ea60: 74 20 6f 6e 63 65 2c 20 65 2e 67 2e 20 20 69 66  t once, e.g.  if
ea70: 20 61 20 71 75 65 72 79 20 6a 6f 69 6e 73 20 61   a query joins a
ea80: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 74   virtual table t
ea90: 6f 20 69 74 73 65 6c 66 3f 0a 2a 2a 20 49 66 20  o itself?.** If 
eaa0: 73 6f 20 70 65 72 68 61 70 73 20 77 65 20 73 68  so perhaps we sh
eab0: 6f 75 6c 64 20 6d 6f 76 65 20 73 6f 6d 65 20 6f  ould move some o
eac0: 66 20 74 68 65 73 65 20 74 6f 20 74 68 65 20 63  f these to the c
ead0: 75 72 73 6f 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f  ursor object..*/
eae0: 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68  .static const ch
eaf0: 61 72 20 2a 63 6f 6e 73 74 20 66 75 6c 6c 74 65  ar *const fullte
eb00: 78 74 5f 7a 53 74 61 74 65 6d 65 6e 74 5b 4d 41  xt_zStatement[MA
eb10: 58 5f 53 54 4d 54 5d 20 3d 20 7b 0a 20 20 2f 2a  X_STMT] = {.  /*
eb20: 20 43 4f 4e 54 45 4e 54 5f 49 4e 53 45 52 54 20   CONTENT_INSERT 
eb30: 2a 2f 20 4e 55 4c 4c 2c 20 20 2f 2a 20 67 65 6e  */ NULL,  /* gen
eb40: 65 72 61 74 65 64 20 69 6e 20 63 6f 6e 74 65 6e  erated in conten
eb50: 74 49 6e 73 65 72 74 53 74 61 74 65 6d 65 6e 74  tInsertStatement
eb60: 28 29 20 2a 2f 0a 20 20 2f 2a 20 43 4f 4e 54 45  () */.  /* CONTE
eb70: 4e 54 5f 53 45 4c 45 43 54 20 2a 2f 20 4e 55 4c  NT_SELECT */ NUL
eb80: 4c 2c 20 20 2f 2a 20 67 65 6e 65 72 61 74 65 64  L,  /* generated
eb90: 20 69 6e 20 63 6f 6e 74 65 6e 74 53 65 6c 65 63   in contentSelec
eba0: 74 53 74 61 74 65 6d 65 6e 74 28 29 20 2a 2f 0a  tStatement() */.
ebb0: 20 20 2f 2a 20 43 4f 4e 54 45 4e 54 5f 55 50 44    /* CONTENT_UPD
ebc0: 41 54 45 20 2a 2f 20 4e 55 4c 4c 2c 20 20 2f 2a  ATE */ NULL,  /*
ebd0: 20 67 65 6e 65 72 61 74 65 64 20 69 6e 20 63 6f   generated in co
ebe0: 6e 74 65 6e 74 55 70 64 61 74 65 53 74 61 74 65  ntentUpdateState
ebf0: 6d 65 6e 74 28 29 20 2a 2f 0a 20 20 2f 2a 20 43  ment() */.  /* C
ec00: 4f 4e 54 45 4e 54 5f 44 45 4c 45 54 45 20 2a 2f  ONTENT_DELETE */
ec10: 20 22 64 65 6c 65 74 65 20 66 72 6f 6d 20 25 5f   "delete from %_
ec20: 63 6f 6e 74 65 6e 74 20 77 68 65 72 65 20 64 6f  content where do
ec30: 63 69 64 20 3d 20 3f 22 2c 0a 20 20 2f 2a 20 43  cid = ?",.  /* C
ec40: 4f 4e 54 45 4e 54 5f 45 58 49 53 54 53 20 2a 2f  ONTENT_EXISTS */
ec50: 20 22 73 65 6c 65 63 74 20 64 6f 63 69 64 20 66   "select docid f
ec60: 72 6f 6d 20 25 5f 63 6f 6e 74 65 6e 74 20 6c 69  rom %_content li
ec70: 6d 69 74 20 31 22 2c 0a 0a 20 20 2f 2a 20 42 4c  mit 1",..  /* BL
ec80: 4f 43 4b 5f 49 4e 53 45 52 54 20 2a 2f 0a 20 20  OCK_INSERT */.  
ec90: 22 69 6e 73 65 72 74 20 69 6e 74 6f 20 25 5f 73  "insert into %_s
eca0: 65 67 6d 65 6e 74 73 20 28 62 6c 6f 63 6b 69 64  egments (blockid
ecb0: 2c 20 62 6c 6f 63 6b 29 20 76 61 6c 75 65 73 20  , block) values 
ecc0: 28 6e 75 6c 6c 2c 20 3f 29 22 2c 0a 20 20 2f 2a  (null, ?)",.  /*
ecd0: 20 42 4c 4f 43 4b 5f 53 45 4c 45 43 54 20 2a 2f   BLOCK_SELECT */
ece0: 20 22 73 65 6c 65 63 74 20 62 6c 6f 63 6b 20 66   "select block f
ecf0: 72 6f 6d 20 25 5f 73 65 67 6d 65 6e 74 73 20 77  rom %_segments w
ed00: 68 65 72 65 20 62 6c 6f 63 6b 69 64 20 3d 20 3f  here blockid = ?
ed10: 22 2c 0a 20 20 2f 2a 20 42 4c 4f 43 4b 5f 44 45  ",.  /* BLOCK_DE
ed20: 4c 45 54 45 20 2a 2f 20 22 64 65 6c 65 74 65 20  LETE */ "delete 
ed30: 66 72 6f 6d 20 25 5f 73 65 67 6d 65 6e 74 73 20  from %_segments 
ed40: 77 68 65 72 65 20 62 6c 6f 63 6b 69 64 20 62 65  where blockid be
ed50: 74 77 65 65 6e 20 3f 20 61 6e 64 20 3f 22 2c 0a  tween ? and ?",.
ed60: 20 20 2f 2a 20 42 4c 4f 43 4b 5f 44 45 4c 45 54    /* BLOCK_DELET
ed70: 45 5f 41 4c 4c 20 2a 2f 20 22 64 65 6c 65 74 65  E_ALL */ "delete
ed80: 20 66 72 6f 6d 20 25 5f 73 65 67 6d 65 6e 74 73   from %_segments
ed90: 22 2c 0a 0a 20 20 2f 2a 20 53 45 47 44 49 52 5f  ",..  /* SEGDIR_
eda0: 4d 41 58 5f 49 4e 44 45 58 20 2a 2f 20 22 73 65  MAX_INDEX */ "se
edb0: 6c 65 63 74 20 6d 61 78 28 69 64 78 29 20 66 72  lect max(idx) fr
edc0: 6f 6d 20 25 5f 73 65 67 64 69 72 20 77 68 65 72  om %_segdir wher
edd0: 65 20 6c 65 76 65 6c 20 3d 20 3f 22 2c 0a 20 20  e level = ?",.  
ede0: 2f 2a 20 53 45 47 44 49 52 5f 53 45 54 20 2a 2f  /* SEGDIR_SET */
edf0: 20 22 69 6e 73 65 72 74 20 69 6e 74 6f 20 25 5f   "insert into %_
ee00: 73 65 67 64 69 72 20 76 61 6c 75 65 73 20 28 3f  segdir values (?
ee10: 2c 20 3f 2c 20 3f 2c 20 3f 2c 20 3f 2c 20 3f 29  , ?, ?, ?, ?, ?)
ee20: 22 2c 0a 20 20 2f 2a 20 53 45 47 44 49 52 5f 53  ",.  /* SEGDIR_S
ee30: 45 4c 45 43 54 5f 4c 45 56 45 4c 20 2a 2f 0a 20  ELECT_LEVEL */. 
ee40: 20 22 73 65 6c 65 63 74 20 73 74 61 72 74 5f 62   "select start_b
ee50: 6c 6f 63 6b 2c 20 6c 65 61 76 65 73 5f 65 6e 64  lock, leaves_end
ee60: 5f 62 6c 6f 63 6b 2c 20 72 6f 6f 74 20 66 72 6f  _block, root fro
ee70: 6d 20 25 5f 73 65 67 64 69 72 20 22 0a 20 20 22  m %_segdir ".  "
ee80: 20 77 68 65 72 65 20 6c 65 76 65 6c 20 3d 20 3f   where level = ?
ee90: 20 6f 72 64 65 72 20 62 79 20 69 64 78 22 2c 0a   order by idx",.
eea0: 20 20 2f 2a 20 53 45 47 44 49 52 5f 53 50 41 4e    /* SEGDIR_SPAN
eeb0: 20 2a 2f 0a 20 20 22 73 65 6c 65 63 74 20 6d 69   */.  "select mi
eec0: 6e 28 73 74 61 72 74 5f 62 6c 6f 63 6b 29 2c 20  n(start_block), 
eed0: 6d 61 78 28 65 6e 64 5f 62 6c 6f 63 6b 29 20 66  max(end_block) f
eee0: 72 6f 6d 20 25 5f 73 65 67 64 69 72 20 22 0a 20  rom %_segdir ". 
eef0: 20 22 20 77 68 65 72 65 20 6c 65 76 65 6c 20 3d   " where level =
ef00: 20 3f 20 61 6e 64 20 73 74 61 72 74 5f 62 6c 6f   ? and start_blo
ef10: 63 6b 20 3c 3e 20 30 22 2c 0a 20 20 2f 2a 20 53  ck <> 0",.  /* S
ef20: 45 47 44 49 52 5f 44 45 4c 45 54 45 20 2a 2f 20  EGDIR_DELETE */ 
ef30: 22 64 65 6c 65 74 65 20 66 72 6f 6d 20 25 5f 73  "delete from %_s
ef40: 65 67 64 69 72 20 77 68 65 72 65 20 6c 65 76 65  egdir where leve
ef50: 6c 20 3d 20 3f 22 2c 0a 0a 20 20 2f 2a 20 4e 4f  l = ?",..  /* NO
ef60: 54 45 28 73 68 65 73 73 29 3a 20 54 68 65 20 66  TE(shess): The f
ef70: 69 72 73 74 20 74 68 72 65 65 20 72 65 73 75 6c  irst three resul
ef80: 74 73 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77  ts of the follow
ef90: 69 6e 67 20 74 77 6f 0a 20 20 2a 2a 20 73 74 61  ing two.  ** sta
efa0: 74 65 6d 65 6e 74 73 20 6d 75 73 74 20 6d 61 74  tements must mat
efb0: 63 68 2e 0a 20 20 2a 2f 0a 20 20 2f 2a 20 53 45  ch..  */.  /* SE
efc0: 47 44 49 52 5f 53 45 4c 45 43 54 5f 53 45 47 4d  GDIR_SELECT_SEGM
efd0: 45 4e 54 20 2a 2f 0a 20 20 22 73 65 6c 65 63 74  ENT */.  "select
efe0: 20 73 74 61 72 74 5f 62 6c 6f 63 6b 2c 20 6c 65   start_block, le
eff0: 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 6b 2c 20  aves_end_block, 
f000: 72 6f 6f 74 20 66 72 6f 6d 20 25 5f 73 65 67 64  root from %_segd
f010: 69 72 20 22 0a 20 20 22 20 77 68 65 72 65 20 6c  ir ".  " where l
f020: 65 76 65 6c 20 3d 20 3f 20 61 6e 64 20 69 64 78  evel = ? and idx
f030: 20 3d 20 3f 22 2c 0a 20 20 2f 2a 20 53 45 47 44   = ?",.  /* SEGD
f040: 49 52 5f 53 45 4c 45 43 54 5f 41 4c 4c 20 2a 2f  IR_SELECT_ALL */
f050: 0a 20 20 22 73 65 6c 65 63 74 20 73 74 61 72 74  .  "select start
f060: 5f 62 6c 6f 63 6b 2c 20 6c 65 61 76 65 73 5f 65  _block, leaves_e
f070: 6e 64 5f 62 6c 6f 63 6b 2c 20 72 6f 6f 74 20 66  nd_block, root f
f080: 72 6f 6d 20 25 5f 73 65 67 64 69 72 20 22 0a 20  rom %_segdir ". 
f090: 20 22 20 6f 72 64 65 72 20 62 79 20 6c 65 76 65   " order by leve
f0a0: 6c 20 64 65 73 63 2c 20 69 64 78 20 61 73 63 22  l desc, idx asc"
f0b0: 2c 0a 20 20 2f 2a 20 53 45 47 44 49 52 5f 44 45  ,.  /* SEGDIR_DE
f0c0: 4c 45 54 45 5f 41 4c 4c 20 2a 2f 20 22 64 65 6c  LETE_ALL */ "del
f0d0: 65 74 65 20 66 72 6f 6d 20 25 5f 73 65 67 64 69  ete from %_segdi
f0e0: 72 22 2c 0a 20 20 2f 2a 20 53 45 47 44 49 52 5f  r",.  /* SEGDIR_
f0f0: 43 4f 55 4e 54 20 2a 2f 20 22 73 65 6c 65 63 74  COUNT */ "select
f100: 20 63 6f 75 6e 74 28 2a 29 2c 20 69 66 6e 75 6c   count(*), ifnul
f110: 6c 28 6d 61 78 28 6c 65 76 65 6c 29 2c 30 29 20  l(max(level),0) 
f120: 66 72 6f 6d 20 25 5f 73 65 67 64 69 72 22 2c 0a  from %_segdir",.
f130: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 63 6f 6e 6e  };../*.** A conn
f140: 65 63 74 69 6f 6e 20 74 6f 20 61 20 66 75 6c 6c  ection to a full
f150: 74 65 78 74 20 69 6e 64 65 78 20 69 73 20 61 6e  text index is an
f160: 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65   instance of the
f170: 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 73 74   following.** st
f180: 72 75 63 74 75 72 65 2e 20 20 54 68 65 20 78 43  ructure.  The xC
f190: 72 65 61 74 65 20 61 6e 64 20 78 43 6f 6e 6e 65  reate and xConne
f1a0: 63 74 20 6d 65 74 68 6f 64 73 20 63 72 65 61 74  ct methods creat
f1b0: 65 20 61 6e 20 69 6e 73 74 61 6e 63 65 0a 2a 2a  e an instance.**
f1c0: 20 6f 66 20 74 68 69 73 20 73 74 72 75 63 74 75   of this structu
f1d0: 72 65 20 61 6e 64 20 78 44 65 73 74 72 6f 79 20  re and xDestroy 
f1e0: 61 6e 64 20 78 44 69 73 63 6f 6e 6e 65 63 74 20  and xDisconnect 
f1f0: 66 72 65 65 20 74 68 61 74 20 69 6e 73 74 61 6e  free that instan
f200: 63 65 2e 0a 2a 2a 20 41 6c 6c 20 6f 74 68 65 72  ce..** All other
f210: 20 6d 65 74 68 6f 64 73 20 72 65 63 65 69 76 65   methods receive
f220: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
f230: 65 20 73 74 72 75 63 74 75 72 65 20 61 73 20 6f  e structure as o
f240: 6e 65 20 6f 66 20 74 68 65 69 72 0a 2a 2a 20 61  ne of their.** a
f250: 72 67 75 6d 65 6e 74 73 2e 0a 2a 2f 0a 73 74 72  rguments..*/.str
f260: 75 63 74 20 66 75 6c 6c 74 65 78 74 5f 76 74 61  uct fulltext_vta
f270: 62 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  b {.  sqlite3_vt
f280: 61 62 20 62 61 73 65 3b 20 20 20 20 20 20 20 20  ab base;        
f290: 20 20 20 20 20 20 20 2f 2a 20 42 61 73 65 20 63         /* Base c
f2a0: 6c 61 73 73 20 75 73 65 64 20 62 79 20 53 51 4c  lass used by SQL
f2b0: 69 74 65 20 63 6f 72 65 20 2a 2f 0a 20 20 73 71  ite core */.  sq
f2c0: 6c 69 74 65 33 20 2a 64 62 3b 20 20 20 20 20 20  lite3 *db;      
f2d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
f2e0: 2a 20 54 68 65 20 64 61 74 61 62 61 73 65 20 63  * The database c
f2f0: 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 63  onnection */.  c
f300: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 62 3b 20  onst char *zDb; 
f310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f320: 2f 2a 20 6c 6f 67 69 63 61 6c 20 64 61 74 61 62  /* logical datab
f330: 61 73 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f  ase name */.  co
f340: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b  nst char *zName;
f350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
f360: 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  * virtual table 
f370: 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 43  name */.  int nC
f380: 6f 6c 75 6d 6e 3b 20 20 20 20 20 20 20 20 20 20  olumn;          
f390: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 75             /* nu
f3a0: 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20  mber of columns 
f3b0: 69 6e 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  in virtual table
f3c0: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61 7a 43   */.  char **azC
f3d0: 6f 6c 75 6d 6e 3b 20 20 20 20 20 20 20 20 20 20  olumn;          
f3e0: 20 20 20 20 20 20 20 2f 2a 20 63 6f 6c 75 6d 6e         /* column
f3f0: 20 6e 61 6d 65 73 2e 20 20 6d 61 6c 6c 6f 63 65   names.  malloce
f400: 64 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61 7a  d */.  char **az
f410: 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 3b 20 20  ContentColumn;  
f420: 20 20 20 20 20 20 20 20 2f 2a 20 63 6f 6c 75 6d          /* colum
f430: 6e 20 6e 61 6d 65 73 20 69 6e 20 63 6f 6e 74 65  n names in conte
f440: 6e 74 20 74 61 62 6c 65 3b 20 6d 61 6c 6c 6f 63  nt table; malloc
f450: 65 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  ed */.  sqlite3_
f460: 74 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 65  tokenizer *pToke
f470: 6e 69 7a 65 72 3b 20 20 20 2f 2a 20 74 6f 6b 65  nizer;   /* toke
f480: 6e 69 7a 65 72 20 66 6f 72 20 69 6e 73 65 72 74  nizer for insert
f490: 73 20 61 6e 64 20 71 75 65 72 69 65 73 20 2a 2f  s and queries */
f4a0: 0a 0a 20 20 2f 2a 20 50 72 65 63 6f 6d 70 69 6c  ..  /* Precompil
f4b0: 65 64 20 73 74 61 74 65 6d 65 6e 74 73 20 77 68  ed statements wh
f4c0: 69 63 68 20 77 65 20 6b 65 65 70 20 61 73 20 6c  ich we keep as l
f4d0: 6f 6e 67 20 61 73 20 74 68 65 20 74 61 62 6c 65  ong as the table
f4e0: 20 69 73 0a 20 20 2a 2a 20 6f 70 65 6e 2e 0a 20   is.  ** open.. 
f4f0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73 74   */.  sqlite3_st
f500: 6d 74 20 2a 70 46 75 6c 6c 74 65 78 74 53 74 61  mt *pFulltextSta
f510: 74 65 6d 65 6e 74 73 5b 4d 41 58 5f 53 54 4d 54  tements[MAX_STMT
f520: 5d 3b 0a 0a 20 20 2f 2a 20 50 72 65 63 6f 6d 70  ];..  /* Precomp
f530: 69 6c 65 64 20 73 74 61 74 65 6d 65 6e 74 73 20  iled statements 
f540: 75 73 65 64 20 66 6f 72 20 73 65 67 6d 65 6e 74  used for segment
f550: 20 6d 65 72 67 65 73 2e 20 20 57 65 20 72 75 6e   merges.  We run
f560: 20 61 0a 20 20 2a 2a 20 73 65 70 61 72 61 74 65   a.  ** separate
f570: 20 73 65 6c 65 63 74 20 61 63 72 6f 73 73 20 74   select across t
f580: 68 65 20 6c 65 61 66 20 6c 65 76 65 6c 20 6f 66  he leaf level of
f590: 20 65 61 63 68 20 74 72 65 65 20 62 65 69 6e 67   each tree being
f5a0: 20 6d 65 72 67 65 64 2e 0a 20 20 2a 2f 0a 20 20   merged..  */.  
f5b0: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 4c  sqlite3_stmt *pL
f5c0: 65 61 66 53 65 6c 65 63 74 53 74 6d 74 73 5b 4d  eafSelectStmts[M
f5d0: 45 52 47 45 5f 43 4f 55 4e 54 5d 3b 0a 20 20 2f  ERGE_COUNT];.  /
f5e0: 2a 20 54 68 65 20 73 74 61 74 65 6d 65 6e 74 20  * The statement 
f5f0: 75 73 65 64 20 74 6f 20 70 72 65 70 61 72 65 20  used to prepare 
f600: 70 4c 65 61 66 53 65 6c 65 63 74 53 74 6d 74 73  pLeafSelectStmts
f610: 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20 4c 45 41  . */.#define LEA
f620: 46 5f 53 45 4c 45 43 54 20 5c 0a 20 20 22 73 65  F_SELECT \.  "se
f630: 6c 65 63 74 20 62 6c 6f 63 6b 20 66 72 6f 6d 20  lect block from 
f640: 25 5f 73 65 67 6d 65 6e 74 73 20 77 68 65 72 65  %_segments where
f650: 20 62 6c 6f 63 6b 69 64 20 62 65 74 77 65 65 6e   blockid between
f660: 20 3f 20 61 6e 64 20 3f 20 6f 72 64 65 72 20 62   ? and ? order b
f670: 79 20 62 6c 6f 63 6b 69 64 22 0a 0a 20 20 2f 2a  y blockid"..  /*
f680: 20 54 68 65 73 65 20 62 75 66 66 65 72 20 70 65   These buffer pe
f690: 6e 64 69 6e 67 20 69 6e 64 65 78 20 75 70 64 61  nding index upda
f6a0: 74 65 73 20 64 75 72 69 6e 67 20 74 72 61 6e 73  tes during trans
f6b0: 61 63 74 69 6f 6e 73 2e 0a 20 20 2a 2a 20 6e 50  actions..  ** nP
f6c0: 65 6e 64 69 6e 67 44 61 74 61 20 65 73 74 69 6d  endingData estim
f6d0: 61 74 65 73 20 74 68 65 20 6d 65 6d 6f 72 79 20  ates the memory 
f6e0: 73 69 7a 65 20 6f 66 20 74 68 65 20 70 65 6e 64  size of the pend
f6f0: 69 6e 67 20 64 61 74 61 2e 20 20 49 74 0a 20 20  ing data.  It.  
f700: 2a 2a 20 64 6f 65 73 6e 27 74 20 69 6e 63 6c 75  ** doesn't inclu
f710: 64 65 20 74 68 65 20 68 61 73 68 2d 62 75 63 6b  de the hash-buck
f720: 65 74 20 6f 76 65 72 68 65 61 64 2c 20 6e 6f 72  et overhead, nor
f730: 20 61 6e 79 20 6d 61 6c 6c 6f 63 0a 20 20 2a 2a   any malloc.  **
f740: 20 6f 76 65 72 68 65 61 64 2e 20 20 57 68 65 6e   overhead.  When
f750: 20 6e 50 65 6e 64 69 6e 67 44 61 74 61 20 65 78   nPendingData ex
f760: 63 65 65 64 73 20 6b 50 65 6e 64 69 6e 67 54 68  ceeds kPendingTh
f770: 72 65 73 68 6f 6c 64 2c 20 74 68 65 0a 20 20 2a  reshold, the.  *
f780: 2a 20 62 75 66 66 65 72 20 69 73 20 66 6c 75 73  * buffer is flus
f790: 68 65 64 20 65 76 65 6e 20 62 65 66 6f 72 65 20  hed even before 
f7a0: 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  the transaction 
f7b0: 63 6c 6f 73 65 73 2e 0a 20 20 2a 2a 20 70 65 6e  closes..  ** pen
f7c0: 64 69 6e 67 54 65 72 6d 73 20 73 74 6f 72 65 73  dingTerms stores
f7d0: 20 74 68 65 20 64 61 74 61 2c 20 61 6e 64 20 69   the data, and i
f7e0: 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20 77 68 65  s only valid whe
f7f0: 6e 20 6e 50 65 6e 64 69 6e 67 44 61 74 61 0a 20  n nPendingData. 
f800: 20 2a 2a 20 69 73 20 3e 3d 30 20 28 6e 50 65 6e   ** is >=0 (nPen
f810: 64 69 6e 67 44 61 74 61 3c 30 20 6d 65 61 6e 73  dingData<0 means
f820: 20 70 65 6e 64 69 6e 67 54 65 72 6d 73 20 68 61   pendingTerms ha
f830: 73 20 6e 6f 74 20 62 65 65 6e 0a 20 20 2a 2a 20  s not been.  ** 
f840: 69 6e 69 74 69 61 6c 69 7a 65 64 29 2e 20 20 69  initialized).  i
f850: 50 72 65 76 44 6f 63 69 64 20 69 73 20 74 68 65  PrevDocid is the
f860: 20 6c 61 73 74 20 64 6f 63 69 64 20 77 72 69 74   last docid writ
f870: 74 65 6e 2c 20 75 73 65 64 20 74 6f 20 6d 61 6b  ten, used to mak
f880: 65 0a 20 20 2a 2a 20 63 65 72 74 61 69 6e 20 77  e.  ** certain w
f890: 65 27 72 65 20 69 6e 73 65 72 74 69 6e 67 20 69  e're inserting i
f8a0: 6e 20 73 6f 72 74 65 64 20 6f 72 64 65 72 2e 0a  n sorted order..
f8b0: 20 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 65 6e 64    */.  int nPend
f8c0: 69 6e 67 44 61 74 61 3b 0a 23 64 65 66 69 6e 65  ingData;.#define
f8d0: 20 6b 50 65 6e 64 69 6e 67 54 68 72 65 73 68 6f   kPendingThresho
f8e0: 6c 64 20 28 31 2a 31 30 32 34 2a 31 30 32 34 29  ld (1*1024*1024)
f8f0: 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  .  sqlite_int64 
f900: 69 50 72 65 76 44 6f 63 69 64 3b 0a 20 20 66 74  iPrevDocid;.  ft
f910: 73 33 48 61 73 68 20 70 65 6e 64 69 6e 67 54 65  s3Hash pendingTe
f920: 72 6d 73 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 57  rms;.};../*.** W
f930: 68 65 6e 20 74 68 65 20 63 6f 72 65 20 77 61 6e  hen the core wan
f940: 74 73 20 74 6f 20 64 6f 20 61 20 71 75 65 72 79  ts to do a query
f950: 2c 20 69 74 20 63 72 65 61 74 65 20 61 20 63 75  , it create a cu
f960: 72 73 6f 72 20 75 73 69 6e 67 20 61 0a 2a 2a 20  rsor using a.** 
f970: 63 61 6c 6c 20 74 6f 20 78 4f 70 65 6e 2e 20 20  call to xOpen.  
f980: 54 68 69 73 20 73 74 72 75 63 74 75 72 65 20 69  This structure i
f990: 73 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66  s an instance of
f9a0: 20 61 20 63 75 72 73 6f 72 2e 20 20 49 74 0a 2a   a cursor.  It.*
f9b0: 2a 20 69 73 20 64 65 73 74 72 6f 79 65 64 20 62  * is destroyed b
f9c0: 79 20 78 43 6c 6f 73 65 2e 0a 2a 2f 0a 74 79 70  y xClose..*/.typ
f9d0: 65 64 65 66 20 73 74 72 75 63 74 20 66 75 6c 6c  edef struct full
f9e0: 74 65 78 74 5f 63 75 72 73 6f 72 20 7b 0a 20 20  text_cursor {.  
f9f0: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
fa00: 73 6f 72 20 62 61 73 65 3b 20 20 20 20 20 20 20  sor base;       
fa10: 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20 75   /* Base class u
fa20: 73 65 64 20 62 79 20 53 51 4c 69 74 65 20 63 6f  sed by SQLite co
fa30: 72 65 20 2a 2f 0a 20 20 51 75 65 72 79 54 79 70  re */.  QueryTyp
fa40: 65 20 69 43 75 72 73 6f 72 54 79 70 65 3b 20 20  e iCursorType;  
fa50: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 70 79           /* Copy
fa60: 20 6f 66 20 73 71 6c 69 74 65 33 5f 69 6e 64 65   of sqlite3_inde
fa70: 78 5f 69 6e 66 6f 2e 69 64 78 4e 75 6d 20 2a 2f  x_info.idxNum */
fa80: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
fa90: 2a 70 53 74 6d 74 3b 20 20 20 20 20 20 20 20 20  *pStmt;         
faa0: 20 20 20 20 2f 2a 20 50 72 65 70 61 72 65 64 20      /* Prepared 
fab0: 73 74 61 74 65 6d 65 6e 74 20 69 6e 20 75 73 65  statement in use
fac0: 20 62 79 20 74 68 65 20 63 75 72 73 6f 72 20 2a   by the cursor *
fad0: 2f 0a 20 20 69 6e 74 20 65 6f 66 3b 20 20 20 20  /.  int eof;    
fae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
faf0: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
fb00: 61 74 20 45 6e 64 20 4f 66 20 52 65 73 75 6c 74  at End Of Result
fb10: 73 20 2a 2f 0a 20 20 46 74 73 33 45 78 70 72 20  s */.  Fts3Expr 
fb20: 2a 70 45 78 70 72 3b 20 20 20 20 20 20 20 20 20  *pExpr;         
fb30: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 72 73 65          /* Parse
fb40: 64 20 4d 41 54 43 48 20 71 75 65 72 79 20 73 74  d MATCH query st
fb50: 72 69 6e 67 20 2a 2f 0a 20 20 53 6e 69 70 70 65  ring */.  Snippe
fb60: 74 20 73 6e 69 70 70 65 74 3b 20 20 20 20 20 20  t snippet;      
fb70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61             /* Ca
fb80: 63 68 65 64 20 73 6e 69 70 70 65 74 20 66 6f 72  ched snippet for
fb90: 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 6f 77   the current row
fba0: 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 75 6d   */.  int iColum
fbb0: 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n;              
fbc0: 20 20 20 20 20 20 20 2f 2a 20 43 6f 6c 75 6d 6e         /* Column
fbd0: 20 62 65 69 6e 67 20 73 65 61 72 63 68 65 64 20   being searched 
fbe0: 2a 2f 0a 20 20 44 61 74 61 42 75 66 66 65 72 20  */.  DataBuffer 
fbf0: 72 65 73 75 6c 74 3b 20 20 20 20 20 20 20 20 20  result;         
fc00: 20 20 20 20 20 20 2f 2a 20 44 6f 63 6c 69 73 74        /* Doclist
fc10: 20 72 65 73 75 6c 74 73 20 66 72 6f 6d 20 66 75   results from fu
fc20: 6c 6c 74 65 78 74 51 75 65 72 79 20 2a 2f 0a 20  lltextQuery */. 
fc30: 20 44 4c 52 65 61 64 65 72 20 72 65 61 64 65 72   DLReader reader
fc40: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
fc50: 20 20 2f 2a 20 52 65 73 75 6c 74 20 72 65 61 64    /* Result read
fc60: 65 72 20 69 66 20 72 65 73 75 6c 74 20 6e 6f 74  er if result not
fc70: 20 65 6d 70 74 79 20 2a 2f 0a 7d 20 66 75 6c 6c   empty */.} full
fc80: 74 65 78 74 5f 63 75 72 73 6f 72 3b 0a 0a 73 74  text_cursor;..st
fc90: 61 74 69 63 20 66 75 6c 6c 74 65 78 74 5f 76 74  atic fulltext_vt
fca0: 61 62 20 2a 63 75 72 73 6f 72 5f 76 74 61 62 28  ab *cursor_vtab(
fcb0: 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20  fulltext_cursor 
fcc0: 2a 63 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 66  *c){.  return (f
fcd0: 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 20  ulltext_vtab *) 
fce0: 63 2d 3e 62 61 73 65 2e 70 56 74 61 62 3b 0a 7d  c->base.pVtab;.}
fcf0: 0a 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 73  ..static const s
fd00: 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 66 74  qlite3_module ft
fd10: 73 33 4d 6f 64 75 6c 65 3b 20 20 20 2f 2a 20 66  s3Module;   /* f
fd20: 6f 72 77 61 72 64 20 64 65 63 6c 61 72 61 74 69  orward declarati
fd30: 6f 6e 20 2a 2f 0a 0a 2f 2a 20 52 65 74 75 72 6e  on */../* Return
fd40: 20 61 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20 67   a dynamically g
fd50: 65 6e 65 72 61 74 65 64 20 73 74 61 74 65 6d 65  enerated stateme
fd60: 6e 74 20 6f 66 20 74 68 65 20 66 6f 72 6d 0a 20  nt of the form. 
fd70: 2a 20 20 20 69 6e 73 65 72 74 20 69 6e 74 6f 20  *   insert into 
fd80: 25 5f 63 6f 6e 74 65 6e 74 20 28 64 6f 63 69 64  %_content (docid
fd90: 2c 20 2e 2e 2e 29 20 76 61 6c 75 65 73 20 28 3f  , ...) values (?
fda0: 2c 20 2e 2e 2e 29 0a 20 2a 2f 0a 73 74 61 74 69  , ...). */.stati
fdb0: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f  c const char *co
fdc0: 6e 74 65 6e 74 49 6e 73 65 72 74 53 74 61 74 65  ntentInsertState
fdd0: 6d 65 6e 74 28 66 75 6c 6c 74 65 78 74 5f 76 74  ment(fulltext_vt
fde0: 61 62 20 2a 76 29 7b 0a 20 20 53 74 72 69 6e 67  ab *v){.  String
fdf0: 42 75 66 66 65 72 20 73 62 3b 0a 20 20 69 6e 74  Buffer sb;.  int
fe00: 20 69 3b 0a 0a 20 20 69 6e 69 74 53 74 72 69 6e   i;..  initStrin
fe10: 67 42 75 66 66 65 72 28 26 73 62 29 3b 0a 20 20  gBuffer(&sb);.  
fe20: 61 70 70 65 6e 64 28 26 73 62 2c 20 22 69 6e 73  append(&sb, "ins
fe30: 65 72 74 20 69 6e 74 6f 20 25 5f 63 6f 6e 74 65  ert into %_conte
fe40: 6e 74 20 28 64 6f 63 69 64 2c 20 22 29 3b 0a 20  nt (docid, ");. 
fe50: 20 61 70 70 65 6e 64 4c 69 73 74 28 26 73 62 2c   appendList(&sb,
fe60: 20 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 76 2d 3e   v->nColumn, v->
fe70: 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 29  azContentColumn)
fe80: 3b 0a 20 20 61 70 70 65 6e 64 28 26 73 62 2c 20  ;.  append(&sb, 
fe90: 22 29 20 76 61 6c 75 65 73 20 28 3f 22 29 3b 0a  ") values (?");.
fea0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 76 2d 3e    for(i=0; i<v->
feb0: 6e 43 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 0a 20 20  nColumn; ++i).  
fec0: 20 20 61 70 70 65 6e 64 28 26 73 62 2c 20 22 2c    append(&sb, ",
fed0: 20 3f 22 29 3b 0a 20 20 61 70 70 65 6e 64 28 26   ?");.  append(&
fee0: 73 62 2c 20 22 29 22 29 3b 0a 20 20 72 65 74 75  sb, ")");.  retu
fef0: 72 6e 20 73 74 72 69 6e 67 42 75 66 66 65 72 44  rn stringBufferD
ff00: 61 74 61 28 26 73 62 29 3b 0a 7d 0a 0a 2f 2a 20  ata(&sb);.}../* 
ff10: 52 65 74 75 72 6e 20 61 20 64 79 6e 61 6d 69 63  Return a dynamic
ff20: 61 6c 6c 79 20 67 65 6e 65 72 61 74 65 64 20 73  ally generated s
ff30: 74 61 74 65 6d 65 6e 74 20 6f 66 20 74 68 65 20  tatement of the 
ff40: 66 6f 72 6d 0a 20 2a 20 20 20 73 65 6c 65 63 74  form. *   select
ff50: 20 3c 63 6f 6e 74 65 6e 74 20 63 6f 6c 75 6d 6e   <content column
ff60: 73 3e 20 66 72 6f 6d 20 25 5f 63 6f 6e 74 65 6e  s> from %_conten
ff70: 74 20 77 68 65 72 65 20 64 6f 63 69 64 20 3d 20  t where docid = 
ff80: 3f 0a 20 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e  ?. */.static con
ff90: 73 74 20 63 68 61 72 20 2a 63 6f 6e 74 65 6e 74  st char *content
ffa0: 53 65 6c 65 63 74 53 74 61 74 65 6d 65 6e 74 28  SelectStatement(
ffb0: 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
ffc0: 29 7b 0a 20 20 53 74 72 69 6e 67 42 75 66 66 65  ){.  StringBuffe
ffd0: 72 20 73 62 3b 0a 20 20 69 6e 69 74 53 74 72 69  r sb;.  initStri
ffe0: 6e 67 42 75 66 66 65 72 28 26 73 62 29 3b 0a 20  ngBuffer(&sb);. 
fff0: 20 61 70 70 65 6e 64 28 26 73 62 2c 20 22 53 45   append(&sb, "SE
10000 4c 45 43 54 20 22 29 3b 0a 20 20 61 70 70 65 6e  LECT ");.  appen
10010 64 4c 69 73 74 28 26 73 62 2c 20 76 2d 3e 6e 43  dList(&sb, v->nC
10020 6f 6c 75 6d 6e 2c 20 76 2d 3e 61 7a 43 6f 6e 74  olumn, v->azCont
10030 65 6e 74 43 6f 6c 75 6d 6e 29 3b 0a 20 20 61 70  entColumn);.  ap
10040 70 65 6e 64 28 26 73 62 2c 20 22 20 46 52 4f 4d  pend(&sb, " FROM
10050 20 25 5f 63 6f 6e 74 65 6e 74 20 57 48 45 52 45   %_content WHERE
10060 20 64 6f 63 69 64 20 3d 20 3f 22 29 3b 0a 20 20   docid = ?");.  
10070 72 65 74 75 72 6e 20 73 74 72 69 6e 67 42 75 66  return stringBuf
10080 66 65 72 44 61 74 61 28 26 73 62 29 3b 0a 7d 0a  ferData(&sb);.}.
10090 0a 2f 2a 20 52 65 74 75 72 6e 20 61 20 64 79 6e  ./* Return a dyn
100a0 61 6d 69 63 61 6c 6c 79 20 67 65 6e 65 72 61 74  amically generat
100b0 65 64 20 73 74 61 74 65 6d 65 6e 74 20 6f 66 20  ed statement of 
100c0 74 68 65 20 66 6f 72 6d 0a 20 2a 20 20 20 75 70  the form. *   up
100d0 64 61 74 65 20 25 5f 63 6f 6e 74 65 6e 74 20 73  date %_content s
100e0 65 74 20 5b 63 6f 6c 5f 30 5d 20 3d 20 3f 2c 20  et [col_0] = ?, 
100f0 5b 63 6f 6c 5f 31 5d 20 3d 20 3f 2c 20 2e 2e 2e  [col_1] = ?, ...
10100 0a 20 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  . *             
10110 20 20 20 20 20 20 20 77 68 65 72 65 20 64 6f 63         where doc
10120 69 64 20 3d 20 3f 0a 20 2a 2f 0a 73 74 61 74 69  id = ?. */.stati
10130 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f  c const char *co
10140 6e 74 65 6e 74 55 70 64 61 74 65 53 74 61 74 65  ntentUpdateState
10150 6d 65 6e 74 28 66 75 6c 6c 74 65 78 74 5f 76 74  ment(fulltext_vt
10160 61 62 20 2a 76 29 7b 0a 20 20 53 74 72 69 6e 67  ab *v){.  String
10170 42 75 66 66 65 72 20 73 62 3b 0a 20 20 69 6e 74  Buffer sb;.  int
10180 20 69 3b 0a 0a 20 20 69 6e 69 74 53 74 72 69 6e   i;..  initStrin
10190 67 42 75 66 66 65 72 28 26 73 62 29 3b 0a 20 20  gBuffer(&sb);.  
101a0 61 70 70 65 6e 64 28 26 73 62 2c 20 22 75 70 64  append(&sb, "upd
101b0 61 74 65 20 25 5f 63 6f 6e 74 65 6e 74 20 73 65  ate %_content se
101c0 74 20 22 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  t ");.  for(i=0;
101d0 20 69 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b   i<v->nColumn; +
101e0 2b 69 29 20 7b 0a 20 20 20 20 69 66 28 20 69 3e  +i) {.    if( i>
101f0 30 20 29 7b 0a 20 20 20 20 20 20 61 70 70 65 6e  0 ){.      appen
10200 64 28 26 73 62 2c 20 22 2c 20 22 29 3b 0a 20 20  d(&sb, ", ");.  
10210 20 20 7d 0a 20 20 20 20 61 70 70 65 6e 64 28 26    }.    append(&
10220 73 62 2c 20 76 2d 3e 61 7a 43 6f 6e 74 65 6e 74  sb, v->azContent
10230 43 6f 6c 75 6d 6e 5b 69 5d 29 3b 0a 20 20 20 20  Column[i]);.    
10240 61 70 70 65 6e 64 28 26 73 62 2c 20 22 20 3d 20  append(&sb, " = 
10250 3f 22 29 3b 0a 20 20 7d 0a 20 20 61 70 70 65 6e  ?");.  }.  appen
10260 64 28 26 73 62 2c 20 22 20 77 68 65 72 65 20 64  d(&sb, " where d
10270 6f 63 69 64 20 3d 20 3f 22 29 3b 0a 20 20 72 65  ocid = ?");.  re
10280 74 75 72 6e 20 73 74 72 69 6e 67 42 75 66 66 65  turn stringBuffe
10290 72 44 61 74 61 28 26 73 62 29 3b 0a 7d 0a 0a 2f  rData(&sb);.}../
102a0 2a 20 50 75 74 73 20 61 20 66 72 65 73 68 6c 79  * Puts a freshly
102b0 2d 70 72 65 70 61 72 65 64 20 73 74 61 74 65 6d  -prepared statem
102c0 65 6e 74 20 64 65 74 65 72 6d 69 6e 65 64 20 62  ent determined b
102d0 79 20 69 53 74 6d 74 20 69 6e 20 2a 70 70 53 74  y iStmt in *ppSt
102e0 6d 74 2e 0a 2a 2a 20 49 66 20 74 68 65 20 69 6e  mt..** If the in
102f0 64 69 63 61 74 65 64 20 73 74 61 74 65 6d 65 6e  dicated statemen
10300 74 20 68 61 73 20 6e 65 76 65 72 20 62 65 65 6e  t has never been
10310 20 70 72 65 70 61 72 65 64 2c 20 69 74 20 69 73   prepared, it is
10320 20 70 72 65 70 61 72 65 64 0a 2a 2a 20 61 6e 64   prepared.** and
10330 20 63 61 63 68 65 64 2c 20 6f 74 68 65 72 77 69   cached, otherwi
10340 73 65 20 74 68 65 20 63 61 63 68 65 64 20 76 65  se the cached ve
10350 72 73 69 6f 6e 20 69 73 20 72 65 73 65 74 2e 0a  rsion is reset..
10360 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 71  */.static int sq
10370 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28  l_get_statement(
10380 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
10390 2c 20 66 75 6c 6c 74 65 78 74 5f 73 74 61 74 65  , fulltext_state
103a0 6d 65 6e 74 20 69 53 74 6d 74 2c 0a 20 20 20 20  ment iStmt,.    
103b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
103c0 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33           sqlite3
103d0 5f 73 74 6d 74 20 2a 2a 70 70 53 74 6d 74 29 7b  _stmt **ppStmt){
103e0 0a 20 20 61 73 73 65 72 74 28 20 69 53 74 6d 74  .  assert( iStmt
103f0 3c 4d 41 58 5f 53 54 4d 54 20 29 3b 0a 20 20 69  <MAX_STMT );.  i
10400 66 28 20 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53  f( v->pFulltextS
10410 74 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d  tatements[iStmt]
10420 3d 3d 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 63 6f  ==NULL ){.    co
10430 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 6d 74 3b  nst char *zStmt;
10440 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a 20 20 20  .    int rc;.   
10450 20 73 77 69 74 63 68 28 20 69 53 74 6d 74 20 29   switch( iStmt )
10460 7b 0a 20 20 20 20 20 20 63 61 73 65 20 43 4f 4e  {.      case CON
10470 54 45 4e 54 5f 49 4e 53 45 52 54 5f 53 54 4d 54  TENT_INSERT_STMT
10480 3a 0a 20 20 20 20 20 20 20 20 7a 53 74 6d 74 20  :.        zStmt 
10490 3d 20 63 6f 6e 74 65 6e 74 49 6e 73 65 72 74 53  = contentInsertS
104a0 74 61 74 65 6d 65 6e 74 28 76 29 3b 20 62 72 65  tatement(v); bre
104b0 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 43  ak;.      case C
104c0 4f 4e 54 45 4e 54 5f 53 45 4c 45 43 54 5f 53 54  ONTENT_SELECT_ST
104d0 4d 54 3a 0a 20 20 20 20 20 20 20 20 7a 53 74 6d  MT:.        zStm
104e0 74 20 3d 20 63 6f 6e 74 65 6e 74 53 65 6c 65 63  t = contentSelec
104f0 74 53 74 61 74 65 6d 65 6e 74 28 76 29 3b 20 62  tStatement(v); b
10500 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65  reak;.      case
10510 20 43 4f 4e 54 45 4e 54 5f 55 50 44 41 54 45 5f   CONTENT_UPDATE_
10520 53 54 4d 54 3a 0a 20 20 20 20 20 20 20 20 7a 53  STMT:.        zS
10530 74 6d 74 20 3d 20 63 6f 6e 74 65 6e 74 55 70 64  tmt = contentUpd
10540 61 74 65 53 74 61 74 65 6d 65 6e 74 28 76 29 3b  ateStatement(v);
10550 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 64 65   break;.      de
10560 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20 7a  fault:.        z
10570 53 74 6d 74 20 3d 20 66 75 6c 6c 74 65 78 74 5f  Stmt = fulltext_
10580 7a 53 74 61 74 65 6d 65 6e 74 5b 69 53 74 6d 74  zStatement[iStmt
10590 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63 20  ];.    }.    rc 
105a0 3d 20 73 71 6c 5f 70 72 65 70 61 72 65 28 76 2d  = sql_prepare(v-
105b0 3e 64 62 2c 20 76 2d 3e 7a 44 62 2c 20 76 2d 3e  >db, v->zDb, v->
105c0 7a 4e 61 6d 65 2c 20 26 76 2d 3e 70 46 75 6c 6c  zName, &v->pFull
105d0 74 65 78 74 53 74 61 74 65 6d 65 6e 74 73 5b 69  textStatements[i
105e0 53 74 6d 74 5d 2c 0a 20 20 20 20 20 20 20 20 20  Stmt],.         
105f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10600 7a 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20  zStmt);.    if( 
10610 7a 53 74 6d 74 20 21 3d 20 66 75 6c 6c 74 65 78  zStmt != fulltex
10620 74 5f 7a 53 74 61 74 65 6d 65 6e 74 5b 69 53 74  t_zStatement[iSt
10630 6d 74 5d 29 20 73 71 6c 69 74 65 33 5f 66 72 65  mt]) sqlite3_fre
10640 65 28 28 76 6f 69 64 20 2a 29 20 7a 53 74 6d 74  e((void *) zStmt
10650 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
10660 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
10670 6e 20 72 63 3b 0a 20 20 7d 20 65 6c 73 65 20 7b  n rc;.  } else {
10680 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20 73 71  .    int rc = sq
10690 6c 69 74 65 33 5f 72 65 73 65 74 28 76 2d 3e 70  lite3_reset(v->p
106a0 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d 65 6e  FulltextStatemen
106b0 74 73 5b 69 53 74 6d 74 5d 29 3b 0a 20 20 20 20  ts[iStmt]);.    
106c0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
106d0 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
106e0 20 7d 0a 0a 20 20 2a 70 70 53 74 6d 74 20 3d 20   }..  *ppStmt = 
106f0 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74 61 74  v->pFulltextStat
10700 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 3b 0a 20  ements[iStmt];. 
10710 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
10720 4b 3b 0a 7d 0a 0a 2f 2a 20 4c 69 6b 65 20 73 71  K;.}../* Like sq
10730 6c 69 74 65 33 5f 73 74 65 70 28 29 2c 20 62 75  lite3_step(), bu
10740 74 20 63 6f 6e 76 65 72 74 20 53 51 4c 49 54 45  t convert SQLITE
10750 5f 44 4f 4e 45 20 74 6f 20 53 51 4c 49 54 45 5f  _DONE to SQLITE_
10760 4f 4b 20 61 6e 64 0a 2a 2a 20 53 51 4c 49 54 45  OK and.** SQLITE
10770 5f 52 4f 57 20 74 6f 20 53 51 4c 49 54 45 5f 45  _ROW to SQLITE_E
10780 52 52 4f 52 2e 20 20 55 73 65 66 75 6c 20 66 6f  RROR.  Useful fo
10790 72 20 73 74 61 74 65 6d 65 6e 74 73 20 6c 69 6b  r statements lik
107a0 65 20 55 50 44 41 54 45 2c 0a 2a 2a 20 77 68 65  e UPDATE,.** whe
107b0 72 65 20 77 65 20 65 78 70 65 63 74 20 6e 6f 20  re we expect no 
107c0 72 65 73 75 6c 74 73 2e 0a 2a 2f 0a 73 74 61 74  results..*/.stat
107d0 69 63 20 69 6e 74 20 73 71 6c 5f 73 69 6e 67 6c  ic int sql_singl
107e0 65 5f 73 74 65 70 28 73 71 6c 69 74 65 33 5f 73  e_step(sqlite3_s
107f0 74 6d 74 20 2a 73 29 7b 0a 20 20 69 6e 74 20 72  tmt *s){.  int r
10800 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70  c = sqlite3_step
10810 28 73 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 72  (s);.  return (r
10820 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 29 20  c==SQLITE_DONE) 
10830 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20 72 63  ? SQLITE_OK : rc
10840 3b 0a 7d 0a 0a 2f 2a 20 4c 69 6b 65 20 73 71 6c  ;.}../* Like sql
10850 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 29  _get_statement()
10860 2c 20 62 75 74 20 66 6f 72 20 73 70 65 63 69 61  , but for specia
10870 6c 20 72 65 70 6c 69 63 61 74 65 64 20 4c 45 41  l replicated LEA
10880 46 5f 53 45 4c 45 43 54 0a 2a 2a 20 73 74 61 74  F_SELECT.** stat
10890 65 6d 65 6e 74 73 2e 20 20 69 64 78 20 2d 31 20  ements.  idx -1 
108a0 69 73 20 61 20 73 70 65 63 69 61 6c 20 63 61 73  is a special cas
108b0 65 20 66 6f 72 20 61 6e 20 75 6e 63 61 63 68 65  e for an uncache
108c0 64 20 76 65 72 73 69 6f 6e 20 6f 66 0a 2a 2a 20  d version of.** 
108d0 74 68 65 20 73 74 61 74 65 6d 65 6e 74 20 28 75  the statement (u
108e0 73 65 64 20 69 6e 20 74 68 65 20 6f 70 74 69 6d  sed in the optim
108f0 69 7a 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  ize implementati
10900 6f 6e 29 2e 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f 28  on)..*/./* TODO(
10910 73 68 65 73 73 29 20 57 72 69 74 65 20 76 65 72  shess) Write ver
10920 73 69 6f 6e 20 66 6f 72 20 67 65 6e 65 72 69 63  sion for generic
10930 20 73 74 61 74 65 6d 65 6e 74 73 20 61 6e 64 20   statements and 
10940 74 68 65 6e 20 73 68 61 72 65 0a 2a 2a 20 74 68  then share.** th
10950 61 74 20 62 65 74 77 65 65 6e 20 74 68 65 20 63  at between the c
10960 61 63 68 65 64 2d 73 74 61 74 65 6d 65 6e 74 20  ached-statement 
10970 66 75 6e 63 74 69 6f 6e 73 2e 0a 2a 2f 0a 73 74  functions..*/.st
10980 61 74 69 63 20 69 6e 74 20 73 71 6c 5f 67 65 74  atic int sql_get
10990 5f 6c 65 61 66 5f 73 74 61 74 65 6d 65 6e 74 28  _leaf_statement(
109a0 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
109b0 2c 20 69 6e 74 20 69 64 78 2c 0a 20 20 20 20 20  , int idx,.     
109c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
109d0 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c               sql
109e0 69 74 65 33 5f 73 74 6d 74 20 2a 2a 70 70 53 74  ite3_stmt **ppSt
109f0 6d 74 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69  mt){.  assert( i
10a00 64 78 3e 3d 2d 31 20 26 26 20 69 64 78 3c 4d 45  dx>=-1 && idx<ME
10a10 52 47 45 5f 43 4f 55 4e 54 20 29 3b 0a 20 20 69  RGE_COUNT );.  i
10a20 66 28 20 69 64 78 3d 3d 2d 31 20 29 7b 0a 20 20  f( idx==-1 ){.  
10a30 20 20 72 65 74 75 72 6e 20 73 71 6c 5f 70 72 65    return sql_pre
10a40 70 61 72 65 28 76 2d 3e 64 62 2c 20 76 2d 3e 7a  pare(v->db, v->z
10a50 44 62 2c 20 76 2d 3e 7a 4e 61 6d 65 2c 20 70 70  Db, v->zName, pp
10a60 53 74 6d 74 2c 20 4c 45 41 46 5f 53 45 4c 45 43  Stmt, LEAF_SELEC
10a70 54 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20  T);.  }else if( 
10a80 76 2d 3e 70 4c 65 61 66 53 65 6c 65 63 74 53 74  v->pLeafSelectSt
10a90 6d 74 73 5b 69 64 78 5d 3d 3d 4e 55 4c 4c 20 29  mts[idx]==NULL )
10aa0 7b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20 73  {.    int rc = s
10ab0 71 6c 5f 70 72 65 70 61 72 65 28 76 2d 3e 64 62  ql_prepare(v->db
10ac0 2c 20 76 2d 3e 7a 44 62 2c 20 76 2d 3e 7a 4e 61  , v->zDb, v->zNa
10ad0 6d 65 2c 20 26 76 2d 3e 70 4c 65 61 66 53 65 6c  me, &v->pLeafSel
10ae0 65 63 74 53 74 6d 74 73 5b 69 64 78 5d 2c 0a 20  ectStmts[idx],. 
10af0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10b00 20 20 20 20 20 20 20 20 4c 45 41 46 5f 53 45 4c          LEAF_SEL
10b10 45 43 54 29 3b 0a 20 20 20 20 69 66 28 20 72 63  ECT);.    if( rc
10b20 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
10b30 74 75 72 6e 20 72 63 3b 0a 20 20 7d 65 6c 73 65  turn rc;.  }else
10b40 7b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20 73  {.    int rc = s
10b50 71 6c 69 74 65 33 5f 72 65 73 65 74 28 76 2d 3e  qlite3_reset(v->
10b60 70 4c 65 61 66 53 65 6c 65 63 74 53 74 6d 74 73  pLeafSelectStmts
10b70 5b 69 64 78 5d 29 3b 0a 20 20 20 20 69 66 28 20  [idx]);.    if( 
10b80 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
10b90 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a  return rc;.  }..
10ba0 20 20 2a 70 70 53 74 6d 74 20 3d 20 76 2d 3e 70    *ppStmt = v->p
10bb0 4c 65 61 66 53 65 6c 65 63 74 53 74 6d 74 73 5b  LeafSelectStmts[
10bc0 69 64 78 5d 3b 0a 20 20 72 65 74 75 72 6e 20 53  idx];.  return S
10bd0 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20  QLITE_OK;.}../* 
10be0 69 6e 73 65 72 74 20 69 6e 74 6f 20 25 5f 63 6f  insert into %_co
10bf0 6e 74 65 6e 74 20 28 64 6f 63 69 64 2c 20 2e 2e  ntent (docid, ..
10c00 2e 29 20 76 61 6c 75 65 73 20 28 5b 64 6f 63 69  .) values ([doci
10c10 64 5d 2c 20 5b 70 56 61 6c 75 65 73 5d 29 0a 2a  d], [pValues]).*
10c20 2a 20 49 66 20 74 68 65 20 64 6f 63 69 64 20 63  * If the docid c
10c30 6f 6e 74 61 69 6e 73 20 53 51 4c 20 4e 55 4c 4c  ontains SQL NULL
10c40 2c 20 74 68 65 6e 20 61 20 75 6e 69 71 75 65 20  , then a unique 
10c50 64 6f 63 69 64 20 77 69 6c 6c 20 62 65 0a 2a 2a  docid will be.**
10c60 20 67 65 6e 65 72 61 74 65 64 2e 0a 2a 2f 0a 73   generated..*/.s
10c70 74 61 74 69 63 20 69 6e 74 20 63 6f 6e 74 65 6e  tatic int conten
10c80 74 5f 69 6e 73 65 72 74 28 66 75 6c 6c 74 65 78  t_insert(fulltex
10c90 74 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74  t_vtab *v, sqlit
10ca0 65 33 5f 76 61 6c 75 65 20 2a 64 6f 63 69 64 2c  e3_value *docid,
10cb0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
10cc0 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
10cd0 65 33 5f 76 61 6c 75 65 20 2a 2a 70 56 61 6c 75  e3_value **pValu
10ce0 65 73 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73  es){.  sqlite3_s
10cf0 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74 20 69 3b  tmt *s;.  int i;
10d00 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f  .  int rc = sql_
10d10 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c  get_statement(v,
10d20 20 43 4f 4e 54 45 4e 54 5f 49 4e 53 45 52 54 5f   CONTENT_INSERT_
10d30 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28  STMT, &s);.  if(
10d40 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
10d50 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72   return rc;..  r
10d60 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
10d70 5f 76 61 6c 75 65 28 73 2c 20 31 2c 20 64 6f 63  _value(s, 1, doc
10d80 69 64 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  id);.  if( rc!=S
10d90 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
10da0 6e 20 72 63 3b 0a 0a 20 20 66 6f 72 28 69 3d 30  n rc;..  for(i=0
10db0 3b 20 69 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20  ; i<v->nColumn; 
10dc0 2b 2b 69 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  ++i){.    rc = s
10dd0 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75  qlite3_bind_valu
10de0 65 28 73 2c 20 32 2b 69 2c 20 70 56 61 6c 75 65  e(s, 2+i, pValue
10df0 73 5b 69 5d 29 3b 0a 20 20 20 20 69 66 28 20 72  s[i]);.    if( r
10e00 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
10e10 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20  eturn rc;.  }.. 
10e20 20 72 65 74 75 72 6e 20 73 71 6c 5f 73 69 6e 67   return sql_sing
10e30 6c 65 5f 73 74 65 70 28 73 29 3b 0a 7d 0a 0a 2f  le_step(s);.}../
10e40 2a 20 75 70 64 61 74 65 20 25 5f 63 6f 6e 74 65  * update %_conte
10e50 6e 74 20 73 65 74 20 63 6f 6c 30 20 3d 20 70 56  nt set col0 = pV
10e60 61 6c 75 65 73 5b 30 5d 2c 20 63 6f 6c 31 20 3d  alues[0], col1 =
10e70 20 70 56 61 6c 75 65 73 5b 31 5d 2c 20 2e 2e 2e   pValues[1], ...
10e80 0a 20 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  . *             
10e90 20 20 20 20 20 77 68 65 72 65 20 64 6f 63 69 64       where docid
10ea0 20 3d 20 5b 69 44 6f 63 69 64 5d 20 2a 2f 0a 73   = [iDocid] */.s
10eb0 74 61 74 69 63 20 69 6e 74 20 63 6f 6e 74 65 6e  tatic int conten
10ec0 74 5f 75 70 64 61 74 65 28 66 75 6c 6c 74 65 78  t_update(fulltex
10ed0 74 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74  t_vtab *v, sqlit
10ee0 65 33 5f 76 61 6c 75 65 20 2a 2a 70 56 61 6c 75  e3_value **pValu
10ef0 65 73 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  es,.            
10f00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
10f10 6c 69 74 65 5f 69 6e 74 36 34 20 69 44 6f 63 69  lite_int64 iDoci
10f20 64 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  d){.  sqlite3_st
10f30 6d 74 20 2a 73 3b 0a 20 20 69 6e 74 20 69 3b 0a  mt *s;.  int i;.
10f40 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67    int rc = sql_g
10f50 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20  et_statement(v, 
10f60 43 4f 4e 54 45 4e 54 5f 55 50 44 41 54 45 5f 53  CONTENT_UPDATE_S
10f70 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20  TMT, &s);.  if( 
10f80 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
10f90 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 66 6f  return rc;..  fo
10fa0 72 28 69 3d 30 3b 20 69 3c 76 2d 3e 6e 43 6f 6c  r(i=0; i<v->nCol
10fb0 75 6d 6e 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 72  umn; ++i){.    r
10fc0 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
10fd0 5f 76 61 6c 75 65 28 73 2c 20 31 2b 69 2c 20 70  _value(s, 1+i, p
10fe0 56 61 6c 75 65 73 5b 69 5d 29 3b 0a 20 20 20 20  Values[i]);.    
10ff0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
11000 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
11010 20 7d 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74   }..  rc = sqlit
11020 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 73 2c  e3_bind_int64(s,
11030 20 31 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 69   1+v->nColumn, i
11040 44 6f 63 69 64 29 3b 0a 20 20 69 66 28 20 72 63  Docid);.  if( rc
11050 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
11060 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 65 74 75  turn rc;..  retu
11070 72 6e 20 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74  rn sql_single_st
11080 65 70 28 73 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  ep(s);.}..static
11090 20 76 6f 69 64 20 66 72 65 65 53 74 72 69 6e 67   void freeString
110a0 41 72 72 61 79 28 69 6e 74 20 6e 53 74 72 69 6e  Array(int nStrin
110b0 67 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a  g, const char **
110c0 70 53 74 72 69 6e 67 29 7b 0a 20 20 69 6e 74 20  pString){.  int 
110d0 69 3b 0a 0a 20 20 66 6f 72 20 28 69 3d 30 20 3b  i;..  for (i=0 ;
110e0 20 69 20 3c 20 6e 53 74 72 69 6e 67 20 3b 20 2b   i < nString ; +
110f0 2b 69 29 20 7b 0a 20 20 20 20 69 66 28 20 70 53  +i) {.    if( pS
11100 74 72 69 6e 67 5b 69 5d 21 3d 4e 55 4c 4c 20 29  tring[i]!=NULL )
11110 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 28 76   sqlite3_free((v
11120 6f 69 64 20 2a 29 20 70 53 74 72 69 6e 67 5b 69  oid *) pString[i
11130 5d 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65  ]);.  }.  sqlite
11140 33 5f 66 72 65 65 28 28 76 6f 69 64 20 2a 29 20  3_free((void *) 
11150 70 53 74 72 69 6e 67 29 3b 0a 7d 0a 0a 2f 2a 20  pString);.}../* 
11160 73 65 6c 65 63 74 20 2a 20 66 72 6f 6d 20 25 5f  select * from %_
11170 63 6f 6e 74 65 6e 74 20 77 68 65 72 65 20 64 6f  content where do
11180 63 69 64 20 3d 20 5b 69 44 6f 63 69 64 5d 0a 20  cid = [iDocid]. 
11190 2a 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  * The caller mus
111a0 74 20 64 65 6c 65 74 65 20 74 68 65 20 72 65 74  t delete the ret
111b0 75 72 6e 65 64 20 61 72 72 61 79 20 61 6e 64 20  urned array and 
111c0 61 6c 6c 20 73 74 72 69 6e 67 73 20 69 6e 20 69  all strings in i
111d0 74 2e 0a 20 2a 20 6e 75 6c 6c 20 66 69 65 6c 64  t.. * null field
111e0 73 20 77 69 6c 6c 20 62 65 20 4e 55 4c 4c 20 69  s will be NULL i
111f0 6e 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 61  n the returned a
11200 72 72 61 79 2e 0a 20 2a 0a 20 2a 20 54 4f 44 4f  rray.. *. * TODO
11210 3a 20 50 65 72 68 61 70 73 20 77 65 20 73 68 6f  : Perhaps we sho
11220 75 6c 64 20 72 65 74 75 72 6e 20 70 6f 69 6e 74  uld return point
11230 65 72 2f 6c 65 6e 67 74 68 20 73 74 72 69 6e 67  er/length string
11240 73 20 68 65 72 65 20 66 6f 72 20 63 6f 6e 73 69  s here for consi
11250 73 74 65 6e 63 79 0a 20 2a 20 77 69 74 68 20 6f  stency. * with o
11260 74 68 65 72 20 63 6f 64 65 20 77 68 69 63 68 20  ther code which 
11270 75 73 65 73 20 70 6f 69 6e 74 65 72 2f 6c 65 6e  uses pointer/len
11280 67 74 68 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69  gth. */.static i
11290 6e 74 20 63 6f 6e 74 65 6e 74 5f 73 65 6c 65 63  nt content_selec
112a0 74 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20  t(fulltext_vtab 
112b0 2a 76 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  *v, sqlite_int64
112c0 20 69 44 6f 63 69 64 2c 0a 20 20 20 20 20 20 20   iDocid,.       
112d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
112e0 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a     const char **
112f0 2a 70 56 61 6c 75 65 73 29 7b 0a 20 20 73 71 6c  *pValues){.  sql
11300 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20  ite3_stmt *s;.  
11310 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 76 61 6c  const char **val
11320 75 65 73 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  ues;.  int i;.  
11330 69 6e 74 20 72 63 3b 0a 0a 20 20 2a 70 56 61 6c  int rc;..  *pVal
11340 75 65 73 20 3d 20 4e 55 4c 4c 3b 0a 0a 20 20 72  ues = NULL;..  r
11350 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74 61 74  c = sql_get_stat
11360 65 6d 65 6e 74 28 76 2c 20 43 4f 4e 54 45 4e 54  ement(v, CONTENT
11370 5f 53 45 4c 45 43 54 5f 53 54 4d 54 2c 20 26 73  _SELECT_STMT, &s
11380 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
11390 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
113a0 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69  rc;..  rc = sqli
113b0 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 73  te3_bind_int64(s
113c0 2c 20 31 2c 20 69 44 6f 63 69 64 29 3b 0a 20 20  , 1, iDocid);.  
113d0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
113e0 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
113f0 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73    rc = sqlite3_s
11400 74 65 70 28 73 29 3b 0a 20 20 69 66 28 20 72 63  tep(s);.  if( rc
11410 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 20 72  !=SQLITE_ROW ) r
11420 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 76 61 6c  eturn rc;..  val
11430 75 65 73 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  ues = (const cha
11440 72 20 2a 2a 29 20 73 71 6c 69 74 65 33 5f 6d 61  r **) sqlite3_ma
11450 6c 6c 6f 63 28 76 2d 3e 6e 43 6f 6c 75 6d 6e 20  lloc(v->nColumn 
11460 2a 20 73 69 7a 65 6f 66 28 63 6f 6e 73 74 20 63  * sizeof(const c
11470 68 61 72 20 2a 29 29 3b 0a 20 20 66 6f 72 28 69  har *));.  for(i
11480 3d 30 3b 20 69 3c 76 2d 3e 6e 43 6f 6c 75 6d 6e  =0; i<v->nColumn
11490 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 69 66 28 20  ; ++i){.    if( 
114a0 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
114b0 79 70 65 28 73 2c 20 69 29 3d 3d 53 51 4c 49 54  ype(s, i)==SQLIT
114c0 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 20 20  E_NULL ){.      
114d0 76 61 6c 75 65 73 5b 69 5d 20 3d 20 4e 55 4c 4c  values[i] = NULL
114e0 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
114f0 20 20 20 76 61 6c 75 65 73 5b 69 5d 20 3d 20 73     values[i] = s
11500 74 72 69 6e 67 5f 64 75 70 28 28 63 68 61 72 2a  tring_dup((char*
11510 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f  )sqlite3_column_
11520 74 65 78 74 28 73 2c 20 69 29 29 3b 0a 20 20 20  text(s, i));.   
11530 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 57 65 20   }.  }..  /* We 
11540 65 78 70 65 63 74 20 6f 6e 6c 79 20 6f 6e 65 20  expect only one 
11550 72 6f 77 2e 20 20 57 65 20 6d 75 73 74 20 65 78  row.  We must ex
11560 65 63 75 74 65 20 61 6e 6f 74 68 65 72 20 73 71  ecute another sq
11570 6c 69 74 65 33 5f 73 74 65 70 28 29 0a 20 20 20  lite3_step().   
11580 2a 20 74 6f 20 63 6f 6d 70 6c 65 74 65 20 74 68  * to complete th
11590 65 20 69 74 65 72 61 74 69 6f 6e 3b 20 6f 74 68  e iteration; oth
115a0 65 72 77 69 73 65 20 74 68 65 20 74 61 62 6c 65  erwise the table
115b0 20 77 69 6c 6c 20 72 65 6d 61 69 6e 20 6c 6f 63   will remain loc
115c0 6b 65 64 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 73  ked. */.  rc = s
115d0 71 6c 69 74 65 33 5f 73 74 65 70 28 73 29 3b 0a  qlite3_step(s);.
115e0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
115f0 5f 44 4f 4e 45 20 29 7b 0a 20 20 20 20 2a 70 56  _DONE ){.    *pV
11600 61 6c 75 65 73 20 3d 20 76 61 6c 75 65 73 3b 0a  alues = values;.
11610 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
11620 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 66 72 65  E_OK;.  }..  fre
11630 65 53 74 72 69 6e 67 41 72 72 61 79 28 76 2d 3e  eStringArray(v->
11640 6e 43 6f 6c 75 6d 6e 2c 20 76 61 6c 75 65 73 29  nColumn, values)
11650 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
11660 0a 0a 2f 2a 20 64 65 6c 65 74 65 20 66 72 6f 6d  ../* delete from
11670 20 25 5f 63 6f 6e 74 65 6e 74 20 77 68 65 72 65   %_content where
11680 20 64 6f 63 69 64 20 3d 20 5b 69 44 6f 63 69 64   docid = [iDocid
11690 20 5d 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74   ] */.static int
116a0 20 63 6f 6e 74 65 6e 74 5f 64 65 6c 65 74 65 28   content_delete(
116b0 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
116c0 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69  , sqlite_int64 i
116d0 44 6f 63 69 64 29 7b 0a 20 20 73 71 6c 69 74 65  Docid){.  sqlite
116e0 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74  3_stmt *s;.  int
116f0 20 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74   rc = sql_get_st
11700 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f 4e 54 45  atement(v, CONTE
11710 4e 54 5f 44 45 4c 45 54 45 5f 53 54 4d 54 2c 20  NT_DELETE_STMT, 
11720 26 73 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  &s);.  if( rc!=S
11730 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
11740 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71  n rc;..  rc = sq
11750 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34  lite3_bind_int64
11760 28 73 2c 20 31 2c 20 69 44 6f 63 69 64 29 3b 0a  (s, 1, iDocid);.
11770 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
11780 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
11790 0a 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 5f 73  ..  return sql_s
117a0 69 6e 67 6c 65 5f 73 74 65 70 28 73 29 3b 0a 7d  ingle_step(s);.}
117b0 0a 0a 2f 2a 20 52 65 74 75 72 6e 73 20 53 51 4c  ../* Returns SQL
117c0 49 54 45 5f 52 4f 57 20 69 66 20 61 6e 79 20 72  ITE_ROW if any r
117d0 6f 77 73 20 65 78 69 73 74 20 69 6e 20 25 5f 63  ows exist in %_c
117e0 6f 6e 74 65 6e 74 2c 20 53 51 4c 49 54 45 5f 44  ontent, SQLITE_D
117f0 4f 4e 45 20 69 66 0a 2a 2a 20 6e 6f 20 72 6f 77  ONE if.** no row
11800 73 20 65 78 69 73 74 2c 20 61 6e 64 20 61 6e 79  s exist, and any
11810 20 65 72 72 6f 72 20 69 6e 20 63 61 73 65 20 6f   error in case o
11820 66 20 66 61 69 6c 75 72 65 2e 0a 2a 2f 0a 73 74  f failure..*/.st
11830 61 74 69 63 20 69 6e 74 20 63 6f 6e 74 65 6e 74  atic int content
11840 5f 65 78 69 73 74 73 28 66 75 6c 6c 74 65 78 74  _exists(fulltext
11850 5f 76 74 61 62 20 2a 76 29 7b 0a 20 20 73 71 6c  _vtab *v){.  sql
11860 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20  ite3_stmt *s;.  
11870 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67 65 74  int rc = sql_get
11880 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 43 4f  _statement(v, CO
11890 4e 54 45 4e 54 5f 45 58 49 53 54 53 5f 53 54 4d  NTENT_EXISTS_STM
118a0 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63  T, &s);.  if( rc
118b0 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
118c0 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d  turn rc;..  rc =
118d0 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 73 29   sqlite3_step(s)
118e0 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
118f0 54 45 5f 52 4f 57 20 29 20 72 65 74 75 72 6e 20  TE_ROW ) return 
11900 72 63 3b 0a 0a 20 20 2f 2a 20 57 65 20 65 78 70  rc;..  /* We exp
11910 65 63 74 20 6f 6e 6c 79 20 6f 6e 65 20 72 6f 77  ect only one row
11920 2e 20 20 57 65 20 6d 75 73 74 20 65 78 65 63 75  .  We must execu
11930 74 65 20 61 6e 6f 74 68 65 72 20 73 71 6c 69 74  te another sqlit
11940 65 33 5f 73 74 65 70 28 29 0a 20 20 20 2a 20 74  e3_step().   * t
11950 6f 20 63 6f 6d 70 6c 65 74 65 20 74 68 65 20 69  o complete the i
11960 74 65 72 61 74 69 6f 6e 3b 20 6f 74 68 65 72 77  teration; otherw
11970 69 73 65 20 74 68 65 20 74 61 62 6c 65 20 77 69  ise the table wi
11980 6c 6c 20 72 65 6d 61 69 6e 20 6c 6f 63 6b 65 64  ll remain locked
11990 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69  . */.  rc = sqli
119a0 74 65 33 5f 73 74 65 70 28 73 29 3b 0a 20 20 69  te3_step(s);.  i
119b0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f  f( rc==SQLITE_DO
119c0 4e 45 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  NE ) return SQLI
119d0 54 45 5f 52 4f 57 3b 0a 20 20 69 66 28 20 72 63  TE_ROW;.  if( rc
119e0 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 20 72  ==SQLITE_ROW ) r
119f0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
11a00 4f 52 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  OR;.  return rc;
11a10 0a 7d 0a 0a 2f 2a 20 69 6e 73 65 72 74 20 69 6e  .}../* insert in
11a20 74 6f 20 25 5f 73 65 67 6d 65 6e 74 73 20 76 61  to %_segments va
11a30 6c 75 65 73 20 28 5b 70 44 61 74 61 5d 29 0a 2a  lues ([pData]).*
11a40 2a 20 20 20 72 65 74 75 72 6e 73 20 61 73 73 69  *   returns assi
11a50 67 6e 65 64 20 62 6c 6f 63 6b 69 64 20 69 6e 20  gned blockid in 
11a60 2a 70 69 42 6c 6f 63 6b 69 64 0a 2a 2f 0a 73 74  *piBlockid.*/.st
11a70 61 74 69 63 20 69 6e 74 20 62 6c 6f 63 6b 5f 69  atic int block_i
11a80 6e 73 65 72 74 28 66 75 6c 6c 74 65 78 74 5f 76  nsert(fulltext_v
11a90 74 61 62 20 2a 76 2c 20 63 6f 6e 73 74 20 63 68  tab *v, const ch
11aa0 61 72 20 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e  ar *pData, int n
11ab0 44 61 74 61 2c 0a 20 20 20 20 20 20 20 20 20 20  Data,.          
11ac0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
11ad0 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 69 42 6c  lite_int64 *piBl
11ae0 6f 63 6b 69 64 29 7b 0a 20 20 73 71 6c 69 74 65  ockid){.  sqlite
11af0 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74  3_stmt *s;.  int
11b00 20 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74   rc = sql_get_st
11b10 61 74 65 6d 65 6e 74 28 76 2c 20 42 4c 4f 43 4b  atement(v, BLOCK
11b20 5f 49 4e 53 45 52 54 5f 53 54 4d 54 2c 20 26 73  _INSERT_STMT, &s
11b30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
11b40 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
11b50 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69  rc;..  rc = sqli
11b60 74 65 33 5f 62 69 6e 64 5f 62 6c 6f 62 28 73 2c  te3_bind_blob(s,
11b70 20 31 2c 20 70 44 61 74 61 2c 20 6e 44 61 74 61   1, pData, nData
11b80 2c 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29  , SQLITE_STATIC)
11b90 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
11ba0 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
11bb0 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  c;..  rc = sqlit
11bc0 65 33 5f 73 74 65 70 28 73 29 3b 0a 20 20 69 66  e3_step(s);.  if
11bd0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52 4f 57  ( rc==SQLITE_ROW
11be0 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
11bf0 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28 20 72 63  _ERROR;.  if( rc
11c00 21 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29 20  !=SQLITE_DONE ) 
11c10 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 2f 2a  return rc;..  /*
11c20 20 62 6c 6f 63 6b 69 64 20 63 6f 6c 75 6d 6e 20   blockid column 
11c30 69 73 20 61 6e 20 61 6c 69 61 73 20 66 6f 72 20  is an alias for 
11c40 72 6f 77 69 64 2e 20 2a 2f 0a 20 20 2a 70 69 42  rowid. */.  *piB
11c50 6c 6f 63 6b 69 64 20 3d 20 73 71 6c 69 74 65 33  lockid = sqlite3
11c60 5f 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77  _last_insert_row
11c70 69 64 28 76 2d 3e 64 62 29 3b 0a 20 20 72 65 74  id(v->db);.  ret
11c80 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
11c90 0a 0a 2f 2a 20 64 65 6c 65 74 65 20 66 72 6f 6d  ../* delete from
11ca0 20 25 5f 73 65 67 6d 65 6e 74 73 0a 2a 2a 20 20   %_segments.**  
11cb0 20 77 68 65 72 65 20 62 6c 6f 63 6b 69 64 20 62   where blockid b
11cc0 65 74 77 65 65 6e 20 5b 69 53 74 61 72 74 42 6c  etween [iStartBl
11cd0 6f 63 6b 69 64 5d 20 61 6e 64 20 5b 69 45 6e 64  ockid] and [iEnd
11ce0 42 6c 6f 63 6b 69 64 5d 0a 2a 2a 0a 2a 2a 20 44  Blockid].**.** D
11cf0 65 6c 65 74 65 73 20 74 68 65 20 72 61 6e 67 65  eletes the range
11d00 20 6f 66 20 62 6c 6f 63 6b 73 2c 20 69 6e 63 6c   of blocks, incl
11d10 75 73 69 76 65 2c 20 75 73 65 64 20 74 6f 20 64  usive, used to d
11d20 65 6c 65 74 65 20 74 68 65 20 62 6c 6f 63 6b 73  elete the blocks
11d30 0a 2a 2a 20 77 68 69 63 68 20 66 6f 72 6d 20 61  .** which form a
11d40 20 73 65 67 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61   segment..*/.sta
11d50 74 69 63 20 69 6e 74 20 62 6c 6f 63 6b 5f 64 65  tic int block_de
11d60 6c 65 74 65 28 66 75 6c 6c 74 65 78 74 5f 76 74  lete(fulltext_vt
11d70 61 62 20 2a 76 2c 0a 20 20 20 20 20 20 20 20 20  ab *v,.         
11d80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
11d90 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 53 74 61  qlite_int64 iSta
11da0 72 74 42 6c 6f 63 6b 69 64 2c 20 73 71 6c 69 74  rtBlockid, sqlit
11db0 65 5f 69 6e 74 36 34 20 69 45 6e 64 42 6c 6f 63  e_int64 iEndBloc
11dc0 6b 69 64 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  kid){.  sqlite3_
11dd0 73 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74 20 72  stmt *s;.  int r
11de0 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74 61 74  c = sql_get_stat
11df0 65 6d 65 6e 74 28 76 2c 20 42 4c 4f 43 4b 5f 44  ement(v, BLOCK_D
11e00 45 4c 45 54 45 5f 53 54 4d 54 2c 20 26 73 29 3b  ELETE_STMT, &s);
11e10 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
11e20 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
11e30 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  ;..  rc = sqlite
11e40 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 73 2c 20  3_bind_int64(s, 
11e50 31 2c 20 69 53 74 61 72 74 42 6c 6f 63 6b 69 64  1, iStartBlockid
11e60 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
11e70 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
11e80 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69  rc;..  rc = sqli
11e90 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 73  te3_bind_int64(s
11ea0 2c 20 32 2c 20 69 45 6e 64 42 6c 6f 63 6b 69 64  , 2, iEndBlockid
11eb0 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
11ec0 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
11ed0 72 63 3b 0a 0a 20 20 72 65 74 75 72 6e 20 73 71  rc;..  return sq
11ee0 6c 5f 73 69 6e 67 6c 65 5f 73 74 65 70 28 73 29  l_single_step(s)
11ef0 3b 0a 7d 0a 0a 2f 2a 20 52 65 74 75 72 6e 73 20  ;.}../* Returns 
11f00 53 51 4c 49 54 45 5f 52 4f 57 20 77 69 74 68 20  SQLITE_ROW with 
11f10 2a 70 69 64 78 20 73 65 74 20 74 6f 20 74 68 65  *pidx set to the
11f20 20 6d 61 78 69 6d 75 6d 20 73 65 67 6d 65 6e 74   maximum segment
11f30 20 69 64 78 20 66 6f 75 6e 64 0a 2a 2a 20 61 74   idx found.** at
11f40 20 69 4c 65 76 65 6c 2e 20 20 52 65 74 75 72 6e   iLevel.  Return
11f50 73 20 53 51 4c 49 54 45 5f 44 4f 4e 45 20 69 66  s SQLITE_DONE if
11f60 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 73 65   there are no se
11f70 67 6d 65 6e 74 73 20 61 74 0a 2a 2a 20 69 4c 65  gments at.** iLe
11f80 76 65 6c 2e 20 20 4f 74 68 65 72 77 69 73 65 20  vel.  Otherwise 
11f90 72 65 74 75 72 6e 73 20 61 6e 20 65 72 72 6f 72  returns an error
11fa0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
11fb0 73 65 67 64 69 72 5f 6d 61 78 5f 69 6e 64 65 78  segdir_max_index
11fc0 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
11fd0 76 2c 20 69 6e 74 20 69 4c 65 76 65 6c 2c 20 69  v, int iLevel, i
11fe0 6e 74 20 2a 70 69 64 78 29 7b 0a 20 20 73 71 6c  nt *pidx){.  sql
11ff0 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20  ite3_stmt *s;.  
12000 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67 65 74  int rc = sql_get
12010 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 53 45  _statement(v, SE
12020 47 44 49 52 5f 4d 41 58 5f 49 4e 44 45 58 5f 53  GDIR_MAX_INDEX_S
12030 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20  TMT, &s);.  if( 
12040 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
12050 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63  return rc;..  rc
12060 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   = sqlite3_bind_
12070 69 6e 74 28 73 2c 20 31 2c 20 69 4c 65 76 65 6c  int(s, 1, iLevel
12080 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
12090 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
120a0 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69  rc;..  rc = sqli
120b0 74 65 33 5f 73 74 65 70 28 73 29 3b 0a 20 20 2f  te3_step(s);.  /
120c0 2a 20 53 68 6f 75 6c 64 20 61 6c 77 61 79 73 20  * Should always 
120d0 67 65 74 20 61 74 20 6c 65 61 73 74 20 6f 6e 65  get at least one
120e0 20 72 6f 77 20 64 75 65 20 74 6f 20 68 6f 77 20   row due to how 
120f0 6d 61 78 28 29 20 77 6f 72 6b 73 2e 20 2a 2f 0a  max() works. */.
12100 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
12110 5f 44 4f 4e 45 20 29 20 72 65 74 75 72 6e 20 53  _DONE ) return S
12120 51 4c 49 54 45 5f 44 4f 4e 45 3b 0a 20 20 69 66  QLITE_DONE;.  if
12130 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57  ( rc!=SQLITE_ROW
12140 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
12150 20 2f 2a 20 4e 55 4c 4c 20 6d 65 61 6e 73 20 74   /* NULL means t
12160 68 61 74 20 74 68 65 72 65 20 77 65 72 65 20 6e  hat there were n
12170 6f 20 69 6e 70 75 74 73 20 74 6f 20 6d 61 78 28  o inputs to max(
12180 29 2e 20 2a 2f 0a 20 20 69 66 28 20 53 51 4c 49  ). */.  if( SQLI
12190 54 45 5f 4e 55 4c 4c 3d 3d 73 71 6c 69 74 65 33  TE_NULL==sqlite3
121a0 5f 63 6f 6c 75 6d 6e 5f 74 79 70 65 28 73 2c 20  _column_type(s, 
121b0 30 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  0) ){.    rc = s
121c0 71 6c 69 74 65 33 5f 73 74 65 70 28 73 29 3b 0a  qlite3_step(s);.
121d0 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
121e0 54 45 5f 52 4f 57 20 29 20 72 65 74 75 72 6e 20  TE_ROW ) return 
121f0 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
12200 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d    return rc;.  }
12210 0a 0a 20 20 2a 70 69 64 78 20 3d 20 73 71 6c 69  ..  *pidx = sqli
12220 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 73  te3_column_int(s
12230 2c 20 30 29 3b 0a 0a 20 20 2f 2a 20 57 65 20 65  , 0);..  /* We e
12240 78 70 65 63 74 20 6f 6e 6c 79 20 6f 6e 65 20 72  xpect only one r
12250 6f 77 2e 20 20 57 65 20 6d 75 73 74 20 65 78 65  ow.  We must exe
12260 63 75 74 65 20 61 6e 6f 74 68 65 72 20 73 71 6c  cute another sql
12270 69 74 65 33 5f 73 74 65 70 28 29 0a 20 20 20 2a  ite3_step().   *
12280 20 74 6f 20 63 6f 6d 70 6c 65 74 65 20 74 68 65   to complete the
12290 20 69 74 65 72 61 74 69 6f 6e 3b 20 6f 74 68 65   iteration; othe
122a0 72 77 69 73 65 20 74 68 65 20 74 61 62 6c 65 20  rwise the table 
122b0 77 69 6c 6c 20 72 65 6d 61 69 6e 20 6c 6f 63 6b  will remain lock
122c0 65 64 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71  ed. */.  rc = sq
122d0 6c 69 74 65 33 5f 73 74 65 70 28 73 29 3b 0a 20  lite3_step(s);. 
122e0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
122f0 52 4f 57 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ROW ) return SQL
12300 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28  ITE_ERROR;.  if(
12310 20 72 63 21 3d 53 51 4c 49 54 45 5f 44 4f 4e 45   rc!=SQLITE_DONE
12320 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
12330 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 52 4f  return SQLITE_RO
12340 57 3b 0a 7d 0a 0a 2f 2a 20 69 6e 73 65 72 74 20  W;.}../* insert 
12350 69 6e 74 6f 20 25 5f 73 65 67 64 69 72 20 76 61  into %_segdir va
12360 6c 75 65 73 20 28 0a 2a 2a 20 20 20 5b 69 4c 65  lues (.**   [iLe
12370 76 65 6c 5d 2c 20 5b 69 64 78 5d 2c 0a 2a 2a 20  vel], [idx],.** 
12380 20 20 5b 69 53 74 61 72 74 42 6c 6f 63 6b 69 64    [iStartBlockid
12390 5d 2c 20 5b 69 4c 65 61 76 65 73 45 6e 64 42 6c  ], [iLeavesEndBl
123a0 6f 63 6b 69 64 5d 2c 20 5b 69 45 6e 64 42 6c 6f  ockid], [iEndBlo
123b0 63 6b 69 64 5d 2c 0a 2a 2a 20 20 20 5b 70 52 6f  ckid],.**   [pRo
123c0 6f 74 44 61 74 61 5d 0a 2a 2a 20 29 0a 2a 2f 0a  otData].** ).*/.
123d0 73 74 61 74 69 63 20 69 6e 74 20 73 65 67 64 69  static int segdi
123e0 72 5f 73 65 74 28 66 75 6c 6c 74 65 78 74 5f 76  r_set(fulltext_v
123f0 74 61 62 20 2a 76 2c 20 69 6e 74 20 69 4c 65 76  tab *v, int iLev
12400 65 6c 2c 20 69 6e 74 20 69 64 78 2c 0a 20 20 20  el, int idx,.   
12410 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12420 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20     sqlite_int64 
12430 69 53 74 61 72 74 42 6c 6f 63 6b 69 64 2c 0a 20  iStartBlockid,. 
12440 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12450 20 20 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36       sqlite_int6
12460 34 20 69 4c 65 61 76 65 73 45 6e 64 42 6c 6f 63  4 iLeavesEndBloc
12470 6b 69 64 2c 0a 20 20 20 20 20 20 20 20 20 20 20  kid,.           
12480 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
12490 65 5f 69 6e 74 36 34 20 69 45 6e 64 42 6c 6f 63  e_int64 iEndBloc
124a0 6b 69 64 2c 0a 20 20 20 20 20 20 20 20 20 20 20  kid,.           
124b0 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74             const
124c0 20 63 68 61 72 20 2a 70 52 6f 6f 74 44 61 74 61   char *pRootData
124d0 2c 20 69 6e 74 20 6e 52 6f 6f 74 44 61 74 61 29  , int nRootData)
124e0 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  {.  sqlite3_stmt
124f0 20 2a 73 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20   *s;.  int rc = 
12500 73 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e  sql_get_statemen
12510 74 28 76 2c 20 53 45 47 44 49 52 5f 53 45 54 5f  t(v, SEGDIR_SET_
12520 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28  STMT, &s);.  if(
12530 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
12540 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72   return rc;..  r
12550 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
12560 5f 69 6e 74 28 73 2c 20 31 2c 20 69 4c 65 76 65  _int(s, 1, iLeve
12570 6c 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  l);.  if( rc!=SQ
12580 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
12590 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c   rc;..  rc = sql
125a0 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 28 73 2c  ite3_bind_int(s,
125b0 20 32 2c 20 69 64 78 29 3b 0a 20 20 69 66 28 20   2, idx);.  if( 
125c0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
125d0 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63  return rc;..  rc
125e0 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   = sqlite3_bind_
125f0 69 6e 74 36 34 28 73 2c 20 33 2c 20 69 53 74 61  int64(s, 3, iSta
12600 72 74 42 6c 6f 63 6b 69 64 29 3b 0a 20 20 69 66  rtBlockid);.  if
12610 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
12620 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
12630 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e  rc = sqlite3_bin
12640 64 5f 69 6e 74 36 34 28 73 2c 20 34 2c 20 69 4c  d_int64(s, 4, iL
12650 65 61 76 65 73 45 6e 64 42 6c 6f 63 6b 69 64 29  eavesEndBlockid)
12660 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
12670 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
12680 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  c;..  rc = sqlit
12690 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 73 2c  e3_bind_int64(s,
126a0 20 35 2c 20 69 45 6e 64 42 6c 6f 63 6b 69 64 29   5, iEndBlockid)
126b0 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
126c0 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
126d0 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  c;..  rc = sqlit
126e0 65 33 5f 62 69 6e 64 5f 62 6c 6f 62 28 73 2c 20  e3_bind_blob(s, 
126f0 36 2c 20 70 52 6f 6f 74 44 61 74 61 2c 20 6e 52  6, pRootData, nR
12700 6f 6f 74 44 61 74 61 2c 20 53 51 4c 49 54 45 5f  ootData, SQLITE_
12710 53 54 41 54 49 43 29 3b 0a 20 20 69 66 28 20 72  STATIC);.  if( r
12720 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
12730 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 65 74  eturn rc;..  ret
12740 75 72 6e 20 73 71 6c 5f 73 69 6e 67 6c 65 5f 73  urn sql_single_s
12750 74 65 70 28 73 29 3b 0a 7d 0a 0a 2f 2a 20 51 75  tep(s);.}../* Qu
12760 65 72 69 65 73 20 25 5f 73 65 67 64 69 72 20 66  eries %_segdir f
12770 6f 72 20 74 68 65 20 62 6c 6f 63 6b 20 73 70 61  or the block spa
12780 6e 20 6f 66 20 74 68 65 20 73 65 67 6d 65 6e 74  n of the segment
12790 73 20 69 6e 20 6c 65 76 65 6c 0a 2a 2a 20 69 4c  s in level.** iL
127a0 65 76 65 6c 2e 20 20 52 65 74 75 72 6e 73 20 53  evel.  Returns S
127b0 51 4c 49 54 45 5f 44 4f 4e 45 20 69 66 20 74 68  QLITE_DONE if th
127c0 65 72 65 20 61 72 65 20 6e 6f 20 62 6c 6f 63 6b  ere are no block
127d0 73 20 66 6f 72 20 69 4c 65 76 65 6c 2c 0a 2a 2a  s for iLevel,.**
127e0 20 53 51 4c 49 54 45 5f 52 4f 57 20 69 66 20 74   SQLITE_ROW if t
127f0 68 65 72 65 20 61 72 65 20 62 6c 6f 63 6b 73 2c  here are blocks,
12800 20 65 6c 73 65 20 61 6e 20 65 72 72 6f 72 2e 0a   else an error..
12810 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
12820 67 64 69 72 5f 73 70 61 6e 28 66 75 6c 6c 74 65  gdir_span(fullte
12830 78 74 5f 76 74 61 62 20 2a 76 2c 20 69 6e 74 20  xt_vtab *v, int 
12840 69 4c 65 76 65 6c 2c 0a 20 20 20 20 20 20 20 20  iLevel,.        
12850 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
12860 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 69 53  qlite_int64 *piS
12870 74 61 72 74 42 6c 6f 63 6b 69 64 2c 0a 20 20 20  tartBlockid,.   
12880 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12890 20 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34      sqlite_int64
128a0 20 2a 70 69 45 6e 64 42 6c 6f 63 6b 69 64 29 7b   *piEndBlockid){
128b0 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
128c0 2a 73 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73  *s;.  int rc = s
128d0 71 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74  ql_get_statement
128e0 28 76 2c 20 53 45 47 44 49 52 5f 53 50 41 4e 5f  (v, SEGDIR_SPAN_
128f0 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 69 66 28  STMT, &s);.  if(
12900 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
12910 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72   return rc;..  r
12920 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
12930 5f 69 6e 74 28 73 2c 20 31 2c 20 69 4c 65 76 65  _int(s, 1, iLeve
12940 6c 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  l);.  if( rc!=SQ
12950 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
12960 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c   rc;..  rc = sql
12970 69 74 65 33 5f 73 74 65 70 28 73 29 3b 0a 20 20  ite3_step(s);.  
12980 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 44  if( rc==SQLITE_D
12990 4f 4e 45 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ONE ) return SQL
129a0 49 54 45 5f 44 4f 4e 45 3b 20 20 2f 2a 20 53 68  ITE_DONE;  /* Sh
129b0 6f 75 6c 64 20 6e 65 76 65 72 20 68 61 70 70 65  ould never happe
129c0 6e 20 2a 2f 0a 20 20 69 66 28 20 72 63 21 3d 53  n */.  if( rc!=S
129d0 51 4c 49 54 45 5f 52 4f 57 20 29 20 72 65 74 75  QLITE_ROW ) retu
129e0 72 6e 20 72 63 3b 0a 0a 20 20 2f 2a 20 54 68 69  rn rc;..  /* Thi
129f0 73 20 68 61 70 70 65 6e 73 20 69 66 20 61 6c 6c  s happens if all
12a00 20 73 65 67 6d 65 6e 74 73 20 61 74 20 74 68 69   segments at thi
12a10 73 20 6c 65 76 65 6c 20 61 72 65 20 65 6e 74 69  s level are enti
12a20 72 65 6c 79 20 69 6e 6c 69 6e 65 2e 20 2a 2f 0a  rely inline. */.
12a30 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4e 55 4c    if( SQLITE_NUL
12a40 4c 3d 3d 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  L==sqlite3_colum
12a50 6e 5f 74 79 70 65 28 73 2c 20 30 29 20 29 7b 0a  n_type(s, 0) ){.
12a60 20 20 20 20 2f 2a 20 57 65 20 65 78 70 65 63 74      /* We expect
12a70 20 6f 6e 6c 79 20 6f 6e 65 20 72 6f 77 2e 20 20   only one row.  
12a80 57 65 20 6d 75 73 74 20 65 78 65 63 75 74 65 20  We must execute 
12a90 61 6e 6f 74 68 65 72 20 73 71 6c 69 74 65 33 5f  another sqlite3_
12aa0 73 74 65 70 28 29 0a 20 20 20 20 20 2a 20 74 6f  step().     * to
12ab0 20 63 6f 6d 70 6c 65 74 65 20 74 68 65 20 69 74   complete the it
12ac0 65 72 61 74 69 6f 6e 3b 20 6f 74 68 65 72 77 69  eration; otherwi
12ad0 73 65 20 74 68 65 20 74 61 62 6c 65 20 77 69 6c  se the table wil
12ae0 6c 20 72 65 6d 61 69 6e 20 6c 6f 63 6b 65 64 2e  l remain locked.
12af0 20 2a 2f 0a 20 20 20 20 69 6e 74 20 72 63 32 20   */.    int rc2 
12b00 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 73  = sqlite3_step(s
12b10 29 3b 0a 20 20 20 20 69 66 28 20 72 63 32 3d 3d  );.    if( rc2==
12b20 53 51 4c 49 54 45 5f 52 4f 57 20 29 20 72 65 74  SQLITE_ROW ) ret
12b30 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  urn SQLITE_ERROR
12b40 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 32  ;.    return rc2
12b50 3b 0a 20 20 7d 0a 0a 20 20 2a 70 69 53 74 61 72  ;.  }..  *piStar
12b60 74 42 6c 6f 63 6b 69 64 20 3d 20 73 71 6c 69 74  tBlockid = sqlit
12b70 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28  e3_column_int64(
12b80 73 2c 20 30 29 3b 0a 20 20 2a 70 69 45 6e 64 42  s, 0);.  *piEndB
12b90 6c 6f 63 6b 69 64 20 3d 20 73 71 6c 69 74 65 33  lockid = sqlite3
12ba0 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 73 2c  _column_int64(s,
12bb0 20 31 29 3b 0a 0a 20 20 2f 2a 20 57 65 20 65 78   1);..  /* We ex
12bc0 70 65 63 74 20 6f 6e 6c 79 20 6f 6e 65 20 72 6f  pect only one ro
12bd0 77 2e 20 20 57 65 20 6d 75 73 74 20 65 78 65 63  w.  We must exec
12be0 75 74 65 20 61 6e 6f 74 68 65 72 20 73 71 6c 69  ute another sqli
12bf0 74 65 33 5f 73 74 65 70 28 29 0a 20 20 20 2a 20  te3_step().   * 
12c00 74 6f 20 63 6f 6d 70 6c 65 74 65 20 74 68 65 20  to complete the 
12c10 69 74 65 72 61 74 69 6f 6e 3b 20 6f 74 68 65 72  iteration; other
12c20 77 69 73 65 20 74 68 65 20 74 61 62 6c 65 20 77  wise the table w
12c30 69 6c 6c 20 72 65 6d 61 69 6e 20 6c 6f 63 6b 65  ill remain locke
12c40 64 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c  d. */.  rc = sql
12c50 69 74 65 33 5f 73 74 65 70 28 73 29 3b 0a 20 20  ite3_step(s);.  
12c60 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52  if( rc==SQLITE_R
12c70 4f 57 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  OW ) return SQLI
12c80 54 45 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28 20  TE_ERROR;.  if( 
12c90 72 63 21 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20  rc!=SQLITE_DONE 
12ca0 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 72  ) return rc;.  r
12cb0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 52 4f 57  eturn SQLITE_ROW
12cc0 3b 0a 7d 0a 0a 2f 2a 20 44 65 6c 65 74 65 20 74  ;.}../* Delete t
12cd0 68 65 20 73 65 67 6d 65 6e 74 20 62 6c 6f 63 6b  he segment block
12ce0 73 20 61 6e 64 20 73 65 67 6d 65 6e 74 20 64 69  s and segment di
12cf0 72 65 63 74 6f 72 79 20 72 65 63 6f 72 64 73 20  rectory records 
12d00 66 6f 72 20 61 6c 6c 0a 2a 2a 20 73 65 67 6d 65  for all.** segme
12d10 6e 74 73 20 61 74 20 69 4c 65 76 65 6c 2e 0a 2a  nts at iLevel..*
12d20 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 67  /.static int seg
12d30 64 69 72 5f 64 65 6c 65 74 65 28 66 75 6c 6c 74  dir_delete(fullt
12d40 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 69 6e 74  ext_vtab *v, int
12d50 20 69 4c 65 76 65 6c 29 7b 0a 20 20 73 71 6c 69   iLevel){.  sqli
12d60 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20 73  te3_stmt *s;.  s
12d70 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 53 74 61  qlite_int64 iSta
12d80 72 74 42 6c 6f 63 6b 69 64 2c 20 69 45 6e 64 42  rtBlockid, iEndB
12d90 6c 6f 63 6b 69 64 3b 0a 20 20 69 6e 74 20 72 63  lockid;.  int rc
12da0 20 3d 20 73 65 67 64 69 72 5f 73 70 61 6e 28 76   = segdir_span(v
12db0 2c 20 69 4c 65 76 65 6c 2c 20 26 69 53 74 61 72  , iLevel, &iStar
12dc0 74 42 6c 6f 63 6b 69 64 2c 20 26 69 45 6e 64 42  tBlockid, &iEndB
12dd0 6c 6f 63 6b 69 64 29 3b 0a 20 20 69 66 28 20 72  lockid);.  if( r
12de0 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20 26 26  c!=SQLITE_ROW &&
12df0 20 72 63 21 3d 53 51 4c 49 54 45 5f 44 4f 4e 45   rc!=SQLITE_DONE
12e00 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
12e10 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
12e20 52 4f 57 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  ROW ){.    rc = 
12e30 62 6c 6f 63 6b 5f 64 65 6c 65 74 65 28 76 2c 20  block_delete(v, 
12e40 69 53 74 61 72 74 42 6c 6f 63 6b 69 64 2c 20 69  iStartBlockid, i
12e50 45 6e 64 42 6c 6f 63 6b 69 64 29 3b 0a 20 20 20  EndBlockid);.   
12e60 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
12e70 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
12e80 20 20 7d 0a 0a 20 20 2f 2a 20 44 65 6c 65 74 65    }..  /* Delete
12e90 20 74 68 65 20 73 65 67 6d 65 6e 74 20 64 69 72   the segment dir
12ea0 65 63 74 6f 72 79 20 69 74 73 65 6c 66 2e 20 2a  ectory itself. *
12eb0 2f 0a 20 20 72 63 20 3d 20 73 71 6c 5f 67 65 74  /.  rc = sql_get
12ec0 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20 53 45  _statement(v, SE
12ed0 47 44 49 52 5f 44 45 4c 45 54 45 5f 53 54 4d 54  GDIR_DELETE_STMT
12ee0 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63 21  , &s);.  if( rc!
12ef0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
12f00 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20  urn rc;..  rc = 
12f10 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74  sqlite3_bind_int
12f20 36 34 28 73 2c 20 31 2c 20 69 4c 65 76 65 6c 29  64(s, 1, iLevel)
12f30 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
12f40 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
12f50 63 3b 0a 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  c;..  return sql
12f60 5f 73 69 6e 67 6c 65 5f 73 74 65 70 28 73 29 3b  _single_step(s);
12f70 0a 7d 0a 0a 2f 2a 20 44 65 6c 65 74 65 20 65 6e  .}../* Delete en
12f80 74 69 72 65 20 66 74 73 20 69 6e 64 65 78 2c 20  tire fts index, 
12f90 53 51 4c 49 54 45 5f 4f 4b 20 6f 6e 20 73 75 63  SQLITE_OK on suc
12fa0 63 65 73 73 2c 20 72 65 6c 65 76 61 6e 74 20 65  cess, relevant e
12fb0 72 72 6f 72 20 6f 6e 0a 2a 2a 20 66 61 69 6c 75  rror on.** failu
12fc0 72 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  re..*/.static in
12fd0 74 20 73 65 67 64 69 72 5f 64 65 6c 65 74 65 5f  t segdir_delete_
12fe0 61 6c 6c 28 66 75 6c 6c 74 65 78 74 5f 76 74 61  all(fulltext_vta
12ff0 62 20 2a 76 29 7b 0a 20 20 73 71 6c 69 74 65 33  b *v){.  sqlite3
13000 5f 73 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74 20  _stmt *s;.  int 
13010 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74 61  rc = sql_get_sta
13020 74 65 6d 65 6e 74 28 76 2c 20 53 45 47 44 49 52  tement(v, SEGDIR
13030 5f 44 45 4c 45 54 45 5f 41 4c 4c 5f 53 54 4d 54  _DELETE_ALL_STMT
13040 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63 21  , &s);.  if( rc!
13050 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
13060 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20  urn rc;..  rc = 
13070 73 71 6c 5f 73 69 6e 67 6c 65 5f 73 74 65 70 28  sql_single_step(
13080 73 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  s);.  if( rc!=SQ
13090 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
130a0 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c   rc;..  rc = sql
130b0 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76  _get_statement(v
130c0 2c 20 42 4c 4f 43 4b 5f 44 45 4c 45 54 45 5f 41  , BLOCK_DELETE_A
130d0 4c 4c 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20  LL_STMT, &s);.  
130e0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
130f0 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
13100 20 20 72 65 74 75 72 6e 20 73 71 6c 5f 73 69 6e    return sql_sin
13110 67 6c 65 5f 73 74 65 70 28 73 29 3b 0a 7d 0a 0a  gle_step(s);.}..
13120 2f 2a 20 52 65 74 75 72 6e 73 20 53 51 4c 49 54  /* Returns SQLIT
13130 45 5f 4f 4b 20 77 69 74 68 20 2a 70 6e 53 65 67  E_OK with *pnSeg
13140 6d 65 6e 74 73 20 73 65 74 20 74 6f 20 74 68 65  ments set to the
13150 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69   number of entri
13160 65 73 20 69 6e 0a 2a 2a 20 25 5f 73 65 67 64 69  es in.** %_segdi
13170 72 20 61 6e 64 20 2a 70 69 4d 61 78 4c 65 76 65  r and *piMaxLeve
13180 6c 20 73 65 74 20 74 6f 20 74 68 65 20 68 69 67  l set to the hig
13190 68 65 73 74 20 6c 65 76 65 6c 20 77 68 69 63 68  hest level which
131a0 20 68 61 73 20 61 0a 2a 2a 20 73 65 67 6d 65 6e   has a.** segmen
131b0 74 2e 20 20 4f 74 68 65 72 77 69 73 65 20 72 65  t.  Otherwise re
131c0 74 75 72 6e 73 20 74 68 65 20 53 51 4c 69 74 65  turns the SQLite
131d0 20 65 72 72 6f 72 20 77 68 69 63 68 20 63 61 75   error which cau
131e0 73 65 64 20 66 61 69 6c 75 72 65 2e 0a 2a 2f 0a  sed failure..*/.
131f0 73 74 61 74 69 63 20 69 6e 74 20 73 65 67 64 69  static int segdi
13200 72 5f 63 6f 75 6e 74 28 66 75 6c 6c 74 65 78 74  r_count(fulltext
13210 5f 76 74 61 62 20 2a 76 2c 20 69 6e 74 20 2a 70  _vtab *v, int *p
13220 6e 53 65 67 6d 65 6e 74 73 2c 20 69 6e 74 20 2a  nSegments, int *
13230 70 69 4d 61 78 4c 65 76 65 6c 29 7b 0a 20 20 73  piMaxLevel){.  s
13240 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a  qlite3_stmt *s;.
13250 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67    int rc = sql_g
13260 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20  et_statement(v, 
13270 53 45 47 44 49 52 5f 43 4f 55 4e 54 5f 53 54 4d  SEGDIR_COUNT_STM
13280 54 2c 20 26 73 29 3b 0a 20 20 69 66 28 20 72 63  T, &s);.  if( rc
13290 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
132a0 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d  turn rc;..  rc =
132b0 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 73 29   sqlite3_step(s)
132c0 3b 0a 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73  ;.  /* TODO(shes
132d0 73 29 3a 20 54 68 69 73 20 63 61 73 65 20 73 68  s): This case sh
132e0 6f 75 6c 64 20 6e 6f 74 20 62 65 20 70 6f 73 73  ould not be poss
132f0 69 62 6c 65 3f 20 20 53 68 6f 75 6c 64 20 73 74  ible?  Should st
13300 72 6f 6e 67 65 72 0a 20 20 2a 2a 20 6d 65 61 73  ronger.  ** meas
13310 75 72 65 73 20 62 65 20 74 61 6b 65 6e 20 69 66  ures be taken if
13320 20 69 74 20 68 61 70 70 65 6e 73 3f 0a 20 20 2a   it happens?.  *
13330 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  /.  if( rc==SQLI
13340 54 45 5f 44 4f 4e 45 20 29 7b 0a 20 20 20 20 2a  TE_DONE ){.    *
13350 70 6e 53 65 67 6d 65 6e 74 73 20 3d 20 30 3b 0a  pnSegments = 0;.
13360 20 20 20 20 2a 70 69 4d 61 78 4c 65 76 65 6c 20      *piMaxLevel 
13370 3d 20 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  = 0;.    return 
13380 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20  SQLITE_OK;.  }. 
13390 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
133a0 52 4f 57 20 29 20 72 65 74 75 72 6e 20 72 63 3b  ROW ) return rc;
133b0 0a 0a 20 20 2a 70 6e 53 65 67 6d 65 6e 74 73 20  ..  *pnSegments 
133c0 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
133d0 5f 69 6e 74 28 73 2c 20 30 29 3b 0a 20 20 2a 70  _int(s, 0);.  *p
133e0 69 4d 61 78 4c 65 76 65 6c 20 3d 20 73 71 6c 69  iMaxLevel = sqli
133f0 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 73  te3_column_int(s
13400 2c 20 31 29 3b 0a 0a 20 20 2f 2a 20 57 65 20 65  , 1);..  /* We e
13410 78 70 65 63 74 20 6f 6e 6c 79 20 6f 6e 65 20 72  xpect only one r
13420 6f 77 2e 20 20 57 65 20 6d 75 73 74 20 65 78 65  ow.  We must exe
13430 63 75 74 65 20 61 6e 6f 74 68 65 72 20 73 71 6c  cute another sql
13440 69 74 65 33 5f 73 74 65 70 28 29 0a 20 20 20 2a  ite3_step().   *
13450 20 74 6f 20 63 6f 6d 70 6c 65 74 65 20 74 68 65   to complete the
13460 20 69 74 65 72 61 74 69 6f 6e 3b 20 6f 74 68 65   iteration; othe
13470 72 77 69 73 65 20 74 68 65 20 74 61 62 6c 65 20  rwise the table 
13480 77 69 6c 6c 20 72 65 6d 61 69 6e 20 6c 6f 63 6b  will remain lock
13490 65 64 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71  ed. */.  rc = sq
134a0 6c 69 74 65 33 5f 73 74 65 70 28 73 29 3b 0a 20  lite3_step(s);. 
134b0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
134c0 44 4f 4e 45 20 29 20 72 65 74 75 72 6e 20 53 51  DONE ) return SQ
134d0 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 72  LITE_OK;.  if( r
134e0 63 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 20  c==SQLITE_ROW ) 
134f0 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
13500 52 4f 52 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  ROR;.  return rc
13510 3b 0a 7d 0a 0a 2f 2a 20 54 4f 44 4f 28 73 68 65  ;.}../* TODO(she
13520 73 73 29 20 63 6c 65 61 72 50 65 6e 64 69 6e 67  ss) clearPending
13530 54 65 72 6d 73 28 29 20 69 73 20 66 61 72 20 64  Terms() is far d
13540 6f 77 6e 20 74 68 65 20 66 69 6c 65 20 62 65 63  own the file bec
13550 61 75 73 65 0a 2a 2a 20 77 72 69 74 65 5a 65 72  ause.** writeZer
13560 6f 53 65 67 6d 65 6e 74 28 29 20 69 73 20 66 61  oSegment() is fa
13570 72 20 64 6f 77 6e 20 74 68 65 20 66 69 6c 65 20  r down the file 
13580 62 65 63 61 75 73 65 20 4c 65 61 66 57 72 69 74  because LeafWrit
13590 65 72 20 69 73 20 66 61 72 0a 2a 2a 20 64 6f 77  er is far.** dow
135a0 6e 20 74 68 65 20 66 69 6c 65 2e 20 20 43 6f 6e  n the file.  Con
135b0 73 69 64 65 72 20 72 65 66 61 63 74 6f 72 69 6e  sider refactorin
135c0 67 20 74 68 65 20 63 6f 64 65 20 74 6f 20 6d 6f  g the code to mo
135d0 76 65 20 74 68 65 20 6e 6f 6e 2d 76 74 61 62 0a  ve the non-vtab.
135e0 2a 2a 20 63 6f 64 65 20 61 62 6f 76 65 20 74 68  ** code above th
135f0 65 20 76 74 61 62 20 63 6f 64 65 20 73 6f 20 74  e vtab code so t
13600 68 61 74 20 77 65 20 64 6f 6e 27 74 20 6e 65 65  hat we don't nee
13610 64 20 74 68 69 73 20 66 6f 72 77 61 72 64 0a 2a  d this forward.*
13620 2a 20 72 65 66 65 72 65 6e 63 65 2e 0a 2a 2f 0a  * reference..*/.
13630 73 74 61 74 69 63 20 69 6e 74 20 63 6c 65 61 72  static int clear
13640 50 65 6e 64 69 6e 67 54 65 72 6d 73 28 66 75 6c  PendingTerms(ful
13650 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 29 3b 0a  ltext_vtab *v);.
13660 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 74 68 65 20  ./*.** Free the 
13670 6d 65 6d 6f 72 79 20 75 73 65 64 20 74 6f 20 63  memory used to c
13680 6f 6e 74 61 69 6e 20 61 20 66 75 6c 6c 74 65 78  ontain a fulltex
13690 74 5f 76 74 61 62 20 73 74 72 75 63 74 75 72 65  t_vtab structure
136a0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
136b0 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 5f 64   fulltext_vtab_d
136c0 65 73 74 72 6f 79 28 66 75 6c 6c 74 65 78 74 5f  estroy(fulltext_
136d0 76 74 61 62 20 2a 76 29 7b 0a 20 20 69 6e 74 20  vtab *v){.  int 
136e0 69 53 74 6d 74 2c 20 69 3b 0a 0a 20 20 46 54 53  iStmt, i;..  FTS
136f0 54 52 41 43 45 28 28 22 46 54 53 33 20 44 65 73  TRACE(("FTS3 Des
13700 74 72 6f 79 20 25 70 5c 6e 22 2c 20 76 29 29 3b  troy %p\n", v));
13710 0a 20 20 66 6f 72 28 20 69 53 74 6d 74 3d 30 3b  .  for( iStmt=0;
13720 20 69 53 74 6d 74 3c 4d 41 58 5f 53 54 4d 54 3b   iStmt<MAX_STMT;
13730 20 69 53 74 6d 74 2b 2b 20 29 7b 0a 20 20 20 20   iStmt++ ){.    
13740 69 66 28 20 76 2d 3e 70 46 75 6c 6c 74 65 78 74  if( v->pFulltext
13750 53 74 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74  Statements[iStmt
13760 5d 21 3d 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 20  ]!=NULL ){.     
13770 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
13780 65 28 76 2d 3e 70 46 75 6c 6c 74 65 78 74 53 74  e(v->pFulltextSt
13790 61 74 65 6d 65 6e 74 73 5b 69 53 74 6d 74 5d 29  atements[iStmt])
137a0 3b 0a 20 20 20 20 20 20 76 2d 3e 70 46 75 6c 6c  ;.      v->pFull
137b0 74 65 78 74 53 74 61 74 65 6d 65 6e 74 73 5b 69  textStatements[i
137c0 53 74 6d 74 5d 20 3d 20 4e 55 4c 4c 3b 0a 20 20  Stmt] = NULL;.  
137d0 20 20 7d 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 20    }.  }..  for( 
137e0 69 3d 30 3b 20 69 3c 4d 45 52 47 45 5f 43 4f 55  i=0; i<MERGE_COU
137f0 4e 54 3b 20 69 2b 2b 20 29 7b 0a 20 20 20 20 69  NT; i++ ){.    i
13800 66 28 20 76 2d 3e 70 4c 65 61 66 53 65 6c 65 63  f( v->pLeafSelec
13810 74 53 74 6d 74 73 5b 69 5d 21 3d 4e 55 4c 4c 20  tStmts[i]!=NULL 
13820 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
13830 5f 66 69 6e 61 6c 69 7a 65 28 76 2d 3e 70 4c 65  _finalize(v->pLe
13840 61 66 53 65 6c 65 63 74 53 74 6d 74 73 5b 69 5d  afSelectStmts[i]
13850 29 3b 0a 20 20 20 20 20 20 76 2d 3e 70 4c 65 61  );.      v->pLea
13860 66 53 65 6c 65 63 74 53 74 6d 74 73 5b 69 5d 20  fSelectStmts[i] 
13870 3d 20 4e 55 4c 4c 3b 0a 20 20 20 20 7d 0a 20 20  = NULL;.    }.  
13880 7d 0a 0a 20 20 69 66 28 20 76 2d 3e 70 54 6f 6b  }..  if( v->pTok
13890 65 6e 69 7a 65 72 21 3d 4e 55 4c 4c 20 29 7b 0a  enizer!=NULL ){.
138a0 20 20 20 20 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65      v->pTokenize
138b0 72 2d 3e 70 4d 6f 64 75 6c 65 2d 3e 78 44 65 73  r->pModule->xDes
138c0 74 72 6f 79 28 76 2d 3e 70 54 6f 6b 65 6e 69 7a  troy(v->pTokeniz
138d0 65 72 29 3b 0a 20 20 20 20 76 2d 3e 70 54 6f 6b  er);.    v->pTok
138e0 65 6e 69 7a 65 72 20 3d 20 4e 55 4c 4c 3b 0a 20  enizer = NULL;. 
138f0 20 7d 0a 0a 20 20 63 6c 65 61 72 50 65 6e 64 69   }..  clearPendi
13900 6e 67 54 65 72 6d 73 28 76 29 3b 0a 0a 20 20 73  ngTerms(v);..  s
13910 71 6c 69 74 65 33 5f 66 72 65 65 28 76 2d 3e 61  qlite3_free(v->a
13920 7a 43 6f 6c 75 6d 6e 29 3b 0a 20 20 66 6f 72 28  zColumn);.  for(
13930 69 20 3d 20 30 3b 20 69 20 3c 20 76 2d 3e 6e 43  i = 0; i < v->nC
13940 6f 6c 75 6d 6e 3b 20 2b 2b 69 29 20 7b 0a 20 20  olumn; ++i) {.  
13950 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 76    sqlite3_free(v
13960 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d  ->azContentColum
13970 6e 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 73 71 6c  n[i]);.  }.  sql
13980 69 74 65 33 5f 66 72 65 65 28 76 2d 3e 61 7a 43  ite3_free(v->azC
13990 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 29 3b 0a 20  ontentColumn);. 
139a0 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 76 29   sqlite3_free(v)
139b0 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e  ;.}../*.** Token
139c0 20 74 79 70 65 73 20 66 6f 72 20 70 61 72 73 69   types for parsi
139d0 6e 67 20 74 68 65 20 61 72 67 75 6d 65 6e 74 73  ng the arguments
139e0 20 74 6f 20 78 43 6f 6e 6e 65 63 74 20 6f 72 20   to xConnect or 
139f0 78 43 72 65 61 74 65 2e 0a 2a 2f 0a 23 64 65 66  xCreate..*/.#def
13a00 69 6e 65 20 54 4f 4b 45 4e 5f 45 4f 46 20 20 20  ine TOKEN_EOF   
13a10 20 20 20 20 20 20 30 20 20 20 20 2f 2a 20 45 6e        0    /* En
13a20 64 20 6f 66 20 66 69 6c 65 20 2a 2f 0a 23 64 65  d of file */.#de
13a30 66 69 6e 65 20 54 4f 4b 45 4e 5f 53 50 41 43 45  fine TOKEN_SPACE
13a40 20 20 20 20 20 20 20 31 20 20 20 20 2f 2a 20 41         1    /* A
13a50 6e 79 20 6b 69 6e 64 20 6f 66 20 77 68 69 74 65  ny kind of white
13a60 73 70 61 63 65 20 2a 2f 0a 23 64 65 66 69 6e 65  space */.#define
13a70 20 54 4f 4b 45 4e 5f 49 44 20 20 20 20 20 20 20   TOKEN_ID       
13a80 20 20 20 32 20 20 20 20 2f 2a 20 41 6e 20 69 64     2    /* An id
13a90 65 6e 74 69 66 69 65 72 20 2a 2f 0a 23 64 65 66  entifier */.#def
13aa0 69 6e 65 20 54 4f 4b 45 4e 5f 53 54 52 49 4e 47  ine TOKEN_STRING
13ab0 20 20 20 20 20 20 33 20 20 20 20 2f 2a 20 41 20        3    /* A 
13ac0 73 74 72 69 6e 67 20 6c 69 74 65 72 61 6c 20 2a  string literal *
13ad0 2f 0a 23 64 65 66 69 6e 65 20 54 4f 4b 45 4e 5f  /.#define TOKEN_
13ae0 50 55 4e 43 54 20 20 20 20 20 20 20 34 20 20 20  PUNCT       4   
13af0 20 2f 2a 20 41 20 73 69 6e 67 6c 65 20 70 75 6e   /* A single pun
13b00 63 74 75 61 74 69 6f 6e 20 63 68 61 72 61 63 74  ctuation charact
13b10 65 72 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 66 20  er */../*.** If 
13b20 58 20 69 73 20 61 20 63 68 61 72 61 63 74 65 72  X is a character
13b30 20 74 68 61 74 20 63 61 6e 20 62 65 20 75 73 65   that can be use
13b40 64 20 69 6e 20 61 6e 20 69 64 65 6e 74 69 66 69  d in an identifi
13b50 65 72 20 74 68 65 6e 0a 2a 2a 20 66 74 73 49 64  er then.** ftsId
13b60 43 68 61 72 28 58 29 20 77 69 6c 6c 20 62 65 20  Char(X) will be 
13b70 74 72 75 65 2e 20 20 4f 74 68 65 72 77 69 73 65  true.  Otherwise
13b80 20 69 74 20 69 73 20 66 61 6c 73 65 2e 0a 2a 2a   it is false..**
13b90 0a 2a 2a 20 46 6f 72 20 41 53 43 49 49 2c 20 61  .** For ASCII, a
13ba0 6e 79 20 63 68 61 72 61 63 74 65 72 20 77 69 74  ny character wit
13bb0 68 20 74 68 65 20 68 69 67 68 2d 6f 72 64 65 72  h the high-order
13bc0 20 62 69 74 20 73 65 74 20 69 73 0a 2a 2a 20 61   bit set is.** a
13bd0 6c 6c 6f 77 65 64 20 69 6e 20 61 6e 20 69 64 65  llowed in an ide
13be0 6e 74 69 66 69 65 72 2e 20 20 46 6f 72 20 37 2d  ntifier.  For 7-
13bf0 62 69 74 20 63 68 61 72 61 63 74 65 72 73 2c 20  bit characters, 
13c00 0a 2a 2a 20 69 73 46 74 73 49 64 43 68 61 72 5b  .** isFtsIdChar[
13c10 58 5d 20 6d 75 73 74 20 62 65 20 31 2e 0a 2a 2a  X] must be 1..**
13c20 0a 2a 2a 20 54 69 63 6b 65 74 20 23 31 30 36 36  .** Ticket #1066
13c30 2e 20 20 74 68 65 20 53 51 4c 20 73 74 61 6e 64  .  the SQL stand
13c40 61 72 64 20 64 6f 65 73 20 6e 6f 74 20 61 6c 6c  ard does not all
13c50 6f 77 20 27 24 27 20 69 6e 20 74 68 65 0a 2a 2a  ow '$' in the.**
13c60 20 6d 69 64 64 6c 65 20 6f 66 20 69 64 65 6e 74   middle of ident
13c70 66 69 65 72 73 2e 20 20 42 75 74 20 6d 61 6e 79  fiers.  But many
13c80 20 53 51 4c 20 69 6d 70 6c 65 6d 65 6e 74 61 74   SQL implementat
13c90 69 6f 6e 73 20 64 6f 2e 20 0a 2a 2a 20 53 51 4c  ions do. .** SQL
13ca0 69 74 65 20 77 69 6c 6c 20 61 6c 6c 6f 77 20 27  ite will allow '
13cb0 24 27 20 69 6e 20 69 64 65 6e 74 69 66 69 65 72  $' in identifier
13cc0 73 20 66 6f 72 20 63 6f 6d 70 61 74 69 62 69 6c  s for compatibil
13cd0 69 74 79 2e 0a 2a 2a 20 42 75 74 20 74 68 65 20  ity..** But the 
13ce0 66 65 61 74 75 72 65 20 69 73 20 75 6e 64 6f 63  feature is undoc
13cf0 75 6d 65 6e 74 65 64 2e 0a 2a 2f 0a 73 74 61 74  umented..*/.stat
13d00 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 69 73  ic const char is
13d10 46 74 73 49 64 43 68 61 72 5b 5d 20 3d 20 7b 0a  FtsIdChar[] = {.
13d20 2f 2a 20 78 30 20 78 31 20 78 32 20 78 33 20 78  /* x0 x1 x2 x3 x
13d30 34 20 78 35 20 78 36 20 78 37 20 78 38 20 78 39  4 x5 x6 x7 x8 x9
13d40 20 78 41 20 78 42 20 78 43 20 78 44 20 78 45 20   xA xB xC xD xE 
13d50 78 46 20 2a 2f 0a 20 20 20 20 30 2c 20 30 2c 20  xF */.    0, 0, 
13d60 30 2c 20 30 2c 20 31 2c 20 30 2c 20 30 2c 20 30  0, 0, 1, 0, 0, 0
13d70 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 0, 0, 0, 0, 0,
13d80 20 30 2c 20 30 2c 20 30 2c 20 20 2f 2a 20 32 78   0, 0, 0,  /* 2x
13d90 20 2a 2f 0a 20 20 20 20 31 2c 20 31 2c 20 31 2c   */.    1, 1, 1,
13da0 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
13db0 31 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30  1, 1, 0, 0, 0, 0
13dc0 2c 20 30 2c 20 30 2c 20 20 2f 2a 20 33 78 20 2a  , 0, 0,  /* 3x *
13dd0 2f 0a 20 20 20 20 30 2c 20 31 2c 20 31 2c 20 31  /.    0, 1, 1, 1
13de0 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
13df0 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
13e00 31 2c 20 31 2c 20 20 2f 2a 20 34 78 20 2a 2f 0a  1, 1,  /* 4x */.
13e10 20 20 20 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20      1, 1, 1, 1, 
13e20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
13e30 2c 20 31 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c  , 1, 0, 0, 0, 0,
13e40 20 31 2c 20 20 2f 2a 20 35 78 20 2a 2f 0a 20 20   1,  /* 5x */.  
13e50 20 20 30 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c    0, 1, 1, 1, 1,
13e60 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20   1, 1, 1, 1, 1, 
13e70 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
13e80 2c 20 20 2f 2a 20 36 78 20 2a 2f 0a 20 20 20 20  ,  /* 6x */.    
13e90 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31  1, 1, 1, 1, 1, 1
13ea0 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c 20 31 2c  , 1, 1, 1, 1, 1,
13eb0 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20   0, 0, 0, 0, 0, 
13ec0 20 2f 2a 20 37 78 20 2a 2f 0a 7d 3b 0a 23 64 65   /* 7x */.};.#de
13ed0 66 69 6e 65 20 66 74 73 49 64 43 68 61 72 28 43  fine ftsIdChar(C
13ee0 29 20 20 28 28 28 63 3d 43 29 26 30 78 38 30 29  )  (((c=C)&0x80)
13ef0 21 3d 30 20 7c 7c 20 28 63 3e 30 78 31 66 20 26  !=0 || (c>0x1f &
13f00 26 20 69 73 46 74 73 49 64 43 68 61 72 5b 63 2d  & isFtsIdChar[c-
13f10 30 78 32 30 5d 29 29 0a 0a 0a 2f 2a 0a 2a 2a 20  0x20])).../*.** 
13f20 52 65 74 75 72 6e 20 74 68 65 20 6c 65 6e 67 74  Return the lengt
13f30 68 20 6f 66 20 74 68 65 20 74 6f 6b 65 6e 20 74  h of the token t
13f40 68 61 74 20 62 65 67 69 6e 73 20 61 74 20 7a 5b  hat begins at z[
13f50 30 5d 2e 20 0a 2a 2a 20 53 74 6f 72 65 20 74 68  0]. .** Store th
13f60 65 20 74 6f 6b 65 6e 20 74 79 70 65 20 69 6e 20  e token type in 
13f70 2a 74 6f 6b 65 6e 54 79 70 65 20 62 65 66 6f 72  *tokenType befor
13f80 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a  e returning..*/.
13f90 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 47 65  static int ftsGe
13fa0 74 54 6f 6b 65 6e 28 63 6f 6e 73 74 20 63 68 61  tToken(const cha
13fb0 72 20 2a 7a 2c 20 69 6e 74 20 2a 74 6f 6b 65 6e  r *z, int *token
13fc0 54 79 70 65 29 7b 0a 20 20 69 6e 74 20 69 2c 20  Type){.  int i, 
13fd0 63 3b 0a 20 20 73 77 69 74 63 68 28 20 2a 7a 20  c;.  switch( *z 
13fe0 29 7b 0a 20 20 20 20 63 61 73 65 20 30 3a 20 7b  ){.    case 0: {
13ff0 0a 20 20 20 20 20 20 2a 74 6f 6b 65 6e 54 79 70  .      *tokenTyp
14000 65 20 3d 20 54 4f 4b 45 4e 5f 45 4f 46 3b 0a 20  e = TOKEN_EOF;. 
14010 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20       return 0;. 
14020 20 20 20 7d 0a 20 20 20 20 63 61 73 65 20 27 20     }.    case ' 
14030 27 3a 20 63 61 73 65 20 27 5c 74 27 3a 20 63 61  ': case '\t': ca
14040 73 65 20 27 5c 6e 27 3a 20 63 61 73 65 20 27 5c  se '\n': case '\
14050 66 27 3a 20 63 61 73 65 20 27 5c 72 27 3a 20 7b  f': case '\r': {
14060 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20  .      for(i=1; 
14070 73 61 66 65 5f 69 73 73 70 61 63 65 28 7a 5b 69  safe_isspace(z[i
14080 5d 29 3b 20 69 2b 2b 29 7b 7d 0a 20 20 20 20 20  ]); i++){}.     
14090 20 2a 74 6f 6b 65 6e 54 79 70 65 20 3d 20 54 4f   *tokenType = TO
140a0 4b 45 4e 5f 53 50 41 43 45 3b 0a 20 20 20 20 20  KEN_SPACE;.     
140b0 20 72 65 74 75 72 6e 20 69 3b 0a 20 20 20 20 7d   return i;.    }
140c0 0a 20 20 20 20 63 61 73 65 20 27 60 27 3a 0a 20  .    case '`':. 
140d0 20 20 20 63 61 73 65 20 27 5c 27 27 3a 0a 20 20     case '\'':.  
140e0 20 20 63 61 73 65 20 27 22 27 3a 20 7b 0a 20 20    case '"': {.  
140f0 20 20 20 20 69 6e 74 20 64 65 6c 69 6d 20 3d 20      int delim = 
14100 7a 5b 30 5d 3b 0a 20 20 20 20 20 20 66 6f 72 28  z[0];.      for(
14110 69 3d 31 3b 20 28 63 3d 7a 5b 69 5d 29 21 3d 30  i=1; (c=z[i])!=0
14120 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
14130 69 66 28 20 63 3d 3d 64 65 6c 69 6d 20 29 7b 0a  if( c==delim ){.
14140 20 20 20 20 20 20 20 20 20 20 69 66 28 20 7a 5b            if( z[
14150 69 2b 31 5d 3d 3d 64 65 6c 69 6d 20 29 7b 0a 20  i+1]==delim ){. 
14160 20 20 20 20 20 20 20 20 20 20 20 69 2b 2b 3b 0a             i++;.
14170 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b            }else{
14180 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65  .            bre
14190 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  ak;.          }.
141a0 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
141b0 7d 0a 20 20 20 20 20 20 2a 74 6f 6b 65 6e 54 79  }.      *tokenTy
141c0 70 65 20 3d 20 54 4f 4b 45 4e 5f 53 54 52 49 4e  pe = TOKEN_STRIN
141d0 47 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  G;.      return 
141e0 69 20 2b 20 28 63 21 3d 30 29 3b 0a 20 20 20 20  i + (c!=0);.    
141f0 7d 0a 20 20 20 20 63 61 73 65 20 27 5b 27 3a 20  }.    case '[': 
14200 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 31 2c  {.      for(i=1,
14210 20 63 3d 7a 5b 30 5d 3b 20 63 21 3d 27 5d 27 20   c=z[0]; c!=']' 
14220 26 26 20 28 63 3d 7a 5b 69 5d 29 21 3d 30 3b 20  && (c=z[i])!=0; 
14230 69 2b 2b 29 7b 7d 0a 20 20 20 20 20 20 2a 74 6f  i++){}.      *to
14240 6b 65 6e 54 79 70 65 20 3d 20 54 4f 4b 45 4e 5f  kenType = TOKEN_
14250 49 44 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e  ID;.      return
14260 20 69 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64 65   i;.    }.    de
14270 66 61 75 6c 74 3a 20 7b 0a 20 20 20 20 20 20 69  fault: {.      i
14280 66 28 20 21 66 74 73 49 64 43 68 61 72 28 2a 7a  f( !ftsIdChar(*z
14290 29 20 29 7b 0a 20 20 20 20 20 20 20 20 62 72 65  ) ){.        bre
142a0 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
142b0 20 20 66 6f 72 28 69 3d 31 3b 20 66 74 73 49 64    for(i=1; ftsId
142c0 43 68 61 72 28 7a 5b 69 5d 29 3b 20 69 2b 2b 29  Char(z[i]); i++)
142d0 7b 7d 0a 20 20 20 20 20 20 2a 74 6f 6b 65 6e 54  {}.      *tokenT
142e0 79 70 65 20 3d 20 54 4f 4b 45 4e 5f 49 44 3b 0a  ype = TOKEN_ID;.
142f0 20 20 20 20 20 20 72 65 74 75 72 6e 20 69 3b 0a        return i;.
14300 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 74 6f 6b      }.  }.  *tok
14310 65 6e 54 79 70 65 20 3d 20 54 4f 4b 45 4e 5f 50  enType = TOKEN_P
14320 55 4e 43 54 3b 0a 20 20 72 65 74 75 72 6e 20 31  UNCT;.  return 1
14330 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 20 74 6f 6b  ;.}../*.** A tok
14340 65 6e 20 65 78 74 72 61 63 74 65 64 20 66 72 6f  en extracted fro
14350 6d 20 61 20 73 74 72 69 6e 67 20 69 73 20 61 6e  m a string is an
14360 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65   instance of the
14370 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 73 74   following.** st
14380 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 74 79 70 65  ructure..*/.type
14390 64 65 66 20 73 74 72 75 63 74 20 46 74 73 54 6f  def struct FtsTo
143a0 6b 65 6e 20 7b 0a 20 20 63 6f 6e 73 74 20 63 68  ken {.  const ch
143b0 61 72 20 2a 7a 3b 20 20 20 20 20 20 20 2f 2a 20  ar *z;       /* 
143c0 50 6f 69 6e 74 65 72 20 74 6f 20 74 6f 6b 65 6e  Pointer to token
143d0 20 74 65 78 74 2e 20 20 4e 6f 74 20 27 5c 30 30   text.  Not '\00
143e0 30 27 20 74 65 72 6d 69 6e 61 74 65 64 20 2a 2f  0' terminated */
143f0 0a 20 20 73 68 6f 72 74 20 69 6e 74 20 6e 3b 20  .  short int n; 
14400 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74          /* Lengt
14410 68 20 6f 66 20 74 68 65 20 74 6f 6b 65 6e 20 74  h of the token t
14420 65 78 74 20 69 6e 20 62 79 74 65 73 2e 20 2a 2f  ext in bytes. */
14430 0a 7d 20 46 74 73 54 6f 6b 65 6e 3b 0a 0a 2f 2a  .} FtsToken;../*
14440 0a 2a 2a 20 47 69 76 65 6e 20 61 20 69 6e 70 75  .** Given a inpu
14450 74 20 73 74 72 69 6e 67 20 28 77 68 69 63 68 20  t string (which 
14460 69 73 20 72 65 61 6c 6c 79 20 6f 6e 65 20 6f 66  is really one of
14470 20 74 68 65 20 61 72 67 76 5b 5d 20 70 61 72 61   the argv[] para
14480 6d 65 74 65 72 73 0a 2a 2a 20 70 61 73 73 65 64  meters.** passed
14490 20 69 6e 74 6f 20 78 43 6f 6e 6e 65 63 74 20 6f   into xConnect o
144a0 72 20 78 43 72 65 61 74 65 29 20 73 70 6c 69 74  r xCreate) split
144b0 20 74 68 65 20 73 74 72 69 6e 67 20 75 70 20 69   the string up i
144c0 6e 74 6f 20 74 6f 6b 65 6e 73 2e 0a 2a 2a 20 52  nto tokens..** R
144d0 65 74 75 72 6e 20 61 6e 20 61 72 72 61 79 20 6f  eturn an array o
144e0 66 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 27 5c  f pointers to '\
144f0 30 30 30 27 20 74 65 72 6d 69 6e 61 74 65 64 20  000' terminated 
14500 73 74 72 69 6e 67 73 2c 20 6f 6e 65 20 73 74 72  strings, one str
14510 69 6e 67 0a 2a 2a 20 66 6f 72 20 65 61 63 68 20  ing.** for each 
14520 6e 6f 6e 2d 77 68 69 74 65 73 70 61 63 65 20 74  non-whitespace t
14530 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  oken..**.** The 
14540 72 65 74 75 72 6e 65 64 20 61 72 72 61 79 20 69  returned array i
14550 73 20 74 65 72 6d 69 6e 61 74 65 64 20 62 79 20  s terminated by 
14560 61 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 70 6f  a single NULL po
14570 69 6e 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 53 70 61  inter..**.** Spa
14580 63 65 20 74 6f 20 68 6f 6c 64 20 74 68 65 20 72  ce to hold the r
14590 65 74 75 72 6e 65 64 20 61 72 72 61 79 20 69 73  eturned array is
145a0 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d 20 61   obtained from a
145b0 20 73 69 6e 67 6c 65 0a 2a 2a 20 6d 61 6c 6c 6f   single.** mallo
145c0 63 20 61 6e 64 20 73 68 6f 75 6c 64 20 62 65 20  c and should be 
145d0 66 72 65 65 64 20 62 79 20 70 61 73 73 69 6e 67  freed by passing
145e0 20 74 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75   the return valu
145f0 65 20 74 6f 20 66 72 65 65 28 29 2e 0a 2a 2a 20  e to free()..** 
14600 54 68 65 20 69 6e 64 69 76 69 64 75 61 6c 20 73  The individual s
14610 74 72 69 6e 67 73 20 77 69 74 68 69 6e 20 74 68  trings within th
14620 65 20 74 6f 6b 65 6e 20 6c 69 73 74 20 61 72 65  e token list are
14630 20 61 6c 6c 20 61 20 70 61 72 74 20 6f 66 0a 2a   all a part of.*
14640 2a 20 74 68 65 20 73 69 6e 67 6c 65 20 6d 65 6d  * the single mem
14650 6f 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 61  ory allocation a
14660 6e 64 20 77 69 6c 6c 20 61 6c 6c 20 62 65 20 66  nd will all be f
14670 72 65 65 64 20 61 74 20 6f 6e 63 65 2e 0a 2a 2f  reed at once..*/
14680 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 2a 74  .static char **t
14690 6f 6b 65 6e 69 7a 65 53 74 72 69 6e 67 28 63 6f  okenizeString(co
146a0 6e 73 74 20 63 68 61 72 20 2a 7a 2c 20 69 6e 74  nst char *z, int
146b0 20 2a 70 6e 54 6f 6b 65 6e 29 7b 0a 20 20 69 6e   *pnToken){.  in
146c0 74 20 6e 54 6f 6b 65 6e 20 3d 20 30 3b 0a 20 20  t nToken = 0;.  
146d0 46 74 73 54 6f 6b 65 6e 20 2a 61 54 6f 6b 65 6e  FtsToken *aToken
146e0 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   = sqlite3_mallo
146f0 63 28 20 73 74 72 6c 65 6e 28 7a 29 20 2a 20 73  c( strlen(z) * s
14700 69 7a 65 6f 66 28 61 54 6f 6b 65 6e 5b 30 5d 29  izeof(aToken[0])
14710 20 29 3b 0a 20 20 69 6e 74 20 6e 20 3d 20 31 3b   );.  int n = 1;
14720 0a 20 20 69 6e 74 20 65 2c 20 69 3b 0a 20 20 69  .  int e, i;.  i
14730 6e 74 20 74 6f 74 61 6c 53 69 7a 65 20 3d 20 30  nt totalSize = 0
14740 3b 0a 20 20 63 68 61 72 20 2a 2a 61 7a 54 6f 6b  ;.  char **azTok
14750 65 6e 3b 0a 20 20 63 68 61 72 20 2a 7a 43 6f 70  en;.  char *zCop
14760 79 3b 0a 20 20 77 68 69 6c 65 28 20 6e 3e 30 20  y;.  while( n>0 
14770 29 7b 0a 20 20 20 20 6e 20 3d 20 66 74 73 47 65  ){.    n = ftsGe
14780 74 54 6f 6b 65 6e 28 7a 2c 20 26 65 29 3b 0a 20  tToken(z, &e);. 
14790 20 20 20 69 66 28 20 65 21 3d 54 4f 4b 45 4e 5f     if( e!=TOKEN_
147a0 53 50 41 43 45 20 29 7b 0a 20 20 20 20 20 20 61  SPACE ){.      a
147b0 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 5d 2e 7a 20  Token[nToken].z 
147c0 3d 20 7a 3b 0a 20 20 20 20 20 20 61 54 6f 6b 65  = z;.      aToke
147d0 6e 5b 6e 54 6f 6b 65 6e 5d 2e 6e 20 3d 20 6e 3b  n[nToken].n = n;
147e0 0a 20 20 20 20 20 20 6e 54 6f 6b 65 6e 2b 2b 3b  .      nToken++;
147f0 0a 20 20 20 20 20 20 74 6f 74 61 6c 53 69 7a 65  .      totalSize
14800 20 2b 3d 20 6e 2b 31 3b 0a 20 20 20 20 7d 0a 20   += n+1;.    }. 
14810 20 20 20 7a 20 2b 3d 20 6e 3b 0a 20 20 7d 0a 20     z += n;.  }. 
14820 20 61 7a 54 6f 6b 65 6e 20 3d 20 28 63 68 61 72   azToken = (char
14830 2a 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  **)sqlite3_mallo
14840 63 28 20 6e 54 6f 6b 65 6e 2a 73 69 7a 65 6f 66  c( nToken*sizeof
14850 28 63 68 61 72 2a 29 20 2b 20 74 6f 74 61 6c 53  (char*) + totalS
14860 69 7a 65 20 29 3b 0a 20 20 7a 43 6f 70 79 20 3d  ize );.  zCopy =
14870 20 28 63 68 61 72 2a 29 26 61 7a 54 6f 6b 65 6e   (char*)&azToken
14880 5b 6e 54 6f 6b 65 6e 5d 3b 0a 20 20 6e 54 6f 6b  [nToken];.  nTok
14890 65 6e 2d 2d 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  en--;.  for(i=0;
148a0 20 69 3c 6e 54 6f 6b 65 6e 3b 20 69 2b 2b 29 7b   i<nToken; i++){
148b0 0a 20 20 20 20 61 7a 54 6f 6b 65 6e 5b 69 5d 20  .    azToken[i] 
148c0 3d 20 7a 43 6f 70 79 3b 0a 20 20 20 20 6e 20 3d  = zCopy;.    n =
148d0 20 61 54 6f 6b 65 6e 5b 69 5d 2e 6e 3b 0a 20 20   aToken[i].n;.  
148e0 20 20 6d 65 6d 63 70 79 28 7a 43 6f 70 79 2c 20    memcpy(zCopy, 
148f0 61 54 6f 6b 65 6e 5b 69 5d 2e 7a 2c 20 6e 29 3b  aToken[i].z, n);
14900 0a 20 20 20 20 7a 43 6f 70 79 5b 6e 5d 20 3d 20  .    zCopy[n] = 
14910 30 3b 0a 20 20 20 20 7a 43 6f 70 79 20 2b 3d 20  0;.    zCopy += 
14920 6e 2b 31 3b 0a 20 20 7d 0a 20 20 61 7a 54 6f 6b  n+1;.  }.  azTok
14930 65 6e 5b 6e 54 6f 6b 65 6e 5d 20 3d 20 30 3b 0a  en[nToken] = 0;.
14940 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61    sqlite3_free(a
14950 54 6f 6b 65 6e 29 3b 0a 20 20 2a 70 6e 54 6f 6b  Token);.  *pnTok
14960 65 6e 20 3d 20 6e 54 6f 6b 65 6e 3b 0a 20 20 72  en = nToken;.  r
14970 65 74 75 72 6e 20 61 7a 54 6f 6b 65 6e 3b 0a 7d  eturn azToken;.}
14980 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 76 65 72 74 20  ../*.** Convert 
14990 61 6e 20 53 51 4c 2d 73 74 79 6c 65 20 71 75 6f  an SQL-style quo
149a0 74 65 64 20 73 74 72 69 6e 67 20 69 6e 74 6f 20  ted string into 
149b0 61 20 6e 6f 72 6d 61 6c 20 73 74 72 69 6e 67 20  a normal string 
149c0 62 79 20 72 65 6d 6f 76 69 6e 67 0a 2a 2a 20 74  by removing.** t
149d0 68 65 20 71 75 6f 74 65 20 63 68 61 72 61 63 74  he quote charact
149e0 65 72 73 2e 20 20 54 68 65 20 63 6f 6e 76 65 72  ers.  The conver
149f0 73 69 6f 6e 20 69 73 20 64 6f 6e 65 20 69 6e 2d  sion is done in-
14a00 70 6c 61 63 65 2e 20 20 49 66 20 74 68 65 0a 2a  place.  If the.*
14a10 2a 20 69 6e 70 75 74 20 64 6f 65 73 20 6e 6f 74  * input does not
14a20 20 62 65 67 69 6e 20 77 69 74 68 20 61 20 71 75   begin with a qu
14a30 6f 74 65 20 63 68 61 72 61 63 74 65 72 2c 20 74  ote character, t
14a40 68 65 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65  hen this routine
14a50 0a 2a 2a 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a  .** is a no-op..
14a60 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 73 3a 0a  **.** Examples:.
14a70 2a 2a 0a 2a 2a 20 20 20 20 20 22 61 62 63 22 20  **.**     "abc" 
14a80 20 20 62 65 63 6f 6d 65 73 20 20 20 61 62 63 0a    becomes   abc.
14a90 2a 2a 20 20 20 20 20 27 78 79 7a 27 20 20 20 62  **     'xyz'   b
14aa0 65 63 6f 6d 65 73 20 20 20 78 79 7a 0a 2a 2a 20  ecomes   xyz.** 
14ab0 20 20 20 20 5b 70 71 72 5d 20 20 20 62 65 63 6f      [pqr]   beco
14ac0 6d 65 73 20 20 20 70 71 72 0a 2a 2a 20 20 20 20  mes   pqr.**    
14ad0 20 60 6d 6e 6f 60 20 20 20 62 65 63 6f 6d 65 73   `mno`   becomes
14ae0 20 20 20 6d 6e 6f 0a 2a 2f 0a 73 74 61 74 69 63     mno.*/.static
14af0 20 76 6f 69 64 20 64 65 71 75 6f 74 65 53 74 72   void dequoteStr
14b00 69 6e 67 28 63 68 61 72 20 2a 7a 29 7b 0a 20 20  ing(char *z){.  
14b10 69 6e 74 20 71 75 6f 74 65 3b 0a 20 20 69 6e 74  int quote;.  int
14b20 20 69 2c 20 6a 3b 0a 20 20 69 66 28 20 7a 3d 3d   i, j;.  if( z==
14b30 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 71 75  0 ) return;.  qu
14b40 6f 74 65 20 3d 20 7a 5b 30 5d 3b 0a 20 20 73 77  ote = z[0];.  sw
14b50 69 74 63 68 28 20 71 75 6f 74 65 20 29 7b 0a 20  itch( quote ){. 
14b60 20 20 20 63 61 73 65 20 27 5c 27 27 3a 20 20 62     case '\'':  b
14b70 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 27  reak;.    case '
14b80 22 27 3a 20 20 20 62 72 65 61 6b 3b 0a 20 20 20  "':   break;.   
14b90 20 63 61 73 65 20 27 60 27 3a 20 20 20 62 72 65   case '`':   bre
14ba0 61 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ak;             
14bb0 20 20 20 2f 2a 20 46 6f 72 20 4d 79 53 51 4c 20     /* For MySQL 
14bc0 63 6f 6d 70 61 74 69 62 69 6c 69 74 79 20 2a 2f  compatibility */
14bd0 0a 20 20 20 20 63 61 73 65 20 27 5b 27 3a 20 20  .    case '[':  
14be0 20 71 75 6f 74 65 20 3d 20 27 5d 27 3b 20 20 62   quote = ']';  b
14bf0 72 65 61 6b 3b 20 20 2f 2a 20 46 6f 72 20 4d 53  reak;  /* For MS
14c00 20 53 71 6c 53 65 72 76 65 72 20 63 6f 6d 70 61   SqlServer compa
14c10 74 69 62 69 6c 69 74 79 20 2a 2f 0a 20 20 20 20  tibility */.    
14c20 64 65 66 61 75 6c 74 3a 20 20 20 20 72 65 74 75  default:    retu
14c30 72 6e 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d  rn;.  }.  for(i=
14c40 31 2c 20 6a 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b  1, j=0; z[i]; i+
14c50 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d  +){.    if( z[i]
14c60 3d 3d 71 75 6f 74 65 20 29 7b 0a 20 20 20 20 20  ==quote ){.     
14c70 20 69 66 28 20 7a 5b 69 2b 31 5d 3d 3d 71 75 6f   if( z[i+1]==quo
14c80 74 65 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 5b  te ){.        z[
14c90 6a 2b 2b 5d 20 3d 20 71 75 6f 74 65 3b 0a 20 20  j++] = quote;.  
14ca0 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20 20        i++;.     
14cb0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
14cc0 7a 5b 6a 2b 2b 5d 20 3d 20 30 3b 0a 20 20 20 20  z[j++] = 0;.    
14cd0 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
14ce0 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20   }.    }else{.  
14cf0 20 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69      z[j++] = z[i
14d00 5d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a  ];.    }.  }.}..
14d10 2f 2a 0a 2a 2a 20 54 68 65 20 69 6e 70 75 74 20  /*.** The input 
14d20 61 7a 49 6e 20 69 73 20 61 20 4e 55 4c 4c 2d 74  azIn is a NULL-t
14d30 65 72 6d 69 6e 61 74 65 64 20 6c 69 73 74 20 6f  erminated list o
14d40 66 20 74 6f 6b 65 6e 73 2e 20 20 52 65 6d 6f 76  f tokens.  Remov
14d50 65 20 74 68 65 20 66 69 72 73 74 0a 2a 2a 20 74  e the first.** t
14d60 6f 6b 65 6e 20 61 6e 64 20 61 6c 6c 20 70 75 6e  oken and all pun
14d70 63 74 75 61 74 69 6f 6e 20 74 6f 6b 65 6e 73 2e  ctuation tokens.
14d80 20 20 52 65 6d 6f 76 65 20 74 68 65 20 71 75 6f    Remove the quo
14d90 74 65 73 20 66 72 6f 6d 0a 2a 2a 20 61 72 6f 75  tes from.** arou
14da0 6e 64 20 73 74 72 69 6e 67 20 6c 69 74 65 72 61  nd string litera
14db0 6c 20 74 6f 6b 65 6e 73 2e 0a 2a 2a 0a 2a 2a 20  l tokens..**.** 
14dc0 45 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20  Example:.**.**  
14dd0 20 20 20 69 6e 70 75 74 3a 20 20 20 20 20 20 74     input:      t
14de0 6f 6b 65 6e 69 7a 65 20 63 68 69 6e 65 73 65 20  okenize chinese 
14df0 28 20 27 73 69 6d 70 6c 69 66 65 64 27 20 2c 20  ( 'simplifed' , 
14e00 27 6d 69 78 65 64 27 20 29 0a 2a 2a 20 20 20 20  'mixed' ).**    
14e10 20 6f 75 74 70 75 74 3a 20 20 20 20 20 63 68 69   output:     chi
14e20 6e 65 73 65 20 73 69 6d 70 6c 69 66 65 64 20 6d  nese simplifed m
14e30 69 78 65 64 0a 2a 2a 0a 2a 2a 20 41 6e 6f 74 68  ixed.**.** Anoth
14e40 65 72 20 65 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a  er example:.**.*
14e50 2a 20 20 20 20 20 69 6e 70 75 74 3a 20 20 20 20  *     input:    
14e60 20 20 64 65 6c 69 6d 69 74 65 72 73 20 28 20 27    delimiters ( '
14e70 5b 27 20 2c 20 27 5d 27 20 2c 20 27 2e 2e 2e 27  [' , ']' , '...'
14e80 20 29 0a 2a 2a 20 20 20 20 20 6f 75 74 70 75 74   ).**     output
14e90 3a 20 20 20 20 20 5b 20 5d 20 2e 2e 2e 0a 2a 2f  :     [ ] ....*/
14ea0 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 6f 6b  .static void tok
14eb0 65 6e 4c 69 73 74 54 6f 49 64 4c 69 73 74 28 63  enListToIdList(c
14ec0 68 61 72 20 2a 2a 61 7a 49 6e 29 7b 0a 20 20 69  har **azIn){.  i
14ed0 6e 74 20 69 2c 20 6a 3b 0a 20 20 69 66 28 20 61  nt i, j;.  if( a
14ee0 7a 49 6e 20 29 7b 0a 20 20 20 20 66 6f 72 28 69  zIn ){.    for(i
14ef0 3d 30 2c 20 6a 3d 2d 31 3b 20 61 7a 49 6e 5b 69  =0, j=-1; azIn[i
14f00 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69  ]; i++){.      i
14f10 66 28 20 73 61 66 65 5f 69 73 61 6c 6e 75 6d 28  f( safe_isalnum(
14f20 61 7a 49 6e 5b 69 5d 5b 30 5d 29 20 7c 7c 20 61  azIn[i][0]) || a
14f30 7a 49 6e 5b 69 5d 5b 31 5d 20 29 7b 0a 20 20 20  zIn[i][1] ){.   
14f40 20 20 20 20 20 64 65 71 75 6f 74 65 53 74 72 69       dequoteStri
14f50 6e 67 28 61 7a 49 6e 5b 69 5d 29 3b 0a 20 20 20  ng(azIn[i]);.   
14f60 20 20 20 20 20 69 66 28 20 6a 3e 3d 30 20 29 7b       if( j>=0 ){
14f70 0a 20 20 20 20 20 20 20 20 20 20 61 7a 49 6e 5b  .          azIn[
14f80 6a 5d 20 3d 20 61 7a 49 6e 5b 69 5d 3b 0a 20 20  j] = azIn[i];.  
14f90 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
14fa0 6a 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  j++;.      }.   
14fb0 20 7d 0a 20 20 20 20 61 7a 49 6e 5b 6a 5d 20 3d   }.    azIn[j] =
14fc0 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a   0;.  }.}.../*.*
14fd0 2a 20 46 69 6e 64 20 74 68 65 20 66 69 72 73 74  * Find the first
14fe0 20 61 6c 70 68 61 6e 75 6d 65 72 69 63 20 74 6f   alphanumeric to
14ff0 6b 65 6e 20 69 6e 20 74 68 65 20 73 74 72 69 6e  ken in the strin
15000 67 20 7a 49 6e 2e 20 20 4e 75 6c 6c 2d 74 65 72  g zIn.  Null-ter
15010 6d 69 6e 61 74 65 0a 2a 2a 20 74 68 69 73 20 74  minate.** this t
15020 6f 6b 65 6e 2e 20 20 52 65 6d 6f 76 65 20 61 6e  oken.  Remove an
15030 79 20 71 75 6f 74 61 74 69 6f 6e 20 6d 61 72 6b  y quotation mark
15040 73 2e 20 20 41 6e 64 20 72 65 74 75 72 6e 20 61  s.  And return a
15050 20 70 6f 69 6e 74 65 72 20 74 6f 0a 2a 2a 20 74   pointer to.** t
15060 68 65 20 72 65 73 75 6c 74 2e 0a 2a 2f 0a 73 74  he result..*/.st
15070 61 74 69 63 20 63 68 61 72 20 2a 66 69 72 73 74  atic char *first
15080 54 6f 6b 65 6e 28 63 68 61 72 20 2a 7a 49 6e 2c  Token(char *zIn,
15090 20 63 68 61 72 20 2a 2a 70 7a 54 61 69 6c 29 7b   char **pzTail){
150a0 0a 20 20 69 6e 74 20 6e 2c 20 74 74 79 70 65 3b  .  int n, ttype;
150b0 0a 20 20 77 68 69 6c 65 28 31 29 7b 0a 20 20 20  .  while(1){.   
150c0 20 6e 20 3d 20 66 74 73 47 65 74 54 6f 6b 65 6e   n = ftsGetToken
150d0 28 7a 49 6e 2c 20 26 74 74 79 70 65 29 3b 0a 20  (zIn, &ttype);. 
150e0 20 20 20 69 66 28 20 74 74 79 70 65 3d 3d 54 4f     if( ttype==TO
150f0 4b 45 4e 5f 53 50 41 43 45 20 29 7b 0a 20 20 20  KEN_SPACE ){.   
15100 20 20 20 7a 49 6e 20 2b 3d 20 6e 3b 0a 20 20 20     zIn += n;.   
15110 20 7d 65 6c 73 65 20 69 66 28 20 74 74 79 70 65   }else if( ttype
15120 3d 3d 54 4f 4b 45 4e 5f 45 4f 46 20 29 7b 0a 20  ==TOKEN_EOF ){. 
15130 20 20 20 20 20 2a 70 7a 54 61 69 6c 20 3d 20 7a       *pzTail = z
15140 49 6e 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e  In;.      return
15150 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   0;.    }else{. 
15160 20 20 20 20 20 7a 49 6e 5b 6e 5d 20 3d 20 30 3b       zIn[n] = 0;
15170 0a 20 20 20 20 20 20 2a 70 7a 54 61 69 6c 20 3d  .      *pzTail =
15180 20 26 7a 49 6e 5b 31 5d 3b 0a 20 20 20 20 20 20   &zIn[1];.      
15190 64 65 71 75 6f 74 65 53 74 72 69 6e 67 28 7a 49  dequoteString(zI
151a0 6e 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e  n);.      return
151b0 20 7a 49 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   zIn;.    }.  }.
151c0 20 20 2f 2a 4e 4f 54 52 45 41 43 48 45 44 2a 2f    /*NOTREACHED*/
151d0 0a 7d 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 74 72  .}../* Return tr
151e0 75 65 20 69 66 2e 2e 2e 0a 2a 2a 0a 2a 2a 20 20  ue if....**.**  
151f0 20 2a 20 20 73 20 62 65 67 69 6e 73 20 77 69 74   *  s begins wit
15200 68 20 74 68 65 20 73 74 72 69 6e 67 20 74 2c 20  h the string t, 
15210 69 67 6e 6f 72 69 6e 67 20 63 61 73 65 0a 2a 2a  ignoring case.**
15220 20 20 20 2a 20 20 73 20 69 73 20 6c 6f 6e 67 65     *  s is longe
15230 72 20 74 68 61 6e 20 74 0a 2a 2a 20 20 20 2a 20  r than t.**   * 
15240 20 54 68 65 20 66 69 72 73 74 20 63 68 61 72 61   The first chara
15250 63 74 65 72 20 6f 66 20 73 20 62 65 79 6f 6e 64  cter of s beyond
15260 20 74 20 69 73 20 6e 6f 74 20 61 20 61 6c 70 68   t is not a alph
15270 61 6e 75 6d 65 72 69 63 0a 2a 2a 20 0a 2a 2a 20  anumeric.** .** 
15280 49 67 6e 6f 72 65 20 6c 65 61 64 69 6e 67 20 73  Ignore leading s
15290 70 61 63 65 20 69 6e 20 2a 73 2e 0a 2a 2a 0a 2a  pace in *s..**.*
152a0 2a 20 54 6f 20 70 75 74 20 69 74 20 61 6e 6f 74  * To put it anot
152b0 68 65 72 20 77 61 79 2c 20 72 65 74 75 72 6e 20  her way, return 
152c0 74 72 75 65 20 69 66 20 74 68 65 20 66 69 72 73  true if the firs
152d0 74 20 74 6f 6b 65 6e 20 6f 66 0a 2a 2a 20 73 5b  t token of.** s[
152e0 5d 20 69 73 20 74 5b 5d 2e 0a 2a 2f 0a 73 74 61  ] is t[]..*/.sta
152f0 74 69 63 20 69 6e 74 20 73 74 61 72 74 73 57 69  tic int startsWi
15300 74 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 73  th(const char *s
15310 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 29  , const char *t)
15320 7b 0a 20 20 77 68 69 6c 65 28 20 73 61 66 65 5f  {.  while( safe_
15330 69 73 73 70 61 63 65 28 2a 73 29 20 29 7b 20 73  isspace(*s) ){ s
15340 2b 2b 3b 20 7d 0a 20 20 77 68 69 6c 65 28 20 2a  ++; }.  while( *
15350 74 20 29 7b 0a 20 20 20 20 69 66 28 20 73 61 66  t ){.    if( saf
15360 65 5f 74 6f 6c 6f 77 65 72 28 2a 73 2b 2b 29 21  e_tolower(*s++)!
15370 3d 73 61 66 65 5f 74 6f 6c 6f 77 65 72 28 2a 74  =safe_tolower(*t
15380 2b 2b 29 20 29 20 72 65 74 75 72 6e 20 30 3b 0a  ++) ) return 0;.
15390 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 2a 73 21    }.  return *s!
153a0 3d 27 5f 27 20 26 26 20 21 73 61 66 65 5f 69 73  ='_' && !safe_is
153b0 61 6c 6e 75 6d 28 2a 73 29 3b 0a 7d 0a 0a 2f 2a  alnum(*s);.}../*
153c0 0a 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20  .** An instance 
153d0 6f 66 20 74 68 69 73 20 73 74 72 75 63 74 75 72  of this structur
153e0 65 20 64 65 66 69 6e 65 73 20 74 68 65 20 22 73  e defines the "s
153f0 70 65 63 22 20 6f 66 20 61 0a 2a 2a 20 66 75 6c  pec" of a.** ful
15400 6c 20 74 65 78 74 20 69 6e 64 65 78 2e 20 20 54  l text index.  T
15410 68 69 73 20 73 74 72 75 63 74 75 72 65 20 69 73  his structure is
15420 20 70 6f 70 75 6c 61 74 65 64 20 62 79 20 70 61   populated by pa
15430 72 73 65 53 70 65 63 0a 2a 2a 20 61 6e 64 20 75  rseSpec.** and u
15440 73 65 20 62 79 20 66 75 6c 6c 74 65 78 74 43 6f  se by fulltextCo
15450 6e 6e 65 63 74 20 61 6e 64 20 66 75 6c 6c 74 65  nnect and fullte
15460 78 74 43 72 65 61 74 65 2e 0a 2a 2f 0a 74 79 70  xtCreate..*/.typ
15470 65 64 65 66 20 73 74 72 75 63 74 20 54 61 62 6c  edef struct Tabl
15480 65 53 70 65 63 20 7b 0a 20 20 63 6f 6e 73 74 20  eSpec {.  const 
15490 63 68 61 72 20 2a 7a 44 62 3b 20 20 20 20 20 20  char *zDb;      
154a0 20 20 20 2f 2a 20 4c 6f 67 69 63 61 6c 20 64 61     /* Logical da
154b0 74 61 62 61 73 65 20 6e 61 6d 65 20 2a 2f 0a 20  tabase name */. 
154c0 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
154d0 6d 65 3b 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d  me;       /* Nam
154e0 65 20 6f 66 20 74 68 65 20 66 75 6c 6c 2d 74 65  e of the full-te
154f0 78 74 20 69 6e 64 65 78 20 2a 2f 0a 20 20 69 6e  xt index */.  in
15500 74 20 6e 43 6f 6c 75 6d 6e 3b 20 20 20 20 20 20  t nColumn;      
15510 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
15520 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 74 6f 20 62   of columns to b
15530 65 20 69 6e 64 65 78 65 64 20 2a 2f 0a 20 20 63  e indexed */.  c
15540 68 61 72 20 2a 2a 61 7a 43 6f 6c 75 6d 6e 3b 20  har **azColumn; 
15550 20 20 20 20 20 20 20 20 2f 2a 20 4f 72 69 67 69          /* Origi
15560 6e 61 6c 20 6e 61 6d 65 73 20 6f 66 20 63 6f 6c  nal names of col
15570 75 6d 6e 73 20 74 6f 20 62 65 20 69 6e 64 65 78  umns to be index
15580 65 64 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61  ed */.  char **a
15590 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 3b 20  zContentColumn; 
155a0 20 2f 2a 20 43 6f 6c 75 6d 6e 20 6e 61 6d 65 73   /* Column names
155b0 20 66 6f 72 20 25 5f 63 6f 6e 74 65 6e 74 20 2a   for %_content *
155c0 2f 0a 20 20 63 68 61 72 20 2a 2a 61 7a 54 6f 6b  /.  char **azTok
155d0 65 6e 69 7a 65 72 3b 20 20 20 20 20 20 2f 2a 20  enizer;      /* 
155e0 4e 61 6d 65 20 6f 66 20 74 6f 6b 65 6e 69 7a 65  Name of tokenize
155f0 72 20 61 6e 64 20 69 74 73 20 61 72 67 75 6d 65  r and its argume
15600 6e 74 73 20 2a 2f 0a 7d 20 54 61 62 6c 65 53 70  nts */.} TableSp
15610 65 63 3b 0a 0a 2f 2a 0a 2a 2a 20 52 65 63 6c 61  ec;../*.** Recla
15620 69 6d 20 61 6c 6c 20 6f 66 20 74 68 65 20 6d 65  im all of the me
15630 6d 6f 72 79 20 75 73 65 64 20 62 79 20 61 20 54  mory used by a T
15640 61 62 6c 65 53 70 65 63 0a 2a 2f 0a 73 74 61 74  ableSpec.*/.stat
15650 69 63 20 76 6f 69 64 20 63 6c 65 61 72 54 61 62  ic void clearTab
15660 6c 65 53 70 65 63 28 54 61 62 6c 65 53 70 65 63  leSpec(TableSpec
15670 20 2a 70 29 20 7b 0a 20 20 73 71 6c 69 74 65 33   *p) {.  sqlite3
15680 5f 66 72 65 65 28 70 2d 3e 61 7a 43 6f 6c 75 6d  _free(p->azColum
15690 6e 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  n);.  sqlite3_fr
156a0 65 65 28 70 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43  ee(p->azContentC
156b0 6f 6c 75 6d 6e 29 3b 0a 20 20 73 71 6c 69 74 65  olumn);.  sqlite
156c0 33 5f 66 72 65 65 28 70 2d 3e 61 7a 54 6f 6b 65  3_free(p->azToke
156d0 6e 69 7a 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 50 61  nizer);.}../* Pa
156e0 72 73 65 20 61 20 43 52 45 41 54 45 20 56 49 52  rse a CREATE VIR
156f0 54 55 41 4c 20 54 41 42 4c 45 20 73 74 61 74 65  TUAL TABLE state
15700 6d 65 6e 74 2c 20 77 68 69 63 68 20 6c 6f 6f 6b  ment, which look
15710 73 20 6c 69 6b 65 20 74 68 69 73 3a 0a 20 2a 0a  s like this:. *.
15720 20 2a 20 43 52 45 41 54 45 20 56 49 52 54 55 41   * CREATE VIRTUA
15730 4c 20 54 41 42 4c 45 20 65 6d 61 69 6c 0a 20 2a  L TABLE email. *
15740 20 20 20 20 20 20 20 20 55 53 49 4e 47 20 66 74          USING ft
15750 73 33 28 73 75 62 6a 65 63 74 2c 20 62 6f 64 79  s3(subject, body
15760 2c 20 74 6f 6b 65 6e 69 7a 65 20 6d 79 74 6f 6b  , tokenize mytok
15770 65 6e 69 7a 65 72 28 6d 79 61 72 67 29 29 0a 20  enizer(myarg)). 
15780 2a 0a 20 2a 20 57 65 20 72 65 74 75 72 6e 20 70  *. * We return p
15790 61 72 73 65 64 20 69 6e 66 6f 72 6d 61 74 69 6f  arsed informatio
157a0 6e 20 69 6e 20 61 20 54 61 62 6c 65 53 70 65 63  n in a TableSpec
157b0 20 73 74 72 75 63 74 75 72 65 2e 0a 20 2a 20 0a   structure.. * .
157c0 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70   */.static int p
157d0 61 72 73 65 53 70 65 63 28 54 61 62 6c 65 53 70  arseSpec(TableSp
157e0 65 63 20 2a 70 53 70 65 63 2c 20 69 6e 74 20 61  ec *pSpec, int a
157f0 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  rgc, const char 
15800 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 20  *const*argv,.   
15810 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15820 20 20 63 68 61 72 2a 2a 70 7a 45 72 72 29 7b 0a    char**pzErr){.
15830 20 20 69 6e 74 20 69 2c 20 6e 3b 0a 20 20 63 68    int i, n;.  ch
15840 61 72 20 2a 7a 2c 20 2a 7a 44 75 6d 6d 79 3b 0a  ar *z, *zDummy;.
15850 20 20 63 68 61 72 20 2a 2a 61 7a 41 72 67 3b 0a    char **azArg;.
15860 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
15870 6f 6b 65 6e 69 7a 65 72 20 3d 20 30 3b 20 20 20  okenizer = 0;   
15880 20 2f 2a 20 61 72 67 76 5b 5d 20 65 6e 74 72 79   /* argv[] entry
15890 20 64 65 73 63 72 69 62 69 6e 67 20 74 68 65 20   describing the 
158a0 74 6f 6b 65 6e 69 7a 65 72 20 2a 2f 0a 0a 20 20  tokenizer */..  
158b0 61 73 73 65 72 74 28 20 61 72 67 63 3e 3d 33 20  assert( argc>=3 
158c0 29 3b 0a 20 20 2f 2a 20 43 75 72 72 65 6e 74 20  );.  /* Current 
158d0 69 6e 74 65 72 66 61 63 65 3a 0a 20 20 2a 2a 20  interface:.  ** 
158e0 61 72 67 76 5b 30 5d 20 2d 20 6d 6f 64 75 6c 65  argv[0] - module
158f0 20 6e 61 6d 65 0a 20 20 2a 2a 20 61 72 67 76 5b   name.  ** argv[
15900 31 5d 20 2d 20 64 61 74 61 62 61 73 65 20 6e 61  1] - database na
15910 6d 65 0a 20 20 2a 2a 20 61 72 67 76 5b 32 5d 20  me.  ** argv[2] 
15920 2d 20 74 61 62 6c 65 20 6e 61 6d 65 0a 20 20 2a  - table name.  *
15930 2a 20 61 72 67 76 5b 33 2e 2e 5d 20 2d 20 63 6f  * argv[3..] - co
15940 6c 75 6d 6e 73 2c 20 6f 70 74 69 6f 6e 61 6c 6c  lumns, optionall
15950 79 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 74 6f  y followed by to
15960 6b 65 6e 69 7a 65 72 20 73 70 65 63 69 66 69 63  kenizer specific
15970 61 74 69 6f 6e 0a 20 20 2a 2a 20 20 20 20 20 20  ation.  **      
15980 20 20 20 20 20 20 20 61 6e 64 20 73 6e 69 70 70         and snipp
15990 65 74 20 64 65 6c 69 6d 69 74 65 72 73 20 73 70  et delimiters sp
159a0 65 63 69 66 69 63 61 74 69 6f 6e 2e 0a 20 20 2a  ecification..  *
159b0 2f 0a 0a 20 20 2f 2a 20 4d 61 6b 65 20 61 20 63  /..  /* Make a c
159c0 6f 70 79 20 6f 66 20 74 68 65 20 63 6f 6d 70 6c  opy of the compl
159d0 65 74 65 20 61 72 67 76 5b 5d 5b 5d 20 61 72 72  ete argv[][] arr
159e0 61 79 20 69 6e 20 61 20 73 69 6e 67 6c 65 20 61  ay in a single a
159f0 6c 6c 6f 63 61 74 69 6f 6e 2e 0a 20 20 2a 2a 20  llocation..  ** 
15a00 54 68 65 20 61 72 67 76 5b 5d 5b 5d 20 61 72 72  The argv[][] arr
15a10 61 79 20 69 73 20 72 65 61 64 2d 6f 6e 6c 79 20  ay is read-only 
15a20 61 6e 64 20 74 72 61 6e 73 69 65 6e 74 2e 20 20  and transient.  
15a30 57 65 20 63 61 6e 20 77 72 69 74 65 20 74 6f 20  We can write to 
15a40 74 68 65 0a 20 20 2a 2a 20 63 6f 70 79 20 69 6e  the.  ** copy in
15a50 20 6f 72 64 65 72 20 74 6f 20 6d 6f 64 69 66 79   order to modify
15a60 20 74 68 69 6e 67 73 20 61 6e 64 20 74 68 65 20   things and the 
15a70 63 6f 70 79 20 69 73 20 70 65 72 73 69 73 74 65  copy is persiste
15a80 6e 74 2e 0a 20 20 2a 2f 0a 20 20 43 4c 45 41 52  nt..  */.  CLEAR
15a90 28 70 53 70 65 63 29 3b 0a 20 20 66 6f 72 28 69  (pSpec);.  for(i
15aa0 3d 6e 3d 30 3b 20 69 3c 61 72 67 63 3b 20 69 2b  =n=0; i<argc; i+
15ab0 2b 29 7b 0a 20 20 20 20 6e 20 2b 3d 20 73 74 72  +){.    n += str
15ac0 6c 65 6e 28 61 72 67 76 5b 69 5d 29 20 2b 20 31  len(argv[i]) + 1
15ad0 3b 0a 20 20 7d 0a 20 20 61 7a 41 72 67 20 3d 20  ;.  }.  azArg = 
15ae0 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20  sqlite3_malloc( 
15af0 73 69 7a 65 6f 66 28 63 68 61 72 2a 29 2a 61 72  sizeof(char*)*ar
15b00 67 63 20 2b 20 6e 20 29 3b 0a 20 20 69 66 28 20  gc + n );.  if( 
15b10 61 7a 41 72 67 3d 3d 30 20 29 7b 0a 20 20 20 20  azArg==0 ){.    
15b20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
15b30 4d 45 4d 3b 0a 20 20 7d 0a 20 20 7a 20 3d 20 28  MEM;.  }.  z = (
15b40 63 68 61 72 2a 29 26 61 7a 41 72 67 5b 61 72 67  char*)&azArg[arg
15b50 63 5d 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  c];.  for(i=0; i
15b60 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20  <argc; i++){.   
15b70 20 61 7a 41 72 67 5b 69 5d 20 3d 20 7a 3b 0a 20   azArg[i] = z;. 
15b80 20 20 20 73 74 72 63 70 79 28 7a 2c 20 61 72 67     strcpy(z, arg
15b90 76 5b 69 5d 29 3b 0a 20 20 20 20 7a 20 2b 3d 20  v[i]);.    z += 
15ba0 73 74 72 6c 65 6e 28 7a 29 2b 31 3b 0a 20 20 7d  strlen(z)+1;.  }
15bb0 0a 0a 20 20 2f 2a 20 49 64 65 6e 74 69 66 79 20  ..  /* Identify 
15bc0 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73  the column names
15bd0 20 61 6e 64 20 74 68 65 20 74 6f 6b 65 6e 69 7a   and the tokeniz
15be0 65 72 20 61 6e 64 20 64 65 6c 69 6d 69 74 65 72  er and delimiter
15bf0 20 61 72 67 75 6d 65 6e 74 73 0a 20 20 2a 2a 20   arguments.  ** 
15c00 69 6e 20 74 68 65 20 61 72 67 76 5b 5d 5b 5d 20  in the argv[][] 
15c10 61 72 72 61 79 2e 0a 20 20 2a 2f 0a 20 20 70 53  array..  */.  pS
15c20 70 65 63 2d 3e 7a 44 62 20 3d 20 61 7a 41 72 67  pec->zDb = azArg
15c30 5b 31 5d 3b 0a 20 20 70 53 70 65 63 2d 3e 7a 4e  [1];.  pSpec->zN
15c40 61 6d 65 20 3d 20 61 7a 41 72 67 5b 32 5d 3b 0a  ame = azArg[2];.
15c50 20 20 70 53 70 65 63 2d 3e 6e 43 6f 6c 75 6d 6e    pSpec->nColumn
15c60 20 3d 20 30 3b 0a 20 20 70 53 70 65 63 2d 3e 61   = 0;.  pSpec->a
15c70 7a 43 6f 6c 75 6d 6e 20 3d 20 61 7a 41 72 67 3b  zColumn = azArg;
15c80 0a 20 20 7a 54 6f 6b 65 6e 69 7a 65 72 20 3d 20  .  zTokenizer = 
15c90 22 74 6f 6b 65 6e 69 7a 65 20 73 69 6d 70 6c 65  "tokenize simple
15ca0 22 3b 0a 20 20 66 6f 72 28 69 3d 33 3b 20 69 3c  ";.  for(i=3; i<
15cb0 61 72 67 63 3b 20 2b 2b 69 29 7b 0a 20 20 20 20  argc; ++i){.    
15cc0 69 66 28 20 73 74 61 72 74 73 57 69 74 68 28 61  if( startsWith(a
15cd0 7a 41 72 67 5b 69 5d 2c 22 74 6f 6b 65 6e 69 7a  zArg[i],"tokeniz
15ce0 65 22 29 20 29 7b 0a 20 20 20 20 20 20 7a 54 6f  e") ){.      zTo
15cf0 6b 65 6e 69 7a 65 72 20 3d 20 61 7a 41 72 67 5b  kenizer = azArg[
15d00 69 5d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  i];.    }else{. 
15d10 20 20 20 20 20 7a 20 3d 20 61 7a 41 72 67 5b 70       z = azArg[p
15d20 53 70 65 63 2d 3e 6e 43 6f 6c 75 6d 6e 5d 20 3d  Spec->nColumn] =
15d30 20 66 69 72 73 74 54 6f 6b 65 6e 28 61 7a 41 72   firstToken(azAr
15d40 67 5b 69 5d 2c 20 26 7a 44 75 6d 6d 79 29 3b 0a  g[i], &zDummy);.
15d50 20 20 20 20 20 20 70 53 70 65 63 2d 3e 6e 43 6f        pSpec->nCo
15d60 6c 75 6d 6e 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20  lumn++;.    }.  
15d70 7d 0a 20 20 69 66 28 20 70 53 70 65 63 2d 3e 6e  }.  if( pSpec->n
15d80 43 6f 6c 75 6d 6e 3d 3d 30 20 29 7b 0a 20 20 20  Column==0 ){.   
15d90 20 61 7a 41 72 67 5b 30 5d 20 3d 20 22 63 6f 6e   azArg[0] = "con
15da0 74 65 6e 74 22 3b 0a 20 20 20 20 70 53 70 65 63  tent";.    pSpec
15db0 2d 3e 6e 43 6f 6c 75 6d 6e 20 3d 20 31 3b 0a 20  ->nColumn = 1;. 
15dc0 20 7d 0a 0a 20 20 2f 2a 0a 20 20 2a 2a 20 43 6f   }..  /*.  ** Co
15dd0 6e 73 74 72 75 63 74 20 74 68 65 20 6c 69 73 74  nstruct the list
15de0 20 6f 66 20 63 6f 6e 74 65 6e 74 20 63 6f 6c 75   of content colu
15df0 6d 6e 20 6e 61 6d 65 73 2e 0a 20 20 2a 2a 0a 20  mn names..  **. 
15e00 20 2a 2a 20 45 61 63 68 20 63 6f 6e 74 65 6e 74   ** Each content
15e10 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 20 77 69 6c   column name wil
15e20 6c 20 62 65 20 6f 66 20 74 68 65 20 66 6f 72 6d  l be of the form
15e30 20 63 4e 4e 41 41 41 41 0a 20 20 2a 2a 20 77 68   cNNAAAA.  ** wh
15e40 65 72 65 20 4e 4e 20 69 73 20 74 68 65 20 63 6f  ere NN is the co
15e50 6c 75 6d 6e 20 6e 75 6d 62 65 72 20 61 6e 64 20  lumn number and 
15e60 41 41 41 41 20 69 73 20 74 68 65 20 73 61 6e 69  AAAA is the sani
15e70 74 69 7a 65 64 0a 20 20 2a 2a 20 63 6f 6c 75 6d  tized.  ** colum
15e80 6e 20 6e 61 6d 65 2e 20 20 22 73 61 6e 69 74 69  n name.  "saniti
15e90 7a 65 64 22 20 6d 65 61 6e 73 20 74 68 61 74 20  zed" means that 
15ea0 73 70 65 63 69 61 6c 20 63 68 61 72 61 63 74 65  special characte
15eb0 72 73 20 61 72 65 0a 20 20 2a 2a 20 63 6f 6e 76  rs are.  ** conv
15ec0 65 72 74 65 64 20 74 6f 20 22 5f 22 2e 20 20 54  erted to "_".  T
15ed0 68 65 20 63 4e 4e 20 70 72 65 66 69 78 20 67 75  he cNN prefix gu
15ee0 61 72 61 6e 74 65 65 73 20 74 68 61 74 20 61 6c  arantees that al
15ef0 6c 20 63 6f 6c 75 6d 6e 0a 20 20 2a 2a 20 6e 61  l column.  ** na
15f00 6d 65 73 20 61 72 65 20 75 6e 69 71 75 65 2e 0a  mes are unique..
15f10 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 20 41 41    **.  ** The AA
15f20 41 41 20 73 75 66 66 69 78 20 69 73 20 6e 6f 74  AA suffix is not
15f30 20 73 74 72 69 63 74 6c 79 20 6e 65 63 65 73 73   strictly necess
15f40 61 72 79 2e 20 20 49 74 20 69 73 20 69 6e 63 6c  ary.  It is incl
15f50 75 64 65 64 0a 20 20 2a 2a 20 66 6f 72 20 74 68  uded.  ** for th
15f60 65 20 63 6f 6e 76 65 6e 69 65 6e 63 65 20 6f 66  e convenience of
15f70 20 70 65 6f 70 6c 65 20 77 68 6f 20 6d 69 67 68   people who migh
15f80 74 20 65 78 61 6d 69 6e 65 20 74 68 65 20 67 65  t examine the ge
15f90 6e 65 72 61 74 65 64 0a 20 20 2a 2a 20 25 5f 63  nerated.  ** %_c
15fa0 6f 6e 74 65 6e 74 20 74 61 62 6c 65 20 61 6e 64  ontent table and
15fb0 20 77 6f 6e 64 65 72 20 77 68 61 74 20 74 68 65   wonder what the
15fc0 20 63 6f 6c 75 6d 6e 73 20 61 72 65 20 75 73 65   columns are use
15fd0 64 20 66 6f 72 2e 0a 20 20 2a 2f 0a 20 20 70 53  d for..  */.  pS
15fe0 70 65 63 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f  pec->azContentCo
15ff0 6c 75 6d 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d  lumn = sqlite3_m
16000 61 6c 6c 6f 63 28 20 70 53 70 65 63 2d 3e 6e 43  alloc( pSpec->nC
16010 6f 6c 75 6d 6e 20 2a 20 73 69 7a 65 6f 66 28 63  olumn * sizeof(c
16020 68 61 72 20 2a 29 20 29 3b 0a 20 20 69 66 28 20  har *) );.  if( 
16030 70 53 70 65 63 2d 3e 61 7a 43 6f 6e 74 65 6e 74  pSpec->azContent
16040 43 6f 6c 75 6d 6e 3d 3d 30 20 29 7b 0a 20 20 20  Column==0 ){.   
16050 20 63 6c 65 61 72 54 61 62 6c 65 53 70 65 63 28   clearTableSpec(
16060 70 53 70 65 63 29 3b 0a 20 20 20 20 72 65 74 75  pSpec);.    retu
16070 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
16080 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d 30 3b 20  .  }.  for(i=0; 
16090 69 3c 70 53 70 65 63 2d 3e 6e 43 6f 6c 75 6d 6e  i<pSpec->nColumn
160a0 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 63 68 61 72  ; i++){.    char
160b0 20 2a 70 3b 0a 20 20 20 20 70 53 70 65 63 2d 3e   *p;.    pSpec->
160c0 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 5b  azContentColumn[
160d0 69 5d 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  i] = sqlite3_mpr
160e0 69 6e 74 66 28 22 63 25 64 25 73 22 2c 20 69 2c  intf("c%d%s", i,
160f0 20 61 7a 41 72 67 5b 69 5d 29 3b 0a 20 20 20 20   azArg[i]);.    
16100 66 6f 72 20 28 70 20 3d 20 70 53 70 65 63 2d 3e  for (p = pSpec->
16110 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 5b  azContentColumn[
16120 69 5d 3b 20 2a 70 20 3b 20 2b 2b 70 29 20 7b 0a  i]; *p ; ++p) {.
16130 20 20 20 20 20 20 69 66 28 20 21 73 61 66 65 5f        if( !safe_
16140 69 73 61 6c 6e 75 6d 28 2a 70 29 20 29 20 2a 70  isalnum(*p) ) *p
16150 20 3d 20 27 5f 27 3b 0a 20 20 20 20 7d 0a 20 20   = '_';.    }.  
16160 7d 0a 0a 20 20 2f 2a 0a 20 20 2a 2a 20 50 61 72  }..  /*.  ** Par
16170 73 65 20 74 68 65 20 74 6f 6b 65 6e 69 7a 65 72  se the tokenizer
16180 20 73 70 65 63 69 66 69 63 61 74 69 6f 6e 20 73   specification s
16190 74 72 69 6e 67 2e 0a 20 20 2a 2f 0a 20 20 70 53  tring..  */.  pS
161a0 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e 69 7a 65 72  pec->azTokenizer
161b0 20 3d 20 74 6f 6b 65 6e 69 7a 65 53 74 72 69 6e   = tokenizeStrin
161c0 67 28 7a 54 6f 6b 65 6e 69 7a 65 72 2c 20 26 6e  g(zTokenizer, &n
161d0 29 3b 0a 20 20 74 6f 6b 65 6e 4c 69 73 74 54 6f  );.  tokenListTo
161e0 49 64 4c 69 73 74 28 70 53 70 65 63 2d 3e 61 7a  IdList(pSpec->az
161f0 54 6f 6b 65 6e 69 7a 65 72 29 3b 0a 0a 20 20 72  Tokenizer);..  r
16200 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
16210 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61  .}../*.** Genera
16220 74 65 20 61 20 43 52 45 41 54 45 20 54 41 42 4c  te a CREATE TABL
16230 45 20 73 74 61 74 65 6d 65 6e 74 20 74 68 61 74  E statement that
16240 20 64 65 73 63 72 69 62 65 73 20 74 68 65 20 73   describes the s
16250 63 68 65 6d 61 20 6f 66 0a 2a 2a 20 74 68 65 20  chema of.** the 
16260 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20  virtual table.  
16270 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72  Return a pointer
16280 20 74 6f 20 74 68 69 73 20 73 63 68 65 6d 61 20   to this schema 
16290 73 74 72 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 53 70  string..**.** Sp
162a0 61 63 65 20 69 73 20 6f 62 74 61 69 6e 65 64 20  ace is obtained 
162b0 66 72 6f 6d 20 73 71 6c 69 74 65 33 5f 6d 70 72  from sqlite3_mpr
162c0 69 6e 74 66 28 29 20 61 6e 64 20 73 68 6f 75 6c  intf() and shoul
162d0 64 20 62 65 20 66 72 65 65 64 0a 2a 2a 20 75 73  d be freed.** us
162e0 69 6e 67 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ing sqlite3_free
162f0 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68  ()..*/.static ch
16300 61 72 20 2a 66 75 6c 6c 74 65 78 74 53 63 68 65  ar *fulltextSche
16310 6d 61 28 0a 20 20 69 6e 74 20 6e 43 6f 6c 75 6d  ma(.  int nColum
16320 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n,              
16330 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
16340 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 63 6f   columns */.  co
16350 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a  nst char *const*
16360 20 61 7a 43 6f 6c 75 6d 6e 2c 20 20 2f 2a 20 4c   azColumn,  /* L
16370 69 73 74 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 2a  ist of columns *
16380 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
16390 7a 54 61 62 6c 65 4e 61 6d 65 20 20 20 20 20 20  zTableName      
163a0 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65    /* Name of the
163b0 20 74 61 62 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69   table */.){.  i
163c0 6e 74 20 69 3b 0a 20 20 63 68 61 72 20 2a 7a 53  nt i;.  char *zS
163d0 63 68 65 6d 61 2c 20 2a 7a 4e 65 78 74 3b 0a 20  chema, *zNext;. 
163e0 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 65   const char *zSe
163f0 70 20 3d 20 22 28 22 3b 0a 20 20 7a 53 63 68 65  p = "(";.  zSche
16400 6d 61 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ma = sqlite3_mpr
16410 69 6e 74 66 28 22 43 52 45 41 54 45 20 54 41 42  intf("CREATE TAB
16420 4c 45 20 78 22 29 3b 0a 20 20 66 6f 72 28 69 3d  LE x");.  for(i=
16430 30 3b 20 69 3c 6e 43 6f 6c 75 6d 6e 3b 20 69 2b  0; i<nColumn; i+
16440 2b 29 7b 0a 20 20 20 20 7a 4e 65 78 74 20 3d 20  +){.    zNext = 
16450 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
16460 22 25 73 25 73 25 51 22 2c 20 7a 53 63 68 65 6d  "%s%s%Q", zSchem
16470 61 2c 20 7a 53 65 70 2c 20 61 7a 43 6f 6c 75 6d  a, zSep, azColum
16480 6e 5b 69 5d 29 3b 0a 20 20 20 20 73 71 6c 69 74  n[i]);.    sqlit
16490 65 33 5f 66 72 65 65 28 7a 53 63 68 65 6d 61 29  e3_free(zSchema)
164a0 3b 0a 20 20 20 20 7a 53 63 68 65 6d 61 20 3d 20  ;.    zSchema = 
164b0 7a 4e 65 78 74 3b 0a 20 20 20 20 7a 53 65 70 20  zNext;.    zSep 
164c0 3d 20 22 2c 22 3b 0a 20 20 7d 0a 20 20 7a 4e 65  = ",";.  }.  zNe
164d0 78 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  xt = sqlite3_mpr
164e0 69 6e 74 66 28 22 25 73 2c 25 51 20 48 49 44 44  intf("%s,%Q HIDD
164f0 45 4e 22 2c 20 7a 53 63 68 65 6d 61 2c 20 7a 54  EN", zSchema, zT
16500 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 73 71 6c  ableName);.  sql
16510 69 74 65 33 5f 66 72 65 65 28 7a 53 63 68 65 6d  ite3_free(zSchem
16520 61 29 3b 0a 20 20 7a 53 63 68 65 6d 61 20 3d 20  a);.  zSchema = 
16530 7a 4e 65 78 74 3b 0a 20 20 7a 4e 65 78 74 20 3d  zNext;.  zNext =
16540 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
16550 28 22 25 73 2c 64 6f 63 69 64 20 48 49 44 44 45  ("%s,docid HIDDE
16560 4e 29 22 2c 20 7a 53 63 68 65 6d 61 29 3b 0a 20  N)", zSchema);. 
16570 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53   sqlite3_free(zS
16580 63 68 65 6d 61 29 3b 0a 20 20 72 65 74 75 72 6e  chema);.  return
16590 20 7a 4e 65 78 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   zNext;.}../*.**
165a0 20 42 75 69 6c 64 20 61 20 6e 65 77 20 73 71 6c   Build a new sql
165b0 69 74 65 33 5f 76 74 61 62 20 73 74 72 75 63 74  ite3_vtab struct
165c0 75 72 65 20 74 68 61 74 20 77 69 6c 6c 20 64 65  ure that will de
165d0 73 63 72 69 62 65 20 74 68 65 0a 2a 2a 20 66 75  scribe the.** fu
165e0 6c 6c 74 65 78 74 20 69 6e 64 65 78 20 64 65 66  lltext index def
165f0 69 6e 65 64 20 62 79 20 73 70 65 63 2e 0a 2a 2f  ined by spec..*/
16600 0a 73 74 61 74 69 63 20 69 6e 74 20 63 6f 6e 73  .static int cons
16610 74 72 75 63 74 56 74 61 62 28 0a 20 20 73 71 6c  tructVtab(.  sql
16620 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20  ite3 *db,       
16630 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 53 51         /* The SQ
16640 4c 69 74 65 20 64 61 74 61 62 61 73 65 20 63 6f  Lite database co
16650 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 66 74  nnection */.  ft
16660 73 33 48 61 73 68 20 2a 70 48 61 73 68 2c 20 20  s3Hash *pHash,  
16670 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20          /* Hash 
16680 74 61 62 6c 65 20 63 6f 6e 74 61 69 6e 69 6e 67  table containing
16690 20 74 6f 6b 65 6e 69 7a 65 72 73 20 2a 2f 0a 20   tokenizers */. 
166a0 20 54 61 62 6c 65 53 70 65 63 20 2a 73 70 65 63   TableSpec *spec
166b0 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61  ,          /* Pa
166c0 72 73 65 64 20 73 70 65 63 20 69 6e 66 6f 72 6d  rsed spec inform
166d0 61 74 69 6f 6e 20 66 72 6f 6d 20 70 61 72 73 65  ation from parse
166e0 53 70 65 63 28 29 20 2a 2f 0a 20 20 73 71 6c 69  Spec() */.  sqli
166f0 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 54 61  te3_vtab **ppVTa
16700 62 2c 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74  b,    /* Write t
16710 68 65 20 72 65 73 75 6c 74 69 6e 67 20 76 74 61  he resulting vta
16720 62 20 73 74 72 75 63 74 75 72 65 20 68 65 72 65  b structure here
16730 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45   */.  char **pzE
16740 72 72 20 20 20 20 20 20 20 20 20 20 20 20 20 20  rr              
16750 2f 2a 20 57 72 69 74 65 20 61 6e 79 20 65 72 72  /* Write any err
16760 6f 72 20 6d 65 73 73 61 67 65 20 68 65 72 65 20  or message here 
16770 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  */.){.  int rc;.
16780 20 20 69 6e 74 20 6e 3b 0a 20 20 66 75 6c 6c 74    int n;.  fullt
16790 65 78 74 5f 76 74 61 62 20 2a 76 20 3d 20 30 3b  ext_vtab *v = 0;
167a0 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33  .  const sqlite3
167b0 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c  _tokenizer_modul
167c0 65 20 2a 6d 20 3d 20 4e 55 4c 4c 3b 0a 20 20 63  e *m = NULL;.  c
167d0 68 61 72 20 2a 73 63 68 65 6d 61 3b 0a 0a 20 20  har *schema;..  
167e0 63 68 61 72 20 63 6f 6e 73 74 20 2a 7a 54 6f 6b  char const *zTok
167f0 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d  ;         /* Nam
16800 65 20 6f 66 20 74 6f 6b 65 6e 69 7a 65 72 20 74  e of tokenizer t
16810 6f 20 75 73 65 20 66 6f 72 20 74 68 69 73 20 66  o use for this f
16820 74 73 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e  ts table */.  in
16830 74 20 6e 54 6f 6b 3b 20 20 20 20 20 20 20 20 20  t nTok;         
16840 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74          /* Lengt
16850 68 20 6f 66 20 7a 54 6f 6b 2c 20 69 6e 63 6c 75  h of zTok, inclu
16860 64 69 6e 67 20 6e 75 6c 20 74 65 72 6d 69 6e 61  ding nul termina
16870 74 6f 72 20 2a 2f 0a 0a 20 20 76 20 3d 20 28 66  tor */..  v = (f
16880 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 20  ulltext_vtab *) 
16890 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
168a0 69 7a 65 6f 66 28 66 75 6c 6c 74 65 78 74 5f 76  izeof(fulltext_v
168b0 74 61 62 29 29 3b 0a 20 20 69 66 28 20 76 3d 3d  tab));.  if( v==
168c0 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  0 ) return SQLIT
168d0 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 43 4c 45 41 52  E_NOMEM;.  CLEAR
168e0 28 76 29 3b 0a 20 20 2f 2a 20 73 71 6c 69 74 65  (v);.  /* sqlite
168f0 20 77 69 6c 6c 20 69 6e 69 74 69 61 6c 69 7a 65   will initialize
16900 20 76 2d 3e 62 61 73 65 20 2a 2f 0a 20 20 76 2d   v->base */.  v-
16910 3e 64 62 20 3d 20 64 62 3b 0a 20 20 76 2d 3e 7a  >db = db;.  v->z
16920 44 62 20 3d 20 73 70 65 63 2d 3e 7a 44 62 3b 20  Db = spec->zDb; 
16930 20 20 20 20 20 20 2f 2a 20 46 72 65 65 64 20 77        /* Freed w
16940 68 65 6e 20 61 7a 43 6f 6c 75 6d 6e 20 69 73 20  hen azColumn is 
16950 66 72 65 65 64 20 2a 2f 0a 20 20 76 2d 3e 7a 4e  freed */.  v->zN
16960 61 6d 65 20 3d 20 73 70 65 63 2d 3e 7a 4e 61 6d  ame = spec->zNam
16970 65 3b 20 20 20 2f 2a 20 46 72 65 65 64 20 77 68  e;   /* Freed wh
16980 65 6e 20 61 7a 43 6f 6c 75 6d 6e 20 69 73 20 66  en azColumn is f
16990 72 65 65 64 20 2a 2f 0a 20 20 76 2d 3e 6e 43 6f  reed */.  v->nCo
169a0 6c 75 6d 6e 20 3d 20 73 70 65 63 2d 3e 6e 43 6f  lumn = spec->nCo
169b0 6c 75 6d 6e 3b 0a 20 20 76 2d 3e 61 7a 43 6f 6e  lumn;.  v->azCon
169c0 74 65 6e 74 43 6f 6c 75 6d 6e 20 3d 20 73 70 65  tentColumn = spe
169d0 63 2d 3e 61 7a 43 6f 6e 74 65 6e 74 43 6f 6c 75  c->azContentColu
169e0 6d 6e 3b 0a 20 20 73 70 65 63 2d 3e 61 7a 43 6f  mn;.  spec->azCo
169f0 6e 74 65 6e 74 43 6f 6c 75 6d 6e 20 3d 20 30 3b  ntentColumn = 0;
16a00 0a 20 20 76 2d 3e 61 7a 43 6f 6c 75 6d 6e 20 3d  .  v->azColumn =
16a10 20 73 70 65 63 2d 3e 61 7a 43 6f 6c 75 6d 6e 3b   spec->azColumn;
16a20 0a 20 20 73 70 65 63 2d 3e 61 7a 43 6f 6c 75 6d  .  spec->azColum
16a30 6e 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 73 70  n = 0;..  if( sp
16a40 65 63 2d 3e 61 7a 54 6f 6b 65 6e 69 7a 65 72 3d  ec->azTokenizer=
16a50 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  =0 ){.    return
16a60 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
16a70 20 7d 0a 0a 20 20 7a 54 6f 6b 20 3d 20 73 70 65   }..  zTok = spe
16a80 63 2d 3e 61 7a 54 6f 6b 65 6e 69 7a 65 72 5b 30  c->azTokenizer[0
16a90 5d 3b 20 0a 20 20 69 66 28 20 21 7a 54 6f 6b 20  ]; .  if( !zTok 
16aa0 29 7b 0a 20 20 20 20 7a 54 6f 6b 20 3d 20 22 73  ){.    zTok = "s
16ab0 69 6d 70 6c 65 22 3b 0a 20 20 7d 0a 20 20 6e 54  imple";.  }.  nT
16ac0 6f 6b 20 3d 20 73 74 72 6c 65 6e 28 7a 54 6f 6b  ok = strlen(zTok
16ad0 29 2b 31 3b 0a 0a 20 20 6d 20 3d 20 28 73 71 6c  )+1;..  m = (sql
16ae0 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 6d  ite3_tokenizer_m
16af0 6f 64 75 6c 65 20 2a 29 73 71 6c 69 74 65 33 46  odule *)sqlite3F
16b00 74 73 33 48 61 73 68 46 69 6e 64 28 70 48 61 73  ts3HashFind(pHas
16b10 68 2c 20 7a 54 6f 6b 2c 20 6e 54 6f 6b 29 3b 0a  h, zTok, nTok);.
16b20 20 20 69 66 28 20 21 6d 20 29 7b 0a 20 20 20 20    if( !m ){.    
16b30 2a 70 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33  *pzErr = sqlite3
16b40 5f 6d 70 72 69 6e 74 66 28 22 75 6e 6b 6e 6f 77  _mprintf("unknow
16b50 6e 20 74 6f 6b 65 6e 69 7a 65 72 3a 20 25 73 22  n tokenizer: %s"
16b60 2c 20 73 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e 69  , spec->azTokeni
16b70 7a 65 72 5b 30 5d 29 3b 0a 20 20 20 20 72 63 20  zer[0]);.    rc 
16b80 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
16b90 20 20 20 20 67 6f 74 6f 20 65 72 72 3b 0a 20 20      goto err;.  
16ba0 7d 0a 0a 20 20 66 6f 72 28 6e 3d 30 3b 20 73 70  }..  for(n=0; sp
16bb0 65 63 2d 3e 61 7a 54 6f 6b 65 6e 69 7a 65 72 5b  ec->azTokenizer[
16bc0 6e 5d 3b 20 6e 2b 2b 29 7b 7d 0a 20 20 69 66 28  n]; n++){}.  if(
16bd0 20 6e 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 6d   n ){.    rc = m
16be0 2d 3e 78 43 72 65 61 74 65 28 6e 2d 31 2c 20 28  ->xCreate(n-1, (
16bf0 63 6f 6e 73 74 20 63 68 61 72 2a 63 6f 6e 73 74  const char*const
16c00 2a 29 26 73 70 65 63 2d 3e 61 7a 54 6f 6b 65 6e  *)&spec->azToken
16c10 69 7a 65 72 5b 31 5d 2c 0a 20 20 20 20 20 20 20  izer[1],.       
16c20 20 20 20 20 20 20 20 20 20 20 20 20 20 26 76 2d               &v-
16c30 3e 70 54 6f 6b 65 6e 69 7a 65 72 29 3b 0a 20 20  >pTokenizer);.  
16c40 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20  }else{.    rc = 
16c50 6d 2d 3e 78 43 72 65 61 74 65 28 30 2c 20 30 2c  m->xCreate(0, 0,
16c60 20 26 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72 29   &v->pTokenizer)
16c70 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 21 3d  ;.  }.  if( rc!=
16c80 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f  SQLITE_OK ) goto
16c90 20 65 72 72 3b 0a 20 20 76 2d 3e 70 54 6f 6b 65   err;.  v->pToke
16ca0 6e 69 7a 65 72 2d 3e 70 4d 6f 64 75 6c 65 20 3d  nizer->pModule =
16cb0 20 6d 3b 0a 0a 20 20 2f 2a 20 54 4f 44 4f 3a 20   m;..  /* TODO: 
16cc0 76 65 72 69 66 79 20 74 68 65 20 65 78 69 73 74  verify the exist
16cd0 65 6e 63 65 20 6f 66 20 62 61 63 6b 69 6e 67 20  ence of backing 
16ce0 74 61 62 6c 65 73 20 66 6f 6f 5f 63 6f 6e 74 65  tables foo_conte
16cf0 6e 74 2c 20 66 6f 6f 5f 74 65 72 6d 20 2a 2f 0a  nt, foo_term */.
16d00 0a 20 20 73 63 68 65 6d 61 20 3d 20 66 75 6c 6c  .  schema = full
16d10 74 65 78 74 53 63 68 65 6d 61 28 76 2d 3e 6e 43  textSchema(v->nC
16d20 6f 6c 75 6d 6e 2c 20 28 63 6f 6e 73 74 20 63 68  olumn, (const ch
16d30 61 72 2a 63 6f 6e 73 74 2a 29 76 2d 3e 61 7a 43  ar*const*)v->azC
16d40 6f 6c 75 6d 6e 2c 0a 20 20 20 20 20 20 20 20 20  olumn,.         
16d50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16d60 20 73 70 65 63 2d 3e 7a 4e 61 6d 65 29 3b 0a 20   spec->zName);. 
16d70 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 64 65   rc = sqlite3_de
16d80 63 6c 61 72 65 5f 76 74 61 62 28 64 62 2c 20 73  clare_vtab(db, s
16d90 63 68 65 6d 61 29 3b 0a 20 20 73 71 6c 69 74 65  chema);.  sqlite
16da0 33 5f 66 72 65 65 28 73 63 68 65 6d 61 29 3b 0a  3_free(schema);.
16db0 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
16dc0 5f 4f 4b 20 29 20 67 6f 74 6f 20 65 72 72 3b 0a  _OK ) goto err;.
16dd0 0a 20 20 6d 65 6d 73 65 74 28 76 2d 3e 70 46 75  .  memset(v->pFu
16de0 6c 6c 74 65 78 74 53 74 61 74 65 6d 65 6e 74 73  lltextStatements
16df0 2c 20 30 2c 20 73 69 7a 65 6f 66 28 76 2d 3e 70  , 0, sizeof(v->p
16e00 46 75 6c 6c 74 65 78 74 53 74 61 74 65 6d 65 6e  FulltextStatemen
16e10 74 73 29 29 3b 0a 0a 20 20 2f 2a 20 49 6e 64 69  ts));..  /* Indi
16e20 63 61 74 65 20 74 68 61 74 20 74 68 65 20 62 75  cate that the bu
16e30 66 66 65 72 20 69 73 20 6e 6f 74 20 6c 69 76 65  ffer is not live
16e40 2e 20 2a 2f 0a 20 20 76 2d 3e 6e 50 65 6e 64 69  . */.  v->nPendi
16e50 6e 67 44 61 74 61 20 3d 20 2d 31 3b 0a 0a 20 20  ngData = -1;..  
16e60 2a 70 70 56 54 61 62 20 3d 20 26 76 2d 3e 62 61  *ppVTab = &v->ba
16e70 73 65 3b 0a 20 20 46 54 53 54 52 41 43 45 28 28  se;.  FTSTRACE((
16e80 22 46 54 53 33 20 43 6f 6e 6e 65 63 74 20 25 70  "FTS3 Connect %p
16e90 5c 6e 22 2c 20 76 29 29 3b 0a 0a 20 20 72 65 74  \n", v));..  ret
16ea0 75 72 6e 20 72 63 3b 0a 0a 65 72 72 3a 0a 20 20  urn rc;..err:.  
16eb0 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 5f 64 65  fulltext_vtab_de
16ec0 73 74 72 6f 79 28 76 29 3b 0a 20 20 72 65 74 75  stroy(v);.  retu
16ed0 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
16ee0 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 43 6f 6e   int fulltextCon
16ef0 6e 65 63 74 28 0a 20 20 73 71 6c 69 74 65 33 20  nect(.  sqlite3 
16f00 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70 41 75  *db,.  void *pAu
16f10 78 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 63  x,.  int argc, c
16f20 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e 73 74  onst char *const
16f30 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33  *argv,.  sqlite3
16f40 5f 76 74 61 62 20 2a 2a 70 70 56 54 61 62 2c 0a  _vtab **ppVTab,.
16f50 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 0a 29    char **pzErr.)
16f60 7b 0a 20 20 54 61 62 6c 65 53 70 65 63 20 73 70  {.  TableSpec sp
16f70 65 63 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 70  ec;.  int rc = p
16f80 61 72 73 65 53 70 65 63 28 26 73 70 65 63 2c 20  arseSpec(&spec, 
16f90 61 72 67 63 2c 20 61 72 67 76 2c 20 70 7a 45 72  argc, argv, pzEr
16fa0 72 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  r);.  if( rc!=SQ
16fb0 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
16fc0 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 63 6f 6e   rc;..  rc = con
16fd0 73 74 72 75 63 74 56 74 61 62 28 64 62 2c 20 28  structVtab(db, (
16fe0 66 74 73 33 48 61 73 68 20 2a 29 70 41 75 78 2c  fts3Hash *)pAux,
16ff0 20 26 73 70 65 63 2c 20 70 70 56 54 61 62 2c 20   &spec, ppVTab, 
17000 70 7a 45 72 72 29 3b 0a 20 20 63 6c 65 61 72 54  pzErr);.  clearT
17010 61 62 6c 65 53 70 65 63 28 26 73 70 65 63 29 3b  ableSpec(&spec);
17020 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
17030 0a 2f 2a 20 54 68 65 20 25 5f 63 6f 6e 74 65 6e  ./* The %_conten
17040 74 20 74 61 62 6c 65 20 68 6f 6c 64 73 20 74 68  t table holds th
17050 65 20 74 65 78 74 20 6f 66 20 65 61 63 68 20 64  e text of each d
17060 6f 63 75 6d 65 6e 74 2c 20 77 69 74 68 0a 2a 2a  ocument, with.**
17070 20 74 68 65 20 64 6f 63 69 64 20 63 6f 6c 75 6d   the docid colum
17080 6e 20 65 78 70 6f 73 65 64 20 61 73 20 74 68 65  n exposed as the
17090 20 53 51 4c 69 74 65 20 72 6f 77 69 64 20 66 6f   SQLite rowid fo
170a0 72 20 74 68 65 20 74 61 62 6c 65 2e 0a 2a 2f 0a  r the table..*/.
170b0 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 54  /* TODO(shess) T
170c0 68 69 73 20 63 6f 6d 6d 65 6e 74 20 6e 65 65 64  his comment need
170d0 73 20 65 6c 61 62 6f 72 61 74 69 6f 6e 20 74 6f  s elaboration to
170e0 20 6d 61 74 63 68 20 74 68 65 20 75 70 64 61 74   match the updat
170f0 65 64 0a 2a 2a 20 63 6f 64 65 2e 20 20 57 6f 72  ed.** code.  Wor
17100 6b 20 69 74 20 69 6e 74 6f 20 74 68 65 20 74 6f  k it into the to
17110 70 2d 6f 66 2d 66 69 6c 65 20 63 6f 6d 6d 65 6e  p-of-file commen
17120 74 20 61 74 20 74 68 61 74 20 74 69 6d 65 2e 0a  t at that time..
17130 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75  */.static int fu
17140 6c 6c 74 65 78 74 43 72 65 61 74 65 28 73 71 6c  lltextCreate(sql
17150 69 74 65 33 20 2a 64 62 2c 20 76 6f 69 64 20 2a  ite3 *db, void *
17160 70 41 75 78 2c 0a 20 20 20 20 20 20 20 20 20 20  pAux,.          
17170 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17180 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20  int argc, const 
17190 63 68 61 72 20 2a 20 63 6f 6e 73 74 20 2a 61 72  char * const *ar
171a0 67 76 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  gv,.            
171b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
171c0 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56  lite3_vtab **ppV
171d0 54 61 62 2c 20 63 68 61 72 20 2a 2a 70 7a 45 72  Tab, char **pzEr
171e0 72 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  r){.  int rc;.  
171f0 54 61 62 6c 65 53 70 65 63 20 73 70 65 63 3b 0a  TableSpec spec;.
17200 20 20 53 74 72 69 6e 67 42 75 66 66 65 72 20 73    StringBuffer s
17210 63 68 65 6d 61 3b 0a 20 20 46 54 53 54 52 41 43  chema;.  FTSTRAC
17220 45 28 28 22 46 54 53 33 20 43 72 65 61 74 65 5c  E(("FTS3 Create\
17230 6e 22 29 29 3b 0a 0a 20 20 72 63 20 3d 20 70 61  n"));..  rc = pa
17240 72 73 65 53 70 65 63 28 26 73 70 65 63 2c 20 61  rseSpec(&spec, a
17250 72 67 63 2c 20 61 72 67 76 2c 20 70 7a 45 72 72  rgc, argv, pzErr
17260 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
17270 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
17280 72 63 3b 0a 0a 20 20 69 6e 69 74 53 74 72 69 6e  rc;..  initStrin
17290 67 42 75 66 66 65 72 28 26 73 63 68 65 6d 61 29  gBuffer(&schema)
172a0 3b 0a 20 20 61 70 70 65 6e 64 28 26 73 63 68 65  ;.  append(&sche
172b0 6d 61 2c 20 22 43 52 45 41 54 45 20 54 41 42 4c  ma, "CREATE TABL
172c0 45 20 25 5f 63 6f 6e 74 65 6e 74 28 22 29 3b 0a  E %_content(");.
172d0 20 20 61 70 70 65 6e 64 28 26 73 63 68 65 6d 61    append(&schema
172e0 2c 20 22 20 20 64 6f 63 69 64 20 49 4e 54 45 47  , "  docid INTEG
172f0 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 22  ER PRIMARY KEY,"
17300 29 3b 0a 20 20 61 70 70 65 6e 64 4c 69 73 74 28  );.  appendList(
17310 26 73 63 68 65 6d 61 2c 20 73 70 65 63 2e 6e 43  &schema, spec.nC
17320 6f 6c 75 6d 6e 2c 20 73 70 65 63 2e 61 7a 43 6f  olumn, spec.azCo
17330 6e 74 65 6e 74 43 6f 6c 75 6d 6e 29 3b 0a 20 20  ntentColumn);.  
17340 61 70 70 65 6e 64 28 26 73 63 68 65 6d 61 2c 20  append(&schema, 
17350 22 29 22 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c  ")");.  rc = sql
17360 5f 65 78 65 63 28 64 62 2c 20 73 70 65 63 2e 7a  _exec(db, spec.z
17370 44 62 2c 20 73 70 65 63 2e 7a 4e 61 6d 65 2c 20  Db, spec.zName, 
17380 73 74 72 69 6e 67 42 75 66 66 65 72 44 61 74 61  stringBufferData
17390 28 26 73 63 68 65 6d 61 29 29 3b 0a 20 20 73 74  (&schema));.  st
173a0 72 69 6e 67 42 75 66 66 65 72 44 65 73 74 72 6f  ringBufferDestro
173b0 79 28 26 73 63 68 65 6d 61 29 3b 0a 20 20 69 66  y(&schema);.  if
173c0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
173d0 29 20 67 6f 74 6f 20 6f 75 74 3b 0a 0a 20 20 72  ) goto out;..  r
173e0 63 20 3d 20 73 71 6c 5f 65 78 65 63 28 64 62 2c  c = sql_exec(db,
173f0 20 73 70 65 63 2e 7a 44 62 2c 20 73 70 65 63 2e   spec.zDb, spec.
17400 7a 4e 61 6d 65 2c 0a 20 20 20 20 20 20 20 20 20  zName,.         
17410 20 20 20 20 20 20 20 22 63 72 65 61 74 65 20 74         "create t
17420 61 62 6c 65 20 25 5f 73 65 67 6d 65 6e 74 73 28  able %_segments(
17430 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ".              
17440 20 20 22 20 20 62 6c 6f 63 6b 69 64 20 49 4e 54    "  blockid INT
17450 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59  EGER PRIMARY KEY
17460 2c 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ,".             
17470 20 20 20 22 20 20 62 6c 6f 63 6b 20 62 6c 6f 62     "  block blob
17480 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ".              
17490 20 20 22 29 3b 22 0a 20 20 20 20 20 20 20 20 20    ");".         
174a0 20 20 20 20 20 20 20 29 3b 0a 20 20 69 66 28 20         );.  if( 
174b0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
174c0 67 6f 74 6f 20 6f 75 74 3b 0a 0a 20 20 72 63 20  goto out;..  rc 
174d0 3d 20 73 71 6c 5f 65 78 65 63 28 64 62 2c 20 73  = sql_exec(db, s
174e0 70 65 63 2e 7a 44 62 2c 20 73 70 65 63 2e 7a 4e  pec.zDb, spec.zN
174f0 61 6d 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ame,.           
17500 20 20 20 20 20 22 63 72 65 61 74 65 20 74 61 62       "create tab
17510 6c 65 20 25 5f 73 65 67 64 69 72 28 22 0a 20 20  le %_segdir(".  
17520 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22 20                " 
17530 20 6c 65 76 65 6c 20 69 6e 74 65 67 65 72 2c 22   level integer,"
17540 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
17550 20 22 20 20 69 64 78 20 69 6e 74 65 67 65 72 2c   "  idx integer,
17560 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ".              
17570 20 20 22 20 20 73 74 61 72 74 5f 62 6c 6f 63 6b    "  start_block
17580 20 69 6e 74 65 67 65 72 2c 22 0a 20 20 20 20 20   integer,".     
17590 20 20 20 20 20 20 20 20 20 20 20 22 20 20 6c 65             "  le
175a0 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 6b 20 69  aves_end_block i
175b0 6e 74 65 67 65 72 2c 22 0a 20 20 20 20 20 20 20  nteger,".       
175c0 20 20 20 20 20 20 20 20 20 22 20 20 65 6e 64 5f           "  end_
175d0 62 6c 6f 63 6b 20 69 6e 74 65 67 65 72 2c 22 0a  block integer,".
175e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
175f0 22 20 20 72 6f 6f 74 20 62 6c 6f 62 2c 22 0a 20  "  root blob,". 
17600 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22                 "
17610 20 20 70 72 69 6d 61 72 79 20 6b 65 79 28 6c 65    primary key(le
17620 76 65 6c 2c 20 69 64 78 29 22 0a 20 20 20 20 20  vel, idx)".     
17630 20 20 20 20 20 20 20 20 20 20 20 22 29 3b 22 29             ");")
17640 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
17650 54 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 6f 75 74  TE_OK ) goto out
17660 3b 0a 0a 20 20 72 63 20 3d 20 63 6f 6e 73 74 72  ;..  rc = constr
17670 75 63 74 56 74 61 62 28 64 62 2c 20 28 66 74 73  uctVtab(db, (fts
17680 33 48 61 73 68 20 2a 29 70 41 75 78 2c 20 26 73  3Hash *)pAux, &s
17690 70 65 63 2c 20 70 70 56 54 61 62 2c 20 70 7a 45  pec, ppVTab, pzE
176a0 72 72 29 3b 0a 0a 6f 75 74 3a 0a 20 20 63 6c 65  rr);..out:.  cle
176b0 61 72 54 61 62 6c 65 53 70 65 63 28 26 73 70 65  arTableSpec(&spe
176c0 63 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  c);.  return rc;
176d0 0a 7d 0a 0a 2f 2a 20 44 65 63 69 64 65 20 68 6f  .}../* Decide ho
176e0 77 20 74 6f 20 68 61 6e 64 6c 65 20 61 6e 20 53  w to handle an S
176f0 51 4c 20 71 75 65 72 79 2e 20 2a 2f 0a 73 74 61  QL query. */.sta
17700 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74  tic int fulltext
17710 42 65 73 74 49 6e 64 65 78 28 73 71 6c 69 74 65  BestIndex(sqlite
17720 33 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20 73  3_vtab *pVTab, s
17730 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66  qlite3_index_inf
17740 6f 20 2a 70 49 6e 66 6f 29 7b 0a 20 20 66 75 6c  o *pInfo){.  ful
17750 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 20 3d 20  ltext_vtab *v = 
17760 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
17770 29 70 56 54 61 62 3b 0a 20 20 69 6e 74 20 69 3b  )pVTab;.  int i;
17780 0a 20 20 46 54 53 54 52 41 43 45 28 28 22 46 54  .  FTSTRACE(("FT
17790 53 33 20 42 65 73 74 49 6e 64 65 78 5c 6e 22 29  S3 BestIndex\n")
177a0 29 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  );..  for(i=0; i
177b0 3c 70 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61  <pInfo->nConstra
177c0 69 6e 74 3b 20 2b 2b 69 29 7b 0a 20 20 20 20 63  int; ++i){.    c
177d0 6f 6e 73 74 20 73 74 72 75 63 74 20 73 71 6c 69  onst struct sqli
177e0 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72  te3_index_constr
177f0 61 69 6e 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e  aint *pConstrain
17800 74 3b 0a 20 20 20 20 70 43 6f 6e 73 74 72 61 69  t;.    pConstrai
17810 6e 74 20 3d 20 26 70 49 6e 66 6f 2d 3e 61 43 6f  nt = &pInfo->aCo
17820 6e 73 74 72 61 69 6e 74 5b 69 5d 3b 0a 20 20 20  nstraint[i];.   
17830 20 69 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74   if( pConstraint
17840 2d 3e 75 73 61 62 6c 65 20 29 20 7b 0a 20 20 20  ->usable ) {.   
17850 20 20 20 69 66 28 20 28 70 43 6f 6e 73 74 72 61     if( (pConstra
17860 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 2d 31  int->iColumn==-1
17870 20 7c 7c 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d   || pConstraint-
17880 3e 69 43 6f 6c 75 6d 6e 3d 3d 76 2d 3e 6e 43 6f  >iColumn==v->nCo
17890 6c 75 6d 6e 2b 31 29 20 26 26 0a 20 20 20 20 20  lumn+1) &&.     
178a0 20 20 20 20 20 70 43 6f 6e 73 74 72 61 69 6e 74       pConstraint
178b0 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 44  ->op==SQLITE_IND
178c0 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 45 51  EX_CONSTRAINT_EQ
178d0 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49 6e 66   ){.        pInf
178e0 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 51 55 45 52  o->idxNum = QUER
178f0 59 5f 44 4f 43 49 44 3b 20 20 20 20 20 20 2f 2a  Y_DOCID;      /*
17900 20 6c 6f 6f 6b 75 70 20 62 79 20 64 6f 63 69 64   lookup by docid
17910 20 2a 2f 0a 20 20 20 20 20 20 20 20 46 54 53 54   */.        FTST
17920 52 41 43 45 28 28 22 46 54 53 33 20 51 55 45 52  RACE(("FTS3 QUER
17930 59 5f 44 4f 43 49 44 5c 6e 22 29 29 3b 0a 20 20  Y_DOCID\n"));.  
17940 20 20 20 20 7d 20 65 6c 73 65 20 69 66 28 20 70      } else if( p
17950 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 69 43 6f 6c  Constraint->iCol
17960 75 6d 6e 3e 3d 30 20 26 26 20 70 43 6f 6e 73 74  umn>=0 && pConst
17970 72 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3c 3d  raint->iColumn<=
17980 76 2d 3e 6e 43 6f 6c 75 6d 6e 20 26 26 0a 20 20  v->nColumn &&.  
17990 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
179a0 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 3d 3d  Constraint->op==
179b0 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e  SQLITE_INDEX_CON
179c0 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 20 29 7b  STRAINT_MATCH ){
179d0 0a 20 20 20 20 20 20 20 20 2f 2a 20 66 75 6c 6c  .        /* full
179e0 2d 74 65 78 74 20 73 65 61 72 63 68 20 2a 2f 0a  -text search */.
179f0 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 69          pInfo->i
17a00 64 78 4e 75 6d 20 3d 20 51 55 45 52 59 5f 46 55  dxNum = QUERY_FU
17a10 4c 4c 54 45 58 54 20 2b 20 70 43 6f 6e 73 74 72  LLTEXT + pConstr
17a20 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20  aint->iColumn;. 
17a30 20 20 20 20 20 20 20 46 54 53 54 52 41 43 45 28         FTSTRACE(
17a40 28 22 46 54 53 33 20 51 55 45 52 59 5f 46 55 4c  ("FTS3 QUERY_FUL
17a50 4c 54 45 58 54 20 25 64 5c 6e 22 2c 20 70 43 6f  LTEXT %d\n", pCo
17a60 6e 73 74 72 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d  nstraint->iColum
17a70 6e 29 29 3b 0a 20 20 20 20 20 20 7d 20 65 6c 73  n));.      } els
17a80 65 20 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20 20  e continue;..   
17a90 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74     pInfo->aConst
17aa0 72 61 69 6e 74 55 73 61 67 65 5b 69 5d 2e 61 72  raintUsage[i].ar
17ab0 67 76 49 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20  gvIndex = 1;.   
17ac0 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74     pInfo->aConst
17ad0 72 61 69 6e 74 55 73 61 67 65 5b 69 5d 2e 6f 6d  raintUsage[i].om
17ae0 69 74 20 3d 20 31 3b 0a 0a 20 20 20 20 20 20 2f  it = 1;..      /
17af0 2a 20 41 6e 20 61 72 62 69 74 72 61 72 79 20 76  * An arbitrary v
17b00 61 6c 75 65 20 66 6f 72 20 6e 6f 77 2e 0a 20 20  alue for now..  
17b10 20 20 20 20 20 2a 20 54 4f 44 4f 3a 20 50 65 72       * TODO: Per
17b20 68 61 70 73 20 64 6f 63 69 64 20 6d 61 74 63 68  haps docid match
17b30 65 73 20 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e  es should be con
17b40 73 69 64 65 72 65 64 20 63 68 65 61 70 65 72 20  sidered cheaper 
17b50 74 68 61 6e 0a 20 20 20 20 20 20 20 2a 20 66 75  than.       * fu
17b60 6c 6c 2d 74 65 78 74 20 73 65 61 72 63 68 65 73  ll-text searches
17b70 2e 20 2a 2f 0a 20 20 20 20 20 20 70 49 6e 66 6f  . */.      pInfo
17b80 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20  ->estimatedCost 
17b90 3d 20 31 2e 30 3b 20 20 20 0a 0a 20 20 20 20 20  = 1.0;   ..     
17ba0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
17bb0 4b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70  K;.    }.  }.  p
17bc0 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 51  Info->idxNum = Q
17bd0 55 45 52 59 5f 47 45 4e 45 52 49 43 3b 0a 20 20  UERY_GENERIC;.  
17be0 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
17bf0 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
17c00 66 75 6c 6c 74 65 78 74 44 69 73 63 6f 6e 6e 65  fulltextDisconne
17c10 63 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  ct(sqlite3_vtab 
17c20 2a 70 56 54 61 62 29 7b 0a 20 20 46 54 53 54 52  *pVTab){.  FTSTR
17c30 41 43 45 28 28 22 46 54 53 33 20 44 69 73 63 6f  ACE(("FTS3 Disco
17c40 6e 6e 65 63 74 20 25 70 5c 6e 22 2c 20 70 56 54  nnect %p\n", pVT
17c50 61 62 29 29 3b 0a 20 20 66 75 6c 6c 74 65 78 74  ab));.  fulltext
17c60 5f 76 74 61 62 5f 64 65 73 74 72 6f 79 28 28 66  _vtab_destroy((f
17c70 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 70  ulltext_vtab *)p
17c80 56 54 61 62 29 3b 0a 20 20 72 65 74 75 72 6e 20  VTab);.  return 
17c90 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74  SQLITE_OK;.}..st
17ca0 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78  atic int fulltex
17cb0 74 44 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33  tDestroy(sqlite3
17cc0 5f 76 74 61 62 20 2a 70 56 54 61 62 29 7b 0a 20  _vtab *pVTab){. 
17cd0 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a   fulltext_vtab *
17ce0 76 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f 76 74  v = (fulltext_vt
17cf0 61 62 20 2a 29 70 56 54 61 62 3b 0a 20 20 69 6e  ab *)pVTab;.  in
17d00 74 20 72 63 3b 0a 0a 20 20 46 54 53 54 52 41 43  t rc;..  FTSTRAC
17d10 45 28 28 22 46 54 53 33 20 44 65 73 74 72 6f 79  E(("FTS3 Destroy
17d20 20 25 70 5c 6e 22 2c 20 70 56 54 61 62 29 29 3b   %p\n", pVTab));
17d30 0a 20 20 72 63 20 3d 20 73 71 6c 5f 65 78 65 63  .  rc = sql_exec
17d40 28 76 2d 3e 64 62 2c 20 76 2d 3e 7a 44 62 2c 20  (v->db, v->zDb, 
17d50 76 2d 3e 7a 4e 61 6d 65 2c 0a 20 20 20 20 20 20  v->zName,.      
17d60 20 20 20 20 20 20 20 20 20 20 22 64 72 6f 70 20            "drop 
17d70 74 61 62 6c 65 20 69 66 20 65 78 69 73 74 73 20  table if exists 
17d80 25 5f 63 6f 6e 74 65 6e 74 3b 22 0a 20 20 20 20  %_content;".    
17d90 20 20 20 20 20 20 20 20 20 20 20 20 22 64 72 6f              "dro
17da0 70 20 74 61 62 6c 65 20 69 66 20 65 78 69 73 74  p table if exist
17db0 73 20 25 5f 73 65 67 6d 65 6e 74 73 3b 22 0a 20  s %_segments;". 
17dc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22                 "
17dd0 64 72 6f 70 20 74 61 62 6c 65 20 69 66 20 65 78  drop table if ex
17de0 69 73 74 73 20 25 5f 73 65 67 64 69 72 3b 22 0a  ists %_segdir;".
17df0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17e00 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
17e10 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
17e20 72 63 3b 0a 0a 20 20 66 75 6c 6c 74 65 78 74 5f  rc;..  fulltext_
17e30 76 74 61 62 5f 64 65 73 74 72 6f 79 28 28 66 75  vtab_destroy((fu
17e40 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 70 56  lltext_vtab *)pV
17e50 54 61 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  Tab);.  return S
17e60 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61  QLITE_OK;.}..sta
17e70 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74  tic int fulltext
17e80 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  Open(sqlite3_vta
17e90 62 20 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65  b *pVTab, sqlite
17ea0 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a  3_vtab_cursor **
17eb0 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 66 75 6c  ppCursor){.  ful
17ec0 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 63 3b  ltext_cursor *c;
17ed0 0a 0a 20 20 63 20 3d 20 28 66 75 6c 6c 74 65 78  ..  c = (fulltex
17ee0 74 5f 63 75 72 73 6f 72 20 2a 29 20 73 71 6c 69  t_cursor *) sqli
17ef0 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
17f00 66 28 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f  f(fulltext_curso
17f10 72 29 29 3b 0a 20 20 69 66 28 20 63 20 29 7b 0a  r));.  if( c ){.
17f20 20 20 20 20 6d 65 6d 73 65 74 28 63 2c 20 30 2c      memset(c, 0,
17f30 20 73 69 7a 65 6f 66 28 66 75 6c 6c 74 65 78 74   sizeof(fulltext
17f40 5f 63 75 72 73 6f 72 29 29 3b 0a 20 20 20 20 2f  _cursor));.    /
17f50 2a 20 73 71 6c 69 74 65 20 77 69 6c 6c 20 69 6e  * sqlite will in
17f60 69 74 69 61 6c 69 7a 65 20 63 2d 3e 62 61 73 65  itialize c->base
17f70 20 2a 2f 0a 20 20 20 20 2a 70 70 43 75 72 73 6f   */.    *ppCurso
17f80 72 20 3d 20 26 63 2d 3e 62 61 73 65 3b 0a 20 20  r = &c->base;.  
17f90 20 20 46 54 53 54 52 41 43 45 28 28 22 46 54 53    FTSTRACE(("FTS
17fa0 33 20 4f 70 65 6e 20 25 70 3a 20 25 70 5c 6e 22  3 Open %p: %p\n"
17fb0 2c 20 70 56 54 61 62 2c 20 63 29 29 3b 0a 20 20  , pVTab, c));.  
17fc0 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
17fd0 4f 4b 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  OK;.  }else{.   
17fe0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
17ff0 4f 4d 45 4d 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20  OMEM;.  }.}../* 
18000 46 72 65 65 20 61 6c 6c 20 6f 66 20 74 68 65 20  Free all of the 
18010 64 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f  dynamically allo
18020 63 61 74 65 64 20 6d 65 6d 6f 72 79 20 68 65 6c  cated memory hel
18030 64 20 62 79 20 74 68 65 0a 2a 2a 20 53 6e 69 70  d by the.** Snip
18040 70 65 74 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  pet.*/.static vo
18050 69 64 20 73 6e 69 70 70 65 74 43 6c 65 61 72 28  id snippetClear(
18060 53 6e 69 70 70 65 74 20 2a 70 29 7b 0a 20 20 73  Snippet *p){.  s
18070 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61  qlite3_free(p->a
18080 4d 61 74 63 68 29 3b 0a 20 20 73 71 6c 69 74 65  Match);.  sqlite
18090 33 5f 66 72 65 65 28 70 2d 3e 7a 4f 66 66 73 65  3_free(p->zOffse
180a0 74 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  t);.  sqlite3_fr
180b0 65 65 28 70 2d 3e 7a 53 6e 69 70 70 65 74 29 3b  ee(p->zSnippet);
180c0 0a 20 20 43 4c 45 41 52 28 70 29 3b 0a 7d 0a 0a  .  CLEAR(p);.}..
180d0 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 61 20 73  /*.** Append a s
180e0 69 6e 67 6c 65 20 65 6e 74 72 79 20 74 6f 20 74  ingle entry to t
180f0 68 65 20 70 2d 3e 61 4d 61 74 63 68 5b 5d 20 6c  he p->aMatch[] l
18100 6f 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  og..*/.static vo
18110 69 64 20 73 6e 69 70 70 65 74 41 70 70 65 6e 64  id snippetAppend
18120 4d 61 74 63 68 28 0a 20 20 53 6e 69 70 70 65 74  Match(.  Snippet
18130 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20 20   *p,            
18140 20 20 20 2f 2a 20 41 70 70 65 6e 64 20 74 68 65     /* Append the
18150 20 65 6e 74 72 79 20 74 6f 20 74 68 69 73 20 73   entry to this s
18160 6e 69 70 70 65 74 20 2a 2f 0a 20 20 69 6e 74 20  nippet */.  int 
18170 69 43 6f 6c 2c 20 69 6e 74 20 69 54 65 72 6d 2c  iCol, int iTerm,
18180 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63 6f 6c        /* The col
18190 75 6d 6e 20 61 6e 64 20 71 75 65 72 79 20 74 65  umn and query te
181a0 72 6d 20 2a 2f 0a 20 20 69 6e 74 20 69 54 6f 6b  rm */.  int iTok
181b0 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  en,             
181c0 20 20 2f 2a 20 4d 61 74 63 68 69 6e 67 20 74 6f    /* Matching to
181d0 6b 65 6e 20 69 6e 20 64 6f 63 75 6d 65 6e 74 20  ken in document 
181e0 2a 2f 0a 20 20 69 6e 74 20 69 53 74 61 72 74 2c  */.  int iStart,
181f0 20 69 6e 74 20 6e 42 79 74 65 20 20 20 20 20 2f   int nByte     /
18200 2a 20 4f 66 66 73 65 74 20 61 6e 64 20 73 69 7a  * Offset and siz
18210 65 20 6f 66 20 74 68 65 20 6d 61 74 63 68 20 2a  e of the match *
18220 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  /.){.  int i;.  
18230 73 74 72 75 63 74 20 73 6e 69 70 70 65 74 4d 61  struct snippetMa
18240 74 63 68 20 2a 70 4d 61 74 63 68 3b 0a 20 20 69  tch *pMatch;.  i
18250 66 28 20 70 2d 3e 6e 4d 61 74 63 68 2b 31 3e 3d  f( p->nMatch+1>=
18260 70 2d 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20 20 20  p->nAlloc ){.   
18270 20 70 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 70 2d 3e   p->nAlloc = p->
18280 6e 41 6c 6c 6f 63 2a 32 20 2b 20 31 30 3b 0a 20  nAlloc*2 + 10;. 
18290 20 20 20 70 2d 3e 61 4d 61 74 63 68 20 3d 20 73     p->aMatch = s
182a0 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63 28 70  qlite3_realloc(p
182b0 2d 3e 61 4d 61 74 63 68 2c 20 70 2d 3e 6e 41 6c  ->aMatch, p->nAl
182c0 6c 6f 63 2a 73 69 7a 65 6f 66 28 70 2d 3e 61 4d  loc*sizeof(p->aM
182d0 61 74 63 68 5b 30 5d 29 20 29 3b 0a 20 20 20 20  atch[0]) );.    
182e0 69 66 28 20 70 2d 3e 61 4d 61 74 63 68 3d 3d 30  if( p->aMatch==0
182f0 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 6e 4d 61   ){.      p->nMa
18300 74 63 68 20 3d 20 30 3b 0a 20 20 20 20 20 20 70  tch = 0;.      p
18310 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 30 3b 0a 20 20  ->nAlloc = 0;.  
18320 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20      return;.    
18330 7d 0a 20 20 7d 0a 20 20 69 20 3d 20 70 2d 3e 6e  }.  }.  i = p->n
18340 4d 61 74 63 68 2b 2b 3b 0a 20 20 70 4d 61 74 63  Match++;.  pMatc
18350 68 20 3d 20 26 70 2d 3e 61 4d 61 74 63 68 5b 69  h = &p->aMatch[i
18360 5d 3b 0a 20 20 70 4d 61 74 63 68 2d 3e 69 43 6f  ];.  pMatch->iCo
18370 6c 20 3d 20 69 43 6f 6c 3b 0a 20 20 70 4d 61 74  l = iCol;.  pMat
18380 63 68 2d 3e 69 54 65 72 6d 20 3d 20 69 54 65 72  ch->iTerm = iTer
18390 6d 3b 0a 20 20 70 4d 61 74 63 68 2d 3e 69 54 6f  m;.  pMatch->iTo
183a0 6b 65 6e 20 3d 20 69 54 6f 6b 65 6e 3b 0a 20 20  ken = iToken;.  
183b0 70 4d 61 74 63 68 2d 3e 69 53 74 61 72 74 20 3d  pMatch->iStart =
183c0 20 69 53 74 61 72 74 3b 0a 20 20 70 4d 61 74 63   iStart;.  pMatc
183d0 68 2d 3e 6e 42 79 74 65 20 3d 20 6e 42 79 74 65  h->nByte = nByte
183e0 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 69 7a 69 6e  ;.}../*.** Sizin
183f0 67 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 6f  g information fo
18400 72 20 74 68 65 20 63 69 72 63 75 6c 61 72 20 62  r the circular b
18410 75 66 66 65 72 20 75 73 65 64 20 69 6e 20 73 6e  uffer used in sn
18420 69 70 70 65 74 4f 66 66 73 65 74 73 4f 66 43 6f  ippetOffsetsOfCo
18430 6c 75 6d 6e 28 29 0a 2a 2f 0a 23 64 65 66 69 6e  lumn().*/.#defin
18440 65 20 46 54 53 33 5f 52 4f 54 4f 52 5f 53 5a 20  e FTS3_ROTOR_SZ 
18450 20 20 28 33 32 29 0a 23 64 65 66 69 6e 65 20 46    (32).#define F
18460 54 53 33 5f 52 4f 54 4f 52 5f 4d 41 53 4b 20 28  TS3_ROTOR_MASK (
18470 46 54 53 33 5f 52 4f 54 4f 52 5f 53 5a 2d 31 29  FTS3_ROTOR_SZ-1)
18480 0a 0a 2f 2a 0a 2a 2a 20 46 75 6e 63 74 69 6f 6e  ../*.** Function
18490 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
184a0 75 67 68 20 74 68 65 20 74 6f 6b 65 6e 73 20 6f  ugh the tokens o
184b0 66 20 61 20 63 6f 6d 70 69 6c 65 64 20 65 78 70  f a compiled exp
184c0 72 65 73 73 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 45  ression..**.** E
184d0 78 63 65 70 74 2c 20 73 6b 69 70 20 61 6c 6c 20  xcept, skip all 
184e0 74 6f 6b 65 6e 73 20 6f 6e 20 74 68 65 20 72 69  tokens on the ri
184f0 67 68 74 2d 68 61 6e 64 20 73 69 64 65 20 6f 66  ght-hand side of
18500 20 61 20 4e 4f 54 20 6f 70 65 72 61 74 6f 72 2e   a NOT operator.
18510 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
18520 6e 20 69 73 20 75 73 65 64 20 74 6f 20 66 69 6e  n is used to fin
18530 64 20 74 6f 6b 65 6e 73 20 61 73 20 70 61 72 74  d tokens as part
18540 20 6f 66 20 73 6e 69 70 70 65 74 20 61 6e 64 20   of snippet and 
18550 6f 66 66 73 65 74 0a 2a 2a 20 67 65 6e 65 72 61  offset.** genera
18560 74 69 6f 6e 20 61 6e 64 20 77 65 20 64 6f 20 6e  tion and we do n
18570 74 20 77 61 6e 74 20 73 6e 69 70 70 65 74 73 20  t want snippets 
18580 61 6e 64 20 6f 66 66 73 65 74 73 20 74 6f 20 72  and offsets to r
18590 65 70 6f 72 74 20 6d 61 74 63 68 65 73 0a 2a 2a  eport matches.**
185a0 20 66 6f 72 20 74 6f 6b 65 6e 73 20 6f 6e 20 74   for tokens on t
185b0 68 65 20 52 48 53 20 6f 66 20 61 20 4e 4f 54 2e  he RHS of a NOT.
185c0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
185d0 74 73 33 4e 65 78 74 45 78 70 72 54 6f 6b 65 6e  ts3NextExprToken
185e0 28 46 74 73 33 45 78 70 72 20 2a 2a 70 70 45 78  (Fts3Expr **ppEx
185f0 70 72 2c 20 69 6e 74 20 2a 70 69 54 6f 6b 65 6e  pr, int *piToken
18600 29 7b 0a 20 20 46 74 73 33 45 78 70 72 20 2a 70  ){.  Fts3Expr *p
18610 20 3d 20 2a 70 70 45 78 70 72 3b 0a 20 20 69 6e   = *ppExpr;.  in
18620 74 20 69 54 6f 6b 65 6e 20 3d 20 2a 70 69 54 6f  t iToken = *piTo
18630 6b 65 6e 3b 0a 20 20 69 66 28 20 69 54 6f 6b 65  ken;.  if( iToke
18640 6e 3c 30 20 29 7b 0a 20 20 20 20 2f 2a 20 49 6e  n<0 ){.    /* In
18650 20 74 68 69 73 20 63 61 73 65 20 74 68 65 20 65   this case the e
18660 78 70 72 65 73 73 69 6f 6e 20 70 20 69 73 20 74  xpression p is t
18670 68 65 20 72 6f 6f 74 20 6f 66 20 61 6e 20 65 78  he root of an ex
18680 70 72 65 73 73 69 6f 6e 20 74 72 65 65 2e 0a 20  pression tree.. 
18690 20 20 20 2a 2a 20 4d 6f 76 65 20 74 6f 20 74 68     ** Move to th
186a0 65 20 66 69 72 73 74 20 74 6f 6b 65 6e 20 69 6e  e first token in
186b0 20 74 68 65 20 65 78 70 72 65 73 73 69 6f 6e 20   the expression 
186c0 74 72 65 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  tree..    */.   
186d0 20 77 68 69 6c 65 28 20 70 2d 3e 70 4c 65 66 74   while( p->pLeft
186e0 20 29 7b 0a 20 20 20 20 20 20 70 20 3d 20 70 2d   ){.      p = p-
186f0 3e 70 4c 65 66 74 3b 0a 20 20 20 20 7d 0a 20 20  >pLeft;.    }.  
18700 20 20 69 54 6f 6b 65 6e 20 3d 20 30 3b 0a 20 20    iToken = 0;.  
18710 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72  }else{.    asser
18720 74 28 70 20 26 26 20 70 2d 3e 65 54 79 70 65 3d  t(p && p->eType=
18730 3d 46 54 53 51 55 45 52 59 5f 50 48 52 41 53 45  =FTSQUERY_PHRASE
18740 20 29 3b 0a 20 20 20 20 69 66 28 20 69 54 6f 6b   );.    if( iTok
18750 65 6e 3c 28 70 2d 3e 70 50 68 72 61 73 65 2d 3e  en<(p->pPhrase->
18760 6e 54 6f 6b 65 6e 2d 31 29 20 29 7b 0a 20 20 20  nToken-1) ){.   
18770 20 20 20 69 54 6f 6b 65 6e 2b 2b 3b 0a 20 20 20     iToken++;.   
18780 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 54   }else{.      iT
18790 6f 6b 65 6e 20 3d 20 30 3b 0a 20 20 20 20 20 20  oken = 0;.      
187a0 77 68 69 6c 65 28 20 70 2d 3e 70 50 61 72 65 6e  while( p->pParen
187b0 74 20 26 26 20 70 2d 3e 70 50 61 72 65 6e 74 2d  t && p->pParent-
187c0 3e 70 4c 65 66 74 21 3d 70 20 29 7b 0a 20 20 20  >pLeft!=p ){.   
187d0 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e       assert( p->
187e0 70 50 61 72 65 6e 74 2d 3e 70 52 69 67 68 74 3d  pParent->pRight=
187f0 3d 70 20 29 3b 0a 20 20 20 20 20 20 20 20 70 20  =p );.        p 
18800 3d 20 70 2d 3e 70 50 61 72 65 6e 74 3b 0a 20 20  = p->pParent;.  
18810 20 20 20 20 7d 0a 20 20 20 20 20 20 70 20 3d 20      }.      p = 
18820 70 2d 3e 70 50 61 72 65 6e 74 3b 0a 20 20 20 20  p->pParent;.    
18830 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20    if( p ){.     
18840 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 70 52     assert( p->pR
18850 69 67 68 74 21 3d 30 20 29 3b 0a 20 20 20 20 20  ight!=0 );.     
18860 20 20 20 70 20 3d 20 70 2d 3e 70 52 69 67 68 74     p = p->pRight
18870 3b 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65 28  ;.        while(
18880 20 70 2d 3e 70 4c 65 66 74 20 29 7b 0a 20 20 20   p->pLeft ){.   
18890 20 20 20 20 20 20 20 70 20 3d 20 70 2d 3e 70 4c         p = p->pL
188a0 65 66 74 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  eft;.        }. 
188b0 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
188c0 0a 0a 20 20 2a 70 70 45 78 70 72 20 3d 20 70 3b  ..  *ppExpr = p;
188d0 0a 20 20 2a 70 69 54 6f 6b 65 6e 20 3d 20 69 54  .  *piToken = iT
188e0 6f 6b 65 6e 3b 0a 20 20 72 65 74 75 72 6e 20 70  oken;.  return p
188f0 3f 31 3a 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  ?1:0;.}../*.** R
18900 65 74 75 72 6e 20 54 52 55 45 20 69 66 20 74 68  eturn TRUE if th
18910 65 20 65 78 70 72 65 73 73 69 6f 6e 20 6e 6f 64  e expression nod
18920 65 20 70 45 78 70 72 20 69 73 20 6c 6f 63 61 74  e pExpr is locat
18930 65 64 20 62 65 6e 65 61 74 68 20 74 68 65 0a 2a  ed beneath the.*
18940 2a 20 52 48 53 20 6f 66 20 61 20 4e 4f 54 20 6f  * RHS of a NOT o
18950 70 65 72 61 74 6f 72 2e 0a 2a 2f 0a 73 74 61 74  perator..*/.stat
18960 69 63 20 69 6e 74 20 66 74 73 33 45 78 70 72 42  ic int fts3ExprB
18970 65 6e 65 61 74 68 4e 6f 74 28 46 74 73 33 45 78  eneathNot(Fts3Ex
18980 70 72 20 2a 70 29 7b 0a 20 20 46 74 73 33 45 78  pr *p){.  Fts3Ex
18990 70 72 20 2a 70 50 61 72 65 6e 74 3b 0a 20 20 77  pr *pParent;.  w
189a0 68 69 6c 65 28 20 70 20 29 7b 0a 20 20 20 20 70  hile( p ){.    p
189b0 50 61 72 65 6e 74 20 3d 20 70 2d 3e 70 50 61 72  Parent = p->pPar
189c0 65 6e 74 3b 0a 20 20 20 20 69 66 28 20 70 50 61  ent;.    if( pPa
189d0 72 65 6e 74 20 26 26 20 70 50 61 72 65 6e 74 2d  rent && pParent-
189e0 3e 65 54 79 70 65 3d 3d 46 54 53 51 55 45 52 59  >eType==FTSQUERY
189f0 5f 4e 4f 54 20 26 26 20 70 50 61 72 65 6e 74 2d  _NOT && pParent-
18a00 3e 70 52 69 67 68 74 3d 3d 70 20 29 7b 0a 20 20  >pRight==p ){.  
18a10 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20      return 1;.  
18a20 20 20 7d 0a 20 20 20 20 70 20 3d 20 70 50 61 72    }.    p = pPar
18a30 65 6e 74 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ent;.  }.  retur
18a40 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64  n 0;.}../*.** Ad
18a50 64 20 65 6e 74 72 69 65 73 20 74 6f 20 70 53 6e  d entries to pSn
18a60 69 70 70 65 74 2d 3e 61 4d 61 74 63 68 5b 5d 20  ippet->aMatch[] 
18a70 66 6f 72 20 65 76 65 72 79 20 6d 61 74 63 68 20  for every match 
18a80 74 68 61 74 20 6f 63 63 75 72 73 20 61 67 61 69  that occurs agai
18a90 6e 73 74 0a 2a 2a 20 64 6f 63 75 6d 65 6e 74 20  nst.** document 
18aa0 7a 44 6f 63 5b 30 2e 2e 6e 44 6f 63 2d 31 5d 20  zDoc[0..nDoc-1] 
18ab0 77 68 69 63 68 20 69 73 20 73 74 6f 72 65 64 20  which is stored 
18ac0 69 6e 20 63 6f 6c 75 6d 6e 20 69 43 6f 6c 75 6d  in column iColum
18ad0 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  n..*/.static voi
18ae0 64 20 73 6e 69 70 70 65 74 4f 66 66 73 65 74 73  d snippetOffsets
18af0 4f 66 43 6f 6c 75 6d 6e 28 0a 20 20 66 75 6c 6c  OfColumn(.  full
18b00 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 70 43 75  text_cursor *pCu
18b10 72 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68  r,         /* Th
18b20 65 20 66 75 6c 6c 74 65 73 74 20 73 65 61 72 63  e fulltest searc
18b30 68 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 53 6e  h cursor */.  Sn
18b40 69 70 70 65 74 20 2a 70 53 6e 69 70 70 65 74 2c  ippet *pSnippet,
18b50 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
18b60 54 68 65 20 53 6e 69 70 70 65 74 20 6f 62 6a 65  The Snippet obje
18b70 63 74 20 74 6f 20 62 65 20 66 69 6c 6c 65 64 20  ct to be filled 
18b80 69 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c  in */.  int iCol
18b90 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  umn,            
18ba0 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20         /* Index 
18bb0 6f 66 20 66 75 6c 6c 74 65 78 74 20 74 61 62 6c  of fulltext tabl
18bc0 65 20 63 6f 6c 75 6d 6e 20 2a 2f 0a 20 20 63 6f  e column */.  co
18bd0 6e 73 74 20 63 68 61 72 20 2a 7a 44 6f 63 2c 20  nst char *zDoc, 
18be0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
18bf0 54 65 78 74 20 6f 66 20 74 68 65 20 66 75 6c 6c  Text of the full
18c00 74 65 78 74 20 74 61 62 6c 65 20 63 6f 6c 75 6d  text table colum
18c10 6e 20 2a 2f 0a 20 20 69 6e 74 20 6e 44 6f 63 20  n */.  int nDoc 
18c20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18c30 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20        /* Length 
18c40 6f 66 20 7a 44 6f 63 20 69 6e 20 62 79 74 65 73  of zDoc in bytes
18c50 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 73   */.){.  const s
18c60 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72  qlite3_tokenizer
18c70 5f 6d 6f 64 75 6c 65 20 2a 70 54 4d 6f 64 75 6c  _module *pTModul
18c80 65 3b 20 20 2f 2a 20 54 68 65 20 74 6f 6b 65 6e  e;  /* The token
18c90 69 7a 65 72 20 6d 6f 64 75 6c 65 20 2a 2f 0a 20  izer module */. 
18ca0 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a   sqlite3_tokeniz
18cb0 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 3b 20  er *pTokenizer; 
18cc0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
18cd0 68 65 20 73 70 65 63 69 66 69 63 20 74 6f 6b 65  he specific toke
18ce0 6e 69 7a 65 72 20 2a 2f 0a 20 20 73 71 6c 69 74  nizer */.  sqlit
18cf0 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63 75 72  e3_tokenizer_cur
18d00 73 6f 72 20 2a 70 54 43 75 72 73 6f 72 3b 20 20  sor *pTCursor;  
18d10 20 20 20 20 20 20 2f 2a 20 54 6f 6b 65 6e 69 7a        /* Tokeniz
18d20 65 72 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66  er cursor */.  f
18d30 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 70 56  ulltext_vtab *pV
18d40 74 61 62 3b 20 20 20 20 20 20 20 20 20 20 20 20  tab;            
18d50 20 20 20 20 2f 2a 20 54 68 65 20 66 75 6c 6c 20      /* The full 
18d60 74 65 78 74 20 69 6e 64 65 78 20 2a 2f 0a 20 20  text index */.  
18d70 69 6e 74 20 6e 43 6f 6c 75 6d 6e 3b 20 20 20 20  int nColumn;    
18d80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18d90 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
18da0 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65  f columns in the
18db0 20 69 6e 64 65 78 20 2a 2f 0a 20 20 69 6e 74 20   index */.  int 
18dc0 69 2c 20 6a 3b 20 20 20 20 20 20 20 20 20 20 20  i, j;           
18dd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18de0 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72   /* Loop counter
18df0 73 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20  s */.  int rc;  
18e00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18e10 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
18e20 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
18e30 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6d 61 74  unsigned int mat
18e40 63 68 2c 20 70 72 65 76 4d 61 74 63 68 3b 20 20  ch, prevMatch;  
18e50 20 20 20 20 20 2f 2a 20 50 68 72 61 73 65 20 73       /* Phrase s
18e60 65 61 72 63 68 20 62 69 74 6d 61 73 6b 73 20 2a  earch bitmasks *
18e70 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
18e80 7a 54 6f 6b 65 6e 3b 20 20 20 20 20 20 20 20 20  zToken;         
18e90 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
18ea0 20 74 6f 6b 65 6e 20 66 72 6f 6d 20 74 68 65 20   token from the 
18eb0 74 6f 6b 65 6e 69 7a 65 72 20 2a 2f 0a 20 20 69  tokenizer */.  i
18ec0 6e 74 20 6e 54 6f 6b 65 6e 3b 20 20 20 20 20 20  nt nToken;      
18ed0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18ee0 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 7a      /* Size of z
18ef0 54 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69  Token */.  int i
18f00 42 65 67 69 6e 2c 20 69 45 6e 64 2c 20 69 50 6f  Begin, iEnd, iPo
18f10 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s;              
18f20 2f 2a 20 4f 66 66 73 65 74 73 20 6f 66 20 62 65  /* Offsets of be
18f30 67 69 6e 6e 69 6e 67 20 61 6e 64 20 65 6e 64 20  ginning and end 
18f40 2a 2f 0a 0a 20 20 2f 2a 20 54 68 65 20 66 6f 6c  */..  /* The fol
18f50 6c 6f 77 69 6e 67 20 76 61 72 69 61 62 6c 65 73  lowing variables
18f60 20 6b 65 65 70 20 61 20 63 69 72 63 75 6c 61 72   keep a circular
18f70 20 62 75 66 66 65 72 20 6f 66 20 74 68 65 20 6c   buffer of the l
18f80 61 73 74 0a 20 20 2a 2a 20 66 65 77 20 74 6f 6b  ast.  ** few tok
18f90 65 6e 73 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ens */.  unsigne
18fa0 64 20 69 6e 74 20 69 52 6f 74 6f 72 20 3d 20 30  d int iRotor = 0
18fb0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
18fc0 20 49 6e 64 65 78 20 6f 66 20 63 75 72 72 65 6e   Index of curren
18fd0 74 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74  t token */.  int
18fe0 20 69 52 6f 74 6f 72 42 65 67 69 6e 5b 46 54 53   iRotorBegin[FTS
18ff0 33 5f 52 4f 54 4f 52 5f 53 5a 5d 3b 20 20 20 20  3_ROTOR_SZ];    
19000 20 20 2f 2a 20 42 65 67 69 6e 6e 69 6e 67 20 6f    /* Beginning o
19010 66 66 73 65 74 20 6f 66 20 74 6f 6b 65 6e 20 2a  ffset of token *
19020 2f 0a 20 20 69 6e 74 20 69 52 6f 74 6f 72 4c 65  /.  int iRotorLe
19030 6e 5b 46 54 53 33 5f 52 4f 54 4f 52 5f 53 5a 5d  n[FTS3_ROTOR_SZ]
19040 3b 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67  ;        /* Leng
19050 74 68 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 0a  th of token */..
19060 20 20 70 56 74 61 62 20 3d 20 63 75 72 73 6f 72    pVtab = cursor
19070 5f 76 74 61 62 28 70 43 75 72 29 3b 0a 20 20 6e  _vtab(pCur);.  n
19080 43 6f 6c 75 6d 6e 20 3d 20 70 56 74 61 62 2d 3e  Column = pVtab->
19090 6e 43 6f 6c 75 6d 6e 3b 0a 20 20 70 54 6f 6b 65  nColumn;.  pToke
190a0 6e 69 7a 65 72 20 3d 20 70 56 74 61 62 2d 3e 70  nizer = pVtab->p
190b0 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20 70 54 4d  Tokenizer;.  pTM
190c0 6f 64 75 6c 65 20 3d 20 70 54 6f 6b 65 6e 69 7a  odule = pTokeniz
190d0 65 72 2d 3e 70 4d 6f 64 75 6c 65 3b 0a 20 20 72  er->pModule;.  r
190e0 63 20 3d 20 70 54 4d 6f 64 75 6c 65 2d 3e 78 4f  c = pTModule->xO
190f0 70 65 6e 28 70 54 6f 6b 65 6e 69 7a 65 72 2c 20  pen(pTokenizer, 
19100 7a 44 6f 63 2c 20 6e 44 6f 63 2c 20 26 70 54 43  zDoc, nDoc, &pTC
19110 75 72 73 6f 72 29 3b 0a 20 20 69 66 28 20 72 63  ursor);.  if( rc
19120 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 70 54 43   ) return;.  pTC
19130 75 72 73 6f 72 2d 3e 70 54 6f 6b 65 6e 69 7a 65  ursor->pTokenize
19140 72 20 3d 20 70 54 6f 6b 65 6e 69 7a 65 72 3b 0a  r = pTokenizer;.
19150 0a 20 20 70 72 65 76 4d 61 74 63 68 20 3d 20 30  .  prevMatch = 0
19160 3b 0a 20 20 77 68 69 6c 65 28 20 21 70 54 4d 6f  ;.  while( !pTMo
19170 64 75 6c 65 2d 3e 78 4e 65 78 74 28 70 54 43 75  dule->xNext(pTCu
19180 72 73 6f 72 2c 20 26 7a 54 6f 6b 65 6e 2c 20 26  rsor, &zToken, &
19190 6e 54 6f 6b 65 6e 2c 20 26 69 42 65 67 69 6e 2c  nToken, &iBegin,
191a0 20 26 69 45 6e 64 2c 20 26 69 50 6f 73 29 20 29   &iEnd, &iPos) )
191b0 7b 0a 20 20 20 20 46 74 73 33 45 78 70 72 20 2a  {.    Fts3Expr *
191c0 70 49 74 65 72 20 3d 20 70 43 75 72 2d 3e 70 45  pIter = pCur->pE
191d0 78 70 72 3b 0a 20 20 20 20 69 6e 74 20 69 49 74  xpr;.    int iIt
191e0 65 72 20 3d 20 2d 31 3b 0a 20 20 20 20 69 52 6f  er = -1;.    iRo
191f0 74 6f 72 42 65 67 69 6e 5b 69 52 6f 74 6f 72 26  torBegin[iRotor&
19200 46 54 53 33 5f 52 4f 54 4f 52 5f 4d 41 53 4b 5d  FTS3_ROTOR_MASK]
19210 20 3d 20 69 42 65 67 69 6e 3b 0a 20 20 20 20 69   = iBegin;.    i
19220 52 6f 74 6f 72 4c 65 6e 5b 69 52 6f 74 6f 72 26  RotorLen[iRotor&
19230 46 54 53 33 5f 52 4f 54 4f 52 5f 4d 41 53 4b 5d  FTS3_ROTOR_MASK]
19240 20 3d 20 69 45 6e 64 2d 69 42 65 67 69 6e 3b 0a   = iEnd-iBegin;.
19250 20 20 20 20 6d 61 74 63 68 20 3d 20 30 3b 0a 20      match = 0;. 
19260 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 28 46     for(i=0; i<(F
19270 54 53 33 5f 52 4f 54 4f 52 5f 53 5a 2d 31 29 20  TS3_ROTOR_SZ-1) 
19280 26 26 20 66 74 73 33 4e 65 78 74 45 78 70 72 54  && fts3NextExprT
19290 6f 6b 65 6e 28 26 70 49 74 65 72 2c 20 26 69 49  oken(&pIter, &iI
192a0 74 65 72 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  ter); i++){.    
192b0 20 20 69 6e 74 20 6e 50 68 72 61 73 65 3b 20 20    int nPhrase;  
192c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
192d0 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 74    /* Number of t
192e0 6f 6b 65 6e 73 20 69 6e 20 63 75 72 72 65 6e 74  okens in current
192f0 20 70 68 72 61 73 65 20 2a 2f 0a 20 20 20 20 20   phrase */.     
19300 20 73 74 72 75 63 74 20 50 68 72 61 73 65 54 6f   struct PhraseTo
19310 6b 65 6e 20 2a 70 54 6f 6b 65 6e 3b 20 20 20 20  ken *pToken;    
19320 20 2f 2a 20 43 75 72 72 65 6e 74 20 74 6f 6b 65   /* Current toke
19330 6e 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 69  n */.      int i
19340 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  Col;            
19350 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
19360 6c 75 6d 6e 20 69 6e 64 65 78 20 2a 2f 0a 0a 20  lumn index */.. 
19370 20 20 20 20 20 69 66 28 20 66 74 73 33 45 78 70       if( fts3Exp
19380 72 42 65 6e 65 61 74 68 4e 6f 74 28 70 49 74 65  rBeneathNot(pIte
19390 72 29 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20  r) ) continue;. 
193a0 20 20 20 20 20 6e 50 68 72 61 73 65 20 3d 20 70       nPhrase = p
193b0 49 74 65 72 2d 3e 70 50 68 72 61 73 65 2d 3e 6e  Iter->pPhrase->n
193c0 54 6f 6b 65 6e 3b 0a 20 20 20 20 20 20 70 54 6f  Token;.      pTo
193d0 6b 65 6e 20 3d 20 26 70 49 74 65 72 2d 3e 70 50  ken = &pIter->pP
193e0 68 72 61 73 65 2d 3e 61 54 6f 6b 65 6e 5b 69 49  hrase->aToken[iI
193f0 74 65 72 5d 3b 0a 20 20 20 20 20 20 69 43 6f 6c  ter];.      iCol
19400 20 3d 20 70 49 74 65 72 2d 3e 70 50 68 72 61 73   = pIter->pPhras
19410 65 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20  e->iColumn;.    
19420 20 20 69 66 28 20 69 43 6f 6c 3e 3d 30 20 26 26    if( iCol>=0 &&
19430 20 69 43 6f 6c 3c 6e 43 6f 6c 75 6d 6e 20 26 26   iCol<nColumn &&
19440 20 69 43 6f 6c 21 3d 69 43 6f 6c 75 6d 6e 20 29   iCol!=iColumn )
19450 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20   continue;.     
19460 20 69 66 28 20 70 54 6f 6b 65 6e 2d 3e 6e 3e 6e   if( pToken->n>n
19470 54 6f 6b 65 6e 20 29 20 63 6f 6e 74 69 6e 75 65  Token ) continue
19480 3b 0a 20 20 20 20 20 20 69 66 28 20 21 70 54 6f  ;.      if( !pTo
19490 6b 65 6e 2d 3e 69 73 50 72 65 66 69 78 20 26 26  ken->isPrefix &&
194a0 20 70 54 6f 6b 65 6e 2d 3e 6e 3c 6e 54 6f 6b 65   pToken->n<nToke
194b0 6e 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20  n ) continue;.  
194c0 20 20 20 20 61 73 73 65 72 74 28 20 70 54 6f 6b      assert( pTok
194d0 65 6e 2d 3e 6e 3c 3d 6e 54 6f 6b 65 6e 20 29 3b  en->n<=nToken );
194e0 0a 20 20 20 20 20 20 69 66 28 20 6d 65 6d 63 6d  .      if( memcm
194f0 70 28 70 54 6f 6b 65 6e 2d 3e 7a 2c 20 7a 54 6f  p(pToken->z, zTo
19500 6b 65 6e 2c 20 70 54 6f 6b 65 6e 2d 3e 6e 29 20  ken, pToken->n) 
19510 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20  ) continue;.    
19520 20 20 69 66 28 20 69 49 74 65 72 3e 30 20 26 26    if( iIter>0 &&
19530 20 28 70 72 65 76 4d 61 74 63 68 20 26 20 28 31   (prevMatch & (1
19540 3c 3c 69 29 29 3d 3d 30 20 29 20 63 6f 6e 74 69  <<i))==0 ) conti
19550 6e 75 65 3b 0a 20 20 20 20 20 20 6d 61 74 63 68  nue;.      match
19560 20 7c 3d 20 31 3c 3c 69 3b 0a 20 20 20 20 20 20   |= 1<<i;.      
19570 69 66 28 20 69 3d 3d 28 46 54 53 33 5f 52 4f 54  if( i==(FTS3_ROT
19580 4f 52 5f 53 5a 2d 32 29 20 7c 7c 20 6e 50 68 72  OR_SZ-2) || nPhr
19590 61 73 65 3d 3d 69 49 74 65 72 2b 31 20 29 7b 0a  ase==iIter+1 ){.
195a0 20 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 6e 50          for(j=nP
195b0 68 72 61 73 65 2d 31 3b 20 6a 3e 3d 30 3b 20 6a  hrase-1; j>=0; j
195c0 2d 2d 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  --){.          i
195d0 6e 74 20 6b 20 3d 20 28 69 52 6f 74 6f 72 2d 6a  nt k = (iRotor-j
195e0 29 20 26 20 46 54 53 33 5f 52 4f 54 4f 52 5f 4d  ) & FTS3_ROTOR_M
195f0 41 53 4b 3b 0a 20 20 20 20 20 20 20 20 20 20 73  ASK;.          s
19600 6e 69 70 70 65 74 41 70 70 65 6e 64 4d 61 74 63  nippetAppendMatc
19610 68 28 70 53 6e 69 70 70 65 74 2c 20 69 43 6f 6c  h(pSnippet, iCol
19620 75 6d 6e 2c 20 69 2d 6a 2c 20 69 50 6f 73 2d 6a  umn, i-j, iPos-j
19630 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
19640 20 20 69 52 6f 74 6f 72 42 65 67 69 6e 5b 6b 5d    iRotorBegin[k]
19650 2c 20 69 52 6f 74 6f 72 4c 65 6e 5b 6b 5d 29 3b  , iRotorLen[k]);
19660 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
19670 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70 72 65   }.    }.    pre
19680 76 4d 61 74 63 68 20 3d 20 6d 61 74 63 68 3c 3c  vMatch = match<<
19690 31 3b 0a 20 20 20 20 69 52 6f 74 6f 72 2b 2b 3b  1;.    iRotor++;
196a0 0a 20 20 7d 0a 20 20 70 54 4d 6f 64 75 6c 65 2d  .  }.  pTModule-
196b0 3e 78 43 6c 6f 73 65 28 70 54 43 75 72 73 6f 72  >xClose(pTCursor
196c0 29 3b 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  );  .}../*.** Re
196d0 6d 6f 76 65 20 65 6e 74 72 69 65 73 20 66 72 6f  move entries fro
196e0 6d 20 74 68 65 20 70 53 6e 69 70 70 65 74 20 73  m the pSnippet s
196f0 74 72 75 63 74 75 72 65 20 74 6f 20 61 63 63 6f  tructure to acco
19700 75 6e 74 20 66 6f 72 20 74 68 65 20 4e 45 41 52  unt for the NEAR
19710 0a 2a 2a 20 6f 70 65 72 61 74 6f 72 2e 20 57 68  .** operator. Wh
19720 65 6e 20 74 68 69 73 20 69 73 20 63 61 6c 6c 65  en this is calle
19730 64 2c 20 70 53 6e 69 70 70 65 74 20 63 6f 6e 74  d, pSnippet cont
19740 61 69 6e 73 20 74 68 65 20 6c 69 73 74 20 6f 66  ains the list of
19750 20 74 6f 6b 65 6e 20 0a 2a 2a 20 6f 66 66 73 65   token .** offse
19760 74 73 20 70 72 6f 64 75 63 65 64 20 62 79 20 74  ts produced by t
19770 72 65 61 74 69 6e 67 20 61 6c 6c 20 4e 45 41 52  reating all NEAR
19780 20 6f 70 65 72 61 74 6f 72 73 20 61 73 20 41 4e   operators as AN
19790 44 20 6f 70 65 72 61 74 6f 72 73 2e 0a 2a 2a 20  D operators..** 
197a0 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65  This function re
197b0 6d 6f 76 65 73 20 61 6e 79 20 65 6e 74 72 69 65  moves any entrie
197c0 73 20 74 68 61 74 20 73 68 6f 75 6c 64 20 6e 6f  s that should no
197d0 74 20 62 65 20 70 72 65 73 65 6e 74 20 61 66 74  t be present aft
197e0 65 72 0a 2a 2a 20 61 63 63 6f 75 6e 74 69 6e 67  er.** accounting
197f0 20 66 6f 72 20 74 68 65 20 4e 45 41 52 20 72 65   for the NEAR re
19800 73 74 72 69 63 74 69 6f 6e 2e 20 46 6f 72 20 65  striction. For e
19810 78 61 6d 70 6c 65 2c 20 69 66 20 74 68 65 20 71  xample, if the q
19820 75 65 72 69 65 64 0a 2a 2a 20 64 6f 63 75 6d 65  ueried.** docume
19830 6e 74 20 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  nt is:.**.**    
19840 20 22 41 20 42 20 43 20 44 20 45 20 41 22 0a 2a   "A B C D E A".*
19850 2a 0a 2a 2a 20 61 6e 64 20 74 68 65 20 71 75 65  *.** and the que
19860 72 79 20 69 73 3a 0a 2a 2a 20 0a 2a 2a 20 20 20  ry is:.** .**   
19870 20 20 41 20 4e 45 41 52 2f 30 20 45 0a 2a 2a 0a    A NEAR/0 E.**.
19880 2a 2a 20 74 68 65 6e 20 77 68 65 6e 20 74 68 69  ** then when thi
19890 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
198a0 6c 6c 65 64 20 74 68 65 20 53 6e 69 70 70 65 74  lled the Snippet
198b0 20 63 6f 6e 74 61 69 6e 73 20 74 6f 6b 65 6e 20   contains token 
198c0 6f 66 66 73 65 74 73 0a 2a 2a 20 30 2c 20 34 20  offsets.** 0, 4 
198d0 61 6e 64 20 35 2e 20 54 68 69 73 20 66 75 6e 63  and 5. This func
198e0 74 69 6f 6e 20 72 65 6d 6f 76 65 73 20 74 68 65  tion removes the
198f0 20 22 30 22 20 65 6e 74 72 79 20 28 62 65 63 61   "0" entry (beca
19900 75 73 65 20 74 68 65 20 66 69 72 73 74 20 41 0a  use the first A.
19910 2a 2a 20 69 73 20 6e 6f 74 20 6e 65 61 72 20 65  ** is not near e
19920 6e 6f 75 67 68 20 74 6f 20 61 6e 20 45 29 2e 0a  nough to an E)..
19930 2a 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 69 73 20  **.** When this 
19940 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
19950 65 64 2c 20 74 68 65 20 76 61 6c 75 65 20 70 6f  ed, the value po
19960 69 6e 74 65 64 20 74 6f 20 62 79 20 70 61 72 61  inted to by para
19970 6d 65 74 65 72 20 70 69 4c 65 66 74 20 69 73 0a  meter piLeft is.
19980 2a 2a 20 74 68 65 20 69 6e 74 65 67 65 72 20 69  ** the integer i
19990 64 20 6f 66 20 74 68 65 20 6c 65 66 74 2d 6d 6f  d of the left-mo
199a0 73 74 20 74 6f 6b 65 6e 20 69 6e 20 74 68 65 20  st token in the 
199b0 65 78 70 72 65 73 73 69 6f 6e 20 74 72 65 65 20  expression tree 
199c0 68 65 61 64 65 64 20 62 79 0a 2a 2a 20 70 45 78  headed by.** pEx
199d0 70 72 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  pr. This functio
199e0 6e 20 69 6e 63 72 65 6d 65 6e 74 73 20 2a 70 69  n increments *pi
199f0 4c 65 66 74 20 62 79 20 74 68 65 20 74 6f 74 61  Left by the tota
19a00 6c 20 6e 75 6d 62 65 72 20 6f 66 20 74 6f 6b 65  l number of toke
19a10 6e 73 0a 2a 2a 20 69 6e 20 74 68 65 20 65 78 70  ns.** in the exp
19a20 72 65 73 73 69 6f 6e 20 74 72 65 65 20 68 65 61  ression tree hea
19a30 64 65 64 20 62 79 20 70 45 78 70 72 2e 0a 2a 2a  ded by pExpr..**
19a40 0a 2a 2a 20 52 65 74 75 72 6e 20 31 20 69 66 20  .** Return 1 if 
19a50 61 6e 79 20 74 72 69 6d 6d 69 6e 67 20 6f 63 63  any trimming occ
19a60 75 72 73 2e 20 20 52 65 74 75 72 6e 20 30 20 69  urs.  Return 0 i
19a70 66 20 6e 6f 20 74 72 69 6d 6d 69 6e 67 20 69 73  f no trimming is
19a80 20 72 65 71 75 69 72 65 64 2e 0a 2a 2f 0a 73 74   required..*/.st
19a90 61 74 69 63 20 69 6e 74 20 74 72 69 6d 53 6e 69  atic int trimSni
19aa0 70 70 65 74 4f 66 66 73 65 74 73 28 0a 20 20 46  ppetOffsets(.  F
19ab0 74 73 33 45 78 70 72 20 2a 70 45 78 70 72 2c 20  ts3Expr *pExpr, 
19ac0 20 20 20 20 20 2f 2a 20 54 68 65 20 73 65 61 72       /* The sear
19ad0 63 68 20 65 78 70 72 65 73 73 69 6f 6e 20 2a 2f  ch expression */
19ae0 0a 20 20 53 6e 69 70 70 65 74 20 2a 70 53 6e 69  .  Snippet *pSni
19af0 70 70 65 74 2c 20 20 20 20 2f 2a 20 54 68 65 20  ppet,    /* The 
19b00 73 65 74 20 6f 66 20 73 6e 69 70 70 65 74 20 6f  set of snippet o
19b10 66 66 73 65 74 73 20 74 6f 20 62 65 20 74 72 69  ffsets to be tri
19b20 6d 6d 65 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  mmed */.  int *p
19b30 69 4c 65 66 74 20 20 20 20 20 20 20 20 20 20 20  iLeft           
19b40 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6c 65 66 74  /* Index of left
19b50 2d 6d 6f 73 74 20 74 6f 6b 65 6e 20 69 6e 20 70  -most token in p
19b60 45 78 70 72 20 2a 2f 0a 29 7b 0a 20 20 69 66 28  Expr */.){.  if(
19b70 20 70 45 78 70 72 20 29 7b 0a 20 20 20 20 69 66   pExpr ){.    if
19b80 28 20 74 72 69 6d 53 6e 69 70 70 65 74 4f 66 66  ( trimSnippetOff
19b90 73 65 74 73 28 70 45 78 70 72 2d 3e 70 4c 65 66  sets(pExpr->pLef
19ba0 74 2c 20 70 53 6e 69 70 70 65 74 2c 20 70 69 4c  t, pSnippet, piL
19bb0 65 66 74 29 20 29 7b 0a 20 20 20 20 20 20 72 65  eft) ){.      re
19bc0 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d 0a 0a 20  turn 1;.    }.. 
19bd0 20 20 20 73 77 69 74 63 68 28 20 70 45 78 70 72     switch( pExpr
19be0 2d 3e 65 54 79 70 65 20 29 7b 0a 20 20 20 20 20  ->eType ){.     
19bf0 20 63 61 73 65 20 46 54 53 51 55 45 52 59 5f 50   case FTSQUERY_P
19c00 48 52 41 53 45 3a 0a 20 20 20 20 20 20 20 20 2a  HRASE:.        *
19c10 70 69 4c 65 66 74 20 2b 3d 20 70 45 78 70 72 2d  piLeft += pExpr-
19c20 3e 70 50 68 72 61 73 65 2d 3e 6e 54 6f 6b 65 6e  >pPhrase->nToken
19c30 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
19c40 0a 20 20 20 20 20 20 63 61 73 65 20 46 54 53 51  .      case FTSQ
19c50 55 45 52 59 5f 4e 45 41 52 3a 20 7b 0a 20 20 20  UERY_NEAR: {.   
19c60 20 20 20 20 20 2f 2a 20 54 68 65 20 72 69 67 68       /* The righ
19c70 74 2d 68 61 6e 64 2d 73 69 64 65 20 6f 66 20 61  t-hand-side of a
19c80 20 4e 45 41 52 20 6f 70 65 72 61 74 6f 72 20 69   NEAR operator i
19c90 73 20 61 6c 77 61 79 73 20 61 20 70 68 72 61 73  s always a phras
19ca0 65 2e 20 54 68 65 0a 20 20 20 20 20 20 20 20 2a  e. The.        *
19cb0 2a 20 6c 65 66 74 2d 68 61 6e 64 2d 73 69 64 65  * left-hand-side
19cc0 20 69 73 20 65 69 74 68 65 72 20 61 20 70 68 72   is either a phr
19cd0 61 73 65 20 6f 72 20 61 6e 20 65 78 70 72 65 73  ase or an expres
19ce0 73 69 6f 6e 20 74 72 65 65 20 74 68 61 74 20 69  sion tree that i
19cf0 73 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 69 74  s .        ** it
19d00 73 65 6c 66 20 68 65 61 64 65 64 20 62 79 20 61  self headed by a
19d10 20 4e 45 41 52 20 6f 70 65 72 61 74 6f 72 2e 20   NEAR operator. 
19d20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 6e  The following in
19d30 69 74 69 61 6c 69 7a 61 74 69 6f 6e 73 0a 20 20  itializations.  
19d40 20 20 20 20 20 20 2a 2a 20 73 65 74 20 6c 6f 63        ** set loc
19d50 61 6c 20 76 61 72 69 61 62 6c 65 20 69 4c 65 66  al variable iLef
19d60 74 20 74 6f 20 74 68 65 20 74 6f 6b 65 6e 20 6e  t to the token n
19d70 75 6d 62 65 72 20 6f 66 20 74 68 65 20 6c 65 66  umber of the lef
19d80 74 2d 6d 6f 73 74 0a 20 20 20 20 20 20 20 20 2a  t-most.        *
19d90 2a 20 74 6f 6b 65 6e 20 69 6e 20 74 68 65 20 72  * token in the r
19da0 69 67 68 74 2d 68 61 6e 64 20 70 68 72 61 73 65  ight-hand phrase
19db0 2c 20 61 6e 64 20 69 52 69 67 68 74 20 74 6f 20  , and iRight to 
19dc0 74 68 65 20 72 69 67 68 74 20 6d 6f 73 74 0a 20  the right most. 
19dd0 20 20 20 20 20 20 20 2a 2a 20 74 6f 6b 65 6e 20         ** token 
19de0 69 6e 20 74 68 65 20 73 61 6d 65 20 70 68 72 61  in the same phra
19df0 73 65 2e 20 46 6f 72 20 65 78 61 6d 70 6c 65 2c  se. For example,
19e00 20 69 66 20 77 65 20 68 61 64 3a 0a 20 20 20 20   if we had:.    
19e10 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a      **.        *
19e20 2a 20 20 20 20 20 3c 63 6f 6c 3e 20 4d 41 54 43  *     <col> MATC
19e30 48 20 27 22 61 62 63 20 64 65 66 22 20 4e 45 41  H '"abc def" NEA
19e40 52 2f 32 20 22 67 68 69 20 6a 6b 6c 22 27 0a 20  R/2 "ghi jkl"'. 
19e50 20 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20         **.      
19e60 20 20 2a 2a 20 74 68 65 6e 20 69 4c 65 66 74 20    ** then iLeft 
19e70 77 69 6c 6c 20 62 65 20 73 65 74 20 74 6f 20 32  will be set to 2
19e80 20 28 74 6f 6b 65 6e 20 6e 75 6d 62 65 72 20 6f   (token number o
19e90 66 20 67 68 69 29 20 61 6e 64 20 6e 54 6f 6b 65  f ghi) and nToke
19ea0 6e 20 77 69 6c 6c 0a 20 20 20 20 20 20 20 20 2a  n will.        *
19eb0 2a 20 62 65 20 73 65 74 20 74 6f 20 34 2e 0a 20  * be set to 4.. 
19ec0 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20         */.      
19ed0 20 20 46 74 73 33 45 78 70 72 20 2a 70 4c 65 66    Fts3Expr *pLef
19ee0 74 20 3d 20 70 45 78 70 72 2d 3e 70 4c 65 66 74  t = pExpr->pLeft
19ef0 3b 0a 20 20 20 20 20 20 20 20 46 74 73 33 45 78  ;.        Fts3Ex
19f00 70 72 20 2a 70 52 69 67 68 74 20 3d 20 70 45 78  pr *pRight = pEx
19f10 70 72 2d 3e 70 52 69 67 68 74 3b 0a 20 20 20 20  pr->pRight;.    
19f20 20 20 20 20 69 6e 74 20 69 4c 65 66 74 20 3d 20      int iLeft = 
19f30 2a 70 69 4c 65 66 74 3b 0a 20 20 20 20 20 20 20  *piLeft;.       
19f40 20 69 6e 74 20 6e 4e 65 61 72 20 3d 20 70 45 78   int nNear = pEx
19f50 70 72 2d 3e 6e 4e 65 61 72 3b 0a 20 20 20 20 20  pr->nNear;.     
19f60 20 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 20 3d 20     int nToken = 
19f70 70 52 69 67 68 74 2d 3e 70 50 68 72 61 73 65 2d  pRight->pPhrase-
19f80 3e 6e 54 6f 6b 65 6e 3b 0a 20 20 20 20 20 20 20  >nToken;.       
19f90 20 69 6e 74 20 6a 6a 2c 20 69 69 3b 0a 20 20 20   int jj, ii;.   
19fa0 20 20 20 20 20 69 66 28 20 70 4c 65 66 74 2d 3e       if( pLeft->
19fb0 65 54 79 70 65 3d 3d 46 54 53 51 55 45 52 59 5f  eType==FTSQUERY_
19fc0 4e 45 41 52 20 29 7b 0a 20 20 20 20 20 20 20 20  NEAR ){.        
19fd0 20 20 70 4c 65 66 74 20 3d 20 70 4c 65 66 74 2d    pLeft = pLeft-
19fe0 3e 70 52 69 67 68 74 3b 0a 20 20 20 20 20 20 20  >pRight;.       
19ff0 20 7d 0a 20 20 20 20 20 20 20 20 61 73 73 65 72   }.        asser
1a000 74 28 20 70 52 69 67 68 74 2d 3e 65 54 79 70 65  t( pRight->eType
1a010 3d 3d 46 54 53 51 55 45 52 59 5f 50 48 52 41 53  ==FTSQUERY_PHRAS
1a020 45 20 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73  E );.        ass
1a030 65 72 74 28 20 70 4c 65 66 74 2d 3e 65 54 79 70  ert( pLeft->eTyp
1a040 65 3d 3d 46 54 53 51 55 45 52 59 5f 50 48 52 41  e==FTSQUERY_PHRA
1a050 53 45 20 29 3b 0a 20 20 20 20 20 20 20 20 6e 54  SE );.        nT
1a060 6f 6b 65 6e 20 2b 3d 20 70 4c 65 66 74 2d 3e 70  oken += pLeft->p
1a070 50 68 72 61 73 65 2d 3e 6e 54 6f 6b 65 6e 3b 0a  Phrase->nToken;.
1a080 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 69 3d  .        for(ii=
1a090 30 3b 20 69 69 3c 70 53 6e 69 70 70 65 74 2d 3e  0; ii<pSnippet->
1a0a0 6e 4d 61 74 63 68 3b 20 69 69 2b 2b 29 7b 0a 20  nMatch; ii++){. 
1a0b0 20 20 20 20 20 20 20 20 20 73 74 72 75 63 74 20           struct 
1a0c0 73 6e 69 70 70 65 74 4d 61 74 63 68 20 2a 70 20  snippetMatch *p 
1a0d0 3d 20 26 70 53 6e 69 70 70 65 74 2d 3e 61 4d 61  = &pSnippet->aMa
1a0e0 74 63 68 5b 69 69 5d 3b 0a 20 20 20 20 20 20 20  tch[ii];.       
1a0f0 20 20 20 69 66 28 20 70 2d 3e 69 54 65 72 6d 3d     if( p->iTerm=
1a100 3d 69 4c 65 66 74 20 29 7b 0a 20 20 20 20 20 20  =iLeft ){.      
1a110 20 20 20 20 20 20 69 6e 74 20 69 73 4f 6b 20 3d        int isOk =
1a120 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20   0;.            
1a130 2f 2a 20 53 6e 69 70 70 65 74 20 69 69 20 69 73  /* Snippet ii is
1a140 20 61 6e 20 6f 63 63 75 72 65 6e 63 65 20 6f 66   an occurence of
1a150 20 71 75 65 72 79 20 74 65 72 6d 20 69 4c 65 66   query term iLef
1a160 74 20 69 6e 20 74 68 65 20 64 6f 63 75 6d 65 6e  t in the documen
1a170 74 2e 0a 20 20 20 20 20 20 20 20 20 20 20 20 2a  t..            *
1a180 2a 20 49 74 20 6f 63 63 75 72 73 20 61 74 20 70  * It occurs at p
1a190 6f 73 69 74 69 6f 6e 20 28 70 2d 3e 69 54 6f 6b  osition (p->iTok
1a1a0 65 6e 29 20 6f 66 20 74 68 65 20 64 6f 63 75 6d  en) of the docum
1a1b0 65 6e 74 2e 20 57 65 20 6e 6f 77 0a 20 20 20 20  ent. We now.    
1a1c0 20 20 20 20 20 20 20 20 2a 2a 20 73 65 61 72 63          ** searc
1a1d0 68 20 66 6f 72 20 61 6e 20 69 6e 73 74 61 6e 63  h for an instanc
1a1e0 65 20 6f 66 20 74 6f 6b 65 6e 20 28 69 4c 65 66  e of token (iLef
1a1f0 74 2d 31 29 20 73 6f 6d 65 77 68 65 72 65 20 69  t-1) somewhere i
1a200 6e 20 74 68 65 20 0a 20 20 20 20 20 20 20 20 20  n the .         
1a210 20 20 20 2a 2a 20 72 61 6e 67 65 20 28 70 2d 3e     ** range (p->
1a220 69 54 6f 6b 65 6e 20 2d 20 6e 4e 65 61 72 29 2e  iToken - nNear).
1a230 2e 2e 28 70 2d 3e 69 54 6f 6b 65 6e 20 2b 20 6e  ..(p->iToken + n
1a240 4e 65 61 72 20 2b 20 6e 54 6f 6b 65 6e 29 20 77  Near + nToken) w
1a250 69 74 68 69 6e 20 0a 20 20 20 20 20 20 20 20 20  ithin .         
1a260 20 20 20 2a 2a 20 74 68 65 20 73 65 74 20 6f 66     ** the set of
1a270 20 73 6e 69 70 70 65 74 4d 61 74 63 68 20 73 74   snippetMatch st
1a280 72 75 63 74 75 72 65 73 2e 20 49 66 20 6f 6e 65  ructures. If one
1a290 20 69 73 20 66 6f 75 6e 64 2c 20 70 72 6f 63 65   is found, proce
1a2a0 65 64 2e 20 0a 20 20 20 20 20 20 20 20 20 20 20  ed. .           
1a2b0 20 2a 2a 20 49 66 20 6f 6e 65 20 63 61 6e 6e 6f   ** If one canno
1a2c0 74 20 62 65 20 66 6f 75 6e 64 2c 20 74 68 65 6e  t be found, then
1a2d0 20 72 65 6d 6f 76 65 20 73 6e 69 70 70 65 74 73   remove snippets
1a2e0 20 69 69 2e 2e 28 69 69 2b 4e 2d 31 29 20 0a 20   ii..(ii+N-1) . 
1a2f0 20 20 20 20 20 20 20 20 20 20 20 2a 2a 20 66 72             ** fr
1a300 6f 6d 20 74 68 65 20 6d 61 74 63 68 69 6e 67 20  om the matching 
1a310 73 6e 69 70 70 65 74 73 2c 20 77 68 65 72 65 20  snippets, where 
1a320 4e 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  N is the number 
1a330 6f 66 20 74 6f 6b 65 6e 73 20 0a 20 20 20 20 20  of tokens .     
1a340 20 20 20 20 20 20 20 2a 2a 20 69 6e 20 70 68 72         ** in phr
1a350 61 73 65 20 70 52 69 67 68 74 2d 3e 70 50 68 72  ase pRight->pPhr
1a360 61 73 65 2e 0a 20 20 20 20 20 20 20 20 20 20 20  ase..           
1a370 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 20 20   */.            
1a380 66 6f 72 28 6a 6a 3d 30 3b 20 69 73 4f 6b 3d 3d  for(jj=0; isOk==
1a390 30 20 26 26 20 6a 6a 3c 70 53 6e 69 70 70 65 74  0 && jj<pSnippet
1a3a0 2d 3e 6e 4d 61 74 63 68 3b 20 6a 6a 2b 2b 29 7b  ->nMatch; jj++){
1a3b0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73  .              s
1a3c0 74 72 75 63 74 20 73 6e 69 70 70 65 74 4d 61 74  truct snippetMat
1a3d0 63 68 20 2a 70 32 20 3d 20 26 70 53 6e 69 70 70  ch *p2 = &pSnipp
1a3e0 65 74 2d 3e 61 4d 61 74 63 68 5b 6a 6a 5d 3b 0a  et->aMatch[jj];.
1a3f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
1a400 28 20 70 32 2d 3e 69 54 65 72 6d 3d 3d 28 69 4c  ( p2->iTerm==(iL
1a410 65 66 74 2d 31 29 20 29 7b 0a 20 20 20 20 20 20  eft-1) ){.      
1a420 20 20 20 20 20 20 20 20 20 20 69 66 28 20 70 32            if( p2
1a430 2d 3e 69 54 6f 6b 65 6e 3e 3d 28 70 2d 3e 69 54  ->iToken>=(p->iT
1a440 6f 6b 65 6e 2d 6e 4e 65 61 72 2d 31 29 20 0a 20  oken-nNear-1) . 
1a450 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a460 26 26 20 70 32 2d 3e 69 54 6f 6b 65 6e 3c 28 70  && p2->iToken<(p
1a470 2d 3e 69 54 6f 6b 65 6e 2b 6e 4e 65 61 72 2b 6e  ->iToken+nNear+n
1a480 54 6f 6b 65 6e 29 20 0a 20 20 20 20 20 20 20 20  Token) .        
1a490 20 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20          ){.     
1a4a0 20 20 20 20 20 20 20 20 20 20 20 20 20 69 73 4f               isO
1a4b0 6b 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20  k = 1;.         
1a4c0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
1a4d0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
1a4e0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
1a4f0 20 20 20 69 66 28 20 21 69 73 4f 6b 20 29 7b 0a     if( !isOk ){.
1a500 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e                in
1a510 74 20 6b 6b 3b 0a 20 20 20 20 20 20 20 20 20 20  t kk;.          
1a520 20 20 20 20 66 6f 72 28 6b 6b 3d 30 3b 20 6b 6b      for(kk=0; kk
1a530 3c 70 52 69 67 68 74 2d 3e 70 50 68 72 61 73 65  <pRight->pPhrase
1a540 2d 3e 6e 54 6f 6b 65 6e 3b 20 6b 6b 2b 2b 29 7b  ->nToken; kk++){
1a550 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1a560 20 70 53 6e 69 70 70 65 74 2d 3e 61 4d 61 74 63   pSnippet->aMatc
1a570 68 5b 6b 6b 2b 69 69 5d 2e 69 54 65 72 6d 20 3d  h[kk+ii].iTerm =
1a580 20 2d 32 3b 0a 20 20 20 20 20 20 20 20 20 20 20   -2;.           
1a590 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20     }.           
1a5a0 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20     return 1;.   
1a5b0 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
1a5c0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
1a5d0 20 69 66 28 20 70 2d 3e 69 54 65 72 6d 3d 3d 28   if( p->iTerm==(
1a5e0 69 4c 65 66 74 2d 31 29 20 29 7b 0a 20 20 20 20  iLeft-1) ){.    
1a5f0 20 20 20 20 20 20 20 20 69 6e 74 20 69 73 4f 6b          int isOk
1a600 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20   = 0;.          
1a610 20 20 66 6f 72 28 6a 6a 3d 30 3b 20 69 73 4f 6b    for(jj=0; isOk
1a620 3d 3d 30 20 26 26 20 6a 6a 3c 70 53 6e 69 70 70  ==0 && jj<pSnipp
1a630 65 74 2d 3e 6e 4d 61 74 63 68 3b 20 6a 6a 2b 2b  et->nMatch; jj++
1a640 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ){.             
1a650 20 73 74 72 75 63 74 20 73 6e 69 70 70 65 74 4d   struct snippetM
1a660 61 74 63 68 20 2a 70 32 20 3d 20 26 70 53 6e 69  atch *p2 = &pSni
1a670 70 70 65 74 2d 3e 61 4d 61 74 63 68 5b 6a 6a 5d  ppet->aMatch[jj]
1a680 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;.              
1a690 69 66 28 20 70 32 2d 3e 69 54 65 72 6d 3d 3d 69  if( p2->iTerm==i
1a6a0 4c 65 66 74 20 29 7b 0a 20 20 20 20 20 20 20 20  Left ){.        
1a6b0 20 20 20 20 20 20 20 20 69 66 28 20 70 32 2d 3e          if( p2->
1a6c0 69 54 6f 6b 65 6e 3c 3d 28 70 2d 3e 69 54 6f 6b  iToken<=(p->iTok
1a6d0 65 6e 2b 6e 4e 65 61 72 2b 31 29 20 0a 20 20 20  en+nNear+1) .   
1a6e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26 26                &&
1a6f0 20 70 32 2d 3e 69 54 6f 6b 65 6e 3e 28 70 2d 3e   p2->iToken>(p->
1a700 69 54 6f 6b 65 6e 2d 6e 4e 65 61 72 2d 6e 54 6f  iToken-nNear-nTo
1a710 6b 65 6e 29 20 0a 20 20 20 20 20 20 20 20 20 20  ken) .          
1a720 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20        ){.       
1a730 20 20 20 20 20 20 20 20 20 20 20 69 73 4f 6b 20             isOk 
1a740 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20 20  = 1;.           
1a750 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
1a760 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
1a770 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20     }.           
1a780 20 69 66 28 20 21 69 73 4f 6b 20 29 7b 0a 20 20   if( !isOk ){.  
1a790 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74 20              int 
1a7a0 6b 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  kk;.            
1a7b0 20 20 66 6f 72 28 6b 6b 3d 30 3b 20 6b 6b 3c 70    for(kk=0; kk<p
1a7c0 4c 65 66 74 2d 3e 70 50 68 72 61 73 65 2d 3e 6e  Left->pPhrase->n
1a7d0 54 6f 6b 65 6e 3b 20 6b 6b 2b 2b 29 7b 0a 20 20  Token; kk++){.  
1a7e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 53                pS
1a7f0 6e 69 70 70 65 74 2d 3e 61 4d 61 74 63 68 5b 69  nippet->aMatch[i
1a800 69 2d 6b 6b 5d 2e 69 54 65 72 6d 20 3d 20 2d 32  i-kk].iTerm = -2
1a810 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;.              
1a820 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  }.              
1a830 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 20 20  return 1;.      
1a840 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
1a850 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20    }.        }.  
1a860 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
1a870 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20     }.    }..    
1a880 69 66 28 20 74 72 69 6d 53 6e 69 70 70 65 74 4f  if( trimSnippetO
1a890 66 66 73 65 74 73 28 70 45 78 70 72 2d 3e 70 52  ffsets(pExpr->pR
1a8a0 69 67 68 74 2c 20 70 53 6e 69 70 70 65 74 2c 20  ight, pSnippet, 
1a8b0 70 69 4c 65 66 74 29 20 29 7b 0a 20 20 20 20 20  piLeft) ){.     
1a8c0 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d   return 1;.    }
1a8d0 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b  .  }.  return 0;
1a8e0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74  .}../*.** Comput
1a8f0 65 20 61 6c 6c 20 6f 66 66 73 65 74 73 20 66 6f  e all offsets fo
1a900 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 6f  r the current ro
1a910 77 20 6f 66 20 74 68 65 20 71 75 65 72 79 2e 20  w of the query. 
1a920 20 0a 2a 2a 20 49 66 20 74 68 65 20 6f 66 66 73   .** If the offs
1a930 65 74 73 20 68 61 76 65 20 61 6c 72 65 61 64 79  ets have already
1a940 20 62 65 65 6e 20 63 6f 6d 70 75 74 65 64 2c 20   been computed, 
1a950 74 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20  this routine is 
1a960 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a 73 74 61 74  a no-op..*/.stat
1a970 69 63 20 76 6f 69 64 20 73 6e 69 70 70 65 74 41  ic void snippetA
1a980 6c 6c 4f 66 66 73 65 74 73 28 66 75 6c 6c 74 65  llOffsets(fullte
1a990 78 74 5f 63 75 72 73 6f 72 20 2a 70 29 7b 0a 20  xt_cursor *p){. 
1a9a0 20 69 6e 74 20 6e 43 6f 6c 75 6d 6e 3b 0a 20 20   int nColumn;.  
1a9b0 69 6e 74 20 69 43 6f 6c 75 6d 6e 2c 20 69 3b 0a  int iColumn, i;.
1a9c0 20 20 69 6e 74 20 69 46 69 72 73 74 2c 20 69 4c    int iFirst, iL
1a9d0 61 73 74 3b 0a 20 20 69 6e 74 20 69 54 65 72 6d  ast;.  int iTerm
1a9e0 20 3d 20 30 3b 0a 20 20 66 75 6c 6c 74 65 78 74   = 0;.  fulltext
1a9f0 5f 76 74 61 62 20 2a 70 46 74 73 20 3d 20 63 75  _vtab *pFts = cu
1aa00 72 73 6f 72 5f 76 74 61 62 28 70 29 3b 0a 0a 20  rsor_vtab(p);.. 
1aa10 20 69 66 28 20 70 2d 3e 73 6e 69 70 70 65 74 2e   if( p->snippet.
1aa20 6e 4d 61 74 63 68 20 7c 7c 20 70 2d 3e 70 45 78  nMatch || p->pEx
1aa30 70 72 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  pr==0 ){.    ret
1aa40 75 72 6e 3b 0a 20 20 7d 0a 20 20 6e 43 6f 6c 75  urn;.  }.  nColu
1aa50 6d 6e 20 3d 20 70 46 74 73 2d 3e 6e 43 6f 6c 75  mn = pFts->nColu
1aa60 6d 6e 3b 0a 20 20 69 43 6f 6c 75 6d 6e 20 3d 20  mn;.  iColumn = 
1aa70 28 70 2d 3e 69 43 75 72 73 6f 72 54 79 70 65 20  (p->iCursorType 
1aa80 2d 20 51 55 45 52 59 5f 46 55 4c 4c 54 45 58 54  - QUERY_FULLTEXT
1aa90 29 3b 0a 20 20 69 66 28 20 69 43 6f 6c 75 6d 6e  );.  if( iColumn
1aaa0 3c 30 20 7c 7c 20 69 43 6f 6c 75 6d 6e 3e 3d 6e  <0 || iColumn>=n
1aab0 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20 2f 2a  Column ){.    /*
1aac0 20 4c 6f 6f 6b 20 66 6f 72 20 6d 61 74 63 68 65   Look for matche
1aad0 73 20 6f 76 65 72 20 61 6c 6c 20 63 6f 6c 75 6d  s over all colum
1aae0 6e 73 20 6f 66 20 74 68 65 20 66 75 6c 6c 2d 74  ns of the full-t
1aaf0 65 78 74 20 69 6e 64 65 78 20 2a 2f 0a 20 20 20  ext index */.   
1ab00 20 69 46 69 72 73 74 20 3d 20 30 3b 0a 20 20 20   iFirst = 0;.   
1ab10 20 69 4c 61 73 74 20 3d 20 6e 43 6f 6c 75 6d 6e   iLast = nColumn
1ab20 2d 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  -1;.  }else{.   
1ab30 20 2f 2a 20 4c 6f 6f 6b 20 66 6f 72 20 6d 61 74   /* Look for mat
1ab40 63 68 65 73 20 69 6e 20 74 68 65 20 69 43 6f 6c  ches in the iCol
1ab50 75 6d 6e 2d 74 68 20 63 6f 6c 75 6d 6e 20 6f 66  umn-th column of
1ab60 20 74 68 65 20 69 6e 64 65 78 20 6f 6e 6c 79 20   the index only 
1ab70 2a 2f 0a 20 20 20 20 69 46 69 72 73 74 20 3d 20  */.    iFirst = 
1ab80 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 69 4c 61  iColumn;.    iLa
1ab90 73 74 20 3d 20 69 43 6f 6c 75 6d 6e 3b 0a 20 20  st = iColumn;.  
1aba0 7d 0a 20 20 66 6f 72 28 69 3d 69 46 69 72 73 74  }.  for(i=iFirst
1abb0 3b 20 69 3c 3d 69 4c 61 73 74 3b 20 69 2b 2b 29  ; i<=iLast; i++)
1abc0 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  {.    const char
1abd0 20 2a 7a 44 6f 63 3b 0a 20 20 20 20 69 6e 74 20   *zDoc;.    int 
1abe0 6e 44 6f 63 3b 0a 20 20 20 20 7a 44 6f 63 20 3d  nDoc;.    zDoc =
1abf0 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71   (const char*)sq
1ac00 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78  lite3_column_tex
1ac10 74 28 70 2d 3e 70 53 74 6d 74 2c 20 69 2b 31 29  t(p->pStmt, i+1)
1ac20 3b 0a 20 20 20 20 6e 44 6f 63 20 3d 20 73 71 6c  ;.    nDoc = sql
1ac30 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65  ite3_column_byte
1ac40 73 28 70 2d 3e 70 53 74 6d 74 2c 20 69 2b 31 29  s(p->pStmt, i+1)
1ac50 3b 0a 20 20 20 20 73 6e 69 70 70 65 74 4f 66 66  ;.    snippetOff
1ac60 73 65 74 73 4f 66 43 6f 6c 75 6d 6e 28 70 2c 20  setsOfColumn(p, 
1ac70 26 70 2d 3e 73 6e 69 70 70 65 74 2c 20 69 2c 20  &p->snippet, i, 
1ac80 7a 44 6f 63 2c 20 6e 44 6f 63 29 3b 0a 20 20 7d  zDoc, nDoc);.  }
1ac90 0a 0a 20 20 77 68 69 6c 65 28 20 74 72 69 6d 53  ..  while( trimS
1aca0 6e 69 70 70 65 74 4f 66 66 73 65 74 73 28 70 2d  nippetOffsets(p-
1acb0 3e 70 45 78 70 72 2c 20 26 70 2d 3e 73 6e 69 70  >pExpr, &p->snip
1acc0 70 65 74 2c 20 26 69 54 65 72 6d 29 20 29 7b 0a  pet, &iTerm) ){.
1acd0 20 20 20 20 69 54 65 72 6d 20 3d 20 30 3b 0a 20      iTerm = 0;. 
1ace0 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 76   }.}../*.** Conv
1acf0 65 72 74 20 74 68 65 20 69 6e 66 6f 72 6d 61 74  ert the informat
1ad00 69 6f 6e 20 69 6e 20 74 68 65 20 61 4d 61 74 63  ion in the aMatc
1ad10 68 5b 5d 20 61 72 72 61 79 20 6f 66 20 74 68 65  h[] array of the
1ad20 20 73 6e 69 70 70 65 74 0a 2a 2a 20 69 6e 74 6f   snippet.** into
1ad30 20 74 68 65 20 73 74 72 69 6e 67 20 7a 4f 66 66   the string zOff
1ad40 73 65 74 5b 30 2e 2e 6e 4f 66 66 73 65 74 2d 31  set[0..nOffset-1
1ad50 5d 2e 20 54 68 69 73 20 73 74 72 69 6e 67 20 69  ]. This string i
1ad60 73 20 75 73 65 64 20 61 73 0a 2a 2a 20 74 68 65  s used as.** the
1ad70 20 72 65 74 75 72 6e 20 6f 66 20 74 68 65 20 53   return of the S
1ad80 51 4c 20 6f 66 66 73 65 74 73 28 29 20 66 75 6e  QL offsets() fun
1ad90 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  ction..*/.static
1ada0 20 76 6f 69 64 20 73 6e 69 70 70 65 74 4f 66 66   void snippetOff
1adb0 73 65 74 54 65 78 74 28 53 6e 69 70 70 65 74 20  setText(Snippet 
1adc0 2a 70 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  *p){.  int i;.  
1add0 69 6e 74 20 63 6e 74 20 3d 20 30 3b 0a 20 20 53  int cnt = 0;.  S
1ade0 74 72 69 6e 67 42 75 66 66 65 72 20 73 62 3b 0a  tringBuffer sb;.
1adf0 20 20 63 68 61 72 20 7a 42 75 66 5b 32 30 30 5d    char zBuf[200]
1ae00 3b 0a 20 20 69 66 28 20 70 2d 3e 7a 4f 66 66 73  ;.  if( p->zOffs
1ae10 65 74 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69  et ) return;.  i
1ae20 6e 69 74 53 74 72 69 6e 67 42 75 66 66 65 72 28  nitStringBuffer(
1ae30 26 73 62 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  &sb);.  for(i=0;
1ae40 20 69 3c 70 2d 3e 6e 4d 61 74 63 68 3b 20 69 2b   i<p->nMatch; i+
1ae50 2b 29 7b 0a 20 20 20 20 73 74 72 75 63 74 20 73  +){.    struct s
1ae60 6e 69 70 70 65 74 4d 61 74 63 68 20 2a 70 4d 61  nippetMatch *pMa
1ae70 74 63 68 20 3d 20 26 70 2d 3e 61 4d 61 74 63 68  tch = &p->aMatch
1ae80 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 70 4d 61  [i];.    if( pMa
1ae90 74 63 68 2d 3e 69 54 65 72 6d 3e 3d 30 20 29 7b  tch->iTerm>=0 ){
1aea0 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 73 6e 69  .      /* If sni
1aeb0 70 70 65 74 4d 61 74 63 68 2e 69 54 65 72 6d 20  ppetMatch.iTerm 
1aec0 69 73 20 6c 65 73 73 20 74 68 61 6e 20 30 2c 20  is less than 0, 
1aed0 74 68 65 6e 20 74 68 65 20 6d 61 74 63 68 20 77  then the match w
1aee0 61 73 20 0a 20 20 20 20 20 20 2a 2a 20 64 69 73  as .      ** dis
1aef0 63 61 72 64 65 64 20 61 73 20 70 61 72 74 20 6f  carded as part o
1af00 66 20 70 72 6f 63 65 73 73 69 6e 67 20 74 68 65  f processing the
1af10 20 4e 45 41 52 20 6f 70 65 72 61 74 6f 72 20 28   NEAR operator (
1af20 73 65 65 20 74 68 65 20 0a 20 20 20 20 20 20 2a  see the .      *
1af30 2a 20 74 72 69 6d 53 6e 69 70 70 65 74 4f 66 66  * trimSnippetOff
1af40 73 65 74 73 46 6f 72 4e 65 61 72 28 29 20 66 75  setsForNear() fu
1af50 6e 63 74 69 6f 6e 20 66 6f 72 20 64 65 74 61 69  nction for detai
1af60 6c 73 29 2e 20 49 67 6e 6f 72 65 20 0a 20 20 20  ls). Ignore .   
1af70 20 20 20 2a 2a 20 69 74 20 69 6e 20 74 68 69 73     ** it in this
1af80 20 63 61 73 65 0a 20 20 20 20 20 20 2a 2f 0a 20   case.      */. 
1af90 20 20 20 20 20 7a 42 75 66 5b 30 5d 20 3d 20 27       zBuf[0] = '
1afa0 20 27 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ';.      sqlite
1afb0 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f  3_snprintf(sizeo
1afc0 66 28 7a 42 75 66 29 2d 31 2c 20 26 7a 42 75 66  f(zBuf)-1, &zBuf
1afd0 5b 63 6e 74 3e 30 5d 2c 20 22 25 64 20 25 64 20  [cnt>0], "%d %d 
1afe0 25 64 20 25 64 22 2c 0a 20 20 20 20 20 20 20 20  %d %d",.        
1aff0 20 20 70 4d 61 74 63 68 2d 3e 69 43 6f 6c 2c 20    pMatch->iCol, 
1b000 70 4d 61 74 63 68 2d 3e 69 54 65 72 6d 2c 20 70  pMatch->iTerm, p
1b010 4d 61 74 63 68 2d 3e 69 53 74 61 72 74 2c 20 70  Match->iStart, p
1b020 4d 61 74 63 68 2d 3e 6e 42 79 74 65 29 3b 0a 20  Match->nByte);. 
1b030 20 20 20 20 20 61 70 70 65 6e 64 28 26 73 62 2c       append(&sb,
1b040 20 7a 42 75 66 29 3b 0a 20 20 20 20 20 20 63 6e   zBuf);.      cn
1b050 74 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  t++;.    }.  }. 
1b060 20 70 2d 3e 7a 4f 66 66 73 65 74 20 3d 20 73 74   p->zOffset = st
1b070 72 69 6e 67 42 75 66 66 65 72 44 61 74 61 28 26  ringBufferData(&
1b080 73 62 29 3b 0a 20 20 70 2d 3e 6e 4f 66 66 73 65  sb);.  p->nOffse
1b090 74 20 3d 20 73 74 72 69 6e 67 42 75 66 66 65 72  t = stringBuffer
1b0a0 4c 65 6e 67 74 68 28 26 73 62 29 3b 0a 7d 0a 0a  Length(&sb);.}..
1b0b0 2f 2a 0a 2a 2a 20 7a 44 6f 63 5b 30 2e 2e 6e 44  /*.** zDoc[0..nD
1b0c0 6f 63 2d 31 5d 20 69 73 20 70 68 72 61 73 65 20  oc-1] is phrase 
1b0d0 6f 66 20 74 65 78 74 2e 20 20 61 4d 61 74 63 68  of text.  aMatch
1b0e0 5b 30 2e 2e 6e 4d 61 74 63 68 2d 31 5d 20 61 72  [0..nMatch-1] ar
1b0f0 65 20 61 20 73 65 74 0a 2a 2a 20 6f 66 20 6d 61  e a set.** of ma
1b100 74 63 68 69 6e 67 20 77 6f 72 64 73 20 73 6f 6d  tching words som
1b110 65 20 6f 66 20 77 68 69 63 68 20 6d 69 67 68 74  e of which might
1b120 20 62 65 20 69 6e 20 7a 44 6f 63 2e 20 20 7a 44   be in zDoc.  zD
1b130 6f 63 20 69 73 20 63 6f 6c 75 6d 6e 0a 2a 2a 20  oc is column.** 
1b140 6e 75 6d 62 65 72 20 69 43 6f 6c 2e 0a 2a 2a 0a  number iCol..**.
1b150 2a 2a 20 69 42 72 65 61 6b 20 69 73 20 73 75 67  ** iBreak is sug
1b160 67 65 73 74 65 64 20 73 70 6f 74 20 69 6e 20 7a  gested spot in z
1b170 44 6f 63 20 77 68 65 72 65 20 77 65 20 63 6f 75  Doc where we cou
1b180 6c 64 20 62 65 67 69 6e 20 6f 72 20 65 6e 64 20  ld begin or end 
1b190 61 6e 0a 2a 2a 20 65 78 63 65 72 70 74 2e 20 20  an.** excerpt.  
1b1a0 52 65 74 75 72 6e 20 61 20 76 61 6c 75 65 20 73  Return a value s
1b1b0 69 6d 69 6c 61 72 20 74 6f 20 69 42 72 65 61 6b  imilar to iBreak
1b1c0 20 62 75 74 20 70 6f 73 73 69 62 6c 79 20 61 64   but possibly ad
1b1d0 6a 75 73 74 65 64 0a 2a 2a 20 74 6f 20 62 65 20  justed.** to be 
1b1e0 61 20 6c 69 74 74 6c 65 20 6c 65 66 74 20 6f 72  a little left or
1b1f0 20 72 69 67 68 74 20 73 6f 20 74 68 61 74 20 74   right so that t
1b200 68 65 20 62 72 65 61 6b 20 70 6f 69 6e 74 20 69  he break point i
1b210 73 20 62 65 74 74 65 72 2e 0a 2a 2f 0a 73 74 61  s better..*/.sta
1b220 74 69 63 20 69 6e 74 20 77 6f 72 64 42 6f 75 6e  tic int wordBoun
1b230 64 61 72 79 28 0a 20 20 69 6e 74 20 69 42 72 65  dary(.  int iBre
1b240 61 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ak,             
1b250 20 20 20 20 20 20 2f 2a 20 54 68 65 20 73 75 67        /* The sug
1b260 67 65 73 74 65 64 20 62 72 65 61 6b 20 70 6f 69  gested break poi
1b270 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  nt */.  const ch
1b280 61 72 20 2a 7a 44 6f 63 2c 20 20 20 20 20 20 20  ar *zDoc,       
1b290 20 20 20 20 20 20 2f 2a 20 44 6f 63 75 6d 65 6e        /* Documen
1b2a0 74 20 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74 20  t text */.  int 
1b2b0 6e 44 6f 63 2c 20 20 20 20 20 20 20 20 20 20 20  nDoc,           
1b2c0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
1b2d0 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
1b2e0 7a 44 6f 63 5b 5d 20 2a 2f 0a 20 20 73 74 72 75  zDoc[] */.  stru
1b2f0 63 74 20 73 6e 69 70 70 65 74 4d 61 74 63 68 20  ct snippetMatch 
1b300 2a 61 4d 61 74 63 68 2c 20 20 2f 2a 20 4d 61 74  *aMatch,  /* Mat
1b310 63 68 69 6e 67 20 77 6f 72 64 73 20 2a 2f 0a 20  ching words */. 
1b320 20 69 6e 74 20 6e 4d 61 74 63 68 2c 20 20 20 20   int nMatch,    
1b330 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b340 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72  * Number of entr
1b350 69 65 73 20 69 6e 20 61 4d 61 74 63 68 5b 5d 20  ies in aMatch[] 
1b360 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 20 20 20  */.  int iCol   
1b370 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b380 20 20 20 2f 2a 20 54 68 65 20 63 6f 6c 75 6d 6e     /* The column
1b390 20 6e 75 6d 62 65 72 20 66 6f 72 20 7a 44 6f 63   number for zDoc
1b3a0 5b 5d 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69  [] */.){.  int i
1b3b0 3b 0a 20 20 69 66 28 20 69 42 72 65 61 6b 3c 3d  ;.  if( iBreak<=
1b3c0 31 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  10 ){.    return
1b3d0 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 42   0;.  }.  if( iB
1b3e0 72 65 61 6b 3e 3d 6e 44 6f 63 2d 31 30 20 29 7b  reak>=nDoc-10 ){
1b3f0 0a 20 20 20 20 72 65 74 75 72 6e 20 6e 44 6f 63  .    return nDoc
1b400 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d 30 3b  ;.  }.  for(i=0;
1b410 20 69 3c 6e 4d 61 74 63 68 20 26 26 20 61 4d 61   i<nMatch && aMa
1b420 74 63 68 5b 69 5d 2e 69 43 6f 6c 3c 69 43 6f 6c  tch[i].iCol<iCol
1b430 3b 20 69 2b 2b 29 7b 7d 0a 20 20 77 68 69 6c 65  ; i++){}.  while
1b440 28 20 69 3c 6e 4d 61 74 63 68 20 26 26 20 61 4d  ( i<nMatch && aM
1b450 61 74 63 68 5b 69 5d 2e 69 53 74 61 72 74 2b 61  atch[i].iStart+a
1b460 4d 61 74 63 68 5b 69 5d 2e 6e 42 79 74 65 3c 69  Match[i].nByte<i
1b470 42 72 65 61 6b 20 29 7b 20 69 2b 2b 3b 20 7d 0a  Break ){ i++; }.
1b480 20 20 69 66 28 20 69 3c 6e 4d 61 74 63 68 20 29    if( i<nMatch )
1b490 7b 0a 20 20 20 20 69 66 28 20 61 4d 61 74 63 68  {.    if( aMatch
1b4a0 5b 69 5d 2e 69 53 74 61 72 74 3c 69 42 72 65 61  [i].iStart<iBrea
1b4b0 6b 2b 31 30 20 29 7b 0a 20 20 20 20 20 20 72 65  k+10 ){.      re
1b4c0 74 75 72 6e 20 61 4d 61 74 63 68 5b 69 5d 2e 69  turn aMatch[i].i
1b4d0 53 74 61 72 74 3b 0a 20 20 20 20 7d 0a 20 20 20  Start;.    }.   
1b4e0 20 69 66 28 20 69 3e 30 20 26 26 20 61 4d 61 74   if( i>0 && aMat
1b4f0 63 68 5b 69 2d 31 5d 2e 69 53 74 61 72 74 2b 61  ch[i-1].iStart+a
1b500 4d 61 74 63 68 5b 69 2d 31 5d 2e 6e 42 79 74 65  Match[i-1].nByte
1b510 3e 3d 69 42 72 65 61 6b 20 29 7b 0a 20 20 20 20  >=iBreak ){.    
1b520 20 20 72 65 74 75 72 6e 20 61 4d 61 74 63 68 5b    return aMatch[
1b530 69 2d 31 5d 2e 69 53 74 61 72 74 3b 0a 20 20 20  i-1].iStart;.   
1b540 20 7d 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d 31   }.  }.  for(i=1
1b550 3b 20 69 3c 3d 31 30 3b 20 69 2b 2b 29 7b 0a 20  ; i<=10; i++){. 
1b560 20 20 20 69 66 28 20 73 61 66 65 5f 69 73 73 70     if( safe_issp
1b570 61 63 65 28 7a 44 6f 63 5b 69 42 72 65 61 6b 2d  ace(zDoc[iBreak-
1b580 69 5d 29 20 29 7b 0a 20 20 20 20 20 20 72 65 74  i]) ){.      ret
1b590 75 72 6e 20 69 42 72 65 61 6b 20 2d 20 69 20 2b  urn iBreak - i +
1b5a0 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66   1;.    }.    if
1b5b0 28 20 73 61 66 65 5f 69 73 73 70 61 63 65 28 7a  ( safe_isspace(z
1b5c0 44 6f 63 5b 69 42 72 65 61 6b 2b 69 5d 29 20 29  Doc[iBreak+i]) )
1b5d0 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 69  {.      return i
1b5e0 42 72 65 61 6b 20 2b 20 69 20 2b 20 31 3b 0a 20  Break + i + 1;. 
1b5f0 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
1b600 6e 20 69 42 72 65 61 6b 3b 0a 7d 0a 0a 0a 0a 2f  n iBreak;.}..../
1b610 2a 0a 2a 2a 20 41 6c 6c 6f 77 65 64 20 76 61 6c  *.** Allowed val
1b620 75 65 73 20 66 6f 72 20 53 6e 69 70 70 65 74 2e  ues for Snippet.
1b630 61 4d 61 74 63 68 5b 5d 2e 73 6e 53 74 61 74 75  aMatch[].snStatu
1b640 73 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4e 49  s.*/.#define SNI
1b650 50 50 45 54 5f 49 47 4e 4f 52 45 20 20 30 20 20  PPET_IGNORE  0  
1b660 20 2f 2a 20 49 74 20 69 73 20 6f 6b 20 74 6f 20   /* It is ok to 
1b670 6f 6d 69 74 20 74 68 69 73 20 6d 61 74 63 68 20  omit this match 
1b680 66 72 6f 6d 20 74 68 65 20 73 6e 69 70 70 65 74  from the snippet
1b690 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 4e 49 50   */.#define SNIP
1b6a0 50 45 54 5f 44 45 53 49 52 45 44 20 31 20 20 20  PET_DESIRED 1   
1b6b0 2f 2a 20 57 65 20 77 61 6e 74 20 74 6f 20 69 6e  /* We want to in
1b6c0 63 6c 75 64 65 20 74 68 69 73 20 6d 61 74 63 68  clude this match
1b6d0 20 69 6e 20 74 68 65 20 73 6e 69 70 70 65 74 20   in the snippet 
1b6e0 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61  */../*.** Genera
1b6f0 74 65 20 74 68 65 20 74 65 78 74 20 6f 66 20 61  te the text of a
1b700 20 73 6e 69 70 70 65 74 2e 0a 2a 2f 0a 73 74 61   snippet..*/.sta
1b710 74 69 63 20 76 6f 69 64 20 73 6e 69 70 70 65 74  tic void snippet
1b720 54 65 78 74 28 0a 20 20 66 75 6c 6c 74 65 78 74  Text(.  fulltext
1b730 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72  _cursor *pCursor
1b740 2c 20 20 20 2f 2a 20 54 68 65 20 63 75 72 73 6f  ,   /* The curso
1b750 72 20 77 65 20 6e 65 65 64 20 74 68 65 20 73 6e  r we need the sn
1b760 69 70 70 65 74 20 66 6f 72 20 2a 2f 0a 20 20 63  ippet for */.  c
1b770 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 61 72  onst char *zStar
1b780 74 4d 61 72 6b 2c 20 20 20 20 20 2f 2a 20 4d 61  tMark,     /* Ma
1b790 72 6b 75 70 20 74 6f 20 61 70 70 65 61 72 20 62  rkup to appear b
1b7a0 65 66 6f 72 65 20 65 61 63 68 20 6d 61 74 63 68  efore each match
1b7b0 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
1b7c0 20 2a 7a 45 6e 64 4d 61 72 6b 2c 20 20 20 20 20   *zEndMark,     
1b7d0 20 20 2f 2a 20 4d 61 72 6b 75 70 20 74 6f 20 61    /* Markup to a
1b7e0 70 70 65 61 72 20 61 66 74 65 72 20 65 61 63 68  ppear after each
1b7f0 20 6d 61 74 63 68 20 2a 2f 0a 20 20 63 6f 6e 73   match */.  cons
1b800 74 20 63 68 61 72 20 2a 7a 45 6c 6c 69 70 73 69  t char *zEllipsi
1b810 73 20 20 20 20 20 20 20 2f 2a 20 45 6c 6c 69 70  s       /* Ellip
1b820 73 69 73 20 6d 61 72 6b 20 2a 2f 0a 29 7b 0a 20  sis mark */.){. 
1b830 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 73 74 72   int i, j;.  str
1b840 75 63 74 20 73 6e 69 70 70 65 74 4d 61 74 63 68  uct snippetMatch
1b850 20 2a 61 4d 61 74 63 68 3b 0a 20 20 69 6e 74 20   *aMatch;.  int 
1b860 6e 4d 61 74 63 68 3b 0a 20 20 69 6e 74 20 6e 44  nMatch;.  int nD
1b870 65 73 69 72 65 64 3b 0a 20 20 53 74 72 69 6e 67  esired;.  String
1b880 42 75 66 66 65 72 20 73 62 3b 0a 20 20 69 6e 74  Buffer sb;.  int
1b890 20 74 61 69 6c 43 6f 6c 3b 0a 20 20 69 6e 74 20   tailCol;.  int 
1b8a0 74 61 69 6c 4f 66 66 73 65 74 3b 0a 20 20 69 6e  tailOffset;.  in
1b8b0 74 20 69 43 6f 6c 3b 0a 20 20 69 6e 74 20 6e 44  t iCol;.  int nD
1b8c0 6f 63 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  oc;.  const char
1b8d0 20 2a 7a 44 6f 63 3b 0a 20 20 69 6e 74 20 69 53   *zDoc;.  int iS
1b8e0 74 61 72 74 2c 20 69 45 6e 64 3b 0a 20 20 69 6e  tart, iEnd;.  in
1b8f0 74 20 74 61 69 6c 45 6c 6c 69 70 73 69 73 20 3d  t tailEllipsis =
1b900 20 30 3b 0a 20 20 69 6e 74 20 69 4d 61 74 63 68   0;.  int iMatch
1b910 3b 0a 20 20 0a 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  ..  sqlite3_
1b920 66 72 65 65 28 70 43 75 72 73 6f 72 2d 3e 73 6e  free(pCursor->sn
1b930 69 70 70 65 74 2e 7a 53 6e 69 70 70 65 74 29 3b  ippet.zSnippet);
1b940 0a 20 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70  .  pCursor->snip
1b950 70 65 74 2e 7a 53 6e 69 70 70 65 74 20 3d 20 30  pet.zSnippet = 0
1b960 3b 0a 20 20 61 4d 61 74 63 68 20 3d 20 70 43 75  ;.  aMatch = pCu
1b970 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74 2e 61 4d  rsor->snippet.aM
1b980 61 74 63 68 3b 0a 20 20 6e 4d 61 74 63 68 20 3d  atch;.  nMatch =
1b990 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65   pCursor->snippe
1b9a0 74 2e 6e 4d 61 74 63 68 3b 0a 20 20 69 6e 69 74  t.nMatch;.  init
1b9b0 53 74 72 69 6e 67 42 75 66 66 65 72 28 26 73 62  StringBuffer(&sb
1b9c0 29 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  );..  for(i=0; i
1b9d0 3c 6e 4d 61 74 63 68 3b 20 69 2b 2b 29 7b 0a 20  <nMatch; i++){. 
1b9e0 20 20 20 61 4d 61 74 63 68 5b 69 5d 2e 73 6e 53     aMatch[i].snS
1b9f0 74 61 74 75 73 20 3d 20 53 4e 49 50 50 45 54 5f  tatus = SNIPPET_
1ba00 49 47 4e 4f 52 45 3b 0a 20 20 7d 0a 20 20 6e 44  IGNORE;.  }.  nD
1ba10 65 73 69 72 65 64 20 3d 20 30 3b 0a 20 20 66 6f  esired = 0;.  fo
1ba20 72 28 69 3d 30 3b 20 69 3c 46 54 53 33 5f 52 4f  r(i=0; i<FTS3_RO
1ba30 54 4f 52 5f 53 5a 3b 20 69 2b 2b 29 7b 0a 20 20  TOR_SZ; i++){.  
1ba40 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 4d 61    for(j=0; j<nMa
1ba50 74 63 68 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20  tch; j++){.     
1ba60 20 69 66 28 20 61 4d 61 74 63 68 5b 6a 5d 2e 69   if( aMatch[j].i
1ba70 54 65 72 6d 3d 3d 69 20 29 7b 0a 20 20 20 20 20  Term==i ){.     
1ba80 20 20 20 61 4d 61 74 63 68 5b 6a 5d 2e 73 6e 53     aMatch[j].snS
1ba90 74 61 74 75 73 20 3d 20 53 4e 49 50 50 45 54 5f  tatus = SNIPPET_
1baa0 44 45 53 49 52 45 44 3b 0a 20 20 20 20 20 20 20  DESIRED;.       
1bab0 20 6e 44 65 73 69 72 65 64 2b 2b 3b 0a 20 20 20   nDesired++;.   
1bac0 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
1bad0 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20    }.    }.  }.. 
1bae0 20 69 4d 61 74 63 68 20 3d 20 30 3b 0a 20 20 74   iMatch = 0;.  t
1baf0 61 69 6c 43 6f 6c 20 3d 20 2d 31 3b 0a 20 20 74  ailCol = -1;.  t
1bb00 61 69 6c 4f 66 66 73 65 74 20 3d 20 30 3b 0a 20  ailOffset = 0;. 
1bb10 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 4d 61 74   for(i=0; i<nMat
1bb20 63 68 20 26 26 20 6e 44 65 73 69 72 65 64 3e 30  ch && nDesired>0
1bb30 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20  ; i++){.    if( 
1bb40 61 4d 61 74 63 68 5b 69 5d 2e 73 6e 53 74 61 74  aMatch[i].snStat
1bb50 75 73 21 3d 53 4e 49 50 50 45 54 5f 44 45 53 49  us!=SNIPPET_DESI
1bb60 52 45 44 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a  RED ) continue;.
1bb70 20 20 20 20 6e 44 65 73 69 72 65 64 2d 2d 3b 0a      nDesired--;.
1bb80 20 20 20 20 69 43 6f 6c 20 3d 20 61 4d 61 74 63      iCol = aMatc
1bb90 68 5b 69 5d 2e 69 43 6f 6c 3b 0a 20 20 20 20 7a  h[i].iCol;.    z
1bba0 44 6f 63 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  Doc = (const cha
1bbb0 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  r*)sqlite3_colum
1bbc0 6e 5f 74 65 78 74 28 70 43 75 72 73 6f 72 2d 3e  n_text(pCursor->
1bbd0 70 53 74 6d 74 2c 20 69 43 6f 6c 2b 31 29 3b 0a  pStmt, iCol+1);.
1bbe0 20 20 20 20 6e 44 6f 63 20 3d 20 73 71 6c 69 74      nDoc = sqlit
1bbf0 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28  e3_column_bytes(
1bc00 70 43 75 72 73 6f 72 2d 3e 70 53 74 6d 74 2c 20  pCursor->pStmt, 
1bc10 69 43 6f 6c 2b 31 29 3b 0a 20 20 20 20 69 53 74  iCol+1);.    iSt
1bc20 61 72 74 20 3d 20 61 4d 61 74 63 68 5b 69 5d 2e  art = aMatch[i].
1bc30 69 53 74 61 72 74 20 2d 20 34 30 3b 0a 20 20 20  iStart - 40;.   
1bc40 20 69 53 74 61 72 74 20 3d 20 77 6f 72 64 42 6f   iStart = wordBo
1bc50 75 6e 64 61 72 79 28 69 53 74 61 72 74 2c 20 7a  undary(iStart, z
1bc60 44 6f 63 2c 20 6e 44 6f 63 2c 20 61 4d 61 74 63  Doc, nDoc, aMatc
1bc70 68 2c 20 6e 4d 61 74 63 68 2c 20 69 43 6f 6c 29  h, nMatch, iCol)
1bc80 3b 0a 20 20 20 20 69 66 28 20 69 53 74 61 72 74  ;.    if( iStart
1bc90 3c 3d 31 30 20 29 7b 0a 20 20 20 20 20 20 69 53  <=10 ){.      iS
1bca0 74 61 72 74 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  tart = 0;.    }.
1bcb0 20 20 20 20 69 66 28 20 69 43 6f 6c 3d 3d 74 61      if( iCol==ta
1bcc0 69 6c 43 6f 6c 20 26 26 20 69 53 74 61 72 74 3c  ilCol && iStart<
1bcd0 3d 74 61 69 6c 4f 66 66 73 65 74 2b 32 30 20 29  =tailOffset+20 )
1bce0 7b 0a 20 20 20 20 20 20 69 53 74 61 72 74 20 3d  {.      iStart =
1bcf0 20 74 61 69 6c 4f 66 66 73 65 74 3b 0a 20 20 20   tailOffset;.   
1bd00 20 7d 0a 20 20 20 20 69 66 28 20 28 69 43 6f 6c   }.    if( (iCol
1bd10 21 3d 74 61 69 6c 43 6f 6c 20 26 26 20 74 61 69  !=tailCol && tai
1bd20 6c 43 6f 6c 3e 3d 30 29 20 7c 7c 20 69 53 74 61  lCol>=0) || iSta
1bd30 72 74 21 3d 74 61 69 6c 4f 66 66 73 65 74 20 29  rt!=tailOffset )
1bd40 7b 0a 20 20 20 20 20 20 74 72 69 6d 57 68 69 74  {.      trimWhit
1bd50 65 53 70 61 63 65 28 26 73 62 29 3b 0a 20 20 20  eSpace(&sb);.   
1bd60 20 20 20 61 70 70 65 6e 64 57 68 69 74 65 53 70     appendWhiteSp
1bd70 61 63 65 28 26 73 62 29 3b 0a 20 20 20 20 20 20  ace(&sb);.      
1bd80 61 70 70 65 6e 64 28 26 73 62 2c 20 7a 45 6c 6c  append(&sb, zEll
1bd90 69 70 73 69 73 29 3b 0a 20 20 20 20 20 20 61 70  ipsis);.      ap
1bda0 70 65 6e 64 57 68 69 74 65 53 70 61 63 65 28 26  pendWhiteSpace(&
1bdb0 73 62 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  sb);.    }.    i
1bdc0 45 6e 64 20 3d 20 61 4d 61 74 63 68 5b 69 5d 2e  End = aMatch[i].
1bdd0 69 53 74 61 72 74 20 2b 20 61 4d 61 74 63 68 5b  iStart + aMatch[
1bde0 69 5d 2e 6e 42 79 74 65 20 2b 20 34 30 3b 0a 20  i].nByte + 40;. 
1bdf0 20 20 20 69 45 6e 64 20 3d 20 77 6f 72 64 42 6f     iEnd = wordBo
1be00 75 6e 64 61 72 79 28 69 45 6e 64 2c 20 7a 44 6f  undary(iEnd, zDo
1be10 63 2c 20 6e 44 6f 63 2c 20 61 4d 61 74 63 68 2c  c, nDoc, aMatch,
1be20 20 6e 4d 61 74 63 68 2c 20 69 43 6f 6c 29 3b 0a   nMatch, iCol);.
1be30 20 20 20 20 69 66 28 20 69 45 6e 64 3e 3d 6e 44      if( iEnd>=nD
1be40 6f 63 2d 31 30 20 29 7b 0a 20 20 20 20 20 20 69  oc-10 ){.      i
1be50 45 6e 64 20 3d 20 6e 44 6f 63 3b 0a 20 20 20 20  End = nDoc;.    
1be60 20 20 74 61 69 6c 45 6c 6c 69 70 73 69 73 20 3d    tailEllipsis =
1be70 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   0;.    }else{. 
1be80 20 20 20 20 20 74 61 69 6c 45 6c 6c 69 70 73 69       tailEllipsi
1be90 73 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20  s = 1;.    }.   
1bea0 20 77 68 69 6c 65 28 20 69 4d 61 74 63 68 3c 6e   while( iMatch<n
1beb0 4d 61 74 63 68 20 26 26 20 61 4d 61 74 63 68 5b  Match && aMatch[
1bec0 69 4d 61 74 63 68 5d 2e 69 43 6f 6c 3c 69 43 6f  iMatch].iCol<iCo
1bed0 6c 20 29 7b 20 69 4d 61 74 63 68 2b 2b 3b 20 7d  l ){ iMatch++; }
1bee0 0a 20 20 20 20 77 68 69 6c 65 28 20 69 53 74 61  .    while( iSta
1bef0 72 74 3c 69 45 6e 64 20 29 7b 0a 20 20 20 20 20  rt<iEnd ){.     
1bf00 20 77 68 69 6c 65 28 20 69 4d 61 74 63 68 3c 6e   while( iMatch<n
1bf10 4d 61 74 63 68 20 26 26 20 61 4d 61 74 63 68 5b  Match && aMatch[
1bf20 69 4d 61 74 63 68 5d 2e 69 53 74 61 72 74 3c 69  iMatch].iStart<i
1bf30 53 74 61 72 74 0a 20 20 20 20 20 20 20 20 20 20  Start.          
1bf40 20 20 20 26 26 20 61 4d 61 74 63 68 5b 69 4d 61     && aMatch[iMa
1bf50 74 63 68 5d 2e 69 43 6f 6c 3c 3d 69 43 6f 6c 20  tch].iCol<=iCol 
1bf60 29 7b 0a 20 20 20 20 20 20 20 20 69 4d 61 74 63  ){.        iMatc
1bf70 68 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  h++;.      }.   
1bf80 20 20 20 69 66 28 20 69 4d 61 74 63 68 3c 6e 4d     if( iMatch<nM
1bf90 61 74 63 68 20 26 26 20 61 4d 61 74 63 68 5b 69  atch && aMatch[i
1bfa0 4d 61 74 63 68 5d 2e 69 53 74 61 72 74 3c 69 45  Match].iStart<iE
1bfb0 6e 64 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  nd.             
1bfc0 26 26 20 61 4d 61 74 63 68 5b 69 4d 61 74 63 68  && aMatch[iMatch
1bfd0 5d 2e 69 43 6f 6c 3d 3d 69 43 6f 6c 20 29 7b 0a  ].iCol==iCol ){.
1bfe0 20 20 20 20 20 20 20 20 6e 61 70 70 65 6e 64 28          nappend(
1bff0 26 73 62 2c 20 26 7a 44 6f 63 5b 69 53 74 61 72  &sb, &zDoc[iStar
1c000 74 5d 2c 20 61 4d 61 74 63 68 5b 69 4d 61 74 63  t], aMatch[iMatc
1c010 68 5d 2e 69 53 74 61 72 74 20 2d 20 69 53 74 61  h].iStart - iSta
1c020 72 74 29 3b 0a 20 20 20 20 20 20 20 20 69 53 74  rt);.        iSt
1c030 61 72 74 20 3d 20 61 4d 61 74 63 68 5b 69 4d 61  art = aMatch[iMa
1c040 74 63 68 5d 2e 69 53 74 61 72 74 3b 0a 20 20 20  tch].iStart;.   
1c050 20 20 20 20 20 61 70 70 65 6e 64 28 26 73 62 2c       append(&sb,
1c060 20 7a 53 74 61 72 74 4d 61 72 6b 29 3b 0a 20 20   zStartMark);.  
1c070 20 20 20 20 20 20 6e 61 70 70 65 6e 64 28 26 73        nappend(&s
1c080 62 2c 20 26 7a 44 6f 63 5b 69 53 74 61 72 74 5d  b, &zDoc[iStart]
1c090 2c 20 61 4d 61 74 63 68 5b 69 4d 61 74 63 68 5d  , aMatch[iMatch]
1c0a0 2e 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 20  .nByte);.       
1c0b0 20 61 70 70 65 6e 64 28 26 73 62 2c 20 7a 45 6e   append(&sb, zEn
1c0c0 64 4d 61 72 6b 29 3b 0a 20 20 20 20 20 20 20 20  dMark);.        
1c0d0 69 53 74 61 72 74 20 2b 3d 20 61 4d 61 74 63 68  iStart += aMatch
1c0e0 5b 69 4d 61 74 63 68 5d 2e 6e 42 79 74 65 3b 0a  [iMatch].nByte;.
1c0f0 20 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 69 4d          for(j=iM
1c100 61 74 63 68 2b 31 3b 20 6a 3c 6e 4d 61 74 63 68  atch+1; j<nMatch
1c110 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; j++){.        
1c120 20 20 69 66 28 20 61 4d 61 74 63 68 5b 6a 5d 2e    if( aMatch[j].
1c130 69 54 65 72 6d 3d 3d 61 4d 61 74 63 68 5b 69 4d  iTerm==aMatch[iM
1c140 61 74 63 68 5d 2e 69 54 65 72 6d 0a 20 20 20 20  atch].iTerm.    
1c150 20 20 20 20 20 20 20 20 20 20 26 26 20 61 4d 61            && aMa
1c160 74 63 68 5b 6a 5d 2e 73 6e 53 74 61 74 75 73 3d  tch[j].snStatus=
1c170 3d 53 4e 49 50 50 45 54 5f 44 45 53 49 52 45 44  =SNIPPET_DESIRED
1c180 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
1c190 6e 44 65 73 69 72 65 64 2d 2d 3b 0a 20 20 20 20  nDesired--;.    
1c1a0 20 20 20 20 20 20 20 20 61 4d 61 74 63 68 5b 6a          aMatch[j
1c1b0 5d 2e 73 6e 53 74 61 74 75 73 20 3d 20 53 4e 49  ].snStatus = SNI
1c1c0 50 50 45 54 5f 49 47 4e 4f 52 45 3b 0a 20 20 20  PPET_IGNORE;.   
1c1d0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
1c1e0 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a   }.      }else{.
1c1f0 20 20 20 20 20 20 20 20 6e 61 70 70 65 6e 64 28          nappend(
1c200 26 73 62 2c 20 26 7a 44 6f 63 5b 69 53 74 61 72  &sb, &zDoc[iStar
1c210 74 5d 2c 20 69 45 6e 64 20 2d 20 69 53 74 61 72  t], iEnd - iStar
1c220 74 29 3b 0a 20 20 20 20 20 20 20 20 69 53 74 61  t);.        iSta
1c230 72 74 20 3d 20 69 45 6e 64 3b 0a 20 20 20 20 20  rt = iEnd;.     
1c240 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 74 61 69   }.    }.    tai
1c250 6c 43 6f 6c 20 3d 20 69 43 6f 6c 3b 0a 20 20 20  lCol = iCol;.   
1c260 20 74 61 69 6c 4f 66 66 73 65 74 20 3d 20 69 45   tailOffset = iE
1c270 6e 64 3b 0a 20 20 7d 0a 20 20 74 72 69 6d 57 68  nd;.  }.  trimWh
1c280 69 74 65 53 70 61 63 65 28 26 73 62 29 3b 0a 20  iteSpace(&sb);. 
1c290 20 69 66 28 20 74 61 69 6c 45 6c 6c 69 70 73 69   if( tailEllipsi
1c2a0 73 20 29 7b 0a 20 20 20 20 61 70 70 65 6e 64 57  s ){.    appendW
1c2b0 68 69 74 65 53 70 61 63 65 28 26 73 62 29 3b 0a  hiteSpace(&sb);.
1c2c0 20 20 20 20 61 70 70 65 6e 64 28 26 73 62 2c 20      append(&sb, 
1c2d0 7a 45 6c 6c 69 70 73 69 73 29 3b 0a 20 20 7d 0a  zEllipsis);.  }.
1c2e0 20 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70    pCursor->snipp
1c2f0 65 74 2e 7a 53 6e 69 70 70 65 74 20 3d 20 73 74  et.zSnippet = st
1c300 72 69 6e 67 42 75 66 66 65 72 44 61 74 61 28 26  ringBufferData(&
1c310 73 62 29 3b 0a 20 20 70 43 75 72 73 6f 72 2d 3e  sb);.  pCursor->
1c320 73 6e 69 70 70 65 74 2e 6e 53 6e 69 70 70 65 74  snippet.nSnippet
1c330 20 3d 20 73 74 72 69 6e 67 42 75 66 66 65 72 4c   = stringBufferL
1c340 65 6e 67 74 68 28 26 73 62 29 3b 0a 7d 0a 0a 0a  ength(&sb);.}...
1c350 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 74 68 65 20  /*.** Close the 
1c360 63 75 72 73 6f 72 2e 20 20 46 6f 72 20 61 64 64  cursor.  For add
1c370 69 74 69 6f 6e 61 6c 20 69 6e 66 6f 72 6d 61 74  itional informat
1c380 69 6f 6e 20 73 65 65 20 74 68 65 20 64 6f 63 75  ion see the docu
1c390 6d 65 6e 74 61 74 69 6f 6e 0a 2a 2a 20 6f 6e 20  mentation.** on 
1c3a0 74 68 65 20 78 43 6c 6f 73 65 20 6d 65 74 68 6f  the xClose metho
1c3b0 64 20 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c  d of the virtual
1c3c0 20 74 61 62 6c 65 20 69 6e 74 65 72 66 61 63 65   table interface
1c3d0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1c3e0 66 75 6c 6c 74 65 78 74 43 6c 6f 73 65 28 73 71  fulltextClose(sq
1c3f0 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
1c400 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20 66  r *pCursor){.  f
1c410 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a  ulltext_cursor *
1c420 63 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f 63 75  c = (fulltext_cu
1c430 72 73 6f 72 20 2a 29 20 70 43 75 72 73 6f 72 3b  rsor *) pCursor;
1c440 0a 20 20 46 54 53 54 52 41 43 45 28 28 22 46 54  .  FTSTRACE(("FT
1c450 53 33 20 43 6c 6f 73 65 20 25 70 5c 6e 22 2c 20  S3 Close %p\n", 
1c460 63 29 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  c));.  sqlite3_f
1c470 69 6e 61 6c 69 7a 65 28 63 2d 3e 70 53 74 6d 74  inalize(c->pStmt
1c480 29 3b 0a 20 20 73 71 6c 69 74 65 33 46 74 73 33  );.  sqlite3Fts3
1c490 45 78 70 72 46 72 65 65 28 63 2d 3e 70 45 78 70  ExprFree(c->pExp
1c4a0 72 29 3b 0a 20 20 73 6e 69 70 70 65 74 43 6c 65  r);.  snippetCle
1c4b0 61 72 28 26 63 2d 3e 73 6e 69 70 70 65 74 29 3b  ar(&c->snippet);
1c4c0 0a 20 20 69 66 28 20 63 2d 3e 72 65 73 75 6c 74  .  if( c->result
1c4d0 2e 6e 44 61 74 61 21 3d 30 20 29 7b 0a 20 20 20  .nData!=0 ){.   
1c4e0 20 64 6c 72 44 65 73 74 72 6f 79 28 26 63 2d 3e   dlrDestroy(&c->
1c4f0 72 65 61 64 65 72 29 3b 0a 20 20 7d 0a 20 20 64  reader);.  }.  d
1c500 61 74 61 42 75 66 66 65 72 44 65 73 74 72 6f 79  ataBufferDestroy
1c510 28 26 63 2d 3e 72 65 73 75 6c 74 29 3b 0a 20 20  (&c->result);.  
1c520 73 71 6c 69 74 65 33 5f 66 72 65 65 28 63 29 3b  sqlite3_free(c);
1c530 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
1c540 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  _OK;.}..static i
1c550 6e 74 20 66 75 6c 6c 74 65 78 74 4e 65 78 74 28  nt fulltextNext(
1c560 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
1c570 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20  sor *pCursor){. 
1c580 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72   fulltext_cursor
1c590 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f   *c = (fulltext_
1c5a0 63 75 72 73 6f 72 20 2a 29 20 70 43 75 72 73 6f  cursor *) pCurso
1c5b0 72 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  r;.  int rc;..  
1c5c0 46 54 53 54 52 41 43 45 28 28 22 46 54 53 33 20  FTSTRACE(("FTS3 
1c5d0 4e 65 78 74 20 25 70 5c 6e 22 2c 20 70 43 75 72  Next %p\n", pCur
1c5e0 73 6f 72 29 29 3b 0a 20 20 73 6e 69 70 70 65 74  sor));.  snippet
1c5f0 43 6c 65 61 72 28 26 63 2d 3e 73 6e 69 70 70 65  Clear(&c->snippe
1c600 74 29 3b 0a 20 20 69 66 28 20 63 2d 3e 69 43 75  t);.  if( c->iCu
1c610 72 73 6f 72 54 79 70 65 20 3c 20 51 55 45 52 59  rsorType < QUERY
1c620 5f 46 55 4c 4c 54 45 58 54 20 29 7b 0a 20 20 20  _FULLTEXT ){.   
1c630 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20   /* TODO(shess) 
1c640 48 61 6e 64 6c 65 20 53 51 4c 49 54 45 5f 53 43  Handle SQLITE_SC
1c650 48 45 4d 41 20 41 4e 44 20 53 51 4c 49 54 45 5f  HEMA AND SQLITE_
1c660 42 55 53 59 2e 20 2a 2f 0a 20 20 20 20 72 63 20  BUSY. */.    rc 
1c670 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 63  = sqlite3_step(c
1c680 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 73 77  ->pStmt);.    sw
1c690 69 74 63 68 28 20 72 63 20 29 7b 0a 20 20 20 20  itch( rc ){.    
1c6a0 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 52 4f    case SQLITE_RO
1c6b0 57 3a 0a 20 20 20 20 20 20 20 20 63 2d 3e 65 6f  W:.        c->eo
1c6c0 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 72  f = 0;.        r
1c6d0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
1c6e0 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
1c6f0 54 45 5f 44 4f 4e 45 3a 0a 20 20 20 20 20 20 20  TE_DONE:.       
1c700 20 63 2d 3e 65 6f 66 20 3d 20 31 3b 0a 20 20 20   c->eof = 1;.   
1c710 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
1c720 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 64 65 66  TE_OK;.      def
1c730 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20 63 2d  ault:.        c-
1c740 3e 65 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20 20  >eof = 1;.      
1c750 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20    return rc;.   
1c760 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 20 20 2f   }.  } else {  /
1c770 2a 20 66 75 6c 6c 2d 74 65 78 74 20 71 75 65 72  * full-text quer
1c780 79 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 71  y */.    rc = sq
1c790 6c 69 74 65 33 5f 72 65 73 65 74 28 63 2d 3e 70  lite3_reset(c->p
1c7a0 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 72  Stmt);.    if( r
1c7b0 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
1c7c0 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20 69  eturn rc;..    i
1c7d0 66 28 20 63 2d 3e 72 65 73 75 6c 74 2e 6e 44 61  f( c->result.nDa
1c7e0 74 61 3d 3d 30 20 7c 7c 20 64 6c 72 41 74 45 6e  ta==0 || dlrAtEn
1c7f0 64 28 26 63 2d 3e 72 65 61 64 65 72 29 20 29 7b  d(&c->reader) ){
1c800 0a 20 20 20 20 20 20 63 2d 3e 65 6f 66 20 3d 20  .      c->eof = 
1c810 31 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  1;.      return 
1c820 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d  SQLITE_OK;.    }
1c830 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
1c840 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 63 2d 3e  3_bind_int64(c->
1c850 70 53 74 6d 74 2c 20 31 2c 20 64 6c 72 44 6f 63  pStmt, 1, dlrDoc
1c860 69 64 28 26 63 2d 3e 72 65 61 64 65 72 29 29 3b  id(&c->reader));
1c870 0a 20 20 20 20 64 6c 72 53 74 65 70 28 26 63 2d  .    dlrStep(&c-
1c880 3e 72 65 61 64 65 72 29 3b 0a 20 20 20 20 69 66  >reader);.    if
1c890 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
1c8a0 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20  ) return rc;.   
1c8b0 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20   /* TODO(shess) 
1c8c0 48 61 6e 64 6c 65 20 53 51 4c 49 54 45 5f 53 43  Handle SQLITE_SC
1c8d0 48 45 4d 41 20 41 4e 44 20 53 51 4c 49 54 45 5f  HEMA AND SQLITE_
1c8e0 42 55 53 59 2e 20 2a 2f 0a 20 20 20 20 72 63 20  BUSY. */.    rc 
1c8f0 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 63  = sqlite3_step(c
1c900 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 69 66  ->pStmt);.    if
1c910 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52 4f 57  ( rc==SQLITE_ROW
1c920 20 29 7b 20 20 20 2f 2a 20 74 68 65 20 63 61 73   ){   /* the cas
1c930 65 20 77 65 20 65 78 70 65 63 74 20 2a 2f 0a 20  e we expect */. 
1c940 20 20 20 20 20 63 2d 3e 65 6f 66 20 3d 20 30 3b       c->eof = 0;
1c950 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
1c960 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20  LITE_OK;.    }. 
1c970 20 20 20 2f 2a 20 61 6e 20 65 72 72 6f 72 20 6f     /* an error o
1c980 63 63 75 72 72 65 64 3b 20 61 62 6f 72 74 20 2a  ccurred; abort *
1c990 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3d  /.    return rc=
1c9a0 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 3f 20 53  =SQLITE_DONE ? S
1c9b0 51 4c 49 54 45 5f 45 52 52 4f 52 20 3a 20 72 63  QLITE_ERROR : rc
1c9c0 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 20 54 4f 44  ;.  }.}.../* TOD
1c9d0 4f 28 73 68 65 73 73 29 20 49 66 20 77 65 20 70  O(shess) If we p
1c9e0 75 73 68 65 64 20 4c 65 61 66 52 65 61 64 65 72  ushed LeafReader
1c9f0 20 74 6f 20 74 68 65 20 74 6f 70 20 6f 66 20 74   to the top of t
1ca00 68 65 20 66 69 6c 65 2c 20 6f 72 20 74 6f 0a 2a  he file, or to.*
1ca10 2a 20 61 6e 6f 74 68 65 72 20 66 69 6c 65 2c 20  * another file, 
1ca20 74 65 72 6d 5f 73 65 6c 65 63 74 28 29 20 63 6f  term_select() co
1ca30 75 6c 64 20 62 65 20 70 75 73 68 65 64 20 61 62  uld be pushed ab
1ca40 6f 76 65 0a 2a 2a 20 64 6f 63 4c 69 73 74 4f 66  ove.** docListOf
1ca50 54 65 72 6d 28 29 2e 0a 2a 2f 0a 73 74 61 74 69  Term()..*/.stati
1ca60 63 20 69 6e 74 20 74 65 72 6d 53 65 6c 65 63 74  c int termSelect
1ca70 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
1ca80 76 2c 20 69 6e 74 20 69 43 6f 6c 75 6d 6e 2c 0a  v, int iColumn,.
1ca90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1caa0 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
1cab0 20 2a 70 54 65 72 6d 2c 20 69 6e 74 20 6e 54 65   *pTerm, int nTe
1cac0 72 6d 2c 20 69 6e 74 20 69 73 50 72 65 66 69 78  rm, int isPrefix
1cad0 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
1cae0 20 20 20 20 20 20 20 20 44 6f 63 4c 69 73 74 54          DocListT
1caf0 79 70 65 20 69 54 79 70 65 2c 20 44 61 74 61 42  ype iType, DataB
1cb00 75 66 66 65 72 20 2a 6f 75 74 29 3b 0a 0a 2f 2a  uffer *out);../*
1cb10 20 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 44 6f   .** Return a Do
1cb20 63 4c 69 73 74 20 63 6f 72 72 65 73 70 6f 6e 64  cList correspond
1cb30 69 6e 67 20 74 6f 20 74 68 65 20 70 68 72 61 73  ing to the phras
1cb40 65 20 2a 70 50 68 72 61 73 65 2e 0a 2a 2a 0a 2a  e *pPhrase..**.*
1cb50 2a 20 54 68 65 20 72 65 73 75 6c 74 69 6e 67 20  * The resulting 
1cb60 44 4c 5f 44 4f 43 49 44 53 20 64 6f 63 6c 69 73  DL_DOCIDS doclis
1cb70 74 20 69 73 20 73 74 6f 72 65 64 20 69 6e 20 70  t is stored in p
1cb80 52 65 73 75 6c 74 2c 20 77 68 69 63 68 20 69 73  Result, which is
1cb90 0a 2a 2a 20 6f 76 65 72 77 72 69 74 74 65 6e 2e  .** overwritten.
1cba0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 64  .*/.static int d
1cbb0 6f 63 4c 69 73 74 4f 66 50 68 72 61 73 65 28 0a  ocListOfPhrase(.
1cbc0 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20    fulltext_vtab 
1cbd0 2a 70 54 61 62 2c 20 20 20 2f 2a 20 54 68 65 20  *pTab,   /* The 
1cbe0 66 75 6c 6c 20 74 65 78 74 20 69 6e 64 65 78 20  full text index 
1cbf0 2a 2f 0a 20 20 46 74 73 33 50 68 72 61 73 65 20  */.  Fts3Phrase 
1cc00 2a 70 50 68 72 61 73 65 2c 20 20 20 2f 2a 20 50  *pPhrase,   /* P
1cc10 68 72 61 73 65 20 74 6f 20 72 65 74 75 72 6e 20  hrase to return 
1cc20 61 20 64 6f 63 6c 69 73 74 20 63 6f 72 72 65 73  a doclist corres
1cc30 70 6f 6e 64 69 6e 67 20 74 6f 20 2a 2f 0a 20 20  ponding to */.  
1cc40 44 6f 63 4c 69 73 74 54 79 70 65 20 65 4c 69 73  DocListType eLis
1cc50 74 54 79 70 65 2c 20 2f 2a 20 45 69 74 68 65 72  tType, /* Either
1cc60 20 44 4c 5f 44 4f 43 49 44 53 20 6f 72 20 44 4c   DL_DOCIDS or DL
1cc70 5f 50 4f 53 49 54 49 4f 4e 53 20 2a 2f 0a 20 20  _POSITIONS */.  
1cc80 44 61 74 61 42 75 66 66 65 72 20 2a 70 52 65 73  DataBuffer *pRes
1cc90 75 6c 74 20 20 20 20 2f 2a 20 57 72 69 74 65 20  ult    /* Write 
1cca0 74 68 65 20 72 65 73 75 6c 74 20 68 65 72 65 20  the result here 
1ccb0 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 69 3b 0a  */.){.  int ii;.
1ccc0 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
1ccd0 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 69 43 6f 6c  E_OK;.  int iCol
1cce0 20 3d 20 70 50 68 72 61 73 65 2d 3e 69 43 6f 6c   = pPhrase->iCol
1ccf0 75 6d 6e 3b 0a 20 20 44 6f 63 4c 69 73 74 54 79  umn;.  DocListTy
1cd00 70 65 20 65 54 79 70 65 20 3d 20 65 4c 69 73 74  pe eType = eList
1cd10 54 79 70 65 3b 0a 20 20 61 73 73 65 72 74 28 20  Type;.  assert( 
1cd20 65 54 79 70 65 3d 3d 44 4c 5f 50 4f 53 49 54 49  eType==DL_POSITI
1cd30 4f 4e 53 20 7c 7c 20 65 54 79 70 65 3d 3d 44 4c  ONS || eType==DL
1cd40 5f 44 4f 43 49 44 53 20 29 3b 0a 20 20 69 66 28  _DOCIDS );.  if(
1cd50 20 70 50 68 72 61 73 65 2d 3e 6e 54 6f 6b 65 6e   pPhrase->nToken
1cd60 3e 31 20 29 7b 0a 20 20 20 20 65 54 79 70 65 20  >1 ){.    eType 
1cd70 3d 20 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 3b 0a  = DL_POSITIONS;.
1cd80 20 20 7d 0a 0a 20 20 2f 2a 20 54 68 69 73 20 63    }..  /* This c
1cd90 6f 64 65 20 73 68 6f 75 6c 64 20 6e 65 76 65 72  ode should never
1cda0 20 62 65 20 63 61 6c 6c 65 64 20 77 69 74 68 20   be called with 
1cdb0 62 75 66 66 65 72 65 64 20 75 70 64 61 74 65 73  buffered updates
1cdc0 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70  . */.  assert( p
1cdd0 54 61 62 2d 3e 6e 50 65 6e 64 69 6e 67 44 61 74  Tab->nPendingDat
1cde0 61 3c 30 20 29 3b 0a 0a 20 20 66 6f 72 28 69 69  a<0 );..  for(ii
1cdf0 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  =0; rc==SQLITE_O
1ce00 4b 20 26 26 20 69 69 3c 70 50 68 72 61 73 65 2d  K && ii<pPhrase-
1ce10 3e 6e 54 6f 6b 65 6e 3b 20 69 69 2b 2b 29 7b 0a  >nToken; ii++){.
1ce20 20 20 20 20 44 61 74 61 42 75 66 66 65 72 20 74      DataBuffer t
1ce30 6d 70 3b 0a 20 20 20 20 73 74 72 75 63 74 20 50  mp;.    struct P
1ce40 68 72 61 73 65 54 6f 6b 65 6e 20 2a 70 20 3d 20  hraseToken *p = 
1ce50 26 70 50 68 72 61 73 65 2d 3e 61 54 6f 6b 65 6e  &pPhrase->aToken
1ce60 5b 69 69 5d 3b 0a 20 20 20 20 72 63 20 3d 20 74  [ii];.    rc = t
1ce70 65 72 6d 53 65 6c 65 63 74 28 70 54 61 62 2c 20  ermSelect(pTab, 
1ce80 69 43 6f 6c 2c 20 70 2d 3e 7a 2c 20 70 2d 3e 6e  iCol, p->z, p->n
1ce90 2c 20 70 2d 3e 69 73 50 72 65 66 69 78 2c 20 65  , p->isPrefix, e
1cea0 54 79 70 65 2c 20 26 74 6d 70 29 3b 0a 20 20 20  Type, &tmp);.   
1ceb0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
1cec0 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  OK ){.      if( 
1ced0 69 69 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  ii==0 ){.       
1cee0 20 2a 70 52 65 73 75 6c 74 20 3d 20 74 6d 70 3b   *pResult = tmp;
1cef0 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
1cf00 20 20 20 20 20 20 44 61 74 61 42 75 66 66 65 72        DataBuffer
1cf10 20 72 65 73 20 3d 20 2a 70 52 65 73 75 6c 74 3b   res = *pResult;
1cf20 0a 20 20 20 20 20 20 20 20 64 61 74 61 42 75 66  .        dataBuf
1cf30 66 65 72 49 6e 69 74 28 70 52 65 73 75 6c 74 2c  ferInit(pResult,
1cf40 20 30 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28   0);.        if(
1cf50 20 69 69 3d 3d 28 70 50 68 72 61 73 65 2d 3e 6e   ii==(pPhrase->n
1cf60 54 6f 6b 65 6e 2d 31 29 20 29 7b 0a 20 20 20 20  Token-1) ){.    
1cf70 20 20 20 20 20 20 65 54 79 70 65 20 3d 20 65 4c        eType = eL
1cf80 69 73 74 54 79 70 65 3b 0a 20 20 20 20 20 20 20  istType;.       
1cf90 20 7d 0a 20 20 20 20 20 20 20 20 64 6f 63 4c 69   }.        docLi
1cfa0 73 74 50 68 72 61 73 65 4d 65 72 67 65 28 0a 20  stPhraseMerge(. 
1cfb0 20 20 20 20 20 20 20 20 20 72 65 73 2e 70 44 61           res.pDa
1cfc0 74 61 2c 20 72 65 73 2e 6e 44 61 74 61 2c 20 74  ta, res.nData, t
1cfd0 6d 70 2e 70 44 61 74 61 2c 20 74 6d 70 2e 6e 44  mp.pData, tmp.nD
1cfe0 61 74 61 2c 20 30 2c 20 30 2c 20 65 54 79 70 65  ata, 0, 0, eType
1cff0 2c 20 70 52 65 73 75 6c 74 0a 20 20 20 20 20 20  , pResult.      
1d000 20 20 29 3b 0a 20 20 20 20 20 20 20 20 64 61 74    );.        dat
1d010 61 42 75 66 66 65 72 44 65 73 74 72 6f 79 28 26  aBufferDestroy(&
1d020 72 65 73 29 3b 0a 20 20 20 20 20 20 20 20 64 61  res);.        da
1d030 74 61 42 75 66 66 65 72 44 65 73 74 72 6f 79 28  taBufferDestroy(
1d040 26 74 6d 70 29 3b 0a 20 20 20 20 20 20 7d 0a 20  &tmp);.      }. 
1d050 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
1d060 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
1d070 45 76 61 6c 75 61 74 65 20 74 68 65 20 66 75 6c  Evaluate the ful
1d080 6c 2d 74 65 78 74 20 65 78 70 72 65 73 73 69 6f  l-text expressio
1d090 6e 20 70 45 78 70 72 20 61 67 61 69 6e 73 74 20  n pExpr against 
1d0a0 66 74 73 33 20 74 61 62 6c 65 20 70 54 61 62 2e  fts3 table pTab.
1d0b0 20 57 72 69 74 65 0a 2a 2a 20 74 68 65 20 72 65   Write.** the re
1d0c0 73 75 6c 74 73 20 69 6e 74 6f 20 70 52 65 73 2e  sults into pRes.
1d0d0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .*/.static int e
1d0e0 76 61 6c 46 74 73 33 45 78 70 72 28 0a 20 20 66  valFts3Expr(.  f
1d0f0 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 70 54  ulltext_vtab *pT
1d100 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ab,           /*
1d110 20 46 74 73 33 20 56 69 72 74 75 61 6c 20 74 61   Fts3 Virtual ta
1d120 62 6c 65 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  ble object */.  
1d130 46 74 73 33 45 78 70 72 20 2a 70 45 78 70 72 2c  Fts3Expr *pExpr,
1d140 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1d150 2a 20 50 61 72 73 65 64 20 66 74 73 33 20 65 78  * Parsed fts3 ex
1d160 70 72 65 73 73 69 6f 6e 20 2a 2f 0a 20 20 44 61  pression */.  Da
1d170 74 61 42 75 66 66 65 72 20 2a 70 52 65 73 20 20  taBuffer *pRes  
1d180 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1d190 4f 55 54 3a 20 57 72 69 74 65 20 72 65 73 75 6c  OUT: Write resul
1d1a0 74 73 20 6f 66 20 74 68 65 20 65 78 70 72 65 73  ts of the expres
1d1b0 73 69 6f 6e 20 68 65 72 65 20 2a 2f 0a 29 7b 0a  sion here */.){.
1d1c0 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
1d1d0 45 5f 4f 4b 3b 0a 0a 20 20 2f 2a 20 49 6e 69 74  E_OK;..  /* Init
1d1e0 69 61 6c 69 7a 65 20 74 68 65 20 6f 75 74 70 75  ialize the outpu
1d1f0 74 20 62 75 66 66 65 72 2e 20 49 66 20 74 68 69  t buffer. If thi
1d200 73 20 69 73 20 61 6e 20 65 6d 70 74 79 20 71 75  s is an empty qu
1d210 65 72 79 20 28 70 45 78 70 72 3d 3d 30 29 2c 20  ery (pExpr==0), 
1d220 0a 20 20 2a 2a 20 74 68 69 73 20 69 73 20 61 6c  .  ** this is al
1d230 6c 20 74 68 61 74 20 6e 65 65 64 73 20 74 6f 20  l that needs to 
1d240 62 65 20 64 6f 6e 65 2e 20 45 6d 70 74 79 20 71  be done. Empty q
1d250 75 65 72 69 65 73 20 70 72 6f 64 75 63 65 20 65  ueries produce e
1d260 6d 70 74 79 20 0a 20 20 2a 2a 20 72 65 73 75 6c  mpty .  ** resul
1d270 74 20 73 65 74 73 2e 0a 20 20 2a 2f 0a 20 20 64  t sets..  */.  d
1d280 61 74 61 42 75 66 66 65 72 49 6e 69 74 28 70 52  ataBufferInit(pR
1d290 65 73 2c 20 30 29 3b 0a 0a 20 20 69 66 28 20 70  es, 0);..  if( p
1d2a0 45 78 70 72 20 29 7b 0a 20 20 20 20 69 66 28 20  Expr ){.    if( 
1d2b0 70 45 78 70 72 2d 3e 65 54 79 70 65 3d 3d 46 54  pExpr->eType==FT
1d2c0 53 51 55 45 52 59 5f 50 48 52 41 53 45 20 29 7b  SQUERY_PHRASE ){
1d2d0 0a 20 20 20 20 20 20 44 6f 63 4c 69 73 74 54 79  .      DocListTy
1d2e0 70 65 20 65 54 79 70 65 20 3d 20 44 4c 5f 44 4f  pe eType = DL_DO
1d2f0 43 49 44 53 3b 0a 20 20 20 20 20 20 69 66 28 20  CIDS;.      if( 
1d300 70 45 78 70 72 2d 3e 70 50 61 72 65 6e 74 20 26  pExpr->pParent &
1d310 26 20 70 45 78 70 72 2d 3e 70 50 61 72 65 6e 74  & pExpr->pParent
1d320 2d 3e 65 54 79 70 65 3d 3d 46 54 53 51 55 45 52  ->eType==FTSQUER
1d330 59 5f 4e 45 41 52 20 29 7b 0a 20 20 20 20 20 20  Y_NEAR ){.      
1d340 20 20 65 54 79 70 65 20 3d 20 44 4c 5f 50 4f 53    eType = DL_POS
1d350 49 54 49 4f 4e 53 3b 0a 20 20 20 20 20 20 7d 0a  ITIONS;.      }.
1d360 20 20 20 20 20 20 72 63 20 3d 20 64 6f 63 4c 69        rc = docLi
1d370 73 74 4f 66 50 68 72 61 73 65 28 70 54 61 62 2c  stOfPhrase(pTab,
1d380 20 70 45 78 70 72 2d 3e 70 50 68 72 61 73 65 2c   pExpr->pPhrase,
1d390 20 65 54 79 70 65 2c 20 70 52 65 73 29 3b 0a 20   eType, pRes);. 
1d3a0 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
1d3b0 44 61 74 61 42 75 66 66 65 72 20 6c 68 73 3b 0a  DataBuffer lhs;.
1d3c0 20 20 20 20 20 20 44 61 74 61 42 75 66 66 65 72        DataBuffer
1d3d0 20 72 68 73 3b 0a 0a 20 20 20 20 20 20 64 61 74   rhs;..      dat
1d3e0 61 42 75 66 66 65 72 49 6e 69 74 28 26 72 68 73  aBufferInit(&rhs
1d3f0 2c 20 30 29 3b 0a 20 20 20 20 20 20 69 66 28 20  , 0);.      if( 
1d400 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d  SQLITE_OK==(rc =
1d410 20 65 76 61 6c 46 74 73 33 45 78 70 72 28 70 54   evalFts3Expr(pT
1d420 61 62 2c 20 70 45 78 70 72 2d 3e 70 4c 65 66 74  ab, pExpr->pLeft
1d430 2c 20 26 6c 68 73 29 29 20 0a 20 20 20 20 20 20  , &lhs)) .      
1d440 20 26 26 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28   && SQLITE_OK==(
1d450 72 63 20 3d 20 65 76 61 6c 46 74 73 33 45 78 70  rc = evalFts3Exp
1d460 72 28 70 54 61 62 2c 20 70 45 78 70 72 2d 3e 70  r(pTab, pExpr->p
1d470 52 69 67 68 74 2c 20 26 72 68 73 29 29 20 0a 20  Right, &rhs)) . 
1d480 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20       ){.        
1d490 73 77 69 74 63 68 28 20 70 45 78 70 72 2d 3e 65  switch( pExpr->e
1d4a0 54 79 70 65 20 29 7b 0a 20 20 20 20 20 20 20 20  Type ){.        
1d4b0 20 20 63 61 73 65 20 46 54 53 51 55 45 52 59 5f    case FTSQUERY_
1d4c0 4e 45 41 52 3a 20 7b 0a 20 20 20 20 20 20 20 20  NEAR: {.        
1d4d0 20 20 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 3b 0a      int nToken;.
1d4e0 20 20 20 20 20 20 20 20 20 20 20 20 46 74 73 33              Fts3
1d4f0 45 78 70 72 20 2a 70 4c 65 66 74 3b 0a 20 20 20  Expr *pLeft;.   
1d500 20 20 20 20 20 20 20 20 20 44 6f 63 4c 69 73 74           DocList
1d510 54 79 70 65 20 65 54 79 70 65 20 3d 20 44 4c 5f  Type eType = DL_
1d520 44 4f 43 49 44 53 3b 0a 20 20 20 20 20 20 20 20  DOCIDS;.        
1d530 20 20 20 20 69 66 28 20 70 45 78 70 72 2d 3e 70      if( pExpr->p
1d540 50 61 72 65 6e 74 20 26 26 20 70 45 78 70 72 2d  Parent && pExpr-
1d550 3e 70 50 61 72 65 6e 74 2d 3e 65 54 79 70 65 3d  >pParent->eType=
1d560 3d 46 54 53 51 55 45 52 59 5f 4e 45 41 52 20 29  =FTSQUERY_NEAR )
1d570 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {.              
1d580 65 54 79 70 65 20 3d 20 44 4c 5f 50 4f 53 49 54  eType = DL_POSIT
1d590 49 4f 4e 53 3b 0a 20 20 20 20 20 20 20 20 20 20  IONS;.          
1d5a0 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20    }.            
1d5b0 70 4c 65 66 74 20 3d 20 70 45 78 70 72 2d 3e 70  pLeft = pExpr->p
1d5c0 4c 65 66 74 3b 0a 20 20 20 20 20 20 20 20 20 20  Left;.          
1d5d0 20 20 77 68 69 6c 65 28 20 70 4c 65 66 74 2d 3e    while( pLeft->
1d5e0 65 54 79 70 65 3d 3d 46 54 53 51 55 45 52 59 5f  eType==FTSQUERY_
1d5f0 4e 45 41 52 20 29 7b 20 0a 20 20 20 20 20 20 20  NEAR ){ .       
1d600 20 20 20 20 20 20 20 70 4c 65 66 74 3d 70 4c 65         pLeft=pLe
1d610 66 74 2d 3e 70 52 69 67 68 74 3b 0a 20 20 20 20  ft->pRight;.    
1d620 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
1d630 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 45        assert( pE
1d640 78 70 72 2d 3e 70 52 69 67 68 74 2d 3e 65 54 79  xpr->pRight->eTy
1d650 70 65 3d 3d 46 54 53 51 55 45 52 59 5f 50 48 52  pe==FTSQUERY_PHR
1d660 41 53 45 20 29 3b 0a 20 20 20 20 20 20 20 20 20  ASE );.         
1d670 20 20 20 61 73 73 65 72 74 28 20 70 4c 65 66 74     assert( pLeft
1d680 2d 3e 65 54 79 70 65 3d 3d 46 54 53 51 55 45 52  ->eType==FTSQUER
1d690 59 5f 50 48 52 41 53 45 20 29 3b 0a 20 20 20 20  Y_PHRASE );.    
1d6a0 20 20 20 20 20 20 20 20 6e 54 6f 6b 65 6e 20 3d          nToken =
1d6b0 20 70 4c 65 66 74 2d 3e 70 50 68 72 61 73 65 2d   pLeft->pPhrase-
1d6c0 3e 6e 54 6f 6b 65 6e 20 2b 20 70 45 78 70 72 2d  >nToken + pExpr-
1d6d0 3e 70 52 69 67 68 74 2d 3e 70 50 68 72 61 73 65  >pRight->pPhrase
1d6e0 2d 3e 6e 54 6f 6b 65 6e 3b 0a 20 20 20 20 20 20  ->nToken;.      
1d6f0 20 20 20 20 20 20 64 6f 63 4c 69 73 74 50 68 72        docListPhr
1d700 61 73 65 4d 65 72 67 65 28 6c 68 73 2e 70 44 61  aseMerge(lhs.pDa
1d710 74 61 2c 20 6c 68 73 2e 6e 44 61 74 61 2c 20 72  ta, lhs.nData, r
1d720 68 73 2e 70 44 61 74 61 2c 20 72 68 73 2e 6e 44  hs.pData, rhs.nD
1d730 61 74 61 2c 20 0a 20 20 20 20 20 20 20 20 20 20  ata, .          
1d740 20 20 20 20 20 20 70 45 78 70 72 2d 3e 6e 4e 65        pExpr->nNe
1d750 61 72 2b 31 2c 20 6e 54 6f 6b 65 6e 2c 20 65 54  ar+1, nToken, eT
1d760 79 70 65 2c 20 70 52 65 73 0a 20 20 20 20 20 20  ype, pRes.      
1d770 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20        );.       
1d780 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
1d790 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
1d7a0 20 20 63 61 73 65 20 46 54 53 51 55 45 52 59 5f    case FTSQUERY_
1d7b0 4e 4f 54 3a 20 7b 0a 20 20 20 20 20 20 20 20 20  NOT: {.         
1d7c0 20 20 20 64 6f 63 4c 69 73 74 45 78 63 65 70 74     docListExcept
1d7d0 4d 65 72 67 65 28 6c 68 73 2e 70 44 61 74 61 2c  Merge(lhs.pData,
1d7e0 20 6c 68 73 2e 6e 44 61 74 61 2c 20 72 68 73 2e   lhs.nData, rhs.
1d7f0 70 44 61 74 61 2c 20 72 68 73 2e 6e 44 61 74 61  pData, rhs.nData
1d800 2c 70 52 65 73 29 3b 0a 20 20 20 20 20 20 20 20  ,pRes);.        
1d810 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
1d820 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
1d830 20 63 61 73 65 20 46 54 53 51 55 45 52 59 5f 41   case FTSQUERY_A
1d840 4e 44 3a 20 7b 0a 20 20 20 20 20 20 20 20 20 20  ND: {.          
1d850 20 20 64 6f 63 4c 69 73 74 41 6e 64 4d 65 72 67    docListAndMerg
1d860 65 28 6c 68 73 2e 70 44 61 74 61 2c 20 6c 68 73  e(lhs.pData, lhs
1d870 2e 6e 44 61 74 61 2c 20 72 68 73 2e 70 44 61 74  .nData, rhs.pDat
1d880 61 2c 20 72 68 73 2e 6e 44 61 74 61 2c 20 70 52  a, rhs.nData, pR
1d890 65 73 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  es);.           
1d8a0 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
1d8b0 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 63 61    }.          ca
1d8c0 73 65 20 46 54 53 51 55 45 52 59 5f 4f 52 3a 20  se FTSQUERY_OR: 
1d8d0 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 6f  {.            do
1d8e0 63 4c 69 73 74 4f 72 4d 65 72 67 65 28 6c 68 73  cListOrMerge(lhs
1d8f0 2e 70 44 61 74 61 2c 20 6c 68 73 2e 6e 44 61 74  .pData, lhs.nDat
1d900 61 2c 20 72 68 73 2e 70 44 61 74 61 2c 20 72 68  a, rhs.pData, rh
1d910 73 2e 6e 44 61 74 61 2c 20 70 52 65 73 29 3b 0a  s.nData, pRes);.
1d920 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61              brea
1d930 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  k;.          }. 
1d940 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
1d950 0a 20 20 20 20 20 20 64 61 74 61 42 75 66 66 65  .      dataBuffe
1d960 72 44 65 73 74 72 6f 79 28 26 6c 68 73 29 3b 0a  rDestroy(&lhs);.
1d970 20 20 20 20 20 20 64 61 74 61 42 75 66 66 65 72        dataBuffer
1d980 44 65 73 74 72 6f 79 28 26 72 68 73 29 3b 0a 20  Destroy(&rhs);. 
1d990 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
1d9a0 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 54 4f 44  rn rc;.}../* TOD
1d9b0 4f 28 73 68 65 73 73 29 20 52 65 66 61 63 74 6f  O(shess) Refacto
1d9c0 72 20 74 68 65 20 63 6f 64 65 20 74 6f 20 72 65  r the code to re
1d9d0 6d 6f 76 65 20 74 68 69 73 20 66 6f 72 77 61 72  move this forwar
1d9e0 64 20 64 65 63 6c 2e 20 2a 2f 0a 73 74 61 74 69  d decl. */.stati
1d9f0 63 20 69 6e 74 20 66 6c 75 73 68 50 65 6e 64 69  c int flushPendi
1da00 6e 67 54 65 72 6d 73 28 66 75 6c 6c 74 65 78 74  ngTerms(fulltext
1da10 5f 76 74 61 62 20 2a 76 29 3b 0a 0a 2f 2a 20 50  _vtab *v);../* P
1da20 65 72 66 6f 72 6d 20 61 20 66 75 6c 6c 2d 74 65  erform a full-te
1da30 78 74 20 71 75 65 72 79 20 75 73 69 6e 67 20 74  xt query using t
1da40 68 65 20 73 65 61 72 63 68 20 65 78 70 72 65 73  he search expres
1da50 73 69 6f 6e 20 69 6e 0a 2a 2a 20 7a 49 6e 70 75  sion in.** zInpu
1da60 74 5b 30 2e 2e 6e 49 6e 70 75 74 2d 31 5d 2e 20  t[0..nInput-1]. 
1da70 20 52 65 74 75 72 6e 20 61 20 6c 69 73 74 20 6f   Return a list o
1da80 66 20 6d 61 74 63 68 69 6e 67 20 64 6f 63 75 6d  f matching docum
1da90 65 6e 74 73 0a 2a 2a 20 69 6e 20 70 52 65 73 75  ents.** in pResu
1daa0 6c 74 2e 0a 2a 2a 0a 2a 2a 20 51 75 65 72 69 65  lt..**.** Querie
1dab0 73 20 6d 75 73 74 20 6d 61 74 63 68 20 63 6f 6c  s must match col
1dac0 75 6d 6e 20 69 43 6f 6c 75 6d 6e 2e 20 20 4f 72  umn iColumn.  Or
1dad0 20 69 66 20 69 43 6f 6c 75 6d 6e 3e 3d 6e 43 6f   if iColumn>=nCo
1dae0 6c 75 6d 6e 0a 2a 2a 20 74 68 65 79 20 61 72 65  lumn.** they are
1daf0 20 61 6c 6c 6f 77 65 64 20 74 6f 20 6d 61 74 63   allowed to matc
1db00 68 20 61 67 61 69 6e 73 74 20 61 6e 79 20 63 6f  h against any co
1db10 6c 75 6d 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lumn..*/.static 
1db20 69 6e 74 20 66 75 6c 6c 74 65 78 74 51 75 65 72  int fulltextQuer
1db30 79 28 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76 74  y(.  fulltext_vt
1db40 61 62 20 2a 76 2c 20 20 20 20 20 20 2f 2a 20 54  ab *v,      /* T
1db50 68 65 20 66 75 6c 6c 20 74 65 78 74 20 69 6e 64  he full text ind
1db60 65 78 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c  ex */.  int iCol
1db70 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20 2f  umn,           /
1db80 2a 20 4d 61 74 63 68 20 61 67 61 69 6e 73 74 20  * Match against 
1db90 74 68 69 73 20 63 6f 6c 75 6d 6e 20 62 79 20 64  this column by d
1dba0 65 66 61 75 6c 74 20 2a 2f 0a 20 20 63 6f 6e 73  efault */.  cons
1dbb0 74 20 63 68 61 72 20 2a 7a 49 6e 70 75 74 2c 20  t char *zInput, 
1dbc0 20 20 20 2f 2a 20 54 68 65 20 71 75 65 72 79 20     /* The query 
1dbd0 73 74 72 69 6e 67 20 2a 2f 0a 20 20 69 6e 74 20  string */.  int 
1dbe0 6e 49 6e 70 75 74 2c 20 20 20 20 20 20 20 20 20  nInput,         
1dbf0 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
1dc00 62 79 74 65 73 20 69 6e 20 7a 49 6e 70 75 74 5b  bytes in zInput[
1dc10 5d 20 2a 2f 0a 20 20 44 61 74 61 42 75 66 66 65  ] */.  DataBuffe
1dc20 72 20 2a 70 52 65 73 75 6c 74 2c 20 20 20 2f 2a  r *pResult,   /*
1dc30 20 57 72 69 74 65 20 74 68 65 20 72 65 73 75 6c   Write the resul
1dc40 74 20 64 6f 63 6c 69 73 74 20 68 65 72 65 20 2a  t doclist here *
1dc50 2f 0a 20 20 46 74 73 33 45 78 70 72 20 2a 2a 70  /.  Fts3Expr **p
1dc60 70 45 78 70 72 20 20 20 20 20 20 20 20 2f 2a 20  pExpr        /* 
1dc70 50 75 74 20 70 61 72 73 65 64 20 71 75 65 72 79  Put parsed query
1dc80 20 73 74 72 69 6e 67 20 68 65 72 65 20 2a 2f 0a   string here */.
1dc90 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  ){.  int rc;..  
1dca0 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 49  /* TODO(shess) I
1dcb0 6e 73 74 65 61 64 20 6f 66 20 66 6c 75 73 68 69  nstead of flushi
1dcc0 6e 67 20 70 65 6e 64 69 6e 67 54 65 72 6d 73 2c  ng pendingTerms,
1dcd0 20 77 65 20 63 6f 75 6c 64 20 71 75 65 72 79 20   we could query 
1dce0 66 6f 72 0a 20 20 2a 2a 20 74 68 65 20 72 65 6c  for.  ** the rel
1dcf0 65 76 61 6e 74 20 74 65 72 6d 20 61 6e 64 20 6d  evant term and m
1dd00 65 72 67 65 20 74 68 65 20 64 6f 63 6c 69 73 74  erge the doclist
1dd10 20 69 6e 74 6f 20 77 68 61 74 20 77 65 20 72 65   into what we re
1dd20 63 65 69 76 65 20 66 72 6f 6d 0a 20 20 2a 2a 20  ceive from.  ** 
1dd30 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 20 57  the database.  W
1dd40 61 69 74 20 61 6e 64 20 73 65 65 20 69 66 20 74  ait and see if t
1dd50 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 6f 6e 20  his is a common 
1dd60 69 73 73 75 65 2c 20 66 69 72 73 74 2e 0a 20 20  issue, first..  
1dd70 2a 2a 0a 20 20 2a 2a 20 41 20 67 6f 6f 64 20 72  **.  ** A good r
1dd80 65 61 73 6f 6e 20 6e 6f 74 20 74 6f 20 66 6c 75  eason not to flu
1dd90 73 68 20 69 73 20 74 6f 20 6e 6f 74 20 67 65 6e  sh is to not gen
1dda0 65 72 61 74 65 20 75 70 64 61 74 65 2d 72 65 6c  erate update-rel
1ddb0 61 74 65 64 0a 20 20 2a 2a 20 65 72 72 6f 72 20  ated.  ** error 
1ddc0 63 6f 64 65 73 20 66 72 6f 6d 20 68 65 72 65 2e  codes from here.
1ddd0 0a 20 20 2a 2f 0a 0a 20 20 2f 2a 20 46 6c 75 73  .  */..  /* Flus
1dde0 68 20 61 6e 79 20 62 75 66 66 65 72 65 64 20 75  h any buffered u
1ddf0 70 64 61 74 65 73 20 62 65 66 6f 72 65 20 65 78  pdates before ex
1de00 65 63 75 74 69 6e 67 20 74 68 65 20 71 75 65 72  ecuting the quer
1de10 79 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 66 6c 75  y. */.  rc = flu
1de20 73 68 50 65 6e 64 69 6e 67 54 65 72 6d 73 28 76  shPendingTerms(v
1de30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
1de40 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 65  ITE_OK ){.    re
1de50 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20  turn rc;.  }..  
1de60 2f 2a 20 50 61 72 73 65 20 74 68 65 20 71 75 65  /* Parse the que
1de70 72 79 20 70 61 73 73 65 64 20 74 6f 20 74 68 65  ry passed to the
1de80 20 4d 41 54 43 48 20 6f 70 65 72 61 74 6f 72 2e   MATCH operator.
1de90 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74   */.  rc = sqlit
1dea0 65 33 46 74 73 33 45 78 70 72 50 61 72 73 65 28  e3Fts3ExprParse(
1deb0 76 2d 3e 70 54 6f 6b 65 6e 69 7a 65 72 2c 20 0a  v->pTokenizer, .
1dec0 20 20 20 20 20 20 76 2d 3e 61 7a 43 6f 6c 75 6d        v->azColum
1ded0 6e 2c 20 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 69  n, v->nColumn, i
1dee0 43 6f 6c 75 6d 6e 2c 20 7a 49 6e 70 75 74 2c 20  Column, zInput, 
1def0 6e 49 6e 70 75 74 2c 20 70 70 45 78 70 72 0a 20  nInput, ppExpr. 
1df00 20 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51   );.  if( rc!=SQ
1df10 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 61  LITE_OK ){.    a
1df20 73 73 65 72 74 28 20 30 3d 3d 28 2a 70 70 45 78  ssert( 0==(*ppEx
1df30 70 72 29 20 29 3b 0a 20 20 20 20 72 65 74 75 72  pr) );.    retur
1df40 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  n rc;.  }..  ret
1df50 75 72 6e 20 65 76 61 6c 46 74 73 33 45 78 70 72  urn evalFts3Expr
1df60 28 76 2c 20 2a 70 70 45 78 70 72 2c 20 70 52 65  (v, *ppExpr, pRe
1df70 73 75 6c 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  sult);.}../*.** 
1df80 54 68 69 73 20 69 73 20 74 68 65 20 78 46 69 6c  This is the xFil
1df90 74 65 72 20 69 6e 74 65 72 66 61 63 65 20 66 6f  ter interface fo
1dfa0 72 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  r the virtual ta
1dfb0 62 6c 65 2e 20 20 53 65 65 0a 2a 2a 20 74 68 65  ble.  See.** the
1dfc0 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 78   virtual table x
1dfd0 46 69 6c 74 65 72 20 6d 65 74 68 6f 64 20 64 6f  Filter method do
1dfe0 63 75 6d 65 6e 74 61 74 69 6f 6e 20 66 6f 72 20  cumentation for 
1dff0 61 64 64 69 74 69 6f 6e 61 6c 0a 2a 2a 20 69 6e  additional.** in
1e000 66 6f 72 6d 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a  formation..**.**
1e010 20 49 66 20 69 64 78 4e 75 6d 3d 3d 51 55 45 52   If idxNum==QUER
1e020 59 5f 47 45 4e 45 52 49 43 20 74 68 65 6e 20 64  Y_GENERIC then d
1e030 6f 20 61 20 66 75 6c 6c 20 74 61 62 6c 65 20 73  o a full table s
1e040 63 61 6e 20 61 67 61 69 6e 73 74 0a 2a 2a 20 74  can against.** t
1e050 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62  he %_content tab
1e060 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 69 64 78  le..**.** If idx
1e070 4e 75 6d 3d 3d 51 55 45 52 59 5f 44 4f 43 49 44  Num==QUERY_DOCID
1e080 20 74 68 65 6e 20 64 6f 20 61 20 64 6f 63 69 64   then do a docid
1e090 20 6c 6f 6f 6b 75 70 20 66 6f 72 20 61 20 73 69   lookup for a si
1e0a0 6e 67 6c 65 20 65 6e 74 72 79 0a 2a 2a 20 69 6e  ngle entry.** in
1e0b0 20 74 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74   the %_content t
1e0c0 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 69  able..**.** If i
1e0d0 64 78 4e 75 6d 3e 3d 51 55 45 52 59 5f 46 55 4c  dxNum>=QUERY_FUL
1e0e0 4c 54 45 58 54 20 74 68 65 6e 20 75 73 65 20 74  LTEXT then use t
1e0f0 68 65 20 66 75 6c 6c 20 74 65 78 74 20 69 6e 64  he full text ind
1e100 65 78 2e 20 20 54 68 65 0a 2a 2a 20 63 6f 6c 75  ex.  The.** colu
1e110 6d 6e 20 6f 6e 20 74 68 65 20 6c 65 66 74 2d 68  mn on the left-h
1e120 61 6e 64 20 73 69 64 65 20 6f 66 20 74 68 65 20  and side of the 
1e130 4d 41 54 43 48 20 6f 70 65 72 61 74 6f 72 20 69  MATCH operator i
1e140 73 20 63 6f 6c 75 6d 6e 0a 2a 2a 20 6e 75 6d 62  s column.** numb
1e150 65 72 20 69 64 78 4e 75 6d 2d 51 55 45 52 59 5f  er idxNum-QUERY_
1e160 46 55 4c 4c 54 45 58 54 2c 20 30 20 69 6e 64 65  FULLTEXT, 0 inde
1e170 78 65 64 2e 20 20 61 72 67 76 5b 30 5d 20 69 73  xed.  argv[0] is
1e180 20 74 68 65 20 72 69 67 68 74 2d 68 61 6e 64 0a   the right-hand.
1e190 2a 2a 20 73 69 64 65 20 6f 66 20 74 68 65 20 4d  ** side of the M
1e1a0 41 54 43 48 20 6f 70 65 72 61 74 6f 72 2e 0a 2a  ATCH operator..*
1e1b0 2f 0a 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29  /./* TODO(shess)
1e1c0 20 55 70 67 72 61 64 65 20 74 68 65 20 63 75 72   Upgrade the cur
1e1d0 73 6f 72 20 69 6e 69 74 69 61 6c 69 7a 61 74 69  sor initializati
1e1e0 6f 6e 20 61 6e 64 20 64 65 73 74 72 75 63 74 69  on and destructi
1e1f0 6f 6e 20 74 6f 0a 2a 2a 20 61 63 63 6f 75 6e 74  on to.** account
1e200 20 66 6f 72 20 66 75 6c 6c 74 65 78 74 46 69 6c   for fulltextFil
1e210 74 65 72 28 29 20 62 65 69 6e 67 20 63 61 6c 6c  ter() being call
1e220 65 64 20 6d 75 6c 74 69 70 6c 65 20 74 69 6d 65  ed multiple time
1e230 73 20 6f 6e 20 74 68 65 0a 2a 2a 20 73 61 6d 65  s on the.** same
1e240 20 63 75 72 73 6f 72 2e 20 20 54 68 65 20 63 75   cursor.  The cu
1e250 72 72 65 6e 74 20 73 6f 6c 75 74 69 6f 6e 20 69  rrent solution i
1e260 73 20 76 65 72 79 20 66 72 61 67 69 6c 65 2e 20  s very fragile. 
1e270 20 41 70 70 6c 79 20 66 69 78 20 74 6f 0a 2a 2a   Apply fix to.**
1e280 20 66 74 73 33 20 61 73 20 61 70 70 72 6f 70 72   fts3 as appropr
1e290 69 61 74 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  iate..*/.static 
1e2a0 69 6e 74 20 66 75 6c 6c 74 65 78 74 46 69 6c 74  int fulltextFilt
1e2b0 65 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  er(.  sqlite3_vt
1e2c0 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73  ab_cursor *pCurs
1e2d0 6f 72 2c 20 20 20 20 20 2f 2a 20 54 68 65 20 63  or,     /* The c
1e2e0 75 72 73 6f 72 20 75 73 65 64 20 66 6f 72 20 74  ursor used for t
1e2f0 68 69 73 20 71 75 65 72 79 20 2a 2f 0a 20 20 69  his query */.  i
1e300 6e 74 20 69 64 78 4e 75 6d 2c 20 63 6f 6e 73 74  nt idxNum, const
1e310 20 63 68 61 72 20 2a 69 64 78 53 74 72 2c 20 20   char *idxStr,  
1e320 20 2f 2a 20 57 68 69 63 68 20 69 6e 64 65 78 69   /* Which indexi
1e330 6e 67 20 73 63 68 65 6d 65 20 74 6f 20 75 73 65  ng scheme to use
1e340 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20   */.  int argc, 
1e350 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
1e360 61 72 67 76 20 20 20 20 2f 2a 20 41 72 67 75 6d  argv    /* Argum
1e370 65 6e 74 73 20 66 6f 72 20 74 68 65 20 69 6e 64  ents for the ind
1e380 65 78 69 6e 67 20 73 63 68 65 6d 65 20 2a 2f 0a  exing scheme */.
1e390 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75  ){.  fulltext_cu
1e3a0 72 73 6f 72 20 2a 63 20 3d 20 28 66 75 6c 6c 74  rsor *c = (fullt
1e3b0 65 78 74 5f 63 75 72 73 6f 72 20 2a 29 20 70 43  ext_cursor *) pC
1e3c0 75 72 73 6f 72 3b 0a 20 20 66 75 6c 6c 74 65 78  ursor;.  fulltex
1e3d0 74 5f 76 74 61 62 20 2a 76 20 3d 20 63 75 72 73  t_vtab *v = curs
1e3e0 6f 72 5f 76 74 61 62 28 63 29 3b 0a 20 20 69 6e  or_vtab(c);.  in
1e3f0 74 20 72 63 3b 0a 0a 20 20 46 54 53 54 52 41 43  t rc;..  FTSTRAC
1e400 45 28 28 22 46 54 53 33 20 46 69 6c 74 65 72 20  E(("FTS3 Filter 
1e410 25 70 5c 6e 22 2c 70 43 75 72 73 6f 72 29 29 3b  %p\n",pCursor));
1e420 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 63 75  ..  /* If the cu
1e430 72 73 6f 72 20 68 61 73 20 61 20 73 74 61 74 65  rsor has a state
1e440 6d 65 6e 74 20 74 68 61 74 20 77 61 73 20 6e 6f  ment that was no
1e450 74 20 70 72 65 70 61 72 65 64 20 61 63 63 6f 72  t prepared accor
1e460 64 69 6e 67 20 74 6f 0a 20 20 2a 2a 20 69 64 78  ding to.  ** idx
1e470 4e 75 6d 2c 20 63 6c 65 61 72 20 69 74 2e 20 20  Num, clear it.  
1e480 49 20 62 65 6c 69 65 76 65 20 61 6c 6c 20 63 61  I believe all ca
1e490 6c 6c 73 20 74 6f 20 66 75 6c 6c 74 65 78 74 46  lls to fulltextF
1e4a0 69 6c 74 65 72 20 77 69 74 68 20 61 0a 20 20 2a  ilter with a.  *
1e4b0 2a 20 67 69 76 65 6e 20 63 75 72 73 6f 72 20 77  * given cursor w
1e4c0 69 6c 6c 20 68 61 76 65 20 74 68 65 20 73 61 6d  ill have the sam
1e4d0 65 20 69 64 78 4e 75 6d 20 2c 20 62 75 74 20 69  e idxNum , but i
1e4e0 6e 20 74 68 69 73 20 63 61 73 65 20 69 74 27 73  n this case it's
1e4f0 0a 20 20 2a 2a 20 65 61 73 79 20 74 6f 20 62 65  .  ** easy to be
1e500 20 73 61 66 65 2e 0a 20 20 2a 2f 0a 20 20 69 66   safe..  */.  if
1e510 28 20 63 2d 3e 70 53 74 6d 74 20 26 26 20 63 2d  ( c->pStmt && c-
1e520 3e 69 43 75 72 73 6f 72 54 79 70 65 21 3d 69 64  >iCursorType!=id
1e530 78 4e 75 6d 20 29 7b 0a 20 20 20 20 73 71 6c 69  xNum ){.    sqli
1e540 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 63 2d 3e  te3_finalize(c->
1e550 70 53 74 6d 74 29 3b 0a 20 20 20 20 63 2d 3e 70  pStmt);.    c->p
1e560 53 74 6d 74 20 3d 20 4e 55 4c 4c 3b 0a 20 20 7d  Stmt = NULL;.  }
1e570 0a 0a 20 20 2f 2a 20 47 65 74 20 61 20 66 72 65  ..  /* Get a fre
1e580 73 68 20 73 74 61 74 65 6d 65 6e 74 20 61 70 70  sh statement app
1e590 72 6f 70 72 69 61 74 65 20 74 6f 20 69 64 78 4e  ropriate to idxN
1e5a0 75 6d 2e 20 2a 2f 0a 20 20 2f 2a 20 54 4f 44 4f  um. */.  /* TODO
1e5b0 28 73 68 65 73 73 29 3a 20 41 64 64 20 61 20 70  (shess): Add a p
1e5c0 72 65 70 61 72 65 64 2d 73 74 61 74 65 6d 65 6e  repared-statemen
1e5d0 74 20 63 61 63 68 65 20 69 6e 20 74 68 65 20 76  t cache in the v
1e5e0 74 20 73 74 72 75 63 74 75 72 65 2e 0a 20 20 2a  t structure..  *
1e5f0 2a 20 54 68 65 20 63 61 63 68 65 20 6d 75 73 74  * The cache must
1e600 20 68 61 6e 64 6c 65 20 6d 75 6c 74 69 70 6c 65   handle multiple
1e610 20 6f 70 65 6e 20 63 75 72 73 6f 72 73 2e 20 20   open cursors.  
1e620 45 61 73 69 65 72 20 74 6f 20 63 61 63 68 65 20  Easier to cache 
1e630 74 68 65 0a 20 20 2a 2a 20 73 74 61 74 65 6d 65  the.  ** stateme
1e640 6e 74 20 76 61 72 69 61 6e 74 73 20 61 74 20 74  nt variants at t
1e650 68 65 20 76 74 20 74 6f 20 72 65 64 75 63 65 20  he vt to reduce 
1e660 6d 61 6c 6c 6f 63 2f 72 65 61 6c 6c 6f 63 2f 66  malloc/realloc/f
1e670 72 65 65 20 68 65 72 65 2e 0a 20 20 2a 2a 20 4f  ree here..  ** O
1e680 72 20 77 65 20 63 6f 75 6c 64 20 68 61 76 65 20  r we could have 
1e690 61 20 53 74 72 69 6e 67 42 75 66 66 65 72 20 76  a StringBuffer v
1e6a0 61 72 69 61 6e 74 20 77 68 69 63 68 20 61 6c 6c  ariant which all
1e6b0 6f 77 65 64 20 73 74 61 63 6b 0a 20 20 2a 2a 20  owed stack.  ** 
1e6c0 63 6f 6e 73 74 72 75 63 74 69 6f 6e 20 66 6f 72  construction for
1e6d0 20 73 6d 61 6c 6c 20 76 61 6c 75 65 73 2e 0a 20   small values.. 
1e6e0 20 2a 2f 0a 20 20 69 66 28 20 21 63 2d 3e 70 53   */.  if( !c->pS
1e6f0 74 6d 74 20 29 7b 0a 20 20 20 20 53 74 72 69 6e  tmt ){.    Strin
1e700 67 42 75 66 66 65 72 20 73 62 3b 0a 20 20 20 20  gBuffer sb;.    
1e710 69 6e 69 74 53 74 72 69 6e 67 42 75 66 66 65 72  initStringBuffer
1e720 28 26 73 62 29 3b 0a 20 20 20 20 61 70 70 65 6e  (&sb);.    appen
1e730 64 28 26 73 62 2c 20 22 53 45 4c 45 43 54 20 64  d(&sb, "SELECT d
1e740 6f 63 69 64 2c 20 22 29 3b 0a 20 20 20 20 61 70  ocid, ");.    ap
1e750 70 65 6e 64 4c 69 73 74 28 26 73 62 2c 20 76 2d  pendList(&sb, v-
1e760 3e 6e 43 6f 6c 75 6d 6e 2c 20 76 2d 3e 61 7a 43  >nColumn, v->azC
1e770 6f 6e 74 65 6e 74 43 6f 6c 75 6d 6e 29 3b 0a 20  ontentColumn);. 
1e780 20 20 20 61 70 70 65 6e 64 28 26 73 62 2c 20 22     append(&sb, "
1e790 20 46 52 4f 4d 20 25 5f 63 6f 6e 74 65 6e 74 22   FROM %_content"
1e7a0 29 3b 0a 20 20 20 20 69 66 28 20 69 64 78 4e 75  );.    if( idxNu
1e7b0 6d 21 3d 51 55 45 52 59 5f 47 45 4e 45 52 49 43  m!=QUERY_GENERIC
1e7c0 20 29 20 61 70 70 65 6e 64 28 26 73 62 2c 20 22   ) append(&sb, "
1e7d0 20 57 48 45 52 45 20 64 6f 63 69 64 20 3d 20 3f   WHERE docid = ?
1e7e0 22 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c  ");.    rc = sql
1e7f0 5f 70 72 65 70 61 72 65 28 76 2d 3e 64 62 2c 20  _prepare(v->db, 
1e800 76 2d 3e 7a 44 62 2c 20 76 2d 3e 7a 4e 61 6d 65  v->zDb, v->zName
1e810 2c 20 26 63 2d 3e 70 53 74 6d 74 2c 0a 20 20 20  , &c->pStmt,.   
1e820 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e830 20 20 73 74 72 69 6e 67 42 75 66 66 65 72 44 61    stringBufferDa
1e840 74 61 28 26 73 62 29 29 3b 0a 20 20 20 20 73 74  ta(&sb));.    st
1e850 72 69 6e 67 42 75 66 66 65 72 44 65 73 74 72 6f  ringBufferDestro
1e860 79 28 26 73 62 29 3b 0a 20 20 20 20 69 66 28 20  y(&sb);.    if( 
1e870 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
1e880 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 63  return rc;.    c
1e890 2d 3e 69 43 75 72 73 6f 72 54 79 70 65 20 3d 20  ->iCursorType = 
1e8a0 69 64 78 4e 75 6d 3b 0a 20 20 7d 65 6c 73 65 7b  idxNum;.  }else{
1e8b0 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
1e8c0 65 74 28 63 2d 3e 70 53 74 6d 74 29 3b 0a 20 20  et(c->pStmt);.  
1e8d0 20 20 61 73 73 65 72 74 28 20 63 2d 3e 69 43 75    assert( c->iCu
1e8e0 72 73 6f 72 54 79 70 65 3d 3d 69 64 78 4e 75 6d  rsorType==idxNum
1e8f0 20 29 3b 0a 20 20 7d 0a 0a 20 20 73 77 69 74 63   );.  }..  switc
1e900 68 28 20 69 64 78 4e 75 6d 20 29 7b 0a 20 20 20  h( idxNum ){.   
1e910 20 63 61 73 65 20 51 55 45 52 59 5f 47 45 4e 45   case QUERY_GENE
1e920 52 49 43 3a 0a 20 20 20 20 20 20 62 72 65 61 6b  RIC:.      break
1e930 3b 0a 0a 20 20 20 20 63 61 73 65 20 51 55 45 52  ;..    case QUER
1e940 59 5f 44 4f 43 49 44 3a 0a 20 20 20 20 20 20 72  Y_DOCID:.      r
1e950 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
1e960 5f 69 6e 74 36 34 28 63 2d 3e 70 53 74 6d 74 2c  _int64(c->pStmt,
1e970 20 31 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   1, sqlite3_valu
1e980 65 5f 69 6e 74 36 34 28 61 72 67 76 5b 30 5d 29  e_int64(argv[0])
1e990 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
1e9a0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
1e9b0 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 62 72  urn rc;.      br
1e9c0 65 61 6b 3b 0a 0a 20 20 20 20 64 65 66 61 75 6c  eak;..    defaul
1e9d0 74 3a 20 20 20 2f 2a 20 66 75 6c 6c 2d 74 65 78  t:   /* full-tex
1e9e0 74 20 73 65 61 72 63 68 20 2a 2f 0a 20 20 20 20  t search */.    
1e9f0 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 43 6f 6c  {.      int iCol
1ea00 20 3d 20 69 64 78 4e 75 6d 2d 51 55 45 52 59 5f   = idxNum-QUERY_
1ea10 46 55 4c 4c 54 45 58 54 3b 0a 20 20 20 20 20 20  FULLTEXT;.      
1ea20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 51 75 65  const char *zQue
1ea30 72 79 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72  ry = (const char
1ea40 20 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65   *)sqlite3_value
1ea50 5f 74 65 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a  _text(argv[0]);.
1ea60 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 64        assert( id
1ea70 78 4e 75 6d 3c 3d 51 55 45 52 59 5f 46 55 4c 4c  xNum<=QUERY_FULL
1ea80 54 45 58 54 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e 29  TEXT+v->nColumn)
1ea90 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
1eaa0 61 72 67 63 3d 3d 31 20 29 3b 0a 20 20 20 20 20  argc==1 );.     
1eab0 20 69 66 28 20 63 2d 3e 72 65 73 75 6c 74 2e 6e   if( c->result.n
1eac0 44 61 74 61 21 3d 30 20 29 7b 0a 20 20 20 20 20  Data!=0 ){.     
1ead0 20 20 20 2f 2a 20 54 68 69 73 20 63 61 73 65 20     /* This case 
1eae0 68 61 70 70 65 6e 73 20 69 66 20 74 68 65 20 73  happens if the s
1eaf0 61 6d 65 20 63 75 72 73 6f 72 20 69 73 20 75 73  ame cursor is us
1eb00 65 64 20 72 65 70 65 61 74 65 64 6c 79 2e 20 2a  ed repeatedly. *
1eb10 2f 0a 20 20 20 20 20 20 20 20 64 6c 72 44 65 73  /.        dlrDes
1eb20 74 72 6f 79 28 26 63 2d 3e 72 65 61 64 65 72 29  troy(&c->reader)
1eb30 3b 0a 20 20 20 20 20 20 20 20 64 61 74 61 42 75  ;.        dataBu
1eb40 66 66 65 72 52 65 73 65 74 28 26 63 2d 3e 72 65  fferReset(&c->re
1eb50 73 75 6c 74 29 3b 0a 20 20 20 20 20 20 7d 65 6c  sult);.      }el
1eb60 73 65 7b 0a 20 20 20 20 20 20 20 20 64 61 74 61  se{.        data
1eb70 42 75 66 66 65 72 49 6e 69 74 28 26 63 2d 3e 72  BufferInit(&c->r
1eb80 65 73 75 6c 74 2c 20 30 29 3b 0a 20 20 20 20 20  esult, 0);.     
1eb90 20 7d 0a 20 20 20 20 20 20 72 63 20 3d 20 66 75   }.      rc = fu
1eba0 6c 6c 74 65 78 74 51 75 65 72 79 28 76 2c 20 69  lltextQuery(v, i
1ebb0 43 6f 6c 2c 20 7a 51 75 65 72 79 2c 20 2d 31 2c  Col, zQuery, -1,
1ebc0 20 26 63 2d 3e 72 65 73 75 6c 74 2c 20 26 63 2d   &c->result, &c-
1ebd0 3e 70 45 78 70 72 29 3b 0a 20 20 20 20 20 20 69  >pExpr);.      i
1ebe0 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
1ebf0 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
1ec00 20 20 20 20 69 66 28 20 63 2d 3e 72 65 73 75 6c      if( c->resul
1ec10 74 2e 6e 44 61 74 61 21 3d 30 20 29 7b 0a 20 20  t.nData!=0 ){.  
1ec20 20 20 20 20 20 20 64 6c 72 49 6e 69 74 28 26 63        dlrInit(&c
1ec30 2d 3e 72 65 61 64 65 72 2c 20 44 4c 5f 44 4f 43  ->reader, DL_DOC
1ec40 49 44 53 2c 20 63 2d 3e 72 65 73 75 6c 74 2e 70  IDS, c->result.p
1ec50 44 61 74 61 2c 20 63 2d 3e 72 65 73 75 6c 74 2e  Data, c->result.
1ec60 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 7d 0a  nData);.      }.
1ec70 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
1ec80 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
1ec90 20 66 75 6c 6c 74 65 78 74 4e 65 78 74 28 70 43   fulltextNext(pC
1eca0 75 72 73 6f 72 29 3b 0a 7d 0a 0a 2f 2a 20 54 68  ursor);.}../* Th
1ecb0 69 73 20 69 73 20 74 68 65 20 78 45 6f 66 20 6d  is is the xEof m
1ecc0 65 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69 72  ethod of the vir
1ecd0 74 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 65  tual table.  The
1ece0 20 53 51 4c 69 74 65 20 63 6f 72 65 0a 2a 2a 20   SQLite core.** 
1ecf0 63 61 6c 6c 73 20 74 68 69 73 20 72 6f 75 74 69  calls this routi
1ed00 6e 65 20 74 6f 20 66 69 6e 64 20 6f 75 74 20 69  ne to find out i
1ed10 66 20 69 74 20 68 61 73 20 72 65 61 63 68 65 64  f it has reached
1ed20 20 74 68 65 20 65 6e 64 20 6f 66 0a 2a 2a 20 61   the end of.** a
1ed30 20 71 75 65 72 79 27 73 20 72 65 73 75 6c 74 73   query's results
1ed40 20 73 65 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20   set..*/.static 
1ed50 69 6e 74 20 66 75 6c 6c 74 65 78 74 45 6f 66 28  int fulltextEof(
1ed60 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
1ed70 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20  sor *pCursor){. 
1ed80 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72   fulltext_cursor
1ed90 20 2a 63 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f   *c = (fulltext_
1eda0 63 75 72 73 6f 72 20 2a 29 20 70 43 75 72 73 6f  cursor *) pCurso
1edb0 72 3b 0a 20 20 72 65 74 75 72 6e 20 63 2d 3e 65  r;.  return c->e
1edc0 6f 66 3b 0a 7d 0a 0a 2f 2a 20 54 68 69 73 20 69  of;.}../* This i
1edd0 73 20 74 68 65 20 78 43 6f 6c 75 6d 6e 20 6d 65  s the xColumn me
1ede0 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69 72 74  thod of the virt
1edf0 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 65 20  ual table.  The 
1ee00 53 51 4c 69 74 65 0a 2a 2a 20 63 6f 72 65 20 63  SQLite.** core c
1ee10 61 6c 6c 73 20 74 68 69 73 20 6d 65 74 68 6f 64  alls this method
1ee20 20 64 75 72 69 6e 67 20 61 20 71 75 65 72 79 20   during a query 
1ee30 77 68 65 6e 20 69 74 20 6e 65 65 64 73 20 74 68  when it needs th
1ee40 65 20 76 61 6c 75 65 0a 2a 2a 20 6f 66 20 61 20  e value.** of a 
1ee50 63 6f 6c 75 6d 6e 20 66 72 6f 6d 20 74 68 65 20  column from the 
1ee60 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20  virtual table.  
1ee70 54 68 69 73 20 6d 65 74 68 6f 64 20 6e 65 65 64  This method need
1ee80 73 20 74 6f 20 75 73 65 0a 2a 2a 20 6f 6e 65 20  s to use.** one 
1ee90 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 72  of the sqlite3_r
1eea0 65 73 75 6c 74 5f 2a 28 29 20 72 6f 75 74 69 6e  esult_*() routin
1eeb0 65 73 20 74 6f 20 73 74 6f 72 65 20 74 68 65 20  es to store the 
1eec0 72 65 71 75 65 73 74 65 64 0a 2a 2a 20 76 61 6c  requested.** val
1eed0 75 65 20 62 61 63 6b 20 69 6e 20 74 68 65 20 70  ue back in the p
1eee0 43 6f 6e 74 65 78 74 2e 0a 2a 2f 0a 73 74 61 74  Context..*/.stat
1eef0 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 43  ic int fulltextC
1ef00 6f 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74  olumn(sqlite3_vt
1ef10 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73  ab_cursor *pCurs
1ef20 6f 72 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  or,.            
1ef30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
1ef40 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70  lite3_context *p
1ef50 43 6f 6e 74 65 78 74 2c 20 69 6e 74 20 69 64 78  Context, int idx
1ef60 43 6f 6c 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74  Col){.  fulltext
1ef70 5f 63 75 72 73 6f 72 20 2a 63 20 3d 20 28 66 75  _cursor *c = (fu
1ef80 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 29  lltext_cursor *)
1ef90 20 70 43 75 72 73 6f 72 3b 0a 20 20 66 75 6c 6c   pCursor;.  full
1efa0 74 65 78 74 5f 76 74 61 62 20 2a 76 20 3d 20 63  text_vtab *v = c
1efb0 75 72 73 6f 72 5f 76 74 61 62 28 63 29 3b 0a 0a  ursor_vtab(c);..
1efc0 20 20 69 66 28 20 69 64 78 43 6f 6c 3c 76 2d 3e    if( idxCol<v->
1efd0 6e 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20 73  nColumn ){.    s
1efe0 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56  qlite3_value *pV
1eff0 61 6c 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c  al = sqlite3_col
1f000 75 6d 6e 5f 76 61 6c 75 65 28 63 2d 3e 70 53 74  umn_value(c->pSt
1f010 6d 74 2c 20 69 64 78 43 6f 6c 2b 31 29 3b 0a 20  mt, idxCol+1);. 
1f020 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
1f030 74 5f 76 61 6c 75 65 28 70 43 6f 6e 74 65 78 74  t_value(pContext
1f040 2c 20 70 56 61 6c 29 3b 0a 20 20 7d 65 6c 73 65  , pVal);.  }else
1f050 20 69 66 28 20 69 64 78 43 6f 6c 3d 3d 76 2d 3e   if( idxCol==v->
1f060 6e 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20 2f  nColumn ){.    /
1f070 2a 20 54 68 65 20 65 78 74 72 61 20 63 6f 6c 75  * The extra colu
1f080 6d 6e 20 77 68 6f 73 65 20 6e 61 6d 65 20 69 73  mn whose name is
1f090 20 74 68 65 20 73 61 6d 65 20 61 73 20 74 68 65   the same as the
1f0a0 20 74 61 62 6c 65 2e 0a 20 20 20 20 2a 2a 20 52   table..    ** R
1f0b0 65 74 75 72 6e 20 61 20 62 6c 6f 62 20 77 68 69  eturn a blob whi
1f0c0 63 68 20 69 73 20 61 20 70 6f 69 6e 74 65 72 20  ch is a pointer 
1f0d0 74 6f 20 74 68 65 20 63 75 72 73 6f 72 0a 20 20  to the cursor.  
1f0e0 20 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33    */.    sqlite3
1f0f0 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28 70 43 6f  _result_blob(pCo
1f100 6e 74 65 78 74 2c 20 26 63 2c 20 73 69 7a 65 6f  ntext, &c, sizeo
1f110 66 28 63 29 2c 20 53 51 4c 49 54 45 5f 54 52 41  f(c), SQLITE_TRA
1f120 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 65 6c 73 65  NSIENT);.  }else
1f130 20 69 66 28 20 69 64 78 43 6f 6c 3d 3d 76 2d 3e   if( idxCol==v->
1f140 6e 43 6f 6c 75 6d 6e 2b 31 20 29 7b 0a 20 20 20  nColumn+1 ){.   
1f150 20 2f 2a 20 54 68 65 20 64 6f 63 69 64 20 63 6f   /* The docid co
1f160 6c 75 6d 6e 2c 20 77 68 69 63 68 20 69 73 20 61  lumn, which is a
1f170 6e 20 61 6c 69 61 73 20 66 6f 72 20 72 6f 77 69  n alias for rowi
1f180 64 2e 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65  d. */.    sqlite
1f190 33 5f 76 61 6c 75 65 20 2a 70 56 61 6c 20 3d 20  3_value *pVal = 
1f1a0 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76  sqlite3_column_v
1f1b0 61 6c 75 65 28 63 2d 3e 70 53 74 6d 74 2c 20 30  alue(c->pStmt, 0
1f1c0 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  );.    sqlite3_r
1f1d0 65 73 75 6c 74 5f 76 61 6c 75 65 28 70 43 6f 6e  esult_value(pCon
1f1e0 74 65 78 74 2c 20 70 56 61 6c 29 3b 0a 20 20 7d  text, pVal);.  }
1f1f0 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
1f200 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 54 68 69 73 20  _OK;.}../* This 
1f210 69 73 20 74 68 65 20 78 52 6f 77 69 64 20 6d 65  is the xRowid me
1f220 74 68 6f 64 2e 20 20 54 68 65 20 53 51 4c 69 74  thod.  The SQLit
1f230 65 20 63 6f 72 65 20 63 61 6c 6c 73 20 74 68 69  e core calls thi
1f240 73 20 72 6f 75 74 69 6e 65 20 74 6f 0a 2a 2a 20  s routine to.** 
1f250 72 65 74 72 69 65 76 65 20 74 68 65 20 72 6f 77  retrieve the row
1f260 69 64 20 66 6f 72 20 74 68 65 20 63 75 72 72 65  id for the curre
1f270 6e 74 20 72 6f 77 20 6f 66 20 74 68 65 20 72 65  nt row of the re
1f280 73 75 6c 74 20 73 65 74 2e 20 20 66 74 73 33 0a  sult set.  fts3.
1f290 2a 2a 20 65 78 70 6f 73 65 73 20 25 5f 63 6f 6e  ** exposes %_con
1f2a0 74 65 6e 74 2e 64 6f 63 69 64 20 61 73 20 74 68  tent.docid as th
1f2b0 65 20 72 6f 77 69 64 20 66 6f 72 20 74 68 65 20  e rowid for the 
1f2c0 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20  virtual table.  
1f2d0 54 68 65 0a 2a 2a 20 72 6f 77 69 64 20 73 68 6f  The.** rowid sho
1f2e0 75 6c 64 20 62 65 20 77 72 69 74 74 65 6e 20 74  uld be written t
1f2f0 6f 20 2a 70 52 6f 77 69 64 2e 0a 2a 2f 0a 73 74  o *pRowid..*/.st
1f300 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78  atic int fulltex
1f310 74 52 6f 77 69 64 28 73 71 6c 69 74 65 33 5f 76  tRowid(sqlite3_v
1f320 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  tab_cursor *pCur
1f330 73 6f 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36  sor, sqlite_int6
1f340 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 66 75  4 *pRowid){.  fu
1f350 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72 20 2a 63  lltext_cursor *c
1f360 20 3d 20 28 66 75 6c 6c 74 65 78 74 5f 63 75 72   = (fulltext_cur
1f370 73 6f 72 20 2a 29 20 70 43 75 72 73 6f 72 3b 0a  sor *) pCursor;.
1f380 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c  .  *pRowid = sql
1f390 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36  ite3_column_int6
1f3a0 34 28 63 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a  4(c->pStmt, 0);.
1f3b0 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
1f3c0 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 41 64 64 20 61 6c  OK;.}../* Add al
1f3d0 6c 20 74 65 72 6d 73 20 69 6e 20 5b 7a 54 65 78  l terms in [zTex
1f3e0 74 5d 20 74 6f 20 70 65 6e 64 69 6e 67 54 65 72  t] to pendingTer
1f3f0 6d 73 20 74 61 62 6c 65 2e 20 20 49 66 20 5b 69  ms table.  If [i
1f400 43 6f 6c 75 6d 6e 5d 20 3e 20 30 2c 0a 2a 2a 20  Column] > 0,.** 
1f410 77 65 20 61 6c 73 6f 20 73 74 6f 72 65 20 70 6f  we also store po
1f420 73 69 74 69 6f 6e 73 20 61 6e 64 20 6f 66 66 73  sitions and offs
1f430 65 74 73 20 69 6e 20 74 68 65 20 68 61 73 68 20  ets in the hash 
1f440 74 61 62 6c 65 20 75 73 69 6e 67 20 74 68 61 74  table using that
1f450 0a 2a 2a 20 63 6f 6c 75 6d 6e 20 6e 75 6d 62 65  .** column numbe
1f460 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  r..*/.static int
1f470 20 62 75 69 6c 64 54 65 72 6d 73 28 66 75 6c 6c   buildTerms(full
1f480 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 73 71  text_vtab *v, sq
1f490 6c 69 74 65 5f 69 6e 74 36 34 20 69 44 6f 63 69  lite_int64 iDoci
1f4a0 64 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  d,.             
1f4b0 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63           const c
1f4c0 68 61 72 20 2a 7a 54 65 78 74 2c 20 69 6e 74 20  har *zText, int 
1f4d0 69 43 6f 6c 75 6d 6e 29 7b 0a 20 20 73 71 6c 69  iColumn){.  sqli
1f4e0 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a 70  te3_tokenizer *p
1f4f0 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 76 2d 3e 70  Tokenizer = v->p
1f500 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20 73 71 6c  Tokenizer;.  sql
1f510 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72 5f 63  ite3_tokenizer_c
1f520 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 3b 0a  ursor *pCursor;.
1f530 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54    const char *pT
1f540 6f 6b 65 6e 3b 0a 20 20 69 6e 74 20 6e 54 6f 6b  oken;.  int nTok
1f550 65 6e 42 79 74 65 73 3b 0a 20 20 69 6e 74 20 69  enBytes;.  int i
1f560 53 74 61 72 74 4f 66 66 73 65 74 2c 20 69 45 6e  StartOffset, iEn
1f570 64 4f 66 66 73 65 74 2c 20 69 50 6f 73 69 74 69  dOffset, iPositi
1f580 6f 6e 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20  on;.  int rc;.. 
1f590 20 72 63 20 3d 20 70 54 6f 6b 65 6e 69 7a 65 72   rc = pTokenizer
1f5a0 2d 3e 70 4d 6f 64 75 6c 65 2d 3e 78 4f 70 65 6e  ->pModule->xOpen
1f5b0 28 70 54 6f 6b 65 6e 69 7a 65 72 2c 20 7a 54 65  (pTokenizer, zTe
1f5c0 78 74 2c 20 2d 31 2c 20 26 70 43 75 72 73 6f 72  xt, -1, &pCursor
1f5d0 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
1f5e0 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
1f5f0 72 63 3b 0a 0a 20 20 70 43 75 72 73 6f 72 2d 3e  rc;..  pCursor->
1f600 70 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 70 54 6f  pTokenizer = pTo
1f610 6b 65 6e 69 7a 65 72 3b 0a 20 20 77 68 69 6c 65  kenizer;.  while
1f620 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63  ( SQLITE_OK==(rc
1f630 3d 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e 70 4d 6f  =pTokenizer->pMo
1f640 64 75 6c 65 2d 3e 78 4e 65 78 74 28 70 43 75 72  dule->xNext(pCur
1f650 73 6f 72 2c 0a 20 20 20 20 20 20 20 20 20 20 20  sor,.           
1f660 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f670 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f680 20 20 20 20 20 20 20 20 26 70 54 6f 6b 65 6e 2c          &pToken,
1f690 20 26 6e 54 6f 6b 65 6e 42 79 74 65 73 2c 0a 20   &nTokenBytes,. 
1f6a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f6b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f6c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f6d0 20 20 26 69 53 74 61 72 74 4f 66 66 73 65 74 2c    &iStartOffset,
1f6e0 20 26 69 45 6e 64 4f 66 66 73 65 74 2c 0a 20 20   &iEndOffset,.  
1f6f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f700 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f710 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f720 20 26 69 50 6f 73 69 74 69 6f 6e 29 29 20 29 7b   &iPosition)) ){
1f730 0a 20 20 20 20 44 4c 43 6f 6c 6c 65 63 74 6f 72  .    DLCollector
1f740 20 2a 70 3b 0a 20 20 20 20 69 6e 74 20 6e 44 61   *p;.    int nDa
1f750 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ta;             
1f760 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
1f770 20 64 6f 63 6c 69 73 74 20 62 65 66 6f 72 65 20   doclist before 
1f780 6f 75 72 20 75 70 64 61 74 65 2e 20 2a 2f 0a 0a  our update. */..
1f790 20 20 20 20 2f 2a 20 50 6f 73 69 74 69 6f 6e 73      /* Positions
1f7a0 20 63 61 6e 27 74 20 62 65 20 6e 65 67 61 74 69   can't be negati
1f7b0 76 65 3b 20 77 65 20 75 73 65 20 2d 31 20 61 73  ve; we use -1 as
1f7c0 20 61 20 74 65 72 6d 69 6e 61 74 6f 72 0a 20 20   a terminator.  
1f7d0 20 20 20 2a 20 69 6e 74 65 72 6e 61 6c 6c 79 2e     * internally.
1f7e0 20 20 54 6f 6b 65 6e 20 63 61 6e 27 74 20 62 65    Token can't be
1f7f0 20 4e 55 4c 4c 20 6f 72 20 65 6d 70 74 79 2e 20   NULL or empty. 
1f800 2a 2f 0a 20 20 20 20 69 66 28 20 69 50 6f 73 69  */.    if( iPosi
1f810 74 69 6f 6e 3c 30 20 7c 7c 20 70 54 6f 6b 65 6e  tion<0 || pToken
1f820 20 3d 3d 20 4e 55 4c 4c 20 7c 7c 20 6e 54 6f 6b   == NULL || nTok
1f830 65 6e 42 79 74 65 73 20 3d 3d 20 30 20 29 7b 0a  enBytes == 0 ){.
1f840 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
1f850 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 62  E_ERROR;.      b
1f860 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  reak;.    }..   
1f870 20 70 20 3d 20 66 74 73 33 48 61 73 68 46 69 6e   p = fts3HashFin
1f880 64 28 26 76 2d 3e 70 65 6e 64 69 6e 67 54 65 72  d(&v->pendingTer
1f890 6d 73 2c 20 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b  ms, pToken, nTok
1f8a0 65 6e 42 79 74 65 73 29 3b 0a 20 20 20 20 69 66  enBytes);.    if
1f8b0 28 20 70 3d 3d 4e 55 4c 4c 20 29 7b 0a 20 20 20  ( p==NULL ){.   
1f8c0 20 20 20 6e 44 61 74 61 20 3d 20 30 3b 0a 20 20     nData = 0;.  
1f8d0 20 20 20 20 70 20 3d 20 64 6c 63 4e 65 77 28 69      p = dlcNew(i
1f8e0 44 6f 63 69 64 2c 20 44 4c 5f 44 45 46 41 55 4c  Docid, DL_DEFAUL
1f8f0 54 29 3b 0a 20 20 20 20 20 20 66 74 73 33 48 61  T);.      fts3Ha
1f900 73 68 49 6e 73 65 72 74 28 26 76 2d 3e 70 65 6e  shInsert(&v->pen
1f910 64 69 6e 67 54 65 72 6d 73 2c 20 70 54 6f 6b 65  dingTerms, pToke
1f920 6e 2c 20 6e 54 6f 6b 65 6e 42 79 74 65 73 2c 20  n, nTokenBytes, 
1f930 70 29 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 4f 76  p);..      /* Ov
1f940 65 72 68 65 61 64 20 66 6f 72 20 6f 75 72 20 68  erhead for our h
1f950 61 73 68 20 74 61 62 6c 65 20 65 6e 74 72 79 2c  ash table entry,
1f960 20 74 68 65 20 6b 65 79 2c 20 61 6e 64 20 74 68   the key, and th
1f970 65 20 76 61 6c 75 65 2e 20 2a 2f 0a 20 20 20 20  e value. */.    
1f980 20 20 76 2d 3e 6e 50 65 6e 64 69 6e 67 44 61 74    v->nPendingDat
1f990 61 20 2b 3d 20 73 69 7a 65 6f 66 28 73 74 72 75  a += sizeof(stru
1f9a0 63 74 20 66 74 73 33 48 61 73 68 45 6c 65 6d 29  ct fts3HashElem)
1f9b0 2b 73 69 7a 65 6f 66 28 2a 70 29 2b 6e 54 6f 6b  +sizeof(*p)+nTok
1f9c0 65 6e 42 79 74 65 73 3b 0a 20 20 20 20 7d 65 6c  enBytes;.    }el
1f9d0 73 65 7b 0a 20 20 20 20 20 20 6e 44 61 74 61 20  se{.      nData 
1f9e0 3d 20 70 2d 3e 62 2e 6e 44 61 74 61 3b 0a 20 20  = p->b.nData;.  
1f9f0 20 20 20 20 69 66 28 20 70 2d 3e 64 6c 77 2e 69      if( p->dlw.i
1fa00 50 72 65 76 44 6f 63 69 64 21 3d 69 44 6f 63 69  PrevDocid!=iDoci
1fa10 64 20 29 20 64 6c 63 4e 65 78 74 28 70 2c 20 69  d ) dlcNext(p, i
1fa20 44 6f 63 69 64 29 3b 0a 20 20 20 20 7d 0a 20 20  Docid);.    }.  
1fa30 20 20 69 66 28 20 69 43 6f 6c 75 6d 6e 3e 3d 30    if( iColumn>=0
1fa40 20 29 7b 0a 20 20 20 20 20 20 64 6c 63 41 64 64   ){.      dlcAdd
1fa50 50 6f 73 28 70 2c 20 69 43 6f 6c 75 6d 6e 2c 20  Pos(p, iColumn, 
1fa60 69 50 6f 73 69 74 69 6f 6e 2c 20 69 53 74 61 72  iPosition, iStar
1fa70 74 4f 66 66 73 65 74 2c 20 69 45 6e 64 4f 66 66  tOffset, iEndOff
1fa80 73 65 74 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  set);.    }..   
1fa90 20 2f 2a 20 41 63 63 75 6d 75 6c 61 74 65 20 64   /* Accumulate d
1faa0 61 74 61 20 61 64 64 65 64 20 62 79 20 64 6c 63  ata added by dlc
1fab0 4e 65 77 20 6f 72 20 64 6c 63 4e 65 78 74 2c 20  New or dlcNext, 
1fac0 61 6e 64 20 64 6c 63 41 64 64 50 6f 73 2e 20 2a  and dlcAddPos. *
1fad0 2f 0a 20 20 20 20 76 2d 3e 6e 50 65 6e 64 69 6e  /.    v->nPendin
1fae0 67 44 61 74 61 20 2b 3d 20 70 2d 3e 62 2e 6e 44  gData += p->b.nD
1faf0 61 74 61 2d 6e 44 61 74 61 3b 0a 20 20 7d 0a 0a  ata-nData;.  }..
1fb00 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29    /* TODO(shess)
1fb10 20 43 68 65 63 6b 20 72 65 74 75 72 6e 3f 20 20   Check return?  
1fb20 53 68 6f 75 6c 64 20 74 68 69 73 20 62 65 20 61  Should this be a
1fb30 62 6c 65 20 74 6f 20 63 61 75 73 65 20 65 72 72  ble to cause err
1fb40 6f 72 73 20 61 74 0a 20 20 2a 2a 20 74 68 69 73  ors at.  ** this
1fb50 20 70 6f 69 6e 74 3f 20 20 41 63 74 75 61 6c 6c   point?  Actuall
1fb60 79 2c 20 73 61 6d 65 20 71 75 65 73 74 69 6f 6e  y, same question
1fb70 20 61 62 6f 75 74 20 73 71 6c 69 74 65 33 5f 66   about sqlite3_f
1fb80 69 6e 61 6c 69 7a 65 28 29 2c 0a 20 20 2a 2a 20  inalize(),.  ** 
1fb90 74 68 6f 75 67 68 20 6f 6e 65 20 63 6f 75 6c 64  though one could
1fba0 20 61 72 67 75 65 20 74 68 61 74 20 66 61 69 6c   argue that fail
1fbb0 75 72 65 20 74 68 65 72 65 20 6d 65 61 6e 73 20  ure there means 
1fbc0 74 68 61 74 20 74 68 65 20 64 61 74 61 20 69 73  that the data is
1fbd0 0a 20 20 2a 2a 20 6e 6f 74 20 64 75 72 61 62 6c  .  ** not durabl
1fbe0 65 2e 20 20 2a 70 6f 6e 64 65 72 2a 0a 20 20 2a  e.  *ponder*.  *
1fbf0 2f 0a 20 20 70 54 6f 6b 65 6e 69 7a 65 72 2d 3e  /.  pTokenizer->
1fc00 70 4d 6f 64 75 6c 65 2d 3e 78 43 6c 6f 73 65 28  pModule->xClose(
1fc10 70 43 75 72 73 6f 72 29 3b 0a 20 20 69 66 28 20  pCursor);.  if( 
1fc20 53 51 4c 49 54 45 5f 44 4f 4e 45 20 3d 3d 20 72  SQLITE_DONE == r
1fc30 63 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  c ) return SQLIT
1fc40 45 5f 4f 4b 3b 0a 20 20 72 65 74 75 72 6e 20 72  E_OK;.  return r
1fc50 63 3b 0a 7d 0a 0a 2f 2a 20 41 64 64 20 64 6f 63  c;.}../* Add doc
1fc60 6c 69 73 74 73 20 66 6f 72 20 61 6c 6c 20 74 65  lists for all te
1fc70 72 6d 73 20 69 6e 20 5b 70 56 61 6c 75 65 73 5d  rms in [pValues]
1fc80 20 74 6f 20 70 65 6e 64 69 6e 67 54 65 72 6d 73   to pendingTerms
1fc90 20 74 61 62 6c 65 2e 20 2a 2f 0a 73 74 61 74 69   table. */.stati
1fca0 63 20 69 6e 74 20 69 6e 73 65 72 74 54 65 72 6d  c int insertTerm
1fcb0 73 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20  s(fulltext_vtab 
1fcc0 2a 76 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  *v, sqlite_int64
1fcd0 20 69 44 6f 63 69 64 2c 0a 20 20 20 20 20 20 20   iDocid,.       
1fce0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fcf0 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
1fd00 70 56 61 6c 75 65 73 29 7b 0a 20 20 69 6e 74 20  pValues){.  int 
1fd10 69 3b 0a 20 20 66 6f 72 28 69 20 3d 20 30 3b 20  i;.  for(i = 0; 
1fd20 69 20 3c 20 76 2d 3e 6e 43 6f 6c 75 6d 6e 20 3b  i < v->nColumn ;
1fd30 20 2b 2b 69 29 7b 0a 20 20 20 20 63 68 61 72 20   ++i){.    char 
1fd40 2a 7a 54 65 78 74 20 3d 20 28 63 68 61 72 2a 29  *zText = (char*)
1fd50 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
1fd60 78 74 28 70 56 61 6c 75 65 73 5b 69 5d 29 3b 0a  xt(pValues[i]);.
1fd70 20 20 20 20 69 6e 74 20 72 63 20 3d 20 62 75 69      int rc = bui
1fd80 6c 64 54 65 72 6d 73 28 76 2c 20 69 44 6f 63 69  ldTerms(v, iDoci
1fd90 64 2c 20 7a 54 65 78 74 2c 20 69 29 3b 0a 20 20  d, zText, i);.  
1fda0 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
1fdb0 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
1fdc0 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51  .  }.  return SQ
1fdd0 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 41  LITE_OK;.}../* A
1fde0 64 64 20 65 6d 70 74 79 20 64 6f 63 6c 69 73 74  dd empty doclist
1fdf0 73 20 66 6f 72 20 61 6c 6c 20 74 65 72 6d 73 20  s for all terms 
1fe00 69 6e 20 74 68 65 20 67 69 76 65 6e 20 72 6f 77  in the given row
1fe10 27 73 20 63 6f 6e 74 65 6e 74 20 74 6f 0a 2a 2a  's content to.**
1fe20 20 70 65 6e 64 69 6e 67 54 65 72 6d 73 2e 0a 2a   pendingTerms..*
1fe30 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 64 65 6c  /.static int del
1fe40 65 74 65 54 65 72 6d 73 28 66 75 6c 6c 74 65 78  eteTerms(fulltex
1fe50 74 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74  t_vtab *v, sqlit
1fe60 65 5f 69 6e 74 36 34 20 69 44 6f 63 69 64 29 7b  e_int64 iDocid){
1fe70 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a  .  const char **
1fe80 70 56 61 6c 75 65 73 3b 0a 20 20 69 6e 74 20 69  pValues;.  int i
1fe90 2c 20 72 63 3b 0a 0a 20 20 2f 2a 20 54 4f 44 4f  , rc;..  /* TODO
1fea0 28 73 68 65 73 73 29 20 53 68 6f 75 6c 64 20 77  (shess) Should w
1feb0 65 20 61 6c 6c 6f 77 20 73 75 63 68 20 74 61 62  e allow such tab
1fec0 6c 65 73 20 61 74 20 61 6c 6c 3f 20 2a 2f 0a 20  les at all? */. 
1fed0 20 69 66 28 20 44 4c 5f 44 45 46 41 55 4c 54 3d   if( DL_DEFAULT=
1fee0 3d 44 4c 5f 44 4f 43 49 44 53 20 29 20 72 65 74  =DL_DOCIDS ) ret
1fef0 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  urn SQLITE_ERROR
1ff00 3b 0a 0a 20 20 72 63 20 3d 20 63 6f 6e 74 65 6e  ;..  rc = conten
1ff10 74 5f 73 65 6c 65 63 74 28 76 2c 20 69 44 6f 63  t_select(v, iDoc
1ff20 69 64 2c 20 26 70 56 61 6c 75 65 73 29 3b 0a 20  id, &pValues);. 
1ff30 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
1ff40 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
1ff50 0a 20 20 66 6f 72 28 69 20 3d 20 30 20 3b 20 69  .  for(i = 0 ; i
1ff60 20 3c 20 76 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 2b   < v->nColumn; +
1ff70 2b 69 29 20 7b 0a 20 20 20 20 72 63 20 3d 20 62  +i) {.    rc = b
1ff80 75 69 6c 64 54 65 72 6d 73 28 76 2c 20 69 44 6f  uildTerms(v, iDo
1ff90 63 69 64 2c 20 70 56 61 6c 75 65 73 5b 69 5d 2c  cid, pValues[i],
1ffa0 20 2d 31 29 3b 0a 20 20 20 20 69 66 28 20 72 63   -1);.    if( rc
1ffb0 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72  !=SQLITE_OK ) br
1ffc0 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 66 72 65 65  eak;.  }..  free
1ffd0 53 74 72 69 6e 67 41 72 72 61 79 28 76 2d 3e 6e  StringArray(v->n
1ffe0 43 6f 6c 75 6d 6e 2c 20 70 56 61 6c 75 65 73 29  Column, pValues)
1fff0 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
20000 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 54 4f 44 4f  E_OK;.}../* TODO
20010 28 73 68 65 73 73 29 20 52 65 66 61 63 74 6f 72  (shess) Refactor
20020 20 74 68 65 20 63 6f 64 65 20 74 6f 20 72 65 6d   the code to rem
20030 6f 76 65 20 74 68 69 73 20 66 6f 72 77 61 72 64  ove this forward
20040 20 64 65 63 6c 2e 20 2a 2f 0a 73 74 61 74 69 63   decl. */.static
20050 20 69 6e 74 20 69 6e 69 74 50 65 6e 64 69 6e 67   int initPending
20060 54 65 72 6d 73 28 66 75 6c 6c 74 65 78 74 5f 76  Terms(fulltext_v
20070 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f 69  tab *v, sqlite_i
20080 6e 74 36 34 20 69 44 6f 63 69 64 29 3b 0a 0a 2f  nt64 iDocid);../
20090 2a 20 49 6e 73 65 72 74 20 61 20 72 6f 77 20 69  * Insert a row i
200a0 6e 74 6f 20 74 68 65 20 25 5f 63 6f 6e 74 65 6e  nto the %_conten
200b0 74 20 74 61 62 6c 65 3b 20 73 65 74 20 2a 70 69  t table; set *pi
200c0 44 6f 63 69 64 20 74 6f 20 62 65 20 74 68 65 20  Docid to be the 
200d0 49 44 20 6f 66 20 74 68 65 0a 2a 2a 20 6e 65 77  ID of the.** new
200e0 20 72 6f 77 2e 20 20 41 64 64 20 64 6f 63 6c 69   row.  Add docli
200f0 73 74 73 20 66 6f 72 20 74 65 72 6d 73 20 74 6f  sts for terms to
20100 20 70 65 6e 64 69 6e 67 54 65 72 6d 73 2e 0a 2a   pendingTerms..*
20110 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 69 6e 64  /.static int ind
20120 65 78 5f 69 6e 73 65 72 74 28 66 75 6c 6c 74 65  ex_insert(fullte
20130 78 74 5f 76 74 61 62 20 2a 76 2c 20 73 71 6c 69  xt_vtab *v, sqli
20140 74 65 33 5f 76 61 6c 75 65 20 2a 70 52 65 71 75  te3_value *pRequ
20150 65 73 74 44 6f 63 69 64 2c 0a 20 20 20 20 20 20  estDocid,.      
20160 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20170 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
20180 2a 2a 70 56 61 6c 75 65 73 2c 20 73 71 6c 69 74  **pValues, sqlit
20190 65 5f 69 6e 74 36 34 20 2a 70 69 44 6f 63 69 64  e_int64 *piDocid
201a0 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  ){.  int rc;..  
201b0 72 63 20 3d 20 63 6f 6e 74 65 6e 74 5f 69 6e 73  rc = content_ins
201c0 65 72 74 28 76 2c 20 70 52 65 71 75 65 73 74 44  ert(v, pRequestD
201d0 6f 63 69 64 2c 20 70 56 61 6c 75 65 73 29 3b 20  ocid, pValues); 
201e0 20 2f 2a 20 65 78 65 63 75 74 65 20 61 6e 20 53   /* execute an S
201f0 51 4c 20 49 4e 53 45 52 54 20 2a 2f 0a 20 20 69  QL INSERT */.  i
20200 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
20210 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
20220 20 2f 2a 20 64 6f 63 69 64 20 63 6f 6c 75 6d 6e   /* docid column
20230 20 69 73 20 61 6e 20 61 6c 69 61 73 20 66 6f 72   is an alias for
20240 20 72 6f 77 69 64 2e 20 2a 2f 0a 20 20 2a 70 69   rowid. */.  *pi
20250 44 6f 63 69 64 20 3d 20 73 71 6c 69 74 65 33 5f  Docid = sqlite3_
20260 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77 69  last_insert_rowi
20270 64 28 76 2d 3e 64 62 29 3b 0a 20 20 72 63 20 3d  d(v->db);.  rc =
20280 20 69 6e 69 74 50 65 6e 64 69 6e 67 54 65 72 6d   initPendingTerm
20290 73 28 76 2c 20 2a 70 69 44 6f 63 69 64 29 3b 0a  s(v, *piDocid);.
202a0 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
202b0 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
202c0 0a 0a 20 20 72 65 74 75 72 6e 20 69 6e 73 65 72  ..  return inser
202d0 74 54 65 72 6d 73 28 76 2c 20 2a 70 69 44 6f 63  tTerms(v, *piDoc
202e0 69 64 2c 20 70 56 61 6c 75 65 73 29 3b 0a 7d 0a  id, pValues);.}.
202f0 0a 2f 2a 20 44 65 6c 65 74 65 20 61 20 72 6f 77  ./* Delete a row
20300 20 66 72 6f 6d 20 74 68 65 20 25 5f 63 6f 6e 74   from the %_cont
20310 65 6e 74 20 74 61 62 6c 65 3b 20 61 64 64 20 65  ent table; add e
20320 6d 70 74 79 20 64 6f 63 6c 69 73 74 73 20 66 6f  mpty doclists fo
20330 72 20 74 65 72 6d 73 0a 2a 2a 20 74 6f 20 70 65  r terms.** to pe
20340 6e 64 69 6e 67 54 65 72 6d 73 2e 0a 2a 2f 0a 73  ndingTerms..*/.s
20350 74 61 74 69 63 20 69 6e 74 20 69 6e 64 65 78 5f  tatic int index_
20360 64 65 6c 65 74 65 28 66 75 6c 6c 74 65 78 74 5f  delete(fulltext_
20370 76 74 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f  vtab *v, sqlite_
20380 69 6e 74 36 34 20 69 52 6f 77 29 7b 0a 20 20 69  int64 iRow){.  i
20390 6e 74 20 72 63 20 3d 20 69 6e 69 74 50 65 6e 64  nt rc = initPend
203a0 69 6e 67 54 65 72 6d 73 28 76 2c 20 69 52 6f 77  ingTerms(v, iRow
203b0 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
203c0 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
203d0 72 63 3b 0a 0a 20 20 72 63 20 3d 20 64 65 6c 65  rc;..  rc = dele
203e0 74 65 54 65 72 6d 73 28 76 2c 20 69 52 6f 77 29  teTerms(v, iRow)
203f0 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
20400 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
20410 63 3b 0a 0a 20 20 72 65 74 75 72 6e 20 63 6f 6e  c;..  return con
20420 74 65 6e 74 5f 64 65 6c 65 74 65 28 76 2c 20 69  tent_delete(v, i
20430 52 6f 77 29 3b 20 20 2f 2a 20 65 78 65 63 75 74  Row);  /* execut
20440 65 20 61 6e 20 53 51 4c 20 44 45 4c 45 54 45 20  e an SQL DELETE 
20450 2a 2f 0a 7d 0a 0a 2f 2a 20 55 70 64 61 74 65 20  */.}../* Update 
20460 61 20 72 6f 77 20 69 6e 20 74 68 65 20 25 5f 63  a row in the %_c
20470 6f 6e 74 65 6e 74 20 74 61 62 6c 65 3b 20 61 64  ontent table; ad
20480 64 20 64 65 6c 65 74 65 20 64 6f 63 6c 69 73 74  d delete doclist
20490 73 20 74 6f 0a 2a 2a 20 70 65 6e 64 69 6e 67 54  s to.** pendingT
204a0 65 72 6d 73 20 66 6f 72 20 6f 6c 64 20 74 65 72  erms for old ter
204b0 6d 73 20 6e 6f 74 20 69 6e 20 74 68 65 20 6e 65  ms not in the ne
204c0 77 20 64 61 74 61 2c 20 61 64 64 20 69 6e 73 65  w data, add inse
204d0 72 74 20 64 6f 63 6c 69 73 74 73 0a 2a 2a 20 74  rt doclists.** t
204e0 6f 20 70 65 6e 64 69 6e 67 54 65 72 6d 73 20 66  o pendingTerms f
204f0 6f 72 20 74 65 72 6d 73 20 69 6e 20 74 68 65 20  or terms in the 
20500 6e 65 77 20 64 61 74 61 2e 0a 2a 2f 0a 73 74 61  new data..*/.sta
20510 74 69 63 20 69 6e 74 20 69 6e 64 65 78 5f 75 70  tic int index_up
20520 64 61 74 65 28 66 75 6c 6c 74 65 78 74 5f 76 74  date(fulltext_vt
20530 61 62 20 2a 76 2c 20 73 71 6c 69 74 65 5f 69 6e  ab *v, sqlite_in
20540 74 36 34 20 69 52 6f 77 2c 0a 20 20 20 20 20 20  t64 iRow,.      
20550 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20560 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
20570 2a 2a 70 56 61 6c 75 65 73 29 7b 0a 20 20 69 6e  **pValues){.  in
20580 74 20 72 63 20 3d 20 69 6e 69 74 50 65 6e 64 69  t rc = initPendi
20590 6e 67 54 65 72 6d 73 28 76 2c 20 69 52 6f 77 29  ngTerms(v, iRow)
205a0 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
205b0 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
205c0 63 3b 0a 0a 20 20 2f 2a 20 47 65 6e 65 72 61 74  c;..  /* Generat
205d0 65 20 61 6e 20 65 6d 70 74 79 20 64 6f 63 6c 69  e an empty docli
205e0 73 74 20 66 6f 72 20 65 61 63 68 20 74 65 72 6d  st for each term
205f0 20 74 68 61 74 20 70 72 65 76 69 6f 75 73 6c 79   that previously
20600 20 61 70 70 65 61 72 65 64 20 69 6e 20 74 68 69   appeared in thi
20610 73 0a 20 20 20 2a 20 72 6f 77 2e 20 2a 2f 0a 20  s.   * row. */. 
20620 20 72 63 20 3d 20 64 65 6c 65 74 65 54 65 72 6d   rc = deleteTerm
20630 73 28 76 2c 20 69 52 6f 77 29 3b 0a 20 20 69 66  s(v, iRow);.  if
20640 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
20650 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
20660 72 63 20 3d 20 63 6f 6e 74 65 6e 74 5f 75 70 64  rc = content_upd
20670 61 74 65 28 76 2c 20 70 56 61 6c 75 65 73 2c 20  ate(v, pValues, 
20680 69 52 6f 77 29 3b 20 20 2f 2a 20 65 78 65 63 75  iRow);  /* execu
20690 74 65 20 61 6e 20 53 51 4c 20 55 50 44 41 54 45  te an SQL UPDATE
206a0 20 2a 2f 0a 20 20 69 66 28 20 72 63 21 3d 53 51   */.  if( rc!=SQ
206b0 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
206c0 20 72 63 3b 0a 0a 20 20 2f 2a 20 4e 6f 77 20 61   rc;..  /* Now a
206d0 64 64 20 70 6f 73 69 74 69 6f 6e 73 20 66 6f 72  dd positions for
206e0 20 74 65 72 6d 73 20 77 68 69 63 68 20 61 70 70   terms which app
206f0 65 61 72 20 69 6e 20 74 68 65 20 75 70 64 61 74  ear in the updat
20700 65 64 20 72 6f 77 2e 20 2a 2f 0a 20 20 72 65 74  ed row. */.  ret
20710 75 72 6e 20 69 6e 73 65 72 74 54 65 72 6d 73 28  urn insertTerms(
20720 76 2c 20 69 52 6f 77 2c 20 70 56 61 6c 75 65 73  v, iRow, pValues
20730 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a  );.}../*********
20740 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20750 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20760 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20770 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 20 49  **********/./* I
20780 6e 74 65 72 69 6f 72 57 72 69 74 65 72 20 69 73  nteriorWriter is
20790 20 75 73 65 64 20 74 6f 20 63 6f 6c 6c 65 63 74   used to collect
207a0 20 74 65 72 6d 73 20 61 6e 64 20 62 6c 6f 63 6b   terms and block
207b0 20 72 65 66 65 72 65 6e 63 65 73 20 69 6e 74 6f   references into
207c0 0a 2a 2a 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64  .** interior nod
207d0 65 73 20 69 6e 20 25 5f 73 65 67 6d 65 6e 74 73  es in %_segments
207e0 2e 20 20 53 65 65 20 63 6f 6d 6d 65 6e 74 61 72  .  See commentar
207f0 79 20 61 74 20 74 6f 70 20 6f 66 20 66 69 6c 65  y at top of file
20800 20 66 6f 72 0a 2a 2a 20 66 6f 72 6d 61 74 2e 0a   for.** format..
20810 2a 2f 0a 0a 2f 2a 20 48 6f 77 20 6c 61 72 67 65  */../* How large
20820 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65 73 20   interior nodes 
20830 63 61 6e 20 67 72 6f 77 2e 20 2a 2f 0a 23 64 65  can grow. */.#de
20840 66 69 6e 65 20 49 4e 54 45 52 49 4f 52 5f 4d 41  fine INTERIOR_MA
20850 58 20 32 30 34 38 0a 0a 2f 2a 20 4d 69 6e 69 6d  X 2048../* Minim
20860 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 74 65 72  um number of ter
20870 6d 73 20 70 65 72 20 69 6e 74 65 72 69 6f 72 20  ms per interior 
20880 6e 6f 64 65 20 28 65 78 63 65 70 74 20 74 68 65  node (except the
20890 20 72 6f 6f 74 29 2e 20 54 68 69 73 0a 2a 2a 20   root). This.** 
208a0 70 72 65 76 65 6e 74 73 20 6c 61 72 67 65 20 74  prevents large t
208b0 65 72 6d 73 20 66 72 6f 6d 20 6d 61 6b 69 6e 67  erms from making
208c0 20 74 68 65 20 74 72 65 65 20 74 6f 6f 20 73 6b   the tree too sk
208d0 69 6e 6e 79 20 2d 20 6d 75 73 74 20 62 65 20 3e  inny - must be >
208e0 30 0a 2a 2a 20 73 6f 20 74 68 61 74 20 74 68 65  0.** so that the
208f0 20 74 72 65 65 20 61 6c 77 61 79 73 20 6d 61 6b   tree always mak
20900 65 73 20 70 72 6f 67 72 65 73 73 2e 20 20 4e 6f  es progress.  No
20910 74 65 20 74 68 61 74 20 74 68 65 20 6d 69 6e 20  te that the min 
20920 74 72 65 65 0a 2a 2a 20 66 61 6e 6f 75 74 20 77  tree.** fanout w
20930 69 6c 6c 20 62 65 20 49 4e 54 45 52 49 4f 52 5f  ill be INTERIOR_
20940 4d 49 4e 5f 54 45 52 4d 53 2b 31 2e 0a 2a 2f 0a  MIN_TERMS+1..*/.
20950 23 64 65 66 69 6e 65 20 49 4e 54 45 52 49 4f 52  #define INTERIOR
20960 5f 4d 49 4e 5f 54 45 52 4d 53 20 37 0a 23 69 66  _MIN_TERMS 7.#if
20970 20 49 4e 54 45 52 49 4f 52 5f 4d 49 4e 5f 54 45   INTERIOR_MIN_TE
20980 52 4d 53 3c 31 0a 23 20 65 72 72 6f 72 20 49 4e  RMS<1.# error IN
20990 54 45 52 49 4f 52 5f 4d 49 4e 5f 54 45 52 4d 53  TERIOR_MIN_TERMS
209a0 20 6d 75 73 74 20 62 65 20 67 72 65 61 74 65 72   must be greater
209b0 20 74 68 61 6e 20 30 2e 0a 23 65 6e 64 69 66 0a   than 0..#endif.
209c0 0a 2f 2a 20 52 4f 4f 54 5f 4d 41 58 20 63 6f 6e  ./* ROOT_MAX con
209d0 74 72 6f 6c 73 20 68 6f 77 20 6d 75 63 68 20 64  trols how much d
209e0 61 74 61 20 69 73 20 73 74 6f 72 65 64 20 69 6e  ata is stored in
209f0 6c 69 6e 65 20 69 6e 20 74 68 65 20 73 65 67 6d  line in the segm
20a00 65 6e 74 0a 2a 2a 20 64 69 72 65 63 74 6f 72 79  ent.** directory
20a10 2e 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f 28 73 68 65  ..*/./* TODO(she
20a20 73 73 29 20 50 75 73 68 20 52 4f 4f 54 5f 4d 41  ss) Push ROOT_MA
20a30 58 20 64 6f 77 6e 20 74 6f 20 77 68 6f 65 76 65  X down to whoeve
20a40 72 20 69 73 20 77 72 69 74 69 6e 67 20 74 68 69  r is writing thi
20a50 6e 67 73 2e 20 20 49 74 27 73 0a 2a 2a 20 6f 6e  ngs.  It's.** on
20a60 6c 79 20 68 65 72 65 20 73 6f 20 74 68 61 74 20  ly here so that 
20a70 69 6e 74 65 72 69 6f 72 57 72 69 74 65 72 52 6f  interiorWriterRo
20a80 6f 74 49 6e 66 6f 28 29 20 61 6e 64 20 6c 65 61  otInfo() and lea
20a90 66 57 72 69 74 65 72 52 6f 6f 74 49 6e 66 6f 28  fWriterRootInfo(
20aa0 29 0a 2a 2a 20 63 61 6e 20 62 6f 74 68 20 73 65  ).** can both se
20ab0 65 20 69 74 2c 20 62 75 74 20 69 66 20 74 68 65  e it, but if the
20ac0 20 63 61 6c 6c 65 72 20 70 61 73 73 65 64 20 69   caller passed i
20ad0 74 20 69 6e 2c 20 77 65 20 77 6f 75 6c 64 6e 27  t in, we wouldn'
20ae0 74 20 65 76 65 6e 0a 2a 2a 20 6e 65 65 64 20 61  t even.** need a
20af0 20 64 65 66 69 6e 65 2e 0a 2a 2f 0a 23 64 65 66   define..*/.#def
20b00 69 6e 65 20 52 4f 4f 54 5f 4d 41 58 20 31 30 32  ine ROOT_MAX 102
20b10 34 0a 23 69 66 20 52 4f 4f 54 5f 4d 41 58 3c 56  4.#if ROOT_MAX<V
20b20 41 52 49 4e 54 5f 4d 41 58 2a 32 0a 23 20 65 72  ARINT_MAX*2.# er
20b30 72 6f 72 20 52 4f 4f 54 5f 4d 41 58 20 6d 75 73  ror ROOT_MAX mus
20b40 74 20 68 61 76 65 20 65 6e 6f 75 67 68 20 73 70  t have enough sp
20b50 61 63 65 20 66 6f 72 20 61 20 68 65 61 64 65 72  ace for a header
20b60 2e 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 49 6e 74  ..#endif../* Int
20b70 65 72 69 6f 72 42 6c 6f 63 6b 20 73 74 6f 72 65  eriorBlock store
20b80 73 20 61 20 6c 69 6e 6b 65 64 2d 6c 69 73 74 20  s a linked-list 
20b90 6f 66 20 69 6e 74 65 72 69 6f 72 20 62 6c 6f 63  of interior bloc
20ba0 6b 73 20 77 68 69 6c 65 20 61 20 6c 6f 77 65 72  ks while a lower
20bb0 0a 2a 2a 20 6c 61 79 65 72 20 69 73 20 62 65 69  .** layer is bei
20bc0 6e 67 20 63 6f 6e 73 74 72 75 63 74 65 64 2e 0a  ng constructed..
20bd0 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  */.typedef struc
20be0 74 20 49 6e 74 65 72 69 6f 72 42 6c 6f 63 6b 20  t InteriorBlock 
20bf0 7b 0a 20 20 44 61 74 61 42 75 66 66 65 72 20 74  {.  DataBuffer t
20c00 65 72 6d 3b 20 20 20 20 20 20 20 20 20 20 20 2f  erm;           /
20c10 2a 20 4c 65 66 74 6d 6f 73 74 20 74 65 72 6d 20  * Leftmost term 
20c20 69 6e 20 62 6c 6f 63 6b 27 73 20 73 75 62 74 72  in block's subtr
20c30 65 65 2e 20 2a 2f 0a 20 20 44 61 74 61 42 75 66  ee. */.  DataBuf
20c40 66 65 72 20 64 61 74 61 3b 20 20 20 20 20 20 20  fer data;       
20c50 20 20 20 20 2f 2a 20 41 63 63 75 6d 75 6c 61 74      /* Accumulat
20c60 65 64 20 64 61 74 61 20 66 6f 72 20 74 68 65 20  ed data for the 
20c70 62 6c 6f 63 6b 2e 20 2a 2f 0a 20 20 73 74 72 75  block. */.  stru
20c80 63 74 20 49 6e 74 65 72 69 6f 72 42 6c 6f 63 6b  ct InteriorBlock
20c90 20 2a 6e 65 78 74 3b 0a 7d 20 49 6e 74 65 72 69   *next;.} Interi
20ca0 6f 72 42 6c 6f 63 6b 3b 0a 0a 73 74 61 74 69 63  orBlock;..static
20cb0 20 49 6e 74 65 72 69 6f 72 42 6c 6f 63 6b 20 2a   InteriorBlock *
20cc0 69 6e 74 65 72 69 6f 72 42 6c 6f 63 6b 4e 65 77  interiorBlockNew
20cd0 28 69 6e 74 20 69 48 65 69 67 68 74 2c 20 73 71  (int iHeight, sq
20ce0 6c 69 74 65 5f 69 6e 74 36 34 20 69 43 68 69 6c  lite_int64 iChil
20cf0 64 42 6c 6f 63 6b 2c 0a 20 20 20 20 20 20 20 20  dBlock,.        
20d00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20d10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63                 c
20d20 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65 72 6d  onst char *pTerm
20d30 2c 20 69 6e 74 20 6e 54 65 72 6d 29 7b 0a 20 20  , int nTerm){.  
20d40 49 6e 74 65 72 69 6f 72 42 6c 6f 63 6b 20 2a 62  InteriorBlock *b
20d50 6c 6f 63 6b 20 3d 20 73 71 6c 69 74 65 33 5f 6d  lock = sqlite3_m
20d60 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 49 6e 74  alloc(sizeof(Int
20d70 65 72 69 6f 72 42 6c 6f 63 6b 29 29 3b 0a 20 20  eriorBlock));.  
20d80 63 68 61 72 20 63 5b 56 41 52 49 4e 54 5f 4d 41  char c[VARINT_MA
20d90 58 2b 56 41 52 49 4e 54 5f 4d 41 58 5d 3b 0a 20  X+VARINT_MAX];. 
20da0 20 69 6e 74 20 6e 3b 0a 0a 20 20 69 66 28 20 62   int n;..  if( b
20db0 6c 6f 63 6b 20 29 7b 0a 20 20 20 20 6d 65 6d 73  lock ){.    mems
20dc0 65 74 28 62 6c 6f 63 6b 2c 20 30 2c 20 73 69 7a  et(block, 0, siz
20dd0 65 6f 66 28 2a 62 6c 6f 63 6b 29 29 3b 0a 20 20  eof(*block));.  
20de0 20 20 64 61 74 61 42 75 66 66 65 72 49 6e 69 74    dataBufferInit
20df0 28 26 62 6c 6f 63 6b 2d 3e 74 65 72 6d 2c 20 30  (&block->term, 0
20e00 29 3b 0a 20 20 20 20 64 61 74 61 42 75 66 66 65  );.    dataBuffe
20e10 72 52 65 70 6c 61 63 65 28 26 62 6c 6f 63 6b 2d  rReplace(&block-
20e20 3e 74 65 72 6d 2c 20 70 54 65 72 6d 2c 20 6e 54  >term, pTerm, nT
20e30 65 72 6d 29 3b 0a 0a 20 20 20 20 6e 20 3d 20 66  erm);..    n = f
20e40 74 73 33 50 75 74 56 61 72 69 6e 74 28 63 2c 20  ts3PutVarint(c, 
20e50 69 48 65 69 67 68 74 29 3b 0a 20 20 20 20 6e 20  iHeight);.    n 
20e60 2b 3d 20 66 74 73 33 50 75 74 56 61 72 69 6e 74  += fts3PutVarint
20e70 28 63 2b 6e 2c 20 69 43 68 69 6c 64 42 6c 6f 63  (c+n, iChildBloc
20e80 6b 29 3b 0a 20 20 20 20 64 61 74 61 42 75 66 66  k);.    dataBuff
20e90 65 72 49 6e 69 74 28 26 62 6c 6f 63 6b 2d 3e 64  erInit(&block->d
20ea0 61 74 61 2c 20 49 4e 54 45 52 49 4f 52 5f 4d 41  ata, INTERIOR_MA
20eb0 58 29 3b 0a 20 20 20 20 64 61 74 61 42 75 66 66  X);.    dataBuff
20ec0 65 72 52 65 70 6c 61 63 65 28 26 62 6c 6f 63 6b  erReplace(&block
20ed0 2d 3e 64 61 74 61 2c 20 63 2c 20 6e 29 3b 0a 20  ->data, c, n);. 
20ee0 20 7d 0a 20 20 72 65 74 75 72 6e 20 62 6c 6f 63   }.  return bloc
20ef0 6b 3b 0a 7d 0a 0a 23 69 66 6e 64 65 66 20 4e 44  k;.}..#ifndef ND
20f00 45 42 55 47 0a 2f 2a 20 56 65 72 69 66 79 20 74  EBUG./* Verify t
20f10 68 61 74 20 74 68 65 20 64 61 74 61 20 69 73 20  hat the data is 
20f20 72 65 61 64 61 62 6c 65 20 61 73 20 61 6e 20 69  readable as an i
20f30 6e 74 65 72 69 6f 72 20 6e 6f 64 65 2e 20 2a 2f  nterior node. */
20f40 0a 73 74 61 74 69 63 20 76 6f 69 64 20 69 6e 74  .static void int
20f50 65 72 69 6f 72 42 6c 6f 63 6b 56 61 6c 69 64 61  eriorBlockValida
20f60 74 65 28 49 6e 74 65 72 69 6f 72 42 6c 6f 63 6b  te(InteriorBlock
20f70 20 2a 70 42 6c 6f 63 6b 29 7b 0a 20 20 63 6f 6e   *pBlock){.  con
20f80 73 74 20 63 68 61 72 20 2a 70 44 61 74 61 20 3d  st char *pData =
20f90 20 70 42 6c 6f 63 6b 2d 3e 64 61 74 61 2e 70 44   pBlock->data.pD
20fa0 61 74 61 3b 0a 20 20 69 6e 74 20 6e 44 61 74 61  ata;.  int nData
20fb0 20 3d 20 70 42 6c 6f 63 6b 2d 3e 64 61 74 61 2e   = pBlock->data.
20fc0 6e 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e 2c 20  nData;.  int n, 
20fd0 69 44 75 6d 6d 79 3b 0a 20 20 73 71 6c 69 74 65  iDummy;.  sqlite
20fe0 5f 69 6e 74 36 34 20 69 42 6c 6f 63 6b 69 64 3b  _int64 iBlockid;
20ff0 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 44 61 74  ..  assert( nDat
21000 61 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  a>0 );.  assert(
21010 20 70 44 61 74 61 21 3d 30 20 29 3b 0a 20 20 61   pData!=0 );.  a
21020 73 73 65 72 74 28 20 70 44 61 74 61 2b 6e 44 61  ssert( pData+nDa
21030 74 61 3e 70 44 61 74 61 20 29 3b 0a 0a 20 20 2f  ta>pData );..  /
21040 2a 20 4d 75 73 74 20 6c 65 61 64 20 77 69 74 68  * Must lead with
21050 20 68 65 69 67 68 74 20 6f 66 20 6e 6f 64 65 20   height of node 
21060 61 73 20 61 20 76 61 72 69 6e 74 28 6e 29 2c 20  as a varint(n), 
21070 6e 3e 30 20 2a 2f 0a 20 20 6e 20 3d 20 66 74 73  n>0 */.  n = fts
21080 33 47 65 74 56 61 72 69 6e 74 33 32 28 70 44 61  3GetVarint32(pDa
21090 74 61 2c 20 26 69 44 75 6d 6d 79 29 3b 0a 20 20  ta, &iDummy);.  
210a0 61 73 73 65 72 74 28 20 6e 3e 30 20 29 3b 0a 20  assert( n>0 );. 
210b0 20 61 73 73 65 72 74 28 20 69 44 75 6d 6d 79 3e   assert( iDummy>
210c0 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 6e  0 );.  assert( n
210d0 3c 6e 44 61 74 61 20 29 3b 0a 20 20 70 44 61 74  <nData );.  pDat
210e0 61 20 2b 3d 20 6e 3b 0a 20 20 6e 44 61 74 61 20  a += n;.  nData 
210f0 2d 3d 20 6e 3b 0a 0a 20 20 2f 2a 20 4d 75 73 74  -= n;..  /* Must
21100 20 63 6f 6e 74 61 69 6e 20 69 42 6c 6f 63 6b 69   contain iBlocki
21110 64 2e 20 2a 2f 0a 20 20 6e 20 3d 20 66 74 73 33  d. */.  n = fts3
21120 47 65 74 56 61 72 69 6e 74 28 70 44 61 74 61 2c  GetVarint(pData,
21130 20 26 69 42 6c 6f 63 6b 69 64 29 3b 0a 20 20 61   &iBlockid);.  a
21140 73 73 65 72 74 28 20 6e 3e 30 20 29 3b 0a 20 20  ssert( n>0 );.  
21150 61 73 73 65 72 74 28 20 6e 3c 3d 6e 44 61 74 61  assert( n<=nData
21160 20 29 3b 0a 20 20 70 44 61 74 61 20 2b 3d 20 6e   );.  pData += n
21170 3b 0a 20 20 6e 44 61 74 61 20 2d 3d 20 6e 3b 0a  ;.  nData -= n;.
21180 0a 20 20 2f 2a 20 5a 65 72 6f 20 6f 72 20 6d 6f  .  /* Zero or mo
21190 72 65 20 74 65 72 6d 73 20 6f 66 20 70 6f 73 69  re terms of posi
211a0 74 69 76 65 20 6c 65 6e 67 74 68 20 2a 2f 0a 20  tive length */. 
211b0 20 69 66 28 20 6e 44 61 74 61 21 3d 30 20 29 7b   if( nData!=0 ){
211c0 0a 20 20 20 20 2f 2a 20 46 69 72 73 74 20 74 65  .    /* First te
211d0 72 6d 20 69 73 20 6e 6f 74 20 64 65 6c 74 61 2d  rm is not delta-
211e0 65 6e 63 6f 64 65 64 2e 20 2a 2f 0a 20 20 20 20  encoded. */.    
211f0 6e 20 3d 20 66 74 73 33 47 65 74 56 61 72 69 6e  n = fts3GetVarin
21200 74 33 32 28 70 44 61 74 61 2c 20 26 69 44 75 6d  t32(pData, &iDum
21210 6d 79 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  my);.    assert(
21220 20 6e 3e 30 20 29 3b 0a 20 20 20 20 61 73 73 65   n>0 );.    asse
21230 72 74 28 20 69 44 75 6d 6d 79 3e 30 20 29 3b 0a  rt( iDummy>0 );.
21240 20 20 20 20 61 73 73 65 72 74 28 20 6e 2b 69 44      assert( n+iD
21250 75 6d 6d 79 3e 30 29 3b 0a 20 20 20 20 61 73 73  ummy>0);.    ass
21260 65 72 74 28 20 6e 2b 69 44 75 6d 6d 79 3c 3d 6e  ert( n+iDummy<=n
21270 44 61 74 61 20 29 3b 0a 20 20 20 20 70 44 61 74  Data );.    pDat
21280 61 20 2b 3d 20 6e 2b 69 44 75 6d 6d 79 3b 0a 20  a += n+iDummy;. 
21290 20 20 20 6e 44 61 74 61 20 2d 3d 20 6e 2b 69 44     nData -= n+iD
212a0 75 6d 6d 79 3b 0a 0a 20 20 20 20 2f 2a 20 46 6f  ummy;..    /* Fo
212b0 6c 6c 6f 77 69 6e 67 20 74 65 72 6d 73 20 64 65  llowing terms de
212c0 6c 74 61 2d 65 6e 63 6f 64 65 64 2e 20 2a 2f 0a  lta-encoded. */.
212d0 20 20 20 20 77 68 69 6c 65 28 20 6e 44 61 74 61      while( nData
212e0 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  !=0 ){.      /* 
212f0 4c 65 6e 67 74 68 20 6f 66 20 73 68 61 72 65 64  Length of shared
21300 20 70 72 65 66 69 78 2e 20 2a 2f 0a 20 20 20 20   prefix. */.    
21310 20 20 6e 20 3d 20 66 74 73 33 47 65 74 56 61 72    n = fts3GetVar
21320 69 6e 74 33 32 28 70 44 61 74 61 2c 20 26 69 44  int32(pData, &iD
21330 75 6d 6d 79 29 3b 0a 20 20 20 20 20 20 61 73 73  ummy);.      ass
21340 65 72 74 28 20 6e 3e 30 20 29 3b 0a 20 20 20 20  ert( n>0 );.    
21350 20 20 61 73 73 65 72 74 28 20 69 44 75 6d 6d 79    assert( iDummy
21360 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20 61 73 73  >=0 );.      ass
21370 65 72 74 28 20 6e 3c 6e 44 61 74 61 20 29 3b 0a  ert( n<nData );.
21380 20 20 20 20 20 20 70 44 61 74 61 20 2b 3d 20 6e        pData += n
21390 3b 0a 20 20 20 20 20 20 6e 44 61 74 61 20 2d 3d  ;.      nData -=
213a0 20 6e 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 4c 65   n;..      /* Le
213b0 6e 67 74 68 20 61 6e 64 20 64 61 74 61 20 6f 66  ngth and data of
213c0 20 64 69 73 74 69 6e 63 74 20 73 75 66 66 69 78   distinct suffix
213d0 2e 20 2a 2f 0a 20 20 20 20 20 20 6e 20 3d 20 66  . */.      n = f
213e0 74 73 33 47 65 74 56 61 72 69 6e 74 33 32 28 70  ts3GetVarint32(p
213f0 44 61 74 61 2c 20 26 69 44 75 6d 6d 79 29 3b 0a  Data, &iDummy);.
21400 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6e 3e        assert( n>
21410 30 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72  0 );.      asser
21420 74 28 20 69 44 75 6d 6d 79 3e 30 20 29 3b 0a 20  t( iDummy>0 );. 
21430 20 20 20 20 20 61 73 73 65 72 74 28 20 6e 2b 69       assert( n+i
21440 44 75 6d 6d 79 3e 30 29 3b 0a 20 20 20 20 20 20  Dummy>0);.      
21450 61 73 73 65 72 74 28 20 6e 2b 69 44 75 6d 6d 79  assert( n+iDummy
21460 3c 3d 6e 44 61 74 61 20 29 3b 0a 20 20 20 20 20  <=nData );.     
21470 20 70 44 61 74 61 20 2b 3d 20 6e 2b 69 44 75 6d   pData += n+iDum
21480 6d 79 3b 0a 20 20 20 20 20 20 6e 44 61 74 61 20  my;.      nData 
21490 2d 3d 20 6e 2b 69 44 75 6d 6d 79 3b 0a 20 20 20  -= n+iDummy;.   
214a0 20 7d 0a 20 20 7d 0a 7d 0a 23 64 65 66 69 6e 65   }.  }.}.#define
214b0 20 41 53 53 45 52 54 5f 56 41 4c 49 44 5f 49 4e   ASSERT_VALID_IN
214c0 54 45 52 49 4f 52 5f 42 4c 4f 43 4b 28 78 29 20  TERIOR_BLOCK(x) 
214d0 69 6e 74 65 72 69 6f 72 42 6c 6f 63 6b 56 61 6c  interiorBlockVal
214e0 69 64 61 74 65 28 78 29 0a 23 65 6c 73 65 0a 23  idate(x).#else.#
214f0 64 65 66 69 6e 65 20 41 53 53 45 52 54 5f 56 41  define ASSERT_VA
21500 4c 49 44 5f 49 4e 54 45 52 49 4f 52 5f 42 4c 4f  LID_INTERIOR_BLO
21510 43 4b 28 78 29 20 61 73 73 65 72 74 28 20 31 20  CK(x) assert( 1 
21520 29 0a 23 65 6e 64 69 66 0a 0a 74 79 70 65 64 65  ).#endif..typede
21530 66 20 73 74 72 75 63 74 20 49 6e 74 65 72 69 6f  f struct Interio
21540 72 57 72 69 74 65 72 20 7b 0a 20 20 69 6e 74 20  rWriter {.  int 
21550 69 48 65 69 67 68 74 3b 20 20 20 20 20 20 20 20  iHeight;        
21560 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 66 72             /* fr
21570 6f 6d 20 30 20 61 74 20 6c 65 61 76 65 73 2e 20  om 0 at leaves. 
21580 2a 2f 0a 20 20 49 6e 74 65 72 69 6f 72 42 6c 6f  */.  InteriorBlo
21590 63 6b 20 2a 66 69 72 73 74 2c 20 2a 6c 61 73 74  ck *first, *last
215a0 3b 0a 20 20 73 74 72 75 63 74 20 49 6e 74 65 72  ;.  struct Inter
215b0 69 6f 72 57 72 69 74 65 72 20 2a 70 61 72 65 6e  iorWriter *paren
215c0 74 57 72 69 74 65 72 3b 0a 0a 20 20 44 61 74 61  tWriter;..  Data
215d0 42 75 66 66 65 72 20 74 65 72 6d 3b 20 20 20 20  Buffer term;    
215e0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
215f0 73 74 20 74 65 72 6d 20 77 72 69 74 74 65 6e 20  st term written 
21600 74 6f 20 62 6c 6f 63 6b 20 22 6c 61 73 74 22 2e  to block "last".
21610 20 2a 2f 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74   */.  sqlite_int
21620 36 34 20 69 4f 70 65 6e 69 6e 67 43 68 69 6c 64  64 iOpeningChild
21630 42 6c 6f 63 6b 3b 20 2f 2a 20 46 69 72 73 74 20  Block; /* First 
21640 63 68 69 6c 64 20 62 6c 6f 63 6b 20 69 6e 20 62  child block in b
21650 6c 6f 63 6b 20 22 6c 61 73 74 22 2e 20 2a 2f 0a  lock "last". */.
21660 23 69 66 6e 64 65 66 20 4e 44 45 42 55 47 0a 20  #ifndef NDEBUG. 
21670 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 4c   sqlite_int64 iL
21680 61 73 74 43 68 69 6c 64 42 6c 6f 63 6b 3b 20 20  astChildBlock;  
21690 2f 2a 20 66 6f 72 20 63 6f 6e 73 69 73 74 65 6e  /* for consisten
216a0 63 79 20 63 68 65 63 6b 73 2e 20 2a 2f 0a 23 65  cy checks. */.#e
216b0 6e 64 69 66 0a 7d 20 49 6e 74 65 72 69 6f 72 57  ndif.} InteriorW
216c0 72 69 74 65 72 3b 0a 0a 2f 2a 20 49 6e 69 74 69  riter;../* Initi
216d0 61 6c 69 7a 65 20 61 6e 20 69 6e 74 65 72 69 6f  alize an interio
216e0 72 20 6e 6f 64 65 20 77 68 65 72 65 20 70 54 65  r node where pTe
216f0 72 6d 5b 6e 54 65 72 6d 5d 20 6d 61 72 6b 73 20  rm[nTerm] marks 
21700 74 68 65 20 6c 65 66 74 6d 6f 73 74 0a 2a 2a 20  the leftmost.** 
21710 74 65 72 6d 20 69 6e 20 74 68 65 20 74 72 65 65  term in the tree
21720 2e 20 20 69 43 68 69 6c 64 42 6c 6f 63 6b 20 69  .  iChildBlock i
21730 73 20 74 68 65 20 6c 65 66 74 6d 6f 73 74 20 63  s the leftmost c
21740 68 69 6c 64 20 62 6c 6f 63 6b 20 61 74 20 74 68  hild block at th
21750 65 0a 2a 2a 20 6e 65 78 74 20 6c 65 76 65 6c 20  e.** next level 
21760 64 6f 77 6e 20 74 68 65 20 74 72 65 65 2e 0a 2a  down the tree..*
21770 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 69 6e  /.static void in
21780 74 65 72 69 6f 72 57 72 69 74 65 72 49 6e 69 74  teriorWriterInit
21790 28 69 6e 74 20 69 48 65 69 67 68 74 2c 20 63 6f  (int iHeight, co
217a0 6e 73 74 20 63 68 61 72 20 2a 70 54 65 72 6d 2c  nst char *pTerm,
217b0 20 69 6e 74 20 6e 54 65 72 6d 2c 0a 20 20 20 20   int nTerm,.    
217c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
217d0 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
217e0 65 5f 69 6e 74 36 34 20 69 43 68 69 6c 64 42 6c  e_int64 iChildBl
217f0 6f 63 6b 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ock,.           
21800 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21810 20 20 20 20 49 6e 74 65 72 69 6f 72 57 72 69 74      InteriorWrit
21820 65 72 20 2a 70 57 72 69 74 65 72 29 7b 0a 20 20  er *pWriter){.  
21830 49 6e 74 65 72 69 6f 72 42 6c 6f 63 6b 20 2a 62  InteriorBlock *b
21840 6c 6f 63 6b 3b 0a 20 20 61 73 73 65 72 74 28 20  lock;.  assert( 
21850 69 48 65 69 67 68 74 3e 30 20 29 3b 0a 20 20 43  iHeight>0 );.  C
21860 4c 45 41 52 28 70 57 72 69 74 65 72 29 3b 0a 0a  LEAR(pWriter);..
21870 20 20 70 57 72 69 74 65 72 2d 3e 69 48 65 69 67    pWriter->iHeig
21880 68 74 20 3d 20 69 48 65 69 67 68 74 3b 0a 20 20  ht = iHeight;.  
21890 70 57 72 69 74 65 72 2d 3e 69 4f 70 65 6e 69 6e  pWriter->iOpenin
218a0 67 43 68 69 6c 64 42 6c 6f 63 6b 20 3d 20 69 43  gChildBlock = iC
218b0 68 69 6c 64 42 6c 6f 63 6b 3b 0a 23 69 66 6e 64  hildBlock;.#ifnd
218c0 65 66 20 4e 44 45 42 55 47 0a 20 20 70 57 72 69  ef NDEBUG.  pWri
218d0 74 65 72 2d 3e 69 4c 61 73 74 43 68 69 6c 64 42  ter->iLastChildB
218e0 6c 6f 63 6b 20 3d 20 69 43 68 69 6c 64 42 6c 6f  lock = iChildBlo
218f0 63 6b 3b 0a 23 65 6e 64 69 66 0a 20 20 62 6c 6f  ck;.#endif.  blo
21900 63 6b 20 3d 20 69 6e 74 65 72 69 6f 72 42 6c 6f  ck = interiorBlo
21910 63 6b 4e 65 77 28 69 48 65 69 67 68 74 2c 20 69  ckNew(iHeight, i
21920 43 68 69 6c 64 42 6c 6f 63 6b 2c 20 70 54 65 72  ChildBlock, pTer
21930 6d 2c 20 6e 54 65 72 6d 29 3b 0a 20 20 70 57 72  m, nTerm);.  pWr
21940 69 74 65 72 2d 3e 6c 61 73 74 20 3d 20 70 57 72  iter->last = pWr
21950 69 74 65 72 2d 3e 66 69 72 73 74 20 3d 20 62 6c  iter->first = bl
21960 6f 63 6b 3b 0a 20 20 41 53 53 45 52 54 5f 56 41  ock;.  ASSERT_VA
21970 4c 49 44 5f 49 4e 54 45 52 49 4f 52 5f 42 4c 4f  LID_INTERIOR_BLO
21980 43 4b 28 70 57 72 69 74 65 72 2d 3e 6c 61 73 74  CK(pWriter->last
21990 29 3b 0a 20 20 64 61 74 61 42 75 66 66 65 72 49  );.  dataBufferI
219a0 6e 69 74 28 26 70 57 72 69 74 65 72 2d 3e 74 65  nit(&pWriter->te
219b0 72 6d 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 20 41 70  rm, 0);.}../* Ap
219c0 70 65 6e 64 20 74 68 65 20 63 68 69 6c 64 20 6e  pend the child n
219d0 6f 64 65 20 72 6f 6f 74 65 64 20 61 74 20 69 43  ode rooted at iC
219e0 68 69 6c 64 42 6c 6f 63 6b 20 74 6f 20 74 68 65  hildBlock to the
219f0 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65 2c 0a   interior node,.
21a00 2a 2a 20 77 69 74 68 20 70 54 65 72 6d 5b 6e 54  ** with pTerm[nT
21a10 65 72 6d 5d 20 61 73 20 74 68 65 20 6c 65 66 74  erm] as the left
21a20 6d 6f 73 74 20 74 65 72 6d 20 69 6e 20 69 43 68  most term in iCh
21a30 69 6c 64 42 6c 6f 63 6b 27 73 20 73 75 62 74 72  ildBlock's subtr
21a40 65 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ee..*/.static vo
21a50 69 64 20 69 6e 74 65 72 69 6f 72 57 72 69 74 65  id interiorWrite
21a60 72 41 70 70 65 6e 64 28 49 6e 74 65 72 69 6f 72  rAppend(Interior
21a70 57 72 69 74 65 72 20 2a 70 57 72 69 74 65 72 2c  Writer *pWriter,
21a80 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
21a90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21aa0 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54    const char *pT
21ab0 65 72 6d 2c 20 69 6e 74 20 6e 54 65 72 6d 2c 0a  erm, int nTerm,.
21ac0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21ad0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21ae0 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 43   sqlite_int64 iC
21af0 68 69 6c 64 42 6c 6f 63 6b 29 7b 0a 20 20 63 68  hildBlock){.  ch
21b00 61 72 20 63 5b 56 41 52 49 4e 54 5f 4d 41 58 2b  ar c[VARINT_MAX+
21b10 56 41 52 49 4e 54 5f 4d 41 58 5d 3b 0a 20 20 69  VARINT_MAX];.  i
21b20 6e 74 20 6e 2c 20 6e 50 72 65 66 69 78 20 3d 20  nt n, nPrefix = 
21b30 30 3b 0a 0a 20 20 41 53 53 45 52 54 5f 56 41 4c  0;..  ASSERT_VAL
21b40 49 44 5f 49 4e 54 45 52 49 4f 52 5f 42 4c 4f 43  ID_INTERIOR_BLOC
21b50 4b 28 70 57 72 69 74 65 72 2d 3e 6c 61 73 74 29  K(pWriter->last)
21b60 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 66 69 72 73  ;..  /* The firs
21b70 74 20 74 65 72 6d 20 77 72 69 74 74 65 6e 20 69  t term written i
21b80 6e 74 6f 20 61 6e 20 69 6e 74 65 72 69 6f 72 20  nto an interior 
21b90 6e 6f 64 65 20 69 73 20 61 63 74 75 61 6c 6c 79  node is actually
21ba0 0a 20 20 2a 2a 20 61 73 73 6f 63 69 61 74 65 64  .  ** associated
21bb0 20 77 69 74 68 20 74 68 65 20 73 65 63 6f 6e 64   with the second
21bc0 20 63 68 69 6c 64 20 61 64 64 65 64 20 28 74 68   child added (th
21bd0 65 20 66 69 72 73 74 20 63 68 69 6c 64 20 77 61  e first child wa
21be0 73 20 61 64 64 65 64 0a 20 20 2a 2a 20 69 6e 20  s added.  ** in 
21bf0 69 6e 74 65 72 69 6f 72 57 72 69 74 65 72 49 6e  interiorWriterIn
21c00 69 74 2c 20 6f 72 20 69 6e 20 74 68 65 20 69 66  it, or in the if
21c10 20 63 6c 61 75 73 65 20 61 74 20 74 68 65 20 62   clause at the b
21c20 6f 74 74 6f 6d 20 6f 66 20 74 68 69 73 0a 20 20  ottom of this.  
21c30 2a 2a 20 66 75 6e 63 74 69 6f 6e 29 2e 20 20 54  ** function).  T
21c40 68 61 74 20 74 65 72 6d 20 67 65 74 73 20 65 6e  hat term gets en
21c50 63 6f 64 65 64 20 73 74 72 61 69 67 68 74 20 75  coded straight u
21c60 70 2c 20 77 69 74 68 20 6e 50 72 65 66 69 78 20  p, with nPrefix 
21c70 6c 65 66 74 0a 20 20 2a 2a 20 61 74 20 30 2e 0a  left.  ** at 0..
21c80 20 20 2a 2f 0a 20 20 69 66 28 20 70 57 72 69 74    */.  if( pWrit
21c90 65 72 2d 3e 74 65 72 6d 2e 6e 44 61 74 61 3d 3d  er->term.nData==
21ca0 30 20 29 7b 0a 20 20 20 20 6e 20 3d 20 66 74 73  0 ){.    n = fts
21cb0 33 50 75 74 56 61 72 69 6e 74 28 63 2c 20 6e 54  3PutVarint(c, nT
21cc0 65 72 6d 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  erm);.  }else{. 
21cd0 20 20 20 77 68 69 6c 65 28 20 6e 50 72 65 66 69     while( nPrefi
21ce0 78 3c 70 57 72 69 74 65 72 2d 3e 74 65 72 6d 2e  x<pWriter->term.
21cf0 6e 44 61 74 61 20 26 26 0a 20 20 20 20 20 20 20  nData &&.       
21d00 20 20 20 20 70 54 65 72 6d 5b 6e 50 72 65 66 69      pTerm[nPrefi
21d10 78 5d 3d 3d 70 57 72 69 74 65 72 2d 3e 74 65 72  x]==pWriter->ter
21d20 6d 2e 70 44 61 74 61 5b 6e 50 72 65 66 69 78 5d  m.pData[nPrefix]
21d30 20 29 7b 0a 20 20 20 20 20 20 6e 50 72 65 66 69   ){.      nPrefi
21d40 78 2b 2b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  x++;.    }..    
21d50 6e 20 3d 20 66 74 73 33 50 75 74 56 61 72 69 6e  n = fts3PutVarin
21d60 74 28 63 2c 20 6e 50 72 65 66 69 78 29 3b 0a 20  t(c, nPrefix);. 
21d70 20 20 20 6e 20 2b 3d 20 66 74 73 33 50 75 74 56     n += fts3PutV
21d80 61 72 69 6e 74 28 63 2b 6e 2c 20 6e 54 65 72 6d  arint(c+n, nTerm
21d90 2d 6e 50 72 65 66 69 78 29 3b 0a 20 20 7d 0a 0a  -nPrefix);.  }..
21da0 23 69 66 6e 64 65 66 20 4e 44 45 42 55 47 0a 20  #ifndef NDEBUG. 
21db0 20 70 57 72 69 74 65 72 2d 3e 69 4c 61 73 74 43   pWriter->iLastC
21dc0 68 69 6c 64 42 6c 6f 63 6b 2b 2b 3b 0a 23 65 6e  hildBlock++;.#en
21dd0 64 69 66 0a 20 20 61 73 73 65 72 74 28 20 70 57  dif.  assert( pW
21de0 72 69 74 65 72 2d 3e 69 4c 61 73 74 43 68 69 6c  riter->iLastChil
21df0 64 42 6c 6f 63 6b 3d 3d 69 43 68 69 6c 64 42 6c  dBlock==iChildBl
21e00 6f 63 6b 20 29 3b 0a 0a 20 20 2f 2a 20 4f 76 65  ock );..  /* Ove
21e10 72 66 6c 6f 77 20 74 6f 20 61 20 6e 65 77 20 62  rflow to a new b
21e20 6c 6f 63 6b 20 69 66 20 74 68 65 20 6e 65 77 20  lock if the new 
21e30 74 65 72 6d 20 6d 61 6b 65 73 20 74 68 65 20 63  term makes the c
21e40 75 72 72 65 6e 74 20 62 6c 6f 63 6b 0a 20 20 2a  urrent block.  *
21e50 2a 20 74 6f 6f 20 62 69 67 2c 20 61 6e 64 20 74  * too big, and t
21e60 68 65 20 63 75 72 72 65 6e 74 20 62 6c 6f 63 6b  he current block
21e70 20 61 6c 72 65 61 64 79 20 68 61 73 20 65 6e 6f   already has eno
21e80 75 67 68 20 74 65 72 6d 73 2e 0a 20 20 2a 2f 0a  ugh terms..  */.
21e90 20 20 69 66 28 20 70 57 72 69 74 65 72 2d 3e 6c    if( pWriter->l
21ea0 61 73 74 2d 3e 64 61 74 61 2e 6e 44 61 74 61 2b  ast->data.nData+
21eb0 6e 2b 6e 54 65 72 6d 2d 6e 50 72 65 66 69 78 3e  n+nTerm-nPrefix>
21ec0 49 4e 54 45 52 49 4f 52 5f 4d 41 58 20 26 26 0a  INTERIOR_MAX &&.
21ed0 20 20 20 20 20 20 69 43 68 69 6c 64 42 6c 6f 63        iChildBloc
21ee0 6b 2d 70 57 72 69 74 65 72 2d 3e 69 4f 70 65 6e  k-pWriter->iOpen
21ef0 69 6e 67 43 68 69 6c 64 42 6c 6f 63 6b 3e 49 4e  ingChildBlock>IN
21f00 54 45 52 49 4f 52 5f 4d 49 4e 5f 54 45 52 4d 53  TERIOR_MIN_TERMS
21f10 20 29 7b 0a 20 20 20 20 70 57 72 69 74 65 72 2d   ){.    pWriter-
21f20 3e 6c 61 73 74 2d 3e 6e 65 78 74 20 3d 20 69 6e  >last->next = in
21f30 74 65 72 69 6f 72 42 6c 6f 63 6b 4e 65 77 28 70  teriorBlockNew(p
21f40 57 72 69 74 65 72 2d 3e 69 48 65 69 67 68 74 2c  Writer->iHeight,
21f50 20 69 43 68 69 6c 64 42 6c 6f 63 6b 2c 0a 20 20   iChildBlock,.  
21f60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21f70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21f80 20 20 20 20 20 20 20 20 20 70 54 65 72 6d 2c 20           pTerm, 
21f90 6e 54 65 72 6d 29 3b 0a 20 20 20 20 70 57 72 69  nTerm);.    pWri
21fa0 74 65 72 2d 3e 6c 61 73 74 20 3d 20 70 57 72 69  ter->last = pWri
21fb0 74 65 72 2d 3e 6c 61 73 74 2d 3e 6e 65 78 74 3b  ter->last->next;
21fc0 0a 20 20 20 20 70 57 72 69 74 65 72 2d 3e 69 4f  .    pWriter->iO
21fd0 70 65 6e 69 6e 67 43 68 69 6c 64 42 6c 6f 63 6b  peningChildBlock
21fe0 20 3d 20 69 43 68 69 6c 64 42 6c 6f 63 6b 3b 0a   = iChildBlock;.
21ff0 20 20 20 20 64 61 74 61 42 75 66 66 65 72 52 65      dataBufferRe
22000 73 65 74 28 26 70 57 72 69 74 65 72 2d 3e 74 65  set(&pWriter->te
22010 72 6d 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  rm);.  }else{.  
22020 20 20 64 61 74 61 42 75 66 66 65 72 41 70 70 65    dataBufferAppe
22030 6e 64 32 28 26 70 57 72 69 74 65 72 2d 3e 6c 61  nd2(&pWriter->la
22040 73 74 2d 3e 64 61 74 61 2c 20 63 2c 20 6e 2c 0a  st->data, c, n,.
22050 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22060 20 20 20 20 20 20 70 54 65 72 6d 2b 6e 50 72 65        pTerm+nPre
22070 66 69 78 2c 20 6e 54 65 72 6d 2d 6e 50 72 65 66  fix, nTerm-nPref
22080 69 78 29 3b 0a 20 20 20 20 64 61 74 61 42 75 66  ix);.    dataBuf
22090 66 65 72 52 65 70 6c 61 63 65 28 26 70 57 72 69  ferReplace(&pWri
220a0 74 65 72 2d 3e 74 65 72 6d 2c 20 70 54 65 72 6d  ter->term, pTerm
220b0 2c 20 6e 54 65 72 6d 29 3b 0a 20 20 7d 0a 20 20  , nTerm);.  }.  
220c0 41 53 53 45 52 54 5f 56 41 4c 49 44 5f 49 4e 54  ASSERT_VALID_INT
220d0 45 52 49 4f 52 5f 42 4c 4f 43 4b 28 70 57 72 69  ERIOR_BLOCK(pWri
220e0 74 65 72 2d 3e 6c 61 73 74 29 3b 0a 7d 0a 0a 2f  ter->last);.}../
220f0 2a 20 46 72 65 65 20 74 68 65 20 73 70 61 63 65  * Free the space
22100 20 75 73 65 64 20 62 79 20 70 57 72 69 74 65 72   used by pWriter
22110 2c 20 69 6e 63 6c 75 64 69 6e 67 20 74 68 65 20  , including the 
22120 6c 69 6e 6b 65 64 2d 6c 69 73 74 20 6f 66 0a 2a  linked-list of.*
22130 2a 20 49 6e 74 65 72 69 6f 72 42 6c 6f 63 6b 73  * InteriorBlocks
22140 2c 20 61 6e 64 20 70 61 72 65 6e 74 57 72 69 74  , and parentWrit
22150 65 72 2c 20 69 66 20 70 72 65 73 65 6e 74 2e 0a  er, if present..
22160 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 69 6e  */.static int in
22170 74 65 72 69 6f 72 57 72 69 74 65 72 44 65 73 74  teriorWriterDest
22180 72 6f 79 28 49 6e 74 65 72 69 6f 72 57 72 69 74  roy(InteriorWrit
22190 65 72 20 2a 70 57 72 69 74 65 72 29 7b 0a 20 20  er *pWriter){.  
221a0 49 6e 74 65 72 69 6f 72 42 6c 6f 63 6b 20 2a 62  InteriorBlock *b
221b0 6c 6f 63 6b 20 3d 20 70 57 72 69 74 65 72 2d 3e  lock = pWriter->
221c0 66 69 72 73 74 3b 0a 0a 20 20 77 68 69 6c 65 28  first;..  while(
221d0 20 62 6c 6f 63 6b 21 3d 4e 55 4c 4c 20 29 7b 0a   block!=NULL ){.
221e0 20 20 20 20 49 6e 74 65 72 69 6f 72 42 6c 6f 63      InteriorBloc
221f0 6b 20 2a 62 20 3d 20 62 6c 6f 63 6b 3b 0a 20 20  k *b = block;.  
22200 20 20 62 6c 6f 63 6b 20 3d 20 62 6c 6f 63 6b 2d    block = block-
22210 3e 6e 65 78 74 3b 0a 20 20 20 20 64 61 74 61 42  >next;.    dataB
22220 75 66 66 65 72 44 65 73 74 72 6f 79 28 26 62 2d  ufferDestroy(&b-
22230 3e 74 65 72 6d 29 3b 0a 20 20 20 20 64 61 74 61  >term);.    data
22240 42 75 66 66 65 72 44 65 73 74 72 6f 79 28 26 62  BufferDestroy(&b
22250 2d 3e 64 61 74 61 29 3b 0a 20 20 20 20 73 71 6c  ->data);.    sql
22260 69 74 65 33 5f 66 72 65 65 28 62 29 3b 0a 20 20  ite3_free(b);.  
22270 7d 0a 20 20 69 66 28 20 70 57 72 69 74 65 72 2d  }.  if( pWriter-
22280 3e 70 61 72 65 6e 74 57 72 69 74 65 72 21 3d 4e  >parentWriter!=N
22290 55 4c 4c 20 29 7b 0a 20 20 20 20 69 6e 74 65 72  ULL ){.    inter
222a0 69 6f 72 57 72 69 74 65 72 44 65 73 74 72 6f 79  iorWriterDestroy
222b0 28 70 57 72 69 74 65 72 2d 3e 70 61 72 65 6e 74  (pWriter->parent
222c0 57 72 69 74 65 72 29 3b 0a 20 20 20 20 73 71 6c  Writer);.    sql
222d0 69 74 65 33 5f 66 72 65 65 28 70 57 72 69 74 65  ite3_free(pWrite
222e0 72 2d 3e 70 61 72 65 6e 74 57 72 69 74 65 72 29  r->parentWriter)
222f0 3b 0a 20 20 7d 0a 20 20 64 61 74 61 42 75 66 66  ;.  }.  dataBuff
22300 65 72 44 65 73 74 72 6f 79 28 26 70 57 72 69 74  erDestroy(&pWrit
22310 65 72 2d 3e 74 65 72 6d 29 3b 0a 20 20 53 43 52  er->term);.  SCR
22320 41 4d 42 4c 45 28 70 57 72 69 74 65 72 29 3b 0a  AMBLE(pWriter);.
22330 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
22340 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 49 66 20 70 57 72  OK;.}../* If pWr
22350 69 74 65 72 20 63 61 6e 20 66 69 74 20 65 6e 74  iter can fit ent
22360 69 72 65 6c 79 20 69 6e 20 52 4f 4f 54 5f 4d 41  irely in ROOT_MA
22370 58 2c 20 72 65 74 75 72 6e 20 69 74 20 61 73 20  X, return it as 
22380 74 68 65 20 72 6f 6f 74 20 69 6e 66 6f 0a 2a 2a  the root info.**
22390 20 64 69 72 65 63 74 6c 79 2c 20 6c 65 61 76 69   directly, leavi
223a0 6e 67 20 2a 70 69 45 6e 64 42 6c 6f 63 6b 69 64  ng *piEndBlockid
223b0 20 75 6e 63 68 61 6e 67 65 64 2e 20 20 4f 74 68   unchanged.  Oth
223c0 65 72 77 69 73 65 2c 20 66 6c 75 73 68 0a 2a 2a  erwise, flush.**
223d0 20 70 57 72 69 74 65 72 20 74 6f 20 25 5f 73 65   pWriter to %_se
223e0 67 6d 65 6e 74 73 2c 20 62 75 69 6c 64 69 6e 67  gments, building
223f0 20 61 20 6e 65 77 20 6c 61 79 65 72 20 6f 66 20   a new layer of 
22400 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65 73 2c 20  interior nodes, 
22410 61 6e 64 0a 2a 2a 20 72 65 63 75 72 73 69 76 65  and.** recursive
22420 6c 79 20 61 73 6b 20 66 6f 72 20 74 68 65 69 72  ly ask for their
22430 20 72 6f 6f 74 20 69 6e 74 6f 2e 0a 2a 2f 0a 73   root into..*/.s
22440 74 61 74 69 63 20 69 6e 74 20 69 6e 74 65 72 69  tatic int interi
22450 6f 72 57 72 69 74 65 72 52 6f 6f 74 49 6e 66 6f  orWriterRootInfo
22460 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
22470 76 2c 20 49 6e 74 65 72 69 6f 72 57 72 69 74 65  v, InteriorWrite
22480 72 20 2a 70 57 72 69 74 65 72 2c 0a 20 20 20 20  r *pWriter,.    
22490 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
224a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63 68                ch
224b0 61 72 20 2a 2a 70 70 52 6f 6f 74 49 6e 66 6f 2c  ar **ppRootInfo,
224c0 20 69 6e 74 20 2a 70 6e 52 6f 6f 74 49 6e 66 6f   int *pnRootInfo
224d0 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
224e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
224f0 20 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34      sqlite_int64
22500 20 2a 70 69 45 6e 64 42 6c 6f 63 6b 69 64 29 7b   *piEndBlockid){
22510 0a 20 20 49 6e 74 65 72 69 6f 72 42 6c 6f 63 6b  .  InteriorBlock
22520 20 2a 62 6c 6f 63 6b 20 3d 20 70 57 72 69 74 65   *block = pWrite
22530 72 2d 3e 66 69 72 73 74 3b 0a 20 20 73 71 6c 69  r->first;.  sqli
22540 74 65 5f 69 6e 74 36 34 20 69 42 6c 6f 63 6b 69  te_int64 iBlocki
22550 64 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b  d = 0;.  int rc;
22560 0a 0a 20 20 2f 2a 20 49 66 20 77 65 20 63 61 6e  ..  /* If we can
22570 20 66 69 74 20 74 68 65 20 73 65 67 6d 65 6e 74   fit the segment
22580 20 69 6e 6c 69 6e 65 20 2a 2f 0a 20 20 69 66 28   inline */.  if(
22590 20 62 6c 6f 63 6b 3d 3d 70 57 72 69 74 65 72 2d   block==pWriter-
225a0 3e 6c 61 73 74 20 26 26 20 62 6c 6f 63 6b 2d 3e  >last && block->
225b0 64 61 74 61 2e 6e 44 61 74 61 3c 52 4f 4f 54 5f  data.nData<ROOT_
225c0 4d 41 58 20 29 7b 0a 20 20 20 20 2a 70 70 52 6f  MAX ){.    *ppRo
225d0 6f 74 49 6e 66 6f 20 3d 20 62 6c 6f 63 6b 2d 3e  otInfo = block->
225e0 64 61 74 61 2e 70 44 61 74 61 3b 0a 20 20 20 20  data.pData;.    
225f0 2a 70 6e 52 6f 6f 74 49 6e 66 6f 20 3d 20 62 6c  *pnRootInfo = bl
22600 6f 63 6b 2d 3e 64 61 74 61 2e 6e 44 61 74 61 3b  ock->data.nData;
22610 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
22620 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  TE_OK;.  }..  /*
22630 20 46 6c 75 73 68 20 74 68 65 20 66 69 72 73 74   Flush the first
22640 20 62 6c 6f 63 6b 20 74 6f 20 25 5f 73 65 67 6d   block to %_segm
22650 65 6e 74 73 2c 20 61 6e 64 20 63 72 65 61 74 65  ents, and create
22660 20 61 20 6e 65 77 20 6c 65 76 65 6c 20 6f 66 0a   a new level of.
22670 20 20 2a 2a 20 69 6e 74 65 72 69 6f 72 20 6e 6f    ** interior no
22680 64 65 2e 0a 20 20 2a 2f 0a 20 20 41 53 53 45 52  de..  */.  ASSER
22690 54 5f 56 41 4c 49 44 5f 49 4e 54 45 52 49 4f 52  T_VALID_INTERIOR
226a0 5f 42 4c 4f 43 4b 28 62 6c 6f 63 6b 29 3b 0a 20  _BLOCK(block);. 
226b0 20 72 63 20 3d 20 62 6c 6f 63 6b 5f 69 6e 73 65   rc = block_inse
226c0 72 74 28 76 2c 20 62 6c 6f 63 6b 2d 3e 64 61 74  rt(v, block->dat
226d0 61 2e 70 44 61 74 61 2c 20 62 6c 6f 63 6b 2d 3e  a.pData, block->
226e0 64 61 74 61 2e 6e 44 61 74 61 2c 20 26 69 42 6c  data.nData, &iBl
226f0 6f 63 6b 69 64 29 3b 0a 20 20 69 66 28 20 72 63  ockid);.  if( rc
22700 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
22710 74 75 72 6e 20 72 63 3b 0a 20 20 2a 70 69 45 6e  turn rc;.  *piEn
22720 64 42 6c 6f 63 6b 69 64 20 3d 20 69 42 6c 6f 63  dBlockid = iBloc
22730 6b 69 64 3b 0a 0a 20 20 70 57 72 69 74 65 72 2d  kid;..  pWriter-
22740 3e 70 61 72 65 6e 74 57 72 69 74 65 72 20 3d 20  >parentWriter = 
22750 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
22760 69 7a 65 6f 66 28 2a 70 57 72 69 74 65 72 2d 3e  izeof(*pWriter->
22770 70 61 72 65 6e 74 57 72 69 74 65 72 29 29 3b 0a  parentWriter));.
22780 20 20 69 6e 74 65 72 69 6f 72 57 72 69 74 65 72    interiorWriter
22790 49 6e 69 74 28 70 57 72 69 74 65 72 2d 3e 69 48  Init(pWriter->iH
227a0 65 69 67 68 74 2b 31 2c 0a 20 20 20 20 20 20 20  eight+1,.       
227b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 62 6c                bl
227c0 6f 63 6b 2d 3e 74 65 72 6d 2e 70 44 61 74 61 2c  ock->term.pData,
227d0 20 62 6c 6f 63 6b 2d 3e 74 65 72 6d 2e 6e 44 61   block->term.nDa
227e0 74 61 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  ta,.            
227f0 20 20 20 20 20 20 20 20 20 69 42 6c 6f 63 6b 69           iBlocki
22800 64 2c 20 70 57 72 69 74 65 72 2d 3e 70 61 72 65  d, pWriter->pare
22810 6e 74 57 72 69 74 65 72 29 3b 0a 0a 20 20 2f 2a  ntWriter);..  /*
22820 20 46 6c 75 73 68 20 61 64 64 69 74 69 6f 6e 61   Flush additiona
22830 6c 20 62 6c 6f 63 6b 73 20 61 6e 64 20 61 70 70  l blocks and app
22840 65 6e 64 20 74 6f 20 74 68 65 20 68 69 67 68 65  end to the highe
22850 72 20 69 6e 74 65 72 69 6f 72 0a 20 20 2a 2a 20  r interior.  ** 
22860 6e 6f 64 65 2e 0a 20 20 2a 2f 0a 20 20 66 6f 72  node..  */.  for
22870 28 62 6c 6f 63 6b 3d 62 6c 6f 63 6b 2d 3e 6e 65  (block=block->ne
22880 78 74 3b 20 62 6c 6f 63 6b 21 3d 4e 55 4c 4c 3b  xt; block!=NULL;
22890 20 62 6c 6f 63 6b 3d 62 6c 6f 63 6b 2d 3e 6e 65   block=block->ne
228a0 78 74 29 7b 0a 20 20 20 20 41 53 53 45 52 54 5f  xt){.    ASSERT_
228b0 56 41 4c 49 44 5f 49 4e 54 45 52 49 4f 52 5f 42  VALID_INTERIOR_B
228c0 4c 4f 43 4b 28 62 6c 6f 63 6b 29 3b 0a 20 20 20  LOCK(block);.   
228d0 20 72 63 20 3d 20 62 6c 6f 63 6b 5f 69 6e 73 65   rc = block_inse
228e0 72 74 28 76 2c 20 62 6c 6f 63 6b 2d 3e 64 61 74  rt(v, block->dat
228f0 61 2e 70 44 61 74 61 2c 20 62 6c 6f 63 6b 2d 3e  a.pData, block->
22900 64 61 74 61 2e 6e 44 61 74 61 2c 20 26 69 42 6c  data.nData, &iBl
22910 6f 63 6b 69 64 29 3b 0a 20 20 20 20 69 66 28 20  ockid);.    if( 
22920 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
22930 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 2a  return rc;.    *
22940 70 69 45 6e 64 42 6c 6f 63 6b 69 64 20 3d 20 69  piEndBlockid = i
22950 42 6c 6f 63 6b 69 64 3b 0a 0a 20 20 20 20 69 6e  Blockid;..    in
22960 74 65 72 69 6f 72 57 72 69 74 65 72 41 70 70 65  teriorWriterAppe
22970 6e 64 28 70 57 72 69 74 65 72 2d 3e 70 61 72 65  nd(pWriter->pare
22980 6e 74 57 72 69 74 65 72 2c 0a 20 20 20 20 20 20  ntWriter,.      
22990 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
229a0 20 20 20 62 6c 6f 63 6b 2d 3e 74 65 72 6d 2e 70     block->term.p
229b0 44 61 74 61 2c 20 62 6c 6f 63 6b 2d 3e 74 65 72  Data, block->ter
229c0 6d 2e 6e 44 61 74 61 2c 20 69 42 6c 6f 63 6b 69  m.nData, iBlocki
229d0 64 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 50 61  d);.  }..  /* Pa
229e0 72 65 6e 74 20 6e 6f 64 65 20 67 65 74 73 20 74  rent node gets t
229f0 68 65 20 63 68 61 6e 63 65 20 74 6f 20 62 65 20  he chance to be 
22a00 74 68 65 20 72 6f 6f 74 2e 20 2a 2f 0a 20 20 72  the root. */.  r
22a10 65 74 75 72 6e 20 69 6e 74 65 72 69 6f 72 57 72  eturn interiorWr
22a20 69 74 65 72 52 6f 6f 74 49 6e 66 6f 28 76 2c 20  iterRootInfo(v, 
22a30 70 57 72 69 74 65 72 2d 3e 70 61 72 65 6e 74 57  pWriter->parentW
22a40 72 69 74 65 72 2c 0a 20 20 20 20 20 20 20 20 20  riter,.         
22a50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22a60 20 20 20 20 20 20 20 70 70 52 6f 6f 74 49 6e 66         ppRootInf
22a70 6f 2c 20 70 6e 52 6f 6f 74 49 6e 66 6f 2c 20 70  o, pnRootInfo, p
22a80 69 45 6e 64 42 6c 6f 63 6b 69 64 29 3b 0a 7d 0a  iEndBlockid);.}.
22a90 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
22aa0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
22ab0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
22ac0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
22ad0 2a 2a 2f 0a 2f 2a 20 49 6e 74 65 72 69 6f 72 52  **/./* InteriorR
22ae0 65 61 64 65 72 20 69 73 20 75 73 65 64 20 74 6f  eader is used to
22af0 20 72 65 61 64 20 6f 66 66 20 74 68 65 20 64 61   read off the da
22b00 74 61 20 66 72 6f 6d 20 61 6e 20 69 6e 74 65 72  ta from an inter
22b10 69 6f 72 20 6e 6f 64 65 0a 2a 2a 20 28 73 65 65  ior node.** (see
22b20 20 63 6f 6d 6d 65 6e 74 20 61 74 20 74 6f 70 20   comment at top 
22b30 6f 66 20 66 69 6c 65 20 66 6f 72 20 74 68 65 20  of file for the 
22b40 66 6f 72 6d 61 74 29 2e 0a 2a 2f 0a 74 79 70 65  format)..*/.type
22b50 64 65 66 20 73 74 72 75 63 74 20 49 6e 74 65 72  def struct Inter
22b60 69 6f 72 52 65 61 64 65 72 20 7b 0a 20 20 63 6f  iorReader {.  co
22b70 6e 73 74 20 63 68 61 72 20 2a 70 44 61 74 61 3b  nst char *pData;
22b80 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a 0a 20  .  int nData;.. 
22b90 20 44 61 74 61 42 75 66 66 65 72 20 74 65 72 6d   DataBuffer term
22ba0 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 72  ;          /* pr
22bb0 65 76 69 6f 75 73 20 74 65 72 6d 2c 20 66 6f 72  evious term, for
22bc0 20 64 65 63 6f 64 69 6e 67 20 74 65 72 6d 20 64   decoding term d
22bd0 65 6c 74 61 2e 20 2a 2f 0a 0a 20 20 73 71 6c 69  elta. */..  sqli
22be0 74 65 5f 69 6e 74 36 34 20 69 42 6c 6f 63 6b 69  te_int64 iBlocki
22bf0 64 3b 0a 7d 20 49 6e 74 65 72 69 6f 72 52 65 61  d;.} InteriorRea
22c00 64 65 72 3b 0a 0a 73 74 61 74 69 63 20 76 6f 69  der;..static voi
22c10 64 20 69 6e 74 65 72 69 6f 72 52 65 61 64 65 72  d interiorReader
22c20 44 65 73 74 72 6f 79 28 49 6e 74 65 72 69 6f 72  Destroy(Interior
22c30 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29  Reader *pReader)
22c40 7b 0a 20 20 64 61 74 61 42 75 66 66 65 72 44 65  {.  dataBufferDe
22c50 73 74 72 6f 79 28 26 70 52 65 61 64 65 72 2d 3e  stroy(&pReader->
22c60 74 65 72 6d 29 3b 0a 20 20 53 43 52 41 4d 42 4c  term);.  SCRAMBL
22c70 45 28 70 52 65 61 64 65 72 29 3b 0a 7d 0a 0a 2f  E(pReader);.}../
22c80 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 54 68  * TODO(shess) Th
22c90 65 20 61 73 73 65 72 74 69 6f 6e 73 20 61 72 65  e assertions are
22ca0 20 67 72 65 61 74 2c 20 62 75 74 20 77 68 61 74   great, but what
22cb0 20 69 66 20 77 65 27 72 65 20 69 6e 20 4e 44 45   if we're in NDE
22cc0 42 55 47 0a 2a 2a 20 61 6e 64 20 74 68 65 20 62  BUG.** and the b
22cd0 6c 6f 62 20 69 73 20 65 6d 70 74 79 20 6f 72 20  lob is empty or 
22ce0 6f 74 68 65 72 77 69 73 65 20 63 6f 6e 74 61 69  otherwise contai
22cf0 6e 73 20 73 75 73 70 65 63 74 20 64 61 74 61 3f  ns suspect data?
22d00 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
22d10 69 6e 74 65 72 69 6f 72 52 65 61 64 65 72 49 6e  interiorReaderIn
22d20 69 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  it(const char *p
22d30 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 2c  Data, int nData,
22d40 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
22d50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22d60 49 6e 74 65 72 69 6f 72 52 65 61 64 65 72 20 2a  InteriorReader *
22d70 70 52 65 61 64 65 72 29 7b 0a 20 20 69 6e 74 20  pReader){.  int 
22d80 6e 2c 20 6e 54 65 72 6d 3b 0a 0a 20 20 2f 2a 20  n, nTerm;..  /* 
22d90 52 65 71 75 69 72 65 20 61 74 20 6c 65 61 73 74  Require at least
22da0 20 74 68 65 20 6c 65 61 64 69 6e 67 20 66 6c 61   the leading fla
22db0 67 20 62 79 74 65 20 2a 2f 0a 20 20 61 73 73 65  g byte */.  asse
22dc0 72 74 28 20 6e 44 61 74 61 3e 30 20 29 3b 0a 20  rt( nData>0 );. 
22dd0 20 61 73 73 65 72 74 28 20 70 44 61 74 61 5b 30   assert( pData[0
22de0 5d 21 3d 27 5c 30 27 20 29 3b 0a 0a 20 20 43 4c  ]!='\0' );..  CL
22df0 45 41 52 28 70 52 65 61 64 65 72 29 3b 0a 0a 20  EAR(pReader);.. 
22e00 20 2f 2a 20 44 65 63 6f 64 65 20 74 68 65 20 62   /* Decode the b
22e10 61 73 65 20 62 6c 6f 63 6b 69 64 2c 20 61 6e 64  ase blockid, and
22e20 20 73 65 74 20 74 68 65 20 63 75 72 73 6f 72 20   set the cursor 
22e30 74 6f 20 74 68 65 20 66 69 72 73 74 20 74 65 72  to the first ter
22e40 6d 2e 20 2a 2f 0a 20 20 6e 20 3d 20 66 74 73 33  m. */.  n = fts3
22e50 47 65 74 56 61 72 69 6e 74 28 70 44 61 74 61 2b  GetVarint(pData+
22e60 31 2c 20 26 70 52 65 61 64 65 72 2d 3e 69 42 6c  1, &pReader->iBl
22e70 6f 63 6b 69 64 29 3b 0a 20 20 61 73 73 65 72 74  ockid);.  assert
22e80 28 20 31 2b 6e 3c 3d 6e 44 61 74 61 20 29 3b 0a  ( 1+n<=nData );.
22e90 20 20 70 52 65 61 64 65 72 2d 3e 70 44 61 74 61    pReader->pData
22ea0 20 3d 20 70 44 61 74 61 2b 31 2b 6e 3b 0a 20 20   = pData+1+n;.  
22eb0 70 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 20 3d  pReader->nData =
22ec0 20 6e 44 61 74 61 2d 28 31 2b 6e 29 3b 0a 0a 20   nData-(1+n);.. 
22ed0 20 2f 2a 20 41 20 73 69 6e 67 6c 65 2d 63 68 69   /* A single-chi
22ee0 6c 64 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65  ld interior node
22ef0 20 28 73 75 63 68 20 61 73 20 77 68 65 6e 20 61   (such as when a
22f00 20 6c 65 61 66 20 6e 6f 64 65 20 77 61 73 20 74   leaf node was t
22f10 6f 6f 0a 20 20 2a 2a 20 6c 61 72 67 65 20 66 6f  oo.  ** large fo
22f20 72 20 74 68 65 20 73 65 67 6d 65 6e 74 20 64 69  r the segment di
22f30 72 65 63 74 6f 72 79 29 20 77 6f 6e 27 74 20 68  rectory) won't h
22f40 61 76 65 20 61 6e 79 20 74 65 72 6d 73 2e 0a 20  ave any terms.. 
22f50 20 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 64   ** Otherwise, d
22f60 65 63 6f 64 65 20 74 68 65 20 66 69 72 73 74 20  ecode the first 
22f70 74 65 72 6d 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  term..  */.  if(
22f80 20 70 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 3d   pReader->nData=
22f90 3d 30 20 29 7b 0a 20 20 20 20 64 61 74 61 42 75  =0 ){.    dataBu
22fa0 66 66 65 72 49 6e 69 74 28 26 70 52 65 61 64 65  fferInit(&pReade
22fb0 72 2d 3e 74 65 72 6d 2c 20 30 29 3b 0a 20 20 7d  r->term, 0);.  }
22fc0 65 6c 73 65 7b 0a 20 20 20 20 6e 20 3d 20 66 74  else{.    n = ft
22fd0 73 33 47 65 74 56 61 72 69 6e 74 33 32 28 70 52  s3GetVarint32(pR
22fe0 65 61 64 65 72 2d 3e 70 44 61 74 61 2c 20 26 6e  eader->pData, &n
22ff0 54 65 72 6d 29 3b 0a 20 20 20 20 64 61 74 61 42  Term);.    dataB
23000 75 66 66 65 72 49 6e 69 74 28 26 70 52 65 61 64  ufferInit(&pRead
23010 65 72 2d 3e 74 65 72 6d 2c 20 6e 54 65 72 6d 29  er->term, nTerm)
23020 3b 0a 20 20 20 20 64 61 74 61 42 75 66 66 65 72  ;.    dataBuffer
23030 52 65 70 6c 61 63 65 28 26 70 52 65 61 64 65 72  Replace(&pReader
23040 2d 3e 74 65 72 6d 2c 20 70 52 65 61 64 65 72 2d  ->term, pReader-
23050 3e 70 44 61 74 61 2b 6e 2c 20 6e 54 65 72 6d 29  >pData+n, nTerm)
23060 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 6e 2b  ;.    assert( n+
23070 6e 54 65 72 6d 3c 3d 70 52 65 61 64 65 72 2d 3e  nTerm<=pReader->
23080 6e 44 61 74 61 20 29 3b 0a 20 20 20 20 70 52 65  nData );.    pRe
23090 61 64 65 72 2d 3e 70 44 61 74 61 20 2b 3d 20 6e  ader->pData += n
230a0 2b 6e 54 65 72 6d 3b 0a 20 20 20 20 70 52 65 61  +nTerm;.    pRea
230b0 64 65 72 2d 3e 6e 44 61 74 61 20 2d 3d 20 6e 2b  der->nData -= n+
230c0 6e 54 65 72 6d 3b 0a 20 20 7d 0a 7d 0a 0a 73 74  nTerm;.  }.}..st
230d0 61 74 69 63 20 69 6e 74 20 69 6e 74 65 72 69 6f  atic int interio
230e0 72 52 65 61 64 65 72 41 74 45 6e 64 28 49 6e 74  rReaderAtEnd(Int
230f0 65 72 69 6f 72 52 65 61 64 65 72 20 2a 70 52 65  eriorReader *pRe
23100 61 64 65 72 29 7b 0a 20 20 72 65 74 75 72 6e 20  ader){.  return 
23110 70 52 65 61 64 65 72 2d 3e 74 65 72 6d 2e 6e 44  pReader->term.nD
23120 61 74 61 3d 3d 30 3b 0a 7d 0a 0a 73 74 61 74 69  ata==0;.}..stati
23130 63 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69  c sqlite_int64 i
23140 6e 74 65 72 69 6f 72 52 65 61 64 65 72 43 75 72  nteriorReaderCur
23150 72 65 6e 74 42 6c 6f 63 6b 69 64 28 49 6e 74 65  rentBlockid(Inte
23160 72 69 6f 72 52 65 61 64 65 72 20 2a 70 52 65 61  riorReader *pRea
23170 64 65 72 29 7b 0a 20 20 72 65 74 75 72 6e 20 70  der){.  return p
23180 52 65 61 64 65 72 2d 3e 69 42 6c 6f 63 6b 69 64  Reader->iBlockid
23190 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
231a0 69 6e 74 65 72 69 6f 72 52 65 61 64 65 72 54 65  interiorReaderTe
231b0 72 6d 42 79 74 65 73 28 49 6e 74 65 72 69 6f 72  rmBytes(Interior
231c0 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29  Reader *pReader)
231d0 7b 0a 20 20 61 73 73 65 72 74 28 20 21 69 6e 74  {.  assert( !int
231e0 65 72 69 6f 72 52 65 61 64 65 72 41 74 45 6e 64  eriorReaderAtEnd
231f0 28 70 52 65 61 64 65 72 29 20 29 3b 0a 20 20 72  (pReader) );.  r
23200 65 74 75 72 6e 20 70 52 65 61 64 65 72 2d 3e 74  eturn pReader->t
23210 65 72 6d 2e 6e 44 61 74 61 3b 0a 7d 0a 73 74 61  erm.nData;.}.sta
23220 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  tic const char *
23230 69 6e 74 65 72 69 6f 72 52 65 61 64 65 72 54 65  interiorReaderTe
23240 72 6d 28 49 6e 74 65 72 69 6f 72 52 65 61 64 65  rm(InteriorReade
23250 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 61  r *pReader){.  a
23260 73 73 65 72 74 28 20 21 69 6e 74 65 72 69 6f 72  ssert( !interior
23270 52 65 61 64 65 72 41 74 45 6e 64 28 70 52 65 61  ReaderAtEnd(pRea
23280 64 65 72 29 20 29 3b 0a 20 20 72 65 74 75 72 6e  der) );.  return
23290 20 70 52 65 61 64 65 72 2d 3e 74 65 72 6d 2e 70   pReader->term.p
232a0 44 61 74 61 3b 0a 7d 0a 0a 2f 2a 20 53 74 65 70  Data;.}../* Step
232b0 20 66 6f 72 77 61 72 64 20 74 6f 20 74 68 65 20   forward to the 
232c0 6e 65 78 74 20 74 65 72 6d 20 69 6e 20 74 68 65  next term in the
232d0 20 6e 6f 64 65 2e 20 2a 2f 0a 73 74 61 74 69 63   node. */.static
232e0 20 76 6f 69 64 20 69 6e 74 65 72 69 6f 72 52 65   void interiorRe
232f0 61 64 65 72 53 74 65 70 28 49 6e 74 65 72 69 6f  aderStep(Interio
23300 72 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72  rReader *pReader
23310 29 7b 0a 20 20 61 73 73 65 72 74 28 20 21 69 6e  ){.  assert( !in
23320 74 65 72 69 6f 72 52 65 61 64 65 72 41 74 45 6e  teriorReaderAtEn
23330 64 28 70 52 65 61 64 65 72 29 20 29 3b 0a 0a 20  d(pReader) );.. 
23340 20 2f 2a 20 49 66 20 74 68 65 20 6c 61 73 74 20   /* If the last 
23350 74 65 72 6d 20 68 61 73 20 62 65 65 6e 20 72 65  term has been re
23360 61 64 2c 20 73 69 67 6e 61 6c 20 65 6f 66 2c 20  ad, signal eof, 
23370 65 6c 73 65 20 63 6f 6e 73 74 72 75 63 74 20 74  else construct t
23380 68 65 0a 20 20 2a 2a 20 6e 65 78 74 20 74 65 72  he.  ** next ter
23390 6d 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 70 52  m..  */.  if( pR
233a0 65 61 64 65 72 2d 3e 6e 44 61 74 61 3d 3d 30 20  eader->nData==0 
233b0 29 7b 0a 20 20 20 20 64 61 74 61 42 75 66 66 65  ){.    dataBuffe
233c0 72 52 65 73 65 74 28 26 70 52 65 61 64 65 72 2d  rReset(&pReader-
233d0 3e 74 65 72 6d 29 3b 0a 20 20 7d 65 6c 73 65 7b  >term);.  }else{
233e0 0a 20 20 20 20 69 6e 74 20 6e 2c 20 6e 50 72 65  .    int n, nPre
233f0 66 69 78 2c 20 6e 53 75 66 66 69 78 3b 0a 0a 20  fix, nSuffix;.. 
23400 20 20 20 6e 20 3d 20 66 74 73 33 47 65 74 56 61     n = fts3GetVa
23410 72 69 6e 74 33 32 28 70 52 65 61 64 65 72 2d 3e  rint32(pReader->
23420 70 44 61 74 61 2c 20 26 6e 50 72 65 66 69 78 29  pData, &nPrefix)
23430 3b 0a 20 20 20 20 6e 20 2b 3d 20 66 74 73 33 47  ;.    n += fts3G
23440 65 74 56 61 72 69 6e 74 33 32 28 70 52 65 61 64  etVarint32(pRead
23450 65 72 2d 3e 70 44 61 74 61 2b 6e 2c 20 26 6e 53  er->pData+n, &nS
23460 75 66 66 69 78 29 3b 0a 0a 20 20 20 20 2f 2a 20  uffix);..    /* 
23470 54 72 75 6e 63 61 74 65 20 74 68 65 20 63 75 72  Truncate the cur
23480 72 65 6e 74 20 74 65 72 6d 20 61 6e 64 20 61 70  rent term and ap
23490 70 65 6e 64 20 73 75 66 66 69 78 20 64 61 74 61  pend suffix data
234a0 2e 20 2a 2f 0a 20 20 20 20 70 52 65 61 64 65 72  . */.    pReader
234b0 2d 3e 74 65 72 6d 2e 6e 44 61 74 61 20 3d 20 6e  ->term.nData = n
234c0 50 72 65 66 69 78 3b 0a 20 20 20 20 64 61 74 61  Prefix;.    data
234d0 42 75 66 66 65 72 41 70 70 65 6e 64 28 26 70 52  BufferAppend(&pR
234e0 65 61 64 65 72 2d 3e 74 65 72 6d 2c 20 70 52 65  eader->term, pRe
234f0 61 64 65 72 2d 3e 70 44 61 74 61 2b 6e 2c 20 6e  ader->pData+n, n
23500 53 75 66 66 69 78 29 3b 0a 0a 20 20 20 20 61 73  Suffix);..    as
23510 73 65 72 74 28 20 6e 2b 6e 53 75 66 66 69 78 3c  sert( n+nSuffix<
23520 3d 70 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 20  =pReader->nData 
23530 29 3b 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e  );.    pReader->
23540 70 44 61 74 61 20 2b 3d 20 6e 2b 6e 53 75 66 66  pData += n+nSuff
23550 69 78 3b 0a 20 20 20 20 70 52 65 61 64 65 72 2d  ix;.    pReader-
23560 3e 6e 44 61 74 61 20 2d 3d 20 6e 2b 6e 53 75 66  >nData -= n+nSuf
23570 66 69 78 3b 0a 20 20 7d 0a 20 20 70 52 65 61 64  fix;.  }.  pRead
23580 65 72 2d 3e 69 42 6c 6f 63 6b 69 64 2b 2b 3b 0a  er->iBlockid++;.
23590 7d 0a 0a 2f 2a 20 43 6f 6d 70 61 72 65 20 74 68  }../* Compare th
235a0 65 20 63 75 72 72 65 6e 74 20 74 65 72 6d 20 74  e current term t
235b0 6f 20 70 54 65 72 6d 5b 6e 54 65 72 6d 5d 2c 20  o pTerm[nTerm], 
235c0 72 65 74 75 72 6e 69 6e 67 20 73 74 72 63 6d 70  returning strcmp
235d0 2d 73 74 79 6c 65 0a 2a 2a 20 72 65 73 75 6c 74  -style.** result
235e0 73 2e 20 20 49 66 20 69 73 50 72 65 66 69 78 2c  s.  If isPrefix,
235f0 20 65 71 75 61 6c 69 74 79 20 6d 65 61 6e 73 20   equality means 
23600 65 71 75 61 6c 20 74 68 72 6f 75 67 68 20 6e 54  equal through nT
23610 65 72 6d 20 62 79 74 65 73 2e 0a 2a 2f 0a 73 74  erm bytes..*/.st
23620 61 74 69 63 20 69 6e 74 20 69 6e 74 65 72 69 6f  atic int interio
23630 72 52 65 61 64 65 72 54 65 72 6d 43 6d 70 28 49  rReaderTermCmp(I
23640 6e 74 65 72 69 6f 72 52 65 61 64 65 72 20 2a 70  nteriorReader *p
23650 52 65 61 64 65 72 2c 0a 20 20 20 20 20 20 20 20  Reader,.        
23660 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23670 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63           const c
23680 68 61 72 20 2a 70 54 65 72 6d 2c 20 69 6e 74 20  har *pTerm, int 
23690 6e 54 65 72 6d 2c 20 69 6e 74 20 69 73 50 72 65  nTerm, int isPre
236a0 66 69 78 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68  fix){.  const ch
236b0 61 72 20 2a 70 52 65 61 64 65 72 54 65 72 6d 20  ar *pReaderTerm 
236c0 3d 20 69 6e 74 65 72 69 6f 72 52 65 61 64 65 72  = interiorReader
236d0 54 65 72 6d 28 70 52 65 61 64 65 72 29 3b 0a 20  Term(pReader);. 
236e0 20 69 6e 74 20 6e 52 65 61 64 65 72 54 65 72 6d   int nReaderTerm
236f0 20 3d 20 69 6e 74 65 72 69 6f 72 52 65 61 64 65   = interiorReade
23700 72 54 65 72 6d 42 79 74 65 73 28 70 52 65 61 64  rTermBytes(pRead
23710 65 72 29 3b 0a 20 20 69 6e 74 20 63 2c 20 6e 20  er);.  int c, n 
23720 3d 20 6e 52 65 61 64 65 72 54 65 72 6d 3c 6e 54  = nReaderTerm<nT
23730 65 72 6d 20 3f 20 6e 52 65 61 64 65 72 54 65 72  erm ? nReaderTer
23740 6d 20 3a 20 6e 54 65 72 6d 3b 0a 0a 20 20 69 66  m : nTerm;..  if
23750 28 20 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66  ( n==0 ){.    if
23760 28 20 6e 52 65 61 64 65 72 54 65 72 6d 3e 30 20  ( nReaderTerm>0 
23770 29 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 20  ) return -1;.   
23780 20 69 66 28 20 6e 54 65 72 6d 3e 30 20 29 20 72   if( nTerm>0 ) r
23790 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 72 65 74  eturn 1;.    ret
237a0 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 63 20  urn 0;.  }..  c 
237b0 3d 20 6d 65 6d 63 6d 70 28 70 52 65 61 64 65 72  = memcmp(pReader
237c0 54 65 72 6d 2c 20 70 54 65 72 6d 2c 20 6e 29 3b  Term, pTerm, n);
237d0 0a 20 20 69 66 28 20 63 21 3d 30 20 29 20 72 65  .  if( c!=0 ) re
237e0 74 75 72 6e 20 63 3b 0a 20 20 69 66 28 20 69 73  turn c;.  if( is
237f0 50 72 65 66 69 78 20 26 26 20 6e 3d 3d 6e 54 65  Prefix && n==nTe
23800 72 6d 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20  rm ) return 0;. 
23810 20 72 65 74 75 72 6e 20 6e 52 65 61 64 65 72 54   return nReaderT
23820 65 72 6d 20 2d 20 6e 54 65 72 6d 3b 0a 7d 0a 0a  erm - nTerm;.}..
23830 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
23840 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
23850 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
23860 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
23870 2a 2f 0a 2f 2a 20 4c 65 61 66 57 72 69 74 65 72  */./* LeafWriter
23880 20 69 73 20 75 73 65 64 20 74 6f 20 63 6f 6c 6c   is used to coll
23890 65 63 74 20 74 65 72 6d 73 20 61 6e 64 20 61 73  ect terms and as
238a0 73 6f 63 69 61 74 65 64 20 64 6f 63 6c 69 73 74  sociated doclist
238b0 20 64 61 74 61 0a 2a 2a 20 69 6e 74 6f 20 6c 65   data.** into le
238c0 61 66 20 62 6c 6f 63 6b 73 20 69 6e 20 25 5f 73  af blocks in %_s
238d0 65 67 6d 65 6e 74 73 20 28 73 65 65 20 74 6f 70  egments (see top
238e0 20 6f 66 20 66 69 6c 65 20 66 6f 72 20 66 6f 72   of file for for
238f0 6d 61 74 20 69 6e 66 6f 29 2e 0a 2a 2a 20 45 78  mat info)..** Ex
23900 70 65 63 74 65 64 20 75 73 61 67 65 20 69 73 3a  pected usage is:
23910 0a 2a 2a 0a 2a 2a 20 4c 65 61 66 57 72 69 74 65  .**.** LeafWrite
23920 72 20 77 72 69 74 65 72 3b 0a 2a 2a 20 6c 65 61  r writer;.** lea
23930 66 57 72 69 74 65 72 49 6e 69 74 28 30 2c 20 30  fWriterInit(0, 0
23940 2c 20 26 77 72 69 74 65 72 29 3b 0a 2a 2a 20 77  , &writer);.** w
23950 68 69 6c 65 28 20 73 6f 72 74 65 64 5f 74 65 72  hile( sorted_ter
23960 6d 73 5f 6c 65 66 74 5f 74 6f 5f 70 72 6f 63 65  ms_left_to_proce
23970 73 73 20 29 7b 0a 2a 2a 20 20 20 2f 2f 20 64 61  ss ){.**   // da
23980 74 61 20 69 73 20 64 6f 63 6c 69 73 74 20 64 61  ta is doclist da
23990 74 61 20 66 6f 72 20 74 68 61 74 20 74 65 72 6d  ta for that term
239a0 2e 0a 2a 2a 20 20 20 72 63 20 3d 20 6c 65 61 66  ..**   rc = leaf
239b0 57 72 69 74 65 72 53 74 65 70 28 76 2c 20 26 77  WriterStep(v, &w
239c0 72 69 74 65 72 2c 20 70 54 65 72 6d 2c 20 6e 54  riter, pTerm, nT
239d0 65 72 6d 2c 20 70 44 61 74 61 2c 20 6e 44 61 74  erm, pData, nDat
239e0 61 29 3b 0a 2a 2a 20 20 20 69 66 28 20 72 63 21  a);.**   if( rc!
239f0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74  =SQLITE_OK ) got
23a00 6f 20 65 72 72 3b 0a 2a 2a 20 7d 0a 2a 2a 20 72  o err;.** }.** r
23a10 63 20 3d 20 6c 65 61 66 57 72 69 74 65 72 46 69  c = leafWriterFi
23a20 6e 61 6c 69 7a 65 28 76 2c 20 26 77 72 69 74 65  nalize(v, &write
23a30 72 29 3b 0a 2a 2a 65 72 72 3a 0a 2a 2a 20 6c 65  r);.**err:.** le
23a40 61 66 57 72 69 74 65 72 44 65 73 74 72 6f 79 28  afWriterDestroy(
23a50 26 77 72 69 74 65 72 29 3b 0a 2a 2a 20 72 65 74  &writer);.** ret
23a60 75 72 6e 20 72 63 3b 0a 2a 2a 0a 2a 2a 20 6c 65  urn rc;.**.** le
23a70 61 66 57 72 69 74 65 72 53 74 65 70 28 29 20 6d  afWriterStep() m
23a80 61 79 20 77 72 69 74 65 20 61 20 63 6f 6c 6c 65  ay write a colle
23a90 63 74 65 64 20 6c 65 61 66 20 6f 75 74 20 74 6f  cted leaf out to
23aa0 20 25 5f 73 65 67 6d 65 6e 74 73 2e 0a 2a 2a 20   %_segments..** 
23ab0 6c 65 61 66 57 72 69 74 65 72 46 69 6e 61 6c 69  leafWriterFinali
23ac0 7a 65 28 29 20 66 69 6e 69 73 68 65 73 20 77 72  ze() finishes wr
23ad0 69 74 69 6e 67 20 61 6e 79 20 62 75 66 66 65 72  iting any buffer
23ae0 65 64 20 64 61 74 61 20 61 6e 64 20 73 74 6f 72  ed data and stor
23af0 65 73 0a 2a 2a 20 61 20 72 6f 6f 74 20 6e 6f 64  es.** a root nod
23b00 65 20 69 6e 20 25 5f 73 65 67 64 69 72 2e 20 20  e in %_segdir.  
23b10 6c 65 61 66 57 72 69 74 65 72 44 65 73 74 72 6f  leafWriterDestro
23b20 79 28 29 20 66 72 65 65 73 20 61 6c 6c 20 62 75  y() frees all bu
23b30 66 66 65 72 73 20 61 6e 64 0a 2a 2a 20 49 6e 74  ffers and.** Int
23b40 65 72 69 6f 72 57 72 69 74 65 72 73 20 61 6c 6c  eriorWriters all
23b50 6f 63 61 74 65 64 20 61 73 20 70 61 72 74 20 6f  ocated as part o
23b60 66 20 77 72 69 74 69 6e 67 20 74 68 69 73 20 73  f writing this s
23b70 65 67 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 4f  egment..**.** TO
23b80 44 4f 28 73 68 65 73 73 29 20 44 6f 63 75 6d 65  DO(shess) Docume
23b90 6e 74 20 6c 65 61 66 57 72 69 74 65 72 53 74 65  nt leafWriterSte
23ba0 70 4d 65 72 67 65 28 29 2e 0a 2a 2f 0a 0a 2f 2a  pMerge()..*/../*
23bb0 20 50 75 74 20 74 65 72 6d 73 20 77 69 74 68 20   Put terms with 
23bc0 64 61 74 61 20 74 68 69 73 20 62 69 67 20 69 6e  data this big in
23bd0 20 74 68 65 69 72 20 6f 77 6e 20 62 6c 6f 63 6b   their own block
23be0 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53 54 41  . */.#define STA
23bf0 4e 44 41 4c 4f 4e 45 5f 4d 49 4e 20 31 30 32 34  NDALONE_MIN 1024
23c00 0a 0a 2f 2a 20 4b 65 65 70 20 6c 65 61 66 20 62  ../* Keep leaf b
23c10 6c 6f 63 6b 73 20 62 65 6c 6f 77 20 74 68 69 73  locks below this
23c20 20 73 69 7a 65 2e 20 2a 2f 0a 23 64 65 66 69 6e   size. */.#defin
23c30 65 20 4c 45 41 46 5f 4d 41 58 20 32 30 34 38 0a  e LEAF_MAX 2048.
23c40 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
23c50 4c 65 61 66 57 72 69 74 65 72 20 7b 0a 20 20 69  LeafWriter {.  i
23c60 6e 74 20 69 4c 65 76 65 6c 3b 0a 20 20 69 6e 74  nt iLevel;.  int
23c70 20 69 64 78 3b 0a 20 20 73 71 6c 69 74 65 5f 69   idx;.  sqlite_i
23c80 6e 74 36 34 20 69 53 74 61 72 74 42 6c 6f 63 6b  nt64 iStartBlock
23c90 69 64 3b 20 20 20 20 20 2f 2a 20 6e 65 65 64 65  id;     /* neede
23ca0 64 20 74 6f 20 63 72 65 61 74 65 20 74 68 65 20  d to create the 
23cb0 72 6f 6f 74 20 69 6e 66 6f 20 2a 2f 0a 20 20 73  root info */.  s
23cc0 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 45 6e 64  qlite_int64 iEnd
23cd0 42 6c 6f 63 6b 69 64 3b 20 20 20 20 20 20 20 2f  Blockid;       /
23ce0 2a 20 77 68 65 6e 20 77 65 27 72 65 20 64 6f 6e  * when we're don
23cf0 65 20 77 72 69 74 69 6e 67 2e 20 2a 2f 0a 0a 20  e writing. */.. 
23d00 20 44 61 74 61 42 75 66 66 65 72 20 74 65 72 6d   DataBuffer term
23d10 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
23d20 20 2f 2a 20 70 72 65 76 69 6f 75 73 20 65 6e 63   /* previous enc
23d30 6f 64 65 64 20 74 65 72 6d 20 2a 2f 0a 20 20 44  oded term */.  D
23d40 61 74 61 42 75 66 66 65 72 20 64 61 74 61 3b 20  ataBuffer data; 
23d50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
23d60 2a 20 65 6e 63 6f 64 69 6e 67 20 62 75 66 66 65  * encoding buffe
23d70 72 20 2a 2f 0a 0a 20 20 2f 2a 20 62 79 74 65 73  r */..  /* bytes
23d80 20 6f 66 20 66 69 72 73 74 20 74 65 72 6d 20 69   of first term i
23d90 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20 6e 6f  n the current no
23da0 64 65 20 77 68 69 63 68 20 64 69 73 74 69 6e 67  de which disting
23db0 75 69 73 68 65 73 20 74 68 61 74 0a 20 20 2a 2a  uishes that.  **
23dc0 20 74 65 72 6d 20 66 72 6f 6d 20 74 68 65 20 6c   term from the l
23dd0 61 73 74 20 74 65 72 6d 20 6f 66 20 74 68 65 20  ast term of the 
23de0 70 72 65 76 69 6f 75 73 20 6e 6f 64 65 2e 0a 20  previous node.. 
23df0 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 65 72 6d 44   */.  int nTermD
23e00 69 73 74 69 6e 63 74 3b 0a 0a 20 20 49 6e 74 65  istinct;..  Inte
23e10 72 69 6f 72 57 72 69 74 65 72 20 70 61 72 65 6e  riorWriter paren
23e20 74 57 72 69 74 65 72 3b 20 20 20 20 2f 2a 20 69  tWriter;    /* i
23e30 66 20 77 65 20 6f 76 65 72 66 6c 6f 77 20 2a 2f  f we overflow */
23e40 0a 20 20 69 6e 74 20 68 61 73 5f 70 61 72 65 6e  .  int has_paren
23e50 74 3b 0a 7d 20 4c 65 61 66 57 72 69 74 65 72 3b  t;.} LeafWriter;
23e60 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6c 65  ..static void le
23e70 61 66 57 72 69 74 65 72 49 6e 69 74 28 69 6e 74  afWriterInit(int
23e80 20 69 4c 65 76 65 6c 2c 20 69 6e 74 20 69 64 78   iLevel, int idx
23e90 2c 20 4c 65 61 66 57 72 69 74 65 72 20 2a 70 57  , LeafWriter *pW
23ea0 72 69 74 65 72 29 7b 0a 20 20 43 4c 45 41 52 28  riter){.  CLEAR(
23eb0 70 57 72 69 74 65 72 29 3b 0a 20 20 70 57 72 69  pWriter);.  pWri
23ec0 74 65 72 2d 3e 69 4c 65 76 65 6c 20 3d 20 69 4c  ter->iLevel = iL
23ed0 65 76 65 6c 3b 0a 20 20 70 57 72 69 74 65 72 2d  evel;.  pWriter-
23ee0 3e 69 64 78 20 3d 20 69 64 78 3b 0a 0a 20 20 64  >idx = idx;..  d
23ef0 61 74 61 42 75 66 66 65 72 49 6e 69 74 28 26 70  ataBufferInit(&p
23f00 57 72 69 74 65 72 2d 3e 74 65 72 6d 2c 20 33 32  Writer->term, 32
23f10 29 3b 0a 0a 20 20 2f 2a 20 53 74 61 72 74 20 6f  );..  /* Start o
23f20 75 74 20 77 69 74 68 20 61 20 72 65 61 73 6f 6e  ut with a reason
23f30 61 62 6c 79 20 73 69 7a 65 64 20 62 6c 6f 63 6b  ably sized block
23f40 2c 20 74 68 6f 75 67 68 20 69 74 20 63 61 6e 20  , though it can 
23f50 67 72 6f 77 2e 20 2a 2f 0a 20 20 64 61 74 61 42  grow. */.  dataB
23f60 75 66 66 65 72 49 6e 69 74 28 26 70 57 72 69 74  ufferInit(&pWrit
23f70 65 72 2d 3e 64 61 74 61 2c 20 4c 45 41 46 5f 4d  er->data, LEAF_M
23f80 41 58 29 3b 0a 7d 0a 0a 23 69 66 6e 64 65 66 20  AX);.}..#ifndef 
23f90 4e 44 45 42 55 47 0a 2f 2a 20 56 65 72 69 66 79  NDEBUG./* Verify
23fa0 20 74 68 61 74 20 74 68 65 20 64 61 74 61 20 69   that the data i
23fb0 73 20 72 65 61 64 61 62 6c 65 20 61 73 20 61 20  s readable as a 
23fc0 6c 65 61 66 20 6e 6f 64 65 2e 20 2a 2f 0a 73 74  leaf node. */.st
23fd0 61 74 69 63 20 76 6f 69 64 20 6c 65 61 66 4e 6f  atic void leafNo
23fe0 64 65 56 61 6c 69 64 61 74 65 28 63 6f 6e 73 74  deValidate(const
23ff0 20 63 68 61 72 20 2a 70 44 61 74 61 2c 20 69 6e   char *pData, in
24000 74 20 6e 44 61 74 61 29 7b 0a 20 20 69 6e 74 20  t nData){.  int 
24010 6e 2c 20 69 44 75 6d 6d 79 3b 0a 0a 20 20 69 66  n, iDummy;..  if
24020 28 20 6e 44 61 74 61 3d 3d 30 20 29 20 72 65 74  ( nData==0 ) ret
24030 75 72 6e 3b 0a 20 20 61 73 73 65 72 74 28 20 6e  urn;.  assert( n
24040 44 61 74 61 3e 30 20 29 3b 0a 20 20 61 73 73 65  Data>0 );.  asse
24050 72 74 28 20 70 44 61 74 61 21 3d 30 20 29 3b 0a  rt( pData!=0 );.
24060 20 20 61 73 73 65 72 74 28 20 70 44 61 74 61 2b    assert( pData+
24070 6e 44 61 74 61 3e 70 44 61 74 61 20 29 3b 0a 0a  nData>pData );..
24080 20 20 2f 2a 20 4d 75 73 74 20 6c 65 61 64 20 77    /* Must lead w
24090 69 74 68 20 61 20 76 61 72 69 6e 74 28 30 29 20  ith a varint(0) 
240a0 2a 2f 0a 20 20 6e 20 3d 20 66 74 73 33 47 65 74  */.  n = fts3Get
240b0 56 61 72 69 6e 74 33 32 28 70 44 61 74 61 2c 20  Varint32(pData, 
240c0 26 69 44 75 6d 6d 79 29 3b 0a 20 20 61 73 73 65  &iDummy);.  asse
240d0 72 74 28 20 69 44 75 6d 6d 79 3d 3d 30 20 29 3b  rt( iDummy==0 );
240e0 0a 20 20 61 73 73 65 72 74 28 20 6e 3e 30 20 29  .  assert( n>0 )
240f0 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 3c 6e 44  ;.  assert( n<nD
24100 61 74 61 20 29 3b 0a 20 20 70 44 61 74 61 20 2b  ata );.  pData +
24110 3d 20 6e 3b 0a 20 20 6e 44 61 74 61 20 2d 3d 20  = n;.  nData -= 
24120 6e 3b 0a 0a 20 20 2f 2a 20 4c 65 61 64 69 6e 67  n;..  /* Leading
24130 20 74 65 72 6d 20 6c 65 6e 67 74 68 20 61 6e 64   term length and
24140 20 64 61 74 61 20 6d 75 73 74 20 66 69 74 20 69   data must fit i
24150 6e 20 62 75 66 66 65 72 2e 20 2a 2f 0a 20 20 6e  n buffer. */.  n
24160 20 3d 20 66 74 73 33 47 65 74 56 61 72 69 6e 74   = fts3GetVarint
24170 33 32 28 70 44 61 74 61 2c 20 26 69 44 75 6d 6d  32(pData, &iDumm
24180 79 29 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 3e  y);.  assert( n>
24190 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 69  0 );.  assert( i
241a0 44 75 6d 6d 79 3e 30 20 29 3b 0a 20 20 61 73 73  Dummy>0 );.  ass
241b0 65 72 74 28 20 6e 2b 69 44 75 6d 6d 79 3e 30 20  ert( n+iDummy>0 
241c0 29 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 2b 69  );.  assert( n+i
241d0 44 75 6d 6d 79 3c 6e 44 61 74 61 20 29 3b 0a 20  Dummy<nData );. 
241e0 20 70 44 61 74 61 20 2b 3d 20 6e 2b 69 44 75 6d   pData += n+iDum
241f0 6d 79 3b 0a 20 20 6e 44 61 74 61 20 2d 3d 20 6e  my;.  nData -= n
24200 2b 69 44 75 6d 6d 79 3b 0a 0a 20 20 2f 2a 20 4c  +iDummy;..  /* L
24210 65 61 64 69 6e 67 20 74 65 72 6d 27 73 20 64 6f  eading term's do
24220 63 6c 69 73 74 20 6c 65 6e 67 74 68 20 61 6e 64  clist length and
24230 20 64 61 74 61 20 6d 75 73 74 20 66 69 74 2e 20   data must fit. 
24240 2a 2f 0a 20 20 6e 20 3d 20 66 74 73 33 47 65 74  */.  n = fts3Get
24250 56 61 72 69 6e 74 33 32 28 70 44 61 74 61 2c 20  Varint32(pData, 
24260 26 69 44 75 6d 6d 79 29 3b 0a 20 20 61 73 73 65  &iDummy);.  asse
24270 72 74 28 20 6e 3e 30 20 29 3b 0a 20 20 61 73 73  rt( n>0 );.  ass
24280 65 72 74 28 20 69 44 75 6d 6d 79 3e 30 20 29 3b  ert( iDummy>0 );
24290 0a 20 20 61 73 73 65 72 74 28 20 6e 2b 69 44 75  .  assert( n+iDu
242a0 6d 6d 79 3e 30 20 29 3b 0a 20 20 61 73 73 65 72  mmy>0 );.  asser
242b0 74 28 20 6e 2b 69 44 75 6d 6d 79 3c 3d 6e 44 61  t( n+iDummy<=nDa
242c0 74 61 20 29 3b 0a 20 20 41 53 53 45 52 54 5f 56  ta );.  ASSERT_V
242d0 41 4c 49 44 5f 44 4f 43 4c 49 53 54 28 44 4c 5f  ALID_DOCLIST(DL_
242e0 44 45 46 41 55 4c 54 2c 20 70 44 61 74 61 2b 6e  DEFAULT, pData+n
242f0 2c 20 69 44 75 6d 6d 79 2c 20 4e 55 4c 4c 29 3b  , iDummy, NULL);
24300 0a 20 20 70 44 61 74 61 20 2b 3d 20 6e 2b 69 44  .  pData += n+iD
24310 75 6d 6d 79 3b 0a 20 20 6e 44 61 74 61 20 2d 3d  ummy;.  nData -=
24320 20 6e 2b 69 44 75 6d 6d 79 3b 0a 0a 20 20 2f 2a   n+iDummy;..  /*
24330 20 56 65 72 69 66 79 20 74 68 61 74 20 74 72 61   Verify that tra
24340 69 6c 69 6e 67 20 74 65 72 6d 73 20 61 6e 64 20  iling terms and 
24350 64 6f 63 6c 69 73 74 73 20 61 6c 73 6f 20 61 72  doclists also ar
24360 65 20 72 65 61 64 61 62 6c 65 2e 20 2a 2f 0a 20  e readable. */. 
24370 20 77 68 69 6c 65 28 20 6e 44 61 74 61 21 3d 30   while( nData!=0
24380 20 29 7b 0a 20 20 20 20 6e 20 3d 20 66 74 73 33   ){.    n = fts3
24390 47 65 74 56 61 72 69 6e 74 33 32 28 70 44 61 74  GetVarint32(pDat
243a0 61 2c 20 26 69 44 75 6d 6d 79 29 3b 0a 20 20 20  a, &iDummy);.   
243b0 20 61 73 73 65 72 74 28 20 6e 3e 30 20 29 3b 0a   assert( n>0 );.
243c0 20 20 20 20 61 73 73 65 72 74 28 20 69 44 75 6d      assert( iDum
243d0 6d 79 3e 3d 30 20 29 3b 0a 20 20 20 20 61 73 73  my>=0 );.    ass
243e0 65 72 74 28 20 6e 3c 6e 44 61 74 61 20 29 3b 0a  ert( n<nData );.
243f0 20 20 20 20 70 44 61 74 61 20 2b 3d 20 6e 3b 0a      pData += n;.
24400 20 20 20 20 6e 44 61 74 61 20 2d 3d 20 6e 3b 0a      nData -= n;.
24410 20 20 20 20 6e 20 3d 20 66 74 73 33 47 65 74 56      n = fts3GetV
24420 61 72 69 6e 74 33 32 28 70 44 61 74 61 2c 20 26  arint32(pData, &
24430 69 44 75 6d 6d 79 29 3b 0a 20 20 20 20 61 73 73  iDummy);.    ass
24440 65 72 74 28 20 6e 3e 30 20 29 3b 0a 20 20 20 20  ert( n>0 );.    
24450 61 73 73 65 72 74 28 20 69 44 75 6d 6d 79 3e 30  assert( iDummy>0
24460 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
24470 6e 2b 69 44 75 6d 6d 79 3e 30 20 29 3b 0a 20 20  n+iDummy>0 );.  
24480 20 20 61 73 73 65 72 74 28 20 6e 2b 69 44 75 6d    assert( n+iDum
24490 6d 79 3c 6e 44 61 74 61 20 29 3b 0a 20 20 20 20  my<nData );.    
244a0 70 44 61 74 61 20 2b 3d 20 6e 2b 69 44 75 6d 6d  pData += n+iDumm
244b0 79 3b 0a 20 20 20 20 6e 44 61 74 61 20 2d 3d 20  y;.    nData -= 
244c0 6e 2b 69 44 75 6d 6d 79 3b 0a 0a 20 20 20 20 6e  n+iDummy;..    n
244d0 20 3d 20 66 74 73 33 47 65 74 56 61 72 69 6e 74   = fts3GetVarint
244e0 33 32 28 70 44 61 74 61 2c 20 26 69 44 75 6d 6d  32(pData, &iDumm
244f0 79 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  y);.    assert( 
24500 6e 3e 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72  n>0 );.    asser
24510 74 28 20 69 44 75 6d 6d 79 3e 30 20 29 3b 0a 20  t( iDummy>0 );. 
24520 20 20 20 61 73 73 65 72 74 28 20 6e 2b 69 44 75     assert( n+iDu
24530 6d 6d 79 3e 30 20 29 3b 0a 20 20 20 20 61 73 73  mmy>0 );.    ass
24540 65 72 74 28 20 6e 2b 69 44 75 6d 6d 79 3c 3d 6e  ert( n+iDummy<=n
24550 44 61 74 61 20 29 3b 0a 20 20 20 20 41 53 53 45  Data );.    ASSE
24560 52 54 5f 56 41 4c 49 44 5f 44 4f 43 4c 49 53 54  RT_VALID_DOCLIST
24570 28 44 4c 5f 44 45 46 41 55 4c 54 2c 20 70 44 61  (DL_DEFAULT, pDa
24580 74 61 2b 6e 2c 20 69 44 75 6d 6d 79 2c 20 4e 55  ta+n, iDummy, NU
24590 4c 4c 29 3b 0a 20 20 20 20 70 44 61 74 61 20 2b  LL);.    pData +
245a0 3d 20 6e 2b 69 44 75 6d 6d 79 3b 0a 20 20 20 20  = n+iDummy;.    
245b0 6e 44 61 74 61 20 2d 3d 20 6e 2b 69 44 75 6d 6d  nData -= n+iDumm
245c0 79 3b 0a 20 20 7d 0a 7d 0a 23 64 65 66 69 6e 65  y;.  }.}.#define
245d0 20 41 53 53 45 52 54 5f 56 41 4c 49 44 5f 4c 45   ASSERT_VALID_LE
245e0 41 46 5f 4e 4f 44 45 28 70 2c 20 6e 29 20 6c 65  AF_NODE(p, n) le
245f0 61 66 4e 6f 64 65 56 61 6c 69 64 61 74 65 28 70  afNodeValidate(p
24600 2c 20 6e 29 0a 23 65 6c 73 65 0a 23 64 65 66 69  , n).#else.#defi
24610 6e 65 20 41 53 53 45 52 54 5f 56 41 4c 49 44 5f  ne ASSERT_VALID_
24620 4c 45 41 46 5f 4e 4f 44 45 28 70 2c 20 6e 29 20  LEAF_NODE(p, n) 
24630 61 73 73 65 72 74 28 20 31 20 29 0a 23 65 6e 64  assert( 1 ).#end
24640 69 66 0a 0a 2f 2a 20 46 6c 75 73 68 20 74 68 65  if../* Flush the
24650 20 63 75 72 72 65 6e 74 20 6c 65 61 66 20 6e 6f   current leaf no
24660 64 65 20 74 6f 20 25 5f 73 65 67 6d 65 6e 74 73  de to %_segments
24670 2c 20 61 6e 64 20 61 64 64 69 6e 67 20 74 68 65  , and adding the
24680 20 72 65 73 75 6c 74 69 6e 67 0a 2a 2a 20 62 6c   resulting.** bl
24690 6f 63 6b 69 64 20 61 6e 64 20 74 68 65 20 73 74  ockid and the st
246a0 61 72 74 69 6e 67 20 74 65 72 6d 20 74 6f 20 74  arting term to t
246b0 68 65 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65  he interior node
246c0 20 77 68 69 63 68 20 77 69 6c 6c 0a 2a 2a 20 63   which will.** c
246d0 6f 6e 74 61 69 6e 20 69 74 2e 0a 2a 2f 0a 73 74  ontain it..*/.st
246e0 61 74 69 63 20 69 6e 74 20 6c 65 61 66 57 72 69  atic int leafWri
246f0 74 65 72 49 6e 74 65 72 6e 61 6c 46 6c 75 73 68  terInternalFlush
24700 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
24710 76 2c 20 4c 65 61 66 57 72 69 74 65 72 20 2a 70  v, LeafWriter *p
24720 57 72 69 74 65 72 2c 0a 20 20 20 20 20 20 20 20  Writer,.        
24730 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24740 20 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 69             int i
24750 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 29  Data, int nData)
24760 7b 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  {.  sqlite_int64
24770 20 69 42 6c 6f 63 6b 69 64 20 3d 20 30 3b 0a 20   iBlockid = 0;. 
24780 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 53 74   const char *pSt
24790 61 72 74 69 6e 67 54 65 72 6d 3b 0a 20 20 69 6e  artingTerm;.  in
247a0 74 20 6e 53 74 61 72 74 69 6e 67 54 65 72 6d 2c  t nStartingTerm,
247b0 20 72 63 2c 20 6e 3b 0a 0a 20 20 2f 2a 20 4d 75   rc, n;..  /* Mu
247c0 73 74 20 68 61 76 65 20 74 68 65 20 6c 65 61 64  st have the lead
247d0 69 6e 67 20 76 61 72 69 6e 74 28 30 29 20 66 6c  ing varint(0) fl
247e0 61 67 2c 20 70 6c 75 73 20 61 74 20 6c 65 61 73  ag, plus at leas
247f0 74 20 73 6f 6d 65 0a 20 20 2a 2a 20 76 61 6c 69  t some.  ** vali
24800 64 2d 6c 6f 6f 6b 69 6e 67 20 64 61 74 61 2e 0a  d-looking data..
24810 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 6e    */.  assert( n
24820 44 61 74 61 3e 32 20 29 3b 0a 20 20 61 73 73 65  Data>2 );.  asse
24830 72 74 28 20 69 44 61 74 61 3e 3d 30 20 29 3b 0a  rt( iData>=0 );.
24840 20 20 61 73 73 65 72 74 28 20 69 44 61 74 61 2b    assert( iData+
24850 6e 44 61 74 61 3c 3d 70 57 72 69 74 65 72 2d 3e  nData<=pWriter->
24860 64 61 74 61 2e 6e 44 61 74 61 20 29 3b 0a 20 20  data.nData );.  
24870 41 53 53 45 52 54 5f 56 41 4c 49 44 5f 4c 45 41  ASSERT_VALID_LEA
24880 46 5f 4e 4f 44 45 28 70 57 72 69 74 65 72 2d 3e  F_NODE(pWriter->
24890 64 61 74 61 2e 70 44 61 74 61 2b 69 44 61 74 61  data.pData+iData
248a0 2c 20 6e 44 61 74 61 29 3b 0a 0a 20 20 72 63 20  , nData);..  rc 
248b0 3d 20 62 6c 6f 63 6b 5f 69 6e 73 65 72 74 28 76  = block_insert(v
248c0 2c 20 70 57 72 69 74 65 72 2d 3e 64 61 74 61 2e  , pWriter->data.
248d0 70 44 61 74 61 2b 69 44 61 74 61 2c 20 6e 44 61  pData+iData, nDa
248e0 74 61 2c 20 26 69 42 6c 6f 63 6b 69 64 29 3b 0a  ta, &iBlockid);.
248f0 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
24900 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
24910 0a 20 20 61 73 73 65 72 74 28 20 69 42 6c 6f 63  .  assert( iBloc
24920 6b 69 64 21 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20  kid!=0 );..  /* 
24930 52 65 63 6f 6e 73 74 72 75 63 74 20 74 68 65 20  Reconstruct the 
24940 66 69 72 73 74 20 74 65 72 6d 20 69 6e 20 74 68  first term in th
24950 65 20 6c 65 61 66 20 66 6f 72 20 70 75 72 70 6f  e leaf for purpo
24960 73 65 73 20 6f 66 20 62 75 69 6c 64 69 6e 67 0a  ses of building.
24970 20 20 2a 2a 20 74 68 65 20 69 6e 74 65 72 69 6f    ** the interio
24980 72 20 6e 6f 64 65 2e 0a 20 20 2a 2f 0a 20 20 6e  r node..  */.  n
24990 20 3d 20 66 74 73 33 47 65 74 56 61 72 69 6e 74   = fts3GetVarint
249a0 33 32 28 70 57 72 69 74 65 72 2d 3e 64 61 74 61  32(pWriter->data
249b0 2e 70 44 61 74 61 2b 69 44 61 74 61 2b 31 2c 20  .pData+iData+1, 
249c0 26 6e 53 74 61 72 74 69 6e 67 54 65 72 6d 29 3b  &nStartingTerm);
249d0 0a 20 20 70 53 74 61 72 74 69 6e 67 54 65 72 6d  .  pStartingTerm
249e0 20 3d 20 70 57 72 69 74 65 72 2d 3e 64 61 74 61   = pWriter->data
249f0 2e 70 44 61 74 61 2b 69 44 61 74 61 2b 31 2b 6e  .pData+iData+1+n
24a00 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 72 69  ;.  assert( pWri
24a10 74 65 72 2d 3e 64 61 74 61 2e 6e 44 61 74 61 3e  ter->data.nData>
24a20 69 44 61 74 61 2b 31 2b 6e 2b 6e 53 74 61 72 74  iData+1+n+nStart
24a30 69 6e 67 54 65 72 6d 20 29 3b 0a 20 20 61 73 73  ingTerm );.  ass
24a40 65 72 74 28 20 70 57 72 69 74 65 72 2d 3e 6e 54  ert( pWriter->nT
24a50 65 72 6d 44 69 73 74 69 6e 63 74 3e 30 20 29 3b  ermDistinct>0 );
24a60 0a 20 20 61 73 73 65 72 74 28 20 70 57 72 69 74  .  assert( pWrit
24a70 65 72 2d 3e 6e 54 65 72 6d 44 69 73 74 69 6e 63  er->nTermDistinc
24a80 74 3c 3d 6e 53 74 61 72 74 69 6e 67 54 65 72 6d  t<=nStartingTerm
24a90 20 29 3b 0a 20 20 6e 53 74 61 72 74 69 6e 67 54   );.  nStartingT
24aa0 65 72 6d 20 3d 20 70 57 72 69 74 65 72 2d 3e 6e  erm = pWriter->n
24ab0 54 65 72 6d 44 69 73 74 69 6e 63 74 3b 0a 0a 20  TermDistinct;.. 
24ac0 20 69 66 28 20 70 57 72 69 74 65 72 2d 3e 68 61   if( pWriter->ha
24ad0 73 5f 70 61 72 65 6e 74 20 29 7b 0a 20 20 20 20  s_parent ){.    
24ae0 69 6e 74 65 72 69 6f 72 57 72 69 74 65 72 41 70  interiorWriterAp
24af0 70 65 6e 64 28 26 70 57 72 69 74 65 72 2d 3e 70  pend(&pWriter->p
24b00 61 72 65 6e 74 57 72 69 74 65 72 2c 0a 20 20 20  arentWriter,.   
24b10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24b20 20 20 20 20 20 20 70 53 74 61 72 74 69 6e 67 54        pStartingT
24b30 65 72 6d 2c 20 6e 53 74 61 72 74 69 6e 67 54 65  erm, nStartingTe
24b40 72 6d 2c 20 69 42 6c 6f 63 6b 69 64 29 3b 0a 20  rm, iBlockid);. 
24b50 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 65   }else{.    inte
24b60 72 69 6f 72 57 72 69 74 65 72 49 6e 69 74 28 31  riorWriterInit(1
24b70 2c 20 70 53 74 61 72 74 69 6e 67 54 65 72 6d 2c  , pStartingTerm,
24b80 20 6e 53 74 61 72 74 69 6e 67 54 65 72 6d 2c 20   nStartingTerm, 
24b90 69 42 6c 6f 63 6b 69 64 2c 0a 20 20 20 20 20 20  iBlockid,.      
24ba0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24bb0 20 26 70 57 72 69 74 65 72 2d 3e 70 61 72 65 6e   &pWriter->paren
24bc0 74 57 72 69 74 65 72 29 3b 0a 20 20 20 20 70 57  tWriter);.    pW
24bd0 72 69 74 65 72 2d 3e 68 61 73 5f 70 61 72 65 6e  riter->has_paren
24be0 74 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  t = 1;.  }..  /*
24bf0 20 54 72 61 63 6b 20 74 68 65 20 73 70 61 6e 20   Track the span 
24c00 6f 66 20 74 68 69 73 20 73 65 67 6d 65 6e 74 27  of this segment'
24c10 73 20 6c 65 61 66 20 6e 6f 64 65 73 2e 20 2a 2f  s leaf nodes. */
24c20 0a 20 20 69 66 28 20 70 57 72 69 74 65 72 2d 3e  .  if( pWriter->
24c30 69 45 6e 64 42 6c 6f 63 6b 69 64 3d 3d 30 20 29  iEndBlockid==0 )
24c40 7b 0a 20 20 20 20 70 57 72 69 74 65 72 2d 3e 69  {.    pWriter->i
24c50 45 6e 64 42 6c 6f 63 6b 69 64 20 3d 20 70 57 72  EndBlockid = pWr
24c60 69 74 65 72 2d 3e 69 53 74 61 72 74 42 6c 6f 63  iter->iStartBloc
24c70 6b 69 64 20 3d 20 69 42 6c 6f 63 6b 69 64 3b 0a  kid = iBlockid;.
24c80 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 57 72    }else{.    pWr
24c90 69 74 65 72 2d 3e 69 45 6e 64 42 6c 6f 63 6b 69  iter->iEndBlocki
24ca0 64 2b 2b 3b 0a 20 20 20 20 61 73 73 65 72 74 28  d++;.    assert(
24cb0 20 69 42 6c 6f 63 6b 69 64 3d 3d 70 57 72 69 74   iBlockid==pWrit
24cc0 65 72 2d 3e 69 45 6e 64 42 6c 6f 63 6b 69 64 20  er->iEndBlockid 
24cd0 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
24ce0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 73 74   SQLITE_OK;.}.st
24cf0 61 74 69 63 20 69 6e 74 20 6c 65 61 66 57 72 69  atic int leafWri
24d00 74 65 72 46 6c 75 73 68 28 66 75 6c 6c 74 65 78  terFlush(fulltex
24d10 74 5f 76 74 61 62 20 2a 76 2c 20 4c 65 61 66 57  t_vtab *v, LeafW
24d20 72 69 74 65 72 20 2a 70 57 72 69 74 65 72 29 7b  riter *pWriter){
24d30 0a 20 20 69 6e 74 20 72 63 20 3d 20 6c 65 61 66  .  int rc = leaf
24d40 57 72 69 74 65 72 49 6e 74 65 72 6e 61 6c 46 6c  WriterInternalFl
24d50 75 73 68 28 76 2c 20 70 57 72 69 74 65 72 2c 20  ush(v, pWriter, 
24d60 30 2c 20 70 57 72 69 74 65 72 2d 3e 64 61 74 61  0, pWriter->data
24d70 2e 6e 44 61 74 61 29 3b 0a 20 20 69 66 28 20 72  .nData);.  if( r
24d80 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
24d90 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 2f 2a 20  eturn rc;..  /* 
24da0 52 65 2d 69 6e 69 74 69 61 6c 69 7a 65 20 74 68  Re-initialize th
24db0 65 20 6f 75 74 70 75 74 20 62 75 66 66 65 72 2e  e output buffer.
24dc0 20 2a 2f 0a 20 20 64 61 74 61 42 75 66 66 65 72   */.  dataBuffer
24dd0 52 65 73 65 74 28 26 70 57 72 69 74 65 72 2d 3e  Reset(&pWriter->
24de0 64 61 74 61 29 3b 0a 0a 20 20 72 65 74 75 72 6e  data);..  return
24df0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
24e00 2a 20 46 65 74 63 68 20 74 68 65 20 72 6f 6f 74  * Fetch the root
24e10 20 69 6e 66 6f 20 66 6f 72 20 74 68 65 20 73 65   info for the se
24e20 67 6d 65 6e 74 2e 20 20 49 66 20 74 68 65 20 65  gment.  If the e
24e30 6e 74 69 72 65 20 6c 65 61 66 20 66 69 74 73 0a  ntire leaf fits.
24e40 2a 2a 20 77 69 74 68 69 6e 20 52 4f 4f 54 5f 4d  ** within ROOT_M
24e50 41 58 2c 20 74 68 65 6e 20 69 74 20 77 69 6c 6c  AX, then it will
24e60 20 62 65 20 72 65 74 75 72 6e 65 64 20 64 69 72   be returned dir
24e70 65 63 74 6c 79 2c 20 6f 74 68 65 72 77 69 73 65  ectly, otherwise
24e80 20 69 74 0a 2a 2a 20 77 69 6c 6c 20 62 65 20 66   it.** will be f
24e90 6c 75 73 68 65 64 20 61 6e 64 20 74 68 65 20 72  lushed and the r
24ea0 6f 6f 74 20 69 6e 66 6f 20 77 69 6c 6c 20 62 65  oot info will be
24eb0 20 72 65 74 75 72 6e 65 64 20 66 72 6f 6d 20 74   returned from t
24ec0 68 65 0a 2a 2a 20 69 6e 74 65 72 69 6f 72 20 6e  he.** interior n
24ed0 6f 64 65 2e 20 20 2a 70 69 45 6e 64 42 6c 6f 63  ode.  *piEndBloc
24ee0 6b 69 64 20 69 73 20 73 65 74 20 74 6f 20 74 68  kid is set to th
24ef0 65 20 62 6c 6f 63 6b 69 64 20 6f 66 20 74 68 65  e blockid of the
24f00 20 6c 61 73 74 0a 2a 2a 20 69 6e 74 65 72 69 6f   last.** interio
24f10 72 20 6f 72 20 6c 65 61 66 20 6e 6f 64 65 20 77  r or leaf node w
24f20 72 69 74 74 65 6e 20 74 6f 20 64 69 73 6b 20 28  ritten to disk (
24f30 30 20 69 66 20 6e 6f 6e 65 20 61 72 65 20 77 72  0 if none are wr
24f40 69 74 74 65 6e 20 61 74 0a 2a 2a 20 61 6c 6c 29  itten at.** all)
24f50 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
24f60 6c 65 61 66 57 72 69 74 65 72 52 6f 6f 74 49 6e  leafWriterRootIn
24f70 66 6f 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62  fo(fulltext_vtab
24f80 20 2a 76 2c 20 4c 65 61 66 57 72 69 74 65 72 20   *v, LeafWriter 
24f90 2a 70 57 72 69 74 65 72 2c 0a 20 20 20 20 20 20  *pWriter,.      
24fa0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24fb0 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 2a 70          char **p
24fc0 70 52 6f 6f 74 49 6e 66 6f 2c 20 69 6e 74 20 2a  pRootInfo, int *
24fd0 70 6e 52 6f 6f 74 49 6e 66 6f 2c 0a 20 20 20 20  pnRootInfo,.    
24fe0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
24ff0 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
25000 5f 69 6e 74 36 34 20 2a 70 69 45 6e 64 42 6c 6f  _int64 *piEndBlo
25010 63 6b 69 64 29 7b 0a 20 20 2f 2a 20 77 65 20 63  ckid){.  /* we c
25020 61 6e 20 66 69 74 20 74 68 65 20 73 65 67 6d 65  an fit the segme
25030 6e 74 20 65 6e 74 69 72 65 6c 79 20 69 6e 6c 69  nt entirely inli
25040 6e 65 20 2a 2f 0a 20 20 69 66 28 20 21 70 57 72  ne */.  if( !pWr
25050 69 74 65 72 2d 3e 68 61 73 5f 70 61 72 65 6e 74  iter->has_parent
25060 20 26 26 20 70 57 72 69 74 65 72 2d 3e 64 61 74   && pWriter->dat
25070 61 2e 6e 44 61 74 61 3c 52 4f 4f 54 5f 4d 41 58  a.nData<ROOT_MAX
25080 20 29 7b 0a 20 20 20 20 2a 70 70 52 6f 6f 74 49   ){.    *ppRootI
25090 6e 66 6f 20 3d 20 70 57 72 69 74 65 72 2d 3e 64  nfo = pWriter->d
250a0 61 74 61 2e 70 44 61 74 61 3b 0a 20 20 20 20 2a  ata.pData;.    *
250b0 70 6e 52 6f 6f 74 49 6e 66 6f 20 3d 20 70 57 72  pnRootInfo = pWr
250c0 69 74 65 72 2d 3e 64 61 74 61 2e 6e 44 61 74 61  iter->data.nData
250d0 3b 0a 20 20 20 20 2a 70 69 45 6e 64 42 6c 6f 63  ;.    *piEndBloc
250e0 6b 69 64 20 3d 20 30 3b 0a 20 20 20 20 72 65 74  kid = 0;.    ret
250f0 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  urn SQLITE_OK;. 
25100 20 7d 0a 0a 20 20 2f 2a 20 46 6c 75 73 68 20 72   }..  /* Flush r
25110 65 6d 61 69 6e 69 6e 67 20 6c 65 61 66 20 64 61  emaining leaf da
25120 74 61 2e 20 2a 2f 0a 20 20 69 66 28 20 70 57 72  ta. */.  if( pWr
25130 69 74 65 72 2d 3e 64 61 74 61 2e 6e 44 61 74 61  iter->data.nData
25140 3e 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63  >0 ){.    int rc
25150 20 3d 20 6c 65 61 66 57 72 69 74 65 72 46 6c 75   = leafWriterFlu
25160 73 68 28 76 2c 20 70 57 72 69 74 65 72 29 3b 0a  sh(v, pWriter);.
25170 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
25180 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
25190 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 57 65 20  c;.  }..  /* We 
251a0 6d 75 73 74 20 68 61 76 65 20 66 6c 75 73 68 65  must have flushe
251b0 64 20 61 20 6c 65 61 66 20 61 74 20 73 6f 6d 65  d a leaf at some
251c0 20 70 6f 69 6e 74 2e 20 2a 2f 0a 20 20 61 73 73   point. */.  ass
251d0 65 72 74 28 20 70 57 72 69 74 65 72 2d 3e 68 61  ert( pWriter->ha
251e0 73 5f 70 61 72 65 6e 74 20 29 3b 0a 0a 20 20 2f  s_parent );..  /
251f0 2a 20 54 65 6e 61 74 69 76 65 6c 79 20 73 65 74  * Tenatively set
25200 20 74 68 65 20 65 6e 64 20 6c 65 61 66 20 62 6c   the end leaf bl
25210 6f 63 6b 69 64 20 61 73 20 74 68 65 20 65 6e 64  ockid as the end
25220 20 62 6c 6f 63 6b 69 64 2e 20 20 49 66 20 74 68   blockid.  If th
25230 65 0a 20 20 2a 2a 20 69 6e 74 65 72 69 6f 72 20  e.  ** interior 
25240 6e 6f 64 65 20 63 61 6e 20 62 65 20 72 65 74 75  node can be retu
25250 72 6e 65 64 20 69 6e 6c 69 6e 65 2c 20 74 68 69  rned inline, thi
25260 73 20 77 69 6c 6c 20 62 65 20 74 68 65 20 66 69  s will be the fi
25270 6e 61 6c 0a 20 20 2a 2a 20 62 6c 6f 63 6b 69 64  nal.  ** blockid
25280 2c 20 6f 74 68 65 72 77 69 73 65 20 69 74 20 77  , otherwise it w
25290 69 6c 6c 20 62 65 20 6f 76 65 72 77 72 69 74 74  ill be overwritt
252a0 65 6e 20 62 79 0a 20 20 2a 2a 20 69 6e 74 65 72  en by.  ** inter
252b0 69 6f 72 57 72 69 74 65 72 52 6f 6f 74 49 6e 66  iorWriterRootInf
252c0 6f 28 29 2e 0a 20 20 2a 2f 0a 20 20 2a 70 69 45  o()..  */.  *piE
252d0 6e 64 42 6c 6f 63 6b 69 64 20 3d 20 70 57 72 69  ndBlockid = pWri
252e0 74 65 72 2d 3e 69 45 6e 64 42 6c 6f 63 6b 69 64  ter->iEndBlockid
252f0 3b 0a 0a 20 20 72 65 74 75 72 6e 20 69 6e 74 65  ;..  return inte
25300 72 69 6f 72 57 72 69 74 65 72 52 6f 6f 74 49 6e  riorWriterRootIn
25310 66 6f 28 76 2c 20 26 70 57 72 69 74 65 72 2d 3e  fo(v, &pWriter->
25320 70 61 72 65 6e 74 57 72 69 74 65 72 2c 0a 20 20  parentWriter,.  
25330 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25340 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 70                pp
25350 52 6f 6f 74 49 6e 66 6f 2c 20 70 6e 52 6f 6f 74  RootInfo, pnRoot
25360 49 6e 66 6f 2c 20 70 69 45 6e 64 42 6c 6f 63 6b  Info, piEndBlock
25370 69 64 29 3b 0a 7d 0a 0a 2f 2a 20 43 6f 6c 6c 65  id);.}../* Colle
25380 63 74 20 74 68 65 20 72 6f 6f 74 49 6e 66 6f 20  ct the rootInfo 
25390 64 61 74 61 20 61 6e 64 20 73 74 6f 72 65 20 69  data and store i
253a0 74 20 69 6e 74 6f 20 74 68 65 20 73 65 67 6d 65  t into the segme
253b0 6e 74 20 64 69 72 65 63 74 6f 72 79 2e 0a 2a 2a  nt directory..**
253c0 20 54 68 69 73 20 68 61 73 20 74 68 65 20 65 66   This has the ef
253d0 66 65 63 74 20 6f 66 20 66 6c 75 73 68 69 6e 67  fect of flushing
253e0 20 74 68 65 20 73 65 67 6d 65 6e 74 27 73 20 6c   the segment's l
253f0 65 61 66 20 64 61 74 61 20 74 6f 0a 2a 2a 20 25  eaf data to.** %
25400 5f 73 65 67 6d 65 6e 74 73 2c 20 61 6e 64 20 61  _segments, and a
25410 6c 73 6f 20 66 6c 75 73 68 69 6e 67 20 61 6e 79  lso flushing any
25420 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65 73 20   interior nodes 
25430 74 6f 20 25 5f 73 65 67 6d 65 6e 74 73 2e 0a 2a  to %_segments..*
25440 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6c 65 61  /.static int lea
25450 66 57 72 69 74 65 72 46 69 6e 61 6c 69 7a 65 28  fWriterFinalize(
25460 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
25470 2c 20 4c 65 61 66 57 72 69 74 65 72 20 2a 70 57  , LeafWriter *pW
25480 72 69 74 65 72 29 7b 0a 20 20 73 71 6c 69 74 65  riter){.  sqlite
25490 5f 69 6e 74 36 34 20 69 45 6e 64 42 6c 6f 63 6b  _int64 iEndBlock
254a0 69 64 3b 0a 20 20 63 68 61 72 20 2a 70 52 6f 6f  id;.  char *pRoo
254b0 74 49 6e 66 6f 3b 0a 20 20 69 6e 74 20 72 63 2c  tInfo;.  int rc,
254c0 20 6e 52 6f 6f 74 49 6e 66 6f 3b 0a 0a 20 20 72   nRootInfo;..  r
254d0 63 20 3d 20 6c 65 61 66 57 72 69 74 65 72 52 6f  c = leafWriterRo
254e0 6f 74 49 6e 66 6f 28 76 2c 20 70 57 72 69 74 65  otInfo(v, pWrite
254f0 72 2c 20 26 70 52 6f 6f 74 49 6e 66 6f 2c 20 26  r, &pRootInfo, &
25500 6e 52 6f 6f 74 49 6e 66 6f 2c 20 26 69 45 6e 64  nRootInfo, &iEnd
25510 42 6c 6f 63 6b 69 64 29 3b 0a 20 20 69 66 28 20  Blockid);.  if( 
25520 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
25530 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 2f 2a  return rc;..  /*
25540 20 44 6f 6e 27 74 20 62 6f 74 68 65 72 20 73 74   Don't bother st
25550 6f 72 69 6e 67 20 61 6e 20 65 6e 74 69 72 65 6c  oring an entirel
25560 79 20 65 6d 70 74 79 20 73 65 67 6d 65 6e 74 2e  y empty segment.
25570 20 2a 2f 0a 20 20 69 66 28 20 69 45 6e 64 42 6c   */.  if( iEndBl
25580 6f 63 6b 69 64 3d 3d 30 20 26 26 20 6e 52 6f 6f  ockid==0 && nRoo
25590 74 49 6e 66 6f 3d 3d 30 20 29 20 72 65 74 75 72  tInfo==0 ) retur
255a0 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  n SQLITE_OK;..  
255b0 72 65 74 75 72 6e 20 73 65 67 64 69 72 5f 73 65  return segdir_se
255c0 74 28 76 2c 20 70 57 72 69 74 65 72 2d 3e 69 4c  t(v, pWriter->iL
255d0 65 76 65 6c 2c 20 70 57 72 69 74 65 72 2d 3e 69  evel, pWriter->i
255e0 64 78 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  dx,.            
255f0 20 20 20 20 20 20 20 20 70 57 72 69 74 65 72 2d          pWriter-
25600 3e 69 53 74 61 72 74 42 6c 6f 63 6b 69 64 2c 20  >iStartBlockid, 
25610 70 57 72 69 74 65 72 2d 3e 69 45 6e 64 42 6c 6f  pWriter->iEndBlo
25620 63 6b 69 64 2c 0a 20 20 20 20 20 20 20 20 20 20  ckid,.          
25630 20 20 20 20 20 20 20 20 20 20 69 45 6e 64 42 6c            iEndBl
25640 6f 63 6b 69 64 2c 20 70 52 6f 6f 74 49 6e 66 6f  ockid, pRootInfo
25650 2c 20 6e 52 6f 6f 74 49 6e 66 6f 29 3b 0a 7d 0a  , nRootInfo);.}.
25660 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6c 65 61  .static void lea
25670 66 57 72 69 74 65 72 44 65 73 74 72 6f 79 28 4c  fWriterDestroy(L
25680 65 61 66 57 72 69 74 65 72 20 2a 70 57 72 69 74  eafWriter *pWrit
25690 65 72 29 7b 0a 20 20 69 66 28 20 70 57 72 69 74  er){.  if( pWrit
256a0 65 72 2d 3e 68 61 73 5f 70 61 72 65 6e 74 20 29  er->has_parent )
256b0 20 69 6e 74 65 72 69 6f 72 57 72 69 74 65 72 44   interiorWriterD
256c0 65 73 74 72 6f 79 28 26 70 57 72 69 74 65 72 2d  estroy(&pWriter-
256d0 3e 70 61 72 65 6e 74 57 72 69 74 65 72 29 3b 0a  >parentWriter);.
256e0 20 20 64 61 74 61 42 75 66 66 65 72 44 65 73 74    dataBufferDest
256f0 72 6f 79 28 26 70 57 72 69 74 65 72 2d 3e 74 65  roy(&pWriter->te
25700 72 6d 29 3b 0a 20 20 64 61 74 61 42 75 66 66 65  rm);.  dataBuffe
25710 72 44 65 73 74 72 6f 79 28 26 70 57 72 69 74 65  rDestroy(&pWrite
25720 72 2d 3e 64 61 74 61 29 3b 0a 7d 0a 0a 2f 2a 20  r->data);.}../* 
25730 45 6e 63 6f 64 65 20 61 20 74 65 72 6d 20 69 6e  Encode a term in
25740 74 6f 20 74 68 65 20 6c 65 61 66 57 72 69 74 65  to the leafWrite
25750 72 2c 20 64 65 6c 74 61 2d 65 6e 63 6f 64 69 6e  r, delta-encodin
25760 67 20 61 73 20 61 70 70 72 6f 70 72 69 61 74 65  g as appropriate
25770 2e 0a 2a 2a 20 52 65 74 75 72 6e 73 20 74 68 65  ..** Returns the
25780 20 6c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 6e   length of the n
25790 65 77 20 74 65 72 6d 20 77 68 69 63 68 20 64 69  ew term which di
257a0 73 74 69 6e 67 75 69 73 68 65 73 20 69 74 20 66  stinguishes it f
257b0 72 6f 6d 20 74 68 65 0a 2a 2a 20 70 72 65 76 69  rom the.** previ
257c0 6f 75 73 20 74 65 72 6d 2c 20 77 68 69 63 68 20  ous term, which 
257d0 63 61 6e 20 62 65 20 75 73 65 64 20 74 6f 20 73  can be used to s
257e0 65 74 20 6e 54 65 72 6d 44 69 73 74 69 6e 63 74  et nTermDistinct
257f0 20 77 68 65 6e 20 61 20 6e 6f 64 65 0a 2a 2a 20   when a node.** 
25800 62 6f 75 6e 64 61 72 79 20 69 73 20 63 72 6f 73  boundary is cros
25810 73 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  sed..*/.static i
25820 6e 74 20 6c 65 61 66 57 72 69 74 65 72 45 6e 63  nt leafWriterEnc
25830 6f 64 65 54 65 72 6d 28 4c 65 61 66 57 72 69 74  odeTerm(LeafWrit
25840 65 72 20 2a 70 57 72 69 74 65 72 2c 0a 20 20 20  er *pWriter,.   
25850 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25860 20 20 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e               con
25870 73 74 20 63 68 61 72 20 2a 70 54 65 72 6d 2c 20  st char *pTerm, 
25880 69 6e 74 20 6e 54 65 72 6d 29 7b 0a 20 20 63 68  int nTerm){.  ch
25890 61 72 20 63 5b 56 41 52 49 4e 54 5f 4d 41 58 2b  ar c[VARINT_MAX+
258a0 56 41 52 49 4e 54 5f 4d 41 58 5d 3b 0a 20 20 69  VARINT_MAX];.  i
258b0 6e 74 20 6e 2c 20 6e 50 72 65 66 69 78 20 3d 20  nt n, nPrefix = 
258c0 30 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 54  0;..  assert( nT
258d0 65 72 6d 3e 30 20 29 3b 0a 20 20 77 68 69 6c 65  erm>0 );.  while
258e0 28 20 6e 50 72 65 66 69 78 3c 70 57 72 69 74 65  ( nPrefix<pWrite
258f0 72 2d 3e 74 65 72 6d 2e 6e 44 61 74 61 20 26 26  r->term.nData &&
25900 0a 20 20 20 20 20 20 20 20 20 70 54 65 72 6d 5b  .         pTerm[
25910 6e 50 72 65 66 69 78 5d 3d 3d 70 57 72 69 74 65  nPrefix]==pWrite
25920 72 2d 3e 74 65 72 6d 2e 70 44 61 74 61 5b 6e 50  r->term.pData[nP
25930 72 65 66 69 78 5d 20 29 7b 0a 20 20 20 20 6e 50  refix] ){.    nP
25940 72 65 66 69 78 2b 2b 3b 0a 20 20 20 20 2f 2a 20  refix++;.    /* 
25950 46 61 69 6c 69 6e 67 20 74 68 69 73 20 69 6d 70  Failing this imp
25960 6c 69 65 73 20 74 68 61 74 20 74 68 65 20 74 65  lies that the te
25970 72 6d 73 20 77 65 72 65 6e 27 74 20 69 6e 20 6f  rms weren't in o
25980 72 64 65 72 2e 20 2a 2f 0a 20 20 20 20 61 73 73  rder. */.    ass
25990 65 72 74 28 20 6e 50 72 65 66 69 78 3c 6e 54 65  ert( nPrefix<nTe
259a0 72 6d 20 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  rm );.  }..  if(
259b0 20 70 57 72 69 74 65 72 2d 3e 64 61 74 61 2e 6e   pWriter->data.n
259c0 44 61 74 61 3d 3d 30 20 29 7b 0a 20 20 20 20 2f  Data==0 ){.    /
259d0 2a 20 45 6e 63 6f 64 65 20 74 68 65 20 6e 6f 64  * Encode the nod
259e0 65 20 68 65 61 64 65 72 20 61 6e 64 20 6c 65 61  e header and lea
259f0 64 69 6e 67 20 74 65 72 6d 20 61 73 3a 0a 20 20  ding term as:.  
25a00 20 20 2a 2a 20 20 76 61 72 69 6e 74 28 30 29 0a    **  varint(0).
25a10 20 20 20 20 2a 2a 20 20 76 61 72 69 6e 74 28 6e      **  varint(n
25a20 54 65 72 6d 29 0a 20 20 20 20 2a 2a 20 20 63 68  Term).    **  ch
25a30 61 72 20 70 54 65 72 6d 5b 6e 54 65 72 6d 5d 0a  ar pTerm[nTerm].
25a40 20 20 20 20 2a 2f 0a 20 20 20 20 6e 20 3d 20 66      */.    n = f
25a50 74 73 33 50 75 74 56 61 72 69 6e 74 28 63 2c 20  ts3PutVarint(c, 
25a60 27 5c 30 27 29 3b 0a 20 20 20 20 6e 20 2b 3d 20  '\0');.    n += 
25a70 66 74 73 33 50 75 74 56 61 72 69 6e 74 28 63 2b  fts3PutVarint(c+
25a80 6e 2c 20 6e 54 65 72 6d 29 3b 0a 20 20 20 20 64  n, nTerm);.    d
25a90 61 74 61 42 75 66 66 65 72 41 70 70 65 6e 64 32  ataBufferAppend2
25aa0 28 26 70 57 72 69 74 65 72 2d 3e 64 61 74 61 2c  (&pWriter->data,
25ab0 20 63 2c 20 6e 2c 20 70 54 65 72 6d 2c 20 6e 54   c, n, pTerm, nT
25ac0 65 72 6d 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  erm);.  }else{. 
25ad0 20 20 20 2f 2a 20 44 65 6c 74 61 2d 65 6e 63 6f     /* Delta-enco
25ae0 64 65 20 74 68 65 20 74 65 72 6d 20 61 73 3a 0a  de the term as:.
25af0 20 20 20 20 2a 2a 20 20 76 61 72 69 6e 74 28 6e      **  varint(n
25b00 50 72 65 66 69 78 29 0a 20 20 20 20 2a 2a 20 20  Prefix).    **  
25b10 76 61 72 69 6e 74 28 6e 53 75 66 66 69 78 29 0a  varint(nSuffix).
25b20 20 20 20 20 2a 2a 20 20 63 68 61 72 20 70 54 65      **  char pTe
25b30 72 6d 53 75 66 66 69 78 5b 6e 53 75 66 66 69 78  rmSuffix[nSuffix
25b40 5d 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6e 20 3d  ].    */.    n =
25b50 20 66 74 73 33 50 75 74 56 61 72 69 6e 74 28 63   fts3PutVarint(c
25b60 2c 20 6e 50 72 65 66 69 78 29 3b 0a 20 20 20 20  , nPrefix);.    
25b70 6e 20 2b 3d 20 66 74 73 33 50 75 74 56 61 72 69  n += fts3PutVari
25b80 6e 74 28 63 2b 6e 2c 20 6e 54 65 72 6d 2d 6e 50  nt(c+n, nTerm-nP
25b90 72 65 66 69 78 29 3b 0a 20 20 20 20 64 61 74 61  refix);.    data
25ba0 42 75 66 66 65 72 41 70 70 65 6e 64 32 28 26 70  BufferAppend2(&p
25bb0 57 72 69 74 65 72 2d 3e 64 61 74 61 2c 20 63 2c  Writer->data, c,
25bc0 20 6e 2c 20 70 54 65 72 6d 2b 6e 50 72 65 66 69   n, pTerm+nPrefi
25bd0 78 2c 20 6e 54 65 72 6d 2d 6e 50 72 65 66 69 78  x, nTerm-nPrefix
25be0 29 3b 0a 20 20 7d 0a 20 20 64 61 74 61 42 75 66  );.  }.  dataBuf
25bf0 66 65 72 52 65 70 6c 61 63 65 28 26 70 57 72 69  ferReplace(&pWri
25c00 74 65 72 2d 3e 74 65 72 6d 2c 20 70 54 65 72 6d  ter->term, pTerm
25c10 2c 20 6e 54 65 72 6d 29 3b 0a 0a 20 20 72 65 74  , nTerm);..  ret
25c20 75 72 6e 20 6e 50 72 65 66 69 78 2b 31 3b 0a 7d  urn nPrefix+1;.}
25c30 0a 0a 2f 2a 20 55 73 65 64 20 74 6f 20 61 76 6f  ../* Used to avo
25c40 69 64 20 61 20 6d 65 6d 6d 6f 76 65 20 77 68 65  id a memmove whe
25c50 6e 20 61 20 6c 61 72 67 65 20 61 6d 6f 75 6e 74  n a large amount
25c60 20 6f 66 20 64 6f 63 6c 69 73 74 20 64 61 74 61   of doclist data
25c70 20 69 73 20 69 6e 0a 2a 2a 20 74 68 65 20 62 75   is in.** the bu
25c80 66 66 65 72 2e 20 20 54 68 69 73 20 63 6f 6e 73  ffer.  This cons
25c90 74 72 75 63 74 73 20 61 20 6e 6f 64 65 20 61 6e  tructs a node an
25ca0 64 20 74 65 72 6d 20 68 65 61 64 65 72 20 62 65  d term header be
25cb0 66 6f 72 65 0a 2a 2a 20 69 44 6f 63 6c 69 73 74  fore.** iDoclist
25cc0 44 61 74 61 20 61 6e 64 20 66 6c 75 73 68 65 73  Data and flushes
25cd0 20 74 68 65 20 72 65 73 75 6c 74 69 6e 67 20 63   the resulting c
25ce0 6f 6d 70 6c 65 74 65 20 6e 6f 64 65 20 75 73 69  omplete node usi
25cf0 6e 67 0a 2a 2a 20 6c 65 61 66 57 72 69 74 65 72  ng.** leafWriter
25d00 49 6e 74 65 72 6e 61 6c 46 6c 75 73 68 28 29 2e  InternalFlush().
25d10 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6c  .*/.static int l
25d20 65 61 66 57 72 69 74 65 72 49 6e 6c 69 6e 65 46  eafWriterInlineF
25d30 6c 75 73 68 28 66 75 6c 6c 74 65 78 74 5f 76 74  lush(fulltext_vt
25d40 61 62 20 2a 76 2c 20 4c 65 61 66 57 72 69 74 65  ab *v, LeafWrite
25d50 72 20 2a 70 57 72 69 74 65 72 2c 0a 20 20 20 20  r *pWriter,.    
25d60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25d70 20 20 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e               con
25d80 73 74 20 63 68 61 72 20 2a 70 54 65 72 6d 2c 20  st char *pTerm, 
25d90 69 6e 74 20 6e 54 65 72 6d 2c 0a 20 20 20 20 20  int nTerm,.     
25da0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25db0 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74 20              int 
25dc0 69 44 6f 63 6c 69 73 74 44 61 74 61 29 7b 0a 20  iDoclistData){. 
25dd0 20 63 68 61 72 20 63 5b 56 41 52 49 4e 54 5f 4d   char c[VARINT_M
25de0 41 58 2b 56 41 52 49 4e 54 5f 4d 41 58 5d 3b 0a  AX+VARINT_MAX];.
25df0 20 20 69 6e 74 20 69 44 61 74 61 2c 20 6e 20 3d    int iData, n =
25e00 20 66 74 73 33 50 75 74 56 61 72 69 6e 74 28 63   fts3PutVarint(c
25e10 2c 20 30 29 3b 0a 20 20 6e 20 2b 3d 20 66 74 73  , 0);.  n += fts
25e20 33 50 75 74 56 61 72 69 6e 74 28 63 2b 6e 2c 20  3PutVarint(c+n, 
25e30 6e 54 65 72 6d 29 3b 0a 0a 20 20 2f 2a 20 54 68  nTerm);..  /* Th
25e40 65 72 65 20 73 68 6f 75 6c 64 20 61 6c 77 61 79  ere should alway
25e50 73 20 62 65 20 72 6f 6f 6d 20 66 6f 72 20 74 68  s be room for th
25e60 65 20 68 65 61 64 65 72 2e 20 20 45 76 65 6e 20  e header.  Even 
25e70 69 66 20 70 54 65 72 6d 20 73 68 61 72 65 64 0a  if pTerm shared.
25e80 20 20 2a 2a 20 61 20 73 75 62 73 74 61 6e 74 69    ** a substanti
25e90 61 6c 20 70 72 65 66 69 78 20 77 69 74 68 20 74  al prefix with t
25ea0 68 65 20 70 72 65 76 69 6f 75 73 20 74 65 72 6d  he previous term
25eb0 2c 20 74 68 65 20 65 6e 74 69 72 65 20 70 72 65  , the entire pre
25ec0 66 69 78 0a 20 20 2a 2a 20 63 6f 75 6c 64 20 62  fix.  ** could b
25ed0 65 20 63 6f 6e 73 74 72 75 63 74 65 64 20 66 72  e constructed fr
25ee0 6f 6d 20 65 61 72 6c 69 65 72 20 64 61 74 61 20  om earlier data 
25ef0 69 6e 20 74 68 65 20 64 6f 63 6c 69 73 74 2c 20  in the doclist, 
25f00 73 6f 20 74 68 65 72 65 0a 20 20 2a 2a 20 73 68  so there.  ** sh
25f10 6f 75 6c 64 20 62 65 20 72 6f 6f 6d 2e 0a 20 20  ould be room..  
25f20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 69 44 6f  */.  assert( iDo
25f30 63 6c 69 73 74 44 61 74 61 3e 3d 6e 2b 6e 54 65  clistData>=n+nTe
25f40 72 6d 20 29 3b 0a 0a 20 20 69 44 61 74 61 20 3d  rm );..  iData =
25f50 20 69 44 6f 63 6c 69 73 74 44 61 74 61 2d 28 6e   iDoclistData-(n
25f60 2b 6e 54 65 72 6d 29 3b 0a 20 20 6d 65 6d 63 70  +nTerm);.  memcp
25f70 79 28 70 57 72 69 74 65 72 2d 3e 64 61 74 61 2e  y(pWriter->data.
25f80 70 44 61 74 61 2b 69 44 61 74 61 2c 20 63 2c 20  pData+iData, c, 
25f90 6e 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70 57 72  n);.  memcpy(pWr
25fa0 69 74 65 72 2d 3e 64 61 74 61 2e 70 44 61 74 61  iter->data.pData
25fb0 2b 69 44 61 74 61 2b 6e 2c 20 70 54 65 72 6d 2c  +iData+n, pTerm,
25fc0 20 6e 54 65 72 6d 29 3b 0a 0a 20 20 72 65 74 75   nTerm);..  retu
25fd0 72 6e 20 6c 65 61 66 57 72 69 74 65 72 49 6e 74  rn leafWriterInt
25fe0 65 72 6e 61 6c 46 6c 75 73 68 28 76 2c 20 70 57  ernalFlush(v, pW
25ff0 72 69 74 65 72 2c 20 69 44 61 74 61 2c 20 70 57  riter, iData, pW
26000 72 69 74 65 72 2d 3e 64 61 74 61 2e 6e 44 61 74  riter->data.nDat
26010 61 2d 69 44 61 74 61 29 3b 0a 7d 0a 0a 2f 2a 20  a-iData);.}../* 
26020 50 75 73 68 20 70 54 65 72 6d 5b 6e 54 65 72 6d  Push pTerm[nTerm
26030 5d 20 61 6c 6f 6e 67 20 77 69 74 68 20 74 68 65  ] along with the
26040 20 64 6f 63 6c 69 73 74 20 64 61 74 61 20 74 6f   doclist data to
26050 20 74 68 65 20 6c 65 61 66 20 6c 61 79 65 72 20   the leaf layer 
26060 6f 66 0a 2a 2a 20 25 5f 73 65 67 6d 65 6e 74 73  of.** %_segments
26070 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
26080 6c 65 61 66 57 72 69 74 65 72 53 74 65 70 4d 65  leafWriterStepMe
26090 72 67 65 28 66 75 6c 6c 74 65 78 74 5f 76 74 61  rge(fulltext_vta
260a0 62 20 2a 76 2c 20 4c 65 61 66 57 72 69 74 65 72  b *v, LeafWriter
260b0 20 2a 70 57 72 69 74 65 72 2c 0a 20 20 20 20 20   *pWriter,.     
260c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
260d0 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20            const 
260e0 63 68 61 72 20 2a 70 54 65 72 6d 2c 20 69 6e 74  char *pTerm, int
260f0 20 6e 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20   nTerm,.        
26100 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26110 20 20 20 20 20 20 20 44 4c 52 65 61 64 65 72 20         DLReader 
26120 2a 70 52 65 61 64 65 72 73 2c 20 69 6e 74 20 6e  *pReaders, int n
26130 52 65 61 64 65 72 73 29 7b 0a 20 20 63 68 61 72  Readers){.  char
26140 20 63 5b 56 41 52 49 4e 54 5f 4d 41 58 2b 56 41   c[VARINT_MAX+VA
26150 52 49 4e 54 5f 4d 41 58 5d 3b 0a 20 20 69 6e 74  RINT_MAX];.  int
26160 20 69 54 65 72 6d 44 61 74 61 20 3d 20 70 57 72   iTermData = pWr
26170 69 74 65 72 2d 3e 64 61 74 61 2e 6e 44 61 74 61  iter->data.nData
26180 2c 20 69 44 6f 63 6c 69 73 74 44 61 74 61 3b 0a  , iDoclistData;.
26190 20 20 69 6e 74 20 69 2c 20 6e 44 61 74 61 2c 20    int i, nData, 
261a0 6e 2c 20 6e 41 63 74 75 61 6c 44 61 74 61 2c 20  n, nActualData, 
261b0 6e 41 63 74 75 61 6c 2c 20 72 63 2c 20 6e 54 65  nActual, rc, nTe
261c0 72 6d 44 69 73 74 69 6e 63 74 3b 0a 0a 20 20 41  rmDistinct;..  A
261d0 53 53 45 52 54 5f 56 41 4c 49 44 5f 4c 45 41 46  SSERT_VALID_LEAF
261e0 5f 4e 4f 44 45 28 70 57 72 69 74 65 72 2d 3e 64  _NODE(pWriter->d
261f0 61 74 61 2e 70 44 61 74 61 2c 20 70 57 72 69 74  ata.pData, pWrit
26200 65 72 2d 3e 64 61 74 61 2e 6e 44 61 74 61 29 3b  er->data.nData);
26210 0a 20 20 6e 54 65 72 6d 44 69 73 74 69 6e 63 74  .  nTermDistinct
26220 20 3d 20 6c 65 61 66 57 72 69 74 65 72 45 6e 63   = leafWriterEnc
26230 6f 64 65 54 65 72 6d 28 70 57 72 69 74 65 72 2c  odeTerm(pWriter,
26240 20 70 54 65 72 6d 2c 20 6e 54 65 72 6d 29 3b 0a   pTerm, nTerm);.
26250 0a 20 20 2f 2a 20 52 65 6d 65 6d 62 65 72 20 6e  .  /* Remember n
26260 54 65 72 6d 44 69 73 74 69 6e 63 74 20 69 66 20  TermDistinct if 
26270 6f 70 65 6e 69 6e 67 20 61 20 6e 65 77 20 6e 6f  opening a new no
26280 64 65 2e 20 2a 2f 0a 20 20 69 66 28 20 69 54 65  de. */.  if( iTe
26290 72 6d 44 61 74 61 3d 3d 30 20 29 20 70 57 72 69  rmData==0 ) pWri
262a0 74 65 72 2d 3e 6e 54 65 72 6d 44 69 73 74 69 6e  ter->nTermDistin
262b0 63 74 20 3d 20 6e 54 65 72 6d 44 69 73 74 69 6e  ct = nTermDistin
262c0 63 74 3b 0a 0a 20 20 69 44 6f 63 6c 69 73 74 44  ct;..  iDoclistD
262d0 61 74 61 20 3d 20 70 57 72 69 74 65 72 2d 3e 64  ata = pWriter->d
262e0 61 74 61 2e 6e 44 61 74 61 3b 0a 0a 20 20 2f 2a  ata.nData;..  /*
262f0 20 45 73 74 69 6d 61 74 65 20 74 68 65 20 6c 65   Estimate the le
26300 6e 67 74 68 20 6f 66 20 74 68 65 20 6d 65 72 67  ngth of the merg
26310 65 64 20 64 6f 63 6c 69 73 74 20 73 6f 20 77 65  ed doclist so we
26320 20 63 61 6e 20 6c 65 61 76 65 20 73 70 61 63 65   can leave space
26330 0a 20 20 2a 2a 20 74 6f 20 65 6e 63 6f 64 65 20  .  ** to encode 
26340 69 74 2e 0a 20 20 2a 2f 0a 20 20 66 6f 72 28 69  it..  */.  for(i
26350 3d 30 2c 20 6e 44 61 74 61 3d 30 3b 20 69 3c 6e  =0, nData=0; i<n
26360 52 65 61 64 65 72 73 3b 20 69 2b 2b 29 7b 0a 20  Readers; i++){. 
26370 20 20 20 6e 44 61 74 61 20 2b 3d 20 64 6c 72 41     nData += dlrA
26380 6c 6c 44 61 74 61 42 79 74 65 73 28 26 70 52 65  llDataBytes(&pRe
26390 61 64 65 72 73 5b 69 5d 29 3b 0a 20 20 7d 0a 20  aders[i]);.  }. 
263a0 20 6e 20 3d 20 66 74 73 33 50 75 74 56 61 72 69   n = fts3PutVari
263b0 6e 74 28 63 2c 20 6e 44 61 74 61 29 3b 0a 20 20  nt(c, nData);.  
263c0 64 61 74 61 42 75 66 66 65 72 41 70 70 65 6e 64  dataBufferAppend
263d0 28 26 70 57 72 69 74 65 72 2d 3e 64 61 74 61 2c  (&pWriter->data,
263e0 20 63 2c 20 6e 29 3b 0a 0a 20 20 64 6f 63 4c 69   c, n);..  docLi
263f0 73 74 4d 65 72 67 65 28 26 70 57 72 69 74 65 72  stMerge(&pWriter
26400 2d 3e 64 61 74 61 2c 20 70 52 65 61 64 65 72 73  ->data, pReaders
26410 2c 20 6e 52 65 61 64 65 72 73 29 3b 0a 20 20 41  , nReaders);.  A
26420 53 53 45 52 54 5f 56 41 4c 49 44 5f 44 4f 43 4c  SSERT_VALID_DOCL
26430 49 53 54 28 44 4c 5f 44 45 46 41 55 4c 54 2c 0a  IST(DL_DEFAULT,.
26440 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26450 20 20 20 20 20 20 20 70 57 72 69 74 65 72 2d 3e         pWriter->
26460 64 61 74 61 2e 70 44 61 74 61 2b 69 44 6f 63 6c  data.pData+iDocl
26470 69 73 74 44 61 74 61 2b 6e 2c 0a 20 20 20 20 20  istData+n,.     
26480 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26490 20 20 70 57 72 69 74 65 72 2d 3e 64 61 74 61 2e    pWriter->data.
264a0 6e 44 61 74 61 2d 69 44 6f 63 6c 69 73 74 44 61  nData-iDoclistDa
264b0 74 61 2d 6e 2c 20 4e 55 4c 4c 29 3b 0a 0a 20 20  ta-n, NULL);..  
264c0 2f 2a 20 54 68 65 20 61 63 74 75 61 6c 20 61 6d  /* The actual am
264d0 6f 75 6e 74 20 6f 66 20 64 6f 63 6c 69 73 74 20  ount of doclist 
264e0 64 61 74 61 20 61 74 20 74 68 69 73 20 70 6f 69  data at this poi
264f0 6e 74 20 63 6f 75 6c 64 20 62 65 20 73 6d 61 6c  nt could be smal
26500 6c 65 72 0a 20 20 2a 2a 20 74 68 61 6e 20 74 68  ler.  ** than th
26510 65 20 6c 65 6e 67 74 68 20 77 65 20 65 6e 63 6f  e length we enco
26520 64 65 64 2e 20 20 41 64 64 69 74 69 6f 6e 61 6c  ded.  Additional
26530 6c 79 2c 20 74 68 65 20 73 70 61 63 65 20 72 65  ly, the space re
26540 71 75 69 72 65 64 20 74 6f 0a 20 20 2a 2a 20 65  quired to.  ** e
26550 6e 63 6f 64 65 20 74 68 69 73 20 6c 65 6e 67 74  ncode this lengt
26560 68 20 63 6f 75 6c 64 20 62 65 20 73 6d 61 6c 6c  h could be small
26570 65 72 2e 20 20 46 6f 72 20 73 6d 61 6c 6c 20 64  er.  For small d
26580 6f 63 6c 69 73 74 73 2c 20 74 68 69 73 20 69 73  oclists, this is
26590 0a 20 20 2a 2a 20 6e 6f 74 20 61 20 62 69 67 20  .  ** not a big 
265a0 64 65 61 6c 2c 20 77 65 20 63 61 6e 20 6a 75 73  deal, we can jus
265b0 74 20 75 73 65 20 6d 65 6d 6d 6f 76 65 28 29 20  t use memmove() 
265c0 74 6f 20 61 64 6a 75 73 74 20 74 68 69 6e 67 73  to adjust things
265d0 2e 0a 20 20 2a 2f 0a 20 20 6e 41 63 74 75 61 6c  ..  */.  nActual
265e0 44 61 74 61 20 3d 20 70 57 72 69 74 65 72 2d 3e  Data = pWriter->
265f0 64 61 74 61 2e 6e 44 61 74 61 2d 28 69 44 6f 63  data.nData-(iDoc
26600 6c 69 73 74 44 61 74 61 2b 6e 29 3b 0a 20 20 6e  listData+n);.  n
26610 41 63 74 75 61 6c 20 3d 20 66 74 73 33 50 75 74  Actual = fts3Put
26620 56 61 72 69 6e 74 28 63 2c 20 6e 41 63 74 75 61  Varint(c, nActua
26630 6c 44 61 74 61 29 3b 0a 20 20 61 73 73 65 72 74  lData);.  assert
26640 28 20 6e 41 63 74 75 61 6c 44 61 74 61 3c 3d 6e  ( nActualData<=n
26650 44 61 74 61 20 29 3b 0a 20 20 61 73 73 65 72 74  Data );.  assert
26660 28 20 6e 41 63 74 75 61 6c 3c 3d 6e 20 29 3b 0a  ( nActual<=n );.
26670 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 6e 65 77  .  /* If the new
26680 20 64 6f 63 6c 69 73 74 20 69 73 20 62 69 67 20   doclist is big 
26690 65 6e 6f 75 67 68 20 66 6f 72 20 66 6f 72 63 65  enough for force
266a0 20 61 20 73 74 61 6e 64 61 6c 6f 6e 65 20 6c 65   a standalone le
266b0 61 66 0a 20 20 2a 2a 20 6e 6f 64 65 2c 20 77 65  af.  ** node, we
266c0 20 63 61 6e 20 69 6d 6d 65 64 69 61 74 65 6c 79   can immediately
266d0 20 66 6c 75 73 68 20 69 74 20 69 6e 6c 69 6e 65   flush it inline
266e0 20 77 69 74 68 6f 75 74 20 64 6f 69 6e 67 20 74   without doing t
266f0 68 65 0a 20 20 2a 2a 20 6d 65 6d 6d 6f 76 65 28  he.  ** memmove(
26700 29 2e 0a 20 20 2a 2f 0a 20 20 2f 2a 20 54 4f 44  )..  */.  /* TOD
26710 4f 28 73 68 65 73 73 29 20 54 68 69 73 20 74 65  O(shess) This te
26720 73 74 20 6d 61 74 63 68 65 73 20 6c 65 61 66 57  st matches leafW
26730 72 69 74 65 72 53 74 65 70 28 29 2c 20 77 68 69  riterStep(), whi
26740 63 68 20 64 6f 65 73 20 74 68 69 73 0a 20 20 2a  ch does this.  *
26750 2a 20 74 65 73 74 20 62 65 66 6f 72 65 20 69 74  * test before it
26760 20 6b 6e 6f 77 73 20 74 68 65 20 63 6f 73 74 20   knows the cost 
26770 74 6f 20 76 61 72 69 6e 74 2d 65 6e 63 6f 64 65  to varint-encode
26780 20 74 68 65 20 74 65 72 6d 20 61 6e 64 0a 20 20   the term and.  
26790 2a 2a 20 64 6f 63 6c 69 73 74 20 6c 65 6e 67 74  ** doclist lengt
267a0 68 73 2e 20 20 41 74 20 73 6f 6d 65 20 70 6f 69  hs.  At some poi
267b0 6e 74 2c 20 63 68 61 6e 67 65 20 74 6f 0a 20 20  nt, change to.  
267c0 2a 2a 20 70 57 72 69 74 65 72 2d 3e 64 61 74 61  ** pWriter->data
267d0 2e 6e 44 61 74 61 2d 69 54 65 72 6d 44 61 74 61  .nData-iTermData
267e0 3e 53 54 41 4e 44 41 4c 4f 4e 45 5f 4d 49 4e 2e  >STANDALONE_MIN.
267f0 0a 20 20 2a 2f 0a 20 20 69 66 28 20 6e 54 65 72  .  */.  if( nTer
26800 6d 2b 6e 41 63 74 75 61 6c 44 61 74 61 3e 53 54  m+nActualData>ST
26810 41 4e 44 41 4c 4f 4e 45 5f 4d 49 4e 20 29 7b 0a  ANDALONE_MIN ){.
26820 20 20 20 20 2f 2a 20 50 75 73 68 20 6c 65 61 66      /* Push leaf
26830 20 6e 6f 64 65 20 66 72 6f 6d 20 62 65 66 6f 72   node from befor
26840 65 20 74 68 69 73 20 74 65 72 6d 2e 20 2a 2f 0a  e this term. */.
26850 20 20 20 20 69 66 28 20 69 54 65 72 6d 44 61 74      if( iTermDat
26860 61 3e 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20  a>0 ){.      rc 
26870 3d 20 6c 65 61 66 57 72 69 74 65 72 49 6e 74 65  = leafWriterInte
26880 72 6e 61 6c 46 6c 75 73 68 28 76 2c 20 70 57 72  rnalFlush(v, pWr
26890 69 74 65 72 2c 20 30 2c 20 69 54 65 72 6d 44 61  iter, 0, iTermDa
268a0 74 61 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  ta);.      if( r
268b0 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
268c0 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20 20  eturn rc;..     
268d0 20 70 57 72 69 74 65 72 2d 3e 6e 54 65 72 6d 44   pWriter->nTermD
268e0 69 73 74 69 6e 63 74 20 3d 20 6e 54 65 72 6d 44  istinct = nTermD
268f0 69 73 74 69 6e 63 74 3b 0a 20 20 20 20 7d 0a 0a  istinct;.    }..
26900 20 20 20 20 2f 2a 20 46 69 78 20 74 68 65 20 65      /* Fix the e
26910 6e 63 6f 64 65 64 20 64 6f 63 6c 69 73 74 20 6c  ncoded doclist l
26920 65 6e 67 74 68 2e 20 2a 2f 0a 20 20 20 20 69 44  ength. */.    iD
26930 6f 63 6c 69 73 74 44 61 74 61 20 2b 3d 20 6e 20  oclistData += n 
26940 2d 20 6e 41 63 74 75 61 6c 3b 0a 20 20 20 20 6d  - nActual;.    m
26950 65 6d 63 70 79 28 70 57 72 69 74 65 72 2d 3e 64  emcpy(pWriter->d
26960 61 74 61 2e 70 44 61 74 61 2b 69 44 6f 63 6c 69  ata.pData+iDocli
26970 73 74 44 61 74 61 2c 20 63 2c 20 6e 41 63 74 75  stData, c, nActu
26980 61 6c 29 3b 0a 0a 20 20 20 20 2f 2a 20 50 75 73  al);..    /* Pus
26990 68 20 74 68 65 20 73 74 61 6e 64 61 6c 6f 6e 65  h the standalone
269a0 20 6c 65 61 66 20 6e 6f 64 65 2e 20 2a 2f 0a 20   leaf node. */. 
269b0 20 20 20 72 63 20 3d 20 6c 65 61 66 57 72 69 74     rc = leafWrit
269c0 65 72 49 6e 6c 69 6e 65 46 6c 75 73 68 28 76 2c  erInlineFlush(v,
269d0 20 70 57 72 69 74 65 72 2c 20 70 54 65 72 6d 2c   pWriter, pTerm,
269e0 20 6e 54 65 72 6d 2c 20 69 44 6f 63 6c 69 73 74   nTerm, iDoclist
269f0 44 61 74 61 29 3b 0a 20 20 20 20 69 66 28 20 72  Data);.    if( r
26a00 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
26a10 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20 2f  eturn rc;..    /
26a20 2a 20 4c 65 61 76 65 20 74 68 65 20 6e 6f 64 65  * Leave the node
26a30 20 65 6d 70 74 79 2e 20 2a 2f 0a 20 20 20 20 64   empty. */.    d
26a40 61 74 61 42 75 66 66 65 72 52 65 73 65 74 28 26  ataBufferReset(&
26a50 70 57 72 69 74 65 72 2d 3e 64 61 74 61 29 3b 0a  pWriter->data);.
26a60 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
26a70 20 20 7d 0a 0a 20 20 2f 2a 20 41 74 20 74 68 69    }..  /* At thi
26a80 73 20 70 6f 69 6e 74 2c 20 77 65 20 6b 6e 6f 77  s point, we know
26a90 20 74 68 61 74 20 74 68 65 20 64 6f 63 6c 69 73   that the doclis
26aa0 74 20 77 61 73 20 73 6d 61 6c 6c 2c 20 73 6f 20  t was small, so 
26ab0 64 6f 20 74 68 65 0a 20 20 2a 2a 20 6d 65 6d 6d  do the.  ** memm
26ac0 6f 76 65 20 69 66 20 69 6e 64 69 63 61 74 65 64  ove if indicated
26ad0 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 6e 41 63  ..  */.  if( nAc
26ae0 74 75 61 6c 3c 6e 20 29 7b 0a 20 20 20 20 6d 65  tual<n ){.    me
26af0 6d 6d 6f 76 65 28 70 57 72 69 74 65 72 2d 3e 64  mmove(pWriter->d
26b00 61 74 61 2e 70 44 61 74 61 2b 69 44 6f 63 6c 69  ata.pData+iDocli
26b10 73 74 44 61 74 61 2b 6e 41 63 74 75 61 6c 2c 0a  stData+nActual,.
26b20 20 20 20 20 20 20 20 20 20 20 20 20 70 57 72 69              pWri
26b30 74 65 72 2d 3e 64 61 74 61 2e 70 44 61 74 61 2b  ter->data.pData+
26b40 69 44 6f 63 6c 69 73 74 44 61 74 61 2b 6e 2c 0a  iDoclistData+n,.
26b50 20 20 20 20 20 20 20 20 20 20 20 20 70 57 72 69              pWri
26b60 74 65 72 2d 3e 64 61 74 61 2e 6e 44 61 74 61 2d  ter->data.nData-
26b70 28 69 44 6f 63 6c 69 73 74 44 61 74 61 2b 6e 29  (iDoclistData+n)
26b80 29 3b 0a 20 20 20 20 70 57 72 69 74 65 72 2d 3e  );.    pWriter->
26b90 64 61 74 61 2e 6e 44 61 74 61 20 2d 3d 20 6e 2d  data.nData -= n-
26ba0 6e 41 63 74 75 61 6c 3b 0a 20 20 7d 0a 0a 20 20  nActual;.  }..  
26bb0 2f 2a 20 52 65 70 6c 61 63 65 20 77 72 69 74 74  /* Replace writt
26bc0 65 6e 20 6c 65 6e 67 74 68 20 77 69 74 68 20 61  en length with a
26bd0 63 74 75 61 6c 20 6c 65 6e 67 74 68 2e 20 2a 2f  ctual length. */
26be0 0a 20 20 6d 65 6d 63 70 79 28 70 57 72 69 74 65  .  memcpy(pWrite
26bf0 72 2d 3e 64 61 74 61 2e 70 44 61 74 61 2b 69 44  r->data.pData+iD
26c00 6f 63 6c 69 73 74 44 61 74 61 2c 20 63 2c 20 6e  oclistData, c, n
26c10 41 63 74 75 61 6c 29 3b 0a 0a 20 20 2f 2a 20 49  Actual);..  /* I
26c20 66 20 74 68 65 20 6e 6f 64 65 20 69 73 20 74 6f  f the node is to
26c30 6f 20 6c 61 72 67 65 2c 20 62 72 65 61 6b 20 74  o large, break t
26c40 68 69 6e 67 73 20 75 70 2e 20 2a 2f 0a 20 20 2f  hings up. */.  /
26c50 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 54 68  * TODO(shess) Th
26c60 69 73 20 74 65 73 74 20 6d 61 74 63 68 65 73 20  is test matches 
26c70 6c 65 61 66 57 72 69 74 65 72 53 74 65 70 28 29  leafWriterStep()
26c80 2c 20 77 68 69 63 68 20 64 6f 65 73 20 74 68 69  , which does thi
26c90 73 0a 20 20 2a 2a 20 74 65 73 74 20 62 65 66 6f  s.  ** test befo
26ca0 72 65 20 69 74 20 6b 6e 6f 77 73 20 74 68 65 20  re it knows the 
26cb0 63 6f 73 74 20 74 6f 20 76 61 72 69 6e 74 2d 65  cost to varint-e
26cc0 6e 63 6f 64 65 20 74 68 65 20 74 65 72 6d 20 61  ncode the term a
26cd0 6e 64 0a 20 20 2a 2a 20 64 6f 63 6c 69 73 74 20  nd.  ** doclist 
26ce0 6c 65 6e 67 74 68 73 2e 20 20 41 74 20 73 6f 6d  lengths.  At som
26cf0 65 20 70 6f 69 6e 74 2c 20 63 68 61 6e 67 65 20  e point, change 
26d00 74 6f 0a 20 20 2a 2a 20 70 57 72 69 74 65 72 2d  to.  ** pWriter-
26d10 3e 64 61 74 61 2e 6e 44 61 74 61 3e 4c 45 41 46  >data.nData>LEAF
26d20 5f 4d 41 58 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  _MAX..  */.  if(
26d30 20 69 54 65 72 6d 44 61 74 61 2b 6e 54 65 72 6d   iTermData+nTerm
26d40 2b 6e 41 63 74 75 61 6c 44 61 74 61 3e 4c 45 41  +nActualData>LEA
26d50 46 5f 4d 41 58 20 29 7b 0a 20 20 20 20 2f 2a 20  F_MAX ){.    /* 
26d60 46 6c 75 73 68 20 6f 75 74 20 74 68 65 20 6c 65  Flush out the le
26d70 61 64 69 6e 67 20 64 61 74 61 20 61 73 20 61 20  ading data as a 
26d80 6e 6f 64 65 20 2a 2f 0a 20 20 20 20 72 63 20 3d  node */.    rc =
26d90 20 6c 65 61 66 57 72 69 74 65 72 49 6e 74 65 72   leafWriterInter
26da0 6e 61 6c 46 6c 75 73 68 28 76 2c 20 70 57 72 69  nalFlush(v, pWri
26db0 74 65 72 2c 20 30 2c 20 69 54 65 72 6d 44 61 74  ter, 0, iTermDat
26dc0 61 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  a);.    if( rc!=
26dd0 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
26de0 72 6e 20 72 63 3b 0a 0a 20 20 20 20 70 57 72 69  rn rc;..    pWri
26df0 74 65 72 2d 3e 6e 54 65 72 6d 44 69 73 74 69 6e  ter->nTermDistin
26e00 63 74 20 3d 20 6e 54 65 72 6d 44 69 73 74 69 6e  ct = nTermDistin
26e10 63 74 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 62 75  ct;..    /* Rebu
26e20 69 6c 64 20 68 65 61 64 65 72 20 75 73 69 6e 67  ild header using
26e30 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 65 72   the current ter
26e40 6d 20 2a 2f 0a 20 20 20 20 6e 20 3d 20 66 74 73  m */.    n = fts
26e50 33 50 75 74 56 61 72 69 6e 74 28 70 57 72 69 74  3PutVarint(pWrit
26e60 65 72 2d 3e 64 61 74 61 2e 70 44 61 74 61 2c 20  er->data.pData, 
26e70 30 29 3b 0a 20 20 20 20 6e 20 2b 3d 20 66 74 73  0);.    n += fts
26e80 33 50 75 74 56 61 72 69 6e 74 28 70 57 72 69 74  3PutVarint(pWrit
26e90 65 72 2d 3e 64 61 74 61 2e 70 44 61 74 61 2b 6e  er->data.pData+n
26ea0 2c 20 6e 54 65 72 6d 29 3b 0a 20 20 20 20 6d 65  , nTerm);.    me
26eb0 6d 63 70 79 28 70 57 72 69 74 65 72 2d 3e 64 61  mcpy(pWriter->da
26ec0 74 61 2e 70 44 61 74 61 2b 6e 2c 20 70 54 65 72  ta.pData+n, pTer
26ed0 6d 2c 20 6e 54 65 72 6d 29 3b 0a 20 20 20 20 6e  m, nTerm);.    n
26ee0 20 2b 3d 20 6e 54 65 72 6d 3b 0a 0a 20 20 20 20   += nTerm;..    
26ef0 2f 2a 20 54 68 65 72 65 20 73 68 6f 75 6c 64 20  /* There should 
26f00 61 6c 77 61 79 73 20 62 65 20 72 6f 6f 6d 2c 20  always be room, 
26f10 62 65 63 61 75 73 65 20 74 68 65 20 70 72 65 76  because the prev
26f20 69 6f 75 73 20 65 6e 63 6f 64 69 6e 67 0a 20 20  ious encoding.  
26f30 20 20 2a 2a 20 69 6e 63 6c 75 64 65 64 20 61 6c    ** included al
26f40 6c 20 64 61 74 61 20 6e 65 63 65 73 73 61 72 79  l data necessary
26f50 20 74 6f 20 63 6f 6e 73 74 72 75 63 74 20 74 68   to construct th
26f60 65 20 74 65 72 6d 2e 0a 20 20 20 20 2a 2f 0a 20  e term..    */. 
26f70 20 20 20 61 73 73 65 72 74 28 20 6e 3c 69 44 6f     assert( n<iDo
26f80 63 6c 69 73 74 44 61 74 61 20 29 3b 0a 20 20 20  clistData );.   
26f90 20 2f 2a 20 53 6f 20 6c 6f 6e 67 20 61 73 20 53   /* So long as S
26fa0 54 41 4e 44 41 4c 4f 4e 45 5f 4d 49 4e 20 69 73  TANDALONE_MIN is
26fb0 20 68 61 6c 66 20 6f 72 20 6c 65 73 73 20 6f 66   half or less of
26fc0 20 4c 45 41 46 5f 4d 41 58 2c 20 74 68 65 0a 20   LEAF_MAX, the. 
26fd0 20 20 20 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20     ** following 
26fe0 6d 65 6d 63 70 79 28 29 20 69 73 20 73 61 66 65  memcpy() is safe
26ff0 20 28 61 73 20 6f 70 70 6f 73 65 64 20 74 6f 20   (as opposed to 
27000 6e 65 65 64 69 6e 67 20 61 20 6d 65 6d 6d 6f 76  needing a memmov
27010 65 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 61  e)..    */.    a
27020 73 73 65 72 74 28 20 32 2a 53 54 41 4e 44 41 4c  ssert( 2*STANDAL
27030 4f 4e 45 5f 4d 49 4e 3c 3d 4c 45 41 46 5f 4d 41  ONE_MIN<=LEAF_MA
27040 58 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  X );.    assert(
27050 20 6e 2b 70 57 72 69 74 65 72 2d 3e 64 61 74 61   n+pWriter->data
27060 2e 6e 44 61 74 61 2d 69 44 6f 63 6c 69 73 74 44  .nData-iDoclistD
27070 61 74 61 3c 69 44 6f 63 6c 69 73 74 44 61 74 61  ata<iDoclistData
27080 20 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 70   );.    memcpy(p
27090 57 72 69 74 65 72 2d 3e 64 61 74 61 2e 70 44 61  Writer->data.pDa
270a0 74 61 2b 6e 2c 0a 20 20 20 20 20 20 20 20 20 20  ta+n,.          
270b0 20 70 57 72 69 74 65 72 2d 3e 64 61 74 61 2e 70   pWriter->data.p
270c0 44 61 74 61 2b 69 44 6f 63 6c 69 73 74 44 61 74  Data+iDoclistDat
270d0 61 2c 0a 20 20 20 20 20 20 20 20 20 20 20 70 57  a,.           pW
270e0 72 69 74 65 72 2d 3e 64 61 74 61 2e 6e 44 61 74  riter->data.nDat
270f0 61 2d 69 44 6f 63 6c 69 73 74 44 61 74 61 29 3b  a-iDoclistData);
27100 0a 20 20 20 20 70 57 72 69 74 65 72 2d 3e 64 61  .    pWriter->da
27110 74 61 2e 6e 44 61 74 61 20 2d 3d 20 69 44 6f 63  ta.nData -= iDoc
27120 6c 69 73 74 44 61 74 61 2d 6e 3b 0a 20 20 7d 0a  listData-n;.  }.
27130 20 20 41 53 53 45 52 54 5f 56 41 4c 49 44 5f 4c    ASSERT_VALID_L
27140 45 41 46 5f 4e 4f 44 45 28 70 57 72 69 74 65 72  EAF_NODE(pWriter
27150 2d 3e 64 61 74 61 2e 70 44 61 74 61 2c 20 70 57  ->data.pData, pW
27160 72 69 74 65 72 2d 3e 64 61 74 61 2e 6e 44 61 74  riter->data.nDat
27170 61 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53 51  a);..  return SQ
27180 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 50  LITE_OK;.}../* P
27190 75 73 68 20 70 54 65 72 6d 5b 6e 54 65 72 6d 5d  ush pTerm[nTerm]
271a0 20 61 6c 6f 6e 67 20 77 69 74 68 20 74 68 65 20   along with the 
271b0 64 6f 63 6c 69 73 74 20 64 61 74 61 20 74 6f 20  doclist data to 
271c0 74 68 65 20 6c 65 61 66 20 6c 61 79 65 72 20 6f  the leaf layer o
271d0 66 0a 2a 2a 20 25 5f 73 65 67 6d 65 6e 74 73 2e  f.** %_segments.
271e0 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f 28 73 68 65 73  .*/./* TODO(shes
271f0 73 29 20 52 65 76 69 73 65 20 77 72 69 74 65 5a  s) Revise writeZ
27200 65 72 6f 53 65 67 6d 65 6e 74 28 29 20 73 6f 20  eroSegment() so 
27210 74 68 61 74 20 64 6f 63 6c 69 73 74 73 20 61 72  that doclists ar
27220 65 0a 2a 2a 20 63 6f 6e 73 74 72 75 63 74 65 64  e.** constructed
27230 20 64 69 72 65 63 74 6c 79 20 69 6e 20 70 57 72   directly in pWr
27240 69 74 65 72 2d 3e 64 61 74 61 2e 0a 2a 2f 0a 73  iter->data..*/.s
27250 74 61 74 69 63 20 69 6e 74 20 6c 65 61 66 57 72  tatic int leafWr
27260 69 74 65 72 53 74 65 70 28 66 75 6c 6c 74 65 78  iterStep(fulltex
27270 74 5f 76 74 61 62 20 2a 76 2c 20 4c 65 61 66 57  t_vtab *v, LeafW
27280 72 69 74 65 72 20 2a 70 57 72 69 74 65 72 2c 0a  riter *pWriter,.
27290 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
272a0 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20            const 
272b0 63 68 61 72 20 2a 70 54 65 72 6d 2c 20 69 6e 74  char *pTerm, int
272c0 20 6e 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20   nTerm,.        
272d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
272e0 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 44    const char *pD
272f0 61 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 29 7b  ata, int nData){
27300 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 44 4c 52  .  int rc;.  DLR
27310 65 61 64 65 72 20 72 65 61 64 65 72 3b 0a 0a 20  eader reader;.. 
27320 20 64 6c 72 49 6e 69 74 28 26 72 65 61 64 65 72   dlrInit(&reader
27330 2c 20 44 4c 5f 44 45 46 41 55 4c 54 2c 20 70 44  , DL_DEFAULT, pD
27340 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 72  ata, nData);.  r
27350 63 20 3d 20 6c 65 61 66 57 72 69 74 65 72 53 74  c = leafWriterSt
27360 65 70 4d 65 72 67 65 28 76 2c 20 70 57 72 69 74  epMerge(v, pWrit
27370 65 72 2c 20 70 54 65 72 6d 2c 20 6e 54 65 72 6d  er, pTerm, nTerm
27380 2c 20 26 72 65 61 64 65 72 2c 20 31 29 3b 0a 20  , &reader, 1);. 
27390 20 64 6c 72 44 65 73 74 72 6f 79 28 26 72 65 61   dlrDestroy(&rea
273a0 64 65 72 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20  der);..  return 
273b0 72 63 3b 0a 7d 0a 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a  rc;.}.../*******
273c0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
273d0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
273e0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
273f0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 20 4c 65  *********/./* Le
27400 61 66 52 65 61 64 65 72 20 69 73 20 75 73 65 64  afReader is used
27410 20 74 6f 20 69 74 65 72 61 74 65 20 6f 76 65 72   to iterate over
27420 20 61 6e 20 69 6e 64 69 76 69 64 75 61 6c 20 6c   an individual l
27430 65 61 66 20 6e 6f 64 65 2e 20 2a 2f 0a 74 79 70  eaf node. */.typ
27440 65 64 65 66 20 73 74 72 75 63 74 20 4c 65 61 66  edef struct Leaf
27450 52 65 61 64 65 72 20 7b 0a 20 20 44 61 74 61 42  Reader {.  DataB
27460 75 66 66 65 72 20 74 65 72 6d 3b 20 20 20 20 20  uffer term;     
27470 20 20 20 20 20 2f 2a 20 63 6f 70 79 20 6f 66 20       /* copy of 
27480 63 75 72 72 65 6e 74 20 74 65 72 6d 2e 20 2a 2f  current term. */
27490 0a 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ..  const char *
274a0 70 44 61 74 61 3b 20 20 20 20 20 20 20 20 2f 2a  pData;        /*
274b0 20 64 61 74 61 20 66 6f 72 20 63 75 72 72 65 6e   data for curren
274c0 74 20 74 65 72 6d 2e 20 2a 2f 0a 20 20 69 6e 74  t term. */.  int
274d0 20 6e 44 61 74 61 3b 0a 7d 20 4c 65 61 66 52 65   nData;.} LeafRe
274e0 61 64 65 72 3b 0a 0a 73 74 61 74 69 63 20 76 6f  ader;..static vo
274f0 69 64 20 6c 65 61 66 52 65 61 64 65 72 44 65 73  id leafReaderDes
27500 74 72 6f 79 28 4c 65 61 66 52 65 61 64 65 72 20  troy(LeafReader 
27510 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 64 61 74  *pReader){.  dat
27520 61 42 75 66 66 65 72 44 65 73 74 72 6f 79 28 26  aBufferDestroy(&
27530 70 52 65 61 64 65 72 2d 3e 74 65 72 6d 29 3b 0a  pReader->term);.
27540 20 20 53 43 52 41 4d 42 4c 45 28 70 52 65 61 64    SCRAMBLE(pRead
27550 65 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  er);.}..static i
27560 6e 74 20 6c 65 61 66 52 65 61 64 65 72 41 74 45  nt leafReaderAtE
27570 6e 64 28 4c 65 61 66 52 65 61 64 65 72 20 2a 70  nd(LeafReader *p
27580 52 65 61 64 65 72 29 7b 0a 20 20 72 65 74 75 72  Reader){.  retur
27590 6e 20 70 52 65 61 64 65 72 2d 3e 6e 44 61 74 61  n pReader->nData
275a0 3c 3d 30 3b 0a 7d 0a 0a 2f 2a 20 41 63 63 65 73  <=0;.}../* Acces
275b0 73 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 65  s the current te
275c0 72 6d 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  rm. */.static in
275d0 74 20 6c 65 61 66 52 65 61 64 65 72 54 65 72 6d  t leafReaderTerm
275e0 42 79 74 65 73 28 4c 65 61 66 52 65 61 64 65 72  Bytes(LeafReader
275f0 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 72 65   *pReader){.  re
27600 74 75 72 6e 20 70 52 65 61 64 65 72 2d 3e 74 65  turn pReader->te
27610 72 6d 2e 6e 44 61 74 61 3b 0a 7d 0a 73 74 61 74  rm.nData;.}.stat
27620 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 6c  ic const char *l
27630 65 61 66 52 65 61 64 65 72 54 65 72 6d 28 4c 65  eafReaderTerm(Le
27640 61 66 52 65 61 64 65 72 20 2a 70 52 65 61 64 65  afReader *pReade
27650 72 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 52  r){.  assert( pR
27660 65 61 64 65 72 2d 3e 74 65 72 6d 2e 6e 44 61 74  eader->term.nDat
27670 61 3e 30 20 29 3b 0a 20 20 72 65 74 75 72 6e 20  a>0 );.  return 
27680 70 52 65 61 64 65 72 2d 3e 74 65 72 6d 2e 70 44  pReader->term.pD
27690 61 74 61 3b 0a 7d 0a 0a 2f 2a 20 41 63 63 65 73  ata;.}../* Acces
276a0 73 20 74 68 65 20 64 6f 63 6c 69 73 74 20 64 61  s the doclist da
276b0 74 61 20 66 6f 72 20 74 68 65 20 63 75 72 72 65  ta for the curre
276c0 6e 74 20 74 65 72 6d 2e 20 2a 2f 0a 73 74 61 74  nt term. */.stat
276d0 69 63 20 69 6e 74 20 6c 65 61 66 52 65 61 64 65  ic int leafReade
276e0 72 44 61 74 61 42 79 74 65 73 28 4c 65 61 66 52  rDataBytes(LeafR
276f0 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b  eader *pReader){
27700 0a 20 20 69 6e 74 20 6e 44 61 74 61 3b 0a 20 20  .  int nData;.  
27710 61 73 73 65 72 74 28 20 70 52 65 61 64 65 72 2d  assert( pReader-
27720 3e 74 65 72 6d 2e 6e 44 61 74 61 3e 30 20 29 3b  >term.nData>0 );
27730 0a 20 20 66 74 73 33 47 65 74 56 61 72 69 6e 74  .  fts3GetVarint
27740 33 32 28 70 52 65 61 64 65 72 2d 3e 70 44 61 74  32(pReader->pDat
27750 61 2c 20 26 6e 44 61 74 61 29 3b 0a 20 20 72 65  a, &nData);.  re
27760 74 75 72 6e 20 6e 44 61 74 61 3b 0a 7d 0a 73 74  turn nData;.}.st
27770 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20  atic const char 
27780 2a 6c 65 61 66 52 65 61 64 65 72 44 61 74 61 28  *leafReaderData(
27790 4c 65 61 66 52 65 61 64 65 72 20 2a 70 52 65 61  LeafReader *pRea
277a0 64 65 72 29 7b 0a 20 20 69 6e 74 20 6e 2c 20 6e  der){.  int n, n
277b0 44 61 74 61 3b 0a 20 20 61 73 73 65 72 74 28 20  Data;.  assert( 
277c0 70 52 65 61 64 65 72 2d 3e 74 65 72 6d 2e 6e 44  pReader->term.nD
277d0 61 74 61 3e 30 20 29 3b 0a 20 20 6e 20 3d 20 66  ata>0 );.  n = f
277e0 74 73 33 47 65 74 56 61 72 69 6e 74 33 32 28 70  ts3GetVarint32(p
277f0 52 65 61 64 65 72 2d 3e 70 44 61 74 61 2c 20 26  Reader->pData, &
27800 6e 44 61 74 61 29 3b 0a 20 20 72 65 74 75 72 6e  nData);.  return
27810 20 70 52 65 61 64 65 72 2d 3e 70 44 61 74 61 2b   pReader->pData+
27820 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  n;.}..static voi
27830 64 20 6c 65 61 66 52 65 61 64 65 72 49 6e 69 74  d leafReaderInit
27840 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 44 61  (const char *pDa
27850 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 2c 0a 20  ta, int nData,. 
27860 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27870 20 20 20 20 20 20 20 20 20 20 4c 65 61 66 52 65            LeafRe
27880 61 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a  ader *pReader){.
27890 20 20 69 6e 74 20 6e 54 65 72 6d 2c 20 6e 3b 0a    int nTerm, n;.
278a0 0a 20 20 61 73 73 65 72 74 28 20 6e 44 61 74 61  .  assert( nData
278b0 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  >0 );.  assert( 
278c0 70 44 61 74 61 5b 30 5d 3d 3d 27 5c 30 27 20 29  pData[0]=='\0' )
278d0 3b 0a 0a 20 20 43 4c 45 41 52 28 70 52 65 61 64  ;..  CLEAR(pRead
278e0 65 72 29 3b 0a 0a 20 20 2f 2a 20 52 65 61 64 20  er);..  /* Read 
278f0 74 68 65 20 66 69 72 73 74 20 74 65 72 6d 2c 20  the first term, 
27900 73 6b 69 70 70 69 6e 67 20 74 68 65 20 68 65 61  skipping the hea
27910 64 65 72 20 62 79 74 65 2e 20 2a 2f 0a 20 20 6e  der byte. */.  n
27920 20 3d 20 66 74 73 33 47 65 74 56 61 72 69 6e 74   = fts3GetVarint
27930 33 32 28 70 44 61 74 61 2b 31 2c 20 26 6e 54 65  32(pData+1, &nTe
27940 72 6d 29 3b 0a 20 20 64 61 74 61 42 75 66 66 65  rm);.  dataBuffe
27950 72 49 6e 69 74 28 26 70 52 65 61 64 65 72 2d 3e  rInit(&pReader->
27960 74 65 72 6d 2c 20 6e 54 65 72 6d 29 3b 0a 20 20  term, nTerm);.  
27970 64 61 74 61 42 75 66 66 65 72 52 65 70 6c 61 63  dataBufferReplac
27980 65 28 26 70 52 65 61 64 65 72 2d 3e 74 65 72 6d  e(&pReader->term
27990 2c 20 70 44 61 74 61 2b 31 2b 6e 2c 20 6e 54 65  , pData+1+n, nTe
279a0 72 6d 29 3b 0a 0a 20 20 2f 2a 20 50 6f 73 69 74  rm);..  /* Posit
279b0 69 6f 6e 20 61 66 74 65 72 20 74 68 65 20 66 69  ion after the fi
279c0 72 73 74 20 74 65 72 6d 2e 20 2a 2f 0a 20 20 61  rst term. */.  a
279d0 73 73 65 72 74 28 20 31 2b 6e 2b 6e 54 65 72 6d  ssert( 1+n+nTerm
279e0 3c 6e 44 61 74 61 20 29 3b 0a 20 20 70 52 65 61  <nData );.  pRea
279f0 64 65 72 2d 3e 70 44 61 74 61 20 3d 20 70 44 61  der->pData = pDa
27a00 74 61 2b 31 2b 6e 2b 6e 54 65 72 6d 3b 0a 20 20  ta+1+n+nTerm;.  
27a10 70 52 65 61 64 65 72 2d 3e 6e 44 61 74 61 20 3d  pReader->nData =
27a20 20 6e 44 61 74 61 2d 31 2d 6e 2d 6e 54 65 72 6d   nData-1-n-nTerm
27a30 3b 0a 7d 0a 0a 2f 2a 20 53 74 65 70 20 74 68 65  ;.}../* Step the
27a40 20 72 65 61 64 65 72 20 66 6f 72 77 61 72 64 20   reader forward 
27a50 74 6f 20 74 68 65 20 6e 65 78 74 20 74 65 72 6d  to the next term
27a60 2e 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  . */.static void
27a70 20 6c 65 61 66 52 65 61 64 65 72 53 74 65 70 28   leafReaderStep(
27a80 4c 65 61 66 52 65 61 64 65 72 20 2a 70 52 65 61  LeafReader *pRea
27a90 64 65 72 29 7b 0a 20 20 69 6e 74 20 6e 2c 20 6e  der){.  int n, n
27aa0 44 61 74 61 2c 20 6e 50 72 65 66 69 78 2c 20 6e  Data, nPrefix, n
27ab0 53 75 66 66 69 78 3b 0a 20 20 61 73 73 65 72 74  Suffix;.  assert
27ac0 28 20 21 6c 65 61 66 52 65 61 64 65 72 41 74 45  ( !leafReaderAtE
27ad0 6e 64 28 70 52 65 61 64 65 72 29 20 29 3b 0a 0a  nd(pReader) );..
27ae0 20 20 2f 2a 20 53 6b 69 70 20 70 72 65 76 69 6f    /* Skip previo
27af0 75 73 20 65 6e 74 72 79 27 73 20 64 61 74 61 20  us entry's data 
27b00 62 6c 6f 63 6b 2e 20 2a 2f 0a 20 20 6e 20 3d 20  block. */.  n = 
27b10 66 74 73 33 47 65 74 56 61 72 69 6e 74 33 32 28  fts3GetVarint32(
27b20 70 52 65 61 64 65 72 2d 3e 70 44 61 74 61 2c 20  pReader->pData, 
27b30 26 6e 44 61 74 61 29 3b 0a 20 20 61 73 73 65 72  &nData);.  asser
27b40 74 28 20 6e 2b 6e 44 61 74 61 3c 3d 70 52 65 61  t( n+nData<=pRea
27b50 64 65 72 2d 3e 6e 44 61 74 61 20 29 3b 0a 20 20  der->nData );.  
27b60 70 52 65 61 64 65 72 2d 3e 70 44 61 74 61 20 2b  pReader->pData +
27b70 3d 20 6e 2b 6e 44 61 74 61 3b 0a 20 20 70 52 65  = n+nData;.  pRe
27b80 61 64 65 72 2d 3e 6e 44 61 74 61 20 2d 3d 20 6e  ader->nData -= n
27b90 2b 6e 44 61 74 61 3b 0a 0a 20 20 69 66 28 20 21  +nData;..  if( !
27ba0 6c 65 61 66 52 65 61 64 65 72 41 74 45 6e 64 28  leafReaderAtEnd(
27bb0 70 52 65 61 64 65 72 29 20 29 7b 0a 20 20 20 20  pReader) ){.    
27bc0 2f 2a 20 43 6f 6e 73 74 72 75 63 74 20 74 68 65  /* Construct the
27bd0 20 6e 65 77 20 74 65 72 6d 20 75 73 69 6e 67 20   new term using 
27be0 61 20 70 72 65 66 69 78 20 66 72 6f 6d 20 74 68  a prefix from th
27bf0 65 20 6f 6c 64 20 74 65 72 6d 20 70 6c 75 73 20  e old term plus 
27c00 61 0a 20 20 20 20 2a 2a 20 73 75 66 66 69 78 20  a.    ** suffix 
27c10 66 72 6f 6d 20 74 68 65 20 6c 65 61 66 20 64 61  from the leaf da
27c20 74 61 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6e  ta..    */.    n
27c30 20 3d 20 66 74 73 33 47 65 74 56 61 72 69 6e 74   = fts3GetVarint
27c40 33 32 28 70 52 65 61 64 65 72 2d 3e 70 44 61 74  32(pReader->pDat
27c50 61 2c 20 26 6e 50 72 65 66 69 78 29 3b 0a 20 20  a, &nPrefix);.  
27c60 20 20 6e 20 2b 3d 20 66 74 73 33 47 65 74 56 61    n += fts3GetVa
27c70 72 69 6e 74 33 32 28 70 52 65 61 64 65 72 2d 3e  rint32(pReader->
27c80 70 44 61 74 61 2b 6e 2c 20 26 6e 53 75 66 66 69  pData+n, &nSuffi
27c90 78 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  x);.    assert( 
27ca0 6e 2b 6e 53 75 66 66 69 78 3c 70 52 65 61 64 65  n+nSuffix<pReade
27cb0 72 2d 3e 6e 44 61 74 61 20 29 3b 0a 20 20 20 20  r->nData );.    
27cc0 70 52 65 61 64 65 72 2d 3e 74 65 72 6d 2e 6e 44  pReader->term.nD
27cd0 61 74 61 20 3d 20 6e 50 72 65 66 69 78 3b 0a 20  ata = nPrefix;. 
27ce0 20 20 20 64 61 74 61 42 75 66 66 65 72 41 70 70     dataBufferApp
27cf0 65 6e 64 28 26 70 52 65 61 64 65 72 2d 3e 74 65  end(&pReader->te
27d00 72 6d 2c 20 70 52 65 61 64 65 72 2d 3e 70 44 61  rm, pReader->pDa
27d10 74 61 2b 6e 2c 20 6e 53 75 66 66 69 78 29 3b 0a  ta+n, nSuffix);.
27d20 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e 70 44  .    pReader->pD
27d30 61 74 61 20 2b 3d 20 6e 2b 6e 53 75 66 66 69 78  ata += n+nSuffix
27d40 3b 0a 20 20 20 20 70 52 65 61 64 65 72 2d 3e 6e  ;.    pReader->n
27d50 44 61 74 61 20 2d 3d 20 6e 2b 6e 53 75 66 66 69  Data -= n+nSuffi
27d60 78 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 73 74 72  x;.  }.}../* str
27d70 63 6d 70 2d 73 74 79 6c 65 20 63 6f 6d 70 61 72  cmp-style compar
27d80 69 73 6f 6e 20 6f 66 20 70 52 65 61 64 65 72 27  ison of pReader'
27d90 73 20 63 75 72 72 65 6e 74 20 74 65 72 6d 20 61  s current term a
27da0 67 61 69 6e 73 74 20 70 54 65 72 6d 2e 0a 2a 2a  gainst pTerm..**
27db0 20 49 66 20 69 73 50 72 65 66 69 78 2c 20 65 71   If isPrefix, eq
27dc0 75 61 6c 69 74 79 20 6d 65 61 6e 73 20 65 71 75  uality means equ
27dd0 61 6c 20 74 68 72 6f 75 67 68 20 6e 54 65 72 6d  al through nTerm
27de0 20 62 79 74 65 73 2e 0a 2a 2f 0a 73 74 61 74 69   bytes..*/.stati
27df0 63 20 69 6e 74 20 6c 65 61 66 52 65 61 64 65 72  c int leafReader
27e00 54 65 72 6d 43 6d 70 28 4c 65 61 66 52 65 61 64  TermCmp(LeafRead
27e10 65 72 20 2a 70 52 65 61 64 65 72 2c 0a 20 20 20  er *pReader,.   
27e20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27e30 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20            const 
27e40 63 68 61 72 20 2a 70 54 65 72 6d 2c 20 69 6e 74  char *pTerm, int
27e50 20 6e 54 65 72 6d 2c 20 69 6e 74 20 69 73 50 72   nTerm, int isPr
27e60 65 66 69 78 29 7b 0a 20 20 69 6e 74 20 63 2c 20  efix){.  int c, 
27e70 6e 20 3d 20 70 52 65 61 64 65 72 2d 3e 74 65 72  n = pReader->ter
27e80 6d 2e 6e 44 61 74 61 3c 6e 54 65 72 6d 20 3f 20  m.nData<nTerm ? 
27e90 70 52 65 61 64 65 72 2d 3e 74 65 72 6d 2e 6e 44  pReader->term.nD
27ea0 61 74 61 20 3a 20 6e 54 65 72 6d 3b 0a 20 20 69  ata : nTerm;.  i
27eb0 66 28 20 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 69  f( n==0 ){.    i
27ec0 66 28 20 70 52 65 61 64 65 72 2d 3e 74 65 72 6d  f( pReader->term
27ed0 2e 6e 44 61 74 61 3e 30 20 29 20 72 65 74 75 72  .nData>0 ) retur
27ee0 6e 20 2d 31 3b 0a 20 20 20 20 69 66 28 6e 54 65  n -1;.    if(nTe
27ef0 72 6d 3e 30 20 29 20 72 65 74 75 72 6e 20 31 3b  rm>0 ) return 1;
27f00 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
27f10 20 7d 0a 0a 20 20 63 20 3d 20 6d 65 6d 63 6d 70   }..  c = memcmp
27f20 28 70 52 65 61 64 65 72 2d 3e 74 65 72 6d 2e 70  (pReader->term.p
27f30 44 61 74 61 2c 20 70 54 65 72 6d 2c 20 6e 29 3b  Data, pTerm, n);
27f40 0a 20 20 69 66 28 20 63 21 3d 30 20 29 20 72 65  .  if( c!=0 ) re
27f50 74 75 72 6e 20 63 3b 0a 20 20 69 66 28 20 69 73  turn c;.  if( is
27f60 50 72 65 66 69 78 20 26 26 20 6e 3d 3d 6e 54 65  Prefix && n==nTe
27f70 72 6d 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20  rm ) return 0;. 
27f80 20 72 65 74 75 72 6e 20 70 52 65 61 64 65 72 2d   return pReader-
27f90 3e 74 65 72 6d 2e 6e 44 61 74 61 20 2d 20 6e 54  >term.nData - nT
27fa0 65 72 6d 3b 0a 7d 0a 0a 0a 2f 2a 2a 2a 2a 2a 2a  erm;.}.../******
27fb0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
27fc0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
27fd0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
27fe0 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 20 4c  **********/./* L
27ff0 65 61 76 65 73 52 65 61 64 65 72 20 77 72 61 70  eavesReader wrap
28000 73 20 4c 65 61 66 52 65 61 64 65 72 20 74 6f 20  s LeafReader to 
28010 61 6c 6c 6f 77 20 69 74 65 72 61 74 69 6e 67 20  allow iterating 
28020 6f 76 65 72 20 74 68 65 20 65 6e 74 69 72 65 0a  over the entire.
28030 2a 2a 20 6c 65 61 66 20 6c 61 79 65 72 20 6f 66  ** leaf layer of
28040 20 74 68 65 20 74 72 65 65 2e 0a 2a 2f 0a 74 79   the tree..*/.ty
28050 70 65 64 65 66 20 73 74 72 75 63 74 20 4c 65 61  pedef struct Lea
28060 76 65 73 52 65 61 64 65 72 20 7b 0a 20 20 69 6e  vesReader {.  in
28070 74 20 69 64 78 3b 20 20 20 20 20 20 20 20 20 20  t idx;          
28080 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78          /* Index
28090 20 77 69 74 68 69 6e 20 74 68 65 20 73 65 67 6d   within the segm
280a0 65 6e 74 2e 20 2a 2f 0a 0a 20 20 73 71 6c 69 74  ent. */..  sqlit
280b0 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 20  e3_stmt *pStmt; 
280c0 20 20 20 20 20 2f 2a 20 53 74 61 74 65 6d 65 6e       /* Statemen
280d0 74 20 77 65 27 72 65 20 73 74 72 65 61 6d 69 6e  t we're streamin
280e0 67 20 6c 65 61 76 65 73 20 66 72 6f 6d 2e 20 2a  g leaves from. *
280f0 2f 0a 20 20 69 6e 74 20 65 6f 66 3b 20 20 20 20  /.  int eof;    
28100 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
28110 20 77 65 27 76 65 20 73 65 65 6e 20 53 51 4c 49   we've seen SQLI
28120 54 45 5f 44 4f 4e 45 20 66 72 6f 6d 20 70 53 74  TE_DONE from pSt
28130 6d 74 2e 20 2a 2f 0a 0a 20 20 4c 65 61 66 52 65  mt. */..  LeafRe
28140 61 64 65 72 20 6c 65 61 66 52 65 61 64 65 72 3b  ader leafReader;
28150 20 20 20 20 2f 2a 20 72 65 61 64 65 72 20 66 6f      /* reader fo
28160 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c 65  r the current le
28170 61 66 2e 20 2a 2f 0a 20 20 44 61 74 61 42 75 66  af. */.  DataBuf
28180 66 65 72 20 72 6f 6f 74 44 61 74 61 3b 20 20 20  fer rootData;   
28190 20 20 20 2f 2a 20 72 6f 6f 74 20 64 61 74 61 20     /* root data 
281a0 66 6f 72 20 69 6e 6c 69 6e 65 2e 20 2a 2f 0a 7d  for inline. */.}
281b0 20 4c 65 61 76 65 73 52 65 61 64 65 72 3b 0a 0a   LeavesReader;..
281c0 2f 2a 20 41 63 63 65 73 73 20 74 68 65 20 63 75  /* Access the cu
281d0 72 72 65 6e 74 20 74 65 72 6d 2e 20 2a 2f 0a 73  rrent term. */.s
281e0 74 61 74 69 63 20 69 6e 74 20 6c 65 61 76 65 73  tatic int leaves
281f0 52 65 61 64 65 72 54 65 72 6d 42 79 74 65 73 28  ReaderTermBytes(
28200 4c 65 61 76 65 73 52 65 61 64 65 72 20 2a 70 52  LeavesReader *pR
28210 65 61 64 65 72 29 7b 0a 20 20 61 73 73 65 72 74  eader){.  assert
28220 28 20 21 70 52 65 61 64 65 72 2d 3e 65 6f 66 20  ( !pReader->eof 
28230 29 3b 0a 20 20 72 65 74 75 72 6e 20 6c 65 61 66  );.  return leaf
28240 52 65 61 64 65 72 54 65 72 6d 42 79 74 65 73 28  ReaderTermBytes(
28250 26 70 52 65 61 64 65 72 2d 3e 6c 65 61 66 52 65  &pReader->leafRe
28260 61 64 65 72 29 3b 0a 7d 0a 73 74 61 74 69 63 20  ader);.}.static 
28270 63 6f 6e 73 74 20 63 68 61 72 20 2a 6c 65 61 76  const char *leav
28280 65 73 52 65 61 64 65 72 54 65 72 6d 28 4c 65 61  esReaderTerm(Lea
28290 76 65 73 52 65 61 64 65 72 20 2a 70 52 65 61 64  vesReader *pRead
282a0 65 72 29 7b 0a 20 20 61 73 73 65 72 74 28 20 21  er){.  assert( !
282b0 70 52 65 61 64 65 72 2d 3e 65 6f 66 20 29 3b 0a  pReader->eof );.
282c0 20 20 72 65 74 75 72 6e 20 6c 65 61 66 52 65 61    return leafRea
282d0 64 65 72 54 65 72 6d 28 26 70 52 65 61 64 65 72  derTerm(&pReader
282e0 2d 3e 6c 65 61 66 52 65 61 64 65 72 29 3b 0a 7d  ->leafReader);.}
282f0 0a 0a 2f 2a 20 41 63 63 65 73 73 20 74 68 65 20  ../* Access the 
28300 64 6f 63 6c 69 73 74 20 64 61 74 61 20 66 6f 72  doclist data for
28310 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 65 72   the current ter
28320 6d 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  m. */.static int
28330 20 6c 65 61 76 65 73 52 65 61 64 65 72 44 61 74   leavesReaderDat
28340 61 42 79 74 65 73 28 4c 65 61 76 65 73 52 65 61  aBytes(LeavesRea
28350 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20  der *pReader){. 
28360 20 61 73 73 65 72 74 28 20 21 70 52 65 61 64 65   assert( !pReade
28370 72 2d 3e 65 6f 66 20 29 3b 0a 20 20 72 65 74 75  r->eof );.  retu
28380 72 6e 20 6c 65 61 66 52 65 61 64 65 72 44 61 74  rn leafReaderDat
28390 61 42 79 74 65 73 28 26 70 52 65 61 64 65 72 2d  aBytes(&pReader-
283a0 3e 6c 65 61 66 52 65 61 64 65 72 29 3b 0a 7d 0a  >leafReader);.}.
283b0 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61  static const cha
283c0 72 20 2a 6c 65 61 76 65 73 52 65 61 64 65 72 44  r *leavesReaderD
283d0 61 74 61 28 4c 65 61 76 65 73 52 65 61 64 65 72  ata(LeavesReader
283e0 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 61 73   *pReader){.  as
283f0 73 65 72 74 28 20 21 70 52 65 61 64 65 72 2d 3e  sert( !pReader->
28400 65 6f 66 20 29 3b 0a 20 20 72 65 74 75 72 6e 20  eof );.  return 
28410 6c 65 61 66 52 65 61 64 65 72 44 61 74 61 28 26  leafReaderData(&
28420 70 52 65 61 64 65 72 2d 3e 6c 65 61 66 52 65 61  pReader->leafRea
28430 64 65 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  der);.}..static 
28440 69 6e 74 20 6c 65 61 76 65 73 52 65 61 64 65 72  int leavesReader
28450 41 74 45 6e 64 28 4c 65 61 76 65 73 52 65 61 64  AtEnd(LeavesRead
28460 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20  er *pReader){.  
28470 72 65 74 75 72 6e 20 70 52 65 61 64 65 72 2d 3e  return pReader->
28480 65 6f 66 3b 0a 7d 0a 0a 2f 2a 20 6c 6f 61 64 53  eof;.}../* loadS
28490 65 67 6d 65 6e 74 4c 65 61 76 65 73 28 29 20 6d  egmentLeaves() m
284a0 61 79 20 6e 6f 74 20 72 65 61 64 20 61 6c 6c 20  ay not read all 
284b0 74 68 65 20 77 61 79 20 74 6f 20 53 51 4c 49 54  the way to SQLIT
284c0 45 5f 44 4f 4e 45 2c 20 74 68 75 73 0a 2a 2a 20  E_DONE, thus.** 
284d0 6c 65 61 76 69 6e 67 20 74 68 65 20 73 74 61 74  leaving the stat
284e0 65 6d 65 6e 74 20 68 61 6e 64 6c 65 20 6f 70 65  ement handle ope
284f0 6e 2c 20 77 68 69 63 68 20 6c 6f 63 6b 73 20 74  n, which locks t
28500 68 65 20 74 61 62 6c 65 2e 0a 2a 2f 0a 2f 2a 20  he table..*/./* 
28510 54 4f 44 4f 28 73 68 65 73 73 29 20 54 68 69 73  TODO(shess) This
28520 20 22 73 6f 6c 75 74 69 6f 6e 22 20 69 73 20 6e   "solution" is n
28530 6f 74 20 73 61 74 69 73 66 61 63 74 6f 72 79 2e  ot satisfactory.
28540 20 20 52 65 61 6c 6c 79 2c 20 74 68 65 72 65 0a    Really, there.
28550 2a 2a 20 73 68 6f 75 6c 64 20 62 65 20 63 68 65  ** should be che
28560 63 6b 2d 69 6e 20 66 75 6e 63 74 69 6f 6e 20 66  ck-in function f
28570 6f 72 20 61 6c 6c 20 73 74 61 74 65 6d 65 6e 74  or all statement
28580 20 68 61 6e 64 6c 65 73 20 77 68 69 63 68 0a 2a   handles which.*
28590 2a 20 61 72 72 61 6e 67 65 73 20 74 6f 20 63 61  * arranges to ca
285a0 6c 6c 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74  ll sqlite3_reset
285b0 28 29 2e 20 20 54 68 69 73 20 6d 6f 73 74 20 6c  ().  This most l
285c0 69 6b 65 6c 79 20 77 69 6c 6c 20 72 65 71 75 69  ikely will requi
285d0 72 65 0a 2a 2a 20 6d 6f 64 69 66 69 63 61 74 69  re.** modificati
285e0 6f 6e 20 74 6f 20 63 6f 6e 74 72 6f 6c 20 66 6c  on to control fl
285f0 6f 77 20 61 6c 6c 20 6f 76 65 72 20 74 68 65 20  ow all over the 
28600 70 6c 61 63 65 2c 20 74 68 6f 75 67 68 2c 20 73  place, though, s
28610 6f 20 66 6f 72 20 6e 6f 77 0a 2a 2a 20 6a 75 73  o for now.** jus
28620 74 20 70 75 6e 74 2e 0a 2a 2a 0a 2a 2a 20 4e 6f  t punt..**.** No
28630 74 65 20 74 68 65 20 74 68 65 20 63 75 72 72 65  te the the curre
28640 6e 74 20 73 79 73 74 65 6d 20 61 73 73 75 6d 65  nt system assume
28650 73 20 74 68 61 74 20 73 65 67 6d 65 6e 74 20 6d  s that segment m
28660 65 72 67 65 73 20 77 69 6c 6c 20 72 75 6e 20 74  erges will run t
28670 6f 0a 2a 2a 20 63 6f 6d 70 6c 65 74 69 6f 6e 2c  o.** completion,
28680 20 77 68 69 63 68 20 69 73 20 77 68 79 20 74 68   which is why th
28690 69 73 20 70 61 72 74 69 63 75 6c 61 72 20 70 72  is particular pr
286a0 6f 62 61 62 6c 79 20 68 61 73 6e 27 74 20 61 72  obably hasn't ar
286b0 69 73 65 6e 20 69 6e 0a 2a 2a 20 74 68 69 73 20  isen in.** this 
286c0 63 61 73 65 2e 20 20 50 72 6f 62 61 62 6c 79 20  case.  Probably 
286d0 61 20 62 72 69 74 74 6c 65 20 61 73 73 75 6d 70  a brittle assump
286e0 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  tion..*/.static 
286f0 69 6e 74 20 6c 65 61 76 65 73 52 65 61 64 65 72  int leavesReader
28700 52 65 73 65 74 28 4c 65 61 76 65 73 52 65 61 64  Reset(LeavesRead
28710 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20  er *pReader){.  
28720 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 5f 72  return sqlite3_r
28730 65 73 65 74 28 70 52 65 61 64 65 72 2d 3e 70 53  eset(pReader->pS
28740 74 6d 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  tmt);.}..static 
28750 76 6f 69 64 20 6c 65 61 76 65 73 52 65 61 64 65  void leavesReade
28760 72 44 65 73 74 72 6f 79 28 4c 65 61 76 65 73 52  rDestroy(LeavesR
28770 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b  eader *pReader){
28780 0a 20 20 2f 2a 20 49 66 20 69 64 78 20 69 73 20  .  /* If idx is 
28790 2d 31 2c 20 74 68 61 74 20 6d 65 61 6e 73 20 77  -1, that means w
287a0 65 27 72 65 20 75 73 69 6e 67 20 61 20 6e 6f 6e  e're using a non
287b0 2d 63 61 63 68 65 64 20 73 74 61 74 65 6d 65 6e  -cached statemen
287c0 74 0a 20 20 2a 2a 20 68 61 6e 64 6c 65 20 69 6e  t.  ** handle in
287d0 20 74 68 65 20 6f 70 74 69 6d 69 7a 65 28 29 20   the optimize() 
287e0 63 61 73 65 2c 20 73 6f 20 77 65 20 6e 65 65 64  case, so we need
287f0 20 74 6f 20 72 65 6c 65 61 73 65 20 69 74 2e 0a   to release it..
28800 20 20 2a 2f 0a 20 20 69 66 28 20 70 52 65 61 64    */.  if( pRead
28810 65 72 2d 3e 70 53 74 6d 74 21 3d 4e 55 4c 4c 20  er->pStmt!=NULL 
28820 26 26 20 70 52 65 61 64 65 72 2d 3e 69 64 78 3d  && pReader->idx=
28830 3d 2d 31 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  =-1 ){.    sqlit
28840 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 52 65 61  e3_finalize(pRea
28850 64 65 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 7d  der->pStmt);.  }
28860 0a 20 20 6c 65 61 66 52 65 61 64 65 72 44 65 73  .  leafReaderDes
28870 74 72 6f 79 28 26 70 52 65 61 64 65 72 2d 3e 6c  troy(&pReader->l
28880 65 61 66 52 65 61 64 65 72 29 3b 0a 20 20 64 61  eafReader);.  da
28890 74 61 42 75 66 66 65 72 44 65 73 74 72 6f 79 28  taBufferDestroy(
288a0 26 70 52 65 61 64 65 72 2d 3e 72 6f 6f 74 44 61  &pReader->rootDa
288b0 74 61 29 3b 0a 20 20 53 43 52 41 4d 42 4c 45 28  ta);.  SCRAMBLE(
288c0 70 52 65 61 64 65 72 29 3b 0a 7d 0a 0a 2f 2a 20  pReader);.}../* 
288d0 49 6e 69 74 69 61 6c 69 7a 65 20 70 52 65 61 64  Initialize pRead
288e0 65 72 20 77 69 74 68 20 74 68 65 20 67 69 76 65  er with the give
288f0 6e 20 72 6f 6f 74 20 64 61 74 61 20 28 69 66 20  n root data (if 
28900 69 53 74 61 72 74 42 6c 6f 63 6b 69 64 3d 3d 30  iStartBlockid==0
28910 0a 2a 2a 20 74 68 65 20 6c 65 61 66 20 64 61 74  .** the leaf dat
28920 61 20 77 61 73 20 65 6e 74 69 72 65 6c 79 20 63  a was entirely c
28930 6f 6e 74 61 69 6e 65 64 20 69 6e 20 74 68 65 20  ontained in the 
28940 72 6f 6f 74 29 2c 20 6f 72 20 66 72 6f 6d 20 74  root), or from t
28950 68 65 0a 2a 2a 20 73 74 72 65 61 6d 20 6f 66 20  he.** stream of 
28960 62 6c 6f 63 6b 73 20 62 65 74 77 65 65 6e 20 69  blocks between i
28970 53 74 61 72 74 42 6c 6f 63 6b 69 64 20 61 6e 64  StartBlockid and
28980 20 69 45 6e 64 42 6c 6f 63 6b 69 64 2c 20 69 6e   iEndBlockid, in
28990 63 6c 75 73 69 76 65 2e 0a 2a 2f 0a 73 74 61 74  clusive..*/.stat
289a0 69 63 20 69 6e 74 20 6c 65 61 76 65 73 52 65 61  ic int leavesRea
289b0 64 65 72 49 6e 69 74 28 66 75 6c 6c 74 65 78 74  derInit(fulltext
289c0 5f 76 74 61 62 20 2a 76 2c 0a 20 20 20 20 20 20  _vtab *v,.      
289d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
289e0 20 20 20 20 20 20 69 6e 74 20 69 64 78 2c 0a 20        int idx,. 
289f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28a00 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
28a10 65 5f 69 6e 74 36 34 20 69 53 74 61 72 74 42 6c  e_int64 iStartBl
28a20 6f 63 6b 69 64 2c 0a 20 20 20 20 20 20 20 20 20  ockid,.         
28a30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28a40 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20     sqlite_int64 
28a50 69 45 6e 64 42 6c 6f 63 6b 69 64 2c 0a 20 20 20  iEndBlockid,.   
28a60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28a70 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63           const c
28a80 68 61 72 20 2a 70 52 6f 6f 74 44 61 74 61 2c 20  har *pRootData, 
28a90 69 6e 74 20 6e 52 6f 6f 74 44 61 74 61 2c 0a 20  int nRootData,. 
28aa0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28ab0 20 20 20 20 20 20 20 20 20 20 20 4c 65 61 76 65             Leave
28ac0 73 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72  sReader *pReader
28ad0 29 7b 0a 20 20 43 4c 45 41 52 28 70 52 65 61 64  ){.  CLEAR(pRead
28ae0 65 72 29 3b 0a 20 20 70 52 65 61 64 65 72 2d 3e  er);.  pReader->
28af0 69 64 78 20 3d 20 69 64 78 3b 0a 0a 20 20 64 61  idx = idx;..  da
28b00 74 61 42 75 66 66 65 72 49 6e 69 74 28 26 70 52  taBufferInit(&pR
28b10 65 61 64 65 72 2d 3e 72 6f 6f 74 44 61 74 61 2c  eader->rootData,
28b20 20 30 29 3b 0a 20 20 69 66 28 20 69 53 74 61 72   0);.  if( iStar
28b30 74 42 6c 6f 63 6b 69 64 3d 3d 30 20 29 7b 0a 20  tBlockid==0 ){. 
28b40 20 20 20 2f 2a 20 45 6e 74 69 72 65 20 6c 65 61     /* Entire lea
28b50 66 20 6c 65 76 65 6c 20 66 69 74 20 69 6e 20 72  f level fit in r
28b60 6f 6f 74 20 64 61 74 61 2e 20 2a 2f 0a 20 20 20  oot data. */.   
28b70 20 64 61 74 61 42 75 66 66 65 72 52 65 70 6c 61   dataBufferRepla
28b80 63 65 28 26 70 52 65 61 64 65 72 2d 3e 72 6f 6f  ce(&pReader->roo
28b90 74 44 61 74 61 2c 20 70 52 6f 6f 74 44 61 74 61  tData, pRootData
28ba0 2c 20 6e 52 6f 6f 74 44 61 74 61 29 3b 0a 20 20  , nRootData);.  
28bb0 20 20 6c 65 61 66 52 65 61 64 65 72 49 6e 69 74    leafReaderInit
28bc0 28 70 52 65 61 64 65 72 2d 3e 72 6f 6f 74 44 61  (pReader->rootDa
28bd0 74 61 2e 70 44 61 74 61 2c 20 70 52 65 61 64 65  ta.pData, pReade
28be0 72 2d 3e 72 6f 6f 74 44 61 74 61 2e 6e 44 61 74  r->rootData.nDat
28bf0 61 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  a,.             
28c00 20 20 20 20 20 20 26 70 52 65 61 64 65 72 2d 3e        &pReader->
28c10 6c 65 61 66 52 65 61 64 65 72 29 3b 0a 20 20 7d  leafReader);.  }
28c20 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65  else{.    sqlite
28c30 33 5f 73 74 6d 74 20 2a 73 3b 0a 20 20 20 20 69  3_stmt *s;.    i
28c40 6e 74 20 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f  nt rc = sql_get_
28c50 6c 65 61 66 5f 73 74 61 74 65 6d 65 6e 74 28 76  leaf_statement(v
28c60 2c 20 69 64 78 2c 20 26 73 29 3b 0a 20 20 20 20  , idx, &s);.    
28c70 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
28c80 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
28c90 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
28ca0 5f 62 69 6e 64 5f 69 6e 74 36 34 28 73 2c 20 31  _bind_int64(s, 1
28cb0 2c 20 69 53 74 61 72 74 42 6c 6f 63 6b 69 64 29  , iStartBlockid)
28cc0 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
28cd0 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
28ce0 20 72 63 3b 0a 0a 20 20 20 20 72 63 20 3d 20 73   rc;..    rc = s
28cf0 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36  qlite3_bind_int6
28d00 34 28 73 2c 20 32 2c 20 69 45 6e 64 42 6c 6f 63  4(s, 2, iEndBloc
28d10 6b 69 64 29 3b 0a 20 20 20 20 69 66 28 20 72 63  kid);.    if( rc
28d20 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
28d30 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20 72 63  turn rc;..    rc
28d40 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28   = sqlite3_step(
28d50 73 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  s);.    if( rc==
28d60 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29 7b 0a 20  SQLITE_DONE ){. 
28d70 20 20 20 20 20 70 52 65 61 64 65 72 2d 3e 65 6f       pReader->eo
28d80 66 20 3d 20 31 3b 0a 20 20 20 20 20 20 72 65 74  f = 1;.      ret
28d90 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  urn SQLITE_OK;. 
28da0 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 21     }.    if( rc!
28db0 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 20 72 65  =SQLITE_ROW ) re
28dc0 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20 70 52  turn rc;..    pR
28dd0 65 61 64 65 72 2d 3e 70 53 74 6d 74 20 3d 20 73  eader->pStmt = s
28de0 3b 0a 20 20 20 20 6c 65 61 66 52 65 61 64 65 72  ;.    leafReader
28df0 49 6e 69 74 28 73 71 6c 69 74 65 33 5f 63 6f 6c  Init(sqlite3_col
28e00 75 6d 6e 5f 62 6c 6f 62 28 70 52 65 61 64 65 72  umn_blob(pReader
28e10 2d 3e 70 53 74 6d 74 2c 20 30 29 2c 0a 20 20 20  ->pStmt, 0),.   
28e20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28e30 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62  sqlite3_column_b
28e40 79 74 65 73 28 70 52 65 61 64 65 72 2d 3e 70 53  ytes(pReader->pS
28e50 74 6d 74 2c 20 30 29 2c 0a 20 20 20 20 20 20 20  tmt, 0),.       
28e60 20 20 20 20 20 20 20 20 20 20 20 20 26 70 52 65              &pRe
28e70 61 64 65 72 2d 3e 6c 65 61 66 52 65 61 64 65 72  ader->leafReader
28e80 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
28e90 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
28ea0 20 53 74 65 70 20 74 68 65 20 63 75 72 72 65 6e   Step the curren
28eb0 74 20 6c 65 61 66 20 66 6f 72 77 61 72 64 20 74  t leaf forward t
28ec0 6f 20 74 68 65 20 6e 65 78 74 20 74 65 72 6d 2e  o the next term.
28ed0 20 20 49 66 20 77 65 20 72 65 61 63 68 20 74 68    If we reach th
28ee0 65 0a 2a 2a 20 65 6e 64 20 6f 66 20 74 68 65 20  e.** end of the 
28ef0 63 75 72 72 65 6e 74 20 6c 65 61 66 2c 20 73 74  current leaf, st
28f00 65 70 20 66 6f 72 77 61 72 64 20 74 6f 20 74 68  ep forward to th
28f10 65 20 6e 65 78 74 20 6c 65 61 66 20 62 6c 6f 63  e next leaf bloc
28f20 6b 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  k..*/.static int
28f30 20 6c 65 61 76 65 73 52 65 61 64 65 72 53 74 65   leavesReaderSte
28f40 70 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20  p(fulltext_vtab 
28f50 2a 76 2c 20 4c 65 61 76 65 73 52 65 61 64 65 72  *v, LeavesReader
28f60 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20 61 73   *pReader){.  as
28f70 73 65 72 74 28 20 21 6c 65 61 76 65 73 52 65 61  sert( !leavesRea
28f80 64 65 72 41 74 45 6e 64 28 70 52 65 61 64 65 72  derAtEnd(pReader
28f90 29 20 29 3b 0a 20 20 6c 65 61 66 52 65 61 64 65  ) );.  leafReade
28fa0 72 53 74 65 70 28 26 70 52 65 61 64 65 72 2d 3e  rStep(&pReader->
28fb0 6c 65 61 66 52 65 61 64 65 72 29 3b 0a 0a 20 20  leafReader);..  
28fc0 69 66 28 20 6c 65 61 66 52 65 61 64 65 72 41 74  if( leafReaderAt
28fd0 45 6e 64 28 26 70 52 65 61 64 65 72 2d 3e 6c 65  End(&pReader->le
28fe0 61 66 52 65 61 64 65 72 29 20 29 7b 0a 20 20 20  afReader) ){.   
28ff0 20 69 6e 74 20 72 63 3b 0a 20 20 20 20 69 66 28   int rc;.    if(
29000 20 70 52 65 61 64 65 72 2d 3e 72 6f 6f 74 44 61   pReader->rootDa
29010 74 61 2e 70 44 61 74 61 20 29 7b 0a 20 20 20 20  ta.pData ){.    
29020 20 20 70 52 65 61 64 65 72 2d 3e 65 6f 66 20 3d    pReader->eof =
29030 20 31 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   1;.      return
29040 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20   SQLITE_OK;.    
29050 7d 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  }.    rc = sqlit
29060 65 33 5f 73 74 65 70 28 70 52 65 61 64 65 72 2d  e3_step(pReader-
29070 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28  >pStmt);.    if(
29080 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20   rc!=SQLITE_ROW 
29090 29 7b 0a 20 20 20 20 20 20 70 52 65 61 64 65 72  ){.      pReader
290a0 2d 3e 65 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20  ->eof = 1;.     
290b0 20 72 65 74 75 72 6e 20 72 63 3d 3d 53 51 4c 49   return rc==SQLI
290c0 54 45 5f 44 4f 4e 45 20 3f 20 53 51 4c 49 54 45  TE_DONE ? SQLITE
290d0 5f 4f 4b 20 3a 20 72 63 3b 0a 20 20 20 20 7d 0a  _OK : rc;.    }.
290e0 20 20 20 20 6c 65 61 66 52 65 61 64 65 72 44 65      leafReaderDe
290f0 73 74 72 6f 79 28 26 70 52 65 61 64 65 72 2d 3e  stroy(&pReader->
29100 6c 65 61 66 52 65 61 64 65 72 29 3b 0a 20 20 20  leafReader);.   
29110 20 6c 65 61 66 52 65 61 64 65 72 49 6e 69 74 28   leafReaderInit(
29120 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62  sqlite3_column_b
29130 6c 6f 62 28 70 52 65 61 64 65 72 2d 3e 70 53 74  lob(pReader->pSt
29140 6d 74 2c 20 30 29 2c 0a 20 20 20 20 20 20 20 20  mt, 0),.        
29150 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
29160 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28  e3_column_bytes(
29170 70 52 65 61 64 65 72 2d 3e 70 53 74 6d 74 2c 20  pReader->pStmt, 
29180 30 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  0),.            
29190 20 20 20 20 20 20 20 26 70 52 65 61 64 65 72 2d         &pReader-
291a0 3e 6c 65 61 66 52 65 61 64 65 72 29 3b 0a 20 20  >leafReader);.  
291b0 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  }.  return SQLIT
291c0 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 4f 72 64 65  E_OK;.}../* Orde
291d0 72 20 4c 65 61 76 65 73 52 65 61 64 65 72 73 20  r LeavesReaders 
291e0 62 79 20 74 68 65 69 72 20 74 65 72 6d 2c 20 69  by their term, i
291f0 67 6e 6f 72 69 6e 67 20 69 64 78 2e 20 20 52 65  gnoring idx.  Re
29200 61 64 65 72 73 20 61 74 20 65 6f 66 0a 2a 2a 20  aders at eof.** 
29210 61 6c 77 61 79 73 20 73 6f 72 74 20 74 6f 20 74  always sort to t
29220 68 65 20 65 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69  he end..*/.stati
29230 63 20 69 6e 74 20 6c 65 61 76 65 73 52 65 61 64  c int leavesRead
29240 65 72 54 65 72 6d 43 6d 70 28 4c 65 61 76 65 73  erTermCmp(Leaves
29250 52 65 61 64 65 72 20 2a 6c 72 31 2c 20 4c 65 61  Reader *lr1, Lea
29260 76 65 73 52 65 61 64 65 72 20 2a 6c 72 32 29 7b  vesReader *lr2){
29270 0a 20 20 69 66 28 20 6c 65 61 76 65 73 52 65 61  .  if( leavesRea
29280 64 65 72 41 74 45 6e 64 28 6c 72 31 29 20 29 7b  derAtEnd(lr1) ){
29290 0a 20 20 20 20 69 66 28 20 6c 65 61 76 65 73 52  .    if( leavesR
292a0 65 61 64 65 72 41 74 45 6e 64 28 6c 72 32 29 20  eaderAtEnd(lr2) 
292b0 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20  ) return 0;.    
292c0 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 0a 20 20  return 1;.  }.  
292d0 69 66 28 20 6c 65 61 76 65 73 52 65 61 64 65 72  if( leavesReader
292e0 41 74 45 6e 64 28 6c 72 32 29 20 29 20 72 65 74  AtEnd(lr2) ) ret
292f0 75 72 6e 20 2d 31 3b 0a 0a 20 20 72 65 74 75 72  urn -1;..  retur
29300 6e 20 6c 65 61 66 52 65 61 64 65 72 54 65 72 6d  n leafReaderTerm
29310 43 6d 70 28 26 6c 72 31 2d 3e 6c 65 61 66 52 65  Cmp(&lr1->leafRe
29320 61 64 65 72 2c 0a 20 20 20 20 20 20 20 20 20 20  ader,.          
29330 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29340 20 6c 65 61 76 65 73 52 65 61 64 65 72 54 65 72   leavesReaderTer
29350 6d 28 6c 72 32 29 2c 20 6c 65 61 76 65 73 52 65  m(lr2), leavesRe
29360 61 64 65 72 54 65 72 6d 42 79 74 65 73 28 6c 72  aderTermBytes(lr
29370 32 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  2),.            
29380 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 30                 0
29390 29 3b 0a 7d 0a 0a 2f 2a 20 53 69 6d 69 6c 61 72  );.}../* Similar
293a0 20 74 6f 20 6c 65 61 76 65 73 52 65 61 64 65 72   to leavesReader
293b0 54 65 72 6d 43 6d 70 28 29 2c 20 77 69 74 68 20  TermCmp(), with 
293c0 61 64 64 69 74 69 6f 6e 61 6c 20 6f 72 64 65 72  additional order
293d0 69 6e 67 20 62 79 20 69 64 78 0a 2a 2a 20 73 6f  ing by idx.** so
293e0 20 74 68 61 74 20 6f 6c 64 65 72 20 73 65 67 6d   that older segm
293f0 65 6e 74 73 20 73 6f 72 74 20 62 65 66 6f 72 65  ents sort before
29400 20 6e 65 77 65 72 20 73 65 67 6d 65 6e 74 73 2e   newer segments.
29410 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6c  .*/.static int l
29420 65 61 76 65 73 52 65 61 64 65 72 43 6d 70 28 4c  eavesReaderCmp(L
29430 65 61 76 65 73 52 65 61 64 65 72 20 2a 6c 72 31  eavesReader *lr1
29440 2c 20 4c 65 61 76 65 73 52 65 61 64 65 72 20 2a  , LeavesReader *
29450 6c 72 32 29 7b 0a 20 20 69 6e 74 20 63 20 3d 20  lr2){.  int c = 
29460 6c 65 61 76 65 73 52 65 61 64 65 72 54 65 72 6d  leavesReaderTerm
29470 43 6d 70 28 6c 72 31 2c 20 6c 72 32 29 3b 0a 20  Cmp(lr1, lr2);. 
29480 20 69 66 28 20 63 21 3d 30 20 29 20 72 65 74 75   if( c!=0 ) retu
29490 72 6e 20 63 3b 0a 20 20 72 65 74 75 72 6e 20 6c  rn c;.  return l
294a0 72 31 2d 3e 69 64 78 2d 6c 72 32 2d 3e 69 64 78  r1->idx-lr2->idx
294b0 3b 0a 7d 0a 0a 2f 2a 20 41 73 73 75 6d 65 20 74  ;.}../* Assume t
294c0 68 61 74 20 70 4c 72 5b 31 5d 2e 2e 70 4c 72 5b  hat pLr[1]..pLr[
294d0 6e 4c 72 5d 20 61 72 65 20 73 6f 72 74 65 64 2e  nLr] are sorted.
294e0 20 20 42 75 62 62 6c 65 20 70 4c 72 5b 30 5d 20    Bubble pLr[0] 
294f0 69 6e 74 6f 20 69 74 73 0a 2a 2a 20 73 6f 72 74  into its.** sort
29500 65 64 20 70 6f 73 69 74 69 6f 6e 2e 0a 2a 2f 0a  ed position..*/.
29510 73 74 61 74 69 63 20 76 6f 69 64 20 6c 65 61 76  static void leav
29520 65 73 52 65 61 64 65 72 52 65 6f 72 64 65 72 28  esReaderReorder(
29530 4c 65 61 76 65 73 52 65 61 64 65 72 20 2a 70 4c  LeavesReader *pL
29540 72 2c 20 69 6e 74 20 6e 4c 72 29 7b 0a 20 20 77  r, int nLr){.  w
29550 68 69 6c 65 28 20 6e 4c 72 3e 31 20 26 26 20 6c  hile( nLr>1 && l
29560 65 61 76 65 73 52 65 61 64 65 72 43 6d 70 28 70  eavesReaderCmp(p
29570 4c 72 2c 20 70 4c 72 2b 31 29 3e 30 20 29 7b 0a  Lr, pLr+1)>0 ){.
29580 20 20 20 20 4c 65 61 76 65 73 52 65 61 64 65 72      LeavesReader
29590 20 74 6d 70 20 3d 20 70 4c 72 5b 30 5d 3b 0a 20   tmp = pLr[0];. 
295a0 20 20 20 70 4c 72 5b 30 5d 20 3d 20 70 4c 72 5b     pLr[0] = pLr[
295b0 31 5d 3b 0a 20 20 20 20 70 4c 72 5b 31 5d 20 3d  1];.    pLr[1] =
295c0 20 74 6d 70 3b 0a 20 20 20 20 6e 4c 72 2d 2d 3b   tmp;.    nLr--;
295d0 0a 20 20 20 20 70 4c 72 2b 2b 3b 0a 20 20 7d 0a  .    pLr++;.  }.
295e0 7d 0a 0a 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65  }../* Initialize
295f0 73 20 70 52 65 61 64 65 72 73 20 77 69 74 68 20  s pReaders with 
29600 74 68 65 20 73 65 67 6d 65 6e 74 73 20 66 72 6f  the segments fro
29610 6d 20 6c 65 76 65 6c 20 69 4c 65 76 65 6c 2c 20  m level iLevel, 
29620 72 65 74 75 72 6e 69 6e 67 0a 2a 2a 20 74 68 65  returning.** the
29630 20 6e 75 6d 62 65 72 20 6f 66 20 73 65 67 6d 65   number of segme
29640 6e 74 73 20 69 6e 20 2a 70 69 52 65 61 64 65 72  nts in *piReader
29650 73 2e 20 20 4c 65 61 76 65 73 20 70 52 65 61 64  s.  Leaves pRead
29660 65 72 73 20 69 6e 20 73 6f 72 74 65 64 0a 2a 2a  ers in sorted.**
29670 20 6f 72 64 65 72 2e 0a 2a 2f 0a 73 74 61 74 69   order..*/.stati
29680 63 20 69 6e 74 20 6c 65 61 76 65 73 52 65 61 64  c int leavesRead
29690 65 72 73 49 6e 69 74 28 66 75 6c 6c 74 65 78 74  ersInit(fulltext
296a0 5f 76 74 61 62 20 2a 76 2c 20 69 6e 74 20 69 4c  _vtab *v, int iL
296b0 65 76 65 6c 2c 0a 20 20 20 20 20 20 20 20 20 20  evel,.          
296c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
296d0 20 20 20 4c 65 61 76 65 73 52 65 61 64 65 72 20     LeavesReader 
296e0 2a 70 52 65 61 64 65 72 73 2c 20 69 6e 74 20 2a  *pReaders, int *
296f0 70 69 52 65 61 64 65 72 73 29 7b 0a 20 20 73 71  piReaders){.  sq
29700 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 3b 0a 20  lite3_stmt *s;. 
29710 20 69 6e 74 20 69 2c 20 72 63 20 3d 20 73 71 6c   int i, rc = sql
29720 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76  _get_statement(v
29730 2c 20 53 45 47 44 49 52 5f 53 45 4c 45 43 54 5f  , SEGDIR_SELECT_
29740 4c 45 56 45 4c 5f 53 54 4d 54 2c 20 26 73 29 3b  LEVEL_STMT, &s);
29750 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
29760 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
29770 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  ;..  rc = sqlite
29780 33 5f 62 69 6e 64 5f 69 6e 74 28 73 2c 20 31 2c  3_bind_int(s, 1,
29790 20 69 4c 65 76 65 6c 29 3b 0a 20 20 69 66 28 20   iLevel);.  if( 
297a0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
297b0 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 69 20  return rc;..  i 
297c0 3d 20 30 3b 0a 20 20 77 68 69 6c 65 28 20 28 72  = 0;.  while( (r
297d0 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70  c = sqlite3_step
297e0 28 73 29 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57  (s))==SQLITE_ROW
297f0 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 5f 69   ){.    sqlite_i
29800 6e 74 36 34 20 69 53 74 61 72 74 20 3d 20 73 71  nt64 iStart = sq
29810 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74  lite3_column_int
29820 36 34 28 73 2c 20 30 29 3b 0a 20 20 20 20 73 71  64(s, 0);.    sq
29830 6c 69 74 65 5f 69 6e 74 36 34 20 69 45 6e 64 20  lite_int64 iEnd 
29840 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
29850 5f 69 6e 74 36 34 28 73 2c 20 31 29 3b 0a 20 20  _int64(s, 1);.  
29860 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 52    const char *pR
29870 6f 6f 74 44 61 74 61 20 3d 20 73 71 6c 69 74 65  ootData = sqlite
29880 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28 73 2c  3_column_blob(s,
29890 20 32 29 3b 0a 20 20 20 20 69 6e 74 20 6e 52 6f   2);.    int nRo
298a0 6f 74 44 61 74 61 20 3d 20 73 71 6c 69 74 65 33  otData = sqlite3
298b0 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 73 2c  _column_bytes(s,
298c0 20 32 29 3b 0a 0a 20 20 20 20 61 73 73 65 72 74   2);..    assert
298d0 28 20 69 3c 4d 45 52 47 45 5f 43 4f 55 4e 54 20  ( i<MERGE_COUNT 
298e0 29 3b 0a 20 20 20 20 72 63 20 3d 20 6c 65 61 76  );.    rc = leav
298f0 65 73 52 65 61 64 65 72 49 6e 69 74 28 76 2c 20  esReaderInit(v, 
29900 69 2c 20 69 53 74 61 72 74 2c 20 69 45 6e 64 2c  i, iStart, iEnd,
29910 20 70 52 6f 6f 74 44 61 74 61 2c 20 6e 52 6f 6f   pRootData, nRoo
29920 74 44 61 74 61 2c 0a 20 20 20 20 20 20 20 20 20  tData,.         
29930 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29940 20 26 70 52 65 61 64 65 72 73 5b 69 5d 29 3b 0a   &pReaders[i]);.
29950 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
29960 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a  TE_OK ) break;..
29970 20 20 20 20 69 2b 2b 3b 0a 20 20 7d 0a 20 20 69      i++;.  }.  i
29980 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 44 4f  f( rc!=SQLITE_DO
29990 4e 45 20 29 7b 0a 20 20 20 20 77 68 69 6c 65 28  NE ){.    while(
299a0 20 69 2d 2d 3e 30 20 29 7b 0a 20 20 20 20 20 20   i-->0 ){.      
299b0 6c 65 61 76 65 73 52 65 61 64 65 72 44 65 73 74  leavesReaderDest
299c0 72 6f 79 28 26 70 52 65 61 64 65 72 73 5b 69 5d  roy(&pReaders[i]
299d0 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74  );.    }.    ret
299e0 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2a  urn rc;.  }..  *
299f0 70 69 52 65 61 64 65 72 73 20 3d 20 69 3b 0a 0a  piReaders = i;..
29a00 20 20 2f 2a 20 4c 65 61 76 65 20 6f 75 72 20 72    /* Leave our r
29a10 65 73 75 6c 74 73 20 73 6f 72 74 65 64 20 62 79  esults sorted by
29a20 20 74 65 72 6d 2c 20 74 68 65 6e 20 61 67 65 2e   term, then age.
29a30 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 69 2d 2d   */.  while( i--
29a40 20 29 7b 0a 20 20 20 20 6c 65 61 76 65 73 52 65   ){.    leavesRe
29a50 61 64 65 72 52 65 6f 72 64 65 72 28 70 52 65 61  aderReorder(pRea
29a60 64 65 72 73 2b 69 2c 20 2a 70 69 52 65 61 64 65  ders+i, *piReade
29a70 72 73 2d 69 29 3b 0a 20 20 7d 0a 20 20 72 65 74  rs-i);.  }.  ret
29a80 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
29a90 0a 0a 2f 2a 20 4d 65 72 67 65 20 64 6f 63 6c 69  ../* Merge docli
29aa0 73 74 73 20 66 72 6f 6d 20 70 52 65 61 64 65 72  sts from pReader
29ab0 73 5b 6e 52 65 61 64 65 72 73 5d 20 69 6e 74 6f  s[nReaders] into
29ac0 20 61 20 73 69 6e 67 6c 65 20 64 6f 63 6c 69 73   a single doclis
29ad0 74 2c 20 77 68 69 63 68 0a 2a 2a 20 69 73 20 77  t, which.** is w
29ae0 72 69 74 74 65 6e 20 74 6f 20 70 57 72 69 74 65  ritten to pWrite
29af0 72 2e 20 20 41 73 73 75 6d 65 73 20 70 52 65 61  r.  Assumes pRea
29b00 64 65 72 73 20 69 73 20 6f 72 64 65 72 65 64 20  ders is ordered 
29b10 6f 6c 64 65 73 74 20 74 6f 0a 2a 2a 20 6e 65 77  oldest to.** new
29b20 65 73 74 2e 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f 28  est..*/./* TODO(
29b30 73 68 65 73 73 29 20 43 6f 6e 73 69 64 65 72 20  shess) Consider 
29b40 70 75 74 74 69 6e 67 20 74 68 69 73 20 69 6e 6c  putting this inl
29b50 69 6e 65 20 69 6e 20 73 65 67 6d 65 6e 74 4d 65  ine in segmentMe
29b60 72 67 65 28 29 2e 20 2a 2f 0a 73 74 61 74 69 63  rge(). */.static
29b70 20 69 6e 74 20 6c 65 61 76 65 73 52 65 61 64 65   int leavesReade
29b80 72 73 4d 65 72 67 65 28 66 75 6c 6c 74 65 78 74  rsMerge(fulltext
29b90 5f 76 74 61 62 20 2a 76 2c 0a 20 20 20 20 20 20  _vtab *v,.      
29ba0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29bb0 20 20 20 20 20 20 20 20 4c 65 61 76 65 73 52 65          LeavesRe
29bc0 61 64 65 72 20 2a 70 52 65 61 64 65 72 73 2c 20  ader *pReaders, 
29bd0 69 6e 74 20 6e 52 65 61 64 65 72 73 2c 0a 20 20  int nReaders,.  
29be0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29bf0 20 20 20 20 20 20 20 20 20 20 20 20 4c 65 61 66              Leaf
29c00 57 72 69 74 65 72 20 2a 70 57 72 69 74 65 72 29  Writer *pWriter)
29c10 7b 0a 20 20 44 4c 52 65 61 64 65 72 20 64 6c 52  {.  DLReader dlR
29c20 65 61 64 65 72 73 5b 4d 45 52 47 45 5f 43 4f 55  eaders[MERGE_COU
29c30 4e 54 5d 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61  NT];.  const cha
29c40 72 20 2a 70 54 65 72 6d 20 3d 20 6c 65 61 76 65  r *pTerm = leave
29c50 73 52 65 61 64 65 72 54 65 72 6d 28 70 52 65 61  sReaderTerm(pRea
29c60 64 65 72 73 29 3b 0a 20 20 69 6e 74 20 69 2c 20  ders);.  int i, 
29c70 6e 54 65 72 6d 20 3d 20 6c 65 61 76 65 73 52 65  nTerm = leavesRe
29c80 61 64 65 72 54 65 72 6d 42 79 74 65 73 28 70 52  aderTermBytes(pR
29c90 65 61 64 65 72 73 29 3b 0a 0a 20 20 61 73 73 65  eaders);..  asse
29ca0 72 74 28 20 6e 52 65 61 64 65 72 73 3c 3d 4d 45  rt( nReaders<=ME
29cb0 52 47 45 5f 43 4f 55 4e 54 20 29 3b 0a 0a 20 20  RGE_COUNT );..  
29cc0 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 52 65 61 64  for(i=0; i<nRead
29cd0 65 72 73 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 64  ers; i++){.    d
29ce0 6c 72 49 6e 69 74 28 26 64 6c 52 65 61 64 65 72  lrInit(&dlReader
29cf0 73 5b 69 5d 2c 20 44 4c 5f 44 45 46 41 55 4c 54  s[i], DL_DEFAULT
29d00 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 65  ,.            le
29d10 61 76 65 73 52 65 61 64 65 72 44 61 74 61 28 70  avesReaderData(p
29d20 52 65 61 64 65 72 73 2b 69 29 2c 0a 20 20 20 20  Readers+i),.    
29d30 20 20 20 20 20 20 20 20 6c 65 61 76 65 73 52 65          leavesRe
29d40 61 64 65 72 44 61 74 61 42 79 74 65 73 28 70 52  aderDataBytes(pR
29d50 65 61 64 65 72 73 2b 69 29 29 3b 0a 20 20 7d 0a  eaders+i));.  }.
29d60 0a 20 20 72 65 74 75 72 6e 20 6c 65 61 66 57 72  .  return leafWr
29d70 69 74 65 72 53 74 65 70 4d 65 72 67 65 28 76 2c  iterStepMerge(v,
29d80 20 70 57 72 69 74 65 72 2c 20 70 54 65 72 6d 2c   pWriter, pTerm,
29d90 20 6e 54 65 72 6d 2c 20 64 6c 52 65 61 64 65 72   nTerm, dlReader
29da0 73 2c 20 6e 52 65 61 64 65 72 73 29 3b 0a 7d 0a  s, nReaders);.}.
29db0 0a 2f 2a 20 46 6f 72 77 61 72 64 20 72 65 66 20  ./* Forward ref 
29dc0 64 75 65 20 74 6f 20 6d 75 74 75 61 6c 20 72 65  due to mutual re
29dd0 63 75 72 73 69 6f 6e 20 77 69 74 68 20 73 65 67  cursion with seg
29de0 64 69 72 4e 65 78 74 49 6e 64 65 78 28 29 2e 20  dirNextIndex(). 
29df0 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
29e00 67 6d 65 6e 74 4d 65 72 67 65 28 66 75 6c 6c 74  gmentMerge(fullt
29e10 65 78 74 5f 76 74 61 62 20 2a 76 2c 20 69 6e 74  ext_vtab *v, int
29e20 20 69 4c 65 76 65 6c 29 3b 0a 0a 2f 2a 20 50 75   iLevel);../* Pu
29e30 74 20 74 68 65 20 6e 65 78 74 20 61 76 61 69 6c  t the next avail
29e40 61 62 6c 65 20 69 6e 64 65 78 20 61 74 20 69 4c  able index at iL
29e50 65 76 65 6c 20 69 6e 74 6f 20 2a 70 69 64 78 2e  evel into *pidx.
29e60 20 20 49 66 20 69 4c 65 76 65 6c 0a 2a 2a 20 61    If iLevel.** a
29e70 6c 72 65 61 64 79 20 68 61 73 20 4d 45 52 47 45  lready has MERGE
29e80 5f 43 4f 55 4e 54 20 73 65 67 6d 65 6e 74 73 2c  _COUNT segments,
29e90 20 74 68 65 79 20 61 72 65 20 6d 65 72 67 65 64   they are merged
29ea0 20 74 6f 20 61 20 68 69 67 68 65 72 0a 2a 2a 20   to a higher.** 
29eb0 6c 65 76 65 6c 20 74 6f 20 6d 61 6b 65 20 72 6f  level to make ro
29ec0 6f 6d 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  om..*/.static in
29ed0 74 20 73 65 67 64 69 72 4e 65 78 74 49 6e 64 65  t segdirNextInde
29ee0 78 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20  x(fulltext_vtab 
29ef0 2a 76 2c 20 69 6e 74 20 69 4c 65 76 65 6c 2c 20  *v, int iLevel, 
29f00 69 6e 74 20 2a 70 69 64 78 29 7b 0a 20 20 69 6e  int *pidx){.  in
29f10 74 20 72 63 20 3d 20 73 65 67 64 69 72 5f 6d 61  t rc = segdir_ma
29f20 78 5f 69 6e 64 65 78 28 76 2c 20 69 4c 65 76 65  x_index(v, iLeve
29f30 6c 2c 20 70 69 64 78 29 3b 0a 20 20 69 66 28 20  l, pidx);.  if( 
29f40 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20  rc==SQLITE_DONE 
29f50 29 7b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ){              
29f60 2f 2a 20 4e 6f 20 73 65 67 6d 65 6e 74 73 20 61  /* No segments a
29f70 74 20 69 4c 65 76 65 6c 2e 20 2a 2f 0a 20 20 20  t iLevel. */.   
29f80 20 2a 70 69 64 78 20 3d 20 30 3b 0a 20 20 7d 65   *pidx = 0;.  }e
29f90 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  lse if( rc==SQLI
29fa0 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 69 66  TE_ROW ){.    if
29fb0 28 20 2a 70 69 64 78 3d 3d 28 4d 45 52 47 45 5f  ( *pidx==(MERGE_
29fc0 43 4f 55 4e 54 2d 31 29 20 29 7b 0a 20 20 20 20  COUNT-1) ){.    
29fd0 20 20 72 63 20 3d 20 73 65 67 6d 65 6e 74 4d 65    rc = segmentMe
29fe0 72 67 65 28 76 2c 20 69 4c 65 76 65 6c 29 3b 0a  rge(v, iLevel);.
29ff0 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
2a000 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
2a010 20 72 63 3b 0a 20 20 20 20 20 20 2a 70 69 64 78   rc;.      *pidx
2a020 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b   = 0;.    }else{
2a030 0a 20 20 20 20 20 20 28 2a 70 69 64 78 29 2b 2b  .      (*pidx)++
2a040 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b  ;.    }.  }else{
2a050 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
2a060 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c    }.  return SQL
2a070 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 4d 65  ITE_OK;.}../* Me
2a080 72 67 65 20 4d 45 52 47 45 5f 43 4f 55 4e 54 20  rge MERGE_COUNT 
2a090 73 65 67 6d 65 6e 74 73 20 61 74 20 69 4c 65 76  segments at iLev
2a0a0 65 6c 20 69 6e 74 6f 20 61 20 6e 65 77 20 73 65  el into a new se
2a0b0 67 6d 65 6e 74 20 61 74 0a 2a 2a 20 69 4c 65 76  gment at.** iLev
2a0c0 65 6c 2b 31 2e 20 20 49 66 20 69 4c 65 76 65 6c  el+1.  If iLevel
2a0d0 2b 31 20 69 73 20 61 6c 72 65 61 64 79 20 66 75  +1 is already fu
2a0e0 6c 6c 20 6f 66 20 73 65 67 6d 65 6e 74 73 2c 20  ll of segments, 
2a0f0 74 68 6f 73 65 20 77 69 6c 6c 20 62 65 0a 2a 2a  those will be.**
2a100 20 6d 65 72 67 65 64 20 74 6f 20 6d 61 6b 65 20   merged to make 
2a110 72 6f 6f 6d 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  room..*/.static 
2a120 69 6e 74 20 73 65 67 6d 65 6e 74 4d 65 72 67 65  int segmentMerge
2a130 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
2a140 76 2c 20 69 6e 74 20 69 4c 65 76 65 6c 29 7b 0a  v, int iLevel){.
2a150 20 20 4c 65 61 66 57 72 69 74 65 72 20 77 72 69    LeafWriter wri
2a160 74 65 72 3b 0a 20 20 4c 65 61 76 65 73 52 65 61  ter;.  LeavesRea
2a170 64 65 72 20 6c 72 73 5b 4d 45 52 47 45 5f 43 4f  der lrs[MERGE_CO
2a180 55 4e 54 5d 3b 0a 20 20 69 6e 74 20 69 2c 20 72  UNT];.  int i, r
2a190 63 2c 20 69 64 78 20 3d 20 30 3b 0a 0a 20 20 2f  c, idx = 0;..  /
2a1a0 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65 20  * Determine the 
2a1b0 6e 65 78 74 20 61 76 61 69 6c 61 62 6c 65 20 73  next available s
2a1c0 65 67 6d 65 6e 74 20 69 6e 64 65 78 20 61 74 20  egment index at 
2a1d0 74 68 65 20 6e 65 78 74 20 6c 65 76 65 6c 2c 0a  the next level,.
2a1e0 20 20 2a 2a 20 6d 65 72 67 69 6e 67 20 61 73 20    ** merging as 
2a1f0 6e 65 63 65 73 73 61 72 79 2e 0a 20 20 2a 2f 0a  necessary..  */.
2a200 20 20 72 63 20 3d 20 73 65 67 64 69 72 4e 65 78    rc = segdirNex
2a210 74 49 6e 64 65 78 28 76 2c 20 69 4c 65 76 65 6c  tIndex(v, iLevel
2a220 2b 31 2c 20 26 69 64 78 29 3b 0a 20 20 69 66 28  +1, &idx);.  if(
2a230 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
2a240 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 2f   return rc;..  /
2a250 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 54 68  * TODO(shess) Th
2a260 69 73 20 61 73 73 75 6d 65 73 20 74 68 61 74 20  is assumes that 
2a270 77 65 27 6c 6c 20 61 6c 77 61 79 73 20 73 65 65  we'll always see
2a280 20 65 78 61 63 74 6c 79 0a 20 20 2a 2a 20 4d 45   exactly.  ** ME
2a290 52 47 45 5f 43 4f 55 4e 54 20 73 65 67 6d 65 6e  RGE_COUNT segmen
2a2a0 74 73 20 74 6f 20 6d 65 72 67 65 20 61 74 20 61  ts to merge at a
2a2b0 20 67 69 76 65 6e 20 6c 65 76 65 6c 2e 20 20 54   given level.  T
2a2c0 68 61 74 20 77 69 6c 6c 20 62 65 0a 20 20 2a 2a  hat will be.  **
2a2d0 20 62 72 6f 6b 65 6e 20 69 66 20 77 65 20 61 6c   broken if we al
2a2e0 6c 6f 77 20 74 68 65 20 64 65 76 65 6c 6f 70 65  low the develope
2a2f0 72 20 74 6f 20 72 65 71 75 65 73 74 20 70 72 65  r to request pre
2a300 65 6d 70 74 69 76 65 20 6f 72 0a 20 20 2a 2a 20  emptive or.  ** 
2a310 64 65 66 65 72 72 65 64 20 6d 65 72 67 69 6e 67  deferred merging
2a320 2e 0a 20 20 2a 2f 0a 20 20 6d 65 6d 73 65 74 28  ..  */.  memset(
2a330 26 6c 72 73 2c 20 27 5c 30 27 2c 20 73 69 7a 65  &lrs, '\0', size
2a340 6f 66 28 6c 72 73 29 29 3b 0a 20 20 72 63 20 3d  of(lrs));.  rc =
2a350 20 6c 65 61 76 65 73 52 65 61 64 65 72 73 49 6e   leavesReadersIn
2a360 69 74 28 76 2c 20 69 4c 65 76 65 6c 2c 20 6c 72  it(v, iLevel, lr
2a370 73 2c 20 26 69 29 3b 0a 20 20 69 66 28 20 72 63  s, &i);.  if( rc
2a380 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
2a390 74 75 72 6e 20 72 63 3b 0a 20 20 61 73 73 65 72  turn rc;.  asser
2a3a0 74 28 20 69 3d 3d 4d 45 52 47 45 5f 43 4f 55 4e  t( i==MERGE_COUN
2a3b0 54 20 29 3b 0a 0a 20 20 6c 65 61 66 57 72 69 74  T );..  leafWrit
2a3c0 65 72 49 6e 69 74 28 69 4c 65 76 65 6c 2b 31 2c  erInit(iLevel+1,
2a3d0 20 69 64 78 2c 20 26 77 72 69 74 65 72 29 3b 0a   idx, &writer);.
2a3e0 0a 20 20 2f 2a 20 53 69 6e 63 65 20 6c 65 61 76  .  /* Since leav
2a3f0 65 73 52 65 61 64 65 72 52 65 6f 72 64 65 72 28  esReaderReorder(
2a400 29 20 70 75 73 68 65 73 20 72 65 61 64 65 72 73  ) pushes readers
2a410 20 61 74 20 65 6f 66 20 74 6f 20 74 68 65 20 65   at eof to the e
2a420 6e 64 2c 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68  nd,.  ** when th
2a430 65 20 66 69 72 73 74 20 72 65 61 64 65 72 20 69  e first reader i
2a440 73 20 65 6d 70 74 79 2c 20 61 6c 6c 20 77 69 6c  s empty, all wil
2a450 6c 20 62 65 20 65 6d 70 74 79 2e 0a 20 20 2a 2f  l be empty..  */
2a460 0a 20 20 77 68 69 6c 65 28 20 21 6c 65 61 76 65  .  while( !leave
2a470 73 52 65 61 64 65 72 41 74 45 6e 64 28 6c 72 73  sReaderAtEnd(lrs
2a480 29 20 29 7b 0a 20 20 20 20 2f 2a 20 46 69 67 75  ) ){.    /* Figu
2a490 72 65 20 6f 75 74 20 68 6f 77 20 6d 61 6e 79 20  re out how many 
2a4a0 72 65 61 64 65 72 73 20 73 68 61 72 65 20 74 68  readers share th
2a4b0 65 69 72 20 6e 65 78 74 20 74 65 72 6d 2e 20 2a  eir next term. *
2a4c0 2f 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69  /.    for(i=1; i
2a4d0 3c 4d 45 52 47 45 5f 43 4f 55 4e 54 20 26 26 20  <MERGE_COUNT && 
2a4e0 21 6c 65 61 76 65 73 52 65 61 64 65 72 41 74 45  !leavesReaderAtE
2a4f0 6e 64 28 6c 72 73 2b 69 29 3b 20 69 2b 2b 29 7b  nd(lrs+i); i++){
2a500 0a 20 20 20 20 20 20 69 66 28 20 30 21 3d 6c 65  .      if( 0!=le
2a510 61 76 65 73 52 65 61 64 65 72 54 65 72 6d 43 6d  avesReaderTermCm
2a520 70 28 6c 72 73 2c 20 6c 72 73 2b 69 29 20 29 20  p(lrs, lrs+i) ) 
2a530 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
2a540 20 20 72 63 20 3d 20 6c 65 61 76 65 73 52 65 61    rc = leavesRea
2a550 64 65 72 73 4d 65 72 67 65 28 76 2c 20 6c 72 73  dersMerge(v, lrs
2a560 2c 20 69 2c 20 26 77 72 69 74 65 72 29 3b 0a 20  , i, &writer);. 
2a570 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
2a580 45 5f 4f 4b 20 29 20 67 6f 74 6f 20 65 72 72 3b  E_OK ) goto err;
2a590 0a 0a 20 20 20 20 2f 2a 20 53 74 65 70 20 66 6f  ..    /* Step fo
2a5a0 72 77 61 72 64 20 74 68 6f 73 65 20 74 68 61 74  rward those that
2a5b0 20 77 65 72 65 20 6d 65 72 67 65 64 2e 20 2a 2f   were merged. */
2a5c0 0a 20 20 20 20 77 68 69 6c 65 28 20 69 2d 2d 3e  .    while( i-->
2a5d0 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  0 ){.      rc = 
2a5e0 6c 65 61 76 65 73 52 65 61 64 65 72 53 74 65 70  leavesReaderStep
2a5f0 28 76 2c 20 6c 72 73 2b 69 29 3b 0a 20 20 20 20  (v, lrs+i);.    
2a600 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
2a610 5f 4f 4b 20 29 20 67 6f 74 6f 20 65 72 72 3b 0a  _OK ) goto err;.
2a620 0a 20 20 20 20 20 20 2f 2a 20 52 65 6f 72 64 65  .      /* Reorde
2a630 72 20 62 79 20 74 65 72 6d 2c 20 74 68 65 6e 20  r by term, then 
2a640 62 79 20 61 67 65 2e 20 2a 2f 0a 20 20 20 20 20  by age. */.     
2a650 20 6c 65 61 76 65 73 52 65 61 64 65 72 52 65 6f   leavesReaderReo
2a660 72 64 65 72 28 6c 72 73 2b 69 2c 20 4d 45 52 47  rder(lrs+i, MERG
2a670 45 5f 43 4f 55 4e 54 2d 69 29 3b 0a 20 20 20 20  E_COUNT-i);.    
2a680 7d 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69 3d 30  }.  }..  for(i=0
2a690 3b 20 69 3c 4d 45 52 47 45 5f 43 4f 55 4e 54 3b  ; i<MERGE_COUNT;
2a6a0 20 69 2b 2b 29 7b 0a 20 20 20 20 6c 65 61 76 65   i++){.    leave
2a6b0 73 52 65 61 64 65 72 44 65 73 74 72 6f 79 28 26  sReaderDestroy(&
2a6c0 6c 72 73 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20  lrs[i]);.  }..  
2a6d0 72 63 20 3d 20 6c 65 61 66 57 72 69 74 65 72 46  rc = leafWriterF
2a6e0 69 6e 61 6c 69 7a 65 28 76 2c 20 26 77 72 69 74  inalize(v, &writ
2a6f0 65 72 29 3b 0a 20 20 6c 65 61 66 57 72 69 74 65  er);.  leafWrite
2a700 72 44 65 73 74 72 6f 79 28 26 77 72 69 74 65 72  rDestroy(&writer
2a710 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
2a720 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
2a730 72 63 3b 0a 0a 20 20 2f 2a 20 44 65 6c 65 74 65  rc;..  /* Delete
2a740 20 74 68 65 20 6d 65 72 67 65 64 20 73 65 67 6d   the merged segm
2a750 65 6e 74 20 64 61 74 61 2e 20 2a 2f 0a 20 20 72  ent data. */.  r
2a760 65 74 75 72 6e 20 73 65 67 64 69 72 5f 64 65 6c  eturn segdir_del
2a770 65 74 65 28 76 2c 20 69 4c 65 76 65 6c 29 3b 0a  ete(v, iLevel);.
2a780 0a 20 65 72 72 3a 0a 20 20 66 6f 72 28 69 3d 30  . err:.  for(i=0
2a790 3b 20 69 3c 4d 45 52 47 45 5f 43 4f 55 4e 54 3b  ; i<MERGE_COUNT;
2a7a0 20 69 2b 2b 29 7b 0a 20 20 20 20 6c 65 61 76 65   i++){.    leave
2a7b0 73 52 65 61 64 65 72 44 65 73 74 72 6f 79 28 26  sReaderDestroy(&
2a7c0 6c 72 73 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 6c  lrs[i]);.  }.  l
2a7d0 65 61 66 57 72 69 74 65 72 44 65 73 74 72 6f 79  eafWriterDestroy
2a7e0 28 26 77 72 69 74 65 72 29 3b 0a 20 20 72 65 74  (&writer);.  ret
2a7f0 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 41 63  urn rc;.}../* Ac
2a800 63 75 6d 75 6c 61 74 65 20 74 68 65 20 75 6e 69  cumulate the uni
2a810 6f 6e 20 6f 66 20 2a 61 63 63 20 61 6e 64 20 2a  on of *acc and *
2a820 70 44 61 74 61 20 69 6e 74 6f 20 2a 61 63 63 2e  pData into *acc.
2a830 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
2a840 64 6f 63 4c 69 73 74 41 63 63 75 6d 75 6c 61 74  docListAccumulat
2a850 65 55 6e 69 6f 6e 28 44 61 74 61 42 75 66 66 65  eUnion(DataBuffe
2a860 72 20 2a 61 63 63 2c 0a 20 20 20 20 20 20 20 20  r *acc,.        
2a870 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a880 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74             const
2a890 20 63 68 61 72 20 2a 70 44 61 74 61 2c 20 69 6e   char *pData, in
2a8a0 74 20 6e 44 61 74 61 29 20 7b 0a 20 20 44 61 74  t nData) {.  Dat
2a8b0 61 42 75 66 66 65 72 20 74 6d 70 20 3d 20 2a 61  aBuffer tmp = *a
2a8c0 63 63 3b 0a 20 20 64 61 74 61 42 75 66 66 65 72  cc;.  dataBuffer
2a8d0 49 6e 69 74 28 61 63 63 2c 20 74 6d 70 2e 6e 44  Init(acc, tmp.nD
2a8e0 61 74 61 2b 6e 44 61 74 61 29 3b 0a 20 20 64 6f  ata+nData);.  do
2a8f0 63 4c 69 73 74 55 6e 69 6f 6e 28 74 6d 70 2e 70  cListUnion(tmp.p
2a900 44 61 74 61 2c 20 74 6d 70 2e 6e 44 61 74 61 2c  Data, tmp.nData,
2a910 20 70 44 61 74 61 2c 20 6e 44 61 74 61 2c 20 61   pData, nData, a
2a920 63 63 29 3b 0a 20 20 64 61 74 61 42 75 66 66 65  cc);.  dataBuffe
2a930 72 44 65 73 74 72 6f 79 28 26 74 6d 70 29 3b 0a  rDestroy(&tmp);.
2a940 7d 0a 0a 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73  }../* TODO(shess
2a950 29 20 49 74 20 6d 69 67 68 74 20 62 65 20 69 6e  ) It might be in
2a960 74 65 72 65 73 74 69 6e 67 20 74 6f 20 65 78 70  teresting to exp
2a970 6c 6f 72 65 20 64 69 66 66 65 72 65 6e 74 20 6d  lore different m
2a980 65 72 67 65 0a 2a 2a 20 73 74 72 61 74 65 67 69  erge.** strategi
2a990 65 73 2c 20 68 65 72 65 2e 20 20 46 6f 72 20 69  es, here.  For i
2a9a0 6e 73 74 61 6e 63 65 2c 20 73 69 6e 63 65 20 74  nstance, since t
2a9b0 68 69 73 20 69 73 20 61 20 73 6f 72 74 65 64 20  his is a sorted 
2a9c0 6d 65 72 67 65 2c 20 77 65 0a 2a 2a 20 63 6f 75  merge, we.** cou
2a9d0 6c 64 20 65 61 73 69 6c 79 20 6d 65 72 67 65 20  ld easily merge 
2a9e0 6d 61 6e 79 20 64 6f 63 6c 69 73 74 73 20 69 6e  many doclists in
2a9f0 20 70 61 72 61 6c 6c 65 6c 2e 20 20 57 69 74 68   parallel.  With
2aa00 20 73 6f 6d 65 0a 2a 2a 20 63 6f 6d 70 72 65 68   some.** compreh
2aa10 65 6e 73 69 6f 6e 20 6f 66 20 74 68 65 20 73 74  ension of the st
2aa20 6f 72 61 67 65 20 66 6f 72 6d 61 74 2c 20 77 65  orage format, we
2aa30 20 63 6f 75 6c 64 20 6d 65 72 67 65 20 61 6c 6c   could merge all
2aa40 20 6f 66 20 74 68 65 0a 2a 2a 20 64 6f 63 6c 69   of the.** docli
2aa50 73 74 73 20 77 69 74 68 69 6e 20 61 20 6c 65 61  sts within a lea
2aa60 66 20 6e 6f 64 65 20 64 69 72 65 63 74 6c 79 20  f node directly 
2aa70 66 72 6f 6d 20 74 68 65 20 6c 65 61 66 20 6e 6f  from the leaf no
2aa80 64 65 27 73 20 73 74 6f 72 61 67 65 2e 0a 2a 2a  de's storage..**
2aa90 20 49 74 20 6d 61 79 20 62 65 20 77 6f 72 74 68   It may be worth
2aaa0 77 68 69 6c 65 20 74 6f 20 6d 65 72 67 65 20 73  while to merge s
2aab0 6d 61 6c 6c 65 72 20 64 6f 63 6c 69 73 74 73 20  maller doclists 
2aac0 62 65 66 6f 72 65 20 6c 61 72 67 65 72 0a 2a 2a  before larger.**
2aad0 20 64 6f 63 6c 69 73 74 73 2c 20 73 69 6e 63 65   doclists, since
2aae0 20 74 68 65 79 20 63 61 6e 20 62 65 20 74 72 61   they can be tra
2aaf0 76 65 72 73 65 64 20 6d 6f 72 65 20 71 75 69 63  versed more quic
2ab00 6b 6c 79 20 2d 20 62 75 74 20 74 68 65 0a 2a 2a  kly - but the.**
2ab10 20 72 65 73 75 6c 74 73 20 6d 61 79 20 68 61 76   results may hav
2ab20 65 20 6c 65 73 73 20 6f 76 65 72 6c 61 70 2c 20  e less overlap, 
2ab30 6d 61 6b 69 6e 67 20 74 68 65 6d 20 6d 6f 72 65  making them more
2ab40 20 65 78 70 65 6e 73 69 76 65 20 69 6e 20 61 0a   expensive in a.
2ab50 2a 2a 20 64 69 66 66 65 72 65 6e 74 20 77 61 79  ** different way
2ab60 2e 0a 2a 2f 0a 0a 2f 2a 20 53 63 61 6e 20 70 52  ..*/../* Scan pR
2ab70 65 61 64 65 72 20 66 6f 72 20 70 54 65 72 6d 2f  eader for pTerm/
2ab80 6e 54 65 72 6d 2c 20 61 6e 64 20 6d 65 72 67 65  nTerm, and merge
2ab90 20 74 68 65 20 74 65 72 6d 27 73 20 64 6f 63 6c   the term's docl
2aba0 69 73 74 20 6f 76 65 72 0a 2a 2a 20 2a 6f 75 74  ist over.** *out
2abb0 20 28 61 6e 79 20 64 6f 63 6c 69 73 74 73 20 77   (any doclists w
2abc0 69 74 68 20 64 75 70 6c 69 63 61 74 65 20 64 6f  ith duplicate do
2abd0 63 69 64 73 20 6f 76 65 72 77 72 69 74 65 20 74  cids overwrite t
2abe0 68 6f 73 65 20 69 6e 20 2a 6f 75 74 29 2e 0a 2a  hose in *out)..*
2abf0 2a 20 49 6e 74 65 72 6e 61 6c 20 66 75 6e 63 74  * Internal funct
2ac00 69 6f 6e 20 66 6f 72 20 6c 6f 61 64 53 65 67 6d  ion for loadSegm
2ac10 65 6e 74 4c 65 61 66 28 29 2e 0a 2a 2f 0a 73 74  entLeaf()..*/.st
2ac20 61 74 69 63 20 69 6e 74 20 6c 6f 61 64 53 65 67  atic int loadSeg
2ac30 6d 65 6e 74 4c 65 61 76 65 73 49 6e 74 28 66 75  mentLeavesInt(fu
2ac40 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20  lltext_vtab *v, 
2ac50 4c 65 61 76 65 73 52 65 61 64 65 72 20 2a 70 52  LeavesReader *pR
2ac60 65 61 64 65 72 2c 0a 20 20 20 20 20 20 20 20 20  eader,.         
2ac70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ac80 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61         const cha
2ac90 72 20 2a 70 54 65 72 6d 2c 20 69 6e 74 20 6e 54  r *pTerm, int nT
2aca0 65 72 6d 2c 20 69 6e 74 20 69 73 50 72 65 66 69  erm, int isPrefi
2acb0 78 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  x,.             
2acc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2acd0 20 20 20 44 61 74 61 42 75 66 66 65 72 20 2a 6f     DataBuffer *o
2ace0 75 74 29 7b 0a 20 20 2f 2a 20 64 6f 63 6c 69 73  ut){.  /* doclis
2acf0 74 20 64 61 74 61 20 69 73 20 61 63 63 75 6d 75  t data is accumu
2ad00 6c 61 74 65 64 20 69 6e 74 6f 20 70 42 75 66 66  lated into pBuff
2ad10 65 72 73 20 73 69 6d 69 6c 61 72 20 74 6f 20 68  ers similar to h
2ad20 6f 77 20 6f 6e 65 20 64 6f 65 73 0a 20 20 2a 2a  ow one does.  **
2ad30 20 69 6e 63 72 65 6d 65 6e 74 20 69 6e 20 62 69   increment in bi
2ad40 6e 61 72 79 20 61 72 69 74 68 6d 65 74 69 63 2e  nary arithmetic.
2ad50 20 20 49 66 20 69 6e 64 65 78 20 30 20 69 73 20    If index 0 is 
2ad60 65 6d 70 74 79 2c 20 74 68 65 20 64 61 74 61 20  empty, the data 
2ad70 69 73 0a 20 20 2a 2a 20 73 74 6f 72 65 64 20 74  is.  ** stored t
2ad80 68 65 72 65 2e 20 20 49 66 20 74 68 65 72 65 20  here.  If there 
2ad90 69 73 20 64 61 74 61 20 74 68 65 72 65 2c 20 69  is data there, i
2ada0 74 20 69 73 20 6d 65 72 67 65 64 20 61 6e 64 20  t is merged and 
2adb0 74 68 65 0a 20 20 2a 2a 20 72 65 73 75 6c 74 73  the.  ** results
2adc0 20 63 61 72 72 69 65 64 20 69 6e 74 6f 20 70 6f   carried into po
2add0 73 69 74 69 6f 6e 20 31 2c 20 77 69 74 68 20 66  sition 1, with f
2ade0 75 72 74 68 65 72 20 6d 65 72 67 65 2d 61 6e 64  urther merge-and
2adf0 2d 63 61 72 72 79 0a 20 20 2a 2a 20 75 6e 74 69  -carry.  ** unti
2ae00 6c 20 61 6e 20 65 6d 70 74 79 20 70 6f 73 69 74  l an empty posit
2ae10 69 6f 6e 20 69 73 20 66 6f 75 6e 64 2e 0a 20 20  ion is found..  
2ae20 2a 2f 0a 20 20 44 61 74 61 42 75 66 66 65 72 20  */.  DataBuffer 
2ae30 2a 70 42 75 66 66 65 72 73 20 3d 20 4e 55 4c 4c  *pBuffers = NULL
2ae40 3b 0a 20 20 69 6e 74 20 6e 42 75 66 66 65 72 73  ;.  int nBuffers
2ae50 20 3d 20 30 2c 20 6e 4d 61 78 42 75 66 66 65 72   = 0, nMaxBuffer
2ae60 73 20 3d 20 30 2c 20 72 63 3b 0a 0a 20 20 61 73  s = 0, rc;..  as
2ae70 73 65 72 74 28 20 6e 54 65 72 6d 3e 30 20 29 3b  sert( nTerm>0 );
2ae80 0a 0a 20 20 66 6f 72 28 72 63 3d 53 51 4c 49 54  ..  for(rc=SQLIT
2ae90 45 5f 4f 4b 3b 20 72 63 3d 3d 53 51 4c 49 54 45  E_OK; rc==SQLITE
2aea0 5f 4f 4b 20 26 26 20 21 6c 65 61 76 65 73 52 65  _OK && !leavesRe
2aeb0 61 64 65 72 41 74 45 6e 64 28 70 52 65 61 64 65  aderAtEnd(pReade
2aec0 72 29 3b 0a 20 20 20 20 20 20 72 63 3d 6c 65 61  r);.      rc=lea
2aed0 76 65 73 52 65 61 64 65 72 53 74 65 70 28 76 2c  vesReaderStep(v,
2aee0 20 70 52 65 61 64 65 72 29 29 7b 0a 20 20 20 20   pReader)){.    
2aef0 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 52  /* TODO(shess) R
2af00 65 61 6c 6c 79 20 77 61 6e 74 20 6c 65 61 76 65  eally want leave
2af10 73 52 65 61 64 65 72 54 65 72 6d 43 6d 70 28 29  sReaderTermCmp()
2af20 2c 20 62 75 74 20 74 68 61 74 20 6e 61 6d 65 20  , but that name 
2af30 69 73 0a 20 20 20 20 2a 2a 20 61 6c 72 65 61 64  is.    ** alread
2af40 79 20 74 61 6b 65 6e 20 74 6f 20 63 6f 6d 70 61  y taken to compa
2af50 72 65 20 74 68 65 20 74 65 72 6d 73 20 6f 66 20  re the terms of 
2af60 74 77 6f 20 4c 65 61 76 65 73 52 65 61 64 65 72  two LeavesReader
2af70 73 2e 20 20 54 68 69 6e 6b 0a 20 20 20 20 2a 2a  s.  Think.    **
2af80 20 6f 6e 20 61 20 62 65 74 74 65 72 20 6e 61 6d   on a better nam
2af90 65 2e 20 20 5b 4d 65 61 6e 77 68 69 6c 65 2c 20  e.  [Meanwhile, 
2afa0 62 72 65 61 6b 20 65 6e 63 61 70 73 75 6c 61 74  break encapsulat
2afb0 69 6f 6e 20 72 61 74 68 65 72 20 74 68 61 6e 0a  ion rather than.
2afc0 20 20 20 20 2a 2a 20 75 73 65 20 61 20 63 6f 6e      ** use a con
2afd0 66 75 73 69 6e 67 20 6e 61 6d 65 2e 5d 0a 20 20  fusing name.].  
2afe0 20 20 2a 2f 0a 20 20 20 20 69 6e 74 20 63 20 3d    */.    int c =
2aff0 20 6c 65 61 66 52 65 61 64 65 72 54 65 72 6d 43   leafReaderTermC
2b000 6d 70 28 26 70 52 65 61 64 65 72 2d 3e 6c 65 61  mp(&pReader->lea
2b010 66 52 65 61 64 65 72 2c 20 70 54 65 72 6d 2c 20  fReader, pTerm, 
2b020 6e 54 65 72 6d 2c 20 69 73 50 72 65 66 69 78 29  nTerm, isPrefix)
2b030 3b 0a 20 20 20 20 69 66 28 20 63 3e 30 20 29 20  ;.    if( c>0 ) 
2b040 62 72 65 61 6b 3b 20 20 20 20 20 20 2f 2a 20 50  break;      /* P
2b050 61 73 74 20 61 6e 79 20 70 6f 73 73 69 62 6c 65  ast any possible
2b060 20 6d 61 74 63 68 65 73 2e 20 2a 2f 0a 20 20 20   matches. */.   
2b070 20 69 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20   if( c==0 ){.   
2b080 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70     const char *p
2b090 44 61 74 61 20 3d 20 6c 65 61 76 65 73 52 65 61  Data = leavesRea
2b0a0 64 65 72 44 61 74 61 28 70 52 65 61 64 65 72 29  derData(pReader)
2b0b0 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 42 75 66  ;.      int iBuf
2b0c0 66 65 72 2c 20 6e 44 61 74 61 20 3d 20 6c 65 61  fer, nData = lea
2b0d0 76 65 73 52 65 61 64 65 72 44 61 74 61 42 79 74  vesReaderDataByt
2b0e0 65 73 28 70 52 65 61 64 65 72 29 3b 0a 0a 20 20  es(pReader);..  
2b0f0 20 20 20 20 2f 2a 20 46 69 6e 64 20 74 68 65 20      /* Find the 
2b100 66 69 72 73 74 20 65 6d 70 74 79 20 62 75 66 66  first empty buff
2b110 65 72 2e 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72  er. */.      for
2b120 28 69 42 75 66 66 65 72 3d 30 3b 20 69 42 75 66  (iBuffer=0; iBuf
2b130 66 65 72 3c 6e 42 75 66 66 65 72 73 3b 20 2b 2b  fer<nBuffers; ++
2b140 69 42 75 66 66 65 72 29 7b 0a 20 20 20 20 20 20  iBuffer){.      
2b150 20 20 69 66 28 20 30 3d 3d 70 42 75 66 66 65 72    if( 0==pBuffer
2b160 73 5b 69 42 75 66 66 65 72 5d 2e 6e 44 61 74 61  s[iBuffer].nData
2b170 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20   ) break;.      
2b180 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 4f 75 74 20  }..      /* Out 
2b190 6f 66 20 62 75 66 66 65 72 73 2c 20 61 64 64 20  of buffers, add 
2b1a0 61 6e 20 65 6d 70 74 79 20 6f 6e 65 2e 20 2a 2f  an empty one. */
2b1b0 0a 20 20 20 20 20 20 69 66 28 20 69 42 75 66 66  .      if( iBuff
2b1c0 65 72 3d 3d 6e 42 75 66 66 65 72 73 20 29 7b 0a  er==nBuffers ){.
2b1d0 20 20 20 20 20 20 20 20 69 66 28 20 6e 42 75 66          if( nBuf
2b1e0 66 65 72 73 3d 3d 6e 4d 61 78 42 75 66 66 65 72  fers==nMaxBuffer
2b1f0 73 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 44  s ){.          D
2b200 61 74 61 42 75 66 66 65 72 20 2a 70 3b 0a 20 20  ataBuffer *p;.  
2b210 20 20 20 20 20 20 20 20 6e 4d 61 78 42 75 66 66          nMaxBuff
2b220 65 72 73 20 2b 3d 20 32 30 3b 0a 0a 20 20 20 20  ers += 20;..    
2b230 20 20 20 20 20 20 2f 2a 20 4d 61 6e 75 61 6c 20        /* Manual 
2b240 72 65 61 6c 6c 6f 63 20 73 6f 20 77 65 20 63 61  realloc so we ca
2b250 6e 20 68 61 6e 64 6c 65 20 4e 55 4c 4c 20 61 70  n handle NULL ap
2b260 70 72 6f 70 72 69 61 74 65 6c 79 2e 20 2a 2f 0a  propriately. */.
2b270 20 20 20 20 20 20 20 20 20 20 70 20 3d 20 73 71            p = sq
2b280 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 4d 61  lite3_malloc(nMa
2b290 78 42 75 66 66 65 72 73 2a 73 69 7a 65 6f 66 28  xBuffers*sizeof(
2b2a0 2a 70 42 75 66 66 65 72 73 29 29 3b 0a 20 20 20  *pBuffers));.   
2b2b0 20 20 20 20 20 20 20 69 66 28 20 70 3d 3d 4e 55         if( p==NU
2b2c0 4c 4c 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  LL ){.          
2b2d0 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
2b2e0 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20 20 20 20  MEM;.           
2b2f0 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
2b300 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 69    }..          i
2b310 66 28 20 6e 42 75 66 66 65 72 73 3e 30 20 29 7b  f( nBuffers>0 ){
2b320 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 73 73  .            ass
2b330 65 72 74 28 70 42 75 66 66 65 72 73 21 3d 4e 55  ert(pBuffers!=NU
2b340 4c 4c 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  LL);.           
2b350 20 6d 65 6d 63 70 79 28 70 2c 20 70 42 75 66 66   memcpy(p, pBuff
2b360 65 72 73 2c 20 6e 42 75 66 66 65 72 73 2a 73 69  ers, nBuffers*si
2b370 7a 65 6f 66 28 2a 70 42 75 66 66 65 72 73 29 29  zeof(*pBuffers))
2b380 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 71  ;.            sq
2b390 6c 69 74 65 33 5f 66 72 65 65 28 70 42 75 66 66  lite3_free(pBuff
2b3a0 65 72 73 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ers);.          
2b3b0 7d 0a 20 20 20 20 20 20 20 20 20 20 70 42 75 66  }.          pBuf
2b3c0 66 65 72 73 20 3d 20 70 3b 0a 20 20 20 20 20 20  fers = p;.      
2b3d0 20 20 7d 0a 20 20 20 20 20 20 20 20 64 61 74 61    }.        data
2b3e0 42 75 66 66 65 72 49 6e 69 74 28 26 28 70 42 75  BufferInit(&(pBu
2b3f0 66 66 65 72 73 5b 6e 42 75 66 66 65 72 73 5d 29  ffers[nBuffers])
2b400 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 6e 42  , 0);.        nB
2b410 75 66 66 65 72 73 2b 2b 3b 0a 20 20 20 20 20 20  uffers++;.      
2b420 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 41 74 20 74  }..      /* At t
2b430 68 69 73 20 70 6f 69 6e 74 2c 20 6d 75 73 74 20  his point, must 
2b440 68 61 76 65 20 61 6e 20 65 6d 70 74 79 20 61 74  have an empty at
2b450 20 69 42 75 66 66 65 72 2e 20 2a 2f 0a 20 20 20   iBuffer. */.   
2b460 20 20 20 61 73 73 65 72 74 28 69 42 75 66 66 65     assert(iBuffe
2b470 72 3c 6e 42 75 66 66 65 72 73 20 26 26 20 70 42  r<nBuffers && pB
2b480 75 66 66 65 72 73 5b 69 42 75 66 66 65 72 5d 2e  uffers[iBuffer].
2b490 6e 44 61 74 61 3d 3d 30 29 3b 0a 0a 20 20 20 20  nData==0);..    
2b4a0 20 20 2f 2a 20 49 66 20 65 6d 70 74 79 20 77 61    /* If empty wa
2b4b0 73 20 66 69 72 73 74 20 62 75 66 66 65 72 2c 20  s first buffer, 
2b4c0 6e 6f 20 6e 65 65 64 20 66 6f 72 20 6d 65 72 67  no need for merg
2b4d0 65 20 6c 6f 67 69 63 2e 20 2a 2f 0a 20 20 20 20  e logic. */.    
2b4e0 20 20 69 66 28 20 69 42 75 66 66 65 72 3d 3d 30    if( iBuffer==0
2b4f0 20 29 7b 0a 20 20 20 20 20 20 20 20 64 61 74 61   ){.        data
2b500 42 75 66 66 65 72 52 65 70 6c 61 63 65 28 26 28  BufferReplace(&(
2b510 70 42 75 66 66 65 72 73 5b 30 5d 29 2c 20 70 44  pBuffers[0]), pD
2b520 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20  ata, nData);.   
2b530 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
2b540 20 20 2f 2a 20 70 41 63 63 20 69 73 20 74 68 65    /* pAcc is the
2b550 20 65 6d 70 74 79 20 62 75 66 66 65 72 20 74 68   empty buffer th
2b560 65 20 6d 65 72 67 65 64 20 64 61 74 61 20 77 69  e merged data wi
2b570 6c 6c 20 65 6e 64 20 75 70 20 69 6e 2e 20 2a 2f  ll end up in. */
2b580 0a 20 20 20 20 20 20 20 20 44 61 74 61 42 75 66  .        DataBuf
2b590 66 65 72 20 2a 70 41 63 63 20 3d 20 26 28 70 42  fer *pAcc = &(pB
2b5a0 75 66 66 65 72 73 5b 69 42 75 66 66 65 72 5d 29  uffers[iBuffer])
2b5b0 3b 0a 20 20 20 20 20 20 20 20 44 61 74 61 42 75  ;.        DataBu
2b5c0 66 66 65 72 20 2a 70 20 3d 20 26 28 70 42 75 66  ffer *p = &(pBuf
2b5d0 66 65 72 73 5b 30 5d 29 3b 0a 0a 20 20 20 20 20  fers[0]);..     
2b5e0 20 20 20 2f 2a 20 48 61 6e 64 6c 65 20 70 6f 73     /* Handle pos
2b5f0 69 74 69 6f 6e 20 30 20 73 70 65 63 69 61 6c 6c  ition 0 speciall
2b600 79 20 74 6f 20 61 76 6f 69 64 20 6e 65 65 64 20  y to avoid need 
2b610 74 6f 20 70 72 69 6d 65 20 70 41 63 63 0a 20 20  to prime pAcc.  
2b620 20 20 20 20 20 20 2a 2a 20 77 69 74 68 20 70 44        ** with pD
2b630 61 74 61 2f 6e 44 61 74 61 2e 0a 20 20 20 20 20  ata/nData..     
2b640 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 64 61     */.        da
2b650 74 61 42 75 66 66 65 72 53 77 61 70 28 70 2c 20  taBufferSwap(p, 
2b660 70 41 63 63 29 3b 0a 20 20 20 20 20 20 20 20 64  pAcc);.        d
2b670 6f 63 4c 69 73 74 41 63 63 75 6d 75 6c 61 74 65  ocListAccumulate
2b680 55 6e 69 6f 6e 28 70 41 63 63 2c 20 70 44 61 74  Union(pAcc, pDat
2b690 61 2c 20 6e 44 61 74 61 29 3b 0a 0a 20 20 20 20  a, nData);..    
2b6a0 20 20 20 20 2f 2a 20 41 63 63 75 6d 75 6c 61 74      /* Accumulat
2b6b0 65 20 72 65 6d 61 69 6e 69 6e 67 20 64 6f 63 6c  e remaining docl
2b6c0 69 73 74 73 20 69 6e 74 6f 20 70 41 63 63 2e 20  ists into pAcc. 
2b6d0 2a 2f 0a 20 20 20 20 20 20 20 20 66 6f 72 28 2b  */.        for(+
2b6e0 2b 70 3b 20 70 3c 70 41 63 63 3b 20 2b 2b 70 29  +p; p<pAcc; ++p)
2b6f0 7b 0a 20 20 20 20 20 20 20 20 20 20 64 6f 63 4c  {.          docL
2b700 69 73 74 41 63 63 75 6d 75 6c 61 74 65 55 6e 69  istAccumulateUni
2b710 6f 6e 28 70 41 63 63 2c 20 70 2d 3e 70 44 61 74  on(pAcc, p->pDat
2b720 61 2c 20 70 2d 3e 6e 44 61 74 61 29 3b 0a 0a 20  a, p->nData);.. 
2b730 20 20 20 20 20 20 20 20 20 2f 2a 20 64 61 74 61           /* data
2b740 42 75 66 66 65 72 52 65 73 65 74 28 29 20 63 6f  BufferReset() co
2b750 75 6c 64 20 61 6c 6c 6f 77 20 61 20 6c 61 72 67  uld allow a larg
2b760 65 20 64 6f 63 6c 69 73 74 20 74 6f 20 62 6c 6f  e doclist to blo
2b770 77 20 75 70 0a 20 20 20 20 20 20 20 20 20 20 2a  w up.          *
2b780 2a 20 6f 75 72 20 6d 65 6d 6f 72 79 20 72 65 71  * our memory req
2b790 75 69 72 65 6d 65 6e 74 73 2e 0a 20 20 20 20 20  uirements..     
2b7a0 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20       */.        
2b7b0 20 20 69 66 28 20 70 2d 3e 6e 43 61 70 61 63 69    if( p->nCapaci
2b7c0 74 79 3c 31 30 32 34 20 29 7b 0a 20 20 20 20 20  ty<1024 ){.     
2b7d0 20 20 20 20 20 20 20 64 61 74 61 42 75 66 66 65         dataBuffe
2b7e0 72 52 65 73 65 74 28 70 29 3b 0a 20 20 20 20 20  rReset(p);.     
2b7f0 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
2b800 20 20 20 20 20 20 20 20 64 61 74 61 42 75 66 66          dataBuff
2b810 65 72 44 65 73 74 72 6f 79 28 70 29 3b 0a 20 20  erDestroy(p);.  
2b820 20 20 20 20 20 20 20 20 20 20 64 61 74 61 42 75            dataBu
2b830 66 66 65 72 49 6e 69 74 28 70 2c 20 30 29 3b 0a  fferInit(p, 0);.
2b840 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
2b850 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
2b860 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 55 6e    }.  }..  /* Un
2b870 69 6f 6e 20 61 6c 6c 20 74 68 65 20 64 6f 63 6c  ion all the docl
2b880 69 73 74 73 20 74 6f 67 65 74 68 65 72 20 69 6e  ists together in
2b890 74 6f 20 2a 6f 75 74 2e 20 2a 2f 0a 20 20 2f 2a  to *out. */.  /*
2b8a0 20 54 4f 44 4f 28 73 68 65 73 73 29 20 57 68 61   TODO(shess) Wha
2b8b0 74 20 69 66 20 2a 6f 75 74 20 69 73 20 62 69 67  t if *out is big
2b8c0 3f 20 20 53 69 67 68 2e 20 2a 2f 0a 20 20 69 66  ?  Sigh. */.  if
2b8d0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
2b8e0 26 26 20 6e 42 75 66 66 65 72 73 3e 30 20 29 7b  && nBuffers>0 ){
2b8f0 0a 20 20 20 20 69 6e 74 20 69 42 75 66 66 65 72  .    int iBuffer
2b900 3b 0a 20 20 20 20 66 6f 72 28 69 42 75 66 66 65  ;.    for(iBuffe
2b910 72 3d 30 3b 20 69 42 75 66 66 65 72 3c 6e 42 75  r=0; iBuffer<nBu
2b920 66 66 65 72 73 3b 20 2b 2b 69 42 75 66 66 65 72  ffers; ++iBuffer
2b930 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 42 75  ){.      if( pBu
2b940 66 66 65 72 73 5b 69 42 75 66 66 65 72 5d 2e 6e  ffers[iBuffer].n
2b950 44 61 74 61 3e 30 20 29 7b 0a 20 20 20 20 20 20  Data>0 ){.      
2b960 20 20 69 66 28 20 6f 75 74 2d 3e 6e 44 61 74 61    if( out->nData
2b970 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
2b980 20 64 61 74 61 42 75 66 66 65 72 53 77 61 70 28   dataBufferSwap(
2b990 6f 75 74 2c 20 26 28 70 42 75 66 66 65 72 73 5b  out, &(pBuffers[
2b9a0 69 42 75 66 66 65 72 5d 29 29 3b 0a 20 20 20 20  iBuffer]));.    
2b9b0 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
2b9c0 20 20 20 20 20 64 6f 63 4c 69 73 74 41 63 63 75       docListAccu
2b9d0 6d 75 6c 61 74 65 55 6e 69 6f 6e 28 6f 75 74 2c  mulateUnion(out,
2b9e0 20 70 42 75 66 66 65 72 73 5b 69 42 75 66 66 65   pBuffers[iBuffe
2b9f0 72 5d 2e 70 44 61 74 61 2c 0a 20 20 20 20 20 20  r].pData,.      
2ba00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ba10 20 20 20 20 20 20 20 20 20 20 20 70 42 75 66 66             pBuff
2ba20 65 72 73 5b 69 42 75 66 66 65 72 5d 2e 6e 44 61  ers[iBuffer].nDa
2ba30 74 61 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ta);.        }. 
2ba40 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
2ba50 0a 0a 20 20 77 68 69 6c 65 28 20 6e 42 75 66 66  ..  while( nBuff
2ba60 65 72 73 2d 2d 20 29 7b 0a 20 20 20 20 64 61 74  ers-- ){.    dat
2ba70 61 42 75 66 66 65 72 44 65 73 74 72 6f 79 28 26  aBufferDestroy(&
2ba80 28 70 42 75 66 66 65 72 73 5b 6e 42 75 66 66 65  (pBuffers[nBuffe
2ba90 72 73 5d 29 29 3b 0a 20 20 7d 0a 20 20 69 66 28  rs]));.  }.  if(
2baa0 20 70 42 75 66 66 65 72 73 21 3d 4e 55 4c 4c 20   pBuffers!=NULL 
2bab0 29 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70  ) sqlite3_free(p
2bac0 42 75 66 66 65 72 73 29 3b 0a 0a 20 20 72 65 74  Buffers);..  ret
2bad0 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 43 61  urn rc;.}../* Ca
2bae0 6c 6c 20 6c 6f 61 64 53 65 67 6d 65 6e 74 4c 65  ll loadSegmentLe
2baf0 61 76 65 73 49 6e 74 28 29 20 77 69 74 68 20 70  avesInt() with p
2bb00 44 61 74 61 2f 6e 44 61 74 61 20 61 73 20 69 6e  Data/nData as in
2bb10 70 75 74 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69  put. */.static i
2bb20 6e 74 20 6c 6f 61 64 53 65 67 6d 65 6e 74 4c 65  nt loadSegmentLe
2bb30 61 66 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62  af(fulltext_vtab
2bb40 20 2a 76 2c 20 63 6f 6e 73 74 20 63 68 61 72 20   *v, const char 
2bb50 2a 70 44 61 74 61 2c 20 69 6e 74 20 6e 44 61 74  *pData, int nDat
2bb60 61 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  a,.             
2bb70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63 6f                co
2bb80 6e 73 74 20 63 68 61 72 20 2a 70 54 65 72 6d 2c  nst char *pTerm,
2bb90 20 69 6e 74 20 6e 54 65 72 6d 2c 20 69 6e 74 20   int nTerm, int 
2bba0 69 73 50 72 65 66 69 78 2c 0a 20 20 20 20 20 20  isPrefix,.      
2bbb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2bbc0 20 20 20 20 20 44 61 74 61 42 75 66 66 65 72 20       DataBuffer 
2bbd0 2a 6f 75 74 29 7b 0a 20 20 4c 65 61 76 65 73 52  *out){.  LeavesR
2bbe0 65 61 64 65 72 20 72 65 61 64 65 72 3b 0a 20 20  eader reader;.  
2bbf0 69 6e 74 20 72 63 3b 0a 0a 20 20 61 73 73 65 72  int rc;..  asser
2bc00 74 28 20 6e 44 61 74 61 3e 31 20 29 3b 0a 20 20  t( nData>1 );.  
2bc10 61 73 73 65 72 74 28 20 2a 70 44 61 74 61 3d 3d  assert( *pData==
2bc20 27 5c 30 27 20 29 3b 0a 20 20 72 63 20 3d 20 6c  '\0' );.  rc = l
2bc30 65 61 76 65 73 52 65 61 64 65 72 49 6e 69 74 28  eavesReaderInit(
2bc40 76 2c 20 30 2c 20 30 2c 20 30 2c 20 70 44 61 74  v, 0, 0, 0, pDat
2bc50 61 2c 20 6e 44 61 74 61 2c 20 26 72 65 61 64 65  a, nData, &reade
2bc60 72 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  r);.  if( rc!=SQ
2bc70 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
2bc80 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 6c 6f 61   rc;..  rc = loa
2bc90 64 53 65 67 6d 65 6e 74 4c 65 61 76 65 73 49 6e  dSegmentLeavesIn
2bca0 74 28 76 2c 20 26 72 65 61 64 65 72 2c 20 70 54  t(v, &reader, pT
2bcb0 65 72 6d 2c 20 6e 54 65 72 6d 2c 20 69 73 50 72  erm, nTerm, isPr
2bcc0 65 66 69 78 2c 20 6f 75 74 29 3b 0a 20 20 6c 65  efix, out);.  le
2bcd0 61 76 65 73 52 65 61 64 65 72 52 65 73 65 74 28  avesReaderReset(
2bce0 26 72 65 61 64 65 72 29 3b 0a 20 20 6c 65 61 76  &reader);.  leav
2bcf0 65 73 52 65 61 64 65 72 44 65 73 74 72 6f 79 28  esReaderDestroy(
2bd00 26 72 65 61 64 65 72 29 3b 0a 20 20 72 65 74 75  &reader);.  retu
2bd10 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 43 61 6c  rn rc;.}../* Cal
2bd20 6c 20 6c 6f 61 64 53 65 67 6d 65 6e 74 4c 65 61  l loadSegmentLea
2bd30 76 65 73 49 6e 74 28 29 20 77 69 74 68 20 74 68  vesInt() with th
2bd40 65 20 6c 65 61 66 20 6e 6f 64 65 73 20 66 72 6f  e leaf nodes fro
2bd50 6d 20 69 53 74 61 72 74 4c 65 61 66 20 74 6f 0a  m iStartLeaf to.
2bd60 2a 2a 20 69 45 6e 64 4c 65 61 66 20 28 69 6e 63  ** iEndLeaf (inc
2bd70 6c 75 73 69 76 65 29 20 61 73 20 69 6e 70 75 74  lusive) as input
2bd80 2c 20 61 6e 64 20 6d 65 72 67 65 20 74 68 65 20  , and merge the 
2bd90 72 65 73 75 6c 74 69 6e 67 20 64 6f 63 6c 69 73  resulting doclis
2bda0 74 20 69 6e 74 6f 0a 2a 2a 20 6f 75 74 2e 0a 2a  t into.** out..*
2bdb0 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6c 6f 61  /.static int loa
2bdc0 64 53 65 67 6d 65 6e 74 4c 65 61 76 65 73 28 66  dSegmentLeaves(f
2bdd0 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c  ulltext_vtab *v,
2bde0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2bdf0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
2be00 6c 69 74 65 5f 69 6e 74 36 34 20 69 53 74 61 72  lite_int64 iStar
2be10 74 4c 65 61 66 2c 20 73 71 6c 69 74 65 5f 69 6e  tLeaf, sqlite_in
2be20 74 36 34 20 69 45 6e 64 4c 65 61 66 2c 0a 20 20  t64 iEndLeaf,.  
2be30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2be40 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74             const
2be50 20 63 68 61 72 20 2a 70 54 65 72 6d 2c 20 69 6e   char *pTerm, in
2be60 74 20 6e 54 65 72 6d 2c 20 69 6e 74 20 69 73 50  t nTerm, int isP
2be70 72 65 66 69 78 2c 0a 20 20 20 20 20 20 20 20 20  refix,.         
2be80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2be90 20 20 20 20 44 61 74 61 42 75 66 66 65 72 20 2a      DataBuffer *
2bea0 6f 75 74 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  out){.  int rc;.
2beb0 20 20 4c 65 61 76 65 73 52 65 61 64 65 72 20 72    LeavesReader r
2bec0 65 61 64 65 72 3b 0a 0a 20 20 61 73 73 65 72 74  eader;..  assert
2bed0 28 20 69 53 74 61 72 74 4c 65 61 66 3c 3d 69 45  ( iStartLeaf<=iE
2bee0 6e 64 4c 65 61 66 20 29 3b 0a 20 20 72 63 20 3d  ndLeaf );.  rc =
2bef0 20 6c 65 61 76 65 73 52 65 61 64 65 72 49 6e 69   leavesReaderIni
2bf00 74 28 76 2c 20 30 2c 20 69 53 74 61 72 74 4c 65  t(v, 0, iStartLe
2bf10 61 66 2c 20 69 45 6e 64 4c 65 61 66 2c 20 4e 55  af, iEndLeaf, NU
2bf20 4c 4c 2c 20 30 2c 20 26 72 65 61 64 65 72 29 3b  LL, 0, &reader);
2bf30 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
2bf40 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
2bf50 3b 0a 0a 20 20 72 63 20 3d 20 6c 6f 61 64 53 65  ;..  rc = loadSe
2bf60 67 6d 65 6e 74 4c 65 61 76 65 73 49 6e 74 28 76  gmentLeavesInt(v
2bf70 2c 20 26 72 65 61 64 65 72 2c 20 70 54 65 72 6d  , &reader, pTerm
2bf80 2c 20 6e 54 65 72 6d 2c 20 69 73 50 72 65 66 69  , nTerm, isPrefi
2bf90 78 2c 20 6f 75 74 29 3b 0a 20 20 6c 65 61 76 65  x, out);.  leave
2bfa0 73 52 65 61 64 65 72 52 65 73 65 74 28 26 72 65  sReaderReset(&re
2bfb0 61 64 65 72 29 3b 0a 20 20 6c 65 61 76 65 73 52  ader);.  leavesR
2bfc0 65 61 64 65 72 44 65 73 74 72 6f 79 28 26 72 65  eaderDestroy(&re
2bfd0 61 64 65 72 29 3b 0a 20 20 72 65 74 75 72 6e 20  ader);.  return 
2bfe0 72 63 3b 0a 7d 0a 0a 2f 2a 20 54 61 6b 69 6e 67  rc;.}../* Taking
2bff0 20 70 44 61 74 61 2f 6e 44 61 74 61 20 61 73 20   pData/nData as 
2c000 61 6e 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65  an interior node
2c010 2c 20 66 69 6e 64 20 74 68 65 20 73 65 71 75 65  , find the seque
2c020 6e 63 65 20 6f 66 20 63 68 69 6c 64 0a 2a 2a 20  nce of child.** 
2c030 6e 6f 64 65 73 20 77 68 69 63 68 20 63 6f 75 6c  nodes which coul
2c040 64 20 69 6e 63 6c 75 64 65 20 70 54 65 72 6d 2f  d include pTerm/
2c050 6e 54 65 72 6d 2f 69 73 50 72 65 66 69 78 2e 20  nTerm/isPrefix. 
2c060 20 4e 6f 74 65 20 74 68 61 74 20 74 68 65 0a 2a   Note that the.*
2c070 2a 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65 20  * interior node 
2c080 74 65 72 6d 73 20 6c 6f 67 69 63 61 6c 6c 79 20  terms logically 
2c090 63 6f 6d 65 20 62 65 74 77 65 65 6e 20 74 68 65  come between the
2c0a0 20 62 6c 6f 63 6b 73 2c 20 73 6f 20 74 68 65 72   blocks, so ther
2c0b0 65 20 69 73 0a 2a 2a 20 6f 6e 65 20 6d 6f 72 65  e is.** one more
2c0c0 20 62 6c 6f 63 6b 69 64 20 74 68 61 6e 20 74 68   blockid than th
2c0d0 65 72 65 20 61 72 65 20 74 65 72 6d 73 20 28 74  ere are terms (t
2c0e0 68 61 74 20 62 6c 6f 63 6b 20 63 6f 6e 74 61 69  hat block contai
2c0f0 6e 73 20 74 65 72 6d 73 20 3e 3d 0a 2a 2a 20 74  ns terms >=.** t
2c100 68 65 20 6c 61 73 74 20 69 6e 74 65 72 69 6f 72  he last interior
2c110 2d 6e 6f 64 65 20 74 65 72 6d 29 2e 0a 2a 2f 0a  -node term)..*/.
2c120 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 54  /* TODO(shess) T
2c130 68 65 20 63 61 6c 6c 69 6e 67 20 63 6f 64 65 20  he calling code 
2c140 6d 61 79 20 61 6c 72 65 61 64 79 20 6b 6e 6f 77  may already know
2c150 20 74 68 61 74 20 74 68 65 20 65 6e 64 20 63 68   that the end ch
2c160 69 6c 64 20 69 73 0a 2a 2a 20 6e 6f 74 20 77 6f  ild is.** not wo
2c170 72 74 68 20 63 61 6c 63 75 6c 61 74 69 6e 67 2c  rth calculating,
2c180 20 62 65 63 61 75 73 65 20 74 68 65 20 65 6e 64   because the end
2c190 20 6d 61 79 20 62 65 20 69 6e 20 61 20 6c 61 74   may be in a lat
2c1a0 65 72 20 73 69 62 6c 69 6e 67 0a 2a 2a 20 6e 6f  er sibling.** no
2c1b0 64 65 2e 20 20 43 6f 6e 73 69 64 65 72 20 77 68  de.  Consider wh
2c1c0 65 74 68 65 72 20 62 72 65 61 6b 69 6e 67 20 73  ether breaking s
2c1d0 79 6d 6d 65 74 72 79 20 69 73 20 77 6f 72 74 68  ymmetry is worth
2c1e0 77 68 69 6c 65 2e 20 20 49 20 73 75 73 70 65 63  while.  I suspec
2c1f0 74 0a 2a 2a 20 69 74 20 69 73 20 6e 6f 74 20 77  t.** it is not w
2c200 6f 72 74 68 77 68 69 6c 65 2e 0a 2a 2f 0a 73 74  orthwhile..*/.st
2c210 61 74 69 63 20 76 6f 69 64 20 67 65 74 43 68 69  atic void getChi
2c220 6c 64 72 65 6e 43 6f 6e 74 61 69 6e 69 6e 67 28  ldrenContaining(
2c230 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 44 61 74  const char *pDat
2c240 61 2c 20 69 6e 74 20 6e 44 61 74 61 2c 0a 20 20  a, int nData,.  
2c250 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2c260 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2c270 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65 72  const char *pTer
2c280 6d 2c 20 69 6e 74 20 6e 54 65 72 6d 2c 20 69 6e  m, int nTerm, in
2c290 74 20 69 73 50 72 65 66 69 78 2c 0a 20 20 20 20  t isPrefix,.    
2c2a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2c2b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
2c2c0 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 69 53 74  lite_int64 *piSt
2c2d0 61 72 74 43 68 69 6c 64 2c 0a 20 20 20 20 20 20  artChild,.      
2c2e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2c2f0 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
2c300 74 65 5f 69 6e 74 36 34 20 2a 70 69 45 6e 64 43  te_int64 *piEndC
2c310 68 69 6c 64 29 7b 0a 20 20 49 6e 74 65 72 69 6f  hild){.  Interio
2c320 72 52 65 61 64 65 72 20 72 65 61 64 65 72 3b 0a  rReader reader;.
2c330 0a 20 20 61 73 73 65 72 74 28 20 6e 44 61 74 61  .  assert( nData
2c340 3e 31 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  >1 );.  assert( 
2c350 2a 70 44 61 74 61 21 3d 27 5c 30 27 20 29 3b 0a  *pData!='\0' );.
2c360 20 20 69 6e 74 65 72 69 6f 72 52 65 61 64 65 72    interiorReader
2c370 49 6e 69 74 28 70 44 61 74 61 2c 20 6e 44 61 74  Init(pData, nDat
2c380 61 2c 20 26 72 65 61 64 65 72 29 3b 0a 0a 20 20  a, &reader);..  
2c390 2f 2a 20 53 63 61 6e 20 66 6f 72 20 74 68 65 20  /* Scan for the 
2c3a0 66 69 72 73 74 20 63 68 69 6c 64 20 77 68 69 63  first child whic
2c3b0 68 20 63 6f 75 6c 64 20 63 6f 6e 74 61 69 6e 20  h could contain 
2c3c0 70 54 65 72 6d 2f 6e 54 65 72 6d 2e 20 2a 2f 0a  pTerm/nTerm. */.
2c3d0 20 20 77 68 69 6c 65 28 20 21 69 6e 74 65 72 69    while( !interi
2c3e0 6f 72 52 65 61 64 65 72 41 74 45 6e 64 28 26 72  orReaderAtEnd(&r
2c3f0 65 61 64 65 72 29 20 29 7b 0a 20 20 20 20 69 66  eader) ){.    if
2c400 28 20 69 6e 74 65 72 69 6f 72 52 65 61 64 65 72  ( interiorReader
2c410 54 65 72 6d 43 6d 70 28 26 72 65 61 64 65 72 2c  TermCmp(&reader,
2c420 20 70 54 65 72 6d 2c 20 6e 54 65 72 6d 2c 20 30   pTerm, nTerm, 0
2c430 29 3e 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  )>0 ) break;.   
2c440 20 69 6e 74 65 72 69 6f 72 52 65 61 64 65 72 53   interiorReaderS
2c450 74 65 70 28 26 72 65 61 64 65 72 29 3b 0a 20 20  tep(&reader);.  
2c460 7d 0a 20 20 2a 70 69 53 74 61 72 74 43 68 69 6c  }.  *piStartChil
2c470 64 20 3d 20 69 6e 74 65 72 69 6f 72 52 65 61 64  d = interiorRead
2c480 65 72 43 75 72 72 65 6e 74 42 6c 6f 63 6b 69 64  erCurrentBlockid
2c490 28 26 72 65 61 64 65 72 29 3b 0a 0a 20 20 2f 2a  (&reader);..  /*
2c4a0 20 4b 65 65 70 20 73 63 61 6e 6e 69 6e 67 20 74   Keep scanning t
2c4b0 6f 20 66 69 6e 64 20 61 20 74 65 72 6d 20 67 72  o find a term gr
2c4c0 65 61 74 65 72 20 74 68 61 6e 20 6f 75 72 20 74  eater than our t
2c4d0 65 72 6d 2c 20 75 73 69 6e 67 20 70 72 65 66 69  erm, using prefi
2c4e0 78 0a 20 20 2a 2a 20 63 6f 6d 70 61 72 69 73 6f  x.  ** compariso
2c4f0 6e 20 69 66 20 69 6e 64 69 63 61 74 65 64 2e 20  n if indicated. 
2c500 20 49 66 20 69 73 50 72 65 66 69 78 20 69 73 20   If isPrefix is 
2c510 66 61 6c 73 65 2c 20 74 68 69 73 20 77 69 6c 6c  false, this will
2c520 20 62 65 20 74 68 65 0a 20 20 2a 2a 20 73 61 6d   be the.  ** sam
2c530 65 20 62 6c 6f 63 6b 69 64 20 61 73 20 74 68 65  e blockid as the
2c540 20 73 74 61 72 74 69 6e 67 20 62 6c 6f 63 6b 2e   starting block.
2c550 0a 20 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 21  .  */.  while( !
2c560 69 6e 74 65 72 69 6f 72 52 65 61 64 65 72 41 74  interiorReaderAt
2c570 45 6e 64 28 26 72 65 61 64 65 72 29 20 29 7b 0a  End(&reader) ){.
2c580 20 20 20 20 69 66 28 20 69 6e 74 65 72 69 6f 72      if( interior
2c590 52 65 61 64 65 72 54 65 72 6d 43 6d 70 28 26 72  ReaderTermCmp(&r
2c5a0 65 61 64 65 72 2c 20 70 54 65 72 6d 2c 20 6e 54  eader, pTerm, nT
2c5b0 65 72 6d 2c 20 69 73 50 72 65 66 69 78 29 3e 30  erm, isPrefix)>0
2c5c0 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 69 6e   ) break;.    in
2c5d0 74 65 72 69 6f 72 52 65 61 64 65 72 53 74 65 70  teriorReaderStep
2c5e0 28 26 72 65 61 64 65 72 29 3b 0a 20 20 7d 0a 20  (&reader);.  }. 
2c5f0 20 2a 70 69 45 6e 64 43 68 69 6c 64 20 3d 20 69   *piEndChild = i
2c600 6e 74 65 72 69 6f 72 52 65 61 64 65 72 43 75 72  nteriorReaderCur
2c610 72 65 6e 74 42 6c 6f 63 6b 69 64 28 26 72 65 61  rentBlockid(&rea
2c620 64 65 72 29 3b 0a 0a 20 20 69 6e 74 65 72 69 6f  der);..  interio
2c630 72 52 65 61 64 65 72 44 65 73 74 72 6f 79 28 26  rReaderDestroy(&
2c640 72 65 61 64 65 72 29 3b 0a 0a 20 20 2f 2a 20 43  reader);..  /* C
2c650 68 69 6c 64 72 65 6e 20 6d 75 73 74 20 61 73 63  hildren must asc
2c660 65 6e 64 2c 20 61 6e 64 20 69 66 20 21 70 72 65  end, and if !pre
2c670 66 69 78 2c 20 62 6f 74 68 20 6d 75 73 74 20 62  fix, both must b
2c680 65 20 74 68 65 20 73 61 6d 65 2e 20 2a 2f 0a 20  e the same. */. 
2c690 20 61 73 73 65 72 74 28 20 2a 70 69 45 6e 64 43   assert( *piEndC
2c6a0 68 69 6c 64 3e 3d 2a 70 69 53 74 61 72 74 43 68  hild>=*piStartCh
2c6b0 69 6c 64 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ild );.  assert(
2c6c0 20 69 73 50 72 65 66 69 78 20 7c 7c 20 2a 70 69   isPrefix || *pi
2c6d0 53 74 61 72 74 43 68 69 6c 64 3d 3d 2a 70 69 45  StartChild==*piE
2c6e0 6e 64 43 68 69 6c 64 20 29 3b 0a 7d 0a 0a 2f 2a  ndChild );.}../*
2c6f0 20 52 65 61 64 20 62 6c 6f 63 6b 20 61 74 20 69   Read block at i
2c700 42 6c 6f 63 6b 69 64 20 61 6e 64 20 70 61 73 73  Blockid and pass
2c710 20 69 74 20 77 69 74 68 20 6f 74 68 65 72 20 70   it with other p
2c720 61 72 61 6d 73 20 74 6f 0a 2a 2a 20 67 65 74 43  arams to.** getC
2c730 68 69 6c 64 72 65 6e 43 6f 6e 74 61 69 6e 69 6e  hildrenContainin
2c740 67 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  g()..*/.static i
2c750 6e 74 20 6c 6f 61 64 41 6e 64 47 65 74 43 68 69  nt loadAndGetChi
2c760 6c 64 72 65 6e 43 6f 6e 74 61 69 6e 69 6e 67 28  ldrenContaining(
2c770 0a 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62  .  fulltext_vtab
2c780 20 2a 76 2c 0a 20 20 73 71 6c 69 74 65 5f 69 6e   *v,.  sqlite_in
2c790 74 36 34 20 69 42 6c 6f 63 6b 69 64 2c 0a 20 20  t64 iBlockid,.  
2c7a0 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65 72  const char *pTer
2c7b0 6d 2c 20 69 6e 74 20 6e 54 65 72 6d 2c 20 69 6e  m, int nTerm, in
2c7c0 74 20 69 73 50 72 65 66 69 78 2c 0a 20 20 73 71  t isPrefix,.  sq
2c7d0 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 69 53 74  lite_int64 *piSt
2c7e0 61 72 74 43 68 69 6c 64 2c 20 73 71 6c 69 74 65  artChild, sqlite
2c7f0 5f 69 6e 74 36 34 20 2a 70 69 45 6e 64 43 68 69  _int64 *piEndChi
2c800 6c 64 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  ld.){.  sqlite3_
2c810 73 74 6d 74 20 2a 73 20 3d 20 4e 55 4c 4c 3b 0a  stmt *s = NULL;.
2c820 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 61 73 73    int rc;..  ass
2c830 65 72 74 28 20 69 42 6c 6f 63 6b 69 64 21 3d 30  ert( iBlockid!=0
2c840 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 54   );.  assert( pT
2c850 65 72 6d 21 3d 4e 55 4c 4c 20 29 3b 0a 20 20 61  erm!=NULL );.  a
2c860 73 73 65 72 74 28 20 6e 54 65 72 6d 21 3d 30 20  ssert( nTerm!=0 
2c870 29 3b 20 20 20 20 20 20 20 20 2f 2a 20 54 4f 44  );        /* TOD
2c880 4f 28 73 68 65 73 73 29 20 57 68 79 20 6e 6f 74  O(shess) Why not
2c890 20 61 6c 6c 6f 77 20 74 68 69 73 3f 20 2a 2f 0a   allow this? */.
2c8a0 20 20 61 73 73 65 72 74 28 20 70 69 53 74 61 72    assert( piStar
2c8b0 74 43 68 69 6c 64 21 3d 4e 55 4c 4c 20 29 3b 0a  tChild!=NULL );.
2c8c0 20 20 61 73 73 65 72 74 28 20 70 69 45 6e 64 43    assert( piEndC
2c8d0 68 69 6c 64 21 3d 4e 55 4c 4c 20 29 3b 0a 0a 20  hild!=NULL );.. 
2c8e0 20 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74   rc = sql_get_st
2c8f0 61 74 65 6d 65 6e 74 28 76 2c 20 42 4c 4f 43 4b  atement(v, BLOCK
2c900 5f 53 45 4c 45 43 54 5f 53 54 4d 54 2c 20 26 73  _SELECT_STMT, &s
2c910 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
2c920 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
2c930 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69  rc;..  rc = sqli
2c940 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 73  te3_bind_int64(s
2c950 2c 20 31 2c 20 69 42 6c 6f 63 6b 69 64 29 3b 0a  , 1, iBlockid);.
2c960 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
2c970 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
2c980 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ..  rc = sqlite3
2c990 5f 73 74 65 70 28 73 29 3b 0a 20 20 69 66 28 20  _step(s);.  if( 
2c9a0 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20  rc==SQLITE_DONE 
2c9b0 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
2c9c0 45 52 52 4f 52 3b 0a 20 20 69 66 28 20 72 63 21  ERROR;.  if( rc!
2c9d0 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 20 72 65  =SQLITE_ROW ) re
2c9e0 74 75 72 6e 20 72 63 3b 0a 0a 20 20 67 65 74 43  turn rc;..  getC
2c9f0 68 69 6c 64 72 65 6e 43 6f 6e 74 61 69 6e 69 6e  hildrenContainin
2ca00 67 28 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  g(sqlite3_column
2ca10 5f 62 6c 6f 62 28 73 2c 20 30 29 2c 20 73 71 6c  _blob(s, 0), sql
2ca20 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65  ite3_column_byte
2ca30 73 28 73 2c 20 30 29 2c 0a 20 20 20 20 20 20 20  s(s, 0),.       
2ca40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ca50 20 70 54 65 72 6d 2c 20 6e 54 65 72 6d 2c 20 69   pTerm, nTerm, i
2ca60 73 50 72 65 66 69 78 2c 20 70 69 53 74 61 72 74  sPrefix, piStart
2ca70 43 68 69 6c 64 2c 20 70 69 45 6e 64 43 68 69 6c  Child, piEndChil
2ca80 64 29 3b 0a 0a 20 20 2f 2a 20 57 65 20 65 78 70  d);..  /* We exp
2ca90 65 63 74 20 6f 6e 6c 79 20 6f 6e 65 20 72 6f 77  ect only one row
2caa0 2e 20 20 57 65 20 6d 75 73 74 20 65 78 65 63 75  .  We must execu
2cab0 74 65 20 61 6e 6f 74 68 65 72 20 73 71 6c 69 74  te another sqlit
2cac0 65 33 5f 73 74 65 70 28 29 0a 20 20 20 2a 20 74  e3_step().   * t
2cad0 6f 20 63 6f 6d 70 6c 65 74 65 20 74 68 65 20 69  o complete the i
2cae0 74 65 72 61 74 69 6f 6e 3b 20 6f 74 68 65 72 77  teration; otherw
2caf0 69 73 65 20 74 68 65 20 74 61 62 6c 65 20 77 69  ise the table wi
2cb00 6c 6c 20 72 65 6d 61 69 6e 0a 20 20 20 2a 20 6c  ll remain.   * l
2cb10 6f 63 6b 65 64 2e 20 2a 2f 0a 20 20 72 63 20 3d  ocked. */.  rc =
2cb20 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 73 29   sqlite3_step(s)
2cb30 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
2cb40 54 45 5f 52 4f 57 20 29 20 72 65 74 75 72 6e 20  TE_ROW ) return 
2cb50 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
2cb60 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 44  if( rc!=SQLITE_D
2cb70 4f 4e 45 20 29 20 72 65 74 75 72 6e 20 72 63 3b  ONE ) return rc;
2cb80 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ..  return SQLIT
2cb90 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 54 72 61 76  E_OK;.}../* Trav
2cba0 65 72 73 65 20 74 68 65 20 74 72 65 65 20 72 65  erse the tree re
2cbb0 70 72 65 73 65 6e 74 65 64 20 62 79 20 70 44 61  presented by pDa
2cbc0 74 61 5b 6e 44 61 74 61 5d 20 6c 6f 6f 6b 69 6e  ta[nData] lookin
2cbd0 67 20 66 6f 72 0a 2a 2a 20 70 54 65 72 6d 5b 6e  g for.** pTerm[n
2cbe0 54 65 72 6d 5d 2c 20 70 6c 61 63 69 6e 67 20 69  Term], placing i
2cbf0 74 73 20 64 6f 63 6c 69 73 74 20 69 6e 74 6f 20  ts doclist into 
2cc00 2a 6f 75 74 2e 20 20 54 68 69 73 20 69 73 20 69  *out.  This is i
2cc10 6e 74 65 72 6e 61 6c 20 74 6f 0a 2a 2a 20 6c 6f  nternal to.** lo
2cc20 61 64 53 65 67 6d 65 6e 74 28 29 20 74 6f 20 6d  adSegment() to m
2cc30 61 6b 65 20 65 72 72 6f 72 2d 68 61 6e 64 6c 69  ake error-handli
2cc40 6e 67 20 63 6c 65 61 6e 65 72 2e 0a 2a 2f 0a 73  ng cleaner..*/.s
2cc50 74 61 74 69 63 20 69 6e 74 20 6c 6f 61 64 53 65  tatic int loadSe
2cc60 67 6d 65 6e 74 49 6e 74 28 66 75 6c 6c 74 65 78  gmentInt(fulltex
2cc70 74 5f 76 74 61 62 20 2a 76 2c 20 63 6f 6e 73 74  t_vtab *v, const
2cc80 20 63 68 61 72 20 2a 70 44 61 74 61 2c 20 69 6e   char *pData, in
2cc90 74 20 6e 44 61 74 61 2c 0a 20 20 20 20 20 20 20  t nData,.       
2cca0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ccb0 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20     sqlite_int64 
2ccc0 69 4c 65 61 76 65 73 45 6e 64 2c 0a 20 20 20 20  iLeavesEnd,.    
2ccd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2cce0 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
2ccf0 20 2a 70 54 65 72 6d 2c 20 69 6e 74 20 6e 54 65   *pTerm, int nTe
2cd00 72 6d 2c 20 69 6e 74 20 69 73 50 72 65 66 69 78  rm, int isPrefix
2cd10 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
2cd20 20 20 20 20 20 20 20 20 20 20 20 20 44 61 74 61              Data
2cd30 42 75 66 66 65 72 20 2a 6f 75 74 29 7b 0a 20 20  Buffer *out){.  
2cd40 2f 2a 20 53 70 65 63 69 61 6c 20 63 61 73 65 20  /* Special case 
2cd50 77 68 65 72 65 20 72 6f 6f 74 20 69 73 20 61 20  where root is a 
2cd60 6c 65 61 66 2e 20 2a 2f 0a 20 20 69 66 28 20 2a  leaf. */.  if( *
2cd70 70 44 61 74 61 3d 3d 27 5c 30 27 20 29 7b 0a 20  pData=='\0' ){. 
2cd80 20 20 20 72 65 74 75 72 6e 20 6c 6f 61 64 53 65     return loadSe
2cd90 67 6d 65 6e 74 4c 65 61 66 28 76 2c 20 70 44 61  gmentLeaf(v, pDa
2cda0 74 61 2c 20 6e 44 61 74 61 2c 20 70 54 65 72 6d  ta, nData, pTerm
2cdb0 2c 20 6e 54 65 72 6d 2c 20 69 73 50 72 65 66 69  , nTerm, isPrefi
2cdc0 78 2c 20 6f 75 74 29 3b 0a 20 20 7d 65 6c 73 65  x, out);.  }else
2cdd0 7b 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a 20 20  {.    int rc;.  
2cde0 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69    sqlite_int64 i
2cdf0 53 74 61 72 74 43 68 69 6c 64 2c 20 69 45 6e 64  StartChild, iEnd
2ce00 43 68 69 6c 64 3b 0a 0a 20 20 20 20 2f 2a 20 50  Child;..    /* P
2ce10 72 6f 63 65 73 73 20 70 44 61 74 61 20 61 73 20  rocess pData as 
2ce20 61 6e 20 69 6e 74 65 72 69 6f 72 20 6e 6f 64 65  an interior node
2ce30 2c 20 74 68 65 6e 20 6c 6f 6f 70 20 64 6f 77 6e  , then loop down
2ce40 20 74 68 65 20 74 72 65 65 0a 20 20 20 20 2a 2a   the tree.    **
2ce50 20 75 6e 74 69 6c 20 77 65 20 66 69 6e 64 20 74   until we find t
2ce60 68 65 20 73 65 74 20 6f 66 20 6c 65 61 66 20 6e  he set of leaf n
2ce70 6f 64 65 73 20 74 6f 20 73 63 61 6e 20 66 6f 72  odes to scan for
2ce80 20 74 68 65 20 74 65 72 6d 2e 0a 20 20 20 20 2a   the term..    *
2ce90 2f 0a 20 20 20 20 67 65 74 43 68 69 6c 64 72 65  /.    getChildre
2cea0 6e 43 6f 6e 74 61 69 6e 69 6e 67 28 70 44 61 74  nContaining(pDat
2ceb0 61 2c 20 6e 44 61 74 61 2c 20 70 54 65 72 6d 2c  a, nData, pTerm,
2cec0 20 6e 54 65 72 6d 2c 20 69 73 50 72 65 66 69 78   nTerm, isPrefix
2ced0 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
2cee0 20 20 20 20 20 20 20 20 20 20 20 20 26 69 53 74              &iSt
2cef0 61 72 74 43 68 69 6c 64 2c 20 26 69 45 6e 64 43  artChild, &iEndC
2cf00 68 69 6c 64 29 3b 0a 20 20 20 20 77 68 69 6c 65  hild);.    while
2cf10 28 20 69 53 74 61 72 74 43 68 69 6c 64 3e 69 4c  ( iStartChild>iL
2cf20 65 61 76 65 73 45 6e 64 20 29 7b 0a 20 20 20 20  eavesEnd ){.    
2cf30 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69    sqlite_int64 i
2cf40 4e 65 78 74 53 74 61 72 74 2c 20 69 4e 65 78 74  NextStart, iNext
2cf50 45 6e 64 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  End;.      rc = 
2cf60 6c 6f 61 64 41 6e 64 47 65 74 43 68 69 6c 64 72  loadAndGetChildr
2cf70 65 6e 43 6f 6e 74 61 69 6e 69 6e 67 28 76 2c 20  enContaining(v, 
2cf80 69 53 74 61 72 74 43 68 69 6c 64 2c 20 70 54 65  iStartChild, pTe
2cf90 72 6d 2c 20 6e 54 65 72 6d 2c 20 69 73 50 72 65  rm, nTerm, isPre
2cfa0 66 69 78 2c 0a 20 20 20 20 20 20 20 20 20 20 20  fix,.           
2cfb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2cfc0 20 20 20 20 20 20 20 20 20 20 20 20 20 26 69 4e               &iN
2cfd0 65 78 74 53 74 61 72 74 2c 20 26 69 4e 65 78 74  extStart, &iNext
2cfe0 45 6e 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20  End);.      if( 
2cff0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
2d000 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 20 20  return rc;..    
2d010 20 20 2f 2a 20 49 66 20 77 65 27 76 65 20 62 72    /* If we've br
2d020 61 6e 63 68 65 64 2c 20 66 6f 6c 6c 6f 77 20 74  anched, follow t
2d030 68 65 20 65 6e 64 20 62 72 61 6e 63 68 2c 20 74  he end branch, t
2d040 6f 6f 2e 20 2a 2f 0a 20 20 20 20 20 20 69 66 28  oo. */.      if(
2d050 20 69 53 74 61 72 74 43 68 69 6c 64 21 3d 69 45   iStartChild!=iE
2d060 6e 64 43 68 69 6c 64 20 29 7b 0a 20 20 20 20 20  ndChild ){.     
2d070 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20     sqlite_int64 
2d080 69 44 75 6d 6d 79 3b 0a 20 20 20 20 20 20 20 20  iDummy;.        
2d090 72 63 20 3d 20 6c 6f 61 64 41 6e 64 47 65 74 43  rc = loadAndGetC
2d0a0 68 69 6c 64 72 65 6e 43 6f 6e 74 61 69 6e 69 6e  hildrenContainin
2d0b0 67 28 76 2c 20 69 45 6e 64 43 68 69 6c 64 2c 20  g(v, iEndChild, 
2d0c0 70 54 65 72 6d 2c 20 6e 54 65 72 6d 2c 20 69 73  pTerm, nTerm, is
2d0d0 50 72 65 66 69 78 2c 0a 20 20 20 20 20 20 20 20  Prefix,.        
2d0e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d0f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d100 20 20 26 69 44 75 6d 6d 79 2c 20 26 69 4e 65 78    &iDummy, &iNex
2d110 74 45 6e 64 29 3b 0a 20 20 20 20 20 20 20 20 69  tEnd);.        i
2d120 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
2d130 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
2d140 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 61 73 73      }..      ass
2d150 65 72 74 28 20 69 4e 65 78 74 53 74 61 72 74 3c  ert( iNextStart<
2d160 3d 69 4e 65 78 74 45 6e 64 20 29 3b 0a 20 20 20  =iNextEnd );.   
2d170 20 20 20 69 53 74 61 72 74 43 68 69 6c 64 20 3d     iStartChild =
2d180 20 69 4e 65 78 74 53 74 61 72 74 3b 0a 20 20 20   iNextStart;.   
2d190 20 20 20 69 45 6e 64 43 68 69 6c 64 20 3d 20 69     iEndChild = i
2d1a0 4e 65 78 74 45 6e 64 3b 0a 20 20 20 20 7d 0a 20  NextEnd;.    }. 
2d1b0 20 20 20 61 73 73 65 72 74 28 20 69 53 74 61 72     assert( iStar
2d1c0 74 43 68 69 6c 64 3c 3d 69 4c 65 61 76 65 73 45  tChild<=iLeavesE
2d1d0 6e 64 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  nd );.    assert
2d1e0 28 20 69 45 6e 64 43 68 69 6c 64 3c 3d 69 4c 65  ( iEndChild<=iLe
2d1f0 61 76 65 73 45 6e 64 20 29 3b 0a 0a 20 20 20 20  avesEnd );..    
2d200 2f 2a 20 53 63 61 6e 20 74 68 72 6f 75 67 68 20  /* Scan through 
2d210 74 68 65 20 6c 65 61 66 20 73 65 67 6d 65 6e 74  the leaf segment
2d220 73 20 66 6f 72 20 64 6f 63 6c 69 73 74 73 2e 20  s for doclists. 
2d230 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 6c 6f  */.    return lo
2d240 61 64 53 65 67 6d 65 6e 74 4c 65 61 76 65 73 28  adSegmentLeaves(
2d250 76 2c 20 69 53 74 61 72 74 43 68 69 6c 64 2c 20  v, iStartChild, 
2d260 69 45 6e 64 43 68 69 6c 64 2c 0a 20 20 20 20 20  iEndChild,.     
2d270 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d280 20 20 20 20 20 20 20 20 70 54 65 72 6d 2c 20 6e          pTerm, n
2d290 54 65 72 6d 2c 20 69 73 50 72 65 66 69 78 2c 20  Term, isPrefix, 
2d2a0 6f 75 74 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20  out);.  }.}../* 
2d2b0 43 61 6c 6c 20 6c 6f 61 64 53 65 67 6d 65 6e 74  Call loadSegment
2d2c0 49 6e 74 28 29 20 74 6f 20 63 6f 6c 6c 65 63 74  Int() to collect
2d2d0 20 74 68 65 20 64 6f 63 6c 69 73 74 20 66 6f 72   the doclist for
2d2e0 20 70 54 65 72 6d 2f 6e 54 65 72 6d 2c 20 74 68   pTerm/nTerm, th
2d2f0 65 6e 0a 2a 2a 20 6d 65 72 67 65 20 69 74 73 20  en.** merge its 
2d300 64 6f 63 6c 69 73 74 20 6f 76 65 72 20 2a 6f 75  doclist over *ou
2d310 74 20 28 61 6e 79 20 64 75 70 6c 69 63 61 74 65  t (any duplicate
2d320 20 64 6f 63 6c 69 73 74 73 20 72 65 61 64 20 66   doclists read f
2d330 72 6f 6d 20 74 68 65 0a 2a 2a 20 73 65 67 6d 65  rom the.** segme
2d340 6e 74 20 72 6f 6f 74 65 64 20 61 74 20 70 44 61  nt rooted at pDa
2d350 74 61 20 77 69 6c 6c 20 6f 76 65 72 77 72 69 74  ta will overwrit
2d360 65 20 74 68 6f 73 65 20 69 6e 20 2a 6f 75 74 29  e those in *out)
2d370 2e 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f 28 73 68 65  ..*/./* TODO(she
2d380 73 73 29 20 43 6f 6e 73 69 64 65 72 20 63 68 61  ss) Consider cha
2d390 6e 67 69 6e 67 20 74 68 69 73 20 74 6f 20 64 65  nging this to de
2d3a0 74 65 72 6d 69 6e 65 20 74 68 65 20 64 65 70 74  termine the dept
2d3b0 68 20 6f 66 20 74 68 65 0a 2a 2a 20 6c 65 61 76  h of the.** leav
2d3c0 65 73 20 75 73 69 6e 67 20 65 69 74 68 65 72 20  es using either 
2d3d0 74 68 65 20 66 69 72 73 74 20 63 68 61 72 61 63  the first charac
2d3e0 74 65 72 73 20 6f 66 20 69 6e 74 65 72 69 6f 72  ters of interior
2d3f0 20 6e 6f 64 65 73 20 28 77 68 65 6e 0a 2a 2a 20   nodes (when.** 
2d400 3d 3d 31 2c 20 77 65 27 72 65 20 6f 6e 65 20 6c  ==1, we're one l
2d410 65 76 65 6c 20 61 62 6f 76 65 20 74 68 65 20 6c  evel above the l
2d420 65 61 76 65 73 29 2c 20 6f 72 20 74 68 65 20 66  eaves), or the f
2d430 69 72 73 74 20 63 68 61 72 61 63 74 65 72 20 6f  irst character o
2d440 66 0a 2a 2a 20 74 68 65 20 72 6f 6f 74 20 28 77  f.** the root (w
2d450 68 69 63 68 20 77 69 6c 6c 20 64 65 73 63 72 69  hich will descri
2d460 62 65 20 74 68 65 20 68 65 69 67 68 74 20 6f 66  be the height of
2d470 20 74 68 65 20 74 72 65 65 20 64 69 72 65 63 74   the tree direct
2d480 6c 79 29 2e 0a 2a 2a 20 45 69 74 68 65 72 20 66  ly)..** Either f
2d490 65 65 6c 73 20 73 6f 6d 65 77 68 61 74 20 74 72  eels somewhat tr
2d4a0 69 63 6b 79 20 74 6f 20 6d 65 2e 0a 2a 2f 0a 2f  icky to me..*/./
2d4b0 2a 20 54 4f 44 4f 28 73 68 65 73 73 29 20 54 68  * TODO(shess) Th
2d4c0 65 20 63 75 72 72 65 6e 74 20 6d 65 72 67 65 20  e current merge 
2d4d0 69 73 20 6c 69 6b 65 6c 79 20 74 6f 20 62 65 20  is likely to be 
2d4e0 73 6c 6f 77 20 66 6f 72 20 6c 61 72 67 65 0a 2a  slow for large.*
2d4f0 2a 20 64 6f 63 6c 69 73 74 73 20 28 74 68 6f 75  * doclists (thou
2d500 67 68 20 69 74 20 73 68 6f 75 6c 64 20 70 72 6f  gh it should pro
2d510 63 65 73 73 20 66 72 6f 6d 20 6e 65 77 65 73 74  cess from newest
2d520 2f 73 6d 61 6c 6c 65 73 74 20 74 6f 0a 2a 2a 20  /smallest to.** 
2d530 6f 6c 64 65 73 74 2f 6c 61 72 67 65 73 74 2c 20  oldest/largest, 
2d540 73 6f 20 69 74 20 6d 61 79 20 6e 6f 74 20 62 65  so it may not be
2d550 20 74 68 61 74 20 62 61 64 29 2e 20 20 49 74 20   that bad).  It 
2d560 6d 69 67 68 74 20 62 65 20 75 73 65 66 75 6c 20  might be useful 
2d570 74 6f 0a 2a 2a 20 6d 6f 64 69 66 79 20 74 68 69  to.** modify thi
2d580 6e 67 73 20 74 6f 20 61 6c 6c 6f 77 20 66 6f 72  ngs to allow for
2d590 20 4e 2d 77 61 79 20 6d 65 72 67 69 6e 67 2e 20   N-way merging. 
2d5a0 20 54 68 69 73 20 63 6f 75 6c 64 20 65 69 74 68   This could eith
2d5b0 65 72 20 62 65 0a 2a 2a 20 77 69 74 68 69 6e 20  er be.** within 
2d5c0 61 20 73 65 67 6d 65 6e 74 2c 20 77 69 74 68 20  a segment, with 
2d5d0 70 61 69 72 77 69 73 65 20 6d 65 72 67 65 73 20  pairwise merges 
2d5e0 61 63 72 6f 73 73 20 73 65 67 6d 65 6e 74 73 2c  across segments,
2d5f0 20 6f 72 20 61 63 72 6f 73 73 0a 2a 2a 20 61 6c   or across.** al
2d600 6c 20 73 65 67 6d 65 6e 74 73 20 61 74 20 6f 6e  l segments at on
2d610 63 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ce..*/.static in
2d620 74 20 6c 6f 61 64 53 65 67 6d 65 6e 74 28 66 75  t loadSegment(fu
2d630 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20  lltext_vtab *v, 
2d640 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 44 61 74  const char *pDat
2d650 61 2c 20 69 6e 74 20 6e 44 61 74 61 2c 0a 20 20  a, int nData,.  
2d660 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d670 20 20 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36       sqlite_int6
2d680 34 20 69 4c 65 61 76 65 73 45 6e 64 2c 0a 20 20  4 iLeavesEnd,.  
2d690 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d6a0 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20       const char 
2d6b0 2a 70 54 65 72 6d 2c 20 69 6e 74 20 6e 54 65 72  *pTerm, int nTer
2d6c0 6d 2c 20 69 6e 74 20 69 73 50 72 65 66 69 78 2c  m, int isPrefix,
2d6d0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2d6e0 20 20 20 20 20 20 20 20 44 61 74 61 42 75 66 66          DataBuff
2d6f0 65 72 20 2a 6f 75 74 29 7b 0a 20 20 44 61 74 61  er *out){.  Data
2d700 42 75 66 66 65 72 20 72 65 73 75 6c 74 3b 0a 20  Buffer result;. 
2d710 20 69 6e 74 20 72 63 3b 0a 0a 20 20 61 73 73 65   int rc;..  asse
2d720 72 74 28 20 6e 44 61 74 61 3e 31 20 29 3b 0a 0a  rt( nData>1 );..
2d730 20 20 2f 2a 20 54 68 69 73 20 63 6f 64 65 20 73    /* This code s
2d740 68 6f 75 6c 64 20 6e 65 76 65 72 20 62 65 20 63  hould never be c
2d750 61 6c 6c 65 64 20 77 69 74 68 20 62 75 66 66 65  alled with buffe
2d760 72 65 64 20 75 70 64 61 74 65 73 2e 20 2a 2f 0a  red updates. */.
2d770 20 20 61 73 73 65 72 74 28 20 76 2d 3e 6e 50 65    assert( v->nPe
2d780 6e 64 69 6e 67 44 61 74 61 3c 30 20 29 3b 0a 0a  ndingData<0 );..
2d790 20 20 64 61 74 61 42 75 66 66 65 72 49 6e 69 74    dataBufferInit
2d7a0 28 26 72 65 73 75 6c 74 2c 20 30 29 3b 0a 20 20  (&result, 0);.  
2d7b0 72 63 20 3d 20 6c 6f 61 64 53 65 67 6d 65 6e 74  rc = loadSegment
2d7c0 49 6e 74 28 76 2c 20 70 44 61 74 61 2c 20 6e 44  Int(v, pData, nD
2d7d0 61 74 61 2c 20 69 4c 65 61 76 65 73 45 6e 64 2c  ata, iLeavesEnd,
2d7e0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2d7f0 20 20 20 20 20 20 20 70 54 65 72 6d 2c 20 6e 54         pTerm, nT
2d800 65 72 6d 2c 20 69 73 50 72 65 66 69 78 2c 20 26  erm, isPrefix, &
2d810 72 65 73 75 6c 74 29 3b 0a 20 20 69 66 28 20 72  result);.  if( r
2d820 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
2d830 72 65 73 75 6c 74 2e 6e 44 61 74 61 3e 30 20 29  result.nData>0 )
2d840 7b 0a 20 20 20 20 69 66 28 20 6f 75 74 2d 3e 6e  {.    if( out->n
2d850 44 61 74 61 3d 3d 30 20 29 7b 0a 20 20 20 20 20  Data==0 ){.     
2d860 20 44 61 74 61 42 75 66 66 65 72 20 74 6d 70 20   DataBuffer tmp 
2d870 3d 20 2a 6f 75 74 3b 0a 20 20 20 20 20 20 2a 6f  = *out;.      *o
2d880 75 74 20 3d 20 72 65 73 75 6c 74 3b 0a 20 20 20  ut = result;.   
2d890 20 20 20 72 65 73 75 6c 74 20 3d 20 74 6d 70 3b     result = tmp;
2d8a0 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
2d8b0 20 20 44 61 74 61 42 75 66 66 65 72 20 6d 65 72    DataBuffer mer
2d8c0 67 65 64 3b 0a 20 20 20 20 20 20 44 4c 52 65 61  ged;.      DLRea
2d8d0 64 65 72 20 72 65 61 64 65 72 73 5b 32 5d 3b 0a  der readers[2];.
2d8e0 0a 20 20 20 20 20 20 64 6c 72 49 6e 69 74 28 26  .      dlrInit(&
2d8f0 72 65 61 64 65 72 73 5b 30 5d 2c 20 44 4c 5f 44  readers[0], DL_D
2d900 45 46 41 55 4c 54 2c 20 6f 75 74 2d 3e 70 44 61  EFAULT, out->pDa
2d910 74 61 2c 20 6f 75 74 2d 3e 6e 44 61 74 61 29 3b  ta, out->nData);
2d920 0a 20 20 20 20 20 20 64 6c 72 49 6e 69 74 28 26  .      dlrInit(&
2d930 72 65 61 64 65 72 73 5b 31 5d 2c 20 44 4c 5f 44  readers[1], DL_D
2d940 45 46 41 55 4c 54 2c 20 72 65 73 75 6c 74 2e 70  EFAULT, result.p
2d950 44 61 74 61 2c 20 72 65 73 75 6c 74 2e 6e 44 61  Data, result.nDa
2d960 74 61 29 3b 0a 20 20 20 20 20 20 64 61 74 61 42  ta);.      dataB
2d970 75 66 66 65 72 49 6e 69 74 28 26 6d 65 72 67 65  ufferInit(&merge
2d980 64 2c 20 6f 75 74 2d 3e 6e 44 61 74 61 2b 72 65  d, out->nData+re
2d990 73 75 6c 74 2e 6e 44 61 74 61 29 3b 0a 20 20 20  sult.nData);.   
2d9a0 20 20 20 64 6f 63 4c 69 73 74 4d 65 72 67 65 28     docListMerge(
2d9b0 26 6d 65 72 67 65 64 2c 20 72 65 61 64 65 72 73  &merged, readers
2d9c0 2c 20 32 29 3b 0a 20 20 20 20 20 20 64 61 74 61  , 2);.      data
2d9d0 42 75 66 66 65 72 44 65 73 74 72 6f 79 28 6f 75  BufferDestroy(ou
2d9e0 74 29 3b 0a 20 20 20 20 20 20 2a 6f 75 74 20 3d  t);.      *out =
2d9f0 20 6d 65 72 67 65 64 3b 0a 20 20 20 20 20 20 64   merged;.      d
2da00 6c 72 44 65 73 74 72 6f 79 28 26 72 65 61 64 65  lrDestroy(&reade
2da10 72 73 5b 30 5d 29 3b 0a 20 20 20 20 20 20 64 6c  rs[0]);.      dl
2da20 72 44 65 73 74 72 6f 79 28 26 72 65 61 64 65 72  rDestroy(&reader
2da30 73 5b 31 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  s[1]);.    }.  }
2da40 0a 20 20 64 61 74 61 42 75 66 66 65 72 44 65 73  .  dataBufferDes
2da50 74 72 6f 79 28 26 72 65 73 75 6c 74 29 3b 0a 20  troy(&result);. 
2da60 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
2da70 2a 20 53 63 61 6e 20 74 68 65 20 64 61 74 61 62  * Scan the datab
2da80 61 73 65 20 61 6e 64 20 6d 65 72 67 65 20 74 6f  ase and merge to
2da90 67 65 74 68 65 72 20 74 68 65 20 70 6f 73 74 69  gether the posti
2daa0 6e 67 20 6c 69 73 74 73 20 66 6f 72 20 74 68 65  ng lists for the
2dab0 20 74 65 72 6d 0a 2a 2a 20 69 6e 74 6f 20 2a 6f   term.** into *o
2dac0 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ut..*/.static in
2dad0 74 20 74 65 72 6d 53 65 6c 65 63 74 28 0a 20 20  t termSelect(.  
2dae0 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
2daf0 2c 20 0a 20 20 69 6e 74 20 69 43 6f 6c 75 6d 6e  , .  int iColumn
2db00 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ,.  const char *
2db10 70 54 65 72 6d 2c 20 69 6e 74 20 6e 54 65 72 6d  pTerm, int nTerm
2db20 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
2db30 20 54 65 72 6d 20 74 6f 20 71 75 65 72 79 20 66   Term to query f
2db40 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 69 73 50 72  or */.  int isPr
2db50 65 66 69 78 2c 20 20 20 20 20 20 20 20 20 20 20  efix,           
2db60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2db70 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 61 20    /* True for a 
2db80 70 72 65 66 69 78 20 73 65 61 72 63 68 20 2a 2f  prefix search */
2db90 0a 20 20 44 6f 63 4c 69 73 74 54 79 70 65 20 69  .  DocListType i
2dba0 54 79 70 65 2c 20 0a 20 20 44 61 74 61 42 75 66  Type, .  DataBuf
2dbb0 66 65 72 20 2a 6f 75 74 20 20 20 20 20 20 20 20  fer *out        
2dbc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2dbd0 20 20 20 2f 2a 20 57 72 69 74 65 20 72 65 73 75     /* Write resu
2dbe0 6c 74 73 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20  lts here */.){. 
2dbf0 20 44 61 74 61 42 75 66 66 65 72 20 64 6f 63 6c   DataBuffer docl
2dc00 69 73 74 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73  ist;.  sqlite3_s
2dc10 74 6d 74 20 2a 73 3b 0a 20 20 69 6e 74 20 72 63  tmt *s;.  int rc
2dc20 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74 61 74 65   = sql_get_state
2dc30 6d 65 6e 74 28 76 2c 20 53 45 47 44 49 52 5f 53  ment(v, SEGDIR_S
2dc40 45 4c 45 43 54 5f 41 4c 4c 5f 53 54 4d 54 2c 20  ELECT_ALL_STMT, 
2dc50 26 73 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  &s);.  if( rc!=S
2dc60 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
2dc70 6e 20 72 63 3b 0a 0a 20 20 2f 2a 20 54 68 69 73  n rc;..  /* This
2dc80 20 63 6f 64 65 20 73 68 6f 75 6c 64 20 6e 65 76   code should nev
2dc90 65 72 20 62 65 20 63 61 6c 6c 65 64 20 77 69 74  er be called wit
2dca0 68 20 62 75 66 66 65 72 65 64 20 75 70 64 61 74  h buffered updat
2dcb0 65 73 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  es. */.  assert(
2dcc0 20 76 2d 3e 6e 50 65 6e 64 69 6e 67 44 61 74 61   v->nPendingData
2dcd0 3c 30 20 29 3b 0a 0a 20 20 64 61 74 61 42 75 66  <0 );..  dataBuf
2dce0 66 65 72 49 6e 69 74 28 26 64 6f 63 6c 69 73 74  ferInit(&doclist
2dcf0 2c 20 30 29 3b 0a 20 20 64 61 74 61 42 75 66 66  , 0);.  dataBuff
2dd00 65 72 49 6e 69 74 28 6f 75 74 2c 20 30 29 3b 0a  erInit(out, 0);.
2dd10 0a 20 20 2f 2a 20 54 72 61 76 65 72 73 65 20 74  .  /* Traverse t
2dd20 68 65 20 73 65 67 6d 65 6e 74 73 20 66 72 6f 6d  he segments from
2dd30 20 6f 6c 64 65 73 74 20 74 6f 20 6e 65 77 65 73   oldest to newes
2dd40 74 20 73 6f 20 74 68 61 74 20 6e 65 77 65 72 20  t so that newer 
2dd50 64 6f 63 6c 69 73 74 0a 20 20 2a 2a 20 65 6c 65  doclist.  ** ele
2dd60 6d 65 6e 74 73 20 66 6f 72 20 67 69 76 65 6e 20  ments for given 
2dd70 64 6f 63 69 64 73 20 6f 76 65 72 77 72 69 74 65  docids overwrite
2dd80 20 6f 6c 64 65 72 20 65 6c 65 6d 65 6e 74 73 2e   older elements.
2dd90 0a 20 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 28  .  */.  while( (
2dda0 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65  rc = sqlite3_ste
2ddb0 70 28 73 29 29 3d 3d 53 51 4c 49 54 45 5f 52 4f  p(s))==SQLITE_RO
2ddc0 57 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63  W ){.    const c
2ddd0 68 61 72 20 2a 70 44 61 74 61 20 3d 20 73 71 6c  har *pData = sql
2dde0 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62  ite3_column_blob
2ddf0 28 73 2c 20 32 29 3b 0a 20 20 20 20 63 6f 6e 73  (s, 2);.    cons
2de00 74 20 69 6e 74 20 6e 44 61 74 61 20 3d 20 73 71  t int nData = sq
2de10 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74  lite3_column_byt
2de20 65 73 28 73 2c 20 32 29 3b 0a 20 20 20 20 63 6f  es(s, 2);.    co
2de30 6e 73 74 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  nst sqlite_int64
2de40 20 69 4c 65 61 76 65 73 45 6e 64 20 3d 20 73 71   iLeavesEnd = sq
2de50 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74  lite3_column_int
2de60 36 34 28 73 2c 20 31 29 3b 0a 20 20 20 20 72 63  64(s, 1);.    rc
2de70 20 3d 20 6c 6f 61 64 53 65 67 6d 65 6e 74 28 76   = loadSegment(v
2de80 2c 20 70 44 61 74 61 2c 20 6e 44 61 74 61 2c 20  , pData, nData, 
2de90 69 4c 65 61 76 65 73 45 6e 64 2c 20 70 54 65 72  iLeavesEnd, pTer
2dea0 6d 2c 20 6e 54 65 72 6d 2c 20 69 73 50 72 65 66  m, nTerm, isPref
2deb0 69 78 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  ix,.            
2dec0 20 20 20 20 20 20 20 20 20 26 64 6f 63 6c 69 73           &doclis
2ded0 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  t);.    if( rc!=
2dee0 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74 6f  SQLITE_OK ) goto
2def0 20 65 72 72 3b 0a 20 20 7d 0a 20 20 69 66 28 20   err;.  }.  if( 
2df00 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20  rc==SQLITE_DONE 
2df10 29 7b 0a 20 20 20 20 69 66 28 20 64 6f 63 6c 69  ){.    if( docli
2df20 73 74 2e 6e 44 61 74 61 21 3d 30 20 29 7b 0a 20  st.nData!=0 ){. 
2df30 20 20 20 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65       /* TODO(she
2df40 73 73 29 20 54 68 65 20 6f 6c 64 20 74 65 72 6d  ss) The old term
2df50 5f 73 65 6c 65 63 74 5f 61 6c 6c 28 29 20 63 6f  _select_all() co
2df60 64 65 20 61 70 70 6c 69 65 64 20 74 68 65 20 63  de applied the c
2df70 6f 6c 75 6d 6e 0a 20 20 20 20 20 20 2a 2a 20 72  olumn.      ** r
2df80 65 73 74 72 69 63 74 20 61 73 20 77 65 20 6d 65  estrict as we me
2df90 72 67 65 64 20 73 65 67 6d 65 6e 74 73 2c 20 6c  rged segments, l
2dfa0 65 61 64 69 6e 67 20 74 6f 20 73 6d 61 6c 6c 65  eading to smalle
2dfb0 72 20 62 75 66 66 65 72 73 2e 0a 20 20 20 20 20  r buffers..     
2dfc0 20 2a 2a 20 54 68 69 73 20 69 73 20 70 72 6f 62   ** This is prob
2dfd0 61 62 6c 79 20 77 6f 72 74 68 77 68 69 6c 65 20  ably worthwhile 
2dfe0 74 6f 20 62 72 69 6e 67 20 62 61 63 6b 2c 20 6f  to bring back, o
2dff0 6e 63 65 20 74 68 65 20 6e 65 77 20 73 74 6f 72  nce the new stor
2e000 61 67 65 0a 20 20 20 20 20 20 2a 2a 20 73 79 73  age.      ** sys
2e010 74 65 6d 20 69 73 20 63 68 65 63 6b 65 64 20 69  tem is checked i
2e020 6e 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  n..      */.    
2e030 20 20 69 66 28 20 69 43 6f 6c 75 6d 6e 3d 3d 76    if( iColumn==v
2e040 2d 3e 6e 43 6f 6c 75 6d 6e 29 20 69 43 6f 6c 75  ->nColumn) iColu
2e050 6d 6e 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20 64  mn = -1;.      d
2e060 6f 63 4c 69 73 74 54 72 69 6d 28 44 4c 5f 44 45  ocListTrim(DL_DE
2e070 46 41 55 4c 54 2c 20 64 6f 63 6c 69 73 74 2e 70  FAULT, doclist.p
2e080 44 61 74 61 2c 20 64 6f 63 6c 69 73 74 2e 6e 44  Data, doclist.nD
2e090 61 74 61 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ata,.           
2e0a0 20 20 20 20 20 20 20 69 43 6f 6c 75 6d 6e 2c 20         iColumn, 
2e0b0 69 54 79 70 65 2c 20 6f 75 74 29 3b 0a 20 20 20  iType, out);.   
2e0c0 20 7d 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49   }.    rc = SQLI
2e0d0 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 65 72 72  TE_OK;.  }.. err
2e0e0 3a 0a 20 20 64 61 74 61 42 75 66 66 65 72 44 65  :.  dataBufferDe
2e0f0 73 74 72 6f 79 28 26 64 6f 63 6c 69 73 74 29 3b  stroy(&doclist);
2e100 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
2e110 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
2e120 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2e130 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2e140 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2e150 2a 2a 2f 0a 2f 2a 20 55 73 65 64 20 74 6f 20 68  **/./* Used to h
2e160 6f 6c 64 20 68 61 73 68 74 61 62 6c 65 20 64 61  old hashtable da
2e170 74 61 20 66 6f 72 20 73 6f 72 74 69 6e 67 2e 20  ta for sorting. 
2e180 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  */.typedef struc
2e190 74 20 54 65 72 6d 44 61 74 61 20 7b 0a 20 20 63  t TermData {.  c
2e1a0 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65 72 6d  onst char *pTerm
2e1b0 3b 0a 20 20 69 6e 74 20 6e 54 65 72 6d 3b 0a 20  ;.  int nTerm;. 
2e1c0 20 44 4c 43 6f 6c 6c 65 63 74 6f 72 20 2a 70 43   DLCollector *pC
2e1d0 6f 6c 6c 65 63 74 6f 72 3b 0a 7d 20 54 65 72 6d  ollector;.} Term
2e1e0 44 61 74 61 3b 0a 0a 2f 2a 20 4f 72 64 65 72 73  Data;../* Orders
2e1f0 20 54 65 72 6d 44 61 74 61 20 65 6c 65 6d 65 6e   TermData elemen
2e200 74 73 20 69 6e 20 73 74 72 63 6d 70 20 66 61 73  ts in strcmp fas
2e210 68 69 6f 6e 20 28 20 3c 30 20 66 6f 72 20 6c 65  hion ( <0 for le
2e220 73 73 2d 74 68 61 6e 2c 20 30 0a 2a 2a 20 66 6f  ss-than, 0.** fo
2e230 72 20 65 71 75 61 6c 2c 20 3e 30 20 66 6f 72 20  r equal, >0 for 
2e240 67 72 65 61 74 65 72 2d 74 68 61 6e 29 2e 0a 2a  greater-than)..*
2e250 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 72  /.static int ter
2e260 6d 44 61 74 61 43 6d 70 28 63 6f 6e 73 74 20 76  mDataCmp(const v
2e270 6f 69 64 20 2a 61 76 2c 20 63 6f 6e 73 74 20 76  oid *av, const v
2e280 6f 69 64 20 2a 62 76 29 7b 0a 20 20 63 6f 6e 73  oid *bv){.  cons
2e290 74 20 54 65 72 6d 44 61 74 61 20 2a 61 20 3d 20  t TermData *a = 
2e2a0 28 63 6f 6e 73 74 20 54 65 72 6d 44 61 74 61 20  (const TermData 
2e2b0 2a 29 61 76 3b 0a 20 20 63 6f 6e 73 74 20 54 65  *)av;.  const Te
2e2c0 72 6d 44 61 74 61 20 2a 62 20 3d 20 28 63 6f 6e  rmData *b = (con
2e2d0 73 74 20 54 65 72 6d 44 61 74 61 20 2a 29 62 76  st TermData *)bv
2e2e0 3b 0a 20 20 69 6e 74 20 6e 20 3d 20 61 2d 3e 6e  ;.  int n = a->n
2e2f0 54 65 72 6d 3c 62 2d 3e 6e 54 65 72 6d 20 3f 20  Term<b->nTerm ? 
2e300 61 2d 3e 6e 54 65 72 6d 20 3a 20 62 2d 3e 6e 54  a->nTerm : b->nT
2e310 65 72 6d 3b 0a 20 20 69 6e 74 20 63 20 3d 20 6d  erm;.  int c = m
2e320 65 6d 63 6d 70 28 61 2d 3e 70 54 65 72 6d 2c 20  emcmp(a->pTerm, 
2e330 62 2d 3e 70 54 65 72 6d 2c 20 6e 29 3b 0a 20 20  b->pTerm, n);.  
2e340 69 66 28 20 63 21 3d 30 20 29 20 72 65 74 75 72  if( c!=0 ) retur
2e350 6e 20 63 3b 0a 20 20 72 65 74 75 72 6e 20 61 2d  n c;.  return a-
2e360 3e 6e 54 65 72 6d 2d 62 2d 3e 6e 54 65 72 6d 3b  >nTerm-b->nTerm;
2e370 0a 7d 0a 0a 2f 2a 20 4f 72 64 65 72 20 70 54 65  .}../* Order pTe
2e380 72 6d 73 20 64 61 74 61 20 62 79 20 74 65 72 6d  rms data by term
2e390 2c 20 74 68 65 6e 20 77 72 69 74 65 20 61 20 6e  , then write a n
2e3a0 65 77 20 6c 65 76 65 6c 20 30 20 73 65 67 6d 65  ew level 0 segme
2e3b0 6e 74 20 75 73 69 6e 67 0a 2a 2a 20 4c 65 61 66  nt using.** Leaf
2e3c0 57 72 69 74 65 72 2e 0a 2a 2f 0a 73 74 61 74 69  Writer..*/.stati
2e3d0 63 20 69 6e 74 20 77 72 69 74 65 5a 65 72 6f 53  c int writeZeroS
2e3e0 65 67 6d 65 6e 74 28 66 75 6c 6c 74 65 78 74 5f  egment(fulltext_
2e3f0 76 74 61 62 20 2a 76 2c 20 66 74 73 33 48 61 73  vtab *v, fts3Has
2e400 68 20 2a 70 54 65 72 6d 73 29 7b 0a 20 20 66 74  h *pTerms){.  ft
2e410 73 33 48 61 73 68 45 6c 65 6d 20 2a 65 3b 0a 20  s3HashElem *e;. 
2e420 20 69 6e 74 20 69 64 78 2c 20 72 63 2c 20 69 2c   int idx, rc, i,
2e430 20 6e 3b 0a 20 20 54 65 72 6d 44 61 74 61 20 2a   n;.  TermData *
2e440 70 44 61 74 61 3b 0a 20 20 4c 65 61 66 57 72 69  pData;.  LeafWri
2e450 74 65 72 20 77 72 69 74 65 72 3b 0a 20 20 44 61  ter writer;.  Da
2e460 74 61 42 75 66 66 65 72 20 64 6c 3b 0a 0a 20 20  taBuffer dl;..  
2e470 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65  /* Determine the
2e480 20 6e 65 78 74 20 69 6e 64 65 78 20 61 74 20 6c   next index at l
2e490 65 76 65 6c 20 30 2c 20 6d 65 72 67 69 6e 67 20  evel 0, merging 
2e4a0 61 73 20 6e 65 63 65 73 73 61 72 79 2e 20 2a 2f  as necessary. */
2e4b0 0a 20 20 72 63 20 3d 20 73 65 67 64 69 72 4e 65  .  rc = segdirNe
2e4c0 78 74 49 6e 64 65 78 28 76 2c 20 30 2c 20 26 69  xtIndex(v, 0, &i
2e4d0 64 78 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  dx);.  if( rc!=S
2e4e0 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
2e4f0 6e 20 72 63 3b 0a 0a 20 20 6e 20 3d 20 66 74 73  n rc;..  n = fts
2e500 33 48 61 73 68 43 6f 75 6e 74 28 70 54 65 72 6d  3HashCount(pTerm
2e510 73 29 3b 0a 20 20 70 44 61 74 61 20 3d 20 73 71  s);.  pData = sq
2e520 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 2a 73  lite3_malloc(n*s
2e530 69 7a 65 6f 66 28 54 65 72 6d 44 61 74 61 29 29  izeof(TermData))
2e540 3b 0a 0a 20 20 66 6f 72 28 69 20 3d 20 30 2c 20  ;..  for(i = 0, 
2e550 65 20 3d 20 66 74 73 33 48 61 73 68 46 69 72 73  e = fts3HashFirs
2e560 74 28 70 54 65 72 6d 73 29 3b 20 65 3b 20 69 2b  t(pTerms); e; i+
2e570 2b 2c 20 65 20 3d 20 66 74 73 33 48 61 73 68 4e  +, e = fts3HashN
2e580 65 78 74 28 65 29 29 7b 0a 20 20 20 20 61 73 73  ext(e)){.    ass
2e590 65 72 74 28 20 69 3c 6e 20 29 3b 0a 20 20 20 20  ert( i<n );.    
2e5a0 70 44 61 74 61 5b 69 5d 2e 70 54 65 72 6d 20 3d  pData[i].pTerm =
2e5b0 20 66 74 73 33 48 61 73 68 4b 65 79 28 65 29 3b   fts3HashKey(e);
2e5c0 0a 20 20 20 20 70 44 61 74 61 5b 69 5d 2e 6e 54  .    pData[i].nT
2e5d0 65 72 6d 20 3d 20 66 74 73 33 48 61 73 68 4b 65  erm = fts3HashKe
2e5e0 79 73 69 7a 65 28 65 29 3b 0a 20 20 20 20 70 44  ysize(e);.    pD
2e5f0 61 74 61 5b 69 5d 2e 70 43 6f 6c 6c 65 63 74 6f  ata[i].pCollecto
2e600 72 20 3d 20 66 74 73 33 48 61 73 68 44 61 74 61  r = fts3HashData
2e610 28 65 29 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72  (e);.  }.  asser
2e620 74 28 20 69 3d 3d 6e 20 29 3b 0a 0a 20 20 2f 2a  t( i==n );..  /*
2e630 20 54 4f 44 4f 28 73 68 65 73 73 29 20 53 68 6f   TODO(shess) Sho
2e640 75 6c 64 20 77 65 20 61 6c 6c 6f 77 20 75 73 65  uld we allow use
2e650 72 2d 64 65 66 69 6e 65 64 20 63 6f 6c 6c 61 74  r-defined collat
2e660 69 6f 6e 20 73 65 71 75 65 6e 63 65 73 2c 0a 20  ion sequences,. 
2e670 20 2a 2a 20 68 65 72 65 3f 20 20 49 20 74 68 69   ** here?  I thi
2e680 6e 6b 20 77 65 20 6f 6e 6c 79 20 6e 65 65 64 20  nk we only need 
2e690 74 68 61 74 20 6f 6e 63 65 20 77 65 20 73 75 70  that once we sup
2e6a0 70 6f 72 74 20 70 72 65 66 69 78 20 73 65 61 72  port prefix sear
2e6b0 63 68 65 73 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  ches..  */.  if(
2e6c0 20 6e 3e 31 20 29 20 71 73 6f 72 74 28 70 44 61   n>1 ) qsort(pDa
2e6d0 74 61 2c 20 6e 2c 20 73 69 7a 65 6f 66 28 2a 70  ta, n, sizeof(*p
2e6e0 44 61 74 61 29 2c 20 74 65 72 6d 44 61 74 61 43  Data), termDataC
2e6f0 6d 70 29 3b 0a 0a 20 20 2f 2a 20 54 4f 44 4f 28  mp);..  /* TODO(
2e700 73 68 65 73 73 29 20 52 65 66 61 63 74 6f 72 20  shess) Refactor 
2e710 73 6f 20 74 68 61 74 20 77 65 20 63 61 6e 20 77  so that we can w
2e720 72 69 74 65 20 64 69 72 65 63 74 6c 79 20 74 6f  rite directly to
2e730 20 74 68 65 20 73 65 67 6d 65 6e 74 0a 20 20 2a   the segment.  *
2e740 2a 20 44 61 74 61 42 75 66 66 65 72 2c 20 61 73  * DataBuffer, as
2e750 20 68 61 70 70 65 6e 73 20 66 6f 72 20 73 65 67   happens for seg
2e760 6d 65 6e 74 20 6d 65 72 67 65 73 2e 0a 20 20 2a  ment merges..  *
2e770 2f 0a 20 20 6c 65 61 66 57 72 69 74 65 72 49 6e  /.  leafWriterIn
2e780 69 74 28 30 2c 20 69 64 78 2c 20 26 77 72 69 74  it(0, idx, &writ
2e790 65 72 29 3b 0a 20 20 64 61 74 61 42 75 66 66 65  er);.  dataBuffe
2e7a0 72 49 6e 69 74 28 26 64 6c 2c 20 30 29 3b 0a 20  rInit(&dl, 0);. 
2e7b0 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 3b 20 69   for(i=0; i<n; i
2e7c0 2b 2b 29 7b 0a 20 20 20 20 64 61 74 61 42 75 66  ++){.    dataBuf
2e7d0 66 65 72 52 65 73 65 74 28 26 64 6c 29 3b 0a 20  ferReset(&dl);. 
2e7e0 20 20 20 64 6c 63 41 64 64 44 6f 63 6c 69 73 74     dlcAddDoclist
2e7f0 28 70 44 61 74 61 5b 69 5d 2e 70 43 6f 6c 6c 65  (pData[i].pColle
2e800 63 74 6f 72 2c 20 26 64 6c 29 3b 0a 20 20 20 20  ctor, &dl);.    
2e810 72 63 20 3d 20 6c 65 61 66 57 72 69 74 65 72 53  rc = leafWriterS
2e820 74 65 70 28 76 2c 20 26 77 72 69 74 65 72 2c 0a  tep(v, &writer,.
2e830 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2e840 20 20 20 20 20 20 20 20 70 44 61 74 61 5b 69 5d          pData[i]
2e850 2e 70 54 65 72 6d 2c 20 70 44 61 74 61 5b 69 5d  .pTerm, pData[i]
2e860 2e 6e 54 65 72 6d 2c 20 64 6c 2e 70 44 61 74 61  .nTerm, dl.pData
2e870 2c 20 64 6c 2e 6e 44 61 74 61 29 3b 0a 20 20 20  , dl.nData);.   
2e880 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
2e890 4f 4b 20 29 20 67 6f 74 6f 20 65 72 72 3b 0a 20  OK ) goto err;. 
2e8a0 20 7d 0a 20 20 72 63 20 3d 20 6c 65 61 66 57 72   }.  rc = leafWr
2e8b0 69 74 65 72 46 69 6e 61 6c 69 7a 65 28 76 2c 20  iterFinalize(v, 
2e8c0 26 77 72 69 74 65 72 29 3b 0a 0a 20 65 72 72 3a  &writer);.. err:
2e8d0 0a 20 20 64 61 74 61 42 75 66 66 65 72 44 65 73  .  dataBufferDes
2e8e0 74 72 6f 79 28 26 64 6c 29 3b 0a 20 20 73 71 6c  troy(&dl);.  sql
2e8f0 69 74 65 33 5f 66 72 65 65 28 70 44 61 74 61 29  ite3_free(pData)
2e900 3b 0a 20 20 6c 65 61 66 57 72 69 74 65 72 44 65  ;.  leafWriterDe
2e910 73 74 72 6f 79 28 26 77 72 69 74 65 72 29 3b 0a  stroy(&writer);.
2e920 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
2e930 2f 2a 20 49 66 20 70 65 6e 64 69 6e 67 54 65 72  /* If pendingTer
2e940 6d 73 20 68 61 73 20 64 61 74 61 2c 20 66 72 65  ms has data, fre
2e950 65 20 69 74 2e 20 2a 2f 0a 73 74 61 74 69 63 20  e it. */.static 
2e960 69 6e 74 20 63 6c 65 61 72 50 65 6e 64 69 6e 67  int clearPending
2e970 54 65 72 6d 73 28 66 75 6c 6c 74 65 78 74 5f 76  Terms(fulltext_v
2e980 74 61 62 20 2a 76 29 7b 0a 20 20 69 66 28 20 76  tab *v){.  if( v
2e990 2d 3e 6e 50 65 6e 64 69 6e 67 44 61 74 61 3e 3d  ->nPendingData>=
2e9a0 30 20 29 7b 0a 20 20 20 20 66 74 73 33 48 61 73  0 ){.    fts3Has
2e9b0 68 45 6c 65 6d 20 2a 65 3b 0a 20 20 20 20 66 6f  hElem *e;.    fo
2e9c0 72 28 65 3d 66 74 73 33 48 61 73 68 46 69 72 73  r(e=fts3HashFirs
2e9d0 74 28 26 76 2d 3e 70 65 6e 64 69 6e 67 54 65 72  t(&v->pendingTer
2e9e0 6d 73 29 3b 20 65 3b 20 65 3d 66 74 73 33 48 61  ms); e; e=fts3Ha
2e9f0 73 68 4e 65 78 74 28 65 29 29 7b 0a 20 20 20 20  shNext(e)){.    
2ea00 20 20 64 6c 63 44 65 6c 65 74 65 28 66 74 73 33    dlcDelete(fts3
2ea10 48 61 73 68 44 61 74 61 28 65 29 29 3b 0a 20 20  HashData(e));.  
2ea20 20 20 7d 0a 20 20 20 20 66 74 73 33 48 61 73 68    }.    fts3Hash
2ea30 43 6c 65 61 72 28 26 76 2d 3e 70 65 6e 64 69 6e  Clear(&v->pendin
2ea40 67 54 65 72 6d 73 29 3b 0a 20 20 20 20 76 2d 3e  gTerms);.    v->
2ea50 6e 50 65 6e 64 69 6e 67 44 61 74 61 20 3d 20 2d  nPendingData = -
2ea60 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  1;.  }.  return 
2ea70 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
2ea80 20 49 66 20 70 65 6e 64 69 6e 67 54 65 72 6d 73   If pendingTerms
2ea90 20 68 61 73 20 64 61 74 61 2c 20 66 6c 75 73 68   has data, flush
2eaa0 20 69 74 20 74 6f 20 61 20 6c 65 76 65 6c 2d 7a   it to a level-z
2eab0 65 72 6f 20 73 65 67 6d 65 6e 74 2c 20 61 6e 64  ero segment, and
2eac0 0a 2a 2a 20 66 72 65 65 20 69 74 2e 0a 2a 2f 0a  .** free it..*/.
2ead0 73 74 61 74 69 63 20 69 6e 74 20 66 6c 75 73 68  static int flush
2eae0 50 65 6e 64 69 6e 67 54 65 72 6d 73 28 66 75 6c  PendingTerms(ful
2eaf0 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 29 7b 0a  ltext_vtab *v){.
2eb00 20 20 69 66 28 20 76 2d 3e 6e 50 65 6e 64 69 6e    if( v->nPendin
2eb10 67 44 61 74 61 3e 3d 30 20 29 7b 0a 20 20 20 20  gData>=0 ){.    
2eb20 69 6e 74 20 72 63 20 3d 20 77 72 69 74 65 5a 65  int rc = writeZe
2eb30 72 6f 53 65 67 6d 65 6e 74 28 76 2c 20 26 76 2d  roSegment(v, &v-
2eb40 3e 70 65 6e 64 69 6e 67 54 65 72 6d 73 29 3b 0a  >pendingTerms);.
2eb50 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
2eb60 54 45 5f 4f 4b 20 29 20 63 6c 65 61 72 50 65 6e  TE_OK ) clearPen
2eb70 64 69 6e 67 54 65 72 6d 73 28 76 29 3b 0a 20 20  dingTerms(v);.  
2eb80 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d    return rc;.  }
2eb90 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
2eba0 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 49 66 20 70 65  _OK;.}../* If pe
2ebb0 6e 64 69 6e 67 54 65 72 6d 73 20 69 73 20 22 74  ndingTerms is "t
2ebc0 6f 6f 20 62 69 67 22 2c 20 6f 72 20 64 6f 63 69  oo big", or doci
2ebd0 64 20 69 73 20 6f 75 74 20 6f 66 20 6f 72 64 65  d is out of orde
2ebe0 72 2c 20 66 6c 75 73 68 20 69 74 2e 0a 2a 2a 20  r, flush it..** 
2ebf0 52 65 67 61 72 64 6c 65 73 73 2c 20 62 65 20 63  Regardless, be c
2ec00 65 72 74 61 69 6e 20 74 68 61 74 20 70 65 6e 64  ertain that pend
2ec10 69 6e 67 54 65 72 6d 73 20 69 73 20 69 6e 69 74  ingTerms is init
2ec20 69 61 6c 69 7a 65 64 20 66 6f 72 20 75 73 65 2e  ialized for use.
2ec30 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 69  .*/.static int i
2ec40 6e 69 74 50 65 6e 64 69 6e 67 54 65 72 6d 73 28  nitPendingTerms(
2ec50 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76  fulltext_vtab *v
2ec60 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69  , sqlite_int64 i
2ec70 44 6f 63 69 64 29 7b 0a 20 20 2f 2a 20 54 4f 44  Docid){.  /* TOD
2ec80 4f 28 73 68 65 73 73 29 20 45 78 70 6c 6f 72 65  O(shess) Explore
2ec90 20 77 68 65 74 68 65 72 20 70 61 72 74 69 61 6c   whether partial
2eca0 6c 79 20 66 6c 75 73 68 69 6e 67 20 74 68 65 20  ly flushing the 
2ecb0 62 75 66 66 65 72 20 6f 6e 0a 20 20 2a 2a 20 66  buffer on.  ** f
2ecc0 6f 72 63 65 64 2d 66 6c 75 73 68 20 77 6f 75 6c  orced-flush woul
2ecd0 64 20 70 72 6f 76 69 64 65 20 62 65 74 74 65 72  d provide better
2ece0 20 70 65 72 66 6f 72 6d 61 6e 63 65 2e 20 20 49   performance.  I
2ecf0 20 73 75 73 70 65 63 74 20 74 68 61 74 20 69 66   suspect that if
2ed00 0a 20 20 2a 2a 20 77 65 20 6f 72 64 65 72 65 64  .  ** we ordered
2ed10 20 74 68 65 20 64 6f 63 6c 69 73 74 73 20 62 79   the doclists by
2ed20 20 73 69 7a 65 20 61 6e 64 20 66 6c 75 73 68 65   size and flushe
2ed30 64 20 74 68 65 20 6c 61 72 67 65 73 74 20 75 6e  d the largest un
2ed40 74 69 6c 20 74 68 65 0a 20 20 2a 2a 20 62 75 66  til the.  ** buf
2ed50 66 65 72 20 77 61 73 20 68 61 6c 66 20 65 6d 70  fer was half emp
2ed60 74 79 2c 20 74 68 61 74 20 77 6f 75 6c 64 20 6c  ty, that would l
2ed70 65 74 20 74 68 65 20 6c 65 73 73 20 66 72 65 71  et the less freq
2ed80 75 65 6e 74 20 74 65 72 6d 73 0a 20 20 2a 2a 20  uent terms.  ** 
2ed90 67 65 6e 65 72 61 74 65 20 6c 6f 6e 67 65 72 20  generate longer 
2eda0 64 6f 63 6c 69 73 74 73 2e 0a 20 20 2a 2f 0a 20  doclists..  */. 
2edb0 20 69 66 28 20 69 44 6f 63 69 64 3c 3d 76 2d 3e   if( iDocid<=v->
2edc0 69 50 72 65 76 44 6f 63 69 64 20 7c 7c 20 76 2d  iPrevDocid || v-
2edd0 3e 6e 50 65 6e 64 69 6e 67 44 61 74 61 3e 6b 50  >nPendingData>kP
2ede0 65 6e 64 69 6e 67 54 68 72 65 73 68 6f 6c 64 20  endingThreshold 
2edf0 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20  ){.    int rc = 
2ee00 66 6c 75 73 68 50 65 6e 64 69 6e 67 54 65 72 6d  flushPendingTerm
2ee10 73 28 76 29 3b 0a 20 20 20 20 69 66 28 20 72 63  s(v);.    if( rc
2ee20 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
2ee30 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 69  turn rc;.  }.  i
2ee40 66 28 20 76 2d 3e 6e 50 65 6e 64 69 6e 67 44 61  f( v->nPendingDa
2ee50 74 61 3c 30 20 29 7b 0a 20 20 20 20 66 74 73 33  ta<0 ){.    fts3
2ee60 48 61 73 68 49 6e 69 74 28 26 76 2d 3e 70 65 6e  HashInit(&v->pen
2ee70 64 69 6e 67 54 65 72 6d 73 2c 20 46 54 53 33 5f  dingTerms, FTS3_
2ee80 48 41 53 48 5f 53 54 52 49 4e 47 2c 20 31 29 3b  HASH_STRING, 1);
2ee90 0a 20 20 20 20 76 2d 3e 6e 50 65 6e 64 69 6e 67  .    v->nPending
2eea0 44 61 74 61 20 3d 20 30 3b 0a 20 20 7d 0a 20 20  Data = 0;.  }.  
2eeb0 76 2d 3e 69 50 72 65 76 44 6f 63 69 64 20 3d 20  v->iPrevDocid = 
2eec0 69 44 6f 63 69 64 3b 0a 20 20 72 65 74 75 72 6e  iDocid;.  return
2eed0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
2eee0 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
2eef0 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65 20 78  implements the x
2ef00 55 70 64 61 74 65 20 63 61 6c 6c 62 61 63 6b 3b  Update callback;
2ef10 20 69 74 20 69 73 20 74 68 65 20 74 6f 70 2d 6c   it is the top-l
2ef20 65 76 65 6c 20 65 6e 74 72 79 0a 20 2a 20 70 6f  evel entry. * po
2ef30 69 6e 74 20 66 6f 72 20 69 6e 73 65 72 74 69 6e  int for insertin
2ef40 67 2c 20 64 65 6c 65 74 69 6e 67 20 6f 72 20 75  g, deleting or u
2ef50 70 64 61 74 69 6e 67 20 61 20 72 6f 77 20 69 6e  pdating a row in
2ef60 20 61 20 66 75 6c 6c 2d 74 65 78 74 20 74 61 62   a full-text tab
2ef70 6c 65 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le. */.static in
2ef80 74 20 66 75 6c 6c 74 65 78 74 55 70 64 61 74 65  t fulltextUpdate
2ef90 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
2efa0 56 74 61 62 2c 20 69 6e 74 20 6e 41 72 67 2c 20  Vtab, int nArg, 
2efb0 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
2efc0 70 70 41 72 67 2c 0a 20 20 20 20 20 20 20 20 20  ppArg,.         
2efd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2efe0 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70   sqlite_int64 *p
2eff0 52 6f 77 69 64 29 7b 0a 20 20 66 75 6c 6c 74 65  Rowid){.  fullte
2f000 78 74 5f 76 74 61 62 20 2a 76 20 3d 20 28 66 75  xt_vtab *v = (fu
2f010 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 20 70  lltext_vtab *) p
2f020 56 74 61 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  Vtab;.  int rc;.
2f030 0a 20 20 46 54 53 54 52 41 43 45 28 28 22 46 54  .  FTSTRACE(("FT
2f040 53 33 20 55 70 64 61 74 65 20 25 70 5c 6e 22 2c  S3 Update %p\n",
2f050 20 70 56 74 61 62 29 29 3b 0a 0a 20 20 69 66 28   pVtab));..  if(
2f060 20 6e 41 72 67 3c 32 20 29 7b 0a 20 20 20 20 72   nArg<2 ){.    r
2f070 63 20 3d 20 69 6e 64 65 78 5f 64 65 6c 65 74 65  c = index_delete
2f080 28 76 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  (v, sqlite3_valu
2f090 65 5f 69 6e 74 36 34 28 70 70 41 72 67 5b 30 5d  e_int64(ppArg[0]
2f0a0 29 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  ));.    if( rc==
2f0b0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
2f0c0 20 20 20 2f 2a 20 49 66 20 77 65 20 6a 75 73 74     /* If we just
2f0d0 20 64 65 6c 65 74 65 64 20 74 68 65 20 6c 61 73   deleted the las
2f0e0 74 20 72 6f 77 20 69 6e 20 74 68 65 20 74 61 62  t row in the tab
2f0f0 6c 65 2c 20 63 6c 65 61 72 20 6f 75 74 20 74 68  le, clear out th
2f100 65 0a 20 20 20 20 20 20 2a 2a 20 69 6e 64 65 78  e.      ** index
2f110 20 64 61 74 61 2e 0a 20 20 20 20 20 20 2a 2f 0a   data..      */.
2f120 20 20 20 20 20 20 72 63 20 3d 20 63 6f 6e 74 65        rc = conte
2f130 6e 74 5f 65 78 69 73 74 73 28 76 29 3b 0a 20 20  nt_exists(v);.  
2f140 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
2f150 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20  TE_ROW ){.      
2f160 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b    rc = SQLITE_OK
2f170 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  ;.      }else if
2f180 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e  ( rc==SQLITE_DON
2f190 45 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20  E ){.        /* 
2f1a0 43 6c 65 61 72 20 74 68 65 20 70 65 6e 64 69 6e  Clear the pendin
2f1b0 67 20 74 65 72 6d 73 20 73 6f 20 77 65 20 64 6f  g terms so we do
2f1c0 6e 27 74 20 66 6c 75 73 68 20 61 20 75 73 65 6c  n't flush a usel
2f1d0 65 73 73 20 6c 65 76 65 6c 2d 30 0a 20 20 20 20  ess level-0.    
2f1e0 20 20 20 20 2a 2a 20 73 65 67 6d 65 6e 74 20 77      ** segment w
2f1f0 68 65 6e 20 74 68 65 20 74 72 61 6e 73 61 63 74  hen the transact
2f200 69 6f 6e 20 63 6c 6f 73 65 73 2e 0a 20 20 20 20  ion closes..    
2f210 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 72      */.        r
2f220 63 20 3d 20 63 6c 65 61 72 50 65 6e 64 69 6e 67  c = clearPending
2f230 54 65 72 6d 73 28 76 29 3b 0a 20 20 20 20 20 20  Terms(v);.      
2f240 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2f250 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20  _OK ){.         
2f260 20 72 63 20 3d 20 73 65 67 64 69 72 5f 64 65 6c   rc = segdir_del
2f270 65 74 65 5f 61 6c 6c 28 76 29 3b 0a 20 20 20 20  ete_all(v);.    
2f280 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
2f290 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 69 66 28    }.  } else if(
2f2a0 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
2f2b0 79 70 65 28 70 70 41 72 67 5b 30 5d 29 20 21 3d  ype(ppArg[0]) !=
2f2c0 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a   SQLITE_NULL ){.
2f2d0 20 20 20 20 2f 2a 20 41 6e 20 75 70 64 61 74 65      /* An update
2f2e0 3a 0a 20 20 20 20 20 2a 20 70 70 41 72 67 5b 30  :.     * ppArg[0
2f2f0 5d 20 3d 20 6f 6c 64 20 72 6f 77 69 64 0a 20 20  ] = old rowid.  
2f300 20 20 20 2a 20 70 70 41 72 67 5b 31 5d 20 3d 20     * ppArg[1] = 
2f310 6e 65 77 20 72 6f 77 69 64 0a 20 20 20 20 20 2a  new rowid.     *
2f320 20 70 70 41 72 67 5b 32 2e 2e 32 2b 76 2d 3e 6e   ppArg[2..2+v->n
2f330 43 6f 6c 75 6d 6e 2d 31 5d 20 3d 20 76 61 6c 75  Column-1] = valu
2f340 65 73 0a 20 20 20 20 20 2a 20 70 70 41 72 67 5b  es.     * ppArg[
2f350 32 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e 5d 20 3d 20  2+v->nColumn] = 
2f360 76 61 6c 75 65 20 66 6f 72 20 6d 61 67 69 63 20  value for magic 
2f370 63 6f 6c 75 6d 6e 20 28 77 65 20 69 67 6e 6f 72  column (we ignor
2f380 65 20 74 68 69 73 29 0a 20 20 20 20 20 2a 20 70  e this).     * p
2f390 70 41 72 67 5b 32 2b 76 2d 3e 6e 43 6f 6c 75 6d  pArg[2+v->nColum
2f3a0 6e 2b 31 5d 20 3d 20 76 61 6c 75 65 20 66 6f 72  n+1] = value for
2f3b0 20 64 6f 63 69 64 0a 20 20 20 20 20 2a 2f 0a 20   docid.     */. 
2f3c0 20 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20     sqlite_int64 
2f3d0 72 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f  rowid = sqlite3_
2f3e0 76 61 6c 75 65 5f 69 6e 74 36 34 28 70 70 41 72  value_int64(ppAr
2f3f0 67 5b 30 5d 29 3b 0a 20 20 20 20 69 66 28 20 73  g[0]);.    if( s
2f400 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
2f410 65 28 70 70 41 72 67 5b 31 5d 29 20 21 3d 20 53  e(ppArg[1]) != S
2f420 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 7c 7c  QLITE_INTEGER ||
2f430 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
2f440 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 70 70 41  _value_int64(ppA
2f450 72 67 5b 31 5d 29 20 21 3d 20 72 6f 77 69 64 20  rg[1]) != rowid 
2f460 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  ){.      rc = SQ
2f470 4c 49 54 45 5f 45 52 52 4f 52 3b 20 20 2f 2a 20  LITE_ERROR;  /* 
2f480 77 65 20 64 6f 6e 27 74 20 61 6c 6c 6f 77 20 63  we don't allow c
2f490 68 61 6e 67 69 6e 67 20 74 68 65 20 72 6f 77 69  hanging the rowi
2f4a0 64 20 2a 2f 0a 20 20 20 20 7d 65 6c 73 65 20 69  d */.    }else i
2f4b0 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  f( sqlite3_value
2f4c0 5f 74 79 70 65 28 70 70 41 72 67 5b 32 2b 76 2d  _type(ppArg[2+v-
2f4d0 3e 6e 43 6f 6c 75 6d 6e 2b 31 5d 29 20 21 3d 20  >nColumn+1]) != 
2f4e0 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 7c  SQLITE_INTEGER |
2f4f0 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  |.              
2f500 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e  sqlite3_value_in
2f510 74 36 34 28 70 70 41 72 67 5b 32 2b 76 2d 3e 6e  t64(ppArg[2+v->n
2f520 43 6f 6c 75 6d 6e 2b 31 5d 29 20 21 3d 20 72 6f  Column+1]) != ro
2f530 77 69 64 20 29 7b 0a 20 20 20 20 20 20 72 63 20  wid ){.      rc 
2f540 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 20  = SQLITE_ERROR; 
2f550 20 2f 2a 20 77 65 20 64 6f 6e 27 74 20 61 6c 6c   /* we don't all
2f560 6f 77 20 63 68 61 6e 67 69 6e 67 20 74 68 65 20  ow changing the 
2f570 64 6f 63 69 64 20 2a 2f 0a 20 20 20 20 7d 65 6c  docid */.    }el
2f580 73 65 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74  se{.      assert
2f590 28 20 6e 41 72 67 3d 3d 32 2b 76 2d 3e 6e 43 6f  ( nArg==2+v->nCo
2f5a0 6c 75 6d 6e 2b 32 29 3b 0a 20 20 20 20 20 20 72  lumn+2);.      r
2f5b0 63 20 3d 20 69 6e 64 65 78 5f 75 70 64 61 74 65  c = index_update
2f5c0 28 76 2c 20 72 6f 77 69 64 2c 20 26 70 70 41 72  (v, rowid, &ppAr
2f5d0 67 5b 32 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  g[2]);.    }.  }
2f5e0 20 65 6c 73 65 20 7b 0a 20 20 20 20 2f 2a 20 41   else {.    /* A
2f5f0 6e 20 69 6e 73 65 72 74 3a 0a 20 20 20 20 20 2a  n insert:.     *
2f600 20 70 70 41 72 67 5b 31 5d 20 3d 20 72 65 71 75   ppArg[1] = requ
2f610 65 73 74 65 64 20 72 6f 77 69 64 0a 20 20 20 20  ested rowid.    
2f620 20 2a 20 70 70 41 72 67 5b 32 2e 2e 32 2b 76 2d   * ppArg[2..2+v-
2f630 3e 6e 43 6f 6c 75 6d 6e 2d 31 5d 20 3d 20 76 61  >nColumn-1] = va
2f640 6c 75 65 73 0a 20 20 20 20 20 2a 20 70 70 41 72  lues.     * ppAr
2f650 67 5b 32 2b 76 2d 3e 6e 43 6f 6c 75 6d 6e 5d 20  g[2+v->nColumn] 
2f660 3d 20 76 61 6c 75 65 20 66 6f 72 20 6d 61 67 69  = value for magi
2f670 63 20 63 6f 6c 75 6d 6e 20 28 77 65 20 69 67 6e  c column (we ign
2f680 6f 72 65 20 74 68 69 73 29 0a 20 20 20 20 20 2a  ore this).     *
2f690 20 70 70 41 72 67 5b 32 2b 76 2d 3e 6e 43 6f 6c   ppArg[2+v->nCol
2f6a0 75 6d 6e 2b 31 5d 20 3d 20 76 61 6c 75 65 20 66  umn+1] = value f
2f6b0 6f 72 20 64 6f 63 69 64 0a 20 20 20 20 20 2a 2f  or docid.     */
2f6c0 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  .    sqlite3_val
2f6d0 75 65 20 2a 70 52 65 71 75 65 73 74 44 6f 63 69  ue *pRequestDoci
2f6e0 64 20 3d 20 70 70 41 72 67 5b 32 2b 76 2d 3e 6e  d = ppArg[2+v->n
2f6f0 43 6f 6c 75 6d 6e 2b 31 5d 3b 0a 20 20 20 20 61  Column+1];.    a
2f700 73 73 65 72 74 28 20 6e 41 72 67 3d 3d 32 2b 76  ssert( nArg==2+v
2f710 2d 3e 6e 43 6f 6c 75 6d 6e 2b 32 29 3b 0a 20 20  ->nColumn+2);.  
2f720 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4e 55 4c    if( SQLITE_NUL
2f730 4c 20 21 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c  L != sqlite3_val
2f740 75 65 5f 74 79 70 65 28 70 52 65 71 75 65 73 74  ue_type(pRequest
2f750 44 6f 63 69 64 29 20 26 26 0a 20 20 20 20 20 20  Docid) &&.      
2f760 20 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 21 3d    SQLITE_NULL !=
2f770 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
2f780 79 70 65 28 70 70 41 72 67 5b 31 5d 29 20 29 7b  ype(ppArg[1]) ){
2f790 0a 20 20 20 20 20 20 2f 2a 20 54 4f 44 4f 28 73  .      /* TODO(s
2f7a0 68 65 73 73 29 20 43 6f 6e 73 69 64 65 72 20 61  hess) Consider a
2f7b0 6c 6c 6f 77 69 6e 67 20 74 68 69 73 20 74 6f 20  llowing this to 
2f7c0 77 6f 72 6b 20 69 66 20 74 68 65 20 76 61 6c 75  work if the valu
2f7d0 65 73 20 61 72 65 0a 20 20 20 20 20 20 2a 2a 20  es are.      ** 
2f7e0 69 64 65 6e 74 69 63 61 6c 2e 20 20 49 27 6d 20  identical.  I'm 
2f7f0 69 6e 63 6c 69 6e 65 64 20 74 6f 20 64 69 73 63  inclined to disc
2f800 6f 75 72 61 67 65 20 74 68 61 74 20 75 73 61 67  ourage that usag
2f810 65 2c 20 74 68 6f 75 67 68 2c 0a 20 20 20 20 20  e, though,.     
2f820 20 2a 2a 20 67 69 76 65 6e 20 74 68 61 74 20 62   ** given that b
2f830 6f 74 68 20 72 6f 77 69 64 20 61 6e 64 20 64 6f  oth rowid and do
2f840 63 69 64 20 61 72 65 20 73 70 65 63 69 61 6c 20  cid are special 
2f850 63 6f 6c 75 6d 6e 73 2e 20 20 42 65 74 74 65 72  columns.  Better
2f860 0a 20 20 20 20 20 20 2a 2a 20 77 6f 75 6c 64 20  .      ** would 
2f870 62 65 20 74 6f 20 64 65 66 69 6e 65 20 6f 6e 65  be to define one
2f880 20 6f 72 20 74 68 65 20 6f 74 68 65 72 20 61 73   or the other as
2f890 20 74 68 65 20 64 65 66 61 75 6c 74 20 77 69 6e   the default win
2f8a0 6e 65 72 2c 0a 20 20 20 20 20 20 2a 2a 20 62 75  ner,.      ** bu
2f8b0 74 20 73 68 6f 75 6c 64 20 69 74 20 62 65 20 66  t should it be f
2f8c0 74 73 33 2d 63 65 6e 74 72 69 63 20 28 64 6f 63  ts3-centric (doc
2f8d0 69 64 29 20 6f 72 20 53 51 4c 69 74 65 2d 63 65  id) or SQLite-ce
2f8e0 6e 74 72 69 63 0a 20 20 20 20 20 20 2a 2a 20 28  ntric.      ** (
2f8f0 72 6f 77 69 64 29 3f 0a 20 20 20 20 20 20 2a 2f  rowid)?.      */
2f900 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
2f910 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 65  TE_ERROR;.    }e
2f920 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20 53  lse{.      if( S
2f930 51 4c 49 54 45 5f 4e 55 4c 4c 20 3d 3d 20 73 71  QLITE_NULL == sq
2f940 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
2f950 28 70 52 65 71 75 65 73 74 44 6f 63 69 64 29 20  (pRequestDocid) 
2f960 29 7b 0a 20 20 20 20 20 20 20 20 70 52 65 71 75  ){.        pRequ
2f970 65 73 74 44 6f 63 69 64 20 3d 20 70 70 41 72 67  estDocid = ppArg
2f980 5b 31 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  [1];.      }.   
2f990 20 20 20 72 63 20 3d 20 69 6e 64 65 78 5f 69 6e     rc = index_in
2f9a0 73 65 72 74 28 76 2c 20 70 52 65 71 75 65 73 74  sert(v, pRequest
2f9b0 44 6f 63 69 64 2c 20 26 70 70 41 72 67 5b 32 5d  Docid, &ppArg[2]
2f9c0 2c 20 70 52 6f 77 69 64 29 3b 0a 20 20 20 20 7d  , pRowid);.    }
2f9d0 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
2f9e0 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
2f9f0 20 66 75 6c 6c 74 65 78 74 53 79 6e 63 28 73 71   fulltextSync(sq
2fa00 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
2fa10 62 29 7b 0a 20 20 46 54 53 54 52 41 43 45 28 28  b){.  FTSTRACE((
2fa20 22 46 54 53 33 20 78 53 79 6e 63 28 29 5c 6e 22  "FTS3 xSync()\n"
2fa30 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 66 6c 75  ));.  return flu
2fa40 73 68 50 65 6e 64 69 6e 67 54 65 72 6d 73 28 28  shPendingTerms((
2fa50 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29  fulltext_vtab *)
2fa60 70 56 74 61 62 29 3b 0a 7d 0a 0a 73 74 61 74 69  pVtab);.}..stati
2fa70 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 42 65  c int fulltextBe
2fa80 67 69 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62  gin(sqlite3_vtab
2fa90 20 2a 70 56 74 61 62 29 7b 0a 20 20 66 75 6c 6c   *pVtab){.  full
2faa0 74 65 78 74 5f 76 74 61 62 20 2a 76 20 3d 20 28  text_vtab *v = (
2fab0 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29  fulltext_vtab *)
2fac0 20 70 56 74 61 62 3b 0a 20 20 46 54 53 54 52 41   pVtab;.  FTSTRA
2fad0 43 45 28 28 22 46 54 53 33 20 78 42 65 67 69 6e  CE(("FTS3 xBegin
2fae0 28 29 5c 6e 22 29 29 3b 0a 0a 20 20 2f 2a 20 41  ()\n"));..  /* A
2faf0 6e 79 20 62 75 66 66 65 72 65 64 20 75 70 64 61  ny buffered upda
2fb00 74 65 73 20 73 68 6f 75 6c 64 20 68 61 76 65 20  tes should have 
2fb10 62 65 65 6e 20 63 6c 65 61 72 65 64 20 62 79 20  been cleared by 
2fb20 74 68 65 20 70 72 65 76 69 6f 75 73 0a 20 20 2a  the previous.  *
2fb30 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 20  * transaction.. 
2fb40 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 76 2d   */.  assert( v-
2fb50 3e 6e 50 65 6e 64 69 6e 67 44 61 74 61 3c 30 20  >nPendingData<0 
2fb60 29 3b 0a 20 20 72 65 74 75 72 6e 20 63 6c 65 61  );.  return clea
2fb70 72 50 65 6e 64 69 6e 67 54 65 72 6d 73 28 76 29  rPendingTerms(v)
2fb80 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
2fb90 66 75 6c 6c 74 65 78 74 43 6f 6d 6d 69 74 28 73  fulltextCommit(s
2fba0 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
2fbb0 61 62 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f  ab){.  fulltext_
2fbc0 76 74 61 62 20 2a 76 20 3d 20 28 66 75 6c 6c 74  vtab *v = (fullt
2fbd0 65 78 74 5f 76 74 61 62 20 2a 29 20 70 56 74 61  ext_vtab *) pVta
2fbe0 62 3b 0a 20 20 46 54 53 54 52 41 43 45 28 28 22  b;.  FTSTRACE(("
2fbf0 46 54 53 33 20 78 43 6f 6d 6d 69 74 28 29 5c 6e  FTS3 xCommit()\n
2fc00 22 29 29 3b 0a 0a 20 20 2f 2a 20 42 75 66 66 65  "));..  /* Buffe
2fc10 72 65 64 20 75 70 64 61 74 65 73 20 73 68 6f 75  red updates shou
2fc20 6c 64 20 68 61 76 65 20 62 65 65 6e 20 63 6c 65  ld have been cle
2fc30 61 72 65 64 20 62 79 20 66 75 6c 6c 74 65 78 74  ared by fulltext
2fc40 53 79 6e 63 28 29 2e 20 2a 2f 0a 20 20 61 73 73  Sync(). */.  ass
2fc50 65 72 74 28 20 76 2d 3e 6e 50 65 6e 64 69 6e 67  ert( v->nPending
2fc60 44 61 74 61 3c 30 20 29 3b 0a 20 20 72 65 74 75  Data<0 );.  retu
2fc70 72 6e 20 63 6c 65 61 72 50 65 6e 64 69 6e 67 54  rn clearPendingT
2fc80 65 72 6d 73 28 76 29 3b 0a 7d 0a 0a 73 74 61 74  erms(v);.}..stat
2fc90 69 63 20 69 6e 74 20 66 75 6c 6c 74 65 78 74 52  ic int fulltextR
2fca0 6f 6c 6c 62 61 63 6b 28 73 71 6c 69 74 65 33 5f  ollback(sqlite3_
2fcb0 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20  vtab *pVtab){.  
2fcc0 46 54 53 54 52 41 43 45 28 28 22 46 54 53 33 20  FTSTRACE(("FTS3 
2fcd0 78 52 6f 6c 6c 62 61 63 6b 28 29 5c 6e 22 29 29  xRollback()\n"))
2fce0 3b 0a 20 20 72 65 74 75 72 6e 20 63 6c 65 61 72  ;.  return clear
2fcf0 50 65 6e 64 69 6e 67 54 65 72 6d 73 28 28 66 75  PendingTerms((fu
2fd00 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 29 70 56  lltext_vtab *)pV
2fd10 74 61 62 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  tab);.}../*.** I
2fd20 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
2fd30 20 74 68 65 20 73 6e 69 70 70 65 74 28 29 20 66   the snippet() f
2fd40 75 6e 63 74 69 6f 6e 20 66 6f 72 20 46 54 53 33  unction for FTS3
2fd50 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
2fd60 73 6e 69 70 70 65 74 46 75 6e 63 28 0a 20 20 73  snippetFunc(.  s
2fd70 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
2fd80 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20  pContext,.  int 
2fd90 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argc,.  sqlite3_
2fda0 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a  value **argv.){.
2fdb0 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f    fulltext_curso
2fdc0 72 20 2a 70 43 75 72 73 6f 72 3b 0a 20 20 69 66  r *pCursor;.  if
2fdd0 28 20 61 72 67 63 3c 31 20 29 20 72 65 74 75 72  ( argc<1 ) retur
2fde0 6e 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33  n;.  if( sqlite3
2fdf0 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 72 67 76  _value_type(argv
2fe00 5b 30 5d 29 21 3d 53 51 4c 49 54 45 5f 42 4c 4f  [0])!=SQLITE_BLO
2fe10 42 20 7c 7c 0a 20 20 20 20 20 20 73 71 6c 69 74  B ||.      sqlit
2fe20 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61  e3_value_bytes(a
2fe30 72 67 76 5b 30 5d 29 21 3d 73 69 7a 65 6f 66 28  rgv[0])!=sizeof(
2fe40 70 43 75 72 73 6f 72 29 20 29 7b 0a 20 20 20 20  pCursor) ){.    
2fe50 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65  sqlite3_result_e
2fe60 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 22  rror(pContext, "
2fe70 69 6c 6c 65 67 61 6c 20 66 69 72 73 74 20 61 72  illegal first ar
2fe80 67 75 6d 65 6e 74 20 74 6f 20 68 74 6d 6c 5f 73  gument to html_s
2fe90 6e 69 70 70 65 74 22 2c 2d 31 29 3b 0a 20 20 7d  nippet",-1);.  }
2fea0 65 6c 73 65 7b 0a 20 20 20 20 63 6f 6e 73 74 20  else{.    const 
2feb0 63 68 61 72 20 2a 7a 53 74 61 72 74 20 3d 20 22  char *zStart = "
2fec0 3c 62 3e 22 3b 0a 20 20 20 20 63 6f 6e 73 74 20  <b>";.    const 
2fed0 63 68 61 72 20 2a 7a 45 6e 64 20 3d 20 22 3c 2f  char *zEnd = "</
2fee0 62 3e 22 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63  b>";.    const c
2fef0 68 61 72 20 2a 7a 45 6c 6c 69 70 73 69 73 20 3d  har *zEllipsis =
2ff00 20 22 3c 62 3e 2e 2e 2e 3c 2f 62 3e 22 3b 0a 20   "<b>...</b>";. 
2ff10 20 20 20 6d 65 6d 63 70 79 28 26 70 43 75 72 73     memcpy(&pCurs
2ff20 6f 72 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  or, sqlite3_valu
2ff30 65 5f 62 6c 6f 62 28 61 72 67 76 5b 30 5d 29 2c  e_blob(argv[0]),
2ff40 20 73 69 7a 65 6f 66 28 70 43 75 72 73 6f 72 29   sizeof(pCursor)
2ff50 29 3b 0a 20 20 20 20 69 66 28 20 61 72 67 63 3e  );.    if( argc>
2ff60 3d 32 20 29 7b 0a 20 20 20 20 20 20 7a 53 74 61  =2 ){.      zSta
2ff70 72 74 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72  rt = (const char
2ff80 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  *)sqlite3_value_
2ff90 74 65 78 74 28 61 72 67 76 5b 31 5d 29 3b 0a 20  text(argv[1]);. 
2ffa0 20 20 20 20 20 69 66 28 20 61 72 67 63 3e 3d 33       if( argc>=3
2ffb0 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 45 6e 64   ){.        zEnd
2ffc0 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29   = (const char*)
2ffd0 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
2ffe0 78 74 28 61 72 67 76 5b 32 5d 29 3b 0a 20 20 20  xt(argv[2]);.   
2fff0 20 20 20 20 20 69 66 28 20 61 72 67 63 3e 3d 34       if( argc>=4
30000 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 45   ){.          zE
30010 6c 6c 69 70 73 69 73 20 3d 20 28 63 6f 6e 73 74  llipsis = (const
30020 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76   char*)sqlite3_v
30030 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 33  alue_text(argv[3
30040 5d 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  ]);.        }.  
30050 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
30060 73 6e 69 70 70 65 74 41 6c 6c 4f 66 66 73 65 74  snippetAllOffset
30070 73 28 70 43 75 72 73 6f 72 29 3b 0a 20 20 20 20  s(pCursor);.    
30080 73 6e 69 70 70 65 74 54 65 78 74 28 70 43 75 72  snippetText(pCur
30090 73 6f 72 2c 20 7a 53 74 61 72 74 2c 20 7a 45 6e  sor, zStart, zEn
300a0 64 2c 20 7a 45 6c 6c 69 70 73 69 73 29 3b 0a 20  d, zEllipsis);. 
300b0 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
300c0 74 5f 74 65 78 74 28 70 43 6f 6e 74 65 78 74 2c  t_text(pContext,
300d0 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65   pCursor->snippe
300e0 74 2e 7a 53 6e 69 70 70 65 74 2c 0a 20 20 20 20  t.zSnippet,.    
300f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30100 20 20 20 20 70 43 75 72 73 6f 72 2d 3e 73 6e 69      pCursor->sni
30110 70 70 65 74 2e 6e 53 6e 69 70 70 65 74 2c 20 53  ppet.nSnippet, S
30120 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20  QLITE_STATIC);. 
30130 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c   }.}../*.** Impl
30140 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
30150 65 20 6f 66 66 73 65 74 73 28 29 20 66 75 6e 63  e offsets() func
30160 74 69 6f 6e 20 66 6f 72 20 46 54 53 33 0a 2a 2f  tion for FTS3.*/
30170 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 6e 69  .static void sni
30180 70 70 65 74 4f 66 66 73 65 74 73 46 75 6e 63 28  ppetOffsetsFunc(
30190 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65  .  sqlite3_conte
301a0 78 74 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20  xt *pContext,.  
301b0 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69  int argc,.  sqli
301c0 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76  te3_value **argv
301d0 0a 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63  .){.  fulltext_c
301e0 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 3b 0a  ursor *pCursor;.
301f0 20 20 69 66 28 20 61 72 67 63 3c 31 20 29 20 72    if( argc<1 ) r
30200 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 73 71 6c  eturn;.  if( sql
30210 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
30220 61 72 67 76 5b 30 5d 29 21 3d 53 51 4c 49 54 45  argv[0])!=SQLITE
30230 5f 42 4c 4f 42 20 7c 7c 0a 20 20 20 20 20 20 73  _BLOB ||.      s
30240 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74  qlite3_value_byt
30250 65 73 28 61 72 67 76 5b 30 5d 29 21 3d 73 69 7a  es(argv[0])!=siz
30260 65 6f 66 28 70 43 75 72 73 6f 72 29 20 29 7b 0a  eof(pCursor) ){.
30270 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
30280 6c 74 5f 65 72 72 6f 72 28 70 43 6f 6e 74 65 78  lt_error(pContex
30290 74 2c 20 22 69 6c 6c 65 67 61 6c 20 66 69 72 73  t, "illegal firs
302a0 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 6f 66  t argument to of
302b0 66 73 65 74 73 22 2c 2d 31 29 3b 0a 20 20 7d 65  fsets",-1);.  }e
302c0 6c 73 65 7b 0a 20 20 20 20 6d 65 6d 63 70 79 28  lse{.    memcpy(
302d0 26 70 43 75 72 73 6f 72 2c 20 73 71 6c 69 74 65  &pCursor, sqlite
302e0 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 61 72 67  3_value_blob(arg
302f0 76 5b 30 5d 29 2c 20 73 69 7a 65 6f 66 28 70 43  v[0]), sizeof(pC
30300 75 72 73 6f 72 29 29 3b 0a 20 20 20 20 73 6e 69  ursor));.    sni
30310 70 70 65 74 41 6c 6c 4f 66 66 73 65 74 73 28 70  ppetAllOffsets(p
30320 43 75 72 73 6f 72 29 3b 0a 20 20 20 20 73 6e 69  Cursor);.    sni
30330 70 70 65 74 4f 66 66 73 65 74 54 65 78 74 28 26  ppetOffsetText(&
30340 70 43 75 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74  pCursor->snippet
30350 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  );.    sqlite3_r
30360 65 73 75 6c 74 5f 74 65 78 74 28 70 43 6f 6e 74  esult_text(pCont
30370 65 78 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ext,.           
30380 20 20 20 20 20 20 20 20 20 20 20 20 20 70 43 75               pCu
30390 72 73 6f 72 2d 3e 73 6e 69 70 70 65 74 2e 7a 4f  rsor->snippet.zO
303a0 66 66 73 65 74 2c 20 70 43 75 72 73 6f 72 2d 3e  ffset, pCursor->
303b0 73 6e 69 70 70 65 74 2e 6e 4f 66 66 73 65 74 2c  snippet.nOffset,
303c0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
303d0 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
303e0 53 54 41 54 49 43 29 3b 0a 20 20 7d 0a 7d 0a 0a  STATIC);.  }.}..
303f0 2f 2a 20 4f 70 74 4c 65 61 76 65 73 52 65 61 64  /* OptLeavesRead
30400 65 72 20 69 73 20 6e 65 61 72 6c 79 20 69 64 65  er is nearly ide
30410 6e 74 69 63 61 6c 20 74 6f 20 4c 65 61 76 65 73  ntical to Leaves
30420 52 65 61 64 65 72 2c 20 65 78 63 65 70 74 20 74  Reader, except t
30430 68 61 74 0a 2a 2a 20 77 68 65 72 65 20 4c 65 61  hat.** where Lea
30440 76 65 73 52 65 61 64 65 72 20 69 73 20 67 65 61  vesReader is gea
30450 72 65 64 20 74 6f 77 61 72 64 73 20 74 68 65 20  red towards the 
30460 6d 65 72 67 69 6e 67 20 6f 66 20 63 6f 6d 70 6c  merging of compl
30470 65 74 65 0a 2a 2a 20 73 65 67 6d 65 6e 74 20 6c  ete.** segment l
30480 65 76 65 6c 73 20 28 77 69 74 68 20 65 78 61 63  evels (with exac
30490 74 6c 79 20 4d 45 52 47 45 5f 43 4f 55 4e 54 20  tly MERGE_COUNT 
304a0 73 65 67 6d 65 6e 74 73 29 2c 20 4f 70 74 4c 65  segments), OptLe
304b0 61 76 65 73 52 65 61 64 65 72 0a 2a 2a 20 69 73  avesReader.** is
304c0 20 67 65 61 72 65 64 20 74 6f 77 61 72 64 73 20   geared towards 
304d0 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  implementation o
304e0 66 20 74 68 65 20 6f 70 74 69 6d 69 7a 65 28 29  f the optimize()
304f0 20 66 75 6e 63 74 69 6f 6e 2c 20 61 6e 64 0a 2a   function, and.*
30500 2a 20 63 61 6e 20 6d 65 72 67 65 20 61 6c 6c 20  * can merge all 
30510 73 65 67 6d 65 6e 74 73 20 73 69 6d 75 6c 74 61  segments simulta
30520 6e 65 6f 75 73 6c 79 2e 20 20 54 68 69 73 20 76  neously.  This v
30530 65 72 73 69 6f 6e 20 6d 61 79 20 62 65 0a 2a 2a  ersion may be.**
30540 20 73 6f 6d 65 77 68 61 74 20 6c 65 73 73 20 65   somewhat less e
30550 66 66 69 63 69 65 6e 74 20 74 68 61 6e 20 4c 65  fficient than Le
30560 61 76 65 73 52 65 61 64 65 72 20 62 65 63 61 75  avesReader becau
30570 73 65 20 69 74 20 6d 65 72 67 65 73 20 69 6e 74  se it merges int
30580 6f 20 61 6e 0a 2a 2a 20 61 63 63 75 6d 75 6c 61  o an.** accumula
30590 74 6f 72 20 72 61 74 68 65 72 20 74 68 61 6e 20  tor rather than 
305a0 64 6f 69 6e 67 20 61 6e 20 4e 2d 77 61 79 20 6d  doing an N-way m
305b0 65 72 67 65 2c 20 62 75 74 20 73 69 6e 63 65 20  erge, but since 
305c0 73 65 67 6d 65 6e 74 0a 2a 2a 20 73 69 7a 65 20  segment.** size 
305d0 67 72 6f 77 73 20 65 78 70 6f 6e 65 6e 74 69 61  grows exponentia
305e0 6c 6c 79 20 28 73 6f 20 73 65 67 6d 65 6e 74 20  lly (so segment 
305f0 63 6f 75 6e 74 20 6c 6f 67 72 69 74 68 6d 69 63  count logrithmic
30600 61 6c 6c 79 29 20 74 68 69 73 20 69 73 0a 2a 2a  ally) this is.**
30610 20 70 72 6f 62 61 62 6c 79 20 6e 6f 74 20 61 6e   probably not an
30620 20 69 6d 6d 65 64 69 61 74 65 20 70 72 6f 62 6c   immediate probl
30630 65 6d 2e 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f 28 73  em..*/./* TODO(s
30640 68 65 73 73 29 3a 20 50 72 6f 76 65 20 74 68 61  hess): Prove tha
30650 74 20 61 73 73 65 72 74 69 6f 6e 2c 20 6f 72 20  t assertion, or 
30660 65 78 74 65 6e 64 20 74 68 65 20 6d 65 72 67 65  extend the merge
30670 20 63 6f 64 65 20 74 6f 0a 2a 2a 20 6d 65 72 67   code to.** merg
30680 65 20 74 72 65 65 20 66 61 73 68 69 6f 6e 20 28  e tree fashion (
30690 6c 69 6b 65 20 74 68 65 20 70 72 65 66 69 78 2d  like the prefix-
306a0 73 65 61 72 63 68 69 6e 67 20 63 6f 64 65 20 64  searching code d
306b0 6f 65 73 29 2e 0a 2a 2f 0a 2f 2a 20 54 4f 44 4f  oes)..*/./* TODO
306c0 28 73 68 65 73 73 29 3a 20 4f 70 74 4c 65 61 76  (shess): OptLeav
306d0 65 73 52 65 61 64 65 72 20 61 6e 64 20 4c 65 61  esReader and Lea
306e0 76 65 73 52 65 61 64 65 72 20 63 6f 75 6c 64 20  vesReader could 
306f0 70 72 6f 62 61 62 6c 79 20 62 65 0a 2a 2a 20 6d  probably be.** m
30700 65 72 67 65 64 20 77 69 74 68 20 6c 69 74 74 6c  erged with littl
30710 65 20 6f 72 20 6e 6f 20 6c 6f 73 73 20 6f 66 20  e or no loss of 
30720 70 65 72 66 6f 72 6d 61 6e 63 65 20 66 6f 72 20  performance for 
30730 4c 65 61 76 65 73 52 65 61 64 65 72 2e 20 20 54  LeavesReader.  T
30740 68 65 0a 2a 2a 20 6d 65 72 67 65 64 20 63 6f 64  he.** merged cod
30750 65 20 77 6f 75 6c 64 20 6e 65 65 64 20 74 6f 20  e would need to 
30760 68 61 6e 64 6c 65 20 3e 4d 45 52 47 45 5f 43 4f  handle >MERGE_CO
30770 55 4e 54 20 73 65 67 6d 65 6e 74 73 2c 20 61 6e  UNT segments, an
30780 64 20 77 6f 75 6c 64 0a 2a 2a 20 61 6c 73 6f 20  d would.** also 
30790 6e 65 65 64 20 74 6f 20 62 65 20 61 62 6c 65 20  need to be able 
307a0 74 6f 20 6f 70 74 69 6f 6e 61 6c 6c 79 20 6f 70  to optionally op
307b0 74 69 6d 69 7a 65 20 61 77 61 79 20 64 65 6c 65  timize away dele
307c0 74 65 73 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20  tes..*/.typedef 
307d0 73 74 72 75 63 74 20 4f 70 74 4c 65 61 76 65 73  struct OptLeaves
307e0 52 65 61 64 65 72 20 7b 0a 20 20 2f 2a 20 53 65  Reader {.  /* Se
307f0 67 6d 65 6e 74 20 6e 75 6d 62 65 72 2c 20 74 6f  gment number, to
30800 20 6f 72 64 65 72 20 72 65 61 64 65 72 73 20 62   order readers b
30810 79 20 61 67 65 2e 20 2a 2f 0a 20 20 69 6e 74 20  y age. */.  int 
30820 73 65 67 6d 65 6e 74 3b 0a 20 20 4c 65 61 76 65  segment;.  Leave
30830 73 52 65 61 64 65 72 20 72 65 61 64 65 72 3b 0a  sReader reader;.
30840 7d 20 4f 70 74 4c 65 61 76 65 73 52 65 61 64 65  } OptLeavesReade
30850 72 3b 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 6f  r;..static int o
30860 70 74 4c 65 61 76 65 73 52 65 61 64 65 72 41 74  ptLeavesReaderAt
30870 45 6e 64 28 4f 70 74 4c 65 61 76 65 73 52 65 61  End(OptLeavesRea
30880 64 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20  der *pReader){. 
30890 20 72 65 74 75 72 6e 20 6c 65 61 76 65 73 52 65   return leavesRe
308a0 61 64 65 72 41 74 45 6e 64 28 26 70 52 65 61 64  aderAtEnd(&pRead
308b0 65 72 2d 3e 72 65 61 64 65 72 29 3b 0a 7d 0a 73  er->reader);.}.s
308c0 74 61 74 69 63 20 69 6e 74 20 6f 70 74 4c 65 61  tatic int optLea
308d0 76 65 73 52 65 61 64 65 72 54 65 72 6d 42 79 74  vesReaderTermByt
308e0 65 73 28 4f 70 74 4c 65 61 76 65 73 52 65 61 64  es(OptLeavesRead
308f0 65 72 20 2a 70 52 65 61 64 65 72 29 7b 0a 20 20  er *pReader){.  
30900 72 65 74 75 72 6e 20 6c 65 61 76 65 73 52 65 61  return leavesRea
30910 64 65 72 54 65 72 6d 42 79 74 65 73 28 26 70 52  derTermBytes(&pR
30920 65 61 64 65 72 2d 3e 72 65 61 64 65 72 29 3b 0a  eader->reader);.
30930 7d 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63  }.static const c
30940 68 61 72 20 2a 6f 70 74 4c 65 61 76 65 73 52 65  har *optLeavesRe
30950 61 64 65 72 44 61 74 61 28 4f 70 74 4c 65 61 76  aderData(OptLeav
30960 65 73 52 65 61 64 65 72 20 2a 70 52 65 61 64 65  esReader *pReade
30970 72 29 7b 0a 20 20 72 65 74 75 72 6e 20 6c 65 61  r){.  return lea
30980 76 65 73 52 65 61 64 65 72 44 61 74 61 28 26 70  vesReaderData(&p
30990 52 65 61 64 65 72 2d 3e 72 65 61 64 65 72 29 3b  Reader->reader);
309a0 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 6f 70  .}.static int op
309b0 74 4c 65 61 76 65 73 52 65 61 64 65 72 44 61 74  tLeavesReaderDat
309c0 61 42 79 74 65 73 28 4f 70 74 4c 65 61 76 65 73  aBytes(OptLeaves
309d0 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72 29  Reader *pReader)
309e0 7b 0a 20 20 72 65 74 75 72 6e 20 6c 65 61 76 65  {.  return leave
309f0 73 52 65 61 64 65 72 44 61 74 61 42 79 74 65 73  sReaderDataBytes
30a00 28 26 70 52 65 61 64 65 72 2d 3e 72 65 61 64 65  (&pReader->reade
30a10 72 29 3b 0a 7d 0a 73 74 61 74 69 63 20 63 6f 6e  r);.}.static con
30a20 73 74 20 63 68 61 72 20 2a 6f 70 74 4c 65 61 76  st char *optLeav
30a30 65 73 52 65 61 64 65 72 54 65 72 6d 28 4f 70 74  esReaderTerm(Opt
30a40 4c 65 61 76 65 73 52 65 61 64 65 72 20 2a 70 52  LeavesReader *pR
30a50 65 61 64 65 72 29 7b 0a 20 20 72 65 74 75 72 6e  eader){.  return
30a60 20 6c 65 61 76 65 73 52 65 61 64 65 72 54 65 72   leavesReaderTer
30a70 6d 28 26 70 52 65 61 64 65 72 2d 3e 72 65 61 64  m(&pReader->read
30a80 65 72 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e  er);.}.static in
30a90 74 20 6f 70 74 4c 65 61 76 65 73 52 65 61 64 65  t optLeavesReade
30aa0 72 53 74 65 70 28 66 75 6c 6c 74 65 78 74 5f 76  rStep(fulltext_v
30ab0 74 61 62 20 2a 76 2c 20 4f 70 74 4c 65 61 76 65  tab *v, OptLeave
30ac0 73 52 65 61 64 65 72 20 2a 70 52 65 61 64 65 72  sReader *pReader
30ad0 29 7b 0a 20 20 72 65 74 75 72 6e 20 6c 65 61 76  ){.  return leav
30ae0 65 73 52 65 61 64 65 72 53 74 65 70 28 76 2c 20  esReaderStep(v, 
30af0 26 70 52 65 61 64 65 72 2d 3e 72 65 61 64 65 72  &pReader->reader
30b00 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  );.}.static int 
30b10 6f 70 74 4c 65 61 76 65 73 52 65 61 64 65 72 54  optLeavesReaderT
30b20 65 72 6d 43 6d 70 28 4f 70 74 4c 65 61 76 65 73  ermCmp(OptLeaves
30b30 52 65 61 64 65 72 20 2a 6c 72 31 2c 20 4f 70 74  Reader *lr1, Opt
30b40 4c 65 61 76 65 73 52 65 61 64 65 72 20 2a 6c 72  LeavesReader *lr
30b50 32 29 7b 0a 20 20 72 65 74 75 72 6e 20 6c 65 61  2){.  return lea
30b60 76 65 73 52 65 61 64 65 72 54 65 72 6d 43 6d 70  vesReaderTermCmp
30b70 28 26 6c 72 31 2d 3e 72 65 61 64 65 72 2c 20 26  (&lr1->reader, &
30b80 6c 72 32 2d 3e 72 65 61 64 65 72 29 3b 0a 7d 0a  lr2->reader);.}.
30b90 2f 2a 20 4f 72 64 65 72 20 62 79 20 74 65 72 6d  /* Order by term
30ba0 20 61 73 63 65 6e 64 69 6e 67 2c 20 73 65 67 6d   ascending, segm
30bb0 65 6e 74 20 61 73 63 65 6e 64 69 6e 67 20 28 6f  ent ascending (o
30bc0 6c 64 65 73 74 20 74 6f 20 6e 65 77 65 73 74 29  ldest to newest)
30bd0 2c 20 77 69 74 68 0a 2a 2a 20 65 78 68 61 75 73  , with.** exhaus
30be0 74 65 64 20 72 65 61 64 65 72 73 20 74 6f 20 74  ted readers to t
30bf0 68 65 20 65 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69  he end..*/.stati
30c00 63 20 69 6e 74 20 6f 70 74 4c 65 61 76 65 73 52  c int optLeavesR
30c10 65 61 64 65 72 43 6d 70 28 4f 70 74 4c 65 61 76  eaderCmp(OptLeav
30c20 65 73 52 65 61 64 65 72 20 2a 6c 72 31 2c 20 4f  esReader *lr1, O
30c30 70 74 4c 65 61 76 65 73 52 65 61 64 65 72 20 2a  ptLeavesReader *
30c40 6c 72 32 29 7b 0a 20 20 69 6e 74 20 63 20 3d 20  lr2){.  int c = 
30c50 6f 70 74 4c 65 61 76 65 73 52 65 61 64 65 72 54  optLeavesReaderT
30c60 65 72 6d 43 6d 70 28 6c 72 31 2c 20 6c 72 32 29  ermCmp(lr1, lr2)
30c70 3b 0a 20 20 69 66 28 20 63 21 3d 30 20 29 20 72  ;.  if( c!=0 ) r
30c80 65 74 75 72 6e 20 63 3b 0a 20 20 72 65 74 75 72  eturn c;.  retur
30c90 6e 20 6c 72 31 2d 3e 73 65 67 6d 65 6e 74 2d 6c  n lr1->segment-l
30ca0 72 32 2d 3e 73 65 67 6d 65 6e 74 3b 0a 7d 0a 2f  r2->segment;.}./
30cb0 2a 20 42 75 62 62 6c 65 20 70 4c 72 5b 30 5d 20  * Bubble pLr[0] 
30cc0 74 6f 20 61 70 70 72 6f 70 72 69 61 74 65 20 70  to appropriate p
30cd0 6c 61 63 65 20 69 6e 20 70 4c 72 5b 31 2e 2e 6e  lace in pLr[1..n
30ce0 4c 72 2d 31 5d 2e 20 20 41 73 73 75 6d 65 73 20  Lr-1].  Assumes 
30cf0 74 68 61 74 0a 2a 2a 20 70 4c 72 5b 31 2e 2e 6e  that.** pLr[1..n
30d00 4c 72 2d 31 5d 20 69 73 20 61 6c 72 65 61 64 79  Lr-1] is already
30d10 20 73 6f 72 74 65 64 2e 0a 2a 2f 0a 73 74 61 74   sorted..*/.stat
30d20 69 63 20 76 6f 69 64 20 6f 70 74 4c 65 61 76 65  ic void optLeave
30d30 73 52 65 61 64 65 72 52 65 6f 72 64 65 72 28 4f  sReaderReorder(O
30d40 70 74 4c 65 61 76 65 73 52 65 61 64 65 72 20 2a  ptLeavesReader *
30d50 70 4c 72 2c 20 69 6e 74 20 6e 4c 72 29 7b 0a 20  pLr, int nLr){. 
30d60 20 77 68 69 6c 65 28 20 6e 4c 72 3e 31 20 26 26   while( nLr>1 &&
30d70 20 6f 70 74 4c 65 61 76 65 73 52 65 61 64 65 72   optLeavesReader
30d80 43 6d 70 28 70 4c 72 2c 20 70 4c 72 2b 31 29 3e  Cmp(pLr, pLr+1)>
30d90 30 20 29 7b 0a 20 20 20 20 4f 70 74 4c 65 61 76  0 ){.    OptLeav
30da0 65 73 52 65 61 64 65 72 20 74 6d 70 20 3d 20 70  esReader tmp = p
30db0 4c 72 5b 30 5d 3b 0a 20 20 20 20 70 4c 72 5b 30  Lr[0];.    pLr[0
30dc0 5d 20 3d 20 70 4c 72 5b 31 5d 3b 0a 20 20 20 20  ] = pLr[1];.    
30dd0 70 4c 72 5b 31 5d 20 3d 20 74 6d 70 3b 0a 20 20  pLr[1] = tmp;.  
30de0 20 20 6e 4c 72 2d 2d 3b 0a 20 20 20 20 70 4c 72    nLr--;.    pLr
30df0 2b 2b 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 6f 70  ++;.  }.}../* op
30e00 74 69 6d 69 7a 65 28 29 20 68 65 6c 70 65 72 20  timize() helper 
30e10 66 75 6e 63 74 69 6f 6e 2e 20 20 50 75 74 20 74  function.  Put t
30e20 68 65 20 72 65 61 64 65 72 73 20 69 6e 20 6f 72  he readers in or
30e30 64 65 72 20 61 6e 64 20 69 74 65 72 61 74 65 0a  der and iterate.
30e40 2a 2a 20 74 68 72 6f 75 67 68 20 74 68 65 6d 2c  ** through them,
30e50 20 6d 65 72 67 69 6e 67 20 64 6f 63 6c 69 73 74   merging doclist
30e60 73 20 66 6f 72 20 6d 61 74 63 68 69 6e 67 20 74  s for matching t
30e70 65 72 6d 73 20 69 6e 74 6f 20 70 57 72 69 74 65  erms into pWrite
30e80 72 2e 0a 2a 2a 20 52 65 74 75 72 6e 73 20 53 51  r..** Returns SQ
30e90 4c 49 54 45 5f 4f 4b 20 6f 6e 20 73 75 63 63 65  LITE_OK on succe
30ea0 73 73 2c 20 6f 72 20 74 68 65 20 53 51 4c 69 74  ss, or the SQLit
30eb0 65 20 65 72 72 6f 72 20 63 6f 64 65 20 77 68 69  e error code whi
30ec0 63 68 0a 2a 2a 20 70 72 65 76 65 6e 74 65 64 20  ch.** prevented 
30ed0 73 75 63 63 65 73 73 2e 0a 2a 2f 0a 73 74 61 74  success..*/.stat
30ee0 69 63 20 69 6e 74 20 6f 70 74 69 6d 69 7a 65 49  ic int optimizeI
30ef0 6e 74 65 72 6e 61 6c 28 66 75 6c 6c 74 65 78 74  nternal(fulltext
30f00 5f 76 74 61 62 20 2a 76 2c 0a 20 20 20 20 20 20  _vtab *v,.      
30f10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30f20 20 20 20 20 20 20 4f 70 74 4c 65 61 76 65 73 52        OptLeavesR
30f30 65 61 64 65 72 20 2a 72 65 61 64 65 72 73 2c 20  eader *readers, 
30f40 69 6e 74 20 6e 52 65 61 64 65 72 73 2c 0a 20 20  int nReaders,.  
30f50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30f60 20 20 20 20 20 20 20 20 20 20 4c 65 61 66 57 72            LeafWr
30f70 69 74 65 72 20 2a 70 57 72 69 74 65 72 29 7b 0a  iter *pWriter){.
30f80 20 20 69 6e 74 20 69 2c 20 72 63 20 3d 20 53 51    int i, rc = SQ
30f90 4c 49 54 45 5f 4f 4b 3b 0a 20 20 44 61 74 61 42  LITE_OK;.  DataB
30fa0 75 66 66 65 72 20 64 6f 63 6c 69 73 74 2c 20 6d  uffer doclist, m
30fb0 65 72 67 65 64 2c 20 74 6d 70 3b 0a 0a 20 20 2f  erged, tmp;..  /
30fc0 2a 20 4f 72 64 65 72 20 74 68 65 20 72 65 61 64  * Order the read
30fd0 65 72 73 2e 20 2a 2f 0a 20 20 69 20 3d 20 6e 52  ers. */.  i = nR
30fe0 65 61 64 65 72 73 3b 0a 20 20 77 68 69 6c 65 28  eaders;.  while(
30ff0 20 69 2d 2d 20 3e 20 30 20 29 7b 0a 20 20 20 20   i-- > 0 ){.    
31000 6f 70 74 4c 65 61 76 65 73 52 65 61 64 65 72 52  optLeavesReaderR
31010 65 6f 72 64 65 72 28 26 72 65 61 64 65 72 73 5b  eorder(&readers[
31020 69 5d 2c 20 6e 52 65 61 64 65 72 73 2d 69 29 3b  i], nReaders-i);
31030 0a 20 20 7d 0a 0a 20 20 64 61 74 61 42 75 66 66  .  }..  dataBuff
31040 65 72 49 6e 69 74 28 26 64 6f 63 6c 69 73 74 2c  erInit(&doclist,
31050 20 4c 45 41 46 5f 4d 41 58 29 3b 0a 20 20 64 61   LEAF_MAX);.  da
31060 74 61 42 75 66 66 65 72 49 6e 69 74 28 26 6d 65  taBufferInit(&me
31070 72 67 65 64 2c 20 4c 45 41 46 5f 4d 41 58 29 3b  rged, LEAF_MAX);
31080 0a 0a 20 20 2f 2a 20 45 78 68 61 75 73 74 65 64  ..  /* Exhausted
31090 20 72 65 61 64 65 72 73 20 62 75 62 62 6c 65 20   readers bubble 
310a0 74 6f 20 74 68 65 20 65 6e 64 2c 20 73 6f 20 77  to the end, so w
310b0 68 65 6e 20 74 68 65 20 66 69 72 73 74 20 72 65  hen the first re
310c0 61 64 65 72 20 69 73 0a 20 20 2a 2a 20 61 74 20  ader is.  ** at 
310d0 65 6f 66 2c 20 61 6c 6c 20 61 72 65 20 61 74 20  eof, all are at 
310e0 65 6f 66 2e 0a 20 20 2a 2f 0a 20 20 77 68 69 6c  eof..  */.  whil
310f0 65 28 20 21 6f 70 74 4c 65 61 76 65 73 52 65 61  e( !optLeavesRea
31100 64 65 72 41 74 45 6e 64 28 26 72 65 61 64 65 72  derAtEnd(&reader
31110 73 5b 30 5d 29 20 29 7b 0a 0a 20 20 20 20 2f 2a  s[0]) ){..    /*
31120 20 46 69 67 75 72 65 20 6f 75 74 20 68 6f 77 20   Figure out how 
31130 6d 61 6e 79 20 72 65 61 64 65 72 73 20 73 68 61  many readers sha
31140 72 65 20 74 68 65 20 6e 65 78 74 20 74 65 72 6d  re the next term
31150 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d 31  . */.    for(i=1
31160 3b 20 69 3c 6e 52 65 61 64 65 72 73 20 26 26 20  ; i<nReaders && 
31170 21 6f 70 74 4c 65 61 76 65 73 52 65 61 64 65 72  !optLeavesReader
31180 41 74 45 6e 64 28 26 72 65 61 64 65 72 73 5b 69  AtEnd(&readers[i
31190 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ]); i++){.      
311a0 69 66 28 20 30 21 3d 6f 70 74 4c 65 61 76 65 73  if( 0!=optLeaves
311b0 52 65 61 64 65 72 54 65 72 6d 43 6d 70 28 26 72  ReaderTermCmp(&r
311c0 65 61 64 65 72 73 5b 30 5d 2c 20 26 72 65 61 64  eaders[0], &read
311d0 65 72 73 5b 69 5d 29 20 29 20 62 72 65 61 6b 3b  ers[i]) ) break;
311e0 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 53  .    }..    /* S
311f0 70 65 63 69 61 6c 2d 63 61 73 65 20 66 6f 72 20  pecial-case for 
31200 6e 6f 20 6d 65 72 67 65 2e 20 2a 2f 0a 20 20 20  no merge. */.   
31210 20 69 66 28 20 69 3d 3d 31 20 29 7b 0a 20 20 20   if( i==1 ){.   
31220 20 20 20 2f 2a 20 54 72 69 6d 20 64 65 6c 65 74     /* Trim delet
31230 69 6f 6e 73 20 66 72 6f 6d 20 74 68 65 20 64 6f  ions from the do
31240 63 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20 20 20  clist. */.      
31250 64 61 74 61 42 75 66 66 65 72 52 65 73 65 74 28  dataBufferReset(
31260 26 6d 65 72 67 65 64 29 3b 0a 20 20 20 20 20 20  &merged);.      
31270 64 6f 63 4c 69 73 74 54 72 69 6d 28 44 4c 5f 44  docListTrim(DL_D
31280 45 46 41 55 4c 54 2c 0a 20 20 20 20 20 20 20 20  EFAULT,.        
31290 20 20 20 20 20 20 20 20 20 20 6f 70 74 4c 65 61            optLea
312a0 76 65 73 52 65 61 64 65 72 44 61 74 61 28 26 72  vesReaderData(&r
312b0 65 61 64 65 72 73 5b 30 5d 29 2c 0a 20 20 20 20  eaders[0]),.    
312c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6f 70                op
312d0 74 4c 65 61 76 65 73 52 65 61 64 65 72 44 61 74  tLeavesReaderDat
312e0 61 42 79 74 65 73 28 26 72 65 61 64 65 72 73 5b  aBytes(&readers[
312f0 30 5d 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20  0]),.           
31300 20 20 20 20 20 20 20 2d 31 2c 20 44 4c 5f 44 45         -1, DL_DE
31310 46 41 55 4c 54 2c 20 26 6d 65 72 67 65 64 29 3b  FAULT, &merged);
31320 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
31330 20 20 44 4c 52 65 61 64 65 72 20 64 6c 52 65 61    DLReader dlRea
31340 64 65 72 73 5b 4d 45 52 47 45 5f 43 4f 55 4e 54  ders[MERGE_COUNT
31350 5d 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 52 65  ];.      int iRe
31360 61 64 65 72 2c 20 6e 52 65 61 64 65 72 73 3b 0a  ader, nReaders;.
31370 0a 20 20 20 20 20 20 2f 2a 20 50 72 69 6d 65 20  .      /* Prime 
31380 74 68 65 20 70 69 70 65 6c 69 6e 65 20 77 69 74  the pipeline wit
31390 68 20 74 68 65 20 66 69 72 73 74 20 72 65 61 64  h the first read
313a0 65 72 27 73 20 64 6f 63 6c 69 73 74 2e 20 20 41  er's doclist.  A
313b0 66 74 65 72 0a 20 20 20 20 20 20 2a 2a 20 6f 6e  fter.      ** on
313c0 65 20 70 61 73 73 20 69 6e 64 65 78 20 30 20 77  e pass index 0 w
313d0 69 6c 6c 20 72 65 66 65 72 65 6e 63 65 20 74 68  ill reference th
313e0 65 20 61 63 63 75 6d 75 6c 61 74 65 64 20 64 6f  e accumulated do
313f0 63 6c 69 73 74 2e 0a 20 20 20 20 20 20 2a 2f 0a  clist..      */.
31400 20 20 20 20 20 20 64 6c 72 49 6e 69 74 28 26 64        dlrInit(&d
31410 6c 52 65 61 64 65 72 73 5b 30 5d 2c 20 44 4c 5f  lReaders[0], DL_
31420 44 45 46 41 55 4c 54 2c 0a 20 20 20 20 20 20 20  DEFAULT,.       
31430 20 20 20 20 20 20 20 6f 70 74 4c 65 61 76 65 73         optLeaves
31440 52 65 61 64 65 72 44 61 74 61 28 26 72 65 61 64  ReaderData(&read
31450 65 72 73 5b 30 5d 29 2c 0a 20 20 20 20 20 20 20  ers[0]),.       
31460 20 20 20 20 20 20 20 6f 70 74 4c 65 61 76 65 73         optLeaves
31470 52 65 61 64 65 72 44 61 74 61 42 79 74 65 73 28  ReaderDataBytes(
31480 26 72 65 61 64 65 72 73 5b 30 5d 29 29 3b 0a 20  &readers[0]));. 
31490 20 20 20 20 20 69 52 65 61 64 65 72 20 3d 20 31       iReader = 1
314a0 3b 0a 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  ;..      assert(
314b0 20 69 52 65 61 64 65 72 3c 69 20 29 3b 20 20 2f   iReader<i );  /
314c0 2a 20 4d 75 73 74 20 65 78 65 63 75 74 65 20 74  * Must execute t
314d0 68 65 20 6c 6f 6f 70 20 61 74 20 6c 65 61 73 74  he loop at least
314e0 20 6f 6e 63 65 2e 20 2a 2f 0a 20 20 20 20 20 20   once. */.      
314f0 77 68 69 6c 65 28 20 69 52 65 61 64 65 72 3c 69  while( iReader<i
31500 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 4d   ){.        /* M
31510 65 72 67 65 20 31 36 20 69 6e 70 75 74 73 20 70  erge 16 inputs p
31520 65 72 20 70 61 73 73 2e 20 2a 2f 0a 20 20 20 20  er pass. */.    
31530 20 20 20 20 66 6f 72 28 20 6e 52 65 61 64 65 72      for( nReader
31540 73 3d 31 3b 20 69 52 65 61 64 65 72 3c 69 20 26  s=1; iReader<i &
31550 26 20 6e 52 65 61 64 65 72 73 3c 4d 45 52 47 45  & nReaders<MERGE
31560 5f 43 4f 55 4e 54 3b 0a 20 20 20 20 20 20 20 20  _COUNT;.        
31570 20 20 20 20 20 69 52 65 61 64 65 72 2b 2b 2c 20       iReader++, 
31580 6e 52 65 61 64 65 72 73 2b 2b 20 29 7b 0a 20 20  nReaders++ ){.  
31590 20 20 20 20 20 20 20 20 64 6c 72 49 6e 69 74 28          dlrInit(
315a0 26 64 6c 52 65 61 64 65 72 73 5b 6e 52 65 61 64  &dlReaders[nRead
315b0 65 72 73 5d 2c 20 44 4c 5f 44 45 46 41 55 4c 54  ers], DL_DEFAULT
315c0 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
315d0 20 20 20 20 6f 70 74 4c 65 61 76 65 73 52 65 61      optLeavesRea
315e0 64 65 72 44 61 74 61 28 26 72 65 61 64 65 72 73  derData(&readers
315f0 5b 69 52 65 61 64 65 72 5d 29 2c 0a 20 20 20 20  [iReader]),.    
31600 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6f 70                op
31610 74 4c 65 61 76 65 73 52 65 61 64 65 72 44 61 74  tLeavesReaderDat
31620 61 42 79 74 65 73 28 26 72 65 61 64 65 72 73 5b  aBytes(&readers[
31630 69 52 65 61 64 65 72 5d 29 29 3b 0a 20 20 20 20  iReader]));.    
31640 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 2f      }..        /
31650 2a 20 4d 65 72 67 65 20 64 6f 63 6c 69 73 74 73  * Merge doclists
31660 20 61 6e 64 20 73 77 61 70 20 72 65 73 75 6c 74   and swap result
31670 20 69 6e 74 6f 20 61 63 63 75 6d 75 6c 61 74 6f   into accumulato
31680 72 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 64 61  r. */.        da
31690 74 61 42 75 66 66 65 72 52 65 73 65 74 28 26 6d  taBufferReset(&m
316a0 65 72 67 65 64 29 3b 0a 20 20 20 20 20 20 20 20  erged);.        
316b0 64 6f 63 4c 69 73 74 4d 65 72 67 65 28 26 6d 65  docListMerge(&me
316c0 72 67 65 64 2c 20 64 6c 52 65 61 64 65 72 73 2c  rged, dlReaders,
316d0 20 6e 52 65 61 64 65 72 73 29 3b 0a 20 20 20 20   nReaders);.    
316e0 20 20 20 20 74 6d 70 20 3d 20 6d 65 72 67 65 64      tmp = merged
316f0 3b 0a 20 20 20 20 20 20 20 20 6d 65 72 67 65 64  ;.        merged
31700 20 3d 20 64 6f 63 6c 69 73 74 3b 0a 20 20 20 20   = doclist;.    
31710 20 20 20 20 64 6f 63 6c 69 73 74 20 3d 20 74 6d      doclist = tm
31720 70 3b 0a 0a 20 20 20 20 20 20 20 20 77 68 69 6c  p;..        whil
31730 65 28 20 6e 52 65 61 64 65 72 73 2d 2d 20 3e 20  e( nReaders-- > 
31740 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 64  0 ){.          d
31750 6c 72 44 65 73 74 72 6f 79 28 26 64 6c 52 65 61  lrDestroy(&dlRea
31760 64 65 72 73 5b 6e 52 65 61 64 65 72 73 5d 29 3b  ders[nReaders]);
31770 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  .        }..    
31780 20 20 20 20 2f 2a 20 41 63 63 75 6d 75 6c 61 74      /* Accumulat
31790 65 64 20 64 6f 63 6c 69 73 74 20 74 6f 20 72 65  ed doclist to re
317a0 61 64 65 72 20 30 20 66 6f 72 20 6e 65 78 74 20  ader 0 for next 
317b0 70 61 73 73 2e 20 2a 2f 0a 20 20 20 20 20 20 20  pass. */.       
317c0 20 64 6c 72 49 6e 69 74 28 26 64 6c 52 65 61 64   dlrInit(&dlRead
317d0 65 72 73 5b 30 5d 2c 20 44 4c 5f 44 45 46 41 55  ers[0], DL_DEFAU
317e0 4c 54 2c 20 64 6f 63 6c 69 73 74 2e 70 44 61 74  LT, doclist.pDat
317f0 61 2c 20 64 6f 63 6c 69 73 74 2e 6e 44 61 74 61  a, doclist.nData
31800 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  );.      }..    
31810 20 20 2f 2a 20 44 65 73 74 72 6f 79 20 72 65 61    /* Destroy rea
31820 64 65 72 20 74 68 61 74 20 77 61 73 20 6c 65 66  der that was lef
31830 74 20 69 6e 20 74 68 65 20 70 69 70 65 6c 69 6e  t in the pipelin
31840 65 2e 20 2a 2f 0a 20 20 20 20 20 20 64 6c 72 44  e. */.      dlrD
31850 65 73 74 72 6f 79 28 26 64 6c 52 65 61 64 65 72  estroy(&dlReader
31860 73 5b 30 5d 29 3b 0a 0a 20 20 20 20 20 20 2f 2a  s[0]);..      /*
31870 20 54 72 69 6d 20 64 65 6c 65 74 69 6f 6e 73 20   Trim deletions 
31880 66 72 6f 6d 20 74 68 65 20 64 6f 63 6c 69 73 74  from the doclist
31890 2e 20 2a 2f 0a 20 20 20 20 20 20 64 61 74 61 42  . */.      dataB
318a0 75 66 66 65 72 52 65 73 65 74 28 26 6d 65 72 67  ufferReset(&merg
318b0 65 64 29 3b 0a 20 20 20 20 20 20 64 6f 63 4c 69  ed);.      docLi
318c0 73 74 54 72 69 6d 28 44 4c 5f 44 45 46 41 55 4c  stTrim(DL_DEFAUL
318d0 54 2c 20 64 6f 63 6c 69 73 74 2e 70 44 61 74 61  T, doclist.pData
318e0 2c 20 64 6f 63 6c 69 73 74 2e 6e 44 61 74 61 2c  , doclist.nData,
318f0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
31900 20 20 20 2d 31 2c 20 44 4c 5f 44 45 46 41 55 4c     -1, DL_DEFAUL
31910 54 2c 20 26 6d 65 72 67 65 64 29 3b 0a 20 20 20  T, &merged);.   
31920 20 7d 0a 0a 20 20 20 20 2f 2a 20 4f 6e 6c 79 20   }..    /* Only 
31930 70 61 73 73 20 64 6f 63 6c 69 73 74 73 20 77 69  pass doclists wi
31940 74 68 20 68 69 74 73 20 28 73 6b 69 70 20 69 66  th hits (skip if
31950 20 61 6c 6c 20 68 69 74 73 20 64 65 6c 65 74 65   all hits delete
31960 64 29 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 6d  d). */.    if( m
31970 65 72 67 65 64 2e 6e 44 61 74 61 3e 30 20 29 7b  erged.nData>0 ){
31980 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 65 61 66  .      rc = leaf
31990 57 72 69 74 65 72 53 74 65 70 28 76 2c 20 70 57  WriterStep(v, pW
319a0 72 69 74 65 72 2c 0a 20 20 20 20 20 20 20 20 20  riter,.         
319b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
319c0 20 6f 70 74 4c 65 61 76 65 73 52 65 61 64 65 72   optLeavesReader
319d0 54 65 72 6d 28 26 72 65 61 64 65 72 73 5b 30 5d  Term(&readers[0]
319e0 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ),.             
319f0 20 20 20 20 20 20 20 20 20 20 20 20 20 6f 70 74               opt
31a00 4c 65 61 76 65 73 52 65 61 64 65 72 54 65 72 6d  LeavesReaderTerm
31a10 42 79 74 65 73 28 26 72 65 61 64 65 72 73 5b 30  Bytes(&readers[0
31a20 5d 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  ]),.            
31a30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6d 65                me
31a40 72 67 65 64 2e 70 44 61 74 61 2c 20 6d 65 72 67  rged.pData, merg
31a50 65 64 2e 6e 44 61 74 61 29 3b 0a 20 20 20 20 20  ed.nData);.     
31a60 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
31a70 4f 4b 20 29 20 67 6f 74 6f 20 65 72 72 3b 0a 20  OK ) goto err;. 
31a80 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 53 74 65     }..    /* Ste
31a90 70 20 6d 65 72 67 65 64 20 72 65 61 64 65 72 73  p merged readers
31aa0 20 74 6f 20 6e 65 78 74 20 74 65 72 6d 20 61 6e   to next term an
31ab0 64 20 72 65 6f 72 64 65 72 2e 20 2a 2f 0a 20 20  d reorder. */.  
31ac0 20 20 77 68 69 6c 65 28 20 69 2d 2d 20 3e 20 30    while( i-- > 0
31ad0 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 6f   ){.      rc = o
31ae0 70 74 4c 65 61 76 65 73 52 65 61 64 65 72 53 74  ptLeavesReaderSt
31af0 65 70 28 76 2c 20 26 72 65 61 64 65 72 73 5b 69  ep(v, &readers[i
31b00 5d 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  ]);.      if( rc
31b10 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f  !=SQLITE_OK ) go
31b20 74 6f 20 65 72 72 3b 0a 0a 20 20 20 20 20 20 6f  to err;..      o
31b30 70 74 4c 65 61 76 65 73 52 65 61 64 65 72 52 65  ptLeavesReaderRe
31b40 6f 72 64 65 72 28 26 72 65 61 64 65 72 73 5b 69  order(&readers[i
31b50 5d 2c 20 6e 52 65 61 64 65 72 73 2d 69 29 3b 0a  ], nReaders-i);.
31b60 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 65 72 72 3a      }.  }.. err:
31b70 0a 20 20 64 61 74 61 42 75 66 66 65 72 44 65 73  .  dataBufferDes
31b80 74 72 6f 79 28 26 64 6f 63 6c 69 73 74 29 3b 0a  troy(&doclist);.
31b90 20 20 64 61 74 61 42 75 66 66 65 72 44 65 73 74    dataBufferDest
31ba0 72 6f 79 28 26 6d 65 72 67 65 64 29 3b 0a 20 20  roy(&merged);.  
31bb0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
31bc0 20 49 6d 70 6c 65 6d 65 6e 74 20 6f 70 74 69 6d   Implement optim
31bd0 69 7a 65 28 29 20 66 75 6e 63 74 69 6f 6e 20 66  ize() function f
31be0 6f 72 20 46 54 53 33 2e 20 20 6f 70 74 69 6d 69  or FTS3.  optimi
31bf0 7a 65 28 74 29 20 6d 65 72 67 65 73 20 61 6c 6c  ze(t) merges all
31c00 0a 2a 2a 20 73 65 67 6d 65 6e 74 73 20 69 6e 20  .** segments in 
31c10 74 68 65 20 66 74 73 20 69 6e 64 65 78 20 69 6e  the fts index in
31c20 74 6f 20 61 20 73 69 6e 67 6c 65 20 73 65 67 6d  to a single segm
31c30 65 6e 74 2e 20 20 27 74 27 20 69 73 20 74 68 65  ent.  't' is the
31c40 20 6d 61 67 69 63 0a 2a 2a 20 74 61 62 6c 65 2d   magic.** table-
31c50 6e 61 6d 65 64 20 63 6f 6c 75 6d 6e 2e 0a 2a 2f  named column..*/
31c60 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6f 70 74  .static void opt
31c70 69 6d 69 7a 65 46 75 6e 63 28 73 71 6c 69 74 65  imizeFunc(sqlite
31c80 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43 6f 6e 74  3_context *pCont
31c90 65 78 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ext,.           
31ca0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e                in
31cb0 74 20 61 72 67 63 2c 20 73 71 6c 69 74 65 33 5f  t argc, sqlite3_
31cc0 76 61 6c 75 65 20 2a 2a 61 72 67 76 29 7b 0a 20  value **argv){. 
31cd0 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73 6f 72   fulltext_cursor
31ce0 20 2a 70 43 75 72 73 6f 72 3b 0a 20 20 69 66 28   *pCursor;.  if(
31cf0 20 61 72 67 63 3e 31 20 29 7b 0a 20 20 20 20 73   argc>1 ){.    s
31d00 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72  qlite3_result_er
31d10 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 22 65  ror(pContext, "e
31d20 78 63 65 73 73 20 61 72 67 75 6d 65 6e 74 73 20  xcess arguments 
31d30 74 6f 20 6f 70 74 69 6d 69 7a 65 28 29 22 2c 2d  to optimize()",-
31d40 31 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20  1);.  }else if( 
31d50 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
31d60 70 65 28 61 72 67 76 5b 30 5d 29 21 3d 53 51 4c  pe(argv[0])!=SQL
31d70 49 54 45 5f 42 4c 4f 42 20 7c 7c 0a 20 20 20 20  ITE_BLOB ||.    
31d80 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
31d90 76 61 6c 75 65 5f 62 79 74 65 73 28 61 72 67 76  value_bytes(argv
31da0 5b 30 5d 29 21 3d 73 69 7a 65 6f 66 28 70 43 75  [0])!=sizeof(pCu
31db0 72 73 6f 72 29 20 29 7b 0a 20 20 20 20 73 71 6c  rsor) ){.    sql
31dc0 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f  ite3_result_erro
31dd0 72 28 70 43 6f 6e 74 65 78 74 2c 20 22 69 6c 6c  r(pContext, "ill
31de0 65 67 61 6c 20 66 69 72 73 74 20 61 72 67 75 6d  egal first argum
31df0 65 6e 74 20 74 6f 20 6f 70 74 69 6d 69 7a 65 22  ent to optimize"
31e00 2c 2d 31 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ,-1);.  }else{. 
31e10 20 20 20 66 75 6c 6c 74 65 78 74 5f 76 74 61 62     fulltext_vtab
31e20 20 2a 76 3b 0a 20 20 20 20 69 6e 74 20 69 2c 20   *v;.    int i, 
31e30 72 63 2c 20 69 4d 61 78 4c 65 76 65 6c 3b 0a 20  rc, iMaxLevel;. 
31e40 20 20 20 4f 70 74 4c 65 61 76 65 73 52 65 61 64     OptLeavesRead
31e50 65 72 20 2a 72 65 61 64 65 72 73 3b 0a 20 20 20  er *readers;.   
31e60 20 69 6e 74 20 6e 52 65 61 64 65 72 73 3b 0a 20   int nReaders;. 
31e70 20 20 20 4c 65 61 66 57 72 69 74 65 72 20 77 72     LeafWriter wr
31e80 69 74 65 72 3b 0a 20 20 20 20 73 71 6c 69 74 65  iter;.    sqlite
31e90 33 5f 73 74 6d 74 20 2a 73 3b 0a 0a 20 20 20 20  3_stmt *s;..    
31ea0 6d 65 6d 63 70 79 28 26 70 43 75 72 73 6f 72 2c  memcpy(&pCursor,
31eb0 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62   sqlite3_value_b
31ec0 6c 6f 62 28 61 72 67 76 5b 30 5d 29 2c 20 73 69  lob(argv[0]), si
31ed0 7a 65 6f 66 28 70 43 75 72 73 6f 72 29 29 3b 0a  zeof(pCursor));.
31ee0 20 20 20 20 76 20 3d 20 63 75 72 73 6f 72 5f 76      v = cursor_v
31ef0 74 61 62 28 70 43 75 72 73 6f 72 29 3b 0a 0a 20  tab(pCursor);.. 
31f00 20 20 20 2f 2a 20 46 6c 75 73 68 20 61 6e 79 20     /* Flush any 
31f10 62 75 66 66 65 72 65 64 20 75 70 64 61 74 65 73  buffered updates
31f20 20 62 65 66 6f 72 65 20 6f 70 74 69 6d 69 7a 69   before optimizi
31f30 6e 67 2e 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20  ng. */.    rc = 
31f40 66 6c 75 73 68 50 65 6e 64 69 6e 67 54 65 72 6d  flushPendingTerm
31f50 73 28 76 29 3b 0a 20 20 20 20 69 66 28 20 72 63  s(v);.    if( rc
31f60 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f  !=SQLITE_OK ) go
31f70 74 6f 20 65 72 72 3b 0a 0a 20 20 20 20 72 63 20  to err;..    rc 
31f80 3d 20 73 65 67 64 69 72 5f 63 6f 75 6e 74 28 76  = segdir_count(v
31f90 2c 20 26 6e 52 65 61 64 65 72 73 2c 20 26 69 4d  , &nReaders, &iM
31fa0 61 78 4c 65 76 65 6c 29 3b 0a 20 20 20 20 69 66  axLevel);.    if
31fb0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
31fc0 29 20 67 6f 74 6f 20 65 72 72 3b 0a 20 20 20 20  ) goto err;.    
31fd0 69 66 28 20 6e 52 65 61 64 65 72 73 3d 3d 30 20  if( nReaders==0 
31fe0 7c 7c 20 6e 52 65 61 64 65 72 73 3d 3d 31 20 29  || nReaders==1 )
31ff0 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
32000 72 65 73 75 6c 74 5f 74 65 78 74 28 70 43 6f 6e  result_text(pCon
32010 74 65 78 74 2c 20 22 49 6e 64 65 78 20 61 6c 72  text, "Index alr
32020 65 61 64 79 20 6f 70 74 69 6d 61 6c 22 2c 20 2d  eady optimal", -
32030 31 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  1,.             
32040 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
32050 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 20  ITE_STATIC);.   
32060 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 7d     return;.    }
32070 0a 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 5f 67  ..    rc = sql_g
32080 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76 2c 20  et_statement(v, 
32090 53 45 47 44 49 52 5f 53 45 4c 45 43 54 5f 41 4c  SEGDIR_SELECT_AL
320a0 4c 5f 53 54 4d 54 2c 20 26 73 29 3b 0a 20 20 20  L_STMT, &s);.   
320b0 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
320c0 4f 4b 20 29 20 67 6f 74 6f 20 65 72 72 3b 0a 0a  OK ) goto err;..
320d0 20 20 20 20 72 65 61 64 65 72 73 20 3d 20 73 71      readers = sq
320e0 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 52 65  lite3_malloc(nRe
320f0 61 64 65 72 73 2a 73 69 7a 65 6f 66 28 72 65 61  aders*sizeof(rea
32100 64 65 72 73 5b 30 5d 29 29 3b 0a 20 20 20 20 69  ders[0]));.    i
32110 66 28 20 72 65 61 64 65 72 73 3d 3d 4e 55 4c 4c  f( readers==NULL
32120 20 29 20 67 6f 74 6f 20 65 72 72 3b 0a 0a 20 20   ) goto err;..  
32130 20 20 2f 2a 20 4e 6f 74 65 20 74 68 61 74 20 74    /* Note that t
32140 68 65 72 65 20 77 69 6c 6c 20 61 6c 72 65 61 64  here will alread
32150 79 20 62 65 20 61 20 73 65 67 6d 65 6e 74 20 61  y be a segment a
32160 74 20 74 68 69 73 20 70 6f 73 69 74 69 6f 6e 0a  t this position.
32170 20 20 20 20 2a 2a 20 75 6e 74 69 6c 20 77 65 20      ** until we 
32180 63 61 6c 6c 20 73 65 67 64 69 72 5f 64 65 6c 65  call segdir_dele
32190 74 65 28 29 20 6f 6e 20 69 4d 61 78 4c 65 76 65  te() on iMaxLeve
321a0 6c 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6c 65  l..    */.    le
321b0 61 66 57 72 69 74 65 72 49 6e 69 74 28 69 4d 61  afWriterInit(iMa
321c0 78 4c 65 76 65 6c 2c 20 30 2c 20 26 77 72 69 74  xLevel, 0, &writ
321d0 65 72 29 3b 0a 0a 20 20 20 20 69 20 3d 20 30 3b  er);..    i = 0;
321e0 0a 20 20 20 20 77 68 69 6c 65 28 20 28 72 63 20  .    while( (rc 
321f0 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 73  = sqlite3_step(s
32200 29 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  ))==SQLITE_ROW )
32210 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 5f 69  {.      sqlite_i
32220 6e 74 36 34 20 69 53 74 61 72 74 20 3d 20 73 71  nt64 iStart = sq
32230 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74  lite3_column_int
32240 36 34 28 73 2c 20 30 29 3b 0a 20 20 20 20 20 20  64(s, 0);.      
32250 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 45 6e  sqlite_int64 iEn
32260 64 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  d = sqlite3_colu
32270 6d 6e 5f 69 6e 74 36 34 28 73 2c 20 31 29 3b 0a  mn_int64(s, 1);.
32280 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
32290 20 2a 70 52 6f 6f 74 44 61 74 61 20 3d 20 73 71   *pRootData = sq
322a0 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f  lite3_column_blo
322b0 62 28 73 2c 20 32 29 3b 0a 20 20 20 20 20 20 69  b(s, 2);.      i
322c0 6e 74 20 6e 52 6f 6f 74 44 61 74 61 20 3d 20 73  nt nRootData = s
322d0 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79  qlite3_column_by
322e0 74 65 73 28 73 2c 20 32 29 3b 0a 0a 20 20 20 20  tes(s, 2);..    
322f0 20 20 61 73 73 65 72 74 28 20 69 3c 6e 52 65 61    assert( i<nRea
32300 64 65 72 73 20 29 3b 0a 20 20 20 20 20 20 72 63  ders );.      rc
32310 20 3d 20 6c 65 61 76 65 73 52 65 61 64 65 72 49   = leavesReaderI
32320 6e 69 74 28 76 2c 20 2d 31 2c 20 69 53 74 61 72  nit(v, -1, iStar
32330 74 2c 20 69 45 6e 64 2c 20 70 52 6f 6f 74 44 61  t, iEnd, pRootDa
32340 74 61 2c 20 6e 52 6f 6f 74 44 61 74 61 2c 0a 20  ta, nRootData,. 
32350 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
32360 20 20 20 20 20 20 20 20 20 20 20 26 72 65 61 64             &read
32370 65 72 73 5b 69 5d 2e 72 65 61 64 65 72 29 3b 0a  ers[i].reader);.
32380 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
32390 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b  LITE_OK ) break;
323a0 0a 0a 20 20 20 20 20 20 72 65 61 64 65 72 73 5b  ..      readers[
323b0 69 5d 2e 73 65 67 6d 65 6e 74 20 3d 20 69 3b 0a  i].segment = i;.
323c0 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20 7d        i++;.    }
323d0 0a 0a 20 20 20 20 2f 2a 20 49 66 20 77 65 20 6d  ..    /* If we m
323e0 61 6e 61 67 65 64 20 74 6f 20 73 75 63 63 65 73  anaged to succes
323f0 73 66 75 6c 6c 79 20 72 65 61 64 20 74 68 65 6d  sfully read them
32400 20 61 6c 6c 2c 20 6f 70 74 69 6d 69 7a 65 20 74   all, optimize t
32410 68 65 6d 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  hem. */.    if( 
32420 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20  rc==SQLITE_DONE 
32430 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  ){.      assert(
32440 20 69 3d 3d 6e 52 65 61 64 65 72 73 20 29 3b 0a   i==nReaders );.
32450 20 20 20 20 20 20 72 63 20 3d 20 6f 70 74 69 6d        rc = optim
32460 69 7a 65 49 6e 74 65 72 6e 61 6c 28 76 2c 20 72  izeInternal(v, r
32470 65 61 64 65 72 73 2c 20 6e 52 65 61 64 65 72 73  eaders, nReaders
32480 2c 20 26 77 72 69 74 65 72 29 3b 0a 20 20 20 20  , &writer);.    
32490 7d 0a 0a 20 20 20 20 77 68 69 6c 65 28 20 69 2d  }..    while( i-
324a0 2d 20 3e 20 30 20 29 7b 0a 20 20 20 20 20 20 6c  - > 0 ){.      l
324b0 65 61 76 65 73 52 65 61 64 65 72 44 65 73 74 72  eavesReaderDestr
324c0 6f 79 28 26 72 65 61 64 65 72 73 5b 69 5d 2e 72  oy(&readers[i].r
324d0 65 61 64 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20  eader);.    }.  
324e0 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 72    sqlite3_free(r
324f0 65 61 64 65 72 73 29 3b 0a 0a 20 20 20 20 2f 2a  eaders);..    /*
32500 20 49 66 20 77 65 27 76 65 20 73 75 63 63 65 73   If we've succes
32510 73 66 75 6c 6c 79 20 67 6f 74 74 65 6e 20 74 6f  sfully gotten to
32520 20 68 65 72 65 2c 20 64 65 6c 65 74 65 20 74 68   here, delete th
32530 65 20 6f 6c 64 20 73 65 67 6d 65 6e 74 73 0a 20  e old segments. 
32540 20 20 20 2a 2a 20 61 6e 64 20 66 6c 75 73 68 20     ** and flush 
32550 74 68 65 20 69 6e 74 65 72 69 6f 72 20 73 74 72  the interior str
32560 75 63 74 75 72 65 20 6f 66 20 74 68 65 20 6e 65  ucture of the ne
32570 77 20 73 65 67 6d 65 6e 74 2e 0a 20 20 20 20 2a  w segment..    *
32580 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  /.    if( rc==SQ
32590 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
325a0 20 66 6f 72 28 20 69 3d 30 3b 20 69 3c 3d 69 4d   for( i=0; i<=iM
325b0 61 78 4c 65 76 65 6c 3b 20 69 2b 2b 20 29 7b 0a  axLevel; i++ ){.
325c0 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65 67          rc = seg
325d0 64 69 72 5f 64 65 6c 65 74 65 28 76 2c 20 69 29  dir_delete(v, i)
325e0 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
325f0 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72  !=SQLITE_OK ) br
32600 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20  eak;.      }..  
32610 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
32620 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 6c 65 61  TE_OK ) rc = lea
32630 66 57 72 69 74 65 72 46 69 6e 61 6c 69 7a 65 28  fWriterFinalize(
32640 76 2c 20 26 77 72 69 74 65 72 29 3b 0a 20 20 20  v, &writer);.   
32650 20 7d 0a 0a 20 20 20 20 6c 65 61 66 57 72 69 74   }..    leafWrit
32660 65 72 44 65 73 74 72 6f 79 28 26 77 72 69 74 65  erDestroy(&write
32670 72 29 3b 0a 0a 20 20 20 20 69 66 28 20 72 63 21  r);..    if( rc!
32680 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 67 6f 74  =SQLITE_OK ) got
32690 6f 20 65 72 72 3b 0a 0a 20 20 20 20 73 71 6c 69  o err;..    sqli
326a0 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 74 28  te3_result_text(
326b0 70 43 6f 6e 74 65 78 74 2c 20 22 49 6e 64 65 78  pContext, "Index
326c0 20 6f 70 74 69 6d 69 7a 65 64 22 2c 20 2d 31 2c   optimized", -1,
326d0 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b   SQLITE_STATIC);
326e0 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 0a 20 20  .    return;..  
326f0 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73 29    /* TODO(shess)
32700 3a 20 45 72 72 6f 72 2d 68 61 6e 64 6c 69 6e 67  : Error-handling
32710 20 6e 65 65 64 73 20 74 6f 20 62 65 20 69 6d 70   needs to be imp
32720 72 6f 76 65 64 20 61 6c 6f 6e 67 20 74 68 65 0a  roved along the.
32730 20 20 20 20 2a 2a 20 6c 69 6e 65 73 20 6f 66 20      ** lines of 
32740 74 68 65 20 64 75 6d 70 5f 20 66 75 6e 63 74 69  the dump_ functi
32750 6f 6e 73 2e 0a 20 20 20 20 2a 2f 0a 20 65 72 72  ons..    */. err
32760 3a 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 63 68  :.    {.      ch
32770 61 72 20 62 75 66 5b 35 31 32 5d 3b 0a 20 20 20  ar buf[512];.   
32780 20 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69     sqlite3_snpri
32790 6e 74 66 28 73 69 7a 65 6f 66 28 62 75 66 29 2c  ntf(sizeof(buf),
327a0 20 62 75 66 2c 20 22 45 72 72 6f 72 20 69 6e 20   buf, "Error in 
327b0 6f 70 74 69 6d 69 7a 65 3a 20 25 73 22 2c 0a 20  optimize: %s",. 
327c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
327d0 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 65 72        sqlite3_er
327e0 72 6d 73 67 28 73 71 6c 69 74 65 33 5f 63 6f 6e  rmsg(sqlite3_con
327f0 74 65 78 74 5f 64 62 5f 68 61 6e 64 6c 65 28 70  text_db_handle(p
32800 43 6f 6e 74 65 78 74 29 29 29 3b 0a 20 20 20 20  Context)));.    
32810 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
32820 5f 65 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c  _error(pContext,
32830 20 62 75 66 2c 20 2d 31 29 3b 0a 20 20 20 20 7d   buf, -1);.    }
32840 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64 65 66 20 53  .  }.}..#ifdef S
32850 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a 20 47 65  QLITE_TEST./* Ge
32860 6e 65 72 61 74 65 20 61 6e 20 65 72 72 6f 72 20  nerate an error 
32870 6f 66 20 74 68 65 20 66 6f 72 6d 20 22 3c 70 72  of the form "<pr
32880 65 66 69 78 3e 3a 20 3c 6d 73 67 3e 22 2e 20 20  efix>: <msg>".  
32890 49 66 20 6d 73 67 20 69 73 20 4e 55 4c 4c 2c 0a  If msg is NULL,.
328a0 2a 2a 20 70 75 6c 6c 20 74 68 65 20 65 72 72 6f  ** pull the erro
328b0 72 20 66 72 6f 6d 20 74 68 65 20 63 6f 6e 74 65  r from the conte
328c0 78 74 27 73 20 64 62 20 68 61 6e 64 6c 65 2e 0a  xt's db handle..
328d0 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 67  */.static void g
328e0 65 6e 65 72 61 74 65 45 72 72 6f 72 28 73 71 6c  enerateError(sql
328f0 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43  ite3_context *pC
32900 6f 6e 74 65 78 74 2c 0a 20 20 20 20 20 20 20 20  ontext,.        
32910 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
32920 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 72    const char *pr
32930 65 66 69 78 2c 20 63 6f 6e 73 74 20 63 68 61 72  efix, const char
32940 20 2a 6d 73 67 29 7b 0a 20 20 63 68 61 72 20 62   *msg){.  char b
32950 75 66 5b 35 31 32 5d 3b 0a 20 20 69 66 28 20 6d  uf[512];.  if( m
32960 73 67 3d 3d 4e 55 4c 4c 20 29 20 6d 73 67 20 3d  sg==NULL ) msg =
32970 20 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 67 28   sqlite3_errmsg(
32980 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 5f  sqlite3_context_
32990 64 62 5f 68 61 6e 64 6c 65 28 70 43 6f 6e 74 65  db_handle(pConte
329a0 78 74 29 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  xt));.  sqlite3_
329b0 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f 66 28  snprintf(sizeof(
329c0 62 75 66 29 2c 20 62 75 66 2c 20 22 25 73 3a 20  buf), buf, "%s: 
329d0 25 73 22 2c 20 70 72 65 66 69 78 2c 20 6d 73 67  %s", prefix, msg
329e0 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 72 65 73  );.  sqlite3_res
329f0 75 6c 74 5f 65 72 72 6f 72 28 70 43 6f 6e 74 65  ult_error(pConte
32a00 78 74 2c 20 62 75 66 2c 20 2d 31 29 3b 0a 7d 0a  xt, buf, -1);.}.
32a10 0a 2f 2a 20 48 65 6c 70 65 72 20 66 75 6e 63 74  ./* Helper funct
32a20 69 6f 6e 20 74 6f 20 63 6f 6c 6c 65 63 74 20 74  ion to collect t
32a30 68 65 20 73 65 74 20 6f 66 20 74 65 72 6d 73 20  he set of terms 
32a40 69 6e 20 74 68 65 20 73 65 67 6d 65 6e 74 20 69  in the segment i
32a50 6e 74 6f 0a 2a 2a 20 70 54 65 72 6d 73 2e 20 20  nto.** pTerms.  
32a60 54 68 65 20 73 65 67 6d 65 6e 74 20 69 73 20 64  The segment is d
32a70 65 66 69 6e 65 64 20 62 79 20 74 68 65 20 6c 65  efined by the le
32a80 61 66 20 6e 6f 64 65 73 20 62 65 74 77 65 65 6e  af nodes between
32a90 0a 2a 2a 20 69 53 74 61 72 74 42 6c 6f 63 6b 69  .** iStartBlocki
32aa0 64 20 61 6e 64 20 69 45 6e 64 42 6c 6f 63 6b 69  d and iEndBlocki
32ab0 64 2c 20 69 6e 63 6c 75 73 69 76 65 2c 20 6f 72  d, inclusive, or
32ac0 20 62 79 20 74 68 65 20 63 6f 6e 74 65 6e 74 73   by the contents
32ad0 20 6f 66 0a 2a 2a 20 70 52 6f 6f 74 44 61 74 61   of.** pRootData
32ae0 20 69 66 20 69 53 74 61 72 74 42 6c 6f 63 6b 69   if iStartBlocki
32af0 64 20 69 73 20 30 20 28 69 6e 20 77 68 69 63 68  d is 0 (in which
32b00 20 63 61 73 65 20 74 68 65 20 65 6e 74 69 72 65   case the entire
32b10 20 73 65 67 6d 65 6e 74 0a 2a 2a 20 66 69 74 20   segment.** fit 
32b20 69 6e 20 61 20 6c 65 61 66 29 2e 0a 2a 2f 0a 73  in a leaf)..*/.s
32b30 74 61 74 69 63 20 69 6e 74 20 63 6f 6c 6c 65 63  tatic int collec
32b40 74 53 65 67 6d 65 6e 74 54 65 72 6d 73 28 66 75  tSegmentTerms(fu
32b50 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a 76 2c 20  lltext_vtab *v, 
32b60 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73 2c  sqlite3_stmt *s,
32b70 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
32b80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
32b90 66 74 73 33 48 61 73 68 20 2a 70 54 65 72 6d 73  fts3Hash *pTerms
32ba0 29 7b 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69 74  ){.  const sqlit
32bb0 65 5f 69 6e 74 36 34 20 69 53 74 61 72 74 42 6c  e_int64 iStartBl
32bc0 6f 63 6b 69 64 20 3d 20 73 71 6c 69 74 65 33 5f  ockid = sqlite3_
32bd0 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 73 2c 20  column_int64(s, 
32be0 30 29 3b 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69  0);.  const sqli
32bf0 74 65 5f 69 6e 74 36 34 20 69 45 6e 64 42 6c 6f  te_int64 iEndBlo
32c00 63 6b 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 63  ckid = sqlite3_c
32c10 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 73 2c 20 31  olumn_int64(s, 1
32c20 29 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  );.  const char 
32c30 2a 70 52 6f 6f 74 44 61 74 61 20 3d 20 73 71 6c  *pRootData = sql
32c40 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62  ite3_column_blob
32c50 28 73 2c 20 32 29 3b 0a 20 20 63 6f 6e 73 74 20  (s, 2);.  const 
32c60 69 6e 74 20 6e 52 6f 6f 74 44 61 74 61 20 3d 20  int nRootData = 
32c70 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62  sqlite3_column_b
32c80 79 74 65 73 28 73 2c 20 32 29 3b 0a 20 20 4c 65  ytes(s, 2);.  Le
32c90 61 76 65 73 52 65 61 64 65 72 20 72 65 61 64 65  avesReader reade
32ca0 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 6c 65  r;.  int rc = le
32cb0 61 76 65 73 52 65 61 64 65 72 49 6e 69 74 28 76  avesReaderInit(v
32cc0 2c 20 30 2c 20 69 53 74 61 72 74 42 6c 6f 63 6b  , 0, iStartBlock
32cd0 69 64 2c 20 69 45 6e 64 42 6c 6f 63 6b 69 64 2c  id, iEndBlockid,
32ce0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
32cf0 20 20 20 20 20 20 20 20 20 20 20 20 20 70 52 6f               pRo
32d00 6f 74 44 61 74 61 2c 20 6e 52 6f 6f 74 44 61 74  otData, nRootDat
32d10 61 2c 20 26 72 65 61 64 65 72 29 3b 0a 20 20 69  a, &reader);.  i
32d20 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
32d30 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
32d40 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49   while( rc==SQLI
32d50 54 45 5f 4f 4b 20 26 26 20 21 6c 65 61 76 65 73  TE_OK && !leaves
32d60 52 65 61 64 65 72 41 74 45 6e 64 28 26 72 65 61  ReaderAtEnd(&rea
32d70 64 65 72 29 20 29 7b 0a 20 20 20 20 63 6f 6e 73  der) ){.    cons
32d80 74 20 63 68 61 72 20 2a 70 54 65 72 6d 20 3d 20  t char *pTerm = 
32d90 6c 65 61 76 65 73 52 65 61 64 65 72 54 65 72 6d  leavesReaderTerm
32da0 28 26 72 65 61 64 65 72 29 3b 0a 20 20 20 20 63  (&reader);.    c
32db0 6f 6e 73 74 20 69 6e 74 20 6e 54 65 72 6d 20 3d  onst int nTerm =
32dc0 20 6c 65 61 76 65 73 52 65 61 64 65 72 54 65 72   leavesReaderTer
32dd0 6d 42 79 74 65 73 28 26 72 65 61 64 65 72 29 3b  mBytes(&reader);
32de0 0a 20 20 20 20 76 6f 69 64 20 2a 6f 6c 64 56 61  .    void *oldVa
32df0 6c 75 65 20 3d 20 73 71 6c 69 74 65 33 46 74 73  lue = sqlite3Fts
32e00 33 48 61 73 68 46 69 6e 64 28 70 54 65 72 6d 73  3HashFind(pTerms
32e10 2c 20 70 54 65 72 6d 2c 20 6e 54 65 72 6d 29 3b  , pTerm, nTerm);
32e20 0a 20 20 20 20 76 6f 69 64 20 2a 6e 65 77 56 61  .    void *newVa
32e30 6c 75 65 20 3d 20 28 76 6f 69 64 20 2a 29 28 28  lue = (void *)((
32e40 63 68 61 72 20 2a 29 6f 6c 64 56 61 6c 75 65 2b  char *)oldValue+
32e50 31 29 3b 0a 0a 20 20 20 20 2f 2a 20 46 72 6f 6d  1);..    /* From
32e60 20 74 68 65 20 63 6f 6d 6d 65 6e 74 20 62 65 66   the comment bef
32e70 6f 72 65 20 73 71 6c 69 74 65 33 46 74 73 33 48  ore sqlite3Fts3H
32e80 61 73 68 49 6e 73 65 72 74 20 69 6e 20 66 74 73  ashInsert in fts
32e90 33 5f 68 61 73 68 2e 63 2c 0a 20 20 20 20 2a 2a  3_hash.c,.    **
32ea0 20 74 68 65 20 64 61 74 61 20 76 61 6c 75 65 20   the data value 
32eb0 70 61 73 73 65 64 20 69 73 20 72 65 74 75 72 6e  passed is return
32ec0 65 64 20 69 6e 20 63 61 73 65 20 6f 66 20 6d 61  ed in case of ma
32ed0 6c 6c 6f 63 20 66 61 69 6c 75 72 65 2e 0a 20 20  lloc failure..  
32ee0 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 6e 65 77    */.    if( new
32ef0 56 61 6c 75 65 3d 3d 73 71 6c 69 74 65 33 46 74  Value==sqlite3Ft
32f00 73 33 48 61 73 68 49 6e 73 65 72 74 28 70 54 65  s3HashInsert(pTe
32f10 72 6d 73 2c 20 70 54 65 72 6d 2c 20 6e 54 65 72  rms, pTerm, nTer
32f20 6d 2c 20 6e 65 77 56 61 6c 75 65 29 20 29 7b 0a  m, newValue) ){.
32f30 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
32f40 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c  E_NOMEM;.    }el
32f50 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 6c  se{.      rc = l
32f60 65 61 76 65 73 52 65 61 64 65 72 53 74 65 70 28  eavesReaderStep(
32f70 76 2c 20 26 72 65 61 64 65 72 29 3b 0a 20 20 20  v, &reader);.   
32f80 20 7d 0a 20 20 7d 0a 0a 20 20 6c 65 61 76 65 73   }.  }..  leaves
32f90 52 65 61 64 65 72 44 65 73 74 72 6f 79 28 26 72  ReaderDestroy(&r
32fa0 65 61 64 65 72 29 3b 0a 20 20 72 65 74 75 72 6e  eader);.  return
32fb0 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 48 65 6c 70 65   rc;.}../* Helpe
32fc0 72 20 66 75 6e 63 74 69 6f 6e 20 74 6f 20 62 75  r function to bu
32fd0 69 6c 64 20 74 68 65 20 72 65 73 75 6c 74 20 73  ild the result s
32fe0 74 72 69 6e 67 20 66 6f 72 20 64 75 6d 70 5f 74  tring for dump_t
32ff0 65 72 6d 73 28 29 2e 20 2a 2f 0a 73 74 61 74 69  erms(). */.stati
33000 63 20 69 6e 74 20 67 65 6e 65 72 61 74 65 54 65  c int generateTe
33010 72 6d 73 52 65 73 75 6c 74 28 73 71 6c 69 74 65  rmsResult(sqlite
33020 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43 6f 6e 74  3_context *pCont
33030 65 78 74 2c 20 66 74 73 33 48 61 73 68 20 2a 70  ext, fts3Hash *p
33040 54 65 72 6d 73 29 7b 0a 20 20 69 6e 74 20 69 54  Terms){.  int iT
33050 65 72 6d 2c 20 6e 54 65 72 6d 73 2c 20 6e 52 65  erm, nTerms, nRe
33060 73 75 6c 74 42 79 74 65 73 2c 20 69 42 79 74 65  sultBytes, iByte
33070 3b 0a 20 20 63 68 61 72 20 2a 72 65 73 75 6c 74  ;.  char *result
33080 3b 0a 20 20 54 65 72 6d 44 61 74 61 20 2a 70 44  ;.  TermData *pD
33090 61 74 61 3b 0a 20 20 66 74 73 33 48 61 73 68 45  ata;.  fts3HashE
330a0 6c 65 6d 20 2a 65 3b 0a 0a 20 20 2f 2a 20 49 74  lem *e;..  /* It
330b0 65 72 61 74 65 20 70 54 65 72 6d 73 20 74 6f 20  erate pTerms to 
330c0 67 65 6e 65 72 61 74 65 20 61 6e 20 61 72 72 61  generate an arra
330d0 79 20 6f 66 20 74 65 72 6d 73 20 69 6e 20 70 44  y of terms in pD
330e0 61 74 61 20 66 6f 72 0a 20 20 2a 2a 20 73 6f 72  ata for.  ** sor
330f0 74 69 6e 67 2e 0a 20 20 2a 2f 0a 20 20 6e 54 65  ting..  */.  nTe
33100 72 6d 73 20 3d 20 66 74 73 33 48 61 73 68 43 6f  rms = fts3HashCo
33110 75 6e 74 28 70 54 65 72 6d 73 29 3b 0a 20 20 61  unt(pTerms);.  a
33120 73 73 65 72 74 28 20 6e 54 65 72 6d 73 3e 30 20  ssert( nTerms>0 
33130 29 3b 0a 20 20 70 44 61 74 61 20 3d 20 73 71 6c  );.  pData = sql
33140 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 54 65 72  ite3_malloc(nTer
33150 6d 73 2a 73 69 7a 65 6f 66 28 54 65 72 6d 44 61  ms*sizeof(TermDa
33160 74 61 29 29 3b 0a 20 20 69 66 28 20 70 44 61 74  ta));.  if( pDat
33170 61 3d 3d 4e 55 4c 4c 20 29 20 72 65 74 75 72 6e  a==NULL ) return
33180 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 0a   SQLITE_NOMEM;..
33190 20 20 6e 52 65 73 75 6c 74 42 79 74 65 73 20 3d    nResultBytes =
331a0 20 30 3b 0a 20 20 66 6f 72 28 69 54 65 72 6d 20   0;.  for(iTerm 
331b0 3d 20 30 2c 20 65 20 3d 20 66 74 73 33 48 61 73  = 0, e = fts3Has
331c0 68 46 69 72 73 74 28 70 54 65 72 6d 73 29 3b 20  hFirst(pTerms); 
331d0 65 3b 20 69 54 65 72 6d 2b 2b 2c 20 65 20 3d 20  e; iTerm++, e = 
331e0 66 74 73 33 48 61 73 68 4e 65 78 74 28 65 29 29  fts3HashNext(e))
331f0 7b 0a 20 20 20 20 6e 52 65 73 75 6c 74 42 79 74  {.    nResultByt
33200 65 73 20 2b 3d 20 66 74 73 33 48 61 73 68 4b 65  es += fts3HashKe
33210 79 73 69 7a 65 28 65 29 2b 31 3b 20 20 20 2f 2a  ysize(e)+1;   /*
33220 20 54 65 72 6d 20 70 6c 75 73 20 74 72 61 69 6c   Term plus trail
33230 69 6e 67 20 73 70 61 63 65 20 2a 2f 0a 20 20 20  ing space */.   
33240 20 61 73 73 65 72 74 28 20 69 54 65 72 6d 3c 6e   assert( iTerm<n
33250 54 65 72 6d 73 20 29 3b 0a 20 20 20 20 70 44 61  Terms );.    pDa
33260 74 61 5b 69 54 65 72 6d 5d 2e 70 54 65 72 6d 20  ta[iTerm].pTerm 
33270 3d 20 66 74 73 33 48 61 73 68 4b 65 79 28 65 29  = fts3HashKey(e)
33280 3b 0a 20 20 20 20 70 44 61 74 61 5b 69 54 65 72  ;.    pData[iTer
33290 6d 5d 2e 6e 54 65 72 6d 20 3d 20 66 74 73 33 48  m].nTerm = fts3H
332a0 61 73 68 4b 65 79 73 69 7a 65 28 65 29 3b 0a 20  ashKeysize(e);. 
332b0 20 20 20 70 44 61 74 61 5b 69 54 65 72 6d 5d 2e     pData[iTerm].
332c0 70 43 6f 6c 6c 65 63 74 6f 72 20 3d 20 66 74 73  pCollector = fts
332d0 33 48 61 73 68 44 61 74 61 28 65 29 3b 20 20 2f  3HashData(e);  /
332e0 2a 20 75 6e 75 73 65 64 20 2a 2f 0a 20 20 7d 0a  * unused */.  }.
332f0 20 20 61 73 73 65 72 74 28 20 69 54 65 72 6d 3d    assert( iTerm=
33300 3d 6e 54 65 72 6d 73 20 29 3b 0a 0a 20 20 61 73  =nTerms );..  as
33310 73 65 72 74 28 20 6e 52 65 73 75 6c 74 42 79 74  sert( nResultByt
33320 65 73 3e 30 20 29 3b 20 20 20 2f 2a 20 6e 54 65  es>0 );   /* nTe
33330 72 6d 73 3e 30 2c 20 6e 52 65 73 75 6c 74 73 42  rms>0, nResultsB
33340 79 74 65 73 20 6d 75 73 74 20 62 65 2c 20 74 6f  ytes must be, to
33350 6f 2e 20 2a 2f 0a 20 20 72 65 73 75 6c 74 20 3d  o. */.  result =
33360 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28   sqlite3_malloc(
33370 6e 52 65 73 75 6c 74 42 79 74 65 73 29 3b 0a 20  nResultBytes);. 
33380 20 69 66 28 20 72 65 73 75 6c 74 3d 3d 4e 55 4c   if( result==NUL
33390 4c 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  L ){.    sqlite3
333a0 5f 66 72 65 65 28 70 44 61 74 61 29 3b 0a 20 20  _free(pData);.  
333b0 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
333c0 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 69 66  NOMEM;.  }..  if
333d0 28 20 6e 54 65 72 6d 73 3e 31 20 29 20 71 73 6f  ( nTerms>1 ) qso
333e0 72 74 28 70 44 61 74 61 2c 20 6e 54 65 72 6d 73  rt(pData, nTerms
333f0 2c 20 73 69 7a 65 6f 66 28 2a 70 44 61 74 61 29  , sizeof(*pData)
33400 2c 20 74 65 72 6d 44 61 74 61 43 6d 70 29 3b 0a  , termDataCmp);.
33410 0a 20 20 2f 2a 20 52 65 61 64 20 74 68 65 20 74  .  /* Read the t
33420 65 72 6d 73 20 69 6e 20 6f 72 64 65 72 20 74 6f  erms in order to
33430 20 62 75 69 6c 64 20 74 68 65 20 72 65 73 75 6c   build the resul
33440 74 2e 20 2a 2f 0a 20 20 69 42 79 74 65 20 3d 20  t. */.  iByte = 
33450 30 3b 0a 20 20 66 6f 72 28 69 54 65 72 6d 3d 30  0;.  for(iTerm=0
33460 3b 20 69 54 65 72 6d 3c 6e 54 65 72 6d 73 3b 20  ; iTerm<nTerms; 
33470 2b 2b 69 54 65 72 6d 29 7b 0a 20 20 20 20 6d 65  ++iTerm){.    me
33480 6d 63 70 79 28 72 65 73 75 6c 74 2b 69 42 79 74  mcpy(result+iByt
33490 65 2c 20 70 44 61 74 61 5b 69 54 65 72 6d 5d 2e  e, pData[iTerm].
334a0 70 54 65 72 6d 2c 20 70 44 61 74 61 5b 69 54 65  pTerm, pData[iTe
334b0 72 6d 5d 2e 6e 54 65 72 6d 29 3b 0a 20 20 20 20  rm].nTerm);.    
334c0 69 42 79 74 65 20 2b 3d 20 70 44 61 74 61 5b 69  iByte += pData[i
334d0 54 65 72 6d 5d 2e 6e 54 65 72 6d 3b 0a 20 20 20  Term].nTerm;.   
334e0 20 72 65 73 75 6c 74 5b 69 42 79 74 65 2b 2b 5d   result[iByte++]
334f0 20 3d 20 27 20 27 3b 0a 20 20 7d 0a 20 20 61 73   = ' ';.  }.  as
33500 73 65 72 74 28 20 69 42 79 74 65 3d 3d 6e 52 65  sert( iByte==nRe
33510 73 75 6c 74 42 79 74 65 73 20 29 3b 0a 20 20 61  sultBytes );.  a
33520 73 73 65 72 74 28 20 72 65 73 75 6c 74 5b 6e 52  ssert( result[nR
33530 65 73 75 6c 74 42 79 74 65 73 2d 31 5d 3d 3d 27  esultBytes-1]=='
33540 20 27 20 29 3b 0a 20 20 72 65 73 75 6c 74 5b 6e   ' );.  result[n
33550 52 65 73 75 6c 74 42 79 74 65 73 2d 31 5d 20 3d  ResultBytes-1] =
33560 20 27 5c 30 27 3b 0a 0a 20 20 2f 2a 20 50 61 73   '\0';..  /* Pas
33570 73 65 73 20 61 77 61 79 20 6f 77 6e 65 72 73 68  ses away ownersh
33580 69 70 20 6f 66 20 72 65 73 75 6c 74 2e 20 2a 2f  ip of result. */
33590 0a 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c  .  sqlite3_resul
335a0 74 5f 74 65 78 74 28 70 43 6f 6e 74 65 78 74 2c  t_text(pContext,
335b0 20 72 65 73 75 6c 74 2c 20 6e 52 65 73 75 6c 74   result, nResult
335c0 42 79 74 65 73 2d 31 2c 20 73 71 6c 69 74 65 33  Bytes-1, sqlite3
335d0 5f 66 72 65 65 29 3b 0a 20 20 73 71 6c 69 74 65  _free);.  sqlite
335e0 33 5f 66 72 65 65 28 70 44 61 74 61 29 3b 0a 20  3_free(pData);. 
335f0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
33600 4b 3b 0a 7d 0a 0a 2f 2a 20 49 6d 70 6c 65 6d 65  K;.}../* Impleme
33610 6e 74 73 20 64 75 6d 70 5f 74 65 72 6d 73 28 29  nts dump_terms()
33620 20 66 6f 72 20 75 73 65 20 69 6e 20 69 6e 73 70   for use in insp
33630 65 63 74 69 6e 67 20 74 68 65 20 66 74 73 33 20  ecting the fts3 
33640 69 6e 64 65 78 20 66 72 6f 6d 0a 2a 2a 20 74 65  index from.** te
33650 73 74 73 2e 20 20 54 45 58 54 20 72 65 73 75 6c  sts.  TEXT resul
33660 74 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65  t containing the
33670 20 6f 72 64 65 72 65 64 20 6c 69 73 74 20 6f 66   ordered list of
33680 20 74 65 72 6d 73 20 6a 6f 69 6e 65 64 20 62 79   terms joined by
33690 0a 2a 2a 20 73 70 61 63 65 73 2e 20 20 64 75 6d  .** spaces.  dum
336a0 70 5f 74 65 72 6d 73 28 74 2c 20 6c 65 76 65 6c  p_terms(t, level
336b0 2c 20 69 64 78 29 20 64 75 6d 70 73 20 74 68 65  , idx) dumps the
336c0 20 74 65 72 6d 73 20 66 6f 72 20 74 68 65 20 73   terms for the s
336d0 65 67 6d 65 6e 74 0a 2a 2a 20 73 70 65 63 69 66  egment.** specif
336e0 69 65 64 20 62 79 20 6c 65 76 65 6c 2c 20 69 64  ied by level, id
336f0 78 20 28 69 6e 20 25 5f 73 65 67 64 69 72 29 2c  x (in %_segdir),
33700 20 77 68 69 6c 65 20 64 75 6d 70 5f 74 65 72 6d   while dump_term
33710 73 28 74 29 20 64 75 6d 70 73 0a 2a 2a 20 61 6c  s(t) dumps.** al
33720 6c 20 74 65 72 6d 73 20 69 6e 20 74 68 65 20 69  l terms in the i
33730 6e 64 65 78 2e 20 20 49 6e 20 62 6f 74 68 20 63  ndex.  In both c
33740 61 73 65 73 20 74 20 69 73 20 74 68 65 20 66 74  ases t is the ft
33750 73 20 74 61 62 6c 65 27 73 20 6d 61 67 69 63 0a  s table's magic.
33760 2a 2a 20 74 61 62 6c 65 2d 6e 61 6d 65 64 20 63  ** table-named c
33770 6f 6c 75 6d 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  olumn..*/.static
33780 20 76 6f 69 64 20 64 75 6d 70 54 65 72 6d 73 46   void dumpTermsF
33790 75 6e 63 28 0a 20 20 73 71 6c 69 74 65 33 5f 63  unc(.  sqlite3_c
337a0 6f 6e 74 65 78 74 20 2a 70 43 6f 6e 74 65 78 74  ontext *pContext
337b0 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 73 71  ,.  int argc, sq
337c0 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72  lite3_value **ar
337d0 67 76 0a 29 7b 0a 20 20 66 75 6c 6c 74 65 78 74  gv.){.  fulltext
337e0 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72  _cursor *pCursor
337f0 3b 0a 20 20 69 66 28 20 61 72 67 63 21 3d 33 20  ;.  if( argc!=3 
33800 26 26 20 61 72 67 63 21 3d 31 20 29 7b 0a 20 20  && argc!=1 ){.  
33810 20 20 67 65 6e 65 72 61 74 65 45 72 72 6f 72 28    generateError(
33820 70 43 6f 6e 74 65 78 74 2c 20 22 64 75 6d 70 5f  pContext, "dump_
33830 74 65 72 6d 73 22 2c 20 22 69 6e 63 6f 72 72 65  terms", "incorre
33840 63 74 20 61 72 67 75 6d 65 6e 74 73 22 29 3b 0a  ct arguments");.
33850 20 20 7d 65 6c 73 65 20 69 66 28 20 73 71 6c 69    }else if( sqli
33860 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61  te3_value_type(a
33870 72 67 76 5b 30 5d 29 21 3d 53 51 4c 49 54 45 5f  rgv[0])!=SQLITE_
33880 42 4c 4f 42 20 7c 7c 0a 20 20 20 20 20 20 20 20  BLOB ||.        
33890 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75      sqlite3_valu
338a0 65 5f 62 79 74 65 73 28 61 72 67 76 5b 30 5d 29  e_bytes(argv[0])
338b0 21 3d 73 69 7a 65 6f 66 28 70 43 75 72 73 6f 72  !=sizeof(pCursor
338c0 29 20 29 7b 0a 20 20 20 20 67 65 6e 65 72 61 74  ) ){.    generat
338d0 65 45 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c  eError(pContext,
338e0 20 22 64 75 6d 70 5f 74 65 72 6d 73 22 2c 20 22   "dump_terms", "
338f0 69 6c 6c 65 67 61 6c 20 66 69 72 73 74 20 61 72  illegal first ar
33900 67 75 6d 65 6e 74 22 29 3b 0a 20 20 7d 65 6c 73  gument");.  }els
33910 65 7b 0a 20 20 20 20 66 75 6c 6c 74 65 78 74 5f  e{.    fulltext_
33920 76 74 61 62 20 2a 76 3b 0a 20 20 20 20 66 74 73  vtab *v;.    fts
33930 33 48 61 73 68 20 74 65 72 6d 73 3b 0a 20 20 20  3Hash terms;.   
33940 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 73   sqlite3_stmt *s
33950 20 3d 20 4e 55 4c 4c 3b 0a 20 20 20 20 69 6e 74   = NULL;.    int
33960 20 72 63 3b 0a 0a 20 20 20 20 6d 65 6d 63 70 79   rc;..    memcpy
33970 28 26 70 43 75 72 73 6f 72 2c 20 73 71 6c 69 74  (&pCursor, sqlit
33980 65 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 61 72  e3_value_blob(ar
33990 67 76 5b 30 5d 29 2c 20 73 69 7a 65 6f 66 28 70  gv[0]), sizeof(p
339a0 43 75 72 73 6f 72 29 29 3b 0a 20 20 20 20 76 20  Cursor));.    v 
339b0 3d 20 63 75 72 73 6f 72 5f 76 74 61 62 28 70 43  = cursor_vtab(pC
339c0 75 72 73 6f 72 29 3b 0a 0a 20 20 20 20 2f 2a 20  ursor);..    /* 
339d0 49 66 20 70 61 73 73 65 64 20 6f 6e 6c 79 20 74  If passed only t
339e0 68 65 20 63 75 72 73 6f 72 20 63 6f 6c 75 6d 6e  he cursor column
339f0 2c 20 67 65 74 20 61 6c 6c 20 73 65 67 6d 65 6e  , get all segmen
33a00 74 73 2e 20 20 4f 74 68 65 72 77 69 73 65 0a 20  ts.  Otherwise. 
33a10 20 20 20 2a 2a 20 67 65 74 20 74 68 65 20 73 65     ** get the se
33a20 67 6d 65 6e 74 20 64 65 73 63 72 69 62 65 64 20  gment described 
33a30 62 79 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  by the following
33a40 20 74 77 6f 20 61 72 67 75 6d 65 6e 74 73 2e 0a   two arguments..
33a50 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 61      */.    if( a
33a60 72 67 63 3d 3d 31 20 29 7b 0a 20 20 20 20 20 20  rgc==1 ){.      
33a70 72 63 20 3d 20 73 71 6c 5f 67 65 74 5f 73 74 61  rc = sql_get_sta
33a80 74 65 6d 65 6e 74 28 76 2c 20 53 45 47 44 49 52  tement(v, SEGDIR
33a90 5f 53 45 4c 45 43 54 5f 41 4c 4c 5f 53 54 4d 54  _SELECT_ALL_STMT
33aa0 2c 20 26 73 29 3b 0a 20 20 20 20 7d 65 6c 73 65  , &s);.    }else
33ab0 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  {.      rc = sql
33ac0 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28 76  _get_statement(v
33ad0 2c 20 53 45 47 44 49 52 5f 53 45 4c 45 43 54 5f  , SEGDIR_SELECT_
33ae0 53 45 47 4d 45 4e 54 5f 53 54 4d 54 2c 20 26 73  SEGMENT_STMT, &s
33af0 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
33b00 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
33b10 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
33b20 65 33 5f 62 69 6e 64 5f 69 6e 74 28 73 2c 20 31  e3_bind_int(s, 1
33b30 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  , sqlite3_value_
33b40 69 6e 74 28 61 72 67 76 5b 31 5d 29 29 3b 0a 20  int(argv[1]));. 
33b50 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
33b60 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
33b70 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
33b80 65 33 5f 62 69 6e 64 5f 69 6e 74 28 73 2c 20 32  e3_bind_int(s, 2
33b90 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  , sqlite3_value_
33ba0 69 6e 74 28 61 72 67 76 5b 32 5d 29 29 3b 0a 20  int(argv[2]));. 
33bb0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
33bc0 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20  .    }..    if( 
33bd0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
33be0 0a 20 20 20 20 20 20 67 65 6e 65 72 61 74 65 45  .      generateE
33bf0 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 22  rror(pContext, "
33c00 64 75 6d 70 5f 74 65 72 6d 73 22 2c 20 4e 55 4c  dump_terms", NUL
33c10 4c 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e  L);.      return
33c20 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
33c30 43 6f 6c 6c 65 63 74 20 74 68 65 20 74 65 72 6d  Collect the term
33c40 73 20 66 6f 72 20 65 61 63 68 20 73 65 67 6d 65  s for each segme
33c50 6e 74 2e 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74  nt. */.    sqlit
33c60 65 33 46 74 73 33 48 61 73 68 49 6e 69 74 28 26  e3Fts3HashInit(&
33c70 74 65 72 6d 73 2c 20 46 54 53 33 5f 48 41 53 48  terms, FTS3_HASH
33c80 5f 53 54 52 49 4e 47 2c 20 31 29 3b 0a 20 20 20  _STRING, 1);.   
33c90 20 77 68 69 6c 65 28 20 28 72 63 20 3d 20 73 71   while( (rc = sq
33ca0 6c 69 74 65 33 5f 73 74 65 70 28 73 29 29 3d 3d  lite3_step(s))==
33cb0 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20  SQLITE_ROW ){.  
33cc0 20 20 20 20 72 63 20 3d 20 63 6f 6c 6c 65 63 74      rc = collect
33cd0 53 65 67 6d 65 6e 74 54 65 72 6d 73 28 76 2c 20  SegmentTerms(v, 
33ce0 73 2c 20 26 74 65 72 6d 73 29 3b 0a 20 20 20 20  s, &terms);.    
33cf0 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
33d00 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  _OK ) break;.   
33d10 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 21 3d   }..    if( rc!=
33d20 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29 7b 0a 20  SQLITE_DONE ){. 
33d30 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73       sqlite3_res
33d40 65 74 28 73 29 3b 0a 20 20 20 20 20 20 67 65 6e  et(s);.      gen
33d50 65 72 61 74 65 45 72 72 6f 72 28 70 43 6f 6e 74  erateError(pCont
33d60 65 78 74 2c 20 22 64 75 6d 70 5f 74 65 72 6d 73  ext, "dump_terms
33d70 22 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 7d 65  ", NULL);.    }e
33d80 6c 73 65 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74  lse{.      const
33d90 20 69 6e 74 20 6e 54 65 72 6d 73 20 3d 20 66 74   int nTerms = ft
33da0 73 33 48 61 73 68 43 6f 75 6e 74 28 26 74 65 72  s3HashCount(&ter
33db0 6d 73 29 3b 0a 20 20 20 20 20 20 69 66 28 20 6e  ms);.      if( n
33dc0 54 65 72 6d 73 3e 30 20 29 7b 0a 20 20 20 20 20  Terms>0 ){.     
33dd0 20 20 20 72 63 20 3d 20 67 65 6e 65 72 61 74 65     rc = generate
33de0 54 65 72 6d 73 52 65 73 75 6c 74 28 70 43 6f 6e  TermsResult(pCon
33df0 74 65 78 74 2c 20 26 74 65 72 6d 73 29 3b 0a 20  text, &terms);. 
33e00 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
33e10 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 29 7b 0a 20  QLITE_NOMEM ){. 
33e20 20 20 20 20 20 20 20 20 20 67 65 6e 65 72 61 74           generat
33e30 65 45 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c  eError(pContext,
33e40 20 22 64 75 6d 70 5f 74 65 72 6d 73 22 2c 20 22   "dump_terms", "
33e50 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 22 29 3b  out of memory");
33e60 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  .        }else{.
33e70 20 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74            assert
33e80 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
33e90 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
33ea0 20 20 20 7d 65 6c 73 65 20 69 66 28 20 61 72 67     }else if( arg
33eb0 63 3d 3d 33 20 29 7b 0a 20 20 20 20 20 20 20 20  c==3 ){.        
33ec0 2f 2a 20 54 68 65 20 73 70 65 63 69 66 69 63 20  /* The specific 
33ed0 73 65 67 6d 65 6e 74 20 61 73 6b 65 64 20 66 6f  segment asked fo
33ee0 72 20 63 6f 75 6c 64 20 6e 6f 74 20 62 65 20 66  r could not be f
33ef0 6f 75 6e 64 2e 20 2a 2f 0a 20 20 20 20 20 20 20  ound. */.       
33f00 20 67 65 6e 65 72 61 74 65 45 72 72 6f 72 28 70   generateError(p
33f10 43 6f 6e 74 65 78 74 2c 20 22 64 75 6d 70 5f 74  Context, "dump_t
33f20 65 72 6d 73 22 2c 20 22 73 65 67 6d 65 6e 74 20  erms", "segment 
33f30 6e 6f 74 20 66 6f 75 6e 64 22 29 3b 0a 20 20 20  not found");.   
33f40 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
33f50 20 20 2f 2a 20 4e 6f 20 73 65 67 6d 65 6e 74 73    /* No segments
33f60 20 66 6f 75 6e 64 2e 20 2a 2f 0a 20 20 20 20 20   found. */.     
33f70 20 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65 73 73     /* TODO(shess
33f80 29 3a 20 49 74 20 73 68 6f 75 6c 64 20 62 65 20  ): It should be 
33f90 69 6d 70 6f 73 73 69 62 6c 65 20 74 6f 20 72 65  impossible to re
33fa0 61 63 68 20 74 68 69 73 2e 20 20 54 68 69 73 0a  ach this.  This.
33fb0 20 20 20 20 20 20 20 20 2a 2a 20 63 61 73 65 20          ** case 
33fc0 63 61 6e 20 6f 6e 6c 79 20 68 61 70 70 65 6e 20  can only happen 
33fd0 66 6f 72 20 61 6e 20 65 6d 70 74 79 20 74 61 62  for an empty tab
33fe0 6c 65 2c 20 69 6e 20 77 68 69 63 68 20 63 61 73  le, in which cas
33ff0 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 53 51 4c  e.        ** SQL
34000 69 74 65 20 68 61 73 20 6e 6f 20 72 6f 77 73 20  ite has no rows 
34010 74 6f 20 63 61 6c 6c 20 74 68 69 73 20 66 75 6e  to call this fun
34020 63 74 69 6f 6e 20 6f 6e 2e 0a 20 20 20 20 20 20  ction on..      
34030 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 73 71 6c    */.        sql
34040 69 74 65 33 5f 72 65 73 75 6c 74 5f 6e 75 6c 6c  ite3_result_null
34050 28 70 43 6f 6e 74 65 78 74 29 3b 0a 20 20 20 20  (pContext);.    
34060 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73 71    }.    }.    sq
34070 6c 69 74 65 33 46 74 73 33 48 61 73 68 43 6c 65  lite3Fts3HashCle
34080 61 72 28 26 74 65 72 6d 73 29 3b 0a 20 20 7d 0a  ar(&terms);.  }.
34090 7d 0a 0a 2f 2a 20 45 78 70 61 6e 64 20 74 68 65  }../* Expand the
340a0 20 44 4c 5f 44 45 46 41 55 4c 54 20 64 6f 63 6c   DL_DEFAULT docl
340b0 69 73 74 20 69 6e 20 70 44 61 74 61 20 69 6e 74  ist in pData int
340c0 6f 20 61 20 74 65 78 74 20 72 65 73 75 6c 74 20  o a text result 
340d0 69 6e 0a 2a 2a 20 70 43 6f 6e 74 65 78 74 2e 0a  in.** pContext..
340e0 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 63  */.static void c
340f0 72 65 61 74 65 44 6f 63 6c 69 73 74 52 65 73 75  reateDoclistResu
34100 6c 74 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65  lt(sqlite3_conte
34110 78 74 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20  xt *pContext,.  
34120 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34130 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63 6f                co
34140 6e 73 74 20 63 68 61 72 20 2a 70 44 61 74 61 2c  nst char *pData,
34150 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 44   int nData){.  D
34160 61 74 61 42 75 66 66 65 72 20 64 75 6d 70 3b 0a  ataBuffer dump;.
34170 20 20 44 4c 52 65 61 64 65 72 20 64 6c 52 65 61    DLReader dlRea
34180 64 65 72 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  der;..  assert( 
34190 70 44 61 74 61 21 3d 4e 55 4c 4c 20 26 26 20 6e  pData!=NULL && n
341a0 44 61 74 61 3e 30 20 29 3b 0a 0a 20 20 64 61 74  Data>0 );..  dat
341b0 61 42 75 66 66 65 72 49 6e 69 74 28 26 64 75 6d  aBufferInit(&dum
341c0 70 2c 20 30 29 3b 0a 20 20 64 6c 72 49 6e 69 74  p, 0);.  dlrInit
341d0 28 26 64 6c 52 65 61 64 65 72 2c 20 44 4c 5f 44  (&dlReader, DL_D
341e0 45 46 41 55 4c 54 2c 20 70 44 61 74 61 2c 20 6e  EFAULT, pData, n
341f0 44 61 74 61 29 3b 0a 20 20 66 6f 72 28 20 3b 20  Data);.  for( ; 
34200 21 64 6c 72 41 74 45 6e 64 28 26 64 6c 52 65 61  !dlrAtEnd(&dlRea
34210 64 65 72 29 3b 20 64 6c 72 53 74 65 70 28 26 64  der); dlrStep(&d
34220 6c 52 65 61 64 65 72 29 20 29 7b 0a 20 20 20 20  lReader) ){.    
34230 63 68 61 72 20 62 75 66 5b 32 35 36 5d 3b 0a 20  char buf[256];. 
34240 20 20 20 50 4c 52 65 61 64 65 72 20 70 6c 52 65     PLReader plRe
34250 61 64 65 72 3b 0a 0a 20 20 20 20 70 6c 72 49 6e  ader;..    plrIn
34260 69 74 28 26 70 6c 52 65 61 64 65 72 2c 20 26 64  it(&plReader, &d
34270 6c 52 65 61 64 65 72 29 3b 0a 20 20 20 20 69 66  lReader);.    if
34280 28 20 44 4c 5f 44 45 46 41 55 4c 54 3d 3d 44 4c  ( DL_DEFAULT==DL
34290 5f 44 4f 43 49 44 53 20 7c 7c 20 70 6c 72 41 74  _DOCIDS || plrAt
342a0 45 6e 64 28 26 70 6c 52 65 61 64 65 72 29 20 29  End(&plReader) )
342b0 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
342c0 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f 66 28  snprintf(sizeof(
342d0 62 75 66 29 2c 20 62 75 66 2c 20 22 5b 25 6c 6c  buf), buf, "[%ll
342e0 64 5d 20 22 2c 20 64 6c 72 44 6f 63 69 64 28 26  d] ", dlrDocid(&
342f0 64 6c 52 65 61 64 65 72 29 29 3b 0a 20 20 20 20  dlReader));.    
34300 20 20 64 61 74 61 42 75 66 66 65 72 41 70 70 65    dataBufferAppe
34310 6e 64 28 26 64 75 6d 70 2c 20 62 75 66 2c 20 73  nd(&dump, buf, s
34320 74 72 6c 65 6e 28 62 75 66 29 29 3b 0a 20 20 20  trlen(buf));.   
34330 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 6e   }else{.      in
34340 74 20 69 43 6f 6c 75 6d 6e 20 3d 20 70 6c 72 43  t iColumn = plrC
34350 6f 6c 75 6d 6e 28 26 70 6c 52 65 61 64 65 72 29  olumn(&plReader)
34360 3b 0a 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ;..      sqlite3
34370 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f 66  _snprintf(sizeof
34380 28 62 75 66 29 2c 20 62 75 66 2c 20 22 5b 25 6c  (buf), buf, "[%l
34390 6c 64 20 25 64 5b 22 2c 0a 20 20 20 20 20 20 20  ld %d[",.       
343a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
343b0 64 6c 72 44 6f 63 69 64 28 26 64 6c 52 65 61 64  dlrDocid(&dlRead
343c0 65 72 29 2c 20 69 43 6f 6c 75 6d 6e 29 3b 0a 20  er), iColumn);. 
343d0 20 20 20 20 20 64 61 74 61 42 75 66 66 65 72 41       dataBufferA
343e0 70 70 65 6e 64 28 26 64 75 6d 70 2c 20 62 75 66  ppend(&dump, buf
343f0 2c 20 73 74 72 6c 65 6e 28 62 75 66 29 29 3b 0a  , strlen(buf));.
34400 0a 20 20 20 20 20 20 66 6f 72 28 20 3b 20 21 70  .      for( ; !p
34410 6c 72 41 74 45 6e 64 28 26 70 6c 52 65 61 64 65  lrAtEnd(&plReade
34420 72 29 3b 20 70 6c 72 53 74 65 70 28 26 70 6c 52  r); plrStep(&plR
34430 65 61 64 65 72 29 20 29 7b 0a 20 20 20 20 20 20  eader) ){.      
34440 20 20 69 66 28 20 70 6c 72 43 6f 6c 75 6d 6e 28    if( plrColumn(
34450 26 70 6c 52 65 61 64 65 72 29 21 3d 69 43 6f 6c  &plReader)!=iCol
34460 75 6d 6e 20 29 7b 0a 20 20 20 20 20 20 20 20 20  umn ){.         
34470 20 69 43 6f 6c 75 6d 6e 20 3d 20 70 6c 72 43 6f   iColumn = plrCo
34480 6c 75 6d 6e 28 26 70 6c 52 65 61 64 65 72 29 3b  lumn(&plReader);
34490 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74  .          sqlit
344a0 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a 65  e3_snprintf(size
344b0 6f 66 28 62 75 66 29 2c 20 62 75 66 2c 20 22 5d  of(buf), buf, "]
344c0 20 25 64 5b 22 2c 20 69 43 6f 6c 75 6d 6e 29 3b   %d[", iColumn);
344d0 0a 20 20 20 20 20 20 20 20 20 20 61 73 73 65 72  .          asser
344e0 74 28 20 64 75 6d 70 2e 6e 44 61 74 61 3e 30 20  t( dump.nData>0 
344f0 29 3b 0a 20 20 20 20 20 20 20 20 20 20 64 75 6d  );.          dum
34500 70 2e 6e 44 61 74 61 2d 2d 3b 20 20 20 20 20 20  p.nData--;      
34510 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
34520 2a 20 4f 76 65 72 77 72 69 74 65 20 74 72 61 69  * Overwrite trai
34530 6c 69 6e 67 20 73 70 61 63 65 2e 20 2a 2f 0a 20  ling space. */. 
34540 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
34550 20 64 75 6d 70 2e 70 44 61 74 61 5b 64 75 6d 70   dump.pData[dump
34560 2e 6e 44 61 74 61 5d 3d 3d 27 20 27 29 3b 0a 20  .nData]==' ');. 
34570 20 20 20 20 20 20 20 20 20 64 61 74 61 42 75 66           dataBuf
34580 66 65 72 41 70 70 65 6e 64 28 26 64 75 6d 70 2c  ferAppend(&dump,
34590 20 62 75 66 2c 20 73 74 72 6c 65 6e 28 62 75 66   buf, strlen(buf
345a0 29 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  ));.        }.  
345b0 20 20 20 20 20 20 69 66 28 20 44 4c 5f 44 45 46        if( DL_DEF
345c0 41 55 4c 54 3d 3d 44 4c 5f 50 4f 53 49 54 49 4f  AULT==DL_POSITIO
345d0 4e 53 5f 4f 46 46 53 45 54 53 20 29 7b 0a 20 20  NS_OFFSETS ){.  
345e0 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
345f0 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f 66 28  snprintf(sizeof(
34600 62 75 66 29 2c 20 62 75 66 2c 20 22 25 64 2c 25  buf), buf, "%d,%
34610 64 2c 25 64 20 22 2c 0a 20 20 20 20 20 20 20 20  d,%d ",.        
34620 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34630 20 20 20 70 6c 72 50 6f 73 69 74 69 6f 6e 28 26     plrPosition(&
34640 70 6c 52 65 61 64 65 72 29 2c 0a 20 20 20 20 20  plReader),.     
34650 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34660 20 20 20 20 20 20 70 6c 72 53 74 61 72 74 4f 66        plrStartOf
34670 66 73 65 74 28 26 70 6c 52 65 61 64 65 72 29 2c  fset(&plReader),
34680 20 70 6c 72 45 6e 64 4f 66 66 73 65 74 28 26 70   plrEndOffset(&p
34690 6c 52 65 61 64 65 72 29 29 3b 0a 20 20 20 20 20  lReader));.     
346a0 20 20 20 7d 65 6c 73 65 20 69 66 28 20 44 4c 5f     }else if( DL_
346b0 44 45 46 41 55 4c 54 3d 3d 44 4c 5f 50 4f 53 49  DEFAULT==DL_POSI
346c0 54 49 4f 4e 53 20 29 7b 0a 20 20 20 20 20 20 20  TIONS ){.       
346d0 20 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69     sqlite3_snpri
346e0 6e 74 66 28 73 69 7a 65 6f 66 28 62 75 66 29 2c  ntf(sizeof(buf),
346f0 20 62 75 66 2c 20 22 25 64 20 22 2c 20 70 6c 72   buf, "%d ", plr
34700 50 6f 73 69 74 69 6f 6e 28 26 70 6c 52 65 61 64  Position(&plRead
34710 65 72 29 29 3b 0a 20 20 20 20 20 20 20 20 7d 65  er));.        }e
34720 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 61  lse{.          a
34730 73 73 65 72 74 28 20 4e 55 4c 4c 3d 3d 22 55 6e  ssert( NULL=="Un
34740 68 61 6e 64 6c 65 64 20 44 4c 5f 44 45 46 41 55  handled DL_DEFAU
34750 4c 54 20 76 61 6c 75 65 22 29 3b 0a 20 20 20 20  LT value");.    
34760 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 64 61      }.        da
34770 74 61 42 75 66 66 65 72 41 70 70 65 6e 64 28 26  taBufferAppend(&
34780 64 75 6d 70 2c 20 62 75 66 2c 20 73 74 72 6c 65  dump, buf, strle
34790 6e 28 62 75 66 29 29 3b 0a 20 20 20 20 20 20 7d  n(buf));.      }
347a0 0a 20 20 20 20 20 20 70 6c 72 44 65 73 74 72 6f  .      plrDestro
347b0 79 28 26 70 6c 52 65 61 64 65 72 29 3b 0a 0a 20  y(&plReader);.. 
347c0 20 20 20 20 20 61 73 73 65 72 74 28 20 64 75 6d       assert( dum
347d0 70 2e 6e 44 61 74 61 3e 30 20 29 3b 0a 20 20 20  p.nData>0 );.   
347e0 20 20 20 64 75 6d 70 2e 6e 44 61 74 61 2d 2d 3b     dump.nData--;
347f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34800 20 20 20 20 20 2f 2a 20 4f 76 65 72 77 72 69 74       /* Overwrit
34810 65 20 74 72 61 69 6c 69 6e 67 20 73 70 61 63 65  e trailing space
34820 2e 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72  . */.      asser
34830 74 28 20 64 75 6d 70 2e 70 44 61 74 61 5b 64 75  t( dump.pData[du
34840 6d 70 2e 6e 44 61 74 61 5d 3d 3d 27 20 27 29 3b  mp.nData]==' ');
34850 0a 20 20 20 20 20 20 64 61 74 61 42 75 66 66 65  .      dataBuffe
34860 72 41 70 70 65 6e 64 28 26 64 75 6d 70 2c 20 22  rAppend(&dump, "
34870 5d 5d 20 22 2c 20 33 29 3b 0a 20 20 20 20 7d 0a  ]] ", 3);.    }.
34880 20 20 7d 0a 20 20 64 6c 72 44 65 73 74 72 6f 79    }.  dlrDestroy
34890 28 26 64 6c 52 65 61 64 65 72 29 3b 0a 0a 20 20  (&dlReader);..  
348a0 61 73 73 65 72 74 28 20 64 75 6d 70 2e 6e 44 61  assert( dump.nDa
348b0 74 61 3e 30 20 29 3b 0a 20 20 64 75 6d 70 2e 6e  ta>0 );.  dump.n
348c0 44 61 74 61 2d 2d 3b 20 20 20 20 20 20 20 20 20  Data--;         
348d0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
348e0 76 65 72 77 72 69 74 65 20 74 72 61 69 6c 69 6e  verwrite trailin
348f0 67 20 73 70 61 63 65 2e 20 2a 2f 0a 20 20 61 73  g space. */.  as
34900 73 65 72 74 28 20 64 75 6d 70 2e 70 44 61 74 61  sert( dump.pData
34910 5b 64 75 6d 70 2e 6e 44 61 74 61 5d 3d 3d 27 20  [dump.nData]==' 
34920 27 29 3b 0a 20 20 64 75 6d 70 2e 70 44 61 74 61  ');.  dump.pData
34930 5b 64 75 6d 70 2e 6e 44 61 74 61 5d 20 3d 20 27  [dump.nData] = '
34940 5c 30 27 3b 0a 20 20 61 73 73 65 72 74 28 20 64  \0';.  assert( d
34950 75 6d 70 2e 6e 44 61 74 61 3e 30 20 29 3b 0a 0a  ump.nData>0 );..
34960 20 20 2f 2a 20 50 61 73 73 65 73 20 6f 77 6e 65    /* Passes owne
34970 72 73 68 69 70 20 6f 66 20 64 75 6d 70 27 73 20  rship of dump's 
34980 62 75 66 66 65 72 20 74 6f 20 70 43 6f 6e 74 65  buffer to pConte
34990 78 74 2e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  xt. */.  sqlite3
349a0 5f 72 65 73 75 6c 74 5f 74 65 78 74 28 70 43 6f  _result_text(pCo
349b0 6e 74 65 78 74 2c 20 64 75 6d 70 2e 70 44 61 74  ntext, dump.pDat
349c0 61 2c 20 64 75 6d 70 2e 6e 44 61 74 61 2c 20 73  a, dump.nData, s
349d0 71 6c 69 74 65 33 5f 66 72 65 65 29 3b 0a 20 20  qlite3_free);.  
349e0 64 75 6d 70 2e 70 44 61 74 61 20 3d 20 4e 55 4c  dump.pData = NUL
349f0 4c 3b 0a 20 20 64 75 6d 70 2e 6e 44 61 74 61 20  L;.  dump.nData 
34a00 3d 20 64 75 6d 70 2e 6e 43 61 70 61 63 69 74 79  = dump.nCapacity
34a10 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 20 49 6d 70 6c   = 0;.}../* Impl
34a20 65 6d 65 6e 74 73 20 64 75 6d 70 5f 64 6f 63 6c  ements dump_docl
34a30 69 73 74 28 29 20 66 6f 72 20 75 73 65 20 69 6e  ist() for use in
34a40 20 69 6e 73 70 65 63 74 69 6e 67 20 74 68 65 20   inspecting the 
34a50 66 74 73 33 20 69 6e 64 65 78 20 66 72 6f 6d 0a  fts3 index from.
34a60 2a 2a 20 74 65 73 74 73 2e 20 20 54 45 58 54 20  ** tests.  TEXT 
34a70 72 65 73 75 6c 74 20 63 6f 6e 74 61 69 6e 69 6e  result containin
34a80 67 20 61 20 73 74 72 69 6e 67 20 72 65 70 72 65  g a string repre
34a90 73 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  sentation of the
34aa0 0a 2a 2a 20 64 6f 63 6c 69 73 74 20 66 6f 72 20  .** doclist for 
34ab0 74 68 65 20 69 6e 64 69 63 61 74 65 64 20 74 65  the indicated te
34ac0 72 6d 2e 20 20 64 75 6d 70 5f 64 6f 63 6c 69 73  rm.  dump_doclis
34ad0 74 28 74 2c 20 74 65 72 6d 2c 20 6c 65 76 65 6c  t(t, term, level
34ae0 2c 20 69 64 78 29 0a 2a 2a 20 64 75 6d 70 73 20  , idx).** dumps 
34af0 74 68 65 20 64 6f 63 6c 69 73 74 20 66 6f 72 20  the doclist for 
34b00 74 65 72 6d 20 66 72 6f 6d 20 74 68 65 20 73 65  term from the se
34b10 67 6d 65 6e 74 20 73 70 65 63 69 66 69 65 64 20  gment specified 
34b20 62 79 20 6c 65 76 65 6c 2c 20 69 64 78 0a 2a 2a  by level, idx.**
34b30 20 28 69 6e 20 25 5f 73 65 67 64 69 72 29 2c 20   (in %_segdir), 
34b40 77 68 69 6c 65 20 64 75 6d 70 5f 64 6f 63 6c 69  while dump_docli
34b50 73 74 28 74 2c 20 74 65 72 6d 29 20 64 75 6d 70  st(t, term) dump
34b60 73 20 74 68 65 20 6c 6f 67 69 63 61 6c 0a 2a 2a  s the logical.**
34b70 20 64 6f 63 6c 69 73 74 20 66 6f 72 20 74 68 65   doclist for the
34b80 20 74 65 72 6d 20 61 63 72 6f 73 73 20 61 6c 6c   term across all
34b90 20 73 65 67 6d 65 6e 74 73 2e 20 20 54 68 65 20   segments.  The 
34ba0 70 65 72 2d 73 65 67 6d 65 6e 74 20 64 6f 63 6c  per-segment docl
34bb0 69 73 74 0a 2a 2a 20 63 61 6e 20 63 6f 6e 74 61  ist.** can conta
34bc0 69 6e 20 64 65 6c 65 74 69 6f 6e 73 2c 20 77 68  in deletions, wh
34bd0 69 6c 65 20 74 68 65 20 66 75 6c 6c 2d 69 6e 64  ile the full-ind
34be0 65 78 20 64 6f 63 6c 69 73 74 20 77 69 6c 6c 20  ex doclist will 
34bf0 6e 6f 74 0a 2a 2a 20 28 64 65 6c 65 74 69 6f 6e  not.** (deletion
34c00 73 20 61 72 65 20 6f 6d 69 74 74 65 64 29 2e 0a  s are omitted)..
34c10 2a 2a 0a 2a 2a 20 52 65 73 75 6c 74 20 66 6f 72  **.** Result for
34c20 6d 61 74 73 20 64 69 66 66 65 72 20 77 69 74 68  mats differ with
34c30 20 74 68 65 20 73 65 74 74 69 6e 67 20 6f 66 20   the setting of 
34c40 44 4c 5f 44 45 46 41 55 4c 54 53 2e 20 20 45 78  DL_DEFAULTS.  Ex
34c50 61 6d 70 6c 65 73 3a 0a 2a 2a 0a 2a 2a 20 44 4c  amples:.**.** DL
34c60 5f 44 4f 43 49 44 53 3a 20 5b 31 5d 20 5b 33 5d  _DOCIDS: [1] [3]
34c70 20 5b 37 5d 0a 2a 2a 20 44 4c 5f 50 4f 53 49 54   [7].** DL_POSIT
34c80 49 4f 4e 53 3a 20 5b 31 20 30 5b 30 20 34 5d 20  IONS: [1 0[0 4] 
34c90 31 5b 31 37 5d 5d 20 5b 33 20 31 5b 35 5d 5d 0a  1[17]] [3 1[5]].
34ca0 2a 2a 20 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 5f  ** DL_POSITIONS_
34cb0 4f 46 46 53 45 54 53 3a 20 5b 31 20 30 5b 30 2c  OFFSETS: [1 0[0,
34cc0 30 2c 33 20 34 2c 32 33 2c 32 36 5d 20 31 5b 31  0,3 4,23,26] 1[1
34cd0 37 2c 31 30 32 2c 31 30 35 5d 5d 20 5b 33 20 31  7,102,105]] [3 1
34ce0 5b 35 2c 32 30 2c 32 33 5d 5d 0a 2a 2a 0a 2a 2a  [5,20,23]].**.**
34cf0 20 49 6e 20 65 61 63 68 20 63 61 73 65 20 74 68   In each case th
34d00 65 20 6e 75 6d 62 65 72 20 61 66 74 65 72 20 74  e number after t
34d10 68 65 20 6f 75 74 65 72 20 27 5b 27 20 69 73 20  he outer '[' is 
34d20 74 68 65 20 64 6f 63 69 64 2e 20 20 49 6e 20 74  the docid.  In t
34d30 68 65 0a 2a 2a 20 6c 61 74 74 65 72 20 74 77 6f  he.** latter two
34d40 20 63 61 73 65 73 2c 20 74 68 65 20 6e 75 6d 62   cases, the numb
34d50 65 72 20 62 65 66 6f 72 65 20 74 68 65 20 69 6e  er before the in
34d60 6e 65 72 20 27 5b 27 20 69 73 20 74 68 65 20 63  ner '[' is the c
34d70 6f 6c 75 6d 6e 0a 2a 2a 20 61 73 73 6f 63 69 61  olumn.** associa
34d80 74 65 64 20 77 69 74 68 20 74 68 65 20 76 61 6c  ted with the val
34d90 75 65 73 20 77 69 74 68 69 6e 2e 20 20 46 6f 72  ues within.  For
34da0 20 44 4c 5f 50 4f 53 49 54 49 4f 4e 53 20 74 68   DL_POSITIONS th
34db0 65 20 6e 75 6d 62 65 72 73 0a 2a 2a 20 77 69 74  e numbers.** wit
34dc0 68 69 6e 20 61 72 65 20 74 68 65 20 70 6f 73 69  hin are the posi
34dd0 74 69 6f 6e 73 2c 20 66 6f 72 20 44 4c 5f 50 4f  tions, for DL_PO
34de0 53 49 54 49 4f 4e 53 5f 4f 46 46 53 45 54 53 20  SITIONS_OFFSETS 
34df0 74 68 65 79 20 61 72 65 20 74 68 65 0a 2a 2a 20  they are the.** 
34e00 70 6f 73 69 74 69 6f 6e 2c 20 74 68 65 20 73 74  position, the st
34e10 61 72 74 20 6f 66 66 73 65 74 2c 20 61 6e 64 20  art offset, and 
34e20 74 68 65 20 65 6e 64 20 6f 66 66 73 65 74 2e 0a  the end offset..
34e30 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64  */.static void d
34e40 75 6d 70 44 6f 63 6c 69 73 74 46 75 6e 63 28 0a  umpDoclistFunc(.
34e50 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78    sqlite3_contex
34e60 74 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69  t *pContext,.  i
34e70 6e 74 20 61 72 67 63 2c 20 73 71 6c 69 74 65 33  nt argc, sqlite3
34e80 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b  _value **argv.){
34e90 0a 20 20 66 75 6c 6c 74 65 78 74 5f 63 75 72 73  .  fulltext_curs
34ea0 6f 72 20 2a 70 43 75 72 73 6f 72 3b 0a 20 20 69  or *pCursor;.  i
34eb0 66 28 20 61 72 67 63 21 3d 32 20 26 26 20 61 72  f( argc!=2 && ar
34ec0 67 63 21 3d 34 20 29 7b 0a 20 20 20 20 67 65 6e  gc!=4 ){.    gen
34ed0 65 72 61 74 65 45 72 72 6f 72 28 70 43 6f 6e 74  erateError(pCont
34ee0 65 78 74 2c 20 22 64 75 6d 70 5f 64 6f 63 6c 69  ext, "dump_docli
34ef0 73 74 22 2c 20 22 69 6e 63 6f 72 72 65 63 74 20  st", "incorrect 
34f00 61 72 67 75 6d 65 6e 74 73 22 29 3b 0a 20 20 7d  arguments");.  }
34f10 65 6c 73 65 20 69 66 28 20 73 71 6c 69 74 65 33  else if( sqlite3
34f20 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 72 67 76  _value_type(argv
34f30 5b 30 5d 29 21 3d 53 51 4c 49 54 45 5f 42 4c 4f  [0])!=SQLITE_BLO
34f40 42 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20  B ||.           
34f50 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62   sqlite3_value_b
34f60 79 74 65 73 28 61 72 67 76 5b 30 5d 29 21 3d 73  ytes(argv[0])!=s
34f70 69 7a 65 6f 66 28 70 43 75 72 73 6f 72 29 20 29  izeof(pCursor) )
34f80 7b 0a 20 20 20 20 67 65 6e 65 72 61 74 65 45 72  {.    generateEr
34f90 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 22 64  ror(pContext, "d
34fa0 75 6d 70 5f 64 6f 63 6c 69 73 74 22 2c 20 22 69  ump_doclist", "i
34fb0 6c 6c 65 67 61 6c 20 66 69 72 73 74 20 61 72 67  llegal first arg
34fc0 75 6d 65 6e 74 22 29 3b 0a 20 20 7d 65 6c 73 65  ument");.  }else
34fd0 20 69 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c   if( sqlite3_val
34fe0 75 65 5f 74 65 78 74 28 61 72 67 76 5b 31 5d 29  ue_text(argv[1])
34ff0 3d 3d 4e 55 4c 4c 20 7c 7c 0a 20 20 20 20 20 20  ==NULL ||.      
35000 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61        sqlite3_va
35010 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 31 5d  lue_text(argv[1]
35020 29 5b 30 5d 3d 3d 27 5c 30 27 20 29 7b 0a 20 20  )[0]=='\0' ){.  
35030 20 20 67 65 6e 65 72 61 74 65 45 72 72 6f 72 28    generateError(
35040 70 43 6f 6e 74 65 78 74 2c 20 22 64 75 6d 70 5f  pContext, "dump_
35050 64 6f 63 6c 69 73 74 22 2c 20 22 65 6d 70 74 79  doclist", "empty
35060 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74   second argument
35070 22 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ");.  }else{.   
35080 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65   const char *pTe
35090 72 6d 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72  rm = (const char
350a0 20 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65   *)sqlite3_value
350b0 5f 74 65 78 74 28 61 72 67 76 5b 31 5d 29 3b 0a  _text(argv[1]);.
350c0 20 20 20 20 63 6f 6e 73 74 20 69 6e 74 20 6e 54      const int nT
350d0 65 72 6d 20 3d 20 73 74 72 6c 65 6e 28 70 54 65  erm = strlen(pTe
350e0 72 6d 29 3b 0a 20 20 20 20 66 75 6c 6c 74 65 78  rm);.    fulltex
350f0 74 5f 76 74 61 62 20 2a 76 3b 0a 20 20 20 20 69  t_vtab *v;.    i
35100 6e 74 20 72 63 3b 0a 20 20 20 20 44 61 74 61 42  nt rc;.    DataB
35110 75 66 66 65 72 20 64 6f 63 6c 69 73 74 3b 0a 0a  uffer doclist;..
35120 20 20 20 20 6d 65 6d 63 70 79 28 26 70 43 75 72      memcpy(&pCur
35130 73 6f 72 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c  sor, sqlite3_val
35140 75 65 5f 62 6c 6f 62 28 61 72 67 76 5b 30 5d 29  ue_blob(argv[0])
35150 2c 20 73 69 7a 65 6f 66 28 70 43 75 72 73 6f 72  , sizeof(pCursor
35160 29 29 3b 0a 20 20 20 20 76 20 3d 20 63 75 72 73  ));.    v = curs
35170 6f 72 5f 76 74 61 62 28 70 43 75 72 73 6f 72 29  or_vtab(pCursor)
35180 3b 0a 0a 20 20 20 20 64 61 74 61 42 75 66 66 65  ;..    dataBuffe
35190 72 49 6e 69 74 28 26 64 6f 63 6c 69 73 74 2c 20  rInit(&doclist, 
351a0 30 29 3b 0a 0a 20 20 20 20 2f 2a 20 74 65 72 6d  0);..    /* term
351b0 53 65 6c 65 63 74 28 29 20 79 69 65 6c 64 73 20  Select() yields 
351c0 74 68 65 20 73 61 6d 65 20 6c 6f 67 69 63 61 6c  the same logical
351d0 20 64 6f 63 6c 69 73 74 20 74 68 61 74 20 71 75   doclist that qu
351e0 65 72 69 65 73 20 61 72 65 0a 20 20 20 20 2a 2a  eries are.    **
351f0 20 72 75 6e 20 61 67 61 69 6e 73 74 2e 0a 20 20   run against..  
35200 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 61 72 67    */.    if( arg
35210 63 3d 3d 32 20 29 7b 0a 20 20 20 20 20 20 72 63  c==2 ){.      rc
35220 20 3d 20 74 65 72 6d 53 65 6c 65 63 74 28 76 2c   = termSelect(v,
35230 20 76 2d 3e 6e 43 6f 6c 75 6d 6e 2c 20 70 54 65   v->nColumn, pTe
35240 72 6d 2c 20 6e 54 65 72 6d 2c 20 30 2c 20 44 4c  rm, nTerm, 0, DL
35250 5f 44 45 46 41 55 4c 54 2c 20 26 64 6f 63 6c 69  _DEFAULT, &docli
35260 73 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  st);.    }else{.
35270 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74        sqlite3_st
35280 6d 74 20 2a 73 20 3d 20 4e 55 4c 4c 3b 0a 0a 20  mt *s = NULL;.. 
35290 20 20 20 20 20 2f 2a 20 47 65 74 20 6f 75 72 20       /* Get our 
352a0 73 70 65 63 69 66 69 63 20 73 65 67 6d 65 6e 74  specific segment
352b0 27 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 20  's information. 
352c0 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  */.      rc = sq
352d0 6c 5f 67 65 74 5f 73 74 61 74 65 6d 65 6e 74 28  l_get_statement(
352e0 76 2c 20 53 45 47 44 49 52 5f 53 45 4c 45 43 54  v, SEGDIR_SELECT
352f0 5f 53 45 47 4d 45 4e 54 5f 53 54 4d 54 2c 20 26  _SEGMENT_STMT, &
35300 73 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  s);.      if( rc
35310 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
35320 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
35330 74 65 33 5f 62 69 6e 64 5f 69 6e 74 28 73 2c 20  te3_bind_int(s, 
35340 31 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  1, sqlite3_value
35350 5f 69 6e 74 28 61 72 67 76 5b 32 5d 29 29 3b 0a  _int(argv[2]));.
35360 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d          if( rc==
35370 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
35380 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
35390 74 65 33 5f 62 69 6e 64 5f 69 6e 74 28 73 2c 20  te3_bind_int(s, 
353a0 32 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  2, sqlite3_value
353b0 5f 69 6e 74 28 61 72 67 76 5b 33 5d 29 29 3b 0a  _int(argv[3]));.
353c0 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
353d0 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  }..      if( rc=
353e0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
353f0 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
35400 65 33 5f 73 74 65 70 28 73 29 3b 0a 0a 20 20 20  e3_step(s);..   
35410 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
35420 49 54 45 5f 44 4f 4e 45 20 29 7b 0a 20 20 20 20  ITE_DONE ){.    
35430 20 20 20 20 20 20 64 61 74 61 42 75 66 66 65 72        dataBuffer
35440 44 65 73 74 72 6f 79 28 26 64 6f 63 6c 69 73 74  Destroy(&doclist
35450 29 3b 0a 20 20 20 20 20 20 20 20 20 20 67 65 6e  );.          gen
35460 65 72 61 74 65 45 72 72 6f 72 28 70 43 6f 6e 74  erateError(pCont
35470 65 78 74 2c 20 22 64 75 6d 70 5f 64 6f 63 6c 69  ext, "dump_docli
35480 73 74 22 2c 20 22 73 65 67 6d 65 6e 74 20 6e 6f  st", "segment no
35490 74 20 66 6f 75 6e 64 22 29 3b 0a 20 20 20 20 20  t found");.     
354a0 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20       return;.   
354b0 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20       }..        
354c0 2f 2a 20 46 6f 75 6e 64 20 61 20 73 65 67 6d 65  /* Found a segme
354d0 6e 74 2c 20 6c 6f 61 64 20 69 74 20 69 6e 74 6f  nt, load it into
354e0 20 64 6f 63 6c 69 73 74 2e 20 2a 2f 0a 20 20 20   doclist. */.   
354f0 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
35500 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20  ITE_ROW ){.     
35510 20 20 20 20 20 63 6f 6e 73 74 20 73 71 6c 69 74       const sqlit
35520 65 5f 69 6e 74 36 34 20 69 4c 65 61 76 65 73 45  e_int64 iLeavesE
35530 6e 64 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c  nd = sqlite3_col
35540 75 6d 6e 5f 69 6e 74 36 34 28 73 2c 20 31 29 3b  umn_int64(s, 1);
35550 0a 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74  .          const
35560 20 63 68 61 72 20 2a 70 44 61 74 61 20 3d 20 73   char *pData = s
35570 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c  qlite3_column_bl
35580 6f 62 28 73 2c 20 32 29 3b 0a 20 20 20 20 20 20  ob(s, 2);.      
35590 20 20 20 20 63 6f 6e 73 74 20 69 6e 74 20 6e 44      const int nD
355a0 61 74 61 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  ata = sqlite3_co
355b0 6c 75 6d 6e 5f 62 79 74 65 73 28 73 2c 20 32 29  lumn_bytes(s, 2)
355c0 3b 0a 0a 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;..          /* 
355d0 6c 6f 61 64 53 65 67 6d 65 6e 74 28 29 20 69 73  loadSegment() is
355e0 20 75 73 65 64 20 62 79 20 74 65 72 6d 53 65 6c   used by termSel
355f0 65 63 74 28 29 20 74 6f 20 6c 6f 61 64 20 65 61  ect() to load ea
35600 63 68 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20  ch.          ** 
35610 73 65 67 6d 65 6e 74 27 73 20 64 61 74 61 2e 0a  segment's data..
35620 20 20 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20            */.   
35630 20 20 20 20 20 20 20 72 63 20 3d 20 6c 6f 61 64         rc = load
35640 53 65 67 6d 65 6e 74 28 76 2c 20 70 44 61 74 61  Segment(v, pData
35650 2c 20 6e 44 61 74 61 2c 20 69 4c 65 61 76 65 73  , nData, iLeaves
35660 45 6e 64 2c 20 70 54 65 72 6d 2c 20 6e 54 65 72  End, pTerm, nTer
35670 6d 2c 20 30 2c 0a 20 20 20 20 20 20 20 20 20 20  m, 0,.          
35680 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
35690 20 26 64 6f 63 6c 69 73 74 29 3b 0a 20 20 20 20   &doclist);.    
356a0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
356b0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
356c0 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
356d0 74 65 33 5f 73 74 65 70 28 73 29 3b 0a 0a 20 20  te3_step(s);..  
356e0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 68 6f            /* Sho
356f0 75 6c 64 20 6e 6f 74 20 68 61 76 65 20 6d 6f 72  uld not have mor
35700 65 20 74 68 61 6e 20 6f 6e 65 20 6d 61 74 63 68  e than one match
35710 69 6e 67 20 73 65 67 6d 65 6e 74 2e 20 2a 2f 0a  ing segment. */.
35720 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20              if( 
35730 72 63 21 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20  rc!=SQLITE_DONE 
35740 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ){.             
35750 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 73   sqlite3_reset(s
35760 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  );.             
35770 20 64 61 74 61 42 75 66 66 65 72 44 65 73 74 72   dataBufferDestr
35780 6f 79 28 26 64 6f 63 6c 69 73 74 29 3b 0a 20 20  oy(&doclist);.  
35790 20 20 20 20 20 20 20 20 20 20 20 20 67 65 6e 65              gene
357a0 72 61 74 65 45 72 72 6f 72 28 70 43 6f 6e 74 65  rateError(pConte
357b0 78 74 2c 20 22 64 75 6d 70 5f 64 6f 63 6c 69 73  xt, "dump_doclis
357c0 74 22 2c 20 22 69 6e 76 61 6c 69 64 20 73 65 67  t", "invalid seg
357d0 64 69 72 22 29 3b 0a 20 20 20 20 20 20 20 20 20  dir");.         
357e0 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20       return;.   
357f0 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
35800 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
35810 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 20 20 20  TE_OK;.         
35820 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
35830 20 20 20 7d 0a 0a 20 20 20 20 20 20 73 71 6c 69     }..      sqli
35840 74 65 33 5f 72 65 73 65 74 28 73 29 3b 0a 20 20  te3_reset(s);.  
35850 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d    }..    if( rc=
35860 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
35870 20 20 20 20 69 66 28 20 64 6f 63 6c 69 73 74 2e      if( doclist.
35880 6e 44 61 74 61 3e 30 20 29 7b 0a 20 20 20 20 20  nData>0 ){.     
35890 20 20 20 63 72 65 61 74 65 44 6f 63 6c 69 73 74     createDoclist
358a0 52 65 73 75 6c 74 28 70 43 6f 6e 74 65 78 74 2c  Result(pContext,
358b0 20 64 6f 63 6c 69 73 74 2e 70 44 61 74 61 2c 20   doclist.pData, 
358c0 64 6f 63 6c 69 73 74 2e 6e 44 61 74 61 29 3b 0a  doclist.nData);.
358d0 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
358e0 20 20 20 20 20 2f 2a 20 54 4f 44 4f 28 73 68 65       /* TODO(she
358f0 73 73 29 3a 20 54 68 69 73 20 63 61 6e 20 68 61  ss): This can ha
35900 70 70 65 6e 20 69 66 20 74 68 65 20 74 65 72 6d  ppen if the term
35910 20 69 73 20 6e 6f 74 20 70 72 65 73 65 6e 74 2c   is not present,
35920 20 6f 72 0a 20 20 20 20 20 20 20 20 2a 2a 20 69   or.        ** i
35930 66 20 61 6c 6c 20 69 6e 73 74 61 6e 63 65 73 20  f all instances 
35940 6f 66 20 74 68 65 20 74 65 72 6d 20 68 61 76 65  of the term have
35950 20 62 65 65 6e 20 64 65 6c 65 74 65 64 20 61 6e   been deleted an
35960 64 20 74 68 69 73 20 69 73 0a 20 20 20 20 20 20  d this is.      
35970 20 20 2a 2a 20 61 6e 20 61 6c 6c 2d 69 6e 64 65    ** an all-inde
35980 78 20 64 75 6d 70 2e 20 20 49 74 20 6d 61 79 20  x dump.  It may 
35990 62 65 20 69 6e 74 65 72 65 73 74 69 6e 67 20 74  be interesting t
359a0 6f 20 64 69 73 74 69 6e 67 75 69 73 68 0a 20 20  o distinguish.  
359b0 20 20 20 20 20 20 2a 2a 20 74 68 65 73 65 20 63        ** these c
359c0 61 73 65 73 2e 0a 20 20 20 20 20 20 20 20 2a 2f  ases..        */
359d0 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
359e0 5f 72 65 73 75 6c 74 5f 74 65 78 74 28 70 43 6f  _result_text(pCo
359f0 6e 74 65 78 74 2c 20 22 22 2c 20 30 2c 20 53 51  ntext, "", 0, SQ
35a00 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20  LITE_STATIC);.  
35a10 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 20      }.    }else 
35a20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4e  if( rc==SQLITE_N
35a30 4f 4d 45 4d 20 29 7b 0a 20 20 20 20 20 20 2f 2a  OMEM ){.      /*
35a40 20 48 61 6e 64 6c 65 20 6f 75 74 2d 6f 66 2d 6d   Handle out-of-m
35a50 65 6d 6f 72 79 20 63 61 73 65 73 20 73 70 65 63  emory cases spec
35a60 69 61 6c 6c 79 20 62 65 63 61 75 73 65 20 69 66  ially because if
35a70 20 74 68 65 79 20 61 72 65 0a 20 20 20 20 20 20   they are.      
35a80 2a 2a 20 67 65 6e 65 72 61 74 65 64 20 69 6e 20  ** generated in 
35a90 66 74 73 33 20 63 6f 64 65 20 74 68 65 79 20 6d  fts3 code they m
35aa0 61 79 20 6e 6f 74 20 62 65 20 72 65 66 6c 65 63  ay not be reflec
35ab0 74 65 64 20 69 6e 20 74 68 65 20 64 62 0a 20 20  ted in the db.  
35ac0 20 20 20 20 2a 2a 20 68 61 6e 64 6c 65 2e 0a 20      ** handle.. 
35ad0 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 2f 2a       */.      /*
35ae0 20 54 4f 44 4f 28 73 68 65 73 73 29 3a 20 48 61   TODO(shess): Ha
35af0 6e 64 6c 65 20 74 68 69 73 20 6d 6f 72 65 20 63  ndle this more c
35b00 6f 6d 70 72 65 68 65 6e 73 69 76 65 6c 79 2e 0a  omprehensively..
35b10 20 20 20 20 20 20 2a 2a 20 73 71 6c 69 74 65 33        ** sqlite3
35b20 45 72 72 53 74 72 28 29 20 68 61 73 20 77 68 61  ErrStr() has wha
35b30 74 20 49 20 6e 65 65 64 2c 20 62 75 74 20 69 73  t I need, but is
35b40 20 69 6e 74 65 72 6e 61 6c 2e 0a 20 20 20 20 20   internal..     
35b50 20 2a 2f 0a 20 20 20 20 20 20 67 65 6e 65 72 61   */.      genera
35b60 74 65 45 72 72 6f 72 28 70 43 6f 6e 74 65 78 74  teError(pContext
35b70 2c 20 22 64 75 6d 70 5f 64 6f 63 6c 69 73 74 22  , "dump_doclist"
35b80 2c 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79  , "out of memory
35b90 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ");.    }else{. 
35ba0 20 20 20 20 20 67 65 6e 65 72 61 74 65 45 72 72       generateErr
35bb0 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 22 64 75  or(pContext, "du
35bc0 6d 70 5f 64 6f 63 6c 69 73 74 22 2c 20 4e 55 4c  mp_doclist", NUL
35bd0 4c 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 64  L);.    }..    d
35be0 61 74 61 42 75 66 66 65 72 44 65 73 74 72 6f 79  ataBufferDestroy
35bf0 28 26 64 6f 63 6c 69 73 74 29 3b 0a 20 20 7d 0a  (&doclist);.  }.
35c00 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20  }.#endif../*.** 
35c10 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 6d 70  This routine imp
35c20 6c 65 6d 65 6e 74 73 20 74 68 65 20 78 46 69 6e  lements the xFin
35c30 64 46 75 6e 63 74 69 6f 6e 20 6d 65 74 68 6f 64  dFunction method
35c40 20 66 6f 72 20 74 68 65 20 46 54 53 33 0a 2a 2a   for the FTS3.**
35c50 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a   virtual table..
35c60 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75  */.static int fu
35c70 6c 6c 74 65 78 74 46 69 6e 64 46 75 6e 63 74 69  lltextFindFuncti
35c80 6f 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  on(.  sqlite3_vt
35c90 61 62 20 2a 70 56 74 61 62 2c 0a 20 20 69 6e 74  ab *pVtab,.  int
35ca0 20 6e 41 72 67 2c 0a 20 20 63 6f 6e 73 74 20 63   nArg,.  const c
35cb0 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20 76 6f  har *zName,.  vo
35cc0 69 64 20 28 2a 2a 70 78 46 75 6e 63 29 28 73 71  id (**pxFunc)(sq
35cd0 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 2a 2c 69  lite3_context*,i
35ce0 6e 74 2c 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  nt,sqlite3_value
35cf0 2a 2a 29 2c 0a 20 20 76 6f 69 64 20 2a 2a 70 70  **),.  void **pp
35d00 41 72 67 0a 29 7b 0a 20 20 69 66 28 20 73 74 72  Arg.){.  if( str
35d10 63 6d 70 28 7a 4e 61 6d 65 2c 22 73 6e 69 70 70  cmp(zName,"snipp
35d20 65 74 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 2a  et")==0 ){.    *
35d30 70 78 46 75 6e 63 20 3d 20 73 6e 69 70 70 65 74  pxFunc = snippet
35d40 46 75 6e 63 3b 0a 20 20 20 20 72 65 74 75 72 6e  Func;.    return
35d50 20 31 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20   1;.  }else if( 
35d60 73 74 72 63 6d 70 28 7a 4e 61 6d 65 2c 22 6f 66  strcmp(zName,"of
35d70 66 73 65 74 73 22 29 3d 3d 30 20 29 7b 0a 20 20  fsets")==0 ){.  
35d80 20 20 2a 70 78 46 75 6e 63 20 3d 20 73 6e 69 70    *pxFunc = snip
35d90 70 65 74 4f 66 66 73 65 74 73 46 75 6e 63 3b 0a  petOffsetsFunc;.
35da0 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20      return 1;.  
35db0 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70  }else if( strcmp
35dc0 28 7a 4e 61 6d 65 2c 22 6f 70 74 69 6d 69 7a 65  (zName,"optimize
35dd0 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 2a 70 78  ")==0 ){.    *px
35de0 46 75 6e 63 20 3d 20 6f 70 74 69 6d 69 7a 65 46  Func = optimizeF
35df0 75 6e 63 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  unc;.    return 
35e00 31 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  1;.#ifdef SQLITE
35e10 5f 54 45 53 54 0a 20 20 20 20 2f 2a 20 4e 4f 54  _TEST.    /* NOT
35e20 45 28 73 68 65 73 73 29 3a 20 54 68 65 73 65 20  E(shess): These 
35e30 66 75 6e 63 74 69 6f 6e 73 20 61 72 65 20 70 72  functions are pr
35e40 65 73 65 6e 74 20 6f 6e 6c 79 20 66 6f 72 20 74  esent only for t
35e50 65 73 74 69 6e 67 0a 20 20 20 20 2a 2a 20 70 75  esting.    ** pu
35e60 72 70 6f 73 65 73 2e 20 20 4e 6f 20 70 61 72 74  rposes.  No part
35e70 69 63 75 6c 61 72 20 65 66 66 6f 72 74 20 69 73  icular effort is
35e80 20 6d 61 64 65 20 74 6f 20 6f 70 74 69 6d 69 7a   made to optimiz
35e90 65 20 74 68 65 69 72 0a 20 20 20 20 2a 2a 20 65  e their.    ** e
35ea0 78 65 63 75 74 69 6f 6e 20 6f 72 20 68 6f 77 20  xecution or how 
35eb0 74 68 65 79 20 62 75 69 6c 64 20 74 68 65 69 72  they build their
35ec0 20 72 65 73 75 6c 74 73 2e 0a 20 20 20 20 2a 2f   results..    */
35ed0 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72  .  }else if( str
35ee0 63 6d 70 28 7a 4e 61 6d 65 2c 22 64 75 6d 70 5f  cmp(zName,"dump_
35ef0 74 65 72 6d 73 22 29 3d 3d 30 20 29 7b 0a 20 20  terms")==0 ){.  
35f00 20 20 2f 2a 20 66 70 72 69 6e 74 66 28 73 74 64    /* fprintf(std
35f10 65 72 72 2c 20 22 46 6f 75 6e 64 20 64 75 6d 70  err, "Found dump
35f20 5f 74 65 72 6d 73 5c 6e 22 29 3b 20 2a 2f 0a 20  _terms\n"); */. 
35f30 20 20 20 2a 70 78 46 75 6e 63 20 3d 20 64 75 6d     *pxFunc = dum
35f40 70 54 65 72 6d 73 46 75 6e 63 3b 0a 20 20 20 20  pTermsFunc;.    
35f50 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 65 6c 73  return 1;.  }els
35f60 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 4e 61  e if( strcmp(zNa
35f70 6d 65 2c 22 64 75 6d 70 5f 64 6f 63 6c 69 73 74  me,"dump_doclist
35f80 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20  ")==0 ){.    /* 
35f90 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
35fa0 22 46 6f 75 6e 64 20 64 75 6d 70 5f 64 6f 63 6c  "Found dump_docl
35fb0 69 73 74 5c 6e 22 29 3b 20 2a 2f 0a 20 20 20 20  ist\n"); */.    
35fc0 2a 70 78 46 75 6e 63 20 3d 20 64 75 6d 70 44 6f  *pxFunc = dumpDo
35fd0 63 6c 69 73 74 46 75 6e 63 3b 0a 20 20 20 20 72  clistFunc;.    r
35fe0 65 74 75 72 6e 20 31 3b 0a 23 65 6e 64 69 66 0a  eturn 1;.#endif.
35ff0 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a    }.  return 0;.
36000 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6e 61 6d 65 20  }../*.** Rename 
36010 61 6e 20 66 74 73 33 20 74 61 62 6c 65 2e 0a 2a  an fts3 table..*
36020 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75 6c  /.static int ful
36030 6c 74 65 78 74 52 65 6e 61 6d 65 28 0a 20 20 73  ltextRename(.  s
36040 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
36050 61 62 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  ab,.  const char
36060 20 2a 7a 4e 61 6d 65 0a 29 7b 0a 20 20 66 75 6c   *zName.){.  ful
36070 6c 74 65 78 74 5f 76 74 61 62 20 2a 70 20 3d 20  ltext_vtab *p = 
36080 28 66 75 6c 6c 74 65 78 74 5f 76 74 61 62 20 2a  (fulltext_vtab *
36090 29 70 56 74 61 62 3b 0a 20 20 69 6e 74 20 72 63  )pVtab;.  int rc
360a0 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
360b0 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 20 3d 20  .  char *zSql = 
360c0 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
360d0 0a 20 20 20 20 22 41 4c 54 45 52 20 54 41 42 4c  .    "ALTER TABL
360e0 45 20 25 51 2e 27 25 71 5f 63 6f 6e 74 65 6e 74  E %Q.'%q_content
360f0 27 20 20 52 45 4e 41 4d 45 20 54 4f 20 27 25 71  '  RENAME TO '%q
36100 5f 63 6f 6e 74 65 6e 74 27 3b 22 0a 20 20 20 20  _content';".    
36110 22 41 4c 54 45 52 20 54 41 42 4c 45 20 25 51 2e  "ALTER TABLE %Q.
36120 27 25 71 5f 73 65 67 6d 65 6e 74 73 27 20 52 45  '%q_segments' RE
36130 4e 41 4d 45 20 54 4f 20 27 25 71 5f 73 65 67 6d  NAME TO '%q_segm
36140 65 6e 74 73 27 3b 22 0a 20 20 20 20 22 41 4c 54  ents';".    "ALT
36150 45 52 20 54 41 42 4c 45 20 25 51 2e 27 25 71 5f  ER TABLE %Q.'%q_
36160 73 65 67 64 69 72 27 20 20 20 52 45 4e 41 4d 45  segdir'   RENAME
36170 20 54 4f 20 27 25 71 5f 73 65 67 64 69 72 27 3b   TO '%q_segdir';
36180 22 0a 20 20 20 20 2c 20 70 2d 3e 7a 44 62 2c 20  ".    , p->zDb, 
36190 70 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 20  p->zName, zName 
361a0 0a 20 20 20 20 2c 20 70 2d 3e 7a 44 62 2c 20 70  .    , p->zDb, p
361b0 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 20 0a  ->zName, zName .
361c0 20 20 20 20 2c 20 70 2d 3e 7a 44 62 2c 20 70 2d      , p->zDb, p-
361d0 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 0a 20 20  >zName, zName.  
361e0 29 3b 0a 20 20 69 66 28 20 7a 53 71 6c 20 29 7b  );.  if( zSql ){
361f0 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
36200 33 5f 65 78 65 63 28 70 2d 3e 64 62 2c 20 7a 53  3_exec(p->db, zS
36210 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20  ql, 0, 0, 0);.  
36220 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
36230 53 71 6c 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  Sql);.  }.  retu
36240 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
36250 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 6d   const sqlite3_m
36260 6f 64 75 6c 65 20 66 74 73 33 4d 6f 64 75 6c 65  odule fts3Module
36270 20 3d 20 7b 0a 20 20 2f 2a 20 69 56 65 72 73 69   = {.  /* iVersi
36280 6f 6e 20 20 20 20 20 20 2a 2f 20 30 2c 0a 20 20  on      */ 0,.  
36290 2f 2a 20 78 43 72 65 61 74 65 20 20 20 20 20 20  /* xCreate      
362a0 20 2a 2f 20 66 75 6c 6c 74 65 78 74 43 72 65 61   */ fulltextCrea
362b0 74 65 2c 0a 20 20 2f 2a 20 78 43 6f 6e 6e 65 63  te,.  /* xConnec
362c0 74 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65  t      */ fullte
362d0 78 74 43 6f 6e 6e 65 63 74 2c 0a 20 20 2f 2a 20  xtConnect,.  /* 
362e0 78 42 65 73 74 49 6e 64 65 78 20 20 20 20 2a 2f  xBestIndex    */
362f0 20 66 75 6c 6c 74 65 78 74 42 65 73 74 49 6e 64   fulltextBestInd
36300 65 78 2c 0a 20 20 2f 2a 20 78 44 69 73 63 6f 6e  ex,.  /* xDiscon
36310 6e 65 63 74 20 20 20 2a 2f 20 66 75 6c 6c 74 65  nect   */ fullte
36320 78 74 44 69 73 63 6f 6e 6e 65 63 74 2c 0a 20 20  xtDisconnect,.  
36330 2f 2a 20 78 44 65 73 74 72 6f 79 20 20 20 20 20  /* xDestroy     
36340 20 2a 2f 20 66 75 6c 6c 74 65 78 74 44 65 73 74   */ fulltextDest
36350 72 6f 79 2c 0a 20 20 2f 2a 20 78 4f 70 65 6e 20  roy,.  /* xOpen 
36360 20 20 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74          */ fullt
36370 65 78 74 4f 70 65 6e 2c 0a 20 20 2f 2a 20 78 43  extOpen,.  /* xC
36380 6c 6f 73 65 20 20 20 20 20 20 20 20 2a 2f 20 66  lose        */ f
36390 75 6c 6c 74 65 78 74 43 6c 6f 73 65 2c 0a 20 20  ulltextClose,.  
363a0 2f 2a 20 78 46 69 6c 74 65 72 20 20 20 20 20 20  /* xFilter      
363b0 20 2a 2f 20 66 75 6c 6c 74 65 78 74 46 69 6c 74   */ fulltextFilt
363c0 65 72 2c 0a 20 20 2f 2a 20 78 4e 65 78 74 20 20  er,.  /* xNext  
363d0 20 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65         */ fullte
363e0 78 74 4e 65 78 74 2c 0a 20 20 2f 2a 20 78 45 6f  xtNext,.  /* xEo
363f0 66 20 20 20 20 20 20 20 20 20 20 2a 2f 20 66 75  f          */ fu
36400 6c 6c 74 65 78 74 45 6f 66 2c 0a 20 20 2f 2a 20  lltextEof,.  /* 
36410 78 43 6f 6c 75 6d 6e 20 20 20 20 20 20 20 2a 2f  xColumn       */
36420 20 66 75 6c 6c 74 65 78 74 43 6f 6c 75 6d 6e 2c   fulltextColumn,
36430 0a 20 20 2f 2a 20 78 52 6f 77 69 64 20 20 20 20  .  /* xRowid    
36440 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74 52      */ fulltextR
36450 6f 77 69 64 2c 0a 20 20 2f 2a 20 78 55 70 64 61  owid,.  /* xUpda
36460 74 65 20 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c  te       */ full
36470 74 65 78 74 55 70 64 61 74 65 2c 0a 20 20 2f 2a  textUpdate,.  /*
36480 20 78 42 65 67 69 6e 20 20 20 20 20 20 20 20 2a   xBegin        *
36490 2f 20 66 75 6c 6c 74 65 78 74 42 65 67 69 6e 2c  / fulltextBegin,
364a0 0a 20 20 2f 2a 20 78 53 79 6e 63 20 20 20 20 20  .  /* xSync     
364b0 20 20 20 20 2a 2f 20 66 75 6c 6c 74 65 78 74 53      */ fulltextS
364c0 79 6e 63 2c 0a 20 20 2f 2a 20 78 43 6f 6d 6d 69  ync,.  /* xCommi
364d0 74 20 20 20 20 20 20 20 2a 2f 20 66 75 6c 6c 74  t       */ fullt
364e0 65 78 74 43 6f 6d 6d 69 74 2c 0a 20 20 2f 2a 20  extCommit,.  /* 
364f0 78 52 6f 6c 6c 62 61 63 6b 20 20 20 20 20 2a 2f  xRollback     */
36500 20 66 75 6c 6c 74 65 78 74 52 6f 6c 6c 62 61 63   fulltextRollbac
36510 6b 2c 0a 20 20 2f 2a 20 78 46 69 6e 64 46 75 6e  k,.  /* xFindFun
36520 63 74 69 6f 6e 20 2a 2f 20 66 75 6c 6c 74 65 78  ction */ fulltex
36530 74 46 69 6e 64 46 75 6e 63 74 69 6f 6e 2c 0a 20  tFindFunction,. 
36540 20 2f 2a 20 78 52 65 6e 61 6d 65 20 2a 2f 20 20   /* xRename */  
36550 20 20 20 20 20 66 75 6c 6c 74 65 78 74 52 65 6e       fulltextRen
36560 61 6d 65 2c 0a 7d 3b 0a 0a 73 74 61 74 69 63 20  ame,.};..static 
36570 76 6f 69 64 20 68 61 73 68 44 65 73 74 72 6f 79  void hashDestroy
36580 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 66 74 73  (void *p){.  fts
36590 33 48 61 73 68 20 2a 70 48 61 73 68 20 3d 20 28  3Hash *pHash = (
365a0 66 74 73 33 48 61 73 68 20 2a 29 70 3b 0a 20 20  fts3Hash *)p;.  
365b0 73 71 6c 69 74 65 33 46 74 73 33 48 61 73 68 43  sqlite3Fts3HashC
365c0 6c 65 61 72 28 70 48 61 73 68 29 3b 0a 20 20 73  lear(pHash);.  s
365d0 71 6c 69 74 65 33 5f 66 72 65 65 28 70 48 61 73  qlite3_free(pHas
365e0 68 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  h);.}../*.** The
365f0 20 66 74 73 33 20 62 75 69 6c 74 2d 69 6e 20 74   fts3 built-in t
36600 6f 6b 65 6e 69 7a 65 72 73 20 2d 20 22 73 69 6d  okenizers - "sim
36610 70 6c 65 22 20 61 6e 64 20 22 70 6f 72 74 65 72  ple" and "porter
36620 22 20 2d 20 61 72 65 20 69 6d 70 6c 65 6d 65 6e  " - are implemen
36630 74 65 64 0a 2a 2a 20 69 6e 20 66 69 6c 65 73 20  ted.** in files 
36640 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 31 2e  fts3_tokenizer1.
36650 63 20 61 6e 64 20 66 74 73 33 5f 70 6f 72 74 65  c and fts3_porte
36660 72 2e 63 20 72 65 73 70 65 63 74 69 76 65 6c 79  r.c respectively
36670 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a  . The following.
36680 2a 2a 20 74 77 6f 20 66 6f 72 77 61 72 64 20 64  ** two forward d
36690 65 63 6c 61 72 61 74 69 6f 6e 73 20 61 72 65 20  eclarations are 
366a0 66 6f 72 20 66 75 6e 63 74 69 6f 6e 73 20 64 65  for functions de
366b0 63 6c 61 72 65 64 20 69 6e 20 74 68 65 73 65 20  clared in these 
366c0 66 69 6c 65 73 0a 2a 2a 20 75 73 65 64 20 74 6f  files.** used to
366d0 20 72 65 74 72 69 65 76 65 20 74 68 65 20 72 65   retrieve the re
366e0 73 70 65 63 74 69 76 65 20 69 6d 70 6c 65 6d 65  spective impleme
366f0 6e 74 61 74 69 6f 6e 73 2e 0a 2a 2a 0a 2a 2a 20  ntations..**.** 
36700 43 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33 46  Calling sqlite3F
36710 74 73 33 53 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a  ts3SimpleTokeniz
36720 65 72 4d 6f 64 75 6c 65 28 29 20 73 65 74 73 20  erModule() sets 
36730 74 68 65 20 76 61 6c 75 65 20 70 6f 69 6e 74 65  the value pointe
36740 64 0a 2a 2a 20 74 6f 20 62 79 20 74 68 65 20 61  d.** to by the a
36750 72 67 75 6d 65 6e 74 20 74 6f 20 70 6f 69 6e 74  rgument to point
36760 20 61 20 74 68 65 20 22 73 69 6d 70 6c 65 22 20   a the "simple" 
36770 74 6f 6b 65 6e 69 7a 65 72 20 69 6d 70 6c 65 6d  tokenizer implem
36780 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2a 20 46 75 6e  entation..** Fun
36790 63 74 69 6f 6e 20 2e 2e 2e 50 6f 72 74 65 72 54  ction ...PorterT
367a0 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 28 29  okenizerModule()
367b0 20 73 65 74 73 20 2a 70 4d 6f 64 75 6c 65 20 74   sets *pModule t
367c0 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 0a 2a  o point to the.*
367d0 2a 20 70 6f 72 74 65 72 20 74 6f 6b 65 6e 69 7a  * porter tokeniz
367e0 65 72 2f 73 74 65 6d 6d 65 72 20 69 6d 70 6c 65  er/stemmer imple
367f0 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 76 6f  mentation..*/.vo
36800 69 64 20 73 71 6c 69 74 65 33 46 74 73 33 53 69  id sqlite3Fts3Si
36810 6d 70 6c 65 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64  mpleTokenizerMod
36820 75 6c 65 28 73 71 6c 69 74 65 33 5f 74 6f 6b 65  ule(sqlite3_toke
36830 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 63 6f 6e  nizer_module con
36840 73 74 2a 2a 70 70 4d 6f 64 75 6c 65 29 3b 0a 76  st**ppModule);.v
36850 6f 69 64 20 73 71 6c 69 74 65 33 46 74 73 33 50  oid sqlite3Fts3P
36860 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 4d 6f  orterTokenizerMo
36870 64 75 6c 65 28 73 71 6c 69 74 65 33 5f 74 6f 6b  dule(sqlite3_tok
36880 65 6e 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 63 6f  enizer_module co
36890 6e 73 74 2a 2a 70 70 4d 6f 64 75 6c 65 29 3b 0a  nst**ppModule);.
368a0 76 6f 69 64 20 73 71 6c 69 74 65 33 46 74 73 33  void sqlite3Fts3
368b0 49 63 75 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  IcuTokenizerModu
368c0 6c 65 28 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e  le(sqlite3_token
368d0 69 7a 65 72 5f 6d 6f 64 75 6c 65 20 63 6f 6e 73  izer_module cons
368e0 74 2a 2a 70 70 4d 6f 64 75 6c 65 29 3b 0a 0a 69  t**ppModule);..i
368f0 6e 74 20 73 71 6c 69 74 65 33 46 74 73 33 49 6e  nt sqlite3Fts3In
36900 69 74 48 61 73 68 54 61 62 6c 65 28 73 71 6c 69  itHashTable(sqli
36910 74 65 33 20 2a 2c 20 66 74 73 33 48 61 73 68 20  te3 *, fts3Hash 
36920 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 29  *, const char *)
36930 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c  ;../*.** Initial
36940 69 73 65 20 74 68 65 20 66 74 73 33 20 65 78 74  ise the fts3 ext
36950 65 6e 73 69 6f 6e 2e 20 49 66 20 74 68 69 73 20  ension. If this 
36960 65 78 74 65 6e 73 69 6f 6e 20 69 73 20 62 75 69  extension is bui
36970 6c 74 20 61 73 20 70 61 72 74 0a 2a 2a 20 6f 66  lt as part.** of
36980 20 74 68 65 20 73 71 6c 69 74 65 20 6c 69 62 72   the sqlite libr
36990 61 72 79 2c 20 74 68 65 6e 20 74 68 69 73 20 66  ary, then this f
369a0 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
369b0 64 20 64 69 72 65 63 74 6c 79 20 62 79 0a 2a 2a  d directly by.**
369c0 20 53 51 4c 69 74 65 2e 20 49 66 20 66 74 73 33   SQLite. If fts3
369d0 20 69 73 20 62 75 69 6c 74 20 61 73 20 61 20 64   is built as a d
369e0 79 6e 61 6d 69 63 61 6c 6c 79 20 6c 6f 61 64 61  ynamically loada
369f0 62 6c 65 20 65 78 74 65 6e 73 69 6f 6e 2c 20 74  ble extension, t
36a00 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20  his.** function 
36a10 69 73 20 63 61 6c 6c 65 64 20 62 79 20 74 68 65  is called by the
36a20 20 73 71 6c 69 74 65 33 5f 65 78 74 65 6e 73 69   sqlite3_extensi
36a30 6f 6e 5f 69 6e 69 74 28 29 20 65 6e 74 72 79 20  on_init() entry 
36a40 70 6f 69 6e 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71  point..*/.int sq
36a50 6c 69 74 65 33 46 74 73 33 49 6e 69 74 28 73 71  lite3Fts3Init(sq
36a60 6c 69 74 65 33 20 2a 64 62 29 7b 0a 20 20 69 6e  lite3 *db){.  in
36a70 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
36a80 3b 0a 20 20 66 74 73 33 48 61 73 68 20 2a 70 48  ;.  fts3Hash *pH
36a90 61 73 68 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74  ash = 0;.  const
36aa0 20 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a   sqlite3_tokeniz
36ab0 65 72 5f 6d 6f 64 75 6c 65 20 2a 70 53 69 6d 70  er_module *pSimp
36ac0 6c 65 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20  le = 0;.  const 
36ad0 73 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65  sqlite3_tokenize
36ae0 72 5f 6d 6f 64 75 6c 65 20 2a 70 50 6f 72 74 65  r_module *pPorte
36af0 72 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20 73  r = 0;.  const s
36b00 71 6c 69 74 65 33 5f 74 6f 6b 65 6e 69 7a 65 72  qlite3_tokenizer
36b10 5f 6d 6f 64 75 6c 65 20 2a 70 49 63 75 20 3d 20  _module *pIcu = 
36b20 30 3b 0a 0a 20 20 73 71 6c 69 74 65 33 46 74 73  0;..  sqlite3Fts
36b30 33 53 69 6d 70 6c 65 54 6f 6b 65 6e 69 7a 65 72  3SimpleTokenizer
36b40 4d 6f 64 75 6c 65 28 26 70 53 69 6d 70 6c 65 29  Module(&pSimple)
36b50 3b 0a 20 20 73 71 6c 69 74 65 33 46 74 73 33 50  ;.  sqlite3Fts3P
36b60 6f 72 74 65 72 54 6f 6b 65 6e 69 7a 65 72 4d 6f  orterTokenizerMo
36b70 64 75 6c 65 28 26 70 50 6f 72 74 65 72 29 3b 0a  dule(&pPorter);.
36b80 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
36b90 41 42 4c 45 5f 49 43 55 0a 20 20 73 71 6c 69 74  ABLE_ICU.  sqlit
36ba0 65 33 46 74 73 33 49 63 75 54 6f 6b 65 6e 69 7a  e3Fts3IcuTokeniz
36bb0 65 72 4d 6f 64 75 6c 65 28 26 70 49 63 75 29 3b  erModule(&pIcu);
36bc0 0a 23 65 6e 64 69 66 0a 0a 20 20 2f 2a 20 41 6c  .#endif..  /* Al
36bd0 6c 6f 63 61 74 65 20 61 6e 64 20 69 6e 69 74 69  locate and initi
36be0 61 6c 69 73 65 20 74 68 65 20 68 61 73 68 2d 74  alise the hash-t
36bf0 61 62 6c 65 20 75 73 65 64 20 74 6f 20 73 74 6f  able used to sto
36c00 72 65 20 74 6f 6b 65 6e 69 7a 65 72 73 2e 20 2a  re tokenizers. *
36c10 2f 0a 20 20 70 48 61 73 68 20 3d 20 73 71 6c 69  /.  pHash = sqli
36c20 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
36c30 66 28 66 74 73 33 48 61 73 68 29 29 3b 0a 20 20  f(fts3Hash));.  
36c40 69 66 28 20 21 70 48 61 73 68 20 29 7b 0a 20 20  if( !pHash ){.  
36c50 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
36c60 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  MEM;.  }else{.  
36c70 20 20 73 71 6c 69 74 65 33 46 74 73 33 48 61 73    sqlite3Fts3Has
36c80 68 49 6e 69 74 28 70 48 61 73 68 2c 20 46 54 53  hInit(pHash, FTS
36c90 33 5f 48 41 53 48 5f 53 54 52 49 4e 47 2c 20 31  3_HASH_STRING, 1
36ca0 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4c 6f 61  );.  }..  /* Loa
36cb0 64 20 74 68 65 20 62 75 69 6c 74 2d 69 6e 20 74  d the built-in t
36cc0 6f 6b 65 6e 69 7a 65 72 73 20 69 6e 74 6f 20 74  okenizers into t
36cd0 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f  he hash table */
36ce0 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
36cf0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 66 28 20  E_OK ){.    if( 
36d00 73 71 6c 69 74 65 33 46 74 73 33 48 61 73 68 49  sqlite3Fts3HashI
36d10 6e 73 65 72 74 28 70 48 61 73 68 2c 20 22 73 69  nsert(pHash, "si
36d20 6d 70 6c 65 22 2c 20 37 2c 20 28 76 6f 69 64 20  mple", 7, (void 
36d30 2a 29 70 53 69 6d 70 6c 65 29 0a 20 20 20 20 20  *)pSimple).     
36d40 7c 7c 20 73 71 6c 69 74 65 33 46 74 73 33 48 61  || sqlite3Fts3Ha
36d50 73 68 49 6e 73 65 72 74 28 70 48 61 73 68 2c 20  shInsert(pHash, 
36d60 22 70 6f 72 74 65 72 22 2c 20 37 2c 20 28 76 6f  "porter", 7, (vo
36d70 69 64 20 2a 29 70 50 6f 72 74 65 72 29 20 0a 20  id *)pPorter) . 
36d80 20 20 20 20 7c 7c 20 28 70 49 63 75 20 26 26 20      || (pIcu && 
36d90 73 71 6c 69 74 65 33 46 74 73 33 48 61 73 68 49  sqlite3Fts3HashI
36da0 6e 73 65 72 74 28 70 48 61 73 68 2c 20 22 69 63  nsert(pHash, "ic
36db0 75 22 2c 20 34 2c 20 28 76 6f 69 64 20 2a 29 70  u", 4, (void *)p
36dc0 49 63 75 29 29 0a 20 20 20 20 29 7b 0a 20 20 20  Icu)).    ){.   
36dd0 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
36de0 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  OMEM;.    }.  }.
36df0 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54  .#ifdef SQLITE_T
36e00 45 53 54 0a 20 20 73 71 6c 69 74 65 33 46 74 73  EST.  sqlite3Fts
36e10 33 45 78 70 72 49 6e 69 74 54 65 73 74 49 6e 74  3ExprInitTestInt
36e20 65 72 66 61 63 65 28 64 62 29 3b 0a 23 65 6e 64  erface(db);.#end
36e30 69 66 0a 0a 20 20 2f 2a 20 43 72 65 61 74 65 20  if..  /* Create 
36e40 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c  the virtual tabl
36e50 65 20 77 72 61 70 70 65 72 20 61 72 6f 75 6e 64  e wrapper around
36e60 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65 20   the hash-table 
36e70 61 6e 64 20 6f 76 65 72 6c 6f 61 64 20 0a 20 20  and overload .  
36e80 2a 2a 20 74 68 65 20 74 77 6f 20 73 63 61 6c 61  ** the two scala
36e90 72 20 66 75 6e 63 74 69 6f 6e 73 2e 20 49 66 20  r functions. If 
36ea0 74 68 69 73 20 69 73 20 73 75 63 63 65 73 73 66  this is successf
36eb0 75 6c 2c 20 72 65 67 69 73 74 65 72 20 74 68 65  ul, register the
36ec0 0a 20 20 2a 2a 20 6d 6f 64 75 6c 65 20 77 69 74  .  ** module wit
36ed0 68 20 73 71 6c 69 74 65 2e 0a 20 20 2a 2f 0a 20  h sqlite..  */. 
36ee0 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d   if( SQLITE_OK==
36ef0 72 63 20 0a 20 20 20 26 26 20 53 51 4c 49 54 45  rc .   && SQLITE
36f00 5f 4f 4b 3d 3d 28 72 63 20 3d 20 73 71 6c 69 74  _OK==(rc = sqlit
36f10 65 33 46 74 73 33 49 6e 69 74 48 61 73 68 54 61  e3Fts3InitHashTa
36f20 62 6c 65 28 64 62 2c 20 70 48 61 73 68 2c 20 22  ble(db, pHash, "
36f30 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65 72 22 29  fts3_tokenizer")
36f40 29 0a 20 20 20 26 26 20 53 51 4c 49 54 45 5f 4f  ).   && SQLITE_O
36f50 4b 3d 3d 28 72 63 20 3d 20 73 71 6c 69 74 65 33  K==(rc = sqlite3
36f60 5f 6f 76 65 72 6c 6f 61 64 5f 66 75 6e 63 74 69  _overload_functi
36f70 6f 6e 28 64 62 2c 20 22 73 6e 69 70 70 65 74 22  on(db, "snippet"
36f80 2c 20 2d 31 29 29 0a 20 20 20 26 26 20 53 51 4c  , -1)).   && SQL
36f90 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 73 71  ITE_OK==(rc = sq
36fa0 6c 69 74 65 33 5f 6f 76 65 72 6c 6f 61 64 5f 66  lite3_overload_f
36fb0 75 6e 63 74 69 6f 6e 28 64 62 2c 20 22 6f 66 66  unction(db, "off
36fc0 73 65 74 73 22 2c 20 2d 31 29 29 0a 20 20 20 26  sets", -1)).   &
36fd0 26 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63  & SQLITE_OK==(rc
36fe0 20 3d 20 73 71 6c 69 74 65 33 5f 6f 76 65 72 6c   = sqlite3_overl
36ff0 6f 61 64 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c  oad_function(db,
37000 20 22 6f 70 74 69 6d 69 7a 65 22 2c 20 2d 31 29   "optimize", -1)
37010 29 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ).#ifdef SQLITE_
37020 54 45 53 54 0a 20 20 20 26 26 20 53 51 4c 49 54  TEST.   && SQLIT
37030 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 73 71 6c 69  E_OK==(rc = sqli
37040 74 65 33 5f 6f 76 65 72 6c 6f 61 64 5f 66 75 6e  te3_overload_fun
37050 63 74 69 6f 6e 28 64 62 2c 20 22 64 75 6d 70 5f  ction(db, "dump_
37060 74 65 72 6d 73 22 2c 20 2d 31 29 29 0a 20 20 20  terms", -1)).   
37070 26 26 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72  && SQLITE_OK==(r
37080 63 20 3d 20 73 71 6c 69 74 65 33 5f 6f 76 65 72  c = sqlite3_over
37090 6c 6f 61 64 5f 66 75 6e 63 74 69 6f 6e 28 64 62  load_function(db
370a0 2c 20 22 64 75 6d 70 5f 64 6f 63 6c 69 73 74 22  , "dump_doclist"
370b0 2c 20 2d 31 29 29 0a 23 65 6e 64 69 66 0a 20 20  , -1)).#endif.  
370c0 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 73 71  ){.    return sq
370d0 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64  lite3_create_mod
370e0 75 6c 65 5f 76 32 28 0a 20 20 20 20 20 20 20 20  ule_v2(.        
370f0 64 62 2c 20 22 66 74 73 33 22 2c 20 26 66 74 73  db, "fts3", &fts
37100 33 4d 6f 64 75 6c 65 2c 20 28 76 6f 69 64 20 2a  3Module, (void *
37110 29 70 48 61 73 68 2c 20 68 61 73 68 44 65 73 74  )pHash, hashDest
37120 72 6f 79 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a  roy.    );.  }..
37130 20 20 2f 2a 20 41 6e 20 65 72 72 6f 72 20 68 61    /* An error ha
37140 73 20 6f 63 63 75 72 72 65 64 2e 20 44 65 6c 65  s occurred. Dele
37150 74 65 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  te the hash tabl
37160 65 20 61 6e 64 20 72 65 74 75 72 6e 20 74 68 65  e and return the
37170 20 65 72 72 6f 72 20 63 6f 64 65 2e 20 2a 2f 0a   error code. */.
37180 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51    assert( rc!=SQ
37190 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 69 66 28  LITE_OK );.  if(
371a0 20 70 48 61 73 68 20 29 7b 0a 20 20 20 20 73 71   pHash ){.    sq
371b0 6c 69 74 65 33 46 74 73 33 48 61 73 68 43 6c 65  lite3Fts3HashCle
371c0 61 72 28 70 48 61 73 68 29 3b 0a 20 20 20 20 73  ar(pHash);.    s
371d0 71 6c 69 74 65 33 5f 66 72 65 65 28 70 48 61 73  qlite3_free(pHas
371e0 68 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  h);.  }.  return
371f0 20 72 63 3b 0a 7d 0a 0a 23 69 66 20 21 53 51 4c   rc;.}..#if !SQL
37200 49 54 45 5f 43 4f 52 45 0a 69 6e 74 20 73 71 6c  ITE_CORE.int sql
37210 69 74 65 33 5f 65 78 74 65 6e 73 69 6f 6e 5f 69  ite3_extension_i
37220 6e 69 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  nit(.  sqlite3 *
37230 64 62 2c 20 0a 20 20 63 68 61 72 20 2a 2a 70 7a  db, .  char **pz
37240 45 72 72 4d 73 67 2c 0a 20 20 63 6f 6e 73 74 20  ErrMsg,.  const 
37250 73 71 6c 69 74 65 33 5f 61 70 69 5f 72 6f 75 74  sqlite3_api_rout
37260 69 6e 65 73 20 2a 70 41 70 69 0a 29 7b 0a 20 20  ines *pApi.){.  
37270 53 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e  SQLITE_EXTENSION
37280 5f 49 4e 49 54 32 28 70 41 70 69 29 0a 20 20 72  _INIT2(pApi).  r
37290 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73  eturn sqlite3Fts
372a0 33 49 6e 69 74 28 64 62 29 3b 0a 7d 0a 23 65 6e  3Init(db);.}.#en
372b0 64 69 66 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 21  dif..#endif /* !
372c0 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 43  defined(SQLITE_C
372d0 4f 52 45 29 20 7c 7c 20 64 65 66 69 6e 65 64 28  ORE) || defined(
372e0 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54  SQLITE_ENABLE_FT
372f0 53 33 29 20 2a 2f 0a                             S3) */.