/ Hex Artifact Content
Login

Artifact 3a121e1a03b29376057b3dfff429ad4f373cd0c3:


0000: 23 20 32 30 30 31 20 53 65 70 74 65 6d 62 65 72  # 2001 September
0010: 20 31 35 0a 23 0a 23 20 54 68 65 20 61 75 74 68   15.#.# The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 23 20 61 20 6c 65 67  place of.# a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 23  is a blessing:.#
0080: 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20 64 6f  .#    May you do
0090: 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20 65 76   good and not ev
00a0: 69 6c 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75  il..#    May you
00b0: 20 66 69 6e 64 20 66 6f 72 67 69 76 65 6e 65 73   find forgivenes
00c0: 73 20 66 6f 72 20 79 6f 75 72 73 65 6c 66 20 61  s for yourself a
00d0: 6e 64 20 66 6f 72 67 69 76 65 20 6f 74 68 65 72  nd forgive other
00e0: 73 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20  s..#    May you 
00f0: 73 68 61 72 65 20 66 72 65 65 6c 79 2c 20 6e 65  share freely, ne
0100: 76 65 72 20 74 61 6b 69 6e 67 20 6d 6f 72 65 20  ver taking more 
0110: 74 68 61 6e 20 79 6f 75 20 67 69 76 65 2e 0a 23  than you give..#
0120: 0a 23 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 2a 0a 23 20 54 68 69 73  *********.# This
0170: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0180: 20 73 6f 6d 65 20 63 6f 6d 6d 6f 6e 20 54 43 4c   some common TCL
0190: 20 72 6f 75 74 69 6e 65 73 20 75 73 65 64 20 66   routines used f
01a0: 6f 72 20 72 65 67 72 65 73 73 69 6f 6e 0a 23 20  or regression.# 
01b0: 74 65 73 74 69 6e 67 20 74 68 65 20 53 51 4c 69  testing the SQLi
01c0: 74 65 20 6c 69 62 72 61 72 79 0a 23 0a 23 20 24  te library.#.# $
01d0: 49 64 3a 20 74 65 73 74 65 72 2e 74 63 6c 2c 76  Id: tester.tcl,v
01e0: 20 31 2e 31 33 31 20 32 30 30 38 2f 30 37 2f 31   1.131 2008/07/1
01f0: 31 20 31 36 3a 31 35 3a 31 38 20 64 72 68 20 45  1 16:15:18 drh E
0200: 78 70 20 24 0a 0a 23 0a 23 20 57 68 61 74 20 66  xp $..#.# What f
0210: 6f 72 20 75 73 65 72 20 69 6e 70 75 74 20 62 65  or user input be
0220: 66 6f 72 65 20 63 6f 6e 74 69 6e 75 69 6e 67 2e  fore continuing.
0230: 20 20 54 68 69 73 20 67 69 76 65 73 20 61 6e 20    This gives an 
0240: 6f 70 70 6f 72 74 75 6e 69 74 79 0a 23 20 74 6f  opportunity.# to
0250: 20 63 6f 6e 6e 65 63 74 20 70 72 6f 66 69 6c 69   connect profili
0260: 6e 67 20 74 6f 6f 6c 73 20 74 6f 20 74 68 65 20  ng tools to the 
0270: 70 72 6f 63 65 73 73 2e 0a 23 0a 66 6f 72 20 7b  process..#.for {
0280: 73 65 74 20 69 20 30 7d 20 7b 24 69 3c 5b 6c 6c  set i 0} {$i<[ll
0290: 65 6e 67 74 68 20 24 61 72 67 76 5d 7d 20 7b 69  ength $argv]} {i
02a0: 6e 63 72 20 69 7d 20 7b 0a 20 20 69 66 20 7b 5b  ncr i} {.  if {[
02b0: 72 65 67 65 78 70 20 7b 5e 2d 2b 70 61 75 73 65  regexp {^-+pause
02c0: 24 7d 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 76  $} [lindex $argv
02d0: 20 24 69 5d 20 61 6c 6c 20 76 61 6c 75 65 5d 7d   $i] all value]}
02e0: 20 7b 0a 20 20 20 20 70 75 74 73 20 2d 6e 6f 6e   {.    puts -non
02f0: 65 77 6c 69 6e 65 20 22 50 72 65 73 73 20 52 45  ewline "Press RE
0300: 54 55 52 4e 20 74 6f 20 62 65 67 69 6e 2e 2e 2e  TURN to begin...
0310: 22 0a 20 20 20 20 66 6c 75 73 68 20 73 74 64 6f  ".    flush stdo
0320: 75 74 0a 20 20 20 20 67 65 74 73 20 73 74 64 69  ut.    gets stdi
0330: 6e 0a 20 20 20 20 73 65 74 20 61 72 67 76 20 5b  n.    set argv [
0340: 6c 72 65 70 6c 61 63 65 20 24 61 72 67 76 20 24  lreplace $argv $
0350: 69 20 24 69 5d 0a 20 20 7d 0a 7d 0a 0a 73 65 74  i $i].  }.}..set
0360: 20 74 63 6c 5f 70 72 65 63 69 73 69 6f 6e 20 31   tcl_precision 1
0370: 35 0a 73 65 74 20 73 71 6c 69 74 65 5f 70 65 6e  5.set sqlite_pen
0380: 64 69 6e 67 5f 62 79 74 65 20 30 78 30 30 31 30  ding_byte 0x0010
0390: 30 30 30 0a 0a 23 20 0a 23 20 43 68 65 63 6b 20  000..# .# Check 
03a0: 74 68 65 20 63 6f 6d 6d 61 6e 64 2d 6c 69 6e 65  the command-line
03b0: 20 61 72 67 75 6d 65 6e 74 73 20 66 6f 72 20 61   arguments for a
03c0: 20 64 65 66 61 75 6c 74 20 73 6f 66 74 2d 68 65   default soft-he
03d0: 61 70 2d 6c 69 6d 69 74 2e 0a 23 20 53 74 6f 72  ap-limit..# Stor
03e0: 65 20 74 68 69 73 20 64 65 66 61 75 6c 74 20 76  e this default v
03f0: 61 6c 75 65 20 69 6e 20 74 68 65 20 67 6c 6f 62  alue in the glob
0400: 61 6c 20 76 61 72 69 61 62 6c 65 20 3a 3a 73 6f  al variable ::so
0410: 66 74 5f 6c 69 6d 69 74 20 61 6e 64 0a 23 20 75  ft_limit and.# u
0420: 70 64 61 74 65 20 74 68 65 20 73 6f 66 74 2d 68  pdate the soft-h
0430: 65 61 70 2d 6c 69 6d 69 74 20 65 61 63 68 20 74  eap-limit each t
0440: 69 6d 65 20 74 68 69 73 20 73 63 72 69 70 74 20  ime this script 
0450: 69 73 20 72 75 6e 2e 20 20 49 6e 20 74 68 61 74  is run.  In that
0460: 0a 23 20 77 61 79 20 69 66 20 61 6e 20 69 6e 64  .# way if an ind
0470: 69 76 69 64 75 61 6c 20 74 65 73 74 20 66 69 6c  ividual test fil
0480: 65 20 63 68 61 6e 67 65 73 20 74 68 65 20 73 6f  e changes the so
0490: 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 2c 20 69  ft-heap-limit, i
04a0: 74 0a 23 20 77 69 6c 6c 20 62 65 20 72 65 73 65  t.# will be rese
04b0: 74 20 61 74 20 74 68 65 20 73 74 61 72 74 20 6f  t at the start o
04c0: 66 20 74 68 65 20 6e 65 78 74 20 74 65 73 74 20  f the next test 
04d0: 66 69 6c 65 2e 0a 23 0a 69 66 20 7b 21 5b 69 6e  file..#.if {![in
04e0: 66 6f 20 65 78 69 73 74 73 20 73 6f 66 74 5f 6c  fo exists soft_l
04f0: 69 6d 69 74 5d 7d 20 7b 0a 20 20 73 65 74 20 73  imit]} {.  set s
0500: 6f 66 74 5f 6c 69 6d 69 74 20 30 0a 20 20 66 6f  oft_limit 0.  fo
0510: 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 3c  r {set i 0} {$i<
0520: 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 76 5d 7d  [llength $argv]}
0530: 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20   {incr i} {.    
0540: 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e 2d 2d  if {[regexp {^--
0550: 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 3d  soft-heap-limit=
0560: 28 2e 2b 29 24 7d 20 5b 6c 69 6e 64 65 78 20 24  (.+)$} [lindex $
0570: 61 72 67 76 20 24 69 5d 20 61 6c 6c 20 76 61 6c  argv $i] all val
0580: 75 65 5d 7d 20 7b 0a 20 20 20 20 20 20 69 66 20  ue]} {.      if 
0590: 7b 24 76 61 6c 75 65 21 3d 22 6f 66 66 22 7d 20  {$value!="off"} 
05a0: 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 73 6f  {.        set so
05b0: 66 74 5f 6c 69 6d 69 74 20 24 76 61 6c 75 65 0a  ft_limit $value.
05c0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73 65        }.      se
05d0: 74 20 61 72 67 76 20 5b 6c 72 65 70 6c 61 63 65  t argv [lreplace
05e0: 20 24 61 72 67 76 20 24 69 20 24 69 5d 0a 20 20   $argv $i $i].  
05f0: 20 20 7d 0a 20 20 7d 0a 7d 0a 73 71 6c 69 74 65    }.  }.}.sqlite
0600: 33 5f 73 6f 66 74 5f 68 65 61 70 5f 6c 69 6d 69  3_soft_heap_limi
0610: 74 20 24 73 6f 66 74 5f 6c 69 6d 69 74 0a 0a 23  t $soft_limit..#
0620: 20 0a 23 20 43 68 65 63 6b 20 74 68 65 20 63 6f   .# Check the co
0630: 6d 6d 61 6e 64 2d 6c 69 6e 65 20 61 72 67 75 6d  mmand-line argum
0640: 65 6e 74 73 20 74 6f 20 73 65 74 20 74 68 65 20  ents to set the 
0650: 6d 65 6d 6f 72 79 20 64 65 62 75 67 67 65 72 0a  memory debugger.
0660: 23 20 62 61 63 6b 74 72 61 63 65 20 64 65 70 74  # backtrace dept
0670: 68 2e 0a 23 0a 23 20 53 65 65 20 74 68 65 20 73  h..#.# See the s
0680: 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f  qlite3_memdebug_
0690: 62 61 63 6b 74 72 61 63 65 28 29 20 66 75 6e 63  backtrace() func
06a0: 74 69 6f 6e 20 69 6e 20 6d 65 6d 32 2e 63 20 6f  tion in mem2.c o
06b0: 72 0a 23 20 74 65 73 74 5f 6d 61 6c 6c 6f 63 2e  r.# test_malloc.
06c0: 63 20 66 6f 72 20 61 64 64 69 74 69 6f 6e 61 6c  c for additional
06d0: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 0a 23 0a   information..#.
06e0: 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24  for {set i 0} {$
06f0: 69 3c 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 76  i<[llength $argv
0700: 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  ]} {incr i} {.  
0710: 69 66 20 7b 5b 6c 69 6e 64 65 78 20 24 61 72 67  if {[lindex $arg
0720: 76 20 24 69 5d 20 65 71 20 22 2d 2d 6d 61 6c 6c  v $i] eq "--mall
0730: 6f 63 74 72 61 63 65 22 7d 20 7b 0a 20 20 20 20  octrace"} {.    
0740: 73 65 74 20 61 72 67 76 20 5b 6c 72 65 70 6c 61  set argv [lrepla
0750: 63 65 20 24 61 72 67 76 20 24 69 20 24 69 5d 0a  ce $argv $i $i].
0760: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64      sqlite3_memd
0770: 65 62 75 67 5f 62 61 63 6b 74 72 61 63 65 20 31  ebug_backtrace 1
0780: 30 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65  0.    sqlite3_me
0790: 6d 64 65 62 75 67 5f 6c 6f 67 20 73 74 61 72 74  mdebug_log start
07a0: 0a 20 20 20 20 73 65 74 20 74 65 73 74 65 72 5f  .    set tester_
07b0: 64 6f 5f 6d 61 6c 6c 6f 63 74 72 61 63 65 20 31  do_malloctrace 1
07c0: 0a 20 20 7d 0a 7d 0a 66 6f 72 20 7b 73 65 74 20  .  }.}.for {set 
07d0: 69 20 30 7d 20 7b 24 69 3c 5b 6c 6c 65 6e 67 74  i 0} {$i<[llengt
07e0: 68 20 24 61 72 67 76 5d 7d 20 7b 69 6e 63 72 20  h $argv]} {incr 
07f0: 69 7d 20 7b 0a 20 20 69 66 20 7b 5b 72 65 67 65  i} {.  if {[rege
0800: 78 70 20 7b 5e 2d 2d 62 61 63 6b 74 72 61 63 65  xp {^--backtrace
0810: 3d 28 5c 64 2b 29 24 7d 20 5b 6c 69 6e 64 65 78  =(\d+)$} [lindex
0820: 20 24 61 72 67 76 20 24 69 5d 20 61 6c 6c 20 76   $argv $i] all v
0830: 61 6c 75 65 5d 7d 20 7b 0a 20 20 20 20 73 71 6c  alue]} {.    sql
0840: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 62 61  ite3_memdebug_ba
0850: 63 6b 74 72 61 63 65 20 24 76 61 6c 75 65 0a 20  cktrace $value. 
0860: 20 20 20 73 65 74 20 61 72 67 76 20 5b 6c 72 65     set argv [lre
0870: 70 6c 61 63 65 20 24 61 72 67 76 20 24 69 20 24  place $argv $i $
0880: 69 5d 0a 20 20 7d 0a 7d 0a 0a 0a 70 72 6f 63 20  i].  }.}...proc 
0890: 6f 73 74 72 61 63 65 5f 63 61 6c 6c 20 7b 7a 43  ostrace_call {zC
08a0: 61 6c 6c 20 6e 43 6c 69 63 6b 20 7a 46 69 6c 65  all nClick zFile
08b0: 20 69 33 32 20 69 36 34 7d 20 7b 0a 20 20 73 65   i32 i64} {.  se
08c0: 74 20 73 20 22 49 4e 53 45 52 54 20 49 4e 54 4f  t s "INSERT INTO
08d0: 20 6f 73 74 72 61 63 65 20 56 41 4c 55 45 53 28   ostrace VALUES(
08e0: 27 24 7a 43 61 6c 6c 27 2c 20 24 6e 43 6c 69 63  '$zCall', $nClic
08f0: 6b 2c 20 27 24 7a 46 69 6c 65 27 2c 20 24 69 33  k, '$zFile', $i3
0900: 32 2c 20 24 69 36 34 29 3b 22 0a 20 20 70 75 74  2, $i64);".  put
0910: 73 20 24 3a 3a 6f 73 74 72 61 63 65 5f 66 64 20  s $::ostrace_fd 
0920: 24 73 0a 7d 0a 0a 66 6f 72 20 7b 73 65 74 20 69  $s.}..for {set i
0930: 20 30 7d 20 7b 24 69 3c 5b 6c 6c 65 6e 67 74 68   0} {$i<[llength
0940: 20 24 61 72 67 76 5d 7d 20 7b 69 6e 63 72 20 69   $argv]} {incr i
0950: 7d 20 7b 0a 20 20 69 66 20 7b 5b 6c 69 6e 64 65  } {.  if {[linde
0960: 78 20 24 61 72 67 76 20 24 69 5d 20 65 71 20 22  x $argv $i] eq "
0970: 2d 2d 6f 73 73 75 6d 6d 61 72 79 22 20 7c 7c 20  --ossummary" || 
0980: 5b 6c 69 6e 64 65 78 20 24 61 72 67 76 20 24 69  [lindex $argv $i
0990: 5d 20 65 71 20 22 2d 2d 6f 73 74 72 61 63 65 22  ] eq "--ostrace"
09a0: 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  } {.    sqlite3_
09b0: 69 6e 73 74 76 66 73 20 63 72 65 61 74 65 20 2d  instvfs create -
09c0: 64 65 66 61 75 6c 74 20 6f 73 74 72 61 63 65 0a  default ostrace.
09d0: 20 20 20 20 73 65 74 20 74 65 73 74 65 72 5f 64      set tester_d
09e0: 6f 5f 6f 73 74 72 61 63 65 20 31 0a 20 20 20 20  o_ostrace 1.    
09f0: 73 65 74 20 6f 73 74 72 61 63 65 5f 66 64 20 5b  set ostrace_fd [
0a00: 6f 70 65 6e 20 6f 73 74 72 61 63 65 2e 73 71 6c  open ostrace.sql
0a10: 20 77 5d 0a 20 20 20 20 70 75 74 73 20 24 6f 73   w].    puts $os
0a20: 74 72 61 63 65 5f 66 64 20 22 42 45 47 49 4e 3b  trace_fd "BEGIN;
0a30: 22 0a 20 20 20 20 69 66 20 7b 5b 6c 69 6e 64 65  ".    if {[linde
0a40: 78 20 24 61 72 67 76 20 24 69 5d 20 65 71 20 22  x $argv $i] eq "
0a50: 2d 2d 6f 73 74 72 61 63 65 22 7d 20 7b 0a 20 20  --ostrace"} {.  
0a60: 20 20 20 20 73 65 74 20 20 20 20 73 20 22 43 52      set    s "CR
0a70: 45 41 54 45 20 54 41 42 4c 45 20 6f 73 74 72 61  EATE TABLE ostra
0a80: 63 65 22 0a 20 20 20 20 20 20 61 70 70 65 6e 64  ce".      append
0a90: 20 73 20 22 28 6d 65 74 68 6f 64 20 54 45 58 54   s "(method TEXT
0aa0: 2c 20 63 6c 69 63 6b 73 20 49 4e 54 2c 20 66 69  , clicks INT, fi
0ab0: 6c 65 20 54 45 58 54 2c 20 69 33 32 20 49 4e 54  le TEXT, i32 INT
0ac0: 2c 20 69 36 34 20 49 4e 54 29 3b 22 0a 20 20 20  , i64 INT);".   
0ad0: 20 20 20 70 75 74 73 20 24 6f 73 74 72 61 63 65     puts $ostrace
0ae0: 5f 66 64 20 24 73 0a 20 20 20 20 20 20 73 71 6c  _fd $s.      sql
0af0: 69 74 65 33 5f 69 6e 73 74 76 66 73 20 63 6f 6e  ite3_instvfs con
0b00: 66 69 67 75 72 65 20 6f 73 74 72 61 63 65 20 6f  figure ostrace o
0b10: 73 74 72 61 63 65 5f 63 61 6c 6c 0a 20 20 20 20  strace_call.    
0b20: 20 20 73 71 6c 69 74 65 33 5f 69 6e 73 74 76 66    sqlite3_instvf
0b30: 73 20 63 6f 6e 66 69 67 75 72 65 20 6f 73 74 72  s configure ostr
0b40: 61 63 65 20 6f 73 74 72 61 63 65 5f 63 61 6c 6c  ace ostrace_call
0b50: 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20 61  .    }.    set a
0b60: 72 67 76 20 5b 6c 72 65 70 6c 61 63 65 20 24 61  rgv [lreplace $a
0b70: 72 67 76 20 24 69 20 24 69 5d 0a 20 20 7d 0a 20  rgv $i $i].  }. 
0b80: 20 69 66 20 7b 5b 6c 69 6e 64 65 78 20 24 61 72   if {[lindex $ar
0b90: 67 76 20 24 69 5d 20 65 71 20 22 2d 2d 62 69 6e  gv $i] eq "--bin
0ba0: 61 72 79 6c 6f 67 22 7d 20 7b 0a 20 20 20 20 73  arylog"} {.    s
0bb0: 65 74 20 74 65 73 74 65 72 5f 64 6f 5f 62 69 6e  et tester_do_bin
0bc0: 61 72 79 6c 6f 67 20 31 0a 0a 20 20 20 20 23 20  arylog 1..    # 
0bd0: 73 71 6c 69 74 65 33 5f 73 69 6d 75 6c 61 74 65  sqlite3_simulate
0be0: 5f 64 65 76 69 63 65 20 2d 63 68 61 72 20 73 61  _device -char sa
0bf0: 66 65 5f 61 70 70 65 6e 64 0a 20 20 20 20 23 20  fe_append.    # 
0c00: 73 71 6c 69 74 65 33 5f 69 6e 73 74 76 66 73 20  sqlite3_instvfs 
0c10: 62 69 6e 61 72 79 6c 6f 67 20 2d 64 65 66 61 75  binarylog -defau
0c20: 6c 74 20 2d 70 61 72 65 6e 74 20 64 65 76 73 79  lt -parent devsy
0c30: 6d 20 62 69 6e 61 72 79 6c 6f 67 20 6f 73 74 72  m binarylog ostr
0c40: 61 63 65 2e 62 69 6e 0a 20 20 20 20 73 71 6c 69  ace.bin.    sqli
0c50: 74 65 33 5f 69 6e 73 74 76 66 73 20 62 69 6e 61  te3_instvfs bina
0c60: 72 79 6c 6f 67 20 2d 64 65 66 61 75 6c 74 20 62  rylog -default b
0c70: 69 6e 61 72 79 6c 6f 67 20 6f 73 74 72 61 63 65  inarylog ostrace
0c80: 2e 62 69 6e 0a 20 20 20 20 73 65 74 20 61 72 67  .bin.    set arg
0c90: 76 20 5b 6c 72 65 70 6c 61 63 65 20 24 61 72 67  v [lreplace $arg
0ca0: 76 20 24 69 20 24 69 5d 0a 20 20 20 20 73 71 6c  v $i $i].    sql
0cb0: 69 74 65 33 5f 69 6e 73 74 76 66 73 20 6d 61 72  ite3_instvfs mar
0cc0: 6b 65 72 20 62 69 6e 61 72 79 6c 6f 67 20 22 24  ker binarylog "$
0cd0: 61 72 67 76 30 20 24 61 72 67 76 22 0a 20 20 7d  argv0 $argv".  }
0ce0: 0a 7d 0a 0a 23 20 0a 23 20 43 68 65 63 6b 20 74  .}..# .# Check t
0cf0: 68 65 20 63 6f 6d 6d 61 6e 64 2d 6c 69 6e 65 20  he command-line 
0d00: 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 73 65 74  arguments to set
0d10: 20 74 68 65 20 6d 61 78 69 6d 75 6d 20 6e 75 6d   the maximum num
0d20: 62 65 72 20 6f 66 0a 23 20 65 72 72 6f 72 73 20  ber of.# errors 
0d30: 74 6f 6c 65 72 61 74 65 64 20 62 65 66 6f 72 65  tolerated before
0d40: 20 68 61 6c 74 69 6e 67 2e 0a 23 0a 69 66 20 7b   halting..#.if {
0d50: 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 6d 61  ![info exists ma
0d60: 78 45 72 72 5d 7d 20 7b 0a 20 20 73 65 74 20 6d  xErr]} {.  set m
0d70: 61 78 45 72 72 20 31 30 30 30 0a 7d 0a 66 6f 72  axErr 1000.}.for
0d80: 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 3c 5b   {set i 0} {$i<[
0d90: 6c 6c 65 6e 67 74 68 20 24 61 72 67 76 5d 7d 20  llength $argv]} 
0da0: 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 69 66 20  {incr i} {.  if 
0db0: 7b 5b 72 65 67 65 78 70 20 7b 5e 2d 2d 6d 61 78  {[regexp {^--max
0dc0: 65 72 72 6f 72 3d 28 5c 64 2b 29 24 7d 20 5b 6c  error=(\d+)$} [l
0dd0: 69 6e 64 65 78 20 24 61 72 67 76 20 24 69 5d 20  index $argv $i] 
0de0: 61 6c 6c 20 6d 61 78 45 72 72 5d 7d 20 7b 0a 20  all maxErr]} {. 
0df0: 20 20 20 73 65 74 20 61 72 67 76 20 5b 6c 72 65     set argv [lre
0e00: 70 6c 61 63 65 20 24 61 72 67 76 20 24 69 20 24  place $argv $i $
0e10: 69 5d 0a 20 20 7d 0a 7d 0a 23 70 75 74 73 20 22  i].  }.}.#puts "
0e20: 4d 61 78 20 65 72 72 6f 72 20 3d 20 24 6d 61 78  Max error = $max
0e30: 45 72 72 22 0a 0a 0a 23 20 55 73 65 20 74 68 65  Err"...# Use the
0e40: 20 70 61 67 65 72 20 63 6f 64 65 63 20 69 66 20   pager codec if 
0e50: 69 74 20 69 73 20 61 76 61 69 6c 61 62 6c 65 0a  it is available.
0e60: 23 0a 69 66 20 7b 5b 73 71 6c 69 74 65 33 20 2d  #.if {[sqlite3 -
0e70: 68 61 73 2d 63 6f 64 65 63 5d 20 26 26 20 5b 69  has-codec] && [i
0e80: 6e 66 6f 20 63 6f 6d 6d 61 6e 64 20 73 71 6c 69  nfo command sqli
0e90: 74 65 5f 6f 72 69 67 5d 3d 3d 22 22 7d 20 7b 0a  te_orig]==""} {.
0ea0: 20 20 72 65 6e 61 6d 65 20 73 71 6c 69 74 65 33    rename sqlite3
0eb0: 20 73 71 6c 69 74 65 5f 6f 72 69 67 0a 20 20 70   sqlite_orig.  p
0ec0: 72 6f 63 20 73 71 6c 69 74 65 33 20 7b 61 72 67  roc sqlite3 {arg
0ed0: 73 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 6c 6c  s} {.    if {[ll
0ee0: 65 6e 67 74 68 20 24 61 72 67 73 5d 3d 3d 32 20  ength $args]==2 
0ef0: 26 26 20 5b 73 74 72 69 6e 67 20 69 6e 64 65 78  && [string index
0f00: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 30   [lindex $args 0
0f10: 5d 20 30 5d 21 3d 22 2d 22 7d 20 7b 0a 20 20 20  ] 0]!="-"} {.   
0f20: 20 20 20 6c 61 70 70 65 6e 64 20 61 72 67 73 20     lappend args 
0f30: 2d 6b 65 79 20 7b 78 79 7a 7a 79 7d 0a 20 20 20  -key {xyzzy}.   
0f40: 20 7d 0a 20 20 20 20 75 70 6c 65 76 65 6c 20 31   }.    uplevel 1
0f50: 20 73 71 6c 69 74 65 5f 6f 72 69 67 20 24 61 72   sqlite_orig $ar
0f60: 67 73 0a 20 20 7d 0a 7d 0a 0a 0a 23 20 43 72 65  gs.  }.}...# Cre
0f70: 61 74 65 20 61 20 74 65 73 74 20 64 61 74 61 62  ate a test datab
0f80: 61 73 65 0a 23 0a 69 66 20 7b 21 5b 69 6e 66 6f  ase.#.if {![info
0f90: 20 65 78 69 73 74 73 20 6e 54 65 73 74 5d 7d 20   exists nTest]} 
0fa0: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 68 75 74  {.  sqlite3_shut
0fb0: 64 6f 77 6e 20 0a 20 20 69 6e 73 74 61 6c 6c 5f  down .  install_
0fc0: 6d 61 6c 6c 6f 63 5f 66 61 75 6c 74 73 69 6d 20  malloc_faultsim 
0fd0: 31 20 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 69  1 .  sqlite3_ini
0fe0: 74 69 61 6c 69 7a 65 0a 7d 0a 63 61 74 63 68 20  tialize.}.catch 
0ff0: 7b 64 62 20 63 6c 6f 73 65 7d 0a 66 69 6c 65 20  {db close}.file 
1000: 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 74 65  delete -force te
1010: 73 74 2e 64 62 0a 66 69 6c 65 20 64 65 6c 65 74  st.db.file delet
1020: 65 20 2d 66 6f 72 63 65 20 74 65 73 74 2e 64 62  e -force test.db
1030: 2d 6a 6f 75 72 6e 61 6c 0a 73 71 6c 69 74 65 33  -journal.sqlite3
1040: 20 64 62 20 2e 2f 74 65 73 74 2e 64 62 0a 73 65   db ./test.db.se
1050: 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33 5f  t ::DB [sqlite3_
1060: 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74  connection_point
1070: 65 72 20 64 62 5d 0a 69 66 20 7b 5b 69 6e 66 6f  er db].if {[info
1080: 20 65 78 69 73 74 73 20 3a 3a 53 45 54 55 50 5f   exists ::SETUP_
1090: 53 51 4c 5d 7d 20 7b 0a 20 20 64 62 20 65 76 61  SQL]} {.  db eva
10a0: 6c 20 24 3a 3a 53 45 54 55 50 5f 53 51 4c 0a 7d  l $::SETUP_SQL.}
10b0: 0a 0a 23 20 41 62 6f 72 74 20 65 61 72 6c 79 20  ..# Abort early 
10c0: 69 66 20 74 68 69 73 20 73 63 72 69 70 74 20 68  if this script h
10d0: 61 73 20 62 65 65 6e 20 72 75 6e 20 62 65 66 6f  as been run befo
10e0: 72 65 2e 0a 23 0a 69 66 20 7b 5b 69 6e 66 6f 20  re..#.if {[info 
10f0: 65 78 69 73 74 73 20 6e 54 65 73 74 5d 7d 20 72  exists nTest]} r
1100: 65 74 75 72 6e 0a 0a 23 20 53 65 74 20 74 68 65  eturn..# Set the
1110: 20 74 65 73 74 20 63 6f 75 6e 74 65 72 73 20 74   test counters t
1120: 6f 20 7a 65 72 6f 0a 23 0a 73 65 74 20 6e 45 72  o zero.#.set nEr
1130: 72 20 30 0a 73 65 74 20 6e 54 65 73 74 20 30 0a  r 0.set nTest 0.
1140: 73 65 74 20 73 6b 69 70 5f 74 65 73 74 20 30 0a  set skip_test 0.
1150: 73 65 74 20 66 61 69 6c 4c 69 73 74 20 7b 7d 0a  set failList {}.
1160: 73 65 74 20 6f 6d 69 74 4c 69 73 74 20 7b 7d 0a  set omitList {}.
1170: 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74  if {![info exist
1180: 73 20 73 70 65 65 64 54 65 73 74 5d 7d 20 7b 0a  s speedTest]} {.
1190: 20 20 73 65 74 20 73 70 65 65 64 54 65 73 74 20    set speedTest 
11a0: 30 0a 7d 0a 0a 23 20 52 65 63 6f 72 64 20 74 68  0.}..# Record th
11b0: 65 20 66 61 63 74 20 74 68 61 74 20 61 20 73 65  e fact that a se
11c0: 71 75 65 6e 63 65 20 6f 66 20 74 65 73 74 73 20  quence of tests 
11d0: 77 65 72 65 20 6f 6d 69 74 74 65 64 2e 0a 23 0a  were omitted..#.
11e0: 70 72 6f 63 20 6f 6d 69 74 5f 74 65 73 74 20 7b  proc omit_test {
11f0: 6e 61 6d 65 20 72 65 61 73 6f 6e 7d 20 7b 0a 20  name reason} {. 
1200: 20 67 6c 6f 62 61 6c 20 6f 6d 69 74 4c 69 73 74   global omitList
1210: 0a 20 20 6c 61 70 70 65 6e 64 20 6f 6d 69 74 4c  .  lappend omitL
1220: 69 73 74 20 5b 6c 69 73 74 20 24 6e 61 6d 65 20  ist [list $name 
1230: 24 72 65 61 73 6f 6e 5d 0a 7d 0a 0a 23 20 49 6e  $reason].}..# In
1240: 76 6f 6b 65 20 74 68 65 20 64 6f 5f 74 65 73 74  voke the do_test
1250: 20 70 72 6f 63 65 64 75 72 65 20 74 6f 20 72 75   procedure to ru
1260: 6e 20 61 20 73 69 6e 67 6c 65 20 74 65 73 74 20  n a single test 
1270: 0a 23 0a 70 72 6f 63 20 64 6f 5f 74 65 73 74 20  .#.proc do_test 
1280: 7b 6e 61 6d 65 20 63 6d 64 20 65 78 70 65 63 74  {name cmd expect
1290: 65 64 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 61  ed} {.  global a
12a0: 72 67 76 20 6e 45 72 72 20 6e 54 65 73 74 20 73  rgv nErr nTest s
12b0: 6b 69 70 5f 74 65 73 74 20 6d 61 78 45 72 72 0a  kip_test maxErr.
12c0: 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62    sqlite3_memdeb
12d0: 75 67 5f 73 65 74 74 69 74 6c 65 20 24 6e 61 6d  ug_settitle $nam
12e0: 65 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78  e.  if {[info ex
12f0: 69 73 74 73 20 3a 3a 74 65 73 74 65 72 5f 64 6f  ists ::tester_do
1300: 5f 62 69 6e 61 72 79 6c 6f 67 5d 7d 20 7b 0a 20  _binarylog]} {. 
1310: 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 73 74 76     sqlite3_instv
1320: 66 73 20 6d 61 72 6b 65 72 20 62 69 6e 61 72 79  fs marker binary
1330: 6c 6f 67 20 22 53 74 61 72 74 20 6f 66 20 24 6e  log "Start of $n
1340: 61 6d 65 22 0a 20 20 7d 0a 20 20 69 66 20 7b 24  ame".  }.  if {$
1350: 73 6b 69 70 5f 74 65 73 74 7d 20 7b 0a 20 20 20  skip_test} {.   
1360: 20 73 65 74 20 73 6b 69 70 5f 74 65 73 74 20 30   set skip_test 0
1370: 0a 20 20 20 20 72 65 74 75 72 6e 0a 20 20 7d 0a  .    return.  }.
1380: 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24    if {[llength $
1390: 61 72 67 76 5d 3d 3d 30 7d 20 7b 20 0a 20 20 20  argv]==0} { .   
13a0: 20 73 65 74 20 67 6f 20 31 0a 20 20 7d 20 65 6c   set go 1.  } el
13b0: 73 65 20 7b 0a 20 20 20 20 73 65 74 20 67 6f 20  se {.    set go 
13c0: 30 0a 20 20 20 20 66 6f 72 65 61 63 68 20 70 61  0.    foreach pa
13d0: 74 74 65 72 6e 20 24 61 72 67 76 20 7b 0a 20 20  ttern $argv {.  
13e0: 20 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20      if {[string 
13f0: 6d 61 74 63 68 20 24 70 61 74 74 65 72 6e 20 24  match $pattern $
1400: 6e 61 6d 65 5d 7d 20 7b 0a 20 20 20 20 20 20 20  name]} {.       
1410: 20 73 65 74 20 67 6f 20 31 0a 20 20 20 20 20 20   set go 1.      
1420: 20 20 62 72 65 61 6b 0a 20 20 20 20 20 20 7d 0a    break.      }.
1430: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 20 7b      }.  }.  if {
1440: 21 24 67 6f 7d 20 72 65 74 75 72 6e 0a 20 20 69  !$go} return.  i
1450: 6e 63 72 20 6e 54 65 73 74 0a 20 20 70 75 74 73  ncr nTest.  puts
1460: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 6e 61 6d   -nonewline $nam
1470: 65 2e 2e 2e 0a 20 20 66 6c 75 73 68 20 73 74 64  e....  flush std
1480: 6f 75 74 0a 20 20 69 66 20 7b 5b 63 61 74 63 68  out.  if {[catch
1490: 20 7b 75 70 6c 65 76 65 6c 20 23 30 20 22 24 63   {uplevel #0 "$c
14a0: 6d 64 3b 5c 6e 22 7d 20 72 65 73 75 6c 74 5d 7d  md;\n"} result]}
14b0: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 5c 6e 45   {.    puts "\nE
14c0: 72 72 6f 72 3a 20 24 72 65 73 75 6c 74 22 0a 20  rror: $result". 
14d0: 20 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20 20     incr nErr.   
14e0: 20 6c 61 70 70 65 6e 64 20 3a 3a 66 61 69 6c 4c   lappend ::failL
14f0: 69 73 74 20 24 6e 61 6d 65 0a 20 20 20 20 69 66  ist $name.    if
1500: 20 7b 24 6e 45 72 72 3e 24 6d 61 78 45 72 72 7d   {$nErr>$maxErr}
1510: 20 7b 70 75 74 73 20 22 2a 2a 2a 20 47 69 76 69   {puts "*** Givi
1520: 6e 67 20 75 70 2e 2e 2e 22 3b 20 66 69 6e 61 6c  ng up..."; final
1530: 69 7a 65 5f 74 65 73 74 69 6e 67 7d 0a 20 20 7d  ize_testing}.  }
1540: 20 65 6c 73 65 69 66 20 7b 5b 73 74 72 69 6e 67   elseif {[string
1550: 20 63 6f 6d 70 61 72 65 20 24 72 65 73 75 6c 74   compare $result
1560: 20 24 65 78 70 65 63 74 65 64 5d 7d 20 7b 0a 20   $expected]} {. 
1570: 20 20 20 70 75 74 73 20 22 5c 6e 45 78 70 65 63     puts "\nExpec
1580: 74 65 64 3a 20 5c 5b 24 65 78 70 65 63 74 65 64  ted: \[$expected
1590: 5c 5d 5c 6e 20 20 20 20 20 47 6f 74 3a 20 5c 5b  \]\n     Got: \[
15a0: 24 72 65 73 75 6c 74 5c 5d 22 0a 20 20 20 20 69  $result\]".    i
15b0: 6e 63 72 20 6e 45 72 72 0a 20 20 20 20 6c 61 70  ncr nErr.    lap
15c0: 70 65 6e 64 20 3a 3a 66 61 69 6c 4c 69 73 74 20  pend ::failList 
15d0: 24 6e 61 6d 65 0a 20 20 20 20 69 66 20 7b 24 6e  $name.    if {$n
15e0: 45 72 72 3e 3d 24 6d 61 78 45 72 72 7d 20 7b 70  Err>=$maxErr} {p
15f0: 75 74 73 20 22 2a 2a 2a 20 47 69 76 69 6e 67 20  uts "*** Giving 
1600: 75 70 2e 2e 2e 22 3b 20 66 69 6e 61 6c 69 7a 65  up..."; finalize
1610: 5f 74 65 73 74 69 6e 67 7d 0a 20 20 7d 20 65 6c  _testing}.  } el
1620: 73 65 20 7b 0a 20 20 20 20 70 75 74 73 20 22 20  se {.    puts " 
1630: 4f 6b 22 0a 20 20 7d 0a 20 20 66 6c 75 73 68 20  Ok".  }.  flush 
1640: 73 74 64 6f 75 74 0a 20 20 69 66 20 7b 5b 69 6e  stdout.  if {[in
1650: 66 6f 20 65 78 69 73 74 73 20 3a 3a 74 65 73 74  fo exists ::test
1660: 65 72 5f 64 6f 5f 62 69 6e 61 72 79 6c 6f 67 5d  er_do_binarylog]
1670: 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  } {.    sqlite3_
1680: 69 6e 73 74 76 66 73 20 6d 61 72 6b 65 72 20 62  instvfs marker b
1690: 69 6e 61 72 79 6c 6f 67 20 22 45 6e 64 20 6f 66  inarylog "End of
16a0: 20 24 6e 61 6d 65 22 0a 20 20 7d 0a 7d 0a 0a 23   $name".  }.}..#
16b0: 20 52 75 6e 20 61 6e 20 53 51 4c 20 73 63 72 69   Run an SQL scri
16c0: 70 74 2e 20 20 0a 23 20 52 65 74 75 72 6e 20 74  pt.  .# Return t
16d0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 6d 69 63  he number of mic
16e0: 72 6f 73 65 63 6f 6e 64 73 20 70 65 72 20 73 74  roseconds per st
16f0: 61 74 65 6d 65 6e 74 2e 0a 23 0a 70 72 6f 63 20  atement..#.proc 
1700: 73 70 65 65 64 5f 74 72 69 61 6c 20 7b 6e 61 6d  speed_trial {nam
1710: 65 20 6e 75 6d 73 74 6d 74 20 75 6e 69 74 73 20  e numstmt units 
1720: 73 71 6c 7d 20 7b 0a 20 20 70 75 74 73 20 2d 6e  sql} {.  puts -n
1730: 6f 6e 65 77 6c 69 6e 65 20 5b 66 6f 72 6d 61 74  onewline [format
1740: 20 7b 25 2d 32 31 2e 32 31 73 20 7d 20 24 6e 61   {%-21.21s } $na
1750: 6d 65 2e 2e 2e 5d 0a 20 20 66 6c 75 73 68 20 73  me...].  flush s
1760: 74 64 6f 75 74 0a 20 20 73 65 74 20 73 70 65 65  tdout.  set spee
1770: 64 20 5b 74 69 6d 65 20 7b 73 71 6c 69 74 65 33  d [time {sqlite3
1780: 5f 65 78 65 63 5f 6e 72 20 64 62 20 24 73 71 6c  _exec_nr db $sql
1790: 7d 5d 0a 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e  }].  set tm [lin
17a0: 64 65 78 20 24 73 70 65 65 64 20 30 5d 0a 20 20  dex $speed 0].  
17b0: 69 66 20 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b 0a  if {$tm == 0} {.
17c0: 20 20 20 20 73 65 74 20 72 61 74 65 20 5b 66 6f      set rate [fo
17d0: 72 6d 61 74 20 25 32 30 73 20 22 6d 61 6e 79 22  rmat %20s "many"
17e0: 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20  ].  } else {.   
17f0: 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61   set rate [forma
1800: 74 20 25 32 30 2e 35 66 20 5b 65 78 70 72 20 7b  t %20.5f [expr {
1810: 31 30 30 30 30 30 30 2e 30 2a 24 6e 75 6d 73 74  1000000.0*$numst
1820: 6d 74 2f 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20 20  mt/$tm}]].  }.  
1830: 73 65 74 20 75 32 20 24 75 6e 69 74 73 2f 73 0a  set u2 $units/s.
1840: 20 20 70 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b    puts [format {
1850: 25 31 32 64 20 75 53 20 25 73 20 25 73 7d 20 24  %12d uS %s %s} $
1860: 74 6d 20 24 72 61 74 65 20 24 75 32 5d 0a 20 20  tm $rate $u2].  
1870: 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d  global total_tim
1880: 65 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 74 69  e.  set total_ti
1890: 6d 65 20 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c  me [expr {$total
18a0: 5f 74 69 6d 65 2b 24 74 6d 7d 5d 0a 7d 0a 70 72  _time+$tm}].}.pr
18b0: 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c 5f 74  oc speed_trial_t
18c0: 63 6c 20 7b 6e 61 6d 65 20 6e 75 6d 73 74 6d 74  cl {name numstmt
18d0: 20 75 6e 69 74 73 20 73 63 72 69 70 74 7d 20 7b   units script} {
18e0: 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69  .  puts -nonewli
18f0: 6e 65 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31  ne [format {%-21
1900: 2e 32 31 73 20 7d 20 24 6e 61 6d 65 2e 2e 2e 5d  .21s } $name...]
1910: 0a 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a  .  flush stdout.
1920: 20 20 73 65 74 20 73 70 65 65 64 20 5b 74 69 6d    set speed [tim
1930: 65 20 7b 65 76 61 6c 20 24 73 63 72 69 70 74 7d  e {eval $script}
1940: 5d 0a 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64  ].  set tm [lind
1950: 65 78 20 24 73 70 65 65 64 20 30 5d 0a 20 20 69  ex $speed 0].  i
1960: 66 20 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20  f {$tm == 0} {. 
1970: 20 20 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72     set rate [for
1980: 6d 61 74 20 25 32 30 73 20 22 6d 61 6e 79 22 5d  mat %20s "many"]
1990: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
19a0: 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74  set rate [format
19b0: 20 25 32 30 2e 35 66 20 5b 65 78 70 72 20 7b 31   %20.5f [expr {1
19c0: 30 30 30 30 30 30 2e 30 2a 24 6e 75 6d 73 74 6d  000000.0*$numstm
19d0: 74 2f 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73  t/$tm}]].  }.  s
19e0: 65 74 20 75 32 20 24 75 6e 69 74 73 2f 73 0a 20  et u2 $units/s. 
19f0: 20 70 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25   puts [format {%
1a00: 31 32 64 20 75 53 20 25 73 20 25 73 7d 20 24 74  12d uS %s %s} $t
1a10: 6d 20 24 72 61 74 65 20 24 75 32 5d 0a 20 20 67  m $rate $u2].  g
1a20: 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65  lobal total_time
1a30: 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d  .  set total_tim
1a40: 65 20 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f  e [expr {$total_
1a50: 74 69 6d 65 2b 24 74 6d 7d 5d 0a 7d 0a 70 72 6f  time+$tm}].}.pro
1a60: 63 20 73 70 65 65 64 5f 74 72 69 61 6c 5f 69 6e  c speed_trial_in
1a70: 69 74 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c  it {name} {.  gl
1a80: 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a  obal total_time.
1a90: 20 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65    set total_time
1aa0: 20 30 0a 7d 0a 70 72 6f 63 20 73 70 65 65 64 5f   0.}.proc speed_
1ab0: 74 72 69 61 6c 5f 73 75 6d 6d 61 72 79 20 7b 6e  trial_summary {n
1ac0: 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20  ame} {.  global 
1ad0: 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 70 75 74  total_time.  put
1ae0: 73 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31 2e  s [format {%-21.
1af0: 32 31 73 20 25 31 32 64 20 75 53 20 54 4f 54 41  21s %12d uS TOTA
1b00: 4c 7d 20 24 6e 61 6d 65 20 24 74 6f 74 61 6c 5f  L} $name $total_
1b10: 74 69 6d 65 5d 0a 7d 0a 0a 23 20 52 75 6e 20 74  time].}..# Run t
1b20: 68 69 73 20 72 6f 75 74 69 6e 65 20 6c 61 73 74  his routine last
1b30: 0a 23 0a 70 72 6f 63 20 66 69 6e 69 73 68 5f 74  .#.proc finish_t
1b40: 65 73 74 20 7b 7d 20 7b 0a 20 20 66 69 6e 61 6c  est {} {.  final
1b50: 69 7a 65 5f 74 65 73 74 69 6e 67 0a 7d 0a 70 72  ize_testing.}.pr
1b60: 6f 63 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74  oc finalize_test
1b70: 69 6e 67 20 7b 7d 20 7b 0a 20 20 67 6c 6f 62 61  ing {} {.  globa
1b80: 6c 20 6e 54 65 73 74 20 6e 45 72 72 20 73 71 6c  l nTest nErr sql
1b90: 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f  ite_open_file_co
1ba0: 75 6e 74 20 6f 6d 69 74 4c 69 73 74 0a 0a 20 20  unt omitList..  
1bb0: 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d  catch {db close}
1bc0: 0a 20 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c  .  catch {db2 cl
1bd0: 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62  ose}.  catch {db
1be0: 33 20 63 6c 6f 73 65 7d 0a 0a 20 20 76 66 73 5f  3 close}..  vfs_
1bf0: 75 6e 6c 69 6e 6b 5f 74 65 73 74 0a 20 20 73 71  unlink_test.  sq
1c00: 6c 69 74 65 33 20 64 62 20 7b 7d 0a 20 20 23 20  lite3 db {}.  # 
1c10: 73 71 6c 69 74 65 33 5f 63 6c 65 61 72 5f 74 73  sqlite3_clear_ts
1c20: 64 5f 6d 65 6d 64 65 62 75 67 0a 20 20 64 62 20  d_memdebug.  db 
1c30: 63 6c 6f 73 65 0a 20 20 73 71 6c 69 74 65 33 5f  close.  sqlite3_
1c40: 72 65 73 65 74 5f 61 75 74 6f 5f 65 78 74 65 6e  reset_auto_exten
1c50: 73 69 6f 6e 0a 20 20 73 65 74 20 68 65 61 70 6c  sion.  set heapl
1c60: 69 6d 69 74 20 5b 73 71 6c 69 74 65 33 5f 73 6f  imit [sqlite3_so
1c70: 66 74 5f 68 65 61 70 5f 6c 69 6d 69 74 5d 0a 20  ft_heap_limit]. 
1c80: 20 69 66 20 7b 24 68 65 61 70 6c 69 6d 69 74 21   if {$heaplimit!
1c90: 3d 24 3a 3a 73 6f 66 74 5f 6c 69 6d 69 74 7d 20  =$::soft_limit} 
1ca0: 7b 0a 20 20 20 20 70 75 74 73 20 22 73 6f 66 74  {.    puts "soft
1cb0: 2d 68 65 61 70 2d 6c 69 6d 69 74 20 63 68 61 6e  -heap-limit chan
1cc0: 67 65 64 20 62 79 20 74 68 69 73 20 73 63 72 69  ged by this scri
1cd0: 70 74 5c 0a 20 20 20 20 20 20 20 20 20 20 66 72  pt\.          fr
1ce0: 6f 6d 20 24 3a 3a 73 6f 66 74 5f 6c 69 6d 69 74  om $::soft_limit
1cf0: 20 74 6f 20 24 68 65 61 70 6c 69 6d 69 74 22 0a   to $heaplimit".
1d00: 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 68 65 61    } elseif {$hea
1d10: 70 6c 69 6d 69 74 21 3d 22 22 20 26 26 20 24 68  plimit!="" && $h
1d20: 65 61 70 6c 69 6d 69 74 3e 30 7d 20 7b 0a 20 20  eaplimit>0} {.  
1d30: 20 20 70 75 74 73 20 22 73 6f 66 74 2d 68 65 61    puts "soft-hea
1d40: 70 2d 6c 69 6d 69 74 20 73 65 74 20 74 6f 20 24  p-limit set to $
1d50: 68 65 61 70 6c 69 6d 69 74 22 0a 20 20 7d 0a 20  heaplimit".  }. 
1d60: 20 73 71 6c 69 74 65 33 5f 73 6f 66 74 5f 68 65   sqlite3_soft_he
1d70: 61 70 5f 6c 69 6d 69 74 20 30 0a 20 20 69 6e 63  ap_limit 0.  inc
1d80: 72 20 6e 54 65 73 74 0a 20 20 70 75 74 73 20 22  r nTest.  puts "
1d90: 24 6e 45 72 72 20 65 72 72 6f 72 73 20 6f 75 74  $nErr errors out
1da0: 20 6f 66 20 24 6e 54 65 73 74 20 74 65 73 74 73   of $nTest tests
1db0: 22 0a 20 20 69 66 20 7b 24 6e 45 72 72 3e 30 7d  ".  if {$nErr>0}
1dc0: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 46 61 69   {.    puts "Fai
1dd0: 6c 75 72 65 73 20 6f 6e 20 74 68 65 73 65 20 74  lures on these t
1de0: 65 73 74 73 3a 20 24 3a 3a 66 61 69 6c 4c 69 73  ests: $::failLis
1df0: 74 22 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 6c 6c  t".  }.  if {[ll
1e00: 65 6e 67 74 68 20 24 6f 6d 69 74 4c 69 73 74 5d  ength $omitList]
1e10: 3e 30 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22  >0} {.    puts "
1e20: 4f 6d 69 74 74 65 64 20 74 65 73 74 20 63 61 73  Omitted test cas
1e30: 65 73 3a 22 0a 20 20 20 20 73 65 74 20 70 72 65  es:".    set pre
1e40: 63 20 7b 7d 0a 20 20 20 20 66 6f 72 65 61 63 68  c {}.    foreach
1e50: 20 7b 72 65 63 7d 20 5b 6c 73 6f 72 74 20 24 6f   {rec} [lsort $o
1e60: 6d 69 74 4c 69 73 74 5d 20 7b 0a 20 20 20 20 20  mitList] {.     
1e70: 20 69 66 20 7b 24 72 65 63 3d 3d 24 70 72 65 63   if {$rec==$prec
1e80: 7d 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20  } continue.     
1e90: 20 73 65 74 20 70 72 65 63 20 24 72 65 63 0a 20   set prec $rec. 
1ea0: 20 20 20 20 20 70 75 74 73 20 5b 66 6f 72 6d 61       puts [forma
1eb0: 74 20 7b 20 20 25 2d 31 32 73 20 25 73 7d 20 5b  t {  %-12s %s} [
1ec0: 6c 69 6e 64 65 78 20 24 72 65 63 20 30 5d 20 5b  lindex $rec 0] [
1ed0: 6c 69 6e 64 65 78 20 24 72 65 63 20 31 5d 5d 0a  lindex $rec 1]].
1ee0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 20 7b      }.  }.  if {
1ef0: 24 6e 45 72 72 3e 30 20 26 26 20 21 5b 77 6f 72  $nErr>0 && ![wor
1f00: 6b 69 6e 67 5f 36 34 62 69 74 5f 69 6e 74 5d 7d  king_64bit_int]}
1f10: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 2a 2a 2a   {.    puts "***
1f20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1f30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1f40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1f50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22  ***************"
1f60: 0a 20 20 20 20 70 75 74 73 20 22 4e 2e 42 2e 3a  .    puts "N.B.:
1f70: 20 20 54 68 65 20 76 65 72 73 69 6f 6e 20 6f 66    The version of
1f80: 20 54 43 4c 20 74 68 61 74 20 79 6f 75 20 75 73   TCL that you us
1f90: 65 64 20 74 6f 20 62 75 69 6c 64 20 74 68 69 73  ed to build this
1fa0: 20 74 65 73 74 20 68 61 72 6e 65 73 73 22 0a 20   test harness". 
1fb0: 20 20 20 70 75 74 73 20 22 69 73 20 64 65 66 65     puts "is defe
1fc0: 63 74 69 76 65 20 69 6e 20 74 68 61 74 20 69 74  ctive in that it
1fd0: 20 64 6f 65 73 20 6e 6f 74 20 73 75 70 70 6f 72   does not suppor
1fe0: 74 20 36 34 2d 62 69 74 20 69 6e 74 65 67 65 72  t 64-bit integer
1ff0: 73 2e 20 20 53 6f 6d 65 20 6f 72 22 0a 20 20 20  s.  Some or".   
2000: 20 70 75 74 73 20 22 61 6c 6c 20 6f 66 20 74 68   puts "all of th
2010: 65 20 74 65 73 74 20 66 61 69 6c 75 72 65 73 20  e test failures 
2020: 61 62 6f 76 65 20 6d 69 67 68 74 20 62 65 20 61  above might be a
2030: 20 72 65 73 75 6c 74 20 66 72 6f 6d 20 74 68 69   result from thi
2040: 73 20 64 65 66 65 63 74 22 0a 20 20 20 20 70 75  s defect".    pu
2050: 74 73 20 22 69 6e 20 79 6f 75 72 20 54 43 4c 20  ts "in your TCL 
2060: 62 75 69 6c 64 2e 22 0a 20 20 20 20 70 75 74 73  build.".    puts
2070: 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   "**************
2080: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2090: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20b0: 2a 2a 2a 2a 22 0a 20 20 7d 0a 20 20 69 66 20 7b  ****".  }.  if {
20c0: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 74  [info exists ::t
20d0: 65 73 74 65 72 5f 64 6f 5f 62 69 6e 61 72 79 6c  ester_do_binaryl
20e0: 6f 67 5d 7d 20 7b 0a 20 20 20 20 73 71 6c 69 74  og]} {.    sqlit
20f0: 65 33 5f 69 6e 73 74 76 66 73 20 64 65 73 74 72  e3_instvfs destr
2100: 6f 79 20 62 69 6e 61 72 79 6c 6f 67 0a 20 20 7d  oy binarylog.  }
2110: 0a 20 20 69 66 20 7b 24 73 71 6c 69 74 65 5f 6f  .  if {$sqlite_o
2120: 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 7d 20  pen_file_count} 
2130: 7b 0a 20 20 20 20 70 75 74 73 20 22 24 73 71 6c  {.    puts "$sql
2140: 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f  ite_open_file_co
2150: 75 6e 74 20 66 69 6c 65 73 20 77 65 72 65 20 6c  unt files were l
2160: 65 66 74 20 6f 70 65 6e 22 0a 20 20 20 20 69 6e  eft open".    in
2170: 63 72 20 6e 45 72 72 0a 20 20 7d 0a 20 20 69 66  cr nErr.  }.  if
2180: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
2190: 3a 74 65 73 74 65 72 5f 64 6f 5f 6f 73 74 72 61  :tester_do_ostra
21a0: 63 65 5d 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  ce]} {.    puts 
21b0: 22 57 72 69 74 69 6e 67 20 6f 73 74 72 61 63 65  "Writing ostrace
21c0: 2e 73 71 6c 2e 2e 2e 22 0a 20 20 20 20 73 65 74  .sql...".    set
21d0: 20 66 64 20 24 3a 3a 6f 73 74 72 61 63 65 5f 66   fd $::ostrace_f
21e0: 64 0a 0a 20 20 20 20 70 75 74 73 20 2d 6e 6f 6e  d..    puts -non
21f0: 65 77 6c 69 6e 65 20 24 66 64 20 22 43 52 45 41  ewline $fd "CREA
2200: 54 45 20 54 41 42 4c 45 20 6f 73 73 75 6d 6d 61  TE TABLE ossumma
2210: 72 79 22 0a 20 20 20 20 70 75 74 73 20 24 66 64  ry".    puts $fd
2220: 20 22 28 6d 65 74 68 6f 64 20 54 45 58 54 2c 20   "(method TEXT, 
2230: 63 6c 69 63 6b 73 20 49 4e 54 45 47 45 52 2c 20  clicks INTEGER, 
2240: 63 6f 75 6e 74 20 49 4e 54 45 47 45 52 29 3b 22  count INTEGER);"
2250: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 72 6f 77  .    foreach row
2260: 20 5b 73 71 6c 69 74 65 33 5f 69 6e 73 74 76 66   [sqlite3_instvf
2270: 73 20 72 65 70 6f 72 74 20 6f 73 74 72 61 63 65  s report ostrace
2280: 5d 20 7b 0a 20 20 20 20 20 20 66 6f 72 65 61 63  ] {.      foreac
2290: 68 20 7b 6d 65 74 68 6f 64 20 63 6f 75 6e 74 20  h {method count 
22a0: 63 6c 69 63 6b 73 7d 20 24 72 6f 77 20 62 72 65  clicks} $row bre
22b0: 61 6b 0a 20 20 20 20 20 20 70 75 74 73 20 24 66  ak.      puts $f
22c0: 64 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 6f  d "INSERT INTO o
22d0: 73 73 75 6d 6d 61 72 79 20 56 41 4c 55 45 53 28  ssummary VALUES(
22e0: 27 24 6d 65 74 68 6f 64 27 2c 20 24 63 6c 69 63  '$method', $clic
22f0: 6b 73 2c 20 24 63 6f 75 6e 74 29 3b 22 0a 20 20  ks, $count);".  
2300: 20 20 7d 0a 20 20 20 20 70 75 74 73 20 24 66 64    }.    puts $fd
2310: 20 22 43 4f 4d 4d 49 54 3b 22 0a 20 20 20 20 63   "COMMIT;".    c
2320: 6c 6f 73 65 20 24 66 64 0a 20 20 20 20 73 71 6c  lose $fd.    sql
2330: 69 74 65 33 5f 69 6e 73 74 76 66 73 20 64 65 73  ite3_instvfs des
2340: 74 72 6f 79 20 6f 73 74 72 61 63 65 0a 20 20 7d  troy ostrace.  }
2350: 0a 20 20 69 66 20 7b 5b 73 71 6c 69 74 65 33 5f  .  if {[sqlite3_
2360: 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 3e 30 7d 20  memory_used]>0} 
2370: 7b 0a 20 20 20 20 70 75 74 73 20 22 55 6e 66 72  {.    puts "Unfr
2380: 65 65 64 20 6d 65 6d 6f 72 79 3a 20 5b 73 71 6c  eed memory: [sql
2390: 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64  ite3_memory_used
23a0: 5d 20 62 79 74 65 73 22 0a 20 20 20 20 69 6e 63  ] bytes".    inc
23b0: 72 20 6e 45 72 72 0a 20 20 20 20 69 66 63 61 70  r nErr.    ifcap
23c0: 61 62 6c 65 20 6d 65 6d 64 65 62 75 67 7c 7c 6d  able memdebug||m
23d0: 65 6d 35 7c 7c 28 6d 65 6d 33 26 26 64 65 62 75  em5||(mem3&&debu
23e0: 67 29 20 7b 0a 20 20 20 20 20 20 70 75 74 73 20  g) {.      puts 
23f0: 22 57 72 69 74 69 6e 67 20 75 6e 66 72 65 65 64  "Writing unfreed
2400: 20 6d 65 6d 6f 72 79 20 6c 6f 67 20 74 6f 20 5c   memory log to \
2410: 22 2e 2f 6d 65 6d 6c 65 61 6b 2e 74 78 74 5c 22  "./memleak.txt\"
2420: 22 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ".      sqlite3_
2430: 6d 65 6d 64 65 62 75 67 5f 64 75 6d 70 20 2e 2f  memdebug_dump ./
2440: 6d 65 6d 6c 65 61 6b 2e 74 78 74 0a 20 20 20 20  memleak.txt.    
2450: 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20  }.  } else {.   
2460: 20 70 75 74 73 20 22 41 6c 6c 20 6d 65 6d 6f 72   puts "All memor
2470: 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 66 72  y allocations fr
2480: 65 65 64 20 2d 20 6e 6f 20 6c 65 61 6b 73 22 0a  eed - no leaks".
2490: 20 20 20 20 69 66 63 61 70 61 62 6c 65 20 6d 65      ifcapable me
24a0: 6d 64 65 62 75 67 7c 7c 6d 65 6d 35 20 7b 0a 20  mdebug||mem5 {. 
24b0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d       sqlite3_mem
24c0: 64 65 62 75 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d  debug_dump ./mem
24d0: 75 73 61 67 65 2e 74 78 74 0a 20 20 20 20 7d 0a  usage.txt.    }.
24e0: 20 20 7d 0a 20 20 73 68 6f 77 5f 6d 65 6d 73 74    }.  show_memst
24f0: 61 74 73 0a 20 20 70 75 74 73 20 22 4d 61 78 69  ats.  puts "Maxi
2500: 6d 75 6d 20 6d 65 6d 6f 72 79 20 75 73 61 67 65  mum memory usage
2510: 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72  : [sqlite3_memor
2520: 79 5f 68 69 67 68 77 61 74 65 72 20 31 5d 20 62  y_highwater 1] b
2530: 79 74 65 73 22 0a 20 20 70 75 74 73 20 22 43 75  ytes".  puts "Cu
2540: 72 72 65 6e 74 20 6d 65 6d 6f 72 79 20 75 73 61  rrent memory usa
2550: 67 65 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d  ge: [sqlite3_mem
2560: 6f 72 79 5f 68 69 67 68 77 61 74 65 72 5d 20 62  ory_highwater] b
2570: 79 74 65 73 22 0a 20 20 69 66 20 7b 5b 69 6e 66  ytes".  if {[inf
2580: 6f 20 63 6f 6d 6d 61 6e 64 73 20 73 71 6c 69 74  o commands sqlit
2590: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6d 61 6c 6c  e3_memdebug_mall
25a0: 6f 63 5f 63 6f 75 6e 74 5d 20 6e 65 20 22 22 7d  oc_count] ne ""}
25b0: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 4e 75 6d   {.    puts "Num
25c0: 62 65 72 20 6f 66 20 6d 61 6c 6c 6f 63 28 29 20  ber of malloc() 
25d0: 20 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64   : [sqlite3_memd
25e0: 65 62 75 67 5f 6d 61 6c 6c 6f 63 5f 63 6f 75 6e  ebug_malloc_coun
25f0: 74 5d 20 63 61 6c 6c 73 22 0a 20 20 7d 0a 20 20  t] calls".  }.  
2600: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
2610: 20 3a 3a 74 65 73 74 65 72 5f 64 6f 5f 6d 61 6c   ::tester_do_mal
2620: 6c 6f 63 74 72 61 63 65 5d 7d 20 7b 0a 20 20 20  loctrace]} {.   
2630: 20 70 75 74 73 20 22 57 72 69 74 69 6e 67 20 6d   puts "Writing m
2640: 61 6c 6c 6f 63 73 2e 73 71 6c 2e 2e 2e 22 0a 20  allocs.sql...". 
2650: 20 20 20 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f     memdebug_log_
2660: 73 71 6c 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  sql.    sqlite3_
2670: 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73 74 6f  memdebug_log sto
2680: 70 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65  p.    sqlite3_me
2690: 6d 64 65 62 75 67 5f 6c 6f 67 20 63 6c 65 61 72  mdebug_log clear
26a0: 0a 0a 20 20 20 20 69 66 20 7b 5b 73 71 6c 69 74  ..    if {[sqlit
26b0: 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 3e  e3_memory_used]>
26c0: 30 7d 20 7b 0a 20 20 20 20 20 20 70 75 74 73 20  0} {.      puts 
26d0: 22 57 72 69 74 69 6e 67 20 6c 65 61 6b 73 2e 73  "Writing leaks.s
26e0: 71 6c 2e 2e 2e 22 0a 20 20 20 20 20 20 73 71 6c  ql...".      sql
26f0: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f  ite3_memdebug_lo
2700: 67 20 73 79 6e 63 0a 20 20 20 20 20 20 6d 65 6d  g sync.      mem
2710: 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c 20 6c 65  debug_log_sql le
2720: 61 6b 73 2e 73 71 6c 0a 20 20 20 20 7d 0a 20 20  aks.sql.    }.  
2730: 7d 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67  }.  foreach f [g
2740: 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  lob -nocomplain 
2750: 74 65 73 74 2e 64 62 2d 2a 2d 6a 6f 75 72 6e 61  test.db-*-journa
2760: 6c 5d 20 7b 0a 20 20 20 20 66 69 6c 65 20 64 65  l] {.    file de
2770: 6c 65 74 65 20 2d 66 6f 72 63 65 20 24 66 0a 20  lete -force $f. 
2780: 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b   }.  foreach f [
2790: 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  glob -nocomplain
27a0: 20 74 65 73 74 2e 64 62 2d 6d 6a 2a 5d 20 7b 0a   test.db-mj*] {.
27b0: 20 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20      file delete 
27c0: 2d 66 6f 72 63 65 20 24 66 0a 20 20 7d 0a 20 20  -force $f.  }.  
27d0: 65 78 69 74 20 5b 65 78 70 72 20 7b 24 6e 45 72  exit [expr {$nEr
27e0: 72 3e 30 7d 5d 0a 7d 0a 0a 23 20 44 69 73 70 6c  r>0}].}..# Displ
27f0: 61 79 20 6d 65 6d 6f 72 79 20 73 74 61 74 69 73  ay memory statis
2800: 74 69 63 73 20 66 6f 72 20 61 6e 61 6c 79 73 69  tics for analysi
2810: 73 20 61 6e 64 20 64 65 62 75 67 67 69 6e 67 20  s and debugging 
2820: 70 75 72 70 6f 73 65 73 2e 0a 23 0a 70 72 6f 63  purposes..#.proc
2830: 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74 73 20 7b   show_memstats {
2840: 7d 20 7b 0a 20 20 73 65 74 20 78 20 5b 73 71 6c  } {.  set x [sql
2850: 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49  ite3_status SQLI
2860: 54 45 5f 53 54 41 54 55 53 5f 4d 45 4d 4f 52 59  TE_STATUS_MEMORY
2870: 5f 55 53 45 44 20 30 5d 0a 20 20 73 65 74 20 76  _USED 0].  set v
2880: 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20  al [format {now 
2890: 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20  %10d  max %10d} 
28a0: 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c  [lindex $x 1] [l
28b0: 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 70  index $x 2]].  p
28c0: 75 74 73 20 22 4d 65 6d 6f 72 79 20 75 73 65 64  uts "Memory used
28d0: 3a 20 20 20 20 20 20 20 20 20 20 24 76 61 6c 22  :          $val"
28e0: 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65  .  set x [sqlite
28f0: 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f  3_status SQLITE_
2900: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
2910: 5f 55 53 45 44 20 30 5d 0a 20 20 73 65 74 20 76  _USED 0].  set v
2920: 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20  al [format {now 
2930: 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20  %10d  max %10d} 
2940: 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c  [lindex $x 1] [l
2950: 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 70  index $x 2]].  p
2960: 75 74 73 20 22 50 61 67 65 2d 63 61 63 68 65 20  uts "Page-cache 
2970: 75 73 65 64 3a 20 20 20 20 20 20 24 76 61 6c 22  used:      $val"
2980: 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65  .  set x [sqlite
2990: 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f  3_status SQLITE_
29a0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
29b0: 5f 4f 56 45 52 46 4c 4f 57 20 30 5d 0a 20 20 73  _OVERFLOW 0].  s
29c0: 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b  et val [format {
29d0: 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25 31  now %10d  max %1
29e0: 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20 31  0d} [lindex $x 1
29f0: 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d  ] [lindex $x 2]]
2a00: 0a 20 20 70 75 74 73 20 22 50 61 67 65 2d 63 61  .  puts "Page-ca
2a10: 63 68 65 20 6f 76 65 72 66 6c 6f 77 3a 20 20 24  che overflow:  $
2a20: 76 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71  val".  set x [sq
2a30: 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c  lite3_status SQL
2a40: 49 54 45 5f 53 54 41 54 55 53 5f 53 43 52 41 54  ITE_STATUS_SCRAT
2a50: 43 48 5f 55 53 45 44 20 30 5d 0a 20 20 73 65 74  CH_USED 0].  set
2a60: 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f   val [format {no
2a70: 77 20 25 31 30 64 20 20 6d 61 78 20 25 31 30 64  w %10d  max %10d
2a80: 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20  } [lindex $x 1] 
2a90: 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20  [lindex $x 2]]. 
2aa0: 20 70 75 74 73 20 22 53 63 72 61 74 63 68 20 6d   puts "Scratch m
2ab0: 65 6d 6f 72 79 20 75 73 65 64 3a 20 20 24 76 61  emory used:  $va
2ac0: 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69  l".  set x [sqli
2ad0: 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54  te3_status SQLIT
2ae0: 45 5f 53 54 41 54 55 53 5f 53 43 52 41 54 43 48  E_STATUS_SCRATCH
2af0: 5f 4f 56 45 52 46 4c 4f 57 20 30 5d 0a 20 20 73  _OVERFLOW 0].  s
2b00: 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b  et val [format {
2b10: 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25 31  now %10d  max %1
2b20: 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20 31  0d} [lindex $x 1
2b30: 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 5d  ] [lindex $x 2]]
2b40: 0a 20 20 70 75 74 73 20 22 53 63 72 61 74 63 68  .  puts "Scratch
2b50: 20 6f 76 65 72 66 6c 6f 77 3a 20 20 20 20 20 24   overflow:     $
2b60: 76 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71  val".  set x [sq
2b70: 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c  lite3_status SQL
2b80: 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c 4f  ITE_STATUS_MALLO
2b90: 43 5f 53 49 5a 45 20 30 5d 0a 20 20 70 75 74 73  C_SIZE 0].  puts
2ba0: 20 22 4d 61 78 69 6d 75 6d 20 61 6c 6c 6f 63 20   "Maximum alloc 
2bb0: 73 69 7a 65 3a 20 20 20 5b 6c 69 6e 64 65 78 20  size:   [lindex 
2bc0: 24 78 20 32 5d 22 0a 7d 0a 0a 23 20 41 20 70 72  $x 2]".}..# A pr
2bd0: 6f 63 65 64 75 72 65 20 74 6f 20 65 78 65 63 75  ocedure to execu
2be0: 74 65 20 53 51 4c 0a 23 0a 70 72 6f 63 20 65 78  te SQL.#.proc ex
2bf0: 65 63 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64  ecsql {sql {db d
2c00: 62 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73 20 22  b}} {.  # puts "
2c10: 53 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20 75 70  SQL = $sql".  up
2c20: 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20  level [list $db 
2c30: 65 76 61 6c 20 24 73 71 6c 5d 0a 7d 0a 0a 23 20  eval $sql].}..# 
2c40: 45 78 65 63 75 74 65 20 53 51 4c 20 61 6e 64 20  Execute SQL and 
2c50: 63 61 74 63 68 20 65 78 63 65 70 74 69 6f 6e 73  catch exceptions
2c60: 2e 0a 23 0a 70 72 6f 63 20 63 61 74 63 68 73 71  ..#.proc catchsq
2c70: 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20  l {sql {db db}} 
2c80: 7b 0a 20 20 23 20 70 75 74 73 20 22 53 51 4c 20  {.  # puts "SQL 
2c90: 3d 20 24 73 71 6c 22 0a 20 20 73 65 74 20 72 20  = $sql".  set r 
2ca0: 5b 63 61 74 63 68 20 7b 24 64 62 20 65 76 61 6c  [catch {$db eval
2cb0: 20 24 73 71 6c 7d 20 6d 73 67 5d 0a 20 20 6c 61   $sql} msg].  la
2cc0: 70 70 65 6e 64 20 72 20 24 6d 73 67 0a 20 20 72  ppend r $msg.  r
2cd0: 65 74 75 72 6e 20 24 72 0a 7d 0a 0a 23 20 44 6f  eturn $r.}..# Do
2ce0: 20 61 6e 20 56 44 42 45 20 63 6f 64 65 20 64 75   an VDBE code du
2cf0: 6d 70 20 6f 6e 20 74 68 65 20 53 51 4c 20 67 69  mp on the SQL gi
2d00: 76 65 6e 0a 23 0a 70 72 6f 63 20 65 78 70 6c 61  ven.#.proc expla
2d10: 69 6e 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d  in {sql {db db}}
2d20: 20 7b 0a 20 20 70 75 74 73 20 22 22 0a 20 20 70   {.  puts "".  p
2d30: 75 74 73 20 22 61 64 64 72 20 20 6f 70 63 6f 64  uts "addr  opcod
2d40: 65 20 20 20 20 20 20 20 20 70 31 20 20 20 20 20  e        p1     
2d50: 20 70 32 20 20 20 20 20 20 70 33 20 20 20 20 20   p2      p3     
2d60: 20 70 34 20 20 20 20 20 20 20 20 20 20 20 20 20   p4             
2d70: 20 20 70 35 20 20 23 22 0a 20 20 70 75 74 73 20    p5  #".  puts 
2d80: 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d  "----  ---------
2d90: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d  ---  ------  ---
2da0: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d  ---  ------  ---
2db0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d  ------------  --
2dc0: 20 20 2d 22 0a 20 20 24 64 62 20 65 76 61 6c 20    -".  $db eval 
2dd0: 22 65 78 70 6c 61 69 6e 20 24 73 71 6c 22 20 7b  "explain $sql" {
2de0: 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 5b 66 6f  } {.    puts [fo
2df0: 72 6d 61 74 20 7b 25 2d 34 64 20 20 25 2d 31 32  rmat {%-4d  %-12
2e00: 2e 31 32 73 20 20 25 2d 36 64 20 20 25 2d 36 64  .12s  %-6d  %-6d
2e10: 20 20 25 2d 36 64 20 20 25 20 2d 31 37 73 20 25    %-6d  % -17s %
2e20: 73 20 20 25 73 7d 20 5c 0a 20 20 20 20 20 20 24  s  %s} \.      $
2e30: 61 64 64 72 20 24 6f 70 63 6f 64 65 20 24 70 31  addr $opcode $p1
2e40: 20 24 70 32 20 24 70 33 20 24 70 34 20 24 70 35   $p2 $p3 $p4 $p5
2e50: 20 24 63 6f 6d 6d 65 6e 74 0a 20 20 20 20 5d 0a   $comment.    ].
2e60: 20 20 7d 0a 7d 0a 0a 23 20 53 68 6f 77 20 74 68    }.}..# Show th
2e70: 65 20 56 44 42 45 20 70 72 6f 67 72 61 6d 20 66  e VDBE program f
2e80: 6f 72 20 61 6e 20 53 51 4c 20 73 74 61 74 65 6d  or an SQL statem
2e90: 65 6e 74 20 62 75 74 20 6f 6d 69 74 20 74 68 65  ent but omit the
2ea0: 20 54 72 61 63 65 0a 23 20 6f 70 63 6f 64 65 20   Trace.# opcode 
2eb0: 61 74 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67  at the beginning
2ec0: 2e 20 20 54 68 69 73 20 70 72 6f 63 65 64 75 72  .  This procedur
2ed0: 65 20 63 61 6e 20 62 65 20 75 73 65 64 20 74 6f  e can be used to
2ee0: 20 70 72 6f 76 65 0a 23 20 74 68 61 74 20 64 69   prove.# that di
2ef0: 66 66 65 72 65 6e 74 20 53 51 4c 20 73 74 61 74  fferent SQL stat
2f00: 65 6d 65 6e 74 73 20 67 65 6e 65 72 61 74 65 20  ements generate 
2f10: 65 78 61 63 74 6c 79 20 74 68 65 20 73 61 6d 65  exactly the same
2f20: 20 56 44 42 45 20 63 6f 64 65 2e 0a 23 0a 70 72   VDBE code..#.pr
2f30: 6f 63 20 65 78 70 6c 61 69 6e 5f 6e 6f 5f 74 72  oc explain_no_tr
2f40: 61 63 65 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 65  ace {sql} {.  se
2f50: 74 20 74 72 20 5b 64 62 20 65 76 61 6c 20 22 45  t tr [db eval "E
2f60: 58 50 4c 41 49 4e 20 24 73 71 6c 22 5d 0a 20 20  XPLAIN $sql"].  
2f70: 72 65 74 75 72 6e 20 5b 6c 72 61 6e 67 65 20 24  return [lrange $
2f80: 74 72 20 37 20 65 6e 64 5d 0a 7d 0a 0a 23 20 41  tr 7 end].}..# A
2f90: 6e 6f 74 68 65 72 20 70 72 6f 63 65 64 75 72 65  nother procedure
2fa0: 20 74 6f 20 65 78 65 63 75 74 65 20 53 51 4c 2e   to execute SQL.
2fb0: 20 20 54 68 69 73 20 6f 6e 65 20 69 6e 63 6c 75    This one inclu
2fc0: 64 65 73 20 74 68 65 20 66 69 65 6c 64 0a 23 20  des the field.# 
2fd0: 6e 61 6d 65 73 20 69 6e 20 74 68 65 20 72 65 74  names in the ret
2fe0: 75 72 6e 65 64 20 6c 69 73 74 2e 0a 23 0a 70 72  urned list..#.pr
2ff0: 6f 63 20 65 78 65 63 73 71 6c 32 20 7b 73 71 6c  oc execsql2 {sql
3000: 7d 20 7b 0a 20 20 73 65 74 20 72 65 73 75 6c 74  } {.  set result
3010: 20 7b 7d 0a 20 20 64 62 20 65 76 61 6c 20 24 73   {}.  db eval $s
3020: 71 6c 20 64 61 74 61 20 7b 0a 20 20 20 20 66 6f  ql data {.    fo
3030: 72 65 61 63 68 20 66 20 24 64 61 74 61 28 2a 29  reach f $data(*)
3040: 20 7b 0a 20 20 20 20 20 20 6c 61 70 70 65 6e 64   {.      lappend
3050: 20 72 65 73 75 6c 74 20 24 66 20 24 64 61 74 61   result $f $data
3060: 28 24 66 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  ($f).    }.  }. 
3070: 20 72 65 74 75 72 6e 20 24 72 65 73 75 6c 74 0a   return $result.
3080: 7d 0a 0a 23 20 55 73 65 20 74 68 65 20 6e 6f 6e  }..# Use the non
3090: 2d 63 61 6c 6c 62 61 63 6b 20 41 50 49 20 74 6f  -callback API to
30a0: 20 65 78 65 63 75 74 65 20 6d 75 6c 74 69 70 6c   execute multipl
30b0: 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 73  e SQL statements
30c0: 0a 23 0a 70 72 6f 63 20 73 74 65 70 73 71 6c 20  .#.proc stepsql 
30d0: 7b 64 62 70 74 72 20 73 71 6c 7d 20 7b 0a 20 20  {dbptr sql} {.  
30e0: 73 65 74 20 73 71 6c 20 5b 73 74 72 69 6e 67 20  set sql [string 
30f0: 74 72 69 6d 20 24 73 71 6c 5d 0a 20 20 73 65 74  trim $sql].  set
3100: 20 72 20 30 0a 20 20 77 68 69 6c 65 20 7b 5b 73   r 0.  while {[s
3110: 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 73 71  tring length $sq
3120: 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20 69 66 20 7b  l]>0} {.    if {
3130: 5b 63 61 74 63 68 20 7b 73 71 6c 69 74 65 33 5f  [catch {sqlite3_
3140: 70 72 65 70 61 72 65 20 24 64 62 70 74 72 20 24  prepare $dbptr $
3150: 73 71 6c 20 2d 31 20 73 71 6c 74 61 69 6c 7d 20  sql -1 sqltail} 
3160: 76 6d 5d 7d 20 7b 0a 20 20 20 20 20 20 72 65 74  vm]} {.      ret
3170: 75 72 6e 20 5b 6c 69 73 74 20 31 20 24 76 6d 5d  urn [list 1 $vm]
3180: 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20 73  .    }.    set s
3190: 71 6c 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20  ql [string trim 
31a0: 24 73 71 6c 74 61 69 6c 5d 0a 23 20 20 20 20 77  $sqltail].#    w
31b0: 68 69 6c 65 20 7b 5b 73 71 6c 69 74 65 5f 73 74  hile {[sqlite_st
31c0: 65 70 20 24 76 6d 20 4e 20 56 41 4c 20 43 4f 4c  ep $vm N VAL COL
31d0: 5d 3d 3d 22 53 51 4c 49 54 45 5f 52 4f 57 22 7d  ]=="SQLITE_ROW"}
31e0: 20 7b 0a 23 20 20 20 20 20 20 66 6f 72 65 61 63   {.#      foreac
31f0: 68 20 76 20 24 56 41 4c 20 7b 6c 61 70 70 65 6e  h v $VAL {lappen
3200: 64 20 72 20 24 76 7d 0a 23 20 20 20 20 7d 0a 20  d r $v}.#    }. 
3210: 20 20 20 77 68 69 6c 65 20 7b 5b 73 71 6c 69 74     while {[sqlit
3220: 65 33 5f 73 74 65 70 20 24 76 6d 5d 3d 3d 22 53  e3_step $vm]=="S
3230: 51 4c 49 54 45 5f 52 4f 57 22 7d 20 7b 0a 20 20  QLITE_ROW"} {.  
3240: 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30      for {set i 0
3250: 7d 20 7b 24 69 3c 5b 73 71 6c 69 74 65 33 5f 64  } {$i<[sqlite3_d
3260: 61 74 61 5f 63 6f 75 6e 74 20 24 76 6d 5d 7d 20  ata_count $vm]} 
3270: 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20  {incr i} {.     
3280: 20 20 20 6c 61 70 70 65 6e 64 20 72 20 5b 73 71     lappend r [sq
3290: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78  lite3_column_tex
32a0: 74 20 24 76 6d 20 24 69 5d 0a 20 20 20 20 20 20  t $vm $i].      
32b0: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b  }.    }.    if {
32c0: 5b 63 61 74 63 68 20 7b 73 71 6c 69 74 65 33 5f  [catch {sqlite3_
32d0: 66 69 6e 61 6c 69 7a 65 20 24 76 6d 7d 20 65 72  finalize $vm} er
32e0: 72 6d 73 67 5d 7d 20 7b 0a 20 20 20 20 20 20 72  rmsg]} {.      r
32f0: 65 74 75 72 6e 20 5b 6c 69 73 74 20 31 20 24 65  eturn [list 1 $e
3300: 72 72 6d 73 67 5d 0a 20 20 20 20 7d 0a 20 20 7d  rrmsg].    }.  }
3310: 0a 20 20 72 65 74 75 72 6e 20 24 72 0a 7d 0a 0a  .  return $r.}..
3320: 23 20 44 65 6c 65 74 65 20 61 20 66 69 6c 65 20  # Delete a file 
3330: 6f 72 20 64 69 72 65 63 74 6f 72 79 0a 23 0a 70  or directory.#.p
3340: 72 6f 63 20 66 6f 72 63 65 64 65 6c 65 74 65 20  roc forcedelete 
3350: 7b 66 69 6c 65 6e 61 6d 65 7d 20 7b 0a 20 20 69  {filename} {.  i
3360: 66 20 7b 5b 63 61 74 63 68 20 7b 66 69 6c 65 20  f {[catch {file 
3370: 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 24 66  delete -force $f
3380: 69 6c 65 6e 61 6d 65 7d 5d 7d 20 7b 0a 20 20 20  ilename}]} {.   
3390: 20 65 78 65 63 20 72 6d 20 2d 72 66 20 24 66 69   exec rm -rf $fi
33a0: 6c 65 6e 61 6d 65 0a 20 20 7d 0a 7d 0a 0a 23 20  lename.  }.}..# 
33b0: 44 6f 20 61 6e 20 69 6e 74 65 67 72 69 74 79 20  Do an integrity 
33c0: 63 68 65 63 6b 20 6f 66 20 74 68 65 20 65 6e 74  check of the ent
33d0: 69 72 65 20 64 61 74 61 62 61 73 65 0a 23 0a 70  ire database.#.p
33e0: 72 6f 63 20 69 6e 74 65 67 72 69 74 79 5f 63 68  roc integrity_ch
33f0: 65 63 6b 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 69  eck {name} {.  i
3400: 66 63 61 70 61 62 6c 65 20 69 6e 74 65 67 72 69  fcapable integri
3410: 74 79 63 6b 20 7b 0a 20 20 20 20 64 6f 5f 74 65  tyck {.    do_te
3420: 73 74 20 24 6e 61 6d 65 20 7b 0a 20 20 20 20 20  st $name {.     
3430: 20 65 78 65 63 73 71 6c 20 7b 50 52 41 47 4d 41   execsql {PRAGMA
3440: 20 69 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b   integrity_check
3450: 7d 0a 20 20 20 20 7d 20 7b 6f 6b 7d 0a 20 20 7d  }.    } {ok}.  }
3460: 0a 7d 0a 0a 70 72 6f 63 20 66 69 78 5f 69 66 63  .}..proc fix_ifc
3470: 61 70 61 62 6c 65 5f 65 78 70 72 20 7b 65 78 70  apable_expr {exp
3480: 72 7d 20 7b 0a 20 20 73 65 74 20 72 65 74 20 22  r} {.  set ret "
3490: 22 0a 20 20 73 65 74 20 73 74 61 74 65 20 30 0a  ".  set state 0.
34a0: 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20    for {set i 0} 
34b0: 7b 24 69 20 3c 20 5b 73 74 72 69 6e 67 20 6c 65  {$i < [string le
34c0: 6e 67 74 68 20 24 65 78 70 72 5d 7d 20 7b 69 6e  ngth $expr]} {in
34d0: 63 72 20 69 7d 20 7b 0a 20 20 20 20 73 65 74 20  cr i} {.    set 
34e0: 63 68 61 72 20 5b 73 74 72 69 6e 67 20 72 61 6e  char [string ran
34f0: 67 65 20 24 65 78 70 72 20 24 69 20 24 69 5d 0a  ge $expr $i $i].
3500: 20 20 20 20 73 65 74 20 6e 65 77 73 74 61 74 65      set newstate
3510: 20 5b 65 78 70 72 20 7b 5b 73 74 72 69 6e 67 20   [expr {[string 
3520: 69 73 20 61 6c 6e 75 6d 20 24 63 68 61 72 5d 20  is alnum $char] 
3530: 7c 7c 20 24 63 68 61 72 20 65 71 20 22 5f 22 7d  || $char eq "_"}
3540: 5d 0a 20 20 20 20 69 66 20 7b 24 6e 65 77 73 74  ].    if {$newst
3550: 61 74 65 20 26 26 20 21 24 73 74 61 74 65 7d 20  ate && !$state} 
3560: 7b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20 72  {.      append r
3570: 65 74 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70  et {$::sqlite_op
3580: 74 69 6f 6e 73 28 7d 0a 20 20 20 20 7d 0a 20 20  tions(}.    }.  
3590: 20 20 69 66 20 7b 21 24 6e 65 77 73 74 61 74 65    if {!$newstate
35a0: 20 26 26 20 24 73 74 61 74 65 7d 20 7b 0a 20 20   && $state} {.  
35b0: 20 20 20 20 61 70 70 65 6e 64 20 72 65 74 20 29      append ret )
35c0: 0a 20 20 20 20 7d 0a 20 20 20 20 61 70 70 65 6e  .    }.    appen
35d0: 64 20 72 65 74 20 24 63 68 61 72 0a 20 20 20 20  d ret $char.    
35e0: 73 65 74 20 73 74 61 74 65 20 24 6e 65 77 73 74  set state $newst
35f0: 61 74 65 0a 20 20 7d 0a 20 20 69 66 20 7b 24 73  ate.  }.  if {$s
3600: 74 61 74 65 7d 20 7b 61 70 70 65 6e 64 20 72 65  tate} {append re
3610: 74 20 29 7d 0a 20 20 72 65 74 75 72 6e 20 24 72  t )}.  return $r
3620: 65 74 0a 7d 0a 0a 23 20 45 76 61 6c 75 61 74 65  et.}..# Evaluate
3630: 20 61 20 62 6f 6f 6c 65 61 6e 20 65 78 70 72 65   a boolean expre
3640: 73 73 69 6f 6e 20 6f 66 20 63 61 70 61 62 69 6c  ssion of capabil
3650: 69 74 69 65 73 2e 20 20 49 66 20 74 72 75 65 2c  ities.  If true,
3660: 20 65 78 65 63 75 74 65 20 74 68 65 0a 23 20 63   execute the.# c
3670: 6f 64 65 2e 20 20 4f 6d 69 74 20 74 68 65 20 63  ode.  Omit the c
3680: 6f 64 65 20 69 66 20 66 61 6c 73 65 2e 0a 23 0a  ode if false..#.
3690: 70 72 6f 63 20 69 66 63 61 70 61 62 6c 65 20 7b  proc ifcapable {
36a0: 65 78 70 72 20 63 6f 64 65 20 7b 65 6c 73 65 20  expr code {else 
36b0: 22 22 7d 20 7b 65 6c 73 65 63 6f 64 65 20 22 22  ""} {elsecode ""
36c0: 7d 7d 20 7b 0a 20 20 23 72 65 67 73 75 62 20 2d  }} {.  #regsub -
36d0: 61 6c 6c 20 7b 5b 61 2d 7a 5f 30 2d 39 5d 2b 7d  all {[a-z_0-9]+}
36e0: 20 24 65 78 70 72 20 7b 24 3a 3a 73 71 6c 69 74   $expr {$::sqlit
36f0: 65 5f 6f 70 74 69 6f 6e 73 28 26 29 7d 20 65 32  e_options(&)} e2
3700: 0a 20 20 73 65 74 20 65 32 20 5b 66 69 78 5f 69  .  set e2 [fix_i
3710: 66 63 61 70 61 62 6c 65 5f 65 78 70 72 20 24 65  fcapable_expr $e
3720: 78 70 72 5d 0a 20 20 69 66 20 28 24 65 32 29 20  xpr].  if ($e2) 
3730: 7b 0a 20 20 20 20 73 65 74 20 63 20 5b 63 61 74  {.    set c [cat
3740: 63 68 20 7b 75 70 6c 65 76 65 6c 20 31 20 24 63  ch {uplevel 1 $c
3750: 6f 64 65 7d 20 72 5d 0a 20 20 7d 20 65 6c 73 65  ode} r].  } else
3760: 20 7b 0a 20 20 20 20 73 65 74 20 63 20 5b 63 61   {.    set c [ca
3770: 74 63 68 20 7b 75 70 6c 65 76 65 6c 20 31 20 24  tch {uplevel 1 $
3780: 65 6c 73 65 63 6f 64 65 7d 20 72 5d 0a 20 20 7d  elsecode} r].  }
3790: 0a 20 20 72 65 74 75 72 6e 20 2d 63 6f 64 65 20  .  return -code 
37a0: 24 63 20 24 72 0a 7d 0a 0a 23 20 54 68 69 73 20  $c $r.}..# This 
37b0: 70 72 6f 63 20 65 78 65 63 73 20 61 20 73 65 70  proc execs a sep
37c0: 65 72 61 74 65 20 70 72 6f 63 65 73 73 20 74 68  erate process th
37d0: 61 74 20 63 72 61 73 68 65 73 20 6d 69 64 77 61  at crashes midwa
37e0: 79 20 74 68 72 6f 75 67 68 20 65 78 65 63 75 74  y through execut
37f0: 69 6e 67 0a 23 20 74 68 65 20 53 51 4c 20 73 63  ing.# the SQL sc
3800: 72 69 70 74 20 24 73 71 6c 20 6f 6e 20 64 61 74  ript $sql on dat
3810: 61 62 61 73 65 20 74 65 73 74 2e 64 62 2e 0a 23  abase test.db..#
3820: 0a 23 20 54 68 65 20 63 72 61 73 68 20 6f 63 63  .# The crash occ
3830: 75 72 73 20 64 75 72 69 6e 67 20 61 20 73 79 6e  urs during a syn
3840: 63 28 29 20 6f 66 20 66 69 6c 65 20 24 63 72 61  c() of file $cra
3850: 73 68 66 69 6c 65 2e 20 57 68 65 6e 20 74 68 65  shfile. When the
3860: 20 63 72 61 73 68 0a 23 20 6f 63 63 75 72 73 20   crash.# occurs 
3870: 61 20 72 61 6e 64 6f 6d 20 73 75 62 73 65 74 20  a random subset 
3880: 6f 66 20 61 6c 6c 20 75 6e 73 79 6e 63 65 64 20  of all unsynced 
3890: 77 72 69 74 65 73 20 6d 61 64 65 20 62 79 20 74  writes made by t
38a0: 68 65 20 70 72 6f 63 65 73 73 20 61 72 65 0a 23  he process are.#
38b0: 20 77 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68   written into th
38c0: 65 20 66 69 6c 65 73 20 6f 6e 20 64 69 73 6b 2e  e files on disk.
38d0: 20 41 72 67 75 6d 65 6e 74 20 24 63 72 61 73 68   Argument $crash
38e0: 64 65 6c 61 79 20 69 6e 64 69 63 61 74 65 73 20  delay indicates 
38f0: 74 68 65 0a 23 20 6e 75 6d 62 65 72 20 6f 66 20  the.# number of 
3900: 66 69 6c 65 20 73 79 6e 63 73 20 74 6f 20 77 61  file syncs to wa
3910: 69 74 20 62 65 66 6f 72 65 20 63 72 61 73 68 69  it before crashi
3920: 6e 67 2e 0a 23 0a 23 20 54 68 65 20 72 65 74 75  ng..#.# The retu
3930: 72 6e 20 76 61 6c 75 65 20 69 73 20 61 20 6c 69  rn value is a li
3940: 73 74 20 6f 66 20 74 77 6f 20 65 6c 65 6d 65 6e  st of two elemen
3950: 74 73 2e 20 54 68 65 20 66 69 72 73 74 20 65 6c  ts. The first el
3960: 65 6d 65 6e 74 20 69 73 20 61 0a 23 20 62 6f 6f  ement is a.# boo
3970: 6c 65 61 6e 2c 20 69 6e 64 69 63 61 74 69 6e 67  lean, indicating
3980: 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f 74 20   whether or not 
3990: 74 68 65 20 70 72 6f 63 65 73 73 20 61 63 74 75  the process actu
39a0: 61 6c 6c 79 20 63 72 61 73 68 65 64 20 6f 72 0a  ally crashed or.
39b0: 23 20 72 65 70 6f 72 74 65 64 20 73 6f 6d 65 20  # reported some 
39c0: 6f 74 68 65 72 20 65 72 72 6f 72 2e 20 54 68 65  other error. The
39d0: 20 73 65 63 6f 6e 64 20 65 6c 65 6d 65 6e 74 20   second element 
39e0: 69 6e 20 74 68 65 20 72 65 74 75 72 6e 65 64 20  in the returned 
39f0: 6c 69 73 74 20 69 73 20 74 68 65 0a 23 20 65 72  list is the.# er
3a00: 72 6f 72 20 6d 65 73 73 61 67 65 2e 20 54 68 69  ror message. Thi
3a10: 73 20 69 73 20 22 63 68 69 6c 64 20 70 72 6f 63  s is "child proc
3a20: 65 73 73 20 65 78 69 74 65 64 20 61 62 6e 6f 72  ess exited abnor
3a30: 6d 61 6c 6c 79 22 20 69 66 20 74 68 65 20 63 72  mally" if the cr
3a40: 61 73 68 0a 23 20 6f 63 63 75 72 65 64 2e 0a 23  ash.# occured..#
3a50: 0a 23 20 20 20 63 72 61 73 68 73 71 6c 20 2d 64  .#   crashsql -d
3a60: 65 6c 61 79 20 43 52 41 53 48 44 45 4c 41 59 20  elay CRASHDELAY 
3a70: 2d 66 69 6c 65 20 43 52 41 53 48 46 49 4c 45 20  -file CRASHFILE 
3a80: 3f 2d 62 6c 6f 63 6b 73 69 7a 65 20 42 4c 4f 43  ?-blocksize BLOC
3a90: 4b 53 49 5a 45 3f 20 24 73 71 6c 0a 23 0a 70 72  KSIZE? $sql.#.pr
3aa0: 6f 63 20 63 72 61 73 68 73 71 6c 20 7b 61 72 67  oc crashsql {arg
3ab0: 73 7d 20 7b 0a 20 20 69 66 20 7b 24 3a 3a 74 63  s} {.  if {$::tc
3ac0: 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66  l_platform(platf
3ad0: 6f 72 6d 29 21 3d 22 75 6e 69 78 22 7d 20 7b 0a  orm)!="unix"} {.
3ae0: 20 20 20 20 65 72 72 6f 72 20 22 63 72 61 73 68      error "crash
3af0: 73 71 6c 20 73 68 6f 75 6c 64 20 6f 6e 6c 79 20  sql should only 
3b00: 62 65 20 75 73 65 64 20 6f 6e 20 75 6e 69 78 22  be used on unix"
3b10: 0a 20 20 7d 0a 0a 20 20 73 65 74 20 62 6c 6f 63  .  }..  set bloc
3b20: 6b 73 69 7a 65 20 22 22 0a 20 20 73 65 74 20 63  ksize "".  set c
3b30: 72 61 73 68 64 65 6c 61 79 20 31 0a 20 20 73 65  rashdelay 1.  se
3b40: 74 20 70 72 6e 67 73 65 65 64 20 30 0a 20 20 73  t prngseed 0.  s
3b50: 65 74 20 74 63 6c 62 6f 64 79 20 7b 7d 0a 20 20  et tclbody {}.  
3b60: 73 65 74 20 63 72 61 73 68 66 69 6c 65 20 22 22  set crashfile ""
3b70: 0a 20 20 73 65 74 20 64 63 20 22 22 0a 20 20 73  .  set dc "".  s
3b80: 65 74 20 73 71 6c 20 5b 6c 69 6e 64 65 78 20 24  et sql [lindex $
3b90: 61 72 67 73 20 65 6e 64 5d 0a 20 20 0a 20 20 66  args end].  .  f
3ba0: 6f 72 20 7b 73 65 74 20 69 69 20 30 7d 20 7b 24  or {set ii 0} {$
3bb0: 69 69 20 3c 20 5b 6c 6c 65 6e 67 74 68 20 24 61  ii < [llength $a
3bc0: 72 67 73 5d 2d 31 7d 20 7b 69 6e 63 72 20 69 69  rgs]-1} {incr ii
3bd0: 20 32 7d 20 7b 0a 20 20 20 20 73 65 74 20 7a 20   2} {.    set z 
3be0: 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 24 69  [lindex $args $i
3bf0: 69 5d 0a 20 20 20 20 73 65 74 20 6e 20 5b 73 74  i].    set n [st
3c00: 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 7a 5d 0a  ring length $z].
3c10: 20 20 20 20 73 65 74 20 7a 32 20 5b 6c 69 6e 64      set z2 [lind
3c20: 65 78 20 24 61 72 67 73 20 5b 65 78 70 72 20 24  ex $args [expr $
3c30: 69 69 2b 31 5d 5d 0a 0a 20 20 20 20 69 66 20 20  ii+1]]..    if  
3c40: 20 20 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72     {$n>1 && [str
3c50: 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 64 65  ing first $z -de
3c60: 6c 61 79 5d 3d 3d 30 7d 20 20 20 20 20 7b 73 65  lay]==0}     {se
3c70: 74 20 63 72 61 73 68 64 65 6c 61 79 20 24 7a 32  t crashdelay $z2
3c80: 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b  } \.    elseif {
3c90: 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20  $n>1 && [string 
3ca0: 66 69 72 73 74 20 24 7a 20 2d 73 65 65 64 5d 3d  first $z -seed]=
3cb0: 3d 30 7d 20 20 20 20 20 20 7b 73 65 74 20 70 72  =0}      {set pr
3cc0: 6e 67 73 65 65 64 20 24 7a 32 7d 20 5c 0a 20 20  ngseed $z2} \.  
3cd0: 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26    elseif {$n>1 &
3ce0: 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20  & [string first 
3cf0: 24 7a 20 2d 66 69 6c 65 5d 3d 3d 30 7d 20 20 20  $z -file]==0}   
3d00: 20 20 20 7b 73 65 74 20 63 72 61 73 68 66 69 6c     {set crashfil
3d10: 65 20 24 7a 32 7d 20 20 5c 0a 20 20 20 20 65 6c  e $z2}  \.    el
3d20: 73 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73  seif {$n>1 && [s
3d30: 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d  tring first $z -
3d40: 74 63 6c 62 6f 64 79 5d 3d 3d 30 7d 20 20 20 7b  tclbody]==0}   {
3d50: 73 65 74 20 74 63 6c 62 6f 64 79 20 24 7a 32 7d  set tclbody $z2}
3d60: 20 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b    \.    elseif {
3d70: 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20  $n>1 && [string 
3d80: 66 69 72 73 74 20 24 7a 20 2d 62 6c 6f 63 6b 73  first $z -blocks
3d90: 69 7a 65 5d 3d 3d 30 7d 20 7b 73 65 74 20 62 6c  ize]==0} {set bl
3da0: 6f 63 6b 73 69 7a 65 20 22 2d 73 20 24 7a 32 22  ocksize "-s $z2"
3db0: 20 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20   } \.    elseif 
3dc0: 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67  {$n>1 && [string
3dd0: 20 66 69 72 73 74 20 24 7a 20 2d 63 68 61 72 61   first $z -chara
3de0: 63 74 65 72 69 73 74 69 63 73 5d 3d 3d 30 7d 20  cteristics]==0} 
3df0: 7b 73 65 74 20 64 63 20 22 2d 63 20 7b 24 7a 32  {set dc "-c {$z2
3e00: 7d 22 20 7d 20 5c 0a 20 20 20 20 65 6c 73 65 20  }" } \.    else 
3e10: 20 20 7b 20 65 72 72 6f 72 20 22 55 6e 72 65 63    { error "Unrec
3e20: 6f 67 6e 69 7a 65 64 20 6f 70 74 69 6f 6e 3a 20  ognized option: 
3e30: 24 7a 22 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 20  $z" }.  }..  if 
3e40: 7b 24 63 72 61 73 68 66 69 6c 65 20 65 71 20 22  {$crashfile eq "
3e50: 22 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72 20 22  "} {.    error "
3e60: 43 6f 6d 70 75 6c 73 6f 72 79 20 6f 70 74 69 6f  Compulsory optio
3e70: 6e 20 2d 66 69 6c 65 20 6d 69 73 73 69 6e 67 22  n -file missing"
3e80: 0a 20 20 7d 0a 0a 20 20 73 65 74 20 63 66 69 6c  .  }..  set cfil
3e90: 65 20 5b 66 69 6c 65 20 6a 6f 69 6e 20 5b 70 77  e [file join [pw
3ea0: 64 5d 20 24 63 72 61 73 68 66 69 6c 65 5d 0a 0a  d] $crashfile]..
3eb0: 20 20 73 65 74 20 66 20 5b 6f 70 65 6e 20 63 72    set f [open cr
3ec0: 61 73 68 2e 74 63 6c 20 77 5d 0a 20 20 70 75 74  ash.tcl w].  put
3ed0: 73 20 24 66 20 22 73 71 6c 69 74 65 33 5f 63 72  s $f "sqlite3_cr
3ee0: 61 73 68 5f 65 6e 61 62 6c 65 20 31 22 0a 20 20  ash_enable 1".  
3ef0: 70 75 74 73 20 24 66 20 22 73 71 6c 69 74 65 33  puts $f "sqlite3
3f00: 5f 63 72 61 73 68 70 61 72 61 6d 73 20 24 62 6c  _crashparams $bl
3f10: 6f 63 6b 73 69 7a 65 20 24 64 63 20 24 63 72 61  ocksize $dc $cra
3f20: 73 68 64 65 6c 61 79 20 24 63 66 69 6c 65 22 0a  shdelay $cfile".
3f30: 20 20 70 75 74 73 20 24 66 20 22 73 65 74 20 73    puts $f "set s
3f40: 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67 5f 62 79  qlite_pending_by
3f50: 74 65 20 24 3a 3a 73 71 6c 69 74 65 5f 70 65 6e  te $::sqlite_pen
3f60: 64 69 6e 67 5f 62 79 74 65 22 0a 20 20 70 75 74  ding_byte".  put
3f70: 73 20 24 66 20 22 73 71 6c 69 74 65 33 20 64 62  s $f "sqlite3 db
3f80: 20 74 65 73 74 2e 64 62 20 2d 76 66 73 20 63 72   test.db -vfs cr
3f90: 61 73 68 22 0a 0a 20 20 23 20 54 68 69 73 20 62  ash"..  # This b
3fa0: 6c 6f 63 6b 20 73 65 74 73 20 74 68 65 20 63 61  lock sets the ca
3fb0: 63 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20  che size of the 
3fc0: 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 74 6f  main database to
3fd0: 20 31 30 0a 20 20 23 20 70 61 67 65 73 2e 20 54   10.  # pages. T
3fe0: 68 69 73 20 69 73 20 64 6f 6e 65 20 69 6e 20 63  his is done in c
3ff0: 61 73 65 20 74 68 65 20 62 75 69 6c 64 20 69 73  ase the build is
4000: 20 63 6f 6e 66 69 67 75 72 65 64 20 74 6f 20 6f   configured to o
4010: 6d 69 74 0a 20 20 23 20 22 50 52 41 47 4d 41 20  mit.  # "PRAGMA 
4020: 63 61 63 68 65 5f 73 69 7a 65 22 2e 0a 20 20 70  cache_size"..  p
4030: 75 74 73 20 24 66 20 7b 64 62 20 65 76 61 6c 20  uts $f {db eval 
4040: 7b 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 73  {SELECT * FROM s
4050: 71 6c 69 74 65 5f 6d 61 73 74 65 72 3b 7d 7d 0a  qlite_master;}}.
4060: 20 20 70 75 74 73 20 24 66 20 7b 73 65 74 20 62    puts $f {set b
4070: 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62  t [btree_from_db
4080: 20 64 62 5d 7d 0a 20 20 70 75 74 73 20 24 66 20   db]}.  puts $f 
4090: 7b 62 74 72 65 65 5f 73 65 74 5f 63 61 63 68 65  {btree_set_cache
40a0: 5f 73 69 7a 65 20 24 62 74 20 31 30 7d 0a 20 20  _size $bt 10}.  
40b0: 69 66 20 7b 24 70 72 6e 67 73 65 65 64 7d 20 7b  if {$prngseed} {
40c0: 0a 20 20 20 20 73 65 74 20 73 65 65 64 20 5b 65  .    set seed [e
40d0: 78 70 72 20 7b 24 70 72 6e 67 73 65 65 64 25 31  xpr {$prngseed%1
40e0: 30 30 30 37 2b 31 7d 5d 0a 20 20 20 20 23 20 70  0007+1}].    # p
40f0: 75 74 73 20 73 65 65 64 3d 24 73 65 65 64 0a 20  uts seed=$seed. 
4100: 20 20 20 70 75 74 73 20 24 66 20 22 64 62 20 65     puts $f "db e
4110: 76 61 6c 20 7b 53 45 4c 45 43 54 20 72 61 6e 64  val {SELECT rand
4120: 6f 6d 62 6c 6f 62 28 24 73 65 65 64 29 7d 22 0a  omblob($seed)}".
4130: 20 20 7d 0a 0a 20 20 69 66 20 7b 5b 73 74 72 69    }..  if {[stri
4140: 6e 67 20 6c 65 6e 67 74 68 20 24 74 63 6c 62 6f  ng length $tclbo
4150: 64 79 5d 3e 30 7d 20 7b 0a 20 20 20 20 70 75 74  dy]>0} {.    put
4160: 73 20 24 66 20 24 74 63 6c 62 6f 64 79 0a 20 20  s $f $tclbody.  
4170: 7d 0a 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20  }.  if {[string 
4180: 6c 65 6e 67 74 68 20 24 73 71 6c 5d 3e 30 7d 20  length $sql]>0} 
4190: 7b 0a 20 20 20 20 70 75 74 73 20 24 66 20 22 64  {.    puts $f "d
41a0: 62 20 65 76 61 6c 20 7b 22 0a 20 20 20 20 70 75  b eval {".    pu
41b0: 74 73 20 24 66 20 20 20 22 24 73 71 6c 22 0a 20  ts $f   "$sql". 
41c0: 20 20 20 70 75 74 73 20 24 66 20 22 7d 22 0a 20     puts $f "}". 
41d0: 20 7d 0a 20 20 63 6c 6f 73 65 20 24 66 0a 0a 20   }.  close $f.. 
41e0: 20 73 65 74 20 72 20 5b 63 61 74 63 68 20 7b 0a   set r [catch {.
41f0: 20 20 20 20 65 78 65 63 20 5b 69 6e 66 6f 20 6e      exec [info n
4200: 61 6d 65 6f 66 65 78 65 63 5d 20 63 72 61 73 68  ameofexec] crash
4210: 2e 74 63 6c 20 3e 40 73 74 64 6f 75 74 0a 20 20  .tcl >@stdout.  
4220: 7d 20 6d 73 67 5d 0a 20 20 6c 61 70 70 65 6e 64  } msg].  lappend
4230: 20 72 20 24 6d 73 67 0a 7d 0a 0a 23 20 55 73 61   r $msg.}..# Usa
4240: 67 65 3a 20 64 6f 5f 69 6f 65 72 72 5f 74 65 73  ge: do_ioerr_tes
4250: 74 20 3c 74 65 73 74 20 6e 75 6d 62 65 72 3e 20  t <test number> 
4260: 3c 6f 70 74 69 6f 6e 73 2e 2e 2e 3e 0a 23 0a 23  <options...>.#.#
4270: 20 54 68 69 73 20 70 72 6f 63 20 69 73 20 75 73   This proc is us
4280: 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20  ed to implement 
4290: 74 65 73 74 20 63 61 73 65 73 20 74 68 61 74 20  test cases that 
42a0: 63 68 65 63 6b 20 74 68 61 74 20 49 4f 20 65 72  check that IO er
42b0: 72 6f 72 73 0a 23 20 61 72 65 20 63 6f 72 72 65  rors.# are corre
42c0: 63 74 6c 79 20 68 61 6e 64 6c 65 64 2e 20 54 68  ctly handled. Th
42d0: 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
42e0: 2c 20 3c 74 65 73 74 20 6e 75 6d 62 65 72 3e 2c  , <test number>,
42f0: 20 69 73 20 61 6e 20 69 6e 74 65 67 65 72 20 0a   is an integer .
4300: 23 20 75 73 65 64 20 74 6f 20 6e 61 6d 65 20 74  # used to name t
4310: 68 65 20 74 65 73 74 73 20 65 78 65 63 75 74 65  he tests execute
4320: 64 20 62 79 20 74 68 69 73 20 70 72 6f 63 2e 20  d by this proc. 
4330: 4f 70 74 69 6f 6e 73 20 61 72 65 20 61 73 20 66  Options are as f
4340: 6f 6c 6c 6f 77 73 3a 0a 23 0a 23 20 20 20 20 20  ollows:.#.#     
4350: 2d 74 63 6c 70 72 65 70 20 20 20 20 20 20 20 20  -tclprep        
4360: 20 20 54 43 4c 20 73 63 72 69 70 74 20 74 6f 20    TCL script to 
4370: 72 75 6e 20 74 6f 20 70 72 65 70 61 72 65 20 74  run to prepare t
4380: 65 73 74 2e 0a 23 20 20 20 20 20 2d 73 71 6c 70  est..#     -sqlp
4390: 72 65 70 20 20 20 20 20 20 20 20 20 20 53 51 4c  rep          SQL
43a0: 20 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20 74   script to run t
43b0: 6f 20 70 72 65 70 61 72 65 20 74 65 73 74 2e 0a  o prepare test..
43c0: 23 20 20 20 20 20 2d 74 63 6c 62 6f 64 79 20 20  #     -tclbody  
43d0: 20 20 20 20 20 20 20 20 54 43 4c 20 73 63 72 69          TCL scri
43e0: 70 74 20 74 6f 20 72 75 6e 20 77 69 74 68 20 49  pt to run with I
43f0: 4f 20 65 72 72 6f 72 20 73 69 6d 75 6c 61 74 69  O error simulati
4400: 6f 6e 2e 0a 23 20 20 20 20 20 2d 73 71 6c 62 6f  on..#     -sqlbo
4410: 64 79 20 20 20 20 20 20 20 20 20 20 54 43 4c 20  dy          TCL 
4420: 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20 77 69  script to run wi
4430: 74 68 20 49 4f 20 65 72 72 6f 72 20 73 69 6d 75  th IO error simu
4440: 6c 61 74 69 6f 6e 2e 0a 23 20 20 20 20 20 2d 65  lation..#     -e
4450: 78 63 6c 75 64 65 20 20 20 20 20 20 20 20 20 20  xclude          
4460: 4c 69 73 74 20 6f 66 20 27 4e 27 20 76 61 6c 75  List of 'N' valu
4470: 65 73 20 6e 6f 74 20 74 6f 20 74 65 73 74 2e 0a  es not to test..
4480: 23 20 20 20 20 20 2d 65 72 63 20 20 20 20 20 20  #     -erc      
4490: 20 20 20 20 20 20 20 20 55 73 65 20 65 78 74 65          Use exte
44a0: 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65  nded result code
44b0: 73 0a 23 20 20 20 20 20 2d 70 65 72 73 69 73 74  s.#     -persist
44c0: 20 20 20 20 20 20 20 20 20 20 4d 61 6b 65 20 73            Make s
44d0: 69 6d 75 6c 61 74 65 64 20 49 2f 4f 20 65 72 72  imulated I/O err
44e0: 6f 72 73 20 70 65 72 73 69 73 74 65 6e 74 0a 23  ors persistent.#
44f0: 20 20 20 20 20 2d 73 74 61 72 74 20 20 20 20 20       -start     
4500: 20 20 20 20 20 20 20 56 61 6c 75 65 20 6f 66 20         Value of 
4510: 27 4e 27 20 74 6f 20 62 65 67 69 6e 20 77 69 74  'N' to begin wit
4520: 68 20 28 64 65 66 61 75 6c 74 20 31 29 0a 23 0a  h (default 1).#.
4530: 23 20 20 20 20 20 2d 63 6b 73 75 6d 20 20 20 20  #     -cksum    
4540: 20 20 20 20 20 20 20 20 42 6f 6f 6c 65 61 6e 2e          Boolean.
4550: 20 49 66 20 74 72 75 65 2c 20 74 65 73 74 20 74   If true, test t
4560: 68 61 74 20 74 68 65 20 64 61 74 61 62 61 73 65  hat the database
4570: 20 64 6f 65 73 0a 23 20 20 20 20 20 20 20 20 20   does.#         
4580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 6f                no
4590: 74 20 63 68 61 6e 67 65 20 64 75 72 69 6e 67 20  t change during 
45a0: 74 68 65 20 65 78 65 63 75 74 69 6f 6e 20 6f 66  the execution of
45b0: 20 74 68 65 20 74 65 73 74 20 63 61 73 65 2e 0a   the test case..
45c0: 23 0a 70 72 6f 63 20 64 6f 5f 69 6f 65 72 72 5f  #.proc do_ioerr_
45d0: 74 65 73 74 20 7b 74 65 73 74 6e 61 6d 65 20 61  test {testname a
45e0: 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20 3a 3a  rgs} {..  set ::
45f0: 69 6f 65 72 72 6f 70 74 73 28 2d 73 74 61 72 74  ioerropts(-start
4600: 29 20 31 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72  ) 1.  set ::ioer
4610: 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 20 30 0a  ropts(-cksum) 0.
4620: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74    set ::ioerropt
4630: 73 28 2d 65 72 63 29 20 30 0a 20 20 73 65 74 20  s(-erc) 0.  set 
4640: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75  ::ioerropts(-cou
4650: 6e 74 29 20 31 30 30 30 30 30 30 30 30 0a 20 20  nt) 100000000.  
4660: 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28  set ::ioerropts(
4670: 2d 70 65 72 73 69 73 74 29 20 31 0a 20 20 73 65  -persist) 1.  se
4680: 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63  t ::ioerropts(-c
4690: 6b 72 65 66 63 6f 75 6e 74 29 20 30 0a 20 20 73  krefcount) 0.  s
46a0: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  et ::ioerropts(-
46b0: 72 65 73 74 6f 72 65 70 72 6e 67 29 20 31 0a 20  restoreprng) 1. 
46c0: 20 61 72 72 61 79 20 73 65 74 20 3a 3a 69 6f 65   array set ::ioe
46d0: 72 72 6f 70 74 73 20 24 61 72 67 73 0a 0a 20 20  rropts $args..  
46e0: 23 20 54 45 4d 50 4f 52 41 52 59 3a 20 46 6f 72  # TEMPORARY: For
46f0: 20 33 2e 35 2e 39 2c 20 64 69 73 61 62 6c 65 20   3.5.9, disable 
4700: 74 65 73 74 69 6e 67 20 6f 66 20 65 78 74 65 6e  testing of exten
4710: 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65 73  ded result codes
4720: 2e 20 54 68 65 72 65 20 61 72 65 0a 20 20 23 20  . There are.  # 
4730: 61 20 63 6f 75 70 6c 65 20 6f 66 20 6f 62 73 63  a couple of obsc
4740: 75 72 65 20 49 4f 20 65 72 72 6f 72 73 20 74 68  ure IO errors th
4750: 61 74 20 64 6f 20 6e 6f 74 20 72 65 74 75 72 6e  at do not return
4760: 20 74 68 65 6d 2e 0a 20 20 73 65 74 20 3a 3a 69   them..  set ::i
4770: 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29 20 30  oerropts(-erc) 0
4780: 0a 0a 20 20 73 65 74 20 3a 3a 67 6f 20 31 0a 20  ..  set ::go 1. 
4790: 20 23 72 65 73 65 74 5f 70 72 6e 67 5f 73 74 61   #reset_prng_sta
47a0: 74 65 0a 20 20 73 61 76 65 5f 70 72 6e 67 5f 73  te.  save_prng_s
47b0: 74 61 74 65 0a 20 20 66 6f 72 20 7b 73 65 74 20  tate.  for {set 
47c0: 6e 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  n $::ioerropts(-
47d0: 73 74 61 72 74 29 7d 20 7b 24 3a 3a 67 6f 20 26  start)} {$::go &
47e0: 26 20 24 6e 3c 32 30 30 7d 20 7b 69 6e 63 72 20  & $n<200} {incr 
47f0: 6e 7d 20 7b 0a 20 20 20 20 73 65 74 20 3a 3a 54  n} {.    set ::T
4800: 4e 20 24 6e 0a 20 20 20 20 69 6e 63 72 20 3a 3a  N $n.    incr ::
4810: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74  ioerropts(-count
4820: 29 20 2d 31 0a 20 20 20 20 69 66 20 7b 24 3a 3a  ) -1.    if {$::
4830: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74  ioerropts(-count
4840: 29 3c 30 7d 20 62 72 65 61 6b 0a 20 0a 20 20 20  )<0} break. .   
4850: 20 23 20 53 6b 69 70 20 74 68 69 73 20 49 4f 20   # Skip this IO 
4860: 65 72 72 6f 72 20 69 66 20 69 74 20 77 61 73 20  error if it was 
4870: 73 70 65 63 69 66 69 65 64 20 77 69 74 68 20 74  specified with t
4880: 68 65 20 22 2d 65 78 63 6c 75 64 65 22 20 6f 70  he "-exclude" op
4890: 74 69 6f 6e 2e 0a 20 20 20 20 69 66 20 7b 5b 69  tion..    if {[i
48a0: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65  nfo exists ::ioe
48b0: 72 72 6f 70 74 73 28 2d 65 78 63 6c 75 64 65 29  rropts(-exclude)
48c0: 5d 7d 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 5b  ]} {.      if {[
48d0: 6c 73 65 61 72 63 68 20 24 3a 3a 69 6f 65 72 72  lsearch $::ioerr
48e0: 6f 70 74 73 28 2d 65 78 63 6c 75 64 65 29 20 24  opts(-exclude) $
48f0: 6e 5d 21 3d 2d 31 7d 20 63 6f 6e 74 69 6e 75 65  n]!=-1} continue
4900: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 24  .    }.    if {$
4910: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 72 65 73  ::ioerropts(-res
4920: 74 6f 72 65 70 72 6e 67 29 7d 20 7b 0a 20 20 20  toreprng)} {.   
4930: 20 20 20 72 65 73 74 6f 72 65 5f 70 72 6e 67 5f     restore_prng_
4940: 73 74 61 74 65 0a 20 20 20 20 7d 0a 0a 20 20 20  state.    }..   
4950: 20 23 20 44 65 6c 65 74 65 20 74 68 65 20 66 69   # Delete the fi
4960: 6c 65 73 20 74 65 73 74 2e 64 62 20 61 6e 64 20  les test.db and 
4970: 74 65 73 74 32 2e 64 62 2c 20 74 68 65 6e 20 65  test2.db, then e
4980: 78 65 63 75 74 65 20 74 68 65 20 54 43 4c 20 61  xecute the TCL a
4990: 6e 64 20 0a 20 20 20 20 23 20 53 51 4c 20 28 69  nd .    # SQL (i
49a0: 6e 20 74 68 61 74 20 6f 72 64 65 72 29 20 74 6f  n that order) to
49b0: 20 70 72 65 70 61 72 65 20 66 6f 72 20 74 68 65   prepare for the
49c0: 20 74 65 73 74 20 63 61 73 65 2e 0a 20 20 20 20   test case..    
49d0: 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d  do_test $testnam
49e0: 65 2e 24 6e 2e 31 20 7b 0a 20 20 20 20 20 20 73  e.$n.1 {.      s
49f0: 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65  et ::sqlite_io_e
4a00: 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20  rror_pending 0. 
4a10: 20 20 20 20 20 63 61 74 63 68 20 7b 64 62 20 63       catch {db c
4a20: 6c 6f 73 65 7d 0a 20 20 20 20 20 20 63 61 74 63  lose}.      catc
4a30: 68 20 7b 66 69 6c 65 20 64 65 6c 65 74 65 20 2d  h {file delete -
4a40: 66 6f 72 63 65 20 74 65 73 74 2e 64 62 7d 0a 20  force test.db}. 
4a50: 20 20 20 20 20 63 61 74 63 68 20 7b 66 69 6c 65       catch {file
4a60: 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 74   delete -force t
4a70: 65 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a  est.db-journal}.
4a80: 20 20 20 20 20 20 63 61 74 63 68 20 7b 66 69 6c        catch {fil
4a90: 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20  e delete -force 
4aa0: 74 65 73 74 32 2e 64 62 7d 0a 20 20 20 20 20 20  test2.db}.      
4ab0: 63 61 74 63 68 20 7b 66 69 6c 65 20 64 65 6c 65  catch {file dele
4ac0: 74 65 20 2d 66 6f 72 63 65 20 74 65 73 74 32 2e  te -force test2.
4ad0: 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a 20 20 20 20  db-journal}.    
4ae0: 20 20 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69    set ::DB [sqli
4af0: 74 65 33 20 64 62 20 74 65 73 74 2e 64 62 3b 20  te3 db test.db; 
4b00: 73 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69  sqlite3_connecti
4b10: 6f 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20  on_pointer db]. 
4b20: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 65 78 74       sqlite3_ext
4b30: 65 6e 64 65 64 5f 72 65 73 75 6c 74 5f 63 6f 64  ended_result_cod
4b40: 65 73 20 24 3a 3a 44 42 20 24 3a 3a 69 6f 65 72  es $::DB $::ioer
4b50: 72 6f 70 74 73 28 2d 65 72 63 29 0a 20 20 20 20  ropts(-erc).    
4b60: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
4b70: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
4b80: 74 63 6c 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20  tclprep)]} {.   
4b90: 20 20 20 20 20 65 76 61 6c 20 24 3a 3a 69 6f 65       eval $::ioe
4ba0: 72 72 6f 70 74 73 28 2d 74 63 6c 70 72 65 70 29  rropts(-tclprep)
4bb0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
4bc0: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
4bd0: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c  ::ioerropts(-sql
4be0: 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20 20 20  prep)]} {.      
4bf0: 20 20 65 78 65 63 73 71 6c 20 24 3a 3a 69 6f 65    execsql $::ioe
4c00: 72 72 6f 70 74 73 28 2d 73 71 6c 70 72 65 70 29  rropts(-sqlprep)
4c10: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 65  .      }.      e
4c20: 78 70 72 20 30 0a 20 20 20 20 7d 20 7b 30 7d 0a  xpr 0.    } {0}.
4c30: 0a 20 20 20 20 23 20 52 65 61 64 20 74 68 65 20  .    # Read the 
4c40: 27 63 68 65 63 6b 73 75 6d 27 20 6f 66 20 74 68  'checksum' of th
4c50: 65 20 64 61 74 61 62 61 73 65 2e 0a 20 20 20 20  e database..    
4c60: 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73  if {$::ioerropts
4c70: 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20 20 20 20  (-cksum)} {.    
4c80: 20 20 73 65 74 20 63 68 65 63 6b 73 75 6d 20 5b    set checksum [
4c90: 63 6b 73 75 6d 5d 0a 20 20 20 20 7d 0a 0a 20 20  cksum].    }..  
4ca0: 20 20 23 20 53 65 74 20 74 68 65 20 4e 74 68 20    # Set the Nth 
4cb0: 49 4f 20 65 72 72 6f 72 20 74 6f 20 66 61 69 6c  IO error to fail
4cc0: 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74  ..    do_test $t
4cd0: 65 73 74 6e 61 6d 65 2e 24 6e 2e 32 20 5b 73 75  estname.$n.2 [su
4ce0: 62 73 74 20 7b 0a 20 20 20 20 20 20 73 65 74 20  bst {.      set 
4cf0: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
4d00: 72 5f 70 65 72 73 69 73 74 20 24 3a 3a 69 6f 65  r_persist $::ioe
4d10: 72 72 6f 70 74 73 28 2d 70 65 72 73 69 73 74 29  rropts(-persist)
4d20: 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c  .      set ::sql
4d30: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e  ite_io_error_pen
4d40: 64 69 6e 67 20 24 6e 0a 20 20 20 20 7d 5d 20 24  ding $n.    }] $
4d50: 6e 0a 20 20 0a 20 20 20 20 23 20 43 72 65 61 74  n.  .    # Creat
4d60: 65 20 61 20 73 69 6e 67 6c 65 20 54 43 4c 20 73  e a single TCL s
4d70: 63 72 69 70 74 20 66 72 6f 6d 20 74 68 65 20 54  cript from the T
4d80: 43 4c 20 61 6e 64 20 53 51 4c 20 73 70 65 63 69  CL and SQL speci
4d90: 66 69 65 64 0a 20 20 20 20 23 20 61 73 20 74 68  fied.    # as th
4da0: 65 20 62 6f 64 79 20 6f 66 20 74 68 65 20 74 65  e body of the te
4db0: 73 74 2e 0a 20 20 20 20 73 65 74 20 3a 3a 69 6f  st..    set ::io
4dc0: 65 72 72 6f 72 62 6f 64 79 20 7b 7d 0a 20 20 20  errorbody {}.   
4dd0: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
4de0: 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74  s ::ioerropts(-t
4df0: 63 6c 62 6f 64 79 29 5d 7d 20 7b 0a 20 20 20 20  clbody)]} {.    
4e00: 20 20 61 70 70 65 6e 64 20 3a 3a 69 6f 65 72 72    append ::ioerr
4e10: 6f 72 62 6f 64 79 20 22 24 3a 3a 69 6f 65 72 72  orbody "$::ioerr
4e20: 6f 70 74 73 28 2d 74 63 6c 62 6f 64 79 29 5c 6e  opts(-tclbody)\n
4e30: 22 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b  ".    }.    if {
4e40: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69  [info exists ::i
4e50: 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f 64  oerropts(-sqlbod
4e60: 79 29 5d 7d 20 7b 0a 20 20 20 20 20 20 61 70 70  y)]} {.      app
4e70: 65 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f 64  end ::ioerrorbod
4e80: 79 20 22 64 62 20 65 76 61 6c 20 7b 24 3a 3a 69  y "db eval {$::i
4e90: 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f 64  oerropts(-sqlbod
4ea0: 79 29 7d 22 0a 20 20 20 20 7d 0a 0a 20 20 20 20  y)}".    }..    
4eb0: 23 20 45 78 65 63 75 74 65 20 74 68 65 20 54 43  # Execute the TC
4ec0: 4c 20 53 63 72 69 70 74 20 63 72 65 61 74 65 64  L Script created
4ed0: 20 69 6e 20 74 68 65 20 61 62 6f 76 65 20 62 6c   in the above bl
4ee0: 6f 63 6b 2e 20 49 66 0a 20 20 20 20 23 20 74 68  ock. If.    # th
4ef0: 65 72 65 20 61 72 65 20 61 74 20 6c 65 61 73 74  ere are at least
4f00: 20 4e 20 49 4f 20 6f 70 65 72 61 74 69 6f 6e 73   N IO operations
4f10: 20 70 65 72 66 6f 72 6d 65 64 20 62 79 20 53 51   performed by SQ
4f20: 4c 69 74 65 20 61 73 0a 20 20 20 20 23 20 61 20  Lite as.    # a 
4f30: 72 65 73 75 6c 74 20 6f 66 20 74 68 65 20 73 63  result of the sc
4f40: 72 69 70 74 2c 20 74 68 65 20 4e 74 68 20 77 69  ript, the Nth wi
4f50: 6c 6c 20 66 61 69 6c 2e 0a 20 20 20 20 64 6f 5f  ll fail..    do_
4f60: 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24  test $testname.$
4f70: 6e 2e 33 20 7b 0a 20 20 20 20 20 20 73 65 74 20  n.3 {.      set 
4f80: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
4f90: 72 5f 68 69 74 20 30 0a 20 20 20 20 20 20 73 65  r_hit 0.      se
4fa0: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
4fb0: 72 6f 72 5f 68 61 72 64 68 69 74 20 30 0a 20 20  ror_hardhit 0.  
4fc0: 20 20 20 20 73 65 74 20 72 20 5b 63 61 74 63 68      set r [catch
4fd0: 20 24 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20   $::ioerrorbody 
4fe0: 6d 73 67 5d 0a 20 20 20 20 20 20 73 65 74 20 3a  msg].      set :
4ff0: 3a 65 72 72 73 65 65 6e 20 24 72 0a 20 20 20 20  :errseen $r.    
5000: 20 20 73 65 74 20 72 63 20 5b 73 71 6c 69 74 65    set rc [sqlite
5010: 33 5f 65 72 72 63 6f 64 65 20 24 3a 3a 44 42 5d  3_errcode $::DB]
5020: 0a 20 20 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f  .      if {$::io
5030: 65 72 72 6f 70 74 73 28 2d 65 72 63 29 7d 20 7b  erropts(-erc)} {
5040: 0a 20 20 20 20 20 20 20 20 23 20 49 66 20 77 65  .        # If we
5050: 20 61 72 65 20 69 6e 20 65 78 74 65 6e 64 65 64   are in extended
5060: 20 72 65 73 75 6c 74 20 63 6f 64 65 20 6d 6f 64   result code mod
5070: 65 2c 20 6d 61 6b 65 20 73 75 72 65 20 61 6c 6c  e, make sure all
5080: 20 6f 66 20 74 68 65 0a 20 20 20 20 20 20 20 20   of the.        
5090: 23 20 49 4f 45 52 52 73 20 77 65 20 67 65 74 20  # IOERRs we get 
50a0: 62 61 63 6b 20 72 65 61 6c 6c 79 20 64 6f 20 68  back really do h
50b0: 61 76 65 20 74 68 65 69 72 20 65 78 74 65 6e 64  ave their extend
50c0: 65 64 20 63 6f 64 65 20 76 61 6c 75 65 73 2e 0a  ed code values..
50d0: 20 20 20 20 20 20 20 20 23 20 49 66 20 61 6e 20          # If an 
50e0: 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20  extended result 
50f0: 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65 64  code is returned
5100: 2c 20 74 68 65 20 73 71 6c 69 74 65 33 5f 65 72  , the sqlite3_er
5110: 72 63 6f 64 65 0a 20 20 20 20 20 20 20 20 23 20  rcode.        # 
5120: 54 43 4c 63 6f 6d 6d 61 6e 64 20 77 69 6c 6c 20  TCLcommand will 
5130: 72 65 74 75 72 6e 20 61 20 73 74 72 69 6e 67 20  return a string 
5140: 6f 66 20 74 68 65 20 66 6f 72 6d 3a 20 20 53 51  of the form:  SQ
5150: 4c 49 54 45 5f 49 4f 45 52 52 2b 6e 6e 6e 6e 0a  LITE_IOERR+nnnn.
5160: 20 20 20 20 20 20 20 20 23 20 77 68 65 72 65 20          # where 
5170: 6e 6e 6e 6e 20 69 73 20 61 20 6e 75 6d 62 65 72  nnnn is a number
5180: 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b 72 65  .        if {[re
5190: 67 65 78 70 20 7b 5e 53 51 4c 49 54 45 5f 49 4f  gexp {^SQLITE_IO
51a0: 45 52 52 7d 20 24 72 63 5d 20 26 26 20 21 5b 72  ERR} $rc] && ![r
51b0: 65 67 65 78 70 20 7b 49 4f 45 52 52 5c 2b 5c 64  egexp {IOERR\+\d
51c0: 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20 20 20 20  } $rc]} {.      
51d0: 20 20 20 20 72 65 74 75 72 6e 20 24 72 63 0a 20      return $rc. 
51e0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
51f0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
5200: 23 20 49 66 20 77 65 20 61 72 65 20 6e 6f 74 20  # If we are not 
5210: 69 6e 20 65 78 74 65 6e 64 65 64 20 72 65 73 75  in extended resu
5220: 6c 74 20 63 6f 64 65 20 6d 6f 64 65 2c 20 6d 61  lt code mode, ma
5230: 6b 65 20 73 75 72 65 20 6e 6f 0a 20 20 20 20 20  ke sure no.     
5240: 20 20 20 23 20 65 78 74 65 6e 64 65 64 20 65 72     # extended er
5250: 72 6f 72 20 63 6f 64 65 73 20 61 72 65 20 72 65  ror codes are re
5260: 74 75 72 6e 65 64 2e 0a 20 20 20 20 20 20 20 20  turned..        
5270: 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5c 2b 5c  if {[regexp {\+\
5280: 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20 20 20  d} $rc]} {.     
5290: 20 20 20 20 20 72 65 74 75 72 6e 20 24 72 63 0a       return $rc.
52a0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
52b0: 7d 0a 20 20 20 20 20 20 23 20 54 68 65 20 74 65  }.      # The te
52c0: 73 74 20 72 65 70 65 61 74 73 20 61 73 20 6c 6f  st repeats as lo
52d0: 6e 67 20 61 73 20 24 3a 3a 67 6f 20 69 73 20 6e  ng as $::go is n
52e0: 6f 6e 2d 7a 65 72 6f 2e 20 20 24 3a 3a 67 6f 20  on-zero.  $::go 
52f0: 73 74 61 72 74 73 20 6f 75 74 0a 20 20 20 20 20  starts out.     
5300: 20 23 20 61 73 20 31 2e 20 20 57 68 65 6e 20 61   # as 1.  When a
5310: 20 74 65 73 74 20 72 75 6e 73 20 74 6f 20 63 6f   test runs to co
5320: 6d 70 6c 65 74 69 6f 6e 20 77 69 74 68 6f 75 74  mpletion without
5330: 20 68 69 74 74 69 6e 67 20 61 6e 20 49 2f 4f 0a   hitting an I/O.
5340: 20 20 20 20 20 20 23 20 65 72 72 6f 72 2c 20 74        # error, t
5350: 68 61 74 20 6d 65 61 6e 73 20 74 68 65 72 65 20  hat means there 
5360: 69 73 20 6e 6f 20 70 6f 69 6e 74 20 69 6e 20 63  is no point in c
5370: 6f 6e 74 69 6e 75 69 6e 67 20 77 69 74 68 20 74  ontinuing with t
5380: 68 69 73 20 74 65 73 74 0a 20 20 20 20 20 20 23  his test.      #
5390: 20 63 61 73 65 20 73 6f 20 73 65 74 20 24 3a 3a   case so set $::
53a0: 67 6f 20 74 6f 20 7a 65 72 6f 2e 0a 20 20 20 20  go to zero..    
53b0: 20 20 23 0a 20 20 20 20 20 20 69 66 20 7b 24 3a    #.      if {$:
53c0: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
53d0: 5f 70 65 6e 64 69 6e 67 3e 30 7d 20 7b 0a 20 20  _pending>0} {.  
53e0: 20 20 20 20 20 20 73 65 74 20 3a 3a 67 6f 20 30        set ::go 0
53f0: 0a 20 20 20 20 20 20 20 20 73 65 74 20 71 20 30  .        set q 0
5400: 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a 3a 73  .        set ::s
5410: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
5420: 65 6e 64 69 6e 67 20 30 0a 20 20 20 20 20 20 7d  ending 0.      }
5430: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
5440: 73 65 74 20 71 20 31 0a 20 20 20 20 20 20 7d 0a  set q 1.      }.
5450: 0a 20 20 20 20 20 20 73 65 74 20 73 20 5b 65 78  .      set s [ex
5460: 70 72 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  pr $::sqlite_io_
5470: 65 72 72 6f 72 5f 68 69 74 3d 3d 30 5d 0a 20 20  error_hit==0].  
5480: 20 20 20 20 69 66 20 7b 24 3a 3a 73 71 6c 69 74      if {$::sqlit
5490: 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 3e 24  e_io_error_hit>$
54a0: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
54b0: 72 5f 68 61 72 64 68 69 74 20 26 26 20 24 72 3d  r_hardhit && $r=
54c0: 3d 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65  =0} {.        se
54d0: 74 20 72 20 31 0a 20 20 20 20 20 20 7d 0a 20 20  t r 1.      }.  
54e0: 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65      set ::sqlite
54f0: 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 20 30 0a  _io_error_hit 0.
5500: 0a 20 20 20 20 20 20 23 20 4f 6e 65 20 6f 66 20  .      # One of 
5510: 74 77 6f 20 74 68 69 6e 67 73 20 6d 75 73 74 20  two things must 
5520: 68 61 76 65 20 68 61 70 70 65 6e 65 64 2e 20 65  have happened. e
5530: 69 74 68 65 72 0a 20 20 20 20 20 20 23 20 20 20  ither.      #   
5540: 31 2e 20 20 57 65 20 6e 65 76 65 72 20 68 69 74  1.  We never hit
5550: 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20 61 6e   the IO error an
5560: 64 20 74 68 65 20 53 51 4c 20 72 65 74 75 72 6e  d the SQL return
5570: 65 64 20 4f 4b 0a 20 20 20 20 20 20 23 20 20 20  ed OK.      #   
5580: 32 2e 20 20 41 6e 20 49 4f 20 65 72 72 6f 72 20  2.  An IO error 
5590: 77 61 73 20 68 69 74 20 61 6e 64 20 74 68 65 20  was hit and the 
55a0: 53 51 4c 20 66 61 69 6c 65 64 0a 20 20 20 20 20  SQL failed.     
55b0: 20 23 0a 20 20 20 20 20 20 65 78 70 72 20 7b 20   #.      expr { 
55c0: 28 24 73 20 26 26 20 21 24 72 20 26 26 20 21 24  ($s && !$r && !$
55d0: 71 29 20 7c 7c 20 28 21 24 73 20 26 26 20 24 72  q) || (!$s && $r
55e0: 20 26 26 20 24 71 29 20 7d 0a 20 20 20 20 7d 20   && $q) }.    } 
55f0: 7b 31 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a 73  {1}..    set ::s
5600: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68  qlite_io_error_h
5610: 69 74 20 30 0a 20 20 20 20 73 65 74 20 3a 3a 73  it 0.    set ::s
5620: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
5630: 65 6e 64 69 6e 67 20 30 0a 0a 20 20 20 20 23 20  ending 0..    # 
5640: 43 68 65 63 6b 20 74 68 61 74 20 6e 6f 20 70 61  Check that no pa
5650: 67 65 20 72 65 66 65 72 65 6e 63 65 73 20 77 65  ge references we
5660: 72 65 20 6c 65 61 6b 65 64 2e 20 54 68 65 72 65  re leaked. There
5670: 20 73 68 6f 75 6c 64 20 62 65 20 0a 20 20 20 20   should be .    
5680: 23 20 61 20 73 69 6e 67 6c 65 20 72 65 66 65 72  # a single refer
5690: 65 6e 63 65 20 69 66 20 74 68 65 72 65 20 69 73  ence if there is
56a0: 20 73 74 69 6c 6c 20 61 6e 20 61 63 74 69 76 65   still an active
56b0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20 0a 20   transaction, . 
56c0: 20 20 20 23 20 6f 72 20 7a 65 72 6f 20 6f 74 68     # or zero oth
56d0: 65 72 77 69 73 65 2e 0a 20 20 20 20 23 0a 20 20  erwise..    #.  
56e0: 20 20 23 20 55 50 44 41 54 45 3a 20 49 66 20 74    # UPDATE: If t
56f0: 68 65 20 49 4f 20 65 72 72 6f 72 20 6f 63 63 75  he IO error occu
5700: 72 73 20 61 66 74 65 72 20 61 20 27 42 45 47 49  rs after a 'BEGI
5710: 4e 27 20 62 75 74 20 62 65 66 6f 72 65 20 61 6e  N' but before an
5720: 79 0a 20 20 20 20 23 20 6c 6f 63 6b 73 20 61 72  y.    # locks ar
5730: 65 20 65 73 74 61 62 6c 69 73 68 65 64 20 6f 6e  e established on
5740: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 73 20   database files 
5750: 28 69 2e 65 2e 20 69 66 20 74 68 65 20 65 72 72  (i.e. if the err
5760: 6f 72 20 0a 20 20 20 20 23 20 6f 63 63 75 72 73  or .    # occurs
5770: 20 77 68 69 6c 65 20 61 74 74 65 6d 70 74 69 6e   while attemptin
5780: 67 20 74 6f 20 64 65 74 65 63 74 20 61 20 68 6f  g to detect a ho
5790: 74 2d 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 29 2c  t-journal file),
57a0: 20 74 68 65 6e 0a 20 20 20 20 23 20 74 68 65 72   then.    # ther
57b0: 65 20 6d 61 79 20 30 20 70 61 67 65 20 72 65 66  e may 0 page ref
57c0: 65 72 65 6e 63 65 73 20 61 6e 64 20 61 6e 20 61  erences and an a
57d0: 63 74 69 76 65 20 74 72 61 6e 73 61 63 74 69 6f  ctive transactio
57e0: 6e 20 61 63 63 6f 72 64 69 6e 67 0a 20 20 20 20  n according.    
57f0: 23 20 74 6f 20 5b 73 71 6c 69 74 65 33 5f 67 65  # to [sqlite3_ge
5800: 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 5d 2e 0a 20  t_autocommit].. 
5810: 20 20 20 23 0a 20 20 20 20 69 66 20 7b 24 3a 3a     #.    if {$::
5820: 67 6f 20 26 26 20 24 3a 3a 73 71 6c 69 74 65 5f  go && $::sqlite_
5830: 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74  io_error_hardhit
5840: 20 26 26 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73   && $::ioerropts
5850: 28 2d 63 6b 72 65 66 63 6f 75 6e 74 29 7d 20 7b  (-ckrefcount)} {
5860: 0a 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20 24  .      do_test $
5870: 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 34 20 7b 0a  testname.$n.4 {.
5880: 20 20 20 20 20 20 20 20 73 65 74 20 62 74 20 5b          set bt [
5890: 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62  btree_from_db db
58a0: 5d 0a 20 20 20 20 20 20 20 20 64 62 5f 65 6e 74  ].        db_ent
58b0: 65 72 20 64 62 0a 20 20 20 20 20 20 20 20 61 72  er db.        ar
58c0: 72 61 79 20 73 65 74 20 73 74 61 74 73 20 5b 62  ray set stats [b
58d0: 74 72 65 65 5f 70 61 67 65 72 5f 73 74 61 74 73  tree_pager_stats
58e0: 20 24 62 74 5d 0a 20 20 20 20 20 20 20 20 64 62   $bt].        db
58f0: 5f 6c 65 61 76 65 20 64 62 0a 20 20 20 20 20 20  _leave db.      
5900: 20 20 73 65 74 20 6e 52 65 66 20 24 73 74 61 74    set nRef $stat
5910: 73 28 72 65 66 29 0a 20 20 20 20 20 20 20 20 65  s(ref).        e
5920: 78 70 72 20 7b 24 6e 52 65 66 20 3d 3d 20 30 20  xpr {$nRef == 0 
5930: 7c 7c 20 28 5b 73 71 6c 69 74 65 33 5f 67 65 74  || ([sqlite3_get
5940: 5f 61 75 74 6f 63 6f 6d 6d 69 74 20 64 62 5d 3d  _autocommit db]=
5950: 3d 30 20 26 26 20 24 6e 52 65 66 20 3d 3d 20 31  =0 && $nRef == 1
5960: 29 7d 0a 20 20 20 20 20 20 7d 20 7b 31 7d 0a 20  )}.      } {1}. 
5970: 20 20 20 7d 0a 0a 20 20 20 20 23 20 49 66 20 74     }..    # If t
5980: 68 65 72 65 20 69 73 20 61 6e 20 6f 70 65 6e 20  here is an open 
5990: 64 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20  database handle 
59a0: 61 6e 64 20 6e 6f 20 6f 70 65 6e 20 74 72 61 6e  and no open tran
59b0: 73 61 63 74 69 6f 6e 2c 20 0a 20 20 20 20 23 20  saction, .    # 
59c0: 61 6e 64 20 74 68 65 20 70 61 67 65 72 20 69 73  and the pager is
59d0: 20 6e 6f 74 20 72 75 6e 6e 69 6e 67 20 69 6e 20   not running in 
59e0: 65 78 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69 6e  exclusive-lockin
59f0: 67 20 6d 6f 64 65 2c 0a 20 20 20 20 23 20 63 68  g mode,.    # ch
5a00: 65 63 6b 20 74 68 61 74 20 74 68 65 20 70 61 67  eck that the pag
5a10: 65 72 20 69 73 20 69 6e 20 22 75 6e 6c 6f 63 6b  er is in "unlock
5a20: 65 64 22 20 73 74 61 74 65 2e 20 54 68 65 6f 72  ed" state. Theor
5a30: 65 74 69 63 61 6c 6c 79 2c 0a 20 20 20 20 23 20  etically,.    # 
5a40: 69 66 20 61 20 63 61 6c 6c 20 74 6f 20 78 55 6e  if a call to xUn
5a50: 6c 6f 63 6b 28 29 20 66 61 69 6c 65 64 20 64 75  lock() failed du
5a60: 65 20 74 6f 20 61 6e 20 49 4f 20 65 72 72 6f 72  e to an IO error
5a70: 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a   the underlying.
5a80: 20 20 20 20 23 20 66 69 6c 65 20 6d 61 79 20 73      # file may s
5a90: 74 69 6c 6c 20 62 65 20 6c 6f 63 6b 65 64 2e 0a  till be locked..
5aa0: 20 20 20 20 23 0a 20 20 20 20 69 66 63 61 70 61      #.    ifcapa
5ab0: 62 6c 65 20 70 72 61 67 6d 61 20 7b 0a 20 20 20  ble pragma {.   
5ac0: 20 20 20 69 66 20 7b 20 5b 69 6e 66 6f 20 63 6f     if { [info co
5ad0: 6d 6d 61 6e 64 73 20 64 62 5d 20 6e 65 20 22 22  mmands db] ne ""
5ae0: 0a 20 20 20 20 20 20 20 20 26 26 20 24 3a 3a 69  .        && $::i
5af0: 6f 65 72 72 6f 70 74 73 28 2d 63 6b 72 65 66 63  oerropts(-ckrefc
5b00: 6f 75 6e 74 29 0a 20 20 20 20 20 20 20 20 26 26  ount).        &&
5b10: 20 5b 64 62 20 6f 6e 65 20 7b 70 72 61 67 6d 61   [db one {pragma
5b20: 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 7d 5d 20   locking_mode}] 
5b30: 65 71 20 22 6e 6f 72 6d 61 6c 22 0a 20 20 20 20  eq "normal".    
5b40: 20 20 20 20 26 26 20 5b 73 71 6c 69 74 65 33 5f      && [sqlite3_
5b50: 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 20 64  get_autocommit d
5b60: 62 5d 0a 20 20 20 20 20 20 7d 20 7b 0a 20 20 20  b].      } {.   
5b70: 20 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65       do_test $te
5b80: 73 74 6e 61 6d 65 2e 24 6e 2e 35 20 7b 0a 20 20  stname.$n.5 {.  
5b90: 20 20 20 20 20 20 20 20 73 65 74 20 62 74 20 5b          set bt [
5ba0: 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62  btree_from_db db
5bb0: 5d 0a 20 20 20 20 20 20 20 20 20 20 64 62 5f 65  ].          db_e
5bc0: 6e 74 65 72 20 64 62 0a 20 20 20 20 20 20 20 20  nter db.        
5bd0: 20 20 61 72 72 61 79 20 73 65 74 20 73 74 61 74    array set stat
5be0: 73 20 5b 62 74 72 65 65 5f 70 61 67 65 72 5f 73  s [btree_pager_s
5bf0: 74 61 74 73 20 24 62 74 5d 0a 20 20 20 20 20 20  tats $bt].      
5c00: 20 20 20 20 64 62 5f 6c 65 61 76 65 20 64 62 0a      db_leave db.
5c10: 20 20 20 20 20 20 20 20 20 20 73 65 74 20 73 74            set st
5c20: 61 74 73 28 73 74 61 74 65 29 0a 20 20 20 20 20  ats(state).     
5c30: 20 20 20 7d 20 30 0a 20 20 20 20 20 20 7d 0a 20     } 0.      }. 
5c40: 20 20 20 7d 0a 0a 20 20 20 20 23 20 49 66 20 61     }..    # If a
5c50: 6e 20 49 4f 20 65 72 72 6f 72 20 6f 63 63 75 72  n IO error occur
5c60: 65 64 2c 20 74 68 65 6e 20 74 68 65 20 63 68 65  ed, then the che
5c70: 63 6b 73 75 6d 20 6f 66 20 74 68 65 20 64 61 74  cksum of the dat
5c80: 61 62 61 73 65 20 73 68 6f 75 6c 64 0a 20 20 20  abase should.   
5c90: 20 23 20 62 65 20 74 68 65 20 73 61 6d 65 20 61   # be the same a
5ca0: 73 20 62 65 66 6f 72 65 20 74 68 65 20 73 63 72  s before the scr
5cb0: 69 70 74 20 74 68 61 74 20 63 61 75 73 65 64 20  ipt that caused 
5cc0: 74 68 65 20 49 4f 20 65 72 72 6f 72 20 77 61 73  the IO error was
5cd0: 20 72 75 6e 2e 0a 20 20 20 20 23 0a 20 20 20 20   run..    #.    
5ce0: 69 66 20 7b 24 3a 3a 67 6f 20 26 26 20 24 3a 3a  if {$::go && $::
5cf0: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
5d00: 68 61 72 64 68 69 74 20 26 26 20 24 3a 3a 69 6f  hardhit && $::io
5d10: 65 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d  erropts(-cksum)}
5d20: 20 7b 0a 20 20 20 20 20 20 64 6f 5f 74 65 73 74   {.      do_test
5d30: 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 36 20   $testname.$n.6 
5d40: 7b 0a 20 20 20 20 20 20 20 20 63 61 74 63 68 20  {.        catch 
5d50: 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20  {db close}.     
5d60: 20 20 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c     catch {db2 cl
5d70: 6f 73 65 7d 0a 20 20 20 20 20 20 20 20 73 65 74  ose}.        set
5d80: 20 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33 20 64   ::DB [sqlite3 d
5d90: 62 20 74 65 73 74 2e 64 62 3b 20 73 71 6c 69 74  b test.db; sqlit
5da0: 65 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f  e3_connection_po
5db0: 69 6e 74 65 72 20 64 62 5d 0a 20 20 20 20 20 20  inter db].      
5dc0: 20 20 63 6b 73 75 6d 0a 20 20 20 20 20 20 7d 20    cksum.      } 
5dd0: 24 63 68 65 63 6b 73 75 6d 0a 20 20 20 20 7d 0a  $checksum.    }.
5de0: 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74  .    set ::sqlit
5df0: 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68  e_io_error_hardh
5e00: 69 74 20 30 0a 20 20 20 20 73 65 74 20 3a 3a 73  it 0.    set ::s
5e10: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
5e20: 65 6e 64 69 6e 67 20 30 0a 20 20 20 20 69 66 20  ending 0.    if 
5e30: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
5e40: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6c 65 61 6e  ioerropts(-clean
5e50: 75 70 29 5d 7d 20 7b 0a 20 20 20 20 20 20 63 61  up)]} {.      ca
5e60: 74 63 68 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73  tch $::ioerropts
5e70: 28 2d 63 6c 65 61 6e 75 70 29 0a 20 20 20 20 7d  (-cleanup).    }
5e80: 0a 20 20 7d 0a 20 20 73 65 74 20 3a 3a 73 71 6c  .  }.  set ::sql
5e90: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e  ite_io_error_pen
5ea0: 64 69 6e 67 20 30 0a 20 20 73 65 74 20 3a 3a 73  ding 0.  set ::s
5eb0: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
5ec0: 65 72 73 69 73 74 20 30 0a 20 20 75 6e 73 65 74  ersist 0.  unset
5ed0: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 0a 7d 0a 0a   ::ioerropts.}..
5ee0: 23 20 52 65 74 75 72 6e 20 61 20 63 68 65 63 6b  # Return a check
5ef0: 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74 68 65  sum based on the
5f00: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
5f10: 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 61   main database a
5f20: 73 73 6f 63 69 61 74 65 64 0a 23 20 77 69 74 68  ssociated.# with
5f30: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 24 64 62 0a   connection $db.
5f40: 23 0a 70 72 6f 63 20 63 6b 73 75 6d 20 7b 7b 64  #.proc cksum {{d
5f50: 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74 20 74  b db}} {.  set t
5f60: 78 74 20 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20  xt [$db eval {. 
5f70: 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65       SELECT name
5f80: 2c 20 74 79 70 65 2c 20 73 71 6c 20 46 52 4f 4d  , type, sql FROM
5f90: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 6f   sqlite_master o
5fa0: 72 64 65 72 20 62 79 20 6e 61 6d 65 0a 20 20 7d  rder by name.  }
5fb0: 5d 5c 6e 0a 20 20 66 6f 72 65 61 63 68 20 74 62  ]\n.  foreach tb
5fc0: 6c 20 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20 20  l [$db eval {.  
5fd0: 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20      SELECT name 
5fe0: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
5ff0: 65 72 20 57 48 45 52 45 20 74 79 70 65 3d 27 74  er WHERE type='t
6000: 61 62 6c 65 27 20 6f 72 64 65 72 20 62 79 20 6e  able' order by n
6010: 61 6d 65 0a 20 20 7d 5d 20 7b 0a 20 20 20 20 61  ame.  }] {.    a
6020: 70 70 65 6e 64 20 74 78 74 20 5b 24 64 62 20 65  ppend txt [$db e
6030: 76 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52  val "SELECT * FR
6040: 4f 4d 20 24 74 62 6c 22 5d 5c 6e 0a 20 20 7d 0a  OM $tbl"]\n.  }.
6050: 20 20 66 6f 72 65 61 63 68 20 70 72 61 67 20 7b    foreach prag {
6060: 64 65 66 61 75 6c 74 5f 73 79 6e 63 68 72 6f 6e  default_synchron
6070: 6f 75 73 20 64 65 66 61 75 6c 74 5f 63 61 63 68  ous default_cach
6080: 65 5f 73 69 7a 65 7d 20 7b 0a 20 20 20 20 61 70  e_size} {.    ap
6090: 70 65 6e 64 20 74 78 74 20 24 70 72 61 67 2d 5b  pend txt $prag-[
60a0: 24 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41  $db eval "PRAGMA
60b0: 20 24 70 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a 20   $prag"]\n.  }. 
60c0: 20 73 65 74 20 63 6b 73 75 6d 20 5b 73 74 72 69   set cksum [stri
60d0: 6e 67 20 6c 65 6e 67 74 68 20 24 74 78 74 5d 2d  ng length $txt]-
60e0: 5b 6d 64 35 20 24 74 78 74 5d 0a 20 20 23 20 70  [md5 $txt].  # p
60f0: 75 74 73 20 24 63 6b 73 75 6d 2d 5b 66 69 6c 65  uts $cksum-[file
6100: 20 73 69 7a 65 20 74 65 73 74 2e 64 62 5d 0a 20   size test.db]. 
6110: 20 72 65 74 75 72 6e 20 24 63 6b 73 75 6d 0a 7d   return $cksum.}
6120: 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20 63  ..# Generate a c
6130: 68 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e  hecksum based on
6140: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
6150: 20 74 68 65 20 6d 61 69 6e 20 61 6e 64 20 74 65   the main and te
6160: 6d 70 20 74 61 62 6c 65 73 0a 23 20 64 61 74 61  mp tables.# data
6170: 62 61 73 65 20 24 64 62 2e 20 49 66 20 74 68 65  base $db. If the
6180: 20 63 68 65 63 6b 73 75 6d 20 6f 66 20 74 77 6f   checksum of two
6190: 20 64 61 74 61 62 61 73 65 73 20 69 73 20 74 68   databases is th
61a0: 65 20 73 61 6d 65 2c 20 61 6e 64 20 74 68 65 0a  e same, and the.
61b0: 23 20 69 6e 74 65 67 72 69 74 79 2d 63 68 65 63  # integrity-chec
61c0: 6b 20 70 61 73 73 65 73 20 66 6f 72 20 62 6f 74  k passes for bot
61d0: 68 2c 20 74 68 65 20 74 77 6f 20 64 61 74 61 62  h, the two datab
61e0: 61 73 65 73 20 61 72 65 20 69 64 65 6e 74 69 63  ases are identic
61f0: 61 6c 2e 0a 23 0a 70 72 6f 63 20 61 6c 6c 63 6b  al..#.proc allck
6200: 73 75 6d 20 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a  sum {{db db}} {.
6210: 20 20 73 65 74 20 72 65 74 20 5b 6c 69 73 74 5d    set ret [list]
6220: 0a 20 20 69 66 63 61 70 61 62 6c 65 20 74 65 6d  .  ifcapable tem
6230: 70 64 62 20 7b 0a 20 20 20 20 73 65 74 20 73 71  pdb {.    set sq
6240: 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54  l {.      SELECT
6250: 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74   name FROM sqlit
6260: 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74  e_master WHERE t
6270: 79 70 65 20 3d 20 27 74 61 62 6c 65 27 20 55 4e  ype = 'table' UN
6280: 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45 43 54  ION.      SELECT
6290: 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74   name FROM sqlit
62a0: 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72 20 57 48  e_temp_master WH
62b0: 45 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c  ERE type = 'tabl
62c0: 65 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53  e' UNION.      S
62d0: 45 4c 45 43 54 20 27 73 71 6c 69 74 65 5f 6d 61  ELECT 'sqlite_ma
62e0: 73 74 65 72 27 20 55 4e 49 4f 4e 0a 20 20 20 20  ster' UNION.    
62f0: 20 20 53 45 4c 45 43 54 20 27 73 71 6c 69 74 65    SELECT 'sqlite
6300: 5f 74 65 6d 70 5f 6d 61 73 74 65 72 27 20 4f 52  _temp_master' OR
6310: 44 45 52 20 42 59 20 31 0a 20 20 20 20 7d 0a 20  DER BY 1.    }. 
6320: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
6330: 74 20 73 71 6c 20 7b 0a 20 20 20 20 20 20 53 45  t sql {.      SE
6340: 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73  LECT name FROM s
6350: 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45  qlite_master WHE
6360: 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65  RE type = 'table
6370: 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45  ' UNION.      SE
6380: 4c 45 43 54 20 27 73 71 6c 69 74 65 5f 6d 61 73  LECT 'sqlite_mas
6390: 74 65 72 27 20 4f 52 44 45 52 20 42 59 20 31 0a  ter' ORDER BY 1.
63a0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20      }.  }.  set 
63b0: 74 62 6c 6c 69 73 74 20 5b 24 64 62 20 65 76 61  tbllist [$db eva
63c0: 6c 20 24 73 71 6c 5d 0a 20 20 73 65 74 20 74 78  l $sql].  set tx
63d0: 74 20 7b 7d 0a 20 20 66 6f 72 65 61 63 68 20 74  t {}.  foreach t
63e0: 62 6c 20 24 74 62 6c 6c 69 73 74 20 7b 0a 20 20  bl $tbllist {.  
63f0: 20 20 61 70 70 65 6e 64 20 74 78 74 20 5b 24 64    append txt [$d
6400: 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a  b eval "SELECT *
6410: 20 46 52 4f 4d 20 24 74 62 6c 22 5d 0a 20 20 7d   FROM $tbl"].  }
6420: 0a 20 20 66 6f 72 65 61 63 68 20 70 72 61 67 20  .  foreach prag 
6430: 7b 64 65 66 61 75 6c 74 5f 63 61 63 68 65 5f 73  {default_cache_s
6440: 69 7a 65 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e  ize} {.    appen
6450: 64 20 74 78 74 20 24 70 72 61 67 2d 5b 24 64 62  d txt $prag-[$db
6460: 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 24 70   eval "PRAGMA $p
6470: 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a 20 20 23 20  rag"]\n.  }.  # 
6480: 70 75 74 73 20 74 78 74 3d 24 74 78 74 0a 20 20  puts txt=$txt.  
6490: 72 65 74 75 72 6e 20 5b 6d 64 35 20 24 74 78 74  return [md5 $txt
64a0: 5d 0a 7d 0a 0a 70 72 6f 63 20 6d 65 6d 64 65 62  ].}..proc memdeb
64b0: 75 67 5f 6c 6f 67 5f 73 71 6c 20 7b 7b 66 69 6c  ug_log_sql {{fil
64c0: 65 6e 61 6d 65 20 6d 61 6c 6c 6f 63 73 2e 73 71  ename mallocs.sq
64d0: 6c 7d 7d 20 7b 0a 0a 20 20 73 65 74 20 64 61 74  l}} {..  set dat
64e0: 61 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65  a [sqlite3_memde
64f0: 62 75 67 5f 6c 6f 67 20 64 75 6d 70 5d 0a 20 20  bug_log dump].  
6500: 73 65 74 20 6e 46 72 61 6d 65 20 5b 65 78 70 72  set nFrame [expr
6510: 20 5b 6c 6c 65 6e 67 74 68 20 5b 6c 69 6e 64 65   [llength [linde
6520: 78 20 24 64 61 74 61 20 30 5d 5d 2d 32 5d 0a 20  x $data 0]]-2]. 
6530: 20 69 66 20 7b 24 6e 46 72 61 6d 65 20 3c 20 30   if {$nFrame < 0
6540: 7d 20 7b 20 72 65 74 75 72 6e 20 22 22 20 7d 0a  } { return "" }.
6550: 0a 20 20 73 65 74 20 64 61 74 61 62 61 73 65 20  .  set database 
6560: 74 65 6d 70 0a 0a 20 20 73 65 74 20 74 62 6c 20  temp..  set tbl 
6570: 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 24 7b  "CREATE TABLE ${
6580: 64 61 74 61 62 61 73 65 7d 2e 6d 61 6c 6c 6f 63  database}.malloc
6590: 28 6e 43 61 6c 6c 2c 20 6e 42 79 74 65 22 0a 20  (nCall, nByte". 
65a0: 20 66 6f 72 20 7b 73 65 74 20 69 69 20 31 7d 20   for {set ii 1} 
65b0: 7b 24 69 69 20 3c 3d 20 24 6e 46 72 61 6d 65 7d  {$ii <= $nFrame}
65c0: 20 7b 69 6e 63 72 20 69 69 7d 20 7b 0a 20 20 20   {incr ii} {.   
65d0: 20 61 70 70 65 6e 64 20 74 62 6c 20 22 2c 20 66   append tbl ", f
65e0: 24 7b 69 69 7d 22 0a 20 20 7d 0a 20 20 61 70 70  ${ii}".  }.  app
65f0: 65 6e 64 20 74 62 6c 20 22 29 3b 5c 6e 22 0a 0a  end tbl ");\n"..
6600: 20 20 73 65 74 20 73 71 6c 20 22 22 0a 20 20 66    set sql "".  f
6610: 6f 72 65 61 63 68 20 65 20 24 64 61 74 61 20 7b  oreach e $data {
6620: 0a 20 20 20 20 61 70 70 65 6e 64 20 73 71 6c 20  .    append sql 
6630: 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 24 7b 64  "INSERT INTO ${d
6640: 61 74 61 62 61 73 65 7d 2e 6d 61 6c 6c 6f 63 20  atabase}.malloc 
6650: 56 41 4c 55 45 53 28 5b 6a 6f 69 6e 20 24 65 20  VALUES([join $e 
6660: 2c 5d 29 3b 5c 6e 22 0a 20 20 20 20 66 6f 72 65  ,]);\n".    fore
6670: 61 63 68 20 66 20 5b 6c 72 61 6e 67 65 20 24 65  ach f [lrange $e
6680: 20 32 20 65 6e 64 5d 20 7b 0a 20 20 20 20 20 20   2 end] {.      
6690: 73 65 74 20 66 72 61 6d 65 73 28 24 66 29 20 31  set frames($f) 1
66a0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 73 65  .    }.  }..  se
66b0: 74 20 74 62 6c 32 20 22 43 52 45 41 54 45 20 54  t tbl2 "CREATE T
66c0: 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73 65 7d  ABLE ${database}
66d0: 2e 66 72 61 6d 65 28 66 72 61 6d 65 20 49 4e 54  .frame(frame INT
66e0: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59  EGER PRIMARY KEY
66f0: 2c 20 6c 69 6e 65 29 3b 5c 6e 22 0a 20 20 73 65  , line);\n".  se
6700: 74 20 74 62 6c 33 20 22 43 52 45 41 54 45 20 54  t tbl3 "CREATE T
6710: 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73 65 7d  ABLE ${database}
6720: 2e 66 69 6c 65 28 6e 61 6d 65 20 50 52 49 4d 41  .file(name PRIMA
6730: 52 59 20 4b 45 59 2c 20 63 6f 6e 74 65 6e 74 29  RY KEY, content)
6740: 3b 5c 6e 22 0a 0a 20 20 66 6f 72 65 61 63 68 20  ;\n"..  foreach 
6750: 66 20 5b 61 72 72 61 79 20 6e 61 6d 65 73 20 66  f [array names f
6760: 72 61 6d 65 73 5d 20 7b 0a 20 20 20 20 73 65 74  rames] {.    set
6770: 20 61 64 64 72 20 5b 66 6f 72 6d 61 74 20 25 78   addr [format %x
6780: 20 24 66 5d 0a 20 20 20 20 73 65 74 20 63 6d 64   $f].    set cmd
6790: 20 22 61 64 64 72 32 6c 69 6e 65 20 2d 65 20 5b   "addr2line -e [
67a0: 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63 5d  info nameofexec]
67b0: 20 24 61 64 64 72 22 0a 20 20 20 20 73 65 74 20   $addr".    set 
67c0: 6c 69 6e 65 20 5b 65 76 61 6c 20 65 78 65 63 20  line [eval exec 
67d0: 24 63 6d 64 5d 0a 20 20 20 20 61 70 70 65 6e 64  $cmd].    append
67e0: 20 73 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54   sql "INSERT INT
67f0: 4f 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 66 72  O ${database}.fr
6800: 61 6d 65 20 56 41 4c 55 45 53 28 24 66 2c 20 27  ame VALUES($f, '
6810: 24 6c 69 6e 65 27 29 3b 5c 6e 22 0a 0a 20 20 20  $line');\n"..   
6820: 20 73 65 74 20 66 69 6c 65 20 5b 6c 69 6e 64 65   set file [linde
6830: 78 20 5b 73 70 6c 69 74 20 24 6c 69 6e 65 20 3a  x [split $line :
6840: 5d 20 30 5d 0a 20 20 20 20 73 65 74 20 66 69 6c  ] 0].    set fil
6850: 65 73 28 24 66 69 6c 65 29 20 31 0a 20 20 7d 0a  es($file) 1.  }.
6860: 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 61 72  .  foreach f [ar
6870: 72 61 79 20 6e 61 6d 65 73 20 66 69 6c 65 73 5d  ray names files]
6880: 20 7b 0a 20 20 20 20 73 65 74 20 63 6f 6e 74 65   {.    set conte
6890: 6e 74 73 20 22 22 0a 20 20 20 20 63 61 74 63 68  nts "".    catch
68a0: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 66 64 20   {.      set fd 
68b0: 5b 6f 70 65 6e 20 24 66 5d 0a 20 20 20 20 20 20  [open $f].      
68c0: 73 65 74 20 63 6f 6e 74 65 6e 74 73 20 5b 72 65  set contents [re
68d0: 61 64 20 24 66 64 5d 0a 20 20 20 20 20 20 63 6c  ad $fd].      cl
68e0: 6f 73 65 20 24 66 64 0a 20 20 20 20 7d 0a 20 20  ose $fd.    }.  
68f0: 20 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20 5b    set contents [
6900: 73 74 72 69 6e 67 20 6d 61 70 20 7b 27 20 27 27  string map {' ''
6910: 7d 20 24 63 6f 6e 74 65 6e 74 73 5d 0a 20 20 20  } $contents].   
6920: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 49 4e 53   append sql "INS
6930: 45 52 54 20 49 4e 54 4f 20 24 7b 64 61 74 61 62  ERT INTO ${datab
6940: 61 73 65 7d 2e 66 69 6c 65 20 56 41 4c 55 45 53  ase}.file VALUES
6950: 28 27 24 66 27 2c 20 27 24 63 6f 6e 74 65 6e 74  ('$f', '$content
6960: 73 27 29 3b 5c 6e 22 0a 20 20 7d 0a 0a 20 20 73  s');\n".  }..  s
6970: 65 74 20 66 64 20 5b 6f 70 65 6e 20 24 66 69 6c  et fd [open $fil
6980: 65 6e 61 6d 65 20 77 5d 0a 20 20 70 75 74 73 20  ename w].  puts 
6990: 24 66 64 20 22 42 45 47 49 4e 3b 20 24 7b 74 62  $fd "BEGIN; ${tb
69a0: 6c 7d 24 7b 74 62 6c 32 7d 24 7b 74 62 6c 33 7d  l}${tbl2}${tbl3}
69b0: 24 7b 73 71 6c 7d 20 3b 20 43 4f 4d 4d 49 54 3b  ${sql} ; COMMIT;
69c0: 22 0a 20 20 63 6c 6f 73 65 20 24 66 64 0a 7d 0a  ".  close $fd.}.
69d0: 0a 23 20 43 6f 70 79 20 66 69 6c 65 20 24 66 72  .# Copy file $fr
69e0: 6f 6d 20 69 6e 74 6f 20 24 74 6f 2e 20 54 68 69  om into $to. Thi
69f0: 73 20 69 73 20 75 73 65 64 20 62 65 63 61 75 73  s is used becaus
6a00: 65 20 73 6f 6d 65 20 76 65 72 73 69 6f 6e 73 20  e some versions 
6a10: 6f 66 0a 23 20 54 43 4c 20 66 6f 72 20 77 69 6e  of.# TCL for win
6a20: 64 6f 77 73 20 28 6e 6f 74 61 62 6c 79 20 74 68  dows (notably th
6a30: 65 20 38 2e 34 2e 31 20 62 69 6e 61 72 79 20 70  e 8.4.1 binary p
6a40: 61 63 6b 61 67 65 20 73 68 69 70 70 65 64 20 77  ackage shipped w
6a50: 69 74 68 20 74 68 65 0a 23 20 63 75 72 72 65 6e  ith the.# curren
6a60: 74 20 6d 69 6e 67 77 20 72 65 6c 65 61 73 65 29  t mingw release)
6a70: 20 68 61 76 65 20 61 20 62 72 6f 6b 65 6e 20 22   have a broken "
6a80: 66 69 6c 65 20 63 6f 70 79 22 20 63 6f 6d 6d 61  file copy" comma
6a90: 6e 64 2e 0a 23 0a 70 72 6f 63 20 63 6f 70 79 5f  nd..#.proc copy_
6aa0: 66 69 6c 65 20 7b 66 72 6f 6d 20 74 6f 7d 20 7b  file {from to} {
6ab0: 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c  .  if {$::tcl_pl
6ac0: 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29  atform(platform)
6ad0: 3d 3d 22 75 6e 69 78 22 7d 20 7b 0a 20 20 20 20  =="unix"} {.    
6ae0: 66 69 6c 65 20 63 6f 70 79 20 2d 66 6f 72 63 65  file copy -force
6af0: 20 24 66 72 6f 6d 20 24 74 6f 0a 20 20 7d 20 65   $from $to.  } e
6b00: 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 66 20  lse {.    set f 
6b10: 5b 6f 70 65 6e 20 24 66 72 6f 6d 5d 0a 20 20 20  [open $from].   
6b20: 20 66 63 6f 6e 66 69 67 75 72 65 20 24 66 20 2d   fconfigure $f -
6b30: 74 72 61 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61  translation bina
6b40: 72 79 0a 20 20 20 20 73 65 74 20 74 20 5b 6f 70  ry.    set t [op
6b50: 65 6e 20 24 74 6f 20 77 5d 0a 20 20 20 20 66 63  en $to w].    fc
6b60: 6f 6e 66 69 67 75 72 65 20 24 74 20 2d 74 72 61  onfigure $t -tra
6b70: 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 0a  nslation binary.
6b80: 20 20 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c      puts -nonewl
6b90: 69 6e 65 20 24 74 20 5b 72 65 61 64 20 24 66 20  ine $t [read $f 
6ba0: 5b 66 69 6c 65 20 73 69 7a 65 20 24 66 72 6f 6d  [file size $from
6bb0: 5d 5d 0a 20 20 20 20 63 6c 6f 73 65 20 24 74 0a  ]].    close $t.
6bc0: 20 20 20 20 63 6c 6f 73 65 20 24 66 0a 20 20 7d      close $f.  }
6bd0: 0a 7d 0a 0a 23 20 49 66 20 74 68 65 20 6c 69 62  .}..# If the lib
6be0: 72 61 72 79 20 69 73 20 63 6f 6d 70 69 6c 65 64  rary is compiled
6bf0: 20 77 69 74 68 20 74 68 65 20 53 51 4c 49 54 45   with the SQLITE
6c00: 5f 44 45 46 41 55 4c 54 5f 41 55 54 4f 56 41 43  _DEFAULT_AUTOVAC
6c10: 55 55 4d 20 6d 61 63 72 6f 20 73 65 74 0a 23 20  UUM macro set.# 
6c20: 74 6f 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65  to non-zero, the
6c30: 6e 20 73 65 74 20 74 68 65 20 67 6c 6f 62 61 6c  n set the global
6c40: 20 76 61 72 69 61 62 6c 65 20 24 41 55 54 4f 56   variable $AUTOV
6c50: 41 43 55 55 4d 20 74 6f 20 31 2e 0a 73 65 74 20  ACUUM to 1..set 
6c60: 41 55 54 4f 56 41 43 55 55 4d 20 24 73 71 6c 69  AUTOVACUUM $sqli
6c70: 74 65 5f 6f 70 74 69 6f 6e 73 28 64 65 66 61 75  te_options(defau
6c80: 6c 74 5f 61 75 74 6f 76 61 63 75 75 6d 29 0a     lt_autovacuum).