/ Hex Artifact Content
Login

Artifact dffad248f9ce090800e272017d2898005c28ee6314fc1dd5550643a02666907a:


0000: 23 20 32 30 30 39 20 4e 6f 76 65 6d 62 65 72 20  # 2009 November 
0010: 30 34 0a 23 0a 23 20 54 68 65 20 61 75 74 68 6f  04.#.# The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 23 20 61 20 6c 65 67 61  lace of.# a lega
0060: 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20 69  l notice, here i
0070: 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 23 0a  s a blessing:.#.
0080: 23 20 20 20 20 4d 61 79 20 79 6f 75 20 64 6f 20  #    May you do 
0090: 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20 65 76 69  good and not evi
00a0: 6c 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20  l..#    May you 
00b0: 66 69 6e 64 20 66 6f 72 67 69 76 65 6e 65 73 73  find forgiveness
00c0: 20 66 6f 72 20 79 6f 75 72 73 65 6c 66 20 61 6e   for yourself an
00d0: 64 20 66 6f 72 67 69 76 65 20 6f 74 68 65 72 73  d forgive others
00e0: 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20 73  ..#    May you s
00f0: 68 61 72 65 20 66 72 65 65 6c 79 2c 20 6e 65 76  hare freely, nev
0100: 65 72 20 74 61 6b 69 6e 67 20 6d 6f 72 65 20 74  er taking more t
0110: 68 61 6e 20 79 6f 75 20 67 69 76 65 2e 0a 23 0a  han you give..#.
0120: 23 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  #***************
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 0a 23 0a 23 20 54 68 69  ********.#.# Thi
0170: 73 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20  s file contains 
0180: 63 6f 6d 6d 6f 6e 20 63 6f 64 65 20 75 73 65 64  common code used
0190: 20 74 68 65 20 66 74 73 33 20 74 65 73 74 73 2e   the fts3 tests.
01a0: 20 41 74 20 6f 6e 65 20 70 6f 69 6e 74 0a 23 20   At one point.# 
01b0: 65 71 75 69 76 61 6c 65 6e 74 20 66 75 6e 63 74  equivalent funct
01c0: 69 6f 6e 61 6c 69 74 79 20 77 61 73 20 69 6d 70  ionality was imp
01d0: 6c 65 6d 65 6e 74 65 64 20 69 6e 20 43 20 63 6f  lemented in C co
01e0: 64 65 2e 20 42 75 74 20 69 74 20 69 73 20 65 61  de. But it is ea
01f0: 73 69 65 72 0a 23 20 74 6f 20 75 73 65 20 54 63  sier.# to use Tc
0200: 6c 2e 0a 23 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  l..#..#---------
0210: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0220: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0230: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0240: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0250: 0a 23 20 49 4e 53 54 52 55 43 54 49 4f 4e 53 0a  .# INSTRUCTIONS.
0260: 23 0a 23 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e  #.# The followin
0270: 67 20 63 6f 6d 6d 61 6e 64 73 20 61 72 65 20 61  g commands are a
0280: 76 61 69 6c 61 62 6c 65 3a 0a 23 0a 23 20 20 20  vailable:.#.#   
0290: 66 74 73 33 5f 62 75 69 6c 64 5f 64 62 5f 31 20  fts3_build_db_1 
02a0: 4e 0a 23 20 20 20 20 20 55 73 69 6e 67 20 64 61  N.#     Using da
02b0: 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 5b 64  tabase handle [d
02c0: 62 5d 20 63 72 65 61 74 65 20 61 6e 20 46 54 53  b] create an FTS
02d0: 34 20 74 61 62 6c 65 20 6e 61 6d 65 64 20 74 31  4 table named t1
02e0: 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 0a 23 20   and populate.# 
02f0: 20 20 20 20 69 74 20 77 69 74 68 20 4e 20 72 6f      it with N ro
0300: 77 73 20 6f 66 20 64 61 74 61 2e 20 4e 20 6d 75  ws of data. N mu
0310: 73 74 20 62 65 20 6c 65 73 73 20 74 68 61 6e 20  st be less than 
0320: 31 30 2c 30 30 30 2e 20 52 65 66 65 72 20 74 6f  10,000. Refer to
0330: 20 74 68 65 0a 23 20 20 20 20 20 68 65 61 64 65   the.#     heade
0340: 72 20 63 6f 6d 6d 65 6e 74 73 20 61 62 6f 76 65  r comments above
0350: 20 74 68 65 20 70 72 6f 63 20 69 6d 70 6c 65 6d   the proc implem
0360: 65 6e 74 61 74 69 6f 6e 20 62 65 6c 6f 77 20 66  entation below f
0370: 6f 72 20 64 65 74 61 69 6c 73 2e 0a 23 0a 23 20  or details..#.# 
0380: 20 20 66 74 73 33 5f 62 75 69 6c 64 5f 64 62 5f    fts3_build_db_
0390: 32 20 4e 0a 23 20 20 20 20 20 55 73 69 6e 67 20  2 N.#     Using 
03a0: 64 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20  database handle 
03b0: 5b 64 62 5d 20 63 72 65 61 74 65 20 61 6e 20 46  [db] create an F
03c0: 54 53 34 20 74 61 62 6c 65 20 6e 61 6d 65 64 20  TS4 table named 
03d0: 74 32 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 0a  t2 and populate.
03e0: 23 20 20 20 20 20 69 74 20 77 69 74 68 20 4e 20  #     it with N 
03f0: 72 6f 77 73 20 6f 66 20 64 61 74 61 2e 20 4e 20  rows of data. N 
0400: 6d 75 73 74 20 62 65 20 6c 65 73 73 20 74 68 61  must be less tha
0410: 6e 20 31 30 30 2c 30 30 30 2e 20 52 65 66 65 72  n 100,000. Refer
0420: 20 74 6f 20 74 68 65 0a 23 20 20 20 20 20 68 65   to the.#     he
0430: 61 64 65 72 20 63 6f 6d 6d 65 6e 74 73 20 61 62  ader comments ab
0440: 6f 76 65 20 74 68 65 20 70 72 6f 63 20 69 6d 70  ove the proc imp
0450: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 62 65 6c 6f  lementation belo
0460: 77 20 66 6f 72 20 64 65 74 61 69 6c 73 2e 0a 23  w for details..#
0470: 0a 23 20 20 20 66 74 73 33 5f 69 6e 74 65 67 72  .#   fts3_integr
0480: 69 74 79 5f 63 68 65 63 6b 20 54 42 4c 0a 23 20  ity_check TBL.# 
0490: 20 20 20 20 54 42 4c 20 6d 75 73 74 20 62 65 20      TBL must be 
04a0: 61 6e 20 46 54 53 20 74 61 62 6c 65 20 69 6e 20  an FTS table in 
04b0: 74 68 65 20 64 61 74 61 62 61 73 65 20 63 75 72  the database cur
04c0: 72 65 6e 74 6c 79 20 6f 70 65 6e 65 64 20 62 79  rently opened by
04d0: 20 68 61 6e 64 6c 65 0a 23 20 20 20 20 20 5b 64   handle.#     [d
04e0: 62 5d 2e 20 54 68 69 73 20 70 72 6f 63 20 6c 6f  b]. This proc lo
04f0: 61 64 73 20 61 6e 64 20 74 6f 6b 65 6e 69 7a 65  ads and tokenize
0500: 73 20 61 6c 6c 20 64 6f 63 75 6d 65 6e 74 73 20  s all documents 
0510: 77 69 74 68 69 6e 20 74 68 65 20 74 61 62 6c 65  within the table
0520: 2c 0a 23 20 20 20 20 20 74 68 65 6e 20 63 68 65  ,.#     then che
0530: 63 6b 73 20 74 68 61 74 20 74 68 65 20 63 75 72  cks that the cur
0540: 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73 20 6f 66  rent contents of
0550: 20 74 68 65 20 46 54 53 20 69 6e 64 65 78 20 6d   the FTS index m
0560: 61 74 63 68 65 73 20 74 68 65 0a 23 20 20 20 20  atches the.#    
0570: 20 72 65 73 75 6c 74 73 2e 0a 23 0a 23 20 20 20   results..#.#   
0580: 66 74 73 33 5f 74 65 72 6d 73 20 54 42 4c 20 57  fts3_terms TBL W
0590: 48 45 52 45 0a 23 20 20 20 20 20 54 6f 64 6f 2e  HERE.#     Todo.
05a0: 0a 23 0a 23 20 20 20 66 74 73 33 5f 64 6f 63 6c  .#.#   fts3_docl
05b0: 69 73 74 20 54 42 4c 20 54 45 52 4d 20 57 48 45  ist TBL TERM WHE
05c0: 52 45 0a 23 20 20 20 20 20 54 6f 64 6f 2e 0a 23  RE.#     Todo..#
05d0: 0a 23 0a 23 0a 0a 69 66 63 61 70 61 62 6c 65 20  .#.#..ifcapable 
05e0: 66 74 73 33 20 7b 0a 20 20 73 71 6c 69 74 65 33  fts3 {.  sqlite3
05f0: 5f 66 74 73 33 5f 6d 61 79 5f 62 65 5f 63 6f 72  _fts3_may_be_cor
0600: 72 75 70 74 20 30 20 0a 7d 0a 0a 23 2d 2d 2d 2d  rupt 0 .}..#----
0610: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0620: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0630: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0640: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0650: 2d 2d 2d 2d 2d 0a 23 20 55 53 41 47 45 3a 20 66  -----.# USAGE: f
0660: 74 73 33 5f 62 75 69 6c 64 5f 64 62 5f 31 20 53  ts3_build_db_1 S
0670: 57 49 54 43 48 45 53 20 4e 0a 23 0a 23 20 42 75  WITCHES N.#.# Bu
0680: 69 6c 64 20 61 20 73 61 6d 70 6c 65 20 46 54 53  ild a sample FTS
0690: 20 74 61 62 6c 65 20 69 6e 20 74 68 65 20 64 61   table in the da
06a0: 74 61 62 61 73 65 20 6f 70 65 6e 65 64 20 62 79  tabase opened by
06b0: 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63   database connec
06c0: 74 69 6f 6e 20 0a 23 20 5b 64 62 5d 2e 20 54 68  tion .# [db]. Th
06d0: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 6e 65  e name of the ne
06e0: 77 20 74 61 62 6c 65 20 69 73 20 22 74 31 22 2e  w table is "t1".
06f0: 0a 23 0a 70 72 6f 63 20 66 74 73 33 5f 62 75 69  .#.proc fts3_bui
0700: 6c 64 5f 64 62 5f 31 20 7b 61 72 67 73 7d 20 7b  ld_db_1 {args} {
0710: 0a 0a 20 20 73 65 74 20 64 65 66 61 75 6c 74 28  ..  set default(
0720: 2d 6d 6f 64 75 6c 65 29 20 66 74 73 34 0a 0a 20  -module) fts4.. 
0730: 20 73 65 74 20 6e 41 72 67 20 5b 6c 6c 65 6e 67   set nArg [lleng
0740: 74 68 20 24 61 72 67 73 5d 0a 20 20 69 66 20 7b  th $args].  if {
0750: 28 24 6e 41 72 67 25 32 29 3d 3d 30 7d 20 7b 0a  ($nArg%2)==0} {.
0760: 20 20 20 20 65 72 72 6f 72 20 22 77 72 6f 6e 67      error "wrong
0770: 20 23 20 61 72 67 73 3a 20 73 68 6f 75 6c 64 20   # args: should 
0780: 62 65 20 5c 22 66 74 73 33 5f 62 75 69 6c 64 5f  be \"fts3_build_
0790: 64 62 5f 31 20 3f 73 77 69 74 63 68 65 73 3f 20  db_1 ?switches? 
07a0: 6e 5c 22 22 0a 20 20 7d 0a 0a 20 20 73 65 74 20  n\"".  }..  set 
07b0: 6e 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20  n [lindex $args 
07c0: 5b 65 78 70 72 20 24 6e 41 72 67 2d 31 5d 5d 0a  [expr $nArg-1]].
07d0: 20 20 61 72 72 61 79 20 73 65 74 20 6f 70 74 73    array set opts
07e0: 20 5b 61 72 72 61 79 20 67 65 74 20 64 65 66 61   [array get defa
07f0: 75 6c 74 5d 0a 20 20 61 72 72 61 79 20 73 65 74  ult].  array set
0800: 20 6f 70 74 73 20 5b 6c 72 61 6e 67 65 20 24 61   opts [lrange $a
0810: 72 67 73 20 30 20 5b 65 78 70 72 20 24 6e 41 72  rgs 0 [expr $nAr
0820: 67 2d 32 5d 5d 0a 20 20 66 6f 72 65 61 63 68 20  g-2]].  foreach 
0830: 6b 20 5b 61 72 72 61 79 20 6e 61 6d 65 73 20 6f  k [array names o
0840: 70 74 73 5d 20 7b 0a 20 20 20 20 69 66 20 7b 30  pts] {.    if {0
0850: 3d 3d 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 64  ==[info exists d
0860: 65 66 61 75 6c 74 28 24 6b 29 5d 7d 20 7b 20 65  efault($k)]} { e
0870: 72 72 6f 72 20 22 75 6e 6b 6e 6f 77 6e 20 6f 70  rror "unknown op
0880: 74 69 6f 6e 3a 20 24 6b 22 20 7d 0a 20 20 7d 0a  tion: $k" }.  }.
0890: 0a 20 20 69 66 20 7b 24 6e 20 3e 20 31 30 30 30  .  if {$n > 1000
08a0: 30 7d 20 7b 65 72 72 6f 72 20 22 6e 20 6d 75 73  0} {error "n mus
08b0: 74 20 62 65 20 3c 3d 20 31 30 30 30 30 22 7d 0a  t be <= 10000"}.
08c0: 20 20 64 62 20 65 76 61 6c 20 22 43 52 45 41 54    db eval "CREAT
08d0: 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20  E VIRTUAL TABLE 
08e0: 74 31 20 55 53 49 4e 47 20 24 6f 70 74 73 28 2d  t1 USING $opts(-
08f0: 6d 6f 64 75 6c 65 29 20 28 78 2c 20 79 29 22 0a  module) (x, y)".
0900: 0a 20 20 73 65 74 20 78 77 6f 72 64 73 20 5b 6c  .  set xwords [l
0910: 69 73 74 20 7a 65 72 6f 20 6f 6e 65 20 74 77 6f  ist zero one two
0920: 20 74 68 72 65 65 20 66 6f 75 72 20 66 69 76 65   three four five
0930: 20 73 69 78 20 73 65 76 65 6e 20 65 69 67 68 74   six seven eight
0940: 20 6e 69 6e 65 20 74 65 6e 5d 0a 20 20 73 65 74   nine ten].  set
0950: 20 79 77 6f 72 64 73 20 5b 6c 69 73 74 20 61 6c   ywords [list al
0960: 70 68 61 20 62 65 74 61 20 67 61 6d 6d 61 20 64  pha beta gamma d
0970: 65 6c 74 61 20 65 70 73 69 6c 6f 6e 20 7a 65 74  elta epsilon zet
0980: 61 20 65 74 61 20 74 68 65 74 61 20 69 6f 74 61  a eta theta iota
0990: 20 6b 61 70 70 61 5d 0a 0a 20 20 66 6f 72 20 7b   kappa]..  for {
09a0: 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 24  set i 0} {$i < $
09b0: 6e 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  n} {incr i} {.  
09c0: 20 20 73 65 74 20 78 20 22 22 0a 20 20 20 20 73    set x "".    s
09d0: 65 74 20 79 20 22 22 0a 0a 20 20 20 20 73 65 74  et y ""..    set
09e0: 20 78 20 5b 6c 69 73 74 5d 0a 20 20 20 20 6c 61   x [list].    la
09f0: 70 70 65 6e 64 20 78 20 5b 6c 69 6e 64 65 78 20  ppend x [lindex 
0a00: 24 78 77 6f 72 64 73 20 5b 65 78 70 72 20 28 24  $xwords [expr ($
0a10: 69 20 2f 20 31 30 30 30 29 20 25 20 31 30 5d 5d  i / 1000) % 10]]
0a20: 0a 20 20 20 20 6c 61 70 70 65 6e 64 20 78 20 5b  .    lappend x [
0a30: 6c 69 6e 64 65 78 20 24 78 77 6f 72 64 73 20 5b  lindex $xwords [
0a40: 65 78 70 72 20 28 24 69 20 2f 20 31 30 30 29 20  expr ($i / 100) 
0a50: 20 25 20 31 30 5d 5d 0a 20 20 20 20 6c 61 70 70   % 10]].    lapp
0a60: 65 6e 64 20 78 20 5b 6c 69 6e 64 65 78 20 24 78  end x [lindex $x
0a70: 77 6f 72 64 73 20 5b 65 78 70 72 20 28 24 69 20  words [expr ($i 
0a80: 2f 20 31 30 29 20 20 20 25 20 31 30 5d 5d 0a 20  / 10)   % 10]]. 
0a90: 20 20 20 6c 61 70 70 65 6e 64 20 78 20 5b 6c 69     lappend x [li
0aa0: 6e 64 65 78 20 24 78 77 6f 72 64 73 20 5b 65 78  ndex $xwords [ex
0ab0: 70 72 20 28 24 69 20 2f 20 31 29 20 20 20 25 20  pr ($i / 1)   % 
0ac0: 31 30 5d 5d 0a 0a 20 20 20 20 73 65 74 20 79 20  10]]..    set y 
0ad0: 5b 6c 69 73 74 5d 0a 20 20 20 20 6c 61 70 70 65  [list].    lappe
0ae0: 6e 64 20 79 20 5b 6c 69 6e 64 65 78 20 24 79 77  nd y [lindex $yw
0af0: 6f 72 64 73 20 5b 65 78 70 72 20 28 24 69 20 2f  ords [expr ($i /
0b00: 20 31 30 30 30 29 20 25 20 31 30 5d 5d 0a 20 20   1000) % 10]].  
0b10: 20 20 6c 61 70 70 65 6e 64 20 79 20 5b 6c 69 6e    lappend y [lin
0b20: 64 65 78 20 24 79 77 6f 72 64 73 20 5b 65 78 70  dex $ywords [exp
0b30: 72 20 28 24 69 20 2f 20 31 30 30 29 20 20 25 20  r ($i / 100)  % 
0b40: 31 30 5d 5d 0a 20 20 20 20 6c 61 70 70 65 6e 64  10]].    lappend
0b50: 20 79 20 5b 6c 69 6e 64 65 78 20 24 79 77 6f 72   y [lindex $ywor
0b60: 64 73 20 5b 65 78 70 72 20 28 24 69 20 2f 20 31  ds [expr ($i / 1
0b70: 30 29 20 20 20 25 20 31 30 5d 5d 0a 20 20 20 20  0)   % 10]].    
0b80: 6c 61 70 70 65 6e 64 20 79 20 5b 6c 69 6e 64 65  lappend y [linde
0b90: 78 20 24 79 77 6f 72 64 73 20 5b 65 78 70 72 20  x $ywords [expr 
0ba0: 28 24 69 20 2f 20 31 29 20 20 20 25 20 31 30 5d  ($i / 1)   % 10]
0bb0: 5d 0a 0a 20 20 20 20 64 62 20 65 76 61 6c 20 7b  ]..    db eval {
0bc0: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 28   INSERT INTO t1(
0bd0: 64 6f 63 69 64 2c 20 78 2c 20 79 29 20 56 41 4c  docid, x, y) VAL
0be0: 55 45 53 28 24 69 2c 20 24 78 2c 20 24 79 29 20  UES($i, $x, $y) 
0bf0: 7d 0a 20 20 7d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d  }.  }.}..#------
0c00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0c10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0c20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0c30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0c40: 2d 2d 2d 0a 23 20 55 53 41 47 45 3a 20 66 74 73  ---.# USAGE: fts
0c50: 33 5f 62 75 69 6c 64 5f 64 62 5f 32 20 4e 20 41  3_build_db_2 N A
0c60: 52 47 53 0a 23 0a 23 20 42 75 69 6c 64 20 61 20  RGS.#.# Build a 
0c70: 73 61 6d 70 6c 65 20 46 54 53 20 74 61 62 6c 65  sample FTS table
0c80: 20 69 6e 20 74 68 65 20 64 61 74 61 62 61 73 65   in the database
0c90: 20 6f 70 65 6e 65 64 20 62 79 20 64 61 74 61 62   opened by datab
0ca0: 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 0a  ase connection .
0cb0: 23 20 5b 64 62 5d 2e 20 54 68 65 20 6e 61 6d 65  # [db]. The name
0cc0: 20 6f 66 20 74 68 65 20 6e 65 77 20 74 61 62 6c   of the new tabl
0cd0: 65 20 69 73 20 22 74 32 22 2e 0a 23 0a 70 72 6f  e is "t2"..#.pro
0ce0: 63 20 66 74 73 33 5f 62 75 69 6c 64 5f 64 62 5f  c fts3_build_db_
0cf0: 32 20 7b 61 72 67 73 7d 20 7b 0a 0a 20 20 73 65  2 {args} {..  se
0d00: 74 20 64 65 66 61 75 6c 74 28 2d 6d 6f 64 75 6c  t default(-modul
0d10: 65 29 20 66 74 73 34 0a 20 20 73 65 74 20 64 65  e) fts4.  set de
0d20: 66 61 75 6c 74 28 2d 65 78 74 72 61 29 20 20 20  fault(-extra)   
0d30: 22 22 0a 0a 20 20 73 65 74 20 6e 41 72 67 20 5b  ""..  set nArg [
0d40: 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 0a 20  llength $args]. 
0d50: 20 69 66 20 7b 28 24 6e 41 72 67 25 32 29 3d 3d   if {($nArg%2)==
0d60: 30 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72 20 22  0} {.    error "
0d70: 77 72 6f 6e 67 20 23 20 61 72 67 73 3a 20 73 68  wrong # args: sh
0d80: 6f 75 6c 64 20 62 65 20 5c 22 66 74 73 33 5f 62  ould be \"fts3_b
0d90: 75 69 6c 64 5f 64 62 5f 31 20 3f 73 77 69 74 63  uild_db_1 ?switc
0da0: 68 65 73 3f 20 6e 5c 22 22 0a 20 20 7d 0a 0a 20  hes? n\"".  }.. 
0db0: 20 73 65 74 20 6e 20 5b 6c 69 6e 64 65 78 20 24   set n [lindex $
0dc0: 61 72 67 73 20 5b 65 78 70 72 20 24 6e 41 72 67  args [expr $nArg
0dd0: 2d 31 5d 5d 0a 20 20 61 72 72 61 79 20 73 65 74  -1]].  array set
0de0: 20 6f 70 74 73 20 5b 61 72 72 61 79 20 67 65 74   opts [array get
0df0: 20 64 65 66 61 75 6c 74 5d 0a 20 20 61 72 72 61   default].  arra
0e00: 79 20 73 65 74 20 6f 70 74 73 20 5b 6c 72 61 6e  y set opts [lran
0e10: 67 65 20 24 61 72 67 73 20 30 20 5b 65 78 70 72  ge $args 0 [expr
0e20: 20 24 6e 41 72 67 2d 32 5d 5d 0a 20 20 66 6f 72   $nArg-2]].  for
0e30: 65 61 63 68 20 6b 20 5b 61 72 72 61 79 20 6e 61  each k [array na
0e40: 6d 65 73 20 6f 70 74 73 5d 20 7b 0a 20 20 20 20  mes opts] {.    
0e50: 69 66 20 7b 30 3d 3d 5b 69 6e 66 6f 20 65 78 69  if {0==[info exi
0e60: 73 74 73 20 64 65 66 61 75 6c 74 28 24 6b 29 5d  sts default($k)]
0e70: 7d 20 7b 20 65 72 72 6f 72 20 22 75 6e 6b 6e 6f  } { error "unkno
0e80: 77 6e 20 6f 70 74 69 6f 6e 3a 20 24 6b 22 20 7d  wn option: $k" }
0e90: 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 24 6e 20 3e  .  }..  if {$n >
0ea0: 20 31 30 30 30 30 30 7d 20 7b 65 72 72 6f 72 20   100000} {error 
0eb0: 22 6e 20 6d 75 73 74 20 62 65 20 3c 3d 20 31 30  "n must be <= 10
0ec0: 30 30 30 30 22 7d 0a 0a 20 20 73 65 74 20 73 71  0000"}..  set sq
0ed0: 6c 20 22 43 52 45 41 54 45 20 56 49 52 54 55 41  l "CREATE VIRTUA
0ee0: 4c 20 54 41 42 4c 45 20 74 32 20 55 53 49 4e 47  L TABLE t2 USING
0ef0: 20 24 6f 70 74 73 28 2d 6d 6f 64 75 6c 65 29 20   $opts(-module) 
0f00: 28 63 6f 6e 74 65 6e 74 22 0a 20 20 69 66 20 7b  (content".  if {
0f10: 24 6f 70 74 73 28 2d 65 78 74 72 61 29 20 21 3d  $opts(-extra) !=
0f20: 20 22 22 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e   ""} {.    appen
0f30: 64 20 73 71 6c 20 22 2c 20 22 20 24 6f 70 74 73  d sql ", " $opts
0f40: 28 2d 65 78 74 72 61 29 0a 20 20 7d 0a 20 20 61  (-extra).  }.  a
0f50: 70 70 65 6e 64 20 73 71 6c 20 22 29 22 0a 20 20  ppend sql ")".  
0f60: 64 62 20 65 76 61 6c 20 24 73 71 6c 0a 0a 20 20  db eval $sql..  
0f70: 73 65 74 20 63 68 61 72 73 20 5b 6c 69 73 74 20  set chars [list 
0f80: 61 20 62 20 63 20 64 20 65 20 66 20 67 20 68 20  a b c d e f g h 
0f90: 20 69 20 6a 20 6b 20 6c 20 6d 20 6e 20 6f 20 70   i j k l m n o p
0fa0: 20 20 71 20 72 20 73 20 74 20 75 20 76 20 77 20    q r s t u v w 
0fb0: 78 20 20 79 20 7a 20 22 22 5d 0a 0a 20 20 66 6f  x  y z ""]..  fo
0fc0: 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20  r {set i 0} {$i 
0fd0: 3c 20 24 6e 7d 20 7b 69 6e 63 72 20 69 7d 20 7b  < $n} {incr i} {
0fe0: 0a 20 20 20 20 73 65 74 20 77 6f 72 64 20 22 22  .    set word ""
0ff0: 0a 20 20 20 20 73 65 74 20 6e 43 68 61 72 20 5b  .    set nChar [
1000: 6c 6c 65 6e 67 74 68 20 24 63 68 61 72 73 5d 0a  llength $chars].
1010: 20 20 20 20 61 70 70 65 6e 64 20 77 6f 72 64 20      append word 
1020: 5b 6c 69 6e 64 65 78 20 24 63 68 61 72 73 20 5b  [lindex $chars [
1030: 65 78 70 72 20 7b 28 24 69 20 2f 20 31 29 20 20  expr {($i / 1)  
1040: 20 25 20 24 6e 43 68 61 72 7d 5d 5d 0a 20 20 20   % $nChar}]].   
1050: 20 61 70 70 65 6e 64 20 77 6f 72 64 20 5b 6c 69   append word [li
1060: 6e 64 65 78 20 24 63 68 61 72 73 20 5b 65 78 70  ndex $chars [exp
1070: 72 20 7b 28 24 69 20 2f 20 24 6e 43 68 61 72 29  r {($i / $nChar)
1080: 20 20 25 20 24 6e 43 68 61 72 7d 5d 5d 0a 20 20    % $nChar}]].  
1090: 20 20 61 70 70 65 6e 64 20 77 6f 72 64 20 5b 6c    append word [l
10a0: 69 6e 64 65 78 20 24 63 68 61 72 73 20 5b 65 78  index $chars [ex
10b0: 70 72 20 7b 28 24 69 20 2f 20 28 24 6e 43 68 61  pr {($i / ($nCha
10c0: 72 2a 24 6e 43 68 61 72 29 29 20 25 20 24 6e 43  r*$nChar)) % $nC
10d0: 68 61 72 7d 5d 5d 0a 0a 20 20 20 20 64 62 20 65  har}]]..    db e
10e0: 76 61 6c 20 7b 20 49 4e 53 45 52 54 20 49 4e 54  val { INSERT INT
10f0: 4f 20 74 32 28 64 6f 63 69 64 2c 20 63 6f 6e 74  O t2(docid, cont
1100: 65 6e 74 29 20 56 41 4c 55 45 53 28 24 69 2c 20  ent) VALUES($i, 
1110: 24 77 6f 72 64 29 20 7d 0a 20 20 7d 0a 7d 0a 0a  $word) }.  }.}..
1120: 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  #---------------
1130: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1140: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1150: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1160: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 55 53 41  ----------.# USA
1170: 47 45 3a 20 66 74 73 33 5f 69 6e 74 65 67 72 69  GE: fts3_integri
1180: 74 79 5f 63 68 65 63 6b 20 54 42 4c 0a 23 0a 23  ty_check TBL.#.#
1190: 20 54 68 69 73 20 70 72 6f 63 20 69 73 20 75 73   This proc is us
11a0: 65 64 20 74 6f 20 76 65 72 69 66 79 20 74 68 61  ed to verify tha
11b0: 74 20 74 68 65 20 66 75 6c 6c 2d 74 65 78 74 20  t the full-text 
11c0: 69 6e 64 65 78 20 69 73 20 63 6f 6e 73 69 73 74  index is consist
11d0: 65 6e 74 20 77 69 74 68 0a 23 20 74 68 65 20 63  ent with.# the c
11e0: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 66  ontents of the f
11f0: 74 73 33 20 74 61 62 6c 65 2e 20 49 6e 20 6f 74  ts3 table. In ot
1200: 68 65 72 20 77 6f 72 64 73 2c 20 69 74 20 63 68  her words, it ch
1210: 65 63 6b 73 20 74 68 61 74 20 74 68 65 0a 23 20  ecks that the.# 
1220: 64 61 74 61 20 69 6e 20 74 68 65 20 25 5f 63 6f  data in the %_co
1230: 6e 74 65 6e 74 73 20 74 61 62 6c 65 20 6d 61 74  ntents table mat
1240: 63 68 65 73 20 74 68 61 74 20 69 6e 20 74 68 65  ches that in the
1250: 20 25 5f 73 65 67 64 69 72 20 61 6e 64 20 25 5f   %_segdir and %_
1260: 73 65 67 6d 65 6e 74 73 20 0a 23 20 74 61 62 6c  segments .# tabl
1270: 65 73 2e 0a 23 0a 23 20 54 68 69 73 20 69 73 20  es..#.# This is 
1280: 6e 6f 74 20 61 6e 20 65 66 66 69 63 69 65 6e 74  not an efficient
1290: 20 70 72 6f 63 65 64 75 72 65 2e 20 49 74 20 75   procedure. It u
12a0: 73 65 73 20 61 20 6c 6f 74 20 6f 66 20 6d 65 6d  ses a lot of mem
12b0: 6f 72 79 20 61 6e 64 20 61 20 6c 6f 74 0a 23 20  ory and a lot.# 
12c0: 6f 66 20 43 50 55 2e 20 42 75 74 20 69 74 20 69  of CPU. But it i
12d0: 73 20 62 65 74 74 65 72 20 74 68 61 6e 20 6e 6f  s better than no
12e0: 74 20 63 68 65 63 6b 69 6e 67 20 61 74 20 61 6c  t checking at al
12f0: 6c 2e 0a 23 0a 23 20 54 68 65 20 70 72 6f 63 65  l..#.# The proce
1300: 64 75 72 65 20 69 73 3a 0a 23 0a 23 20 20 20 31  dure is:.#.#   1
1310: 29 20 52 65 61 64 20 74 68 65 20 65 6e 74 69 72  ) Read the entir
1320: 65 20 66 75 6c 6c 2d 74 65 78 74 20 69 6e 64 65  e full-text inde
1330: 78 20 66 72 6f 6d 20 74 68 65 20 25 5f 73 65 67  x from the %_seg
1340: 64 69 72 20 61 6e 64 20 25 5f 73 65 67 6d 65 6e  dir and %_segmen
1350: 74 73 0a 23 20 20 20 20 20 20 74 61 62 6c 65 73  ts.#      tables
1360: 20 69 6e 74 6f 20 6d 65 6d 6f 72 79 2e 20 46 6f   into memory. Fo
1370: 72 20 65 61 63 68 20 65 6e 74 72 79 20 69 6e 20  r each entry in 
1380: 74 68 65 20 69 6e 64 65 78 2c 20 74 68 65 20 66  the index, the f
1390: 6f 6c 6c 6f 77 69 6e 67 20 69 73 0a 23 20 20 20  ollowing is.#   
13a0: 20 20 20 64 6f 6e 65 3a 0a 23 0a 23 20 20 20 20     done:.#.#    
13b0: 20 20 20 20 20 20 73 65 74 20 43 28 24 69 44 6f        set C($iDo
13c0: 63 69 64 2c 24 69 43 6f 6c 2c 24 69 50 6f 73 69  cid,$iCol,$iPosi
13d0: 74 69 6f 6e 29 20 24 7a 54 65 72 6d 0a 23 0a 23  tion) $zTerm.#.#
13e0: 20 20 20 32 29 20 49 74 65 72 61 74 65 20 74 68     2) Iterate th
13f0: 72 6f 75 67 68 20 65 61 63 68 20 63 6f 6c 75 6d  rough each colum
1400: 6e 20 6f 66 20 65 61 63 68 20 72 6f 77 20 6f 66  n of each row of
1410: 20 74 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74   the %_content t
1420: 61 62 6c 65 2e 20 0a 23 20 20 20 20 20 20 54 6f  able. .#      To
1430: 6b 65 6e 69 7a 65 20 61 6c 6c 20 64 6f 63 75 6d  kenize all docum
1440: 65 6e 74 73 2c 20 61 6e 64 20 63 68 65 63 6b 20  ents, and check 
1450: 74 68 61 74 20 66 6f 72 20 65 61 63 68 20 74 6f  that for each to
1460: 6b 65 6e 20 74 68 65 72 65 20 69 73 0a 23 20 20  ken there is.#  
1470: 20 20 20 20 61 20 63 6f 72 72 65 73 70 6f 6e 64      a correspond
1480: 69 6e 67 20 65 6e 74 72 79 20 69 6e 20 74 68 65  ing entry in the
1490: 20 24 43 20 61 72 72 61 79 2e 20 41 66 74 65 72   $C array. After
14a0: 20 63 68 65 63 6b 69 6e 67 20 61 20 74 6f 6b 65   checking a toke
14b0: 6e 2c 0a 23 20 20 20 20 20 20 5b 75 6e 73 65 74  n,.#      [unset
14c0: 5d 20 74 68 65 20 24 43 20 61 72 72 61 79 20 65  ] the $C array e
14d0: 6e 74 72 79 2e 0a 23 0a 23 20 20 20 33 29 20 43  ntry..#.#   3) C
14e0: 68 65 63 6b 20 74 68 61 74 20 61 72 72 61 79 20  heck that array 
14f0: 24 43 20 69 73 20 6e 6f 77 20 65 6d 70 74 79 2e  $C is now empty.
1500: 0a 23 20 20 20 20 20 20 0a 23 0a 70 72 6f 63 20  .#      .#.proc 
1510: 66 74 73 33 5f 69 6e 74 65 67 72 69 74 79 5f 63  fts3_integrity_c
1520: 68 65 63 6b 20 7b 74 62 6c 7d 20 7b 0a 0a 20 20  heck {tbl} {..  
1530: 66 74 73 33 5f 72 65 61 64 32 20 24 74 62 6c 20  fts3_read2 $tbl 
1540: 31 20 41 0a 0a 20 20 66 6f 72 65 61 63 68 20 7a  1 A..  foreach z
1550: 54 65 72 6d 20 5b 61 72 72 61 79 20 6e 61 6d 65  Term [array name
1560: 73 20 41 5d 20 7b 0a 20 20 20 20 23 70 75 74 73  s A] {.    #puts
1570: 20 24 7a 54 65 72 6d 0a 20 20 20 20 66 6f 72 65   $zTerm.    fore
1580: 61 63 68 20 64 6f 63 6c 69 73 74 20 24 41 28 24  ach doclist $A($
1590: 7a 54 65 72 6d 29 20 7b 0a 20 20 20 20 20 20 73  zTerm) {.      s
15a0: 65 74 20 64 6f 63 69 64 20 30 0a 20 20 20 20 20  et docid 0.     
15b0: 20 77 68 69 6c 65 20 7b 5b 73 74 72 69 6e 67 20   while {[string 
15c0: 6c 65 6e 67 74 68 20 24 64 6f 63 6c 69 73 74 5d  length $doclist]
15d0: 3e 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65  >0} {.        se
15e0: 74 20 69 43 6f 6c 20 30 0a 20 20 20 20 20 20 20  t iCol 0.       
15f0: 20 73 65 74 20 69 50 6f 73 20 30 0a 20 20 20 20   set iPos 0.    
1600: 20 20 20 20 73 65 74 20 6c 50 6f 73 20 5b 6c 69      set lPos [li
1610: 73 74 5d 0a 20 20 20 20 20 20 20 20 73 65 74 20  st].        set 
1620: 6c 43 6f 6c 20 5b 6c 69 73 74 5d 0a 0a 20 20 20  lCol [list]..   
1630: 20 20 20 20 20 23 20 46 69 72 73 74 20 76 61 72       # First var
1640: 69 6e 74 20 6f 66 20 61 20 64 6f 63 6c 69 73 74  int of a doclist
1650: 2d 65 6e 74 72 79 20 69 73 20 74 68 65 20 64 6f  -entry is the do
1660: 63 69 64 2e 20 44 65 6c 74 61 2d 63 6f 6d 70 72  cid. Delta-compr
1670: 65 73 73 65 64 0a 20 20 20 20 20 20 20 20 23 20  essed.        # 
1680: 77 69 74 68 20 72 65 73 70 65 63 74 20 74 6f 20  with respect to 
1690: 74 68 65 20 64 6f 63 69 64 20 6f 66 20 74 68 65  the docid of the
16a0: 20 70 72 65 76 69 6f 75 73 20 65 6e 74 72 79 2e   previous entry.
16b0: 0a 20 20 20 20 20 20 20 20 23 0a 20 20 20 20 20  .        #.     
16c0: 20 20 20 69 6e 63 72 20 64 6f 63 69 64 20 5b 67     incr docid [g
16d0: 6f 62 62 6c 65 5f 76 61 72 69 6e 74 20 64 6f 63  obble_varint doc
16e0: 6c 69 73 74 5d 0a 20 20 20 20 20 20 20 20 69 66  list].        if
16f0: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 44   {[info exists D
1700: 28 24 7a 54 65 72 6d 2c 24 64 6f 63 69 64 29 5d  ($zTerm,$docid)]
1710: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 77 68  } {.          wh
1720: 69 6c 65 20 7b 5b 73 65 74 20 69 44 65 6c 74 61  ile {[set iDelta
1730: 20 5b 67 6f 62 62 6c 65 5f 76 61 72 69 6e 74 20   [gobble_varint 
1740: 64 6f 63 6c 69 73 74 5d 5d 20 21 3d 20 30 7d 20  doclist]] != 0} 
1750: 7b 7d 0a 20 20 20 20 20 20 20 20 20 20 63 6f 6e  {}.          con
1760: 74 69 6e 75 65 0a 20 20 20 20 20 20 20 20 7d 0a  tinue.        }.
1770: 20 20 20 20 20 20 20 20 73 65 74 20 44 28 24 7a          set D($z
1780: 54 65 72 6d 2c 24 64 6f 63 69 64 29 20 31 0a 0a  Term,$docid) 1..
1790: 20 20 20 20 20 20 20 20 23 20 47 6f 62 62 6c 65          # Gobble
17a0: 20 76 61 72 69 6e 74 73 20 75 6e 74 69 6c 20 74   varints until t
17b0: 68 65 20 30 78 30 30 20 74 68 61 74 20 74 65 72  he 0x00 that ter
17c0: 6d 69 6e 61 74 65 73 20 74 68 65 20 64 6f 63 6c  minates the docl
17d0: 69 73 74 2d 65 6e 74 72 79 0a 20 20 20 20 20 20  ist-entry.      
17e0: 20 20 23 20 69 73 20 66 6f 75 6e 64 2e 0a 20 20    # is found..  
17f0: 20 20 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 65        while {[se
1800: 74 20 69 44 65 6c 74 61 20 5b 67 6f 62 62 6c 65  t iDelta [gobble
1810: 5f 76 61 72 69 6e 74 20 64 6f 63 6c 69 73 74 5d  _varint doclist]
1820: 5d 20 3e 20 30 7d 20 7b 0a 20 20 20 20 20 20 20  ] > 0} {.       
1830: 20 20 20 69 66 20 7b 24 69 44 65 6c 74 61 20 3d     if {$iDelta =
1840: 3d 20 31 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  = 1} {.         
1850: 20 20 20 73 65 74 20 69 43 6f 6c 20 5b 67 6f 62     set iCol [gob
1860: 62 6c 65 5f 76 61 72 69 6e 74 20 64 6f 63 6c 69  ble_varint docli
1870: 73 74 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  st].            
1880: 73 65 74 20 69 50 6f 73 20 30 0a 20 20 20 20 20  set iPos 0.     
1890: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
18a0: 20 20 20 20 20 20 20 20 20 20 69 6e 63 72 20 69            incr i
18b0: 50 6f 73 20 24 69 44 65 6c 74 61 0a 20 20 20 20  Pos $iDelta.    
18c0: 20 20 20 20 20 20 20 20 69 6e 63 72 20 69 50 6f          incr iPo
18d0: 73 20 2d 32 0a 20 20 20 20 20 20 20 20 20 20 20  s -2.           
18e0: 20 73 65 74 20 43 28 24 64 6f 63 69 64 2c 24 69   set C($docid,$i
18f0: 43 6f 6c 2c 24 69 50 6f 73 29 20 24 7a 54 65 72  Col,$iPos) $zTer
1900: 6d 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  m.          }.  
1910: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
1920: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 66 6f 72      }.  }..  for
1930: 65 61 63 68 20 6b 65 79 20 5b 61 72 72 61 79 20  each key [array 
1940: 6e 61 6d 65 73 20 43 5d 20 7b 0a 20 20 20 20 23  names C] {.    #
1950: 70 75 74 73 20 22 24 6b 65 79 20 2d 3e 20 24 43  puts "$key -> $C
1960: 28 24 6b 65 79 29 22 0a 20 20 7d 0a 0a 0a 20 20  ($key)".  }...  
1970: 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20  db eval "SELECT 
1980: 2a 20 46 52 4f 4d 20 24 7b 74 62 6c 7d 5f 63 6f  * FROM ${tbl}_co
1990: 6e 74 65 6e 74 22 20 45 20 7b 0a 20 20 20 20 73  ntent" E {.    s
19a0: 65 74 20 69 43 6f 6c 20 30 0a 20 20 20 20 73 65  et iCol 0.    se
19b0: 74 20 69 44 6f 63 20 24 45 28 64 6f 63 69 64 29  t iDoc $E(docid)
19c0: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 63 6f 6c  .    foreach col
19d0: 20 5b 6c 72 61 6e 67 65 20 24 45 28 2a 29 20 31   [lrange $E(*) 1
19e0: 20 65 6e 64 5d 20 7b 0a 20 20 20 20 20 20 73 65   end] {.      se
19f0: 74 20 63 20 24 45 28 24 63 6f 6c 29 0a 20 20 20  t c $E($col).   
1a00: 20 20 20 73 65 74 20 73 71 6c 20 7b 53 45 4c 45     set sql {SELE
1a10: 43 54 20 66 74 73 33 5f 74 6f 6b 65 6e 69 7a 65  CT fts3_tokenize
1a20: 72 5f 74 65 73 74 28 27 73 69 6d 70 6c 65 27 2c  r_test('simple',
1a30: 20 24 63 29 7d 0a 0a 20 20 20 20 20 20 66 6f 72   $c)}..      for
1a40: 65 61 63 68 20 7b 70 6f 73 20 74 65 72 6d 20 64  each {pos term d
1a50: 75 6d 6d 79 7d 20 5b 64 62 20 6f 6e 65 20 24 73  ummy} [db one $s
1a60: 71 6c 5d 20 7b 0a 20 20 20 20 20 20 20 20 69 66  ql] {.        if
1a70: 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20   {![info exists 
1a80: 43 28 24 69 44 6f 63 2c 24 69 43 6f 6c 2c 24 70  C($iDoc,$iCol,$p
1a90: 6f 73 29 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20  os)]} {.        
1aa0: 20 20 73 65 74 20 65 73 20 22 45 72 72 6f 72 20    set es "Error 
1ab0: 61 74 20 64 6f 63 69 64 3d 24 69 44 6f 63 20 63  at docid=$iDoc c
1ac0: 6f 6c 3d 24 69 43 6f 6c 20 70 6f 73 3d 24 70 6f  ol=$iCol pos=$po
1ad0: 73 2e 20 49 6e 64 65 78 20 69 73 20 6d 69 73 73  s. Index is miss
1ae0: 69 6e 67 22 0a 20 20 20 20 20 20 20 20 20 20 6c  ing".          l
1af0: 61 70 70 65 6e 64 20 65 72 72 6f 72 73 20 24 65  append errors $e
1b00: 73 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65  s.        } else
1b10: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 20   {.          if 
1b20: 7b 5b 73 74 72 69 6e 67 20 63 6f 6d 70 61 72 65  {[string compare
1b30: 20 24 43 28 24 69 44 6f 63 2c 24 69 43 6f 6c 2c   $C($iDoc,$iCol,
1b40: 24 70 6f 73 29 20 24 74 65 72 6d 5d 7d 20 7b 0a  $pos) $term]} {.
1b50: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20              set 
1b60: 20 20 20 65 73 20 22 45 72 72 6f 72 20 61 74 20     es "Error at 
1b70: 64 6f 63 69 64 3d 24 69 44 6f 63 20 63 6f 6c 3d  docid=$iDoc col=
1b80: 24 69 43 6f 6c 20 70 6f 73 3d 24 70 6f 73 2e 20  $iCol pos=$pos. 
1b90: 49 6e 64 65 78 20 22 0a 20 20 20 20 20 20 20 20  Index ".        
1ba0: 20 20 20 20 61 70 70 65 6e 64 20 65 73 20 22 68      append es "h
1bb0: 61 73 20 5c 22 24 43 28 24 69 44 6f 63 2c 24 69  as \"$C($iDoc,$i
1bc0: 43 6f 6c 2c 24 70 6f 73 29 5c 22 2c 20 64 6f 63  Col,$pos)\", doc
1bd0: 75 6d 65 6e 74 20 68 61 73 20 5c 22 24 74 65 72  ument has \"$ter
1be0: 6d 5c 22 22 0a 20 20 20 20 20 20 20 20 20 20 20  m\"".           
1bf0: 20 6c 61 70 70 65 6e 64 20 65 72 72 6f 72 73 20   lappend errors 
1c00: 24 65 73 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  $es.          }.
1c10: 20 20 20 20 20 20 20 20 20 20 75 6e 73 65 74 20            unset 
1c20: 43 28 24 69 44 6f 63 2c 24 69 43 6f 6c 2c 24 70  C($iDoc,$iCol,$p
1c30: 6f 73 29 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  os).        }.  
1c40: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 6e 63 72      }.      incr
1c50: 20 69 43 6f 6c 0a 20 20 20 20 7d 0a 20 20 7d 0a   iCol.    }.  }.
1c60: 0a 20 20 66 6f 72 65 61 63 68 20 63 20 5b 61 72  .  foreach c [ar
1c70: 72 61 79 20 6e 61 6d 65 73 20 43 5d 20 7b 0a 20  ray names C] {. 
1c80: 20 20 20 6c 61 70 70 65 6e 64 20 65 72 72 6f 72     lappend error
1c90: 73 20 22 42 61 64 20 69 6e 64 65 78 20 65 6e 74  s "Bad index ent
1ca0: 72 79 3a 20 24 63 20 2d 3e 20 24 43 28 24 63 29  ry: $c -> $C($c)
1cb0: 22 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 5b 69 6e  ".  }..  if {[in
1cc0: 66 6f 20 65 78 69 73 74 73 20 65 72 72 6f 72 73  fo exists errors
1cd0: 5d 7d 20 7b 20 72 65 74 75 72 6e 20 5b 6a 6f 69  ]} { return [joi
1ce0: 6e 20 24 65 72 72 6f 72 73 20 22 5c 6e 22 5d 20  n $errors "\n"] 
1cf0: 7d 0a 20 20 72 65 74 75 72 6e 20 22 6f 6b 22 0a  }.  return "ok".
1d00: 7d 0a 0a 23 20 55 53 41 47 45 3a 20 66 74 73 33  }..# USAGE: fts3
1d10: 5f 74 65 72 6d 73 20 54 42 4c 20 57 48 45 52 45  _terms TBL WHERE
1d20: 0a 23 0a 23 20 41 72 67 75 6d 65 6e 74 20 54 42  .#.# Argument TB
1d30: 4c 20 6d 75 73 74 20 62 65 20 74 68 65 20 6e 61  L must be the na
1d40: 6d 65 20 6f 66 20 61 6e 20 46 54 53 33 20 74 61  me of an FTS3 ta
1d50: 62 6c 65 2e 20 41 72 67 75 6d 65 6e 74 20 57 48  ble. Argument WH
1d60: 45 52 45 20 69 73 20 61 6e 0a 23 20 53 51 4c 20  ERE is an.# SQL 
1d70: 65 78 70 72 65 73 73 69 6f 6e 20 74 68 61 74 20  expression that 
1d80: 77 69 6c 6c 20 62 65 20 75 73 65 64 20 61 73 20  will be used as 
1d90: 74 68 65 20 57 48 45 52 45 20 63 6c 61 75 73 65  the WHERE clause
1da0: 20 77 68 65 6e 20 73 63 61 6e 6e 69 6e 67 0a 23   when scanning.#
1db0: 20 74 68 65 20 25 5f 73 65 67 64 69 72 20 74 61   the %_segdir ta
1dc0: 62 6c 65 2e 20 41 73 20 69 6e 20 74 68 65 20 66  ble. As in the f
1dd0: 6f 6c 6c 6f 77 69 6e 67 20 71 75 65 72 79 3a 0a  ollowing query:.
1de0: 23 0a 23 20 20 20 22 53 45 4c 45 43 54 20 2a 20  #.#   "SELECT * 
1df0: 46 52 4f 4d 20 24 7b 54 42 4c 7d 5f 73 65 67 64  FROM ${TBL}_segd
1e00: 69 72 20 57 48 45 52 45 20 24 7b 57 48 45 52 45  ir WHERE ${WHERE
1e10: 7d 22 0a 23 0a 23 20 54 68 69 73 20 66 75 6e 63  }".#.# This func
1e20: 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 61 20 6c  tion returns a l
1e30: 69 73 74 20 6f 66 20 61 6c 6c 20 74 65 72 6d 73  ist of all terms
1e40: 20 70 72 65 73 65 6e 74 20 69 6e 20 74 68 65 20   present in the 
1e50: 73 65 67 6d 65 6e 74 73 0a 23 20 73 65 6c 65 63  segments.# selec
1e60: 74 65 64 20 62 79 20 74 68 65 20 73 74 61 74 65  ted by the state
1e70: 6d 65 6e 74 20 61 62 6f 76 65 2e 0a 23 0a 70 72  ment above..#.pr
1e80: 6f 63 20 66 74 73 33 5f 74 65 72 6d 73 20 7b 74  oc fts3_terms {t
1e90: 62 6c 20 77 68 65 72 65 7d 20 7b 0a 20 20 66 74  bl where} {.  ft
1ea0: 73 33 5f 72 65 61 64 20 24 74 62 6c 20 24 77 68  s3_read $tbl $wh
1eb0: 65 72 65 20 61 0a 20 20 72 65 74 75 72 6e 20 5b  ere a.  return [
1ec0: 6c 73 6f 72 74 20 5b 61 72 72 61 79 20 6e 61 6d  lsort [array nam
1ed0: 65 73 20 61 5d 5d 0a 7d 0a 0a 0a 23 20 55 53 41  es a]].}...# USA
1ee0: 47 45 3a 20 66 74 73 33 5f 64 6f 63 6c 69 73 74  GE: fts3_doclist
1ef0: 20 54 42 4c 20 54 45 52 4d 20 57 48 45 52 45 0a   TBL TERM WHERE.
1f00: 23 0a 23 20 41 72 67 75 6d 65 6e 74 20 54 42 4c  #.# Argument TBL
1f10: 20 6d 75 73 74 20 62 65 20 74 68 65 20 6e 61 6d   must be the nam
1f20: 65 20 6f 66 20 61 6e 20 46 54 53 33 20 74 61 62  e of an FTS3 tab
1f30: 6c 65 2e 20 54 45 52 4d 20 69 73 20 61 20 74 65  le. TERM is a te
1f40: 72 6d 20 74 68 61 74 20 6d 61 79 0a 23 20 6f 72  rm that may.# or
1f50: 20 6d 61 79 20 6e 6f 74 20 62 65 20 70 72 65 73   may not be pres
1f60: 65 6e 74 20 69 6e 20 74 68 65 20 74 61 62 6c 65  ent in the table
1f70: 2e 20 41 72 67 75 6d 65 6e 74 20 57 48 45 52 45  . Argument WHERE
1f80: 20 69 73 20 75 73 65 64 20 74 6f 20 73 65 6c 65   is used to sele
1f90: 63 74 20 61 20 0a 23 20 73 75 62 73 65 74 20 6f  ct a .# subset o
1fa0: 66 20 74 68 65 20 62 2d 74 72 65 65 20 73 65 67  f the b-tree seg
1fb0: 6d 65 6e 74 73 20 69 6e 20 74 68 65 20 61 73 73  ments in the ass
1fc0: 6f 63 69 61 74 65 64 20 66 75 6c 6c 2d 74 65 78  ociated full-tex
1fd0: 74 20 69 6e 64 65 78 20 61 73 20 0a 23 20 64 65  t index as .# de
1fe0: 73 63 72 69 62 65 64 20 61 62 6f 76 65 20 66 6f  scribed above fo
1ff0: 72 20 5b 66 74 73 33 5f 74 65 72 6d 73 5d 2e 0a  r [fts3_terms]..
2000: 23 0a 23 20 54 68 69 73 20 66 75 6e 63 74 69 6f  #.# This functio
2010: 6e 20 72 65 74 75 72 6e 73 20 74 68 65 20 72 65  n returns the re
2020: 73 75 6c 74 73 20 6f 66 20 6d 65 72 67 69 6e 67  sults of merging
2030: 20 74 68 65 20 64 6f 63 6c 69 73 74 73 20 61 73   the doclists as
2040: 73 6f 63 69 61 74 65 64 0a 23 20 77 69 74 68 20  sociated.# with 
2050: 54 45 52 4d 20 69 6e 20 74 68 65 20 73 65 6c 65  TERM in the sele
2060: 63 74 65 64 20 73 65 67 6d 65 6e 74 73 2e 20 45  cted segments. E
2070: 61 63 68 20 64 6f 63 6c 69 73 74 20 69 73 20 61  ach doclist is a
2080: 6e 20 65 6c 65 6d 65 6e 74 20 6f 66 20 74 68 65  n element of the
2090: 0a 23 20 72 65 74 75 72 6e 65 64 20 6c 69 73 74  .# returned list
20a0: 2e 20 45 61 63 68 20 64 6f 63 6c 69 73 74 20 69  . Each doclist i
20b0: 73 20 66 6f 72 6d 61 74 74 65 64 20 61 73 20 66  s formatted as f
20c0: 6f 6c 6c 6f 77 73 3a 0a 23 0a 23 20 20 20 5b 24  ollows:.#.#   [$
20d0: 64 6f 63 69 64 20 3f 24 63 6f 6c 5b 24 6f 66 66  docid ?$col[$off
20e0: 31 20 24 6f 66 66 32 2e 2e 2e 5d 3f 2e 2e 2e 5d  1 $off2...]?...]
20f0: 0a 23 0a 23 20 54 68 65 20 66 6f 72 6d 61 74 74  .#.# The formatt
2100: 69 6e 67 20 69 73 20 6f 64 64 20 66 6f 72 20 61  ing is odd for a
2110: 20 54 63 6c 20 63 6f 6d 6d 61 6e 64 20 69 6e 20   Tcl command in 
2120: 6f 72 64 65 72 20 74 6f 20 62 65 20 63 6f 6d 70  order to be comp
2130: 61 74 69 62 6c 65 20 77 69 74 68 0a 23 20 74 68  atible with.# th
2140: 65 20 6f 72 69 67 69 6e 61 6c 20 43 2d 6c 61 6e  e original C-lan
2150: 67 75 61 67 65 20 69 6d 70 6c 65 6d 65 6e 74 61  guage implementa
2160: 74 69 6f 6e 2e 20 49 66 20 61 72 67 75 6d 65 6e  tion. If argumen
2170: 74 20 57 48 45 52 45 20 69 73 20 22 31 22 2c 20  t WHERE is "1", 
2180: 74 68 65 6e 20 0a 23 20 61 6e 79 20 65 6d 70 74  then .# any empt
2190: 79 20 64 6f 63 6c 69 73 74 73 20 61 72 65 20 6f  y doclists are o
21a0: 6d 69 74 74 65 64 20 66 72 6f 6d 20 74 68 65 20  mitted from the 
21b0: 72 65 74 75 72 6e 65 64 20 6c 69 73 74 2e 0a 23  returned list..#
21c0: 0a 70 72 6f 63 20 66 74 73 33 5f 64 6f 63 6c 69  .proc fts3_docli
21d0: 73 74 20 7b 74 62 6c 20 74 65 72 6d 20 77 68 65  st {tbl term whe
21e0: 72 65 7d 20 7b 0a 20 20 66 74 73 33 5f 72 65 61  re} {.  fts3_rea
21f0: 64 20 24 74 62 6c 20 24 77 68 65 72 65 20 61 0a  d $tbl $where a.
2200: 0a 0a 20 20 66 6f 72 65 61 63 68 20 64 6f 63 6c  ..  foreach docl
2210: 69 73 74 20 24 61 28 24 74 65 72 6d 29 20 7b 0a  ist $a($term) {.
2220: 20 20 20 20 73 65 74 20 64 6f 63 69 64 20 30 0a      set docid 0.
2230: 0a 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 74 72  .    while {[str
2240: 69 6e 67 20 6c 65 6e 67 74 68 20 24 64 6f 63 6c  ing length $docl
2250: 69 73 74 5d 3e 30 7d 20 7b 0a 20 20 20 20 20 20  ist]>0} {.      
2260: 73 65 74 20 69 43 6f 6c 20 30 0a 20 20 20 20 20  set iCol 0.     
2270: 20 73 65 74 20 69 50 6f 73 20 30 0a 20 20 20 20   set iPos 0.    
2280: 20 20 73 65 74 20 6c 50 6f 73 20 5b 6c 69 73 74    set lPos [list
2290: 5d 0a 20 20 20 20 20 20 73 65 74 20 6c 43 6f 6c  ].      set lCol
22a0: 20 5b 6c 69 73 74 5d 0a 20 20 20 20 20 20 69 6e   [list].      in
22b0: 63 72 20 64 6f 63 69 64 20 5b 67 6f 62 62 6c 65  cr docid [gobble
22c0: 5f 76 61 72 69 6e 74 20 64 6f 63 6c 69 73 74 5d  _varint doclist]
22d0: 0a 20 20 0a 20 20 20 20 20 20 77 68 69 6c 65 20  .  .      while 
22e0: 7b 5b 73 65 74 20 69 44 65 6c 74 61 20 5b 67 6f  {[set iDelta [go
22f0: 62 62 6c 65 5f 76 61 72 69 6e 74 20 64 6f 63 6c  bble_varint docl
2300: 69 73 74 5d 5d 20 3e 20 30 7d 20 7b 0a 20 20 20  ist]] > 0} {.   
2310: 20 20 20 20 20 69 66 20 7b 24 69 44 65 6c 74 61       if {$iDelta
2320: 20 3d 3d 20 31 7d 20 7b 0a 20 20 20 20 20 20 20   == 1} {.       
2330: 20 20 20 6c 61 70 70 65 6e 64 20 6c 43 6f 6c 20     lappend lCol 
2340: 5b 6c 69 73 74 20 24 69 43 6f 6c 20 24 6c 50 6f  [list $iCol $lPo
2350: 73 5d 0a 20 20 20 20 20 20 20 20 20 20 73 65 74  s].          set
2360: 20 69 50 6f 73 20 30 0a 20 20 20 20 20 20 20 20   iPos 0.        
2370: 20 20 73 65 74 20 6c 50 6f 73 20 5b 6c 69 73 74    set lPos [list
2380: 5d 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20  ].          set 
2390: 69 43 6f 6c 20 5b 67 6f 62 62 6c 65 5f 76 61 72  iCol [gobble_var
23a0: 69 6e 74 20 64 6f 63 6c 69 73 74 5d 0a 20 20 20  int doclist].   
23b0: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
23c0: 20 20 20 20 20 20 20 20 69 6e 63 72 20 69 50 6f          incr iPo
23d0: 73 20 24 69 44 65 6c 74 61 0a 20 20 20 20 20 20  s $iDelta.      
23e0: 20 20 20 20 69 6e 63 72 20 69 50 6f 73 20 2d 32      incr iPos -2
23f0: 0a 20 20 20 20 20 20 20 20 20 20 6c 61 70 70 65  .          lappe
2400: 6e 64 20 6c 50 6f 73 20 24 69 50 6f 73 0a 20 20  nd lPos $iPos.  
2410: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
2420: 20 20 0a 20 20 20 20 20 20 69 66 20 7b 5b 6c 6c    .      if {[ll
2430: 65 6e 67 74 68 20 24 6c 50 6f 73 5d 3e 30 7d 20  ength $lPos]>0} 
2440: 7b 0a 20 20 20 20 20 20 20 20 6c 61 70 70 65 6e  {.        lappen
2450: 64 20 6c 43 6f 6c 20 5b 6c 69 73 74 20 24 69 43  d lCol [list $iC
2460: 6f 6c 20 24 6c 50 6f 73 5d 0a 20 20 20 20 20 20  ol $lPos].      
2470: 7d 0a 20 20 0a 20 20 20 20 20 20 69 66 20 7b 24  }.  .      if {$
2480: 77 68 65 72 65 20 21 3d 20 22 31 22 20 7c 7c 20  where != "1" || 
2490: 5b 6c 6c 65 6e 67 74 68 20 24 6c 43 6f 6c 5d 3e  [llength $lCol]>
24a0: 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74  0} {.        set
24b0: 20 72 65 74 28 24 64 6f 63 69 64 29 20 24 6c 43   ret($docid) $lC
24c0: 6f 6c 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20  ol.      } else 
24d0: 7b 0a 20 20 20 20 20 20 20 20 75 6e 73 65 74 20  {.        unset 
24e0: 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 72 65 74 28  -nocomplain ret(
24f0: 24 64 6f 63 69 64 29 0a 20 20 20 20 20 20 7d 0a  $docid).      }.
2500: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 73 65 74      }.  }..  set
2510: 20 6c 44 6f 63 20 5b 6c 69 73 74 5d 0a 20 20 66   lDoc [list].  f
2520: 6f 72 65 61 63 68 20 64 6f 63 69 64 20 5b 6c 73  oreach docid [ls
2530: 6f 72 74 20 2d 69 6e 74 65 67 65 72 20 5b 61 72  ort -integer [ar
2540: 72 61 79 20 6e 61 6d 65 73 20 72 65 74 5d 5d 20  ray names ret]] 
2550: 7b 0a 20 20 20 20 73 65 74 20 6c 43 6f 6c 20 5b  {.    set lCol [
2560: 6c 69 73 74 5d 0a 20 20 20 20 73 65 74 20 63 6f  list].    set co
2570: 6c 73 20 22 22 0a 20 20 20 20 66 6f 72 65 61 63  ls "".    foreac
2580: 68 20 63 6f 6c 20 24 72 65 74 28 24 64 6f 63 69  h col $ret($doci
2590: 64 29 20 7b 0a 20 20 20 20 20 20 66 6f 72 65 61  d) {.      forea
25a0: 63 68 20 7b 69 43 6f 6c 20 6c 50 6f 73 7d 20 24  ch {iCol lPos} $
25b0: 63 6f 6c 20 7b 7d 0a 20 20 20 20 20 20 61 70 70  col {}.      app
25c0: 65 6e 64 20 63 6f 6c 73 20 22 20 24 69 43 6f 6c  end cols " $iCol
25d0: 5c 5b 5b 6a 6f 69 6e 20 24 6c 50 6f 73 20 7b 20  \[[join $lPos { 
25e0: 7d 5d 5c 5d 22 0a 20 20 20 20 7d 0a 20 20 20 20  }]\]".    }.    
25f0: 6c 61 70 70 65 6e 64 20 6c 44 6f 63 20 22 5c 5b  lappend lDoc "\[
2600: 24 7b 64 6f 63 69 64 7d 24 7b 63 6f 6c 73 7d 5c  ${docid}${cols}\
2610: 5d 22 0a 20 20 7d 0a 0a 20 20 6a 6f 69 6e 20 24  ]".  }..  join $
2620: 6c 44 6f 63 20 22 20 22 0a 7d 0a 0a 23 23 23 23  lDoc " ".}..####
2630: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
2640: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
2650: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
2660: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
2670: 23 23 23 23 23 23 23 0a 0a 70 72 6f 63 20 67 6f  #######..proc go
2680: 62 62 6c 65 5f 76 61 72 69 6e 74 20 7b 76 61 72  bble_varint {var
2690: 6e 61 6d 65 7d 20 7b 0a 20 20 75 70 76 61 72 20  name} {.  upvar 
26a0: 24 76 61 72 6e 61 6d 65 20 62 6c 6f 62 0a 20 20  $varname blob.  
26b0: 73 65 74 20 6e 20 5b 72 65 61 64 5f 66 74 73 33  set n [read_fts3
26c0: 76 61 72 69 6e 74 20 24 62 6c 6f 62 20 72 65 74  varint $blob ret
26d0: 5d 0a 20 20 73 65 74 20 62 6c 6f 62 20 5b 73 74  ].  set blob [st
26e0: 72 69 6e 67 20 72 61 6e 67 65 20 24 62 6c 6f 62  ring range $blob
26f0: 20 24 6e 20 65 6e 64 5d 0a 20 20 72 65 74 75 72   $n end].  retur
2700: 6e 20 24 72 65 74 0a 7d 0a 70 72 6f 63 20 67 6f  n $ret.}.proc go
2710: 62 62 6c 65 5f 73 74 72 69 6e 67 20 7b 76 61 72  bble_string {var
2720: 6e 61 6d 65 20 6e 4c 65 6e 67 74 68 7d 20 7b 0a  name nLength} {.
2730: 20 20 75 70 76 61 72 20 24 76 61 72 6e 61 6d 65    upvar $varname
2740: 20 62 6c 6f 62 0a 20 20 73 65 74 20 72 65 74 20   blob.  set ret 
2750: 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 62  [string range $b
2760: 6c 6f 62 20 30 20 5b 65 78 70 72 20 24 6e 4c 65  lob 0 [expr $nLe
2770: 6e 67 74 68 2d 31 5d 5d 0a 20 20 73 65 74 20 62  ngth-1]].  set b
2780: 6c 6f 62 20 5b 73 74 72 69 6e 67 20 72 61 6e 67  lob [string rang
2790: 65 20 24 62 6c 6f 62 20 24 6e 4c 65 6e 67 74 68  e $blob $nLength
27a0: 20 65 6e 64 5d 0a 20 20 72 65 74 75 72 6e 20 24   end].  return $
27b0: 72 65 74 0a 7d 0a 0a 23 20 54 68 65 20 61 72 67  ret.}..# The arg
27c0: 75 6d 65 6e 74 20 69 73 20 61 20 62 6c 6f 62 20  ument is a blob 
27d0: 6f 66 20 64 61 74 61 20 72 65 70 72 65 73 65 6e  of data represen
27e0: 74 69 6e 67 20 61 6e 20 46 54 53 33 20 73 65 67  ting an FTS3 seg
27f0: 6d 65 6e 74 20 6c 65 61 66 2e 20 0a 23 20 52 65  ment leaf. .# Re
2800: 74 75 72 6e 20 61 20 6c 69 73 74 20 63 6f 6e 73  turn a list cons
2810: 69 73 74 69 6e 67 20 6f 66 20 61 6c 74 65 72 6e  isting of altern
2820: 61 74 69 6e 67 20 74 65 72 6d 73 20 28 73 74 72  ating terms (str
2830: 69 6e 67 73 29 20 61 6e 64 20 64 6f 63 6c 69 73  ings) and doclis
2840: 74 73 0a 23 20 28 62 6c 6f 62 73 20 6f 66 20 64  ts.# (blobs of d
2850: 61 74 61 29 2e 0a 23 0a 70 72 6f 63 20 66 74 73  ata)..#.proc fts
2860: 33 5f 72 65 61 64 6c 65 61 66 20 7b 62 6c 6f 62  3_readleaf {blob
2870: 7d 20 7b 0a 20 20 73 65 74 20 7a 50 72 65 76 20  } {.  set zPrev 
2880: 22 22 0a 20 20 73 65 74 20 74 65 72 6d 73 20 5b  "".  set terms [
2890: 6c 69 73 74 5d 0a 0a 20 20 77 68 69 6c 65 20 7b  list]..  while {
28a0: 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24  [string length $
28b0: 62 6c 6f 62 5d 20 3e 20 30 7d 20 7b 0a 20 20 20  blob] > 0} {.   
28c0: 20 73 65 74 20 6e 50 72 65 66 69 78 20 5b 67 6f   set nPrefix [go
28d0: 62 62 6c 65 5f 76 61 72 69 6e 74 20 62 6c 6f 62  bble_varint blob
28e0: 5d 0a 20 20 20 20 73 65 74 20 6e 53 75 66 66 69  ].    set nSuffi
28f0: 78 20 5b 67 6f 62 62 6c 65 5f 76 61 72 69 6e 74  x [gobble_varint
2900: 20 62 6c 6f 62 5d 0a 0a 20 20 20 20 73 65 74 20   blob]..    set 
2910: 7a 54 65 72 6d 20 5b 73 74 72 69 6e 67 20 72 61  zTerm [string ra
2920: 6e 67 65 20 24 7a 50 72 65 76 20 30 20 5b 65 78  nge $zPrev 0 [ex
2930: 70 72 20 24 6e 50 72 65 66 69 78 2d 31 5d 5d 0a  pr $nPrefix-1]].
2940: 20 20 20 20 61 70 70 65 6e 64 20 7a 54 65 72 6d      append zTerm
2950: 20 5b 67 6f 62 62 6c 65 5f 73 74 72 69 6e 67 20   [gobble_string 
2960: 62 6c 6f 62 20 24 6e 53 75 66 66 69 78 5d 0a 20  blob $nSuffix]. 
2970: 20 20 20 73 65 74 20 6e 44 6f 63 6c 69 73 74 20     set nDoclist 
2980: 5b 67 6f 62 62 6c 65 5f 76 61 72 69 6e 74 20 62  [gobble_varint b
2990: 6c 6f 62 5d 0a 20 20 20 20 73 65 74 20 64 6f 63  lob].    set doc
29a0: 6c 69 73 74 20 5b 67 6f 62 62 6c 65 5f 73 74 72  list [gobble_str
29b0: 69 6e 67 20 62 6c 6f 62 20 24 6e 44 6f 63 6c 69  ing blob $nDocli
29c0: 73 74 5d 0a 0a 20 20 20 20 6c 61 70 70 65 6e 64  st]..    lappend
29d0: 20 74 65 72 6d 73 20 24 7a 54 65 72 6d 20 24 64   terms $zTerm $d
29e0: 6f 63 6c 69 73 74 0a 20 20 20 20 73 65 74 20 7a  oclist.    set z
29f0: 50 72 65 76 20 24 7a 54 65 72 6d 0a 20 20 7d 0a  Prev $zTerm.  }.
2a00: 0a 20 20 72 65 74 75 72 6e 20 24 74 65 72 6d 73  .  return $terms
2a10: 0a 7d 0a 0a 70 72 6f 63 20 66 74 73 33 5f 72 65  .}..proc fts3_re
2a20: 61 64 32 20 7b 74 62 6c 20 77 68 65 72 65 20 76  ad2 {tbl where v
2a30: 61 72 6e 61 6d 65 7d 20 7b 0a 20 20 75 70 76 61  arname} {.  upva
2a40: 72 20 24 76 61 72 6e 61 6d 65 20 61 0a 20 20 61  r $varname a.  a
2a50: 72 72 61 79 20 75 6e 73 65 74 20 61 0a 20 20 64  rray unset a.  d
2a60: 62 20 65 76 61 6c 20 22 20 53 45 4c 45 43 54 20  b eval " SELECT 
2a70: 73 74 61 72 74 5f 62 6c 6f 63 6b 2c 20 6c 65 61  start_block, lea
2a80: 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 6b 2c 20 72  ves_end_block, r
2a90: 6f 6f 74 20 0a 20 20 20 20 20 20 20 20 20 20 20  oot .           
2aa0: 20 46 52 4f 4d 20 24 7b 74 62 6c 7d 5f 73 65 67   FROM ${tbl}_seg
2ab0: 64 69 72 20 57 48 45 52 45 20 24 77 68 65 72 65  dir WHERE $where
2ac0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 4f 52 44  .            ORD
2ad0: 45 52 20 42 59 20 6c 65 76 65 6c 20 41 53 43 2c  ER BY level ASC,
2ae0: 20 69 64 78 20 44 45 53 43 0a 20 20 22 20 7b 0a   idx DESC.  " {.
2af0: 20 20 20 20 73 65 74 20 63 20 30 0a 20 20 20 20      set c 0.    
2b00: 62 69 6e 61 72 79 20 73 63 61 6e 20 24 72 6f 6f  binary scan $roo
2b10: 74 20 63 20 63 0a 20 20 20 20 69 66 20 7b 24 63  t c c.    if {$c
2b20: 3d 3d 30 7d 20 7b 0a 20 20 20 20 20 20 66 6f 72  ==0} {.      for
2b30: 65 61 63 68 20 7b 74 20 64 7d 20 5b 66 74 73 33  each {t d} [fts3
2b40: 5f 72 65 61 64 6c 65 61 66 20 24 72 6f 6f 74 5d  _readleaf $root]
2b50: 20 7b 20 6c 61 70 70 65 6e 64 20 61 28 24 74 29   { lappend a($t)
2b60: 20 24 64 20 7d 0a 20 20 20 20 7d 20 65 6c 73 65   $d }.    } else
2b70: 20 7b 0a 20 20 20 20 20 20 64 62 20 65 76 61 6c   {.      db eval
2b80: 20 22 20 53 45 4c 45 43 54 20 62 6c 6f 63 6b 20   " SELECT block 
2b90: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2ba0: 20 46 52 4f 4d 20 24 7b 74 62 6c 7d 5f 73 65 67   FROM ${tbl}_seg
2bb0: 6d 65 6e 74 73 20 0a 20 20 20 20 20 20 20 20 20  ments .         
2bc0: 20 20 20 20 20 20 20 57 48 45 52 45 20 62 6c 6f         WHERE blo
2bd0: 63 6b 69 64 3e 3d 24 73 74 61 72 74 5f 62 6c 6f  ckid>=$start_blo
2be0: 63 6b 20 41 4e 44 20 62 6c 6f 63 6b 69 64 3c 3d  ck AND blockid<=
2bf0: 24 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63  $leaves_end_bloc
2c00: 6b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k.              
2c10: 20 20 4f 52 44 45 52 20 42 59 20 62 6c 6f 63 6b    ORDER BY block
2c20: 69 64 0a 20 20 20 20 20 20 22 20 7b 0a 20 20 20  id.      " {.   
2c30: 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b 74 20       foreach {t 
2c40: 64 7d 20 5b 66 74 73 33 5f 72 65 61 64 6c 65 61  d} [fts3_readlea
2c50: 66 20 24 62 6c 6f 63 6b 5d 20 7b 20 6c 61 70 70  f $block] { lapp
2c60: 65 6e 64 20 61 28 24 74 29 20 24 64 20 7d 0a 20  end a($t) $d }. 
2c70: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
2c80: 0a 7d 0a 0a 70 72 6f 63 20 66 74 73 33 5f 72 65  .}..proc fts3_re
2c90: 61 64 20 7b 74 62 6c 20 77 68 65 72 65 20 76 61  ad {tbl where va
2ca0: 72 6e 61 6d 65 7d 20 7b 0a 20 20 75 70 76 61 72  rname} {.  upvar
2cb0: 20 24 76 61 72 6e 61 6d 65 20 61 0a 20 20 61 72   $varname a.  ar
2cc0: 72 61 79 20 75 6e 73 65 74 20 61 0a 20 20 64 62  ray unset a.  db
2cd0: 20 65 76 61 6c 20 22 20 53 45 4c 45 43 54 20 73   eval " SELECT s
2ce0: 74 61 72 74 5f 62 6c 6f 63 6b 2c 20 6c 65 61 76  tart_block, leav
2cf0: 65 73 5f 65 6e 64 5f 62 6c 6f 63 6b 2c 20 72 6f  es_end_block, ro
2d00: 6f 74 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  ot .            
2d10: 46 52 4f 4d 20 24 7b 74 62 6c 7d 5f 73 65 67 64  FROM ${tbl}_segd
2d20: 69 72 20 57 48 45 52 45 20 24 77 68 65 72 65 0a  ir WHERE $where.
2d30: 20 20 20 20 20 20 20 20 20 20 20 20 4f 52 44 45              ORDE
2d40: 52 20 42 59 20 6c 65 76 65 6c 20 44 45 53 43 2c  R BY level DESC,
2d50: 20 69 64 78 20 41 53 43 0a 20 20 22 20 7b 0a 20   idx ASC.  " {. 
2d60: 20 20 20 69 66 20 7b 24 73 74 61 72 74 5f 62 6c     if {$start_bl
2d70: 6f 63 6b 20 3d 3d 20 30 7d 20 7b 0a 20 20 20 20  ock == 0} {.    
2d80: 20 20 66 6f 72 65 61 63 68 20 7b 74 20 64 7d 20    foreach {t d} 
2d90: 5b 66 74 73 33 5f 72 65 61 64 6c 65 61 66 20 24  [fts3_readleaf $
2da0: 72 6f 6f 74 5d 20 7b 20 6c 61 70 70 65 6e 64 20  root] { lappend 
2db0: 61 28 24 74 29 20 24 64 20 7d 0a 20 20 20 20 7d  a($t) $d }.    }
2dc0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 64 62   else {.      db
2dd0: 20 65 76 61 6c 20 22 20 53 45 4c 45 43 54 20 62   eval " SELECT b
2de0: 6c 6f 63 6b 20 0a 20 20 20 20 20 20 20 20 20 20  lock .          
2df0: 20 20 20 20 20 20 46 52 4f 4d 20 24 7b 74 62 6c        FROM ${tbl
2e00: 7d 5f 73 65 67 6d 65 6e 74 73 20 0a 20 20 20 20  }_segments .    
2e10: 20 20 20 20 20 20 20 20 20 20 20 20 57 48 45 52              WHER
2e20: 45 20 62 6c 6f 63 6b 69 64 3e 3d 24 73 74 61 72  E blockid>=$star
2e30: 74 5f 62 6c 6f 63 6b 20 41 4e 44 20 62 6c 6f 63  t_block AND bloc
2e40: 6b 69 64 3c 24 6c 65 61 76 65 73 5f 65 6e 64 5f  kid<$leaves_end_
2e50: 62 6c 6f 63 6b 0a 20 20 20 20 20 20 20 20 20 20  block.          
2e60: 20 20 20 20 20 20 4f 52 44 45 52 20 42 59 20 62        ORDER BY b
2e70: 6c 6f 63 6b 69 64 0a 20 20 20 20 20 20 22 20 7b  lockid.      " {
2e80: 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68  .        foreach
2e90: 20 7b 74 20 64 7d 20 5b 66 74 73 33 5f 72 65 61   {t d} [fts3_rea
2ea0: 64 6c 65 61 66 20 24 62 6c 6f 63 6b 5d 20 7b 20  dleaf $block] { 
2eb0: 6c 61 70 70 65 6e 64 20 61 28 24 74 29 20 24 64  lappend a($t) $d
2ec0: 20 7d 0a 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   }..      }.    
2ed0: 7d 0a 20 20 7d 0a 7d 0a 0a 23 23 23 23 23 23 23  }.  }.}..#######
2ee0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
2ef0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
2f00: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
2f10: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
2f20: 23 23 23 0a 0a                                   ###..