/ Hex Artifact Content
Login

Artifact 7e6e28cf813e132b84336cdd33804c1be2a1bc80:


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 30 39 20 32 30 30 38 2f 30 33 2f 32   1.109 2008/03/2
01f0: 31 20 31 37 3a 32 39 3a 33 38 20 64 61 6e 69 65  1 17:29:38 danie
0200: 6c 6b 31 39 37 37 20 45 78 70 20 24 0a 0a 0a 73  lk1977 Exp $...s
0210: 65 74 20 74 63 6c 5f 70 72 65 63 69 73 69 6f 6e  et tcl_precision
0220: 20 31 35 0a 73 65 74 20 73 71 6c 69 74 65 5f 70   15.set sqlite_p
0230: 65 6e 64 69 6e 67 5f 62 79 74 65 20 30 78 30 30  ending_byte 0x00
0240: 31 30 30 30 30 0a 0a 23 20 0a 23 20 43 68 65 63  10000..# .# Chec
0250: 6b 20 74 68 65 20 63 6f 6d 6d 61 6e 64 2d 6c 69  k the command-li
0260: 6e 65 20 61 72 67 75 6d 65 6e 74 73 20 66 6f 72  ne arguments for
0270: 20 61 20 64 65 66 61 75 6c 74 20 73 6f 66 74 2d   a default soft-
0280: 68 65 61 70 2d 6c 69 6d 69 74 2e 0a 23 20 53 74  heap-limit..# St
0290: 6f 72 65 20 74 68 69 73 20 64 65 66 61 75 6c 74  ore this default
02a0: 20 76 61 6c 75 65 20 69 6e 20 74 68 65 20 67 6c   value in the gl
02b0: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 20 3a 3a  obal variable ::
02c0: 73 6f 66 74 5f 6c 69 6d 69 74 20 61 6e 64 0a 23  soft_limit and.#
02d0: 20 75 70 64 61 74 65 20 74 68 65 20 73 6f 66 74   update the soft
02e0: 2d 68 65 61 70 2d 6c 69 6d 69 74 20 65 61 63 68  -heap-limit each
02f0: 20 74 69 6d 65 20 74 68 69 73 20 73 63 72 69 70   time this scrip
0300: 74 20 69 73 20 72 75 6e 2e 20 20 49 6e 20 74 68  t is run.  In th
0310: 61 74 0a 23 20 77 61 79 20 69 66 20 61 6e 20 69  at.# way if an i
0320: 6e 64 69 76 69 64 75 61 6c 20 74 65 73 74 20 66  ndividual test f
0330: 69 6c 65 20 63 68 61 6e 67 65 73 20 74 68 65 20  ile changes the 
0340: 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 2c  soft-heap-limit,
0350: 20 69 74 0a 23 20 77 69 6c 6c 20 62 65 20 72 65   it.# will be re
0360: 73 65 74 20 61 74 20 74 68 65 20 73 74 61 72 74  set at the start
0370: 20 6f 66 20 74 68 65 20 6e 65 78 74 20 74 65 73   of the next tes
0380: 74 20 66 69 6c 65 2e 0a 23 0a 69 66 20 7b 21 5b  t file..#.if {![
0390: 69 6e 66 6f 20 65 78 69 73 74 73 20 73 6f 66 74  info exists soft
03a0: 5f 6c 69 6d 69 74 5d 7d 20 7b 0a 20 20 73 65 74  _limit]} {.  set
03b0: 20 73 6f 66 74 5f 6c 69 6d 69 74 20 30 0a 20 20   soft_limit 0.  
03c0: 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24  for {set i 0} {$
03d0: 69 3c 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 76  i<[llength $argv
03e0: 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  ]} {incr i} {.  
03f0: 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e    if {[regexp {^
0400: 2d 2d 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69  --soft-heap-limi
0410: 74 3d 28 2e 2b 29 24 7d 20 5b 6c 69 6e 64 65 78  t=(.+)$} [lindex
0420: 20 24 61 72 67 76 20 24 69 5d 20 61 6c 6c 20 76   $argv $i] all v
0430: 61 6c 75 65 5d 7d 20 7b 0a 20 20 20 20 20 20 69  alue]} {.      i
0440: 66 20 7b 24 76 61 6c 75 65 21 3d 22 6f 66 66 22  f {$value!="off"
0450: 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  } {.        set 
0460: 73 6f 66 74 5f 6c 69 6d 69 74 20 24 76 61 6c 75  soft_limit $valu
0470: 65 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  e.      }.      
0480: 73 65 74 20 61 72 67 76 20 5b 6c 72 65 70 6c 61  set argv [lrepla
0490: 63 65 20 24 61 72 67 76 20 24 69 20 24 69 5d 0a  ce $argv $i $i].
04a0: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 73 71 6c 69      }.  }.}.sqli
04b0: 74 65 33 5f 73 6f 66 74 5f 68 65 61 70 5f 6c 69  te3_soft_heap_li
04c0: 6d 69 74 20 24 73 6f 66 74 5f 6c 69 6d 69 74 0a  mit $soft_limit.
04d0: 0a 23 20 0a 23 20 43 68 65 63 6b 20 74 68 65 20  .# .# Check the 
04e0: 63 6f 6d 6d 61 6e 64 2d 6c 69 6e 65 20 61 72 67  command-line arg
04f0: 75 6d 65 6e 74 73 20 74 6f 20 73 65 74 20 74 68  uments to set th
0500: 65 20 6d 65 6d 6f 72 79 20 64 65 62 75 67 67 65  e memory debugge
0510: 72 0a 23 20 62 61 63 6b 74 72 61 63 65 20 64 65  r.# backtrace de
0520: 70 74 68 2e 0a 23 0a 23 20 53 65 65 20 74 68 65  pth..#.# See the
0530: 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75   sqlite3_memdebu
0540: 67 5f 62 61 63 6b 74 72 61 63 65 28 29 20 66 75  g_backtrace() fu
0550: 6e 63 74 69 6f 6e 20 69 6e 20 6d 65 6d 32 2e 63  nction in mem2.c
0560: 20 6f 72 0a 23 20 74 65 73 74 5f 6d 61 6c 6c 6f   or.# test_mallo
0570: 63 2e 63 20 66 6f 72 20 61 64 64 69 74 69 6f 6e  c.c for addition
0580: 61 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 0a  al information..
0590: 23 0a 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20  #.for {set i 0} 
05a0: 7b 24 69 3c 5b 6c 6c 65 6e 67 74 68 20 24 61 72  {$i<[llength $ar
05b0: 67 76 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a  gv]} {incr i} {.
05c0: 20 20 69 66 20 7b 5b 6c 69 6e 64 65 78 20 24 61    if {[lindex $a
05d0: 72 67 76 20 24 69 5d 20 65 71 20 22 2d 2d 6d 61  rgv $i] eq "--ma
05e0: 6c 6c 6f 63 74 72 61 63 65 22 7d 20 7b 0a 20 20  lloctrace"} {.  
05f0: 20 20 73 65 74 20 61 72 67 76 20 5b 6c 72 65 70    set argv [lrep
0600: 6c 61 63 65 20 24 61 72 67 76 20 24 69 20 24 69  lace $argv $i $i
0610: 5d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65  ].    sqlite3_me
0620: 6d 64 65 62 75 67 5f 62 61 63 6b 74 72 61 63 65  mdebug_backtrace
0630: 20 35 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d   5.    sqlite3_m
0640: 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73 74 61 72  emdebug_log star
0650: 74 0a 20 20 20 20 73 65 74 20 61 72 67 76 20 5b  t.    set argv [
0660: 6c 72 65 70 6c 61 63 65 20 24 61 72 67 76 20 24  lreplace $argv $
0670: 69 20 24 69 5d 0a 20 20 20 20 73 65 74 20 74 65  i $i].    set te
0680: 73 74 65 72 5f 64 6f 5f 6d 61 6c 6c 6f 63 74 72  ster_do_malloctr
0690: 61 63 65 20 31 0a 20 20 7d 0a 7d 0a 66 6f 72 20  ace 1.  }.}.for 
06a0: 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 3c 5b 6c  {set i 0} {$i<[l
06b0: 6c 65 6e 67 74 68 20 24 61 72 67 76 5d 7d 20 7b  length $argv]} {
06c0: 69 6e 63 72 20 69 7d 20 7b 0a 20 20 69 66 20 7b  incr i} {.  if {
06d0: 5b 72 65 67 65 78 70 20 7b 5e 2d 2d 62 61 63 6b  [regexp {^--back
06e0: 74 72 61 63 65 3d 28 5c 64 2b 29 24 7d 20 5b 6c  trace=(\d+)$} [l
06f0: 69 6e 64 65 78 20 24 61 72 67 76 20 24 69 5d 20  index $argv $i] 
0700: 61 6c 6c 20 76 61 6c 75 65 5d 7d 20 7b 0a 20 20  all value]} {.  
0710: 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62    sqlite3_memdeb
0720: 75 67 5f 62 61 63 6b 74 72 61 63 65 20 24 76 61  ug_backtrace $va
0730: 6c 75 65 0a 20 20 20 20 73 65 74 20 61 72 67 76  lue.    set argv
0740: 20 5b 6c 72 65 70 6c 61 63 65 20 24 61 72 67 76   [lreplace $argv
0750: 20 24 69 20 24 69 5d 0a 20 20 7d 0a 7d 0a 0a 23   $i $i].  }.}..#
0760: 20 0a 23 20 43 68 65 63 6b 20 74 68 65 20 63 6f   .# Check the co
0770: 6d 6d 61 6e 64 2d 6c 69 6e 65 20 61 72 67 75 6d  mmand-line argum
0780: 65 6e 74 73 20 74 6f 20 73 65 74 20 74 68 65 20  ents to set the 
0790: 6d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f  maximum number o
07a0: 66 0a 23 20 65 72 72 6f 72 73 20 74 6f 6c 65 72  f.# errors toler
07b0: 61 74 65 64 20 62 65 66 6f 72 65 20 68 61 6c 74  ated before halt
07c0: 69 6e 67 2e 0a 23 0a 69 66 20 7b 21 5b 69 6e 66  ing..#.if {![inf
07d0: 6f 20 65 78 69 73 74 73 20 6d 61 78 45 72 72 5d  o exists maxErr]
07e0: 7d 20 7b 0a 20 20 73 65 74 20 6d 61 78 45 72 72  } {.  set maxErr
07f0: 20 31 30 30 30 0a 7d 0a 66 6f 72 20 7b 73 65 74   1000.}.for {set
0800: 20 69 20 30 7d 20 7b 24 69 3c 5b 6c 6c 65 6e 67   i 0} {$i<[lleng
0810: 74 68 20 24 61 72 67 76 5d 7d 20 7b 69 6e 63 72  th $argv]} {incr
0820: 20 69 7d 20 7b 0a 20 20 69 66 20 7b 5b 72 65 67   i} {.  if {[reg
0830: 65 78 70 20 7b 5e 2d 2d 6d 61 78 65 72 72 6f 72  exp {^--maxerror
0840: 3d 28 5c 64 2b 29 24 7d 20 5b 6c 69 6e 64 65 78  =(\d+)$} [lindex
0850: 20 24 61 72 67 76 20 24 69 5d 20 61 6c 6c 20 6d   $argv $i] all m
0860: 61 78 45 72 72 5d 7d 20 7b 0a 20 20 20 20 73 65  axErr]} {.    se
0870: 74 20 61 72 67 76 20 5b 6c 72 65 70 6c 61 63 65  t argv [lreplace
0880: 20 24 61 72 67 76 20 24 69 20 24 69 5d 0a 20 20   $argv $i $i].  
0890: 7d 0a 7d 0a 23 70 75 74 73 20 22 4d 61 78 20 65  }.}.#puts "Max e
08a0: 72 72 6f 72 20 3d 20 24 6d 61 78 45 72 72 22 0a  rror = $maxErr".
08b0: 0a 0a 23 20 55 73 65 20 74 68 65 20 70 61 67 65  ..# Use the page
08c0: 72 20 63 6f 64 65 63 20 69 66 20 69 74 20 69 73  r codec if it is
08d0: 20 61 76 61 69 6c 61 62 6c 65 0a 23 0a 69 66 20   available.#.if 
08e0: 7b 5b 73 71 6c 69 74 65 33 20 2d 68 61 73 2d 63  {[sqlite3 -has-c
08f0: 6f 64 65 63 5d 20 26 26 20 5b 69 6e 66 6f 20 63  odec] && [info c
0900: 6f 6d 6d 61 6e 64 20 73 71 6c 69 74 65 5f 6f 72  ommand sqlite_or
0910: 69 67 5d 3d 3d 22 22 7d 20 7b 0a 20 20 72 65 6e  ig]==""} {.  ren
0920: 61 6d 65 20 73 71 6c 69 74 65 33 20 73 71 6c 69  ame sqlite3 sqli
0930: 74 65 5f 6f 72 69 67 0a 20 20 70 72 6f 63 20 73  te_orig.  proc s
0940: 71 6c 69 74 65 33 20 7b 61 72 67 73 7d 20 7b 0a  qlite3 {args} {.
0950: 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68      if {[llength
0960: 20 24 61 72 67 73 5d 3d 3d 32 20 26 26 20 5b 73   $args]==2 && [s
0970: 74 72 69 6e 67 20 69 6e 64 65 78 20 5b 6c 69 6e  tring index [lin
0980: 64 65 78 20 24 61 72 67 73 20 30 5d 20 30 5d 21  dex $args 0] 0]!
0990: 3d 22 2d 22 7d 20 7b 0a 20 20 20 20 20 20 6c 61  ="-"} {.      la
09a0: 70 70 65 6e 64 20 61 72 67 73 20 2d 6b 65 79 20  ppend args -key 
09b0: 7b 78 79 7a 7a 79 7d 0a 20 20 20 20 7d 0a 20 20  {xyzzy}.    }.  
09c0: 20 20 75 70 6c 65 76 65 6c 20 31 20 73 71 6c 69    uplevel 1 sqli
09d0: 74 65 5f 6f 72 69 67 20 24 61 72 67 73 0a 20 20  te_orig $args.  
09e0: 7d 0a 7d 0a 0a 0a 23 20 43 72 65 61 74 65 20 61  }.}...# Create a
09f0: 20 74 65 73 74 20 64 61 74 61 62 61 73 65 0a 23   test database.#
0a00: 0a 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65  .catch {db close
0a10: 7d 0a 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66  }.file delete -f
0a20: 6f 72 63 65 20 74 65 73 74 2e 64 62 0a 66 69 6c  orce test.db.fil
0a30: 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20  e delete -force 
0a40: 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 0a  test.db-journal.
0a50: 73 71 6c 69 74 65 33 20 64 62 20 2e 2f 74 65 73  sqlite3 db ./tes
0a60: 74 2e 64 62 0a 73 65 74 20 3a 3a 44 42 20 5b 73  t.db.set ::DB [s
0a70: 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f  qlite3_connectio
0a80: 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a 69 66  n_pointer db].if
0a90: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
0aa0: 3a 53 45 54 55 50 5f 53 51 4c 5d 7d 20 7b 0a 20  :SETUP_SQL]} {. 
0ab0: 20 64 62 20 65 76 61 6c 20 24 3a 3a 53 45 54 55   db eval $::SETU
0ac0: 50 5f 53 51 4c 0a 7d 0a 0a 23 20 41 62 6f 72 74  P_SQL.}..# Abort
0ad0: 20 65 61 72 6c 79 20 69 66 20 74 68 69 73 20 73   early if this s
0ae0: 63 72 69 70 74 20 68 61 73 20 62 65 65 6e 20 72  cript has been r
0af0: 75 6e 20 62 65 66 6f 72 65 2e 0a 23 0a 69 66 20  un before..#.if 
0b00: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 6e 54  {[info exists nT
0b10: 65 73 74 5d 7d 20 72 65 74 75 72 6e 0a 0a 23 20  est]} return..# 
0b20: 53 65 74 20 74 68 65 20 74 65 73 74 20 63 6f 75  Set the test cou
0b30: 6e 74 65 72 73 20 74 6f 20 7a 65 72 6f 0a 23 0a  nters to zero.#.
0b40: 73 65 74 20 6e 45 72 72 20 30 0a 73 65 74 20 6e  set nErr 0.set n
0b50: 54 65 73 74 20 30 0a 73 65 74 20 73 6b 69 70 5f  Test 0.set skip_
0b60: 74 65 73 74 20 30 0a 73 65 74 20 66 61 69 6c 4c  test 0.set failL
0b70: 69 73 74 20 7b 7d 0a 69 66 20 7b 21 5b 69 6e 66  ist {}.if {![inf
0b80: 6f 20 65 78 69 73 74 73 20 73 70 65 65 64 54 65  o exists speedTe
0b90: 73 74 5d 7d 20 7b 0a 20 20 73 65 74 20 73 70 65  st]} {.  set spe
0ba0: 65 64 54 65 73 74 20 30 0a 7d 0a 0a 23 20 49 6e  edTest 0.}..# In
0bb0: 76 6f 6b 65 20 74 68 65 20 64 6f 5f 74 65 73 74  voke the do_test
0bc0: 20 70 72 6f 63 65 64 75 72 65 20 74 6f 20 72 75   procedure to ru
0bd0: 6e 20 61 20 73 69 6e 67 6c 65 20 74 65 73 74 20  n a single test 
0be0: 0a 23 0a 70 72 6f 63 20 64 6f 5f 74 65 73 74 20  .#.proc do_test 
0bf0: 7b 6e 61 6d 65 20 63 6d 64 20 65 78 70 65 63 74  {name cmd expect
0c00: 65 64 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 61  ed} {.  global a
0c10: 72 67 76 20 6e 45 72 72 20 6e 54 65 73 74 20 73  rgv nErr nTest s
0c20: 6b 69 70 5f 74 65 73 74 20 6d 61 78 45 72 72 0a  kip_test maxErr.
0c30: 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62    sqlite3_memdeb
0c40: 75 67 5f 73 65 74 74 69 74 6c 65 20 24 6e 61 6d  ug_settitle $nam
0c50: 65 0a 20 20 69 66 20 7b 24 73 6b 69 70 5f 74 65  e.  if {$skip_te
0c60: 73 74 7d 20 7b 0a 20 20 20 20 73 65 74 20 73 6b  st} {.    set sk
0c70: 69 70 5f 74 65 73 74 20 30 0a 20 20 20 20 72 65  ip_test 0.    re
0c80: 74 75 72 6e 0a 20 20 7d 0a 20 20 69 66 20 7b 5b  turn.  }.  if {[
0c90: 6c 6c 65 6e 67 74 68 20 24 61 72 67 76 5d 3d 3d  llength $argv]==
0ca0: 30 7d 20 7b 20 0a 20 20 20 20 73 65 74 20 67 6f  0} { .    set go
0cb0: 20 31 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20   1.  } else {.  
0cc0: 20 20 73 65 74 20 67 6f 20 30 0a 20 20 20 20 66    set go 0.    f
0cd0: 6f 72 65 61 63 68 20 70 61 74 74 65 72 6e 20 24  oreach pattern $
0ce0: 61 72 67 76 20 7b 0a 20 20 20 20 20 20 69 66 20  argv {.      if 
0cf0: 7b 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20 24  {[string match $
0d00: 70 61 74 74 65 72 6e 20 24 6e 61 6d 65 5d 7d 20  pattern $name]} 
0d10: 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 67 6f  {.        set go
0d20: 20 31 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b   1.        break
0d30: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
0d40: 20 7d 0a 20 20 69 66 20 7b 21 24 67 6f 7d 20 72   }.  if {!$go} r
0d50: 65 74 75 72 6e 0a 20 20 69 6e 63 72 20 6e 54 65  eturn.  incr nTe
0d60: 73 74 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77  st.  puts -nonew
0d70: 6c 69 6e 65 20 24 6e 61 6d 65 2e 2e 2e 0a 20 20  line $name....  
0d80: 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20 69  flush stdout.  i
0d90: 66 20 7b 5b 63 61 74 63 68 20 7b 75 70 6c 65 76  f {[catch {uplev
0da0: 65 6c 20 23 30 20 22 24 63 6d 64 3b 5c 6e 22 7d  el #0 "$cmd;\n"}
0db0: 20 72 65 73 75 6c 74 5d 7d 20 7b 0a 20 20 20 20   result]} {.    
0dc0: 70 75 74 73 20 22 5c 6e 45 72 72 6f 72 3a 20 24  puts "\nError: $
0dd0: 72 65 73 75 6c 74 22 0a 20 20 20 20 69 6e 63 72  result".    incr
0de0: 20 6e 45 72 72 0a 20 20 20 20 6c 61 70 70 65 6e   nErr.    lappen
0df0: 64 20 3a 3a 66 61 69 6c 4c 69 73 74 20 24 6e 61  d ::failList $na
0e00: 6d 65 0a 20 20 20 20 69 66 20 7b 24 6e 45 72 72  me.    if {$nErr
0e10: 3e 24 6d 61 78 45 72 72 7d 20 7b 70 75 74 73 20  >$maxErr} {puts 
0e20: 22 2a 2a 2a 20 47 69 76 69 6e 67 20 75 70 2e 2e  "*** Giving up..
0e30: 2e 22 3b 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73  ."; finalize_tes
0e40: 74 69 6e 67 7d 0a 20 20 7d 20 65 6c 73 65 69 66  ting}.  } elseif
0e50: 20 7b 5b 73 74 72 69 6e 67 20 63 6f 6d 70 61 72   {[string compar
0e60: 65 20 24 72 65 73 75 6c 74 20 24 65 78 70 65 63  e $result $expec
0e70: 74 65 64 5d 7d 20 7b 0a 20 20 20 20 70 75 74 73  ted]} {.    puts
0e80: 20 22 5c 6e 45 78 70 65 63 74 65 64 3a 20 5c 5b   "\nExpected: \[
0e90: 24 65 78 70 65 63 74 65 64 5c 5d 5c 6e 20 20 20  $expected\]\n   
0ea0: 20 20 47 6f 74 3a 20 5c 5b 24 72 65 73 75 6c 74    Got: \[$result
0eb0: 5c 5d 22 0a 20 20 20 20 69 6e 63 72 20 6e 45 72  \]".    incr nEr
0ec0: 72 0a 20 20 20 20 6c 61 70 70 65 6e 64 20 3a 3a  r.    lappend ::
0ed0: 66 61 69 6c 4c 69 73 74 20 24 6e 61 6d 65 0a 20  failList $name. 
0ee0: 20 20 20 69 66 20 7b 24 6e 45 72 72 3e 3d 24 6d     if {$nErr>=$m
0ef0: 61 78 45 72 72 7d 20 7b 70 75 74 73 20 22 2a 2a  axErr} {puts "**
0f00: 2a 20 47 69 76 69 6e 67 20 75 70 2e 2e 2e 22 3b  * Giving up...";
0f10: 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e   finalize_testin
0f20: 67 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  g}.  } else {.  
0f30: 20 20 70 75 74 73 20 22 20 4f 6b 22 0a 20 20 7d    puts " Ok".  }
0f40: 0a 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a  .  flush stdout.
0f50: 7d 0a 0a 23 20 52 75 6e 20 61 6e 20 53 51 4c 20  }..# Run an SQL 
0f60: 73 63 72 69 70 74 2e 20 20 0a 23 20 52 65 74 75  script.  .# Retu
0f70: 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  rn the number of
0f80: 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73 20 70 65   microseconds pe
0f90: 72 20 73 74 61 74 65 6d 65 6e 74 2e 0a 23 0a 70  r statement..#.p
0fa0: 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c 20  roc speed_trial 
0fb0: 7b 6e 61 6d 65 20 6e 75 6d 73 74 6d 74 20 75 6e  {name numstmt un
0fc0: 69 74 73 20 73 71 6c 7d 20 7b 0a 20 20 70 75 74  its sql} {.  put
0fd0: 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b 66 6f  s -nonewline [fo
0fe0: 72 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73 20 7d  rmat {%-21.21s }
0ff0: 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66 6c 75   $name...].  flu
1000: 73 68 20 73 74 64 6f 75 74 0a 20 20 73 65 74 20  sh stdout.  set 
1010: 73 70 65 65 64 20 5b 74 69 6d 65 20 7b 73 71 6c  speed [time {sql
1020: 69 74 65 33 5f 65 78 65 63 5f 6e 72 20 64 62 20  ite3_exec_nr db 
1030: 24 73 71 6c 7d 5d 0a 20 20 73 65 74 20 74 6d 20  $sql}].  set tm 
1040: 5b 6c 69 6e 64 65 78 20 24 73 70 65 65 64 20 30  [lindex $speed 0
1050: 5d 0a 20 20 69 66 20 7b 24 74 6d 20 3d 3d 20 30  ].  if {$tm == 0
1060: 7d 20 7b 0a 20 20 20 20 73 65 74 20 72 61 74 65  } {.    set rate
1070: 20 5b 66 6f 72 6d 61 74 20 25 32 30 73 20 22 6d   [format %20s "m
1080: 61 6e 79 22 5d 0a 20 20 7d 20 65 6c 73 65 20 7b  any"].  } else {
1090: 0a 20 20 20 20 73 65 74 20 72 61 74 65 20 5b 66  .    set rate [f
10a0: 6f 72 6d 61 74 20 25 32 30 2e 35 66 20 5b 65 78  ormat %20.5f [ex
10b0: 70 72 20 7b 31 30 30 30 30 30 30 2e 30 2a 24 6e  pr {1000000.0*$n
10c0: 75 6d 73 74 6d 74 2f 24 74 6d 7d 5d 5d 0a 20 20  umstmt/$tm}]].  
10d0: 7d 0a 20 20 73 65 74 20 75 32 20 24 75 6e 69 74  }.  set u2 $unit
10e0: 73 2f 73 0a 20 20 70 75 74 73 20 5b 66 6f 72 6d  s/s.  puts [form
10f0: 61 74 20 7b 25 31 32 64 20 75 53 20 25 73 20 25  at {%12d uS %s %
1100: 73 7d 20 24 74 6d 20 24 72 61 74 65 20 24 75 32  s} $tm $rate $u2
1110: 5d 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c  ].  global total
1120: 5f 74 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61  _time.  set tota
1130: 6c 5f 74 69 6d 65 20 5b 65 78 70 72 20 7b 24 74  l_time [expr {$t
1140: 6f 74 61 6c 5f 74 69 6d 65 2b 24 74 6d 7d 5d 0a  otal_time+$tm}].
1150: 7d 0a 70 72 6f 63 20 73 70 65 65 64 5f 74 72 69  }.proc speed_tri
1160: 61 6c 5f 69 6e 69 74 20 7b 6e 61 6d 65 7d 20 7b  al_init {name} {
1170: 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f  .  global total_
1180: 74 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61 6c  time.  set total
1190: 5f 74 69 6d 65 20 30 0a 7d 0a 70 72 6f 63 20 73  _time 0.}.proc s
11a0: 70 65 65 64 5f 74 72 69 61 6c 5f 73 75 6d 6d 61  peed_trial_summa
11b0: 72 79 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c  ry {name} {.  gl
11c0: 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a  obal total_time.
11d0: 20 20 70 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b    puts [format {
11e0: 25 2d 32 31 2e 32 31 73 20 25 31 32 64 20 75 53  %-21.21s %12d uS
11f0: 20 54 4f 54 41 4c 7d 20 24 6e 61 6d 65 20 24 74   TOTAL} $name $t
1200: 6f 74 61 6c 5f 74 69 6d 65 5d 0a 7d 0a 0a 23 20  otal_time].}..# 
1210: 52 75 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65  Run this routine
1220: 20 6c 61 73 74 0a 23 0a 70 72 6f 63 20 66 69 6e   last.#.proc fin
1230: 69 73 68 5f 74 65 73 74 20 7b 7d 20 7b 0a 20 20  ish_test {} {.  
1240: 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67  finalize_testing
1250: 0a 7d 0a 70 72 6f 63 20 66 69 6e 61 6c 69 7a 65  .}.proc finalize
1260: 5f 74 65 73 74 69 6e 67 20 7b 7d 20 7b 0a 20 20  _testing {} {.  
1270: 67 6c 6f 62 61 6c 20 6e 54 65 73 74 20 6e 45 72  global nTest nEr
1280: 72 20 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69  r sqlite_open_fi
1290: 6c 65 5f 63 6f 75 6e 74 0a 0a 20 20 63 61 74 63  le_count..  catc
12a0: 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 63  h {db close}.  c
12b0: 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d  atch {db2 close}
12c0: 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20 63 6c  .  catch {db3 cl
12d0: 6f 73 65 7d 0a 0a 20 20 76 66 73 5f 75 6e 6c 69  ose}..  vfs_unli
12e0: 6e 6b 5f 74 65 73 74 0a 20 20 73 71 6c 69 74 65  nk_test.  sqlite
12f0: 33 20 64 62 20 7b 7d 0a 20 20 23 20 73 71 6c 69  3 db {}.  # sqli
1300: 74 65 33 5f 63 6c 65 61 72 5f 74 73 64 5f 6d 65  te3_clear_tsd_me
1310: 6d 64 65 62 75 67 0a 20 20 64 62 20 63 6c 6f 73  mdebug.  db clos
1320: 65 0a 20 20 73 71 6c 69 74 65 33 5f 72 65 73 65  e.  sqlite3_rese
1330: 74 5f 61 75 74 6f 5f 65 78 74 65 6e 73 69 6f 6e  t_auto_extension
1340: 0a 20 20 73 65 74 20 68 65 61 70 6c 69 6d 69 74  .  set heaplimit
1350: 20 5b 73 71 6c 69 74 65 33 5f 73 6f 66 74 5f 68   [sqlite3_soft_h
1360: 65 61 70 5f 6c 69 6d 69 74 5d 0a 20 20 69 66 20  eap_limit].  if 
1370: 7b 24 68 65 61 70 6c 69 6d 69 74 21 3d 24 3a 3a  {$heaplimit!=$::
1380: 73 6f 66 74 5f 6c 69 6d 69 74 7d 20 7b 0a 20 20  soft_limit} {.  
1390: 20 20 70 75 74 73 20 22 73 6f 66 74 2d 68 65 61    puts "soft-hea
13a0: 70 2d 6c 69 6d 69 74 20 63 68 61 6e 67 65 64 20  p-limit changed 
13b0: 62 79 20 74 68 69 73 20 73 63 72 69 70 74 5c 0a  by this script\.
13c0: 20 20 20 20 20 20 20 20 20 20 66 72 6f 6d 20 24            from $
13d0: 3a 3a 73 6f 66 74 5f 6c 69 6d 69 74 20 74 6f 20  ::soft_limit to 
13e0: 24 68 65 61 70 6c 69 6d 69 74 22 0a 20 20 7d 20  $heaplimit".  } 
13f0: 65 6c 73 65 69 66 20 7b 24 68 65 61 70 6c 69 6d  elseif {$heaplim
1400: 69 74 21 3d 22 22 20 26 26 20 24 68 65 61 70 6c  it!="" && $heapl
1410: 69 6d 69 74 3e 30 7d 20 7b 0a 20 20 20 20 70 75  imit>0} {.    pu
1420: 74 73 20 22 73 6f 66 74 2d 68 65 61 70 2d 6c 69  ts "soft-heap-li
1430: 6d 69 74 20 73 65 74 20 74 6f 20 24 68 65 61 70  mit set to $heap
1440: 6c 69 6d 69 74 22 0a 20 20 7d 0a 20 20 73 71 6c  limit".  }.  sql
1450: 69 74 65 33 5f 73 6f 66 74 5f 68 65 61 70 5f 6c  ite3_soft_heap_l
1460: 69 6d 69 74 20 30 0a 20 20 69 6e 63 72 20 6e 54  imit 0.  incr nT
1470: 65 73 74 0a 20 20 70 75 74 73 20 22 24 6e 45 72  est.  puts "$nEr
1480: 72 20 65 72 72 6f 72 73 20 6f 75 74 20 6f 66 20  r errors out of 
1490: 24 6e 54 65 73 74 20 74 65 73 74 73 22 0a 20 20  $nTest tests".  
14a0: 69 66 20 7b 24 6e 45 72 72 3e 30 7d 20 7b 0a 20  if {$nErr>0} {. 
14b0: 20 20 20 70 75 74 73 20 22 46 61 69 6c 75 72 65     puts "Failure
14c0: 73 20 6f 6e 20 74 68 65 73 65 20 74 65 73 74 73  s on these tests
14d0: 3a 20 24 3a 3a 66 61 69 6c 4c 69 73 74 22 0a 20  : $::failList". 
14e0: 20 7d 0a 20 20 69 66 20 7b 24 6e 45 72 72 3e 30   }.  if {$nErr>0
14f0: 20 26 26 20 21 5b 77 6f 72 6b 69 6e 67 5f 36 34   && ![working_64
1500: 62 69 74 5f 69 6e 74 5d 7d 20 7b 0a 20 20 20 20  bit_int]} {.    
1510: 70 75 74 73 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  puts "**********
1520: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1530: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1540: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1550: 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 20 20 70 75  ********".    pu
1560: 74 73 20 22 4e 2e 42 2e 3a 20 20 54 68 65 20 76  ts "N.B.:  The v
1570: 65 72 73 69 6f 6e 20 6f 66 20 54 43 4c 20 74 68  ersion of TCL th
1580: 61 74 20 79 6f 75 20 75 73 65 64 20 74 6f 20 62  at you used to b
1590: 75 69 6c 64 20 74 68 69 73 20 74 65 73 74 20 68  uild this test h
15a0: 61 72 6e 65 73 73 22 0a 20 20 20 20 70 75 74 73  arness".    puts
15b0: 20 22 69 73 20 64 65 66 65 63 74 69 76 65 20 69   "is defective i
15c0: 6e 20 74 68 61 74 20 69 74 20 64 6f 65 73 20 6e  n that it does n
15d0: 6f 74 20 73 75 70 70 6f 72 74 20 36 34 2d 62 69  ot support 64-bi
15e0: 74 20 69 6e 74 65 67 65 72 73 2e 20 20 53 6f 6d  t integers.  Som
15f0: 65 20 6f 72 22 0a 20 20 20 20 70 75 74 73 20 22  e or".    puts "
1600: 61 6c 6c 20 6f 66 20 74 68 65 20 74 65 73 74 20  all of the test 
1610: 66 61 69 6c 75 72 65 73 20 61 62 6f 76 65 20 6d  failures above m
1620: 69 67 68 74 20 62 65 20 61 20 72 65 73 75 6c 74  ight be a result
1630: 20 66 72 6f 6d 20 74 68 69 73 20 64 65 66 65 63   from this defec
1640: 74 22 0a 20 20 20 20 70 75 74 73 20 22 69 6e 20  t".    puts "in 
1650: 79 6f 75 72 20 54 43 4c 20 62 75 69 6c 64 2e 22  your TCL build."
1660: 0a 20 20 20 20 70 75 74 73 20 22 2a 2a 2a 2a 2a  .    puts "*****
1670: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1680: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1690: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
16a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20  *************". 
16b0: 20 7d 0a 20 20 69 66 20 7b 24 73 71 6c 69 74 65   }.  if {$sqlite
16c0: 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74  _open_file_count
16d0: 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 24 73  } {.    puts "$s
16e0: 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f  qlite_open_file_
16f0: 63 6f 75 6e 74 20 66 69 6c 65 73 20 77 65 72 65  count files were
1700: 20 6c 65 66 74 20 6f 70 65 6e 22 0a 20 20 20 20   left open".    
1710: 69 6e 63 72 20 6e 45 72 72 0a 20 20 7d 0a 20 20  incr nErr.  }.  
1720: 69 66 20 7b 5b 73 71 6c 69 74 65 33 5f 6d 65 6d  if {[sqlite3_mem
1730: 6f 72 79 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a 20  ory_used]>0} {. 
1740: 20 20 20 70 75 74 73 20 22 55 6e 66 72 65 65 64     puts "Unfreed
1750: 20 6d 65 6d 6f 72 79 3a 20 5b 73 71 6c 69 74 65   memory: [sqlite
1760: 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 20 62  3_memory_used] b
1770: 79 74 65 73 22 0a 20 20 20 20 69 6e 63 72 20 6e  ytes".    incr n
1780: 45 72 72 0a 20 20 20 20 69 66 63 61 70 61 62 6c  Err.    ifcapabl
1790: 65 20 6d 65 6d 64 65 62 75 67 7c 7c 6d 65 6d 35  e memdebug||mem5
17a0: 7c 7c 28 6d 65 6d 33 26 26 64 65 62 75 67 29 20  ||(mem3&&debug) 
17b0: 7b 0a 20 20 20 20 20 20 70 75 74 73 20 22 57 72  {.      puts "Wr
17c0: 69 74 69 6e 67 20 75 6e 66 72 65 65 64 20 6d 65  iting unfreed me
17d0: 6d 6f 72 79 20 6c 6f 67 20 74 6f 20 5c 22 2e 2f  mory log to \"./
17e0: 6d 65 6d 6c 65 61 6b 2e 74 78 74 5c 22 22 0a 20  memleak.txt\"". 
17f0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d       sqlite3_mem
1800: 64 65 62 75 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d  debug_dump ./mem
1810: 6c 65 61 6b 2e 74 78 74 0a 20 20 20 20 7d 0a 20  leak.txt.    }. 
1820: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 70 75   } else {.    pu
1830: 74 73 20 22 41 6c 6c 20 6d 65 6d 6f 72 79 20 61  ts "All memory a
1840: 6c 6c 6f 63 61 74 69 6f 6e 73 20 66 72 65 65 64  llocations freed
1850: 20 2d 20 6e 6f 20 6c 65 61 6b 73 22 0a 20 20 20   - no leaks".   
1860: 20 69 66 63 61 70 61 62 6c 65 20 6d 65 6d 64 65   ifcapable memde
1870: 62 75 67 7c 7c 6d 65 6d 35 20 7b 0a 20 20 20 20  bug||mem5 {.    
1880: 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62    sqlite3_memdeb
1890: 75 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d 75 73 61  ug_dump ./memusa
18a0: 67 65 2e 74 78 74 0a 20 20 20 20 7d 0a 20 20 7d  ge.txt.    }.  }
18b0: 0a 20 20 70 75 74 73 20 22 4d 61 78 69 6d 75 6d  .  puts "Maximum
18c0: 20 6d 65 6d 6f 72 79 20 75 73 61 67 65 3a 20 5b   memory usage: [
18d0: 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 68  sqlite3_memory_h
18e0: 69 67 68 77 61 74 65 72 20 31 5d 20 62 79 74 65  ighwater 1] byte
18f0: 73 22 0a 20 20 70 75 74 73 20 22 43 75 72 72 65  s".  puts "Curre
1900: 6e 74 20 6d 65 6d 6f 72 79 20 75 73 61 67 65 3a  nt memory usage:
1910: 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79   [sqlite3_memory
1920: 5f 68 69 67 68 77 61 74 65 72 5d 20 62 79 74 65  _highwater] byte
1930: 73 22 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 63  s".  if {[info c
1940: 6f 6d 6d 61 6e 64 73 20 73 71 6c 69 74 65 33 5f  ommands sqlite3_
1950: 6d 65 6d 64 65 62 75 67 5f 6d 61 6c 6c 6f 63 5f  memdebug_malloc_
1960: 63 6f 75 6e 74 5d 20 6e 65 20 22 22 7d 20 7b 0a  count] ne ""} {.
1970: 20 20 20 20 70 75 74 73 20 22 4e 75 6d 62 65 72      puts "Number
1980: 20 6f 66 20 6d 61 6c 6c 6f 63 28 29 20 20 3a 20   of malloc()  : 
1990: 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75  [sqlite3_memdebu
19a0: 67 5f 6d 61 6c 6c 6f 63 5f 63 6f 75 6e 74 5d 20  g_malloc_count] 
19b0: 63 61 6c 6c 73 22 0a 20 20 7d 0a 20 20 69 66 20  calls".  }.  if 
19c0: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
19d0: 74 65 73 74 65 72 5f 64 6f 5f 6d 61 6c 6c 6f 63  tester_do_malloc
19e0: 74 72 61 63 65 5d 7d 20 7b 0a 20 20 20 20 70 75  trace]} {.    pu
19f0: 74 73 20 22 57 72 69 74 69 6e 67 20 6d 61 6c 6c  ts "Writing mall
1a00: 6f 63 73 2e 73 71 6c 2e 2e 2e 22 0a 20 20 20 20  ocs.sql...".    
1a10: 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c  memdebug_log_sql
1a20: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d  .    sqlite3_mem
1a30: 64 65 62 75 67 5f 6c 6f 67 20 73 74 6f 70 0a 20  debug_log stop. 
1a40: 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65     sqlite3_memde
1a50: 62 75 67 5f 6c 6f 67 20 63 6c 65 61 72 0a 20 20  bug_log clear.  
1a60: 7d 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67  }.  foreach f [g
1a70: 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  lob -nocomplain 
1a80: 74 65 73 74 2e 64 62 2d 2a 2d 6a 6f 75 72 6e 61  test.db-*-journa
1a90: 6c 5d 20 7b 0a 20 20 20 20 66 69 6c 65 20 64 65  l] {.    file de
1aa0: 6c 65 74 65 20 2d 66 6f 72 63 65 20 24 66 0a 20  lete -force $f. 
1ab0: 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b   }.  foreach f [
1ac0: 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  glob -nocomplain
1ad0: 20 74 65 73 74 2e 64 62 2d 6d 6a 2a 5d 20 7b 0a   test.db-mj*] {.
1ae0: 20 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20      file delete 
1af0: 2d 66 6f 72 63 65 20 24 66 0a 20 20 7d 0a 20 20  -force $f.  }.  
1b00: 65 78 69 74 20 5b 65 78 70 72 20 7b 24 6e 45 72  exit [expr {$nEr
1b10: 72 3e 30 7d 5d 0a 7d 0a 0a 23 20 41 20 70 72 6f  r>0}].}..# A pro
1b20: 63 65 64 75 72 65 20 74 6f 20 65 78 65 63 75 74  cedure to execut
1b30: 65 20 53 51 4c 0a 23 0a 70 72 6f 63 20 65 78 65  e SQL.#.proc exe
1b40: 63 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62  csql {sql {db db
1b50: 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73 20 22 53  }} {.  # puts "S
1b60: 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20 75 70 6c  QL = $sql".  upl
1b70: 65 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65  evel [list $db e
1b80: 76 61 6c 20 24 73 71 6c 5d 0a 7d 0a 0a 23 20 45  val $sql].}..# E
1b90: 78 65 63 75 74 65 20 53 51 4c 20 61 6e 64 20 63  xecute SQL and c
1ba0: 61 74 63 68 20 65 78 63 65 70 74 69 6f 6e 73 2e  atch exceptions.
1bb0: 0a 23 0a 70 72 6f 63 20 63 61 74 63 68 73 71 6c  .#.proc catchsql
1bc0: 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b   {sql {db db}} {
1bd0: 0a 20 20 23 20 70 75 74 73 20 22 53 51 4c 20 3d  .  # puts "SQL =
1be0: 20 24 73 71 6c 22 0a 20 20 73 65 74 20 72 20 5b   $sql".  set r [
1bf0: 63 61 74 63 68 20 7b 24 64 62 20 65 76 61 6c 20  catch {$db eval 
1c00: 24 73 71 6c 7d 20 6d 73 67 5d 0a 20 20 6c 61 70  $sql} msg].  lap
1c10: 70 65 6e 64 20 72 20 24 6d 73 67 0a 20 20 72 65  pend r $msg.  re
1c20: 74 75 72 6e 20 24 72 0a 7d 0a 0a 23 20 44 6f 20  turn $r.}..# Do 
1c30: 61 6e 20 56 44 42 45 20 63 6f 64 65 20 64 75 6d  an VDBE code dum
1c40: 70 20 6f 6e 20 74 68 65 20 53 51 4c 20 67 69 76  p on the SQL giv
1c50: 65 6e 0a 23 0a 70 72 6f 63 20 65 78 70 6c 61 69  en.#.proc explai
1c60: 6e 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20  n {sql {db db}} 
1c70: 7b 0a 20 20 70 75 74 73 20 22 22 0a 20 20 70 75  {.  puts "".  pu
1c80: 74 73 20 22 61 64 64 72 20 20 6f 70 63 6f 64 65  ts "addr  opcode
1c90: 20 20 20 20 20 20 20 20 70 31 20 20 20 20 20 20          p1      
1ca0: 70 32 20 20 20 20 20 20 70 33 20 20 20 20 20 20  p2      p3      
1cb0: 70 34 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p4              
1cc0: 20 70 35 20 20 23 22 0a 20 20 70 75 74 73 20 22   p5  #".  puts "
1cd0: 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----  ----------
1ce0: 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d  --  ------  ----
1cf0: 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d  --  ------  ----
1d00: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 20  -----------  -- 
1d10: 20 2d 22 0a 20 20 24 64 62 20 65 76 61 6c 20 22   -".  $db eval "
1d20: 65 78 70 6c 61 69 6e 20 24 73 71 6c 22 20 7b 7d  explain $sql" {}
1d30: 20 7b 0a 20 20 20 20 70 75 74 73 20 5b 66 6f 72   {.    puts [for
1d40: 6d 61 74 20 7b 25 2d 34 64 20 20 25 2d 31 32 2e  mat {%-4d  %-12.
1d50: 31 32 73 20 20 25 2d 36 64 20 20 25 2d 36 64 20  12s  %-6d  %-6d 
1d60: 20 25 2d 36 64 20 20 25 20 2d 31 37 73 20 25 73   %-6d  % -17s %s
1d70: 20 20 25 73 7d 20 5c 0a 20 20 20 20 20 20 24 61    %s} \.      $a
1d80: 64 64 72 20 24 6f 70 63 6f 64 65 20 24 70 31 20  ddr $opcode $p1 
1d90: 24 70 32 20 24 70 33 20 24 70 34 20 24 70 35 20  $p2 $p3 $p4 $p5 
1da0: 24 63 6f 6d 6d 65 6e 74 0a 20 20 20 20 5d 0a 20  $comment.    ]. 
1db0: 20 7d 0a 7d 0a 0a 23 20 41 6e 6f 74 68 65 72 20   }.}..# Another 
1dc0: 70 72 6f 63 65 64 75 72 65 20 74 6f 20 65 78 65  procedure to exe
1dd0: 63 75 74 65 20 53 51 4c 2e 20 20 54 68 69 73 20  cute SQL.  This 
1de0: 6f 6e 65 20 69 6e 63 6c 75 64 65 73 20 74 68 65  one includes the
1df0: 20 66 69 65 6c 64 0a 23 20 6e 61 6d 65 73 20 69   field.# names i
1e00: 6e 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 6c  n the returned l
1e10: 69 73 74 2e 0a 23 0a 70 72 6f 63 20 65 78 65 63  ist..#.proc exec
1e20: 73 71 6c 32 20 7b 73 71 6c 7d 20 7b 0a 20 20 73  sql2 {sql} {.  s
1e30: 65 74 20 72 65 73 75 6c 74 20 7b 7d 0a 20 20 64  et result {}.  d
1e40: 62 20 65 76 61 6c 20 24 73 71 6c 20 64 61 74 61  b eval $sql data
1e50: 20 7b 0a 20 20 20 20 66 6f 72 65 61 63 68 20 66   {.    foreach f
1e60: 20 24 64 61 74 61 28 2a 29 20 7b 0a 20 20 20 20   $data(*) {.    
1e70: 20 20 6c 61 70 70 65 6e 64 20 72 65 73 75 6c 74    lappend result
1e80: 20 24 66 20 24 64 61 74 61 28 24 66 29 0a 20 20   $f $data($f).  
1e90: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
1ea0: 20 24 72 65 73 75 6c 74 0a 7d 0a 0a 23 20 55 73   $result.}..# Us
1eb0: 65 20 74 68 65 20 6e 6f 6e 2d 63 61 6c 6c 62 61  e the non-callba
1ec0: 63 6b 20 41 50 49 20 74 6f 20 65 78 65 63 75 74  ck API to execut
1ed0: 65 20 6d 75 6c 74 69 70 6c 65 20 53 51 4c 20 73  e multiple SQL s
1ee0: 74 61 74 65 6d 65 6e 74 73 0a 23 0a 70 72 6f 63  tatements.#.proc
1ef0: 20 73 74 65 70 73 71 6c 20 7b 64 62 70 74 72 20   stepsql {dbptr 
1f00: 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 73 71 6c  sql} {.  set sql
1f10: 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 24 73   [string trim $s
1f20: 71 6c 5d 0a 20 20 73 65 74 20 72 20 30 0a 20 20  ql].  set r 0.  
1f30: 77 68 69 6c 65 20 7b 5b 73 74 72 69 6e 67 20 6c  while {[string l
1f40: 65 6e 67 74 68 20 24 73 71 6c 5d 3e 30 7d 20 7b  ength $sql]>0} {
1f50: 0a 20 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20  .    if {[catch 
1f60: 7b 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65  {sqlite3_prepare
1f70: 20 24 64 62 70 74 72 20 24 73 71 6c 20 2d 31 20   $dbptr $sql -1 
1f80: 73 71 6c 74 61 69 6c 7d 20 76 6d 5d 7d 20 7b 0a  sqltail} vm]} {.
1f90: 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b 6c 69        return [li
1fa0: 73 74 20 31 20 24 76 6d 5d 0a 20 20 20 20 7d 0a  st 1 $vm].    }.
1fb0: 20 20 20 20 73 65 74 20 73 71 6c 20 5b 73 74 72      set sql [str
1fc0: 69 6e 67 20 74 72 69 6d 20 24 73 71 6c 74 61 69  ing trim $sqltai
1fd0: 6c 5d 0a 23 20 20 20 20 77 68 69 6c 65 20 7b 5b  l].#    while {[
1fe0: 73 71 6c 69 74 65 5f 73 74 65 70 20 24 76 6d 20  sqlite_step $vm 
1ff0: 4e 20 56 41 4c 20 43 4f 4c 5d 3d 3d 22 53 51 4c  N VAL COL]=="SQL
2000: 49 54 45 5f 52 4f 57 22 7d 20 7b 0a 23 20 20 20  ITE_ROW"} {.#   
2010: 20 20 20 66 6f 72 65 61 63 68 20 76 20 24 56 41     foreach v $VA
2020: 4c 20 7b 6c 61 70 70 65 6e 64 20 72 20 24 76 7d  L {lappend r $v}
2030: 0a 23 20 20 20 20 7d 0a 20 20 20 20 77 68 69 6c  .#    }.    whil
2040: 65 20 7b 5b 73 71 6c 69 74 65 33 5f 73 74 65 70  e {[sqlite3_step
2050: 20 24 76 6d 5d 3d 3d 22 53 51 4c 49 54 45 5f 52   $vm]=="SQLITE_R
2060: 4f 57 22 7d 20 7b 0a 20 20 20 20 20 20 66 6f 72  OW"} {.      for
2070: 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 3c 5b   {set i 0} {$i<[
2080: 73 71 6c 69 74 65 33 5f 64 61 74 61 5f 63 6f 75  sqlite3_data_cou
2090: 6e 74 20 24 76 6d 5d 7d 20 7b 69 6e 63 72 20 69  nt $vm]} {incr i
20a0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 6c 61 70 70  } {.        lapp
20b0: 65 6e 64 20 72 20 5b 73 71 6c 69 74 65 33 5f 63  end r [sqlite3_c
20c0: 6f 6c 75 6d 6e 5f 74 65 78 74 20 24 76 6d 20 24  olumn_text $vm $
20d0: 69 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  i].      }.    }
20e0: 0a 20 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20  .    if {[catch 
20f0: 7b 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a  {sqlite3_finaliz
2100: 65 20 24 76 6d 7d 20 65 72 72 6d 73 67 5d 7d 20  e $vm} errmsg]} 
2110: 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b  {.      return [
2120: 6c 69 73 74 20 31 20 24 65 72 72 6d 73 67 5d 0a  list 1 $errmsg].
2130: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
2140: 72 6e 20 24 72 0a 7d 0a 0a 23 20 44 65 6c 65 74  rn $r.}..# Delet
2150: 65 20 61 20 66 69 6c 65 20 6f 72 20 64 69 72 65  e a file or dire
2160: 63 74 6f 72 79 0a 23 0a 70 72 6f 63 20 66 6f 72  ctory.#.proc for
2170: 63 65 64 65 6c 65 74 65 20 7b 66 69 6c 65 6e 61  cedelete {filena
2180: 6d 65 7d 20 7b 0a 20 20 69 66 20 7b 5b 63 61 74  me} {.  if {[cat
2190: 63 68 20 7b 66 69 6c 65 20 64 65 6c 65 74 65 20  ch {file delete 
21a0: 2d 66 6f 72 63 65 20 24 66 69 6c 65 6e 61 6d 65  -force $filename
21b0: 7d 5d 7d 20 7b 0a 20 20 20 20 65 78 65 63 20 72  }]} {.    exec r
21c0: 6d 20 2d 72 66 20 24 66 69 6c 65 6e 61 6d 65 0a  m -rf $filename.
21d0: 20 20 7d 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20 69    }.}..# Do an i
21e0: 6e 74 65 67 72 69 74 79 20 63 68 65 63 6b 20 6f  ntegrity check o
21f0: 66 20 74 68 65 20 65 6e 74 69 72 65 20 64 61 74  f the entire dat
2200: 61 62 61 73 65 0a 23 0a 70 72 6f 63 20 69 6e 74  abase.#.proc int
2210: 65 67 72 69 74 79 5f 63 68 65 63 6b 20 7b 6e 61  egrity_check {na
2220: 6d 65 7d 20 7b 0a 20 20 69 66 63 61 70 61 62 6c  me} {.  ifcapabl
2230: 65 20 69 6e 74 65 67 72 69 74 79 63 6b 20 7b 0a  e integrityck {.
2240: 20 20 20 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d      do_test $nam
2250: 65 20 7b 0a 20 20 20 20 20 20 65 78 65 63 73 71  e {.      execsq
2260: 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74 65 67 72  l {PRAGMA integr
2270: 69 74 79 5f 63 68 65 63 6b 7d 0a 20 20 20 20 7d  ity_check}.    }
2280: 20 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a 70 72 6f   {ok}.  }.}..pro
2290: 63 20 66 69 78 5f 69 66 63 61 70 61 62 6c 65 5f  c fix_ifcapable_
22a0: 65 78 70 72 20 7b 65 78 70 72 7d 20 7b 0a 20 20  expr {expr} {.  
22b0: 73 65 74 20 72 65 74 20 22 22 0a 20 20 73 65 74  set ret "".  set
22c0: 20 73 74 61 74 65 20 30 0a 20 20 66 6f 72 20 7b   state 0.  for {
22d0: 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 5b  set i 0} {$i < [
22e0: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 65  string length $e
22f0: 78 70 72 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b  xpr]} {incr i} {
2300: 0a 20 20 20 20 73 65 74 20 63 68 61 72 20 5b 73  .    set char [s
2310: 74 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78 70  tring range $exp
2320: 72 20 24 69 20 24 69 5d 0a 20 20 20 20 73 65 74  r $i $i].    set
2330: 20 6e 65 77 73 74 61 74 65 20 5b 65 78 70 72 20   newstate [expr 
2340: 7b 5b 73 74 72 69 6e 67 20 69 73 20 61 6c 6e 75  {[string is alnu
2350: 6d 20 24 63 68 61 72 5d 20 7c 7c 20 24 63 68 61  m $char] || $cha
2360: 72 20 65 71 20 22 5f 22 7d 5d 0a 20 20 20 20 69  r eq "_"}].    i
2370: 66 20 7b 24 6e 65 77 73 74 61 74 65 20 26 26 20  f {$newstate && 
2380: 21 24 73 74 61 74 65 7d 20 7b 0a 20 20 20 20 20  !$state} {.     
2390: 20 61 70 70 65 6e 64 20 72 65 74 20 7b 24 3a 3a   append ret {$::
23a0: 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28 7d  sqlite_options(}
23b0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 21  .    }.    if {!
23c0: 24 6e 65 77 73 74 61 74 65 20 26 26 20 24 73 74  $newstate && $st
23d0: 61 74 65 7d 20 7b 0a 20 20 20 20 20 20 61 70 70  ate} {.      app
23e0: 65 6e 64 20 72 65 74 20 29 0a 20 20 20 20 7d 0a  end ret ).    }.
23f0: 20 20 20 20 61 70 70 65 6e 64 20 72 65 74 20 24      append ret $
2400: 63 68 61 72 0a 20 20 20 20 73 65 74 20 73 74 61  char.    set sta
2410: 74 65 20 24 6e 65 77 73 74 61 74 65 0a 20 20 7d  te $newstate.  }
2420: 0a 20 20 69 66 20 7b 24 73 74 61 74 65 7d 20 7b  .  if {$state} {
2430: 61 70 70 65 6e 64 20 72 65 74 20 29 7d 0a 20 20  append ret )}.  
2440: 72 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a 0a 23  return $ret.}..#
2450: 20 45 76 61 6c 75 61 74 65 20 61 20 62 6f 6f 6c   Evaluate a bool
2460: 65 61 6e 20 65 78 70 72 65 73 73 69 6f 6e 20 6f  ean expression o
2470: 66 20 63 61 70 61 62 69 6c 69 74 69 65 73 2e 20  f capabilities. 
2480: 20 49 66 20 74 72 75 65 2c 20 65 78 65 63 75 74   If true, execut
2490: 65 20 74 68 65 0a 23 20 63 6f 64 65 2e 20 20 4f  e the.# code.  O
24a0: 6d 69 74 20 74 68 65 20 63 6f 64 65 20 69 66 20  mit the code if 
24b0: 66 61 6c 73 65 2e 0a 23 0a 70 72 6f 63 20 69 66  false..#.proc if
24c0: 63 61 70 61 62 6c 65 20 7b 65 78 70 72 20 63 6f  capable {expr co
24d0: 64 65 20 7b 65 6c 73 65 20 22 22 7d 20 7b 65 6c  de {else ""} {el
24e0: 73 65 63 6f 64 65 20 22 22 7d 7d 20 7b 0a 20 20  secode ""}} {.  
24f0: 23 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 5b 61  #regsub -all {[a
2500: 2d 7a 5f 30 2d 39 5d 2b 7d 20 24 65 78 70 72 20  -z_0-9]+} $expr 
2510: 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f  {$::sqlite_optio
2520: 6e 73 28 26 29 7d 20 65 32 0a 20 20 73 65 74 20  ns(&)} e2.  set 
2530: 65 32 20 5b 66 69 78 5f 69 66 63 61 70 61 62 6c  e2 [fix_ifcapabl
2540: 65 5f 65 78 70 72 20 24 65 78 70 72 5d 0a 20 20  e_expr $expr].  
2550: 69 66 20 28 24 65 32 29 20 7b 0a 20 20 20 20 73  if ($e2) {.    s
2560: 65 74 20 63 20 5b 63 61 74 63 68 20 7b 75 70 6c  et c [catch {upl
2570: 65 76 65 6c 20 31 20 24 63 6f 64 65 7d 20 72 5d  evel 1 $code} r]
2580: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
2590: 73 65 74 20 63 20 5b 63 61 74 63 68 20 7b 75 70  set c [catch {up
25a0: 6c 65 76 65 6c 20 31 20 24 65 6c 73 65 63 6f 64  level 1 $elsecod
25b0: 65 7d 20 72 5d 0a 20 20 7d 0a 20 20 72 65 74 75  e} r].  }.  retu
25c0: 72 6e 20 2d 63 6f 64 65 20 24 63 20 24 72 0a 7d  rn -code $c $r.}
25d0: 0a 0a 23 20 54 68 69 73 20 70 72 6f 63 20 65 78  ..# This proc ex
25e0: 65 63 73 20 61 20 73 65 70 65 72 61 74 65 20 70  ecs a seperate p
25f0: 72 6f 63 65 73 73 20 74 68 61 74 20 63 72 61 73  rocess that cras
2600: 68 65 73 20 6d 69 64 77 61 79 20 74 68 72 6f 75  hes midway throu
2610: 67 68 20 65 78 65 63 75 74 69 6e 67 0a 23 20 74  gh executing.# t
2620: 68 65 20 53 51 4c 20 73 63 72 69 70 74 20 24 73  he SQL script $s
2630: 71 6c 20 6f 6e 20 64 61 74 61 62 61 73 65 20 74  ql on database t
2640: 65 73 74 2e 64 62 2e 0a 23 0a 23 20 54 68 65 20  est.db..#.# The 
2650: 63 72 61 73 68 20 6f 63 63 75 72 73 20 64 75 72  crash occurs dur
2660: 69 6e 67 20 61 20 73 79 6e 63 28 29 20 6f 66 20  ing a sync() of 
2670: 66 69 6c 65 20 24 63 72 61 73 68 66 69 6c 65 2e  file $crashfile.
2680: 20 57 68 65 6e 20 74 68 65 20 63 72 61 73 68 0a   When the crash.
2690: 23 20 6f 63 63 75 72 73 20 61 20 72 61 6e 64 6f  # occurs a rando
26a0: 6d 20 73 75 62 73 65 74 20 6f 66 20 61 6c 6c 20  m subset of all 
26b0: 75 6e 73 79 6e 63 65 64 20 77 72 69 74 65 73 20  unsynced writes 
26c0: 6d 61 64 65 20 62 79 20 74 68 65 20 70 72 6f 63  made by the proc
26d0: 65 73 73 20 61 72 65 0a 23 20 77 72 69 74 74 65  ess are.# writte
26e0: 6e 20 69 6e 74 6f 20 74 68 65 20 66 69 6c 65 73  n into the files
26f0: 20 6f 6e 20 64 69 73 6b 2e 20 41 72 67 75 6d 65   on disk. Argume
2700: 6e 74 20 24 63 72 61 73 68 64 65 6c 61 79 20 69  nt $crashdelay i
2710: 6e 64 69 63 61 74 65 73 20 74 68 65 0a 23 20 6e  ndicates the.# n
2720: 75 6d 62 65 72 20 6f 66 20 66 69 6c 65 20 73 79  umber of file sy
2730: 6e 63 73 20 74 6f 20 77 61 69 74 20 62 65 66 6f  ncs to wait befo
2740: 72 65 20 63 72 61 73 68 69 6e 67 2e 0a 23 0a 23  re crashing..#.#
2750: 20 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75   The return valu
2760: 65 20 69 73 20 61 20 6c 69 73 74 20 6f 66 20 74  e is a list of t
2770: 77 6f 20 65 6c 65 6d 65 6e 74 73 2e 20 54 68 65  wo elements. The
2780: 20 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 20 69   first element i
2790: 73 20 61 0a 23 20 62 6f 6f 6c 65 61 6e 2c 20 69  s a.# boolean, i
27a0: 6e 64 69 63 61 74 69 6e 67 20 77 68 65 74 68 65  ndicating whethe
27b0: 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 70 72 6f  r or not the pro
27c0: 63 65 73 73 20 61 63 74 75 61 6c 6c 79 20 63 72  cess actually cr
27d0: 61 73 68 65 64 20 6f 72 0a 23 20 72 65 70 6f 72  ashed or.# repor
27e0: 74 65 64 20 73 6f 6d 65 20 6f 74 68 65 72 20 65  ted some other e
27f0: 72 72 6f 72 2e 20 54 68 65 20 73 65 63 6f 6e 64  rror. The second
2800: 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65 20   element in the 
2810: 72 65 74 75 72 6e 65 64 20 6c 69 73 74 20 69 73  returned list is
2820: 20 74 68 65 0a 23 20 65 72 72 6f 72 20 6d 65 73   the.# error mes
2830: 73 61 67 65 2e 20 54 68 69 73 20 69 73 20 22 63  sage. This is "c
2840: 68 69 6c 64 20 70 72 6f 63 65 73 73 20 65 78 69  hild process exi
2850: 74 65 64 20 61 62 6e 6f 72 6d 61 6c 6c 79 22 20  ted abnormally" 
2860: 69 66 20 74 68 65 20 63 72 61 73 68 0a 23 20 6f  if the crash.# o
2870: 63 63 75 72 65 64 2e 0a 23 0a 23 20 20 20 63 72  ccured..#.#   cr
2880: 61 73 68 73 71 6c 20 2d 64 65 6c 61 79 20 43 52  ashsql -delay CR
2890: 41 53 48 44 45 4c 41 59 20 2d 66 69 6c 65 20 43  ASHDELAY -file C
28a0: 52 41 53 48 46 49 4c 45 20 3f 2d 62 6c 6f 63 6b  RASHFILE ?-block
28b0: 73 69 7a 65 20 42 4c 4f 43 4b 53 49 5a 45 3f 20  size BLOCKSIZE? 
28c0: 24 73 71 6c 0a 23 0a 70 72 6f 63 20 63 72 61 73  $sql.#.proc cras
28d0: 68 73 71 6c 20 7b 61 72 67 73 7d 20 7b 0a 20 20  hsql {args} {.  
28e0: 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66  if {$::tcl_platf
28f0: 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 21 3d 22  orm(platform)!="
2900: 75 6e 69 78 22 7d 20 7b 0a 20 20 20 20 65 72 72  unix"} {.    err
2910: 6f 72 20 22 63 72 61 73 68 73 71 6c 20 73 68 6f  or "crashsql sho
2920: 75 6c 64 20 6f 6e 6c 79 20 62 65 20 75 73 65 64  uld only be used
2930: 20 6f 6e 20 75 6e 69 78 22 0a 20 20 7d 0a 0a 20   on unix".  }.. 
2940: 20 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65 20 22   set blocksize "
2950: 22 0a 20 20 73 65 74 20 63 72 61 73 68 64 65 6c  ".  set crashdel
2960: 61 79 20 31 0a 20 20 73 65 74 20 70 72 6e 67 73  ay 1.  set prngs
2970: 65 65 64 20 30 0a 20 20 73 65 74 20 74 63 6c 62  eed 0.  set tclb
2980: 6f 64 79 20 7b 7d 0a 20 20 73 65 74 20 63 72 61  ody {}.  set cra
2990: 73 68 66 69 6c 65 20 22 22 0a 20 20 73 65 74 20  shfile "".  set 
29a0: 64 63 20 22 22 0a 20 20 73 65 74 20 73 71 6c 20  dc "".  set sql 
29b0: 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 65 6e  [lindex $args en
29c0: 64 5d 0a 20 20 0a 20 20 66 6f 72 20 7b 73 65 74  d].  .  for {set
29d0: 20 69 69 20 30 7d 20 7b 24 69 69 20 3c 20 5b 6c   ii 0} {$ii < [l
29e0: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 2d 31 7d  length $args]-1}
29f0: 20 7b 69 6e 63 72 20 69 69 20 32 7d 20 7b 0a 20   {incr ii 2} {. 
2a00: 20 20 20 73 65 74 20 7a 20 5b 6c 69 6e 64 65 78     set z [lindex
2a10: 20 24 61 72 67 73 20 24 69 69 5d 0a 20 20 20 20   $args $ii].    
2a20: 73 65 74 20 6e 20 5b 73 74 72 69 6e 67 20 6c 65  set n [string le
2a30: 6e 67 74 68 20 24 7a 5d 0a 20 20 20 20 73 65 74  ngth $z].    set
2a40: 20 7a 32 20 5b 6c 69 6e 64 65 78 20 24 61 72 67   z2 [lindex $arg
2a50: 73 20 5b 65 78 70 72 20 24 69 69 2b 31 5d 5d 0a  s [expr $ii+1]].
2a60: 0a 20 20 20 20 69 66 20 20 20 20 20 7b 24 6e 3e  .    if     {$n>
2a70: 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72  1 && [string fir
2a80: 73 74 20 24 7a 20 2d 64 65 6c 61 79 5d 3d 3d 30  st $z -delay]==0
2a90: 7d 20 20 20 20 20 7b 73 65 74 20 63 72 61 73 68  }     {set crash
2aa0: 64 65 6c 61 79 20 24 7a 32 7d 20 5c 0a 20 20 20  delay $z2} \.   
2ab0: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26   elseif {$n>1 &&
2ac0: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
2ad0: 7a 20 2d 73 65 65 64 5d 3d 3d 30 7d 20 20 20 20  z -seed]==0}    
2ae0: 20 20 7b 73 65 74 20 70 72 6e 67 73 65 65 64 20    {set prngseed 
2af0: 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69  $z2} \.    elsei
2b00: 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69  f {$n>1 && [stri
2b10: 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 66 69 6c  ng first $z -fil
2b20: 65 5d 3d 3d 30 7d 20 20 20 20 20 20 7b 73 65 74  e]==0}      {set
2b30: 20 63 72 61 73 68 66 69 6c 65 20 24 7a 32 7d 20   crashfile $z2} 
2b40: 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24   \.    elseif {$
2b50: 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66  n>1 && [string f
2b60: 69 72 73 74 20 24 7a 20 2d 74 63 6c 62 6f 64 79  irst $z -tclbody
2b70: 5d 3d 3d 30 7d 20 20 20 7b 73 65 74 20 74 63 6c  ]==0}   {set tcl
2b80: 62 6f 64 79 20 24 7a 32 7d 20 20 5c 0a 20 20 20  body $z2}  \.   
2b90: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26   elseif {$n>1 &&
2ba0: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
2bb0: 7a 20 2d 62 6c 6f 63 6b 73 69 7a 65 5d 3d 3d 30  z -blocksize]==0
2bc0: 7d 20 7b 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65  } {set blocksize
2bd0: 20 22 2d 73 20 24 7a 32 22 20 7d 20 5c 0a 20 20   "-s $z2" } \.  
2be0: 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26    elseif {$n>1 &
2bf0: 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20  & [string first 
2c00: 24 7a 20 2d 63 68 61 72 61 63 74 65 72 69 73 74  $z -characterist
2c10: 69 63 73 5d 3d 3d 30 7d 20 7b 73 65 74 20 64 63  ics]==0} {set dc
2c20: 20 22 2d 63 20 7b 24 7a 32 7d 22 20 7d 20 5c 0a   "-c {$z2}" } \.
2c30: 20 20 20 20 65 6c 73 65 20 20 20 7b 20 65 72 72      else   { err
2c40: 6f 72 20 22 55 6e 72 65 63 6f 67 6e 69 7a 65 64  or "Unrecognized
2c50: 20 6f 70 74 69 6f 6e 3a 20 24 7a 22 20 7d 0a 20   option: $z" }. 
2c60: 20 7d 0a 0a 20 20 69 66 20 7b 24 63 72 61 73 68   }..  if {$crash
2c70: 66 69 6c 65 20 65 71 20 22 22 7d 20 7b 0a 20 20  file eq ""} {.  
2c80: 20 20 65 72 72 6f 72 20 22 43 6f 6d 70 75 6c 73    error "Compuls
2c90: 6f 72 79 20 6f 70 74 69 6f 6e 20 2d 66 69 6c 65  ory option -file
2ca0: 20 6d 69 73 73 69 6e 67 22 0a 20 20 7d 0a 0a 20   missing".  }.. 
2cb0: 20 73 65 74 20 63 66 69 6c 65 20 5b 66 69 6c 65   set cfile [file
2cc0: 20 6a 6f 69 6e 20 5b 70 77 64 5d 20 24 63 72 61   join [pwd] $cra
2cd0: 73 68 66 69 6c 65 5d 0a 0a 20 20 73 65 74 20 66  shfile]..  set f
2ce0: 20 5b 6f 70 65 6e 20 63 72 61 73 68 2e 74 63 6c   [open crash.tcl
2cf0: 20 77 5d 0a 20 20 70 75 74 73 20 24 66 20 22 73   w].  puts $f "s
2d00: 71 6c 69 74 65 33 5f 63 72 61 73 68 5f 65 6e 61  qlite3_crash_ena
2d10: 62 6c 65 20 31 22 0a 20 20 70 75 74 73 20 24 66  ble 1".  puts $f
2d20: 20 22 73 71 6c 69 74 65 33 5f 63 72 61 73 68 70   "sqlite3_crashp
2d30: 61 72 61 6d 73 20 24 62 6c 6f 63 6b 73 69 7a 65  arams $blocksize
2d40: 20 24 64 63 20 24 63 72 61 73 68 64 65 6c 61 79   $dc $crashdelay
2d50: 20 24 63 66 69 6c 65 22 0a 20 20 70 75 74 73 20   $cfile".  puts 
2d60: 24 66 20 22 73 65 74 20 73 71 6c 69 74 65 5f 70  $f "set sqlite_p
2d70: 65 6e 64 69 6e 67 5f 62 79 74 65 20 24 3a 3a 73  ending_byte $::s
2d80: 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67 5f 62 79  qlite_pending_by
2d90: 74 65 22 0a 20 20 70 75 74 73 20 24 66 20 22 73  te".  puts $f "s
2da0: 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64  qlite3 db test.d
2db0: 62 20 2d 76 66 73 20 63 72 61 73 68 22 0a 0a 20  b -vfs crash".. 
2dc0: 20 23 20 54 68 69 73 20 62 6c 6f 63 6b 20 73 65   # This block se
2dd0: 74 73 20 74 68 65 20 63 61 63 68 65 20 73 69 7a  ts the cache siz
2de0: 65 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 64 61  e of the main da
2df0: 74 61 62 61 73 65 20 74 6f 20 31 30 0a 20 20 23  tabase to 10.  #
2e00: 20 70 61 67 65 73 2e 20 54 68 69 73 20 69 73 20   pages. This is 
2e10: 64 6f 6e 65 20 69 6e 20 63 61 73 65 20 74 68 65  done in case the
2e20: 20 62 75 69 6c 64 20 69 73 20 63 6f 6e 66 69 67   build is config
2e30: 75 72 65 64 20 74 6f 20 6f 6d 69 74 0a 20 20 23  ured to omit.  #
2e40: 20 22 50 52 41 47 4d 41 20 63 61 63 68 65 5f 73   "PRAGMA cache_s
2e50: 69 7a 65 22 2e 0a 20 20 70 75 74 73 20 24 66 20  ize"..  puts $f 
2e60: 7b 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54  {db eval {SELECT
2e70: 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d   * FROM sqlite_m
2e80: 61 73 74 65 72 3b 7d 7d 0a 20 20 70 75 74 73 20  aster;}}.  puts 
2e90: 24 66 20 7b 73 65 74 20 62 74 20 5b 62 74 72 65  $f {set bt [btre
2ea0: 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 7d 0a 20  e_from_db db]}. 
2eb0: 20 70 75 74 73 20 24 66 20 7b 62 74 72 65 65 5f   puts $f {btree_
2ec0: 73 65 74 5f 63 61 63 68 65 5f 73 69 7a 65 20 24  set_cache_size $
2ed0: 62 74 20 31 30 7d 0a 20 20 69 66 20 7b 24 70 72  bt 10}.  if {$pr
2ee0: 6e 67 73 65 65 64 7d 20 7b 0a 20 20 20 20 73 65  ngseed} {.    se
2ef0: 74 20 73 65 65 64 20 5b 65 78 70 72 20 7b 24 70  t seed [expr {$p
2f00: 72 6e 67 73 65 65 64 25 31 30 30 30 37 2b 31 7d  rngseed%10007+1}
2f10: 5d 0a 20 20 20 20 23 20 70 75 74 73 20 73 65 65  ].    # puts see
2f20: 64 3d 24 73 65 65 64 0a 20 20 20 20 70 75 74 73  d=$seed.    puts
2f30: 20 24 66 20 22 64 62 20 65 76 61 6c 20 7b 53 45   $f "db eval {SE
2f40: 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62 28  LECT randomblob(
2f50: 24 73 65 65 64 29 7d 22 0a 20 20 7d 0a 0a 20 20  $seed)}".  }..  
2f60: 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67  if {[string leng
2f70: 74 68 20 24 74 63 6c 62 6f 64 79 5d 3e 30 7d 20  th $tclbody]>0} 
2f80: 7b 0a 20 20 20 20 70 75 74 73 20 24 66 20 24 74  {.    puts $f $t
2f90: 63 6c 62 6f 64 79 0a 20 20 7d 0a 20 20 69 66 20  clbody.  }.  if 
2fa0: 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20  {[string length 
2fb0: 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20 70  $sql]>0} {.    p
2fc0: 75 74 73 20 24 66 20 22 64 62 20 65 76 61 6c 20  uts $f "db eval 
2fd0: 7b 22 0a 20 20 20 20 70 75 74 73 20 24 66 20 20  {".    puts $f  
2fe0: 20 22 24 73 71 6c 22 0a 20 20 20 20 70 75 74 73   "$sql".    puts
2ff0: 20 24 66 20 22 7d 22 0a 20 20 7d 0a 20 20 63 6c   $f "}".  }.  cl
3000: 6f 73 65 20 24 66 0a 0a 20 20 73 65 74 20 72 20  ose $f..  set r 
3010: 5b 63 61 74 63 68 20 7b 0a 20 20 20 20 65 78 65  [catch {.    exe
3020: 63 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78  c [info nameofex
3030: 65 63 5d 20 63 72 61 73 68 2e 74 63 6c 20 3e 40  ec] crash.tcl >@
3040: 73 74 64 6f 75 74 0a 20 20 7d 20 6d 73 67 5d 0a  stdout.  } msg].
3050: 20 20 6c 61 70 70 65 6e 64 20 72 20 24 6d 73 67    lappend r $msg
3060: 0a 7d 0a 0a 23 20 55 73 61 67 65 3a 20 64 6f 5f  .}..# Usage: do_
3070: 69 6f 65 72 72 5f 74 65 73 74 20 3c 74 65 73 74  ioerr_test <test
3080: 20 6e 75 6d 62 65 72 3e 20 3c 6f 70 74 69 6f 6e   number> <option
3090: 73 2e 2e 2e 3e 0a 23 0a 23 20 54 68 69 73 20 70  s...>.#.# This p
30a0: 72 6f 63 20 69 73 20 75 73 65 64 20 74 6f 20 69  roc is used to i
30b0: 6d 70 6c 65 6d 65 6e 74 20 74 65 73 74 20 63 61  mplement test ca
30c0: 73 65 73 20 74 68 61 74 20 63 68 65 63 6b 20 74  ses that check t
30d0: 68 61 74 20 49 4f 20 65 72 72 6f 72 73 0a 23 20  hat IO errors.# 
30e0: 61 72 65 20 63 6f 72 72 65 63 74 6c 79 20 68 61  are correctly ha
30f0: 6e 64 6c 65 64 2e 20 54 68 65 20 66 69 72 73 74  ndled. The first
3100: 20 61 72 67 75 6d 65 6e 74 2c 20 3c 74 65 73 74   argument, <test
3110: 20 6e 75 6d 62 65 72 3e 2c 20 69 73 20 61 6e 20   number>, is an 
3120: 69 6e 74 65 67 65 72 20 0a 23 20 75 73 65 64 20  integer .# used 
3130: 74 6f 20 6e 61 6d 65 20 74 68 65 20 74 65 73 74  to name the test
3140: 73 20 65 78 65 63 75 74 65 64 20 62 79 20 74 68  s executed by th
3150: 69 73 20 70 72 6f 63 2e 20 4f 70 74 69 6f 6e 73  is proc. Options
3160: 20 61 72 65 20 61 73 20 66 6f 6c 6c 6f 77 73 3a   are as follows:
3170: 0a 23 0a 23 20 20 20 20 20 2d 74 63 6c 70 72 65  .#.#     -tclpre
3180: 70 20 20 20 20 20 20 20 20 20 20 54 43 4c 20 73  p          TCL s
3190: 63 72 69 70 74 20 74 6f 20 72 75 6e 20 74 6f 20  cript to run to 
31a0: 70 72 65 70 61 72 65 20 74 65 73 74 2e 0a 23 20  prepare test..# 
31b0: 20 20 20 20 2d 73 71 6c 70 72 65 70 20 20 20 20      -sqlprep    
31c0: 20 20 20 20 20 20 53 51 4c 20 73 63 72 69 70 74        SQL script
31d0: 20 74 6f 20 72 75 6e 20 74 6f 20 70 72 65 70 61   to run to prepa
31e0: 72 65 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d  re test..#     -
31f0: 74 63 6c 62 6f 64 79 20 20 20 20 20 20 20 20 20  tclbody         
3200: 20 54 43 4c 20 73 63 72 69 70 74 20 74 6f 20 72   TCL script to r
3210: 75 6e 20 77 69 74 68 20 49 4f 20 65 72 72 6f 72  un with IO error
3220: 20 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20 20   simulation..#  
3230: 20 20 20 2d 73 71 6c 62 6f 64 79 20 20 20 20 20     -sqlbody     
3240: 20 20 20 20 20 54 43 4c 20 73 63 72 69 70 74 20       TCL script 
3250: 74 6f 20 72 75 6e 20 77 69 74 68 20 49 4f 20 65  to run with IO e
3260: 72 72 6f 72 20 73 69 6d 75 6c 61 74 69 6f 6e 2e  rror simulation.
3270: 0a 23 20 20 20 20 20 2d 65 78 63 6c 75 64 65 20  .#     -exclude 
3280: 20 20 20 20 20 20 20 20 20 4c 69 73 74 20 6f 66           List of
3290: 20 27 4e 27 20 76 61 6c 75 65 73 20 6e 6f 74 20   'N' values not 
32a0: 74 6f 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d  to test..#     -
32b0: 65 72 63 20 20 20 20 20 20 20 20 20 20 20 20 20  erc             
32c0: 20 55 73 65 20 65 78 74 65 6e 64 65 64 20 72 65   Use extended re
32d0: 73 75 6c 74 20 63 6f 64 65 73 0a 23 20 20 20 20  sult codes.#    
32e0: 20 2d 70 65 72 73 69 73 74 20 20 20 20 20 20 20   -persist       
32f0: 20 20 20 4d 61 6b 65 20 73 69 6d 75 6c 61 74 65     Make simulate
3300: 64 20 49 2f 4f 20 65 72 72 6f 72 73 20 70 65 72  d I/O errors per
3310: 73 69 73 74 65 6e 74 0a 23 20 20 20 20 20 2d 73  sistent.#     -s
3320: 74 61 72 74 20 20 20 20 20 20 20 20 20 20 20 20  tart            
3330: 56 61 6c 75 65 20 6f 66 20 27 4e 27 20 74 6f 20  Value of 'N' to 
3340: 62 65 67 69 6e 20 77 69 74 68 20 28 64 65 66 61  begin with (defa
3350: 75 6c 74 20 31 29 0a 23 0a 23 20 20 20 20 20 2d  ult 1).#.#     -
3360: 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20 20 20  cksum           
3370: 20 42 6f 6f 6c 65 61 6e 2e 20 49 66 20 74 72 75   Boolean. If tru
3380: 65 2c 20 74 65 73 74 20 74 68 61 74 20 74 68 65  e, test that the
3390: 20 64 61 74 61 62 61 73 65 20 64 6f 65 73 0a 23   database does.#
33a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
33b0: 20 20 20 20 20 20 20 6e 6f 74 20 63 68 61 6e 67         not chang
33c0: 65 20 64 75 72 69 6e 67 20 74 68 65 20 65 78 65  e during the exe
33d0: 63 75 74 69 6f 6e 20 6f 66 20 74 68 65 20 74 65  cution of the te
33e0: 73 74 20 63 61 73 65 2e 0a 23 0a 70 72 6f 63 20  st case..#.proc 
33f0: 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20 7b 74  do_ioerr_test {t
3400: 65 73 74 6e 61 6d 65 20 61 72 67 73 7d 20 7b 0a  estname args} {.
3410: 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70  .  set ::ioerrop
3420: 74 73 28 2d 73 74 61 72 74 29 20 31 0a 20 20 73  ts(-start) 1.  s
3430: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  et ::ioerropts(-
3440: 63 6b 73 75 6d 29 20 30 0a 20 20 73 65 74 20 3a  cksum) 0.  set :
3450: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29  :ioerropts(-erc)
3460: 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72   0.  set ::ioerr
3470: 6f 70 74 73 28 2d 63 6f 75 6e 74 29 20 31 30 30  opts(-count) 100
3480: 30 30 30 30 30 30 0a 20 20 73 65 74 20 3a 3a 69  000000.  set ::i
3490: 6f 65 72 72 6f 70 74 73 28 2d 70 65 72 73 69 73  oerropts(-persis
34a0: 74 29 20 31 0a 20 20 61 72 72 61 79 20 73 65 74  t) 1.  array set
34b0: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 20 24 61 72   ::ioerropts $ar
34c0: 67 73 0a 0a 20 20 73 65 74 20 3a 3a 67 6f 20 31  gs..  set ::go 1
34d0: 0a 20 20 23 72 65 73 65 74 5f 70 72 6e 67 5f 73  .  #reset_prng_s
34e0: 74 61 74 65 0a 20 20 73 61 76 65 5f 70 72 6e 67  tate.  save_prng
34f0: 5f 73 74 61 74 65 0a 20 20 66 6f 72 20 7b 73 65  _state.  for {se
3500: 74 20 6e 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73  t n $::ioerropts
3510: 28 2d 73 74 61 72 74 29 7d 20 7b 24 3a 3a 67 6f  (-start)} {$::go
3520: 7d 20 7b 69 6e 63 72 20 6e 7d 20 7b 0a 20 20 20  } {incr n} {.   
3530: 20 73 65 74 20 3a 3a 54 4e 20 24 6e 0a 20 20 20   set ::TN $n.   
3540: 20 69 6e 63 72 20 3a 3a 69 6f 65 72 72 6f 70 74   incr ::ioerropt
3550: 73 28 2d 63 6f 75 6e 74 29 20 2d 31 0a 20 20 20  s(-count) -1.   
3560: 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74   if {$::ioerropt
3570: 73 28 2d 63 6f 75 6e 74 29 3c 30 7d 20 62 72 65  s(-count)<0} bre
3580: 61 6b 0a 20 0a 20 20 20 20 23 20 53 6b 69 70 20  ak. .    # Skip 
3590: 74 68 69 73 20 49 4f 20 65 72 72 6f 72 20 69 66  this IO error if
35a0: 20 69 74 20 77 61 73 20 73 70 65 63 69 66 69 65   it was specifie
35b0: 64 20 77 69 74 68 20 74 68 65 20 22 2d 65 78 63  d with the "-exc
35c0: 6c 75 64 65 22 20 6f 70 74 69 6f 6e 2e 0a 20 20  lude" option..  
35d0: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
35e0: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
35f0: 65 78 63 6c 75 64 65 29 5d 7d 20 7b 0a 20 20 20  exclude)]} {.   
3600: 20 20 20 69 66 20 7b 5b 6c 73 65 61 72 63 68 20     if {[lsearch 
3610: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 78  $::ioerropts(-ex
3620: 63 6c 75 64 65 29 20 24 6e 5d 21 3d 2d 31 7d 20  clude) $n]!=-1} 
3630: 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 7d 0a 20  continue.    }. 
3640: 20 20 20 72 65 73 74 6f 72 65 5f 70 72 6e 67 5f     restore_prng_
3650: 73 74 61 74 65 0a 0a 20 20 20 20 23 20 44 65 6c  state..    # Del
3660: 65 74 65 20 74 68 65 20 66 69 6c 65 73 20 74 65  ete the files te
3670: 73 74 2e 64 62 20 61 6e 64 20 74 65 73 74 32 2e  st.db and test2.
3680: 64 62 2c 20 74 68 65 6e 20 65 78 65 63 75 74 65  db, then execute
3690: 20 74 68 65 20 54 43 4c 20 61 6e 64 20 0a 20 20   the TCL and .  
36a0: 20 20 23 20 53 51 4c 20 28 69 6e 20 74 68 61 74    # SQL (in that
36b0: 20 6f 72 64 65 72 29 20 74 6f 20 70 72 65 70 61   order) to prepa
36c0: 72 65 20 66 6f 72 20 74 68 65 20 74 65 73 74 20  re for the test 
36d0: 63 61 73 65 2e 0a 20 20 20 20 64 6f 5f 74 65 73  case..    do_tes
36e0: 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 31  t $testname.$n.1
36f0: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73   {.      set ::s
3700: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70  qlite_io_error_p
3710: 65 6e 64 69 6e 67 20 30 0a 20 20 20 20 20 20 63  ending 0.      c
3720: 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a  atch {db close}.
3730: 20 20 20 20 20 20 63 61 74 63 68 20 7b 66 69 6c        catch {fil
3740: 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20  e delete -force 
3750: 74 65 73 74 2e 64 62 7d 0a 20 20 20 20 20 20 63  test.db}.      c
3760: 61 74 63 68 20 7b 66 69 6c 65 20 64 65 6c 65 74  atch {file delet
3770: 65 20 2d 66 6f 72 63 65 20 74 65 73 74 2e 64 62  e -force test.db
3780: 2d 6a 6f 75 72 6e 61 6c 7d 0a 20 20 20 20 20 20  -journal}.      
3790: 63 61 74 63 68 20 7b 66 69 6c 65 20 64 65 6c 65  catch {file dele
37a0: 74 65 20 2d 66 6f 72 63 65 20 74 65 73 74 32 2e  te -force test2.
37b0: 64 62 7d 0a 20 20 20 20 20 20 63 61 74 63 68 20  db}.      catch 
37c0: 7b 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f  {file delete -fo
37d0: 72 63 65 20 74 65 73 74 32 2e 64 62 2d 6a 6f 75  rce test2.db-jou
37e0: 72 6e 61 6c 7d 0a 20 20 20 20 20 20 73 65 74 20  rnal}.      set 
37f0: 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33 20 64 62  ::DB [sqlite3 db
3800: 20 74 65 73 74 2e 64 62 3b 20 73 71 6c 69 74 65   test.db; sqlite
3810: 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69  3_connection_poi
3820: 6e 74 65 72 20 64 62 5d 0a 20 20 20 20 20 20 73  nter db].      s
3830: 71 6c 69 74 65 33 5f 65 78 74 65 6e 64 65 64 5f  qlite3_extended_
3840: 72 65 73 75 6c 74 5f 63 6f 64 65 73 20 24 3a 3a  result_codes $::
3850: 44 42 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  DB $::ioerropts(
3860: 2d 65 72 63 29 0a 20 20 20 20 20 20 69 66 20 7b  -erc).      if {
3870: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69  [info exists ::i
3880: 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 70 72 65  oerropts(-tclpre
3890: 70 29 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 65  p)]} {.        e
38a0: 76 61 6c 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73  val $::ioerropts
38b0: 28 2d 74 63 6c 70 72 65 70 29 0a 20 20 20 20 20  (-tclprep).     
38c0: 20 7d 0a 20 20 20 20 20 20 69 66 20 7b 5b 69 6e   }.      if {[in
38d0: 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72  fo exists ::ioer
38e0: 72 6f 70 74 73 28 2d 73 71 6c 70 72 65 70 29 5d  ropts(-sqlprep)]
38f0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 65 78 65 63  } {.        exec
3900: 73 71 6c 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73  sql $::ioerropts
3910: 28 2d 73 71 6c 70 72 65 70 29 0a 20 20 20 20 20  (-sqlprep).     
3920: 20 7d 0a 20 20 20 20 20 20 65 78 70 72 20 30 0a   }.      expr 0.
3930: 20 20 20 20 7d 20 7b 30 7d 0a 0a 20 20 20 20 23      } {0}..    #
3940: 20 52 65 61 64 20 74 68 65 20 27 63 68 65 63 6b   Read the 'check
3950: 73 75 6d 27 20 6f 66 20 74 68 65 20 64 61 74 61  sum' of the data
3960: 62 61 73 65 2e 0a 20 20 20 20 69 66 20 7b 24 3a  base..    if {$:
3970: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73 75  :ioerropts(-cksu
3980: 6d 29 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20  m)} {.      set 
3990: 63 68 65 63 6b 73 75 6d 20 5b 63 6b 73 75 6d 5d  checksum [cksum]
39a0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 53 65  .    }..    # Se
39b0: 74 20 74 68 65 20 4e 74 68 20 49 4f 20 65 72 72  t the Nth IO err
39c0: 6f 72 20 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20  or to fail..    
39d0: 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d  do_test $testnam
39e0: 65 2e 24 6e 2e 32 20 5b 73 75 62 73 74 20 7b 0a  e.$n.2 [subst {.
39f0: 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69        set ::sqli
3a00: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 72 73  te_io_error_pers
3a10: 69 73 74 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73  ist $::ioerropts
3a20: 28 2d 70 65 72 73 69 73 74 29 0a 20 20 20 20 20  (-persist).     
3a30: 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f   set ::sqlite_io
3a40: 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 24  _error_pending $
3a50: 6e 0a 20 20 20 20 7d 5d 20 24 6e 0a 20 20 0a 20  n.    }] $n.  . 
3a60: 20 20 20 23 20 43 72 65 61 74 65 20 61 20 73 69     # Create a si
3a70: 6e 67 6c 65 20 54 43 4c 20 73 63 72 69 70 74 20  ngle TCL script 
3a80: 66 72 6f 6d 20 74 68 65 20 54 43 4c 20 61 6e 64  from the TCL and
3a90: 20 53 51 4c 20 73 70 65 63 69 66 69 65 64 0a 20   SQL specified. 
3aa0: 20 20 20 23 20 61 73 20 74 68 65 20 62 6f 64 79     # as the body
3ab0: 20 6f 66 20 74 68 65 20 74 65 73 74 2e 0a 20 20   of the test..  
3ac0: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 72 62    set ::ioerrorb
3ad0: 6f 64 79 20 7b 7d 0a 20 20 20 20 69 66 20 7b 5b  ody {}.    if {[
3ae0: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f  info exists ::io
3af0: 65 72 72 6f 70 74 73 28 2d 74 63 6c 62 6f 64 79  erropts(-tclbody
3b00: 29 5d 7d 20 7b 0a 20 20 20 20 20 20 61 70 70 65  )]} {.      appe
3b10: 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79  nd ::ioerrorbody
3b20: 20 22 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d   "$::ioerropts(-
3b30: 74 63 6c 62 6f 64 79 29 5c 6e 22 0a 20 20 20 20  tclbody)\n".    
3b40: 7d 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20  }.    if {[info 
3b50: 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70  exists ::ioerrop
3b60: 74 73 28 2d 73 71 6c 62 6f 64 79 29 5d 7d 20 7b  ts(-sqlbody)]} {
3b70: 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20 3a 3a  .      append ::
3b80: 69 6f 65 72 72 6f 72 62 6f 64 79 20 22 64 62 20  ioerrorbody "db 
3b90: 65 76 61 6c 20 7b 24 3a 3a 69 6f 65 72 72 6f 70  eval {$::ioerrop
3ba0: 74 73 28 2d 73 71 6c 62 6f 64 79 29 7d 22 0a 20  ts(-sqlbody)}". 
3bb0: 20 20 20 7d 0a 0a 20 20 20 20 23 20 45 78 65 63     }..    # Exec
3bc0: 75 74 65 20 74 68 65 20 54 43 4c 20 53 63 72 69  ute the TCL Scri
3bd0: 70 74 20 63 72 65 61 74 65 64 20 69 6e 20 74 68  pt created in th
3be0: 65 20 61 62 6f 76 65 20 62 6c 6f 63 6b 2e 20 49  e above block. I
3bf0: 66 0a 20 20 20 20 23 20 74 68 65 72 65 20 61 72  f.    # there ar
3c00: 65 20 61 74 20 6c 65 61 73 74 20 4e 20 49 4f 20  e at least N IO 
3c10: 6f 70 65 72 61 74 69 6f 6e 73 20 70 65 72 66 6f  operations perfo
3c20: 72 6d 65 64 20 62 79 20 53 51 4c 69 74 65 20 61  rmed by SQLite a
3c30: 73 0a 20 20 20 20 23 20 61 20 72 65 73 75 6c 74  s.    # a result
3c40: 20 6f 66 20 74 68 65 20 73 63 72 69 70 74 2c 20   of the script, 
3c50: 74 68 65 20 4e 74 68 20 77 69 6c 6c 20 66 61 69  the Nth will fai
3c60: 6c 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24  l..    do_test $
3c70: 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 33 20 7b 0a  testname.$n.3 {.
3c80: 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69        set ::sqli
3c90: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 20  te_io_error_hit 
3ca0: 30 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71  0.      set ::sq
3cb0: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61  lite_io_error_ha
3cc0: 72 64 68 69 74 20 30 0a 20 20 20 20 20 20 73 65  rdhit 0.      se
3cd0: 74 20 72 20 5b 63 61 74 63 68 20 24 3a 3a 69 6f  t r [catch $::io
3ce0: 65 72 72 6f 72 62 6f 64 79 20 6d 73 67 5d 0a 20  errorbody msg]. 
3cf0: 20 20 20 20 20 73 65 74 20 3a 3a 65 72 72 73 65       set ::errse
3d00: 65 6e 20 24 72 0a 20 20 20 20 20 20 73 65 74 20  en $r.      set 
3d10: 72 63 20 5b 73 71 6c 69 74 65 33 5f 65 72 72 63  rc [sqlite3_errc
3d20: 6f 64 65 20 24 3a 3a 44 42 5d 0a 20 20 20 20 20  ode $::DB].     
3d30: 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74   if {$::ioerropt
3d40: 73 28 2d 65 72 63 29 7d 20 7b 0a 20 20 20 20 20  s(-erc)} {.     
3d50: 20 20 20 23 20 49 66 20 77 65 20 61 72 65 20 69     # If we are i
3d60: 6e 20 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c  n extended resul
3d70: 74 20 63 6f 64 65 20 6d 6f 64 65 2c 20 6d 61 6b  t code mode, mak
3d80: 65 20 73 75 72 65 20 61 6c 6c 20 6f 66 20 74 68  e sure all of th
3d90: 65 0a 20 20 20 20 20 20 20 20 23 20 49 4f 45 52  e.        # IOER
3da0: 52 73 20 77 65 20 67 65 74 20 62 61 63 6b 20 72  Rs we get back r
3db0: 65 61 6c 6c 79 20 64 6f 20 68 61 76 65 20 74 68  eally do have th
3dc0: 65 69 72 20 65 78 74 65 6e 64 65 64 20 63 6f 64  eir extended cod
3dd0: 65 20 76 61 6c 75 65 73 2e 0a 20 20 20 20 20 20  e values..      
3de0: 20 20 23 20 49 66 20 61 6e 20 65 78 74 65 6e 64    # If an extend
3df0: 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65 20 69  ed result code i
3e00: 73 20 72 65 74 75 72 6e 65 64 2c 20 74 68 65 20  s returned, the 
3e10: 73 71 6c 69 74 65 33 5f 65 72 72 63 6f 64 65 0a  sqlite3_errcode.
3e20: 20 20 20 20 20 20 20 20 23 20 54 43 4c 63 6f 6d          # TCLcom
3e30: 6d 61 6e 64 20 77 69 6c 6c 20 72 65 74 75 72 6e  mand will return
3e40: 20 61 20 73 74 72 69 6e 67 20 6f 66 20 74 68 65   a string of the
3e50: 20 66 6f 72 6d 3a 20 20 53 51 4c 49 54 45 5f 49   form:  SQLITE_I
3e60: 4f 45 52 52 2b 6e 6e 6e 6e 0a 20 20 20 20 20 20  OERR+nnnn.      
3e70: 20 20 23 20 77 68 65 72 65 20 6e 6e 6e 6e 20 69    # where nnnn i
3e80: 73 20 61 20 6e 75 6d 62 65 72 0a 20 20 20 20 20  s a number.     
3e90: 20 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b     if {[regexp {
3ea0: 5e 53 51 4c 49 54 45 5f 49 4f 45 52 52 7d 20 24  ^SQLITE_IOERR} $
3eb0: 72 63 5d 20 26 26 20 21 5b 72 65 67 65 78 70 20  rc] && ![regexp 
3ec0: 7b 49 4f 45 52 52 5c 2b 5c 64 7d 20 24 72 63 5d  {IOERR\+\d} $rc]
3ed0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65  } {.          re
3ee0: 74 75 72 6e 20 24 72 63 0a 20 20 20 20 20 20 20  turn $rc.       
3ef0: 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20   }.      } else 
3f00: 7b 0a 20 20 20 20 20 20 20 20 23 20 49 66 20 77  {.        # If w
3f10: 65 20 61 72 65 20 6e 6f 74 20 69 6e 20 65 78 74  e are not in ext
3f20: 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64  ended result cod
3f30: 65 20 6d 6f 64 65 2c 20 6d 61 6b 65 20 73 75 72  e mode, make sur
3f40: 65 20 6e 6f 0a 20 20 20 20 20 20 20 20 23 20 65  e no.        # e
3f50: 78 74 65 6e 64 65 64 20 65 72 72 6f 72 20 63 6f  xtended error co
3f60: 64 65 73 20 61 72 65 20 72 65 74 75 72 6e 65 64  des are returned
3f70: 2e 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b 72  ..        if {[r
3f80: 65 67 65 78 70 20 7b 5c 2b 5c 64 7d 20 24 72 63  egexp {\+\d} $rc
3f90: 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 72  ]} {.          r
3fa0: 65 74 75 72 6e 20 24 72 63 0a 20 20 20 20 20 20  eturn $rc.      
3fb0: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
3fc0: 20 20 23 20 54 68 65 20 74 65 73 74 20 72 65 70    # The test rep
3fd0: 65 61 74 73 20 61 73 20 6c 6f 6e 67 20 61 73 20  eats as long as 
3fe0: 24 3a 3a 67 6f 20 69 73 20 6e 6f 6e 2d 7a 65 72  $::go is non-zer
3ff0: 6f 2e 20 20 24 3a 3a 67 6f 20 73 74 61 72 74 73  o.  $::go starts
4000: 20 6f 75 74 0a 20 20 20 20 20 20 23 20 61 73 20   out.      # as 
4010: 31 2e 20 20 57 68 65 6e 20 61 20 74 65 73 74 20  1.  When a test 
4020: 72 75 6e 73 20 74 6f 20 63 6f 6d 70 6c 65 74 69  runs to completi
4030: 6f 6e 20 77 69 74 68 6f 75 74 20 68 69 74 74 69  on without hitti
4040: 6e 67 20 61 6e 20 49 2f 4f 0a 20 20 20 20 20 20  ng an I/O.      
4050: 23 20 65 72 72 6f 72 2c 20 74 68 61 74 20 6d 65  # error, that me
4060: 61 6e 73 20 74 68 65 72 65 20 69 73 20 6e 6f 20  ans there is no 
4070: 70 6f 69 6e 74 20 69 6e 20 63 6f 6e 74 69 6e 75  point in continu
4080: 69 6e 67 20 77 69 74 68 20 74 68 69 73 20 74 65  ing with this te
4090: 73 74 0a 20 20 20 20 20 20 23 20 63 61 73 65 20  st.      # case 
40a0: 73 6f 20 73 65 74 20 24 3a 3a 67 6f 20 74 6f 20  so set $::go to 
40b0: 7a 65 72 6f 2e 0a 20 20 20 20 20 20 23 0a 20 20  zero..      #.  
40c0: 20 20 20 20 69 66 20 7b 24 3a 3a 73 71 6c 69 74      if {$::sqlit
40d0: 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69  e_io_error_pendi
40e0: 6e 67 3e 30 7d 20 7b 0a 20 20 20 20 20 20 20 20  ng>0} {.        
40f0: 73 65 74 20 3a 3a 67 6f 20 30 0a 20 20 20 20 20  set ::go 0.     
4100: 20 20 20 73 65 74 20 71 20 30 0a 20 20 20 20 20     set q 0.     
4110: 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f     set ::sqlite_
4120: 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67  io_error_pending
4130: 20 30 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20   0.      } else 
4140: 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 71 20  {.        set q 
4150: 31 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  1.      }..     
4160: 20 73 65 74 20 73 20 5b 65 78 70 72 20 24 3a 3a   set s [expr $::
4170: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
4180: 68 69 74 3d 3d 30 5d 0a 20 20 20 20 20 20 69 66  hit==0].      if
4190: 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65   {$::sqlite_io_e
41a0: 72 72 6f 72 5f 68 69 74 3e 24 3a 3a 73 71 6c 69  rror_hit>$::sqli
41b0: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64  te_io_error_hard
41c0: 68 69 74 20 26 26 20 24 72 3d 3d 30 7d 20 7b 0a  hit && $r==0} {.
41d0: 20 20 20 20 20 20 20 20 73 65 74 20 72 20 31 0a          set r 1.
41e0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73 65        }.      se
41f0: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
4200: 72 6f 72 5f 68 69 74 20 30 0a 0a 20 20 20 20 20  ror_hit 0..     
4210: 20 23 20 4f 6e 65 20 6f 66 20 74 77 6f 20 74 68   # One of two th
4220: 69 6e 67 73 20 6d 75 73 74 20 68 61 76 65 20 68  ings must have h
4230: 61 70 70 65 6e 65 64 2e 20 65 69 74 68 65 72 0a  appened. either.
4240: 20 20 20 20 20 20 23 20 20 20 31 2e 20 20 57 65        #   1.  We
4250: 20 6e 65 76 65 72 20 68 69 74 20 74 68 65 20 49   never hit the I
4260: 4f 20 65 72 72 6f 72 20 61 6e 64 20 74 68 65 20  O error and the 
4270: 53 51 4c 20 72 65 74 75 72 6e 65 64 20 4f 4b 0a  SQL returned OK.
4280: 20 20 20 20 20 20 23 20 20 20 32 2e 20 20 41 6e        #   2.  An
4290: 20 49 4f 20 65 72 72 6f 72 20 77 61 73 20 68 69   IO error was hi
42a0: 74 20 61 6e 64 20 74 68 65 20 53 51 4c 20 66 61  t and the SQL fa
42b0: 69 6c 65 64 0a 20 20 20 20 20 20 23 0a 20 20 20  iled.      #.   
42c0: 20 20 20 65 78 70 72 20 7b 20 28 24 73 20 26 26     expr { ($s &&
42d0: 20 21 24 72 20 26 26 20 21 24 71 29 20 7c 7c 20   !$r && !$q) || 
42e0: 28 21 24 73 20 26 26 20 24 72 20 26 26 20 24 71  (!$s && $r && $q
42f0: 29 20 7d 0a 20 20 20 20 7d 20 7b 31 7d 0a 0a 20  ) }.    } {1}.. 
4300: 20 20 20 23 20 49 66 20 61 6e 20 49 4f 20 65 72     # If an IO er
4310: 72 6f 72 20 6f 63 63 75 72 65 64 2c 20 74 68 65  ror occured, the
4320: 6e 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 6f  n the checksum o
4330: 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20 73  f the database s
4340: 68 6f 75 6c 64 0a 20 20 20 20 23 20 62 65 20 74  hould.    # be t
4350: 68 65 20 73 61 6d 65 20 61 73 20 62 65 66 6f 72  he same as befor
4360: 65 20 74 68 65 20 73 63 72 69 70 74 20 74 68 61  e the script tha
4370: 74 20 63 61 75 73 65 64 20 74 68 65 20 49 4f 20  t caused the IO 
4380: 65 72 72 6f 72 20 77 61 73 20 72 75 6e 2e 0a 20  error was run.. 
4390: 20 20 20 69 66 20 7b 24 3a 3a 67 6f 20 26 26 20     if {$::go && 
43a0: 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72  $::sqlite_io_err
43b0: 6f 72 5f 68 61 72 64 68 69 74 20 26 26 20 24 3a  or_hardhit && $:
43c0: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73 75  :ioerropts(-cksu
43d0: 6d 29 7d 20 7b 0a 20 20 20 20 20 20 64 6f 5f 74  m)} {.      do_t
43e0: 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e  est $testname.$n
43f0: 2e 34 20 7b 0a 20 20 20 20 20 20 20 20 63 61 74  .4 {.        cat
4400: 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20  ch {db close}.  
4410: 20 20 20 20 20 20 73 65 74 20 3a 3a 44 42 20 5b        set ::DB [
4420: 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e  sqlite3 db test.
4430: 64 62 3b 20 73 71 6c 69 74 65 33 5f 63 6f 6e 6e  db; sqlite3_conn
4440: 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72 20 64  ection_pointer d
4450: 62 5d 0a 20 20 20 20 20 20 20 20 63 6b 73 75 6d  b].        cksum
4460: 0a 20 20 20 20 20 20 7d 20 24 63 68 65 63 6b 73  .      } $checks
4470: 75 6d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 65  um.    }..    se
4480: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
4490: 72 6f 72 5f 68 61 72 64 68 69 74 20 30 0a 20 20  ror_hardhit 0.  
44a0: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
44b0: 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20  o_error_pending 
44c0: 30 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20  0.    if {[info 
44d0: 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70  exists ::ioerrop
44e0: 74 73 28 2d 63 6c 65 61 6e 75 70 29 5d 7d 20 7b  ts(-cleanup)]} {
44f0: 0a 20 20 20 20 20 20 63 61 74 63 68 20 24 3a 3a  .      catch $::
4500: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6c 65 61 6e  ioerropts(-clean
4510: 75 70 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  up).    }.  }.  
4520: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  set ::sqlite_io_
4530: 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a  error_pending 0.
4540: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
4550: 6f 5f 65 72 72 6f 72 5f 70 65 72 73 69 73 74 20  o_error_persist 
4560: 30 0a 20 20 75 6e 73 65 74 20 3a 3a 69 6f 65 72  0.  unset ::ioer
4570: 72 6f 70 74 73 0a 7d 0a 0a 23 20 52 65 74 75 72  ropts.}..# Retur
4580: 6e 20 61 20 63 68 65 63 6b 73 75 6d 20 62 61 73  n a checksum bas
4590: 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e  ed on the conten
45a0: 74 73 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 64  ts of the main d
45b0: 61 74 61 62 61 73 65 20 61 73 73 6f 63 69 61 74  atabase associat
45c0: 65 64 0a 23 20 77 69 74 68 20 63 6f 6e 6e 65 63  ed.# with connec
45d0: 74 69 6f 6e 20 24 64 62 0a 23 0a 70 72 6f 63 20  tion $db.#.proc 
45e0: 63 6b 73 75 6d 20 7b 7b 64 62 20 64 62 7d 7d 20  cksum {{db db}} 
45f0: 7b 0a 20 20 73 65 74 20 74 78 74 20 5b 24 64 62  {.  set txt [$db
4600: 20 65 76 61 6c 20 7b 0a 20 20 20 20 20 20 53 45   eval {.      SE
4610: 4c 45 43 54 20 6e 61 6d 65 2c 20 74 79 70 65 2c  LECT name, type,
4620: 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c 69 74 65   sql FROM sqlite
4630: 5f 6d 61 73 74 65 72 20 6f 72 64 65 72 20 62 79  _master order by
4640: 20 6e 61 6d 65 0a 20 20 7d 5d 5c 6e 0a 20 20 66   name.  }]\n.  f
4650: 6f 72 65 61 63 68 20 74 62 6c 20 5b 24 64 62 20  oreach tbl [$db 
4660: 65 76 61 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c  eval {.      SEL
4670: 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71  ECT name FROM sq
4680: 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52  lite_master WHER
4690: 45 20 74 79 70 65 3d 27 74 61 62 6c 65 27 20 6f  E type='table' o
46a0: 72 64 65 72 20 62 79 20 6e 61 6d 65 0a 20 20 7d  rder by name.  }
46b0: 5d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74  ] {.    append t
46c0: 78 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45  xt [$db eval "SE
46d0: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24 74 62 6c  LECT * FROM $tbl
46e0: 22 5d 5c 6e 0a 20 20 7d 0a 20 20 66 6f 72 65 61  "]\n.  }.  forea
46f0: 63 68 20 70 72 61 67 20 7b 64 65 66 61 75 6c 74  ch prag {default
4700: 5f 73 79 6e 63 68 72 6f 6e 6f 75 73 20 64 65 66  _synchronous def
4710: 61 75 6c 74 5f 63 61 63 68 65 5f 73 69 7a 65 7d  ault_cache_size}
4720: 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78   {.    append tx
4730: 74 20 24 70 72 61 67 2d 5b 24 64 62 20 65 76 61  t $prag-[$db eva
4740: 6c 20 22 50 52 41 47 4d 41 20 24 70 72 61 67 22  l "PRAGMA $prag"
4750: 5d 5c 6e 0a 20 20 7d 0a 20 20 73 65 74 20 63 6b  ]\n.  }.  set ck
4760: 73 75 6d 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67  sum [string leng
4770: 74 68 20 24 74 78 74 5d 2d 5b 6d 64 35 20 24 74  th $txt]-[md5 $t
4780: 78 74 5d 0a 20 20 23 20 70 75 74 73 20 24 63 6b  xt].  # puts $ck
4790: 73 75 6d 2d 5b 66 69 6c 65 20 73 69 7a 65 20 74  sum-[file size t
47a0: 65 73 74 2e 64 62 5d 0a 20 20 72 65 74 75 72 6e  est.db].  return
47b0: 20 24 63 6b 73 75 6d 0a 7d 0a 0a 23 20 47 65 6e   $cksum.}..# Gen
47c0: 65 72 61 74 65 20 61 20 63 68 65 63 6b 73 75 6d  erate a checksum
47d0: 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20 63 6f   based on the co
47e0: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 6d 61  ntents of the ma
47f0: 69 6e 20 61 6e 64 20 74 65 6d 70 20 74 61 62 6c  in and temp tabl
4800: 65 73 0a 23 20 64 61 74 61 62 61 73 65 20 24 64  es.# database $d
4810: 62 2e 20 49 66 20 74 68 65 20 63 68 65 63 6b 73  b. If the checks
4820: 75 6d 20 6f 66 20 74 77 6f 20 64 61 74 61 62 61  um of two databa
4830: 73 65 73 20 69 73 20 74 68 65 20 73 61 6d 65 2c  ses is the same,
4840: 20 61 6e 64 20 74 68 65 0a 23 20 69 6e 74 65 67   and the.# integ
4850: 72 69 74 79 2d 63 68 65 63 6b 20 70 61 73 73 65  rity-check passe
4860: 73 20 66 6f 72 20 62 6f 74 68 2c 20 74 68 65 20  s for both, the 
4870: 74 77 6f 20 64 61 74 61 62 61 73 65 73 20 61 72  two databases ar
4880: 65 20 69 64 65 6e 74 69 63 61 6c 2e 0a 23 0a 70  e identical..#.p
4890: 72 6f 63 20 61 6c 6c 63 6b 73 75 6d 20 7b 7b 64  roc allcksum {{d
48a0: 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74 20 72  b db}} {.  set r
48b0: 65 74 20 5b 6c 69 73 74 5d 0a 20 20 69 66 63 61  et [list].  ifca
48c0: 70 61 62 6c 65 20 74 65 6d 70 64 62 20 7b 0a 20  pable tempdb {. 
48d0: 20 20 20 73 65 74 20 73 71 6c 20 7b 0a 20 20 20     set sql {.   
48e0: 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46     SELECT name F
48f0: 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65  ROM sqlite_maste
4900: 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20 27  r WHERE type = '
4910: 74 61 62 6c 65 27 20 55 4e 49 4f 4e 0a 20 20 20  table' UNION.   
4920: 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46     SELECT name F
4930: 52 4f 4d 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f  ROM sqlite_temp_
4940: 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70  master WHERE typ
4950: 65 20 3d 20 27 74 61 62 6c 65 27 20 55 4e 49 4f  e = 'table' UNIO
4960: 4e 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 27  N.      SELECT '
4970: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 27 20 55  sqlite_master' U
4980: 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45 43  NION.      SELEC
4990: 54 20 27 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d  T 'sqlite_temp_m
49a0: 61 73 74 65 72 27 20 4f 52 44 45 52 20 42 59 20  aster' ORDER BY 
49b0: 31 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65  1.    }.  } else
49c0: 20 7b 0a 20 20 20 20 73 65 74 20 73 71 6c 20 7b   {.    set sql {
49d0: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61  .      SELECT na
49e0: 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d  me FROM sqlite_m
49f0: 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65  aster WHERE type
4a00: 20 3d 20 27 74 61 62 6c 65 27 20 55 4e 49 4f 4e   = 'table' UNION
4a10: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 27 73  .      SELECT 's
4a20: 71 6c 69 74 65 5f 6d 61 73 74 65 72 27 20 4f 52  qlite_master' OR
4a30: 44 45 52 20 42 59 20 31 0a 20 20 20 20 7d 0a 20  DER BY 1.    }. 
4a40: 20 7d 0a 20 20 73 65 74 20 74 62 6c 6c 69 73 74   }.  set tbllist
4a50: 20 5b 24 64 62 20 65 76 61 6c 20 24 73 71 6c 5d   [$db eval $sql]
4a60: 0a 20 20 73 65 74 20 74 78 74 20 7b 7d 0a 20 20  .  set txt {}.  
4a70: 66 6f 72 65 61 63 68 20 74 62 6c 20 24 74 62 6c  foreach tbl $tbl
4a80: 6c 69 73 74 20 7b 0a 20 20 20 20 61 70 70 65 6e  list {.    appen
4a90: 64 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c 20  d txt [$db eval 
4aa0: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24  "SELECT * FROM $
4ab0: 74 62 6c 22 5d 0a 20 20 7d 0a 20 20 66 6f 72 65  tbl"].  }.  fore
4ac0: 61 63 68 20 70 72 61 67 20 7b 64 65 66 61 75 6c  ach prag {defaul
4ad0: 74 5f 63 61 63 68 65 5f 73 69 7a 65 7d 20 7b 0a  t_cache_size} {.
4ae0: 20 20 20 20 61 70 70 65 6e 64 20 74 78 74 20 24      append txt $
4af0: 70 72 61 67 2d 5b 24 64 62 20 65 76 61 6c 20 22  prag-[$db eval "
4b00: 50 52 41 47 4d 41 20 24 70 72 61 67 22 5d 5c 6e  PRAGMA $prag"]\n
4b10: 0a 20 20 7d 0a 20 20 23 20 70 75 74 73 20 74 78  .  }.  # puts tx
4b20: 74 3d 24 74 78 74 0a 20 20 72 65 74 75 72 6e 20  t=$txt.  return 
4b30: 5b 6d 64 35 20 24 74 78 74 5d 0a 7d 0a 0a 70 72  [md5 $txt].}..pr
4b40: 6f 63 20 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f  oc memdebug_log_
4b50: 73 71 6c 20 7b 7b 66 69 6c 65 6e 61 6d 65 20 6d  sql {{filename m
4b60: 61 6c 6c 6f 63 73 2e 73 71 6c 7d 7d 20 7b 0a 0a  allocs.sql}} {..
4b70: 20 20 73 65 74 20 64 61 74 61 20 5b 73 71 6c 69    set data [sqli
4b80: 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67  te3_memdebug_log
4b90: 20 64 75 6d 70 5d 0a 20 20 73 65 74 20 6e 46 72   dump].  set nFr
4ba0: 61 6d 65 20 5b 65 78 70 72 20 5b 6c 6c 65 6e 67  ame [expr [lleng
4bb0: 74 68 20 5b 6c 69 6e 64 65 78 20 24 64 61 74 61  th [lindex $data
4bc0: 20 30 5d 5d 2d 32 5d 0a 20 20 69 66 20 7b 24 6e   0]]-2].  if {$n
4bd0: 46 72 61 6d 65 20 3c 20 30 7d 20 7b 20 72 65 74  Frame < 0} { ret
4be0: 75 72 6e 20 22 22 20 7d 0a 0a 20 20 73 65 74 20  urn "" }..  set 
4bf0: 64 61 74 61 62 61 73 65 20 74 65 6d 70 0a 0a 20  database temp.. 
4c00: 20 73 65 74 20 74 62 6c 20 22 43 52 45 41 54 45   set tbl "CREATE
4c10: 20 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61 73   TABLE ${databas
4c20: 65 7d 2e 6d 61 6c 6c 6f 63 28 6e 43 61 6c 6c 2c  e}.malloc(nCall,
4c30: 20 6e 42 79 74 65 22 0a 20 20 66 6f 72 20 7b 73   nByte".  for {s
4c40: 65 74 20 69 69 20 31 7d 20 7b 24 69 69 20 3c 3d  et ii 1} {$ii <=
4c50: 20 24 6e 46 72 61 6d 65 7d 20 7b 69 6e 63 72 20   $nFrame} {incr 
4c60: 69 69 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64  ii} {.    append
4c70: 20 74 62 6c 20 22 2c 20 66 24 7b 69 69 7d 22 0a   tbl ", f${ii}".
4c80: 20 20 7d 0a 20 20 61 70 70 65 6e 64 20 74 62 6c    }.  append tbl
4c90: 20 22 29 3b 5c 6e 22 0a 0a 20 20 73 65 74 20 73   ");\n"..  set s
4ca0: 71 6c 20 22 22 0a 20 20 66 6f 72 65 61 63 68 20  ql "".  foreach 
4cb0: 65 20 24 64 61 74 61 20 7b 0a 20 20 20 20 61 70  e $data {.    ap
4cc0: 70 65 6e 64 20 73 71 6c 20 22 49 4e 53 45 52 54  pend sql "INSERT
4cd0: 20 49 4e 54 4f 20 24 7b 64 61 74 61 62 61 73 65   INTO ${database
4ce0: 7d 2e 6d 61 6c 6c 6f 63 20 56 41 4c 55 45 53 28  }.malloc VALUES(
4cf0: 5b 6a 6f 69 6e 20 24 65 20 2c 5d 29 3b 5c 6e 22  [join $e ,]);\n"
4d00: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 66 20 5b  .    foreach f [
4d10: 6c 72 61 6e 67 65 20 24 65 20 32 20 65 6e 64 5d  lrange $e 2 end]
4d20: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 66 72 61   {.      set fra
4d30: 6d 65 73 28 24 66 29 20 31 0a 20 20 20 20 7d 0a  mes($f) 1.    }.
4d40: 20 20 7d 0a 0a 20 20 73 65 74 20 74 62 6c 32 20    }..  set tbl2 
4d50: 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 24 7b  "CREATE TABLE ${
4d60: 64 61 74 61 62 61 73 65 7d 2e 66 72 61 6d 65 28  database}.frame(
4d70: 66 72 61 6d 65 20 49 4e 54 45 47 45 52 20 50 52  frame INTEGER PR
4d80: 49 4d 41 52 59 20 4b 45 59 2c 20 6c 69 6e 65 29  IMARY KEY, line)
4d90: 3b 5c 6e 22 0a 20 20 73 65 74 20 74 62 6c 33 20  ;\n".  set tbl3 
4da0: 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 24 7b  "CREATE TABLE ${
4db0: 64 61 74 61 62 61 73 65 7d 2e 66 69 6c 65 28 6e  database}.file(n
4dc0: 61 6d 65 20 50 52 49 4d 41 52 59 20 4b 45 59 2c  ame PRIMARY KEY,
4dd0: 20 63 6f 6e 74 65 6e 74 29 3b 5c 6e 22 0a 0a 20   content);\n".. 
4de0: 20 66 6f 72 65 61 63 68 20 66 20 5b 61 72 72 61   foreach f [arra
4df0: 79 20 6e 61 6d 65 73 20 66 72 61 6d 65 73 5d 20  y names frames] 
4e00: 7b 0a 20 20 20 20 73 65 74 20 61 64 64 72 20 5b  {.    set addr [
4e10: 66 6f 72 6d 61 74 20 25 78 20 24 66 5d 0a 20 20  format %x $f].  
4e20: 20 20 73 65 74 20 63 6d 64 20 22 61 64 64 72 32    set cmd "addr2
4e30: 6c 69 6e 65 20 2d 65 20 5b 69 6e 66 6f 20 6e 61  line -e [info na
4e40: 6d 65 6f 66 65 78 65 63 5d 20 24 61 64 64 72 22  meofexec] $addr"
4e50: 0a 20 20 20 20 73 65 74 20 6c 69 6e 65 20 5b 65  .    set line [e
4e60: 76 61 6c 20 65 78 65 63 20 24 63 6d 64 5d 0a 20  val exec $cmd]. 
4e70: 20 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 49     append sql "I
4e80: 4e 53 45 52 54 20 49 4e 54 4f 20 24 7b 64 61 74  NSERT INTO ${dat
4e90: 61 62 61 73 65 7d 2e 66 72 61 6d 65 20 56 41 4c  abase}.frame VAL
4ea0: 55 45 53 28 24 66 2c 20 27 24 6c 69 6e 65 27 29  UES($f, '$line')
4eb0: 3b 5c 6e 22 0a 0a 20 20 20 20 73 65 74 20 66 69  ;\n"..    set fi
4ec0: 6c 65 20 5b 6c 69 6e 64 65 78 20 5b 73 70 6c 69  le [lindex [spli
4ed0: 74 20 24 6c 69 6e 65 20 3a 5d 20 30 5d 0a 20 20  t $line :] 0].  
4ee0: 20 20 73 65 74 20 66 69 6c 65 73 28 24 66 69 6c    set files($fil
4ef0: 65 29 20 31 0a 20 20 7d 0a 0a 20 20 66 6f 72 65  e) 1.  }..  fore
4f00: 61 63 68 20 66 20 5b 61 72 72 61 79 20 6e 61 6d  ach f [array nam
4f10: 65 73 20 66 69 6c 65 73 5d 20 7b 0a 20 20 20 20  es files] {.    
4f20: 73 65 74 20 63 6f 6e 74 65 6e 74 73 20 22 22 0a  set contents "".
4f30: 20 20 20 20 63 61 74 63 68 20 7b 0a 20 20 20 20      catch {.    
4f40: 20 20 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 24    set fd [open $
4f50: 66 5d 0a 20 20 20 20 20 20 73 65 74 20 63 6f 6e  f].      set con
4f60: 74 65 6e 74 73 20 5b 72 65 61 64 20 24 66 64 5d  tents [read $fd]
4f70: 0a 20 20 20 20 20 20 63 6c 6f 73 65 20 24 66 64  .      close $fd
4f80: 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20 63  .    }.    set c
4f90: 6f 6e 74 65 6e 74 73 20 5b 73 74 72 69 6e 67 20  ontents [string 
4fa0: 6d 61 70 20 7b 27 20 27 27 7d 20 24 63 6f 6e 74  map {' ''} $cont
4fb0: 65 6e 74 73 5d 0a 20 20 20 20 61 70 70 65 6e 64  ents].    append
4fc0: 20 73 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54   sql "INSERT INT
4fd0: 4f 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 66 69  O ${database}.fi
4fe0: 6c 65 20 56 41 4c 55 45 53 28 27 24 66 27 2c 20  le VALUES('$f', 
4ff0: 27 24 63 6f 6e 74 65 6e 74 73 27 29 3b 5c 6e 22  '$contents');\n"
5000: 0a 20 20 7d 0a 0a 20 20 73 65 74 20 66 64 20 5b  .  }..  set fd [
5010: 6f 70 65 6e 20 24 66 69 6c 65 6e 61 6d 65 20 77  open $filename w
5020: 5d 0a 20 20 70 75 74 73 20 24 66 64 20 22 42 45  ].  puts $fd "BE
5030: 47 49 4e 3b 20 24 7b 74 62 6c 7d 24 7b 74 62 6c  GIN; ${tbl}${tbl
5040: 32 7d 24 7b 74 62 6c 33 7d 24 7b 73 71 6c 7d 20  2}${tbl3}${sql} 
5050: 3b 20 43 4f 4d 4d 49 54 3b 22 0a 20 20 63 6c 6f  ; COMMIT;".  clo
5060: 73 65 20 24 66 64 0a 7d 0a 0a 23 20 43 6f 70 79  se $fd.}..# Copy
5070: 20 66 69 6c 65 20 24 66 72 6f 6d 20 69 6e 74 6f   file $from into
5080: 20 24 74 6f 2e 20 54 68 69 73 20 69 73 20 75 73   $to. This is us
5090: 65 64 20 62 65 63 61 75 73 65 20 73 6f 6d 65 20  ed because some 
50a0: 76 65 72 73 69 6f 6e 73 20 6f 66 0a 23 20 54 43  versions of.# TC
50b0: 4c 20 66 6f 72 20 77 69 6e 64 6f 77 73 20 28 6e  L for windows (n
50c0: 6f 74 61 62 6c 79 20 74 68 65 20 38 2e 34 2e 31  otably the 8.4.1
50d0: 20 62 69 6e 61 72 79 20 70 61 63 6b 61 67 65 20   binary package 
50e0: 73 68 69 70 70 65 64 20 77 69 74 68 20 74 68 65  shipped with the
50f0: 0a 23 20 63 75 72 72 65 6e 74 20 6d 69 6e 67 77  .# current mingw
5100: 20 72 65 6c 65 61 73 65 29 20 68 61 76 65 20 61   release) have a
5110: 20 62 72 6f 6b 65 6e 20 22 66 69 6c 65 20 63 6f   broken "file co
5120: 70 79 22 20 63 6f 6d 6d 61 6e 64 2e 0a 23 0a 70  py" command..#.p
5130: 72 6f 63 20 63 6f 70 79 5f 66 69 6c 65 20 7b 66  roc copy_file {f
5140: 72 6f 6d 20 74 6f 7d 20 7b 0a 20 20 69 66 20 7b  rom to} {.  if {
5150: 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28  $::tcl_platform(
5160: 70 6c 61 74 66 6f 72 6d 29 3d 3d 22 75 6e 69 78  platform)=="unix
5170: 22 7d 20 7b 0a 20 20 20 20 66 69 6c 65 20 63 6f  "} {.    file co
5180: 70 79 20 2d 66 6f 72 63 65 20 24 66 72 6f 6d 20  py -force $from 
5190: 24 74 6f 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20  $to.  } else {. 
51a0: 20 20 20 73 65 74 20 66 20 5b 6f 70 65 6e 20 24     set f [open $
51b0: 66 72 6f 6d 5d 0a 20 20 20 20 66 63 6f 6e 66 69  from].    fconfi
51c0: 67 75 72 65 20 24 66 20 2d 74 72 61 6e 73 6c 61  gure $f -transla
51d0: 74 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20 20 20  tion binary.    
51e0: 73 65 74 20 74 20 5b 6f 70 65 6e 20 24 74 6f 20  set t [open $to 
51f0: 77 5d 0a 20 20 20 20 66 63 6f 6e 66 69 67 75 72  w].    fconfigur
5200: 65 20 24 74 20 2d 74 72 61 6e 73 6c 61 74 69 6f  e $t -translatio
5210: 6e 20 62 69 6e 61 72 79 0a 20 20 20 20 70 75 74  n binary.    put
5220: 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 74 20  s -nonewline $t 
5230: 5b 72 65 61 64 20 24 66 20 5b 66 69 6c 65 20 73  [read $f [file s
5240: 69 7a 65 20 24 66 72 6f 6d 5d 5d 0a 20 20 20 20  ize $from]].    
5250: 63 6c 6f 73 65 20 24 74 0a 20 20 20 20 63 6c 6f  close $t.    clo
5260: 73 65 20 24 66 0a 20 20 7d 0a 7d 0a 0a 23 20 49  se $f.  }.}..# I
5270: 66 20 74 68 65 20 6c 69 62 72 61 72 79 20 69 73  f the library is
5280: 20 63 6f 6d 70 69 6c 65 64 20 77 69 74 68 20 74   compiled with t
5290: 68 65 20 53 51 4c 49 54 45 5f 44 45 46 41 55 4c  he SQLITE_DEFAUL
52a0: 54 5f 41 55 54 4f 56 41 43 55 55 4d 20 6d 61 63  T_AUTOVACUUM mac
52b0: 72 6f 20 73 65 74 0a 23 20 74 6f 20 6e 6f 6e 2d  ro set.# to non-
52c0: 7a 65 72 6f 2c 20 74 68 65 6e 20 73 65 74 20 74  zero, then set t
52d0: 68 65 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62  he global variab
52e0: 6c 65 20 24 41 55 54 4f 56 41 43 55 55 4d 20 74  le $AUTOVACUUM t
52f0: 6f 20 31 2e 0a 73 65 74 20 41 55 54 4f 56 41 43  o 1..set AUTOVAC
5300: 55 55 4d 20 24 73 71 6c 69 74 65 5f 6f 70 74 69  UUM $sqlite_opti
5310: 6f 6e 73 28 64 65 66 61 75 6c 74 5f 61 75 74 6f  ons(default_auto
5320: 76 61 63 75 75 6d 29 0a                          vacuum).