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

Artifact dcebe3c5bf15f3b4ba015b4b2237030c1e384941:


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 38 30 20 32 30 30 37 2f 30 34 2f 32 38   1.80 2007/04/28
01f0: 20 31 35 3a 34 37 3a 34 35 20 64 61 6e 69 65 6c   15:47:45 daniel
0200: 6b 31 39 37 37 20 45 78 70 20 24 0a 0a 23 20 4d  k1977 Exp $..# M
0210: 61 6b 65 20 73 75 72 65 20 74 63 6c 73 71 6c 69  ake sure tclsqli
0220: 74 65 33 20 77 61 73 20 63 6f 6d 70 69 6c 65 64  te3 was compiled
0230: 20 63 6f 72 72 65 63 74 6c 79 2e 20 20 41 62 6f   correctly.  Abo
0240: 72 74 20 6e 6f 77 20 77 69 74 68 20 61 6e 0a 23  rt now with an.#
0250: 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 20 69   error message i
0260: 66 20 6e 6f 74 2e 0a 23 0a 69 66 20 7b 5b 73 71  f not..#.if {[sq
0270: 6c 69 74 65 33 20 2d 74 63 6c 2d 75 73 65 73 2d  lite3 -tcl-uses-
0280: 75 74 66 5d 7d 20 7b 0a 20 20 69 66 20 7b 22 5c  utf]} {.  if {"\
0290: 75 31 32 33 34 22 3d 3d 22 75 31 32 33 34 22 7d  u1234"=="u1234"}
02a0: 20 7b 0a 20 20 20 20 70 75 74 73 20 73 74 64 65   {.    puts stde
02b0: 72 72 20 22 2a 2a 2a 2a 2a 20 42 55 49 4c 44 20  rr "***** BUILD 
02c0: 50 52 4f 42 4c 45 4d 20 2a 2a 2a 2a 2a 22 0a 20  PROBLEM *****". 
02d0: 20 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22     puts stderr "
02e0: 24 61 72 67 76 30 20 77 61 73 20 6c 69 6e 6b 65  $argv0 was linke
02f0: 64 20 61 67 61 69 6e 73 74 20 61 6e 20 6f 6c 64  d against an old
0300: 65 72 20 76 65 72 73 69 6f 6e 22 0a 20 20 20 20  er version".    
0310: 70 75 74 73 20 73 74 64 65 72 72 20 22 6f 66 20  puts stderr "of 
0320: 54 43 4c 20 74 68 61 74 20 64 6f 65 73 20 6e 6f  TCL that does no
0330: 74 20 73 75 70 70 6f 72 74 20 55 6e 69 63 6f 64  t support Unicod
0340: 65 2c 20 62 75 74 20 75 73 65 73 20 61 20 68 65  e, but uses a he
0350: 61 64 65 72 22 0a 20 20 20 20 70 75 74 73 20 73  ader".    puts s
0360: 74 64 65 72 72 20 22 66 69 6c 65 20 28 5c 22 74  tderr "file (\"t
0370: 63 6c 2e 68 5c 22 29 20 66 72 6f 6d 20 61 20 6e  cl.h\") from a n
0380: 65 77 20 54 43 4c 20 76 65 72 73 69 6f 6e 20 74  ew TCL version t
0390: 68 61 74 20 64 6f 65 73 20 73 75 70 70 6f 72 74  hat does support
03a0: 22 0a 20 20 20 20 70 75 74 73 20 73 74 64 65 72  ".    puts stder
03b0: 72 20 22 55 6e 69 63 6f 64 65 2e 20 20 54 68 69  r "Unicode.  Thi
03c0: 73 20 63 6f 6d 62 69 6e 61 74 69 6f 6e 20 63 61  s combination ca
03d0: 75 73 65 73 20 69 6e 74 65 72 6e 61 6c 20 65 72  uses internal er
03e0: 72 6f 72 73 2e 22 0a 20 20 20 20 70 75 74 73 20  rors.".    puts 
03f0: 73 74 64 65 72 72 20 22 52 65 63 6f 6d 70 69 6c  stderr "Recompil
0400: 65 20 75 73 69 6e 67 20 61 20 54 43 4c 20 6c 69  e using a TCL li
0410: 62 72 61 72 79 20 61 6e 64 20 68 65 61 64 65 72  brary and header
0420: 20 66 69 6c 65 20 74 68 61 74 20 6d 61 74 63 68   file that match
0430: 22 0a 20 20 20 20 70 75 74 73 20 73 74 64 65 72  ".    puts stder
0440: 72 20 22 61 6e 64 20 74 72 79 20 61 67 61 69 6e  r "and try again
0450: 2e 5c 6e 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .\n*************
0460: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20  *************". 
0470: 20 20 20 65 78 69 74 20 31 0a 20 20 7d 0a 7d 20     exit 1.  }.} 
0480: 65 6c 73 65 20 7b 0a 20 20 69 66 20 7b 22 5c 75  else {.  if {"\u
0490: 31 32 33 34 22 21 3d 22 75 31 32 33 34 22 7d 20  1234"!="u1234"} 
04a0: 7b 0a 20 20 20 20 70 75 74 73 20 73 74 64 65 72  {.    puts stder
04b0: 72 20 22 2a 2a 2a 2a 2a 20 42 55 49 4c 44 20 50  r "***** BUILD P
04c0: 52 4f 42 4c 45 4d 20 2a 2a 2a 2a 2a 22 0a 20 20  ROBLEM *****".  
04d0: 20 20 70 75 74 73 20 73 74 64 65 72 72 20 22 24    puts stderr "$
04e0: 61 72 67 76 30 20 77 61 73 20 6c 69 6e 6b 65 64  argv0 was linked
04f0: 20 61 67 61 69 6e 73 74 20 61 6e 20 6e 65 77 65   against an newe
0500: 72 20 76 65 72 73 69 6f 6e 22 0a 20 20 20 20 70  r version".    p
0510: 75 74 73 20 73 74 64 65 72 72 20 22 6f 66 20 54  uts stderr "of T
0520: 43 4c 20 74 68 61 74 20 73 75 70 70 6f 72 74 73  CL that supports
0530: 20 55 6e 69 63 6f 64 65 2c 20 62 75 74 20 75 73   Unicode, but us
0540: 65 73 20 61 20 68 65 61 64 65 72 20 66 69 6c 65  es a header file
0550: 22 0a 20 20 20 20 70 75 74 73 20 73 74 64 65 72  ".    puts stder
0560: 72 20 22 28 5c 22 74 63 6c 2e 68 5c 22 29 20 66  r "(\"tcl.h\") f
0570: 72 6f 6d 20 61 20 6f 6c 64 20 54 43 4c 20 76 65  rom a old TCL ve
0580: 72 73 69 6f 6e 20 74 68 61 74 20 64 6f 65 73 20  rsion that does 
0590: 6e 6f 74 20 73 75 70 70 6f 72 74 22 0a 20 20 20  not support".   
05a0: 20 70 75 74 73 20 73 74 64 65 72 72 20 22 55 6e   puts stderr "Un
05b0: 69 63 6f 64 65 2e 20 20 54 68 69 73 20 63 6f 6d  icode.  This com
05c0: 62 69 6e 61 74 69 6f 6e 20 63 61 75 73 65 73 20  bination causes 
05d0: 69 6e 74 65 72 6e 61 6c 20 65 72 72 6f 72 73 2e  internal errors.
05e0: 22 0a 20 20 20 20 70 75 74 73 20 73 74 64 65 72  ".    puts stder
05f0: 72 20 22 52 65 63 6f 6d 70 69 6c 65 20 75 73 69  r "Recompile usi
0600: 6e 67 20 61 20 54 43 4c 20 6c 69 62 72 61 72 79  ng a TCL library
0610: 20 61 6e 64 20 68 65 61 64 65 72 20 66 69 6c 65   and header file
0620: 20 74 68 61 74 20 6d 61 74 63 68 22 0a 20 20 20   that match".   
0630: 20 70 75 74 73 20 73 74 64 65 72 72 20 22 61 6e   puts stderr "an
0640: 64 20 74 72 79 20 61 67 61 69 6e 2e 5c 6e 2a 2a  d try again.\n**
0650: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0660: 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 20 20 65 78  ********".    ex
0670: 69 74 20 31 0a 20 20 7d 0a 7d 0a 0a 73 65 74 20  it 1.  }.}..set 
0680: 74 63 6c 5f 70 72 65 63 69 73 69 6f 6e 20 31 35  tcl_precision 15
0690: 0a 73 65 74 20 73 71 6c 69 74 65 5f 70 65 6e 64  .set sqlite_pend
06a0: 69 6e 67 5f 62 79 74 65 20 30 78 30 30 31 30 30  ing_byte 0x00100
06b0: 30 30 0a 0a 23 20 55 73 65 20 74 68 65 20 70 61  00..# Use the pa
06c0: 67 65 72 20 63 6f 64 65 63 20 69 66 20 69 74 20  ger codec if it 
06d0: 69 73 20 61 76 61 69 6c 61 62 6c 65 0a 23 0a 69  is available.#.i
06e0: 66 20 7b 5b 73 71 6c 69 74 65 33 20 2d 68 61 73  f {[sqlite3 -has
06f0: 2d 63 6f 64 65 63 5d 20 26 26 20 5b 69 6e 66 6f  -codec] && [info
0700: 20 63 6f 6d 6d 61 6e 64 20 73 71 6c 69 74 65 5f   command sqlite_
0710: 6f 72 69 67 5d 3d 3d 22 22 7d 20 7b 0a 20 20 72  orig]==""} {.  r
0720: 65 6e 61 6d 65 20 73 71 6c 69 74 65 33 20 73 71  ename sqlite3 sq
0730: 6c 69 74 65 5f 6f 72 69 67 0a 20 20 70 72 6f 63  lite_orig.  proc
0740: 20 73 71 6c 69 74 65 33 20 7b 61 72 67 73 7d 20   sqlite3 {args} 
0750: 7b 0a 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67  {.    if {[lleng
0760: 74 68 20 24 61 72 67 73 5d 3d 3d 32 20 26 26 20  th $args]==2 && 
0770: 5b 73 74 72 69 6e 67 20 69 6e 64 65 78 20 5b 6c  [string index [l
0780: 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d 20 30  index $args 0] 0
0790: 5d 21 3d 22 2d 22 7d 20 7b 0a 20 20 20 20 20 20  ]!="-"} {.      
07a0: 6c 61 70 70 65 6e 64 20 61 72 67 73 20 2d 6b 65  lappend args -ke
07b0: 79 20 7b 78 79 7a 7a 79 7d 0a 20 20 20 20 7d 0a  y {xyzzy}.    }.
07c0: 20 20 20 20 75 70 6c 65 76 65 6c 20 31 20 73 71      uplevel 1 sq
07d0: 6c 69 74 65 5f 6f 72 69 67 20 24 61 72 67 73 0a  lite_orig $args.
07e0: 20 20 7d 0a 7d 0a 0a 0a 23 20 43 72 65 61 74 65    }.}...# Create
07f0: 20 61 20 74 65 73 74 20 64 61 74 61 62 61 73 65   a test database
0800: 0a 23 0a 63 61 74 63 68 20 7b 64 62 20 63 6c 6f  .#.catch {db clo
0810: 73 65 7d 0a 66 69 6c 65 20 64 65 6c 65 74 65 20  se}.file delete 
0820: 2d 66 6f 72 63 65 20 74 65 73 74 2e 64 62 0a 66  -force test.db.f
0830: 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63  ile delete -forc
0840: 65 20 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e 61  e test.db-journa
0850: 6c 0a 73 71 6c 69 74 65 33 20 64 62 20 2e 2f 74  l.sqlite3 db ./t
0860: 65 73 74 2e 64 62 0a 73 65 74 20 3a 3a 44 42 20  est.db.set ::DB 
0870: 5b 73 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74  [sqlite3_connect
0880: 69 6f 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a  ion_pointer db].
0890: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
08a0: 20 3a 3a 53 45 54 55 50 5f 53 51 4c 5d 7d 20 7b   ::SETUP_SQL]} {
08b0: 0a 20 20 64 62 20 65 76 61 6c 20 24 3a 3a 53 45  .  db eval $::SE
08c0: 54 55 50 5f 53 51 4c 0a 7d 0a 0a 23 20 41 62 6f  TUP_SQL.}..# Abo
08d0: 72 74 20 65 61 72 6c 79 20 69 66 20 74 68 69 73  rt early if this
08e0: 20 73 63 72 69 70 74 20 68 61 73 20 62 65 65 6e   script has been
08f0: 20 72 75 6e 20 62 65 66 6f 72 65 2e 0a 23 0a 69   run before..#.i
0900: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
0910: 6e 54 65 73 74 5d 7d 20 72 65 74 75 72 6e 0a 0a  nTest]} return..
0920: 23 20 53 65 74 20 74 68 65 20 74 65 73 74 20 63  # Set the test c
0930: 6f 75 6e 74 65 72 73 20 74 6f 20 7a 65 72 6f 0a  ounters to zero.
0940: 23 0a 73 65 74 20 6e 45 72 72 20 30 0a 73 65 74  #.set nErr 0.set
0950: 20 6e 54 65 73 74 20 30 0a 73 65 74 20 73 6b 69   nTest 0.set ski
0960: 70 5f 74 65 73 74 20 30 0a 73 65 74 20 66 61 69  p_test 0.set fai
0970: 6c 4c 69 73 74 20 7b 7d 0a 73 65 74 20 6d 61 78  lList {}.set max
0980: 45 72 72 20 31 30 30 30 0a 69 66 20 7b 21 5b 69  Err 1000.if {![i
0990: 6e 66 6f 20 65 78 69 73 74 73 20 73 70 65 65 64  nfo exists speed
09a0: 54 65 73 74 5d 7d 20 7b 0a 20 20 73 65 74 20 73  Test]} {.  set s
09b0: 70 65 65 64 54 65 73 74 20 30 0a 7d 0a 0a 23 20  peedTest 0.}..# 
09c0: 49 6e 76 6f 6b 65 20 74 68 65 20 64 6f 5f 74 65  Invoke the do_te
09d0: 73 74 20 70 72 6f 63 65 64 75 72 65 20 74 6f 20  st procedure to 
09e0: 72 75 6e 20 61 20 73 69 6e 67 6c 65 20 74 65 73  run a single tes
09f0: 74 20 0a 23 0a 70 72 6f 63 20 64 6f 5f 74 65 73  t .#.proc do_tes
0a00: 74 20 7b 6e 61 6d 65 20 63 6d 64 20 65 78 70 65  t {name cmd expe
0a10: 63 74 65 64 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c  cted} {.  global
0a20: 20 61 72 67 76 20 6e 45 72 72 20 6e 54 65 73 74   argv nErr nTest
0a30: 20 73 6b 69 70 5f 74 65 73 74 20 6d 61 78 45 72   skip_test maxEr
0a40: 72 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65  r.  set ::sqlite
0a50: 5f 6d 61 6c 6c 6f 63 5f 69 64 20 24 6e 61 6d 65  _malloc_id $name
0a60: 0a 20 20 69 66 20 7b 24 73 6b 69 70 5f 74 65 73  .  if {$skip_tes
0a70: 74 7d 20 7b 0a 20 20 20 20 73 65 74 20 73 6b 69  t} {.    set ski
0a80: 70 5f 74 65 73 74 20 30 0a 20 20 20 20 72 65 74  p_test 0.    ret
0a90: 75 72 6e 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 6c  urn.  }.  if {[l
0aa0: 6c 65 6e 67 74 68 20 24 61 72 67 76 5d 3d 3d 30  length $argv]==0
0ab0: 7d 20 7b 20 0a 20 20 20 20 73 65 74 20 67 6f 20  } { .    set go 
0ac0: 31 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20  1.  } else {.   
0ad0: 20 73 65 74 20 67 6f 20 30 0a 20 20 20 20 66 6f   set go 0.    fo
0ae0: 72 65 61 63 68 20 70 61 74 74 65 72 6e 20 24 61  reach pattern $a
0af0: 72 67 76 20 7b 0a 20 20 20 20 20 20 69 66 20 7b  rgv {.      if {
0b00: 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20 24 70  [string match $p
0b10: 61 74 74 65 72 6e 20 24 6e 61 6d 65 5d 7d 20 7b  attern $name]} {
0b20: 0a 20 20 20 20 20 20 20 20 73 65 74 20 67 6f 20  .        set go 
0b30: 31 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 0a  1.        break.
0b40: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
0b50: 7d 0a 20 20 69 66 20 7b 21 24 67 6f 7d 20 72 65  }.  if {!$go} re
0b60: 74 75 72 6e 0a 20 20 69 6e 63 72 20 6e 54 65 73  turn.  incr nTes
0b70: 74 0a 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c  t.  puts -nonewl
0b80: 69 6e 65 20 24 6e 61 6d 65 2e 2e 2e 0a 20 20 66  ine $name....  f
0b90: 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20 69 66  lush stdout.  if
0ba0: 20 7b 5b 63 61 74 63 68 20 7b 75 70 6c 65 76 65   {[catch {upleve
0bb0: 6c 20 23 30 20 22 24 63 6d 64 3b 5c 6e 22 7d 20  l #0 "$cmd;\n"} 
0bc0: 72 65 73 75 6c 74 5d 7d 20 7b 0a 20 20 20 20 70  result]} {.    p
0bd0: 75 74 73 20 22 5c 6e 45 72 72 6f 72 3a 20 24 72  uts "\nError: $r
0be0: 65 73 75 6c 74 22 0a 20 20 20 20 69 6e 63 72 20  esult".    incr 
0bf0: 6e 45 72 72 0a 20 20 20 20 6c 61 70 70 65 6e 64  nErr.    lappend
0c00: 20 3a 3a 66 61 69 6c 4c 69 73 74 20 24 6e 61 6d   ::failList $nam
0c10: 65 0a 20 20 20 20 69 66 20 7b 24 6e 45 72 72 3e  e.    if {$nErr>
0c20: 24 6d 61 78 45 72 72 7d 20 7b 70 75 74 73 20 22  $maxErr} {puts "
0c30: 2a 2a 2a 20 47 69 76 69 6e 67 20 75 70 2e 2e 2e  *** Giving up...
0c40: 22 3b 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74  "; finalize_test
0c50: 69 6e 67 7d 0a 20 20 7d 20 65 6c 73 65 69 66 20  ing}.  } elseif 
0c60: 7b 5b 73 74 72 69 6e 67 20 63 6f 6d 70 61 72 65  {[string compare
0c70: 20 24 72 65 73 75 6c 74 20 24 65 78 70 65 63 74   $result $expect
0c80: 65 64 5d 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  ed]} {.    puts 
0c90: 22 5c 6e 45 78 70 65 63 74 65 64 3a 20 5c 5b 24  "\nExpected: \[$
0ca0: 65 78 70 65 63 74 65 64 5c 5d 5c 6e 20 20 20 20  expected\]\n    
0cb0: 20 47 6f 74 3a 20 5c 5b 24 72 65 73 75 6c 74 5c   Got: \[$result\
0cc0: 5d 22 0a 20 20 20 20 69 6e 63 72 20 6e 45 72 72  ]".    incr nErr
0cd0: 0a 20 20 20 20 6c 61 70 70 65 6e 64 20 3a 3a 66  .    lappend ::f
0ce0: 61 69 6c 4c 69 73 74 20 24 6e 61 6d 65 0a 20 20  ailList $name.  
0cf0: 20 20 69 66 20 7b 24 6e 45 72 72 3e 3d 24 6d 61    if {$nErr>=$ma
0d00: 78 45 72 72 7d 20 7b 70 75 74 73 20 22 2a 2a 2a  xErr} {puts "***
0d10: 20 47 69 76 69 6e 67 20 75 70 2e 2e 2e 22 3b 20   Giving up..."; 
0d20: 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67  finalize_testing
0d30: 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20  }.  } else {.   
0d40: 20 70 75 74 73 20 22 20 4f 6b 22 0a 20 20 7d 0a   puts " Ok".  }.
0d50: 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 7d    flush stdout.}
0d60: 0a 0a 23 20 52 75 6e 20 61 6e 20 53 51 4c 20 73  ..# Run an SQL s
0d70: 63 72 69 70 74 2e 20 20 0a 23 20 52 65 74 75 72  cript.  .# Retur
0d80: 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  n the number of 
0d90: 6d 69 63 72 6f 73 65 63 6f 6e 64 73 20 70 65 72  microseconds per
0da0: 20 73 74 61 74 65 6d 65 6e 74 2e 0a 23 0a 70 72   statement..#.pr
0db0: 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c 20 7b  oc speed_trial {
0dc0: 6e 61 6d 65 20 6e 75 6d 73 74 6d 74 20 75 6e 69  name numstmt uni
0dd0: 74 73 20 73 71 6c 7d 20 7b 0a 20 20 70 75 74 73  ts sql} {.  puts
0de0: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b 66 6f 72   -nonewline [for
0df0: 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73 20 7d 20  mat {%-21.21s } 
0e00: 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66 6c 75 73  $name...].  flus
0e10: 68 20 73 74 64 6f 75 74 0a 20 20 73 65 74 20 73  h stdout.  set s
0e20: 70 65 65 64 20 5b 74 69 6d 65 20 7b 73 71 6c 69  peed [time {sqli
0e30: 74 65 33 5f 65 78 65 63 5f 6e 72 20 64 62 20 24  te3_exec_nr db $
0e40: 73 71 6c 7d 5d 0a 20 20 73 65 74 20 74 6d 20 5b  sql}].  set tm [
0e50: 6c 69 6e 64 65 78 20 24 73 70 65 65 64 20 30 5d  lindex $speed 0]
0e60: 0a 20 20 73 65 74 20 72 61 74 65 20 5b 65 78 70  .  set rate [exp
0e70: 72 20 7b 31 30 30 30 30 30 30 2e 30 2a 24 6e 75  r {1000000.0*$nu
0e80: 6d 73 74 6d 74 2f 24 74 6d 7d 5d 0a 20 20 73 65  mstmt/$tm}].  se
0e90: 74 20 75 32 20 24 75 6e 69 74 73 2f 73 0a 20 20  t u2 $units/s.  
0ea0: 70 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25 31  puts [format {%1
0eb0: 32 64 20 75 53 20 25 32 30 2e 35 66 20 25 73 7d  2d uS %20.5f %s}
0ec0: 20 24 74 6d 20 24 72 61 74 65 20 24 75 32 5d 0a   $tm $rate $u2].
0ed0: 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74    global total_t
0ee0: 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f  ime.  set total_
0ef0: 74 69 6d 65 20 5b 65 78 70 72 20 7b 24 74 6f 74  time [expr {$tot
0f00: 61 6c 5f 74 69 6d 65 2b 24 74 6d 7d 5d 0a 7d 0a  al_time+$tm}].}.
0f10: 70 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c  proc speed_trial
0f20: 5f 69 6e 69 74 20 7b 6e 61 6d 65 7d 20 7b 0a 20  _init {name} {. 
0f30: 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69   global total_ti
0f40: 6d 65 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f 74  me.  set total_t
0f50: 69 6d 65 20 30 0a 7d 0a 70 72 6f 63 20 73 70 65  ime 0.}.proc spe
0f60: 65 64 5f 74 72 69 61 6c 5f 73 75 6d 6d 61 72 79  ed_trial_summary
0f70: 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62   {name} {.  glob
0f80: 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20  al total_time.  
0f90: 70 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25 2d  puts [format {%-
0fa0: 32 31 2e 32 31 73 20 25 31 32 64 20 75 53 20 54  21.21s %12d uS T
0fb0: 4f 54 41 4c 7d 20 24 6e 61 6d 65 20 24 74 6f 74  OTAL} $name $tot
0fc0: 61 6c 5f 74 69 6d 65 5d 0a 7d 0a 0a 23 20 54 68  al_time].}..# Th
0fd0: 65 20 70 72 6f 63 65 64 75 72 65 20 75 73 65 73  e procedure uses
0fe0: 20 74 68 65 20 73 70 65 63 69 61 6c 20 22 73 71   the special "sq
0ff0: 6c 69 74 65 5f 6d 61 6c 6c 6f 63 5f 73 74 61 74  lite_malloc_stat
1000: 22 20 63 6f 6d 6d 61 6e 64 0a 23 20 28 77 68 69  " command.# (whi
1010: 63 68 20 69 73 20 6f 6e 6c 79 20 61 76 61 69 6c  ch is only avail
1020: 61 62 6c 65 20 69 66 20 53 51 4c 69 74 65 20 69  able if SQLite i
1030: 73 20 63 6f 6d 70 69 6c 65 64 20 77 69 74 68 20  s compiled with 
1040: 2d 44 53 51 4c 49 54 45 5f 44 45 42 55 47 3d 31  -DSQLITE_DEBUG=1
1050: 29 0a 23 20 74 6f 20 73 65 65 20 68 6f 77 20 6d  ).# to see how m
1060: 61 6e 79 20 6d 61 6c 6c 6f 63 28 29 73 20 68 61  any malloc()s ha
1070: 76 65 20 6e 6f 74 20 62 65 65 6e 20 66 72 65 65  ve not been free
1080: 28 29 65 64 2e 20 20 54 68 65 20 6e 75 6d 62 65  ()ed.  The numbe
1090: 72 0a 23 20 6f 66 20 73 75 72 70 6c 75 73 20 6d  r.# of surplus m
10a0: 61 6c 6c 6f 63 28 29 73 20 69 73 20 73 74 6f 72  alloc()s is stor
10b0: 65 64 20 69 6e 20 74 68 65 20 67 6c 6f 62 61 6c  ed in the global
10c0: 20 76 61 72 69 61 62 6c 65 20 24 3a 3a 4c 65 61   variable $::Lea
10d0: 6b 2e 0a 23 20 49 66 20 74 68 65 20 76 61 6c 75  k..# If the valu
10e0: 65 20 69 6e 20 24 3a 3a 4c 65 61 6b 20 67 72 6f  e in $::Leak gro
10f0: 77 73 2c 20 69 74 20 6d 61 79 20 6d 65 61 6e 20  ws, it may mean 
1100: 74 68 65 72 65 20 69 73 20 61 20 6d 65 6d 6f 72  there is a memor
1110: 79 20 6c 65 61 6b 0a 23 20 69 6e 20 74 68 65 20  y leak.# in the 
1120: 6c 69 62 72 61 72 79 2e 0a 23 0a 70 72 6f 63 20  library..#.proc 
1130: 6d 65 6d 6c 65 61 6b 5f 63 68 65 63 6b 20 7b 7d  memleak_check {}
1140: 20 7b 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 63   {.  if {[info c
1150: 6f 6d 6d 61 6e 64 20 73 71 6c 69 74 65 5f 6d 61  ommand sqlite_ma
1160: 6c 6c 6f 63 5f 73 74 61 74 5d 21 3d 22 22 7d 20  lloc_stat]!=""} 
1170: 7b 0a 20 20 20 20 73 65 74 20 72 20 5b 73 71 6c  {.    set r [sql
1180: 69 74 65 5f 6d 61 6c 6c 6f 63 5f 73 74 61 74 5d  ite_malloc_stat]
1190: 0a 20 20 20 20 73 65 74 20 3a 3a 4c 65 61 6b 20  .    set ::Leak 
11a0: 5b 65 78 70 72 20 7b 5b 6c 69 6e 64 65 78 20 24  [expr {[lindex $
11b0: 72 20 30 5d 2d 5b 6c 69 6e 64 65 78 20 24 72 20  r 0]-[lindex $r 
11c0: 31 5d 7d 5d 0a 20 20 7d 0a 7d 0a 0a 23 20 52 75  1]}].  }.}..# Ru
11d0: 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 6c  n this routine l
11e0: 61 73 74 0a 23 0a 70 72 6f 63 20 66 69 6e 69 73  ast.#.proc finis
11f0: 68 5f 74 65 73 74 20 7b 7d 20 7b 0a 20 20 66 69  h_test {} {.  fi
1200: 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67 0a 7d  nalize_testing.}
1210: 0a 70 72 6f 63 20 66 69 6e 61 6c 69 7a 65 5f 74  .proc finalize_t
1220: 65 73 74 69 6e 67 20 7b 7d 20 7b 0a 20 20 67 6c  esting {} {.  gl
1230: 6f 62 61 6c 20 6e 54 65 73 74 20 6e 45 72 72 20  obal nTest nErr 
1240: 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65  sqlite_open_file
1250: 5f 63 6f 75 6e 74 0a 20 20 69 66 20 7b 24 6e 45  _count.  if {$nE
1260: 72 72 3d 3d 30 7d 20 6d 65 6d 6c 65 61 6b 5f 63  rr==0} memleak_c
1270: 68 65 63 6b 0a 0a 20 20 63 61 74 63 68 20 7b 64  heck..  catch {d
1280: 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68  b close}.  catch
1290: 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63   {db2 close}.  c
12a0: 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d  atch {db3 close}
12b0: 0a 0a 20 20 63 61 74 63 68 20 7b 0a 20 20 20 20  ..  catch {.    
12c0: 70 70 5f 63 68 65 63 6b 5f 66 6f 72 5f 6c 65 61  pp_check_for_lea
12d0: 6b 73 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33  ks.  }.  sqlite3
12e0: 20 64 62 20 7b 7d 0a 20 20 23 20 73 71 6c 69 74   db {}.  # sqlit
12f0: 65 33 5f 63 6c 65 61 72 5f 74 73 64 5f 6d 65 6d  e3_clear_tsd_mem
1300: 64 65 62 75 67 0a 20 20 64 62 20 63 6c 6f 73 65  debug.  db close
1310: 0a 20 20 69 66 20 7b 24 3a 3a 73 71 6c 69 74 65  .  if {$::sqlite
1320: 33 5f 74 73 64 5f 63 6f 75 6e 74 7d 20 7b 0a 20  3_tsd_count} {. 
1330: 20 20 20 20 70 75 74 73 20 22 54 68 72 65 61 64      puts "Thread
1340: 2d 73 70 65 63 69 66 69 63 20 64 61 74 61 20 6c  -specific data l
1350: 65 61 6b 3a 20 24 3a 3a 73 71 6c 69 74 65 33 5f  eak: $::sqlite3_
1360: 74 73 64 5f 63 6f 75 6e 74 20 69 6e 73 74 61 6e  tsd_count instan
1370: 63 65 73 22 0a 20 20 20 20 20 69 6e 63 72 20 6e  ces".     incr n
1380: 45 72 72 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20  Err.  } else {. 
1390: 20 20 20 20 70 75 74 73 20 22 54 68 72 65 61 64      puts "Thread
13a0: 2d 73 70 65 63 69 66 69 63 20 64 61 74 61 20 64  -specific data d
13b0: 65 61 6c 6c 6f 63 61 74 65 64 20 70 72 6f 70 65  eallocated prope
13c0: 72 6c 79 22 0a 20 20 7d 0a 20 20 69 6e 63 72 20  rly".  }.  incr 
13d0: 6e 54 65 73 74 0a 20 20 70 75 74 73 20 22 24 6e  nTest.  puts "$n
13e0: 45 72 72 20 65 72 72 6f 72 73 20 6f 75 74 20 6f  Err errors out o
13f0: 66 20 24 6e 54 65 73 74 20 74 65 73 74 73 22 0a  f $nTest tests".
1400: 20 20 70 75 74 73 20 22 46 61 69 6c 75 72 65 73    puts "Failures
1410: 20 6f 6e 20 74 68 65 73 65 20 74 65 73 74 73 3a   on these tests:
1420: 20 24 3a 3a 66 61 69 6c 4c 69 73 74 22 0a 20 20   $::failList".  
1430: 69 66 20 7b 24 6e 45 72 72 3e 30 20 26 26 20 21  if {$nErr>0 && !
1440: 5b 77 6f 72 6b 69 6e 67 5f 36 34 62 69 74 5f 69  [working_64bit_i
1450: 6e 74 5d 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  nt]} {.    puts 
1460: 22 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 2a 2a 2a 2a 2a  ****************
14a0: 2a 2a 2a 22 0a 20 20 20 20 70 75 74 73 20 22 4e  ***".    puts "N
14b0: 2e 42 2e 3a 20 20 54 68 65 20 76 65 72 73 69 6f  .B.:  The versio
14c0: 6e 20 6f 66 20 54 43 4c 20 74 68 61 74 20 79 6f  n of TCL that yo
14d0: 75 20 75 73 65 64 20 74 6f 20 62 75 69 6c 64 20  u used to build 
14e0: 74 68 69 73 20 74 65 73 74 20 68 61 72 6e 65 73  this test harnes
14f0: 73 22 0a 20 20 20 20 70 75 74 73 20 22 69 73 20  s".    puts "is 
1500: 64 65 66 65 63 74 69 76 65 20 69 6e 20 74 68 61  defective in tha
1510: 74 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 73 75  t it does not su
1520: 70 70 6f 72 74 20 36 34 2d 62 69 74 20 69 6e 74  pport 64-bit int
1530: 65 67 65 72 73 2e 20 20 53 6f 6d 65 20 6f 72 22  egers.  Some or"
1540: 0a 20 20 20 20 70 75 74 73 20 22 61 6c 6c 20 6f  .    puts "all o
1550: 66 20 74 68 65 20 74 65 73 74 20 66 61 69 6c 75  f the test failu
1560: 72 65 73 20 61 62 6f 76 65 20 6d 69 67 68 74 20  res above might 
1570: 62 65 20 61 20 72 65 73 75 6c 74 20 66 72 6f 6d  be a result from
1580: 20 74 68 69 73 20 64 65 66 65 63 74 22 0a 20 20   this defect".  
1590: 20 20 70 75 74 73 20 22 69 6e 20 79 6f 75 72 20    puts "in your 
15a0: 54 43 4c 20 62 75 69 6c 64 2e 22 0a 20 20 20 20  TCL build.".    
15b0: 70 75 74 73 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  puts "**********
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: 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 7d 0a 20 20  ********".  }.  
1600: 69 66 20 7b 24 73 71 6c 69 74 65 5f 6f 70 65 6e  if {$sqlite_open
1610: 5f 66 69 6c 65 5f 63 6f 75 6e 74 7d 20 7b 0a 20  _file_count} {. 
1620: 20 20 20 70 75 74 73 20 22 24 73 71 6c 69 74 65     puts "$sqlite
1630: 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74  _open_file_count
1640: 20 66 69 6c 65 73 20 77 65 72 65 20 6c 65 66 74   files were left
1650: 20 6f 70 65 6e 22 0a 20 20 20 20 69 6e 63 72 20   open".    incr 
1660: 6e 45 72 72 0a 20 20 7d 0a 20 20 66 6f 72 65 61  nErr.  }.  forea
1670: 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f  ch f [glob -noco
1680: 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2d 2a  mplain test.db-*
1690: 2d 6a 6f 75 72 6e 61 6c 5d 20 7b 0a 20 20 20 20  -journal] {.    
16a0: 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72  file delete -for
16b0: 63 65 20 24 66 0a 20 20 7d 0a 20 20 66 6f 72 65  ce $f.  }.  fore
16c0: 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63  ach f [glob -noc
16d0: 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2d  omplain test.db-
16e0: 6d 6a 2a 5d 20 7b 0a 20 20 20 20 66 69 6c 65 20  mj*] {.    file 
16f0: 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 24 66  delete -force $f
1700: 0a 20 20 7d 0a 20 20 65 78 69 74 20 5b 65 78 70  .  }.  exit [exp
1710: 72 20 7b 24 6e 45 72 72 3e 30 7d 5d 0a 7d 0a 0a  r {$nErr>0}].}..
1720: 23 20 41 20 70 72 6f 63 65 64 75 72 65 20 74 6f  # A procedure to
1730: 20 65 78 65 63 75 74 65 20 53 51 4c 0a 23 0a 70   execute SQL.#.p
1740: 72 6f 63 20 65 78 65 63 73 71 6c 20 7b 73 71 6c  roc execsql {sql
1750: 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 23 20   {db db}} {.  # 
1760: 70 75 74 73 20 22 53 51 4c 20 3d 20 24 73 71 6c  puts "SQL = $sql
1770: 22 0a 20 20 75 70 6c 65 76 65 6c 20 5b 6c 69 73  ".  uplevel [lis
1780: 74 20 24 64 62 20 65 76 61 6c 20 24 73 71 6c 5d  t $db eval $sql]
1790: 0a 7d 0a 0a 23 20 45 78 65 63 75 74 65 20 53 51  .}..# Execute SQ
17a0: 4c 20 61 6e 64 20 63 61 74 63 68 20 65 78 63 65  L and catch exce
17b0: 70 74 69 6f 6e 73 2e 0a 23 0a 70 72 6f 63 20 63  ptions..#.proc c
17c0: 61 74 63 68 73 71 6c 20 7b 73 71 6c 20 7b 64 62  atchsql {sql {db
17d0: 20 64 62 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73   db}} {.  # puts
17e0: 20 22 53 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20   "SQL = $sql".  
17f0: 73 65 74 20 72 20 5b 63 61 74 63 68 20 7b 24 64  set r [catch {$d
1800: 62 20 65 76 61 6c 20 24 73 71 6c 7d 20 6d 73 67  b eval $sql} msg
1810: 5d 0a 20 20 6c 61 70 70 65 6e 64 20 72 20 24 6d  ].  lappend r $m
1820: 73 67 0a 20 20 72 65 74 75 72 6e 20 24 72 0a 7d  sg.  return $r.}
1830: 0a 0a 23 20 44 6f 20 61 6e 20 56 44 42 45 20 63  ..# Do an VDBE c
1840: 6f 64 65 20 64 75 6d 70 20 6f 6e 20 74 68 65 20  ode dump on the 
1850: 53 51 4c 20 67 69 76 65 6e 0a 23 0a 70 72 6f 63  SQL given.#.proc
1860: 20 65 78 70 6c 61 69 6e 20 7b 73 71 6c 20 7b 64   explain {sql {d
1870: 62 20 64 62 7d 7d 20 7b 0a 20 20 70 75 74 73 20  b db}} {.  puts 
1880: 22 22 0a 20 20 70 75 74 73 20 22 61 64 64 72 20  "".  puts "addr 
1890: 20 6f 70 63 6f 64 65 20 20 20 20 20 20 20 20 70   opcode        p
18a0: 31 20 20 20 20 20 20 20 70 32 20 20 20 20 20 70  1       p2     p
18b0: 33 20 20 20 20 20 20 20 20 20 20 20 20 20 22 0a  3             ".
18c0: 20 20 70 75 74 73 20 22 2d 2d 2d 2d 20 20 2d 2d    puts "----  --
18d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d  ----------  ----
18e0: 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d  --  ------  ----
18f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 22 0a 20 20 24  -----------".  $
1900: 64 62 20 65 76 61 6c 20 22 65 78 70 6c 61 69 6e  db eval "explain
1910: 20 24 73 71 6c 22 20 7b 7d 20 7b 0a 20 20 20 20   $sql" {} {.    
1920: 70 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25 2d  puts [format {%-
1930: 34 64 20 20 25 2d 31 32 2e 31 32 73 20 20 25 2d  4d  %-12.12s  %-
1940: 36 64 20 20 25 2d 36 64 20 20 25 73 7d 20 24 61  6d  %-6d  %s} $a
1950: 64 64 72 20 24 6f 70 63 6f 64 65 20 24 70 31 20  ddr $opcode $p1 
1960: 24 70 32 20 24 70 33 5d 0a 20 20 7d 0a 7d 0a 0a  $p2 $p3].  }.}..
1970: 23 20 41 6e 6f 74 68 65 72 20 70 72 6f 63 65 64  # Another proced
1980: 75 72 65 20 74 6f 20 65 78 65 63 75 74 65 20 53  ure to execute S
1990: 51 4c 2e 20 20 54 68 69 73 20 6f 6e 65 20 69 6e  QL.  This one in
19a0: 63 6c 75 64 65 73 20 74 68 65 20 66 69 65 6c 64  cludes the field
19b0: 0a 23 20 6e 61 6d 65 73 20 69 6e 20 74 68 65 20  .# names in the 
19c0: 72 65 74 75 72 6e 65 64 20 6c 69 73 74 2e 0a 23  returned list..#
19d0: 0a 70 72 6f 63 20 65 78 65 63 73 71 6c 32 20 7b  .proc execsql2 {
19e0: 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 72 65 73  sql} {.  set res
19f0: 75 6c 74 20 7b 7d 0a 20 20 64 62 20 65 76 61 6c  ult {}.  db eval
1a00: 20 24 73 71 6c 20 64 61 74 61 20 7b 0a 20 20 20   $sql data {.   
1a10: 20 66 6f 72 65 61 63 68 20 66 20 24 64 61 74 61   foreach f $data
1a20: 28 2a 29 20 7b 0a 20 20 20 20 20 20 6c 61 70 70  (*) {.      lapp
1a30: 65 6e 64 20 72 65 73 75 6c 74 20 24 66 20 24 64  end result $f $d
1a40: 61 74 61 28 24 66 29 0a 20 20 20 20 7d 0a 20 20  ata($f).    }.  
1a50: 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 65 73 75  }.  return $resu
1a60: 6c 74 0a 7d 0a 0a 23 20 55 73 65 20 74 68 65 20  lt.}..# Use the 
1a70: 6e 6f 6e 2d 63 61 6c 6c 62 61 63 6b 20 41 50 49  non-callback API
1a80: 20 74 6f 20 65 78 65 63 75 74 65 20 6d 75 6c 74   to execute mult
1a90: 69 70 6c 65 20 53 51 4c 20 73 74 61 74 65 6d 65  iple SQL stateme
1aa0: 6e 74 73 0a 23 0a 70 72 6f 63 20 73 74 65 70 73  nts.#.proc steps
1ab0: 71 6c 20 7b 64 62 70 74 72 20 73 71 6c 7d 20 7b  ql {dbptr sql} {
1ac0: 0a 20 20 73 65 74 20 73 71 6c 20 5b 73 74 72 69  .  set sql [stri
1ad0: 6e 67 20 74 72 69 6d 20 24 73 71 6c 5d 0a 20 20  ng trim $sql].  
1ae0: 73 65 74 20 72 20 30 0a 20 20 77 68 69 6c 65 20  set r 0.  while 
1af0: 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20  {[string length 
1b00: 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20 69  $sql]>0} {.    i
1b10: 66 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74  f {[catch {sqlit
1b20: 65 33 5f 70 72 65 70 61 72 65 20 24 64 62 70 74  e3_prepare $dbpt
1b30: 72 20 24 73 71 6c 20 2d 31 20 73 71 6c 74 61 69  r $sql -1 sqltai
1b40: 6c 7d 20 76 6d 5d 7d 20 7b 0a 20 20 20 20 20 20  l} vm]} {.      
1b50: 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31 20 24  return [list 1 $
1b60: 76 6d 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73 65  vm].    }.    se
1b70: 74 20 73 71 6c 20 5b 73 74 72 69 6e 67 20 74 72  t sql [string tr
1b80: 69 6d 20 24 73 71 6c 74 61 69 6c 5d 0a 23 20 20  im $sqltail].#  
1b90: 20 20 77 68 69 6c 65 20 7b 5b 73 71 6c 69 74 65    while {[sqlite
1ba0: 5f 73 74 65 70 20 24 76 6d 20 4e 20 56 41 4c 20  _step $vm N VAL 
1bb0: 43 4f 4c 5d 3d 3d 22 53 51 4c 49 54 45 5f 52 4f  COL]=="SQLITE_RO
1bc0: 57 22 7d 20 7b 0a 23 20 20 20 20 20 20 66 6f 72  W"} {.#      for
1bd0: 65 61 63 68 20 76 20 24 56 41 4c 20 7b 6c 61 70  each v $VAL {lap
1be0: 70 65 6e 64 20 72 20 24 76 7d 0a 23 20 20 20 20  pend r $v}.#    
1bf0: 7d 0a 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 71  }.    while {[sq
1c00: 6c 69 74 65 33 5f 73 74 65 70 20 24 76 6d 5d 3d  lite3_step $vm]=
1c10: 3d 22 53 51 4c 49 54 45 5f 52 4f 57 22 7d 20 7b  ="SQLITE_ROW"} {
1c20: 0a 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20  .      for {set 
1c30: 69 20 30 7d 20 7b 24 69 3c 5b 73 71 6c 69 74 65  i 0} {$i<[sqlite
1c40: 33 5f 64 61 74 61 5f 63 6f 75 6e 74 20 24 76 6d  3_data_count $vm
1c50: 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  ]} {incr i} {.  
1c60: 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20 72 20        lappend r 
1c70: 5b 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f  [sqlite3_column_
1c80: 74 65 78 74 20 24 76 6d 20 24 69 5d 0a 20 20 20  text $vm $i].   
1c90: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
1ca0: 66 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74  f {[catch {sqlit
1cb0: 65 33 5f 66 69 6e 61 6c 69 7a 65 20 24 76 6d 7d  e3_finalize $vm}
1cc0: 20 65 72 72 6d 73 67 5d 7d 20 7b 0a 20 20 20 20   errmsg]} {.    
1cd0: 20 20 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31    return [list 1
1ce0: 20 24 65 72 72 6d 73 67 5d 0a 20 20 20 20 7d 0a   $errmsg].    }.
1cf0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 0a    }.  return $r.
1d00: 7d 0a 0a 23 20 44 65 6c 65 74 65 20 61 20 66 69  }..# Delete a fi
1d10: 6c 65 20 6f 72 20 64 69 72 65 63 74 6f 72 79 0a  le or directory.
1d20: 23 0a 70 72 6f 63 20 66 6f 72 63 65 64 65 6c 65  #.proc forcedele
1d30: 74 65 20 7b 66 69 6c 65 6e 61 6d 65 7d 20 7b 0a  te {filename} {.
1d40: 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 66 69    if {[catch {fi
1d50: 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65  le delete -force
1d60: 20 24 66 69 6c 65 6e 61 6d 65 7d 5d 7d 20 7b 0a   $filename}]} {.
1d70: 20 20 20 20 65 78 65 63 20 72 6d 20 2d 72 66 20      exec rm -rf 
1d80: 24 66 69 6c 65 6e 61 6d 65 0a 20 20 7d 0a 7d 0a  $filename.  }.}.
1d90: 0a 23 20 44 6f 20 61 6e 20 69 6e 74 65 67 72 69  .# Do an integri
1da0: 74 79 20 63 68 65 63 6b 20 6f 66 20 74 68 65 20  ty check of the 
1db0: 65 6e 74 69 72 65 20 64 61 74 61 62 61 73 65 0a  entire database.
1dc0: 23 0a 70 72 6f 63 20 69 6e 74 65 67 72 69 74 79  #.proc integrity
1dd0: 5f 63 68 65 63 6b 20 7b 6e 61 6d 65 7d 20 7b 0a  _check {name} {.
1de0: 20 20 69 66 63 61 70 61 62 6c 65 20 69 6e 74 65    ifcapable inte
1df0: 67 72 69 74 79 63 6b 20 7b 0a 20 20 20 20 64 6f  grityck {.    do
1e00: 5f 74 65 73 74 20 24 6e 61 6d 65 20 7b 0a 20 20  _test $name {.  
1e10: 20 20 20 20 65 78 65 63 73 71 6c 20 7b 50 52 41      execsql {PRA
1e20: 47 4d 41 20 69 6e 74 65 67 72 69 74 79 5f 63 68  GMA integrity_ch
1e30: 65 63 6b 7d 0a 20 20 20 20 7d 20 7b 6f 6b 7d 0a  eck}.    } {ok}.
1e40: 20 20 7d 0a 7d 0a 0a 23 20 45 76 61 6c 75 61 74    }.}..# Evaluat
1e50: 65 20 61 20 62 6f 6f 6c 65 61 6e 20 65 78 70 72  e a boolean expr
1e60: 65 73 73 69 6f 6e 20 6f 66 20 63 61 70 61 62 69  ession of capabi
1e70: 6c 69 74 69 65 73 2e 20 20 49 66 20 74 72 75 65  lities.  If true
1e80: 2c 20 65 78 65 63 75 74 65 20 74 68 65 0a 23 20  , execute the.# 
1e90: 63 6f 64 65 2e 20 20 4f 6d 69 74 20 74 68 65 20  code.  Omit the 
1ea0: 63 6f 64 65 20 69 66 20 66 61 6c 73 65 2e 0a 23  code if false..#
1eb0: 0a 70 72 6f 63 20 69 66 63 61 70 61 62 6c 65 20  .proc ifcapable 
1ec0: 7b 65 78 70 72 20 63 6f 64 65 20 7b 65 6c 73 65  {expr code {else
1ed0: 20 22 22 7d 20 7b 65 6c 73 65 63 6f 64 65 20 22   ""} {elsecode "
1ee0: 22 7d 7d 20 7b 0a 20 20 72 65 67 73 75 62 20 2d  "}} {.  regsub -
1ef0: 61 6c 6c 20 7b 5b 61 2d 7a 5f 30 2d 39 5d 2b 7d  all {[a-z_0-9]+}
1f00: 20 24 65 78 70 72 20 7b 24 3a 3a 73 71 6c 69 74   $expr {$::sqlit
1f10: 65 5f 6f 70 74 69 6f 6e 73 28 26 29 7d 20 65 32  e_options(&)} e2
1f20: 0a 20 20 69 66 20 28 24 65 32 29 20 7b 0a 20 20  .  if ($e2) {.  
1f30: 20 20 73 65 74 20 63 20 5b 63 61 74 63 68 20 7b    set c [catch {
1f40: 75 70 6c 65 76 65 6c 20 31 20 24 63 6f 64 65 7d  uplevel 1 $code}
1f50: 20 72 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20   r].  } else {. 
1f60: 20 20 20 73 65 74 20 63 20 5b 63 61 74 63 68 20     set c [catch 
1f70: 7b 75 70 6c 65 76 65 6c 20 31 20 24 65 6c 73 65  {uplevel 1 $else
1f80: 63 6f 64 65 7d 20 72 5d 0a 20 20 7d 0a 20 20 72  code} r].  }.  r
1f90: 65 74 75 72 6e 20 2d 63 6f 64 65 20 24 63 20 24  eturn -code $c $
1fa0: 72 0a 7d 0a 0a 23 20 54 68 69 73 20 70 72 6f 63  r.}..# This proc
1fb0: 20 65 78 65 63 73 20 61 20 73 65 70 65 72 61 74   execs a seperat
1fc0: 65 20 70 72 6f 63 65 73 73 20 74 68 61 74 20 63  e process that c
1fd0: 72 61 73 68 65 73 20 6d 69 64 77 61 79 20 74 68  rashes midway th
1fe0: 72 6f 75 67 68 20 65 78 65 63 75 74 69 6e 67 0a  rough executing.
1ff0: 23 20 74 68 65 20 53 51 4c 20 73 63 72 69 70 74  # the SQL script
2000: 20 24 73 71 6c 20 6f 6e 20 64 61 74 61 62 61 73   $sql on databas
2010: 65 20 74 65 73 74 2e 64 62 2e 0a 23 0a 23 20 54  e test.db..#.# T
2020: 68 65 20 63 72 61 73 68 20 6f 63 63 75 72 73 20  he crash occurs 
2030: 64 75 72 69 6e 67 20 61 20 73 79 6e 63 28 29 20  during a sync() 
2040: 6f 66 20 66 69 6c 65 20 24 63 72 61 73 68 66 69  of file $crashfi
2050: 6c 65 2e 20 57 68 65 6e 20 74 68 65 20 63 72 61  le. When the cra
2060: 73 68 0a 23 20 6f 63 63 75 72 73 20 61 20 72 61  sh.# occurs a ra
2070: 6e 64 6f 6d 20 73 75 62 73 65 74 20 6f 66 20 61  ndom subset of a
2080: 6c 6c 20 75 6e 73 79 6e 63 65 64 20 77 72 69 74  ll unsynced writ
2090: 65 73 20 6d 61 64 65 20 62 79 20 74 68 65 20 70  es made by the p
20a0: 72 6f 63 65 73 73 20 61 72 65 0a 23 20 77 72 69  rocess are.# wri
20b0: 74 74 65 6e 20 69 6e 74 6f 20 74 68 65 20 66 69  tten into the fi
20c0: 6c 65 73 20 6f 6e 20 64 69 73 6b 2e 20 41 72 67  les on disk. Arg
20d0: 75 6d 65 6e 74 20 24 63 72 61 73 68 64 65 6c 61  ument $crashdela
20e0: 79 20 69 6e 64 69 63 61 74 65 73 20 74 68 65 0a  y indicates the.
20f0: 23 20 6e 75 6d 62 65 72 20 6f 66 20 66 69 6c 65  # number of file
2100: 20 73 79 6e 63 73 20 74 6f 20 77 61 69 74 20 62   syncs to wait b
2110: 65 66 6f 72 65 20 63 72 61 73 68 69 6e 67 2e 0a  efore crashing..
2120: 23 0a 23 20 54 68 65 20 72 65 74 75 72 6e 20 76  #.# The return v
2130: 61 6c 75 65 20 69 73 20 61 20 6c 69 73 74 20 6f  alue is a list o
2140: 66 20 74 77 6f 20 65 6c 65 6d 65 6e 74 73 2e 20  f two elements. 
2150: 54 68 65 20 66 69 72 73 74 20 65 6c 65 6d 65 6e  The first elemen
2160: 74 20 69 73 20 61 0a 23 20 62 6f 6f 6c 65 61 6e  t is a.# boolean
2170: 2c 20 69 6e 64 69 63 61 74 69 6e 67 20 77 68 65  , indicating whe
2180: 74 68 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20  ther or not the 
2190: 70 72 6f 63 65 73 73 20 61 63 74 75 61 6c 6c 79  process actually
21a0: 20 63 72 61 73 68 65 64 20 6f 72 0a 23 20 72 65   crashed or.# re
21b0: 70 6f 72 74 65 64 20 73 6f 6d 65 20 6f 74 68 65  ported some othe
21c0: 72 20 65 72 72 6f 72 2e 20 54 68 65 20 73 65 63  r error. The sec
21d0: 6f 6e 64 20 65 6c 65 6d 65 6e 74 20 69 6e 20 74  ond element in t
21e0: 68 65 20 72 65 74 75 72 6e 65 64 20 6c 69 73 74  he returned list
21f0: 20 69 73 20 74 68 65 0a 23 20 65 72 72 6f 72 20   is the.# error 
2200: 6d 65 73 73 61 67 65 2e 20 54 68 69 73 20 69 73  message. This is
2210: 20 22 63 68 69 6c 64 20 70 72 6f 63 65 73 73 20   "child process 
2220: 65 78 69 74 65 64 20 61 62 6e 6f 72 6d 61 6c 6c  exited abnormall
2230: 79 22 20 69 66 20 74 68 65 20 63 72 61 73 68 0a  y" if the crash.
2240: 23 20 6f 63 63 75 72 65 64 2e 0a 23 0a 23 20 20  # occured..#.#  
2250: 20 63 72 61 73 68 73 71 6c 20 2d 64 65 6c 61 79   crashsql -delay
2260: 20 43 52 41 53 48 44 45 4c 41 59 20 2d 66 69 6c   CRASHDELAY -fil
2270: 65 20 43 52 41 53 48 46 49 4c 45 20 3f 2d 62 6c  e CRASHFILE ?-bl
2280: 6f 63 6b 73 69 7a 65 20 42 4c 4f 43 4b 53 49 5a  ocksize BLOCKSIZ
2290: 45 20 24 73 71 6c 0a 23 0a 70 72 6f 63 20 63 72  E $sql.#.proc cr
22a0: 61 73 68 73 71 6c 20 7b 61 72 67 73 7d 20 7b 0a  ashsql {args} {.
22b0: 20 20 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61    if {$::tcl_pla
22c0: 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 21  tform(platform)!
22d0: 3d 22 75 6e 69 78 22 7d 20 7b 0a 20 20 20 20 65  ="unix"} {.    e
22e0: 72 72 6f 72 20 22 63 72 61 73 68 73 71 6c 20 73  rror "crashsql s
22f0: 68 6f 75 6c 64 20 6f 6e 6c 79 20 62 65 20 75 73  hould only be us
2300: 65 64 20 6f 6e 20 75 6e 69 78 22 0a 20 20 7d 0a  ed on unix".  }.
2310: 0a 20 20 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65  .  set blocksize
2320: 20 22 22 0a 20 20 73 65 74 20 63 72 61 73 68 64   "".  set crashd
2330: 65 6c 61 79 20 31 0a 20 20 73 65 74 20 63 72 61  elay 1.  set cra
2340: 73 68 66 69 6c 65 20 22 22 0a 20 20 73 65 74 20  shfile "".  set 
2350: 73 71 6c 20 5b 6c 69 6e 64 65 78 20 24 61 72 67  sql [lindex $arg
2360: 73 20 65 6e 64 5d 0a 20 20 0a 20 20 66 6f 72 20  s end].  .  for 
2370: 7b 73 65 74 20 69 69 20 30 7d 20 7b 24 69 69 20  {set ii 0} {$ii 
2380: 3c 20 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73  < [llength $args
2390: 5d 2d 31 7d 20 7b 69 6e 63 72 20 69 69 20 32 7d  ]-1} {incr ii 2}
23a0: 20 7b 0a 20 20 20 20 73 65 74 20 7a 20 5b 6c 69   {.    set z [li
23b0: 6e 64 65 78 20 24 61 72 67 73 20 24 69 69 5d 0a  ndex $args $ii].
23c0: 20 20 20 20 73 65 74 20 6e 20 5b 73 74 72 69 6e      set n [strin
23d0: 67 20 6c 65 6e 67 74 68 20 24 7a 5d 0a 20 20 20  g length $z].   
23e0: 20 73 65 74 20 7a 32 20 5b 6c 69 6e 64 65 78 20   set z2 [lindex 
23f0: 24 61 72 67 73 20 5b 65 78 70 72 20 24 69 69 2b  $args [expr $ii+
2400: 31 5d 5d 0a 0a 20 20 20 20 69 66 20 20 20 20 20  1]]..    if     
2410: 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67  {$n>1 && [string
2420: 20 66 69 72 73 74 20 24 7a 20 2d 64 65 6c 61 79   first $z -delay
2430: 5d 3d 3d 30 7d 20 20 20 20 20 7b 73 65 74 20 63  ]==0}     {set c
2440: 72 61 73 68 64 65 6c 61 79 20 24 7a 32 7d 20 5c  rashdelay $z2} \
2450: 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e  .    elseif {$n>
2460: 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72  1 && [string fir
2470: 73 74 20 24 7a 20 2d 66 69 6c 65 5d 3d 3d 30 7d  st $z -file]==0}
2480: 20 20 20 20 20 20 7b 73 65 74 20 63 72 61 73 68        {set crash
2490: 66 69 6c 65 20 24 7a 32 7d 20 20 5c 0a 20 20 20  file $z2}  \.   
24a0: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26   elseif {$n>1 &&
24b0: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
24c0: 7a 20 2d 62 6c 6f 63 6b 73 69 7a 65 5d 3d 3d 30  z -blocksize]==0
24d0: 7d 20 7b 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65  } {set blocksize
24e0: 20 24 7a 32 7d 20 20 5c 0a 20 20 20 20 65 6c 73   $z2}  \.    els
24f0: 65 20 20 20 7b 20 65 72 72 6f 72 20 22 55 6e 72  e   { error "Unr
2500: 65 63 6f 67 6e 69 7a 65 64 20 6f 70 74 69 6f 6e  ecognized option
2510: 3a 20 24 7a 22 20 7d 0a 20 20 7d 0a 0a 20 20 69  : $z" }.  }..  i
2520: 66 20 7b 24 63 72 61 73 68 66 69 6c 65 20 65 71  f {$crashfile eq
2530: 20 22 22 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72   ""} {.    error
2540: 20 22 43 6f 6d 70 75 6c 73 6f 72 79 20 6f 70 74   "Compulsory opt
2550: 69 6f 6e 20 2d 66 69 6c 65 20 6d 69 73 73 69 6e  ion -file missin
2560: 67 22 0a 20 20 7d 0a 0a 20 20 73 65 74 20 63 66  g".  }..  set cf
2570: 69 6c 65 20 5b 66 69 6c 65 20 6a 6f 69 6e 20 5b  ile [file join [
2580: 70 77 64 5d 20 24 63 72 61 73 68 66 69 6c 65 5d  pwd] $crashfile]
2590: 0a 0a 20 20 73 65 74 20 66 20 5b 6f 70 65 6e 20  ..  set f [open 
25a0: 63 72 61 73 68 2e 74 63 6c 20 77 5d 0a 20 20 70  crash.tcl w].  p
25b0: 75 74 73 20 24 66 20 22 73 71 6c 69 74 65 33 5f  uts $f "sqlite3_
25c0: 63 72 61 73 68 70 61 72 61 6d 73 20 24 63 72 61  crashparams $cra
25d0: 73 68 64 65 6c 61 79 20 24 63 66 69 6c 65 20 24  shdelay $cfile $
25e0: 62 6c 6f 63 6b 73 69 7a 65 22 0a 20 20 70 75 74  blocksize".  put
25f0: 73 20 24 66 20 22 73 65 74 20 73 71 6c 69 74 65  s $f "set sqlite
2600: 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 20 24 3a  _pending_byte $:
2610: 3a 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67 5f  :sqlite_pending_
2620: 62 79 74 65 22 0a 20 20 70 75 74 73 20 24 66 20  byte".  puts $f 
2630: 22 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74  "sqlite3 db test
2640: 2e 64 62 22 0a 0a 20 20 23 20 54 68 69 73 20 62  .db"..  # This b
2650: 6c 6f 63 6b 20 73 65 74 73 20 74 68 65 20 63 61  lock sets the ca
2660: 63 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20  che size of the 
2670: 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 74 6f  main database to
2680: 20 31 30 0a 20 20 23 20 70 61 67 65 73 2e 20 54   10.  # pages. T
2690: 68 69 73 20 69 73 20 64 6f 6e 65 20 69 6e 20 63  his is done in c
26a0: 61 73 65 20 74 68 65 20 62 75 69 6c 64 20 69 73  ase the build is
26b0: 20 63 6f 6e 66 69 67 75 72 65 64 20 74 6f 20 6f   configured to o
26c0: 6d 69 74 0a 20 20 23 20 22 50 52 41 47 4d 41 20  mit.  # "PRAGMA 
26d0: 63 61 63 68 65 5f 73 69 7a 65 22 2e 0a 20 20 70  cache_size"..  p
26e0: 75 74 73 20 24 66 20 7b 64 62 20 65 76 61 6c 20  uts $f {db eval 
26f0: 7b 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 73  {SELECT * FROM s
2700: 71 6c 69 74 65 5f 6d 61 73 74 65 72 3b 7d 7d 0a  qlite_master;}}.
2710: 20 20 70 75 74 73 20 24 66 20 7b 73 65 74 20 62    puts $f {set b
2720: 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62  t [btree_from_db
2730: 20 64 62 5d 7d 0a 20 20 70 75 74 73 20 24 66 20   db]}.  puts $f 
2740: 7b 62 74 72 65 65 5f 73 65 74 5f 63 61 63 68 65  {btree_set_cache
2750: 5f 73 69 7a 65 20 24 62 74 20 31 30 7d 0a 0a 20  _size $bt 10}.. 
2760: 20 70 75 74 73 20 24 66 20 22 64 62 20 65 76 61   puts $f "db eva
2770: 6c 20 7b 22 0a 20 20 70 75 74 73 20 24 66 20 20  l {".  puts $f  
2780: 20 22 24 73 71 6c 22 0a 20 20 70 75 74 73 20 24   "$sql".  puts $
2790: 66 20 22 7d 22 0a 20 20 63 6c 6f 73 65 20 24 66  f "}".  close $f
27a0: 0a 0a 20 20 73 65 74 20 72 20 5b 63 61 74 63 68  ..  set r [catch
27b0: 20 7b 0a 20 20 20 20 65 78 65 63 20 5b 69 6e 66   {.    exec [inf
27c0: 6f 20 6e 61 6d 65 6f 66 65 78 65 63 5d 20 63 72  o nameofexec] cr
27d0: 61 73 68 2e 74 63 6c 20 3e 40 73 74 64 6f 75 74  ash.tcl >@stdout
27e0: 0a 20 20 7d 20 6d 73 67 5d 0a 20 20 6c 61 70 70  .  } msg].  lapp
27f0: 65 6e 64 20 72 20 24 6d 73 67 0a 7d 0a 0a 23 20  end r $msg.}..# 
2800: 55 73 61 67 65 3a 20 64 6f 5f 69 6f 65 72 72 5f  Usage: do_ioerr_
2810: 74 65 73 74 20 3c 74 65 73 74 20 6e 75 6d 62 65  test <test numbe
2820: 72 3e 20 3c 6f 70 74 69 6f 6e 73 2e 2e 2e 3e 0a  r> <options...>.
2830: 23 0a 23 20 54 68 69 73 20 70 72 6f 63 20 69 73  #.# This proc is
2840: 20 75 73 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65   used to impleme
2850: 6e 74 20 74 65 73 74 20 63 61 73 65 73 20 74 68  nt test cases th
2860: 61 74 20 63 68 65 63 6b 20 74 68 61 74 20 49 4f  at check that IO
2870: 20 65 72 72 6f 72 73 0a 23 20 61 72 65 20 63 6f   errors.# are co
2880: 72 72 65 63 74 6c 79 20 68 61 6e 64 6c 65 64 2e  rrectly handled.
2890: 20 54 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   The first argum
28a0: 65 6e 74 2c 20 3c 74 65 73 74 20 6e 75 6d 62 65  ent, <test numbe
28b0: 72 3e 2c 20 69 73 20 61 6e 20 69 6e 74 65 67 65  r>, is an intege
28c0: 72 20 0a 23 20 75 73 65 64 20 74 6f 20 6e 61 6d  r .# used to nam
28d0: 65 20 74 68 65 20 74 65 73 74 73 20 65 78 65 63  e the tests exec
28e0: 75 74 65 64 20 62 79 20 74 68 69 73 20 70 72 6f  uted by this pro
28f0: 63 2e 20 4f 70 74 69 6f 6e 73 20 61 72 65 20 61  c. Options are a
2900: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 23 0a 23 20 20  s follows:.#.#  
2910: 20 20 20 2d 74 63 6c 70 72 65 70 20 20 20 20 20     -tclprep     
2920: 20 20 20 20 20 54 43 4c 20 73 63 72 69 70 74 20       TCL script 
2930: 74 6f 20 72 75 6e 20 74 6f 20 70 72 65 70 61 72  to run to prepar
2940: 65 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d 73  e test..#     -s
2950: 71 6c 70 72 65 70 20 20 20 20 20 20 20 20 20 20  qlprep          
2960: 53 51 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75  SQL script to ru
2970: 6e 20 74 6f 20 70 72 65 70 61 72 65 20 74 65 73  n to prepare tes
2980: 74 2e 0a 23 20 20 20 20 20 2d 74 63 6c 62 6f 64  t..#     -tclbod
2990: 79 20 20 20 20 20 20 20 20 20 20 54 43 4c 20 73  y          TCL s
29a0: 63 72 69 70 74 20 74 6f 20 72 75 6e 20 77 69 74  cript to run wit
29b0: 68 20 49 4f 20 65 72 72 6f 72 20 73 69 6d 75 6c  h IO error simul
29c0: 61 74 69 6f 6e 2e 0a 23 20 20 20 20 20 2d 73 71  ation..#     -sq
29d0: 6c 62 6f 64 79 20 20 20 20 20 20 20 20 20 20 54  lbody          T
29e0: 43 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75 6e  CL script to run
29f0: 20 77 69 74 68 20 49 4f 20 65 72 72 6f 72 20 73   with IO error s
2a00: 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20 20 20 20  imulation..#    
2a10: 20 2d 65 78 63 6c 75 64 65 20 20 20 20 20 20 20   -exclude       
2a20: 20 20 20 4c 69 73 74 20 6f 66 20 27 4e 27 20 76     List of 'N' v
2a30: 61 6c 75 65 73 20 6e 6f 74 20 74 6f 20 74 65 73  alues not to tes
2a40: 74 2e 0a 23 20 20 20 20 20 2d 65 72 63 20 20 20  t..#     -erc   
2a50: 20 20 20 20 20 20 20 20 20 20 20 55 73 65 20 65             Use e
2a60: 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63  xtended result c
2a70: 6f 64 65 73 0a 23 20 20 20 20 20 2d 70 65 72 73  odes.#     -pers
2a80: 69 73 74 20 20 20 20 20 20 20 20 20 20 4d 61 6b  ist          Mak
2a90: 65 20 73 69 6d 75 6c 61 74 65 64 20 49 2f 4f 20  e simulated I/O 
2aa0: 65 72 72 6f 72 73 20 70 65 72 73 69 73 74 65 6e  errors persisten
2ab0: 74 0a 23 20 20 20 20 20 2d 73 74 61 72 74 20 20  t.#     -start  
2ac0: 20 20 20 20 20 20 20 20 20 20 56 61 6c 75 65 20            Value 
2ad0: 6f 66 20 27 4e 27 20 74 6f 20 62 65 67 69 6e 20  of 'N' to begin 
2ae0: 77 69 74 68 20 28 64 65 66 61 75 6c 74 20 31 29  with (default 1)
2af0: 0a 23 0a 23 20 20 20 20 20 2d 63 6b 73 75 6d 20  .#.#     -cksum 
2b00: 20 20 20 20 20 20 20 20 20 20 20 42 6f 6f 6c 65             Boole
2b10: 61 6e 2e 20 49 66 20 74 72 75 65 2c 20 74 65 73  an. If true, tes
2b20: 74 20 74 68 61 74 20 74 68 65 20 64 61 74 61 62  t that the datab
2b30: 61 73 65 20 64 6f 65 73 0a 23 20 20 20 20 20 20  ase does.#      
2b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2b50: 20 6e 6f 74 20 63 68 61 6e 67 65 20 64 75 72 69   not change duri
2b60: 6e 67 20 74 68 65 20 65 78 65 63 75 74 69 6f 6e  ng the execution
2b70: 20 6f 66 20 74 68 65 20 74 65 73 74 20 63 61 73   of the test cas
2b80: 65 2e 0a 23 0a 70 72 6f 63 20 64 6f 5f 69 6f 65  e..#.proc do_ioe
2b90: 72 72 5f 74 65 73 74 20 7b 74 65 73 74 6e 61 6d  rr_test {testnam
2ba0: 65 20 61 72 67 73 7d 20 7b 0a 0a 20 20 73 65 74  e args} {..  set
2bb0: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 74   ::ioerropts(-st
2bc0: 61 72 74 29 20 31 0a 20 20 73 65 74 20 3a 3a 69  art) 1.  set ::i
2bd0: 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29  oerropts(-cksum)
2be0: 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72   0.  set ::ioerr
2bf0: 6f 70 74 73 28 2d 65 72 63 29 20 30 0a 20 20 73  opts(-erc) 0.  s
2c00: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  et ::ioerropts(-
2c10: 63 6f 75 6e 74 29 20 31 30 30 30 30 30 30 30 30  count) 100000000
2c20: 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70  .  set ::ioerrop
2c30: 74 73 28 2d 70 65 72 73 69 73 74 29 20 31 0a 20  ts(-persist) 1. 
2c40: 20 61 72 72 61 79 20 73 65 74 20 3a 3a 69 6f 65   array set ::ioe
2c50: 72 72 6f 70 74 73 20 24 61 72 67 73 0a 0a 20 20  rropts $args..  
2c60: 73 65 74 20 3a 3a 67 6f 20 31 0a 20 20 66 6f 72  set ::go 1.  for
2c70: 20 7b 73 65 74 20 6e 20 24 3a 3a 69 6f 65 72 72   {set n $::ioerr
2c80: 6f 70 74 73 28 2d 73 74 61 72 74 29 7d 20 7b 24  opts(-start)} {$
2c90: 3a 3a 67 6f 7d 20 7b 69 6e 63 72 20 6e 7d 20 7b  ::go} {incr n} {
2ca0: 0a 73 65 74 20 3a 3a 54 4e 20 24 6e 0a 20 20 20  .set ::TN $n.   
2cb0: 20 69 6e 63 72 20 3a 3a 69 6f 65 72 72 6f 70 74   incr ::ioerropt
2cc0: 73 28 2d 63 6f 75 6e 74 29 20 2d 31 0a 20 20 20  s(-count) -1.   
2cd0: 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74   if {$::ioerropt
2ce0: 73 28 2d 63 6f 75 6e 74 29 3c 30 7d 20 62 72 65  s(-count)<0} bre
2cf0: 61 6b 0a 20 0a 20 20 20 20 23 20 53 6b 69 70 20  ak. .    # Skip 
2d00: 74 68 69 73 20 49 4f 20 65 72 72 6f 72 20 69 66  this IO error if
2d10: 20 69 74 20 77 61 73 20 73 70 65 63 69 66 69 65   it was specifie
2d20: 64 20 77 69 74 68 20 74 68 65 20 22 2d 65 78 63  d with the "-exc
2d30: 6c 75 64 65 22 20 6f 70 74 69 6f 6e 2e 0a 20 20  lude" option..  
2d40: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
2d50: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
2d60: 65 78 63 6c 75 64 65 29 5d 7d 20 7b 0a 20 20 20  exclude)]} {.   
2d70: 20 20 20 69 66 20 7b 5b 6c 73 65 61 72 63 68 20     if {[lsearch 
2d80: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 78  $::ioerropts(-ex
2d90: 63 6c 75 64 65 29 20 24 6e 5d 21 3d 2d 31 7d 20  clude) $n]!=-1} 
2da0: 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 7d 0a 0a  continue.    }..
2db0: 20 20 20 20 23 20 44 65 6c 65 74 65 20 74 68 65      # Delete the
2dc0: 20 66 69 6c 65 73 20 74 65 73 74 2e 64 62 20 61   files test.db a
2dd0: 6e 64 20 74 65 73 74 32 2e 64 62 2c 20 74 68 65  nd test2.db, the
2de0: 6e 20 65 78 65 63 75 74 65 20 74 68 65 20 54 43  n execute the TC
2df0: 4c 20 61 6e 64 20 0a 20 20 20 20 23 20 53 51 4c  L and .    # SQL
2e00: 20 28 69 6e 20 74 68 61 74 20 6f 72 64 65 72 29   (in that order)
2e10: 20 74 6f 20 70 72 65 70 61 72 65 20 66 6f 72 20   to prepare for 
2e20: 74 68 65 20 74 65 73 74 20 63 61 73 65 2e 0a 20  the test case.. 
2e30: 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74     do_test $test
2e40: 6e 61 6d 65 2e 24 6e 2e 31 20 7b 0a 20 20 20 20  name.$n.1 {.    
2e50: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
2e60: 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20  o_error_pending 
2e70: 30 0a 20 20 20 20 20 20 63 61 74 63 68 20 7b 64  0.      catch {d
2e80: 62 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20 63  b close}.      c
2e90: 61 74 63 68 20 7b 66 69 6c 65 20 64 65 6c 65 74  atch {file delet
2ea0: 65 20 2d 66 6f 72 63 65 20 74 65 73 74 2e 64 62  e -force test.db
2eb0: 7d 0a 20 20 20 20 20 20 63 61 74 63 68 20 7b 66  }.      catch {f
2ec0: 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63  ile delete -forc
2ed0: 65 20 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e 61  e test.db-journa
2ee0: 6c 7d 0a 20 20 20 20 20 20 63 61 74 63 68 20 7b  l}.      catch {
2ef0: 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72  file delete -for
2f00: 63 65 20 74 65 73 74 32 2e 64 62 7d 0a 20 20 20  ce test2.db}.   
2f10: 20 20 20 63 61 74 63 68 20 7b 66 69 6c 65 20 64     catch {file d
2f20: 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 74 65 73  elete -force tes
2f30: 74 32 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d 0a 20  t2.db-journal}. 
2f40: 20 20 20 20 20 73 65 74 20 3a 3a 44 42 20 5b 73       set ::DB [s
2f50: 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64  qlite3 db test.d
2f60: 62 3b 20 73 71 6c 69 74 65 33 5f 63 6f 6e 6e 65  b; sqlite3_conne
2f70: 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72 20 64 62  ction_pointer db
2f80: 5d 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ].      sqlite3_
2f90: 65 78 74 65 6e 64 65 64 5f 72 65 73 75 6c 74 5f  extended_result_
2fa0: 63 6f 64 65 73 20 24 3a 3a 44 42 20 24 3a 3a 69  codes $::DB $::i
2fb0: 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29 0a 20  oerropts(-erc). 
2fc0: 20 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65       if {[info e
2fd0: 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74  xists ::ioerropt
2fe0: 73 28 2d 74 63 6c 70 72 65 70 29 5d 7d 20 7b 0a  s(-tclprep)]} {.
2ff0: 20 20 20 20 20 20 20 20 65 76 61 6c 20 24 3a 3a          eval $::
3000: 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 70 72  ioerropts(-tclpr
3010: 65 70 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ep).      }.    
3020: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
3030: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
3040: 73 71 6c 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20  sqlprep)]} {.   
3050: 20 20 20 20 20 65 78 65 63 73 71 6c 20 24 3a 3a       execsql $::
3060: 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 70 72  ioerropts(-sqlpr
3070: 65 70 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ep).      }.    
3080: 20 20 65 78 70 72 20 30 0a 20 20 20 20 7d 20 7b    expr 0.    } {
3090: 30 7d 0a 0a 20 20 20 20 23 20 52 65 61 64 20 74  0}..    # Read t
30a0: 68 65 20 27 63 68 65 63 6b 73 75 6d 27 20 6f 66  he 'checksum' of
30b0: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 20   the database.. 
30c0: 20 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f     if {$::ioerro
30d0: 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20  pts(-cksum)} {. 
30e0: 20 20 20 20 20 73 65 74 20 63 68 65 63 6b 73 75       set checksu
30f0: 6d 20 5b 63 6b 73 75 6d 5d 0a 20 20 20 20 7d 0a  m [cksum].    }.
3100: 20 20 0a 20 20 20 20 23 20 53 65 74 20 74 68 65    .    # Set the
3110: 20 4e 74 68 20 49 4f 20 65 72 72 6f 72 20 74 6f   Nth IO error to
3120: 20 66 61 69 6c 2e 0a 20 20 20 20 64 6f 5f 74 65   fail..    do_te
3130: 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e  st $testname.$n.
3140: 32 20 5b 73 75 62 73 74 20 7b 0a 20 20 20 20 20  2 [subst {.     
3150: 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f   set ::sqlite_io
3160: 5f 65 72 72 6f 72 5f 70 65 72 73 69 73 74 20 24  _error_persist $
3170: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 70 65 72  ::ioerropts(-per
3180: 73 69 73 74 29 0a 20 20 20 20 20 20 73 65 74 20  sist).      set 
3190: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
31a0: 72 5f 70 65 6e 64 69 6e 67 20 24 6e 0a 20 20 20  r_pending $n.   
31b0: 20 7d 5d 20 24 6e 0a 20 20 0a 20 20 20 20 23 20   }] $n.  .    # 
31c0: 43 72 65 61 74 65 20 61 20 73 69 6e 67 6c 65 20  Create a single 
31d0: 54 43 4c 20 73 63 72 69 70 74 20 66 72 6f 6d 20  TCL script from 
31e0: 74 68 65 20 54 43 4c 20 61 6e 64 20 53 51 4c 20  the TCL and SQL 
31f0: 73 70 65 63 69 66 69 65 64 0a 20 20 20 20 23 20  specified.    # 
3200: 61 73 20 74 68 65 20 62 6f 64 79 20 6f 66 20 74  as the body of t
3210: 68 65 20 74 65 73 74 2e 0a 20 20 20 20 73 65 74  he test..    set
3220: 20 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 7b   ::ioerrorbody {
3230: 7d 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20  }.    if {[info 
3240: 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70  exists ::ioerrop
3250: 74 73 28 2d 74 63 6c 62 6f 64 79 29 5d 7d 20 7b  ts(-tclbody)]} {
3260: 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20 3a 3a  .      append ::
3270: 69 6f 65 72 72 6f 72 62 6f 64 79 20 22 24 3a 3a  ioerrorbody "$::
3280: 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 62 6f  ioerropts(-tclbo
3290: 64 79 29 5c 6e 22 0a 20 20 20 20 7d 0a 20 20 20  dy)\n".    }.   
32a0: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
32b0: 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73  s ::ioerropts(-s
32c0: 71 6c 62 6f 64 79 29 5d 7d 20 7b 0a 20 20 20 20  qlbody)]} {.    
32d0: 20 20 61 70 70 65 6e 64 20 3a 3a 69 6f 65 72 72    append ::ioerr
32e0: 6f 72 62 6f 64 79 20 22 64 62 20 65 76 61 6c 20  orbody "db eval 
32f0: 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73  {$::ioerropts(-s
3300: 71 6c 62 6f 64 79 29 7d 22 0a 20 20 20 20 7d 0a  qlbody)}".    }.
3310: 0a 20 20 20 20 23 20 45 78 65 63 75 74 65 20 74  .    # Execute t
3320: 68 65 20 54 43 4c 20 53 63 72 69 70 74 20 63 72  he TCL Script cr
3330: 65 61 74 65 64 20 69 6e 20 74 68 65 20 61 62 6f  eated in the abo
3340: 76 65 20 62 6c 6f 63 6b 2e 20 49 66 0a 20 20 20  ve block. If.   
3350: 20 23 20 74 68 65 72 65 20 61 72 65 20 61 74 20   # there are at 
3360: 6c 65 61 73 74 20 4e 20 49 4f 20 6f 70 65 72 61  least N IO opera
3370: 74 69 6f 6e 73 20 70 65 72 66 6f 72 6d 65 64 20  tions performed 
3380: 62 79 20 53 51 4c 69 74 65 20 61 73 0a 20 20 20  by SQLite as.   
3390: 20 23 20 61 20 72 65 73 75 6c 74 20 6f 66 20 74   # a result of t
33a0: 68 65 20 73 63 72 69 70 74 2c 20 74 68 65 20 4e  he script, the N
33b0: 74 68 20 77 69 6c 6c 20 66 61 69 6c 2e 0a 20 20  th will fail..  
33c0: 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e    do_test $testn
33d0: 61 6d 65 2e 24 6e 2e 33 20 7b 0a 20 20 20 20 20  ame.$n.3 {.     
33e0: 20 73 65 74 20 72 20 5b 63 61 74 63 68 20 24 3a   set r [catch $:
33f0: 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 6d 73 67  :ioerrorbody msg
3400: 5d 0a 20 20 20 20 20 20 73 65 74 20 72 63 20 5b  ].      set rc [
3410: 73 71 6c 69 74 65 33 5f 65 72 72 63 6f 64 65 20  sqlite3_errcode 
3420: 24 3a 3a 44 42 5d 0a 20 20 20 20 20 20 69 66 20  $::DB].      if 
3430: 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65  {$::ioerropts(-e
3440: 72 63 29 7d 20 7b 0a 20 20 20 20 20 20 20 20 23  rc)} {.        #
3450: 20 49 66 20 77 65 20 61 72 65 20 69 6e 20 65 78   If we are in ex
3460: 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f  tended result co
3470: 64 65 20 6d 6f 64 65 2c 20 6d 61 6b 65 20 73 75  de mode, make su
3480: 72 65 20 61 6c 6c 20 6f 66 20 74 68 65 0a 20 20  re all of the.  
3490: 20 20 20 20 20 20 23 20 49 4f 45 52 52 73 20 77        # IOERRs w
34a0: 65 20 67 65 74 20 62 61 63 6b 20 72 65 61 6c 6c  e get back reall
34b0: 79 20 64 6f 20 68 61 76 65 20 74 68 65 69 72 20  y do have their 
34c0: 65 78 74 65 6e 64 65 64 20 63 6f 64 65 20 76 61  extended code va
34d0: 6c 75 65 73 2e 0a 20 20 20 20 20 20 20 20 23 20  lues..        # 
34e0: 49 66 20 61 6e 20 65 78 74 65 6e 64 65 64 20 72  If an extended r
34f0: 65 73 75 6c 74 20 63 6f 64 65 20 69 73 20 72 65  esult code is re
3500: 74 75 72 6e 65 64 2c 20 74 68 65 20 73 71 6c 69  turned, the sqli
3510: 74 65 33 5f 65 72 72 63 6f 64 65 0a 20 20 20 20  te3_errcode.    
3520: 20 20 20 20 23 20 54 43 4c 63 6f 6d 6d 61 6e 64      # TCLcommand
3530: 20 77 69 6c 6c 20 72 65 74 75 72 6e 20 61 20 73   will return a s
3540: 74 72 69 6e 67 20 6f 66 20 74 68 65 20 66 6f 72  tring of the for
3550: 6d 3a 20 20 53 51 4c 49 54 45 5f 49 4f 45 52 52  m:  SQLITE_IOERR
3560: 2b 6e 6e 6e 6e 0a 20 20 20 20 20 20 20 20 23 20  +nnnn.        # 
3570: 77 68 65 72 65 20 6e 6e 6e 6e 20 69 73 20 61 20  where nnnn is a 
3580: 6e 75 6d 62 65 72 0a 20 20 20 20 20 20 20 20 69  number.        i
3590: 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e 53 51 4c  f {[regexp {^SQL
35a0: 49 54 45 5f 49 4f 45 52 52 7d 20 24 72 63 5d 20  ITE_IOERR} $rc] 
35b0: 26 26 20 21 5b 72 65 67 65 78 70 20 7b 49 4f 45  && ![regexp {IOE
35c0: 52 52 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a  RR\+\d} $rc]} {.
35d0: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
35e0: 20 24 72 63 0a 20 20 20 20 20 20 20 20 7d 0a 20   $rc.        }. 
35f0: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
3600: 20 20 20 20 20 20 23 20 49 66 20 77 65 20 61 72        # If we ar
3610: 65 20 6e 6f 74 20 69 6e 20 65 78 74 65 6e 64 65  e not in extende
3620: 64 20 72 65 73 75 6c 74 20 63 6f 64 65 20 6d 6f  d result code mo
3630: 64 65 2c 20 6d 61 6b 65 20 73 75 72 65 20 6e 6f  de, make sure no
3640: 0a 20 20 20 20 20 20 20 20 23 20 65 78 74 65 6e  .        # exten
3650: 64 65 64 20 65 72 72 6f 72 20 63 6f 64 65 73 20  ded error codes 
3660: 61 72 65 20 72 65 74 75 72 6e 65 64 2e 0a 20 20  are returned..  
3670: 20 20 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78        if {[regex
3680: 70 20 7b 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b  p {\+\d} $rc]} {
3690: 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72  .          retur
36a0: 6e 20 24 72 63 0a 20 20 20 20 20 20 20 20 7d 0a  n $rc.        }.
36b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 23 20        }.      # 
36c0: 54 68 65 20 74 65 73 74 20 72 65 70 65 61 74 73  The test repeats
36d0: 20 61 73 20 6c 6f 6e 67 20 61 73 20 24 3a 3a 67   as long as $::g
36e0: 6f 20 69 73 20 74 72 75 65 2e 20 20 0a 20 20 20  o is true.  .   
36f0: 20 20 20 73 65 74 20 3a 3a 67 6f 20 5b 65 78 70     set ::go [exp
3700: 72 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  r {$::sqlite_io_
3710: 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 3c 3d 30  error_pending<=0
3720: 7d 5d 0a 20 20 20 20 20 20 73 65 74 20 73 20 5b  }].      set s [
3730: 65 78 70 72 20 24 3a 3a 73 71 6c 69 74 65 5f 69  expr $::sqlite_i
3740: 6f 5f 65 72 72 6f 72 5f 68 69 74 3d 3d 30 5d 0a  o_error_hit==0].
3750: 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69        set ::sqli
3760: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 20  te_io_error_hit 
3770: 30 0a 0a 20 20 20 20 20 20 23 20 4f 6e 65 20 6f  0..      # One o
3780: 66 20 74 77 6f 20 74 68 69 6e 67 73 20 6d 75 73  f two things mus
3790: 74 20 68 61 76 65 20 68 61 70 70 65 6e 65 64 2e  t have happened.
37a0: 20 65 69 74 68 65 72 0a 20 20 20 20 20 20 23 20   either.      # 
37b0: 20 20 31 2e 20 20 57 65 20 6e 65 76 65 72 20 68    1.  We never h
37c0: 69 74 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20  it the IO error 
37d0: 61 6e 64 20 74 68 65 20 53 51 4c 20 72 65 74 75  and the SQL retu
37e0: 72 6e 65 64 20 4f 4b 0a 20 20 20 20 20 20 23 20  rned OK.      # 
37f0: 20 20 32 2e 20 20 41 6e 20 49 4f 20 65 72 72 6f    2.  An IO erro
3800: 72 20 77 61 73 20 68 69 74 20 61 6e 64 20 74 68  r was hit and th
3810: 65 20 53 51 4c 20 66 61 69 6c 65 64 0a 20 20 20  e SQL failed.   
3820: 20 20 20 23 0a 20 20 20 20 20 20 65 78 70 72 20     #.      expr 
3830: 7b 20 28 24 73 20 26 26 20 21 24 72 20 26 26 20  { ($s && !$r && 
3840: 21 24 3a 3a 67 6f 29 20 7c 7c 20 28 21 24 73 20  !$::go) || (!$s 
3850: 26 26 20 24 72 20 26 26 20 24 3a 3a 67 6f 29 20  && $r && $::go) 
3860: 7d 0a 20 20 20 20 7d 20 7b 31 7d 0a 0a 20 20 20  }.    } {1}..   
3870: 20 23 20 49 66 20 61 6e 20 49 4f 20 65 72 72 6f   # If an IO erro
3880: 72 20 6f 63 63 75 72 65 64 2c 20 74 68 65 6e 20  r occured, then 
3890: 74 68 65 20 63 68 65 63 6b 73 75 6d 20 6f 66 20  the checksum of 
38a0: 74 68 65 20 64 61 74 61 62 61 73 65 20 73 68 6f  the database sho
38b0: 75 6c 64 0a 20 20 20 20 23 20 62 65 20 74 68 65  uld.    # be the
38c0: 20 73 61 6d 65 20 61 73 20 62 65 66 6f 72 65 20   same as before 
38d0: 74 68 65 20 73 63 72 69 70 74 20 74 68 61 74 20  the script that 
38e0: 63 61 75 73 65 64 20 74 68 65 20 49 4f 20 65 72  caused the IO er
38f0: 72 6f 72 20 77 61 73 20 72 75 6e 2e 0a 20 20 20  ror was run..   
3900: 20 69 66 20 7b 24 3a 3a 67 6f 20 26 26 20 24 3a   if {$::go && $:
3910: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73 75  :ioerropts(-cksu
3920: 6d 29 7d 20 7b 0a 20 20 20 20 20 20 64 6f 5f 74  m)} {.      do_t
3930: 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e  est $testname.$n
3940: 2e 34 20 7b 0a 20 20 20 20 20 20 20 20 63 61 74  .4 {.        cat
3950: 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20  ch {db close}.  
3960: 20 20 20 20 20 20 73 65 74 20 3a 3a 44 42 20 5b        set ::DB [
3970: 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e  sqlite3 db test.
3980: 64 62 3b 20 73 71 6c 69 74 65 33 5f 63 6f 6e 6e  db; sqlite3_conn
3990: 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72 20 64  ection_pointer d
39a0: 62 5d 0a 20 20 20 20 20 20 20 20 63 6b 73 75 6d  b].        cksum
39b0: 0a 20 20 20 20 20 20 7d 20 24 63 68 65 63 6b 73  .      } $checks
39c0: 75 6d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 65  um.    }..    se
39d0: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
39e0: 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20  ror_pending 0.  
39f0: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
3a00: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
3a10: 63 6c 65 61 6e 75 70 29 5d 7d 20 7b 0a 20 20 20  cleanup)]} {.   
3a20: 20 20 20 63 61 74 63 68 20 24 3a 3a 69 6f 65 72     catch $::ioer
3a30: 72 6f 70 74 73 28 2d 63 6c 65 61 6e 75 70 29 0a  ropts(-cleanup).
3a40: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20      }.  }.  set 
3a50: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
3a60: 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20 73 65  r_pending 0.  se
3a70: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
3a80: 72 6f 72 5f 70 65 72 73 69 73 74 20 30 0a 20 20  ror_persist 0.  
3a90: 75 6e 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74  unset ::ioerropt
3aa0: 73 0a 7d 0a 0a 23 20 52 65 74 75 72 6e 20 61 20  s.}..# Return a 
3ab0: 63 68 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f  checksum based o
3ac0: 6e 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  n the contents o
3ad0: 66 20 64 61 74 61 62 61 73 65 20 27 64 62 27 2e  f database 'db'.
3ae0: 0a 23 0a 70 72 6f 63 20 63 6b 73 75 6d 20 7b 7b  .#.proc cksum {{
3af0: 64 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74 20  db db}} {.  set 
3b00: 74 78 74 20 5b 24 64 62 20 65 76 61 6c 20 7b 0a  txt [$db eval {.
3b10: 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d        SELECT nam
3b20: 65 2c 20 74 79 70 65 2c 20 73 71 6c 20 46 52 4f  e, type, sql FRO
3b30: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20  M sqlite_master 
3b40: 6f 72 64 65 72 20 62 79 20 6e 61 6d 65 0a 20 20  order by name.  
3b50: 7d 5d 5c 6e 0a 20 20 66 6f 72 65 61 63 68 20 74  }]\n.  foreach t
3b60: 62 6c 20 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20  bl [$db eval {. 
3b70: 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65       SELECT name
3b80: 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73   FROM sqlite_mas
3b90: 74 65 72 20 57 48 45 52 45 20 74 79 70 65 3d 27  ter WHERE type='
3ba0: 74 61 62 6c 65 27 20 6f 72 64 65 72 20 62 79 20  table' order by 
3bb0: 6e 61 6d 65 0a 20 20 7d 5d 20 7b 0a 20 20 20 20  name.  }] {.    
3bc0: 61 70 70 65 6e 64 20 74 78 74 20 5b 24 64 62 20  append txt [$db 
3bd0: 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46  eval "SELECT * F
3be0: 52 4f 4d 20 24 74 62 6c 22 5d 5c 6e 0a 20 20 7d  ROM $tbl"]\n.  }
3bf0: 0a 20 20 66 6f 72 65 61 63 68 20 70 72 61 67 20  .  foreach prag 
3c00: 7b 64 65 66 61 75 6c 74 5f 73 79 6e 63 68 72 6f  {default_synchro
3c10: 6e 6f 75 73 20 64 65 66 61 75 6c 74 5f 63 61 63  nous default_cac
3c20: 68 65 5f 73 69 7a 65 7d 20 7b 0a 20 20 20 20 61  he_size} {.    a
3c30: 70 70 65 6e 64 20 74 78 74 20 24 70 72 61 67 2d  ppend txt $prag-
3c40: 5b 24 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d  [$db eval "PRAGM
3c50: 41 20 24 70 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a  A $prag"]\n.  }.
3c60: 20 20 73 65 74 20 63 6b 73 75 6d 20 5b 73 74 72    set cksum [str
3c70: 69 6e 67 20 6c 65 6e 67 74 68 20 24 74 78 74 5d  ing length $txt]
3c80: 2d 5b 6d 64 35 20 24 74 78 74 5d 0a 20 20 23 20  -[md5 $txt].  # 
3c90: 70 75 74 73 20 24 63 6b 73 75 6d 2d 5b 66 69 6c  puts $cksum-[fil
3ca0: 65 20 73 69 7a 65 20 74 65 73 74 2e 64 62 5d 0a  e size test.db].
3cb0: 20 20 72 65 74 75 72 6e 20 24 63 6b 73 75 6d 0a    return $cksum.
3cc0: 7d 0a 0a 23 20 43 6f 70 79 20 66 69 6c 65 20 24  }..# Copy file $
3cd0: 66 72 6f 6d 20 69 6e 74 6f 20 24 74 6f 2e 20 54  from into $to. T
3ce0: 68 69 73 20 69 73 20 75 73 65 64 20 62 65 63 61  his is used beca
3cf0: 75 73 65 20 73 6f 6d 65 20 76 65 72 73 69 6f 6e  use some version
3d00: 73 20 6f 66 0a 23 20 54 43 4c 20 66 6f 72 20 77  s of.# TCL for w
3d10: 69 6e 64 6f 77 73 20 28 6e 6f 74 61 62 6c 79 20  indows (notably 
3d20: 74 68 65 20 38 2e 34 2e 31 20 62 69 6e 61 72 79  the 8.4.1 binary
3d30: 20 70 61 63 6b 61 67 65 20 73 68 69 70 70 65 64   package shipped
3d40: 20 77 69 74 68 20 74 68 65 0a 23 20 63 75 72 72   with the.# curr
3d50: 65 6e 74 20 6d 69 6e 67 77 20 72 65 6c 65 61 73  ent mingw releas
3d60: 65 29 20 68 61 76 65 20 61 20 62 72 6f 6b 65 6e  e) have a broken
3d70: 20 22 66 69 6c 65 20 63 6f 70 79 22 20 63 6f 6d   "file copy" com
3d80: 6d 61 6e 64 2e 0a 23 0a 70 72 6f 63 20 63 6f 70  mand..#.proc cop
3d90: 79 5f 66 69 6c 65 20 7b 66 72 6f 6d 20 74 6f 7d  y_file {from to}
3da0: 20 7b 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c 5f   {.  if {$::tcl_
3db0: 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72  platform(platfor
3dc0: 6d 29 3d 3d 22 75 6e 69 78 22 7d 20 7b 0a 20 20  m)=="unix"} {.  
3dd0: 20 20 66 69 6c 65 20 63 6f 70 79 20 2d 66 6f 72    file copy -for
3de0: 63 65 20 24 66 72 6f 6d 20 24 74 6f 0a 20 20 7d  ce $from $to.  }
3df0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20   else {.    set 
3e00: 66 20 5b 6f 70 65 6e 20 24 66 72 6f 6d 5d 0a 20  f [open $from]. 
3e10: 20 20 20 66 63 6f 6e 66 69 67 75 72 65 20 24 66     fconfigure $f
3e20: 20 2d 74 72 61 6e 73 6c 61 74 69 6f 6e 20 62 69   -translation bi
3e30: 6e 61 72 79 0a 20 20 20 20 73 65 74 20 74 20 5b  nary.    set t [
3e40: 6f 70 65 6e 20 24 74 6f 20 77 5d 0a 20 20 20 20  open $to w].    
3e50: 66 63 6f 6e 66 69 67 75 72 65 20 24 74 20 2d 74  fconfigure $t -t
3e60: 72 61 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72  ranslation binar
3e70: 79 0a 20 20 20 20 70 75 74 73 20 2d 6e 6f 6e 65  y.    puts -none
3e80: 77 6c 69 6e 65 20 24 74 20 5b 72 65 61 64 20 24  wline $t [read $
3e90: 66 20 5b 66 69 6c 65 20 73 69 7a 65 20 24 66 72  f [file size $fr
3ea0: 6f 6d 5d 5d 0a 20 20 20 20 63 6c 6f 73 65 20 24  om]].    close $
3eb0: 74 0a 20 20 20 20 63 6c 6f 73 65 20 24 66 0a 20  t.    close $f. 
3ec0: 20 7d 0a 7d 0a 0a 23 20 54 68 69 73 20 63 6f 6d   }.}..# This com
3ed0: 6d 61 6e 64 20 63 68 65 63 6b 73 20 66 6f 72 20  mand checks for 
3ee0: 6f 75 74 73 74 61 6e 64 69 6e 67 20 63 61 6c 6c  outstanding call
3ef0: 73 20 74 6f 20 73 71 6c 69 74 65 4d 61 6c 6c 6f  s to sqliteMallo
3f00: 63 28 29 20 66 72 6f 6d 20 77 69 74 68 69 6e 0a  c() from within.
3f10: 23 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68  # the current th
3f20: 72 65 61 64 2e 20 41 20 6c 69 73 74 20 69 73 20  read. A list is 
3f30: 72 65 74 75 72 6e 65 64 20 77 69 74 68 20 6f 6e  returned with on
3f40: 65 20 65 6e 74 72 79 20 66 6f 72 20 65 61 63 68  e entry for each
3f50: 20 6f 75 74 73 74 61 6e 64 69 6e 67 0a 23 20 6d   outstanding.# m
3f60: 61 6c 6c 6f 63 2e 20 45 61 63 68 20 6c 69 73 74  alloc. Each list
3f70: 20 65 6e 74 72 79 20 69 73 20 69 74 73 65 6c 66   entry is itself
3f80: 20 61 20 6c 69 73 74 20 6f 66 20 35 20 69 74 65   a list of 5 ite
3f90: 6d 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a  ms, as follows:.
3fa0: 23 0a 23 20 20 20 20 20 7b 20 3c 6e 75 6d 62 65  #.#     { <numbe
3fb0: 72 2d 62 79 74 65 73 3e 20 3c 66 69 6c 65 2d 6e  r-bytes> <file-n
3fc0: 61 6d 65 3e 20 3c 6c 69 6e 65 2d 6e 75 6d 62 65  ame> <line-numbe
3fd0: 72 3e 20 3c 74 65 73 74 2d 63 61 73 65 3e 20 3c  r> <test-case> <
3fe0: 73 74 61 63 6b 2d 64 75 6d 70 3e 20 7d 0a 23 0a  stack-dump> }.#.
3ff0: 70 72 6f 63 20 63 68 65 63 6b 5f 66 6f 72 5f 6c  proc check_for_l
4000: 65 61 6b 73 20 7b 7d 20 7b 0a 20 20 73 65 74 20  eaks {} {.  set 
4010: 72 65 74 20 5b 6c 69 73 74 5d 0a 20 20 73 65 74  ret [list].  set
4020: 20 63 6e 74 20 30 0a 20 20 66 6f 72 65 61 63 68   cnt 0.  foreach
4030: 20 61 6c 6c 6f 63 20 5b 73 71 6c 69 74 65 5f 6d   alloc [sqlite_m
4040: 61 6c 6c 6f 63 5f 6f 75 74 73 74 61 6e 64 69 6e  alloc_outstandin
4050: 67 5d 20 7b 0a 20 20 20 20 66 6f 72 65 61 63 68  g] {.    foreach
4060: 20 7b 6e 42 79 74 65 73 20 66 69 6c 65 20 69 4c   {nBytes file iL
4070: 69 6e 65 20 75 73 65 72 73 74 72 69 6e 67 20 62  ine userstring b
4080: 61 63 6b 74 72 61 63 65 7d 20 24 61 6c 6c 6f 63  acktrace} $alloc
4090: 20 7b 7d 0a 20 20 20 20 73 65 74 20 73 74 61 63   {}.    set stac
40a0: 6b 20 5b 6c 69 73 74 5d 0a 20 20 20 20 73 65 74  k [list].    set
40b0: 20 73 6b 69 70 20 30 0a 0a 20 20 20 20 23 20 54   skip 0..    # T
40c0: 68 65 20 66 69 72 73 74 20 63 6f 6d 6d 61 6e 64  he first command
40d0: 20 69 6e 20 74 68 69 73 20 62 6c 6f 63 6b 20 77   in this block w
40e0: 69 6c 6c 20 70 72 6f 62 61 62 6c 79 20 66 61 69  ill probably fai
40f0: 6c 20 6f 6e 20 77 69 6e 64 6f 77 73 2e 20 54 68  l on windows. Th
4100: 69 73 0a 20 20 20 20 23 20 6d 65 61 6e 73 20 74  is.    # means t
4110: 68 65 72 65 20 77 69 6c 6c 20 62 65 20 6e 6f 20  here will be no 
4120: 73 74 61 63 6b 20 64 75 6d 70 20 61 76 61 69 6c  stack dump avail
4130: 61 62 6c 65 2e 0a 20 20 20 20 69 66 20 7b 24 63  able..    if {$c
4140: 6e 74 20 3c 20 32 35 20 26 26 20 24 62 61 63 6b  nt < 25 && $back
4150: 74 72 61 63 65 21 3d 22 22 7d 20 7b 0a 20 20 20  trace!=""} {.   
4160: 20 20 20 63 61 74 63 68 20 7b 0a 20 20 20 20 20     catch {.     
4170: 20 20 20 73 65 74 20 73 74 75 66 66 20 5b 65 76     set stuff [ev
4180: 61 6c 20 22 65 78 65 63 20 61 64 64 72 32 6c 69  al "exec addr2li
4190: 6e 65 20 2d 65 20 2e 2f 74 65 73 74 66 69 78 74  ne -e ./testfixt
41a0: 75 72 65 20 2d 66 20 24 62 61 63 6b 74 72 61 63  ure -f $backtrac
41b0: 65 22 5d 0a 20 20 20 20 20 20 20 20 66 6f 72 65  e"].        fore
41c0: 61 63 68 20 7b 66 75 6e 63 20 6c 69 6e 65 7d 20  ach {func line} 
41d0: 24 73 74 75 66 66 20 7b 0a 20 20 20 20 20 20 20  $stuff {.       
41e0: 20 20 20 69 66 20 7b 24 66 75 6e 63 20 21 3d 20     if {$func != 
41f0: 22 3f 3f 22 20 7c 7c 20 24 6c 69 6e 65 20 21 3d  "??" || $line !=
4200: 20 22 3f 3f 3a 30 22 7d 20 7b 0a 20 20 20 20 20   "??:0"} {.     
4210: 20 20 20 20 20 20 20 72 65 67 65 78 70 20 7b 2e         regexp {.
4220: 2a 2f 28 2e 2a 29 7d 20 24 6c 69 6e 65 20 64 75  */(.*)} $line du
4230: 6d 6d 79 20 6c 69 6e 65 0a 20 20 20 20 20 20 20  mmy line.       
4240: 20 20 20 20 20 6c 61 70 70 65 6e 64 20 73 74 61       lappend sta
4250: 63 6b 20 22 24 7b 66 75 6e 63 7d 28 29 20 24 6c  ck "${func}() $l
4260: 69 6e 65 22 0a 20 20 20 20 20 20 20 20 20 20 7d  ine".          }
4270: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
4280: 20 20 20 20 69 66 20 7b 5b 6c 69 6e 64 65 78 20      if {[lindex 
4290: 24 73 74 61 63 6b 20 65 6e 64 5d 20 21 3d 20 22  $stack end] != "
42a0: 2e 2e 2e 22 7d 20 7b 0a 20 20 20 20 20 20 20 20  ..."} {.        
42b0: 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20 73 74        lappend st
42c0: 61 63 6b 20 22 2e 2e 2e 22 0a 20 20 20 20 20 20  ack "...".      
42d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
42e0: 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20    }.        }.  
42f0: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 6e 63 72      }.      incr
4300: 20 63 6e 74 0a 20 20 20 20 7d 0a 0a 20 20 20 20   cnt.    }..    
4310: 69 66 20 7b 21 24 73 6b 69 70 7d 20 7b 0a 20 20  if {!$skip} {.  
4320: 20 20 20 20 6c 61 70 70 65 6e 64 20 72 65 74 20      lappend ret 
4330: 5b 6c 69 73 74 20 24 6e 42 79 74 65 73 20 24 66  [list $nBytes $f
4340: 69 6c 65 20 24 69 4c 69 6e 65 20 24 75 73 65 72  ile $iLine $user
4350: 73 74 72 69 6e 67 20 24 73 74 61 63 6b 5d 0a 20  string $stack]. 
4360: 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
4370: 6e 20 24 72 65 74 0a 7d 0a 0a 23 20 50 72 65 74  n $ret.}..# Pret
4380: 74 79 20 70 72 69 6e 74 20 61 20 72 65 70 6f 72  ty print a repor
4390: 74 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20 72  t based on the r
43a0: 65 74 75 72 6e 20 76 61 6c 75 65 20 6f 66 20 5b  eturn value of [
43b0: 63 68 65 63 6b 5f 66 6f 72 5f 6c 65 61 6b 73 5d  check_for_leaks]
43c0: 20 74 6f 0a 23 20 73 74 64 6f 75 74 2e 0a 70 72   to.# stdout..pr
43d0: 6f 63 20 70 70 5f 63 68 65 63 6b 5f 66 6f 72 5f  oc pp_check_for_
43e0: 6c 65 61 6b 73 20 7b 7d 20 7b 0a 20 20 73 65 74  leaks {} {.  set
43f0: 20 6c 20 5b 63 68 65 63 6b 5f 66 6f 72 5f 6c 65   l [check_for_le
4400: 61 6b 73 5d 0a 20 20 73 65 74 20 6e 20 30 0a 20  aks].  set n 0. 
4410: 20 66 6f 72 65 61 63 68 20 6c 65 61 6b 20 24 6c   foreach leak $l
4420: 20 7b 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b   {.    foreach {
4430: 6e 42 79 74 65 73 20 66 69 6c 65 20 69 4c 69 6e  nBytes file iLin
4440: 65 20 75 73 65 72 73 74 72 69 6e 67 20 73 74 61  e userstring sta
4450: 63 6b 7d 20 24 6c 65 61 6b 20 7b 7d 0a 20 20 20  ck} $leak {}.   
4460: 20 70 75 74 73 20 22 24 6e 42 79 74 65 73 20 62   puts "$nBytes b
4470: 79 74 65 73 20 6c 65 61 6b 65 64 20 61 74 20 24  ytes leaked at $
4480: 66 69 6c 65 3a 24 69 4c 69 6e 65 20 28 24 75 73  file:$iLine ($us
4490: 65 72 73 74 72 69 6e 67 29 22 0a 20 20 20 20 66  erstring)".    f
44a0: 6f 72 65 61 63 68 20 66 72 61 6d 65 20 24 73 74  oreach frame $st
44b0: 61 63 6b 20 7b 0a 20 20 20 20 20 20 70 75 74 73  ack {.      puts
44c0: 20 22 20 20 20 20 20 20 20 20 24 66 72 61 6d 65   "        $frame
44d0: 22 0a 20 20 20 20 7d 0a 20 20 20 20 69 6e 63 72  ".    }.    incr
44e0: 20 6e 20 24 6e 42 79 74 65 73 0a 20 20 7d 0a 20   n $nBytes.  }. 
44f0: 20 70 75 74 73 20 22 4d 65 6d 6f 72 79 20 6c 65   puts "Memory le
4500: 61 6b 65 64 3a 20 24 6e 20 62 79 74 65 73 20 69  aked: $n bytes i
4510: 6e 20 5b 6c 6c 65 6e 67 74 68 20 24 6c 5d 20 61  n [llength $l] a
4520: 6c 6c 6f 63 61 74 69 6f 6e 73 22 0a 20 20 70 75  llocations".  pu
4530: 74 73 20 22 22 0a 7d 0a 0a 23 20 49 66 20 74 68  ts "".}..# If th
4540: 65 20 6c 69 62 72 61 72 79 20 69 73 20 63 6f 6d  e library is com
4550: 70 69 6c 65 64 20 77 69 74 68 20 74 68 65 20 53  piled with the S
4560: 51 4c 49 54 45 5f 44 45 46 41 55 4c 54 5f 41 55  QLITE_DEFAULT_AU
4570: 54 4f 56 41 43 55 55 4d 20 6d 61 63 72 6f 20 73  TOVACUUM macro s
4580: 65 74 0a 23 20 74 6f 20 6e 6f 6e 2d 7a 65 72 6f  et.# to non-zero
4590: 2c 20 74 68 65 6e 20 73 65 74 20 74 68 65 20 67  , then set the g
45a0: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 20 24  lobal variable $
45b0: 41 55 54 4f 56 41 43 55 55 4d 20 74 6f 20 31 2e  AUTOVACUUM to 1.
45c0: 0a 73 65 74 20 41 55 54 4f 56 41 43 55 55 4d 20  .set AUTOVACUUM 
45d0: 24 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28  $sqlite_options(
45e0: 64 65 66 61 75 6c 74 5f 61 75 74 6f 76 61 63 75  default_autovacu
45f0: 75 6d 29 0a                                      um).