/ Hex Artifact Content
Login

Artifact b01c584144b5064f30e6c648145a2dd6bc440841:


0000: 23 20 32 30 31 34 20 44 65 63 20 31 39 0a 23 0a  # 2014 Dec 19.#.
0010: 23 20 54 68 65 20 61 75 74 68 6f 72 20 64 69 73  # The author dis
0020: 63 6c 61 69 6d 73 20 63 6f 70 79 72 69 67 68 74  claims copyright
0030: 20 74 6f 20 74 68 69 73 20 73 6f 75 72 63 65 20   to this source 
0040: 63 6f 64 65 2e 20 20 49 6e 20 70 6c 61 63 65 20  code.  In place 
0050: 6f 66 0a 23 20 61 20 6c 65 67 61 6c 20 6e 6f 74  of.# a legal not
0060: 69 63 65 2c 20 68 65 72 65 20 69 73 20 61 20 62  ice, here is a b
0070: 6c 65 73 73 69 6e 67 3a 0a 23 0a 23 20 20 20 20  lessing:.#.#    
0080: 4d 61 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20  May you do good 
0090: 61 6e 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 23 20  and not evil..# 
00a0: 20 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20     May you find 
00b0: 66 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20  forgiveness for 
00c0: 79 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72  yourself and for
00d0: 67 69 76 65 20 6f 74 68 65 72 73 2e 0a 23 20 20  give others..#  
00e0: 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20    May you share 
00f0: 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61  freely, never ta
0100: 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79  king more than y
0110: 6f 75 20 67 69 76 65 2e 0a 23 0a 23 2a 2a 2a 2a  ou give..#.#****
0120: 2a 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 0a 23 0a 0a 69 66 20 7b 21 5b 69 6e 66  ***.#..if {![inf
0170: 6f 20 65 78 69 73 74 73 20 74 65 73 74 64 69 72  o exists testdir
0180: 5d 7d 20 7b 0a 20 20 73 65 74 20 74 65 73 74 64  ]} {.  set testd
0190: 69 72 20 5b 66 69 6c 65 20 6a 6f 69 6e 20 5b 66  ir [file join [f
01a0: 69 6c 65 20 64 69 72 6e 61 6d 65 20 5b 69 6e 66  ile dirname [inf
01b0: 6f 20 73 63 72 69 70 74 5d 5d 20 2e 2e 20 2e 2e  o script]] .. ..
01c0: 20 2e 2e 20 74 65 73 74 5d 0a 7d 0a 73 6f 75 72   .. test].}.sour
01d0: 63 65 20 24 74 65 73 74 64 69 72 2f 74 65 73 74  ce $testdir/test
01e0: 65 72 2e 74 63 6c 0a 0a 69 66 63 61 70 61 62 6c  er.tcl..ifcapabl
01f0: 65 20 21 66 74 73 35 20 7b 0a 20 20 70 72 6f 63  e !fts5 {.  proc
0200: 20 72 65 74 75 72 6e 5f 69 66 5f 6e 6f 5f 66 74   return_if_no_ft
0210: 73 35 20 7b 7d 20 7b 0a 20 20 20 20 66 69 6e 69  s5 {} {.    fini
0220: 73 68 5f 74 65 73 74 0a 20 20 20 20 72 65 74 75  sh_test.    retu
0230: 72 6e 20 2d 63 6f 64 65 20 72 65 74 75 72 6e 0a  rn -code return.
0240: 20 20 7d 0a 20 20 72 65 74 75 72 6e 0a 7d 20 65    }.  return.} e
0250: 6c 73 65 20 7b 0a 20 20 70 72 6f 63 20 72 65 74  lse {.  proc ret
0260: 75 72 6e 5f 69 66 5f 6e 6f 5f 66 74 73 35 20 7b  urn_if_no_fts5 {
0270: 7d 20 7b 7d 0a 7d 0a 0a 63 61 74 63 68 20 7b 20  } {}.}..catch { 
0280: 0a 20 20 73 71 6c 69 74 65 33 5f 66 74 73 35 5f  .  sqlite3_fts5_
0290: 6d 61 79 5f 62 65 5f 63 6f 72 72 75 70 74 20 30  may_be_corrupt 0
02a0: 20 0a 20 20 72 65 73 65 74 5f 64 62 0a 7d 0a 0a   .  reset_db.}..
02b0: 70 72 6f 63 20 66 74 73 35 5f 74 65 73 74 5f 70  proc fts5_test_p
02c0: 6f 73 6c 69 73 74 20 7b 63 6d 64 7d 20 7b 0a 20  oslist {cmd} {. 
02d0: 20 73 65 74 20 72 65 73 20 5b 6c 69 73 74 5d 0a   set res [list].
02e0: 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20    for {set i 0} 
02f0: 7b 24 69 20 3c 20 5b 24 63 6d 64 20 78 49 6e 73  {$i < [$cmd xIns
0300: 74 43 6f 75 6e 74 5d 7d 20 7b 69 6e 63 72 20 69  tCount]} {incr i
0310: 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65 6e 64 20  } {.    lappend 
0320: 72 65 73 20 5b 73 74 72 69 6e 67 20 6d 61 70 20  res [string map 
0330: 7b 7b 20 7d 20 2e 7d 20 5b 24 63 6d 64 20 78 49  {{ } .} [$cmd xI
0340: 6e 73 74 20 24 69 5d 5d 0a 20 20 7d 0a 20 20 73  nst $i]].  }.  s
0350: 65 74 20 72 65 73 0a 7d 0a 0a 70 72 6f 63 20 66  et res.}..proc f
0360: 74 73 35 5f 74 65 73 74 5f 70 6f 73 6c 69 73 74  ts5_test_poslist
0370: 32 20 7b 63 6d 64 7d 20 7b 0a 20 20 73 65 74 20  2 {cmd} {.  set 
0380: 72 65 73 20 5b 6c 69 73 74 5d 0a 0a 20 20 66 6f  res [list]..  fo
0390: 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20  r {set i 0} {$i 
03a0: 3c 20 5b 24 63 6d 64 20 78 50 68 72 61 73 65 43  < [$cmd xPhraseC
03b0: 6f 75 6e 74 5d 7d 20 7b 69 6e 63 72 20 69 7d 20  ount]} {incr i} 
03c0: 7b 0a 20 20 20 20 24 63 6d 64 20 78 50 68 72 61  {.    $cmd xPhra
03d0: 73 65 46 6f 72 65 61 63 68 20 24 69 20 63 20 6f  seForeach $i c o
03e0: 20 7b 0a 20 20 20 20 20 20 6c 61 70 70 65 6e 64   {.      lappend
03f0: 20 72 65 73 20 24 69 2e 24 63 2e 24 6f 0a 20 20   res $i.$c.$o.  
0400: 20 20 7d 0a 20 20 7d 0a 0a 20 20 23 73 65 74 20    }.  }..  #set 
0410: 72 65 73 0a 20 20 73 6f 72 74 5f 70 6f 73 6c 69  res.  sort_posli
0420: 73 74 20 24 72 65 73 0a 7d 0a 0a 70 72 6f 63 20  st $res.}..proc 
0430: 66 74 73 35 5f 74 65 73 74 5f 63 6f 6c 6c 69 73  fts5_test_collis
0440: 74 20 7b 63 6d 64 7d 20 7b 0a 20 20 73 65 74 20  t {cmd} {.  set 
0450: 72 65 73 20 5b 6c 69 73 74 5d 0a 0a 20 20 66 6f  res [list]..  fo
0460: 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20  r {set i 0} {$i 
0470: 3c 20 5b 24 63 6d 64 20 78 50 68 72 61 73 65 43  < [$cmd xPhraseC
0480: 6f 75 6e 74 5d 7d 20 7b 69 6e 63 72 20 69 7d 20  ount]} {incr i} 
0490: 7b 0a 20 20 20 20 24 63 6d 64 20 78 50 68 72 61  {.    $cmd xPhra
04a0: 73 65 43 6f 6c 75 6d 6e 46 6f 72 65 61 63 68 20  seColumnForeach 
04b0: 24 69 20 63 20 7b 20 6c 61 70 70 65 6e 64 20 72  $i c { lappend r
04c0: 65 73 20 24 69 2e 24 63 20 7d 0a 20 20 7d 0a 0a  es $i.$c }.  }..
04d0: 20 20 73 65 74 20 72 65 73 0a 7d 0a 0a 70 72 6f    set res.}..pro
04e0: 63 20 66 74 73 35 5f 74 65 73 74 5f 63 6f 6c 75  c fts5_test_colu
04f0: 6d 6e 73 69 7a 65 20 7b 63 6d 64 7d 20 7b 0a 20  mnsize {cmd} {. 
0500: 20 73 65 74 20 72 65 73 20 5b 6c 69 73 74 5d 0a   set res [list].
0510: 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20    for {set i 0} 
0520: 7b 24 69 20 3c 20 5b 24 63 6d 64 20 78 43 6f 6c  {$i < [$cmd xCol
0530: 75 6d 6e 43 6f 75 6e 74 5d 7d 20 7b 69 6e 63 72  umnCount]} {incr
0540: 20 69 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65 6e   i} {.    lappen
0550: 64 20 72 65 73 20 5b 24 63 6d 64 20 78 43 6f 6c  d res [$cmd xCol
0560: 75 6d 6e 53 69 7a 65 20 24 69 5d 0a 20 20 7d 0a  umnSize $i].  }.
0570: 20 20 73 65 74 20 72 65 73 0a 7d 0a 0a 70 72 6f    set res.}..pro
0580: 63 20 66 74 73 35 5f 74 65 73 74 5f 63 6f 6c 75  c fts5_test_colu
0590: 6d 6e 74 65 78 74 20 7b 63 6d 64 7d 20 7b 0a 20  mntext {cmd} {. 
05a0: 20 73 65 74 20 72 65 73 20 5b 6c 69 73 74 5d 0a   set res [list].
05b0: 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20    for {set i 0} 
05c0: 7b 24 69 20 3c 20 5b 24 63 6d 64 20 78 43 6f 6c  {$i < [$cmd xCol
05d0: 75 6d 6e 43 6f 75 6e 74 5d 7d 20 7b 69 6e 63 72  umnCount]} {incr
05e0: 20 69 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65 6e   i} {.    lappen
05f0: 64 20 72 65 73 20 5b 24 63 6d 64 20 78 43 6f 6c  d res [$cmd xCol
0600: 75 6d 6e 54 65 78 74 20 24 69 5d 0a 20 20 7d 0a  umnText $i].  }.
0610: 20 20 73 65 74 20 72 65 73 0a 7d 0a 0a 70 72 6f    set res.}..pro
0620: 63 20 66 74 73 35 5f 74 65 73 74 5f 63 6f 6c 75  c fts5_test_colu
0630: 6d 6e 74 6f 74 61 6c 73 69 7a 65 20 7b 63 6d 64  mntotalsize {cmd
0640: 7d 20 7b 0a 20 20 73 65 74 20 72 65 73 20 5b 6c  } {.  set res [l
0650: 69 73 74 5d 0a 20 20 66 6f 72 20 7b 73 65 74 20  ist].  for {set 
0660: 69 20 30 7d 20 7b 24 69 20 3c 20 5b 24 63 6d 64  i 0} {$i < [$cmd
0670: 20 78 43 6f 6c 75 6d 6e 43 6f 75 6e 74 5d 7d 20   xColumnCount]} 
0680: 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 6c  {incr i} {.    l
0690: 61 70 70 65 6e 64 20 72 65 73 20 5b 24 63 6d 64  append res [$cmd
06a0: 20 78 43 6f 6c 75 6d 6e 54 6f 74 61 6c 53 69 7a   xColumnTotalSiz
06b0: 65 20 24 69 5d 0a 20 20 7d 0a 20 20 73 65 74 20  e $i].  }.  set 
06c0: 72 65 73 0a 7d 0a 0a 70 72 6f 63 20 74 65 73 74  res.}..proc test
06d0: 5f 61 70 70 65 6e 64 5f 74 6f 6b 65 6e 20 7b 76  _append_token {v
06e0: 61 72 6e 61 6d 65 20 74 6f 6b 65 6e 20 69 53 74  arname token iSt
06f0: 61 72 74 20 69 45 6e 64 7d 20 7b 0a 20 20 75 70  art iEnd} {.  up
0700: 76 61 72 20 24 76 61 72 6e 61 6d 65 20 76 61 72  var $varname var
0710: 0a 20 20 6c 61 70 70 65 6e 64 20 76 61 72 20 24  .  lappend var $
0720: 74 6f 6b 65 6e 0a 20 20 72 65 74 75 72 6e 20 22  token.  return "
0730: 53 51 4c 49 54 45 5f 4f 4b 22 0a 7d 0a 70 72 6f  SQLITE_OK".}.pro
0740: 63 20 66 74 73 35 5f 74 65 73 74 5f 74 6f 6b 65  c fts5_test_toke
0750: 6e 69 7a 65 20 7b 63 6d 64 7d 20 7b 0a 20 20 73  nize {cmd} {.  s
0760: 65 74 20 72 65 73 20 5b 6c 69 73 74 5d 0a 20 20  et res [list].  
0770: 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24  for {set i 0} {$
0780: 69 20 3c 20 5b 24 63 6d 64 20 78 43 6f 6c 75 6d  i < [$cmd xColum
0790: 6e 43 6f 75 6e 74 5d 7d 20 7b 69 6e 63 72 20 69  nCount]} {incr i
07a0: 7d 20 7b 0a 20 20 20 20 73 65 74 20 74 6f 6b 65  } {.    set toke
07b0: 6e 73 20 5b 6c 69 73 74 5d 0a 20 20 20 20 24 63  ns [list].    $c
07c0: 6d 64 20 78 54 6f 6b 65 6e 69 7a 65 20 5b 24 63  md xTokenize [$c
07d0: 6d 64 20 78 43 6f 6c 75 6d 6e 54 65 78 74 20 24  md xColumnText $
07e0: 69 5d 20 5b 6c 69 73 74 20 74 65 73 74 5f 61 70  i] [list test_ap
07f0: 70 65 6e 64 5f 74 6f 6b 65 6e 20 74 6f 6b 65 6e  pend_token token
0800: 73 5d 0a 20 20 20 20 6c 61 70 70 65 6e 64 20 72  s].    lappend r
0810: 65 73 20 24 74 6f 6b 65 6e 73 0a 20 20 7d 0a 20  es $tokens.  }. 
0820: 20 73 65 74 20 72 65 73 0a 7d 0a 0a 70 72 6f 63   set res.}..proc
0830: 20 66 74 73 35 5f 74 65 73 74 5f 72 6f 77 63 6f   fts5_test_rowco
0840: 75 6e 74 20 7b 63 6d 64 7d 20 7b 0a 20 20 24 63  unt {cmd} {.  $c
0850: 6d 64 20 78 52 6f 77 43 6f 75 6e 74 0a 7d 0a 0a  md xRowCount.}..
0860: 70 72 6f 63 20 74 65 73 74 5f 71 75 65 72 79 70  proc test_queryp
0870: 68 72 61 73 65 5f 63 62 20 7b 63 6e 74 20 63 6d  hrase_cb {cnt cm
0880: 64 7d 20 7b 0a 20 20 75 70 76 61 72 20 24 63 6e  d} {.  upvar $cn
0890: 74 20 4c 20 0a 20 20 66 6f 72 20 7b 73 65 74 20  t L .  for {set 
08a0: 69 20 30 7d 20 7b 24 69 20 3c 20 5b 24 63 6d 64  i 0} {$i < [$cmd
08b0: 20 78 49 6e 73 74 43 6f 75 6e 74 5d 7d 20 7b 69   xInstCount]} {i
08c0: 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 66 6f 72  ncr i} {.    for
08d0: 65 61 63 68 20 7b 69 70 20 69 63 20 69 6f 7d 20  each {ip ic io} 
08e0: 5b 24 63 6d 64 20 78 49 6e 73 74 20 24 69 5d 20  [$cmd xInst $i] 
08f0: 62 72 65 61 6b 0a 20 20 20 20 73 65 74 20 41 28  break.    set A(
0900: 24 69 63 29 20 31 0a 20 20 7d 0a 20 20 66 6f 72  $ic) 1.  }.  for
0910: 65 61 63 68 20 69 63 20 5b 61 72 72 61 79 20 6e  each ic [array n
0920: 61 6d 65 73 20 41 5d 20 7b 0a 20 20 20 20 6c 73  ames A] {.    ls
0930: 65 74 20 4c 20 24 69 63 20 5b 65 78 70 72 20 7b  et L $ic [expr {
0940: 5b 6c 69 6e 64 65 78 20 24 4c 20 24 69 63 5d 20  [lindex $L $ic] 
0950: 2b 20 31 7d 5d 0a 20 20 7d 0a 7d 0a 70 72 6f 63  + 1}].  }.}.proc
0960: 20 66 74 73 35 5f 74 65 73 74 5f 71 75 65 72 79   fts5_test_query
0970: 70 68 72 61 73 65 20 7b 63 6d 64 7d 20 7b 0a 20  phrase {cmd} {. 
0980: 20 73 65 74 20 72 65 73 20 5b 6c 69 73 74 5d 0a   set res [list].
0990: 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20    for {set i 0} 
09a0: 7b 24 69 20 3c 20 5b 24 63 6d 64 20 78 50 68 72  {$i < [$cmd xPhr
09b0: 61 73 65 43 6f 75 6e 74 5d 7d 20 7b 69 6e 63 72  aseCount]} {incr
09c0: 20 69 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 6e   i} {.    set cn
09d0: 74 20 5b 6c 69 73 74 5d 0a 20 20 20 20 66 6f 72  t [list].    for
09e0: 20 7b 73 65 74 20 6a 20 30 7d 20 7b 24 6a 20 3c   {set j 0} {$j <
09f0: 20 5b 24 63 6d 64 20 78 43 6f 6c 75 6d 6e 43 6f   [$cmd xColumnCo
0a00: 75 6e 74 5d 7d 20 7b 69 6e 63 72 20 6a 7d 20 7b  unt]} {incr j} {
0a10: 20 6c 61 70 70 65 6e 64 20 63 6e 74 20 30 20 7d   lappend cnt 0 }
0a20: 0a 20 20 20 20 24 63 6d 64 20 78 51 75 65 72 79  .    $cmd xQuery
0a30: 50 68 72 61 73 65 20 24 69 20 5b 6c 69 73 74 20  Phrase $i [list 
0a40: 74 65 73 74 5f 71 75 65 72 79 70 68 72 61 73 65  test_queryphrase
0a50: 5f 63 62 20 63 6e 74 5d 0a 20 20 20 20 6c 61 70  _cb cnt].    lap
0a60: 70 65 6e 64 20 72 65 73 20 24 63 6e 74 0a 20 20  pend res $cnt.  
0a70: 7d 0a 20 20 73 65 74 20 72 65 73 0a 7d 0a 0a 70  }.  set res.}..p
0a80: 72 6f 63 20 66 74 73 35 5f 74 65 73 74 5f 70 68  roc fts5_test_ph
0a90: 72 61 73 65 63 6f 75 6e 74 20 7b 63 6d 64 7d 20  rasecount {cmd} 
0aa0: 7b 0a 20 20 24 63 6d 64 20 78 50 68 72 61 73 65  {.  $cmd xPhrase
0ab0: 43 6f 75 6e 74 0a 7d 0a 0a 70 72 6f 63 20 66 74  Count.}..proc ft
0ac0: 73 35 5f 74 65 73 74 5f 61 6c 6c 20 7b 63 6d 64  s5_test_all {cmd
0ad0: 7d 20 7b 0a 20 20 73 65 74 20 72 65 73 20 5b 6c  } {.  set res [l
0ae0: 69 73 74 5d 0a 20 20 6c 61 70 70 65 6e 64 20 72  ist].  lappend r
0af0: 65 73 20 63 6f 6c 75 6d 6e 73 69 7a 65 20 20 20  es columnsize   
0b00: 20 20 20 5b 66 74 73 35 5f 74 65 73 74 5f 63 6f     [fts5_test_co
0b10: 6c 75 6d 6e 73 69 7a 65 20 24 63 6d 64 5d 0a 20  lumnsize $cmd]. 
0b20: 20 6c 61 70 70 65 6e 64 20 72 65 73 20 63 6f 6c   lappend res col
0b30: 75 6d 6e 74 65 78 74 20 20 20 20 20 20 5b 66 74  umntext      [ft
0b40: 73 35 5f 74 65 73 74 5f 63 6f 6c 75 6d 6e 74 65  s5_test_columnte
0b50: 78 74 20 24 63 6d 64 5d 0a 20 20 6c 61 70 70 65  xt $cmd].  lappe
0b60: 6e 64 20 72 65 73 20 63 6f 6c 75 6d 6e 74 6f 74  nd res columntot
0b70: 61 6c 73 69 7a 65 20 5b 66 74 73 35 5f 74 65 73  alsize [fts5_tes
0b80: 74 5f 63 6f 6c 75 6d 6e 74 6f 74 61 6c 73 69 7a  t_columntotalsiz
0b90: 65 20 24 63 6d 64 5d 0a 20 20 6c 61 70 70 65 6e  e $cmd].  lappen
0ba0: 64 20 72 65 73 20 70 6f 73 6c 69 73 74 20 20 20  d res poslist   
0bb0: 20 20 20 20 20 20 5b 66 74 73 35 5f 74 65 73 74        [fts5_test
0bc0: 5f 70 6f 73 6c 69 73 74 20 24 63 6d 64 5d 0a 20  _poslist $cmd]. 
0bd0: 20 6c 61 70 70 65 6e 64 20 72 65 73 20 74 6f 6b   lappend res tok
0be0: 65 6e 69 7a 65 20 20 20 20 20 20 20 20 5b 66 74  enize        [ft
0bf0: 73 35 5f 74 65 73 74 5f 74 6f 6b 65 6e 69 7a 65  s5_test_tokenize
0c00: 20 24 63 6d 64 5d 0a 20 20 6c 61 70 70 65 6e 64   $cmd].  lappend
0c10: 20 72 65 73 20 72 6f 77 63 6f 75 6e 74 20 20 20   res rowcount   
0c20: 20 20 20 20 20 5b 66 74 73 35 5f 74 65 73 74 5f       [fts5_test_
0c30: 72 6f 77 63 6f 75 6e 74 20 24 63 6d 64 5d 0a 20  rowcount $cmd]. 
0c40: 20 73 65 74 20 72 65 73 0a 7d 0a 0a 70 72 6f 63   set res.}..proc
0c50: 20 66 74 73 35 5f 61 75 78 5f 74 65 73 74 5f 66   fts5_aux_test_f
0c60: 75 6e 63 74 69 6f 6e 73 20 7b 64 62 7d 20 7b 0a  unctions {db} {.
0c70: 20 20 66 6f 72 65 61 63 68 20 66 20 7b 0a 20 20    foreach f {.  
0c80: 20 20 66 74 73 35 5f 74 65 73 74 5f 63 6f 6c 75    fts5_test_colu
0c90: 6d 6e 73 69 7a 65 0a 20 20 20 20 66 74 73 35 5f  mnsize.    fts5_
0ca0: 74 65 73 74 5f 63 6f 6c 75 6d 6e 74 65 78 74 0a  test_columntext.
0cb0: 20 20 20 20 66 74 73 35 5f 74 65 73 74 5f 63 6f      fts5_test_co
0cc0: 6c 75 6d 6e 74 6f 74 61 6c 73 69 7a 65 0a 20 20  lumntotalsize.  
0cd0: 20 20 66 74 73 35 5f 74 65 73 74 5f 70 6f 73 6c    fts5_test_posl
0ce0: 69 73 74 0a 20 20 20 20 66 74 73 35 5f 74 65 73  ist.    fts5_tes
0cf0: 74 5f 70 6f 73 6c 69 73 74 32 0a 20 20 20 20 66  t_poslist2.    f
0d00: 74 73 35 5f 74 65 73 74 5f 63 6f 6c 6c 69 73 74  ts5_test_collist
0d10: 0a 20 20 20 20 66 74 73 35 5f 74 65 73 74 5f 74  .    fts5_test_t
0d20: 6f 6b 65 6e 69 7a 65 0a 20 20 20 20 66 74 73 35  okenize.    fts5
0d30: 5f 74 65 73 74 5f 72 6f 77 63 6f 75 6e 74 0a 20  _test_rowcount. 
0d40: 20 20 20 66 74 73 35 5f 74 65 73 74 5f 61 6c 6c     fts5_test_all
0d50: 0a 0a 20 20 20 20 66 74 73 35 5f 74 65 73 74 5f  ..    fts5_test_
0d60: 71 75 65 72 79 70 68 72 61 73 65 0a 20 20 20 20  queryphrase.    
0d70: 66 74 73 35 5f 74 65 73 74 5f 70 68 72 61 73 65  fts5_test_phrase
0d80: 63 6f 75 6e 74 0a 20 20 7d 20 7b 0a 20 20 20 20  count.  } {.    
0d90: 73 71 6c 69 74 65 33 5f 66 74 73 35 5f 63 72 65  sqlite3_fts5_cre
0da0: 61 74 65 5f 66 75 6e 63 74 69 6f 6e 20 24 64 62  ate_function $db
0db0: 20 24 66 20 24 66 0a 20 20 7d 0a 7d 0a 0a 70 72   $f $f.  }.}..pr
0dc0: 6f 63 20 66 74 73 35 5f 73 65 67 63 6f 75 6e 74  oc fts5_segcount
0dd0: 20 7b 74 62 6c 7d 20 7b 0a 20 20 73 65 74 20 4e   {tbl} {.  set N
0de0: 20 30 0a 20 20 66 6f 72 65 61 63 68 20 6e 20 5b   0.  foreach n [
0df0: 66 74 73 35 5f 6c 65 76 65 6c 5f 73 65 67 73 20  fts5_level_segs 
0e00: 24 74 62 6c 5d 20 7b 20 69 6e 63 72 20 4e 20 24  $tbl] { incr N $
0e10: 6e 20 7d 0a 20 20 73 65 74 20 4e 0a 7d 0a 0a 70  n }.  set N.}..p
0e20: 72 6f 63 20 66 74 73 35 5f 6c 65 76 65 6c 5f 73  roc fts5_level_s
0e30: 65 67 73 20 7b 74 62 6c 7d 20 7b 0a 20 20 73 65  egs {tbl} {.  se
0e40: 74 20 73 71 6c 20 22 53 45 4c 45 43 54 20 66 74  t sql "SELECT ft
0e50: 73 35 5f 64 65 63 6f 64 65 28 72 6f 77 69 64 2c  s5_decode(rowid,
0e60: 62 6c 6f 63 6b 29 20 61 53 20 72 20 46 52 4f 4d  block) aS r FROM
0e70: 20 24 7b 74 62 6c 7d 5f 64 61 74 61 20 57 48 45   ${tbl}_data WHE
0e80: 52 45 20 72 6f 77 69 64 3d 31 30 22 0a 20 20 73  RE rowid=10".  s
0e90: 65 74 20 72 65 74 20 5b 6c 69 73 74 5d 0a 20 20  et ret [list].  
0ea0: 66 6f 72 65 61 63 68 20 4c 20 5b 6c 72 61 6e 67  foreach L [lrang
0eb0: 65 20 5b 64 62 20 6f 6e 65 20 24 73 71 6c 5d 20  e [db one $sql] 
0ec0: 31 20 65 6e 64 5d 20 7b 0a 20 20 20 20 6c 61 70  1 end] {.    lap
0ed0: 70 65 6e 64 20 72 65 74 20 5b 65 78 70 72 20 5b  pend ret [expr [
0ee0: 6c 6c 65 6e 67 74 68 20 24 4c 5d 20 2d 20 33 5d  llength $L] - 3]
0ef0: 0a 20 20 7d 0a 20 20 73 65 74 20 72 65 74 0a 7d  .  }.  set ret.}
0f00: 20 0a 0a 70 72 6f 63 20 66 74 73 35 5f 6c 65 76   ..proc fts5_lev
0f10: 65 6c 5f 73 65 67 69 64 73 20 7b 74 62 6c 7d 20  el_segids {tbl} 
0f20: 7b 0a 20 20 73 65 74 20 73 71 6c 20 22 53 45 4c  {.  set sql "SEL
0f30: 45 43 54 20 66 74 73 35 5f 64 65 63 6f 64 65 28  ECT fts5_decode(
0f40: 72 6f 77 69 64 2c 62 6c 6f 63 6b 29 20 61 53 20  rowid,block) aS 
0f50: 72 20 46 52 4f 4d 20 24 7b 74 62 6c 7d 5f 64 61  r FROM ${tbl}_da
0f60: 74 61 20 57 48 45 52 45 20 72 6f 77 69 64 3d 31  ta WHERE rowid=1
0f70: 30 22 0a 20 20 73 65 74 20 72 65 74 20 5b 6c 69  0".  set ret [li
0f80: 73 74 5d 0a 20 20 66 6f 72 65 61 63 68 20 4c 20  st].  foreach L 
0f90: 5b 6c 72 61 6e 67 65 20 5b 64 62 20 6f 6e 65 20  [lrange [db one 
0fa0: 24 73 71 6c 5d 20 31 20 65 6e 64 5d 20 7b 0a 20  $sql] 1 end] {. 
0fb0: 20 20 20 73 65 74 20 6c 76 6c 20 5b 6c 69 73 74     set lvl [list
0fc0: 5d 0a 20 20 20 20 66 6f 72 65 61 63 68 20 53 20  ].    foreach S 
0fd0: 5b 6c 72 61 6e 67 65 20 24 4c 20 33 20 65 6e 64  [lrange $L 3 end
0fe0: 5d 20 7b 0a 20 20 20 20 20 20 72 65 67 65 78 70  ] {.      regexp
0ff0: 20 7b 69 64 3d 28 5b 31 32 33 34 35 36 37 38 39   {id=([123456789
1000: 30 5d 2a 29 7d 20 24 53 20 2d 3e 20 73 65 67 69  0]*)} $S -> segi
1010: 64 0a 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20  d.      lappend 
1020: 6c 76 6c 20 24 73 65 67 69 64 0a 20 20 20 20 7d  lvl $segid.    }
1030: 0a 20 20 20 20 6c 61 70 70 65 6e 64 20 72 65 74  .    lappend ret
1040: 20 24 6c 76 6c 0a 20 20 7d 0a 20 20 73 65 74 20   $lvl.  }.  set 
1050: 72 65 74 0a 7d 0a 0a 70 72 6f 63 20 66 74 73 35  ret.}..proc fts5
1060: 5f 72 6e 64 64 6f 63 20 7b 6e 7d 20 7b 0a 20 20  _rnddoc {n} {.  
1070: 73 65 74 20 6d 61 70 20 5b 6c 69 73 74 20 30 20  set map [list 0 
1080: 61 20 20 31 20 62 20 20 32 20 63 20 20 33 20 64  a  1 b  2 c  3 d
1090: 20 20 34 20 65 20 20 35 20 66 20 20 36 20 67 20    4 e  5 f  6 g 
10a0: 20 37 20 68 20 20 38 20 69 20 20 39 20 6a 5d 0a   7 h  8 i  9 j].
10b0: 20 20 73 65 74 20 64 6f 63 20 5b 6c 69 73 74 5d    set doc [list]
10c0: 0a 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d  .  for {set i 0}
10d0: 20 7b 24 69 20 3c 20 24 6e 7d 20 7b 69 6e 63 72   {$i < $n} {incr
10e0: 20 69 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65 6e   i} {.    lappen
10f0: 64 20 64 6f 63 20 22 78 5b 73 74 72 69 6e 67 20  d doc "x[string 
1100: 6d 61 70 20 24 6d 61 70 20 5b 66 6f 72 6d 61 74  map $map [format
1110: 20 25 2e 33 64 20 5b 65 78 70 72 20 69 6e 74 28   %.3d [expr int(
1120: 72 61 6e 64 28 29 2a 31 30 30 30 29 5d 5d 5d 22  rand()*1000)]]]"
1130: 0a 20 20 7d 0a 20 20 73 65 74 20 64 6f 63 0a 7d  .  }.  set doc.}
1140: 0a 0a 23 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 2d 2d 2d 2d 2d 2d  ----------------
1170: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1180: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 55  ------------.# U
1190: 73 61 67 65 3a 0a 23 0a 23 20 20 20 6e 65 61 72  sage:.#.#   near
11a0: 73 65 74 20 61 43 6f 6c 20 3f 2d 70 63 20 56 41  set aCol ?-pc VA
11b0: 52 4e 41 4d 45 3f 20 3f 2d 6e 65 61 72 20 4e 3f  RNAME? ?-near N?
11c0: 20 3f 2d 63 6f 6c 20 43 3f 20 2d 2d 20 70 68 72   ?-col C? -- phr
11d0: 61 73 65 31 20 70 68 72 61 73 65 32 2e 2e 2e 0a  ase1 phrase2....
11e0: 23 0a 23 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64  #.# This command
11f0: 20 69 73 20 75 73 65 64 20 74 6f 20 74 65 73 74   is used to test
1200: 20 69 66 20 61 20 64 6f 63 75 6d 65 6e 74 20 28   if a document (
1210: 73 65 74 20 6f 66 20 63 6f 6c 75 6d 6e 20 76 61  set of column va
1220: 6c 75 65 73 29 20 6d 61 74 63 68 65 73 0a 23 20  lues) matches.# 
1230: 74 68 65 20 6c 6f 67 69 63 61 6c 20 65 71 75 69  the logical equi
1240: 76 61 6c 65 6e 74 20 6f 66 20 61 20 73 69 6e 67  valent of a sing
1250: 6c 65 20 46 54 53 35 20 4e 45 41 52 28 29 20 63  le FTS5 NEAR() c
1260: 6c 75 6d 70 20 61 6e 64 2c 20 69 66 20 73 6f 2c  lump and, if so,
1270: 20 72 65 74 75 72 6e 0a 23 20 74 68 65 20 65 71   return.# the eq
1280: 75 69 76 61 6c 65 6e 74 20 6f 66 20 61 6e 20 46  uivalent of an F
1290: 54 53 35 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73  TS5 position lis
12a0: 74 2e 0a 23 0a 23 20 50 61 72 61 6d 65 74 65 72  t..#.# Parameter
12b0: 20 24 61 43 6f 6c 20 69 73 20 70 61 73 73 65 64   $aCol is passed
12c0: 20 61 20 6c 69 73 74 20 6f 66 20 74 68 65 20 63   a list of the c
12d0: 6f 6c 75 6d 6e 20 76 61 6c 75 65 73 20 66 6f 72  olumn values for
12e0: 20 74 68 65 20 64 6f 63 75 6d 65 6e 74 0a 23 20   the document.# 
12f0: 74 6f 20 74 65 73 74 2e 20 50 61 72 61 6d 65 74  to test. Paramet
1300: 65 72 73 20 24 70 68 72 61 73 65 31 20 61 6e 64  ers $phrase1 and
1310: 20 73 6f 20 6f 6e 20 61 72 65 20 74 68 65 20 70   so on are the p
1320: 68 72 61 73 65 73 2e 0a 23 0a 23 20 54 68 65 20  hrases..#.# The 
1330: 72 65 73 75 6c 74 20 69 73 20 61 20 6c 69 73 74  result is a list
1340: 20 6f 66 20 70 68 72 61 73 65 20 68 69 74 73 2e   of phrase hits.
1350: 20 45 61 63 68 20 70 68 72 61 73 65 20 68 69 74   Each phrase hit
1360: 20 69 73 20 66 6f 72 6d 61 74 74 65 64 20 61 73   is formatted as
1370: 0a 23 20 74 68 72 65 65 20 69 6e 74 65 67 65 72  .# three integer
1380: 73 20 73 65 70 61 72 61 74 65 64 20 62 79 20 22  s separated by "
1390: 2e 22 20 63 68 61 72 61 63 74 65 72 73 2c 20 69  ." characters, i
13a0: 6e 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  n the following 
13b0: 66 6f 72 6d 61 74 3a 0a 23 0a 23 20 20 20 3c 70  format:.#.#   <p
13c0: 68 72 61 73 65 20 6e 75 6d 62 65 72 3e 20 2e 20  hrase number> . 
13d0: 3c 63 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72 3e 20  <column number> 
13e0: 2e 20 3c 74 6f 6b 65 6e 20 6f 66 66 73 65 74 3e  . <token offset>
13f0: 0a 23 0a 23 20 4f 70 74 69 6f 6e 73 3a 0a 23 0a  .#.# Options:.#.
1400: 23 20 20 20 2d 6e 65 61 72 20 4e 20 20 20 20 20  #   -near N     
1410: 20 20 20 28 4e 45 41 52 20 64 69 73 74 61 6e 63     (NEAR distanc
1420: 65 2e 20 44 65 66 61 75 6c 74 20 31 30 29 0a 23  e. Default 10).#
1430: 20 20 20 2d 63 6f 6c 20 20 43 20 20 20 20 20 20     -col  C      
1440: 20 20 28 4c 69 73 74 20 6f 66 20 63 6f 6c 75 6d    (List of colum
1450: 6e 20 69 6e 64 65 78 65 73 20 74 6f 20 6d 61 74  n indexes to mat
1460: 63 68 20 61 67 61 69 6e 73 74 29 0a 23 20 20 20  ch against).#   
1470: 2d 70 63 20 20 20 56 41 52 4e 41 4d 45 20 20 28  -pc   VARNAME  (
1480: 76 61 72 69 61 62 6c 65 20 69 6e 20 63 61 6c 6c  variable in call
1490: 65 72 20 66 72 61 6d 65 20 74 6f 20 75 73 65 20  er frame to use 
14a0: 66 6f 72 20 70 68 72 61 73 65 20 6e 75 6d 62 65  for phrase numbe
14b0: 72 69 6e 67 29 0a 23 20 20 20 2d 64 69 63 74 20  ring).#   -dict 
14c0: 56 41 52 4e 41 4d 45 20 20 28 61 72 72 61 79 20  VARNAME  (array 
14d0: 69 6e 20 63 61 6c 6c 65 72 20 66 72 61 6d 65 20  in caller frame 
14e0: 74 6f 20 75 73 65 20 66 6f 72 20 73 79 6e 6f 6e  to use for synon
14f0: 79 6d 73 29 0a 23 0a 70 72 6f 63 20 6e 65 61 72  yms).#.proc near
1500: 73 65 74 20 7b 61 43 6f 6c 20 61 72 67 73 7d 20  set {aCol args} 
1510: 7b 0a 0a 20 20 23 20 50 72 6f 63 65 73 73 20 74  {..  # Process t
1520: 68 65 20 63 6f 6d 6d 61 6e 64 20 6c 69 6e 65 20  he command line 
1530: 6f 70 74 69 6f 6e 73 2e 0a 20 20 23 0a 20 20 73  options..  #.  s
1540: 65 74 20 4f 28 2d 6e 65 61 72 29 20 31 30 0a 20  et O(-near) 10. 
1550: 20 73 65 74 20 4f 28 2d 63 6f 6c 29 20 20 7b 7d   set O(-col)  {}
1560: 0a 20 20 73 65 74 20 4f 28 2d 70 63 29 20 20 20  .  set O(-pc)   
1570: 22 22 0a 20 20 73 65 74 20 4f 28 2d 64 69 63 74  "".  set O(-dict
1580: 29 20 22 22 0a 0a 20 20 73 65 74 20 6e 4f 70 74  ) ""..  set nOpt
1590: 20 5b 6c 73 65 61 72 63 68 20 2d 65 78 61 63 74   [lsearch -exact
15a0: 20 24 61 72 67 73 20 2d 2d 5d 0a 20 20 69 66 20   $args --].  if 
15b0: 7b 24 6e 4f 70 74 3c 30 7d 20 7b 20 65 72 72 6f  {$nOpt<0} { erro
15c0: 72 20 22 6e 6f 20 2d 2d 20 6f 70 74 69 6f 6e 22  r "no -- option"
15d0: 20 7d 0a 0a 20 20 23 20 53 65 74 20 24 6c 50 68   }..  # Set $lPh
15e0: 72 61 73 65 20 74 6f 20 62 65 20 61 20 6c 69 73  rase to be a lis
15f0: 74 20 6f 66 20 70 68 72 61 73 65 73 2e 20 24 6e  t of phrases. $n
1600: 50 68 72 61 73 65 20 69 74 73 20 6c 65 6e 67 74  Phrase its lengt
1610: 68 2e 0a 20 20 73 65 74 20 6c 50 68 72 61 73 65  h..  set lPhrase
1620: 20 5b 6c 72 61 6e 67 65 20 24 61 72 67 73 20 5b   [lrange $args [
1630: 65 78 70 72 20 24 6e 4f 70 74 2b 31 5d 20 65 6e  expr $nOpt+1] en
1640: 64 5d 0a 20 20 73 65 74 20 6e 50 68 72 61 73 65  d].  set nPhrase
1650: 20 5b 6c 6c 65 6e 67 74 68 20 24 6c 50 68 72 61   [llength $lPhra
1660: 73 65 5d 0a 0a 20 20 66 6f 72 65 61 63 68 20 7b  se]..  foreach {
1670: 6b 20 76 7d 20 5b 6c 72 61 6e 67 65 20 24 61 72  k v} [lrange $ar
1680: 67 73 20 30 20 5b 65 78 70 72 20 24 6e 4f 70 74  gs 0 [expr $nOpt
1690: 2d 31 5d 5d 20 7b 0a 20 20 20 20 69 66 20 7b 5b  -1]] {.    if {[
16a0: 69 6e 66 6f 20 65 78 69 73 74 73 20 4f 28 24 6b  info exists O($k
16b0: 29 5d 3d 3d 30 7d 20 7b 20 65 72 72 6f 72 20 22  )]==0} { error "
16c0: 75 6e 72 65 63 6f 67 6e 69 7a 65 64 20 6f 70 74  unrecognized opt
16d0: 69 6f 6e 20 24 6b 22 20 7d 0a 20 20 20 20 73 65  ion $k" }.    se
16e0: 74 20 4f 28 24 6b 29 20 24 76 0a 20 20 7d 0a 0a  t O($k) $v.  }..
16f0: 20 20 69 66 20 7b 24 4f 28 2d 70 63 29 20 3d 3d    if {$O(-pc) ==
1700: 20 22 22 7d 20 7b 0a 20 20 20 20 73 65 74 20 63   ""} {.    set c
1710: 6f 75 6e 74 65 72 20 30 0a 20 20 7d 20 65 6c 73  ounter 0.  } els
1720: 65 20 7b 0a 20 20 20 20 75 70 76 61 72 20 24 4f  e {.    upvar $O
1730: 28 2d 70 63 29 20 63 6f 75 6e 74 65 72 0a 20 20  (-pc) counter.  
1740: 7d 0a 0a 20 20 69 66 20 7b 24 4f 28 2d 64 69 63  }..  if {$O(-dic
1750: 74 29 21 3d 22 22 7d 20 7b 20 75 70 76 61 72 20  t)!=""} { upvar 
1760: 24 4f 28 2d 64 69 63 74 29 20 61 44 69 63 74 20  $O(-dict) aDict 
1770: 7d 0a 0a 20 20 66 6f 72 20 7b 73 65 74 20 6a 20  }..  for {set j 
1780: 30 7d 20 7b 24 6a 20 3c 20 5b 6c 6c 65 6e 67 74  0} {$j < [llengt
1790: 68 20 24 61 43 6f 6c 5d 7d 20 7b 69 6e 63 72 20  h $aCol]} {incr 
17a0: 6a 7d 20 7b 0a 20 20 20 20 66 6f 72 20 7b 73 65  j} {.    for {se
17b0: 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 24 6e 50  t i 0} {$i < $nP
17c0: 68 72 61 73 65 7d 20 7b 69 6e 63 72 20 69 7d 20  hrase} {incr i} 
17d0: 7b 20 0a 20 20 20 20 20 20 73 65 74 20 41 28 24  { .      set A($
17e0: 6a 2c 24 69 29 20 5b 6c 69 73 74 5d 0a 20 20 20  j,$i) [list].   
17f0: 20 7d 0a 20 20 7d 0a 0a 20 20 23 20 4c 6f 6f 70   }.  }..  # Loop
1800: 20 74 68 72 6f 75 67 68 20 65 61 63 68 20 63 6f   through each co
1810: 6c 75 6d 6e 20 6f 66 20 74 68 65 20 63 75 72 72  lumn of the curr
1820: 65 6e 74 20 72 6f 77 2e 0a 20 20 66 6f 72 20 7b  ent row..  for {
1830: 73 65 74 20 69 43 6f 6c 20 30 7d 20 7b 24 69 43  set iCol 0} {$iC
1840: 6f 6c 20 3c 20 5b 6c 6c 65 6e 67 74 68 20 24 61  ol < [llength $a
1850: 43 6f 6c 5d 7d 20 7b 69 6e 63 72 20 69 43 6f 6c  Col]} {incr iCol
1860: 7d 20 7b 0a 0a 20 20 20 20 23 20 49 66 20 74 68  } {..    # If th
1870: 65 72 65 20 69 73 20 61 20 63 6f 6c 75 6d 6e 20  ere is a column 
1880: 66 69 6c 74 65 72 2c 20 74 65 73 74 20 77 68 65  filter, test whe
1890: 74 68 65 72 20 74 68 69 73 20 63 6f 6c 75 6d 6e  ther this column
18a0: 20 69 73 20 65 78 63 6c 75 64 65 64 2e 20 49 66   is excluded. If
18b0: 0a 20 20 20 20 23 20 73 6f 2c 20 73 6b 69 70 20  .    # so, skip 
18c0: 74 6f 20 74 68 65 20 6e 65 78 74 20 69 74 65 72  to the next iter
18d0: 61 74 69 6f 6e 20 6f 66 20 74 68 69 73 20 6c 6f  ation of this lo
18e0: 6f 70 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 73  op. Otherwise, s
18f0: 65 74 20 7a 43 6f 6c 20 74 6f 20 74 68 65 0a 20  et zCol to the. 
1900: 20 20 20 23 20 63 6f 6c 75 6d 6e 20 76 61 6c 75     # column valu
1910: 65 20 61 6e 64 20 6e 54 6f 6b 65 6e 20 74 6f 20  e and nToken to 
1920: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 6f  the number of to
1930: 6b 65 6e 73 20 74 68 61 74 20 63 6f 6d 70 72 69  kens that compri
1940: 73 65 20 69 74 2e 0a 20 20 20 20 69 66 20 7b 24  se it..    if {$
1950: 4f 28 2d 63 6f 6c 29 21 3d 22 22 20 26 26 20 5b  O(-col)!="" && [
1960: 6c 73 65 61 72 63 68 20 24 4f 28 2d 63 6f 6c 29  lsearch $O(-col)
1970: 20 24 69 43 6f 6c 5d 3c 30 7d 20 63 6f 6e 74 69   $iCol]<0} conti
1980: 6e 75 65 0a 20 20 20 20 73 65 74 20 7a 43 6f 6c  nue.    set zCol
1990: 20 5b 6c 69 6e 64 65 78 20 24 61 43 6f 6c 20 24   [lindex $aCol $
19a0: 69 43 6f 6c 5d 0a 20 20 20 20 73 65 74 20 6e 54  iCol].    set nT
19b0: 6f 6b 65 6e 20 5b 6c 6c 65 6e 67 74 68 20 24 7a  oken [llength $z
19c0: 43 6f 6c 5d 0a 0a 20 20 20 20 23 20 45 61 63 68  Col]..    # Each
19d0: 20 69 74 65 72 61 74 69 6f 6e 20 6f 66 20 74 68   iteration of th
19e0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6c 6f 6f 70  e following loop
19f0: 20 73 65 61 72 63 68 65 73 20 61 20 73 75 62 73   searches a subs
1a00: 74 72 69 6e 67 20 6f 66 20 74 68 65 20 0a 20 20  tring of the .  
1a10: 20 20 23 20 63 6f 6c 75 6d 6e 20 76 61 6c 75 65    # column value
1a20: 20 66 6f 72 20 70 68 72 61 73 65 20 6d 61 74 63   for phrase matc
1a30: 68 65 73 2e 20 54 68 65 20 6c 61 73 74 20 74 6f  hes. The last to
1a40: 6b 65 6e 20 6f 66 20 74 68 65 20 73 75 62 73 74  ken of the subst
1a50: 72 69 6e 67 0a 20 20 20 20 23 20 69 73 20 74 6f  ring.    # is to
1a60: 6b 65 6e 20 24 69 4c 61 73 74 20 6f 66 20 74 68  ken $iLast of th
1a70: 65 20 63 6f 6c 75 6d 6e 20 76 61 6c 75 65 2e 20  e column value. 
1a80: 54 68 65 20 66 69 72 73 74 20 74 6f 6b 65 6e 20  The first token 
1a90: 69 73 3a 0a 20 20 20 20 23 0a 20 20 20 20 23 20  is:.    #.    # 
1aa0: 20 20 69 46 69 72 73 74 20 3d 20 28 24 69 4c 61    iFirst = ($iLa
1ab0: 73 74 20 2d 20 24 4f 28 2d 6e 65 61 72 29 20 2d  st - $O(-near) -
1ac0: 20 31 29 0a 20 20 20 20 23 0a 20 20 20 20 23 20   1).    #.    # 
1ad0: 77 68 65 72 65 20 24 73 7a 20 69 73 20 74 68 65  where $sz is the
1ae0: 20 6c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 70   length of the p
1af0: 68 72 61 73 65 20 62 65 69 6e 67 20 73 65 61 72  hrase being sear
1b00: 63 68 65 64 20 66 6f 72 2e 20 41 20 70 68 72 61  ched for. A phra
1b10: 73 65 20 0a 20 20 20 20 23 20 63 6f 75 6e 74 73  se .    # counts
1b20: 20 61 73 20 6d 61 74 63 68 69 6e 67 20 74 68 65   as matching the
1b30: 20 73 75 62 73 74 72 69 6e 67 20 69 66 20 69 74   substring if it
1b40: 73 20 66 69 72 73 74 20 74 6f 6b 65 6e 20 6c 69  s first token li
1b50: 65 73 20 6f 6e 20 6f 72 20 62 65 66 6f 72 65 0a  es on or before.
1b60: 20 20 20 20 23 20 24 69 4c 61 73 74 20 61 6e 64      # $iLast and
1b70: 20 69 74 73 20 6c 61 73 74 20 74 6f 6b 65 6e 20   its last token 
1b80: 6f 6e 20 6f 72 20 61 66 74 65 72 20 24 69 46 69  on or after $iFi
1b90: 72 73 74 2e 0a 20 20 20 20 23 0a 20 20 20 20 23  rst..    #.    #
1ba0: 20 46 6f 72 20 65 78 61 6d 70 6c 65 2c 20 69 66   For example, if
1bb0: 20 74 68 65 20 71 75 65 72 79 20 69 73 20 22 4e   the query is "N
1bc0: 45 41 52 28 61 2b 62 20 63 2c 20 32 29 22 20 61  EAR(a+b c, 2)" a
1bd0: 6e 64 20 74 68 65 20 63 6f 6c 75 6d 6e 20 76 61  nd the column va
1be0: 6c 75 65 3a 0a 20 20 20 20 23 0a 20 20 20 20 23  lue:.    #.    #
1bf0: 20 20 20 22 78 20 78 20 78 20 78 20 41 20 42 20     "x x x x A B 
1c00: 78 20 78 20 43 20 78 22 0a 20 20 20 20 23 20 20  x x C x".    #  
1c10: 20 20 30 20 31 20 32 20 33 20 34 20 35 20 36 20    0 1 2 3 4 5 6 
1c20: 37 20 38 20 39 22 0a 20 20 20 20 23 0a 20 20 20  7 8 9".    #.   
1c30: 20 23 20 77 68 65 6e 20 28 69 4c 61 73 74 3d 3d   # when (iLast==
1c40: 38 20 26 26 20 69 46 69 72 73 74 3d 35 29 20 74  8 && iFirst=5) t
1c50: 68 65 20 72 61 6e 67 65 20 77 69 6c 6c 20 63 6f  he range will co
1c60: 6e 74 61 69 6e 20 62 6f 74 68 20 70 68 72 61 73  ntain both phras
1c70: 65 73 20 61 6e 64 0a 20 20 20 20 23 20 73 6f 20  es and.    # so 
1c80: 62 6f 74 68 20 69 6e 73 74 61 6e 63 65 73 20 63  both instances c
1c90: 61 6e 20 62 65 20 61 64 64 65 64 20 74 6f 20 74  an be added to t
1ca0: 68 65 20 6f 75 74 70 75 74 20 70 6f 73 6c 69 73  he output poslis
1cb0: 74 73 2e 0a 20 20 20 20 23 0a 20 20 20 20 73 65  ts..    #.    se
1cc0: 74 20 69 4c 61 73 74 20 5b 65 78 70 72 20 24 4f  t iLast [expr $O
1cd0: 28 2d 6e 65 61 72 29 20 3e 3d 20 24 6e 54 6f 6b  (-near) >= $nTok
1ce0: 65 6e 20 3f 20 24 6e 54 6f 6b 65 6e 20 2d 20 31  en ? $nToken - 1
1cf0: 20 3a 20 24 4f 28 2d 6e 65 61 72 29 5d 0a 20 20   : $O(-near)].  
1d00: 20 20 66 6f 72 20 7b 20 7d 20 7b 24 69 4c 61 73    for { } {$iLas
1d10: 74 20 3c 20 24 6e 54 6f 6b 65 6e 7d 20 7b 69 6e  t < $nToken} {in
1d20: 63 72 20 69 4c 61 73 74 7d 20 7b 0a 0a 20 20 20  cr iLast} {..   
1d30: 20 20 20 63 61 74 63 68 20 7b 20 61 72 72 61 79     catch { array
1d40: 20 75 6e 73 65 74 20 42 20 7d 0a 20 20 20 20 20   unset B }.     
1d50: 20 0a 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74   .      for {set
1d60: 20 69 50 68 72 61 73 65 20 30 7d 20 7b 24 69 50   iPhrase 0} {$iP
1d70: 68 72 61 73 65 3c 24 6e 50 68 72 61 73 65 7d 20  hrase<$nPhrase} 
1d80: 7b 69 6e 63 72 20 69 50 68 72 61 73 65 7d 20 7b  {incr iPhrase} {
1d90: 0a 20 20 20 20 20 20 20 20 73 65 74 20 70 20 5b  .        set p [
1da0: 6c 69 6e 64 65 78 20 24 6c 50 68 72 61 73 65 20  lindex $lPhrase 
1db0: 24 69 50 68 72 61 73 65 5d 0a 20 20 20 20 20 20  $iPhrase].      
1dc0: 20 20 73 65 74 20 6e 50 6d 31 20 5b 65 78 70 72    set nPm1 [expr
1dd0: 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 70 5d 20 2d   {[llength $p] -
1de0: 20 31 7d 5d 0a 20 20 20 20 20 20 20 20 73 65 74   1}].        set
1df0: 20 69 46 69 72 73 74 20 5b 65 78 70 72 20 24 69   iFirst [expr $i
1e00: 4c 61 73 74 20 2d 20 24 4f 28 2d 6e 65 61 72 29  Last - $O(-near)
1e10: 20 2d 20 5b 6c 6c 65 6e 67 74 68 20 24 70 5d 5d   - [llength $p]]
1e20: 0a 0a 20 20 20 20 20 20 20 20 66 6f 72 20 7b 73  ..        for {s
1e30: 65 74 20 69 20 24 69 46 69 72 73 74 7d 20 7b 24  et i $iFirst} {$
1e40: 69 20 3c 3d 20 24 69 4c 61 73 74 7d 20 7b 69 6e  i <= $iLast} {in
1e50: 63 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 20 20  cr i} {.        
1e60: 20 20 73 65 74 20 6c 43 61 6e 64 20 5b 6c 72 61    set lCand [lra
1e70: 6e 67 65 20 24 7a 43 6f 6c 20 24 69 20 5b 65 78  nge $zCol $i [ex
1e80: 70 72 20 24 69 2b 24 6e 50 6d 31 5d 5d 0a 20 20  pr $i+$nPm1]].  
1e90: 20 20 20 20 20 20 20 20 73 65 74 20 62 4d 61 74          set bMat
1ea0: 63 68 20 31 0a 20 20 20 20 20 20 20 20 20 20 66  ch 1.          f
1eb0: 6f 72 65 61 63 68 20 74 6f 6b 20 24 70 20 74 65  oreach tok $p te
1ec0: 72 6d 20 24 6c 43 61 6e 64 20 7b 0a 20 20 20 20  rm $lCand {.    
1ed0: 20 20 20 20 20 20 20 20 69 66 20 7b 5b 6e 65 61          if {[nea
1ee0: 72 73 65 74 5f 6d 61 74 63 68 20 61 44 69 63 74  rset_match aDict
1ef0: 20 24 74 6f 6b 20 24 74 65 72 6d 5d 3d 3d 30 7d   $tok $term]==0}
1f00: 20 7b 20 73 65 74 20 62 4d 61 74 63 68 20 30 20   { set bMatch 0 
1f10: 3b 20 62 72 65 61 6b 20 7d 0a 20 20 20 20 20 20  ; break }.      
1f20: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
1f30: 69 66 20 7b 24 62 4d 61 74 63 68 7d 20 7b 20 6c  if {$bMatch} { l
1f40: 61 70 70 65 6e 64 20 42 28 24 69 50 68 72 61 73  append B($iPhras
1f50: 65 29 20 24 69 20 7d 0a 20 20 20 20 20 20 20 20  e) $i }.        
1f60: 7d 0a 0a 20 20 20 20 20 20 20 20 69 66 20 7b 21  }..        if {!
1f70: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 42 28 24  [info exists B($
1f80: 69 50 68 72 61 73 65 29 5d 7d 20 62 72 65 61 6b  iPhrase)]} break
1f90: 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
1fa0: 69 66 20 7b 24 69 50 68 72 61 73 65 3d 3d 24 6e  if {$iPhrase==$n
1fb0: 50 68 72 61 73 65 7d 20 7b 0a 20 20 20 20 20 20  Phrase} {.      
1fc0: 20 20 66 6f 72 20 7b 73 65 74 20 69 50 68 72 61    for {set iPhra
1fd0: 73 65 20 30 7d 20 7b 24 69 50 68 72 61 73 65 3c  se 0} {$iPhrase<
1fe0: 24 6e 50 68 72 61 73 65 7d 20 7b 69 6e 63 72 20  $nPhrase} {incr 
1ff0: 69 50 68 72 61 73 65 7d 20 7b 0a 20 20 20 20 20  iPhrase} {.     
2000: 20 20 20 20 20 73 65 74 20 41 28 24 69 43 6f 6c       set A($iCol
2010: 2c 24 69 50 68 72 61 73 65 29 20 5b 63 6f 6e 63  ,$iPhrase) [conc
2020: 61 74 20 24 41 28 24 69 43 6f 6c 2c 24 69 50 68  at $A($iCol,$iPh
2030: 72 61 73 65 29 20 24 42 28 24 69 50 68 72 61 73  rase) $B($iPhras
2040: 65 29 5d 0a 20 20 20 20 20 20 20 20 20 20 73 65  e)].          se
2050: 74 20 41 28 24 69 43 6f 6c 2c 24 69 50 68 72 61  t A($iCol,$iPhra
2060: 73 65 29 20 5b 6c 73 6f 72 74 20 2d 69 6e 74 65  se) [lsort -inte
2070: 67 65 72 20 2d 75 6e 69 71 20 24 41 28 24 69 43  ger -uniq $A($iC
2080: 6f 6c 2c 24 69 50 68 72 61 73 65 29 5d 0a 20 20  ol,$iPhrase)].  
2090: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
20a0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 73 65 74      }.  }..  set
20b0: 20 72 65 73 20 5b 6c 69 73 74 5d 0a 20 20 23 70   res [list].  #p
20c0: 75 74 73 20 5b 61 72 72 61 79 20 6e 61 6d 65 73  uts [array names
20d0: 20 41 5d 0a 0a 20 20 66 6f 72 20 7b 73 65 74 20   A]..  for {set 
20e0: 69 50 68 72 61 73 65 20 30 7d 20 7b 24 69 50 68  iPhrase 0} {$iPh
20f0: 72 61 73 65 3c 24 6e 50 68 72 61 73 65 7d 20 7b  rase<$nPhrase} {
2100: 69 6e 63 72 20 69 50 68 72 61 73 65 7d 20 7b 0a  incr iPhrase} {.
2110: 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 43 6f      for {set iCo
2120: 6c 20 30 7d 20 7b 24 69 43 6f 6c 20 3c 20 5b 6c  l 0} {$iCol < [l
2130: 6c 65 6e 67 74 68 20 24 61 43 6f 6c 5d 7d 20 7b  length $aCol]} {
2140: 69 6e 63 72 20 69 43 6f 6c 7d 20 7b 0a 20 20 20  incr iCol} {.   
2150: 20 20 20 66 6f 72 65 61 63 68 20 61 20 24 41 28     foreach a $A(
2160: 24 69 43 6f 6c 2c 24 69 50 68 72 61 73 65 29 20  $iCol,$iPhrase) 
2170: 7b 0a 20 20 20 20 20 20 20 20 6c 61 70 70 65 6e  {.        lappen
2180: 64 20 72 65 73 20 22 24 63 6f 75 6e 74 65 72 2e  d res "$counter.
2190: 24 69 43 6f 6c 2e 24 61 22 0a 20 20 20 20 20 20  $iCol.$a".      
21a0: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 6e 63 72  }.    }.    incr
21b0: 20 63 6f 75 6e 74 65 72 0a 20 20 7d 0a 0a 20 20   counter.  }..  
21c0: 23 70 75 74 73 20 22 24 61 43 6f 6c 20 2d 3e 20  #puts "$aCol -> 
21d0: 24 72 65 73 22 0a 20 20 73 6f 72 74 5f 70 6f 73  $res".  sort_pos
21e0: 6c 69 73 74 20 24 72 65 73 0a 7d 0a 0a 70 72 6f  list $res.}..pro
21f0: 63 20 6e 65 61 72 73 65 74 5f 6d 61 74 63 68 20  c nearset_match 
2200: 7b 61 44 69 63 74 56 61 72 20 74 6f 6b 20 74 65  {aDictVar tok te
2210: 72 6d 7d 20 7b 0a 20 20 69 66 20 7b 5b 73 74 72  rm} {.  if {[str
2220: 69 6e 67 20 6d 61 74 63 68 20 24 74 6f 6b 20 24  ing match $tok $
2230: 74 65 72 6d 5d 7d 20 7b 20 72 65 74 75 72 6e 20  term]} { return 
2240: 31 20 7d 0a 0a 20 20 75 70 76 61 72 20 24 61 44  1 }..  upvar $aD
2250: 69 63 74 56 61 72 20 61 44 69 63 74 0a 20 20 69  ictVar aDict.  i
2260: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
2270: 61 44 69 63 74 28 24 74 6f 6b 29 5d 7d 20 7b 0a  aDict($tok)]} {.
2280: 20 20 20 20 66 6f 72 65 61 63 68 20 73 20 24 61      foreach s $a
2290: 44 69 63 74 28 24 74 6f 6b 29 20 7b 0a 20 20 20  Dict($tok) {.   
22a0: 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 6d     if {[string m
22b0: 61 74 63 68 20 24 73 20 24 74 65 72 6d 5d 7d 20  atch $s $term]} 
22c0: 7b 20 72 65 74 75 72 6e 20 31 20 7d 0a 20 20 20  { return 1 }.   
22d0: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
22e0: 30 3b 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  0;.}..#---------
22f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2300: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2310: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2320: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2330: 0a 23 20 55 73 61 67 65 3a 0a 23 0a 23 20 20 20  .# Usage:.#.#   
2340: 73 6f 72 74 5f 70 6f 73 6c 69 73 74 20 4c 49 53  sort_poslist LIS
2350: 54 0a 23 0a 23 20 53 6f 72 74 20 61 20 70 6f 73  T.#.# Sort a pos
2360: 69 74 69 6f 6e 20 6c 69 73 74 20 6f 66 20 74 68  ition list of th
2370: 65 20 74 79 70 65 20 72 65 74 75 72 6e 65 64 20  e type returned 
2380: 62 79 20 63 6f 6d 6d 61 6e 64 20 5b 6e 65 61 72  by command [near
2390: 73 65 74 5d 0a 23 0a 70 72 6f 63 20 73 6f 72 74  set].#.proc sort
23a0: 5f 70 6f 73 6c 69 73 74 20 7b 4c 7d 20 7b 0a 20  _poslist {L} {. 
23b0: 20 6c 73 6f 72 74 20 2d 63 6f 6d 6d 61 6e 64 20   lsort -command 
23c0: 69 6e 73 74 63 6f 6d 70 61 72 65 20 24 4c 0a 7d  instcompare $L.}
23d0: 0a 70 72 6f 63 20 69 6e 73 74 63 6f 6d 70 61 72  .proc instcompar
23e0: 65 20 7b 6c 68 73 20 72 68 73 7d 20 7b 0a 20 20  e {lhs rhs} {.  
23f0: 66 6f 72 65 61 63 68 20 7b 70 31 20 63 31 20 6f  foreach {p1 c1 o
2400: 31 7d 20 5b 73 70 6c 69 74 20 24 6c 68 73 20 2e  1} [split $lhs .
2410: 5d 20 7b 7d 0a 20 20 66 6f 72 65 61 63 68 20 7b  ] {}.  foreach {
2420: 70 32 20 63 32 20 6f 32 7d 20 5b 73 70 6c 69 74  p2 c2 o2} [split
2430: 20 24 72 68 73 20 2e 5d 20 7b 7d 0a 0a 20 20 73   $rhs .] {}..  s
2440: 65 74 20 72 65 73 20 5b 65 78 70 72 20 24 63 31  et res [expr $c1
2450: 20 2d 20 24 63 32 5d 0a 20 20 69 66 20 7b 24 72   - $c2].  if {$r
2460: 65 73 3d 3d 30 7d 20 7b 20 73 65 74 20 72 65 73  es==0} { set res
2470: 20 5b 65 78 70 72 20 24 6f 31 20 2d 20 24 6f 32   [expr $o1 - $o2
2480: 5d 20 7d 0a 20 20 69 66 20 7b 24 72 65 73 3d 3d  ] }.  if {$res==
2490: 30 7d 20 7b 20 73 65 74 20 72 65 73 20 5b 65 78  0} { set res [ex
24a0: 70 72 20 24 70 31 20 2d 20 24 70 32 5d 20 7d 0a  pr $p1 - $p2] }.
24b0: 0a 20 20 72 65 74 75 72 6e 20 24 72 65 73 0a 7d  .  return $res.}
24c0: 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#-------------
24d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
24e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
24f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2500: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 4c  ------------.# L
2510: 6f 67 69 63 61 6c 20 6f 70 65 72 61 74 6f 72 73  ogical operators
2520: 20 75 73 65 64 20 62 79 20 74 68 65 20 63 6f 6d   used by the com
2530: 6d 61 6e 64 73 20 72 65 74 75 72 6e 65 64 20 62  mands returned b
2540: 79 20 66 74 73 35 5f 74 63 6c 5f 65 78 70 72 28  y fts5_tcl_expr(
2550: 29 2e 0a 23 0a 70 72 6f 63 20 41 4e 44 20 7b 61  )..#.proc AND {a
2560: 72 67 73 7d 20 7b 0a 20 20 66 6f 72 65 61 63 68  rgs} {.  foreach
2570: 20 61 20 24 61 72 67 73 20 7b 0a 20 20 20 20 69   a $args {.    i
2580: 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 5d 3d  f {[llength $a]=
2590: 3d 30 7d 20 7b 20 72 65 74 75 72 6e 20 5b 6c 69  =0} { return [li
25a0: 73 74 5d 20 7d 0a 20 20 7d 0a 20 20 73 6f 72 74  st] }.  }.  sort
25b0: 5f 70 6f 73 6c 69 73 74 20 5b 63 6f 6e 63 61 74  _poslist [concat
25c0: 20 7b 2a 7d 24 61 72 67 73 5d 0a 7d 0a 70 72 6f   {*}$args].}.pro
25d0: 63 20 4f 52 20 7b 61 72 67 73 7d 20 7b 0a 20 20  c OR {args} {.  
25e0: 73 6f 72 74 5f 70 6f 73 6c 69 73 74 20 5b 63 6f  sort_poslist [co
25f0: 6e 63 61 74 20 7b 2a 7d 24 61 72 67 73 5d 0a 7d  ncat {*}$args].}
2600: 0a 70 72 6f 63 20 4e 4f 54 20 7b 61 20 62 7d 20  .proc NOT {a b} 
2610: 7b 0a 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68  {.  if {[llength
2620: 20 24 62 5d 3e 30 7d 20 7b 20 72 65 74 75 72 6e   $b]>0} { return
2630: 20 5b 6c 69 73 74 5d 20 7d 0a 20 20 72 65 74 75   [list] }.  retu
2640: 72 6e 20 24 61 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d  rn $a.}..#------
2650: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2660: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2670: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2680: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2690: 2d 2d 2d 0a 23 20 54 68 69 73 20 63 6f 6d 6d 61  ---.# This comma
26a0: 6e 64 20 69 73 20 73 69 6d 69 6c 61 72 20 74 6f  nd is similar to
26b0: 20 5b 73 70 6c 69 74 5d 2c 20 65 78 63 65 70 74   [split], except
26c0: 20 74 68 61 74 20 69 74 20 61 6c 73 6f 20 70 72   that it also pr
26d0: 6f 76 69 64 65 73 20 74 68 65 0a 23 20 73 74 61  ovides the.# sta
26e0: 72 74 20 61 6e 64 20 65 6e 64 20 6f 66 66 73 65  rt and end offse
26f0: 74 73 20 6f 66 20 65 61 63 68 20 74 6f 6b 65 6e  ts of each token
2700: 2e 20 46 6f 72 20 65 78 61 6d 70 6c 65 3a 0a 23  . For example:.#
2710: 0a 23 20 20 20 5b 66 74 73 35 5f 74 6f 6b 65 6e  .#   [fts5_token
2720: 69 7a 65 5f 73 70 6c 69 74 20 22 61 62 63 20 64  ize_split "abc d
2730: 20 65 66 22 5d 20 2d 3e 20 7b 61 62 63 20 30 20   ef"] -> {abc 0 
2740: 33 20 64 20 34 20 35 20 65 66 20 36 20 38 7d 0a  3 d 4 5 ef 6 8}.
2750: 23 0a 0a 70 72 6f 63 20 67 6f 62 62 6c 65 5f 77  #..proc gobble_w
2760: 68 69 74 65 73 70 61 63 65 20 7b 74 65 78 74 76  hitespace {textv
2770: 61 72 7d 20 7b 0a 20 20 75 70 76 61 72 20 24 74  ar} {.  upvar $t
2780: 65 78 74 76 61 72 20 74 0a 20 20 72 65 67 65 78  extvar t.  regex
2790: 70 20 7b 28 5b 20 5d 2a 29 28 2e 2a 29 7d 20 24  p {([ ]*)(.*)} $
27a0: 74 20 2d 3e 20 73 70 61 63 65 20 74 0a 20 20 72  t -> space t.  r
27b0: 65 74 75 72 6e 20 5b 73 74 72 69 6e 67 20 6c 65  eturn [string le
27c0: 6e 67 74 68 20 24 73 70 61 63 65 5d 0a 7d 0a 0a  ngth $space].}..
27d0: 70 72 6f 63 20 67 6f 62 62 6c 65 5f 74 65 78 74  proc gobble_text
27e0: 20 7b 74 65 78 74 76 61 72 20 77 6f 72 64 76 61   {textvar wordva
27f0: 72 7d 20 7b 0a 20 20 75 70 76 61 72 20 24 74 65  r} {.  upvar $te
2800: 78 74 76 61 72 20 74 0a 20 20 75 70 76 61 72 20  xtvar t.  upvar 
2810: 24 77 6f 72 64 76 61 72 20 77 0a 20 20 72 65 67  $wordvar w.  reg
2820: 65 78 70 20 7b 28 5b 5e 20 5d 2a 29 28 2e 2a 29  exp {([^ ]*)(.*)
2830: 7d 20 24 74 20 2d 3e 20 77 20 74 0a 20 20 72 65  } $t -> w t.  re
2840: 74 75 72 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e  turn [string len
2850: 67 74 68 20 24 77 5d 0a 7d 0a 0a 70 72 6f 63 20  gth $w].}..proc 
2860: 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 5f 73 70  fts5_tokenize_sp
2870: 6c 69 74 20 7b 74 65 78 74 7d 20 7b 0a 20 20 73  lit {text} {.  s
2880: 65 74 20 74 6f 6b 65 6e 20 22 22 0a 20 20 73 65  et token "".  se
2890: 74 20 72 65 74 20 5b 6c 69 73 74 5d 0a 20 20 73  t ret [list].  s
28a0: 65 74 20 69 4f 66 66 20 5b 67 6f 62 62 6c 65 5f  et iOff [gobble_
28b0: 77 68 69 74 65 73 70 61 63 65 20 74 65 78 74 5d  whitespace text]
28c0: 0a 20 20 77 68 69 6c 65 20 7b 5b 73 65 74 20 6e  .  while {[set n
28d0: 54 6f 6b 65 6e 20 5b 67 6f 62 62 6c 65 5f 74 65  Token [gobble_te
28e0: 78 74 20 74 65 78 74 20 77 6f 72 64 5d 5d 7d 20  xt text word]]} 
28f0: 7b 0a 20 20 20 20 6c 61 70 70 65 6e 64 20 72 65  {.    lappend re
2900: 74 20 24 77 6f 72 64 20 24 69 4f 66 66 20 5b 65  t $word $iOff [e
2910: 78 70 72 20 24 69 4f 66 66 2b 24 6e 54 6f 6b 65  xpr $iOff+$nToke
2920: 6e 5d 0a 20 20 20 20 69 6e 63 72 20 69 4f 66 66  n].    incr iOff
2930: 20 24 6e 54 6f 6b 65 6e 0a 20 20 20 20 69 6e 63   $nToken.    inc
2940: 72 20 69 4f 66 66 20 5b 67 6f 62 62 6c 65 5f 77  r iOff [gobble_w
2950: 68 69 74 65 73 70 61 63 65 20 74 65 78 74 5d 0a  hitespace text].
2960: 20 20 7d 0a 0a 20 20 73 65 74 20 72 65 74 0a 7d    }..  set ret.}
2970: 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#-------------
2980: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2990: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
29a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
29b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 70  ------------.#.p
29c0: 72 6f 63 20 66 6f 72 65 61 63 68 5f 64 65 74 61  roc foreach_deta
29d0: 69 6c 5f 6d 6f 64 65 20 7b 70 72 65 66 69 78 20  il_mode {prefix 
29e0: 73 63 72 69 70 74 7d 20 7b 0a 20 20 73 65 74 20  script} {.  set 
29f0: 73 61 76 65 64 20 24 3a 3a 74 65 73 74 70 72 65  saved $::testpre
2a00: 66 69 78 0a 20 20 66 6f 72 65 61 63 68 20 64 20  fix.  foreach d 
2a10: 5b 6c 69 73 74 20 66 75 6c 6c 20 63 6f 6c 20 6e  [list full col n
2a20: 6f 6e 65 5d 20 7b 0a 20 20 20 20 73 65 74 20 73  one] {.    set s
2a30: 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 5b 6c 69   [string map [li
2a40: 73 74 20 25 44 45 54 41 49 4c 25 20 24 64 5d 20  st %DETAIL% $d] 
2a50: 24 73 63 72 69 70 74 5d 0a 20 20 20 20 73 65 74  $script].    set
2a60: 20 3a 3a 64 65 74 61 69 6c 20 24 64 0a 20 20 20   ::detail $d.   
2a70: 20 73 65 74 20 3a 3a 74 65 73 74 70 72 65 66 69   set ::testprefi
2a80: 78 20 22 24 70 72 65 66 69 78 2d 24 64 22 0a 20  x "$prefix-$d". 
2a90: 20 20 20 72 65 73 65 74 5f 64 62 0a 20 20 20 20     reset_db.    
2aa0: 75 70 6c 65 76 65 6c 20 24 73 0a 20 20 20 20 75  uplevel $s.    u
2ab0: 6e 73 65 74 20 3a 3a 64 65 74 61 69 6c 0a 20 20  nset ::detail.  
2ac0: 7d 0a 20 20 73 65 74 20 3a 3a 74 65 73 74 70 72  }.  set ::testpr
2ad0: 65 66 69 78 20 24 73 61 76 65 64 0a 7d 0a 0a 70  efix $saved.}..p
2ae0: 72 6f 63 20 64 65 74 61 69 6c 5f 63 68 65 63 6b  roc detail_check
2af0: 20 7b 7d 20 7b 0a 20 20 69 66 20 7b 24 3a 3a 64   {} {.  if {$::d
2b00: 65 74 61 69 6c 20 21 3d 20 22 6e 6f 6e 65 22 20  etail != "none" 
2b10: 26 26 20 24 3a 3a 64 65 74 61 69 6c 21 3d 22 66  && $::detail!="f
2b20: 75 6c 6c 22 20 26 26 20 24 3a 3a 64 65 74 61 69  ull" && $::detai
2b30: 6c 21 3d 22 63 6f 6c 22 7d 20 7b 0a 20 20 20 20  l!="col"} {.    
2b40: 65 72 72 6f 72 20 22 6e 6f 74 20 69 6e 20 66 6f  error "not in fo
2b50: 72 65 61 63 68 5f 64 65 74 61 69 6c 5f 6d 6f 64  reach_detail_mod
2b60: 65 20 7b 2e 2e 2e 7d 20 62 6c 6f 63 6b 22 0a 20  e {...} block". 
2b70: 20 7d 0a 7d 0a 70 72 6f 63 20 64 65 74 61 69 6c   }.}.proc detail
2b80: 5f 69 73 5f 6e 6f 6e 65 20 7b 7d 20 7b 20 64 65  _is_none {} { de
2b90: 74 61 69 6c 5f 63 68 65 63 6b 20 3b 20 65 78 70  tail_check ; exp
2ba0: 72 20 7b 24 3a 3a 64 65 74 61 69 6c 20 3d 3d 20  r {$::detail == 
2bb0: 22 6e 6f 6e 65 22 7d 20 7d 0a 70 72 6f 63 20 64  "none"} }.proc d
2bc0: 65 74 61 69 6c 5f 69 73 5f 63 6f 6c 20 7b 7d 20  etail_is_col {} 
2bd0: 20 7b 20 64 65 74 61 69 6c 5f 63 68 65 63 6b 20   { detail_check 
2be0: 3b 20 65 78 70 72 20 7b 24 3a 3a 64 65 74 61 69  ; expr {$::detai
2bf0: 6c 20 3d 3d 20 22 63 6f 6c 22 20 7d 20 7d 0a 70  l == "col" } }.p
2c00: 72 6f 63 20 64 65 74 61 69 6c 5f 69 73 5f 66 75  roc detail_is_fu
2c10: 6c 6c 20 7b 7d 20 7b 20 64 65 74 61 69 6c 5f 63  ll {} { detail_c
2c20: 68 65 63 6b 20 3b 20 65 78 70 72 20 7b 24 3a 3a  heck ; expr {$::
2c30: 64 65 74 61 69 6c 20 3d 3d 20 22 66 75 6c 6c 22  detail == "full"
2c40: 7d 20 7d 0a 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  } }...#---------
2c50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2c60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2c70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2c80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2c90: 0a 23 20 43 6f 6e 76 65 72 74 20 61 20 70 6f 73  .# Convert a pos
2ca0: 6c 69 73 74 20 6f 66 20 74 68 65 20 74 79 70 65  list of the type
2cb0: 20 72 65 74 75 72 6e 65 64 20 62 79 20 66 74 73   returned by fts
2cc0: 35 5f 74 65 73 74 5f 70 6f 73 6c 69 73 74 28 29  5_test_poslist()
2cd0: 20 74 6f 20 61 20 0a 23 20 63 6f 6c 6c 69 73 74   to a .# collist
2ce0: 20 61 73 20 72 65 74 75 72 6e 65 64 20 62 79 20   as returned by 
2cf0: 66 74 73 35 5f 74 65 73 74 5f 63 6f 6c 6c 69 73  fts5_test_collis
2d00: 74 28 29 2e 0a 23 0a 70 72 6f 63 20 66 74 73 35  t()..#.proc fts5
2d10: 5f 70 6f 73 6c 69 73 74 32 63 6f 6c 6c 69 73 74  _poslist2collist
2d20: 20 7b 70 6f 73 6c 69 73 74 7d 20 7b 0a 20 20 73   {poslist} {.  s
2d30: 65 74 20 72 65 73 20 5b 6c 69 73 74 5d 0a 20 20  et res [list].  
2d40: 66 6f 72 65 61 63 68 20 68 20 24 70 6f 73 6c 69  foreach h $posli
2d50: 73 74 20 7b 0a 20 20 20 20 72 65 67 65 78 70 20  st {.    regexp 
2d60: 7b 28 2e 2a 29 5c 2e 5b 31 32 33 34 35 36 37 38  {(.*)\.[12345678
2d70: 39 30 5d 2b 7d 20 24 68 20 2d 3e 20 63 61 6e 64  90]+} $h -> cand
2d80: 0a 20 20 20 20 6c 61 70 70 65 6e 64 20 72 65 73  .    lappend res
2d90: 20 24 63 61 6e 64 0a 20 20 7d 0a 20 20 73 65 74   $cand.  }.  set
2da0: 20 72 65 73 20 5b 6c 73 6f 72 74 20 2d 63 6f 6d   res [lsort -com
2db0: 6d 61 6e 64 20 66 74 73 35 5f 63 6f 6c 6c 69 73  mand fts5_collis
2dc0: 74 5f 65 6c 65 6d 5f 63 6f 6d 70 61 72 65 20 2d  t_elem_compare -
2dd0: 75 6e 69 71 75 65 20 24 72 65 73 5d 0a 20 20 72  unique $res].  r
2de0: 65 74 75 72 6e 20 24 72 65 73 0a 7d 0a 0a 23 20  eturn $res.}..# 
2df0: 43 6f 6d 70 61 72 69 73 6f 6e 20 66 75 6e 63 74  Comparison funct
2e00: 69 6f 6e 20 75 73 65 64 20 62 79 20 66 74 73 35  ion used by fts5
2e10: 5f 70 6f 73 6c 69 73 74 32 63 6f 6c 6c 69 73 74  _poslist2collist
2e20: 20 74 6f 20 73 6f 72 74 20 63 6f 6c 6c 69 73 74   to sort collist
2e30: 20 65 6e 74 72 69 65 73 2e 0a 70 72 6f 63 20 66   entries..proc f
2e40: 74 73 35 5f 63 6f 6c 6c 69 73 74 5f 65 6c 65 6d  ts5_collist_elem
2e50: 5f 63 6f 6d 70 61 72 65 20 7b 61 20 62 7d 20 7b  _compare {a b} {
2e60: 0a 20 20 66 6f 72 65 61 63 68 20 7b 61 31 20 61  .  foreach {a1 a
2e70: 32 7d 20 5b 73 70 6c 69 74 20 24 61 20 2e 5d 20  2} [split $a .] 
2e80: 7b 7d 0a 20 20 66 6f 72 65 61 63 68 20 7b 62 31  {}.  foreach {b1
2e90: 20 62 32 7d 20 5b 73 70 6c 69 74 20 24 62 20 2e   b2} [split $b .
2ea0: 5d 20 7b 7d 0a 0a 20 20 69 66 20 7b 24 61 31 3d  ] {}..  if {$a1=
2eb0: 3d 24 62 31 7d 20 7b 20 72 65 74 75 72 6e 20 5b  =$b1} { return [
2ec0: 65 78 70 72 20 24 61 32 20 2d 20 24 62 32 5d 20  expr $a2 - $b2] 
2ed0: 7d 0a 20 20 72 65 74 75 72 6e 20 5b 65 78 70 72  }.  return [expr
2ee0: 20 24 61 31 20 2d 20 24 62 31 5d 0a 7d 0a 0a 0a   $a1 - $b1].}...
2ef0: 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  #---------------
2f00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2f10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2f20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2f30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 43 6f  -----------.# Co
2f40: 6e 73 74 72 75 63 74 20 61 6e 64 20 72 65 74 75  nstruct and retu
2f50: 72 6e 20 61 20 74 63 6c 20 6c 69 73 74 20 65 71  rn a tcl list eq
2f60: 75 69 76 61 6c 65 6e 74 20 74 6f 20 74 68 61 74  uivalent to that
2f70: 20 72 65 74 75 72 6e 65 64 20 62 79 20 74 68 65   returned by the
2f80: 20 53 51 4c 0a 23 20 71 75 65 72 79 20 65 78 65   SQL.# query exe
2f90: 63 75 74 65 64 20 61 67 61 69 6e 73 74 20 64 61  cuted against da
2fa0: 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 5b 64  tabase handle [d
2fb0: 62 5d 3a 0a 23 0a 23 20 20 20 53 45 4c 45 43 54  b]:.#.#   SELECT
2fc0: 20 0a 23 20 20 20 20 20 72 6f 77 69 64 2c 20 0a   .#     rowid, .
2fd0: 23 20 20 20 20 20 66 74 73 35 5f 74 65 73 74 5f  #     fts5_test_
2fe0: 70 6f 73 6c 69 73 74 28 24 74 62 6c 29 2c 0a 23  poslist($tbl),.#
2ff0: 20 20 20 20 20 66 74 73 35 5f 74 65 73 74 5f 63       fts5_test_c
3000: 6f 6c 6c 69 73 74 28 24 74 62 6c 29 20 0a 23 20  ollist($tbl) .# 
3010: 20 20 46 52 4f 4d 20 24 74 62 6c 28 27 24 65 78    FROM $tbl('$ex
3020: 70 72 27 29 0a 23 20 20 20 4f 52 44 45 52 20 42  pr').#   ORDER B
3030: 59 20 72 6f 77 69 64 20 24 6f 72 64 65 72 3b 0a  Y rowid $order;.
3040: 23 0a 70 72 6f 63 20 66 74 73 35 5f 71 75 65 72  #.proc fts5_quer
3050: 79 5f 64 61 74 61 20 7b 65 78 70 72 20 74 62 6c  y_data {expr tbl
3060: 20 7b 6f 72 64 65 72 20 41 53 43 7d 20 7b 61 44   {order ASC} {aD
3070: 69 63 74 56 61 72 20 22 22 7d 7d 20 7b 0a 0a 20  ictVar ""}} {.. 
3080: 20 23 20 46 69 67 75 72 65 20 6f 75 74 20 74 68   # Figure out th
3090: 65 20 73 65 74 20 6f 66 20 63 6f 6c 75 6d 6e 73  e set of columns
30a0: 20 69 6e 20 74 68 65 20 46 54 53 35 20 74 61 62   in the FTS5 tab
30b0: 6c 65 2e 20 54 68 69 73 20 72 6f 75 74 69 6e 65  le. This routine
30c0: 20 64 6f 65 73 0a 20 20 23 20 6e 6f 74 20 68 61   does.  # not ha
30d0: 6e 64 6c 65 20 74 61 62 6c 65 73 20 77 69 74 68  ndle tables with
30e0: 20 55 4e 49 4e 44 45 58 45 44 20 63 6f 6c 75 6d   UNINDEXED colum
30f0: 6e 73 2c 20 62 75 74 20 69 66 20 69 74 20 64 69  ns, but if it di
3100: 64 2c 20 69 74 20 77 6f 75 6c 64 0a 20 20 23 20  d, it would.  # 
3110: 68 61 76 65 20 74 6f 20 62 65 20 68 65 72 65 2e  have to be here.
3120: 0a 20 20 64 62 20 65 76 61 6c 20 22 50 52 41 47  .  db eval "PRAG
3130: 4d 41 20 74 61 62 6c 65 5f 69 6e 66 6f 20 3d 20  MA table_info = 
3140: 24 74 62 6c 22 20 78 20 7b 20 6c 61 70 70 65 6e  $tbl" x { lappen
3150: 64 20 6c 43 6f 6c 73 20 24 78 28 6e 61 6d 65 29  d lCols $x(name)
3160: 20 7d 0a 0a 20 20 73 65 74 20 64 20 22 22 0a 20   }..  set d "". 
3170: 20 69 66 20 7b 24 61 44 69 63 74 56 61 72 20 21   if {$aDictVar !
3180: 3d 20 22 22 7d 20 7b 0a 20 20 20 20 75 70 76 61  = ""} {.    upva
3190: 72 20 24 61 44 69 63 74 56 61 72 20 61 44 69 63  r $aDictVar aDic
31a0: 74 0a 20 20 20 20 73 65 74 20 64 20 61 44 69 63  t.    set d aDic
31b0: 74 0a 20 20 7d 0a 0a 20 20 73 65 74 20 63 6f 6c  t.  }..  set col
31c0: 73 20 22 22 0a 20 20 66 6f 72 65 61 63 68 20 65  s "".  foreach e
31d0: 20 24 6c 43 6f 6c 73 20 7b 20 61 70 70 65 6e 64   $lCols { append
31e0: 20 63 6f 6c 73 20 22 2c 20 27 24 65 27 22 20 7d   cols ", '$e'" }
31f0: 0a 20 20 73 65 74 20 74 63 6c 65 78 70 72 20 5b  .  set tclexpr [
3200: 64 62 20 6f 6e 65 20 5b 73 75 62 73 74 20 2d 6e  db one [subst -n
3210: 6f 76 61 72 20 7b 0a 20 20 20 20 53 45 4c 45 43  ovar {.    SELEC
3220: 54 20 66 74 73 35 5f 65 78 70 72 5f 74 63 6c 28  T fts5_expr_tcl(
3230: 20 24 65 78 70 72 2c 20 27 6e 65 61 72 73 65 74   $expr, 'nearset
3240: 20 24 63 6f 6c 73 20 2d 64 69 63 74 20 24 64 20   $cols -dict $d 
3250: 2d 70 63 20 3a 3a 70 63 27 20 5b 73 65 74 20 63  -pc ::pc' [set c
3260: 6f 6c 73 5d 20 29 0a 20 20 7d 5d 5d 0a 0a 20 20  ols] ).  }]]..  
3270: 73 65 74 20 72 65 73 20 5b 6c 69 73 74 5d 0a 20  set res [list]. 
3280: 20 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54   db eval "SELECT
3290: 20 72 6f 77 69 64 2c 20 2a 20 46 52 4f 4d 20 24   rowid, * FROM $
32a0: 74 62 6c 20 4f 52 44 45 52 20 42 59 20 72 6f 77  tbl ORDER BY row
32b0: 69 64 20 24 6f 72 64 65 72 22 20 78 20 7b 0a 20  id $order" x {. 
32c0: 20 20 20 73 65 74 20 63 6f 6c 73 20 5b 6c 69 73     set cols [lis
32d0: 74 5d 0a 20 20 20 20 66 6f 72 65 61 63 68 20 63  t].    foreach c
32e0: 6f 6c 20 24 6c 43 6f 6c 73 20 7b 20 6c 61 70 70  ol $lCols { lapp
32f0: 65 6e 64 20 63 6f 6c 73 20 24 78 28 24 63 6f 6c  end cols $x($col
3300: 29 20 7d 0a 20 20 20 20 0a 20 20 20 20 73 65 74  ) }.    .    set
3310: 20 3a 3a 70 63 20 30 0a 20 20 20 20 73 65 74 20   ::pc 0.    set 
3320: 72 6f 77 64 61 74 61 20 5b 65 76 61 6c 20 24 74  rowdata [eval $t
3330: 63 6c 65 78 70 72 5d 0a 20 20 20 20 69 66 20 7b  clexpr].    if {
3340: 24 72 6f 77 64 61 74 61 20 21 3d 20 22 22 7d 20  $rowdata != ""} 
3350: 7b 20 0a 20 20 20 20 20 20 6c 61 70 70 65 6e 64  { .      lappend
3360: 20 72 65 73 20 24 78 28 72 6f 77 69 64 29 20 24   res $x(rowid) $
3370: 72 6f 77 64 61 74 61 20 5b 66 74 73 35 5f 70 6f  rowdata [fts5_po
3380: 73 6c 69 73 74 32 63 6f 6c 6c 69 73 74 20 24 72  slist2collist $r
3390: 6f 77 64 61 74 61 5d 0a 20 20 20 20 7d 0a 20 20  owdata].    }.  
33a0: 7d 0a 0a 20 20 73 65 74 20 72 65 73 0a 7d 0a 0a  }..  set res.}..
33b0: 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  #---------------
33c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
33d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
33e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
33f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 53 69 6d  ----------.# Sim
3400: 69 6c 61 72 20 74 6f 20 5b 66 74 73 35 5f 71 75  ilar to [fts5_qu
3410: 65 72 79 5f 64 61 74 61 5d 2c 20 62 75 74 20 6f  ery_data], but o
3420: 6d 69 74 20 74 68 65 20 63 6f 6c 6c 69 73 74 20  mit the collist 
3430: 66 69 65 6c 64 2e 0a 23 0a 70 72 6f 63 20 66 74  field..#.proc ft
3440: 73 35 5f 70 6f 73 6c 69 73 74 5f 64 61 74 61 20  s5_poslist_data 
3450: 7b 65 78 70 72 20 74 62 6c 20 7b 6f 72 64 65 72  {expr tbl {order
3460: 20 41 53 43 7d 20 7b 61 44 69 63 74 56 61 72 20   ASC} {aDictVar 
3470: 22 22 7d 7d 20 7b 0a 20 20 73 65 74 20 72 65 73  ""}} {.  set res
3480: 20 5b 6c 69 73 74 5d 0a 0a 20 20 69 66 20 7b 24   [list]..  if {$
3490: 61 44 69 63 74 56 61 72 21 3d 22 22 7d 20 7b 0a  aDictVar!=""} {.
34a0: 20 20 20 20 75 70 76 61 72 20 24 61 44 69 63 74      upvar $aDict
34b0: 56 61 72 20 61 44 69 63 74 0a 20 20 20 20 73 65  Var aDict.    se
34c0: 74 20 64 69 63 74 20 61 44 69 63 74 0a 20 20 7d  t dict aDict.  }
34d0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20   else {.    set 
34e0: 64 69 63 74 20 22 22 0a 20 20 7d 0a 0a 20 20 66  dict "".  }..  f
34f0: 6f 72 65 61 63 68 20 7b 72 6f 77 69 64 20 70 6f  oreach {rowid po
3500: 73 6c 69 73 74 20 63 6f 6c 6c 69 73 74 7d 20 5b  slist collist} [
3510: 66 74 73 35 5f 71 75 65 72 79 5f 64 61 74 61 20  fts5_query_data 
3520: 24 65 78 70 72 20 24 74 62 6c 20 24 6f 72 64 65  $expr $tbl $orde
3530: 72 20 24 64 69 63 74 5d 20 7b 0a 20 20 20 20 6c  r $dict] {.    l
3540: 61 70 70 65 6e 64 20 72 65 73 20 24 72 6f 77 69  append res $rowi
3550: 64 20 24 70 6f 73 6c 69 73 74 0a 20 20 7d 0a 20  d $poslist.  }. 
3560: 20 73 65 74 20 72 65 73 0a 7d 0a 0a 70 72 6f 63   set res.}..proc
3570: 20 66 74 73 35 5f 63 6f 6c 6c 69 73 74 5f 64 61   fts5_collist_da
3580: 74 61 20 7b 65 78 70 72 20 74 62 6c 20 7b 6f 72  ta {expr tbl {or
3590: 64 65 72 20 41 53 43 7d 20 7b 61 44 69 63 74 56  der ASC} {aDictV
35a0: 61 72 20 22 22 7d 7d 20 7b 0a 20 20 73 65 74 20  ar ""}} {.  set 
35b0: 72 65 73 20 5b 6c 69 73 74 5d 0a 0a 20 20 69 66  res [list]..  if
35c0: 20 7b 24 61 44 69 63 74 56 61 72 21 3d 22 22 7d   {$aDictVar!=""}
35d0: 20 7b 0a 20 20 20 20 75 70 76 61 72 20 24 61 44   {.    upvar $aD
35e0: 69 63 74 56 61 72 20 61 44 69 63 74 0a 20 20 20  ictVar aDict.   
35f0: 20 73 65 74 20 64 69 63 74 20 61 44 69 63 74 0a   set dict aDict.
3600: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73    } else {.    s
3610: 65 74 20 64 69 63 74 20 22 22 0a 20 20 7d 0a 0a  et dict "".  }..
3620: 20 20 66 6f 72 65 61 63 68 20 7b 72 6f 77 69 64    foreach {rowid
3630: 20 70 6f 73 6c 69 73 74 20 63 6f 6c 6c 69 73 74   poslist collist
3640: 7d 20 5b 66 74 73 35 5f 71 75 65 72 79 5f 64 61  } [fts5_query_da
3650: 74 61 20 24 65 78 70 72 20 24 74 62 6c 20 24 6f  ta $expr $tbl $o
3660: 72 64 65 72 20 24 64 69 63 74 5d 20 7b 0a 20 20  rder $dict] {.  
3670: 20 20 6c 61 70 70 65 6e 64 20 72 65 73 20 24 72    lappend res $r
3680: 6f 77 69 64 20 24 63 6f 6c 6c 69 73 74 0a 20 20  owid $collist.  
3690: 7d 0a 20 20 73 65 74 20 72 65 73 0a 7d 0a 0a 23  }.  set res.}..#
36a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
36b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
36c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
36d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
36e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 0a 23 20 54  ---------.#..# T
36f0: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 77 69 6c 6c  his command will
3700: 20 6f 6e 6c 79 20 77 6f 72 6b 20 69 6e 73 69 64   only work insid
3710: 65 20 61 20 5b 66 6f 72 65 61 63 68 5f 64 65 74  e a [foreach_det
3720: 61 69 6c 5f 6d 6f 64 65 5d 20 62 6c 6f 63 6b 2e  ail_mode] block.
3730: 20 49 74 20 74 65 73 74 73 0a 23 20 77 68 65 74   It tests.# whet
3740: 68 65 72 20 6f 72 20 6e 6f 74 20 65 78 70 72 65  her or not expre
3750: 73 73 69 6f 6e 20 24 65 78 70 72 20 72 75 6e 20  ssion $expr run 
3760: 6f 6e 20 46 54 53 35 20 74 61 62 6c 65 20 24 74  on FTS5 table $t
3770: 62 6c 20 69 73 20 73 75 70 70 6f 72 74 65 64 20  bl is supported 
3780: 62 79 0a 23 20 74 68 65 20 63 75 72 72 65 6e 74  by.# the current
3790: 20 6d 6f 64 65 2e 20 49 66 20 73 6f 2c 20 31 20   mode. If so, 1 
37a0: 69 73 20 72 65 74 75 72 6e 65 64 2e 20 49 66 20  is returned. If 
37b0: 6e 6f 74 2c 20 30 2e 0a 23 0a 23 20 20 20 64 65  not, 0..#.#   de
37c0: 74 61 69 6c 3d 66 75 6c 6c 20 20 20 20 28 61 6c  tail=full    (al
37d0: 6c 20 71 75 65 72 69 65 73 20 73 75 70 70 6f 72  l queries suppor
37e0: 74 65 64 29 0a 23 20 20 20 64 65 74 61 69 6c 3d  ted).#   detail=
37f0: 63 6f 6c 20 20 20 20 20 28 61 6c 6c 20 62 75 74  col     (all but
3800: 20 70 68 72 61 73 65 20 71 75 65 72 69 65 73 20   phrase queries 
3810: 61 6e 64 20 4e 45 41 52 20 71 75 65 72 69 65 73  and NEAR queries
3820: 29 0a 23 20 20 20 64 65 74 61 69 6c 3d 6e 6f 6e  ).#   detail=non
3830: 65 20 20 20 20 28 61 6c 6c 20 62 75 74 20 70 68  e    (all but ph
3840: 72 61 73 65 20 71 75 65 72 69 65 73 2c 20 4e 45  rase queries, NE
3850: 41 52 20 71 75 65 72 69 65 73 2c 20 61 6e 64 20  AR queries, and 
3860: 63 6f 6c 75 6d 6e 20 66 69 6c 74 65 72 73 29 0a  column filters).
3870: 23 0a 70 72 6f 63 20 66 74 73 35 5f 65 78 70 72  #.proc fts5_expr
3880: 5f 6f 6b 20 7b 65 78 70 72 20 74 62 6c 7d 20 7b  _ok {expr tbl} {
3890: 0a 0a 20 20 69 66 20 7b 21 5b 64 65 74 61 69 6c  ..  if {![detail
38a0: 5f 69 73 5f 66 75 6c 6c 5d 7d 20 7b 0a 20 20 20  _is_full]} {.   
38b0: 20 73 65 74 20 6e 65 61 72 73 65 74 20 22 6e 65   set nearset "ne
38c0: 61 72 73 65 74 5f 72 63 22 0a 20 20 20 20 69 66  arset_rc".    if
38d0: 20 7b 5b 64 65 74 61 69 6c 5f 69 73 5f 63 6f 6c   {[detail_is_col
38e0: 5d 7d 20 7b 20 73 65 74 20 6e 65 61 72 73 65 74  ]} { set nearset
38f0: 20 22 6e 65 61 72 73 65 74 5f 72 66 22 20 7d 0a   "nearset_rf" }.
3900: 0a 20 20 20 20 73 65 74 20 3a 3a 65 78 70 72 5f  .    set ::expr_
3910: 6e 6f 74 5f 6f 6b 20 30 0a 20 20 20 20 64 62 20  not_ok 0.    db 
3920: 65 76 61 6c 20 22 50 52 41 47 4d 41 20 74 61 62  eval "PRAGMA tab
3930: 6c 65 5f 69 6e 66 6f 20 3d 20 24 74 62 6c 22 20  le_info = $tbl" 
3940: 78 20 7b 20 6c 61 70 70 65 6e 64 20 6c 43 6f 6c  x { lappend lCol
3950: 73 20 24 78 28 6e 61 6d 65 29 20 7d 0a 0a 20 20  s $x(name) }..  
3960: 20 20 73 65 74 20 63 6f 6c 73 20 22 22 0a 20 20    set cols "".  
3970: 20 20 66 6f 72 65 61 63 68 20 65 20 24 6c 43 6f    foreach e $lCo
3980: 6c 73 20 7b 20 61 70 70 65 6e 64 20 63 6f 6c 73  ls { append cols
3990: 20 22 2c 20 27 24 65 27 22 20 7d 0a 20 20 20 20   ", '$e'" }.    
39a0: 73 65 74 20 3a 3a 70 63 20 30 0a 20 20 20 20 73  set ::pc 0.    s
39b0: 65 74 20 74 63 6c 65 78 70 72 20 5b 64 62 20 6f  et tclexpr [db o
39c0: 6e 65 20 5b 73 75 62 73 74 20 2d 6e 6f 76 61 72  ne [subst -novar
39d0: 20 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20   {.      SELECT 
39e0: 66 74 73 35 5f 65 78 70 72 5f 74 63 6c 28 20 24  fts5_expr_tcl( $
39f0: 65 78 70 72 2c 20 27 5b 73 65 74 20 6e 65 61 72  expr, '[set near
3a00: 73 65 74 5d 20 24 63 6f 6c 73 20 2d 70 63 20 3a  set] $cols -pc :
3a10: 3a 70 63 27 20 5b 73 65 74 20 63 6f 6c 73 5d 20  :pc' [set cols] 
3a20: 29 0a 20 20 20 20 7d 5d 5d 0a 20 20 20 20 65 76  ).    }]].    ev
3a30: 61 6c 20 24 74 63 6c 65 78 70 72 0a 20 20 20 20  al $tclexpr.    
3a40: 69 66 20 7b 24 3a 3a 65 78 70 72 5f 6e 6f 74 5f  if {$::expr_not_
3a50: 6f 6b 7d 20 7b 20 72 65 74 75 72 6e 20 30 20 7d  ok} { return 0 }
3a60: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 31  .  }..  return 1
3a70: 0a 7d 0a 0a 23 20 48 65 6c 70 65 72 20 66 6f 72  .}..# Helper for
3a80: 20 5b 66 74 73 35 5f 65 78 70 72 5f 6f 6b 5d 0a   [fts5_expr_ok].
3a90: 70 72 6f 63 20 6e 65 61 72 73 65 74 5f 72 66 20  proc nearset_rf 
3aa0: 7b 61 43 6f 6c 20 61 72 67 73 7d 20 7b 0a 20 20  {aCol args} {.  
3ab0: 73 65 74 20 69 64 78 20 5b 6c 73 65 61 72 63 68  set idx [lsearch
3ac0: 20 2d 65 78 61 63 74 20 24 61 72 67 73 20 2d 2d   -exact $args --
3ad0: 5d 0a 20 20 69 66 20 7b 24 69 64 78 20 21 3d 20  ].  if {$idx != 
3ae0: 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 2d  [llength $args]-
3af0: 32 20 7c 7c 20 5b 6c 6c 65 6e 67 74 68 20 5b 6c  2 || [llength [l
3b00: 69 6e 64 65 78 20 24 61 72 67 73 20 65 6e 64 5d  index $args end]
3b10: 5d 21 3d 31 7d 20 7b 0a 20 20 20 20 73 65 74 20  ]!=1} {.    set 
3b20: 3a 3a 65 78 70 72 5f 6e 6f 74 5f 6f 6b 20 31 0a  ::expr_not_ok 1.
3b30: 20 20 7d 0a 20 20 6c 69 73 74 0a 7d 0a 0a 23 20    }.  list.}..# 
3b40: 48 65 6c 70 65 72 20 66 6f 72 20 5b 66 74 73 35  Helper for [fts5
3b50: 5f 65 78 70 72 5f 6f 6b 5d 0a 70 72 6f 63 20 6e  _expr_ok].proc n
3b60: 65 61 72 73 65 74 5f 72 63 20 7b 61 43 6f 6c 20  earset_rc {aCol 
3b70: 61 72 67 73 7d 20 7b 0a 20 20 6e 65 61 72 73 65  args} {.  nearse
3b80: 74 5f 72 66 20 24 61 43 6f 6c 20 7b 2a 7d 24 61  t_rf $aCol {*}$a
3b90: 72 67 73 0a 20 20 69 66 20 7b 5b 6c 73 65 61 72  rgs.  if {[lsear
3ba0: 63 68 20 24 61 72 67 73 20 2d 63 6f 6c 5d 3e 3d  ch $args -col]>=
3bb0: 30 7d 20 7b 20 0a 20 20 20 20 73 65 74 20 3a 3a  0} { .    set ::
3bc0: 65 78 70 72 5f 6e 6f 74 5f 6f 6b 20 31 0a 20 20  expr_not_ok 1.  
3bd0: 7d 0a 20 20 6c 69 73 74 0a 7d 0a 0a 0a 23 2d 2d  }.  list.}...#--
3be0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3bf0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3c00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3c10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3c20: 2d 2d 2d 2d 2d 2d 2d 0a 23 20 43 6f 64 65 20 66  -------.# Code f
3c30: 6f 72 20 61 20 73 69 6d 70 6c 65 20 54 63 6c 20  or a simple Tcl 
3c40: 74 6f 6b 65 6e 69 7a 65 72 20 74 68 61 74 20 73  tokenizer that s
3c50: 75 70 70 6f 72 74 73 20 73 79 6e 6f 6e 79 6d 73  upports synonyms
3c60: 20 61 74 20 71 75 65 72 79 20 74 69 6d 65 2e 0a   at query time..
3c70: 23 0a 70 72 6f 63 20 74 63 6c 6e 75 6d 5f 74 6f  #.proc tclnum_to
3c80: 6b 65 6e 69 7a 65 20 7b 6d 6f 64 65 20 74 66 6c  kenize {mode tfl
3c90: 61 67 73 20 74 65 78 74 7d 20 7b 0a 20 20 66 6f  ags text} {.  fo
3ca0: 72 65 61 63 68 20 7b 77 20 69 53 74 61 72 74 20  reach {w iStart 
3cb0: 69 45 6e 64 7d 20 5b 66 74 73 35 5f 74 6f 6b 65  iEnd} [fts5_toke
3cc0: 6e 69 7a 65 5f 73 70 6c 69 74 20 24 74 65 78 74  nize_split $text
3cd0: 5d 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  ] {.    sqlite3_
3ce0: 66 74 73 35 5f 74 6f 6b 65 6e 20 24 77 20 24 69  fts5_token $w $i
3cf0: 53 74 61 72 74 20 24 69 45 6e 64 0a 20 20 20 20  Start $iEnd.    
3d00: 69 66 20 7b 24 74 66 6c 61 67 73 20 3d 3d 20 24  if {$tflags == $
3d10: 6d 6f 64 65 20 26 26 20 5b 69 6e 66 6f 20 65 78  mode && [info ex
3d20: 69 73 74 73 20 3a 3a 74 63 6c 6e 75 6d 5f 73 79  ists ::tclnum_sy
3d30: 6e 28 24 77 29 5d 7d 20 7b 0a 20 20 20 20 20 20  n($w)]} {.      
3d40: 66 6f 72 65 61 63 68 20 73 20 24 3a 3a 74 63 6c  foreach s $::tcl
3d50: 6e 75 6d 5f 73 79 6e 28 24 77 29 20 20 7b 20 73  num_syn($w)  { s
3d60: 71 6c 69 74 65 33 5f 66 74 73 35 5f 74 6f 6b 65  qlite3_fts5_toke
3d70: 6e 20 2d 63 6f 6c 6f 20 24 73 20 24 69 53 74 61  n -colo $s $iSta
3d80: 72 74 20 24 69 45 6e 64 20 7d 0a 20 20 20 20 7d  rt $iEnd }.    }
3d90: 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 74 63 6c  .  }.}..proc tcl
3da0: 6e 75 6d 5f 63 72 65 61 74 65 20 7b 61 72 67 73  num_create {args
3db0: 7d 20 7b 0a 20 20 73 65 74 20 6d 6f 64 65 20 71  } {.  set mode q
3dc0: 75 65 72 79 0a 20 20 69 66 20 7b 5b 6c 6c 65 6e  uery.  if {[llen
3dd0: 67 74 68 20 24 61 72 67 73 5d 7d 20 7b 0a 20 20  gth $args]} {.  
3de0: 20 20 73 65 74 20 6d 6f 64 65 20 5b 6c 69 6e 64    set mode [lind
3df0: 65 78 20 24 61 72 67 73 20 30 5d 0a 20 20 7d 0a  ex $args 0].  }.
3e00: 20 20 69 66 20 7b 24 6d 6f 64 65 20 21 3d 20 22    if {$mode != "
3e10: 71 75 65 72 79 22 20 26 26 20 24 6d 6f 64 65 20  query" && $mode 
3e20: 21 3d 20 22 64 6f 63 75 6d 65 6e 74 22 7d 20 7b  != "document"} {
3e30: 20 65 72 72 6f 72 20 22 62 61 64 20 6d 6f 64 65   error "bad mode
3e40: 3a 20 24 6d 6f 64 65 22 20 7d 0a 20 20 72 65 74  : $mode" }.  ret
3e50: 75 72 6e 20 5b 6c 69 73 74 20 74 63 6c 6e 75 6d  urn [list tclnum
3e60: 5f 74 6f 6b 65 6e 69 7a 65 20 24 6d 6f 64 65 5d  _tokenize $mode]
3e70: 0a 7d 0a 0a 70 72 6f 63 20 66 74 73 35 5f 74 63  .}..proc fts5_tc
3e80: 6c 6e 75 6d 5f 72 65 67 69 73 74 65 72 20 7b 64  lnum_register {d
3e90: 62 7d 20 7b 0a 20 20 66 6f 72 65 61 63 68 20 53  b} {.  foreach S
3ea0: 59 4e 44 49 43 54 20 7b 0a 20 20 20 20 7b 7a 65  YNDICT {.    {ze
3eb0: 72 6f 20 20 30 7d 0a 20 20 20 20 7b 6f 6e 65 20  ro  0}.    {one 
3ec0: 20 20 31 20 69 7d 0a 20 20 20 20 7b 74 77 6f 20    1 i}.    {two 
3ed0: 20 20 32 20 69 69 7d 0a 20 20 20 20 7b 74 68 72    2 ii}.    {thr
3ee0: 65 65 20 33 20 69 69 69 7d 0a 20 20 20 20 7b 66  ee 3 iii}.    {f
3ef0: 6f 75 72 20 20 34 20 69 76 7d 0a 20 20 20 20 7b  our  4 iv}.    {
3f00: 66 69 76 65 20 20 35 20 76 7d 0a 20 20 20 20 7b  five  5 v}.    {
3f10: 73 69 78 20 20 20 36 20 76 69 7d 0a 20 20 20 20  six   6 vi}.    
3f20: 7b 73 65 76 65 6e 20 37 20 76 69 69 7d 0a 20 20  {seven 7 vii}.  
3f30: 20 20 7b 65 69 67 68 74 20 38 20 76 69 69 69 7d    {eight 8 viii}
3f40: 0a 20 20 20 20 7b 6e 69 6e 65 20 20 39 20 69 78  .    {nine  9 ix
3f50: 7d 0a 0a 20 20 20 20 7b 61 31 20 61 32 20 61 33  }..    {a1 a2 a3
3f60: 20 61 34 20 61 35 20 61 36 20 61 37 20 61 38 20   a4 a5 a6 a7 a8 
3f70: 61 39 7d 0a 20 20 20 20 7b 62 31 20 62 32 20 62  a9}.    {b1 b2 b
3f80: 33 20 62 34 20 62 35 20 62 36 20 62 37 20 62 38  3 b4 b5 b6 b7 b8
3f90: 20 62 39 7d 0a 20 20 20 20 7b 63 31 20 63 32 20   b9}.    {c1 c2 
3fa0: 63 33 20 63 34 20 63 35 20 63 36 20 63 37 20 63  c3 c4 c5 c6 c7 c
3fb0: 38 20 63 39 7d 0a 20 20 7d 20 7b 0a 20 20 20 20  8 c9}.  } {.    
3fc0: 66 6f 72 65 61 63 68 20 73 20 24 53 59 4e 44 49  foreach s $SYNDI
3fd0: 43 54 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6f  CT {.      set o
3fe0: 20 5b 6c 69 73 74 5d 0a 20 20 20 20 20 20 66 6f   [list].      fo
3ff0: 72 65 61 63 68 20 78 20 24 53 59 4e 44 49 43 54  reach x $SYNDICT
4000: 20 7b 69 66 20 7b 24 78 21 3d 24 73 7d 20 7b 6c   {if {$x!=$s} {l
4010: 61 70 70 65 6e 64 20 6f 20 24 78 7d 7d 0a 20 20  append o $x}}.  
4020: 20 20 20 20 73 65 74 20 3a 3a 74 63 6c 6e 75 6d      set ::tclnum
4030: 5f 73 79 6e 28 24 73 29 20 24 6f 0a 20 20 20 20  _syn($s) $o.    
4040: 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  }.  }.  sqlite3_
4050: 66 74 73 35 5f 63 72 65 61 74 65 5f 74 6f 6b 65  fts5_create_toke
4060: 6e 69 7a 65 72 20 64 62 20 74 63 6c 6e 75 6d 20  nizer db tclnum 
4070: 74 63 6c 6e 75 6d 5f 63 72 65 61 74 65 0a 7d 0a  tclnum_create.}.
4080: 23 0a 23 20 45 6e 64 20 6f 66 20 74 6f 6b 65 6e  #.# End of token
4090: 69 7a 65 72 20 63 6f 64 65 2e 0a 23 2d 2d 2d 2d  izer code..#----
40a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
40b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
40c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
40d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
40e0: 2d 2d 2d 2d 2d 0a 0a                             -----..