/ Hex Artifact Content
Login

Artifact 31935839b1b601a5955572cb4e8060513c96bde0:


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 55 53 41 47 45 3a 20 66 74 73 33 5f 69  .# USAGE: fts3_i
0260: 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b 20 54  ntegrity_check T
0270: 42 4c 0a 23 0a 23 20 54 68 69 73 20 70 72 6f 63  BL.#.# This proc
0280: 20 69 73 20 75 73 65 64 20 74 6f 20 76 65 72 69   is used to veri
0290: 66 79 20 74 68 61 74 20 74 68 65 20 66 75 6c 6c  fy that the full
02a0: 2d 74 65 78 74 20 69 6e 64 65 78 20 69 73 20 63  -text index is c
02b0: 6f 6e 73 69 73 74 65 6e 74 20 77 69 74 68 0a 23  onsistent with.#
02c0: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
02d0: 20 74 68 65 20 66 74 73 33 20 74 61 62 6c 65 2e   the fts3 table.
02e0: 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c   In other words,
02f0: 20 69 74 20 63 68 65 63 6b 73 20 74 68 61 74 20   it checks that 
0300: 74 68 65 0a 23 20 64 61 74 61 20 69 6e 20 74 68  the.# data in th
0310: 65 20 25 5f 63 6f 6e 74 65 6e 74 73 20 74 61 62  e %_contents tab
0320: 6c 65 20 6d 61 74 63 68 65 73 20 74 68 61 74 20  le matches that 
0330: 69 6e 20 74 68 65 20 25 5f 73 65 67 64 69 72 20  in the %_segdir 
0340: 61 6e 64 20 25 5f 73 65 67 6d 65 6e 74 73 20 0a  and %_segments .
0350: 23 20 74 61 62 6c 65 73 2e 0a 23 0a 23 20 54 68  # tables..#.# Th
0360: 69 73 20 69 73 20 6e 6f 74 20 61 6e 20 65 66 66  is is not an eff
0370: 69 63 69 65 6e 74 20 70 72 6f 63 65 64 75 72 65  icient procedure
0380: 2e 20 49 74 20 75 73 65 73 20 61 20 6c 6f 74 20  . It uses a lot 
0390: 6f 66 20 6d 65 6d 6f 72 79 20 61 6e 64 20 61 20  of memory and a 
03a0: 6c 6f 74 0a 23 20 6f 66 20 43 50 55 2e 20 42 75  lot.# of CPU. Bu
03b0: 74 20 69 74 20 69 73 20 62 65 74 74 65 72 20 74  t it is better t
03c0: 68 61 6e 20 6e 6f 74 20 63 68 65 63 6b 69 6e 67  han not checking
03d0: 20 61 74 20 61 6c 6c 2e 0a 23 0a 23 20 54 68 65   at all..#.# The
03e0: 20 70 72 6f 63 65 64 75 72 65 20 69 73 3a 0a 23   procedure is:.#
03f0: 0a 23 20 20 20 31 29 20 52 65 61 64 20 74 68 65  .#   1) Read the
0400: 20 65 6e 74 69 72 65 20 66 75 6c 6c 2d 74 65 78   entire full-tex
0410: 74 20 69 6e 64 65 78 20 66 72 6f 6d 20 74 68 65  t index from the
0420: 20 25 5f 73 65 67 64 69 72 20 61 6e 64 20 25 5f   %_segdir and %_
0430: 73 65 67 6d 65 6e 74 73 0a 23 20 20 20 20 20 20  segments.#      
0440: 74 61 62 6c 65 73 20 69 6e 74 6f 20 6d 65 6d 6f  tables into memo
0450: 72 79 2e 20 46 6f 72 20 65 61 63 68 20 65 6e 74  ry. For each ent
0460: 72 79 20 69 6e 20 74 68 65 20 69 6e 64 65 78 2c  ry in the index,
0470: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69   the following i
0480: 73 0a 23 20 20 20 20 20 20 64 6f 6e 65 3a 0a 23  s.#      done:.#
0490: 0a 23 20 20 20 20 20 20 20 20 20 20 73 65 74 20  .#          set 
04a0: 43 28 24 69 44 6f 63 69 64 2c 24 69 43 6f 6c 2c  C($iDocid,$iCol,
04b0: 24 69 50 6f 73 69 74 69 6f 6e 29 20 24 7a 54 65  $iPosition) $zTe
04c0: 72 6d 0a 23 0a 23 20 20 20 32 29 20 49 74 65 72  rm.#.#   2) Iter
04d0: 61 74 65 20 74 68 72 6f 75 67 68 20 65 61 63 68  ate through each
04e0: 20 63 6f 6c 75 6d 6e 20 6f 66 20 65 61 63 68 20   column of each 
04f0: 72 6f 77 20 6f 66 20 74 68 65 20 25 5f 63 6f 6e  row of the %_con
0500: 74 65 6e 74 20 74 61 62 6c 65 2e 20 0a 23 20 20  tent table. .#  
0510: 20 20 20 20 54 6f 6b 65 6e 69 7a 65 20 61 6c 6c      Tokenize all
0520: 20 64 6f 63 75 6d 65 6e 74 73 2c 20 61 6e 64 20   documents, and 
0530: 63 68 65 63 6b 20 74 68 61 74 20 66 6f 72 20 65  check that for e
0540: 61 63 68 20 74 6f 6b 65 6e 20 74 68 65 72 65 20  ach token there 
0550: 69 73 0a 23 20 20 20 20 20 20 61 20 63 6f 72 72  is.#      a corr
0560: 65 73 70 6f 6e 64 69 6e 67 20 65 6e 74 72 79 20  esponding entry 
0570: 69 6e 20 74 68 65 20 24 43 20 61 72 72 61 79 2e  in the $C array.
0580: 20 41 66 74 65 72 20 63 68 65 63 6b 69 6e 67 20   After checking 
0590: 61 20 74 6f 6b 65 6e 2c 0a 23 20 20 20 20 20 20  a token,.#      
05a0: 5b 75 6e 73 65 74 5d 20 74 68 65 20 24 43 20 61  [unset] the $C a
05b0: 72 72 61 79 20 65 6e 74 72 79 2e 0a 23 0a 23 20  rray entry..#.# 
05c0: 20 20 33 29 20 43 68 65 63 6b 20 74 68 61 74 20    3) Check that 
05d0: 61 72 72 61 79 20 24 43 20 69 73 20 6e 6f 77 20  array $C is now 
05e0: 65 6d 70 74 79 2e 0a 23 20 20 20 20 20 20 0a 23  empty..#      .#
05f0: 0a 70 72 6f 63 20 66 74 73 33 5f 69 6e 74 65 67  .proc fts3_integ
0600: 72 69 74 79 5f 63 68 65 63 6b 20 7b 74 62 6c 7d  rity_check {tbl}
0610: 20 7b 0a 0a 20 20 66 74 73 33 5f 72 65 61 64 32   {..  fts3_read2
0620: 20 24 74 62 6c 20 31 20 41 0a 0a 20 20 66 6f 72   $tbl 1 A..  for
0630: 65 61 63 68 20 7a 54 65 72 6d 20 5b 61 72 72 61  each zTerm [arra
0640: 79 20 6e 61 6d 65 73 20 41 5d 20 7b 0a 20 20 20  y names A] {.   
0650: 20 66 6f 72 65 61 63 68 20 64 6f 63 6c 69 73 74   foreach doclist
0660: 20 24 41 28 24 7a 54 65 72 6d 29 20 7b 0a 20 20   $A($zTerm) {.  
0670: 20 20 20 20 73 65 74 20 64 6f 63 69 64 20 30 0a      set docid 0.
0680: 20 20 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 74        while {[st
0690: 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 64 6f 63  ring length $doc
06a0: 6c 69 73 74 5d 3e 30 7d 20 7b 0a 20 20 20 20 20  list]>0} {.     
06b0: 20 20 20 73 65 74 20 69 43 6f 6c 20 30 0a 20 20     set iCol 0.  
06c0: 20 20 20 20 20 20 73 65 74 20 69 50 6f 73 20 30        set iPos 0
06d0: 0a 20 20 20 20 20 20 20 20 73 65 74 20 6c 50 6f  .        set lPo
06e0: 73 20 5b 6c 69 73 74 5d 0a 20 20 20 20 20 20 20  s [list].       
06f0: 20 73 65 74 20 6c 43 6f 6c 20 5b 6c 69 73 74 5d   set lCol [list]
0700: 0a 0a 20 20 20 20 20 20 20 20 23 20 46 69 72 73  ..        # Firs
0710: 74 20 76 61 72 69 6e 74 20 6f 66 20 61 20 64 6f  t varint of a do
0720: 63 6c 69 73 74 2d 65 6e 74 72 79 20 69 73 20 74  clist-entry is t
0730: 68 65 20 64 6f 63 69 64 2e 20 44 65 6c 74 61 2d  he docid. Delta-
0740: 63 6f 6d 70 72 65 73 73 65 64 0a 20 20 20 20 20  compressed.     
0750: 20 20 20 23 20 77 69 74 68 20 72 65 73 70 65 63     # with respec
0760: 74 20 74 6f 20 74 68 65 20 64 6f 63 69 64 20 6f  t to the docid o
0770: 66 20 74 68 65 20 70 72 65 76 69 6f 75 73 20 65  f the previous e
0780: 6e 74 72 79 2e 0a 20 20 20 20 20 20 20 20 23 0a  ntry..        #.
0790: 20 20 20 20 20 20 20 20 69 6e 63 72 20 64 6f 63          incr doc
07a0: 69 64 20 5b 67 6f 62 62 6c 65 5f 76 61 72 69 6e  id [gobble_varin
07b0: 74 20 64 6f 63 6c 69 73 74 5d 0a 20 20 20 20 20  t doclist].     
07c0: 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69     if {[info exi
07d0: 73 74 73 20 44 28 24 7a 54 65 72 6d 2c 24 64 6f  sts D($zTerm,$do
07e0: 63 69 64 29 5d 7d 20 7b 0a 20 20 20 20 20 20 20  cid)]} {.       
07f0: 20 20 20 77 68 69 6c 65 20 7b 5b 73 65 74 20 69     while {[set i
0800: 44 65 6c 74 61 20 5b 67 6f 62 62 6c 65 5f 76 61  Delta [gobble_va
0810: 72 69 6e 74 20 64 6f 63 6c 69 73 74 5d 5d 20 21  rint doclist]] !
0820: 3d 20 30 7d 20 7b 7d 0a 20 20 20 20 20 20 20 20  = 0} {}.        
0830: 20 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20    continue.     
0840: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 73 65 74     }.        set
0850: 20 44 28 24 7a 54 65 72 6d 2c 24 64 6f 63 69 64   D($zTerm,$docid
0860: 29 20 31 0a 0a 20 20 20 20 20 20 20 20 23 20 47  ) 1..        # G
0870: 6f 62 62 6c 65 20 76 61 72 69 6e 74 73 20 75 6e  obble varints un
0880: 74 69 6c 20 74 68 65 20 30 78 30 30 20 74 68 61  til the 0x00 tha
0890: 74 20 74 65 72 6d 69 6e 61 74 65 73 20 74 68 65  t terminates the
08a0: 20 64 6f 63 6c 69 73 74 2d 65 6e 74 72 79 0a 20   doclist-entry. 
08b0: 20 20 20 20 20 20 20 23 20 69 73 20 66 6f 75 6e         # is foun
08c0: 64 2e 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65  d..        while
08d0: 20 7b 5b 73 65 74 20 69 44 65 6c 74 61 20 5b 67   {[set iDelta [g
08e0: 6f 62 62 6c 65 5f 76 61 72 69 6e 74 20 64 6f 63  obble_varint doc
08f0: 6c 69 73 74 5d 5d 20 3e 20 30 7d 20 7b 0a 20 20  list]] > 0} {.  
0900: 20 20 20 20 20 20 20 20 69 66 20 7b 24 69 44 65          if {$iDe
0910: 6c 74 61 20 3d 3d 20 31 7d 20 7b 0a 20 20 20 20  lta == 1} {.    
0920: 20 20 20 20 20 20 20 20 73 65 74 20 69 43 6f 6c          set iCol
0930: 20 5b 67 6f 62 62 6c 65 5f 76 61 72 69 6e 74 20   [gobble_varint 
0940: 64 6f 63 6c 69 73 74 5d 0a 20 20 20 20 20 20 20  doclist].       
0950: 20 20 20 20 20 73 65 74 20 69 50 6f 73 20 30 0a       set iPos 0.
0960: 20 20 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65            } else
0970: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69   {.            i
0980: 6e 63 72 20 69 50 6f 73 20 24 69 44 65 6c 74 61  ncr iPos $iDelta
0990: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 63  .            inc
09a0: 72 20 69 50 6f 73 20 2d 32 0a 20 20 20 20 20 20  r iPos -2.      
09b0: 20 20 20 20 20 20 73 65 74 20 43 28 24 64 6f 63        set C($doc
09c0: 69 64 2c 24 69 43 6f 6c 2c 24 69 50 6f 73 29 20  id,$iCol,$iPos) 
09d0: 24 7a 54 65 72 6d 0a 20 20 20 20 20 20 20 20 20  $zTerm.         
09e0: 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
09f0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
0a00: 20 20 66 6f 72 65 61 63 68 20 6b 65 79 20 5b 61    foreach key [a
0a10: 72 72 61 79 20 6e 61 6d 65 73 20 43 5d 20 7b 0a  rray names C] {.
0a20: 20 20 20 20 23 70 75 74 73 20 22 24 6b 65 79 20      #puts "$key 
0a30: 2d 3e 20 24 43 28 24 6b 65 79 29 22 0a 20 20 7d  -> $C($key)".  }
0a40: 0a 0a 0a 20 20 64 62 20 65 76 61 6c 20 22 53 45  ...  db eval "SE
0a50: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24 7b 74 62  LECT * FROM ${tb
0a60: 6c 7d 5f 63 6f 6e 74 65 6e 74 22 20 45 20 7b 0a  l}_content" E {.
0a70: 20 20 20 20 73 65 74 20 69 43 6f 6c 20 30 0a 20      set iCol 0. 
0a80: 20 20 20 73 65 74 20 69 44 6f 63 20 24 45 28 64     set iDoc $E(d
0a90: 6f 63 69 64 29 0a 20 20 20 20 66 6f 72 65 61 63  ocid).    foreac
0aa0: 68 20 63 6f 6c 20 5b 6c 72 61 6e 67 65 20 24 45  h col [lrange $E
0ab0: 28 2a 29 20 31 20 65 6e 64 5d 20 7b 0a 20 20 20  (*) 1 end] {.   
0ac0: 20 20 20 73 65 74 20 63 20 24 45 28 24 63 6f 6c     set c $E($col
0ad0: 29 0a 20 20 20 20 20 20 73 65 74 20 73 71 6c 20  ).      set sql 
0ae0: 7b 53 45 4c 45 43 54 20 66 74 73 33 5f 74 6f 6b  {SELECT fts3_tok
0af0: 65 6e 69 7a 65 72 5f 74 65 73 74 28 27 73 69 6d  enizer_test('sim
0b00: 70 6c 65 27 2c 20 24 63 29 7d 0a 0a 20 20 20 20  ple', $c)}..    
0b10: 20 20 66 6f 72 65 61 63 68 20 7b 70 6f 73 20 74    foreach {pos t
0b20: 65 72 6d 20 64 75 6d 6d 79 7d 20 5b 64 62 20 6f  erm dummy} [db o
0b30: 6e 65 20 24 73 71 6c 5d 20 7b 0a 20 20 20 20 20  ne $sql] {.     
0b40: 20 20 20 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78     if {![info ex
0b50: 69 73 74 73 20 43 28 24 69 44 6f 63 2c 24 69 43  ists C($iDoc,$iC
0b60: 6f 6c 2c 24 70 6f 73 29 5d 7d 20 7b 0a 20 20 20  ol,$pos)]} {.   
0b70: 20 20 20 20 20 20 20 73 65 74 20 65 73 20 22 45         set es "E
0b80: 72 72 6f 72 20 61 74 20 64 6f 63 69 64 3d 24 69  rror at docid=$i
0b90: 44 6f 63 20 63 6f 6c 3d 24 69 43 6f 6c 20 70 6f  Doc col=$iCol po
0ba0: 73 3d 24 70 6f 73 2e 20 49 6e 64 65 78 20 69 73  s=$pos. Index is
0bb0: 20 6d 69 73 73 69 6e 67 22 0a 20 20 20 20 20 20   missing".      
0bc0: 20 20 20 20 6c 61 70 70 65 6e 64 20 65 72 72 6f      lappend erro
0bd0: 72 73 20 24 65 73 0a 20 20 20 20 20 20 20 20 7d  rs $es.        }
0be0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
0bf0: 20 20 69 66 20 7b 24 43 28 24 69 44 6f 63 2c 24    if {$C($iDoc,$
0c00: 69 43 6f 6c 2c 24 70 6f 73 29 20 21 3d 20 22 24  iCol,$pos) != "$
0c10: 74 65 72 6d 22 7d 20 7b 0a 20 20 20 20 20 20 20  term"} {.       
0c20: 20 20 20 20 20 73 65 74 20 20 20 20 65 73 20 22       set    es "
0c30: 45 72 72 6f 72 20 61 74 20 64 6f 63 69 64 3d 24  Error at docid=$
0c40: 69 44 6f 63 20 63 6f 6c 3d 24 69 43 6f 6c 20 70  iDoc col=$iCol p
0c50: 6f 73 3d 24 70 6f 73 2e 20 49 6e 64 65 78 20 22  os=$pos. Index "
0c60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 70 70  .            app
0c70: 65 6e 64 20 65 73 20 22 68 61 73 20 5c 22 24 43  end es "has \"$C
0c80: 28 24 69 44 6f 63 2c 24 69 43 6f 6c 2c 24 70 6f  ($iDoc,$iCol,$po
0c90: 73 29 5c 22 2c 20 64 6f 63 75 6d 65 6e 74 20 68  s)\", document h
0ca0: 61 73 20 5c 22 24 74 65 72 6d 5c 22 22 0a 20 20  as \"$term\"".  
0cb0: 20 20 20 20 20 20 20 20 20 20 6c 61 70 70 65 6e            lappen
0cc0: 64 20 65 72 72 6f 72 73 20 24 65 73 0a 20 20 20  d errors $es.   
0cd0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
0ce0: 20 20 20 75 6e 73 65 74 20 43 28 24 69 44 6f 63     unset C($iDoc
0cf0: 2c 24 69 43 6f 6c 2c 24 70 6f 73 29 0a 20 20 20  ,$iCol,$pos).   
0d00: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
0d10: 20 20 20 20 20 69 6e 63 72 20 69 43 6f 6c 0a 20       incr iCol. 
0d20: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 66 6f 72 65     }.  }..  fore
0d30: 61 63 68 20 63 20 5b 61 72 72 61 79 20 6e 61 6d  ach c [array nam
0d40: 65 73 20 43 5d 20 7b 0a 20 20 20 20 6c 61 70 70  es C] {.    lapp
0d50: 65 6e 64 20 65 72 72 6f 72 73 20 22 42 61 64 20  end errors "Bad 
0d60: 69 6e 64 65 78 20 65 6e 74 72 79 3a 20 24 63 20  index entry: $c 
0d70: 2d 3e 20 24 43 28 24 63 29 22 0a 20 20 7d 0a 0a  -> $C($c)".  }..
0d80: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
0d90: 74 73 20 65 72 72 6f 72 73 5d 7d 20 7b 20 72 65  ts errors]} { re
0da0: 74 75 72 6e 20 5b 6a 6f 69 6e 20 24 65 72 72 6f  turn [join $erro
0db0: 72 73 20 22 5c 6e 22 5d 20 7d 0a 20 20 72 65 74  rs "\n"] }.  ret
0dc0: 75 72 6e 20 22 6f 6b 22 0a 7d 0a 0a 23 20 55 53  urn "ok".}..# US
0dd0: 41 47 45 3a 20 66 74 73 33 5f 74 65 72 6d 73 20  AGE: fts3_terms 
0de0: 54 42 4c 20 57 48 45 52 45 0a 23 0a 23 20 41 72  TBL WHERE.#.# Ar
0df0: 67 75 6d 65 6e 74 20 54 42 4c 20 6d 75 73 74 20  gument TBL must 
0e00: 62 65 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61  be the name of a
0e10: 6e 20 46 54 53 33 20 74 61 62 6c 65 2e 20 41 72  n FTS3 table. Ar
0e20: 67 75 6d 65 6e 74 20 57 48 45 52 45 20 69 73 20  gument WHERE is 
0e30: 61 6e 0a 23 20 53 51 4c 20 65 78 70 72 65 73 73  an.# SQL express
0e40: 69 6f 6e 20 74 68 61 74 20 77 69 6c 6c 20 62 65  ion that will be
0e50: 20 75 73 65 64 20 61 73 20 74 68 65 20 57 48 45   used as the WHE
0e60: 52 45 20 63 6c 61 75 73 65 20 77 68 65 6e 20 73  RE clause when s
0e70: 63 61 6e 6e 69 6e 67 0a 23 20 74 68 65 20 25 5f  canning.# the %_
0e80: 73 65 67 64 69 72 20 74 61 62 6c 65 2e 20 41 73  segdir table. As
0e90: 20 69 6e 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   in the followin
0ea0: 67 20 71 75 65 72 79 3a 0a 23 0a 23 20 20 20 22  g query:.#.#   "
0eb0: 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24 7b  SELECT * FROM ${
0ec0: 54 42 4c 7d 5f 73 65 67 64 69 72 20 57 48 45 52  TBL}_segdir WHER
0ed0: 45 20 24 7b 57 48 45 52 45 7d 22 0a 23 0a 23 20  E ${WHERE}".#.# 
0ee0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65  This function re
0ef0: 74 75 72 6e 73 20 61 20 6c 69 73 74 20 6f 66 20  turns a list of 
0f00: 61 6c 6c 20 74 65 72 6d 73 20 70 72 65 73 65 6e  all terms presen
0f10: 74 20 69 6e 20 74 68 65 20 73 65 67 6d 65 6e 74  t in the segment
0f20: 73 0a 23 20 73 65 6c 65 63 74 65 64 20 62 79 20  s.# selected by 
0f30: 74 68 65 20 73 74 61 74 65 6d 65 6e 74 20 61 62  the statement ab
0f40: 6f 76 65 2e 0a 23 0a 70 72 6f 63 20 66 74 73 33  ove..#.proc fts3
0f50: 5f 74 65 72 6d 73 20 7b 74 62 6c 20 77 68 65 72  _terms {tbl wher
0f60: 65 7d 20 7b 0a 20 20 66 74 73 33 5f 72 65 61 64  e} {.  fts3_read
0f70: 20 24 74 62 6c 20 24 77 68 65 72 65 20 61 0a 20   $tbl $where a. 
0f80: 20 72 65 74 75 72 6e 20 5b 6c 73 6f 72 74 20 5b   return [lsort [
0f90: 61 72 72 61 79 20 6e 61 6d 65 73 20 61 5d 5d 0a  array names a]].
0fa0: 7d 0a 0a 0a 23 20 55 53 41 47 45 3a 20 66 74 73  }...# USAGE: fts
0fb0: 33 5f 64 6f 63 6c 69 73 74 20 54 42 4c 20 54 45  3_doclist TBL TE
0fc0: 52 4d 20 57 48 45 52 45 0a 23 0a 23 20 41 72 67  RM WHERE.#.# Arg
0fd0: 75 6d 65 6e 74 20 54 42 4c 20 6d 75 73 74 20 62  ument TBL must b
0fe0: 65 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61 6e  e the name of an
0ff0: 20 46 54 53 33 20 74 61 62 6c 65 2e 20 54 45 52   FTS3 table. TER
1000: 4d 20 69 73 20 61 20 74 65 72 6d 20 74 68 61 74  M is a term that
1010: 20 6d 61 79 0a 23 20 6f 72 20 6d 61 79 20 6e 6f   may.# or may no
1020: 74 20 62 65 20 70 72 65 73 65 6e 74 20 69 6e 20  t be present in 
1030: 74 68 65 20 74 61 62 6c 65 2e 20 41 72 67 75 6d  the table. Argum
1040: 65 6e 74 20 57 48 45 52 45 20 69 73 20 75 73 65  ent WHERE is use
1050: 64 20 74 6f 20 73 65 6c 65 63 74 20 61 20 0a 23  d to select a .#
1060: 20 73 75 62 73 65 74 20 6f 66 20 74 68 65 20 62   subset of the b
1070: 2d 74 72 65 65 20 73 65 67 6d 65 6e 74 73 20 69  -tree segments i
1080: 6e 20 74 68 65 20 61 73 73 6f 63 69 61 74 65 64  n the associated
1090: 20 66 75 6c 6c 2d 74 65 78 74 20 69 6e 64 65 78   full-text index
10a0: 20 61 73 20 0a 23 20 64 65 73 63 72 69 62 65 64   as .# described
10b0: 20 61 62 6f 76 65 20 66 6f 72 20 5b 66 74 73 33   above for [fts3
10c0: 5f 74 65 72 6d 73 5d 2e 0a 23 0a 23 20 54 68 69  _terms]..#.# Thi
10d0: 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72  s function retur
10e0: 6e 73 20 74 68 65 20 72 65 73 75 6c 74 73 20 6f  ns the results o
10f0: 66 20 6d 65 72 67 69 6e 67 20 74 68 65 20 64 6f  f merging the do
1100: 63 6c 69 73 74 73 20 61 73 73 6f 63 69 61 74 65  clists associate
1110: 64 0a 23 20 77 69 74 68 20 54 45 52 4d 20 69 6e  d.# with TERM in
1120: 20 74 68 65 20 73 65 6c 65 63 74 65 64 20 73 65   the selected se
1130: 67 6d 65 6e 74 73 2e 20 45 61 63 68 20 64 6f 63  gments. Each doc
1140: 6c 69 73 74 20 69 73 20 61 6e 20 65 6c 65 6d 65  list is an eleme
1150: 6e 74 20 6f 66 20 74 68 65 0a 23 20 72 65 74 75  nt of the.# retu
1160: 72 6e 65 64 20 6c 69 73 74 2e 20 45 61 63 68 20  rned list. Each 
1170: 64 6f 63 6c 69 73 74 20 69 73 20 66 6f 72 6d 61  doclist is forma
1180: 74 74 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73 3a  tted as follows:
1190: 0a 23 0a 23 20 20 20 5b 24 64 6f 63 69 64 20 3f  .#.#   [$docid ?
11a0: 24 63 6f 6c 5b 24 6f 66 66 31 20 24 6f 66 66 32  $col[$off1 $off2
11b0: 2e 2e 2e 5d 3f 2e 2e 2e 5d 0a 23 0a 23 20 54 68  ...]?...].#.# Th
11c0: 65 20 66 6f 72 6d 61 74 74 69 6e 67 20 69 73 20  e formatting is 
11d0: 6f 64 64 20 66 6f 72 20 61 20 54 63 6c 20 63 6f  odd for a Tcl co
11e0: 6d 6d 61 6e 64 20 69 6e 20 6f 72 64 65 72 20 74  mmand in order t
11f0: 6f 20 62 65 20 63 6f 6d 70 61 74 69 62 6c 65 20  o be compatible 
1200: 77 69 74 68 0a 23 20 74 68 65 20 6f 72 69 67 69  with.# the origi
1210: 6e 61 6c 20 43 2d 6c 61 6e 67 75 61 67 65 20 69  nal C-language i
1220: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 20 49  mplementation. I
1230: 66 20 61 72 67 75 6d 65 6e 74 20 57 48 45 52 45  f argument WHERE
1240: 20 69 73 20 22 31 22 2c 20 74 68 65 6e 20 0a 23   is "1", then .#
1250: 20 61 6e 79 20 65 6d 70 74 79 20 64 6f 63 6c 69   any empty docli
1260: 73 74 73 20 61 72 65 20 6f 6d 69 74 74 65 64 20  sts are omitted 
1270: 66 72 6f 6d 20 74 68 65 20 72 65 74 75 72 6e 65  from the returne
1280: 64 20 6c 69 73 74 2e 0a 23 0a 70 72 6f 63 20 66  d list..#.proc f
1290: 74 73 33 5f 64 6f 63 6c 69 73 74 20 7b 74 62 6c  ts3_doclist {tbl
12a0: 20 74 65 72 6d 20 77 68 65 72 65 7d 20 7b 0a 20   term where} {. 
12b0: 20 66 74 73 33 5f 72 65 61 64 20 24 74 62 6c 20   fts3_read $tbl 
12c0: 24 77 68 65 72 65 20 61 0a 0a 0a 20 20 66 6f 72  $where a...  for
12d0: 65 61 63 68 20 64 6f 63 6c 69 73 74 20 24 61 28  each doclist $a(
12e0: 24 74 65 72 6d 29 20 7b 0a 20 20 20 20 73 65 74  $term) {.    set
12f0: 20 64 6f 63 69 64 20 30 0a 0a 20 20 20 20 77 68   docid 0..    wh
1300: 69 6c 65 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e  ile {[string len
1310: 67 74 68 20 24 64 6f 63 6c 69 73 74 5d 3e 30 7d  gth $doclist]>0}
1320: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 69 43 6f   {.      set iCo
1330: 6c 20 30 0a 20 20 20 20 20 20 73 65 74 20 69 50  l 0.      set iP
1340: 6f 73 20 30 0a 20 20 20 20 20 20 73 65 74 20 6c  os 0.      set l
1350: 50 6f 73 20 5b 6c 69 73 74 5d 0a 20 20 20 20 20  Pos [list].     
1360: 20 73 65 74 20 6c 43 6f 6c 20 5b 6c 69 73 74 5d   set lCol [list]
1370: 0a 20 20 20 20 20 20 69 6e 63 72 20 64 6f 63 69  .      incr doci
1380: 64 20 5b 67 6f 62 62 6c 65 5f 76 61 72 69 6e 74  d [gobble_varint
1390: 20 64 6f 63 6c 69 73 74 5d 0a 20 20 0a 20 20 20   doclist].  .   
13a0: 20 20 20 77 68 69 6c 65 20 7b 5b 73 65 74 20 69     while {[set i
13b0: 44 65 6c 74 61 20 5b 67 6f 62 62 6c 65 5f 76 61  Delta [gobble_va
13c0: 72 69 6e 74 20 64 6f 63 6c 69 73 74 5d 5d 20 3e  rint doclist]] >
13d0: 20 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 69 66   0} {.        if
13e0: 20 7b 24 69 44 65 6c 74 61 20 3d 3d 20 31 7d 20   {$iDelta == 1} 
13f0: 7b 0a 20 20 20 20 20 20 20 20 20 20 6c 61 70 70  {.          lapp
1400: 65 6e 64 20 6c 43 6f 6c 20 5b 6c 69 73 74 20 24  end lCol [list $
1410: 69 43 6f 6c 20 24 6c 50 6f 73 5d 0a 20 20 20 20  iCol $lPos].    
1420: 20 20 20 20 20 20 73 65 74 20 69 50 6f 73 20 30        set iPos 0
1430: 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20 6c  .          set l
1440: 50 6f 73 20 5b 6c 69 73 74 5d 0a 20 20 20 20 20  Pos [list].     
1450: 20 20 20 20 20 73 65 74 20 69 43 6f 6c 20 5b 67       set iCol [g
1460: 6f 62 62 6c 65 5f 76 61 72 69 6e 74 20 64 6f 63  obble_varint doc
1470: 6c 69 73 74 5d 0a 20 20 20 20 20 20 20 20 7d 20  list].        } 
1480: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 20  else {.         
1490: 20 69 6e 63 72 20 69 50 6f 73 20 24 69 44 65 6c   incr iPos $iDel
14a0: 74 61 0a 20 20 20 20 20 20 20 20 20 20 69 6e 63  ta.          inc
14b0: 72 20 69 50 6f 73 20 2d 32 0a 20 20 20 20 20 20  r iPos -2.      
14c0: 20 20 20 20 6c 61 70 70 65 6e 64 20 6c 50 6f 73      lappend lPos
14d0: 20 24 69 50 6f 73 0a 20 20 20 20 20 20 20 20 7d   $iPos.        }
14e0: 0a 20 20 20 20 20 20 7d 0a 20 20 0a 20 20 20 20  .      }.  .    
14f0: 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24    if {[llength $
1500: 6c 50 6f 73 5d 3e 30 7d 20 7b 0a 20 20 20 20 20  lPos]>0} {.     
1510: 20 20 20 6c 61 70 70 65 6e 64 20 6c 43 6f 6c 20     lappend lCol 
1520: 5b 6c 69 73 74 20 24 69 43 6f 6c 20 24 6c 50 6f  [list $iCol $lPo
1530: 73 5d 0a 20 20 20 20 20 20 7d 0a 20 20 0a 20 20  s].      }.  .  
1540: 20 20 20 20 69 66 20 7b 24 77 68 65 72 65 20 21      if {$where !
1550: 3d 20 22 31 22 20 7c 7c 20 5b 6c 6c 65 6e 67 74  = "1" || [llengt
1560: 68 20 24 6c 43 6f 6c 5d 3e 30 7d 20 7b 0a 20 20  h $lCol]>0} {.  
1570: 20 20 20 20 20 20 73 65 74 20 72 65 74 28 24 64        set ret($d
1580: 6f 63 69 64 29 20 24 6c 43 6f 6c 0a 20 20 20 20  ocid) $lCol.    
1590: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
15a0: 20 20 20 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70     unset -nocomp
15b0: 6c 61 69 6e 20 72 65 74 28 24 64 6f 63 69 64 29  lain ret($docid)
15c0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
15d0: 20 7d 0a 0a 20 20 73 65 74 20 6c 44 6f 63 20 5b   }..  set lDoc [
15e0: 6c 69 73 74 5d 0a 20 20 66 6f 72 65 61 63 68 20  list].  foreach 
15f0: 64 6f 63 69 64 20 5b 6c 73 6f 72 74 20 2d 69 6e  docid [lsort -in
1600: 74 65 67 65 72 20 5b 61 72 72 61 79 20 6e 61 6d  teger [array nam
1610: 65 73 20 72 65 74 5d 5d 20 7b 0a 20 20 20 20 73  es ret]] {.    s
1620: 65 74 20 6c 43 6f 6c 20 5b 6c 69 73 74 5d 0a 20  et lCol [list]. 
1630: 20 20 20 73 65 74 20 63 6f 6c 73 20 22 22 0a 20     set cols "". 
1640: 20 20 20 66 6f 72 65 61 63 68 20 63 6f 6c 20 24     foreach col $
1650: 72 65 74 28 24 64 6f 63 69 64 29 20 7b 0a 20 20  ret($docid) {.  
1660: 20 20 20 20 66 6f 72 65 61 63 68 20 7b 69 43 6f      foreach {iCo
1670: 6c 20 6c 50 6f 73 7d 20 24 63 6f 6c 20 7b 7d 0a  l lPos} $col {}.
1680: 20 20 20 20 20 20 61 70 70 65 6e 64 20 63 6f 6c        append col
1690: 73 20 22 20 24 69 43 6f 6c 5c 5b 5b 6a 6f 69 6e  s " $iCol\[[join
16a0: 20 24 6c 50 6f 73 20 7b 20 7d 5d 5c 5d 22 0a 20   $lPos { }]\]". 
16b0: 20 20 20 7d 0a 20 20 20 20 6c 61 70 70 65 6e 64     }.    lappend
16c0: 20 6c 44 6f 63 20 22 5c 5b 24 7b 64 6f 63 69 64   lDoc "\[${docid
16d0: 7d 24 7b 63 6f 6c 73 7d 5c 5d 22 0a 20 20 7d 0a  }${cols}\]".  }.
16e0: 0a 20 20 6a 6f 69 6e 20 24 6c 44 6f 63 20 22 20  .  join $lDoc " 
16f0: 22 0a 7d 0a 0a 23 23 23 23 23 23 23 23 23 23 23  ".}..###########
1700: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
1710: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
1720: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
1730: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
1740: 0a 0a 70 72 6f 63 20 67 6f 62 62 6c 65 5f 76 61  ..proc gobble_va
1750: 72 69 6e 74 20 7b 76 61 72 6e 61 6d 65 7d 20 7b  rint {varname} {
1760: 0a 20 20 75 70 76 61 72 20 24 76 61 72 6e 61 6d  .  upvar $varnam
1770: 65 20 62 6c 6f 62 0a 20 20 73 65 74 20 6e 20 5b  e blob.  set n [
1780: 72 65 61 64 5f 76 61 72 69 6e 74 20 24 62 6c 6f  read_varint $blo
1790: 62 20 72 65 74 5d 0a 20 20 73 65 74 20 62 6c 6f  b ret].  set blo
17a0: 62 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20  b [string range 
17b0: 24 62 6c 6f 62 20 24 6e 20 65 6e 64 5d 0a 20 20  $blob $n end].  
17c0: 72 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a 70 72  return $ret.}.pr
17d0: 6f 63 20 67 6f 62 62 6c 65 5f 73 74 72 69 6e 67  oc gobble_string
17e0: 20 7b 76 61 72 6e 61 6d 65 20 6e 4c 65 6e 67 74   {varname nLengt
17f0: 68 7d 20 7b 0a 20 20 75 70 76 61 72 20 24 76 61  h} {.  upvar $va
1800: 72 6e 61 6d 65 20 62 6c 6f 62 0a 20 20 73 65 74  rname blob.  set
1810: 20 72 65 74 20 5b 73 74 72 69 6e 67 20 72 61 6e   ret [string ran
1820: 67 65 20 24 62 6c 6f 62 20 30 20 5b 65 78 70 72  ge $blob 0 [expr
1830: 20 24 6e 4c 65 6e 67 74 68 2d 31 5d 5d 0a 20 20   $nLength-1]].  
1840: 73 65 74 20 62 6c 6f 62 20 5b 73 74 72 69 6e 67  set blob [string
1850: 20 72 61 6e 67 65 20 24 62 6c 6f 62 20 24 6e 4c   range $blob $nL
1860: 65 6e 67 74 68 20 65 6e 64 5d 0a 20 20 72 65 74  ength end].  ret
1870: 75 72 6e 20 24 72 65 74 0a 7d 0a 0a 23 20 54 68  urn $ret.}..# Th
1880: 65 20 61 72 67 75 6d 65 6e 74 20 69 73 20 61 20  e argument is a 
1890: 62 6c 6f 62 20 6f 66 20 64 61 74 61 20 72 65 70  blob of data rep
18a0: 72 65 73 65 6e 74 69 6e 67 20 61 6e 20 46 54 53  resenting an FTS
18b0: 33 20 73 65 67 6d 65 6e 74 20 6c 65 61 66 2e 20  3 segment leaf. 
18c0: 0a 23 20 52 65 74 75 72 6e 20 61 20 6c 69 73 74  .# Return a list
18d0: 20 63 6f 6e 73 69 73 74 69 6e 67 20 6f 66 20 61   consisting of a
18e0: 6c 74 65 72 6e 61 74 69 6e 67 20 74 65 72 6d 73  lternating terms
18f0: 20 28 73 74 72 69 6e 67 73 29 20 61 6e 64 20 64   (strings) and d
1900: 6f 63 6c 69 73 74 73 0a 23 20 28 62 6c 6f 62 73  oclists.# (blobs
1910: 20 6f 66 20 64 61 74 61 29 2e 0a 23 0a 70 72 6f   of data)..#.pro
1920: 63 20 66 74 73 33 5f 72 65 61 64 6c 65 61 66 20  c fts3_readleaf 
1930: 7b 62 6c 6f 62 7d 20 7b 0a 20 20 73 65 74 20 7a  {blob} {.  set z
1940: 50 72 65 76 20 22 22 0a 20 20 73 65 74 20 74 65  Prev "".  set te
1950: 72 6d 73 20 5b 6c 69 73 74 5d 0a 0a 20 20 77 68  rms [list]..  wh
1960: 69 6c 65 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e  ile {[string len
1970: 67 74 68 20 24 62 6c 6f 62 5d 20 3e 20 30 7d 20  gth $blob] > 0} 
1980: 7b 0a 20 20 20 20 73 65 74 20 6e 50 72 65 66 69  {.    set nPrefi
1990: 78 20 5b 67 6f 62 62 6c 65 5f 76 61 72 69 6e 74  x [gobble_varint
19a0: 20 62 6c 6f 62 5d 0a 20 20 20 20 73 65 74 20 6e   blob].    set n
19b0: 53 75 66 66 69 78 20 5b 67 6f 62 62 6c 65 5f 76  Suffix [gobble_v
19c0: 61 72 69 6e 74 20 62 6c 6f 62 5d 0a 0a 20 20 20  arint blob]..   
19d0: 20 73 65 74 20 7a 54 65 72 6d 20 5b 73 74 72 69   set zTerm [stri
19e0: 6e 67 20 72 61 6e 67 65 20 24 7a 50 72 65 76 20  ng range $zPrev 
19f0: 30 20 5b 65 78 70 72 20 24 6e 50 72 65 66 69 78  0 [expr $nPrefix
1a00: 2d 31 5d 5d 0a 20 20 20 20 61 70 70 65 6e 64 20  -1]].    append 
1a10: 7a 54 65 72 6d 20 5b 67 6f 62 62 6c 65 5f 73 74  zTerm [gobble_st
1a20: 72 69 6e 67 20 62 6c 6f 62 20 24 6e 53 75 66 66  ring blob $nSuff
1a30: 69 78 5d 0a 20 20 20 20 73 65 74 20 64 6f 63 6c  ix].    set docl
1a40: 69 73 74 20 5b 67 6f 62 62 6c 65 5f 73 74 72 69  ist [gobble_stri
1a50: 6e 67 20 62 6c 6f 62 20 5b 67 6f 62 62 6c 65 5f  ng blob [gobble_
1a60: 76 61 72 69 6e 74 20 62 6c 6f 62 5d 5d 0a 0a 20  varint blob]].. 
1a70: 20 20 20 6c 61 70 70 65 6e 64 20 74 65 72 6d 73     lappend terms
1a80: 20 24 7a 54 65 72 6d 20 24 64 6f 63 6c 69 73 74   $zTerm $doclist
1a90: 0a 20 20 20 20 73 65 74 20 7a 50 72 65 76 20 24  .    set zPrev $
1aa0: 7a 54 65 72 6d 0a 20 20 7d 0a 0a 20 20 72 65 74  zTerm.  }..  ret
1ab0: 75 72 6e 20 24 74 65 72 6d 73 0a 7d 0a 0a 70 72  urn $terms.}..pr
1ac0: 6f 63 20 66 74 73 33 5f 72 65 61 64 32 20 7b 74  oc fts3_read2 {t
1ad0: 62 6c 20 77 68 65 72 65 20 76 61 72 6e 61 6d 65  bl where varname
1ae0: 7d 20 7b 0a 20 20 75 70 76 61 72 20 24 76 61 72  } {.  upvar $var
1af0: 6e 61 6d 65 20 61 0a 20 20 61 72 72 61 79 20 75  name a.  array u
1b00: 6e 73 65 74 20 61 0a 20 20 64 62 20 65 76 61 6c  nset a.  db eval
1b10: 20 22 20 53 45 4c 45 43 54 20 73 74 61 72 74 5f   " SELECT start_
1b20: 62 6c 6f 63 6b 2c 20 6c 65 61 76 65 73 5f 65 6e  block, leaves_en
1b30: 64 5f 62 6c 6f 63 6b 2c 20 72 6f 6f 74 20 0a 20  d_block, root . 
1b40: 20 20 20 20 20 20 20 20 20 20 20 46 52 4f 4d 20             FROM 
1b50: 24 7b 74 62 6c 7d 5f 73 65 67 64 69 72 20 57 48  ${tbl}_segdir WH
1b60: 45 52 45 20 24 77 68 65 72 65 0a 20 20 20 20 20  ERE $where.     
1b70: 20 20 20 20 20 20 20 4f 52 44 45 52 20 42 59 20         ORDER BY 
1b80: 6c 65 76 65 6c 20 41 53 43 2c 20 69 64 78 20 44  level ASC, idx D
1b90: 45 53 43 0a 20 20 22 20 7b 0a 20 20 20 20 69 66  ESC.  " {.    if
1ba0: 20 7b 24 73 74 61 72 74 5f 62 6c 6f 63 6b 20 3d   {$start_block =
1bb0: 3d 20 30 7d 20 7b 0a 20 20 20 20 20 20 66 6f 72  = 0} {.      for
1bc0: 65 61 63 68 20 7b 74 20 64 7d 20 5b 66 74 73 33  each {t d} [fts3
1bd0: 5f 72 65 61 64 6c 65 61 66 20 24 72 6f 6f 74 5d  _readleaf $root]
1be0: 20 7b 20 6c 61 70 70 65 6e 64 20 61 28 24 74 29   { lappend a($t)
1bf0: 20 24 64 20 7d 0a 20 20 20 20 7d 20 65 6c 73 65   $d }.    } else
1c00: 20 7b 0a 20 20 20 20 20 20 64 62 20 65 76 61 6c   {.      db eval
1c10: 20 22 20 53 45 4c 45 43 54 20 62 6c 6f 63 6b 20   " SELECT block 
1c20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1c30: 20 46 52 4f 4d 20 24 7b 74 62 6c 7d 5f 73 65 67   FROM ${tbl}_seg
1c40: 6d 65 6e 74 73 20 0a 20 20 20 20 20 20 20 20 20  ments .         
1c50: 20 20 20 20 20 20 20 57 48 45 52 45 20 62 6c 6f         WHERE blo
1c60: 63 6b 69 64 3e 3d 24 73 74 61 72 74 5f 62 6c 6f  ckid>=$start_blo
1c70: 63 6b 20 41 4e 44 20 62 6c 6f 63 6b 69 64 3c 3d  ck AND blockid<=
1c80: 24 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63  $leaves_end_bloc
1c90: 6b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k.              
1ca0: 20 20 4f 52 44 45 52 20 42 59 20 62 6c 6f 63 6b    ORDER BY block
1cb0: 69 64 0a 20 20 20 20 20 20 22 20 7b 0a 20 20 20  id.      " {.   
1cc0: 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b 74 20       foreach {t 
1cd0: 64 7d 20 5b 66 74 73 33 5f 72 65 61 64 6c 65 61  d} [fts3_readlea
1ce0: 66 20 24 62 6c 6f 63 6b 5d 20 7b 20 6c 61 70 70  f $block] { lapp
1cf0: 65 6e 64 20 61 28 24 74 29 20 24 64 20 7d 0a 0a  end a($t) $d }..
1d00: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
1d10: 7d 0a 7d 0a 0a 70 72 6f 63 20 66 74 73 33 5f 72  }.}..proc fts3_r
1d20: 65 61 64 20 7b 74 62 6c 20 77 68 65 72 65 20 76  ead {tbl where v
1d30: 61 72 6e 61 6d 65 7d 20 7b 0a 20 20 75 70 76 61  arname} {.  upva
1d40: 72 20 24 76 61 72 6e 61 6d 65 20 61 0a 20 20 61  r $varname a.  a
1d50: 72 72 61 79 20 75 6e 73 65 74 20 61 0a 20 20 64  rray unset a.  d
1d60: 62 20 65 76 61 6c 20 22 20 53 45 4c 45 43 54 20  b eval " SELECT 
1d70: 73 74 61 72 74 5f 62 6c 6f 63 6b 2c 20 6c 65 61  start_block, lea
1d80: 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 6b 2c 20 72  ves_end_block, r
1d90: 6f 6f 74 20 0a 20 20 20 20 20 20 20 20 20 20 20  oot .           
1da0: 20 46 52 4f 4d 20 24 7b 74 62 6c 7d 5f 73 65 67   FROM ${tbl}_seg
1db0: 64 69 72 20 57 48 45 52 45 20 24 77 68 65 72 65  dir WHERE $where
1dc0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 4f 52 44  .            ORD
1dd0: 45 52 20 42 59 20 6c 65 76 65 6c 20 44 45 53 43  ER BY level DESC
1de0: 2c 20 69 64 78 20 41 53 43 0a 20 20 22 20 7b 0a  , idx ASC.  " {.
1df0: 20 20 20 20 69 66 20 7b 24 73 74 61 72 74 5f 62      if {$start_b
1e00: 6c 6f 63 6b 20 3d 3d 20 30 7d 20 7b 0a 20 20 20  lock == 0} {.   
1e10: 20 20 20 66 6f 72 65 61 63 68 20 7b 74 20 64 7d     foreach {t d}
1e20: 20 5b 66 74 73 33 5f 72 65 61 64 6c 65 61 66 20   [fts3_readleaf 
1e30: 24 72 6f 6f 74 5d 20 7b 20 6c 61 70 70 65 6e 64  $root] { lappend
1e40: 20 61 28 24 74 29 20 24 64 20 7d 0a 20 20 20 20   a($t) $d }.    
1e50: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 64  } else {.      d
1e60: 62 20 65 76 61 6c 20 22 20 53 45 4c 45 43 54 20  b eval " SELECT 
1e70: 62 6c 6f 63 6b 20 0a 20 20 20 20 20 20 20 20 20  block .         
1e80: 20 20 20 20 20 20 20 46 52 4f 4d 20 24 7b 74 62         FROM ${tb
1e90: 6c 7d 5f 73 65 67 6d 65 6e 74 73 20 0a 20 20 20  l}_segments .   
1ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 57 48 45               WHE
1eb0: 52 45 20 62 6c 6f 63 6b 69 64 3e 3d 24 73 74 61  RE blockid>=$sta
1ec0: 72 74 5f 62 6c 6f 63 6b 20 41 4e 44 20 62 6c 6f  rt_block AND blo
1ed0: 63 6b 69 64 3c 24 6c 65 61 76 65 73 5f 65 6e 64  ckid<$leaves_end
1ee0: 5f 62 6c 6f 63 6b 0a 20 20 20 20 20 20 20 20 20  _block.         
1ef0: 20 20 20 20 20 20 20 4f 52 44 45 52 20 42 59 20         ORDER BY 
1f00: 62 6c 6f 63 6b 69 64 0a 20 20 20 20 20 20 22 20  blockid.      " 
1f10: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63  {.        foreac
1f20: 68 20 7b 74 20 64 7d 20 5b 66 74 73 33 5f 72 65  h {t d} [fts3_re
1f30: 61 64 6c 65 61 66 20 24 62 6c 6f 63 6b 5d 20 7b  adleaf $block] {
1f40: 20 6c 61 70 70 65 6e 64 20 61 28 24 74 29 20 24   lappend a($t) $
1f50: 64 20 7d 0a 0a 20 20 20 20 20 20 7d 0a 20 20 20  d }..      }.   
1f60: 20 7d 0a 20 20 7d 0a 7d 0a 0a 23 23 23 23 23 23   }.  }.}..######
1f70: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
1f80: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
1f90: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
1fa0: 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23  ################
1fb0: 23 23 23 23 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  ####..#---------
1fc0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1fd0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1fe0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1ff0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2000: 0a 23 20 54 68 69 73 20 70 72 6f 63 20 69 73 20  .# This proc is 
2010: 75 73 65 64 20 74 6f 20 74 65 73 74 20 61 20 73  used to test a s
2020: 69 6e 67 6c 65 20 53 45 4c 45 43 54 20 73 74 61  ingle SELECT sta
2030: 74 65 6d 65 6e 74 2e 20 50 61 72 61 6d 65 74 65  tement. Paramete
2040: 72 20 24 6e 61 6d 65 20 69 73 0a 23 20 70 61 73  r $name is.# pas
2050: 73 65 64 20 61 20 6e 61 6d 65 20 66 6f 72 20 74  sed a name for t
2060: 68 65 20 74 65 73 74 20 63 61 73 65 20 28 69 2e  he test case (i.
2070: 65 2e 20 22 66 74 73 33 5f 6d 61 6c 6c 6f 63 2d  e. "fts3_malloc-
2080: 31 2e 34 2e 31 22 29 20 61 6e 64 20 70 61 72 61  1.4.1") and para
2090: 6d 65 74 65 72 0a 23 20 24 73 71 6c 20 69 73 20  meter.# $sql is 
20a0: 70 61 73 73 65 64 20 74 68 65 20 74 65 78 74 20  passed the text 
20b0: 6f 66 20 74 68 65 20 53 45 4c 45 43 54 20 73 74  of the SELECT st
20c0: 61 74 65 6d 65 6e 74 2e 20 50 61 72 61 6d 65 74  atement. Paramet
20d0: 65 72 20 24 72 65 73 75 6c 74 20 69 73 0a 23 20  er $result is.# 
20e0: 73 65 74 20 74 6f 20 74 68 65 20 65 78 70 65 63  set to the expec
20f0: 74 65 64 20 6f 75 74 70 75 74 20 69 66 20 74 68  ted output if th
2100: 65 20 53 45 4c 45 43 54 20 73 74 61 74 65 6d 65  e SELECT stateme
2110: 6e 74 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  nt is successful
2120: 6c 79 0a 23 20 65 78 65 63 75 74 65 64 20 75 73  ly.# executed us
2130: 69 6e 67 20 5b 64 62 20 65 76 61 6c 5d 2e 0a 23  ing [db eval]..#
2140: 0a 23 20 45 78 61 6d 70 6c 65 3a 0a 23 0a 23 20  .# Example:.#.# 
2150: 20 20 64 6f 5f 73 65 6c 65 63 74 5f 74 65 73 74    do_select_test
2160: 20 74 65 73 74 63 61 73 65 2d 31 2e 31 20 22 53   testcase-1.1 "S
2170: 45 4c 45 43 54 20 31 2b 31 2c 20 31 2b 32 22 20  ELECT 1+1, 1+2" 
2180: 7b 31 20 32 7d 0a 23 0a 23 20 49 66 20 67 6c 6f  {1 2}.#.# If glo
2190: 62 61 6c 20 76 61 72 69 61 62 6c 65 20 44 4f 5f  bal variable DO_
21a0: 4d 41 4c 4c 4f 43 5f 54 45 53 54 20 69 73 20 73  MALLOC_TEST is s
21b0: 65 74 20 74 6f 20 61 20 6e 6f 6e 2d 7a 65 72 6f  et to a non-zero
21c0: 20 76 61 6c 75 65 2c 20 6f 72 20 69 66 0a 23 20   value, or if.# 
21d0: 69 74 20 69 73 20 6e 6f 74 20 64 65 66 69 6e 65  it is not define
21e0: 64 20 61 74 20 61 6c 6c 2c 20 74 68 65 6e 20 4f  d at all, then O
21f0: 4f 4d 20 74 65 73 74 69 6e 67 20 69 73 20 70 65  OM testing is pe
2200: 72 66 6f 72 6d 65 64 20 6f 6e 20 74 68 65 20 53  rformed on the S
2210: 45 4c 45 43 54 0a 23 20 73 74 61 74 65 6d 65 6e  ELECT.# statemen
2220: 74 2e 20 45 61 63 68 20 4f 4f 4d 20 74 65 73 74  t. Each OOM test
2230: 20 63 61 73 65 20 69 73 20 73 61 69 64 20 74 6f   case is said to
2240: 20 70 61 73 73 20 69 66 20 65 69 74 68 65 72 20   pass if either 
2250: 28 61 29 20 65 78 65 63 75 74 69 6e 67 0a 23 20  (a) executing.# 
2260: 74 68 65 20 53 45 4c 45 43 54 20 73 74 61 74 65  the SELECT state
2270: 6d 65 6e 74 20 73 75 63 63 65 65 64 73 20 61 6e  ment succeeds an
2280: 64 20 74 68 65 20 72 65 73 75 6c 74 73 20 6d 61  d the results ma
2290: 74 63 68 20 74 68 6f 73 65 20 73 70 65 63 69 66  tch those specif
22a0: 69 65 64 0a 23 20 62 79 20 70 61 72 61 6d 65 74  ied.# by paramet
22b0: 65 72 20 24 72 65 73 75 6c 74 2c 20 6f 72 20 28  er $result, or (
22c0: 62 29 20 54 43 4c 20 74 68 72 6f 77 73 20 61 6e  b) TCL throws an
22d0: 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 22   "out of memory"
22e0: 20 65 72 72 6f 72 2e 0a 23 0a 23 20 49 66 20 44   error..#.# If D
22f0: 4f 5f 4d 41 4c 4c 4f 43 5f 54 45 53 54 20 69 73  O_MALLOC_TEST is
2300: 20 64 65 66 69 6e 65 64 20 61 6e 64 20 73 65 74   defined and set
2310: 20 74 6f 20 7a 65 72 6f 2c 20 74 68 65 6e 20 74   to zero, then t
2320: 68 65 20 53 45 4c 45 43 54 20 73 74 61 74 65 6d  he SELECT statem
2330: 65 6e 74 0a 23 20 69 73 20 65 78 65 63 75 74 65  ent.# is execute
2340: 64 20 6a 75 73 74 20 6f 6e 63 65 2e 20 49 6e 20  d just once. In 
2350: 74 68 69 73 20 63 61 73 65 20 74 68 65 20 74 65  this case the te
2360: 73 74 20 63 61 73 65 20 70 61 73 73 65 73 20 69  st case passes i
2370: 66 20 74 68 65 20 72 65 73 75 6c 74 73 0a 23 20  f the results.# 
2380: 6d 61 74 63 68 20 74 68 65 20 65 78 70 65 63 74  match the expect
2390: 65 64 20 72 65 73 75 6c 74 73 20 70 61 73 73 65  ed results passe
23a0: 64 20 76 69 61 20 70 61 72 61 6d 65 74 65 72 20  d via parameter 
23b0: 24 72 65 73 75 6c 74 2e 0a 23 0a 70 72 6f 63 20  $result..#.proc 
23c0: 64 6f 5f 73 65 6c 65 63 74 5f 74 65 73 74 20 7b  do_select_test {
23d0: 6e 61 6d 65 20 73 71 6c 20 72 65 73 75 6c 74 7d  name sql result}
23e0: 20 7b 0a 20 20 64 6f 50 61 73 73 69 76 65 54 65   {.  doPassiveTe
23f0: 73 74 20 24 6e 61 6d 65 20 24 73 71 6c 20 5b 6c  st $name $sql [l
2400: 69 73 74 20 30 20 24 72 65 73 75 6c 74 5d 0a 7d  ist 0 $result].}
2410: 0a 0a 70 72 6f 63 20 64 6f 5f 65 72 72 6f 72 5f  ..proc do_error_
2420: 74 65 73 74 20 7b 6e 61 6d 65 20 73 71 6c 20 65  test {name sql e
2430: 72 72 6f 72 7d 20 7b 0a 20 20 64 6f 50 61 73 73  rror} {.  doPass
2440: 69 76 65 54 65 73 74 20 24 6e 61 6d 65 20 24 73  iveTest $name $s
2450: 71 6c 20 5b 6c 69 73 74 20 31 20 24 65 72 72 6f  ql [list 1 $erro
2460: 72 5d 0a 7d 0a 0a 70 72 6f 63 20 64 6f 50 61 73  r].}..proc doPas
2470: 73 69 76 65 54 65 73 74 20 7b 6e 61 6d 65 20 73  siveTest {name s
2480: 71 6c 20 63 61 74 63 68 72 65 73 7d 20 7b 0a 20  ql catchres} {. 
2490: 20 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73   if {![info exis
24a0: 74 73 20 3a 3a 44 4f 5f 4d 41 4c 4c 4f 43 5f 54  ts ::DO_MALLOC_T
24b0: 45 53 54 5d 7d 20 7b 20 73 65 74 20 3a 3a 44 4f  EST]} { set ::DO
24c0: 5f 4d 41 4c 4c 4f 43 5f 54 45 53 54 20 31 20 7d  _MALLOC_TEST 1 }
24d0: 0a 0a 20 20 69 66 20 7b 24 3a 3a 44 4f 5f 4d 41  ..  if {$::DO_MA
24e0: 4c 4c 4f 43 5f 54 45 53 54 7d 20 7b 0a 20 20 20  LLOC_TEST} {.   
24f0: 20 73 65 74 20 61 6e 73 77 65 72 73 20 5b 6c 69   set answers [li
2500: 73 74 20 7b 31 20 7b 6f 75 74 20 6f 66 20 6d 65  st {1 {out of me
2510: 6d 6f 72 79 7d 7d 20 24 63 61 74 63 68 72 65 73  mory}} $catchres
2520: 5d 0a 20 20 20 20 73 65 74 20 6d 6f 64 65 73 20  ].    set modes 
2530: 5b 6c 69 73 74 20 31 30 30 30 30 30 20 74 72 61  [list 100000 tra
2540: 6e 73 69 65 6e 74 20 31 20 70 65 72 73 69 73 74  nsient 1 persist
2550: 65 6e 74 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a  ent].  } else {.
2560: 20 20 20 20 73 65 74 20 61 6e 73 77 65 72 73 20      set answers 
2570: 5b 6c 69 73 74 20 24 63 61 74 63 68 72 65 73 5d  [list $catchres]
2580: 0a 20 20 20 20 73 65 74 20 6d 6f 64 65 73 20 5b  .    set modes [
2590: 6c 69 73 74 20 30 20 6e 6f 66 61 69 6c 5d 0a 20  list 0 nofail]. 
25a0: 20 7d 0a 20 20 73 65 74 20 73 74 72 20 5b 6a 6f   }.  set str [jo
25b0: 69 6e 20 24 61 6e 73 77 65 72 73 20 22 20 4f 52  in $answers " OR
25c0: 20 22 5d 0a 0a 20 20 66 6f 72 65 61 63 68 20 7b   "]..  foreach {
25d0: 6e 52 65 70 65 61 74 20 7a 4e 61 6d 65 7d 20 24  nRepeat zName} $
25e0: 6d 6f 64 65 73 20 7b 0a 20 20 20 20 66 6f 72 20  modes {.    for 
25f0: 7b 73 65 74 20 69 46 61 69 6c 20 31 7d 20 31 20  {set iFail 1} 1 
2600: 7b 69 6e 63 72 20 69 46 61 69 6c 7d 20 7b 0a 20  {incr iFail} {. 
2610: 20 20 20 20 20 69 66 20 7b 24 3a 3a 44 4f 5f 4d       if {$::DO_M
2620: 41 4c 4c 4f 43 5f 54 45 53 54 7d 20 7b 73 71 6c  ALLOC_TEST} {sql
2630: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 66 61  ite3_memdebug_fa
2640: 69 6c 20 24 69 46 61 69 6c 20 2d 72 65 70 65 61  il $iFail -repea
2650: 74 20 24 6e 52 65 70 65 61 74 7d 0a 0a 20 20 20  t $nRepeat}..   
2660: 20 20 20 73 65 74 20 72 65 73 20 5b 63 61 74 63     set res [catc
2670: 68 73 71 6c 20 24 73 71 6c 5d 0a 20 20 20 20 20  hsql $sql].     
2680: 20 69 66 20 7b 5b 6c 73 65 61 72 63 68 20 2d 65   if {[lsearch -e
2690: 78 61 63 74 20 24 61 6e 73 77 65 72 73 20 24 72  xact $answers $r
26a0: 65 73 5d 3e 3d 30 7d 20 7b 0a 20 20 20 20 20 20  es]>=0} {.      
26b0: 20 20 73 65 74 20 72 65 73 20 24 73 74 72 0a 20    set res $str. 
26c0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 64 6f 5f       }.      do_
26d0: 74 65 73 74 20 24 6e 61 6d 65 2e 24 7a 4e 61 6d  test $name.$zNam
26e0: 65 2e 24 69 46 61 69 6c 20 5b 6c 69 73 74 20 73  e.$iFail [list s
26f0: 65 74 20 7b 7d 20 24 72 65 73 5d 20 24 73 74 72  et {} $res] $str
2700: 0a 20 20 20 20 20 20 73 65 74 20 6e 46 61 69 6c  .      set nFail
2710: 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62   [sqlite3_memdeb
2720: 75 67 5f 66 61 69 6c 20 2d 31 20 2d 62 65 6e 69  ug_fail -1 -beni
2730: 67 6e 63 6e 74 20 6e 42 65 6e 69 67 6e 5d 0a 20  gncnt nBenign]. 
2740: 20 20 20 20 20 69 66 20 7b 24 6e 46 61 69 6c 3d       if {$nFail=
2750: 3d 30 7d 20 62 72 65 61 6b 0a 20 20 20 20 7d 0a  =0} break.    }.
2760: 20 20 7d 0a 7d 0a 0a 0a 23 2d 2d 2d 2d 2d 2d 2d    }.}...#-------
2770: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2780: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2790: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
27a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
27b0: 2d 2d 0a 23 20 54 65 73 74 20 61 20 73 69 6e 67  --.# Test a sing
27c0: 6c 65 20 77 72 69 74 65 20 74 6f 20 74 68 65 20  le write to the 
27d0: 64 61 74 61 62 61 73 65 2e 20 49 6e 20 74 68 69  database. In thi
27e0: 73 20 63 61 73 65 20 61 20 20 22 77 72 69 74 65  s case a  "write
27f0: 22 20 69 73 20 61 20 0a 23 20 44 45 4c 45 54 45  " is a .# DELETE
2800: 2c 20 55 50 44 41 54 45 20 6f 72 20 49 4e 53 45  , UPDATE or INSE
2810: 52 54 20 73 74 61 74 65 6d 65 6e 74 2e 0a 23 0a  RT statement..#.
2820: 23 20 49 66 20 4f 4f 4d 20 74 65 73 74 69 6e 67  # If OOM testing
2830: 20 69 73 20 70 65 72 66 6f 72 6d 65 64 2c 20 74   is performed, t
2840: 68 65 72 65 20 61 72 65 20 73 65 76 65 72 61 6c  here are several
2850: 20 61 63 63 65 70 74 61 62 6c 65 20 6f 75 74 63   acceptable outc
2860: 6f 6d 65 73 3a 0a 23 0a 23 20 20 20 31 29 20 54  omes:.#.#   1) T
2870: 68 65 20 77 72 69 74 65 20 73 75 63 63 65 65 64  he write succeed
2880: 73 2e 20 4e 6f 20 65 72 72 6f 72 20 69 73 20 72  s. No error is r
2890: 65 74 75 72 6e 65 64 2e 0a 23 0a 23 20 20 20 32  eturned..#.#   2
28a0: 29 20 41 6e 20 22 6f 75 74 20 6f 66 20 6d 65 6d  ) An "out of mem
28b0: 6f 72 79 22 20 65 78 63 65 70 74 69 6f 6e 20 69  ory" exception i
28c0: 73 20 74 68 72 6f 77 6e 20 61 6e 64 3a 0a 23 0a  s thrown and:.#.
28d0: 23 20 20 20 20 20 61 29 20 54 68 65 20 73 74 61  #     a) The sta
28e0: 74 65 6d 65 6e 74 20 68 61 73 20 6e 6f 20 65 66  tement has no ef
28f0: 66 65 63 74 2c 20 4f 52 0a 23 20 20 20 20 20 62  fect, OR.#     b
2900: 29 20 54 68 65 20 63 75 72 72 65 6e 74 20 74 72  ) The current tr
2910: 61 6e 73 61 63 74 69 6f 6e 20 69 73 20 72 6f 6c  ansaction is rol
2920: 6c 65 64 20 62 61 63 6b 2c 20 4f 52 0a 23 20 20  led back, OR.#  
2930: 20 20 20 63 29 20 54 68 65 20 73 74 61 74 65 6d     c) The statem
2940: 65 6e 74 20 73 75 63 63 65 65 64 73 2e 20 54 68  ent succeeds. Th
2950: 69 73 20 63 61 6e 20 6f 6e 6c 79 20 68 61 70 70  is can only happ
2960: 65 6e 20 69 66 20 74 68 65 20 63 6f 6e 6e 65 63  en if the connec
2970: 74 69 6f 6e 0a 23 20 20 20 20 20 20 20 20 69 73  tion.#        is
2980: 20 69 6e 20 61 75 74 6f 2d 63 6f 6d 6d 69 74 20   in auto-commit 
2990: 6d 6f 64 65 20 28 61 66 74 65 72 20 74 68 65 20  mode (after the 
29a0: 73 74 61 74 65 6d 65 6e 74 20 69 73 20 65 78 65  statement is exe
29b0: 63 75 74 65 64 2c 20 73 6f 20 74 68 69 73 0a 23  cuted, so this.#
29c0: 20 20 20 20 20 20 20 20 69 6e 63 6c 75 64 65 73          includes
29d0: 20 43 4f 4d 4d 49 54 20 73 74 61 74 65 6d 65 6e   COMMIT statemen
29e0: 74 73 29 2e 0a 23 0a 23 20 49 66 20 74 68 65 20  ts)..#.# If the 
29f0: 77 72 69 74 65 20 6f 70 65 72 61 74 69 6f 6e 20  write operation 
2a00: 65 76 65 6e 74 75 61 6c 6c 79 20 73 75 63 63 65  eventually succe
2a10: 65 64 73 2c 20 7a 65 72 6f 20 69 73 20 72 65 74  eds, zero is ret
2a20: 75 72 6e 65 64 2e 20 49 66 20 61 0a 23 20 74 72  urned. If a.# tr
2a30: 61 6e 73 61 63 74 69 6f 6e 20 69 73 20 72 6f 6c  ansaction is rol
2a40: 6c 65 64 20 62 61 63 6b 2c 20 6e 6f 6e 2d 7a 65  led back, non-ze
2a50: 72 6f 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a  ro is returned..
2a60: 23 0a 23 20 50 61 72 61 6d 65 74 65 72 20 24 6e  #.# Parameter $n
2a70: 61 6d 65 20 69 73 20 74 68 65 20 6e 61 6d 65 20  ame is the name 
2a80: 74 6f 20 75 73 65 20 66 6f 72 20 74 68 65 20 74  to use for the t
2a90: 65 73 74 20 63 61 73 65 20 28 6f 72 20 74 65 73  est case (or tes
2aa0: 74 20 63 61 73 65 73 29 2e 0a 23 20 54 68 65 20  t cases)..# The 
2ab0: 73 65 63 6f 6e 64 20 70 61 72 61 6d 65 74 65 72  second parameter
2ac0: 2c 20 24 74 62 6c 2c 20 73 68 6f 75 6c 64 20 62  , $tbl, should b
2ad0: 65 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68  e the name of th
2ae0: 65 20 64 61 74 61 62 61 73 65 20 74 61 62 6c 65  e database table
2af0: 0a 23 20 62 65 69 6e 67 20 6d 6f 64 69 66 69 65  .# being modifie
2b00: 64 2e 20 50 61 72 61 6d 65 74 65 72 20 24 73 71  d. Parameter $sq
2b10: 6c 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 53  l contains the S
2b20: 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20  QL statement to 
2b30: 74 65 73 74 2e 0a 23 0a 70 72 6f 63 20 64 6f 5f  test..#.proc do_
2b40: 77 72 69 74 65 5f 74 65 73 74 20 7b 6e 61 6d 65  write_test {name
2b50: 20 74 62 6c 20 73 71 6c 7d 20 7b 0a 20 20 69 66   tbl sql} {.  if
2b60: 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20   {![info exists 
2b70: 3a 3a 44 4f 5f 4d 41 4c 4c 4f 43 5f 54 45 53 54  ::DO_MALLOC_TEST
2b80: 5d 7d 20 7b 20 73 65 74 20 3a 3a 44 4f 5f 4d 41  ]} { set ::DO_MA
2b90: 4c 4c 4f 43 5f 54 45 53 54 20 31 20 7d 0a 0a 20  LLOC_TEST 1 }.. 
2ba0: 20 23 20 46 69 67 75 72 65 20 6f 75 74 20 61 6e   # Figure out an
2bb0: 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20 67 65   statement to ge
2bc0: 74 20 61 20 63 68 65 63 6b 73 75 6d 20 66 6f 72  t a checksum for
2bd0: 20 74 61 62 6c 65 20 24 74 62 6c 2e 0a 20 20 64   table $tbl..  d
2be0: 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a  b eval "SELECT *
2bf0: 20 46 52 4f 4d 20 24 74 62 6c 22 20 56 20 62 72   FROM $tbl" V br
2c00: 65 61 6b 0a 20 20 73 65 74 20 63 6b 73 75 6d 73  eak.  set cksums
2c10: 71 6c 20 22 53 45 4c 45 43 54 20 6d 64 35 73 75  ql "SELECT md5su
2c20: 6d 28 5b 6a 6f 69 6e 20 5b 63 6f 6e 63 61 74 20  m([join [concat 
2c30: 72 6f 77 69 64 20 24 56 28 2a 29 5d 20 2c 5d 29  rowid $V(*)] ,])
2c40: 20 46 52 4f 4d 20 24 74 62 6c 22 0a 0a 20 20 23   FROM $tbl"..  #
2c50: 20 43 61 6c 63 75 6c 61 74 65 20 74 68 65 20 69   Calculate the i
2c60: 6e 69 74 69 61 6c 20 74 61 62 6c 65 20 63 68 65  nitial table che
2c70: 63 6b 73 75 6d 2e 0a 20 20 73 65 74 20 63 6b 73  cksum..  set cks
2c80: 75 6d 31 20 5b 64 62 20 6f 6e 65 20 24 63 6b 73  um1 [db one $cks
2c90: 75 6d 73 71 6c 5d 0a 0a 20 20 69 66 20 7b 24 3a  umsql]..  if {$:
2ca0: 3a 44 4f 5f 4d 41 4c 4c 4f 43 5f 54 45 53 54 20  :DO_MALLOC_TEST 
2cb0: 7d 20 7b 0a 20 20 20 20 73 65 74 20 61 6e 73 77  } {.    set answ
2cc0: 65 72 73 20 5b 6c 69 73 74 20 7b 31 20 7b 6f 75  ers [list {1 {ou
2cd0: 74 20 6f 66 20 6d 65 6d 6f 72 79 7d 7d 20 7b 30  t of memory}} {0
2ce0: 20 7b 7d 7d 5d 0a 20 20 20 20 69 66 20 7b 24 3a   {}}].    if {$:
2cf0: 3a 44 4f 5f 4d 41 4c 4c 4f 43 5f 54 45 53 54 3d  :DO_MALLOC_TEST=
2d00: 3d 31 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20  =1} {.      set 
2d10: 6d 6f 64 65 73 20 7b 31 30 30 30 30 30 20 74 72  modes {100000 tr
2d20: 61 6e 73 69 65 6e 74 7d 0a 20 20 20 20 7d 20 65  ansient}.    } e
2d30: 6c 73 65 20 7b 0a 20 20 20 20 20 20 73 65 74 20  lse {.      set 
2d40: 6d 6f 64 65 73 20 7b 31 20 70 65 72 73 69 73 74  modes {1 persist
2d50: 65 6e 74 7d 0a 20 20 20 20 7d 0a 20 20 7d 20 65  ent}.    }.  } e
2d60: 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 61 6e  lse {.    set an
2d70: 73 77 65 72 73 20 5b 6c 69 73 74 20 7b 30 20 7b  swers [list {0 {
2d80: 7d 7d 5d 0a 20 20 20 20 73 65 74 20 6d 6f 64 65  }}].    set mode
2d90: 73 20 5b 6c 69 73 74 20 30 20 6e 6f 66 61 69 6c  s [list 0 nofail
2da0: 5d 0a 20 20 7d 0a 20 20 73 65 74 20 73 74 72 20  ].  }.  set str 
2db0: 5b 6a 6f 69 6e 20 24 61 6e 73 77 65 72 73 20 22  [join $answers "
2dc0: 20 4f 52 20 22 5d 0a 0a 20 20 66 6f 72 65 61 63   OR "]..  foreac
2dd0: 68 20 7b 6e 52 65 70 65 61 74 20 7a 4e 61 6d 65  h {nRepeat zName
2de0: 7d 20 24 6d 6f 64 65 73 20 7b 0a 20 20 20 20 66  } $modes {.    f
2df0: 6f 72 20 7b 73 65 74 20 69 46 61 69 6c 20 31 7d  or {set iFail 1}
2e00: 20 31 20 7b 69 6e 63 72 20 69 46 61 69 6c 7d 20   1 {incr iFail} 
2e10: 7b 0a 20 20 20 20 20 20 69 66 20 7b 24 3a 3a 44  {.      if {$::D
2e20: 4f 5f 4d 41 4c 4c 4f 43 5f 54 45 53 54 7d 20 7b  O_MALLOC_TEST} {
2e30: 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67  sqlite3_memdebug
2e40: 5f 66 61 69 6c 20 24 69 46 61 69 6c 20 2d 72 65  _fail $iFail -re
2e50: 70 65 61 74 20 24 6e 52 65 70 65 61 74 7d 0a 0a  peat $nRepeat}..
2e60: 20 20 20 20 20 20 73 65 74 20 72 65 73 20 5b 75        set res [u
2e70: 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 63 61 74  plevel [list cat
2e80: 63 68 73 71 6c 20 24 73 71 6c 5d 5d 0a 20 20 20  chsql $sql]].   
2e90: 20 20 20 73 65 74 20 6e 46 61 69 6c 20 5b 73 71     set nFail [sq
2ea0: 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 66  lite3_memdebug_f
2eb0: 61 69 6c 20 2d 31 20 2d 62 65 6e 69 67 6e 63 6e  ail -1 -benigncn
2ec0: 74 20 6e 42 65 6e 69 67 6e 5d 0a 20 20 20 20 20  t nBenign].     
2ed0: 20 69 66 20 7b 24 6e 46 61 69 6c 3d 3d 30 7d 20   if {$nFail==0} 
2ee0: 7b 0a 20 20 20 20 20 20 20 20 64 6f 5f 74 65 73  {.        do_tes
2ef0: 74 20 24 6e 61 6d 65 2e 24 7a 4e 61 6d 65 2e 24  t $name.$zName.$
2f00: 69 46 61 69 6c 20 5b 6c 69 73 74 20 73 65 74 20  iFail [list set 
2f10: 7b 7d 20 24 72 65 73 5d 20 7b 30 20 7b 7d 7d 0a  {} $res] {0 {}}.
2f20: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 0a 20          return. 
2f30: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
2f40: 20 20 20 20 20 20 69 66 20 7b 5b 6c 73 65 61 72        if {[lsear
2f50: 63 68 20 24 61 6e 73 77 65 72 73 20 24 72 65 73  ch $answers $res
2f60: 5d 3e 3d 30 7d 20 7b 0a 20 20 20 20 20 20 20 20  ]>=0} {.        
2f70: 20 20 73 65 74 20 72 65 73 20 24 73 74 72 0a 20    set res $str. 
2f80: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
2f90: 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d 65 2e 24   do_test $name.$
2fa0: 7a 4e 61 6d 65 2e 24 69 46 61 69 6c 20 5b 6c 69  zName.$iFail [li
2fb0: 73 74 20 73 65 74 20 7b 7d 20 24 72 65 73 5d 20  st set {} $res] 
2fc0: 24 73 74 72 0a 20 20 20 20 20 20 20 20 73 65 74  $str.        set
2fd0: 20 63 6b 73 75 6d 32 20 5b 64 62 20 6f 6e 65 20   cksum2 [db one 
2fe0: 24 63 6b 73 75 6d 73 71 6c 5d 0a 20 20 20 20 20  $cksumsql].     
2ff0: 20 20 20 69 66 20 7b 24 63 6b 73 75 6d 31 20 21     if {$cksum1 !
3000: 3d 20 24 63 6b 73 75 6d 32 7d 20 72 65 74 75 72  = $cksum2} retur
3010: 6e 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  n.      }.    }.
3020: 20 20 7d 0a 7d 0a                                  }.}.