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

Artifact effe3dae968afd8bb27c8792883788eeba821942:


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 39 20 32 30 30 37 2f 30 34 2f 31 39   1.79 2007/04/19
01f0: 20 31 32 3a 33 30 3a 35 34 20 64 72 68 20 45 78   12:30:54 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 20 20 66 6c 75 73 68 20  Ok".  }.  flush 
0d50: 73 74 64 6f 75 74 0a 7d 0a 0a 23 20 52 75 6e 20  stdout.}..# Run 
0d60: 61 6e 20 53 51 4c 20 73 63 72 69 70 74 2e 20 20  an SQL script.  
0d70: 0a 23 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75  .# Return the nu
0d80: 6d 62 65 72 20 6f 66 20 6d 69 63 72 6f 73 65 63  mber of microsec
0d90: 6f 6e 64 73 20 70 65 72 20 73 74 61 74 65 6d 65  onds per stateme
0da0: 6e 74 2e 0a 23 0a 70 72 6f 63 20 73 70 65 65 64  nt..#.proc speed
0db0: 5f 74 72 69 61 6c 20 7b 6e 61 6d 65 20 6e 75 6d  _trial {name num
0dc0: 73 74 6d 74 20 75 6e 69 74 73 20 73 71 6c 7d 20  stmt units sql} 
0dd0: 7b 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c  {.  puts -nonewl
0de0: 69 6e 65 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32  ine [format {%-2
0df0: 31 2e 32 31 73 20 7d 20 24 6e 61 6d 65 2e 2e 2e  1.21s } $name...
0e00: 5d 0a 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74  ].  flush stdout
0e10: 0a 20 20 73 65 74 20 73 70 65 65 64 20 5b 74 69  .  set speed [ti
0e20: 6d 65 20 7b 73 71 6c 69 74 65 33 5f 65 78 65 63  me {sqlite3_exec
0e30: 5f 6e 72 20 64 62 20 24 73 71 6c 7d 5d 0a 20 20  _nr db $sql}].  
0e40: 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78 20 24  set tm [lindex $
0e50: 73 70 65 65 64 20 30 5d 0a 20 20 73 65 74 20 72  speed 0].  set r
0e60: 61 74 65 20 5b 65 78 70 72 20 7b 31 30 30 30 30  ate [expr {10000
0e70: 30 30 2e 30 2a 24 6e 75 6d 73 74 6d 74 2f 24 74  00.0*$numstmt/$t
0e80: 6d 7d 5d 0a 20 20 73 65 74 20 75 32 20 24 75 6e  m}].  set u2 $un
0e90: 69 74 73 2f 73 0a 20 20 70 75 74 73 20 5b 66 6f  its/s.  puts [fo
0ea0: 72 6d 61 74 20 7b 25 31 32 64 20 75 53 20 25 32  rmat {%12d uS %2
0eb0: 30 2e 35 66 20 25 73 7d 20 24 74 6d 20 24 72 61  0.5f %s} $tm $ra
0ec0: 74 65 20 24 75 32 5d 0a 20 20 67 6c 6f 62 61 6c  te $u2].  global
0ed0: 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 73 65   total_time.  se
0ee0: 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20 5b 65 78  t total_time [ex
0ef0: 70 72 20 7b 24 74 6f 74 61 6c 5f 74 69 6d 65 2b  pr {$total_time+
0f00: 24 74 6d 7d 5d 0a 7d 0a 70 72 6f 63 20 73 70 65  $tm}].}.proc spe
0f10: 65 64 5f 74 72 69 61 6c 5f 69 6e 69 74 20 7b 6e  ed_trial_init {n
0f20: 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20  ame} {.  global 
0f30: 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 73 65 74  total_time.  set
0f40: 20 74 6f 74 61 6c 5f 74 69 6d 65 20 30 0a 7d 0a   total_time 0.}.
0f50: 70 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c  proc speed_trial
0f60: 5f 73 75 6d 6d 61 72 79 20 7b 6e 61 6d 65 7d 20  _summary {name} 
0f70: 7b 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c  {.  global total
0f80: 5f 74 69 6d 65 0a 20 20 70 75 74 73 20 5b 66 6f  _time.  puts [fo
0f90: 72 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73 20 25  rmat {%-21.21s %
0fa0: 31 32 64 20 75 53 20 54 4f 54 41 4c 7d 20 24 6e  12d uS TOTAL} $n
0fb0: 61 6d 65 20 24 74 6f 74 61 6c 5f 74 69 6d 65 5d  ame $total_time]
0fc0: 0a 7d 0a 0a 23 20 54 68 65 20 70 72 6f 63 65 64  .}..# The proced
0fd0: 75 72 65 20 75 73 65 73 20 74 68 65 20 73 70 65  ure uses the spe
0fe0: 63 69 61 6c 20 22 73 71 6c 69 74 65 5f 6d 61 6c  cial "sqlite_mal
0ff0: 6c 6f 63 5f 73 74 61 74 22 20 63 6f 6d 6d 61 6e  loc_stat" comman
1000: 64 0a 23 20 28 77 68 69 63 68 20 69 73 20 6f 6e  d.# (which is on
1010: 6c 79 20 61 76 61 69 6c 61 62 6c 65 20 69 66 20  ly available if 
1020: 53 51 4c 69 74 65 20 69 73 20 63 6f 6d 70 69 6c  SQLite is compil
1030: 65 64 20 77 69 74 68 20 2d 44 53 51 4c 49 54 45  ed with -DSQLITE
1040: 5f 44 45 42 55 47 3d 31 29 0a 23 20 74 6f 20 73  _DEBUG=1).# to s
1050: 65 65 20 68 6f 77 20 6d 61 6e 79 20 6d 61 6c 6c  ee how many mall
1060: 6f 63 28 29 73 20 68 61 76 65 20 6e 6f 74 20 62  oc()s have not b
1070: 65 65 6e 20 66 72 65 65 28 29 65 64 2e 20 20 54  een free()ed.  T
1080: 68 65 20 6e 75 6d 62 65 72 0a 23 20 6f 66 20 73  he number.# of s
1090: 75 72 70 6c 75 73 20 6d 61 6c 6c 6f 63 28 29 73  urplus malloc()s
10a0: 20 69 73 20 73 74 6f 72 65 64 20 69 6e 20 74 68   is stored in th
10b0: 65 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  e global variabl
10c0: 65 20 24 3a 3a 4c 65 61 6b 2e 0a 23 20 49 66 20  e $::Leak..# If 
10d0: 74 68 65 20 76 61 6c 75 65 20 69 6e 20 24 3a 3a  the value in $::
10e0: 4c 65 61 6b 20 67 72 6f 77 73 2c 20 69 74 20 6d  Leak grows, it m
10f0: 61 79 20 6d 65 61 6e 20 74 68 65 72 65 20 69 73  ay mean there is
1100: 20 61 20 6d 65 6d 6f 72 79 20 6c 65 61 6b 0a 23   a memory leak.#
1110: 20 69 6e 20 74 68 65 20 6c 69 62 72 61 72 79 2e   in the library.
1120: 0a 23 0a 70 72 6f 63 20 6d 65 6d 6c 65 61 6b 5f  .#.proc memleak_
1130: 63 68 65 63 6b 20 7b 7d 20 7b 0a 20 20 69 66 20  check {} {.  if 
1140: 7b 5b 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64 20 73  {[info command s
1150: 71 6c 69 74 65 5f 6d 61 6c 6c 6f 63 5f 73 74 61  qlite_malloc_sta
1160: 74 5d 21 3d 22 22 7d 20 7b 0a 20 20 20 20 73 65  t]!=""} {.    se
1170: 74 20 72 20 5b 73 71 6c 69 74 65 5f 6d 61 6c 6c  t r [sqlite_mall
1180: 6f 63 5f 73 74 61 74 5d 0a 20 20 20 20 73 65 74  oc_stat].    set
1190: 20 3a 3a 4c 65 61 6b 20 5b 65 78 70 72 20 7b 5b   ::Leak [expr {[
11a0: 6c 69 6e 64 65 78 20 24 72 20 30 5d 2d 5b 6c 69  lindex $r 0]-[li
11b0: 6e 64 65 78 20 24 72 20 31 5d 7d 5d 0a 20 20 7d  ndex $r 1]}].  }
11c0: 0a 7d 0a 0a 23 20 52 75 6e 20 74 68 69 73 20 72  .}..# Run this r
11d0: 6f 75 74 69 6e 65 20 6c 61 73 74 0a 23 0a 70 72  outine last.#.pr
11e0: 6f 63 20 66 69 6e 69 73 68 5f 74 65 73 74 20 7b  oc finish_test {
11f0: 7d 20 7b 0a 20 20 66 69 6e 61 6c 69 7a 65 5f 74  } {.  finalize_t
1200: 65 73 74 69 6e 67 0a 7d 0a 70 72 6f 63 20 66 69  esting.}.proc fi
1210: 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67 20 7b  nalize_testing {
1220: 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 6e 54 65  } {.  global nTe
1230: 73 74 20 6e 45 72 72 20 73 71 6c 69 74 65 5f 6f  st nErr sqlite_o
1240: 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 0a 20  pen_file_count. 
1250: 20 69 66 20 7b 24 6e 45 72 72 3d 3d 30 7d 20 6d   if {$nErr==0} m
1260: 65 6d 6c 65 61 6b 5f 63 68 65 63 6b 0a 0a 20 20  emleak_check..  
1270: 63 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d  catch {db close}
1280: 0a 20 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c  .  catch {db2 cl
1290: 6f 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62  ose}.  catch {db
12a0: 33 20 63 6c 6f 73 65 7d 0a 0a 20 20 63 61 74 63  3 close}..  catc
12b0: 68 20 7b 0a 20 20 20 20 70 70 5f 63 68 65 63 6b  h {.    pp_check
12c0: 5f 66 6f 72 5f 6c 65 61 6b 73 0a 20 20 7d 0a 20  _for_leaks.  }. 
12d0: 20 73 71 6c 69 74 65 33 20 64 62 20 7b 7d 0a 20   sqlite3 db {}. 
12e0: 20 23 20 73 71 6c 69 74 65 33 5f 63 6c 65 61 72   # sqlite3_clear
12f0: 5f 74 73 64 5f 6d 65 6d 64 65 62 75 67 0a 20 20  _tsd_memdebug.  
1300: 64 62 20 63 6c 6f 73 65 0a 20 20 69 66 20 7b 24  db close.  if {$
1310: 3a 3a 73 71 6c 69 74 65 33 5f 74 73 64 5f 63 6f  ::sqlite3_tsd_co
1320: 75 6e 74 7d 20 7b 0a 20 20 20 20 20 70 75 74 73  unt} {.     puts
1330: 20 22 54 68 72 65 61 64 2d 73 70 65 63 69 66 69   "Thread-specifi
1340: 63 20 64 61 74 61 20 6c 65 61 6b 3a 20 24 3a 3a  c data leak: $::
1350: 73 71 6c 69 74 65 33 5f 74 73 64 5f 63 6f 75 6e  sqlite3_tsd_coun
1360: 74 20 69 6e 73 74 61 6e 63 65 73 22 0a 20 20 20  t instances".   
1370: 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20 7d 20    incr nErr.  } 
1380: 65 6c 73 65 20 7b 0a 20 20 20 20 20 70 75 74 73  else {.     puts
1390: 20 22 54 68 72 65 61 64 2d 73 70 65 63 69 66 69   "Thread-specifi
13a0: 63 20 64 61 74 61 20 64 65 61 6c 6c 6f 63 61 74  c data deallocat
13b0: 65 64 20 70 72 6f 70 65 72 6c 79 22 0a 20 20 7d  ed properly".  }
13c0: 0a 20 20 69 6e 63 72 20 6e 54 65 73 74 0a 20 20  .  incr nTest.  
13d0: 70 75 74 73 20 22 24 6e 45 72 72 20 65 72 72 6f  puts "$nErr erro
13e0: 72 73 20 6f 75 74 20 6f 66 20 24 6e 54 65 73 74  rs out of $nTest
13f0: 20 74 65 73 74 73 22 0a 20 20 70 75 74 73 20 22   tests".  puts "
1400: 46 61 69 6c 75 72 65 73 20 6f 6e 20 74 68 65 73  Failures on thes
1410: 65 20 74 65 73 74 73 3a 20 24 3a 3a 66 61 69 6c  e tests: $::fail
1420: 4c 69 73 74 22 0a 20 20 69 66 20 7b 24 6e 45 72  List".  if {$nEr
1430: 72 3e 30 20 26 26 20 21 5b 77 6f 72 6b 69 6e 67  r>0 && ![working
1440: 5f 36 34 62 69 74 5f 69 6e 74 5d 7d 20 7b 0a 20  _64bit_int]} {. 
1450: 20 20 20 70 75 74 73 20 22 2a 2a 2a 2a 2a 2a 2a     puts "*******
1460: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1480: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1490: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 20  ***********".   
14a0: 20 70 75 74 73 20 22 4e 2e 42 2e 3a 20 20 54 68   puts "N.B.:  Th
14b0: 65 20 76 65 72 73 69 6f 6e 20 6f 66 20 54 43 4c  e version of TCL
14c0: 20 74 68 61 74 20 79 6f 75 20 75 73 65 64 20 74   that you used t
14d0: 6f 20 62 75 69 6c 64 20 74 68 69 73 20 74 65 73  o build this tes
14e0: 74 20 68 61 72 6e 65 73 73 22 0a 20 20 20 20 70  t harness".    p
14f0: 75 74 73 20 22 69 73 20 64 65 66 65 63 74 69 76  uts "is defectiv
1500: 65 20 69 6e 20 74 68 61 74 20 69 74 20 64 6f 65  e in that it doe
1510: 73 20 6e 6f 74 20 73 75 70 70 6f 72 74 20 36 34  s not support 64
1520: 2d 62 69 74 20 69 6e 74 65 67 65 72 73 2e 20 20  -bit integers.  
1530: 53 6f 6d 65 20 6f 72 22 0a 20 20 20 20 70 75 74  Some or".    put
1540: 73 20 22 61 6c 6c 20 6f 66 20 74 68 65 20 74 65  s "all of the te
1550: 73 74 20 66 61 69 6c 75 72 65 73 20 61 62 6f 76  st failures abov
1560: 65 20 6d 69 67 68 74 20 62 65 20 61 20 72 65 73  e might be a res
1570: 75 6c 74 20 66 72 6f 6d 20 74 68 69 73 20 64 65  ult from this de
1580: 66 65 63 74 22 0a 20 20 20 20 70 75 74 73 20 22  fect".    puts "
1590: 69 6e 20 79 6f 75 72 20 54 43 4c 20 62 75 69 6c  in your TCL buil
15a0: 64 2e 22 0a 20 20 20 20 70 75 74 73 20 22 2a 2a  d.".    puts "**
15b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
15c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
15d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
15e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
15f0: 22 0a 20 20 7d 0a 20 20 69 66 20 7b 24 73 71 6c  ".  }.  if {$sql
1600: 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f  ite_open_file_co
1610: 75 6e 74 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  unt} {.    puts 
1620: 22 24 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69  "$sqlite_open_fi
1630: 6c 65 5f 63 6f 75 6e 74 20 66 69 6c 65 73 20 77  le_count files w
1640: 65 72 65 20 6c 65 66 74 20 6f 70 65 6e 22 0a 20  ere left open". 
1650: 20 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20 7d     incr nErr.  }
1660: 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c  .  foreach f [gl
1670: 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74  ob -nocomplain t
1680: 65 73 74 2e 64 62 2d 2a 2d 6a 6f 75 72 6e 61 6c  est.db-*-journal
1690: 5d 20 7b 0a 20 20 20 20 66 69 6c 65 20 64 65 6c  ] {.    file del
16a0: 65 74 65 20 2d 66 6f 72 63 65 20 24 66 0a 20 20  ete -force $f.  
16b0: 7d 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67  }.  foreach f [g
16c0: 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  lob -nocomplain 
16d0: 74 65 73 74 2e 64 62 2d 6d 6a 2a 5d 20 7b 0a 20  test.db-mj*] {. 
16e0: 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d     file delete -
16f0: 66 6f 72 63 65 20 24 66 0a 20 20 7d 0a 20 20 65  force $f.  }.  e
1700: 78 69 74 20 5b 65 78 70 72 20 7b 24 6e 45 72 72  xit [expr {$nErr
1710: 3e 30 7d 5d 0a 7d 0a 0a 23 20 41 20 70 72 6f 63  >0}].}..# A proc
1720: 65 64 75 72 65 20 74 6f 20 65 78 65 63 75 74 65  edure to execute
1730: 20 53 51 4c 0a 23 0a 70 72 6f 63 20 65 78 65 63   SQL.#.proc exec
1740: 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d  sql {sql {db db}
1750: 7d 20 7b 0a 20 20 23 20 70 75 74 73 20 22 53 51  } {.  # puts "SQ
1760: 4c 20 3d 20 24 73 71 6c 22 0a 20 20 75 70 6c 65  L = $sql".  uple
1770: 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65 76  vel [list $db ev
1780: 61 6c 20 24 73 71 6c 5d 0a 7d 0a 0a 23 20 45 78  al $sql].}..# Ex
1790: 65 63 75 74 65 20 53 51 4c 20 61 6e 64 20 63 61  ecute SQL and ca
17a0: 74 63 68 20 65 78 63 65 70 74 69 6f 6e 73 2e 0a  tch exceptions..
17b0: 23 0a 70 72 6f 63 20 63 61 74 63 68 73 71 6c 20  #.proc catchsql 
17c0: 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b 0a  {sql {db db}} {.
17d0: 20 20 23 20 70 75 74 73 20 22 53 51 4c 20 3d 20    # puts "SQL = 
17e0: 24 73 71 6c 22 0a 20 20 73 65 74 20 72 20 5b 63  $sql".  set r [c
17f0: 61 74 63 68 20 7b 24 64 62 20 65 76 61 6c 20 24  atch {$db eval $
1800: 73 71 6c 7d 20 6d 73 67 5d 0a 20 20 6c 61 70 70  sql} msg].  lapp
1810: 65 6e 64 20 72 20 24 6d 73 67 0a 20 20 72 65 74  end r $msg.  ret
1820: 75 72 6e 20 24 72 0a 7d 0a 0a 23 20 44 6f 20 61  urn $r.}..# Do a
1830: 6e 20 56 44 42 45 20 63 6f 64 65 20 64 75 6d 70  n VDBE code dump
1840: 20 6f 6e 20 74 68 65 20 53 51 4c 20 67 69 76 65   on the SQL give
1850: 6e 0a 23 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e  n.#.proc explain
1860: 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b   {sql {db db}} {
1870: 0a 20 20 70 75 74 73 20 22 22 0a 20 20 70 75 74  .  puts "".  put
1880: 73 20 22 61 64 64 72 20 20 6f 70 63 6f 64 65 20  s "addr  opcode 
1890: 20 20 20 20 20 20 20 70 31 20 20 20 20 20 20 20         p1       
18a0: 70 32 20 20 20 20 20 70 33 20 20 20 20 20 20 20  p2     p3       
18b0: 20 20 20 20 20 20 22 0a 20 20 70 75 74 73 20 22        ".  puts "
18c0: 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----  ----------
18d0: 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d  --  ------  ----
18e0: 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  --  ------------
18f0: 2d 2d 2d 22 0a 20 20 24 64 62 20 65 76 61 6c 20  ---".  $db eval 
1900: 22 65 78 70 6c 61 69 6e 20 24 73 71 6c 22 20 7b  "explain $sql" {
1910: 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 5b 66 6f  } {.    puts [fo
1920: 72 6d 61 74 20 7b 25 2d 34 64 20 20 25 2d 31 32  rmat {%-4d  %-12
1930: 2e 31 32 73 20 20 25 2d 36 64 20 20 25 2d 36 64  .12s  %-6d  %-6d
1940: 20 20 25 73 7d 20 24 61 64 64 72 20 24 6f 70 63    %s} $addr $opc
1950: 6f 64 65 20 24 70 31 20 24 70 32 20 24 70 33 5d  ode $p1 $p2 $p3]
1960: 0a 20 20 7d 0a 7d 0a 0a 23 20 41 6e 6f 74 68 65  .  }.}..# Anothe
1970: 72 20 70 72 6f 63 65 64 75 72 65 20 74 6f 20 65  r procedure to e
1980: 78 65 63 75 74 65 20 53 51 4c 2e 20 20 54 68 69  xecute SQL.  Thi
1990: 73 20 6f 6e 65 20 69 6e 63 6c 75 64 65 73 20 74  s one includes t
19a0: 68 65 20 66 69 65 6c 64 0a 23 20 6e 61 6d 65 73  he field.# names
19b0: 20 69 6e 20 74 68 65 20 72 65 74 75 72 6e 65 64   in the returned
19c0: 20 6c 69 73 74 2e 0a 23 0a 70 72 6f 63 20 65 78   list..#.proc ex
19d0: 65 63 73 71 6c 32 20 7b 73 71 6c 7d 20 7b 0a 20  ecsql2 {sql} {. 
19e0: 20 73 65 74 20 72 65 73 75 6c 74 20 7b 7d 0a 20   set result {}. 
19f0: 20 64 62 20 65 76 61 6c 20 24 73 71 6c 20 64 61   db eval $sql da
1a00: 74 61 20 7b 0a 20 20 20 20 66 6f 72 65 61 63 68  ta {.    foreach
1a10: 20 66 20 24 64 61 74 61 28 2a 29 20 7b 0a 20 20   f $data(*) {.  
1a20: 20 20 20 20 6c 61 70 70 65 6e 64 20 72 65 73 75      lappend resu
1a30: 6c 74 20 24 66 20 24 64 61 74 61 28 24 66 29 0a  lt $f $data($f).
1a40: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
1a50: 72 6e 20 24 72 65 73 75 6c 74 0a 7d 0a 0a 23 20  rn $result.}..# 
1a60: 55 73 65 20 74 68 65 20 6e 6f 6e 2d 63 61 6c 6c  Use the non-call
1a70: 62 61 63 6b 20 41 50 49 20 74 6f 20 65 78 65 63  back API to exec
1a80: 75 74 65 20 6d 75 6c 74 69 70 6c 65 20 53 51 4c  ute multiple SQL
1a90: 20 73 74 61 74 65 6d 65 6e 74 73 0a 23 0a 70 72   statements.#.pr
1aa0: 6f 63 20 73 74 65 70 73 71 6c 20 7b 64 62 70 74  oc stepsql {dbpt
1ab0: 72 20 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 73  r sql} {.  set s
1ac0: 71 6c 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20  ql [string trim 
1ad0: 24 73 71 6c 5d 0a 20 20 73 65 74 20 72 20 30 0a  $sql].  set r 0.
1ae0: 20 20 77 68 69 6c 65 20 7b 5b 73 74 72 69 6e 67    while {[string
1af0: 20 6c 65 6e 67 74 68 20 24 73 71 6c 5d 3e 30 7d   length $sql]>0}
1b00: 20 7b 0a 20 20 20 20 69 66 20 7b 5b 63 61 74 63   {.    if {[catc
1b10: 68 20 7b 73 71 6c 69 74 65 33 5f 70 72 65 70 61  h {sqlite3_prepa
1b20: 72 65 20 24 64 62 70 74 72 20 24 73 71 6c 20 2d  re $dbptr $sql -
1b30: 31 20 73 71 6c 74 61 69 6c 7d 20 76 6d 5d 7d 20  1 sqltail} vm]} 
1b40: 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b  {.      return [
1b50: 6c 69 73 74 20 31 20 24 76 6d 5d 0a 20 20 20 20  list 1 $vm].    
1b60: 7d 0a 20 20 20 20 73 65 74 20 73 71 6c 20 5b 73  }.    set sql [s
1b70: 74 72 69 6e 67 20 74 72 69 6d 20 24 73 71 6c 74  tring trim $sqlt
1b80: 61 69 6c 5d 0a 23 20 20 20 20 77 68 69 6c 65 20  ail].#    while 
1b90: 7b 5b 73 71 6c 69 74 65 5f 73 74 65 70 20 24 76  {[sqlite_step $v
1ba0: 6d 20 4e 20 56 41 4c 20 43 4f 4c 5d 3d 3d 22 53  m N VAL COL]=="S
1bb0: 51 4c 49 54 45 5f 52 4f 57 22 7d 20 7b 0a 23 20  QLITE_ROW"} {.# 
1bc0: 20 20 20 20 20 66 6f 72 65 61 63 68 20 76 20 24       foreach v $
1bd0: 56 41 4c 20 7b 6c 61 70 70 65 6e 64 20 72 20 24  VAL {lappend r $
1be0: 76 7d 0a 23 20 20 20 20 7d 0a 20 20 20 20 77 68  v}.#    }.    wh
1bf0: 69 6c 65 20 7b 5b 73 71 6c 69 74 65 33 5f 73 74  ile {[sqlite3_st
1c00: 65 70 20 24 76 6d 5d 3d 3d 22 53 51 4c 49 54 45  ep $vm]=="SQLITE
1c10: 5f 52 4f 57 22 7d 20 7b 0a 20 20 20 20 20 20 66  _ROW"} {.      f
1c20: 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69  or {set i 0} {$i
1c30: 3c 5b 73 71 6c 69 74 65 33 5f 64 61 74 61 5f 63  <[sqlite3_data_c
1c40: 6f 75 6e 74 20 24 76 6d 5d 7d 20 7b 69 6e 63 72  ount $vm]} {incr
1c50: 20 69 7d 20 7b 0a 20 20 20 20 20 20 20 20 6c 61   i} {.        la
1c60: 70 70 65 6e 64 20 72 20 5b 73 71 6c 69 74 65 33  ppend r [sqlite3
1c70: 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 20 24 76 6d  _column_text $vm
1c80: 20 24 69 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20   $i].      }.   
1c90: 20 7d 0a 20 20 20 20 69 66 20 7b 5b 63 61 74 63   }.    if {[catc
1ca0: 68 20 7b 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  h {sqlite3_final
1cb0: 69 7a 65 20 24 76 6d 7d 20 65 72 72 6d 73 67 5d  ize $vm} errmsg]
1cc0: 7d 20 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e  } {.      return
1cd0: 20 5b 6c 69 73 74 20 31 20 24 65 72 72 6d 73 67   [list 1 $errmsg
1ce0: 5d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ].    }.  }.  re
1cf0: 74 75 72 6e 20 24 72 0a 7d 0a 0a 23 20 44 65 6c  turn $r.}..# Del
1d00: 65 74 65 20 61 20 66 69 6c 65 20 6f 72 20 64 69  ete a file or di
1d10: 72 65 63 74 6f 72 79 0a 23 0a 70 72 6f 63 20 66  rectory.#.proc f
1d20: 6f 72 63 65 64 65 6c 65 74 65 20 7b 66 69 6c 65  orcedelete {file
1d30: 6e 61 6d 65 7d 20 7b 0a 20 20 69 66 20 7b 5b 63  name} {.  if {[c
1d40: 61 74 63 68 20 7b 66 69 6c 65 20 64 65 6c 65 74  atch {file delet
1d50: 65 20 2d 66 6f 72 63 65 20 24 66 69 6c 65 6e 61  e -force $filena
1d60: 6d 65 7d 5d 7d 20 7b 0a 20 20 20 20 65 78 65 63  me}]} {.    exec
1d70: 20 72 6d 20 2d 72 66 20 24 66 69 6c 65 6e 61 6d   rm -rf $filenam
1d80: 65 0a 20 20 7d 0a 7d 0a 0a 23 20 44 6f 20 61 6e  e.  }.}..# Do an
1d90: 20 69 6e 74 65 67 72 69 74 79 20 63 68 65 63 6b   integrity check
1da0: 20 6f 66 20 74 68 65 20 65 6e 74 69 72 65 20 64   of the entire d
1db0: 61 74 61 62 61 73 65 0a 23 0a 70 72 6f 63 20 69  atabase.#.proc i
1dc0: 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b 20 7b  ntegrity_check {
1dd0: 6e 61 6d 65 7d 20 7b 0a 20 20 69 66 63 61 70 61  name} {.  ifcapa
1de0: 62 6c 65 20 69 6e 74 65 67 72 69 74 79 63 6b 20  ble integrityck 
1df0: 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 6e  {.    do_test $n
1e00: 61 6d 65 20 7b 0a 20 20 20 20 20 20 65 78 65 63  ame {.      exec
1e10: 73 71 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74 65  sql {PRAGMA inte
1e20: 67 72 69 74 79 5f 63 68 65 63 6b 7d 0a 20 20 20  grity_check}.   
1e30: 20 7d 20 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a 23   } {ok}.  }.}..#
1e40: 20 45 76 61 6c 75 61 74 65 20 61 20 62 6f 6f 6c   Evaluate a bool
1e50: 65 61 6e 20 65 78 70 72 65 73 73 69 6f 6e 20 6f  ean expression o
1e60: 66 20 63 61 70 61 62 69 6c 69 74 69 65 73 2e 20  f capabilities. 
1e70: 20 49 66 20 74 72 75 65 2c 20 65 78 65 63 75 74   If true, execut
1e80: 65 20 74 68 65 0a 23 20 63 6f 64 65 2e 20 20 4f  e the.# code.  O
1e90: 6d 69 74 20 74 68 65 20 63 6f 64 65 20 69 66 20  mit the code if 
1ea0: 66 61 6c 73 65 2e 0a 23 0a 70 72 6f 63 20 69 66  false..#.proc if
1eb0: 63 61 70 61 62 6c 65 20 7b 65 78 70 72 20 63 6f  capable {expr co
1ec0: 64 65 20 7b 65 6c 73 65 20 22 22 7d 20 7b 65 6c  de {else ""} {el
1ed0: 73 65 63 6f 64 65 20 22 22 7d 7d 20 7b 0a 20 20  secode ""}} {.  
1ee0: 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 5b 61 2d  regsub -all {[a-
1ef0: 7a 5f 30 2d 39 5d 2b 7d 20 24 65 78 70 72 20 7b  z_0-9]+} $expr {
1f00: 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e  $::sqlite_option
1f10: 73 28 26 29 7d 20 65 32 0a 20 20 69 66 20 28 24  s(&)} e2.  if ($
1f20: 65 32 29 20 7b 0a 20 20 20 20 73 65 74 20 63 20  e2) {.    set c 
1f30: 5b 63 61 74 63 68 20 7b 75 70 6c 65 76 65 6c 20  [catch {uplevel 
1f40: 31 20 24 63 6f 64 65 7d 20 72 5d 0a 20 20 7d 20  1 $code} r].  } 
1f50: 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 63  else {.    set c
1f60: 20 5b 63 61 74 63 68 20 7b 75 70 6c 65 76 65 6c   [catch {uplevel
1f70: 20 31 20 24 65 6c 73 65 63 6f 64 65 7d 20 72 5d   1 $elsecode} r]
1f80: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 2d 63  .  }.  return -c
1f90: 6f 64 65 20 24 63 20 24 72 0a 7d 0a 0a 23 20 54  ode $c $r.}..# T
1fa0: 68 69 73 20 70 72 6f 63 20 65 78 65 63 73 20 61  his proc execs a
1fb0: 20 73 65 70 65 72 61 74 65 20 70 72 6f 63 65 73   seperate proces
1fc0: 73 20 74 68 61 74 20 63 72 61 73 68 65 73 20 6d  s that crashes m
1fd0: 69 64 77 61 79 20 74 68 72 6f 75 67 68 20 65 78  idway through ex
1fe0: 65 63 75 74 69 6e 67 0a 23 20 74 68 65 20 53 51  ecuting.# the SQ
1ff0: 4c 20 73 63 72 69 70 74 20 24 73 71 6c 20 6f 6e  L script $sql on
2000: 20 64 61 74 61 62 61 73 65 20 74 65 73 74 2e 64   database test.d
2010: 62 2e 0a 23 0a 23 20 54 68 65 20 63 72 61 73 68  b..#.# The crash
2020: 20 6f 63 63 75 72 73 20 64 75 72 69 6e 67 20 61   occurs during a
2030: 20 73 79 6e 63 28 29 20 6f 66 20 66 69 6c 65 20   sync() of file 
2040: 24 63 72 61 73 68 66 69 6c 65 2e 20 57 68 65 6e  $crashfile. When
2050: 20 74 68 65 20 63 72 61 73 68 0a 23 20 6f 63 63   the crash.# occ
2060: 75 72 73 20 61 20 72 61 6e 64 6f 6d 20 73 75 62  urs a random sub
2070: 73 65 74 20 6f 66 20 61 6c 6c 20 75 6e 73 79 6e  set of all unsyn
2080: 63 65 64 20 77 72 69 74 65 73 20 6d 61 64 65 20  ced writes made 
2090: 62 79 20 74 68 65 20 70 72 6f 63 65 73 73 20 61  by the process a
20a0: 72 65 0a 23 20 77 72 69 74 74 65 6e 20 69 6e 74  re.# written int
20b0: 6f 20 74 68 65 20 66 69 6c 65 73 20 6f 6e 20 64  o the files on d
20c0: 69 73 6b 2e 20 41 72 67 75 6d 65 6e 74 20 24 63  isk. Argument $c
20d0: 72 61 73 68 64 65 6c 61 79 20 69 6e 64 69 63 61  rashdelay indica
20e0: 74 65 73 20 74 68 65 0a 23 20 6e 75 6d 62 65 72  tes the.# number
20f0: 20 6f 66 20 66 69 6c 65 20 73 79 6e 63 73 20 74   of file syncs t
2100: 6f 20 77 61 69 74 20 62 65 66 6f 72 65 20 63 72  o wait before cr
2110: 61 73 68 69 6e 67 2e 0a 23 0a 23 20 54 68 65 20  ashing..#.# The 
2120: 72 65 74 75 72 6e 20 76 61 6c 75 65 20 69 73 20  return value is 
2130: 61 20 6c 69 73 74 20 6f 66 20 74 77 6f 20 65 6c  a list of two el
2140: 65 6d 65 6e 74 73 2e 20 54 68 65 20 66 69 72 73  ements. The firs
2150: 74 20 65 6c 65 6d 65 6e 74 20 69 73 20 61 0a 23  t element is a.#
2160: 20 62 6f 6f 6c 65 61 6e 2c 20 69 6e 64 69 63 61   boolean, indica
2170: 74 69 6e 67 20 77 68 65 74 68 65 72 20 6f 72 20  ting whether or 
2180: 6e 6f 74 20 74 68 65 20 70 72 6f 63 65 73 73 20  not the process 
2190: 61 63 74 75 61 6c 6c 79 20 63 72 61 73 68 65 64  actually crashed
21a0: 20 6f 72 0a 23 20 72 65 70 6f 72 74 65 64 20 73   or.# reported s
21b0: 6f 6d 65 20 6f 74 68 65 72 20 65 72 72 6f 72 2e  ome other error.
21c0: 20 54 68 65 20 73 65 63 6f 6e 64 20 65 6c 65 6d   The second elem
21d0: 65 6e 74 20 69 6e 20 74 68 65 20 72 65 74 75 72  ent in the retur
21e0: 6e 65 64 20 6c 69 73 74 20 69 73 20 74 68 65 0a  ned list is the.
21f0: 23 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 2e  # error message.
2200: 20 54 68 69 73 20 69 73 20 22 63 68 69 6c 64 20   This is "child 
2210: 70 72 6f 63 65 73 73 20 65 78 69 74 65 64 20 61  process exited a
2220: 62 6e 6f 72 6d 61 6c 6c 79 22 20 69 66 20 74 68  bnormally" if th
2230: 65 20 63 72 61 73 68 0a 23 20 6f 63 63 75 72 65  e crash.# occure
2240: 64 2e 0a 23 0a 23 20 20 20 63 72 61 73 68 73 71  d..#.#   crashsq
2250: 6c 20 2d 64 65 6c 61 79 20 43 52 41 53 48 44 45  l -delay CRASHDE
2260: 4c 41 59 20 2d 66 69 6c 65 20 43 52 41 53 48 46  LAY -file CRASHF
2270: 49 4c 45 20 3f 2d 62 6c 6f 63 6b 73 69 7a 65 20  ILE ?-blocksize 
2280: 42 4c 4f 43 4b 53 49 5a 45 20 24 73 71 6c 0a 23  BLOCKSIZE $sql.#
2290: 0a 70 72 6f 63 20 63 72 61 73 68 73 71 6c 20 7b  .proc crashsql {
22a0: 61 72 67 73 7d 20 7b 0a 20 20 69 66 20 7b 24 3a  args} {.  if {$:
22b0: 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c  :tcl_platform(pl
22c0: 61 74 66 6f 72 6d 29 21 3d 22 75 6e 69 78 22 7d  atform)!="unix"}
22d0: 20 7b 0a 20 20 20 20 65 72 72 6f 72 20 22 63 72   {.    error "cr
22e0: 61 73 68 73 71 6c 20 73 68 6f 75 6c 64 20 6f 6e  ashsql should on
22f0: 6c 79 20 62 65 20 75 73 65 64 20 6f 6e 20 75 6e  ly be used on un
2300: 69 78 22 0a 20 20 7d 0a 0a 20 20 73 65 74 20 62  ix".  }..  set b
2310: 6c 6f 63 6b 73 69 7a 65 20 22 22 0a 20 20 73 65  locksize "".  se
2320: 74 20 63 72 61 73 68 64 65 6c 61 79 20 31 0a 20  t crashdelay 1. 
2330: 20 73 65 74 20 63 72 61 73 68 66 69 6c 65 20 22   set crashfile "
2340: 22 0a 20 20 73 65 74 20 73 71 6c 20 5b 6c 69 6e  ".  set sql [lin
2350: 64 65 78 20 24 61 72 67 73 20 65 6e 64 5d 0a 20  dex $args end]. 
2360: 20 0a 20 20 66 6f 72 20 7b 73 65 74 20 69 69 20   .  for {set ii 
2370: 30 7d 20 7b 24 69 69 20 3c 20 5b 6c 6c 65 6e 67  0} {$ii < [lleng
2380: 74 68 20 24 61 72 67 73 5d 2d 31 7d 20 7b 69 6e  th $args]-1} {in
2390: 63 72 20 69 69 20 32 7d 20 7b 0a 20 20 20 20 73  cr ii 2} {.    s
23a0: 65 74 20 7a 20 5b 6c 69 6e 64 65 78 20 24 61 72  et z [lindex $ar
23b0: 67 73 20 24 69 69 5d 0a 20 20 20 20 73 65 74 20  gs $ii].    set 
23c0: 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68  n [string length
23d0: 20 24 7a 5d 0a 20 20 20 20 73 65 74 20 7a 32 20   $z].    set z2 
23e0: 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 5b 65  [lindex $args [e
23f0: 78 70 72 20 24 69 69 2b 31 5d 5d 0a 0a 20 20 20  xpr $ii+1]]..   
2400: 20 69 66 20 20 20 20 20 7b 24 6e 3e 31 20 26 26   if     {$n>1 &&
2410: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
2420: 7a 20 2d 64 65 6c 61 79 5d 3d 3d 30 7d 20 20 20  z -delay]==0}   
2430: 20 20 7b 73 65 74 20 63 72 61 73 68 64 65 6c 61    {set crashdela
2440: 79 20 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73  y $z2} \.    els
2450: 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74  eif {$n>1 && [st
2460: 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d 66  ring first $z -f
2470: 69 6c 65 5d 3d 3d 30 7d 20 20 20 20 20 20 7b 73  ile]==0}      {s
2480: 65 74 20 63 72 61 73 68 66 69 6c 65 20 24 7a 32  et crashfile $z2
2490: 7d 20 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20  }  \.    elseif 
24a0: 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67  {$n>1 && [string
24b0: 20 66 69 72 73 74 20 24 7a 20 2d 62 6c 6f 63 6b   first $z -block
24c0: 73 69 7a 65 5d 3d 3d 30 7d 20 7b 73 65 74 20 62  size]==0} {set b
24d0: 6c 6f 63 6b 73 69 7a 65 20 24 7a 32 7d 20 20 5c  locksize $z2}  \
24e0: 0a 20 20 20 20 65 6c 73 65 20 20 20 7b 20 65 72  .    else   { er
24f0: 72 6f 72 20 22 55 6e 72 65 63 6f 67 6e 69 7a 65  ror "Unrecognize
2500: 64 20 6f 70 74 69 6f 6e 3a 20 24 7a 22 20 7d 0a  d option: $z" }.
2510: 20 20 7d 0a 0a 20 20 69 66 20 7b 24 63 72 61 73    }..  if {$cras
2520: 68 66 69 6c 65 20 65 71 20 22 22 7d 20 7b 0a 20  hfile eq ""} {. 
2530: 20 20 20 65 72 72 6f 72 20 22 43 6f 6d 70 75 6c     error "Compul
2540: 73 6f 72 79 20 6f 70 74 69 6f 6e 20 2d 66 69 6c  sory option -fil
2550: 65 20 6d 69 73 73 69 6e 67 22 0a 20 20 7d 0a 0a  e missing".  }..
2560: 20 20 73 65 74 20 63 66 69 6c 65 20 5b 66 69 6c    set cfile [fil
2570: 65 20 6a 6f 69 6e 20 5b 70 77 64 5d 20 24 63 72  e join [pwd] $cr
2580: 61 73 68 66 69 6c 65 5d 0a 0a 20 20 73 65 74 20  ashfile]..  set 
2590: 66 20 5b 6f 70 65 6e 20 63 72 61 73 68 2e 74 63  f [open crash.tc
25a0: 6c 20 77 5d 0a 20 20 70 75 74 73 20 24 66 20 22  l w].  puts $f "
25b0: 73 71 6c 69 74 65 33 5f 63 72 61 73 68 70 61 72  sqlite3_crashpar
25c0: 61 6d 73 20 24 63 72 61 73 68 64 65 6c 61 79 20  ams $crashdelay 
25d0: 24 63 66 69 6c 65 20 24 62 6c 6f 63 6b 73 69 7a  $cfile $blocksiz
25e0: 65 22 0a 20 20 70 75 74 73 20 24 66 20 22 73 65  e".  puts $f "se
25f0: 74 20 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67  t sqlite_pending
2600: 5f 62 79 74 65 20 24 3a 3a 73 71 6c 69 74 65 5f  _byte $::sqlite_
2610: 70 65 6e 64 69 6e 67 5f 62 79 74 65 22 0a 20 20  pending_byte".  
2620: 70 75 74 73 20 24 66 20 22 73 71 6c 69 74 65 33  puts $f "sqlite3
2630: 20 64 62 20 74 65 73 74 2e 64 62 22 0a 0a 20 20   db test.db"..  
2640: 23 20 54 68 69 73 20 62 6c 6f 63 6b 20 73 65 74  # This block set
2650: 73 20 74 68 65 20 63 61 63 68 65 20 73 69 7a 65  s the cache size
2660: 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 64 61 74   of the main dat
2670: 61 62 61 73 65 20 74 6f 20 31 30 0a 20 20 23 20  abase to 10.  # 
2680: 70 61 67 65 73 2e 20 54 68 69 73 20 69 73 20 64  pages. This is d
2690: 6f 6e 65 20 69 6e 20 63 61 73 65 20 74 68 65 20  one in case the 
26a0: 62 75 69 6c 64 20 69 73 20 63 6f 6e 66 69 67 75  build is configu
26b0: 72 65 64 20 74 6f 20 6f 6d 69 74 0a 20 20 23 20  red to omit.  # 
26c0: 22 50 52 41 47 4d 41 20 63 61 63 68 65 5f 73 69  "PRAGMA cache_si
26d0: 7a 65 22 2e 0a 20 20 70 75 74 73 20 24 66 20 7b  ze"..  puts $f {
26e0: 64 62 20 65 76 61 6c 20 7b 53 45 4c 45 43 54 20  db eval {SELECT 
26f0: 2a 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61  * FROM sqlite_ma
2700: 73 74 65 72 3b 7d 7d 0a 20 20 70 75 74 73 20 24  ster;}}.  puts $
2710: 66 20 7b 73 65 74 20 62 74 20 5b 62 74 72 65 65  f {set bt [btree
2720: 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 7d 0a 20 20  _from_db db]}.  
2730: 70 75 74 73 20 24 66 20 7b 62 74 72 65 65 5f 73  puts $f {btree_s
2740: 65 74 5f 63 61 63 68 65 5f 73 69 7a 65 20 24 62  et_cache_size $b
2750: 74 20 31 30 7d 0a 0a 20 20 70 75 74 73 20 24 66  t 10}..  puts $f
2760: 20 22 64 62 20 65 76 61 6c 20 7b 22 0a 20 20 70   "db eval {".  p
2770: 75 74 73 20 24 66 20 20 20 22 24 73 71 6c 22 0a  uts $f   "$sql".
2780: 20 20 70 75 74 73 20 24 66 20 22 7d 22 0a 20 20    puts $f "}".  
2790: 63 6c 6f 73 65 20 24 66 0a 0a 20 20 73 65 74 20  close $f..  set 
27a0: 72 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20 65  r [catch {.    e
27b0: 78 65 63 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66  xec [info nameof
27c0: 65 78 65 63 5d 20 63 72 61 73 68 2e 74 63 6c 20  exec] crash.tcl 
27d0: 3e 40 73 74 64 6f 75 74 0a 20 20 7d 20 6d 73 67  >@stdout.  } msg
27e0: 5d 0a 20 20 6c 61 70 70 65 6e 64 20 72 20 24 6d  ].  lappend r $m
27f0: 73 67 0a 7d 0a 0a 23 20 55 73 61 67 65 3a 20 64  sg.}..# Usage: d
2800: 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20 3c 74 65  o_ioerr_test <te
2810: 73 74 20 6e 75 6d 62 65 72 3e 20 3c 6f 70 74 69  st number> <opti
2820: 6f 6e 73 2e 2e 2e 3e 0a 23 0a 23 20 54 68 69 73  ons...>.#.# This
2830: 20 70 72 6f 63 20 69 73 20 75 73 65 64 20 74 6f   proc is used to
2840: 20 69 6d 70 6c 65 6d 65 6e 74 20 74 65 73 74 20   implement test 
2850: 63 61 73 65 73 20 74 68 61 74 20 63 68 65 63 6b  cases that check
2860: 20 74 68 61 74 20 49 4f 20 65 72 72 6f 72 73 0a   that IO errors.
2870: 23 20 61 72 65 20 63 6f 72 72 65 63 74 6c 79 20  # are correctly 
2880: 68 61 6e 64 6c 65 64 2e 20 54 68 65 20 66 69 72  handled. The fir
2890: 73 74 20 61 72 67 75 6d 65 6e 74 2c 20 3c 74 65  st argument, <te
28a0: 73 74 20 6e 75 6d 62 65 72 3e 2c 20 69 73 20 61  st number>, is a
28b0: 6e 20 69 6e 74 65 67 65 72 20 0a 23 20 75 73 65  n integer .# use
28c0: 64 20 74 6f 20 6e 61 6d 65 20 74 68 65 20 74 65  d to name the te
28d0: 73 74 73 20 65 78 65 63 75 74 65 64 20 62 79 20  sts executed by 
28e0: 74 68 69 73 20 70 72 6f 63 2e 20 4f 70 74 69 6f  this proc. Optio
28f0: 6e 73 20 61 72 65 20 61 73 20 66 6f 6c 6c 6f 77  ns are as follow
2900: 73 3a 0a 23 0a 23 20 20 20 20 20 2d 74 63 6c 70  s:.#.#     -tclp
2910: 72 65 70 20 20 20 20 20 20 20 20 20 20 54 43 4c  rep          TCL
2920: 20 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20 74   script to run t
2930: 6f 20 70 72 65 70 61 72 65 20 74 65 73 74 2e 0a  o prepare test..
2940: 23 20 20 20 20 20 2d 73 71 6c 70 72 65 70 20 20  #     -sqlprep  
2950: 20 20 20 20 20 20 20 20 53 51 4c 20 73 63 72 69          SQL scri
2960: 70 74 20 74 6f 20 72 75 6e 20 74 6f 20 70 72 65  pt to run to pre
2970: 70 61 72 65 20 74 65 73 74 2e 0a 23 20 20 20 20  pare test..#    
2980: 20 2d 74 63 6c 62 6f 64 79 20 20 20 20 20 20 20   -tclbody       
2990: 20 20 20 54 43 4c 20 73 63 72 69 70 74 20 74 6f     TCL script to
29a0: 20 72 75 6e 20 77 69 74 68 20 49 4f 20 65 72 72   run with IO err
29b0: 6f 72 20 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23  or simulation..#
29c0: 20 20 20 20 20 2d 73 71 6c 62 6f 64 79 20 20 20       -sqlbody   
29d0: 20 20 20 20 20 20 20 54 43 4c 20 73 63 72 69 70         TCL scrip
29e0: 74 20 74 6f 20 72 75 6e 20 77 69 74 68 20 49 4f  t to run with IO
29f0: 20 65 72 72 6f 72 20 73 69 6d 75 6c 61 74 69 6f   error simulatio
2a00: 6e 2e 0a 23 20 20 20 20 20 2d 65 78 63 6c 75 64  n..#     -exclud
2a10: 65 20 20 20 20 20 20 20 20 20 20 4c 69 73 74 20  e          List 
2a20: 6f 66 20 27 4e 27 20 76 61 6c 75 65 73 20 6e 6f  of 'N' values no
2a30: 74 20 74 6f 20 74 65 73 74 2e 0a 23 20 20 20 20  t to test..#    
2a40: 20 2d 65 72 63 20 20 20 20 20 20 20 20 20 20 20   -erc           
2a50: 20 20 20 55 73 65 20 65 78 74 65 6e 64 65 64 20     Use extended 
2a60: 72 65 73 75 6c 74 20 63 6f 64 65 73 0a 23 20 20  result codes.#  
2a70: 20 20 20 2d 70 65 72 73 69 73 74 20 20 20 20 20     -persist     
2a80: 20 20 20 20 20 4d 61 6b 65 20 73 69 6d 75 6c 61       Make simula
2a90: 74 65 64 20 49 2f 4f 20 65 72 72 6f 72 73 20 70  ted I/O errors p
2aa0: 65 72 73 69 73 74 65 6e 74 0a 23 20 20 20 20 20  ersistent.#     
2ab0: 2d 73 74 61 72 74 20 20 20 20 20 20 20 20 20 20  -start          
2ac0: 20 20 56 61 6c 75 65 20 6f 66 20 27 4e 27 20 74    Value of 'N' t
2ad0: 6f 20 62 65 67 69 6e 20 77 69 74 68 20 28 64 65  o begin with (de
2ae0: 66 61 75 6c 74 20 31 29 0a 23 0a 23 20 20 20 20  fault 1).#.#    
2af0: 20 2d 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20   -cksum         
2b00: 20 20 20 42 6f 6f 6c 65 61 6e 2e 20 49 66 20 74     Boolean. If t
2b10: 72 75 65 2c 20 74 65 73 74 20 74 68 61 74 20 74  rue, test that t
2b20: 68 65 20 64 61 74 61 62 61 73 65 20 64 6f 65 73  he database does
2b30: 0a 23 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .#              
2b40: 20 20 20 20 20 20 20 20 20 6e 6f 74 20 63 68 61           not cha
2b50: 6e 67 65 20 64 75 72 69 6e 67 20 74 68 65 20 65  nge during the e
2b60: 78 65 63 75 74 69 6f 6e 20 6f 66 20 74 68 65 20  xecution of the 
2b70: 74 65 73 74 20 63 61 73 65 2e 0a 23 0a 70 72 6f  test case..#.pro
2b80: 63 20 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20  c do_ioerr_test 
2b90: 7b 74 65 73 74 6e 61 6d 65 20 61 72 67 73 7d 20  {testname args} 
2ba0: 7b 0a 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72  {..  set ::ioerr
2bb0: 6f 70 74 73 28 2d 73 74 61 72 74 29 20 31 0a 20  opts(-start) 1. 
2bc0: 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73   set ::ioerropts
2bd0: 28 2d 63 6b 73 75 6d 29 20 30 0a 20 20 73 65 74  (-cksum) 0.  set
2be0: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72   ::ioerropts(-er
2bf0: 63 29 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65  c) 0.  set ::ioe
2c00: 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29 20 31  rropts(-count) 1
2c10: 30 30 30 30 30 30 30 30 0a 20 20 73 65 74 20 3a  00000000.  set :
2c20: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 70 65 72 73  :ioerropts(-pers
2c30: 69 73 74 29 20 31 0a 20 20 61 72 72 61 79 20 73  ist) 1.  array s
2c40: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 20 24  et ::ioerropts $
2c50: 61 72 67 73 0a 0a 20 20 73 65 74 20 3a 3a 67 6f  args..  set ::go
2c60: 20 31 0a 20 20 66 6f 72 20 7b 73 65 74 20 6e 20   1.  for {set n 
2c70: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 74  $::ioerropts(-st
2c80: 61 72 74 29 7d 20 7b 24 3a 3a 67 6f 7d 20 7b 69  art)} {$::go} {i
2c90: 6e 63 72 20 6e 7d 20 7b 0a 20 20 20 20 69 6e 63  ncr n} {.    inc
2ca0: 72 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63  r ::ioerropts(-c
2cb0: 6f 75 6e 74 29 20 2d 31 0a 20 20 20 20 69 66 20  ount) -1.    if 
2cc0: 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63  {$::ioerropts(-c
2cd0: 6f 75 6e 74 29 3c 30 7d 20 62 72 65 61 6b 0a 20  ount)<0} break. 
2ce0: 0a 20 20 20 20 23 20 53 6b 69 70 20 74 68 69 73  .    # Skip this
2cf0: 20 49 4f 20 65 72 72 6f 72 20 69 66 20 69 74 20   IO error if it 
2d00: 77 61 73 20 73 70 65 63 69 66 69 65 64 20 77 69  was specified wi
2d10: 74 68 20 74 68 65 20 22 2d 65 78 63 6c 75 64 65  th the "-exclude
2d20: 22 20 6f 70 74 69 6f 6e 2e 0a 20 20 20 20 69 66  " option..    if
2d30: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
2d40: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 78 63 6c  :ioerropts(-excl
2d50: 75 64 65 29 5d 7d 20 7b 0a 20 20 20 20 20 20 69  ude)]} {.      i
2d60: 66 20 7b 5b 6c 73 65 61 72 63 68 20 24 3a 3a 69  f {[lsearch $::i
2d70: 6f 65 72 72 6f 70 74 73 28 2d 65 78 63 6c 75 64  oerropts(-exclud
2d80: 65 29 20 24 6e 5d 21 3d 2d 31 7d 20 63 6f 6e 74  e) $n]!=-1} cont
2d90: 69 6e 75 65 0a 20 20 20 20 7d 0a 0a 20 20 20 20  inue.    }..    
2da0: 23 20 44 65 6c 65 74 65 20 74 68 65 20 66 69 6c  # Delete the fil
2db0: 65 73 20 74 65 73 74 2e 64 62 20 61 6e 64 20 74  es test.db and t
2dc0: 65 73 74 32 2e 64 62 2c 20 74 68 65 6e 20 65 78  est2.db, then ex
2dd0: 65 63 75 74 65 20 74 68 65 20 54 43 4c 20 61 6e  ecute the TCL an
2de0: 64 20 0a 20 20 20 20 23 20 53 51 4c 20 28 69 6e  d .    # SQL (in
2df0: 20 74 68 61 74 20 6f 72 64 65 72 29 20 74 6f 20   that order) to 
2e00: 70 72 65 70 61 72 65 20 66 6f 72 20 74 68 65 20  prepare for the 
2e10: 74 65 73 74 20 63 61 73 65 2e 0a 20 20 20 20 64  test case..    d
2e20: 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65  o_test $testname
2e30: 2e 24 6e 2e 31 20 7b 0a 20 20 20 20 20 20 73 65  .$n.1 {.      se
2e40: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
2e50: 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20  ror_pending 0.  
2e60: 20 20 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c      catch {db cl
2e70: 6f 73 65 7d 0a 20 20 20 20 20 20 63 61 74 63 68  ose}.      catch
2e80: 20 7b 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66   {file delete -f
2e90: 6f 72 63 65 20 74 65 73 74 2e 64 62 7d 0a 20 20  orce test.db}.  
2ea0: 20 20 20 20 63 61 74 63 68 20 7b 66 69 6c 65 20      catch {file 
2eb0: 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 74 65  delete -force te
2ec0: 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a 20  st.db-journal}. 
2ed0: 20 20 20 20 20 63 61 74 63 68 20 7b 66 69 6c 65       catch {file
2ee0: 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 74   delete -force t
2ef0: 65 73 74 32 2e 64 62 7d 0a 20 20 20 20 20 20 63  est2.db}.      c
2f00: 61 74 63 68 20 7b 66 69 6c 65 20 64 65 6c 65 74  atch {file delet
2f10: 65 20 2d 66 6f 72 63 65 20 74 65 73 74 32 2e 64  e -force test2.d
2f20: 62 2d 6a 6f 75 72 6e 61 6c 7d 0a 20 20 20 20 20  b-journal}.     
2f30: 20 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74   set ::DB [sqlit
2f40: 65 33 20 64 62 20 74 65 73 74 2e 64 62 3b 20 73  e3 db test.db; s
2f50: 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f  qlite3_connectio
2f60: 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20  n_pointer db].  
2f70: 20 20 20 20 73 71 6c 69 74 65 33 5f 65 78 74 65      sqlite3_exte
2f80: 6e 64 65 64 5f 72 65 73 75 6c 74 5f 63 6f 64 65  nded_result_code
2f90: 73 20 24 3a 3a 44 42 20 24 3a 3a 69 6f 65 72 72  s $::DB $::ioerr
2fa0: 6f 70 74 73 28 2d 65 72 63 29 0a 20 20 20 20 20  opts(-erc).     
2fb0: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
2fc0: 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74  s ::ioerropts(-t
2fd0: 63 6c 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20  clprep)]} {.    
2fe0: 20 20 20 20 65 76 61 6c 20 24 3a 3a 69 6f 65 72      eval $::ioer
2ff0: 72 6f 70 74 73 28 2d 74 63 6c 70 72 65 70 29 0a  ropts(-tclprep).
3000: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
3010: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
3020: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 70  :ioerropts(-sqlp
3030: 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20 20 20 20  rep)]} {.       
3040: 20 65 78 65 63 73 71 6c 20 24 3a 3a 69 6f 65 72   execsql $::ioer
3050: 72 6f 70 74 73 28 2d 73 71 6c 70 72 65 70 29 0a  ropts(-sqlprep).
3060: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 65 78        }.      ex
3070: 70 72 20 30 0a 20 20 20 20 7d 20 7b 30 7d 0a 0a  pr 0.    } {0}..
3080: 20 20 20 20 23 20 52 65 61 64 20 74 68 65 20 27      # Read the '
3090: 63 68 65 63 6b 73 75 6d 27 20 6f 66 20 74 68 65  checksum' of the
30a0: 20 64 61 74 61 62 61 73 65 2e 0a 20 20 20 20 69   database..    i
30b0: 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  f {$::ioerropts(
30c0: 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20 20 20 20 20  -cksum)} {.     
30d0: 20 73 65 74 20 63 68 65 63 6b 73 75 6d 20 5b 63   set checksum [c
30e0: 6b 73 75 6d 5d 0a 20 20 20 20 7d 0a 20 20 0a 20  ksum].    }.  . 
30f0: 20 20 20 23 20 53 65 74 20 74 68 65 20 4e 74 68     # Set the Nth
3100: 20 49 4f 20 65 72 72 6f 72 20 74 6f 20 66 61 69   IO error to fai
3110: 6c 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24  l..    do_test $
3120: 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 32 20 5b 73  testname.$n.2 [s
3130: 75 62 73 74 20 7b 0a 20 20 20 20 20 20 73 65 74  ubst {.      set
3140: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
3150: 6f 72 5f 70 65 72 73 69 73 74 20 24 3a 3a 69 6f  or_persist $::io
3160: 65 72 72 6f 70 74 73 28 2d 70 65 72 73 69 73 74  erropts(-persist
3170: 29 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71  ).      set ::sq
3180: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65  lite_io_error_pe
3190: 6e 64 69 6e 67 20 24 6e 0a 20 20 20 20 7d 5d 20  nding $n.    }] 
31a0: 24 6e 0a 20 20 0a 20 20 20 20 23 20 43 72 65 61  $n.  .    # Crea
31b0: 74 65 20 61 20 73 69 6e 67 6c 65 20 54 43 4c 20  te a single TCL 
31c0: 73 63 72 69 70 74 20 66 72 6f 6d 20 74 68 65 20  script from the 
31d0: 54 43 4c 20 61 6e 64 20 53 51 4c 20 73 70 65 63  TCL and SQL spec
31e0: 69 66 69 65 64 0a 20 20 20 20 23 20 61 73 20 74  ified.    # as t
31f0: 68 65 20 62 6f 64 79 20 6f 66 20 74 68 65 20 74  he body of the t
3200: 65 73 74 2e 0a 20 20 20 20 73 65 74 20 3a 3a 69  est..    set ::i
3210: 6f 65 72 72 6f 72 62 6f 64 79 20 7b 7d 0a 20 20  oerrorbody {}.  
3220: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
3230: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
3240: 74 63 6c 62 6f 64 79 29 5d 7d 20 7b 0a 20 20 20  tclbody)]} {.   
3250: 20 20 20 61 70 70 65 6e 64 20 3a 3a 69 6f 65 72     append ::ioer
3260: 72 6f 72 62 6f 64 79 20 22 24 3a 3a 69 6f 65 72  rorbody "$::ioer
3270: 72 6f 70 74 73 28 2d 74 63 6c 62 6f 64 79 29 5c  ropts(-tclbody)\
3280: 6e 22 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20  n".    }.    if 
3290: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
32a0: 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f  ioerropts(-sqlbo
32b0: 64 79 29 5d 7d 20 7b 0a 20 20 20 20 20 20 61 70  dy)]} {.      ap
32c0: 70 65 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f  pend ::ioerrorbo
32d0: 64 79 20 22 64 62 20 65 76 61 6c 20 7b 24 3a 3a  dy "db eval {$::
32e0: 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f  ioerropts(-sqlbo
32f0: 64 79 29 7d 22 0a 20 20 20 20 7d 0a 0a 20 20 20  dy)}".    }..   
3300: 20 23 20 45 78 65 63 75 74 65 20 74 68 65 20 54   # Execute the T
3310: 43 4c 20 53 63 72 69 70 74 20 63 72 65 61 74 65  CL Script create
3320: 64 20 69 6e 20 74 68 65 20 61 62 6f 76 65 20 62  d in the above b
3330: 6c 6f 63 6b 2e 20 49 66 0a 20 20 20 20 23 20 74  lock. If.    # t
3340: 68 65 72 65 20 61 72 65 20 61 74 20 6c 65 61 73  here are at leas
3350: 74 20 4e 20 49 4f 20 6f 70 65 72 61 74 69 6f 6e  t N IO operation
3360: 73 20 70 65 72 66 6f 72 6d 65 64 20 62 79 20 53  s performed by S
3370: 51 4c 69 74 65 20 61 73 0a 20 20 20 20 23 20 61  QLite as.    # a
3380: 20 72 65 73 75 6c 74 20 6f 66 20 74 68 65 20 73   result of the s
3390: 63 72 69 70 74 2c 20 74 68 65 20 4e 74 68 20 77  cript, the Nth w
33a0: 69 6c 6c 20 66 61 69 6c 2e 0a 20 20 20 20 64 6f  ill fail..    do
33b0: 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e  _test $testname.
33c0: 24 6e 2e 33 20 7b 0a 20 20 20 20 20 20 73 65 74  $n.3 {.      set
33d0: 20 72 20 5b 63 61 74 63 68 20 24 3a 3a 69 6f 65   r [catch $::ioe
33e0: 72 72 6f 72 62 6f 64 79 20 6d 73 67 5d 0a 20 20  rrorbody msg].  
33f0: 20 20 20 20 73 65 74 20 72 63 20 5b 73 71 6c 69      set rc [sqli
3400: 74 65 33 5f 65 72 72 63 6f 64 65 20 24 3a 3a 44  te3_errcode $::D
3410: 42 5d 0a 20 20 20 20 20 20 69 66 20 7b 24 3a 3a  B].      if {$::
3420: 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29 7d  ioerropts(-erc)}
3430: 20 7b 0a 20 20 20 20 20 20 20 20 23 20 49 66 20   {.        # If 
3440: 77 65 20 61 72 65 20 69 6e 20 65 78 74 65 6e 64  we are in extend
3450: 65 64 20 72 65 73 75 6c 74 20 63 6f 64 65 20 6d  ed result code m
3460: 6f 64 65 2c 20 6d 61 6b 65 20 73 75 72 65 20 61  ode, make sure a
3470: 6c 6c 20 6f 66 20 74 68 65 0a 20 20 20 20 20 20  ll of the.      
3480: 20 20 23 20 49 4f 45 52 52 73 20 77 65 20 67 65    # IOERRs we ge
3490: 74 20 62 61 63 6b 20 72 65 61 6c 6c 79 20 64 6f  t back really do
34a0: 20 68 61 76 65 20 74 68 65 69 72 20 65 78 74 65   have their exte
34b0: 6e 64 65 64 20 63 6f 64 65 20 76 61 6c 75 65 73  nded code values
34c0: 2e 0a 20 20 20 20 20 20 20 20 23 20 49 66 20 61  ..        # If a
34d0: 6e 20 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c  n extended resul
34e0: 74 20 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e  t code is return
34f0: 65 64 2c 20 74 68 65 20 73 71 6c 69 74 65 33 5f  ed, the sqlite3_
3500: 65 72 72 63 6f 64 65 0a 20 20 20 20 20 20 20 20  errcode.        
3510: 23 20 54 43 4c 63 6f 6d 6d 61 6e 64 20 77 69 6c  # TCLcommand wil
3520: 6c 20 72 65 74 75 72 6e 20 61 20 73 74 72 69 6e  l return a strin
3530: 67 20 6f 66 20 74 68 65 20 66 6f 72 6d 3a 20 20  g of the form:  
3540: 53 51 4c 49 54 45 5f 49 4f 45 52 52 2b 6e 6e 6e  SQLITE_IOERR+nnn
3550: 6e 0a 20 20 20 20 20 20 20 20 23 20 77 68 65 72  n.        # wher
3560: 65 20 6e 6e 6e 6e 20 69 73 20 61 20 6e 75 6d 62  e nnnn is a numb
3570: 65 72 0a 20 20 20 20 20 20 20 20 69 66 20 7b 5b  er.        if {[
3580: 72 65 67 65 78 70 20 7b 5e 53 51 4c 49 54 45 5f  regexp {^SQLITE_
3590: 49 4f 45 52 52 7d 20 24 72 63 5d 20 26 26 20 21  IOERR} $rc] && !
35a0: 5b 72 65 67 65 78 70 20 7b 49 4f 45 52 52 5c 2b  [regexp {IOERR\+
35b0: 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20 20  \d} $rc]} {.    
35c0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 24 72 63        return $rc
35d0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
35e0: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20   } else {.      
35f0: 20 20 23 20 49 66 20 77 65 20 61 72 65 20 6e 6f    # If we are no
3600: 74 20 69 6e 20 65 78 74 65 6e 64 65 64 20 72 65  t in extended re
3610: 73 75 6c 74 20 63 6f 64 65 20 6d 6f 64 65 2c 20  sult code mode, 
3620: 6d 61 6b 65 20 73 75 72 65 20 6e 6f 0a 20 20 20  make sure no.   
3630: 20 20 20 20 20 23 20 65 78 74 65 6e 64 65 64 20       # extended 
3640: 65 72 72 6f 72 20 63 6f 64 65 73 20 61 72 65 20  error codes are 
3650: 72 65 74 75 72 6e 65 64 2e 0a 20 20 20 20 20 20  returned..      
3660: 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5c    if {[regexp {\
3670: 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20 20 20  +\d} $rc]} {.   
3680: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 24 72         return $r
3690: 63 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  c.        }.    
36a0: 20 20 7d 0a 20 20 20 20 20 20 23 20 54 68 65 20    }.      # The 
36b0: 74 65 73 74 20 72 65 70 65 61 74 73 20 61 73 20  test repeats as 
36c0: 6c 6f 6e 67 20 61 73 20 24 3a 3a 67 6f 20 69 73  long as $::go is
36d0: 20 74 72 75 65 2e 20 20 0a 20 20 20 20 20 20 73   true.  .      s
36e0: 65 74 20 3a 3a 67 6f 20 5b 65 78 70 72 20 7b 24  et ::go [expr {$
36f0: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
3700: 72 5f 70 65 6e 64 69 6e 67 3c 3d 30 7d 5d 0a 20  r_pending<=0}]. 
3710: 20 20 20 20 20 73 65 74 20 73 20 5b 65 78 70 72       set s [expr
3720: 20 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72   $::sqlite_io_er
3730: 72 6f 72 5f 68 69 74 3d 3d 30 5d 0a 20 20 20 20  ror_hit==0].    
3740: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
3750: 6f 5f 65 72 72 6f 72 5f 68 69 74 20 30 0a 0a 20  o_error_hit 0.. 
3760: 20 20 20 20 20 23 20 4f 6e 65 20 6f 66 20 74 77       # One of tw
3770: 6f 20 74 68 69 6e 67 73 20 6d 75 73 74 20 68 61  o things must ha
3780: 76 65 20 68 61 70 70 65 6e 65 64 2e 20 65 69 74  ve happened. eit
3790: 68 65 72 0a 20 20 20 20 20 20 23 20 20 20 31 2e  her.      #   1.
37a0: 20 20 57 65 20 6e 65 76 65 72 20 68 69 74 20 74    We never hit t
37b0: 68 65 20 49 4f 20 65 72 72 6f 72 20 61 6e 64 20  he IO error and 
37c0: 74 68 65 20 53 51 4c 20 72 65 74 75 72 6e 65 64  the SQL returned
37d0: 20 4f 4b 0a 20 20 20 20 20 20 23 20 20 20 32 2e   OK.      #   2.
37e0: 20 20 41 6e 20 49 4f 20 65 72 72 6f 72 20 77 61    An IO error wa
37f0: 73 20 68 69 74 20 61 6e 64 20 74 68 65 20 53 51  s hit and the SQ
3800: 4c 20 66 61 69 6c 65 64 0a 20 20 20 20 20 20 23  L failed.      #
3810: 0a 20 20 20 20 20 20 65 78 70 72 20 7b 20 28 24  .      expr { ($
3820: 73 20 26 26 20 21 24 72 20 26 26 20 21 24 3a 3a  s && !$r && !$::
3830: 67 6f 29 20 7c 7c 20 28 21 24 73 20 26 26 20 24  go) || (!$s && $
3840: 72 20 26 26 20 24 3a 3a 67 6f 29 20 7d 0a 20 20  r && $::go) }.  
3850: 20 20 7d 20 7b 31 7d 0a 0a 20 20 20 20 23 20 49    } {1}..    # I
3860: 66 20 61 6e 20 49 4f 20 65 72 72 6f 72 20 6f 63  f an IO error oc
3870: 63 75 72 65 64 2c 20 74 68 65 6e 20 74 68 65 20  cured, then the 
3880: 63 68 65 63 6b 73 75 6d 20 6f 66 20 74 68 65 20  checksum of the 
3890: 64 61 74 61 62 61 73 65 20 73 68 6f 75 6c 64 0a  database should.
38a0: 20 20 20 20 23 20 62 65 20 74 68 65 20 73 61 6d      # be the sam
38b0: 65 20 61 73 20 62 65 66 6f 72 65 20 74 68 65 20  e as before the 
38c0: 73 63 72 69 70 74 20 74 68 61 74 20 63 61 75 73  script that caus
38d0: 65 64 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20  ed the IO error 
38e0: 77 61 73 20 72 75 6e 2e 0a 20 20 20 20 69 66 20  was run..    if 
38f0: 7b 24 3a 3a 67 6f 20 26 26 20 24 3a 3a 69 6f 65  {$::go && $::ioe
3900: 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20  rropts(-cksum)} 
3910: 7b 0a 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20  {.      do_test 
3920: 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 34 20 7b  $testname.$n.4 {
3930: 0a 20 20 20 20 20 20 20 20 63 61 74 63 68 20 7b  .        catch {
3940: 64 62 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20  db close}.      
3950: 20 20 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69    set ::DB [sqli
3960: 74 65 33 20 64 62 20 74 65 73 74 2e 64 62 3b 20  te3 db test.db; 
3970: 73 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69  sqlite3_connecti
3980: 6f 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20  on_pointer db]. 
3990: 20 20 20 20 20 20 20 63 6b 73 75 6d 0a 20 20 20         cksum.   
39a0: 20 20 20 7d 20 24 63 68 65 63 6b 73 75 6d 0a 20     } $checksum. 
39b0: 20 20 20 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a     }..    set ::
39c0: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
39d0: 70 65 6e 64 69 6e 67 20 30 0a 20 20 20 20 69 66  pending 0.    if
39e0: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
39f0: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6c 65 61  :ioerropts(-clea
3a00: 6e 75 70 29 5d 7d 20 7b 0a 20 20 20 20 20 20 63  nup)]} {.      c
3a10: 61 74 63 68 20 24 3a 3a 69 6f 65 72 72 6f 70 74  atch $::ioerropt
3a20: 73 28 2d 63 6c 65 61 6e 75 70 29 0a 20 20 20 20  s(-cleanup).    
3a30: 7d 0a 20 20 7d 0a 20 20 73 65 74 20 3a 3a 73 71  }.  }.  set ::sq
3a40: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65  lite_io_error_pe
3a50: 6e 64 69 6e 67 20 30 0a 20 20 73 65 74 20 3a 3a  nding 0.  set ::
3a60: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
3a70: 70 65 72 73 69 73 74 20 30 0a 20 20 75 6e 73 65  persist 0.  unse
3a80: 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 0a 7d 0a  t ::ioerropts.}.
3a90: 0a 23 20 52 65 74 75 72 6e 20 61 20 63 68 65 63  .# Return a chec
3aa0: 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74 68  ksum based on th
3ab0: 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 64 61  e contents of da
3ac0: 74 61 62 61 73 65 20 27 64 62 27 2e 0a 23 0a 70  tabase 'db'..#.p
3ad0: 72 6f 63 20 63 6b 73 75 6d 20 7b 7b 64 62 20 64  roc cksum {{db d
3ae0: 62 7d 7d 20 7b 0a 20 20 73 65 74 20 74 78 74 20  b}} {.  set txt 
3af0: 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20  [$db eval {.    
3b00: 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20 74    SELECT name, t
3b10: 79 70 65 2c 20 73 71 6c 20 46 52 4f 4d 20 73 71  ype, sql FROM sq
3b20: 6c 69 74 65 5f 6d 61 73 74 65 72 20 6f 72 64 65  lite_master orde
3b30: 72 20 62 79 20 6e 61 6d 65 0a 20 20 7d 5d 5c 6e  r by name.  }]\n
3b40: 0a 20 20 66 6f 72 65 61 63 68 20 74 62 6c 20 5b  .  foreach tbl [
3b50: 24 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20 20  $db eval {.     
3b60: 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f   SELECT name FRO
3b70: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20  M sqlite_master 
3b80: 57 48 45 52 45 20 74 79 70 65 3d 27 74 61 62 6c  WHERE type='tabl
3b90: 65 27 20 6f 72 64 65 72 20 62 79 20 6e 61 6d 65  e' order by name
3ba0: 0a 20 20 7d 5d 20 7b 0a 20 20 20 20 61 70 70 65  .  }] {.    appe
3bb0: 6e 64 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c  nd txt [$db eval
3bc0: 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20   "SELECT * FROM 
3bd0: 24 74 62 6c 22 5d 5c 6e 0a 20 20 7d 0a 20 20 66  $tbl"]\n.  }.  f
3be0: 6f 72 65 61 63 68 20 70 72 61 67 20 7b 64 65 66  oreach prag {def
3bf0: 61 75 6c 74 5f 73 79 6e 63 68 72 6f 6e 6f 75 73  ault_synchronous
3c00: 20 64 65 66 61 75 6c 74 5f 63 61 63 68 65 5f 73   default_cache_s
3c10: 69 7a 65 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e  ize} {.    appen
3c20: 64 20 74 78 74 20 24 70 72 61 67 2d 5b 24 64 62  d txt $prag-[$db
3c30: 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 24 70   eval "PRAGMA $p
3c40: 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a 20 20 73 65  rag"]\n.  }.  se
3c50: 74 20 63 6b 73 75 6d 20 5b 73 74 72 69 6e 67 20  t cksum [string 
3c60: 6c 65 6e 67 74 68 20 24 74 78 74 5d 2d 5b 6d 64  length $txt]-[md
3c70: 35 20 24 74 78 74 5d 0a 20 20 23 20 70 75 74 73  5 $txt].  # puts
3c80: 20 24 63 6b 73 75 6d 2d 5b 66 69 6c 65 20 73 69   $cksum-[file si
3c90: 7a 65 20 74 65 73 74 2e 64 62 5d 0a 20 20 72 65  ze test.db].  re
3ca0: 74 75 72 6e 20 24 63 6b 73 75 6d 0a 7d 0a 0a 23  turn $cksum.}..#
3cb0: 20 43 6f 70 79 20 66 69 6c 65 20 24 66 72 6f 6d   Copy file $from
3cc0: 20 69 6e 74 6f 20 24 74 6f 2e 20 54 68 69 73 20   into $to. This 
3cd0: 69 73 20 75 73 65 64 20 62 65 63 61 75 73 65 20  is used because 
3ce0: 73 6f 6d 65 20 76 65 72 73 69 6f 6e 73 20 6f 66  some versions of
3cf0: 0a 23 20 54 43 4c 20 66 6f 72 20 77 69 6e 64 6f  .# TCL for windo
3d00: 77 73 20 28 6e 6f 74 61 62 6c 79 20 74 68 65 20  ws (notably the 
3d10: 38 2e 34 2e 31 20 62 69 6e 61 72 79 20 70 61 63  8.4.1 binary pac
3d20: 6b 61 67 65 20 73 68 69 70 70 65 64 20 77 69 74  kage shipped wit
3d30: 68 20 74 68 65 0a 23 20 63 75 72 72 65 6e 74 20  h the.# current 
3d40: 6d 69 6e 67 77 20 72 65 6c 65 61 73 65 29 20 68  mingw release) h
3d50: 61 76 65 20 61 20 62 72 6f 6b 65 6e 20 22 66 69  ave a broken "fi
3d60: 6c 65 20 63 6f 70 79 22 20 63 6f 6d 6d 61 6e 64  le copy" command
3d70: 2e 0a 23 0a 70 72 6f 63 20 63 6f 70 79 5f 66 69  ..#.proc copy_fi
3d80: 6c 65 20 7b 66 72 6f 6d 20 74 6f 7d 20 7b 0a 20  le {from to} {. 
3d90: 20 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74   if {$::tcl_plat
3da0: 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 3d 3d  form(platform)==
3db0: 22 75 6e 69 78 22 7d 20 7b 0a 20 20 20 20 66 69  "unix"} {.    fi
3dc0: 6c 65 20 63 6f 70 79 20 2d 66 6f 72 63 65 20 24  le copy -force $
3dd0: 66 72 6f 6d 20 24 74 6f 0a 20 20 7d 20 65 6c 73  from $to.  } els
3de0: 65 20 7b 0a 20 20 20 20 73 65 74 20 66 20 5b 6f  e {.    set f [o
3df0: 70 65 6e 20 24 66 72 6f 6d 5d 0a 20 20 20 20 66  pen $from].    f
3e00: 63 6f 6e 66 69 67 75 72 65 20 24 66 20 2d 74 72  configure $f -tr
3e10: 61 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79  anslation binary
3e20: 0a 20 20 20 20 73 65 74 20 74 20 5b 6f 70 65 6e  .    set t [open
3e30: 20 24 74 6f 20 77 5d 0a 20 20 20 20 66 63 6f 6e   $to w].    fcon
3e40: 66 69 67 75 72 65 20 24 74 20 2d 74 72 61 6e 73  figure $t -trans
3e50: 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20  lation binary.  
3e60: 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e    puts -nonewlin
3e70: 65 20 24 74 20 5b 72 65 61 64 20 24 66 20 5b 66  e $t [read $f [f
3e80: 69 6c 65 20 73 69 7a 65 20 24 66 72 6f 6d 5d 5d  ile size $from]]
3e90: 0a 20 20 20 20 63 6c 6f 73 65 20 24 74 0a 20 20  .    close $t.  
3ea0: 20 20 63 6c 6f 73 65 20 24 66 0a 20 20 7d 0a 7d    close $f.  }.}
3eb0: 0a 0a 23 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64  ..# This command
3ec0: 20 63 68 65 63 6b 73 20 66 6f 72 20 6f 75 74 73   checks for outs
3ed0: 74 61 6e 64 69 6e 67 20 63 61 6c 6c 73 20 74 6f  tanding calls to
3ee0: 20 73 71 6c 69 74 65 4d 61 6c 6c 6f 63 28 29 20   sqliteMalloc() 
3ef0: 66 72 6f 6d 20 77 69 74 68 69 6e 0a 23 20 74 68  from within.# th
3f00: 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64  e current thread
3f10: 2e 20 41 20 6c 69 73 74 20 69 73 20 72 65 74 75  . A list is retu
3f20: 72 6e 65 64 20 77 69 74 68 20 6f 6e 65 20 65 6e  rned with one en
3f30: 74 72 79 20 66 6f 72 20 65 61 63 68 20 6f 75 74  try for each out
3f40: 73 74 61 6e 64 69 6e 67 0a 23 20 6d 61 6c 6c 6f  standing.# mallo
3f50: 63 2e 20 45 61 63 68 20 6c 69 73 74 20 65 6e 74  c. Each list ent
3f60: 72 79 20 69 73 20 69 74 73 65 6c 66 20 61 20 6c  ry is itself a l
3f70: 69 73 74 20 6f 66 20 35 20 69 74 65 6d 73 2c 20  ist of 5 items, 
3f80: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 23 0a 23 20  as follows:.#.# 
3f90: 20 20 20 20 7b 20 3c 6e 75 6d 62 65 72 2d 62 79      { <number-by
3fa0: 74 65 73 3e 20 3c 66 69 6c 65 2d 6e 61 6d 65 3e  tes> <file-name>
3fb0: 20 3c 6c 69 6e 65 2d 6e 75 6d 62 65 72 3e 20 3c   <line-number> <
3fc0: 74 65 73 74 2d 63 61 73 65 3e 20 3c 73 74 61 63  test-case> <stac
3fd0: 6b 2d 64 75 6d 70 3e 20 7d 0a 23 0a 70 72 6f 63  k-dump> }.#.proc
3fe0: 20 63 68 65 63 6b 5f 66 6f 72 5f 6c 65 61 6b 73   check_for_leaks
3ff0: 20 7b 7d 20 7b 0a 20 20 73 65 74 20 72 65 74 20   {} {.  set ret 
4000: 5b 6c 69 73 74 5d 0a 20 20 73 65 74 20 63 6e 74  [list].  set cnt
4010: 20 30 0a 20 20 66 6f 72 65 61 63 68 20 61 6c 6c   0.  foreach all
4020: 6f 63 20 5b 73 71 6c 69 74 65 5f 6d 61 6c 6c 6f  oc [sqlite_mallo
4030: 63 5f 6f 75 74 73 74 61 6e 64 69 6e 67 5d 20 7b  c_outstanding] {
4040: 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b 6e 42  .    foreach {nB
4050: 79 74 65 73 20 66 69 6c 65 20 69 4c 69 6e 65 20  ytes file iLine 
4060: 75 73 65 72 73 74 72 69 6e 67 20 62 61 63 6b 74  userstring backt
4070: 72 61 63 65 7d 20 24 61 6c 6c 6f 63 20 7b 7d 0a  race} $alloc {}.
4080: 20 20 20 20 73 65 74 20 73 74 61 63 6b 20 5b 6c      set stack [l
4090: 69 73 74 5d 0a 20 20 20 20 73 65 74 20 73 6b 69  ist].    set ski
40a0: 70 20 30 0a 0a 20 20 20 20 23 20 54 68 65 20 66  p 0..    # The f
40b0: 69 72 73 74 20 63 6f 6d 6d 61 6e 64 20 69 6e 20  irst command in 
40c0: 74 68 69 73 20 62 6c 6f 63 6b 20 77 69 6c 6c 20  this block will 
40d0: 70 72 6f 62 61 62 6c 79 20 66 61 69 6c 20 6f 6e  probably fail on
40e0: 20 77 69 6e 64 6f 77 73 2e 20 54 68 69 73 0a 20   windows. This. 
40f0: 20 20 20 23 20 6d 65 61 6e 73 20 74 68 65 72 65     # means there
4100: 20 77 69 6c 6c 20 62 65 20 6e 6f 20 73 74 61 63   will be no stac
4110: 6b 20 64 75 6d 70 20 61 76 61 69 6c 61 62 6c 65  k dump available
4120: 2e 0a 20 20 20 20 69 66 20 7b 24 63 6e 74 20 3c  ..    if {$cnt <
4130: 20 32 35 20 26 26 20 24 62 61 63 6b 74 72 61 63   25 && $backtrac
4140: 65 21 3d 22 22 7d 20 7b 0a 20 20 20 20 20 20 63  e!=""} {.      c
4150: 61 74 63 68 20 7b 0a 20 20 20 20 20 20 20 20 73  atch {.        s
4160: 65 74 20 73 74 75 66 66 20 5b 65 76 61 6c 20 22  et stuff [eval "
4170: 65 78 65 63 20 61 64 64 72 32 6c 69 6e 65 20 2d  exec addr2line -
4180: 65 20 2e 2f 74 65 73 74 66 69 78 74 75 72 65 20  e ./testfixture 
4190: 2d 66 20 24 62 61 63 6b 74 72 61 63 65 22 5d 0a  -f $backtrace"].
41a0: 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20          foreach 
41b0: 7b 66 75 6e 63 20 6c 69 6e 65 7d 20 24 73 74 75  {func line} $stu
41c0: 66 66 20 7b 0a 20 20 20 20 20 20 20 20 20 20 69  ff {.          i
41d0: 66 20 7b 24 66 75 6e 63 20 21 3d 20 22 3f 3f 22  f {$func != "??"
41e0: 20 7c 7c 20 24 6c 69 6e 65 20 21 3d 20 22 3f 3f   || $line != "??
41f0: 3a 30 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  :0"} {.         
4200: 20 20 20 72 65 67 65 78 70 20 7b 2e 2a 2f 28 2e     regexp {.*/(.
4210: 2a 29 7d 20 24 6c 69 6e 65 20 64 75 6d 6d 79 20  *)} $line dummy 
4220: 6c 69 6e 65 0a 20 20 20 20 20 20 20 20 20 20 20  line.           
4230: 20 6c 61 70 70 65 6e 64 20 73 74 61 63 6b 20 22   lappend stack "
4240: 24 7b 66 75 6e 63 7d 28 29 20 24 6c 69 6e 65 22  ${func}() $line"
4250: 0a 20 20 20 20 20 20 20 20 20 20 7d 20 65 6c 73  .          } els
4260: 65 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  e {.            
4270: 69 66 20 7b 5b 6c 69 6e 64 65 78 20 24 73 74 61  if {[lindex $sta
4280: 63 6b 20 65 6e 64 5d 20 21 3d 20 22 2e 2e 2e 22  ck end] != "..."
4290: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  } {.            
42a0: 20 20 6c 61 70 70 65 6e 64 20 73 74 61 63 6b 20    lappend stack 
42b0: 22 2e 2e 2e 22 0a 20 20 20 20 20 20 20 20 20 20  "...".          
42c0: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 7d 0a    }.          }.
42d0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
42e0: 7d 0a 20 20 20 20 20 20 69 6e 63 72 20 63 6e 74  }.      incr cnt
42f0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20 7b  .    }..    if {
4300: 21 24 73 6b 69 70 7d 20 7b 0a 20 20 20 20 20 20  !$skip} {.      
4310: 6c 61 70 70 65 6e 64 20 72 65 74 20 5b 6c 69 73  lappend ret [lis
4320: 74 20 24 6e 42 79 74 65 73 20 24 66 69 6c 65 20  t $nBytes $file 
4330: 24 69 4c 69 6e 65 20 24 75 73 65 72 73 74 72 69  $iLine $userstri
4340: 6e 67 20 24 73 74 61 63 6b 5d 0a 20 20 20 20 7d  ng $stack].    }
4350: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72  .  }.  return $r
4360: 65 74 0a 7d 0a 0a 23 20 50 72 65 74 74 79 20 70  et.}..# Pretty p
4370: 72 69 6e 74 20 61 20 72 65 70 6f 72 74 20 62 61  rint a report ba
4380: 73 65 64 20 6f 6e 20 74 68 65 20 72 65 74 75 72  sed on the retur
4390: 6e 20 76 61 6c 75 65 20 6f 66 20 5b 63 68 65 63  n value of [chec
43a0: 6b 5f 66 6f 72 5f 6c 65 61 6b 73 5d 20 74 6f 0a  k_for_leaks] to.
43b0: 23 20 73 74 64 6f 75 74 2e 0a 70 72 6f 63 20 70  # stdout..proc p
43c0: 70 5f 63 68 65 63 6b 5f 66 6f 72 5f 6c 65 61 6b  p_check_for_leak
43d0: 73 20 7b 7d 20 7b 0a 20 20 73 65 74 20 6c 20 5b  s {} {.  set l [
43e0: 63 68 65 63 6b 5f 66 6f 72 5f 6c 65 61 6b 73 5d  check_for_leaks]
43f0: 0a 20 20 73 65 74 20 6e 20 30 0a 20 20 66 6f 72  .  set n 0.  for
4400: 65 61 63 68 20 6c 65 61 6b 20 24 6c 20 7b 0a 20  each leak $l {. 
4410: 20 20 20 66 6f 72 65 61 63 68 20 7b 6e 42 79 74     foreach {nByt
4420: 65 73 20 66 69 6c 65 20 69 4c 69 6e 65 20 75 73  es file iLine us
4430: 65 72 73 74 72 69 6e 67 20 73 74 61 63 6b 7d 20  erstring stack} 
4440: 24 6c 65 61 6b 20 7b 7d 0a 20 20 20 20 70 75 74  $leak {}.    put
4450: 73 20 22 24 6e 42 79 74 65 73 20 62 79 74 65 73  s "$nBytes bytes
4460: 20 6c 65 61 6b 65 64 20 61 74 20 24 66 69 6c 65   leaked at $file
4470: 3a 24 69 4c 69 6e 65 20 28 24 75 73 65 72 73 74  :$iLine ($userst
4480: 72 69 6e 67 29 22 0a 20 20 20 20 66 6f 72 65 61  ring)".    forea
4490: 63 68 20 66 72 61 6d 65 20 24 73 74 61 63 6b 20  ch frame $stack 
44a0: 7b 0a 20 20 20 20 20 20 70 75 74 73 20 22 20 20  {.      puts "  
44b0: 20 20 20 20 20 20 24 66 72 61 6d 65 22 0a 20 20        $frame".  
44c0: 20 20 7d 0a 20 20 20 20 69 6e 63 72 20 6e 20 24    }.    incr n $
44d0: 6e 42 79 74 65 73 0a 20 20 7d 0a 20 20 70 75 74  nBytes.  }.  put
44e0: 73 20 22 4d 65 6d 6f 72 79 20 6c 65 61 6b 65 64  s "Memory leaked
44f0: 3a 20 24 6e 20 62 79 74 65 73 20 69 6e 20 5b 6c  : $n bytes in [l
4500: 6c 65 6e 67 74 68 20 24 6c 5d 20 61 6c 6c 6f 63  length $l] alloc
4510: 61 74 69 6f 6e 73 22 0a 20 20 70 75 74 73 20 22  ations".  puts "
4520: 22 0a 7d 0a 0a 23 20 49 66 20 74 68 65 20 6c 69  ".}..# If the li
4530: 62 72 61 72 79 20 69 73 20 63 6f 6d 70 69 6c 65  brary is compile
4540: 64 20 77 69 74 68 20 74 68 65 20 53 51 4c 49 54  d with the SQLIT
4550: 45 5f 44 45 46 41 55 4c 54 5f 41 55 54 4f 56 41  E_DEFAULT_AUTOVA
4560: 43 55 55 4d 20 6d 61 63 72 6f 20 73 65 74 0a 23  CUUM macro set.#
4570: 20 74 6f 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68   to non-zero, th
4580: 65 6e 20 73 65 74 20 74 68 65 20 67 6c 6f 62 61  en set the globa
4590: 6c 20 76 61 72 69 61 62 6c 65 20 24 41 55 54 4f  l variable $AUTO
45a0: 56 41 43 55 55 4d 20 74 6f 20 31 2e 0a 73 65 74  VACUUM to 1..set
45b0: 20 41 55 54 4f 56 41 43 55 55 4d 20 24 73 71 6c   AUTOVACUUM $sql
45c0: 69 74 65 5f 6f 70 74 69 6f 6e 73 28 64 65 66 61  ite_options(defa
45d0: 75 6c 74 5f 61 75 74 6f 76 61 63 75 75 6d 29 0a  ult_autovacuum).