/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact a1940002407a4797c7748d633b92c58bfaa211cf:


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 37 30 20 32 30 30 36 2f 31 31 2f 32 33   1.70 2006/11/23
01f0: 20 30 39 3a 33 39 3a 31 36 20 64 72 68 20 45 78   09:39:16 drh Ex
0200: 70 20 24 0a 0a 23 20 4d 61 6b 65 20 73 75 72 65  p $..# Make sure
0210: 20 74 63 6c 73 71 6c 69 74 65 33 20 77 61 73 20   tclsqlite3 was 
0220: 63 6f 6d 70 69 6c 65 64 20 63 6f 72 72 65 63 74  compiled correct
0230: 6c 79 2e 20 20 41 62 6f 72 74 20 6e 6f 77 20 77  ly.  Abort now w
0240: 69 74 68 20 61 6e 0a 23 20 65 72 72 6f 72 20 6d  ith an.# error m
0250: 65 73 73 61 67 65 20 69 66 20 6e 6f 74 2e 0a 23  essage if not..#
0260: 0a 69 66 20 7b 5b 73 71 6c 69 74 65 33 20 2d 74  .if {[sqlite3 -t
0270: 63 6c 2d 75 73 65 73 2d 75 74 66 5d 7d 20 7b 0a  cl-uses-utf]} {.
0280: 20 20 69 66 20 7b 22 5c 75 31 32 33 34 22 3d 3d    if {"\u1234"==
0290: 22 75 31 32 33 34 22 7d 20 7b 0a 20 20 20 20 70  "u1234"} {.    p
02a0: 75 74 73 20 73 74 64 65 72 72 20 22 2a 2a 2a 2a  uts stderr "****
02b0: 2a 20 42 55 49 4c 44 20 50 52 4f 42 4c 45 4d 20  * BUILD PROBLEM 
02c0: 2a 2a 2a 2a 2a 22 0a 20 20 20 20 70 75 74 73 20  *****".    puts 
02d0: 73 74 64 65 72 72 20 22 24 61 72 67 76 30 20 77  stderr "$argv0 w
02e0: 61 73 20 6c 69 6e 6b 65 64 20 61 67 61 69 6e 73  as linked agains
02f0: 74 20 61 6e 20 6f 6c 64 65 72 20 76 65 72 73 69  t an older versi
0300: 6f 6e 22 0a 20 20 20 20 70 75 74 73 20 73 74 64  on".    puts std
0310: 65 72 72 20 22 6f 66 20 54 43 4c 20 74 68 61 74  err "of TCL that
0320: 20 64 6f 65 73 20 6e 6f 74 20 73 75 70 70 6f 72   does not suppor
0330: 74 20 55 6e 69 63 6f 64 65 2c 20 62 75 74 20 75  t Unicode, but u
0340: 73 65 73 20 61 20 68 65 61 64 65 72 22 0a 20 20  ses a header".  
0350: 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22 66    puts stderr "f
0360: 69 6c 65 20 28 5c 22 74 63 6c 2e 68 5c 22 29 20  ile (\"tcl.h\") 
0370: 66 72 6f 6d 20 61 20 6e 65 77 20 54 43 4c 20 76  from a new TCL v
0380: 65 72 73 69 6f 6e 20 74 68 61 74 20 64 6f 65 73  ersion that does
0390: 20 73 75 70 70 6f 72 74 22 0a 20 20 20 20 70 75   support".    pu
03a0: 74 73 20 73 74 64 65 72 72 20 22 55 6e 69 63 6f  ts stderr "Unico
03b0: 64 65 2e 20 20 54 68 69 73 20 63 6f 6d 62 69 6e  de.  This combin
03c0: 61 74 69 6f 6e 20 63 61 75 73 65 73 20 69 6e 74  ation causes int
03d0: 65 72 6e 61 6c 20 65 72 72 6f 72 73 2e 22 0a 20  ernal errors.". 
03e0: 20 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22     puts stderr "
03f0: 52 65 63 6f 6d 70 69 6c 65 20 75 73 69 6e 67 20  Recompile using 
0400: 61 20 54 43 4c 20 6c 69 62 72 61 72 79 20 61 6e  a TCL library an
0410: 64 20 68 65 61 64 65 72 20 66 69 6c 65 20 74 68  d header file th
0420: 61 74 20 6d 61 74 63 68 22 0a 20 20 20 20 70 75  at match".    pu
0430: 74 73 20 73 74 64 65 72 72 20 22 61 6e 64 20 74  ts stderr "and t
0440: 72 79 20 61 67 61 69 6e 2e 5c 6e 2a 2a 2a 2a 2a  ry again.\n*****
0450: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0460: 2a 2a 2a 2a 2a 22 0a 20 20 20 20 65 78 69 74 20  *****".    exit 
0470: 31 0a 20 20 7d 0a 7d 20 65 6c 73 65 20 7b 0a 20  1.  }.} else {. 
0480: 20 69 66 20 7b 22 5c 75 31 32 33 34 22 21 3d 22   if {"\u1234"!="
0490: 75 31 32 33 34 22 7d 20 7b 0a 20 20 20 20 70 75  u1234"} {.    pu
04a0: 74 73 20 73 74 64 65 72 72 20 22 2a 2a 2a 2a 2a  ts stderr "*****
04b0: 20 42 55 49 4c 44 20 50 52 4f 42 4c 45 4d 20 2a   BUILD PROBLEM *
04c0: 2a 2a 2a 2a 22 0a 20 20 20 20 70 75 74 73 20 73  ****".    puts s
04d0: 74 64 65 72 72 20 22 24 61 72 67 76 30 20 77 61  tderr "$argv0 wa
04e0: 73 20 6c 69 6e 6b 65 64 20 61 67 61 69 6e 73 74  s linked against
04f0: 20 61 6e 20 6e 65 77 65 72 20 76 65 72 73 69 6f   an newer versio
0500: 6e 22 0a 20 20 20 20 70 75 74 73 20 73 74 64 65  n".    puts stde
0510: 72 72 20 22 6f 66 20 54 43 4c 20 74 68 61 74 20  rr "of TCL that 
0520: 73 75 70 70 6f 72 74 73 20 55 6e 69 63 6f 64 65  supports Unicode
0530: 2c 20 62 75 74 20 75 73 65 73 20 61 20 68 65 61  , but uses a hea
0540: 64 65 72 20 66 69 6c 65 22 0a 20 20 20 20 70 75  der file".    pu
0550: 74 73 20 73 74 64 65 72 72 20 22 28 5c 22 74 63  ts stderr "(\"tc
0560: 6c 2e 68 5c 22 29 20 66 72 6f 6d 20 61 20 6f 6c  l.h\") from a ol
0570: 64 20 54 43 4c 20 76 65 72 73 69 6f 6e 20 74 68  d TCL version th
0580: 61 74 20 64 6f 65 73 20 6e 6f 74 20 73 75 70 70  at does not supp
0590: 6f 72 74 22 0a 20 20 20 20 70 75 74 73 20 73 74  ort".    puts st
05a0: 64 65 72 72 20 22 55 6e 69 63 6f 64 65 2e 20 20  derr "Unicode.  
05b0: 54 68 69 73 20 63 6f 6d 62 69 6e 61 74 69 6f 6e  This combination
05c0: 20 63 61 75 73 65 73 20 69 6e 74 65 72 6e 61 6c   causes internal
05d0: 20 65 72 72 6f 72 73 2e 22 0a 20 20 20 20 70 75   errors.".    pu
05e0: 74 73 20 73 74 64 65 72 72 20 22 52 65 63 6f 6d  ts stderr "Recom
05f0: 70 69 6c 65 20 75 73 69 6e 67 20 61 20 54 43 4c  pile using a TCL
0600: 20 6c 69 62 72 61 72 79 20 61 6e 64 20 68 65 61   library and hea
0610: 64 65 72 20 66 69 6c 65 20 74 68 61 74 20 6d 61  der file that ma
0620: 74 63 68 22 0a 20 20 20 20 70 75 74 73 20 73 74  tch".    puts st
0630: 64 65 72 72 20 22 61 6e 64 20 74 72 79 20 61 67  derr "and try ag
0640: 61 69 6e 2e 5c 6e 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ain.\n**********
0650: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0660: 22 0a 20 20 20 20 65 78 69 74 20 31 0a 20 20 7d  ".    exit 1.  }
0670: 0a 7d 0a 0a 73 65 74 20 74 63 6c 5f 70 72 65 63  .}..set tcl_prec
0680: 69 73 69 6f 6e 20 31 35 0a 73 65 74 20 73 71 6c  ision 15.set sql
0690: 69 74 65 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65  ite_pending_byte
06a0: 20 30 78 30 30 31 30 30 30 30 0a 0a 23 20 55 73   0x0010000..# Us
06b0: 65 20 74 68 65 20 70 61 67 65 72 20 63 6f 64 65  e the pager code
06c0: 63 20 69 66 20 69 74 20 69 73 20 61 76 61 69 6c  c if it is avail
06d0: 61 62 6c 65 0a 23 0a 69 66 20 7b 5b 73 71 6c 69  able.#.if {[sqli
06e0: 74 65 33 20 2d 68 61 73 2d 63 6f 64 65 63 5d 20  te3 -has-codec] 
06f0: 26 26 20 5b 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64  && [info command
0700: 20 73 71 6c 69 74 65 5f 6f 72 69 67 5d 3d 3d 22   sqlite_orig]=="
0710: 22 7d 20 7b 0a 20 20 72 65 6e 61 6d 65 20 73 71  "} {.  rename sq
0720: 6c 69 74 65 33 20 73 71 6c 69 74 65 5f 6f 72 69  lite3 sqlite_ori
0730: 67 0a 20 20 70 72 6f 63 20 73 71 6c 69 74 65 33  g.  proc sqlite3
0740: 20 7b 61 72 67 73 7d 20 7b 0a 20 20 20 20 69 66   {args} {.    if
0750: 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73   {[llength $args
0760: 5d 3d 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20  ]==2 && [string 
0770: 69 6e 64 65 78 20 5b 6c 69 6e 64 65 78 20 24 61  index [lindex $a
0780: 72 67 73 20 30 5d 20 30 5d 21 3d 22 2d 22 7d 20  rgs 0] 0]!="-"} 
0790: 7b 0a 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20  {.      lappend 
07a0: 61 72 67 73 20 2d 6b 65 79 20 7b 78 79 7a 7a 79  args -key {xyzzy
07b0: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 75 70 6c 65  }.    }.    uple
07c0: 76 65 6c 20 31 20 73 71 6c 69 74 65 5f 6f 72 69  vel 1 sqlite_ori
07d0: 67 20 24 61 72 67 73 0a 20 20 7d 0a 7d 0a 0a 0a  g $args.  }.}...
07e0: 23 20 43 72 65 61 74 65 20 61 20 74 65 73 74 20  # Create a test 
07f0: 64 61 74 61 62 61 73 65 0a 23 0a 63 61 74 63 68  database.#.catch
0800: 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 66 69 6c 65   {db close}.file
0810: 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 74   delete -force t
0820: 65 73 74 2e 64 62 0a 66 69 6c 65 20 64 65 6c 65  est.db.file dele
0830: 74 65 20 2d 66 6f 72 63 65 20 74 65 73 74 2e 64  te -force test.d
0840: 62 2d 6a 6f 75 72 6e 61 6c 0a 73 71 6c 69 74 65  b-journal.sqlite
0850: 33 20 64 62 20 2e 2f 74 65 73 74 2e 64 62 0a 73  3 db ./test.db.s
0860: 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33  et ::DB [sqlite3
0870: 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e  _connection_poin
0880: 74 65 72 20 64 62 5d 0a 69 66 20 7b 5b 69 6e 66  ter db].if {[inf
0890: 6f 20 65 78 69 73 74 73 20 3a 3a 53 45 54 55 50  o exists ::SETUP
08a0: 5f 53 51 4c 5d 7d 20 7b 0a 20 20 64 62 20 65 76  _SQL]} {.  db ev
08b0: 61 6c 20 24 3a 3a 53 45 54 55 50 5f 53 51 4c 0a  al $::SETUP_SQL.
08c0: 7d 0a 0a 23 20 41 62 6f 72 74 20 65 61 72 6c 79  }..# Abort early
08d0: 20 69 66 20 74 68 69 73 20 73 63 72 69 70 74 20   if this script 
08e0: 68 61 73 20 62 65 65 6e 20 72 75 6e 20 62 65 66  has been run bef
08f0: 6f 72 65 2e 0a 23 0a 69 66 20 7b 5b 69 6e 66 6f  ore..#.if {[info
0900: 20 65 78 69 73 74 73 20 6e 54 65 73 74 5d 7d 20   exists nTest]} 
0910: 72 65 74 75 72 6e 0a 0a 23 20 53 65 74 20 74 68  return..# Set th
0920: 65 20 74 65 73 74 20 63 6f 75 6e 74 65 72 73 20  e test counters 
0930: 74 6f 20 7a 65 72 6f 0a 23 0a 73 65 74 20 6e 45  to zero.#.set nE
0940: 72 72 20 30 0a 73 65 74 20 6e 54 65 73 74 20 30  rr 0.set nTest 0
0950: 0a 73 65 74 20 73 6b 69 70 5f 74 65 73 74 20 30  .set skip_test 0
0960: 0a 73 65 74 20 66 61 69 6c 4c 69 73 74 20 7b 7d  .set failList {}
0970: 0a 73 65 74 20 6d 61 78 45 72 72 20 31 30 30 30  .set maxErr 1000
0980: 0a 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73  .if {![info exis
0990: 74 73 20 73 70 65 65 64 54 65 73 74 5d 7d 20 7b  ts speedTest]} {
09a0: 0a 20 20 73 65 74 20 73 70 65 65 64 54 65 73 74  .  set speedTest
09b0: 20 30 0a 7d 0a 0a 23 20 49 6e 76 6f 6b 65 20 74   0.}..# Invoke t
09c0: 68 65 20 64 6f 5f 74 65 73 74 20 70 72 6f 63 65  he do_test proce
09d0: 64 75 72 65 20 74 6f 20 72 75 6e 20 61 20 73 69  dure to run a si
09e0: 6e 67 6c 65 20 74 65 73 74 20 0a 23 0a 70 72 6f  ngle test .#.pro
09f0: 63 20 64 6f 5f 74 65 73 74 20 7b 6e 61 6d 65 20  c do_test {name 
0a00: 63 6d 64 20 65 78 70 65 63 74 65 64 7d 20 7b 0a  cmd expected} {.
0a10: 20 20 67 6c 6f 62 61 6c 20 61 72 67 76 20 6e 45    global argv nE
0a20: 72 72 20 6e 54 65 73 74 20 73 6b 69 70 5f 74 65  rr nTest skip_te
0a30: 73 74 20 6d 61 78 45 72 72 0a 20 20 73 65 74 20  st maxErr.  set 
0a40: 3a 3a 73 71 6c 69 74 65 5f 6d 61 6c 6c 6f 63 5f  ::sqlite_malloc_
0a50: 69 64 20 24 6e 61 6d 65 0a 20 20 69 66 20 7b 24  id $name.  if {$
0a60: 73 6b 69 70 5f 74 65 73 74 7d 20 7b 0a 20 20 20  skip_test} {.   
0a70: 20 73 65 74 20 73 6b 69 70 5f 74 65 73 74 20 30   set skip_test 0
0a80: 0a 20 20 20 20 72 65 74 75 72 6e 0a 20 20 7d 0a  .    return.  }.
0a90: 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24    if {[llength $
0aa0: 61 72 67 76 5d 3d 3d 30 7d 20 7b 20 0a 20 20 20  argv]==0} { .   
0ab0: 20 73 65 74 20 67 6f 20 31 0a 20 20 7d 20 65 6c   set go 1.  } el
0ac0: 73 65 20 7b 0a 20 20 20 20 73 65 74 20 67 6f 20  se {.    set go 
0ad0: 30 0a 20 20 20 20 66 6f 72 65 61 63 68 20 70 61  0.    foreach pa
0ae0: 74 74 65 72 6e 20 24 61 72 67 76 20 7b 0a 20 20  ttern $argv {.  
0af0: 20 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20      if {[string 
0b00: 6d 61 74 63 68 20 24 70 61 74 74 65 72 6e 20 24  match $pattern $
0b10: 6e 61 6d 65 5d 7d 20 7b 0a 20 20 20 20 20 20 20  name]} {.       
0b20: 20 73 65 74 20 67 6f 20 31 0a 20 20 20 20 20 20   set go 1.      
0b30: 20 20 62 72 65 61 6b 0a 20 20 20 20 20 20 7d 0a    break.      }.
0b40: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 20 7b      }.  }.  if {
0b50: 21 24 67 6f 7d 20 72 65 74 75 72 6e 0a 20 20 69  !$go} return.  i
0b60: 6e 63 72 20 6e 54 65 73 74 0a 20 20 70 75 74 73  ncr nTest.  puts
0b70: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 6e 61 6d   -nonewline $nam
0b80: 65 2e 2e 2e 0a 20 20 66 6c 75 73 68 20 73 74 64  e....  flush std
0b90: 6f 75 74 0a 20 20 69 66 20 7b 5b 63 61 74 63 68  out.  if {[catch
0ba0: 20 7b 75 70 6c 65 76 65 6c 20 23 30 20 22 24 63   {uplevel #0 "$c
0bb0: 6d 64 3b 5c 6e 22 7d 20 72 65 73 75 6c 74 5d 7d  md;\n"} result]}
0bc0: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 5c 6e 45   {.    puts "\nE
0bd0: 72 72 6f 72 3a 20 24 72 65 73 75 6c 74 22 0a 20  rror: $result". 
0be0: 20 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20 20     incr nErr.   
0bf0: 20 6c 61 70 70 65 6e 64 20 3a 3a 66 61 69 6c 4c   lappend ::failL
0c00: 69 73 74 20 24 6e 61 6d 65 0a 20 20 20 20 69 66  ist $name.    if
0c10: 20 7b 24 6e 45 72 72 3e 24 6d 61 78 45 72 72 7d   {$nErr>$maxErr}
0c20: 20 7b 70 75 74 73 20 22 2a 2a 2a 20 47 69 76 69   {puts "*** Givi
0c30: 6e 67 20 75 70 2e 2e 2e 22 3b 20 66 69 6e 61 6c  ng up..."; final
0c40: 69 7a 65 5f 74 65 73 74 69 6e 67 7d 0a 20 20 7d  ize_testing}.  }
0c50: 20 65 6c 73 65 69 66 20 7b 5b 73 74 72 69 6e 67   elseif {[string
0c60: 20 63 6f 6d 70 61 72 65 20 24 72 65 73 75 6c 74   compare $result
0c70: 20 24 65 78 70 65 63 74 65 64 5d 7d 20 7b 0a 20   $expected]} {. 
0c80: 20 20 20 70 75 74 73 20 22 5c 6e 45 78 70 65 63     puts "\nExpec
0c90: 74 65 64 3a 20 5c 5b 24 65 78 70 65 63 74 65 64  ted: \[$expected
0ca0: 5c 5d 5c 6e 20 20 20 20 20 47 6f 74 3a 20 5c 5b  \]\n     Got: \[
0cb0: 24 72 65 73 75 6c 74 5c 5d 22 0a 20 20 20 20 69  $result\]".    i
0cc0: 6e 63 72 20 6e 45 72 72 0a 20 20 20 20 6c 61 70  ncr nErr.    lap
0cd0: 70 65 6e 64 20 3a 3a 66 61 69 6c 4c 69 73 74 20  pend ::failList 
0ce0: 24 6e 61 6d 65 0a 20 20 20 20 69 66 20 7b 24 6e  $name.    if {$n
0cf0: 45 72 72 3e 3d 24 6d 61 78 45 72 72 7d 20 7b 70  Err>=$maxErr} {p
0d00: 75 74 73 20 22 2a 2a 2a 20 47 69 76 69 6e 67 20  uts "*** Giving 
0d10: 75 70 2e 2e 2e 22 3b 20 66 69 6e 61 6c 69 7a 65  up..."; finalize
0d20: 5f 74 65 73 74 69 6e 67 7d 0a 20 20 7d 20 65 6c  _testing}.  } el
0d30: 73 65 20 7b 0a 20 20 20 20 70 75 74 73 20 22 20  se {.    puts " 
0d40: 4f 6b 22 0a 20 20 7d 0a 7d 0a 0a 23 20 52 75 6e  Ok".  }.}..# Run
0d50: 20 61 6e 20 53 51 4c 20 73 63 72 69 70 74 2e 20   an SQL script. 
0d60: 20 0a 23 20 52 65 74 75 72 6e 20 74 68 65 20 6e   .# Return the n
0d70: 75 6d 62 65 72 20 6f 66 20 6d 69 63 72 6f 73 65  umber of microse
0d80: 63 6f 6e 64 73 20 70 65 72 20 73 74 61 74 65 6d  conds per statem
0d90: 65 6e 74 2e 0a 23 0a 70 72 6f 63 20 73 70 65 65  ent..#.proc spee
0da0: 64 5f 74 72 69 61 6c 20 7b 6e 61 6d 65 20 6e 75  d_trial {name nu
0db0: 6d 73 74 6d 74 20 73 71 6c 7d 20 7b 0a 20 20 70  mstmt sql} {.  p
0dc0: 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b  uts -nonewline [
0dd0: 66 6f 72 6d 61 74 20 7b 25 2d 32 30 2e 32 30 73  format {%-20.20s
0de0: 20 7d 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66   } $name...].  f
0df0: 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20 73 65  lush stdout.  se
0e00: 74 20 73 70 65 65 64 20 5b 74 69 6d 65 20 7b 73  t speed [time {s
0e10: 71 6c 69 74 65 33 5f 65 78 65 63 5f 6e 72 20 64  qlite3_exec_nr d
0e20: 62 20 24 73 71 6c 7d 5d 0a 20 20 73 65 74 20 74  b $sql}].  set t
0e30: 6d 20 5b 6c 69 6e 64 65 78 20 24 73 70 65 65 64  m [lindex $speed
0e40: 20 30 5d 0a 20 20 73 65 74 20 70 65 72 20 5b 65   0].  set per [e
0e50: 78 70 72 20 7b 24 74 6d 2f 28 31 2e 30 2a 24 6e  xpr {$tm/(1.0*$n
0e60: 75 6d 73 74 6d 74 29 7d 5d 0a 20 20 73 65 74 20  umstmt)}].  set 
0e70: 72 61 74 65 20 5b 65 78 70 72 20 7b 31 30 30 30  rate [expr {1000
0e80: 30 30 30 2e 30 2a 24 6e 75 6d 73 74 6d 74 2f 24  000.0*$numstmt/$
0e90: 74 6d 7d 5d 0a 20 20 70 75 74 73 20 5b 66 6f 72  tm}].  puts [for
0ea0: 6d 61 74 20 7b 25 32 30 2e 31 66 20 75 73 2f 73  mat {%20.1f us/s
0eb0: 74 6d 74 20 25 32 30 2e 35 66 20 73 74 6d 74 2f  tmt %20.5f stmt/
0ec0: 73 7d 20 24 70 65 72 20 24 72 61 74 65 5d 0a 7d  s} $per $rate].}
0ed0: 0a 0a 23 20 54 68 65 20 70 72 6f 63 65 64 75 72  ..# The procedur
0ee0: 65 20 75 73 65 73 20 74 68 65 20 73 70 65 63 69  e uses the speci
0ef0: 61 6c 20 22 73 71 6c 69 74 65 5f 6d 61 6c 6c 6f  al "sqlite_mallo
0f00: 63 5f 73 74 61 74 22 20 63 6f 6d 6d 61 6e 64 0a  c_stat" command.
0f10: 23 20 28 77 68 69 63 68 20 69 73 20 6f 6e 6c 79  # (which is only
0f20: 20 61 76 61 69 6c 61 62 6c 65 20 69 66 20 53 51   available if SQ
0f30: 4c 69 74 65 20 69 73 20 63 6f 6d 70 69 6c 65 64  Lite is compiled
0f40: 20 77 69 74 68 20 2d 44 53 51 4c 49 54 45 5f 44   with -DSQLITE_D
0f50: 45 42 55 47 3d 31 29 0a 23 20 74 6f 20 73 65 65  EBUG=1).# to see
0f60: 20 68 6f 77 20 6d 61 6e 79 20 6d 61 6c 6c 6f 63   how many malloc
0f70: 28 29 73 20 68 61 76 65 20 6e 6f 74 20 62 65 65  ()s have not bee
0f80: 6e 20 66 72 65 65 28 29 65 64 2e 20 20 54 68 65  n free()ed.  The
0f90: 20 6e 75 6d 62 65 72 0a 23 20 6f 66 20 73 75 72   number.# of sur
0fa0: 70 6c 75 73 20 6d 61 6c 6c 6f 63 28 29 73 20 69  plus malloc()s i
0fb0: 73 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20  s stored in the 
0fc0: 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 20  global variable 
0fd0: 24 3a 3a 4c 65 61 6b 2e 0a 23 20 49 66 20 74 68  $::Leak..# If th
0fe0: 65 20 76 61 6c 75 65 20 69 6e 20 24 3a 3a 4c 65  e value in $::Le
0ff0: 61 6b 20 67 72 6f 77 73 2c 20 69 74 20 6d 61 79  ak grows, it may
1000: 20 6d 65 61 6e 20 74 68 65 72 65 20 69 73 20 61   mean there is a
1010: 20 6d 65 6d 6f 72 79 20 6c 65 61 6b 0a 23 20 69   memory leak.# i
1020: 6e 20 74 68 65 20 6c 69 62 72 61 72 79 2e 0a 23  n the library..#
1030: 0a 70 72 6f 63 20 6d 65 6d 6c 65 61 6b 5f 63 68  .proc memleak_ch
1040: 65 63 6b 20 7b 7d 20 7b 0a 20 20 69 66 20 7b 5b  eck {} {.  if {[
1050: 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64 20 73 71 6c  info command sql
1060: 69 74 65 5f 6d 61 6c 6c 6f 63 5f 73 74 61 74 5d  ite_malloc_stat]
1070: 21 3d 22 22 7d 20 7b 0a 20 20 20 20 73 65 74 20  !=""} {.    set 
1080: 72 20 5b 73 71 6c 69 74 65 5f 6d 61 6c 6c 6f 63  r [sqlite_malloc
1090: 5f 73 74 61 74 5d 0a 20 20 20 20 73 65 74 20 3a  _stat].    set :
10a0: 3a 4c 65 61 6b 20 5b 65 78 70 72 20 7b 5b 6c 69  :Leak [expr {[li
10b0: 6e 64 65 78 20 24 72 20 30 5d 2d 5b 6c 69 6e 64  ndex $r 0]-[lind
10c0: 65 78 20 24 72 20 31 5d 7d 5d 0a 20 20 7d 0a 7d  ex $r 1]}].  }.}
10d0: 0a 0a 23 20 52 75 6e 20 74 68 69 73 20 72 6f 75  ..# Run this rou
10e0: 74 69 6e 65 20 6c 61 73 74 0a 23 0a 70 72 6f 63  tine last.#.proc
10f0: 20 66 69 6e 69 73 68 5f 74 65 73 74 20 7b 7d 20   finish_test {} 
1100: 7b 0a 20 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73  {.  finalize_tes
1110: 74 69 6e 67 0a 7d 0a 70 72 6f 63 20 66 69 6e 61  ting.}.proc fina
1120: 6c 69 7a 65 5f 74 65 73 74 69 6e 67 20 7b 7d 20  lize_testing {} 
1130: 7b 0a 20 20 67 6c 6f 62 61 6c 20 6e 54 65 73 74  {.  global nTest
1140: 20 6e 45 72 72 20 73 71 6c 69 74 65 5f 6f 70 65   nErr sqlite_ope
1150: 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 0a 20 20 69  n_file_count.  i
1160: 66 20 7b 24 6e 45 72 72 3d 3d 30 7d 20 6d 65 6d  f {$nErr==0} mem
1170: 6c 65 61 6b 5f 63 68 65 63 6b 0a 0a 20 20 63 61  leak_check..  ca
1180: 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20  tch {db close}. 
1190: 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73   catch {db2 clos
11a0: 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20  e}.  catch {db3 
11b0: 63 6c 6f 73 65 7d 0a 0a 20 20 63 61 74 63 68 20  close}..  catch 
11c0: 7b 0a 20 20 20 20 70 70 5f 63 68 65 63 6b 5f 66  {.    pp_check_f
11d0: 6f 72 5f 6c 65 61 6b 73 0a 20 20 7d 0a 20 20 73  or_leaks.  }.  s
11e0: 71 6c 69 74 65 33 20 64 62 20 7b 7d 0a 20 20 23  qlite3 db {}.  #
11f0: 20 73 71 6c 69 74 65 33 5f 63 6c 65 61 72 5f 74   sqlite3_clear_t
1200: 73 64 5f 6d 65 6d 64 65 62 75 67 0a 20 20 64 62  sd_memdebug.  db
1210: 20 63 6c 6f 73 65 0a 20 20 69 66 20 7b 24 3a 3a   close.  if {$::
1220: 73 71 6c 69 74 65 33 5f 74 73 64 5f 63 6f 75 6e  sqlite3_tsd_coun
1230: 74 7d 20 7b 0a 20 20 20 20 20 70 75 74 73 20 22  t} {.     puts "
1240: 54 68 72 65 61 64 2d 73 70 65 63 69 66 69 63 20  Thread-specific 
1250: 64 61 74 61 20 6c 65 61 6b 3a 20 24 3a 3a 73 71  data leak: $::sq
1260: 6c 69 74 65 33 5f 74 73 64 5f 63 6f 75 6e 74 20  lite3_tsd_count 
1270: 69 6e 73 74 61 6e 63 65 73 22 0a 20 20 20 20 20  instances".     
1280: 69 6e 63 72 20 6e 45 72 72 0a 20 20 7d 20 65 6c  incr nErr.  } el
1290: 73 65 20 7b 0a 20 20 20 20 20 70 75 74 73 20 22  se {.     puts "
12a0: 54 68 72 65 61 64 2d 73 70 65 63 69 66 69 63 20  Thread-specific 
12b0: 64 61 74 61 20 64 65 61 6c 6c 6f 63 61 74 65 64  data deallocated
12c0: 20 70 72 6f 70 65 72 6c 79 22 0a 20 20 7d 0a 20   properly".  }. 
12d0: 20 69 6e 63 72 20 6e 54 65 73 74 0a 20 20 70 75   incr nTest.  pu
12e0: 74 73 20 22 24 6e 45 72 72 20 65 72 72 6f 72 73  ts "$nErr errors
12f0: 20 6f 75 74 20 6f 66 20 24 6e 54 65 73 74 20 74   out of $nTest t
1300: 65 73 74 73 22 0a 20 20 70 75 74 73 20 22 46 61  ests".  puts "Fa
1310: 69 6c 75 72 65 73 20 6f 6e 20 74 68 65 73 65 20  ilures on these 
1320: 74 65 73 74 73 3a 20 24 3a 3a 66 61 69 6c 4c 69  tests: $::failLi
1330: 73 74 22 0a 20 20 69 66 20 7b 24 6e 45 72 72 3e  st".  if {$nErr>
1340: 30 20 26 26 20 21 5b 77 6f 72 6b 69 6e 67 5f 36  0 && ![working_6
1350: 34 62 69 74 5f 69 6e 74 5d 7d 20 7b 0a 20 20 20  4bit_int]} {.   
1360: 20 70 75 74 73 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a   puts "*********
1370: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1380: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1390: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
13a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 20 20 70  *********".    p
13b0: 75 74 73 20 22 4e 2e 42 2e 3a 20 20 54 68 65 20  uts "N.B.:  The 
13c0: 76 65 72 73 69 6f 6e 20 6f 66 20 54 43 4c 20 74  version of TCL t
13d0: 68 61 74 20 79 6f 75 20 75 73 65 64 20 74 6f 20  hat you used to 
13e0: 62 75 69 6c 64 20 74 68 69 73 20 74 65 73 74 20  build this test 
13f0: 68 61 72 6e 65 73 73 22 0a 20 20 20 20 70 75 74  harness".    put
1400: 73 20 22 69 73 20 64 65 66 65 63 74 69 76 65 20  s "is defective 
1410: 69 6e 20 74 68 61 74 20 69 74 20 64 6f 65 73 20  in that it does 
1420: 6e 6f 74 20 73 75 70 70 6f 72 74 20 36 34 2d 62  not support 64-b
1430: 69 74 20 69 6e 74 65 67 65 72 73 2e 20 20 53 6f  it integers.  So
1440: 6d 65 20 6f 72 22 0a 20 20 20 20 70 75 74 73 20  me or".    puts 
1450: 22 61 6c 6c 20 6f 66 20 74 68 65 20 74 65 73 74  "all of the test
1460: 20 66 61 69 6c 75 72 65 73 20 61 62 6f 76 65 20   failures above 
1470: 6d 69 67 68 74 20 62 65 20 61 20 72 65 73 75 6c  might be a resul
1480: 74 20 66 72 6f 6d 20 74 68 69 73 20 64 65 66 65  t from this defe
1490: 63 74 22 0a 20 20 20 20 70 75 74 73 20 22 69 6e  ct".    puts "in
14a0: 20 79 6f 75 72 20 54 43 4c 20 62 75 69 6c 64 2e   your TCL build.
14b0: 22 0a 20 20 20 20 70 75 74 73 20 22 2a 2a 2a 2a  ".    puts "****
14c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
14d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
14e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
14f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a  **************".
1500: 20 20 7d 0a 20 20 69 66 20 7b 24 73 71 6c 69 74    }.  if {$sqlit
1510: 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e  e_open_file_coun
1520: 74 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 24  t} {.    puts "$
1530: 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65  sqlite_open_file
1540: 5f 63 6f 75 6e 74 20 66 69 6c 65 73 20 77 65 72  _count files wer
1550: 65 20 6c 65 66 74 20 6f 70 65 6e 22 0a 20 20 20  e left open".   
1560: 20 69 6e 63 72 20 6e 45 72 72 0a 20 20 7d 0a 20   incr nErr.  }. 
1570: 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f 62   foreach f [glob
1580: 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73   -nocomplain tes
1590: 74 2e 64 62 2d 2a 2d 6a 6f 75 72 6e 61 6c 5d 20  t.db-*-journal] 
15a0: 7b 0a 20 20 20 20 66 69 6c 65 20 64 65 6c 65 74  {.    file delet
15b0: 65 20 2d 66 6f 72 63 65 20 24 66 0a 20 20 7d 0a  e -force $f.  }.
15c0: 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c 6f    foreach f [glo
15d0: 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74 65  b -nocomplain te
15e0: 73 74 2e 64 62 2d 6d 6a 2a 5d 20 7b 0a 20 20 20  st.db-mj*] {.   
15f0: 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f   file delete -fo
1600: 72 63 65 20 24 66 0a 20 20 7d 0a 20 20 65 78 69  rce $f.  }.  exi
1610: 74 20 5b 65 78 70 72 20 7b 24 6e 45 72 72 3e 30  t [expr {$nErr>0
1620: 7d 5d 0a 7d 0a 0a 23 20 41 20 70 72 6f 63 65 64  }].}..# A proced
1630: 75 72 65 20 74 6f 20 65 78 65 63 75 74 65 20 53  ure to execute S
1640: 51 4c 0a 23 0a 70 72 6f 63 20 65 78 65 63 73 71  QL.#.proc execsq
1650: 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20  l {sql {db db}} 
1660: 7b 0a 20 20 23 20 70 75 74 73 20 22 53 51 4c 20  {.  # puts "SQL 
1670: 3d 20 24 73 71 6c 22 0a 20 20 75 70 6c 65 76 65  = $sql".  upleve
1680: 6c 20 5b 6c 69 73 74 20 24 64 62 20 65 76 61 6c  l [list $db eval
1690: 20 24 73 71 6c 5d 0a 7d 0a 0a 23 20 45 78 65 63   $sql].}..# Exec
16a0: 75 74 65 20 53 51 4c 20 61 6e 64 20 63 61 74 63  ute SQL and catc
16b0: 68 20 65 78 63 65 70 74 69 6f 6e 73 2e 0a 23 0a  h exceptions..#.
16c0: 70 72 6f 63 20 63 61 74 63 68 73 71 6c 20 7b 73  proc catchsql {s
16d0: 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20  ql {db db}} {.  
16e0: 23 20 70 75 74 73 20 22 53 51 4c 20 3d 20 24 73  # puts "SQL = $s
16f0: 71 6c 22 0a 20 20 73 65 74 20 72 20 5b 63 61 74  ql".  set r [cat
1700: 63 68 20 7b 24 64 62 20 65 76 61 6c 20 24 73 71  ch {$db eval $sq
1710: 6c 7d 20 6d 73 67 5d 0a 20 20 6c 61 70 70 65 6e  l} msg].  lappen
1720: 64 20 72 20 24 6d 73 67 0a 20 20 72 65 74 75 72  d r $msg.  retur
1730: 6e 20 24 72 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20  n $r.}..# Do an 
1740: 56 44 42 45 20 63 6f 64 65 20 64 75 6d 70 20 6f  VDBE code dump o
1750: 6e 20 74 68 65 20 53 51 4c 20 67 69 76 65 6e 0a  n the SQL given.
1760: 23 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e 20 7b  #.proc explain {
1770: 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20  sql {db db}} {. 
1780: 20 70 75 74 73 20 22 22 0a 20 20 70 75 74 73 20   puts "".  puts 
1790: 22 61 64 64 72 20 20 6f 70 63 6f 64 65 20 20 20  "addr  opcode   
17a0: 20 20 20 20 20 70 31 20 20 20 20 20 20 20 70 32       p1       p2
17b0: 20 20 20 20 20 70 33 20 20 20 20 20 20 20 20 20       p3         
17c0: 20 20 20 20 22 0a 20 20 70 75 74 73 20 22 2d 2d      ".  puts "--
17d0: 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  --  ------------
17e0: 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d    ------  ------
17f0: 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d    --------------
1800: 2d 22 0a 20 20 24 64 62 20 65 76 61 6c 20 22 65  -".  $db eval "e
1810: 78 70 6c 61 69 6e 20 24 73 71 6c 22 20 7b 7d 20  xplain $sql" {} 
1820: 7b 0a 20 20 20 20 70 75 74 73 20 5b 66 6f 72 6d  {.    puts [form
1830: 61 74 20 7b 25 2d 34 64 20 20 25 2d 31 32 2e 31  at {%-4d  %-12.1
1840: 32 73 20 20 25 2d 36 64 20 20 25 2d 36 64 20 20  2s  %-6d  %-6d  
1850: 25 73 7d 20 24 61 64 64 72 20 24 6f 70 63 6f 64  %s} $addr $opcod
1860: 65 20 24 70 31 20 24 70 32 20 24 70 33 5d 0a 20  e $p1 $p2 $p3]. 
1870: 20 7d 0a 7d 0a 0a 23 20 41 6e 6f 74 68 65 72 20   }.}..# Another 
1880: 70 72 6f 63 65 64 75 72 65 20 74 6f 20 65 78 65  procedure to exe
1890: 63 75 74 65 20 53 51 4c 2e 20 20 54 68 69 73 20  cute SQL.  This 
18a0: 6f 6e 65 20 69 6e 63 6c 75 64 65 73 20 74 68 65  one includes the
18b0: 20 66 69 65 6c 64 0a 23 20 6e 61 6d 65 73 20 69   field.# names i
18c0: 6e 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 6c  n the returned l
18d0: 69 73 74 2e 0a 23 0a 70 72 6f 63 20 65 78 65 63  ist..#.proc exec
18e0: 73 71 6c 32 20 7b 73 71 6c 7d 20 7b 0a 20 20 73  sql2 {sql} {.  s
18f0: 65 74 20 72 65 73 75 6c 74 20 7b 7d 0a 20 20 64  et result {}.  d
1900: 62 20 65 76 61 6c 20 24 73 71 6c 20 64 61 74 61  b eval $sql data
1910: 20 7b 0a 20 20 20 20 66 6f 72 65 61 63 68 20 66   {.    foreach f
1920: 20 24 64 61 74 61 28 2a 29 20 7b 0a 20 20 20 20   $data(*) {.    
1930: 20 20 6c 61 70 70 65 6e 64 20 72 65 73 75 6c 74    lappend result
1940: 20 24 66 20 24 64 61 74 61 28 24 66 29 0a 20 20   $f $data($f).  
1950: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
1960: 20 24 72 65 73 75 6c 74 0a 7d 0a 0a 23 20 55 73   $result.}..# Us
1970: 65 20 74 68 65 20 6e 6f 6e 2d 63 61 6c 6c 62 61  e the non-callba
1980: 63 6b 20 41 50 49 20 74 6f 20 65 78 65 63 75 74  ck API to execut
1990: 65 20 6d 75 6c 74 69 70 6c 65 20 53 51 4c 20 73  e multiple SQL s
19a0: 74 61 74 65 6d 65 6e 74 73 0a 23 0a 70 72 6f 63  tatements.#.proc
19b0: 20 73 74 65 70 73 71 6c 20 7b 64 62 70 74 72 20   stepsql {dbptr 
19c0: 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 73 71 6c  sql} {.  set sql
19d0: 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 24 73   [string trim $s
19e0: 71 6c 5d 0a 20 20 73 65 74 20 72 20 30 0a 20 20  ql].  set r 0.  
19f0: 77 68 69 6c 65 20 7b 5b 73 74 72 69 6e 67 20 6c  while {[string l
1a00: 65 6e 67 74 68 20 24 73 71 6c 5d 3e 30 7d 20 7b  ength $sql]>0} {
1a10: 0a 20 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20  .    if {[catch 
1a20: 7b 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65  {sqlite3_prepare
1a30: 20 24 64 62 70 74 72 20 24 73 71 6c 20 2d 31 20   $dbptr $sql -1 
1a40: 73 71 6c 74 61 69 6c 7d 20 76 6d 5d 7d 20 7b 0a  sqltail} vm]} {.
1a50: 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b 6c 69        return [li
1a60: 73 74 20 31 20 24 76 6d 5d 0a 20 20 20 20 7d 0a  st 1 $vm].    }.
1a70: 20 20 20 20 73 65 74 20 73 71 6c 20 5b 73 74 72      set sql [str
1a80: 69 6e 67 20 74 72 69 6d 20 24 73 71 6c 74 61 69  ing trim $sqltai
1a90: 6c 5d 0a 23 20 20 20 20 77 68 69 6c 65 20 7b 5b  l].#    while {[
1aa0: 73 71 6c 69 74 65 5f 73 74 65 70 20 24 76 6d 20  sqlite_step $vm 
1ab0: 4e 20 56 41 4c 20 43 4f 4c 5d 3d 3d 22 53 51 4c  N VAL COL]=="SQL
1ac0: 49 54 45 5f 52 4f 57 22 7d 20 7b 0a 23 20 20 20  ITE_ROW"} {.#   
1ad0: 20 20 20 66 6f 72 65 61 63 68 20 76 20 24 56 41     foreach v $VA
1ae0: 4c 20 7b 6c 61 70 70 65 6e 64 20 72 20 24 76 7d  L {lappend r $v}
1af0: 0a 23 20 20 20 20 7d 0a 20 20 20 20 77 68 69 6c  .#    }.    whil
1b00: 65 20 7b 5b 73 71 6c 69 74 65 33 5f 73 74 65 70  e {[sqlite3_step
1b10: 20 24 76 6d 5d 3d 3d 22 53 51 4c 49 54 45 5f 52   $vm]=="SQLITE_R
1b20: 4f 57 22 7d 20 7b 0a 20 20 20 20 20 20 66 6f 72  OW"} {.      for
1b30: 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 3c 5b   {set i 0} {$i<[
1b40: 73 71 6c 69 74 65 33 5f 64 61 74 61 5f 63 6f 75  sqlite3_data_cou
1b50: 6e 74 20 24 76 6d 5d 7d 20 7b 69 6e 63 72 20 69  nt $vm]} {incr i
1b60: 7d 20 7b 0a 20 20 20 20 20 20 20 20 6c 61 70 70  } {.        lapp
1b70: 65 6e 64 20 72 20 5b 73 71 6c 69 74 65 33 5f 63  end r [sqlite3_c
1b80: 6f 6c 75 6d 6e 5f 74 65 78 74 20 24 76 6d 20 24  olumn_text $vm $
1b90: 69 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  i].      }.    }
1ba0: 0a 20 20 20 20 69 66 20 7b 5b 63 61 74 63 68 20  .    if {[catch 
1bb0: 7b 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a  {sqlite3_finaliz
1bc0: 65 20 24 76 6d 7d 20 65 72 72 6d 73 67 5d 7d 20  e $vm} errmsg]} 
1bd0: 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b  {.      return [
1be0: 6c 69 73 74 20 31 20 24 65 72 72 6d 73 67 5d 0a  list 1 $errmsg].
1bf0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
1c00: 72 6e 20 24 72 0a 7d 0a 0a 23 20 44 65 6c 65 74  rn $r.}..# Delet
1c10: 65 20 61 20 66 69 6c 65 20 6f 72 20 64 69 72 65  e a file or dire
1c20: 63 74 6f 72 79 0a 23 0a 70 72 6f 63 20 66 6f 72  ctory.#.proc for
1c30: 63 65 64 65 6c 65 74 65 20 7b 66 69 6c 65 6e 61  cedelete {filena
1c40: 6d 65 7d 20 7b 0a 20 20 69 66 20 7b 5b 63 61 74  me} {.  if {[cat
1c50: 63 68 20 7b 66 69 6c 65 20 64 65 6c 65 74 65 20  ch {file delete 
1c60: 2d 66 6f 72 63 65 20 24 66 69 6c 65 6e 61 6d 65  -force $filename
1c70: 7d 5d 7d 20 7b 0a 20 20 20 20 65 78 65 63 20 72  }]} {.    exec r
1c80: 6d 20 2d 72 66 20 24 66 69 6c 65 6e 61 6d 65 0a  m -rf $filename.
1c90: 20 20 7d 0a 7d 0a 0a 23 20 44 6f 20 61 6e 20 69    }.}..# Do an i
1ca0: 6e 74 65 67 72 69 74 79 20 63 68 65 63 6b 20 6f  ntegrity check o
1cb0: 66 20 74 68 65 20 65 6e 74 69 72 65 20 64 61 74  f the entire dat
1cc0: 61 62 61 73 65 0a 23 0a 70 72 6f 63 20 69 6e 74  abase.#.proc int
1cd0: 65 67 72 69 74 79 5f 63 68 65 63 6b 20 7b 6e 61  egrity_check {na
1ce0: 6d 65 7d 20 7b 0a 20 20 69 66 63 61 70 61 62 6c  me} {.  ifcapabl
1cf0: 65 20 69 6e 74 65 67 72 69 74 79 63 6b 20 7b 0a  e integrityck {.
1d00: 20 20 20 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d      do_test $nam
1d10: 65 20 7b 0a 20 20 20 20 20 20 65 78 65 63 73 71  e {.      execsq
1d20: 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74 65 67 72  l {PRAGMA integr
1d30: 69 74 79 5f 63 68 65 63 6b 7d 0a 20 20 20 20 7d  ity_check}.    }
1d40: 20 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a 23 20 45   {ok}.  }.}..# E
1d50: 76 61 6c 75 61 74 65 20 61 20 62 6f 6f 6c 65 61  valuate a boolea
1d60: 6e 20 65 78 70 72 65 73 73 69 6f 6e 20 6f 66 20  n expression of 
1d70: 63 61 70 61 62 69 6c 69 74 69 65 73 2e 20 20 49  capabilities.  I
1d80: 66 20 74 72 75 65 2c 20 65 78 65 63 75 74 65 20  f true, execute 
1d90: 74 68 65 0a 23 20 63 6f 64 65 2e 20 20 4f 6d 69  the.# code.  Omi
1da0: 74 20 74 68 65 20 63 6f 64 65 20 69 66 20 66 61  t the code if fa
1db0: 6c 73 65 2e 0a 23 0a 70 72 6f 63 20 69 66 63 61  lse..#.proc ifca
1dc0: 70 61 62 6c 65 20 7b 65 78 70 72 20 63 6f 64 65  pable {expr code
1dd0: 20 7b 65 6c 73 65 20 22 22 7d 20 7b 65 6c 73 65   {else ""} {else
1de0: 63 6f 64 65 20 22 22 7d 7d 20 7b 0a 20 20 72 65  code ""}} {.  re
1df0: 67 73 75 62 20 2d 61 6c 6c 20 7b 5b 61 2d 7a 5f  gsub -all {[a-z_
1e00: 30 2d 39 5d 2b 7d 20 24 65 78 70 72 20 7b 24 3a  0-9]+} $expr {$:
1e10: 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28  :sqlite_options(
1e20: 26 29 7d 20 65 32 0a 20 20 69 66 20 28 24 65 32  &)} e2.  if ($e2
1e30: 29 20 7b 0a 20 20 20 20 73 65 74 20 63 20 5b 63  ) {.    set c [c
1e40: 61 74 63 68 20 7b 75 70 6c 65 76 65 6c 20 31 20  atch {uplevel 1 
1e50: 24 63 6f 64 65 7d 20 72 5d 0a 20 20 7d 20 65 6c  $code} r].  } el
1e60: 73 65 20 7b 0a 20 20 20 20 73 65 74 20 63 20 5b  se {.    set c [
1e70: 63 61 74 63 68 20 7b 75 70 6c 65 76 65 6c 20 31  catch {uplevel 1
1e80: 20 24 65 6c 73 65 63 6f 64 65 7d 20 72 5d 0a 20   $elsecode} r]. 
1e90: 20 7d 0a 20 20 72 65 74 75 72 6e 20 2d 63 6f 64   }.  return -cod
1ea0: 65 20 24 63 20 24 72 0a 7d 0a 0a 23 20 54 68 69  e $c $r.}..# Thi
1eb0: 73 20 70 72 6f 63 20 65 78 65 63 73 20 61 20 73  s proc execs a s
1ec0: 65 70 65 72 61 74 65 20 70 72 6f 63 65 73 73 20  eperate process 
1ed0: 74 68 61 74 20 63 72 61 73 68 65 73 20 6d 69 64  that crashes mid
1ee0: 77 61 79 20 74 68 72 6f 75 67 68 20 65 78 65 63  way through exec
1ef0: 75 74 69 6e 67 0a 23 20 74 68 65 20 53 51 4c 20  uting.# the SQL 
1f00: 73 63 72 69 70 74 20 24 73 71 6c 20 6f 6e 20 64  script $sql on d
1f10: 61 74 61 62 61 73 65 20 74 65 73 74 2e 64 62 2e  atabase test.db.
1f20: 0a 23 0a 23 20 54 68 65 20 63 72 61 73 68 20 6f  .#.# The crash o
1f30: 63 63 75 72 73 20 64 75 72 69 6e 67 20 61 20 73  ccurs during a s
1f40: 79 6e 63 28 29 20 6f 66 20 66 69 6c 65 20 24 63  ync() of file $c
1f50: 72 61 73 68 66 69 6c 65 2e 20 57 68 65 6e 20 74  rashfile. When t
1f60: 68 65 20 63 72 61 73 68 0a 23 20 6f 63 63 75 72  he crash.# occur
1f70: 73 20 61 20 72 61 6e 64 6f 6d 20 73 75 62 73 65  s a random subse
1f80: 74 20 6f 66 20 61 6c 6c 20 75 6e 73 79 6e 63 65  t of all unsynce
1f90: 64 20 77 72 69 74 65 73 20 6d 61 64 65 20 62 79  d writes made by
1fa0: 20 74 68 65 20 70 72 6f 63 65 73 73 20 61 72 65   the process are
1fb0: 0a 23 20 77 72 69 74 74 65 6e 20 69 6e 74 6f 20  .# written into 
1fc0: 74 68 65 20 66 69 6c 65 73 20 6f 6e 20 64 69 73  the files on dis
1fd0: 6b 2e 20 41 72 67 75 6d 65 6e 74 20 24 63 72 61  k. Argument $cra
1fe0: 73 68 64 65 6c 61 79 20 69 6e 64 69 63 61 74 65  shdelay indicate
1ff0: 73 20 74 68 65 0a 23 20 6e 75 6d 62 65 72 20 6f  s the.# number o
2000: 66 20 66 69 6c 65 20 73 79 6e 63 73 20 74 6f 20  f file syncs to 
2010: 77 61 69 74 20 62 65 66 6f 72 65 20 63 72 61 73  wait before cras
2020: 68 69 6e 67 2e 0a 23 0a 23 20 54 68 65 20 72 65  hing..#.# The re
2030: 74 75 72 6e 20 76 61 6c 75 65 20 69 73 20 61 20  turn value is a 
2040: 6c 69 73 74 20 6f 66 20 74 77 6f 20 65 6c 65 6d  list of two elem
2050: 65 6e 74 73 2e 20 54 68 65 20 66 69 72 73 74 20  ents. The first 
2060: 65 6c 65 6d 65 6e 74 20 69 73 20 61 0a 23 20 62  element is a.# b
2070: 6f 6f 6c 65 61 6e 2c 20 69 6e 64 69 63 61 74 69  oolean, indicati
2080: 6e 67 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f  ng whether or no
2090: 74 20 74 68 65 20 70 72 6f 63 65 73 73 20 61 63  t the process ac
20a0: 74 75 61 6c 6c 79 20 63 72 61 73 68 65 64 20 6f  tually crashed o
20b0: 72 0a 23 20 72 65 70 6f 72 74 65 64 20 73 6f 6d  r.# reported som
20c0: 65 20 6f 74 68 65 72 20 65 72 72 6f 72 2e 20 54  e other error. T
20d0: 68 65 20 73 65 63 6f 6e 64 20 65 6c 65 6d 65 6e  he second elemen
20e0: 74 20 69 6e 20 74 68 65 20 72 65 74 75 72 6e 65  t in the returne
20f0: 64 20 6c 69 73 74 20 69 73 20 74 68 65 0a 23 20  d list is the.# 
2100: 65 72 72 6f 72 20 6d 65 73 73 61 67 65 2e 20 54  error message. T
2110: 68 69 73 20 69 73 20 22 63 68 69 6c 64 20 70 72  his is "child pr
2120: 6f 63 65 73 73 20 65 78 69 74 65 64 20 61 62 6e  ocess exited abn
2130: 6f 72 6d 61 6c 6c 79 22 20 69 66 20 74 68 65 20  ormally" if the 
2140: 63 72 61 73 68 0a 23 20 6f 63 63 75 72 65 64 2e  crash.# occured.
2150: 0a 23 0a 70 72 6f 63 20 63 72 61 73 68 73 71 6c  .#.proc crashsql
2160: 20 7b 63 72 61 73 68 64 65 6c 61 79 20 63 72 61   {crashdelay cra
2170: 73 68 66 69 6c 65 20 73 71 6c 7d 20 7b 0a 20 20  shfile sql} {.  
2180: 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66  if {$::tcl_platf
2190: 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 21 3d 22  orm(platform)!="
21a0: 75 6e 69 78 22 7d 20 7b 0a 20 20 20 20 65 72 72  unix"} {.    err
21b0: 6f 72 20 22 63 72 61 73 68 73 71 6c 20 73 68 6f  or "crashsql sho
21c0: 75 6c 64 20 6f 6e 6c 79 20 62 65 20 75 73 65 64  uld only be used
21d0: 20 6f 6e 20 75 6e 69 78 22 0a 20 20 7d 0a 20 20   on unix".  }.  
21e0: 73 65 74 20 63 66 69 6c 65 20 5b 66 69 6c 65 20  set cfile [file 
21f0: 6a 6f 69 6e 20 5b 70 77 64 5d 20 24 63 72 61 73  join [pwd] $cras
2200: 68 66 69 6c 65 5d 0a 0a 20 20 73 65 74 20 66 20  hfile]..  set f 
2210: 5b 6f 70 65 6e 20 63 72 61 73 68 2e 74 63 6c 20  [open crash.tcl 
2220: 77 5d 0a 20 20 70 75 74 73 20 24 66 20 22 73 71  w].  puts $f "sq
2230: 6c 69 74 65 33 5f 63 72 61 73 68 70 61 72 61 6d  lite3_crashparam
2240: 73 20 24 63 72 61 73 68 64 65 6c 61 79 20 24 63  s $crashdelay $c
2250: 66 69 6c 65 22 0a 20 20 70 75 74 73 20 24 66 20  file".  puts $f 
2260: 22 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74  "sqlite3 db test
2270: 2e 64 62 22 0a 20 20 70 75 74 73 20 24 66 20 22  .db".  puts $f "
2280: 64 62 20 65 76 61 6c 20 7b 70 72 61 67 6d 61 20  db eval {pragma 
2290: 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 31 30 7d  cache_size = 10}
22a0: 22 0a 20 20 70 75 74 73 20 24 66 20 22 64 62 20  ".  puts $f "db 
22b0: 65 76 61 6c 20 7b 22 0a 20 20 70 75 74 73 20 24  eval {".  puts $
22c0: 66 20 20 20 22 24 73 71 6c 22 0a 20 20 70 75 74  f   "$sql".  put
22d0: 73 20 24 66 20 22 7d 22 0a 20 20 63 6c 6f 73 65  s $f "}".  close
22e0: 20 24 66 0a 0a 20 20 73 65 74 20 72 20 5b 63 61   $f..  set r [ca
22f0: 74 63 68 20 7b 0a 20 20 20 20 65 78 65 63 20 5b  tch {.    exec [
2300: 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63 5d  info nameofexec]
2310: 20 63 72 61 73 68 2e 74 63 6c 20 3e 40 73 74 64   crash.tcl >@std
2320: 6f 75 74 0a 20 20 7d 20 6d 73 67 5d 0a 20 20 6c  out.  } msg].  l
2330: 61 70 70 65 6e 64 20 72 20 24 6d 73 67 0a 7d 0a  append r $msg.}.
2340: 0a 23 20 55 73 61 67 65 3a 20 64 6f 5f 69 6f 65  .# Usage: do_ioe
2350: 72 72 5f 74 65 73 74 20 3c 74 65 73 74 20 6e 75  rr_test <test nu
2360: 6d 62 65 72 3e 20 3c 6f 70 74 69 6f 6e 73 2e 2e  mber> <options..
2370: 2e 3e 0a 23 0a 23 20 54 68 69 73 20 70 72 6f 63  .>.#.# This proc
2380: 20 69 73 20 75 73 65 64 20 74 6f 20 69 6d 70 6c   is used to impl
2390: 65 6d 65 6e 74 20 74 65 73 74 20 63 61 73 65 73  ement test cases
23a0: 20 74 68 61 74 20 63 68 65 63 6b 20 74 68 61 74   that check that
23b0: 20 49 4f 20 65 72 72 6f 72 73 0a 23 20 61 72 65   IO errors.# are
23c0: 20 63 6f 72 72 65 63 74 6c 79 20 68 61 6e 64 6c   correctly handl
23d0: 65 64 2e 20 54 68 65 20 66 69 72 73 74 20 61 72  ed. The first ar
23e0: 67 75 6d 65 6e 74 2c 20 3c 74 65 73 74 20 6e 75  gument, <test nu
23f0: 6d 62 65 72 3e 2c 20 69 73 20 61 6e 20 69 6e 74  mber>, is an int
2400: 65 67 65 72 20 0a 23 20 75 73 65 64 20 74 6f 20  eger .# used to 
2410: 6e 61 6d 65 20 74 68 65 20 74 65 73 74 73 20 65  name the tests e
2420: 78 65 63 75 74 65 64 20 62 79 20 74 68 69 73 20  xecuted by this 
2430: 70 72 6f 63 2e 20 4f 70 74 69 6f 6e 73 20 61 72  proc. Options ar
2440: 65 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 23 0a  e as follows:.#.
2450: 23 20 20 20 20 20 2d 74 63 6c 70 72 65 70 20 20  #     -tclprep  
2460: 20 20 20 20 20 20 20 20 54 43 4c 20 73 63 72 69          TCL scri
2470: 70 74 20 74 6f 20 72 75 6e 20 74 6f 20 70 72 65  pt to run to pre
2480: 70 61 72 65 20 74 65 73 74 2e 0a 23 20 20 20 20  pare test..#    
2490: 20 2d 73 71 6c 70 72 65 70 20 20 20 20 20 20 20   -sqlprep       
24a0: 20 20 20 53 51 4c 20 73 63 72 69 70 74 20 74 6f     SQL script to
24b0: 20 72 75 6e 20 74 6f 20 70 72 65 70 61 72 65 20   run to prepare 
24c0: 74 65 73 74 2e 0a 23 20 20 20 20 20 2d 74 63 6c  test..#     -tcl
24d0: 62 6f 64 79 20 20 20 20 20 20 20 20 20 20 54 43  body          TC
24e0: 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20  L script to run 
24f0: 77 69 74 68 20 49 4f 20 65 72 72 6f 72 20 73 69  with IO error si
2500: 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20 20 20 20 20  mulation..#     
2510: 2d 73 71 6c 62 6f 64 79 20 20 20 20 20 20 20 20  -sqlbody        
2520: 20 20 54 43 4c 20 73 63 72 69 70 74 20 74 6f 20    TCL script to 
2530: 72 75 6e 20 77 69 74 68 20 49 4f 20 65 72 72 6f  run with IO erro
2540: 72 20 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20  r simulation..# 
2550: 20 20 20 20 2d 65 78 63 6c 75 64 65 20 20 20 20      -exclude    
2560: 20 20 20 20 20 20 4c 69 73 74 20 6f 66 20 27 4e        List of 'N
2570: 27 20 76 61 6c 75 65 73 20 6e 6f 74 20 74 6f 20  ' values not to 
2580: 74 65 73 74 2e 0a 23 20 20 20 20 20 2d 65 72 63  test..#     -erc
2590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 55 73                Us
25a0: 65 20 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c  e extended resul
25b0: 74 20 63 6f 64 65 73 0a 23 20 20 20 20 20 2d 73  t codes.#     -s
25c0: 74 61 72 74 20 20 20 20 20 20 20 20 20 20 20 20  tart            
25d0: 56 61 6c 75 65 20 6f 66 20 27 4e 27 20 74 6f 20  Value of 'N' to 
25e0: 62 65 67 69 6e 20 77 69 74 68 20 28 64 65 66 61  begin with (defa
25f0: 75 6c 74 20 31 29 0a 23 0a 23 20 20 20 20 20 2d  ult 1).#.#     -
2600: 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20 20 20  cksum           
2610: 20 42 6f 6f 6c 65 61 6e 2e 20 49 66 20 74 72 75   Boolean. If tru
2620: 65 2c 20 74 65 73 74 20 74 68 61 74 20 74 68 65  e, test that the
2630: 20 64 61 74 61 62 61 73 65 20 64 6f 65 73 0a 23   database does.#
2640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2650: 20 20 20 20 20 20 20 6e 6f 74 20 63 68 61 6e 67         not chang
2660: 65 20 64 75 72 69 6e 67 20 74 68 65 20 65 78 65  e during the exe
2670: 63 75 74 69 6f 6e 20 6f 66 20 74 68 65 20 74 65  cution of the te
2680: 73 74 20 63 61 73 65 2e 0a 23 0a 70 72 6f 63 20  st case..#.proc 
2690: 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20 7b 74  do_ioerr_test {t
26a0: 65 73 74 6e 61 6d 65 20 61 72 67 73 7d 20 7b 0a  estname args} {.
26b0: 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70  .  set ::ioerrop
26c0: 74 73 28 2d 73 74 61 72 74 29 20 31 0a 20 20 73  ts(-start) 1.  s
26d0: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  et ::ioerropts(-
26e0: 63 6b 73 75 6d 29 20 30 0a 20 20 73 65 74 20 3a  cksum) 0.  set :
26f0: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29  :ioerropts(-erc)
2700: 20 30 0a 20 20 61 72 72 61 79 20 73 65 74 20 3a   0.  array set :
2710: 3a 69 6f 65 72 72 6f 70 74 73 20 24 61 72 67 73  :ioerropts $args
2720: 0a 0a 20 20 73 65 74 20 3a 3a 67 6f 20 31 0a 20  ..  set ::go 1. 
2730: 20 66 6f 72 20 7b 73 65 74 20 6e 20 24 3a 3a 69   for {set n $::i
2740: 6f 65 72 72 6f 70 74 73 28 2d 73 74 61 72 74 29  oerropts(-start)
2750: 7d 20 7b 24 3a 3a 67 6f 7d 20 7b 69 6e 63 72 20  } {$::go} {incr 
2760: 6e 7d 20 7b 0a 20 0a 20 20 20 20 23 20 53 6b 69  n} {. .    # Ski
2770: 70 20 74 68 69 73 20 49 4f 20 65 72 72 6f 72 20  p this IO error 
2780: 69 66 20 69 74 20 77 61 73 20 73 70 65 63 69 66  if it was specif
2790: 69 65 64 20 77 69 74 68 20 74 68 65 20 22 2d 65  ied with the "-e
27a0: 78 63 6c 75 64 65 22 20 6f 70 74 69 6f 6e 2e 0a  xclude" option..
27b0: 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78      if {[info ex
27c0: 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73  ists ::ioerropts
27d0: 28 2d 65 78 63 6c 75 64 65 29 5d 7d 20 7b 0a 20  (-exclude)]} {. 
27e0: 20 20 20 20 20 69 66 20 7b 5b 6c 73 65 61 72 63       if {[lsearc
27f0: 68 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  h $::ioerropts(-
2800: 65 78 63 6c 75 64 65 29 20 24 6e 5d 21 3d 2d 31  exclude) $n]!=-1
2810: 7d 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 7d  } continue.    }
2820: 0a 0a 20 20 20 20 23 20 44 65 6c 65 74 65 20 74  ..    # Delete t
2830: 68 65 20 66 69 6c 65 73 20 74 65 73 74 2e 64 62  he files test.db
2840: 20 61 6e 64 20 74 65 73 74 32 2e 64 62 2c 20 74   and test2.db, t
2850: 68 65 6e 20 65 78 65 63 75 74 65 20 74 68 65 20  hen execute the 
2860: 54 43 4c 20 61 6e 64 20 0a 20 20 20 20 23 20 53  TCL and .    # S
2870: 51 4c 20 28 69 6e 20 74 68 61 74 20 6f 72 64 65  QL (in that orde
2880: 72 29 20 74 6f 20 70 72 65 70 61 72 65 20 66 6f  r) to prepare fo
2890: 72 20 74 68 65 20 74 65 73 74 20 63 61 73 65 2e  r the test case.
28a0: 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65  .    do_test $te
28b0: 73 74 6e 61 6d 65 2e 24 6e 2e 31 20 7b 0a 20 20  stname.$n.1 {.  
28c0: 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65      set ::sqlite
28d0: 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e  _io_error_pendin
28e0: 67 20 30 0a 20 20 20 20 20 20 63 61 74 63 68 20  g 0.      catch 
28f0: 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20  {db close}.     
2900: 20 63 61 74 63 68 20 7b 66 69 6c 65 20 64 65 6c   catch {file del
2910: 65 74 65 20 2d 66 6f 72 63 65 20 74 65 73 74 2e  ete -force test.
2920: 64 62 7d 0a 20 20 20 20 20 20 63 61 74 63 68 20  db}.      catch 
2930: 7b 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f  {file delete -fo
2940: 72 63 65 20 74 65 73 74 2e 64 62 2d 6a 6f 75 72  rce test.db-jour
2950: 6e 61 6c 7d 0a 20 20 20 20 20 20 63 61 74 63 68  nal}.      catch
2960: 20 7b 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66   {file delete -f
2970: 6f 72 63 65 20 74 65 73 74 32 2e 64 62 7d 0a 20  orce test2.db}. 
2980: 20 20 20 20 20 63 61 74 63 68 20 7b 66 69 6c 65       catch {file
2990: 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 74   delete -force t
29a0: 65 73 74 32 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d  est2.db-journal}
29b0: 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 44 42 20  .      set ::DB 
29c0: 5b 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74  [sqlite3 db test
29d0: 2e 64 62 3b 20 73 71 6c 69 74 65 33 5f 63 6f 6e  .db; sqlite3_con
29e0: 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72 20  nection_pointer 
29f0: 64 62 5d 0a 20 20 20 20 20 20 73 71 6c 69 74 65  db].      sqlite
2a00: 33 5f 65 78 74 65 6e 64 65 64 5f 72 65 73 75 6c  3_extended_resul
2a10: 74 5f 63 6f 64 65 73 20 24 3a 3a 44 42 20 24 3a  t_codes $::DB $:
2a20: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29  :ioerropts(-erc)
2a30: 0a 20 20 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f  .      if {[info
2a40: 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f   exists ::ioerro
2a50: 70 74 73 28 2d 74 63 6c 70 72 65 70 29 5d 7d 20  pts(-tclprep)]} 
2a60: 7b 0a 20 20 20 20 20 20 20 20 65 76 61 6c 20 24  {.        eval $
2a70: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c  ::ioerropts(-tcl
2a80: 70 72 65 70 29 0a 20 20 20 20 20 20 7d 0a 20 20  prep).      }.  
2a90: 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78      if {[info ex
2aa0: 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73  ists ::ioerropts
2ab0: 28 2d 73 71 6c 70 72 65 70 29 5d 7d 20 7b 0a 20  (-sqlprep)]} {. 
2ac0: 20 20 20 20 20 20 20 65 78 65 63 73 71 6c 20 24         execsql $
2ad0: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c  ::ioerropts(-sql
2ae0: 70 72 65 70 29 0a 20 20 20 20 20 20 7d 0a 20 20  prep).      }.  
2af0: 20 20 20 20 65 78 70 72 20 30 0a 20 20 20 20 7d      expr 0.    }
2b00: 20 7b 30 7d 0a 0a 20 20 20 20 23 20 52 65 61 64   {0}..    # Read
2b10: 20 74 68 65 20 27 63 68 65 63 6b 73 75 6d 27 20   the 'checksum' 
2b20: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 2e  of the database.
2b30: 0a 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72  .    if {$::ioer
2b40: 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b  ropts(-cksum)} {
2b50: 0a 20 20 20 20 20 20 73 65 74 20 63 68 65 63 6b  .      set check
2b60: 73 75 6d 20 5b 63 6b 73 75 6d 5d 0a 20 20 20 20  sum [cksum].    
2b70: 7d 0a 20 20 0a 20 20 20 20 23 20 53 65 74 20 74  }.  .    # Set t
2b80: 68 65 20 4e 74 68 20 49 4f 20 65 72 72 6f 72 20  he Nth IO error 
2b90: 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20 64 6f 5f  to fail..    do_
2ba0: 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24  test $testname.$
2bb0: 6e 2e 32 20 5b 73 75 62 73 74 20 7b 0a 20 20 20  n.2 [subst {.   
2bc0: 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f     set ::sqlite_
2bd0: 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67  io_error_pending
2be0: 20 24 6e 0a 20 20 20 20 7d 5d 20 24 6e 0a 20 20   $n.    }] $n.  
2bf0: 0a 20 20 20 20 23 20 43 72 65 61 74 65 20 61 20  .    # Create a 
2c00: 73 69 6e 67 6c 65 20 54 43 4c 20 73 63 72 69 70  single TCL scrip
2c10: 74 20 66 72 6f 6d 20 74 68 65 20 54 43 4c 20 61  t from the TCL a
2c20: 6e 64 20 53 51 4c 20 73 70 65 63 69 66 69 65 64  nd SQL specified
2c30: 0a 20 20 20 20 23 20 61 73 20 74 68 65 20 62 6f  .    # as the bo
2c40: 64 79 20 6f 66 20 74 68 65 20 74 65 73 74 2e 0a  dy of the test..
2c50: 20 20 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f      set ::ioerro
2c60: 72 62 6f 64 79 20 7b 7d 0a 20 20 20 20 69 66 20  rbody {}.    if 
2c70: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
2c80: 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 62 6f  ioerropts(-tclbo
2c90: 64 79 29 5d 7d 20 7b 0a 20 20 20 20 20 20 61 70  dy)]} {.      ap
2ca0: 70 65 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f  pend ::ioerrorbo
2cb0: 64 79 20 22 24 3a 3a 69 6f 65 72 72 6f 70 74 73  dy "$::ioerropts
2cc0: 28 2d 74 63 6c 62 6f 64 79 29 5c 6e 22 0a 20 20  (-tclbody)\n".  
2cd0: 20 20 7d 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66    }.    if {[inf
2ce0: 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72  o exists ::ioerr
2cf0: 6f 70 74 73 28 2d 73 71 6c 62 6f 64 79 29 5d 7d  opts(-sqlbody)]}
2d00: 20 7b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20   {.      append 
2d10: 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 22 64  ::ioerrorbody "d
2d20: 62 20 65 76 61 6c 20 7b 24 3a 3a 69 6f 65 72 72  b eval {$::ioerr
2d30: 6f 70 74 73 28 2d 73 71 6c 62 6f 64 79 29 7d 22  opts(-sqlbody)}"
2d40: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 45 78  .    }..    # Ex
2d50: 65 63 75 74 65 20 74 68 65 20 54 43 4c 20 53 63  ecute the TCL Sc
2d60: 72 69 70 74 20 63 72 65 61 74 65 64 20 69 6e 20  ript created in 
2d70: 74 68 65 20 61 62 6f 76 65 20 62 6c 6f 63 6b 2e  the above block.
2d80: 20 49 66 0a 20 20 20 20 23 20 74 68 65 72 65 20   If.    # there 
2d90: 61 72 65 20 61 74 20 6c 65 61 73 74 20 4e 20 49  are at least N I
2da0: 4f 20 6f 70 65 72 61 74 69 6f 6e 73 20 70 65 72  O operations per
2db0: 66 6f 72 6d 65 64 20 62 79 20 53 51 4c 69 74 65  formed by SQLite
2dc0: 20 61 73 0a 20 20 20 20 23 20 61 20 72 65 73 75   as.    # a resu
2dd0: 6c 74 20 6f 66 20 74 68 65 20 73 63 72 69 70 74  lt of the script
2de0: 2c 20 74 68 65 20 4e 74 68 20 77 69 6c 6c 20 66  , the Nth will f
2df0: 61 69 6c 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74  ail..    do_test
2e00: 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 33 20   $testname.$n.3 
2e10: 7b 0a 20 20 20 20 20 20 73 65 74 20 72 20 5b 63  {.      set r [c
2e20: 61 74 63 68 20 24 3a 3a 69 6f 65 72 72 6f 72 62  atch $::ioerrorb
2e30: 6f 64 79 20 6d 73 67 5d 0a 20 20 20 20 20 20 23  ody msg].      #
2e40: 20 70 75 74 73 20 72 63 3d 5b 73 71 6c 69 74 65   puts rc=[sqlite
2e50: 33 5f 65 72 72 63 6f 64 65 20 24 3a 3a 44 42 5d  3_errcode $::DB]
2e60: 0a 20 20 20 20 20 20 73 65 74 20 72 63 20 5b 73  .      set rc [s
2e70: 71 6c 69 74 65 33 5f 65 72 72 63 6f 64 65 20 24  qlite3_errcode $
2e80: 3a 3a 44 42 5d 0a 20 20 20 20 20 20 69 66 20 7b  ::DB].      if {
2e90: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72  $::ioerropts(-er
2ea0: 63 29 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20  c)} {.        # 
2eb0: 49 6e 20 65 78 74 65 6e 64 65 64 20 72 65 73 75  In extended resu
2ec0: 6c 74 20 6d 6f 64 65 2c 20 61 6c 6c 20 49 4f 45  lt mode, all IOE
2ed0: 52 52 73 20 61 72 65 20 71 75 61 6c 69 66 69 65  RRs are qualifie
2ee0: 64 20 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b  d .        if {[
2ef0: 72 65 67 65 78 70 20 7b 5e 53 51 4c 49 54 45 5f  regexp {^SQLITE_
2f00: 49 4f 45 52 52 7d 20 24 72 63 5d 20 26 26 20 21  IOERR} $rc] && !
2f10: 5b 72 65 67 65 78 70 20 7b 49 4f 45 52 52 5c 2b  [regexp {IOERR\+
2f20: 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20 20  \d} $rc]} {.    
2f30: 20 20 20 20 20 20 72 65 74 75 72 6e 20 24 72 63        return $rc
2f40: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
2f50: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20   } else {.      
2f60: 20 20 23 20 4e 6f 74 20 69 6e 20 65 78 74 65 6e    # Not in exten
2f70: 64 65 64 20 72 65 73 75 6c 74 20 6d 6f 64 65 2c  ded result mode,
2f80: 20 6e 6f 20 65 72 72 6f 72 73 20 61 72 65 20 71   no errors are q
2f90: 75 61 6c 69 66 69 65 64 0a 20 20 20 20 20 20 20  ualified.       
2fa0: 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5c 2b   if {[regexp {\+
2fb0: 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20 20  \d} $rc]} {.    
2fc0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 24 72 63        return $rc
2fd0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
2fe0: 20 7d 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 67   }.      set ::g
2ff0: 6f 20 5b 65 78 70 72 20 7b 24 3a 3a 73 71 6c 69  o [expr {$::sqli
3000: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64  te_io_error_pend
3010: 69 6e 67 3c 3d 30 7d 5d 0a 20 20 20 20 20 20 73  ing<=0}].      s
3020: 65 74 20 73 20 5b 65 78 70 72 20 24 3a 3a 73 71  et s [expr $::sq
3030: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69  lite_io_error_hi
3040: 74 3d 3d 30 5d 0a 20 20 20 20 20 20 73 65 74 20  t==0].      set 
3050: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
3060: 72 5f 68 69 74 20 30 0a 20 20 20 20 20 20 23 20  r_hit 0.      # 
3070: 70 75 74 73 20 22 24 3a 3a 73 71 6c 69 74 65 5f  puts "$::sqlite_
3080: 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67  io_error_pending
3090: 20 24 72 20 24 6d 73 67 22 0a 20 20 20 20 20 20   $r $msg".      
30a0: 23 20 70 75 74 73 20 22 72 3d 24 72 20 73 3d 24  # puts "r=$r s=$
30b0: 73 20 67 6f 3d 24 3a 3a 67 6f 20 6d 73 67 3d 5c  s go=$::go msg=\
30c0: 22 24 6d 73 67 5c 22 22 0a 20 20 20 20 20 20 65  "$msg\"".      e
30d0: 78 70 72 20 7b 20 28 24 73 20 26 26 20 21 24 72  xpr { ($s && !$r
30e0: 20 26 26 20 21 24 3a 3a 67 6f 29 20 7c 7c 20 28   && !$::go) || (
30f0: 21 24 73 20 26 26 20 24 72 20 26 26 20 24 3a 3a  !$s && $r && $::
3100: 67 6f 29 20 7d 0a 20 20 20 20 20 20 23 20 65 78  go) }.      # ex
3110: 70 72 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 69 6f  pr {$::sqlite_io
3120: 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 3e 30  _error_pending>0
3130: 20 7c 7c 20 24 72 21 3d 30 7d 0a 20 20 20 20 7d   || $r!=0}.    }
3140: 20 7b 31 7d 0a 0a 20 20 20 20 23 20 49 66 20 61   {1}..    # If a
3150: 6e 20 49 4f 20 65 72 72 6f 72 20 6f 63 63 75 72  n IO error occur
3160: 65 64 2c 20 74 68 65 6e 20 74 68 65 20 63 68 65  ed, then the che
3170: 63 6b 73 75 6d 20 6f 66 20 74 68 65 20 64 61 74  cksum of the dat
3180: 61 62 61 73 65 20 73 68 6f 75 6c 64 0a 20 20 20  abase should.   
3190: 20 23 20 62 65 20 74 68 65 20 73 61 6d 65 20 61   # be the same a
31a0: 73 20 62 65 66 6f 72 65 20 74 68 65 20 73 63 72  s before the scr
31b0: 69 70 74 20 74 68 61 74 20 63 61 75 73 65 64 20  ipt that caused 
31c0: 74 68 65 20 49 4f 20 65 72 72 6f 72 20 77 61 73  the IO error was
31d0: 20 72 75 6e 2e 0a 20 20 20 20 69 66 20 7b 24 3a   run..    if {$:
31e0: 3a 67 6f 20 26 26 20 24 3a 3a 69 6f 65 72 72 6f  :go && $::ioerro
31f0: 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20  pts(-cksum)} {. 
3200: 20 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65       do_test $te
3210: 73 74 6e 61 6d 65 2e 24 6e 2e 34 20 7b 0a 20 20  stname.$n.4 {.  
3220: 20 20 20 20 20 20 63 61 74 63 68 20 7b 64 62 20        catch {db 
3230: 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20 20 20 73  close}.        s
3240: 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33  et ::DB [sqlite3
3250: 20 64 62 20 74 65 73 74 2e 64 62 3b 20 73 71 6c   db test.db; sql
3260: 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f  ite3_connection_
3270: 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20 20 20  pointer db].    
3280: 20 20 20 20 63 6b 73 75 6d 0a 20 20 20 20 20 20      cksum.      
3290: 7d 20 24 63 68 65 63 6b 73 75 6d 0a 20 20 20 20  } $checksum.    
32a0: 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c  }..    set ::sql
32b0: 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e  ite_io_error_pen
32c0: 64 69 6e 67 20 30 0a 20 20 20 20 69 66 20 7b 5b  ding 0.    if {[
32d0: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f  info exists ::io
32e0: 65 72 72 6f 70 74 73 28 2d 63 6c 65 61 6e 75 70  erropts(-cleanup
32f0: 29 5d 7d 20 7b 0a 20 20 20 20 20 20 63 61 74 63  )]} {.      catc
3300: 68 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  h $::ioerropts(-
3310: 63 6c 65 61 6e 75 70 29 0a 20 20 20 20 7d 0a 20  cleanup).    }. 
3320: 20 7d 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74   }.  set ::sqlit
3330: 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69  e_io_error_pendi
3340: 6e 67 20 30 0a 20 20 75 6e 73 65 74 20 3a 3a 69  ng 0.  unset ::i
3350: 6f 65 72 72 6f 70 74 73 0a 7d 0a 0a 23 20 52 65  oerropts.}..# Re
3360: 74 75 72 6e 20 61 20 63 68 65 63 6b 73 75 6d 20  turn a checksum 
3370: 62 61 73 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e  based on the con
3380: 74 65 6e 74 73 20 6f 66 20 64 61 74 61 62 61 73  tents of databas
3390: 65 20 27 64 62 27 2e 0a 23 0a 70 72 6f 63 20 63  e 'db'..#.proc c
33a0: 6b 73 75 6d 20 7b 7b 64 62 20 64 62 7d 7d 20 7b  ksum {{db db}} {
33b0: 0a 20 20 73 65 74 20 74 78 74 20 5b 24 64 62 20  .  set txt [$db 
33c0: 65 76 61 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c  eval {.      SEL
33d0: 45 43 54 20 6e 61 6d 65 2c 20 74 79 70 65 2c 20  ECT name, type, 
33e0: 73 71 6c 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f  sql FROM sqlite_
33f0: 6d 61 73 74 65 72 20 6f 72 64 65 72 20 62 79 20  master order by 
3400: 6e 61 6d 65 0a 20 20 7d 5d 5c 6e 0a 20 20 66 6f  name.  }]\n.  fo
3410: 72 65 61 63 68 20 74 62 6c 20 5b 24 64 62 20 65  reach tbl [$db e
3420: 76 61 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c 45  val {.      SELE
3430: 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c  CT name FROM sql
3440: 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45  ite_master WHERE
3450: 20 74 79 70 65 3d 27 74 61 62 6c 65 27 20 6f 72   type='table' or
3460: 64 65 72 20 62 79 20 6e 61 6d 65 0a 20 20 7d 5d  der by name.  }]
3470: 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78   {.    append tx
3480: 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45 4c  t [$db eval "SEL
3490: 45 43 54 20 2a 20 46 52 4f 4d 20 24 74 62 6c 22  ECT * FROM $tbl"
34a0: 5d 5c 6e 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63  ]\n.  }.  foreac
34b0: 68 20 70 72 61 67 20 7b 64 65 66 61 75 6c 74 5f  h prag {default_
34c0: 73 79 6e 63 68 72 6f 6e 6f 75 73 20 64 65 66 61  synchronous defa
34d0: 75 6c 74 5f 63 61 63 68 65 5f 73 69 7a 65 7d 20  ult_cache_size} 
34e0: 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78 74  {.    append txt
34f0: 20 24 70 72 61 67 2d 5b 24 64 62 20 65 76 61 6c   $prag-[$db eval
3500: 20 22 50 52 41 47 4d 41 20 24 70 72 61 67 22 5d   "PRAGMA $prag"]
3510: 5c 6e 0a 20 20 7d 0a 20 20 73 65 74 20 63 6b 73  \n.  }.  set cks
3520: 75 6d 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74  um [string lengt
3530: 68 20 24 74 78 74 5d 2d 5b 6d 64 35 20 24 74 78  h $txt]-[md5 $tx
3540: 74 5d 0a 20 20 23 20 70 75 74 73 20 24 63 6b 73  t].  # puts $cks
3550: 75 6d 2d 5b 66 69 6c 65 20 73 69 7a 65 20 74 65  um-[file size te
3560: 73 74 2e 64 62 5d 0a 20 20 72 65 74 75 72 6e 20  st.db].  return 
3570: 24 63 6b 73 75 6d 0a 7d 0a 0a 23 20 43 6f 70 79  $cksum.}..# Copy
3580: 20 66 69 6c 65 20 24 66 72 6f 6d 20 69 6e 74 6f   file $from into
3590: 20 24 74 6f 2e 20 54 68 69 73 20 69 73 20 75 73   $to. This is us
35a0: 65 64 20 62 65 63 61 75 73 65 20 73 6f 6d 65 20  ed because some 
35b0: 76 65 72 73 69 6f 6e 73 20 6f 66 0a 23 20 54 43  versions of.# TC
35c0: 4c 20 66 6f 72 20 77 69 6e 64 6f 77 73 20 28 6e  L for windows (n
35d0: 6f 74 61 62 6c 79 20 74 68 65 20 38 2e 34 2e 31  otably the 8.4.1
35e0: 20 62 69 6e 61 72 79 20 70 61 63 6b 61 67 65 20   binary package 
35f0: 73 68 69 70 70 65 64 20 77 69 74 68 20 74 68 65  shipped with the
3600: 0a 23 20 63 75 72 72 65 6e 74 20 6d 69 6e 67 77  .# current mingw
3610: 20 72 65 6c 65 61 73 65 29 20 68 61 76 65 20 61   release) have a
3620: 20 62 72 6f 6b 65 6e 20 22 66 69 6c 65 20 63 6f   broken "file co
3630: 70 79 22 20 63 6f 6d 6d 61 6e 64 2e 0a 23 0a 70  py" command..#.p
3640: 72 6f 63 20 63 6f 70 79 5f 66 69 6c 65 20 7b 66  roc copy_file {f
3650: 72 6f 6d 20 74 6f 7d 20 7b 0a 20 20 69 66 20 7b  rom to} {.  if {
3660: 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28  $::tcl_platform(
3670: 70 6c 61 74 66 6f 72 6d 29 3d 3d 22 75 6e 69 78  platform)=="unix
3680: 22 7d 20 7b 0a 20 20 20 20 66 69 6c 65 20 63 6f  "} {.    file co
3690: 70 79 20 2d 66 6f 72 63 65 20 24 66 72 6f 6d 20  py -force $from 
36a0: 24 74 6f 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20  $to.  } else {. 
36b0: 20 20 20 73 65 74 20 66 20 5b 6f 70 65 6e 20 24     set f [open $
36c0: 66 72 6f 6d 5d 0a 20 20 20 20 66 63 6f 6e 66 69  from].    fconfi
36d0: 67 75 72 65 20 24 66 20 2d 74 72 61 6e 73 6c 61  gure $f -transla
36e0: 74 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20 20 20  tion binary.    
36f0: 73 65 74 20 74 20 5b 6f 70 65 6e 20 24 74 6f 20  set t [open $to 
3700: 77 5d 0a 20 20 20 20 66 63 6f 6e 66 69 67 75 72  w].    fconfigur
3710: 65 20 24 74 20 2d 74 72 61 6e 73 6c 61 74 69 6f  e $t -translatio
3720: 6e 20 62 69 6e 61 72 79 0a 20 20 20 20 70 75 74  n binary.    put
3730: 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24 74 20  s -nonewline $t 
3740: 5b 72 65 61 64 20 24 66 20 5b 66 69 6c 65 20 73  [read $f [file s
3750: 69 7a 65 20 24 66 72 6f 6d 5d 5d 0a 20 20 20 20  ize $from]].    
3760: 63 6c 6f 73 65 20 24 74 0a 20 20 20 20 63 6c 6f  close $t.    clo
3770: 73 65 20 24 66 0a 20 20 7d 0a 7d 0a 0a 23 20 54  se $f.  }.}..# T
3780: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 63 68 65 63  his command chec
3790: 6b 73 20 66 6f 72 20 6f 75 74 73 74 61 6e 64 69  ks for outstandi
37a0: 6e 67 20 63 61 6c 6c 73 20 74 6f 20 73 71 6c 69  ng calls to sqli
37b0: 74 65 4d 61 6c 6c 6f 63 28 29 20 66 72 6f 6d 20  teMalloc() from 
37c0: 77 69 74 68 69 6e 0a 23 20 74 68 65 20 63 75 72  within.# the cur
37d0: 72 65 6e 74 20 74 68 72 65 61 64 2e 20 41 20 6c  rent thread. A l
37e0: 69 73 74 20 69 73 20 72 65 74 75 72 6e 65 64 20  ist is returned 
37f0: 77 69 74 68 20 6f 6e 65 20 65 6e 74 72 79 20 66  with one entry f
3800: 6f 72 20 65 61 63 68 20 6f 75 74 73 74 61 6e 64  or each outstand
3810: 69 6e 67 0a 23 20 6d 61 6c 6c 6f 63 2e 20 45 61  ing.# malloc. Ea
3820: 63 68 20 6c 69 73 74 20 65 6e 74 72 79 20 69 73  ch list entry is
3830: 20 69 74 73 65 6c 66 20 61 20 6c 69 73 74 20 6f   itself a list o
3840: 66 20 35 20 69 74 65 6d 73 2c 20 61 73 20 66 6f  f 5 items, as fo
3850: 6c 6c 6f 77 73 3a 0a 23 0a 23 20 20 20 20 20 7b  llows:.#.#     {
3860: 20 3c 6e 75 6d 62 65 72 2d 62 79 74 65 73 3e 20   <number-bytes> 
3870: 3c 66 69 6c 65 2d 6e 61 6d 65 3e 20 3c 6c 69 6e  <file-name> <lin
3880: 65 2d 6e 75 6d 62 65 72 3e 20 3c 74 65 73 74 2d  e-number> <test-
3890: 63 61 73 65 3e 20 3c 73 74 61 63 6b 2d 64 75 6d  case> <stack-dum
38a0: 70 3e 20 7d 0a 23 0a 70 72 6f 63 20 63 68 65 63  p> }.#.proc chec
38b0: 6b 5f 66 6f 72 5f 6c 65 61 6b 73 20 7b 7d 20 7b  k_for_leaks {} {
38c0: 0a 20 20 73 65 74 20 72 65 74 20 5b 6c 69 73 74  .  set ret [list
38d0: 5d 0a 20 20 73 65 74 20 63 6e 74 20 30 0a 20 20  ].  set cnt 0.  
38e0: 66 6f 72 65 61 63 68 20 61 6c 6c 6f 63 20 5b 73  foreach alloc [s
38f0: 71 6c 69 74 65 5f 6d 61 6c 6c 6f 63 5f 6f 75 74  qlite_malloc_out
3900: 73 74 61 6e 64 69 6e 67 5d 20 7b 0a 20 20 20 20  standing] {.    
3910: 66 6f 72 65 61 63 68 20 7b 6e 42 79 74 65 73 20  foreach {nBytes 
3920: 66 69 6c 65 20 69 4c 69 6e 65 20 75 73 65 72 73  file iLine users
3930: 74 72 69 6e 67 20 62 61 63 6b 74 72 61 63 65 7d  tring backtrace}
3940: 20 24 61 6c 6c 6f 63 20 7b 7d 0a 20 20 20 20 73   $alloc {}.    s
3950: 65 74 20 73 74 61 63 6b 20 5b 6c 69 73 74 5d 0a  et stack [list].
3960: 20 20 20 20 73 65 74 20 73 6b 69 70 20 30 0a 0a      set skip 0..
3970: 20 20 20 20 23 20 54 68 65 20 66 69 72 73 74 20      # The first 
3980: 63 6f 6d 6d 61 6e 64 20 69 6e 20 74 68 69 73 20  command in this 
3990: 62 6c 6f 63 6b 20 77 69 6c 6c 20 70 72 6f 62 61  block will proba
39a0: 62 6c 79 20 66 61 69 6c 20 6f 6e 20 77 69 6e 64  bly fail on wind
39b0: 6f 77 73 2e 20 54 68 69 73 0a 20 20 20 20 23 20  ows. This.    # 
39c0: 6d 65 61 6e 73 20 74 68 65 72 65 20 77 69 6c 6c  means there will
39d0: 20 62 65 20 6e 6f 20 73 74 61 63 6b 20 64 75 6d   be no stack dum
39e0: 70 20 61 76 61 69 6c 61 62 6c 65 2e 0a 20 20 20  p available..   
39f0: 20 69 66 20 7b 24 63 6e 74 20 3c 20 32 35 20 26   if {$cnt < 25 &
3a00: 26 20 24 62 61 63 6b 74 72 61 63 65 21 3d 22 22  & $backtrace!=""
3a10: 7d 20 7b 0a 20 20 20 20 20 20 63 61 74 63 68 20  } {.      catch 
3a20: 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 73 74  {.        set st
3a30: 75 66 66 20 5b 65 76 61 6c 20 22 65 78 65 63 20  uff [eval "exec 
3a40: 61 64 64 72 32 6c 69 6e 65 20 2d 65 20 2e 2f 74  addr2line -e ./t
3a50: 65 73 74 66 69 78 74 75 72 65 20 2d 66 20 24 62  estfixture -f $b
3a60: 61 63 6b 74 72 61 63 65 22 5d 0a 20 20 20 20 20  acktrace"].     
3a70: 20 20 20 66 6f 72 65 61 63 68 20 7b 66 75 6e 63     foreach {func
3a80: 20 6c 69 6e 65 7d 20 24 73 74 75 66 66 20 7b 0a   line} $stuff {.
3a90: 20 20 20 20 20 20 20 20 20 20 69 66 20 7b 24 66            if {$f
3aa0: 75 6e 63 20 21 3d 20 22 3f 3f 22 20 7c 7c 20 24  unc != "??" || $
3ab0: 6c 69 6e 65 20 21 3d 20 22 3f 3f 3a 30 22 7d 20  line != "??:0"} 
3ac0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65  {.            re
3ad0: 67 65 78 70 20 7b 2e 2a 2f 28 2e 2a 29 7d 20 24  gexp {.*/(.*)} $
3ae0: 6c 69 6e 65 20 64 75 6d 6d 79 20 6c 69 6e 65 0a  line dummy line.
3af0: 20 20 20 20 20 20 20 20 20 20 20 20 6c 61 70 70              lapp
3b00: 65 6e 64 20 73 74 61 63 6b 20 22 24 7b 66 75 6e  end stack "${fun
3b10: 63 7d 28 29 20 24 6c 69 6e 65 22 0a 20 20 20 20  c}() $line".    
3b20: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20        } else {. 
3b30: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 7b 5b             if {[
3b40: 6c 69 6e 64 65 78 20 24 73 74 61 63 6b 20 65 6e  lindex $stack en
3b50: 64 5d 20 21 3d 20 22 2e 2e 2e 22 7d 20 7b 0a 20  d] != "..."} {. 
3b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 61 70               lap
3b70: 70 65 6e 64 20 73 74 61 63 6b 20 22 2e 2e 2e 22  pend stack "..."
3b80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20  .            }. 
3b90: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
3ba0: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
3bb0: 20 20 20 69 6e 63 72 20 63 6e 74 0a 20 20 20 20     incr cnt.    
3bc0: 7d 0a 0a 20 20 20 20 69 66 20 7b 21 24 73 6b 69  }..    if {!$ski
3bd0: 70 7d 20 7b 0a 20 20 20 20 20 20 6c 61 70 70 65  p} {.      lappe
3be0: 6e 64 20 72 65 74 20 5b 6c 69 73 74 20 24 6e 42  nd ret [list $nB
3bf0: 79 74 65 73 20 24 66 69 6c 65 20 24 69 4c 69 6e  ytes $file $iLin
3c00: 65 20 24 75 73 65 72 73 74 72 69 6e 67 20 24 73  e $userstring $s
3c10: 74 61 63 6b 5d 0a 20 20 20 20 7d 0a 20 20 7d 0a  tack].    }.  }.
3c20: 20 20 72 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a    return $ret.}.
3c30: 0a 23 20 50 72 65 74 74 79 20 70 72 69 6e 74 20  .# Pretty print 
3c40: 61 20 72 65 70 6f 72 74 20 62 61 73 65 64 20 6f  a report based o
3c50: 6e 20 74 68 65 20 72 65 74 75 72 6e 20 76 61 6c  n the return val
3c60: 75 65 20 6f 66 20 5b 63 68 65 63 6b 5f 66 6f 72  ue of [check_for
3c70: 5f 6c 65 61 6b 73 5d 20 74 6f 0a 23 20 73 74 64  _leaks] to.# std
3c80: 6f 75 74 2e 0a 70 72 6f 63 20 70 70 5f 63 68 65  out..proc pp_che
3c90: 63 6b 5f 66 6f 72 5f 6c 65 61 6b 73 20 7b 7d 20  ck_for_leaks {} 
3ca0: 7b 0a 20 20 73 65 74 20 6c 20 5b 63 68 65 63 6b  {.  set l [check
3cb0: 5f 66 6f 72 5f 6c 65 61 6b 73 5d 0a 20 20 73 65  _for_leaks].  se
3cc0: 74 20 6e 20 30 0a 20 20 66 6f 72 65 61 63 68 20  t n 0.  foreach 
3cd0: 6c 65 61 6b 20 24 6c 20 7b 0a 20 20 20 20 66 6f  leak $l {.    fo
3ce0: 72 65 61 63 68 20 7b 6e 42 79 74 65 73 20 66 69  reach {nBytes fi
3cf0: 6c 65 20 69 4c 69 6e 65 20 75 73 65 72 73 74 72  le iLine userstr
3d00: 69 6e 67 20 73 74 61 63 6b 7d 20 24 6c 65 61 6b  ing stack} $leak
3d10: 20 7b 7d 0a 20 20 20 20 70 75 74 73 20 22 24 6e   {}.    puts "$n
3d20: 42 79 74 65 73 20 62 79 74 65 73 20 6c 65 61 6b  Bytes bytes leak
3d30: 65 64 20 61 74 20 24 66 69 6c 65 3a 24 69 4c 69  ed at $file:$iLi
3d40: 6e 65 20 28 24 75 73 65 72 73 74 72 69 6e 67 29  ne ($userstring)
3d50: 22 0a 20 20 20 20 66 6f 72 65 61 63 68 20 66 72  ".    foreach fr
3d60: 61 6d 65 20 24 73 74 61 63 6b 20 7b 0a 20 20 20  ame $stack {.   
3d70: 20 20 20 70 75 74 73 20 22 20 20 20 20 20 20 20     puts "       
3d80: 20 24 66 72 61 6d 65 22 0a 20 20 20 20 7d 0a 20   $frame".    }. 
3d90: 20 20 20 69 6e 63 72 20 6e 20 24 6e 42 79 74 65     incr n $nByte
3da0: 73 0a 20 20 7d 0a 20 20 70 75 74 73 20 22 4d 65  s.  }.  puts "Me
3db0: 6d 6f 72 79 20 6c 65 61 6b 65 64 3a 20 24 6e 20  mory leaked: $n 
3dc0: 62 79 74 65 73 20 69 6e 20 5b 6c 6c 65 6e 67 74  bytes in [llengt
3dd0: 68 20 24 6c 5d 20 61 6c 6c 6f 63 61 74 69 6f 6e  h $l] allocation
3de0: 73 22 0a 20 20 70 75 74 73 20 22 22 0a 7d 0a 0a  s".  puts "".}..
3df0: 23 20 49 66 20 74 68 65 20 6c 69 62 72 61 72 79  # If the library
3e00: 20 69 73 20 63 6f 6d 70 69 6c 65 64 20 77 69 74   is compiled wit
3e10: 68 20 74 68 65 20 53 51 4c 49 54 45 5f 44 45 46  h the SQLITE_DEF
3e20: 41 55 4c 54 5f 41 55 54 4f 56 41 43 55 55 4d 20  AULT_AUTOVACUUM 
3e30: 6d 61 63 72 6f 20 73 65 74 0a 23 20 74 6f 20 6e  macro set.# to n
3e40: 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 73 65  on-zero, then se
3e50: 74 20 74 68 65 20 67 6c 6f 62 61 6c 20 76 61 72  t the global var
3e60: 69 61 62 6c 65 20 24 41 55 54 4f 56 41 43 55 55  iable $AUTOVACUU
3e70: 4d 20 74 6f 20 31 2e 0a 73 65 74 20 41 55 54 4f  M to 1..set AUTO
3e80: 56 41 43 55 55 4d 20 24 73 71 6c 69 74 65 5f 6f  VACUUM $sqlite_o
3e90: 70 74 69 6f 6e 73 28 64 65 66 61 75 6c 74 5f 61  ptions(default_a
3ea0: 75 74 6f 76 61 63 75 75 6d 29 0a                 utovacuum).