/ Hex Artifact Content
Login

Artifact cab2b46972cd50c3939a0e30e0b37e73f558bc2d:


0000: 23 20 32 30 30 31 20 53 65 70 74 65 6d 62 65 72  # 2001 September
0010: 20 31 35 0a 23 0a 23 20 54 68 65 20 61 75 74 68   15.#.# The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 23 20 61 20 6c 65 67  place of.# a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 23  is a blessing:.#
0080: 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20 64 6f  .#    May you do
0090: 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20 65 76   good and not ev
00a0: 69 6c 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75  il..#    May you
00b0: 20 66 69 6e 64 20 66 6f 72 67 69 76 65 6e 65 73   find forgivenes
00c0: 73 20 66 6f 72 20 79 6f 75 72 73 65 6c 66 20 61  s for yourself a
00d0: 6e 64 20 66 6f 72 67 69 76 65 20 6f 74 68 65 72  nd forgive other
00e0: 73 2e 0a 23 20 20 20 20 4d 61 79 20 79 6f 75 20  s..#    May you 
00f0: 73 68 61 72 65 20 66 72 65 65 6c 79 2c 20 6e 65  share freely, ne
0100: 76 65 72 20 74 61 6b 69 6e 67 20 6d 6f 72 65 20  ver taking more 
0110: 74 68 61 6e 20 79 6f 75 20 67 69 76 65 2e 0a 23  than you give..#
0120: 0a 23 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .#**************
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 23 20 54 68 69 73  *********.# This
0170: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0180: 20 73 6f 6d 65 20 63 6f 6d 6d 6f 6e 20 54 43 4c   some common TCL
0190: 20 72 6f 75 74 69 6e 65 73 20 75 73 65 64 20 66   routines used f
01a0: 6f 72 20 72 65 67 72 65 73 73 69 6f 6e 0a 23 20  or regression.# 
01b0: 74 65 73 74 69 6e 67 20 74 68 65 20 53 51 4c 69  testing the SQLi
01c0: 74 65 20 6c 69 62 72 61 72 79 0a 23 0a 23 20 24  te library.#.# $
01d0: 49 64 3a 20 74 65 73 74 65 72 2e 74 63 6c 2c 76  Id: tester.tcl,v
01e0: 20 31 2e 31 34 33 20 32 30 30 39 2f 30 34 2f 30   1.143 2009/04/0
01f0: 39 20 30 31 3a 32 33 3a 34 39 20 64 72 68 20 45  9 01:23:49 drh E
0200: 78 70 20 24 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d  xp $..#---------
0210: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0220: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0230: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0240: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0250: 0a 23 20 54 68 65 20 63 6f 6d 6d 61 6e 64 73 20  .# The commands 
0260: 70 72 6f 76 69 64 65 64 20 62 79 20 74 68 65 20  provided by the 
0270: 63 6f 64 65 20 69 6e 20 74 68 69 73 20 66 69 6c  code in this fil
0280: 65 20 74 6f 20 68 65 6c 70 20 77 69 74 68 20 63  e to help with c
0290: 72 65 61 74 69 6e 67 20 0a 23 20 74 65 73 74 20  reating .# test 
02a0: 63 61 73 65 73 20 61 72 65 20 61 73 20 66 6f 6c  cases are as fol
02b0: 6c 6f 77 73 3a 0a 23 0a 23 20 43 6f 6d 6d 61 6e  lows:.#.# Comman
02c0: 64 73 20 74 6f 20 6d 61 6e 69 70 75 6c 61 74 65  ds to manipulate
02d0: 20 74 68 65 20 64 62 20 61 6e 64 20 74 68 65 20   the db and the 
02e0: 66 69 6c 65 2d 73 79 73 74 65 6d 20 61 74 20 61  file-system at a
02f0: 20 68 69 67 68 20 6c 65 76 65 6c 3a 0a 23 0a 23   high level:.#.#
0300: 20 20 20 20 20 20 63 6f 70 79 5f 66 69 6c 65 20        copy_file 
0310: 20 20 20 20 20 20 20 20 20 20 20 20 20 46 52 4f               FRO
0320: 4d 20 54 4f 0a 23 20 20 20 20 20 20 64 72 6f 70  M TO.#      drop
0330: 5f 61 6c 6c 5f 74 61 62 6c 65 20 20 20 20 20 20  _all_table      
0340: 20 20 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 66     ?DB?.#      f
0350: 6f 72 63 65 64 65 6c 65 74 65 20 20 20 20 20 20  orcedelete      
0360: 20 20 20 20 20 20 46 49 4c 45 4e 41 4d 45 0a 23        FILENAME.#
0370: 0a 23 20 54 65 73 74 20 74 68 65 20 63 61 70 61  .# Test the capa
0380: 62 69 6c 69 74 79 20 6f 66 20 74 68 65 20 53 51  bility of the SQ
0390: 4c 69 74 65 20 76 65 72 73 69 6f 6e 20 62 75 69  Lite version bui
03a0: 6c 74 20 69 6e 74 6f 20 74 68 65 20 69 6e 74 65  lt into the inte
03b0: 72 70 72 65 74 65 72 20 74 6f 0a 23 20 64 65 74  rpreter to.# det
03c0: 65 72 6d 69 6e 65 20 69 66 20 61 20 73 70 65 63  ermine if a spec
03d0: 69 66 69 63 20 74 65 73 74 20 63 61 6e 20 62 65  ific test can be
03e0: 20 72 75 6e 3a 0a 23 0a 23 20 20 20 20 20 20 69   run:.#.#      i
03f0: 66 63 61 70 61 62 6c 65 20 20 20 20 20 20 20 20  fcapable        
0400: 20 20 20 20 20 20 45 58 50 52 0a 23 0a 23 20 43        EXPR.#.# C
0410: 61 6c 75 6c 61 74 65 20 63 68 65 63 6b 73 75 6d  alulate checksum
0420: 73 20 62 61 73 65 64 20 6f 6e 20 64 61 74 61 62  s based on datab
0430: 61 73 65 20 63 6f 6e 74 65 6e 74 73 3a 0a 23 0a  ase contents:.#.
0440: 23 20 20 20 20 20 20 64 62 63 6b 73 75 6d 20 20  #      dbcksum  
0450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 44 42                DB
0460: 20 44 42 4e 41 4d 45 0a 23 20 20 20 20 20 20 61   DBNAME.#      a
0470: 6c 6c 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20  llcksum         
0480: 20 20 20 20 20 20 3f 44 42 3f 0a 23 20 20 20 20        ?DB?.#    
0490: 20 20 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20    cksum         
04a0: 20 20 20 20 20 20 20 20 20 3f 44 42 3f 0a 23 0a           ?DB?.#.
04b0: 23 20 43 6f 6d 6d 61 6e 64 73 20 74 6f 20 65 78  # Commands to ex
04c0: 65 63 75 74 65 2f 65 78 70 6c 61 69 6e 20 53 51  ecute/explain SQ
04d0: 4c 20 73 74 61 74 65 6d 65 6e 74 73 3a 0a 23 0a  L statements:.#.
04e0: 23 20 20 20 20 20 20 73 74 65 70 73 71 6c 20 20  #      stepsql  
04f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 44 42                DB
0500: 20 53 51 4c 0a 23 20 20 20 20 20 20 65 78 65 63   SQL.#      exec
0510: 73 71 6c 32 20 20 20 20 20 20 20 20 20 20 20 20  sql2            
0520: 20 20 20 53 51 4c 0a 23 20 20 20 20 20 20 65 78     SQL.#      ex
0530: 70 6c 61 69 6e 5f 6e 6f 5f 74 72 61 63 65 20 20  plain_no_trace  
0540: 20 20 20 20 20 53 51 4c 0a 23 20 20 20 20 20 20       SQL.#      
0550: 65 78 70 6c 61 69 6e 20 20 20 20 20 20 20 20 20  explain         
0560: 20 20 20 20 20 20 20 53 51 4c 20 3f 44 42 3f 0a         SQL ?DB?.
0570: 23 20 20 20 20 20 20 63 61 74 63 68 73 71 6c 20  #      catchsql 
0580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
0590: 4c 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 65 78  L ?DB?.#      ex
05a0: 65 63 73 71 6c 20 20 20 20 20 20 20 20 20 20 20  ecsql           
05b0: 20 20 20 20 20 53 51 4c 20 3f 44 42 3f 0a 23 0a       SQL ?DB?.#.
05c0: 23 20 43 6f 6d 6d 61 6e 64 73 20 74 6f 20 72 75  # Commands to ru
05d0: 6e 20 74 65 73 74 20 63 61 73 65 73 3a 0a 23 0a  n test cases:.#.
05e0: 23 20 20 20 20 20 20 64 6f 5f 69 6f 65 72 72 5f  #      do_ioerr_
05f0: 74 65 73 74 20 20 20 20 20 20 20 20 20 20 54 45  test          TE
0600: 53 54 4e 41 4d 45 20 41 52 47 53 2e 2e 2e 0a 23  STNAME ARGS....#
0610: 20 20 20 20 20 20 63 72 61 73 68 73 71 6c 20 20        crashsql  
0620: 20 20 20 20 20 20 20 20 20 20 20 20 20 41 52 47               ARG
0630: 53 2e 2e 2e 0a 23 20 20 20 20 20 20 69 6e 74 65  S....#      inte
0640: 67 72 69 74 79 5f 63 68 65 63 6b 20 20 20 20 20  grity_check     
0650: 20 20 20 54 45 53 54 4e 41 4d 45 20 3f 44 42 3f     TESTNAME ?DB?
0660: 0a 23 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20  .#      do_test 
0670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54                 T
0680: 45 53 54 4e 41 4d 45 20 53 43 52 49 50 54 20 45  ESTNAME SCRIPT E
0690: 58 50 45 43 54 45 44 0a 23 20 20 20 20 20 20 64  XPECTED.#      d
06a0: 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20 20  o_execsql_test  
06b0: 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45 20 53        TESTNAME S
06c0: 51 4c 20 45 58 50 45 43 54 45 44 0a 23 20 20 20  QL EXPECTED.#   
06d0: 20 20 20 64 6f 5f 63 61 74 63 68 73 71 6c 5f 74     do_catchsql_t
06e0: 65 73 74 20 20 20 20 20 20 20 54 45 53 54 4e 41  est       TESTNA
06f0: 4d 45 20 53 51 4c 20 45 58 50 45 43 54 45 44 0a  ME SQL EXPECTED.
0700: 23 0a 23 20 43 6f 6d 6d 61 6e 64 73 20 70 72 6f  #.# Commands pro
0710: 76 69 64 69 6e 67 20 61 20 6c 6f 77 65 72 20 6c  viding a lower l
0720: 65 76 65 6c 20 69 6e 74 65 72 66 61 63 65 20 74  evel interface t
0730: 6f 20 74 68 65 20 67 6c 6f 62 61 6c 20 74 65 73  o the global tes
0740: 74 20 63 6f 75 6e 74 65 72 73 3a 0a 23 0a 23 20  t counters:.#.# 
0750: 20 20 20 20 20 73 65 74 5f 74 65 73 74 5f 63 6f       set_test_co
0760: 75 6e 74 65 72 20 20 20 20 20 20 20 43 4f 55 4e  unter       COUN
0770: 54 45 52 20 3f 56 41 4c 55 45 3f 0a 23 20 20 20  TER ?VALUE?.#   
0780: 20 20 20 6f 6d 69 74 5f 74 65 73 74 20 20 20 20     omit_test    
0790: 20 20 20 20 20 20 20 20 20 20 54 45 53 54 4e 41            TESTNA
07a0: 4d 45 20 52 45 41 53 4f 4e 0a 23 20 20 20 20 20  ME REASON.#     
07b0: 20 66 61 69 6c 5f 74 65 73 74 20 20 20 20 20 20   fail_test      
07c0: 20 20 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45          TESTNAME
07d0: 0a 23 20 20 20 20 20 20 69 6e 63 72 5f 6e 74 65  .#      incr_nte
07e0: 73 74 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 20 72  st.#.# Command r
07f0: 75 6e 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66  un at the end of
0800: 20 65 61 63 68 20 74 65 73 74 20 66 69 6c 65 3a   each test file:
0810: 0a 23 0a 23 20 20 20 20 20 20 66 69 6e 69 73 68  .#.#      finish
0820: 5f 74 65 73 74 0a 23 0a 23 20 43 6f 6d 6d 61 6e  _test.#.# Comman
0830: 64 73 20 74 6f 20 68 65 6c 70 20 63 72 65 61 74  ds to help creat
0840: 65 20 74 65 73 74 20 66 69 6c 65 73 20 74 68 61  e test files tha
0850: 74 20 72 75 6e 20 77 69 74 68 20 74 68 65 20 22  t run with the "
0860: 57 41 4c 22 20 61 6e 64 20 6f 74 68 65 72 0a 23  WAL" and other.#
0870: 20 70 65 72 6d 75 74 61 74 69 6f 6e 73 20 28 73   permutations (s
0880: 65 65 20 66 69 6c 65 20 70 65 72 6d 75 74 61 74  ee file permutat
0890: 69 6f 6e 73 2e 74 65 73 74 29 3a 0a 23 0a 23 20  ions.test):.#.# 
08a0: 20 20 20 20 20 77 61 6c 5f 69 73 5f 77 61 6c 5f       wal_is_wal_
08b0: 6d 6f 64 65 0a 23 20 20 20 20 20 20 77 61 6c 5f  mode.#      wal_
08c0: 73 65 74 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65  set_journal_mode
08d0: 20 20 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 77     ?DB?.#      w
08e0: 61 6c 5f 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c  al_check_journal
08f0: 5f 6d 6f 64 65 20 54 45 53 54 4e 41 4d 45 3f 44  _mode TESTNAME?D
0900: 42 3f 0a 23 20 20 20 20 20 20 70 65 72 6d 75 74  B?.#      permut
0910: 61 74 69 6f 6e 0a 23 0a 0a 23 20 53 65 74 20 74  ation.#..# Set t
0920: 68 65 20 70 72 65 63 69 73 69 6f 6e 20 6f 66 20  he precision of 
0930: 46 50 20 61 72 69 74 68 6d 61 74 69 63 20 75 73  FP arithmatic us
0940: 65 64 20 62 79 20 74 68 65 20 69 6e 74 65 72 70  ed by the interp
0950: 72 65 74 65 72 2e 20 41 6e 64 20 0a 23 20 63 6f  reter. And .# co
0960: 6e 66 69 67 75 72 65 20 53 51 4c 69 74 65 20 74  nfigure SQLite t
0970: 6f 20 74 61 6b 65 20 64 61 74 61 62 61 73 65 20  o take database 
0980: 66 69 6c 65 20 6c 6f 63 6b 73 20 6f 6e 20 74 68  file locks on th
0990: 65 20 70 61 67 65 20 74 68 61 74 20 62 65 67 69  e page that begi
09a0: 6e 73 0a 23 20 36 34 4b 42 20 69 6e 74 6f 20 74  ns.# 64KB into t
09b0: 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
09c0: 20 69 6e 73 74 65 61 64 20 6f 66 20 74 68 65 20   instead of the 
09d0: 6f 6e 65 20 31 47 42 20 69 6e 2e 20 54 68 69 73  one 1GB in. This
09e0: 20 6d 65 61 6e 73 0a 23 20 74 68 65 20 63 6f 64   means.# the cod
09f0: 65 20 74 68 61 74 20 68 61 6e 64 6c 65 73 20 74  e that handles t
0a00: 68 61 74 20 73 70 65 63 69 61 6c 20 63 61 73 65  hat special case
0a10: 20 63 61 6e 20 62 65 20 74 65 73 74 65 64 20 77   can be tested w
0a20: 69 74 68 6f 75 74 20 63 72 65 61 74 69 6e 67 0a  ithout creating.
0a30: 23 20 76 65 72 79 20 6c 61 72 67 65 20 64 61 74  # very large dat
0a40: 61 62 61 73 65 20 66 69 6c 65 73 2e 0a 23 0a 73  abase files..#.s
0a50: 65 74 20 74 63 6c 5f 70 72 65 63 69 73 69 6f 6e  et tcl_precision
0a60: 20 31 35 0a 73 71 6c 69 74 65 33 5f 74 65 73 74   15.sqlite3_test
0a70: 5f 63 6f 6e 74 72 6f 6c 5f 70 65 6e 64 69 6e 67  _control_pending
0a80: 5f 62 79 74 65 20 30 78 30 30 31 30 30 30 30 0a  _byte 0x0010000.
0a90: 0a 0a 23 20 49 66 20 74 68 65 20 70 61 67 65 72  ..# If the pager
0aa0: 20 63 6f 64 65 63 20 69 73 20 61 76 61 69 6c 61   codec is availa
0ab0: 62 6c 65 2c 20 63 72 65 61 74 65 20 61 20 77 72  ble, create a wr
0ac0: 61 70 70 65 72 20 66 6f 72 20 74 68 65 20 5b 73  apper for the [s
0ad0: 71 6c 69 74 65 33 5d 20 0a 23 20 63 6f 6d 6d 61  qlite3] .# comma
0ae0: 6e 64 20 74 68 61 74 20 61 70 70 65 6e 64 73 20  nd that appends 
0af0: 22 2d 6b 65 79 20 7b 78 79 7a 7a 79 7d 22 20 74  "-key {xyzzy}" t
0b00: 6f 20 74 68 65 20 63 6f 6d 6d 61 6e 64 20 6c 69  o the command li
0b10: 6e 65 2e 20 69 2e 65 2e 20 74 68 69 73 3a 0a 23  ne. i.e. this:.#
0b20: 0a 23 20 20 20 20 20 73 71 6c 69 74 65 33 20 64  .#     sqlite3 d
0b30: 62 20 74 65 73 74 2e 64 62 0a 23 0a 23 20 62 65  b test.db.#.# be
0b40: 63 6f 6d 65 73 0a 23 0a 23 20 20 20 20 20 73 71  comes.#.#     sq
0b50: 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64 62  lite3 db test.db
0b60: 20 2d 6b 65 79 20 7b 78 79 7a 7a 79 7d 0a 23 0a   -key {xyzzy}.#.
0b70: 69 66 20 7b 5b 69 6e 66 6f 20 63 6f 6d 6d 61 6e  if {[info comman
0b80: 64 20 73 71 6c 69 74 65 5f 6f 72 69 67 5d 3d 3d  d sqlite_orig]==
0b90: 22 22 7d 20 7b 0a 20 20 72 65 6e 61 6d 65 20 73  ""} {.  rename s
0ba0: 71 6c 69 74 65 33 20 73 71 6c 69 74 65 5f 6f 72  qlite3 sqlite_or
0bb0: 69 67 0a 20 20 70 72 6f 63 20 73 71 6c 69 74 65  ig.  proc sqlite
0bc0: 33 20 7b 61 72 67 73 7d 20 7b 0a 20 20 20 20 69  3 {args} {.    i
0bd0: 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67  f {[llength $arg
0be0: 73 5d 3e 3d 32 20 26 26 20 5b 73 74 72 69 6e 67  s]>=2 && [string
0bf0: 20 69 6e 64 65 78 20 5b 6c 69 6e 64 65 78 20 24   index [lindex $
0c00: 61 72 67 73 20 30 5d 20 30 5d 21 3d 22 2d 22 7d  args 0] 0]!="-"}
0c10: 20 7b 0a 20 20 20 20 20 20 23 20 54 68 69 73 20   {.      # This 
0c20: 63 6f 6d 6d 61 6e 64 20 69 73 20 6f 70 65 6e 69  command is openi
0c30: 6e 67 20 61 20 6e 65 77 20 64 61 74 61 62 61 73  ng a new databas
0c40: 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e 0a 20 20  e connection..  
0c50: 20 20 20 20 23 0a 20 20 20 20 20 20 69 66 20 7b      #.      if {
0c60: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47  [info exists ::G
0c70: 28 70 65 72 6d 3a 73 71 6c 69 74 65 33 5f 61 72  (perm:sqlite3_ar
0c80: 67 73 29 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20  gs)]} {.        
0c90: 73 65 74 20 61 72 67 73 20 5b 63 6f 6e 63 61 74  set args [concat
0ca0: 20 24 61 72 67 73 20 24 3a 3a 47 28 70 65 72 6d   $args $::G(perm
0cb0: 3a 73 71 6c 69 74 65 33 5f 61 72 67 73 29 5d 0a  :sqlite3_args)].
0cc0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
0cd0: 20 7b 5b 73 71 6c 69 74 65 5f 6f 72 69 67 20 2d   {[sqlite_orig -
0ce0: 68 61 73 2d 63 6f 64 65 63 5d 20 26 26 20 21 5b  has-codec] && ![
0cf0: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 64 6f  info exists ::do
0d00: 5f 6e 6f 74 5f 75 73 65 5f 63 6f 64 65 63 5d 7d  _not_use_codec]}
0d10: 20 7b 0a 20 20 20 20 20 20 20 20 6c 61 70 70 65   {.        lappe
0d20: 6e 64 20 61 72 67 73 20 2d 6b 65 79 20 7b 78 79  nd args -key {xy
0d30: 7a 7a 79 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20  zzy}.      }..  
0d40: 20 20 20 20 73 65 74 20 72 65 73 20 5b 75 70 6c      set res [upl
0d50: 65 76 65 6c 20 31 20 73 71 6c 69 74 65 5f 6f 72  evel 1 sqlite_or
0d60: 69 67 20 24 61 72 67 73 5d 0a 20 20 20 20 20 20  ig $args].      
0d70: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
0d80: 20 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73 71 6c   ::G(perm:presql
0d90: 29 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 5b 6c  )]} {.        [l
0da0: 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d 20 65  index $args 0] e
0db0: 76 61 6c 20 24 3a 3a 47 28 70 65 72 6d 3a 70 72  val $::G(perm:pr
0dc0: 65 73 71 6c 29 0a 20 20 20 20 20 20 7d 0a 20 20  esql).      }.  
0dd0: 20 20 20 20 73 65 74 20 72 65 73 0a 20 20 20 20      set res.    
0de0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 23  } else {.      #
0df0: 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64 20 69 73   This command is
0e00: 20 6e 6f 74 20 6f 70 65 6e 69 6e 67 20 61 20 6e   not opening a n
0e10: 65 77 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e  ew database conn
0e20: 65 63 74 69 6f 6e 2e 20 50 61 73 73 20 74 68 65  ection. Pass the
0e30: 20 0a 20 20 20 20 20 20 23 20 61 72 67 75 6d 65   .      # argume
0e40: 6e 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74  nts through to t
0e50: 68 65 20 43 20 69 6d 70 6c 65 6d 65 6e 61 74 69  he C implemenati
0e60: 6f 6e 20 61 73 20 74 68 65 20 61 72 65 2e 0a 20  on as the are.. 
0e70: 20 20 20 20 20 23 0a 20 20 20 20 20 20 75 70 6c       #.      upl
0e80: 65 76 65 6c 20 31 20 73 71 6c 69 74 65 5f 6f 72  evel 1 sqlite_or
0e90: 69 67 20 24 61 72 67 73 0a 20 20 20 20 7d 0a 20  ig $args.    }. 
0ea0: 20 7d 0a 7d 0a 0a 70 72 6f 63 20 65 78 65 63 70   }.}..proc execp
0eb0: 72 65 73 71 6c 20 7b 68 61 6e 64 6c 65 20 61 72  resql {handle ar
0ec0: 67 73 7d 20 7b 0a 20 20 74 72 61 63 65 20 72 65  gs} {.  trace re
0ed0: 6d 6f 76 65 20 65 78 65 63 75 74 69 6f 6e 20 24  move execution $
0ee0: 68 61 6e 64 6c 65 20 65 6e 74 65 72 20 5b 6c 69  handle enter [li
0ef0: 73 74 20 65 78 65 63 70 72 65 73 71 6c 20 24 68  st execpresql $h
0f00: 61 6e 64 6c 65 5d 0a 20 20 69 66 20 7b 5b 69 6e  andle].  if {[in
0f10: 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 70 65  fo exists ::G(pe
0f20: 72 6d 3a 70 72 65 73 71 6c 29 5d 7d 20 7b 0a 20  rm:presql)]} {. 
0f30: 20 20 20 24 68 61 6e 64 6c 65 20 65 76 61 6c 20     $handle eval 
0f40: 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73 71 6c  $::G(perm:presql
0f50: 29 0a 20 20 7d 0a 7d 0a 0a 23 20 54 68 69 73 20  ).  }.}..# This 
0f60: 63 6f 6d 6d 61 6e 64 20 73 68 6f 75 6c 64 20 62  command should b
0f70: 65 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20 6c  e called after l
0f80: 6f 61 64 69 6e 67 20 74 65 73 74 65 72 2e 74 63  oading tester.tc
0f90: 6c 20 66 72 6f 6d 20 77 69 74 68 69 6e 0a 23 20  l from within.# 
0fa0: 61 6c 6c 20 74 65 73 74 20 73 63 72 69 70 74 73  all test scripts
0fb0: 20 74 68 61 74 20 61 72 65 20 69 6e 63 6f 6d 70   that are incomp
0fc0: 61 74 69 62 6c 65 20 77 69 74 68 20 65 6e 63 72  atible with encr
0fd0: 79 70 74 69 6f 6e 20 63 6f 64 65 63 73 2e 0a 23  yption codecs..#
0fe0: 0a 70 72 6f 63 20 64 6f 5f 6e 6f 74 5f 75 73 65  .proc do_not_use
0ff0: 5f 63 6f 64 65 63 20 7b 7d 20 7b 0a 20 20 73 65  _codec {} {.  se
1000: 74 20 3a 3a 64 6f 5f 6e 6f 74 5f 75 73 65 5f 63  t ::do_not_use_c
1010: 6f 64 65 63 20 31 0a 20 20 72 65 73 65 74 5f 64  odec 1.  reset_d
1020: 62 0a 7d 0a 0a 23 20 54 68 65 20 66 6f 6c 6c 6f  b.}..# The follo
1030: 77 69 6e 67 20 62 6c 6f 63 6b 20 6f 6e 6c 79 20  wing block only 
1040: 72 75 6e 73 20 74 68 65 20 66 69 72 73 74 20 74  runs the first t
1050: 69 6d 65 20 74 68 69 73 20 66 69 6c 65 20 69 73  ime this file is
1060: 20 73 6f 75 72 63 65 64 2e 20 49 74 0a 23 20 64   sourced. It.# d
1070: 6f 65 73 20 6e 6f 74 20 72 75 6e 20 69 6e 20 73  oes not run in s
1080: 6c 61 76 65 20 69 6e 74 65 72 70 72 65 74 65 72  lave interpreter
1090: 73 20 28 73 69 6e 63 65 20 74 68 65 20 3a 3a 63  s (since the ::c
10a0: 6d 64 6c 69 6e 65 61 72 67 20 61 72 72 61 79 20  mdlinearg array 
10b0: 69 73 0a 23 20 70 6f 70 75 6c 61 74 65 64 20 62  is.# populated b
10c0: 65 66 6f 72 65 20 74 68 65 20 74 65 73 74 20 73  efore the test s
10d0: 63 72 69 70 74 20 69 73 20 72 75 6e 20 69 6e 20  cript is run in 
10e0: 73 6c 61 76 65 20 69 6e 74 65 72 70 72 65 74 65  slave interprete
10f0: 72 73 29 2e 0a 23 0a 69 66 20 7b 5b 69 6e 66 6f  rs)..#.if {[info
1100: 20 65 78 69 73 74 73 20 63 6d 64 6c 69 6e 65 61   exists cmdlinea
1110: 72 67 5d 3d 3d 30 7d 20 7b 0a 0a 20 20 23 20 50  rg]==0} {..  # P
1120: 61 72 73 65 20 61 6e 79 20 6f 70 74 69 6f 6e 73  arse any options
1130: 20 73 70 65 63 69 66 69 65 64 20 69 6e 20 74 68   specified in th
1140: 65 20 24 61 72 67 76 20 61 72 72 61 79 2e 20 54  e $argv array. T
1150: 68 69 73 20 73 63 72 69 70 74 20 61 63 63 65 70  his script accep
1160: 74 73 20 74 68 65 20 0a 20 20 23 20 66 6f 6c 6c  ts the .  # foll
1170: 6f 77 69 6e 67 20 6f 70 74 69 6f 6e 73 3a 20 0a  owing options: .
1180: 20 20 23 0a 20 20 23 20 20 20 2d 2d 70 61 75 73    #.  #   --paus
1190: 65 0a 20 20 23 20 20 20 2d 2d 73 6f 66 74 2d 68  e.  #   --soft-h
11a0: 65 61 70 2d 6c 69 6d 69 74 3d 4e 4e 0a 20 20 23  eap-limit=NN.  #
11b0: 20 20 20 2d 2d 6d 61 78 65 72 72 6f 72 3d 4e 4e     --maxerror=NN
11c0: 0a 20 20 23 20 20 20 2d 2d 6d 61 6c 6c 6f 63 74  .  #   --malloct
11d0: 72 61 63 65 3d 4e 0a 20 20 23 20 20 20 2d 2d 62  race=N.  #   --b
11e0: 61 63 6b 74 72 61 63 65 3d 4e 0a 20 20 23 20 20  acktrace=N.  #  
11f0: 20 2d 2d 62 69 6e 61 72 79 6c 6f 67 3d 4e 0a 20   --binarylog=N. 
1200: 20 23 20 20 20 2d 2d 73 6f 61 6b 3d 4e 0a 20 20   #   --soak=N.  
1210: 23 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61  #.  set cmdlinea
1220: 72 67 28 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d  rg(soft-heap-lim
1230: 69 74 29 20 20 20 20 30 0a 20 20 73 65 74 20 63  it)    0.  set c
1240: 6d 64 6c 69 6e 65 61 72 67 28 6d 61 78 65 72 72  mdlinearg(maxerr
1250: 6f 72 29 20 20 20 20 20 20 20 20 31 30 30 30 0a  or)        1000.
1260: 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67    set cmdlinearg
1270: 28 6d 61 6c 6c 6f 63 74 72 61 63 65 29 20 20 20  (malloctrace)   
1280: 20 20 20 20 20 30 0a 20 20 73 65 74 20 63 6d 64       0.  set cmd
1290: 6c 69 6e 65 61 72 67 28 62 61 63 6b 74 72 61 63  linearg(backtrac
12a0: 65 29 20 20 20 20 20 20 20 20 20 31 30 0a 20 20  e)         10.  
12b0: 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 62  set cmdlinearg(b
12c0: 69 6e 61 72 79 6c 6f 67 29 20 20 20 20 20 20 20  inarylog)       
12d0: 20 20 20 30 0a 20 20 73 65 74 20 63 6d 64 6c 69     0.  set cmdli
12e0: 6e 65 61 72 67 28 73 6f 61 6b 29 20 20 20 20 20  nearg(soak)     
12f0: 20 20 20 20 20 20 20 20 20 20 30 0a 0a 20 20 73            0..  s
1300: 65 74 20 6c 65 66 74 6f 76 65 72 20 5b 6c 69 73  et leftover [lis
1310: 74 5d 0a 20 20 66 6f 72 65 61 63 68 20 61 20 24  t].  foreach a $
1320: 61 72 67 76 20 7b 0a 20 20 20 20 73 77 69 74 63  argv {.    switc
1330: 68 20 2d 72 65 67 65 78 70 20 2d 2d 20 24 61 20  h -regexp -- $a 
1340: 7b 0a 20 20 20 20 20 20 7b 5e 2d 2b 70 61 75 73  {.      {^-+paus
1350: 65 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20  e$} {.        # 
1360: 57 61 69 74 20 66 6f 72 20 75 73 65 72 20 69 6e  Wait for user in
1370: 70 75 74 20 62 65 66 6f 72 65 20 63 6f 6e 74 69  put before conti
1380: 6e 75 69 6e 67 2e 20 54 68 69 73 20 69 73 20 74  nuing. This is t
1390: 6f 20 67 69 76 65 20 74 68 65 20 75 73 65 72 20  o give the user 
13a0: 61 6e 20 0a 20 20 20 20 20 20 20 20 23 20 6f 70  an .        # op
13b0: 70 6f 72 74 75 6e 69 74 79 20 74 6f 20 63 6f 6e  portunity to con
13c0: 6e 65 63 74 20 70 72 6f 66 69 6c 69 6e 67 20 74  nect profiling t
13d0: 6f 6f 6c 73 20 74 6f 20 74 68 65 20 70 72 6f 63  ools to the proc
13e0: 65 73 73 2e 0a 20 20 20 20 20 20 20 20 70 75 74  ess..        put
13f0: 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 22 50 72  s -nonewline "Pr
1400: 65 73 73 20 52 45 54 55 52 4e 20 74 6f 20 62 65  ess RETURN to be
1410: 67 69 6e 2e 2e 2e 22 0a 20 20 20 20 20 20 20 20  gin...".        
1420: 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20 20  flush stdout.   
1430: 20 20 20 20 20 67 65 74 73 20 73 74 64 69 6e 0a       gets stdin.
1440: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e        }.      {^
1450: 2d 2b 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69  -+soft-heap-limi
1460: 74 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20  t=.+$} {.       
1470: 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20   foreach {dummy 
1480: 63 6d 64 6c 69 6e 65 61 72 67 28 73 6f 66 74 2d  cmdlinearg(soft-
1490: 68 65 61 70 2d 6c 69 6d 69 74 29 7d 20 5b 73 70  heap-limit)} [sp
14a0: 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a  lit $a =] break.
14b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e        }.      {^
14c0: 2d 2b 6d 61 78 65 72 72 6f 72 3d 2e 2b 24 7d 20  -+maxerror=.+$} 
14d0: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63  {.        foreac
14e0: 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65  h {dummy cmdline
14f0: 61 72 67 28 6d 61 78 65 72 72 6f 72 29 7d 20 5b  arg(maxerror)} [
1500: 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61  split $a =] brea
1510: 6b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  k.      }.      
1520: 7b 5e 2d 2b 6d 61 6c 6c 6f 63 74 72 61 63 65 3d  {^-+malloctrace=
1530: 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66  .+$} {.        f
1540: 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d  oreach {dummy cm
1550: 64 6c 69 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74  dlinearg(malloct
1560: 72 61 63 65 29 7d 20 5b 73 70 6c 69 74 20 24 61  race)} [split $a
1570: 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20   =] break.      
1580: 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72    if {$cmdlinear
1590: 67 28 6d 61 6c 6c 6f 63 74 72 61 63 65 29 7d 20  g(malloctrace)} 
15a0: 7b 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c 69  {.          sqli
15b0: 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67  te3_memdebug_log
15c0: 20 73 74 61 72 74 0a 20 20 20 20 20 20 20 20 7d   start.        }
15d0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b  .      }.      {
15e0: 5e 2d 2b 62 61 63 6b 74 72 61 63 65 3d 2e 2b 24  ^-+backtrace=.+$
15f0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65  } {.        fore
1600: 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69  ach {dummy cmdli
1610: 6e 65 61 72 67 28 62 61 63 6b 74 72 61 63 65 29  nearg(backtrace)
1620: 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62  } [split $a =] b
1630: 72 65 61 6b 0a 20 20 20 20 20 20 20 20 73 71 6c  reak.        sql
1640: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 62 61  ite3_memdebug_ba
1650: 63 6b 74 72 61 63 65 20 24 76 61 6c 75 65 0a 20  cktrace $value. 
1660: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e 2d       }.      {^-
1670: 2b 62 69 6e 61 72 79 6c 6f 67 3d 2e 2b 24 7d 20  +binarylog=.+$} 
1680: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63  {.        foreac
1690: 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65  h {dummy cmdline
16a0: 61 72 67 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20  arg(binarylog)} 
16b0: 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65  [split $a =] bre
16c0: 61 6b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  ak.      }.     
16d0: 20 7b 5e 2d 2b 73 6f 61 6b 3d 2e 2b 24 7d 20 7b   {^-+soak=.+$} {
16e0: 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68  .        foreach
16f0: 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61   {dummy cmdlinea
1700: 72 67 28 73 6f 61 6b 29 7d 20 5b 73 70 6c 69 74  rg(soak)} [split
1710: 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20   $a =] break.   
1720: 20 20 20 20 20 73 65 74 20 3a 3a 47 28 69 73 73       set ::G(iss
1730: 6f 61 6b 29 20 24 63 6d 64 6c 69 6e 65 61 72 67  oak) $cmdlinearg
1740: 28 73 6f 61 6b 29 0a 20 20 20 20 20 20 7d 0a 20  (soak).      }. 
1750: 20 20 20 20 20 64 65 66 61 75 6c 74 20 7b 0a 20       default {. 
1760: 20 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20 6c         lappend l
1770: 65 66 74 6f 76 65 72 20 24 61 0a 20 20 20 20 20  eftover $a.     
1780: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73   }.    }.  }.  s
1790: 65 74 20 61 72 67 76 20 24 6c 65 66 74 6f 76 65  et argv $leftove
17a0: 72 0a 0a 20 20 23 20 49 6e 73 74 61 6c 6c 20 74  r..  # Install t
17b0: 68 65 20 6d 61 6c 6c 6f 63 20 6c 61 79 65 72 20  he malloc layer 
17c0: 75 73 65 64 20 74 6f 20 69 6e 6a 65 63 74 20 4f  used to inject O
17d0: 4f 4d 20 65 72 72 6f 72 73 2e 20 41 6e 64 20 74  OM errors. And t
17e0: 68 65 20 27 61 75 74 6f 6d 61 74 69 63 27 0a 20  he 'automatic'. 
17f0: 20 23 20 65 78 74 65 6e 73 69 6f 6e 73 2e 20 54   # extensions. T
1800: 68 69 73 20 6f 6e 6c 79 20 6e 65 65 64 73 20 74  his only needs t
1810: 6f 20 62 65 20 64 6f 6e 65 20 6f 6e 63 65 20 66  o be done once f
1820: 6f 72 20 74 68 65 20 70 72 6f 63 65 73 73 2e 0a  or the process..
1830: 20 20 23 0a 20 20 73 71 6c 69 74 65 33 5f 73 68    #.  sqlite3_sh
1840: 75 74 64 6f 77 6e 20 0a 20 20 69 6e 73 74 61 6c  utdown .  instal
1850: 6c 5f 6d 61 6c 6c 6f 63 5f 66 61 75 6c 74 73 69  l_malloc_faultsi
1860: 6d 20 31 20 0a 20 20 73 71 6c 69 74 65 33 5f 69  m 1 .  sqlite3_i
1870: 6e 69 74 69 61 6c 69 7a 65 0a 20 20 61 75 74 6f  nitialize.  auto
1880: 69 6e 73 74 61 6c 6c 5f 74 65 73 74 5f 66 75 6e  install_test_fun
1890: 63 74 69 6f 6e 73 0a 0a 20 20 23 20 49 66 20 74  ctions..  # If t
18a0: 68 65 20 2d 2d 62 69 6e 61 72 79 6c 6f 67 20 6f  he --binarylog o
18b0: 70 74 69 6f 6e 20 77 61 73 20 73 70 65 63 69 66  ption was specif
18c0: 69 65 64 2c 20 63 72 65 61 74 65 20 74 68 65 20  ied, create the 
18d0: 6c 6f 67 67 69 6e 67 20 56 46 53 2e 20 54 68 69  logging VFS. Thi
18e0: 73 0a 20 20 23 20 63 61 6c 6c 20 69 6e 73 74 61  s.  # call insta
18f0: 6c 6c 73 20 74 68 65 20 6e 65 77 20 56 46 53 20  lls the new VFS 
1900: 61 73 20 74 68 65 20 64 65 66 61 75 6c 74 20 66  as the default f
1910: 6f 72 20 61 6c 6c 20 53 51 4c 69 74 65 20 63 6f  or all SQLite co
1920: 6e 6e 65 63 74 69 6f 6e 73 2e 0a 20 20 23 0a 20  nnections..  #. 
1930: 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65 61 72 67   if {$cmdlinearg
1940: 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20 7b 0a 20  (binarylog)} {. 
1950: 20 20 20 76 66 73 6c 6f 67 20 6e 65 77 20 62 69     vfslog new bi
1960: 6e 61 72 79 6c 6f 67 20 7b 7d 20 76 66 73 6c 6f  narylog {} vfslo
1970: 67 2e 62 69 6e 0a 20 20 7d 0a 0a 20 20 23 20 53  g.bin.  }..  # S
1980: 65 74 20 74 68 65 20 62 61 63 6b 74 72 61 63 65  et the backtrace
1990: 20 64 65 70 74 68 2c 20 69 66 20 6d 61 6c 6c 6f   depth, if mallo
19a0: 63 20 74 72 61 63 69 6e 67 20 69 73 20 65 6e 61  c tracing is ena
19b0: 62 6c 65 64 2e 0a 20 20 23 0a 20 20 69 66 20 7b  bled..  #.  if {
19c0: 24 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 6c 6c  $cmdlinearg(mall
19d0: 6f 63 74 72 61 63 65 29 7d 20 7b 0a 20 20 20 20  octrace)} {.    
19e0: 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67  sqlite3_memdebug
19f0: 5f 62 61 63 6b 74 72 61 63 65 20 24 63 6d 64 6c  _backtrace $cmdl
1a00: 69 6e 65 61 72 67 28 62 61 63 6b 74 72 61 63 65  inearg(backtrace
1a10: 29 0a 20 20 7d 0a 7d 0a 0a 23 20 55 70 64 61 74  ).  }.}..# Updat
1a20: 65 20 74 68 65 20 73 6f 66 74 2d 68 65 61 70 2d  e the soft-heap-
1a30: 6c 69 6d 69 74 20 65 61 63 68 20 74 69 6d 65 20  limit each time 
1a40: 74 68 69 73 20 73 63 72 69 70 74 20 69 73 20 72  this script is r
1a50: 75 6e 2e 20 49 6e 20 74 68 61 74 0a 23 20 77 61  un. In that.# wa
1a60: 79 20 69 66 20 61 6e 20 69 6e 64 69 76 69 64 75  y if an individu
1a70: 61 6c 20 74 65 73 74 20 66 69 6c 65 20 63 68 61  al test file cha
1a80: 6e 67 65 73 20 74 68 65 20 73 6f 66 74 2d 68 65  nges the soft-he
1a90: 61 70 2d 6c 69 6d 69 74 2c 20 69 74 0a 23 20 77  ap-limit, it.# w
1aa0: 69 6c 6c 20 62 65 20 72 65 73 65 74 20 61 74 20  ill be reset at 
1ab0: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
1ac0: 20 6e 65 78 74 20 74 65 73 74 20 66 69 6c 65 2e   next test file.
1ad0: 0a 23 0a 73 71 6c 69 74 65 33 5f 73 6f 66 74 5f  .#.sqlite3_soft_
1ae0: 68 65 61 70 5f 6c 69 6d 69 74 20 24 63 6d 64 6c  heap_limit $cmdl
1af0: 69 6e 65 61 72 67 28 73 6f 66 74 2d 68 65 61 70  inearg(soft-heap
1b00: 2d 6c 69 6d 69 74 29 0a 0a 23 20 43 72 65 61 74  -limit)..# Creat
1b10: 65 20 61 20 74 65 73 74 20 64 61 74 61 62 61 73  e a test databas
1b20: 65 0a 23 0a 70 72 6f 63 20 72 65 73 65 74 5f 64  e.#.proc reset_d
1b30: 62 20 7b 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b  b {} {.  catch {
1b40: 64 62 20 63 6c 6f 73 65 7d 0a 20 20 66 69 6c 65  db close}.  file
1b50: 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 74   delete -force t
1b60: 65 73 74 2e 64 62 0a 20 20 66 69 6c 65 20 64 65  est.db.  file de
1b70: 6c 65 74 65 20 2d 66 6f 72 63 65 20 74 65 73 74  lete -force test
1b80: 2e 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20 66 69  .db-journal.  fi
1b90: 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65  le delete -force
1ba0: 20 74 65 73 74 2e 64 62 2d 77 61 6c 0a 20 20 73   test.db-wal.  s
1bb0: 71 6c 69 74 65 33 20 64 62 20 2e 2f 74 65 73 74  qlite3 db ./test
1bc0: 2e 64 62 0a 20 20 73 65 74 20 3a 3a 44 42 20 5b  .db.  set ::DB [
1bd0: 73 71 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69  sqlite3_connecti
1be0: 6f 6e 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20  on_pointer db]. 
1bf0: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
1c00: 73 20 3a 3a 53 45 54 55 50 5f 53 51 4c 5d 7d 20  s ::SETUP_SQL]} 
1c10: 7b 0a 20 20 20 20 64 62 20 65 76 61 6c 20 24 3a  {.    db eval $:
1c20: 3a 53 45 54 55 50 5f 53 51 4c 0a 20 20 7d 0a 7d  :SETUP_SQL.  }.}
1c30: 0a 72 65 73 65 74 5f 64 62 0a 0a 23 20 41 62 6f  .reset_db..# Abo
1c40: 72 74 20 65 61 72 6c 79 20 69 66 20 74 68 69 73  rt early if this
1c50: 20 73 63 72 69 70 74 20 68 61 73 20 62 65 65 6e   script has been
1c60: 20 72 75 6e 20 62 65 66 6f 72 65 2e 0a 23 0a 69   run before..#.i
1c70: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
1c80: 54 43 28 63 6f 75 6e 74 29 5d 7d 20 72 65 74 75  TC(count)]} retu
1c90: 72 6e 0a 0a 23 20 49 6e 69 74 69 61 6c 69 7a 65  rn..# Initialize
1ca0: 20 74 68 65 20 74 65 73 74 20 63 6f 75 6e 74 65   the test counte
1cb0: 72 73 20 61 6e 64 20 73 65 74 20 75 70 20 63 6f  rs and set up co
1cc0: 6d 6d 61 6e 64 73 20 74 6f 20 61 63 63 65 73 73  mmands to access
1cd0: 20 74 68 65 6d 2e 0a 23 20 4f 72 2c 20 69 66 20   them..# Or, if 
1ce0: 74 68 69 73 20 69 73 20 61 20 73 6c 61 76 65 20  this is a slave 
1cf0: 69 6e 74 65 72 70 72 65 74 65 72 2c 20 73 65 74  interpreter, set
1d00: 20 75 70 20 61 6c 69 61 73 65 73 20 74 6f 20 77   up aliases to w
1d10: 72 69 74 65 20 74 68 65 0a 23 20 63 6f 75 6e 74  rite the.# count
1d20: 65 72 73 20 69 6e 20 74 68 65 20 70 61 72 65 6e  ers in the paren
1d30: 74 20 69 6e 74 65 72 70 72 65 74 65 72 2e 0a 23  t interpreter..#
1d40: 0a 69 66 20 7b 30 3d 3d 5b 69 6e 66 6f 20 65 78  .if {0==[info ex
1d50: 69 73 74 73 20 3a 3a 53 4c 41 56 45 5d 7d 20 7b  ists ::SLAVE]} {
1d60: 0a 20 20 73 65 74 20 54 43 28 65 72 72 6f 72 73  .  set TC(errors
1d70: 29 20 20 20 20 30 0a 20 20 73 65 74 20 54 43 28  )    0.  set TC(
1d80: 63 6f 75 6e 74 29 20 20 20 20 20 30 0a 20 20 73  count)     0.  s
1d90: 65 74 20 54 43 28 66 61 69 6c 5f 6c 69 73 74 29  et TC(fail_list)
1da0: 20 5b 6c 69 73 74 5d 0a 20 20 73 65 74 20 54 43   [list].  set TC
1db0: 28 6f 6d 69 74 5f 6c 69 73 74 29 20 5b 6c 69 73  (omit_list) [lis
1dc0: 74 5d 0a 0a 20 20 70 72 6f 63 20 73 65 74 5f 74  t]..  proc set_t
1dd0: 65 73 74 5f 63 6f 75 6e 74 65 72 20 7b 63 6f 75  est_counter {cou
1de0: 6e 74 65 72 20 61 72 67 73 7d 20 7b 0a 20 20 20  nter args} {.   
1df0: 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61   if {[llength $a
1e00: 72 67 73 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65  rgs]} {.      se
1e10: 74 20 3a 3a 54 43 28 24 63 6f 75 6e 74 65 72 29  t ::TC($counter)
1e20: 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 30   [lindex $args 0
1e30: 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20  ].    }.    set 
1e40: 3a 3a 54 43 28 24 63 6f 75 6e 74 65 72 29 0a 20  ::TC($counter). 
1e50: 20 7d 0a 7d 0a 0a 23 20 52 65 63 6f 72 64 20 74   }.}..# Record t
1e60: 68 65 20 66 61 63 74 20 74 68 61 74 20 61 20 73  he fact that a s
1e70: 65 71 75 65 6e 63 65 20 6f 66 20 74 65 73 74 73  equence of tests
1e80: 20 77 65 72 65 20 6f 6d 69 74 74 65 64 2e 0a 23   were omitted..#
1e90: 0a 70 72 6f 63 20 6f 6d 69 74 5f 74 65 73 74 20  .proc omit_test 
1ea0: 7b 6e 61 6d 65 20 72 65 61 73 6f 6e 7d 20 7b 0a  {name reason} {.
1eb0: 20 20 73 65 74 20 6f 6d 69 74 4c 69 73 74 20 5b    set omitList [
1ec0: 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72  set_test_counter
1ed0: 20 6f 6d 69 74 5f 6c 69 73 74 5d 0a 20 20 6c 61   omit_list].  la
1ee0: 70 70 65 6e 64 20 6f 6d 69 74 4c 69 73 74 20 5b  ppend omitList [
1ef0: 6c 69 73 74 20 24 6e 61 6d 65 20 24 72 65 61 73  list $name $reas
1f00: 6f 6e 5d 0a 20 20 73 65 74 5f 74 65 73 74 5f 63  on].  set_test_c
1f10: 6f 75 6e 74 65 72 20 6f 6d 69 74 5f 6c 69 73 74  ounter omit_list
1f20: 20 24 6f 6d 69 74 4c 69 73 74 0a 7d 0a 0a 23 20   $omitList.}..# 
1f30: 52 65 63 6f 72 64 20 74 68 65 20 66 61 63 74 20  Record the fact 
1f40: 74 68 61 74 20 61 20 74 65 73 74 20 66 61 69 6c  that a test fail
1f50: 65 64 2e 0a 23 0a 70 72 6f 63 20 66 61 69 6c 5f  ed..#.proc fail_
1f60: 74 65 73 74 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20  test {name} {.  
1f70: 73 65 74 20 66 20 5b 73 65 74 5f 74 65 73 74 5f  set f [set_test_
1f80: 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69 73  counter fail_lis
1f90: 74 5d 0a 20 20 6c 61 70 70 65 6e 64 20 66 20 24  t].  lappend f $
1fa0: 6e 61 6d 65 0a 20 20 73 65 74 5f 74 65 73 74 5f  name.  set_test_
1fb0: 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69 73  counter fail_lis
1fc0: 74 20 24 66 0a 20 20 73 65 74 5f 74 65 73 74 5f  t $f.  set_test_
1fd0: 63 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 20 5b  counter errors [
1fe0: 65 78 70 72 20 5b 73 65 74 5f 74 65 73 74 5f 63  expr [set_test_c
1ff0: 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 20 2b  ounter errors] +
2000: 20 31 5d 0a 0a 20 20 73 65 74 20 6e 46 61 69 6c   1]..  set nFail
2010: 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74   [set_test_count
2020: 65 72 20 65 72 72 6f 72 73 5d 0a 20 20 69 66 20  er errors].  if 
2030: 7b 24 6e 46 61 69 6c 3e 3d 24 3a 3a 63 6d 64 6c  {$nFail>=$::cmdl
2040: 69 6e 65 61 72 67 28 6d 61 78 65 72 72 6f 72 29  inearg(maxerror)
2050: 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 2a 2a  } {.    puts "**
2060: 2a 20 47 69 76 69 6e 67 20 75 70 2e 2e 2e 22 0a  * Giving up...".
2070: 20 20 20 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73      finalize_tes
2080: 74 69 6e 67 0a 20 20 7d 0a 7d 0a 0a 23 20 49 6e  ting.  }.}..# In
2090: 63 72 65 6d 65 6e 74 20 74 68 65 20 6e 75 6d 62  crement the numb
20a0: 65 72 20 6f 66 20 74 65 73 74 73 20 72 75 6e 0a  er of tests run.
20b0: 23 0a 70 72 6f 63 20 69 6e 63 72 5f 6e 74 65 73  #.proc incr_ntes
20c0: 74 20 7b 7d 20 7b 0a 20 20 73 65 74 5f 74 65 73  t {} {.  set_tes
20d0: 74 5f 63 6f 75 6e 74 65 72 20 63 6f 75 6e 74 20  t_counter count 
20e0: 5b 65 78 70 72 20 5b 73 65 74 5f 74 65 73 74 5f  [expr [set_test_
20f0: 63 6f 75 6e 74 65 72 20 63 6f 75 6e 74 5d 20 2b  counter count] +
2100: 20 31 5d 0a 7d 0a 0a 0a 23 20 49 6e 76 6f 6b 65   1].}...# Invoke
2110: 20 74 68 65 20 64 6f 5f 74 65 73 74 20 70 72 6f   the do_test pro
2120: 63 65 64 75 72 65 20 74 6f 20 72 75 6e 20 61 20  cedure to run a 
2130: 73 69 6e 67 6c 65 20 74 65 73 74 20 0a 23 0a 70  single test .#.p
2140: 72 6f 63 20 64 6f 5f 74 65 73 74 20 7b 6e 61 6d  roc do_test {nam
2150: 65 20 63 6d 64 20 65 78 70 65 63 74 65 64 7d 20  e cmd expected} 
2160: 7b 0a 0a 20 20 67 6c 6f 62 61 6c 20 61 72 67 76  {..  global argv
2170: 20 63 6d 64 6c 69 6e 65 61 72 67 0a 0a 20 20 73   cmdlinearg..  s
2180: 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f  qlite3_memdebug_
2190: 73 65 74 74 69 74 6c 65 20 24 6e 61 6d 65 0a 0a  settitle $name..
21a0: 23 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20  #  if {[llength 
21b0: 24 61 72 67 76 5d 3d 3d 30 7d 20 7b 20 0a 23 20  $argv]==0} { .# 
21c0: 20 20 20 73 65 74 20 67 6f 20 31 0a 23 20 20 7d     set go 1.#  }
21d0: 20 65 6c 73 65 20 7b 0a 23 20 20 20 20 73 65 74   else {.#    set
21e0: 20 67 6f 20 30 0a 23 20 20 20 20 66 6f 72 65 61   go 0.#    forea
21f0: 63 68 20 70 61 74 74 65 72 6e 20 24 61 72 67 76  ch pattern $argv
2200: 20 7b 0a 23 20 20 20 20 20 20 69 66 20 7b 5b 73   {.#      if {[s
2210: 74 72 69 6e 67 20 6d 61 74 63 68 20 24 70 61 74  tring match $pat
2220: 74 65 72 6e 20 24 6e 61 6d 65 5d 7d 20 7b 0a 23  tern $name]} {.#
2230: 20 20 20 20 20 20 20 20 73 65 74 20 67 6f 20 31          set go 1
2240: 0a 23 20 20 20 20 20 20 20 20 62 72 65 61 6b 0a  .#        break.
2250: 23 20 20 20 20 20 20 7d 0a 23 20 20 20 20 7d 0a  #      }.#    }.
2260: 23 20 20 7d 0a 0a 20 20 69 66 20 7b 5b 69 6e 66  #  }..  if {[inf
2270: 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 70 65 72  o exists ::G(per
2280: 6d 3a 70 72 65 66 69 78 29 5d 7d 20 7b 0a 20 20  m:prefix)]} {.  
2290: 20 20 73 65 74 20 6e 61 6d 65 20 22 24 3a 3a 47    set name "$::G
22a0: 28 70 65 72 6d 3a 70 72 65 66 69 78 29 24 6e 61  (perm:prefix)$na
22b0: 6d 65 22 0a 20 20 7d 0a 0a 20 20 69 6e 63 72 5f  me".  }..  incr_
22c0: 6e 74 65 73 74 0a 20 20 70 75 74 73 20 2d 6e 6f  ntest.  puts -no
22d0: 6e 65 77 6c 69 6e 65 20 24 6e 61 6d 65 2e 2e 2e  newline $name...
22e0: 0a 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a  .  flush stdout.
22f0: 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 75 70    if {[catch {up
2300: 6c 65 76 65 6c 20 23 30 20 22 24 63 6d 64 3b 5c  level #0 "$cmd;\
2310: 6e 22 7d 20 72 65 73 75 6c 74 5d 7d 20 7b 0a 20  n"} result]} {. 
2320: 20 20 20 70 75 74 73 20 22 5c 6e 45 72 72 6f 72     puts "\nError
2330: 3a 20 24 72 65 73 75 6c 74 22 0a 20 20 20 20 66  : $result".    f
2340: 61 69 6c 5f 74 65 73 74 20 24 6e 61 6d 65 0a 20  ail_test $name. 
2350: 20 7d 20 65 6c 73 65 69 66 20 7b 5b 73 74 72 69   } elseif {[stri
2360: 6e 67 20 63 6f 6d 70 61 72 65 20 24 72 65 73 75  ng compare $resu
2370: 6c 74 20 24 65 78 70 65 63 74 65 64 5d 7d 20 7b  lt $expected]} {
2380: 0a 20 20 20 20 70 75 74 73 20 22 5c 6e 45 78 70  .    puts "\nExp
2390: 65 63 74 65 64 3a 20 5c 5b 24 65 78 70 65 63 74  ected: \[$expect
23a0: 65 64 5c 5d 5c 6e 20 20 20 20 20 47 6f 74 3a 20  ed\]\n     Got: 
23b0: 5c 5b 24 72 65 73 75 6c 74 5c 5d 22 0a 20 20 20  \[$result\]".   
23c0: 20 66 61 69 6c 5f 74 65 73 74 20 24 6e 61 6d 65   fail_test $name
23d0: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
23e0: 70 75 74 73 20 22 20 4f 6b 22 0a 20 20 7d 0a 20  puts " Ok".  }. 
23f0: 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 7d 0a   flush stdout.}.
2400: 20 20 20 20 0a 70 72 6f 63 20 64 6f 5f 65 78 65      .proc do_exe
2410: 63 73 71 6c 5f 74 65 73 74 20 7b 74 65 73 74 6e  csql_test {testn
2420: 61 6d 65 20 73 71 6c 20 72 65 73 75 6c 74 7d 20  ame sql result} 
2430: 7b 0a 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74  {.  uplevel do_t
2440: 65 73 74 20 24 74 65 73 74 6e 61 6d 65 20 5b 6c  est $testname [l
2450: 69 73 74 20 22 65 78 65 63 73 71 6c 20 7b 24 73  ist "execsql {$s
2460: 71 6c 7d 22 5d 20 5b 6c 69 73 74 20 24 72 65 73  ql}"] [list $res
2470: 75 6c 74 5d 0a 7d 0a 70 72 6f 63 20 64 6f 5f 63  ult].}.proc do_c
2480: 61 74 63 68 73 71 6c 5f 74 65 73 74 20 7b 74 65  atchsql_test {te
2490: 73 74 6e 61 6d 65 20 73 71 6c 20 72 65 73 75 6c  stname sql resul
24a0: 74 7d 20 7b 0a 20 20 75 70 6c 65 76 65 6c 20 64  t} {.  uplevel d
24b0: 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65  o_test $testname
24c0: 20 5b 6c 69 73 74 20 22 63 61 74 63 68 73 71 6c   [list "catchsql
24d0: 20 7b 24 73 71 6c 7d 22 5d 20 5b 6c 69 73 74 20   {$sql}"] [list 
24e0: 24 72 65 73 75 6c 74 5d 0a 7d 0a 0a 0a 23 20 52  $result].}...# R
24f0: 75 6e 20 61 6e 20 53 51 4c 20 73 63 72 69 70 74  un an SQL script
2500: 2e 20 20 0a 23 20 52 65 74 75 72 6e 20 74 68 65  .  .# Return the
2510: 20 6e 75 6d 62 65 72 20 6f 66 20 6d 69 63 72 6f   number of micro
2520: 73 65 63 6f 6e 64 73 20 70 65 72 20 73 74 61 74  seconds per stat
2530: 65 6d 65 6e 74 2e 0a 23 0a 70 72 6f 63 20 73 70  ement..#.proc sp
2540: 65 65 64 5f 74 72 69 61 6c 20 7b 6e 61 6d 65 20  eed_trial {name 
2550: 6e 75 6d 73 74 6d 74 20 75 6e 69 74 73 20 73 71  numstmt units sq
2560: 6c 7d 20 7b 0a 20 20 70 75 74 73 20 2d 6e 6f 6e  l} {.  puts -non
2570: 65 77 6c 69 6e 65 20 5b 66 6f 72 6d 61 74 20 7b  ewline [format {
2580: 25 2d 32 31 2e 32 31 73 20 7d 20 24 6e 61 6d 65  %-21.21s } $name
2590: 2e 2e 2e 5d 0a 20 20 66 6c 75 73 68 20 73 74 64  ...].  flush std
25a0: 6f 75 74 0a 20 20 73 65 74 20 73 70 65 65 64 20  out.  set speed 
25b0: 5b 74 69 6d 65 20 7b 73 71 6c 69 74 65 33 5f 65  [time {sqlite3_e
25c0: 78 65 63 5f 6e 72 20 64 62 20 24 73 71 6c 7d 5d  xec_nr db $sql}]
25d0: 0a 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65  .  set tm [linde
25e0: 78 20 24 73 70 65 65 64 20 30 5d 0a 20 20 69 66  x $speed 0].  if
25f0: 20 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20 20   {$tm == 0} {.  
2600: 20 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d    set rate [form
2610: 61 74 20 25 32 30 73 20 22 6d 61 6e 79 22 5d 0a  at %20s "many"].
2620: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73    } else {.    s
2630: 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74 20  et rate [format 
2640: 25 32 30 2e 35 66 20 5b 65 78 70 72 20 7b 31 30  %20.5f [expr {10
2650: 30 30 30 30 30 2e 30 2a 24 6e 75 6d 73 74 6d 74  00000.0*$numstmt
2660: 2f 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73 65  /$tm}]].  }.  se
2670: 74 20 75 32 20 24 75 6e 69 74 73 2f 73 0a 20 20  t u2 $units/s.  
2680: 70 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25 31  puts [format {%1
2690: 32 64 20 75 53 20 25 73 20 25 73 7d 20 24 74 6d  2d uS %s %s} $tm
26a0: 20 24 72 61 74 65 20 24 75 32 5d 0a 20 20 67 6c   $rate $u2].  gl
26b0: 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a  obal total_time.
26c0: 20 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65    set total_time
26d0: 20 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f 74   [expr {$total_t
26e0: 69 6d 65 2b 24 74 6d 7d 5d 0a 7d 0a 70 72 6f 63  ime+$tm}].}.proc
26f0: 20 73 70 65 65 64 5f 74 72 69 61 6c 5f 74 63 6c   speed_trial_tcl
2700: 20 7b 6e 61 6d 65 20 6e 75 6d 73 74 6d 74 20 75   {name numstmt u
2710: 6e 69 74 73 20 73 63 72 69 70 74 7d 20 7b 0a 20  nits script} {. 
2720: 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65   puts -nonewline
2730: 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31 2e 32   [format {%-21.2
2740: 31 73 20 7d 20 24 6e 61 6d 65 2e 2e 2e 5d 0a 20  1s } $name...]. 
2750: 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 20 20   flush stdout.  
2760: 73 65 74 20 73 70 65 65 64 20 5b 74 69 6d 65 20  set speed [time 
2770: 7b 65 76 61 6c 20 24 73 63 72 69 70 74 7d 5d 0a  {eval $script}].
2780: 20 20 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78    set tm [lindex
2790: 20 24 73 70 65 65 64 20 30 5d 0a 20 20 69 66 20   $speed 0].  if 
27a0: 7b 24 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20 20 20  {$tm == 0} {.   
27b0: 20 73 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61   set rate [forma
27c0: 74 20 25 32 30 73 20 22 6d 61 6e 79 22 5d 0a 20  t %20s "many"]. 
27d0: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
27e0: 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74 20 25  t rate [format %
27f0: 32 30 2e 35 66 20 5b 65 78 70 72 20 7b 31 30 30  20.5f [expr {100
2800: 30 30 30 30 2e 30 2a 24 6e 75 6d 73 74 6d 74 2f  0000.0*$numstmt/
2810: 24 74 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73 65 74  $tm}]].  }.  set
2820: 20 75 32 20 24 75 6e 69 74 73 2f 73 0a 20 20 70   u2 $units/s.  p
2830: 75 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25 31 32  uts [format {%12
2840: 64 20 75 53 20 25 73 20 25 73 7d 20 24 74 6d 20  d uS %s %s} $tm 
2850: 24 72 61 74 65 20 24 75 32 5d 0a 20 20 67 6c 6f  $rate $u2].  glo
2860: 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20  bal total_time. 
2870: 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20   set total_time 
2880: 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f 74 69  [expr {$total_ti
2890: 6d 65 2b 24 74 6d 7d 5d 0a 7d 0a 70 72 6f 63 20  me+$tm}].}.proc 
28a0: 73 70 65 65 64 5f 74 72 69 61 6c 5f 69 6e 69 74  speed_trial_init
28b0: 20 7b 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62   {name} {.  glob
28c0: 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20  al total_time.  
28d0: 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20 30  set total_time 0
28e0: 0a 20 20 73 71 6c 69 74 65 33 20 76 65 72 73 64  .  sqlite3 versd
28f0: 62 20 3a 6d 65 6d 6f 72 79 3a 0a 20 20 73 65 74  b :memory:.  set
2900: 20 76 65 72 73 20 5b 76 65 72 73 64 62 20 6f 6e   vers [versdb on
2910: 65 20 7b 53 45 4c 45 43 54 20 73 71 6c 69 74 65  e {SELECT sqlite
2920: 5f 73 6f 75 72 63 65 5f 69 64 28 29 7d 5d 0a 20  _source_id()}]. 
2930: 20 76 65 72 73 64 62 20 63 6c 6f 73 65 0a 20 20   versdb close.  
2940: 70 75 74 73 20 22 53 51 4c 69 74 65 20 24 76 65  puts "SQLite $ve
2950: 72 73 22 0a 7d 0a 70 72 6f 63 20 73 70 65 65 64  rs".}.proc speed
2960: 5f 74 72 69 61 6c 5f 73 75 6d 6d 61 72 79 20 7b  _trial_summary {
2970: 6e 61 6d 65 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c  name} {.  global
2980: 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 70 75   total_time.  pu
2990: 74 73 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31  ts [format {%-21
29a0: 2e 32 31 73 20 25 31 32 64 20 75 53 20 54 4f 54  .21s %12d uS TOT
29b0: 41 4c 7d 20 24 6e 61 6d 65 20 24 74 6f 74 61 6c  AL} $name $total
29c0: 5f 74 69 6d 65 5d 0a 7d 0a 0a 23 20 52 75 6e 20  _time].}..# Run 
29d0: 74 68 69 73 20 72 6f 75 74 69 6e 65 20 6c 61 73  this routine las
29e0: 74 0a 23 0a 70 72 6f 63 20 66 69 6e 69 73 68 5f  t.#.proc finish_
29f0: 74 65 73 74 20 7b 7d 20 7b 0a 20 20 63 61 74 63  test {} {.  catc
2a00: 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20 63  h {db close}.  c
2a10: 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d  atch {db2 close}
2a20: 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20 63 6c  .  catch {db3 cl
2a30: 6f 73 65 7d 0a 20 20 69 66 20 7b 30 3d 3d 5b 69  ose}.  if {0==[i
2a40: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 53 4c 41  nfo exists ::SLA
2a50: 56 45 5d 7d 20 7b 20 66 69 6e 61 6c 69 7a 65 5f  VE]} { finalize_
2a60: 74 65 73 74 69 6e 67 20 7d 0a 7d 0a 70 72 6f 63  testing }.}.proc
2a70: 20 66 69 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e   finalize_testin
2a80: 67 20 7b 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20  g {} {.  global 
2a90: 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65  sqlite_open_file
2aa0: 5f 63 6f 75 6e 74 0a 0a 20 20 73 65 74 20 6f 6d  _count..  set om
2ab0: 69 74 4c 69 73 74 20 5b 73 65 74 5f 74 65 73 74  itList [set_test
2ac0: 5f 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f 6c 69  _counter omit_li
2ad0: 73 74 5d 0a 0a 20 20 63 61 74 63 68 20 7b 64 62  st]..  catch {db
2ae0: 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20   close}.  catch 
2af0: 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63 61  {db2 close}.  ca
2b00: 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65 7d 0a  tch {db3 close}.
2b10: 0a 20 20 76 66 73 5f 75 6e 6c 69 6e 6b 5f 74 65  .  vfs_unlink_te
2b20: 73 74 0a 20 20 73 71 6c 69 74 65 33 20 64 62 20  st.  sqlite3 db 
2b30: 7b 7d 0a 20 20 23 20 73 71 6c 69 74 65 33 5f 63  {}.  # sqlite3_c
2b40: 6c 65 61 72 5f 74 73 64 5f 6d 65 6d 64 65 62 75  lear_tsd_memdebu
2b50: 67 0a 20 20 64 62 20 63 6c 6f 73 65 0a 20 20 73  g.  db close.  s
2b60: 71 6c 69 74 65 33 5f 72 65 73 65 74 5f 61 75 74  qlite3_reset_aut
2b70: 6f 5f 65 78 74 65 6e 73 69 6f 6e 0a 0a 20 20 73  o_extension..  s
2b80: 71 6c 69 74 65 33 5f 73 6f 66 74 5f 68 65 61 70  qlite3_soft_heap
2b90: 5f 6c 69 6d 69 74 20 30 0a 20 20 73 65 74 20 6e  _limit 0.  set n
2ba0: 54 65 73 74 20 5b 69 6e 63 72 5f 6e 74 65 73 74  Test [incr_ntest
2bb0: 5d 0a 20 20 73 65 74 20 6e 45 72 72 20 5b 73 65  ].  set nErr [se
2bc0: 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 65  t_test_counter e
2bd0: 72 72 6f 72 73 5d 0a 0a 20 20 70 75 74 73 20 22  rrors]..  puts "
2be0: 24 6e 45 72 72 20 65 72 72 6f 72 73 20 6f 75 74  $nErr errors out
2bf0: 20 6f 66 20 24 6e 54 65 73 74 20 74 65 73 74 73   of $nTest tests
2c00: 22 0a 20 20 69 66 20 7b 24 6e 45 72 72 3e 30 7d  ".  if {$nErr>0}
2c10: 20 7b 0a 20 20 20 20 70 75 74 73 20 22 46 61 69   {.    puts "Fai
2c20: 6c 75 72 65 73 20 6f 6e 20 74 68 65 73 65 20 74  lures on these t
2c30: 65 73 74 73 3a 20 5b 73 65 74 5f 74 65 73 74 5f  ests: [set_test_
2c40: 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69 73  counter fail_lis
2c50: 74 5d 22 0a 20 20 7d 0a 20 20 72 75 6e 5f 74 68  t]".  }.  run_th
2c60: 72 65 61 64 5f 74 65 73 74 73 20 31 0a 20 20 69  read_tests 1.  i
2c70: 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 6f 6d 69  f {[llength $omi
2c80: 74 4c 69 73 74 5d 3e 30 7d 20 7b 0a 20 20 20 20  tList]>0} {.    
2c90: 70 75 74 73 20 22 4f 6d 69 74 74 65 64 20 74 65  puts "Omitted te
2ca0: 73 74 20 63 61 73 65 73 3a 22 0a 20 20 20 20 73  st cases:".    s
2cb0: 65 74 20 70 72 65 63 20 7b 7d 0a 20 20 20 20 66  et prec {}.    f
2cc0: 6f 72 65 61 63 68 20 7b 72 65 63 7d 20 5b 6c 73  oreach {rec} [ls
2cd0: 6f 72 74 20 24 6f 6d 69 74 4c 69 73 74 5d 20 7b  ort $omitList] {
2ce0: 0a 20 20 20 20 20 20 69 66 20 7b 24 72 65 63 3d  .      if {$rec=
2cf0: 3d 24 70 72 65 63 7d 20 63 6f 6e 74 69 6e 75 65  =$prec} continue
2d00: 0a 20 20 20 20 20 20 73 65 74 20 70 72 65 63 20  .      set prec 
2d10: 24 72 65 63 0a 20 20 20 20 20 20 70 75 74 73 20  $rec.      puts 
2d20: 5b 66 6f 72 6d 61 74 20 7b 20 20 25 2d 31 32 73  [format {  %-12s
2d30: 20 25 73 7d 20 5b 6c 69 6e 64 65 78 20 24 72 65   %s} [lindex $re
2d40: 63 20 30 5d 20 5b 6c 69 6e 64 65 78 20 24 72 65  c 0] [lindex $re
2d50: 63 20 31 5d 5d 0a 20 20 20 20 7d 0a 20 20 7d 0a  c 1]].    }.  }.
2d60: 20 20 69 66 20 7b 24 6e 45 72 72 3e 30 20 26 26    if {$nErr>0 &&
2d70: 20 21 5b 77 6f 72 6b 69 6e 67 5f 36 34 62 69 74   ![working_64bit
2d80: 5f 69 6e 74 5d 7d 20 7b 0a 20 20 20 20 70 75 74  _int]} {.    put
2d90: 73 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  s "*************
2da0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2db0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2dc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2dd0: 2a 2a 2a 2a 2a 22 0a 20 20 20 20 70 75 74 73 20  *****".    puts 
2de0: 22 4e 2e 42 2e 3a 20 20 54 68 65 20 76 65 72 73  "N.B.:  The vers
2df0: 69 6f 6e 20 6f 66 20 54 43 4c 20 74 68 61 74 20  ion of TCL that 
2e00: 79 6f 75 20 75 73 65 64 20 74 6f 20 62 75 69 6c  you used to buil
2e10: 64 20 74 68 69 73 20 74 65 73 74 20 68 61 72 6e  d this test harn
2e20: 65 73 73 22 0a 20 20 20 20 70 75 74 73 20 22 69  ess".    puts "i
2e30: 73 20 64 65 66 65 63 74 69 76 65 20 69 6e 20 74  s defective in t
2e40: 68 61 74 20 69 74 20 64 6f 65 73 20 6e 6f 74 20  hat it does not 
2e50: 73 75 70 70 6f 72 74 20 36 34 2d 62 69 74 20 69  support 64-bit i
2e60: 6e 74 65 67 65 72 73 2e 20 20 53 6f 6d 65 20 6f  ntegers.  Some o
2e70: 72 22 0a 20 20 20 20 70 75 74 73 20 22 61 6c 6c  r".    puts "all
2e80: 20 6f 66 20 74 68 65 20 74 65 73 74 20 66 61 69   of the test fai
2e90: 6c 75 72 65 73 20 61 62 6f 76 65 20 6d 69 67 68  lures above migh
2ea0: 74 20 62 65 20 61 20 72 65 73 75 6c 74 20 66 72  t be a result fr
2eb0: 6f 6d 20 74 68 69 73 20 64 65 66 65 63 74 22 0a  om this defect".
2ec0: 20 20 20 20 70 75 74 73 20 22 69 6e 20 79 6f 75      puts "in you
2ed0: 72 20 54 43 4c 20 62 75 69 6c 64 2e 22 0a 20 20  r TCL build.".  
2ee0: 20 20 70 75 74 73 20 22 2a 2a 2a 2a 2a 2a 2a 2a    puts "********
2ef0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 7d 0a  **********".  }.
2f30: 20 20 69 66 20 7b 24 3a 3a 63 6d 64 6c 69 6e 65    if {$::cmdline
2f40: 61 72 67 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20  arg(binarylog)} 
2f50: 7b 0a 20 20 20 20 76 66 73 6c 6f 67 20 66 69 6e  {.    vfslog fin
2f60: 61 6c 69 7a 65 20 62 69 6e 61 72 79 6c 6f 67 0a  alize binarylog.
2f70: 20 20 7d 0a 20 20 69 66 20 7b 24 73 71 6c 69 74    }.  if {$sqlit
2f80: 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e  e_open_file_coun
2f90: 74 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 24  t} {.    puts "$
2fa0: 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65  sqlite_open_file
2fb0: 5f 63 6f 75 6e 74 20 66 69 6c 65 73 20 77 65 72  _count files wer
2fc0: 65 20 6c 65 66 74 20 6f 70 65 6e 22 0a 20 20 20  e left open".   
2fd0: 20 69 6e 63 72 20 6e 45 72 72 0a 20 20 7d 0a 20   incr nErr.  }. 
2fe0: 20 69 66 20 7b 5b 73 71 6c 69 74 65 33 5f 6d 65   if {[sqlite3_me
2ff0: 6d 6f 72 79 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a  mory_used]>0} {.
3000: 20 20 20 20 70 75 74 73 20 22 55 6e 66 72 65 65      puts "Unfree
3010: 64 20 6d 65 6d 6f 72 79 3a 20 5b 73 71 6c 69 74  d memory: [sqlit
3020: 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 20  e3_memory_used] 
3030: 62 79 74 65 73 22 0a 20 20 20 20 69 6e 63 72 20  bytes".    incr 
3040: 6e 45 72 72 0a 20 20 20 20 69 66 63 61 70 61 62  nErr.    ifcapab
3050: 6c 65 20 6d 65 6d 64 65 62 75 67 7c 7c 6d 65 6d  le memdebug||mem
3060: 35 7c 7c 28 6d 65 6d 33 26 26 64 65 62 75 67 29  5||(mem3&&debug)
3070: 20 7b 0a 20 20 20 20 20 20 70 75 74 73 20 22 57   {.      puts "W
3080: 72 69 74 69 6e 67 20 75 6e 66 72 65 65 64 20 6d  riting unfreed m
3090: 65 6d 6f 72 79 20 6c 6f 67 20 74 6f 20 5c 22 2e  emory log to \".
30a0: 2f 6d 65 6d 6c 65 61 6b 2e 74 78 74 5c 22 22 0a  /memleak.txt\"".
30b0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 65        sqlite3_me
30c0: 6d 64 65 62 75 67 5f 64 75 6d 70 20 2e 2f 6d 65  mdebug_dump ./me
30d0: 6d 6c 65 61 6b 2e 74 78 74 0a 20 20 20 20 7d 0a  mleak.txt.    }.
30e0: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 70    } else {.    p
30f0: 75 74 73 20 22 41 6c 6c 20 6d 65 6d 6f 72 79 20  uts "All memory 
3100: 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 66 72 65 65  allocations free
3110: 64 20 2d 20 6e 6f 20 6c 65 61 6b 73 22 0a 20 20  d - no leaks".  
3120: 20 20 69 66 63 61 70 61 62 6c 65 20 6d 65 6d 64    ifcapable memd
3130: 65 62 75 67 7c 7c 6d 65 6d 35 20 7b 0a 20 20 20  ebug||mem5 {.   
3140: 20 20 20 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65     sqlite3_memde
3150: 62 75 67 5f 64 75 6d 70 20 2e 2f 6d 65 6d 75 73  bug_dump ./memus
3160: 61 67 65 2e 74 78 74 0a 20 20 20 20 7d 0a 20 20  age.txt.    }.  
3170: 7d 0a 20 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74  }.  show_memstat
3180: 73 0a 20 20 70 75 74 73 20 22 4d 61 78 69 6d 75  s.  puts "Maximu
3190: 6d 20 6d 65 6d 6f 72 79 20 75 73 61 67 65 3a 20  m memory usage: 
31a0: 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f  [sqlite3_memory_
31b0: 68 69 67 68 77 61 74 65 72 20 31 5d 20 62 79 74  highwater 1] byt
31c0: 65 73 22 0a 20 20 70 75 74 73 20 22 43 75 72 72  es".  puts "Curr
31d0: 65 6e 74 20 6d 65 6d 6f 72 79 20 75 73 61 67 65  ent memory usage
31e0: 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72  : [sqlite3_memor
31f0: 79 5f 68 69 67 68 77 61 74 65 72 5d 20 62 79 74  y_highwater] byt
3200: 65 73 22 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20  es".  if {[info 
3210: 63 6f 6d 6d 61 6e 64 73 20 73 71 6c 69 74 65 33  commands sqlite3
3220: 5f 6d 65 6d 64 65 62 75 67 5f 6d 61 6c 6c 6f 63  _memdebug_malloc
3230: 5f 63 6f 75 6e 74 5d 20 6e 65 20 22 22 7d 20 7b  _count] ne ""} {
3240: 0a 20 20 20 20 70 75 74 73 20 22 4e 75 6d 62 65  .    puts "Numbe
3250: 72 20 6f 66 20 6d 61 6c 6c 6f 63 28 29 20 20 3a  r of malloc()  :
3260: 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62   [sqlite3_memdeb
3270: 75 67 5f 6d 61 6c 6c 6f 63 5f 63 6f 75 6e 74 5d  ug_malloc_count]
3280: 20 63 61 6c 6c 73 22 0a 20 20 7d 0a 20 20 69 66   calls".  }.  if
3290: 20 7b 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 28   {$::cmdlinearg(
32a0: 6d 61 6c 6c 6f 63 74 72 61 63 65 29 7d 20 7b 0a  malloctrace)} {.
32b0: 20 20 20 20 70 75 74 73 20 22 57 72 69 74 69 6e      puts "Writin
32c0: 67 20 6d 61 6c 6c 6f 63 73 2e 73 71 6c 2e 2e 2e  g mallocs.sql...
32d0: 22 0a 20 20 20 20 6d 65 6d 64 65 62 75 67 5f 6c  ".    memdebug_l
32e0: 6f 67 5f 73 71 6c 0a 20 20 20 20 73 71 6c 69 74  og_sql.    sqlit
32f0: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20  e3_memdebug_log 
3300: 73 74 6f 70 0a 20 20 20 20 73 71 6c 69 74 65 33  stop.    sqlite3
3310: 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 20 63 6c  _memdebug_log cl
3320: 65 61 72 0a 0a 20 20 20 20 69 66 20 7b 5b 73 71  ear..    if {[sq
3330: 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65  lite3_memory_use
3340: 64 5d 3e 30 7d 20 7b 0a 20 20 20 20 20 20 70 75  d]>0} {.      pu
3350: 74 73 20 22 57 72 69 74 69 6e 67 20 6c 65 61 6b  ts "Writing leak
3360: 73 2e 73 71 6c 2e 2e 2e 22 0a 20 20 20 20 20 20  s.sql...".      
3370: 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67  sqlite3_memdebug
3380: 5f 6c 6f 67 20 73 79 6e 63 0a 20 20 20 20 20 20  _log sync.      
3390: 6d 65 6d 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c  memdebug_log_sql
33a0: 20 6c 65 61 6b 73 2e 73 71 6c 0a 20 20 20 20 7d   leaks.sql.    }
33b0: 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 66  .  }.  foreach f
33c0: 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61   [glob -nocompla
33d0: 69 6e 20 74 65 73 74 2e 64 62 2d 2a 2d 6a 6f 75  in test.db-*-jou
33e0: 72 6e 61 6c 5d 20 7b 0a 20 20 20 20 66 69 6c 65  rnal] {.    file
33f0: 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 24   delete -force $
3400: 66 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20  f.  }.  foreach 
3410: 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c  f [glob -nocompl
3420: 61 69 6e 20 74 65 73 74 2e 64 62 2d 6d 6a 2a 5d  ain test.db-mj*]
3430: 20 7b 0a 20 20 20 20 66 69 6c 65 20 64 65 6c 65   {.    file dele
3440: 74 65 20 2d 66 6f 72 63 65 20 24 66 0a 20 20 7d  te -force $f.  }
3450: 0a 20 20 65 78 69 74 20 5b 65 78 70 72 20 7b 24  .  exit [expr {$
3460: 6e 45 72 72 3e 30 7d 5d 0a 7d 0a 0a 23 20 44 69  nErr>0}].}..# Di
3470: 73 70 6c 61 79 20 6d 65 6d 6f 72 79 20 73 74 61  splay memory sta
3480: 74 69 73 74 69 63 73 20 66 6f 72 20 61 6e 61 6c  tistics for anal
3490: 79 73 69 73 20 61 6e 64 20 64 65 62 75 67 67 69  ysis and debuggi
34a0: 6e 67 20 70 75 72 70 6f 73 65 73 2e 0a 23 0a 70  ng purposes..#.p
34b0: 72 6f 63 20 73 68 6f 77 5f 6d 65 6d 73 74 61 74  roc show_memstat
34c0: 73 20 7b 7d 20 7b 0a 20 20 73 65 74 20 78 20 5b  s {} {.  set x [
34d0: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53  sqlite3_status S
34e0: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 45 4d  QLITE_STATUS_MEM
34f0: 4f 52 59 5f 55 53 45 44 20 30 5d 0a 20 20 73 65  ORY_USED 0].  se
3500: 74 20 79 20 5b 73 71 6c 69 74 65 33 5f 73 74 61  t y [sqlite3_sta
3510: 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55  tus SQLITE_STATU
3520: 53 5f 4d 41 4c 4c 4f 43 5f 53 49 5a 45 20 30 5d  S_MALLOC_SIZE 0]
3530: 0a 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d  .  set val [form
3540: 61 74 20 7b 6e 6f 77 20 25 31 30 64 20 20 6d 61  at {now %10d  ma
3550: 78 20 25 31 30 64 20 20 6d 61 78 2d 73 69 7a 65  x %10d  max-size
3560: 20 25 31 30 64 7d 20 5c 0a 20 20 20 20 20 20 20   %10d} \.       
3570: 20 20 20 20 20 20 20 5b 6c 69 6e 64 65 78 20 24         [lindex $
3580: 78 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20  x 1] [lindex $x 
3590: 32 5d 20 5b 6c 69 6e 64 65 78 20 24 79 20 32 5d  2] [lindex $y 2]
35a0: 5d 0a 20 20 70 75 74 73 20 22 4d 65 6d 6f 72 79  ].  puts "Memory
35b0: 20 75 73 65 64 3a 20 20 20 20 20 20 20 20 20 20   used:          
35c0: 24 76 61 6c 22 0a 20 20 73 65 74 20 78 20 5b 73  $val".  set x [s
35d0: 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51  qlite3_status SQ
35e0: 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45  LITE_STATUS_PAGE
35f0: 43 41 43 48 45 5f 55 53 45 44 20 30 5d 0a 20 20  CACHE_USED 0].  
3600: 73 65 74 20 79 20 5b 73 71 6c 69 74 65 33 5f 73  set y [sqlite3_s
3610: 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41  tatus SQLITE_STA
3620: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53 49  TUS_PAGECACHE_SI
3630: 5a 45 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20  ZE 0].  set val 
3640: 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30  [format {now %10
3650: 64 20 20 6d 61 78 20 25 31 30 64 20 20 6d 61 78  d  max %10d  max
3660: 2d 73 69 7a 65 20 25 31 30 64 7d 20 5c 0a 20 20  -size %10d} \.  
3670: 20 20 20 20 20 20 20 20 20 20 20 20 5b 6c 69 6e              [lin
3680: 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65  dex $x 1] [linde
3690: 78 20 24 78 20 32 5d 20 5b 6c 69 6e 64 65 78 20  x $x 2] [lindex 
36a0: 24 79 20 32 5d 5d 0a 20 20 70 75 74 73 20 22 50  $y 2]].  puts "P
36b0: 61 67 65 2d 63 61 63 68 65 20 75 73 65 64 3a 20  age-cache used: 
36c0: 20 20 20 20 20 24 76 61 6c 22 0a 20 20 73 65 74       $val".  set
36d0: 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74   x [sqlite3_stat
36e0: 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53  us SQLITE_STATUS
36f0: 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46  _PAGECACHE_OVERF
3700: 4c 4f 57 20 30 5d 0a 20 20 73 65 74 20 76 61 6c  LOW 0].  set val
3710: 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31   [format {now %1
3720: 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c  0d  max %10d} [l
3730: 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e  index $x 1] [lin
3740: 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 70 75 74  dex $x 2]].  put
3750: 73 20 22 50 61 67 65 2d 63 61 63 68 65 20 6f 76  s "Page-cache ov
3760: 65 72 66 6c 6f 77 3a 20 20 24 76 61 6c 22 0a 20  erflow:  $val". 
3770: 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65 33 5f   set x [sqlite3_
3780: 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54  status SQLITE_ST
3790: 41 54 55 53 5f 53 43 52 41 54 43 48 5f 55 53 45  ATUS_SCRATCH_USE
37a0: 44 20 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b  D 0].  set val [
37b0: 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64  format {now %10d
37c0: 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e    max %10d} [lin
37d0: 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65  dex $x 1] [linde
37e0: 78 20 24 78 20 32 5d 5d 0a 20 20 70 75 74 73 20  x $x 2]].  puts 
37f0: 22 53 63 72 61 74 63 68 20 6d 65 6d 6f 72 79 20  "Scratch memory 
3800: 75 73 65 64 3a 20 20 24 76 61 6c 22 0a 20 20 73  used:  $val".  s
3810: 65 74 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74  et x [sqlite3_st
3820: 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54  atus SQLITE_STAT
3830: 55 53 5f 53 43 52 41 54 43 48 5f 4f 56 45 52 46  US_SCRATCH_OVERF
3840: 4c 4f 57 20 30 5d 0a 20 20 73 65 74 20 79 20 5b  LOW 0].  set y [
3850: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53  sqlite3_status S
3860: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 53 43 52  QLITE_STATUS_SCR
3870: 41 54 43 48 5f 53 49 5a 45 20 30 5d 0a 20 20 73  ATCH_SIZE 0].  s
3880: 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b  et val [format {
3890: 6e 6f 77 20 25 31 30 64 20 20 6d 61 78 20 25 31  now %10d  max %1
38a0: 30 64 20 20 6d 61 78 2d 73 69 7a 65 20 25 31 30  0d  max-size %10
38b0: 64 7d 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20  d} \.           
38c0: 20 20 20 20 5b 6c 69 6e 64 65 78 20 24 78 20 31      [lindex $x 1
38d0: 5d 20 5b 6c 69 6e 64 65 78 20 24 78 20 32 5d 20  ] [lindex $x 2] 
38e0: 5b 6c 69 6e 64 65 78 20 24 79 20 32 5d 5d 0a 20  [lindex $y 2]]. 
38f0: 20 70 75 74 73 20 22 53 63 72 61 74 63 68 20 6f   puts "Scratch o
3900: 76 65 72 66 6c 6f 77 3a 20 20 20 20 20 24 76 61  verflow:     $va
3910: 6c 22 0a 20 20 69 66 63 61 70 61 62 6c 65 20 79  l".  ifcapable y
3920: 79 74 72 61 63 6b 6d 61 78 73 74 61 63 6b 64 65  ytrackmaxstackde
3930: 70 74 68 20 7b 0a 20 20 20 20 73 65 74 20 78 20  pth {.    set x 
3940: 5b 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20  [sqlite3_status 
3950: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
3960: 52 53 45 52 5f 53 54 41 43 4b 20 30 5d 0a 20 20  RSER_STACK 0].  
3970: 20 20 73 65 74 20 76 61 6c 20 5b 66 6f 72 6d 61    set val [forma
3980: 74 20 7b 20 20 20 20 20 20 20 20 20 20 20 20 20  t {             
3990: 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c 69 6e    max %10d} [lin
39a0: 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 20 20 70  dex $x 2]].    p
39b0: 75 74 73 20 22 50 61 72 73 65 72 20 73 74 61 63  uts "Parser stac
39c0: 6b 20 64 65 70 74 68 3a 20 20 20 20 24 76 61 6c  k depth:    $val
39d0: 22 0a 20 20 7d 0a 7d 0a 0a 23 20 41 20 70 72 6f  ".  }.}..# A pro
39e0: 63 65 64 75 72 65 20 74 6f 20 65 78 65 63 75 74  cedure to execut
39f0: 65 20 53 51 4c 0a 23 0a 70 72 6f 63 20 65 78 65  e SQL.#.proc exe
3a00: 63 73 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62  csql {sql {db db
3a10: 7d 7d 20 7b 0a 20 20 23 20 70 75 74 73 20 22 53  }} {.  # puts "S
3a20: 51 4c 20 3d 20 24 73 71 6c 22 0a 20 20 75 70 6c  QL = $sql".  upl
3a30: 65 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65  evel [list $db e
3a40: 76 61 6c 20 24 73 71 6c 5d 0a 7d 0a 0a 23 20 45  val $sql].}..# E
3a50: 78 65 63 75 74 65 20 53 51 4c 20 61 6e 64 20 63  xecute SQL and c
3a60: 61 74 63 68 20 65 78 63 65 70 74 69 6f 6e 73 2e  atch exceptions.
3a70: 0a 23 0a 70 72 6f 63 20 63 61 74 63 68 73 71 6c  .#.proc catchsql
3a80: 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b   {sql {db db}} {
3a90: 0a 20 20 23 20 70 75 74 73 20 22 53 51 4c 20 3d  .  # puts "SQL =
3aa0: 20 24 73 71 6c 22 0a 20 20 73 65 74 20 72 20 5b   $sql".  set r [
3ab0: 63 61 74 63 68 20 5b 6c 69 73 74 20 75 70 6c 65  catch [list uple
3ac0: 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20 65 76  vel [list $db ev
3ad0: 61 6c 20 24 73 71 6c 5d 5d 20 6d 73 67 5d 0a 20  al $sql]] msg]. 
3ae0: 20 6c 61 70 70 65 6e 64 20 72 20 24 6d 73 67 0a   lappend r $msg.
3af0: 20 20 72 65 74 75 72 6e 20 24 72 0a 7d 0a 0a 23    return $r.}..#
3b00: 20 44 6f 20 61 6e 20 56 44 42 45 20 63 6f 64 65   Do an VDBE code
3b10: 20 64 75 6d 70 20 6f 6e 20 74 68 65 20 53 51 4c   dump on the SQL
3b20: 20 67 69 76 65 6e 0a 23 0a 70 72 6f 63 20 65 78   given.#.proc ex
3b30: 70 6c 61 69 6e 20 7b 73 71 6c 20 7b 64 62 20 64  plain {sql {db d
3b40: 62 7d 7d 20 7b 0a 20 20 70 75 74 73 20 22 22 0a  b}} {.  puts "".
3b50: 20 20 70 75 74 73 20 22 61 64 64 72 20 20 6f 70    puts "addr  op
3b60: 63 6f 64 65 20 20 20 20 20 20 20 20 70 31 20 20  code        p1  
3b70: 20 20 20 20 70 32 20 20 20 20 20 20 70 33 20 20      p2      p3  
3b80: 20 20 20 20 70 34 20 20 20 20 20 20 20 20 20 20      p4          
3b90: 20 20 20 20 20 70 35 20 20 23 22 0a 20 20 70 75       p5  #".  pu
3ba0: 74 73 20 22 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d  ts "----  ------
3bb0: 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20  ------  ------  
3bc0: 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20  ------  ------  
3bd0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20  --------------- 
3be0: 20 2d 2d 20 20 2d 22 0a 20 20 24 64 62 20 65 76   --  -".  $db ev
3bf0: 61 6c 20 22 65 78 70 6c 61 69 6e 20 24 73 71 6c  al "explain $sql
3c00: 22 20 7b 7d 20 7b 0a 20 20 20 20 70 75 74 73 20  " {} {.    puts 
3c10: 5b 66 6f 72 6d 61 74 20 7b 25 2d 34 64 20 20 25  [format {%-4d  %
3c20: 2d 31 32 2e 31 32 73 20 20 25 2d 36 64 20 20 25  -12.12s  %-6d  %
3c30: 2d 36 64 20 20 25 2d 36 64 20 20 25 20 2d 31 37  -6d  %-6d  % -17
3c40: 73 20 25 73 20 20 25 73 7d 20 5c 0a 20 20 20 20  s %s  %s} \.    
3c50: 20 20 24 61 64 64 72 20 24 6f 70 63 6f 64 65 20    $addr $opcode 
3c60: 24 70 31 20 24 70 32 20 24 70 33 20 24 70 34 20  $p1 $p2 $p3 $p4 
3c70: 24 70 35 20 24 63 6f 6d 6d 65 6e 74 0a 20 20 20  $p5 $comment.   
3c80: 20 5d 0a 20 20 7d 0a 7d 0a 0a 23 20 53 68 6f 77   ].  }.}..# Show
3c90: 20 74 68 65 20 56 44 42 45 20 70 72 6f 67 72 61   the VDBE progra
3ca0: 6d 20 66 6f 72 20 61 6e 20 53 51 4c 20 73 74 61  m for an SQL sta
3cb0: 74 65 6d 65 6e 74 20 62 75 74 20 6f 6d 69 74 20  tement but omit 
3cc0: 74 68 65 20 54 72 61 63 65 0a 23 20 6f 70 63 6f  the Trace.# opco
3cd0: 64 65 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e  de at the beginn
3ce0: 69 6e 67 2e 20 20 54 68 69 73 20 70 72 6f 63 65  ing.  This proce
3cf0: 64 75 72 65 20 63 61 6e 20 62 65 20 75 73 65 64  dure can be used
3d00: 20 74 6f 20 70 72 6f 76 65 0a 23 20 74 68 61 74   to prove.# that
3d10: 20 64 69 66 66 65 72 65 6e 74 20 53 51 4c 20 73   different SQL s
3d20: 74 61 74 65 6d 65 6e 74 73 20 67 65 6e 65 72 61  tatements genera
3d30: 74 65 20 65 78 61 63 74 6c 79 20 74 68 65 20 73  te exactly the s
3d40: 61 6d 65 20 56 44 42 45 20 63 6f 64 65 2e 0a 23  ame VDBE code..#
3d50: 0a 70 72 6f 63 20 65 78 70 6c 61 69 6e 5f 6e 6f  .proc explain_no
3d60: 5f 74 72 61 63 65 20 7b 73 71 6c 7d 20 7b 0a 20  _trace {sql} {. 
3d70: 20 73 65 74 20 74 72 20 5b 64 62 20 65 76 61 6c   set tr [db eval
3d80: 20 22 45 58 50 4c 41 49 4e 20 24 73 71 6c 22 5d   "EXPLAIN $sql"]
3d90: 0a 20 20 72 65 74 75 72 6e 20 5b 6c 72 61 6e 67  .  return [lrang
3da0: 65 20 24 74 72 20 37 20 65 6e 64 5d 0a 7d 0a 0a  e $tr 7 end].}..
3db0: 23 20 41 6e 6f 74 68 65 72 20 70 72 6f 63 65 64  # Another proced
3dc0: 75 72 65 20 74 6f 20 65 78 65 63 75 74 65 20 53  ure to execute S
3dd0: 51 4c 2e 20 20 54 68 69 73 20 6f 6e 65 20 69 6e  QL.  This one in
3de0: 63 6c 75 64 65 73 20 74 68 65 20 66 69 65 6c 64  cludes the field
3df0: 0a 23 20 6e 61 6d 65 73 20 69 6e 20 74 68 65 20  .# names in the 
3e00: 72 65 74 75 72 6e 65 64 20 6c 69 73 74 2e 0a 23  returned list..#
3e10: 0a 70 72 6f 63 20 65 78 65 63 73 71 6c 32 20 7b  .proc execsql2 {
3e20: 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 72 65 73  sql} {.  set res
3e30: 75 6c 74 20 7b 7d 0a 20 20 64 62 20 65 76 61 6c  ult {}.  db eval
3e40: 20 24 73 71 6c 20 64 61 74 61 20 7b 0a 20 20 20   $sql data {.   
3e50: 20 66 6f 72 65 61 63 68 20 66 20 24 64 61 74 61   foreach f $data
3e60: 28 2a 29 20 7b 0a 20 20 20 20 20 20 6c 61 70 70  (*) {.      lapp
3e70: 65 6e 64 20 72 65 73 75 6c 74 20 24 66 20 24 64  end result $f $d
3e80: 61 74 61 28 24 66 29 0a 20 20 20 20 7d 0a 20 20  ata($f).    }.  
3e90: 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 65 73 75  }.  return $resu
3ea0: 6c 74 0a 7d 0a 0a 23 20 55 73 65 20 74 68 65 20  lt.}..# Use the 
3eb0: 6e 6f 6e 2d 63 61 6c 6c 62 61 63 6b 20 41 50 49  non-callback API
3ec0: 20 74 6f 20 65 78 65 63 75 74 65 20 6d 75 6c 74   to execute mult
3ed0: 69 70 6c 65 20 53 51 4c 20 73 74 61 74 65 6d 65  iple SQL stateme
3ee0: 6e 74 73 0a 23 0a 70 72 6f 63 20 73 74 65 70 73  nts.#.proc steps
3ef0: 71 6c 20 7b 64 62 70 74 72 20 73 71 6c 7d 20 7b  ql {dbptr sql} {
3f00: 0a 20 20 73 65 74 20 73 71 6c 20 5b 73 74 72 69  .  set sql [stri
3f10: 6e 67 20 74 72 69 6d 20 24 73 71 6c 5d 0a 20 20  ng trim $sql].  
3f20: 73 65 74 20 72 20 30 0a 20 20 77 68 69 6c 65 20  set r 0.  while 
3f30: 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20  {[string length 
3f40: 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20 69  $sql]>0} {.    i
3f50: 66 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74  f {[catch {sqlit
3f60: 65 33 5f 70 72 65 70 61 72 65 20 24 64 62 70 74  e3_prepare $dbpt
3f70: 72 20 24 73 71 6c 20 2d 31 20 73 71 6c 74 61 69  r $sql -1 sqltai
3f80: 6c 7d 20 76 6d 5d 7d 20 7b 0a 20 20 20 20 20 20  l} vm]} {.      
3f90: 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31 20 24  return [list 1 $
3fa0: 76 6d 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73 65  vm].    }.    se
3fb0: 74 20 73 71 6c 20 5b 73 74 72 69 6e 67 20 74 72  t sql [string tr
3fc0: 69 6d 20 24 73 71 6c 74 61 69 6c 5d 0a 23 20 20  im $sqltail].#  
3fd0: 20 20 77 68 69 6c 65 20 7b 5b 73 71 6c 69 74 65    while {[sqlite
3fe0: 5f 73 74 65 70 20 24 76 6d 20 4e 20 56 41 4c 20  _step $vm N VAL 
3ff0: 43 4f 4c 5d 3d 3d 22 53 51 4c 49 54 45 5f 52 4f  COL]=="SQLITE_RO
4000: 57 22 7d 20 7b 0a 23 20 20 20 20 20 20 66 6f 72  W"} {.#      for
4010: 65 61 63 68 20 76 20 24 56 41 4c 20 7b 6c 61 70  each v $VAL {lap
4020: 70 65 6e 64 20 72 20 24 76 7d 0a 23 20 20 20 20  pend r $v}.#    
4030: 7d 0a 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 71  }.    while {[sq
4040: 6c 69 74 65 33 5f 73 74 65 70 20 24 76 6d 5d 3d  lite3_step $vm]=
4050: 3d 22 53 51 4c 49 54 45 5f 52 4f 57 22 7d 20 7b  ="SQLITE_ROW"} {
4060: 0a 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20  .      for {set 
4070: 69 20 30 7d 20 7b 24 69 3c 5b 73 71 6c 69 74 65  i 0} {$i<[sqlite
4080: 33 5f 64 61 74 61 5f 63 6f 75 6e 74 20 24 76 6d  3_data_count $vm
4090: 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  ]} {incr i} {.  
40a0: 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20 72 20        lappend r 
40b0: 5b 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f  [sqlite3_column_
40c0: 74 65 78 74 20 24 76 6d 20 24 69 5d 0a 20 20 20  text $vm $i].   
40d0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
40e0: 66 20 7b 5b 63 61 74 63 68 20 7b 73 71 6c 69 74  f {[catch {sqlit
40f0: 65 33 5f 66 69 6e 61 6c 69 7a 65 20 24 76 6d 7d  e3_finalize $vm}
4100: 20 65 72 72 6d 73 67 5d 7d 20 7b 0a 20 20 20 20   errmsg]} {.    
4110: 20 20 72 65 74 75 72 6e 20 5b 6c 69 73 74 20 31    return [list 1
4120: 20 24 65 72 72 6d 73 67 5d 0a 20 20 20 20 7d 0a   $errmsg].    }.
4130: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 0a    }.  return $r.
4140: 7d 0a 0a 23 20 44 65 6c 65 74 65 20 61 20 66 69  }..# Delete a fi
4150: 6c 65 20 6f 72 20 64 69 72 65 63 74 6f 72 79 0a  le or directory.
4160: 23 0a 70 72 6f 63 20 66 6f 72 63 65 64 65 6c 65  #.proc forcedele
4170: 74 65 20 7b 66 69 6c 65 6e 61 6d 65 7d 20 7b 0a  te {filename} {.
4180: 20 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 66 69    if {[catch {fi
4190: 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65  le delete -force
41a0: 20 24 66 69 6c 65 6e 61 6d 65 7d 5d 7d 20 7b 0a   $filename}]} {.
41b0: 20 20 20 20 65 78 65 63 20 72 6d 20 2d 72 66 20      exec rm -rf 
41c0: 24 66 69 6c 65 6e 61 6d 65 0a 20 20 7d 0a 7d 0a  $filename.  }.}.
41d0: 0a 23 20 44 6f 20 61 6e 20 69 6e 74 65 67 72 69  .# Do an integri
41e0: 74 79 20 63 68 65 63 6b 20 6f 66 20 74 68 65 20  ty check of the 
41f0: 65 6e 74 69 72 65 20 64 61 74 61 62 61 73 65 0a  entire database.
4200: 23 0a 70 72 6f 63 20 69 6e 74 65 67 72 69 74 79  #.proc integrity
4210: 5f 63 68 65 63 6b 20 7b 6e 61 6d 65 20 7b 64 62  _check {name {db
4220: 20 64 62 7d 7d 20 7b 0a 20 20 69 66 63 61 70 61   db}} {.  ifcapa
4230: 62 6c 65 20 69 6e 74 65 67 72 69 74 79 63 6b 20  ble integrityck 
4240: 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24 6e  {.    do_test $n
4250: 61 6d 65 20 5b 6c 69 73 74 20 65 78 65 63 73 71  ame [list execsq
4260: 6c 20 7b 50 52 41 47 4d 41 20 69 6e 74 65 67 72  l {PRAGMA integr
4270: 69 74 79 5f 63 68 65 63 6b 7d 20 24 64 62 5d 20  ity_check} $db] 
4280: 7b 6f 6b 7d 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63  {ok}.  }.}..proc
4290: 20 66 69 78 5f 69 66 63 61 70 61 62 6c 65 5f 65   fix_ifcapable_e
42a0: 78 70 72 20 7b 65 78 70 72 7d 20 7b 0a 20 20 73  xpr {expr} {.  s
42b0: 65 74 20 72 65 74 20 22 22 0a 20 20 73 65 74 20  et ret "".  set 
42c0: 73 74 61 74 65 20 30 0a 20 20 66 6f 72 20 7b 73  state 0.  for {s
42d0: 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 5b 73  et i 0} {$i < [s
42e0: 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 65 78  tring length $ex
42f0: 70 72 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a  pr]} {incr i} {.
4300: 20 20 20 20 73 65 74 20 63 68 61 72 20 5b 73 74      set char [st
4310: 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78 70 72  ring range $expr
4320: 20 24 69 20 24 69 5d 0a 20 20 20 20 73 65 74 20   $i $i].    set 
4330: 6e 65 77 73 74 61 74 65 20 5b 65 78 70 72 20 7b  newstate [expr {
4340: 5b 73 74 72 69 6e 67 20 69 73 20 61 6c 6e 75 6d  [string is alnum
4350: 20 24 63 68 61 72 5d 20 7c 7c 20 24 63 68 61 72   $char] || $char
4360: 20 65 71 20 22 5f 22 7d 5d 0a 20 20 20 20 69 66   eq "_"}].    if
4370: 20 7b 24 6e 65 77 73 74 61 74 65 20 26 26 20 21   {$newstate && !
4380: 24 73 74 61 74 65 7d 20 7b 0a 20 20 20 20 20 20  $state} {.      
4390: 61 70 70 65 6e 64 20 72 65 74 20 7b 24 3a 3a 73  append ret {$::s
43a0: 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28 7d 0a  qlite_options(}.
43b0: 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 21 24      }.    if {!$
43c0: 6e 65 77 73 74 61 74 65 20 26 26 20 24 73 74 61  newstate && $sta
43d0: 74 65 7d 20 7b 0a 20 20 20 20 20 20 61 70 70 65  te} {.      appe
43e0: 6e 64 20 72 65 74 20 29 0a 20 20 20 20 7d 0a 20  nd ret ).    }. 
43f0: 20 20 20 61 70 70 65 6e 64 20 72 65 74 20 24 63     append ret $c
4400: 68 61 72 0a 20 20 20 20 73 65 74 20 73 74 61 74  har.    set stat
4410: 65 20 24 6e 65 77 73 74 61 74 65 0a 20 20 7d 0a  e $newstate.  }.
4420: 20 20 69 66 20 7b 24 73 74 61 74 65 7d 20 7b 61    if {$state} {a
4430: 70 70 65 6e 64 20 72 65 74 20 29 7d 0a 20 20 72  ppend ret )}.  r
4440: 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a 0a 23 20  eturn $ret.}..# 
4450: 45 76 61 6c 75 61 74 65 20 61 20 62 6f 6f 6c 65  Evaluate a boole
4460: 61 6e 20 65 78 70 72 65 73 73 69 6f 6e 20 6f 66  an expression of
4470: 20 63 61 70 61 62 69 6c 69 74 69 65 73 2e 20 20   capabilities.  
4480: 49 66 20 74 72 75 65 2c 20 65 78 65 63 75 74 65  If true, execute
4490: 20 74 68 65 0a 23 20 63 6f 64 65 2e 20 20 4f 6d   the.# code.  Om
44a0: 69 74 20 74 68 65 20 63 6f 64 65 20 69 66 20 66  it the code if f
44b0: 61 6c 73 65 2e 0a 23 0a 70 72 6f 63 20 69 66 63  alse..#.proc ifc
44c0: 61 70 61 62 6c 65 20 7b 65 78 70 72 20 63 6f 64  apable {expr cod
44d0: 65 20 7b 65 6c 73 65 20 22 22 7d 20 7b 65 6c 73  e {else ""} {els
44e0: 65 63 6f 64 65 20 22 22 7d 7d 20 7b 0a 20 20 23  ecode ""}} {.  #
44f0: 72 65 67 73 75 62 20 2d 61 6c 6c 20 7b 5b 61 2d  regsub -all {[a-
4500: 7a 5f 30 2d 39 5d 2b 7d 20 24 65 78 70 72 20 7b  z_0-9]+} $expr {
4510: 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e  $::sqlite_option
4520: 73 28 26 29 7d 20 65 32 0a 20 20 73 65 74 20 65  s(&)} e2.  set e
4530: 32 20 5b 66 69 78 5f 69 66 63 61 70 61 62 6c 65  2 [fix_ifcapable
4540: 5f 65 78 70 72 20 24 65 78 70 72 5d 0a 20 20 69  _expr $expr].  i
4550: 66 20 28 24 65 32 29 20 7b 0a 20 20 20 20 73 65  f ($e2) {.    se
4560: 74 20 63 20 5b 63 61 74 63 68 20 7b 75 70 6c 65  t c [catch {uple
4570: 76 65 6c 20 31 20 24 63 6f 64 65 7d 20 72 5d 0a  vel 1 $code} r].
4580: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73    } else {.    s
4590: 65 74 20 63 20 5b 63 61 74 63 68 20 7b 75 70 6c  et c [catch {upl
45a0: 65 76 65 6c 20 31 20 24 65 6c 73 65 63 6f 64 65  evel 1 $elsecode
45b0: 7d 20 72 5d 0a 20 20 7d 0a 20 20 72 65 74 75 72  } r].  }.  retur
45c0: 6e 20 2d 63 6f 64 65 20 24 63 20 24 72 0a 7d 0a  n -code $c $r.}.
45d0: 0a 23 20 54 68 69 73 20 70 72 6f 63 20 65 78 65  .# This proc exe
45e0: 63 73 20 61 20 73 65 70 65 72 61 74 65 20 70 72  cs a seperate pr
45f0: 6f 63 65 73 73 20 74 68 61 74 20 63 72 61 73 68  ocess that crash
4600: 65 73 20 6d 69 64 77 61 79 20 74 68 72 6f 75 67  es midway throug
4610: 68 20 65 78 65 63 75 74 69 6e 67 0a 23 20 74 68  h executing.# th
4620: 65 20 53 51 4c 20 73 63 72 69 70 74 20 24 73 71  e SQL script $sq
4630: 6c 20 6f 6e 20 64 61 74 61 62 61 73 65 20 74 65  l on database te
4640: 73 74 2e 64 62 2e 0a 23 0a 23 20 54 68 65 20 63  st.db..#.# The c
4650: 72 61 73 68 20 6f 63 63 75 72 73 20 64 75 72 69  rash occurs duri
4660: 6e 67 20 61 20 73 79 6e 63 28 29 20 6f 66 20 66  ng a sync() of f
4670: 69 6c 65 20 24 63 72 61 73 68 66 69 6c 65 2e 20  ile $crashfile. 
4680: 57 68 65 6e 20 74 68 65 20 63 72 61 73 68 0a 23  When the crash.#
4690: 20 6f 63 63 75 72 73 20 61 20 72 61 6e 64 6f 6d   occurs a random
46a0: 20 73 75 62 73 65 74 20 6f 66 20 61 6c 6c 20 75   subset of all u
46b0: 6e 73 79 6e 63 65 64 20 77 72 69 74 65 73 20 6d  nsynced writes m
46c0: 61 64 65 20 62 79 20 74 68 65 20 70 72 6f 63 65  ade by the proce
46d0: 73 73 20 61 72 65 0a 23 20 77 72 69 74 74 65 6e  ss are.# written
46e0: 20 69 6e 74 6f 20 74 68 65 20 66 69 6c 65 73 20   into the files 
46f0: 6f 6e 20 64 69 73 6b 2e 20 41 72 67 75 6d 65 6e  on disk. Argumen
4700: 74 20 24 63 72 61 73 68 64 65 6c 61 79 20 69 6e  t $crashdelay in
4710: 64 69 63 61 74 65 73 20 74 68 65 0a 23 20 6e 75  dicates the.# nu
4720: 6d 62 65 72 20 6f 66 20 66 69 6c 65 20 73 79 6e  mber of file syn
4730: 63 73 20 74 6f 20 77 61 69 74 20 62 65 66 6f 72  cs to wait befor
4740: 65 20 63 72 61 73 68 69 6e 67 2e 0a 23 0a 23 20  e crashing..#.# 
4750: 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65  The return value
4760: 20 69 73 20 61 20 6c 69 73 74 20 6f 66 20 74 77   is a list of tw
4770: 6f 20 65 6c 65 6d 65 6e 74 73 2e 20 54 68 65 20  o elements. The 
4780: 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 20 69 73  first element is
4790: 20 61 0a 23 20 62 6f 6f 6c 65 61 6e 2c 20 69 6e   a.# boolean, in
47a0: 64 69 63 61 74 69 6e 67 20 77 68 65 74 68 65 72  dicating whether
47b0: 20 6f 72 20 6e 6f 74 20 74 68 65 20 70 72 6f 63   or not the proc
47c0: 65 73 73 20 61 63 74 75 61 6c 6c 79 20 63 72 61  ess actually cra
47d0: 73 68 65 64 20 6f 72 0a 23 20 72 65 70 6f 72 74  shed or.# report
47e0: 65 64 20 73 6f 6d 65 20 6f 74 68 65 72 20 65 72  ed some other er
47f0: 72 6f 72 2e 20 54 68 65 20 73 65 63 6f 6e 64 20  ror. The second 
4800: 65 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65 20 72  element in the r
4810: 65 74 75 72 6e 65 64 20 6c 69 73 74 20 69 73 20  eturned list is 
4820: 74 68 65 0a 23 20 65 72 72 6f 72 20 6d 65 73 73  the.# error mess
4830: 61 67 65 2e 20 54 68 69 73 20 69 73 20 22 63 68  age. This is "ch
4840: 69 6c 64 20 70 72 6f 63 65 73 73 20 65 78 69 74  ild process exit
4850: 65 64 20 61 62 6e 6f 72 6d 61 6c 6c 79 22 20 69  ed abnormally" i
4860: 66 20 74 68 65 20 63 72 61 73 68 0a 23 20 6f 63  f the crash.# oc
4870: 63 75 72 65 64 2e 0a 23 0a 23 20 20 20 63 72 61  cured..#.#   cra
4880: 73 68 73 71 6c 20 2d 64 65 6c 61 79 20 43 52 41  shsql -delay CRA
4890: 53 48 44 45 4c 41 59 20 2d 66 69 6c 65 20 43 52  SHDELAY -file CR
48a0: 41 53 48 46 49 4c 45 20 3f 2d 62 6c 6f 63 6b 73  ASHFILE ?-blocks
48b0: 69 7a 65 20 42 4c 4f 43 4b 53 49 5a 45 3f 20 24  ize BLOCKSIZE? $
48c0: 73 71 6c 0a 23 0a 70 72 6f 63 20 63 72 61 73 68  sql.#.proc crash
48d0: 73 71 6c 20 7b 61 72 67 73 7d 20 7b 0a 0a 20 20  sql {args} {..  
48e0: 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65 20 22 22  set blocksize ""
48f0: 0a 20 20 73 65 74 20 63 72 61 73 68 64 65 6c 61  .  set crashdela
4900: 79 20 31 0a 20 20 73 65 74 20 70 72 6e 67 73 65  y 1.  set prngse
4910: 65 64 20 30 0a 20 20 73 65 74 20 74 63 6c 62 6f  ed 0.  set tclbo
4920: 64 79 20 7b 7d 0a 20 20 73 65 74 20 63 72 61 73  dy {}.  set cras
4930: 68 66 69 6c 65 20 22 22 0a 20 20 73 65 74 20 64  hfile "".  set d
4940: 63 20 22 22 0a 20 20 73 65 74 20 73 71 6c 20 5b  c "".  set sql [
4950: 6c 69 6e 64 65 78 20 24 61 72 67 73 20 65 6e 64  lindex $args end
4960: 5d 0a 20 20 0a 20 20 66 6f 72 20 7b 73 65 74 20  ].  .  for {set 
4970: 69 69 20 30 7d 20 7b 24 69 69 20 3c 20 5b 6c 6c  ii 0} {$ii < [ll
4980: 65 6e 67 74 68 20 24 61 72 67 73 5d 2d 31 7d 20  ength $args]-1} 
4990: 7b 69 6e 63 72 20 69 69 20 32 7d 20 7b 0a 20 20  {incr ii 2} {.  
49a0: 20 20 73 65 74 20 7a 20 5b 6c 69 6e 64 65 78 20    set z [lindex 
49b0: 24 61 72 67 73 20 24 69 69 5d 0a 20 20 20 20 73  $args $ii].    s
49c0: 65 74 20 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e  et n [string len
49d0: 67 74 68 20 24 7a 5d 0a 20 20 20 20 73 65 74 20  gth $z].    set 
49e0: 7a 32 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 73  z2 [lindex $args
49f0: 20 5b 65 78 70 72 20 24 69 69 2b 31 5d 5d 0a 0a   [expr $ii+1]]..
4a00: 20 20 20 20 69 66 20 20 20 20 20 7b 24 6e 3e 31      if     {$n>1
4a10: 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73   && [string firs
4a20: 74 20 24 7a 20 2d 64 65 6c 61 79 5d 3d 3d 30 7d  t $z -delay]==0}
4a30: 20 20 20 20 20 7b 73 65 74 20 63 72 61 73 68 64       {set crashd
4a40: 65 6c 61 79 20 24 7a 32 7d 20 5c 0a 20 20 20 20  elay $z2} \.    
4a50: 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26 20  elseif {$n>1 && 
4a60: 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a  [string first $z
4a70: 20 2d 73 65 65 64 5d 3d 3d 30 7d 20 20 20 20 20   -seed]==0}     
4a80: 20 7b 73 65 74 20 70 72 6e 67 73 65 65 64 20 24   {set prngseed $
4a90: 7a 32 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69 66  z2} \.    elseif
4aa0: 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e   {$n>1 && [strin
4ab0: 67 20 66 69 72 73 74 20 24 7a 20 2d 66 69 6c 65  g first $z -file
4ac0: 5d 3d 3d 30 7d 20 20 20 20 20 20 7b 73 65 74 20  ]==0}      {set 
4ad0: 63 72 61 73 68 66 69 6c 65 20 24 7a 32 7d 20 20  crashfile $z2}  
4ae0: 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e  \.    elseif {$n
4af0: 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69  >1 && [string fi
4b00: 72 73 74 20 24 7a 20 2d 74 63 6c 62 6f 64 79 5d  rst $z -tclbody]
4b10: 3d 3d 30 7d 20 20 20 7b 73 65 74 20 74 63 6c 62  ==0}   {set tclb
4b20: 6f 64 79 20 24 7a 32 7d 20 20 5c 0a 20 20 20 20  ody $z2}  \.    
4b30: 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26 20  elseif {$n>1 && 
4b40: 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a  [string first $z
4b50: 20 2d 62 6c 6f 63 6b 73 69 7a 65 5d 3d 3d 30 7d   -blocksize]==0}
4b60: 20 7b 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65 20   {set blocksize 
4b70: 22 2d 73 20 24 7a 32 22 20 7d 20 5c 0a 20 20 20  "-s $z2" } \.   
4b80: 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26   elseif {$n>1 &&
4b90: 20 5b 73 74 72 69 6e 67 20 66 69 72 73 74 20 24   [string first $
4ba0: 7a 20 2d 63 68 61 72 61 63 74 65 72 69 73 74 69  z -characteristi
4bb0: 63 73 5d 3d 3d 30 7d 20 7b 73 65 74 20 64 63 20  cs]==0} {set dc 
4bc0: 22 2d 63 20 7b 24 7a 32 7d 22 20 7d 20 5c 0a 20  "-c {$z2}" } \. 
4bd0: 20 20 20 65 6c 73 65 20 20 20 7b 20 65 72 72 6f     else   { erro
4be0: 72 20 22 55 6e 72 65 63 6f 67 6e 69 7a 65 64 20  r "Unrecognized 
4bf0: 6f 70 74 69 6f 6e 3a 20 24 7a 22 20 7d 0a 20 20  option: $z" }.  
4c00: 7d 0a 0a 20 20 69 66 20 7b 24 63 72 61 73 68 66  }..  if {$crashf
4c10: 69 6c 65 20 65 71 20 22 22 7d 20 7b 0a 20 20 20  ile eq ""} {.   
4c20: 20 65 72 72 6f 72 20 22 43 6f 6d 70 75 6c 73 6f   error "Compulso
4c30: 72 79 20 6f 70 74 69 6f 6e 20 2d 66 69 6c 65 20  ry option -file 
4c40: 6d 69 73 73 69 6e 67 22 0a 20 20 7d 0a 0a 20 20  missing".  }..  
4c50: 23 20 24 63 72 61 73 68 66 69 6c 65 20 67 65 74  # $crashfile get
4c60: 73 20 63 6f 6d 70 61 72 65 64 20 74 6f 20 74 68  s compared to th
4c70: 65 20 6e 61 74 69 76 65 20 66 69 6c 65 6e 61 6d  e native filenam
4c80: 65 20 69 6e 20 0a 20 20 23 20 63 66 53 79 6e 63  e in .  # cfSync
4c90: 28 29 2c 20 77 68 69 63 68 20 63 61 6e 20 62 65  (), which can be
4ca0: 20 64 69 66 66 65 72 65 6e 74 20 74 68 65 6e 20   different then 
4cb0: 77 68 61 74 20 54 43 4c 20 75 73 65 73 20 62 79  what TCL uses by
4cc0: 0a 20 20 23 20 64 65 66 61 75 6c 74 2c 20 73 6f  .  # default, so
4cd0: 20 68 65 72 65 20 77 65 20 66 6f 72 63 65 20 69   here we force i
4ce0: 74 20 74 6f 20 74 68 65 20 22 6e 61 74 69 76 65  t to the "native
4cf0: 6e 61 6d 65 22 20 66 6f 72 6d 61 74 2e 0a 20 20  name" format..  
4d00: 73 65 74 20 63 66 69 6c 65 20 5b 73 74 72 69 6e  set cfile [strin
4d10: 67 20 6d 61 70 20 7b 5c 5c 20 5c 5c 5c 5c 7d 20  g map {\\ \\\\} 
4d20: 5b 66 69 6c 65 20 6e 61 74 69 76 65 6e 61 6d 65  [file nativename
4d30: 20 5b 66 69 6c 65 20 6a 6f 69 6e 20 5b 70 77 64   [file join [pwd
4d40: 5d 20 24 63 72 61 73 68 66 69 6c 65 5d 5d 5d 0a  ] $crashfile]]].
4d50: 0a 20 20 73 65 74 20 66 20 5b 6f 70 65 6e 20 63  .  set f [open c
4d60: 72 61 73 68 2e 74 63 6c 20 77 5d 0a 20 20 70 75  rash.tcl w].  pu
4d70: 74 73 20 24 66 20 22 73 71 6c 69 74 65 33 5f 63  ts $f "sqlite3_c
4d80: 72 61 73 68 5f 65 6e 61 62 6c 65 20 31 22 0a 20  rash_enable 1". 
4d90: 20 70 75 74 73 20 24 66 20 22 73 71 6c 69 74 65   puts $f "sqlite
4da0: 33 5f 63 72 61 73 68 70 61 72 61 6d 73 20 24 62  3_crashparams $b
4db0: 6c 6f 63 6b 73 69 7a 65 20 24 64 63 20 24 63 72  locksize $dc $cr
4dc0: 61 73 68 64 65 6c 61 79 20 24 63 66 69 6c 65 22  ashdelay $cfile"
4dd0: 0a 20 20 70 75 74 73 20 24 66 20 22 73 71 6c 69  .  puts $f "sqli
4de0: 74 65 33 5f 74 65 73 74 5f 63 6f 6e 74 72 6f 6c  te3_test_control
4df0: 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 20 24 3a  _pending_byte $:
4e00: 3a 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67 5f  :sqlite_pending_
4e10: 62 79 74 65 22 0a 20 20 70 75 74 73 20 24 66 20  byte".  puts $f 
4e20: 22 73 71 6c 69 74 65 33 20 64 62 20 74 65 73 74  "sqlite3 db test
4e30: 2e 64 62 20 2d 76 66 73 20 63 72 61 73 68 22 0a  .db -vfs crash".
4e40: 0a 20 20 23 20 54 68 69 73 20 62 6c 6f 63 6b 20  .  # This block 
4e50: 73 65 74 73 20 74 68 65 20 63 61 63 68 65 20 73  sets the cache s
4e60: 69 7a 65 20 6f 66 20 74 68 65 20 6d 61 69 6e 20  ize of the main 
4e70: 64 61 74 61 62 61 73 65 20 74 6f 20 31 30 0a 20  database to 10. 
4e80: 20 23 20 70 61 67 65 73 2e 20 54 68 69 73 20 69   # pages. This i
4e90: 73 20 64 6f 6e 65 20 69 6e 20 63 61 73 65 20 74  s done in case t
4ea0: 68 65 20 62 75 69 6c 64 20 69 73 20 63 6f 6e 66  he build is conf
4eb0: 69 67 75 72 65 64 20 74 6f 20 6f 6d 69 74 0a 20  igured to omit. 
4ec0: 20 23 20 22 50 52 41 47 4d 41 20 63 61 63 68 65   # "PRAGMA cache
4ed0: 5f 73 69 7a 65 22 2e 0a 20 20 70 75 74 73 20 24  _size"..  puts $
4ee0: 66 20 7b 64 62 20 65 76 61 6c 20 7b 53 45 4c 45  f {db eval {SELE
4ef0: 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74 65  CT * FROM sqlite
4f00: 5f 6d 61 73 74 65 72 3b 7d 7d 0a 20 20 70 75 74  _master;}}.  put
4f10: 73 20 24 66 20 7b 73 65 74 20 62 74 20 5b 62 74  s $f {set bt [bt
4f20: 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 7d  ree_from_db db]}
4f30: 0a 20 20 70 75 74 73 20 24 66 20 7b 62 74 72 65  .  puts $f {btre
4f40: 65 5f 73 65 74 5f 63 61 63 68 65 5f 73 69 7a 65  e_set_cache_size
4f50: 20 24 62 74 20 31 30 7d 0a 20 20 69 66 20 7b 24   $bt 10}.  if {$
4f60: 70 72 6e 67 73 65 65 64 7d 20 7b 0a 20 20 20 20  prngseed} {.    
4f70: 73 65 74 20 73 65 65 64 20 5b 65 78 70 72 20 7b  set seed [expr {
4f80: 24 70 72 6e 67 73 65 65 64 25 31 30 30 30 37 2b  $prngseed%10007+
4f90: 31 7d 5d 0a 20 20 20 20 23 20 70 75 74 73 20 73  1}].    # puts s
4fa0: 65 65 64 3d 24 73 65 65 64 0a 20 20 20 20 70 75  eed=$seed.    pu
4fb0: 74 73 20 24 66 20 22 64 62 20 65 76 61 6c 20 7b  ts $f "db eval {
4fc0: 53 45 4c 45 43 54 20 72 61 6e 64 6f 6d 62 6c 6f  SELECT randomblo
4fd0: 62 28 24 73 65 65 64 29 7d 22 0a 20 20 7d 0a 0a  b($seed)}".  }..
4fe0: 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 6c 65    if {[string le
4ff0: 6e 67 74 68 20 24 74 63 6c 62 6f 64 79 5d 3e 30  ngth $tclbody]>0
5000: 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 24 66 20  } {.    puts $f 
5010: 24 74 63 6c 62 6f 64 79 0a 20 20 7d 0a 20 20 69  $tclbody.  }.  i
5020: 66 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74  f {[string lengt
5030: 68 20 24 73 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20  h $sql]>0} {.   
5040: 20 70 75 74 73 20 24 66 20 22 64 62 20 65 76 61   puts $f "db eva
5050: 6c 20 7b 22 0a 20 20 20 20 70 75 74 73 20 24 66  l {".    puts $f
5060: 20 20 20 22 24 73 71 6c 22 0a 20 20 20 20 70 75     "$sql".    pu
5070: 74 73 20 24 66 20 22 7d 22 0a 20 20 7d 0a 20 20  ts $f "}".  }.  
5080: 63 6c 6f 73 65 20 24 66 0a 20 20 73 65 74 20 72  close $f.  set r
5090: 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20 65 78   [catch {.    ex
50a0: 65 63 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66 65  ec [info nameofe
50b0: 78 65 63 5d 20 63 72 61 73 68 2e 74 63 6c 20 3e  xec] crash.tcl >
50c0: 40 73 74 64 6f 75 74 0a 20 20 7d 20 6d 73 67 5d  @stdout.  } msg]
50d0: 0a 20 20 0a 20 20 23 20 57 69 6e 64 6f 77 73 2f  .  .  # Windows/
50e0: 41 63 74 69 76 65 53 74 61 74 65 20 54 43 4c 20  ActiveState TCL 
50f0: 72 65 74 75 72 6e 73 20 61 20 73 6c 69 67 68 74  returns a slight
5100: 6c 79 20 64 69 66 66 65 72 65 6e 74 0a 20 20 23  ly different.  #
5110: 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 2e 20   error message. 
5120: 20 57 65 20 6d 61 70 20 74 68 61 74 20 74 6f 20   We map that to 
5130: 74 68 65 20 65 78 70 65 63 74 65 64 20 6d 65 73  the expected mes
5140: 73 61 67 65 0a 20 20 23 20 73 6f 20 74 68 61 74  sage.  # so that
5150: 20 77 65 20 64 6f 6e 27 74 20 68 61 76 65 20 74   we don't have t
5160: 6f 20 63 68 61 6e 67 65 20 61 6c 6c 20 6f 66 20  o change all of 
5170: 74 68 65 20 74 65 73 74 0a 20 20 23 20 63 61 73  the test.  # cas
5180: 65 73 2e 0a 20 20 69 66 20 7b 24 3a 3a 74 63 6c  es..  if {$::tcl
5190: 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f  _platform(platfo
51a0: 72 6d 29 3d 3d 22 77 69 6e 64 6f 77 73 22 7d 20  rm)=="windows"} 
51b0: 7b 0a 20 20 20 20 69 66 20 7b 24 6d 73 67 3d 3d  {.    if {$msg==
51c0: 22 63 68 69 6c 64 20 6b 69 6c 6c 65 64 3a 20 75  "child killed: u
51d0: 6e 6b 6e 6f 77 6e 20 73 69 67 6e 61 6c 22 7d 20  nknown signal"} 
51e0: 7b 0a 20 20 20 20 20 20 73 65 74 20 6d 73 67 20  {.      set msg 
51f0: 22 63 68 69 6c 64 20 70 72 6f 63 65 73 73 20 65  "child process e
5200: 78 69 74 65 64 20 61 62 6e 6f 72 6d 61 6c 6c 79  xited abnormally
5210: 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20  ".    }.  }.  . 
5220: 20 6c 61 70 70 65 6e 64 20 72 20 24 6d 73 67 0a   lappend r $msg.
5230: 7d 0a 0a 23 20 55 73 61 67 65 3a 20 64 6f 5f 69  }..# Usage: do_i
5240: 6f 65 72 72 5f 74 65 73 74 20 3c 74 65 73 74 20  oerr_test <test 
5250: 6e 75 6d 62 65 72 3e 20 3c 6f 70 74 69 6f 6e 73  number> <options
5260: 2e 2e 2e 3e 0a 23 0a 23 20 54 68 69 73 20 70 72  ...>.#.# This pr
5270: 6f 63 20 69 73 20 75 73 65 64 20 74 6f 20 69 6d  oc is used to im
5280: 70 6c 65 6d 65 6e 74 20 74 65 73 74 20 63 61 73  plement test cas
5290: 65 73 20 74 68 61 74 20 63 68 65 63 6b 20 74 68  es that check th
52a0: 61 74 20 49 4f 20 65 72 72 6f 72 73 0a 23 20 61  at IO errors.# a
52b0: 72 65 20 63 6f 72 72 65 63 74 6c 79 20 68 61 6e  re correctly han
52c0: 64 6c 65 64 2e 20 54 68 65 20 66 69 72 73 74 20  dled. The first 
52d0: 61 72 67 75 6d 65 6e 74 2c 20 3c 74 65 73 74 20  argument, <test 
52e0: 6e 75 6d 62 65 72 3e 2c 20 69 73 20 61 6e 20 69  number>, is an i
52f0: 6e 74 65 67 65 72 20 0a 23 20 75 73 65 64 20 74  nteger .# used t
5300: 6f 20 6e 61 6d 65 20 74 68 65 20 74 65 73 74 73  o name the tests
5310: 20 65 78 65 63 75 74 65 64 20 62 79 20 74 68 69   executed by thi
5320: 73 20 70 72 6f 63 2e 20 4f 70 74 69 6f 6e 73 20  s proc. Options 
5330: 61 72 65 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a  are as follows:.
5340: 23 0a 23 20 20 20 20 20 2d 74 63 6c 70 72 65 70  #.#     -tclprep
5350: 20 20 20 20 20 20 20 20 20 20 54 43 4c 20 73 63            TCL sc
5360: 72 69 70 74 20 74 6f 20 72 75 6e 20 74 6f 20 70  ript to run to p
5370: 72 65 70 61 72 65 20 74 65 73 74 2e 0a 23 20 20  repare test..#  
5380: 20 20 20 2d 73 71 6c 70 72 65 70 20 20 20 20 20     -sqlprep     
5390: 20 20 20 20 20 53 51 4c 20 73 63 72 69 70 74 20       SQL script 
53a0: 74 6f 20 72 75 6e 20 74 6f 20 70 72 65 70 61 72  to run to prepar
53b0: 65 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d 74  e test..#     -t
53c0: 63 6c 62 6f 64 79 20 20 20 20 20 20 20 20 20 20  clbody          
53d0: 54 43 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75  TCL script to ru
53e0: 6e 20 77 69 74 68 20 49 4f 20 65 72 72 6f 72 20  n with IO error 
53f0: 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20 20 20  simulation..#   
5400: 20 20 2d 73 71 6c 62 6f 64 79 20 20 20 20 20 20    -sqlbody      
5410: 20 20 20 20 54 43 4c 20 73 63 72 69 70 74 20 74      TCL script t
5420: 6f 20 72 75 6e 20 77 69 74 68 20 49 4f 20 65 72  o run with IO er
5430: 72 6f 72 20 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a  ror simulation..
5440: 23 20 20 20 20 20 2d 65 78 63 6c 75 64 65 20 20  #     -exclude  
5450: 20 20 20 20 20 20 20 20 4c 69 73 74 20 6f 66 20          List of 
5460: 27 4e 27 20 76 61 6c 75 65 73 20 6e 6f 74 20 74  'N' values not t
5470: 6f 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d 65  o test..#     -e
5480: 72 63 20 20 20 20 20 20 20 20 20 20 20 20 20 20  rc              
5490: 55 73 65 20 65 78 74 65 6e 64 65 64 20 72 65 73  Use extended res
54a0: 75 6c 74 20 63 6f 64 65 73 0a 23 20 20 20 20 20  ult codes.#     
54b0: 2d 70 65 72 73 69 73 74 20 20 20 20 20 20 20 20  -persist        
54c0: 20 20 4d 61 6b 65 20 73 69 6d 75 6c 61 74 65 64    Make simulated
54d0: 20 49 2f 4f 20 65 72 72 6f 72 73 20 70 65 72 73   I/O errors pers
54e0: 69 73 74 65 6e 74 0a 23 20 20 20 20 20 2d 73 74  istent.#     -st
54f0: 61 72 74 20 20 20 20 20 20 20 20 20 20 20 20 56  art            V
5500: 61 6c 75 65 20 6f 66 20 27 4e 27 20 74 6f 20 62  alue of 'N' to b
5510: 65 67 69 6e 20 77 69 74 68 20 28 64 65 66 61 75  egin with (defau
5520: 6c 74 20 31 29 0a 23 0a 23 20 20 20 20 20 2d 63  lt 1).#.#     -c
5530: 6b 73 75 6d 20 20 20 20 20 20 20 20 20 20 20 20  ksum            
5540: 42 6f 6f 6c 65 61 6e 2e 20 49 66 20 74 72 75 65  Boolean. If true
5550: 2c 20 74 65 73 74 20 74 68 61 74 20 74 68 65 20  , test that the 
5560: 64 61 74 61 62 61 73 65 20 64 6f 65 73 0a 23 20  database does.# 
5570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5580: 20 20 20 20 20 20 6e 6f 74 20 63 68 61 6e 67 65        not change
5590: 20 64 75 72 69 6e 67 20 74 68 65 20 65 78 65 63   during the exec
55a0: 75 74 69 6f 6e 20 6f 66 20 74 68 65 20 74 65 73  ution of the tes
55b0: 74 20 63 61 73 65 2e 0a 23 0a 70 72 6f 63 20 64  t case..#.proc d
55c0: 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20 7b 74 65  o_ioerr_test {te
55d0: 73 74 6e 61 6d 65 20 61 72 67 73 7d 20 7b 0a 0a  stname args} {..
55e0: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74    set ::ioerropt
55f0: 73 28 2d 73 74 61 72 74 29 20 31 0a 20 20 73 65  s(-start) 1.  se
5600: 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63  t ::ioerropts(-c
5610: 6b 73 75 6d 29 20 30 0a 20 20 73 65 74 20 3a 3a  ksum) 0.  set ::
5620: 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29 20  ioerropts(-erc) 
5630: 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f  0.  set ::ioerro
5640: 70 74 73 28 2d 63 6f 75 6e 74 29 20 31 30 30 30  pts(-count) 1000
5650: 30 30 30 30 30 0a 20 20 73 65 74 20 3a 3a 69 6f  00000.  set ::io
5660: 65 72 72 6f 70 74 73 28 2d 70 65 72 73 69 73 74  erropts(-persist
5670: 29 20 31 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72  ) 1.  set ::ioer
5680: 72 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f 75 6e  ropts(-ckrefcoun
5690: 74 29 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65  t) 0.  set ::ioe
56a0: 72 72 6f 70 74 73 28 2d 72 65 73 74 6f 72 65 70  rropts(-restorep
56b0: 72 6e 67 29 20 31 0a 20 20 61 72 72 61 79 20 73  rng) 1.  array s
56c0: 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 20 24  et ::ioerropts $
56d0: 61 72 67 73 0a 0a 20 20 23 20 54 45 4d 50 4f 52  args..  # TEMPOR
56e0: 41 52 59 3a 20 46 6f 72 20 33 2e 35 2e 39 2c 20  ARY: For 3.5.9, 
56f0: 64 69 73 61 62 6c 65 20 74 65 73 74 69 6e 67 20  disable testing 
5700: 6f 66 20 65 78 74 65 6e 64 65 64 20 72 65 73 75  of extended resu
5710: 6c 74 20 63 6f 64 65 73 2e 20 54 68 65 72 65 20  lt codes. There 
5720: 61 72 65 0a 20 20 23 20 61 20 63 6f 75 70 6c 65  are.  # a couple
5730: 20 6f 66 20 6f 62 73 63 75 72 65 20 49 4f 20 65   of obscure IO e
5740: 72 72 6f 72 73 20 74 68 61 74 20 64 6f 20 6e 6f  rrors that do no
5750: 74 20 72 65 74 75 72 6e 20 74 68 65 6d 2e 0a 20  t return them.. 
5760: 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73   set ::ioerropts
5770: 28 2d 65 72 63 29 20 30 0a 0a 20 20 73 65 74 20  (-erc) 0..  set 
5780: 3a 3a 67 6f 20 31 0a 20 20 23 72 65 73 65 74 5f  ::go 1.  #reset_
5790: 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 73 61 76  prng_state.  sav
57a0: 65 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 66  e_prng_state.  f
57b0: 6f 72 20 7b 73 65 74 20 6e 20 24 3a 3a 69 6f 65  or {set n $::ioe
57c0: 72 72 6f 70 74 73 28 2d 73 74 61 72 74 29 7d 20  rropts(-start)} 
57d0: 7b 24 3a 3a 67 6f 7d 20 7b 69 6e 63 72 20 6e 7d  {$::go} {incr n}
57e0: 20 7b 0a 20 20 20 20 73 65 74 20 3a 3a 54 4e 20   {.    set ::TN 
57f0: 24 6e 0a 20 20 20 20 69 6e 63 72 20 3a 3a 69 6f  $n.    incr ::io
5800: 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29 20  erropts(-count) 
5810: 2d 31 0a 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f  -1.    if {$::io
5820: 65 72 72 6f 70 74 73 28 2d 63 6f 75 6e 74 29 3c  erropts(-count)<
5830: 30 7d 20 62 72 65 61 6b 0a 20 0a 20 20 20 20 23  0} break. .    #
5840: 20 53 6b 69 70 20 74 68 69 73 20 49 4f 20 65 72   Skip this IO er
5850: 72 6f 72 20 69 66 20 69 74 20 77 61 73 20 73 70  ror if it was sp
5860: 65 63 69 66 69 65 64 20 77 69 74 68 20 74 68 65  ecified with the
5870: 20 22 2d 65 78 63 6c 75 64 65 22 20 6f 70 74 69   "-exclude" opti
5880: 6f 6e 2e 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66  on..    if {[inf
5890: 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72  o exists ::ioerr
58a0: 6f 70 74 73 28 2d 65 78 63 6c 75 64 65 29 5d 7d  opts(-exclude)]}
58b0: 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 5b 6c 73   {.      if {[ls
58c0: 65 61 72 63 68 20 24 3a 3a 69 6f 65 72 72 6f 70  earch $::ioerrop
58d0: 74 73 28 2d 65 78 63 6c 75 64 65 29 20 24 6e 5d  ts(-exclude) $n]
58e0: 21 3d 2d 31 7d 20 63 6f 6e 74 69 6e 75 65 0a 20  !=-1} continue. 
58f0: 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 24 3a 3a     }.    if {$::
5900: 69 6f 65 72 72 6f 70 74 73 28 2d 72 65 73 74 6f  ioerropts(-resto
5910: 72 65 70 72 6e 67 29 7d 20 7b 0a 20 20 20 20 20  reprng)} {.     
5920: 20 72 65 73 74 6f 72 65 5f 70 72 6e 67 5f 73 74   restore_prng_st
5930: 61 74 65 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23  ate.    }..    #
5940: 20 44 65 6c 65 74 65 20 74 68 65 20 66 69 6c 65   Delete the file
5950: 73 20 74 65 73 74 2e 64 62 20 61 6e 64 20 74 65  s test.db and te
5960: 73 74 32 2e 64 62 2c 20 74 68 65 6e 20 65 78 65  st2.db, then exe
5970: 63 75 74 65 20 74 68 65 20 54 43 4c 20 61 6e 64  cute the TCL and
5980: 20 0a 20 20 20 20 23 20 53 51 4c 20 28 69 6e 20   .    # SQL (in 
5990: 74 68 61 74 20 6f 72 64 65 72 29 20 74 6f 20 70  that order) to p
59a0: 72 65 70 61 72 65 20 66 6f 72 20 74 68 65 20 74  repare for the t
59b0: 65 73 74 20 63 61 73 65 2e 0a 20 20 20 20 64 6f  est case..    do
59c0: 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e  _test $testname.
59d0: 24 6e 2e 31 20 7b 0a 20 20 20 20 20 20 73 65 74  $n.1 {.      set
59e0: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
59f0: 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20 20  or_pending 0.   
5a00: 20 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f     catch {db clo
5a10: 73 65 7d 0a 20 20 20 20 20 20 63 61 74 63 68 20  se}.      catch 
5a20: 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 20 20  {db2 close}.    
5a30: 20 20 63 61 74 63 68 20 7b 66 69 6c 65 20 64 65    catch {file de
5a40: 6c 65 74 65 20 2d 66 6f 72 63 65 20 74 65 73 74  lete -force test
5a50: 2e 64 62 7d 0a 20 20 20 20 20 20 63 61 74 63 68  .db}.      catch
5a60: 20 7b 66 69 6c 65 20 64 65 6c 65 74 65 20 2d 66   {file delete -f
5a70: 6f 72 63 65 20 74 65 73 74 2e 64 62 2d 6a 6f 75  orce test.db-jou
5a80: 72 6e 61 6c 7d 0a 20 20 20 20 20 20 63 61 74 63  rnal}.      catc
5a90: 68 20 7b 66 69 6c 65 20 64 65 6c 65 74 65 20 2d  h {file delete -
5aa0: 66 6f 72 63 65 20 74 65 73 74 32 2e 64 62 7d 0a  force test2.db}.
5ab0: 20 20 20 20 20 20 63 61 74 63 68 20 7b 66 69 6c        catch {fil
5ac0: 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20  e delete -force 
5ad0: 74 65 73 74 32 2e 64 62 2d 6a 6f 75 72 6e 61 6c  test2.db-journal
5ae0: 7d 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 44 42  }.      set ::DB
5af0: 20 5b 73 71 6c 69 74 65 33 20 64 62 20 74 65 73   [sqlite3 db tes
5b00: 74 2e 64 62 3b 20 73 71 6c 69 74 65 33 5f 63 6f  t.db; sqlite3_co
5b10: 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65 72  nnection_pointer
5b20: 20 64 62 5d 0a 20 20 20 20 20 20 73 71 6c 69 74   db].      sqlit
5b30: 65 33 5f 65 78 74 65 6e 64 65 64 5f 72 65 73 75  e3_extended_resu
5b40: 6c 74 5f 63 6f 64 65 73 20 24 3a 3a 44 42 20 24  lt_codes $::DB $
5b50: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72 63  ::ioerropts(-erc
5b60: 29 0a 20 20 20 20 20 20 69 66 20 7b 5b 69 6e 66  ).      if {[inf
5b70: 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72  o exists ::ioerr
5b80: 6f 70 74 73 28 2d 74 63 6c 70 72 65 70 29 5d 7d  opts(-tclprep)]}
5b90: 20 7b 0a 20 20 20 20 20 20 20 20 65 76 61 6c 20   {.        eval 
5ba0: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74 63  $::ioerropts(-tc
5bb0: 6c 70 72 65 70 29 0a 20 20 20 20 20 20 7d 0a 20  lprep).      }. 
5bc0: 20 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65       if {[info e
5bd0: 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74  xists ::ioerropt
5be0: 73 28 2d 73 71 6c 70 72 65 70 29 5d 7d 20 7b 0a  s(-sqlprep)]} {.
5bf0: 20 20 20 20 20 20 20 20 65 78 65 63 73 71 6c 20          execsql 
5c00: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71  $::ioerropts(-sq
5c10: 6c 70 72 65 70 29 0a 20 20 20 20 20 20 7d 0a 20  lprep).      }. 
5c20: 20 20 20 20 20 65 78 70 72 20 30 0a 20 20 20 20       expr 0.    
5c30: 7d 20 7b 30 7d 0a 0a 20 20 20 20 23 20 52 65 61  } {0}..    # Rea
5c40: 64 20 74 68 65 20 27 63 68 65 63 6b 73 75 6d 27  d the 'checksum'
5c50: 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65   of the database
5c60: 2e 0a 20 20 20 20 69 66 20 7b 24 3a 3a 69 6f 65  ..    if {$::ioe
5c70: 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20  rropts(-cksum)} 
5c80: 7b 0a 20 20 20 20 20 20 73 65 74 20 63 68 65 63  {.      set chec
5c90: 6b 73 75 6d 20 5b 63 6b 73 75 6d 5d 0a 20 20 20  ksum [cksum].   
5ca0: 20 7d 0a 0a 20 20 20 20 23 20 53 65 74 20 74 68   }..    # Set th
5cb0: 65 20 4e 74 68 20 49 4f 20 65 72 72 6f 72 20 74  e Nth IO error t
5cc0: 6f 20 66 61 69 6c 2e 0a 20 20 20 20 64 6f 5f 74  o fail..    do_t
5cd0: 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e  est $testname.$n
5ce0: 2e 32 20 5b 73 75 62 73 74 20 7b 0a 20 20 20 20  .2 [subst {.    
5cf0: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
5d00: 6f 5f 65 72 72 6f 72 5f 70 65 72 73 69 73 74 20  o_error_persist 
5d10: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 70 65  $::ioerropts(-pe
5d20: 72 73 69 73 74 29 0a 20 20 20 20 20 20 73 65 74  rsist).      set
5d30: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
5d40: 6f 72 5f 70 65 6e 64 69 6e 67 20 24 6e 0a 20 20  or_pending $n.  
5d50: 20 20 7d 5d 20 24 6e 0a 20 20 0a 20 20 20 20 23    }] $n.  .    #
5d60: 20 43 72 65 61 74 65 20 61 20 73 69 6e 67 6c 65   Create a single
5d70: 20 54 43 4c 20 73 63 72 69 70 74 20 66 72 6f 6d   TCL script from
5d80: 20 74 68 65 20 54 43 4c 20 61 6e 64 20 53 51 4c   the TCL and SQL
5d90: 20 73 70 65 63 69 66 69 65 64 0a 20 20 20 20 23   specified.    #
5da0: 20 61 73 20 74 68 65 20 62 6f 64 79 20 6f 66 20   as the body of 
5db0: 74 68 65 20 74 65 73 74 2e 0a 20 20 20 20 73 65  the test..    se
5dc0: 74 20 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20  t ::ioerrorbody 
5dd0: 7b 7d 0a 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f  {}.    if {[info
5de0: 20 65 78 69 73 74 73 20 3a 3a 69 6f 65 72 72 6f   exists ::ioerro
5df0: 70 74 73 28 2d 74 63 6c 62 6f 64 79 29 5d 7d 20  pts(-tclbody)]} 
5e00: 7b 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20 3a  {.      append :
5e10: 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 22 24 3a  :ioerrorbody "$:
5e20: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c 62  :ioerropts(-tclb
5e30: 6f 64 79 29 5c 6e 22 0a 20 20 20 20 7d 0a 20 20  ody)\n".    }.  
5e40: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
5e50: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
5e60: 73 71 6c 62 6f 64 79 29 5d 7d 20 7b 0a 20 20 20  sqlbody)]} {.   
5e70: 20 20 20 61 70 70 65 6e 64 20 3a 3a 69 6f 65 72     append ::ioer
5e80: 72 6f 72 62 6f 64 79 20 22 64 62 20 65 76 61 6c  rorbody "db eval
5e90: 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d   {$::ioerropts(-
5ea0: 73 71 6c 62 6f 64 79 29 7d 22 0a 20 20 20 20 7d  sqlbody)}".    }
5eb0: 0a 0a 20 20 20 20 23 20 45 78 65 63 75 74 65 20  ..    # Execute 
5ec0: 74 68 65 20 54 43 4c 20 53 63 72 69 70 74 20 63  the TCL Script c
5ed0: 72 65 61 74 65 64 20 69 6e 20 74 68 65 20 61 62  reated in the ab
5ee0: 6f 76 65 20 62 6c 6f 63 6b 2e 20 49 66 0a 20 20  ove block. If.  
5ef0: 20 20 23 20 74 68 65 72 65 20 61 72 65 20 61 74    # there are at
5f00: 20 6c 65 61 73 74 20 4e 20 49 4f 20 6f 70 65 72   least N IO oper
5f10: 61 74 69 6f 6e 73 20 70 65 72 66 6f 72 6d 65 64  ations performed
5f20: 20 62 79 20 53 51 4c 69 74 65 20 61 73 0a 20 20   by SQLite as.  
5f30: 20 20 23 20 61 20 72 65 73 75 6c 74 20 6f 66 20    # a result of 
5f40: 74 68 65 20 73 63 72 69 70 74 2c 20 74 68 65 20  the script, the 
5f50: 4e 74 68 20 77 69 6c 6c 20 66 61 69 6c 2e 0a 20  Nth will fail.. 
5f60: 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74     do_test $test
5f70: 6e 61 6d 65 2e 24 6e 2e 33 20 7b 0a 20 20 20 20  name.$n.3 {.    
5f80: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
5f90: 6f 5f 65 72 72 6f 72 5f 68 69 74 20 30 0a 20 20  o_error_hit 0.  
5fa0: 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65      set ::sqlite
5fb0: 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69  _io_error_hardhi
5fc0: 74 20 30 0a 20 20 20 20 20 20 73 65 74 20 72 20  t 0.      set r 
5fd0: 5b 63 61 74 63 68 20 24 3a 3a 69 6f 65 72 72 6f  [catch $::ioerro
5fe0: 72 62 6f 64 79 20 6d 73 67 5d 0a 20 20 20 20 20  rbody msg].     
5ff0: 20 73 65 74 20 3a 3a 65 72 72 73 65 65 6e 20 24   set ::errseen $
6000: 72 0a 20 20 20 20 20 20 73 65 74 20 72 63 20 5b  r.      set rc [
6010: 73 71 6c 69 74 65 33 5f 65 72 72 63 6f 64 65 20  sqlite3_errcode 
6020: 24 3a 3a 44 42 5d 0a 20 20 20 20 20 20 69 66 20  $::DB].      if 
6030: 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65  {$::ioerropts(-e
6040: 72 63 29 7d 20 7b 0a 20 20 20 20 20 20 20 20 23  rc)} {.        #
6050: 20 49 66 20 77 65 20 61 72 65 20 69 6e 20 65 78   If we are in ex
6060: 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f  tended result co
6070: 64 65 20 6d 6f 64 65 2c 20 6d 61 6b 65 20 73 75  de mode, make su
6080: 72 65 20 61 6c 6c 20 6f 66 20 74 68 65 0a 20 20  re all of the.  
6090: 20 20 20 20 20 20 23 20 49 4f 45 52 52 73 20 77        # IOERRs w
60a0: 65 20 67 65 74 20 62 61 63 6b 20 72 65 61 6c 6c  e get back reall
60b0: 79 20 64 6f 20 68 61 76 65 20 74 68 65 69 72 20  y do have their 
60c0: 65 78 74 65 6e 64 65 64 20 63 6f 64 65 20 76 61  extended code va
60d0: 6c 75 65 73 2e 0a 20 20 20 20 20 20 20 20 23 20  lues..        # 
60e0: 49 66 20 61 6e 20 65 78 74 65 6e 64 65 64 20 72  If an extended r
60f0: 65 73 75 6c 74 20 63 6f 64 65 20 69 73 20 72 65  esult code is re
6100: 74 75 72 6e 65 64 2c 20 74 68 65 20 73 71 6c 69  turned, the sqli
6110: 74 65 33 5f 65 72 72 63 6f 64 65 0a 20 20 20 20  te3_errcode.    
6120: 20 20 20 20 23 20 54 43 4c 63 6f 6d 6d 61 6e 64      # TCLcommand
6130: 20 77 69 6c 6c 20 72 65 74 75 72 6e 20 61 20 73   will return a s
6140: 74 72 69 6e 67 20 6f 66 20 74 68 65 20 66 6f 72  tring of the for
6150: 6d 3a 20 20 53 51 4c 49 54 45 5f 49 4f 45 52 52  m:  SQLITE_IOERR
6160: 2b 6e 6e 6e 6e 0a 20 20 20 20 20 20 20 20 23 20  +nnnn.        # 
6170: 77 68 65 72 65 20 6e 6e 6e 6e 20 69 73 20 61 20  where nnnn is a 
6180: 6e 75 6d 62 65 72 0a 20 20 20 20 20 20 20 20 69  number.        i
6190: 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e 53 51 4c  f {[regexp {^SQL
61a0: 49 54 45 5f 49 4f 45 52 52 7d 20 24 72 63 5d 20  ITE_IOERR} $rc] 
61b0: 26 26 20 21 5b 72 65 67 65 78 70 20 7b 49 4f 45  && ![regexp {IOE
61c0: 52 52 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a  RR\+\d} $rc]} {.
61d0: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
61e0: 20 24 72 63 0a 20 20 20 20 20 20 20 20 7d 0a 20   $rc.        }. 
61f0: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
6200: 20 20 20 20 20 20 23 20 49 66 20 77 65 20 61 72        # If we ar
6210: 65 20 6e 6f 74 20 69 6e 20 65 78 74 65 6e 64 65  e not in extende
6220: 64 20 72 65 73 75 6c 74 20 63 6f 64 65 20 6d 6f  d result code mo
6230: 64 65 2c 20 6d 61 6b 65 20 73 75 72 65 20 6e 6f  de, make sure no
6240: 0a 20 20 20 20 20 20 20 20 23 20 65 78 74 65 6e  .        # exten
6250: 64 65 64 20 65 72 72 6f 72 20 63 6f 64 65 73 20  ded error codes 
6260: 61 72 65 20 72 65 74 75 72 6e 65 64 2e 0a 20 20  are returned..  
6270: 20 20 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78        if {[regex
6280: 70 20 7b 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b  p {\+\d} $rc]} {
6290: 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72  .          retur
62a0: 6e 20 24 72 63 0a 20 20 20 20 20 20 20 20 7d 0a  n $rc.        }.
62b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 23 20        }.      # 
62c0: 54 68 65 20 74 65 73 74 20 72 65 70 65 61 74 73  The test repeats
62d0: 20 61 73 20 6c 6f 6e 67 20 61 73 20 24 3a 3a 67   as long as $::g
62e0: 6f 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2e 20 20  o is non-zero.  
62f0: 24 3a 3a 67 6f 20 73 74 61 72 74 73 20 6f 75 74  $::go starts out
6300: 0a 20 20 20 20 20 20 23 20 61 73 20 31 2e 20 20  .      # as 1.  
6310: 57 68 65 6e 20 61 20 74 65 73 74 20 72 75 6e 73  When a test runs
6320: 20 74 6f 20 63 6f 6d 70 6c 65 74 69 6f 6e 20 77   to completion w
6330: 69 74 68 6f 75 74 20 68 69 74 74 69 6e 67 20 61  ithout hitting a
6340: 6e 20 49 2f 4f 0a 20 20 20 20 20 20 23 20 65 72  n I/O.      # er
6350: 72 6f 72 2c 20 74 68 61 74 20 6d 65 61 6e 73 20  ror, that means 
6360: 74 68 65 72 65 20 69 73 20 6e 6f 20 70 6f 69 6e  there is no poin
6370: 74 20 69 6e 20 63 6f 6e 74 69 6e 75 69 6e 67 20  t in continuing 
6380: 77 69 74 68 20 74 68 69 73 20 74 65 73 74 0a 20  with this test. 
6390: 20 20 20 20 20 23 20 63 61 73 65 20 73 6f 20 73       # case so s
63a0: 65 74 20 24 3a 3a 67 6f 20 74 6f 20 7a 65 72 6f  et $::go to zero
63b0: 2e 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20 20  ..      #.      
63c0: 69 66 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 69 6f  if {$::sqlite_io
63d0: 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 3e 30  _error_pending>0
63e0: 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  } {.        set 
63f0: 3a 3a 67 6f 20 30 0a 20 20 20 20 20 20 20 20 73  ::go 0.        s
6400: 65 74 20 71 20 30 0a 20 20 20 20 20 20 20 20 73  et q 0.        s
6410: 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65  et ::sqlite_io_e
6420: 72 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20  rror_pending 0. 
6430: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
6440: 20 20 20 20 20 20 73 65 74 20 71 20 31 0a 20 20        set q 1.  
6450: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 73 65 74      }..      set
6460: 20 73 20 5b 65 78 70 72 20 24 3a 3a 73 71 6c 69   s [expr $::sqli
6470: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 3d  te_io_error_hit=
6480: 3d 30 5d 0a 20 20 20 20 20 20 69 66 20 7b 24 3a  =0].      if {$:
6490: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
64a0: 5f 68 69 74 3e 24 3a 3a 73 71 6c 69 74 65 5f 69  _hit>$::sqlite_i
64b0: 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20  o_error_hardhit 
64c0: 26 26 20 24 72 3d 3d 30 7d 20 7b 0a 20 20 20 20  && $r==0} {.    
64d0: 20 20 20 20 73 65 74 20 72 20 31 0a 20 20 20 20      set r 1.    
64e0: 20 20 7d 0a 20 20 20 20 20 20 73 65 74 20 3a 3a    }.      set ::
64f0: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
6500: 68 69 74 20 30 0a 0a 20 20 20 20 20 20 23 20 4f  hit 0..      # O
6510: 6e 65 20 6f 66 20 74 77 6f 20 74 68 69 6e 67 73  ne of two things
6520: 20 6d 75 73 74 20 68 61 76 65 20 68 61 70 70 65   must have happe
6530: 6e 65 64 2e 20 65 69 74 68 65 72 0a 20 20 20 20  ned. either.    
6540: 20 20 23 20 20 20 31 2e 20 20 57 65 20 6e 65 76    #   1.  We nev
6550: 65 72 20 68 69 74 20 74 68 65 20 49 4f 20 65 72  er hit the IO er
6560: 72 6f 72 20 61 6e 64 20 74 68 65 20 53 51 4c 20  ror and the SQL 
6570: 72 65 74 75 72 6e 65 64 20 4f 4b 0a 20 20 20 20  returned OK.    
6580: 20 20 23 20 20 20 32 2e 20 20 41 6e 20 49 4f 20    #   2.  An IO 
6590: 65 72 72 6f 72 20 77 61 73 20 68 69 74 20 61 6e  error was hit an
65a0: 64 20 74 68 65 20 53 51 4c 20 66 61 69 6c 65 64  d the SQL failed
65b0: 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20 20 23  .      #.      #
65c0: 70 75 74 73 20 22 73 3d 24 73 20 72 3d 24 72 20  puts "s=$s r=$r 
65d0: 71 3d 24 71 22 0a 20 20 20 20 20 20 65 78 70 72  q=$q".      expr
65e0: 20 7b 20 28 24 73 20 26 26 20 21 24 72 20 26 26   { ($s && !$r &&
65f0: 20 21 24 71 29 20 7c 7c 20 28 21 24 73 20 26 26   !$q) || (!$s &&
6600: 20 24 72 20 26 26 20 24 71 29 20 7d 0a 20 20 20   $r && $q) }.   
6610: 20 7d 20 7b 31 7d 0a 0a 20 20 20 20 73 65 74 20   } {1}..    set 
6620: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
6630: 72 5f 68 69 74 20 30 0a 20 20 20 20 73 65 74 20  r_hit 0.    set 
6640: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
6650: 72 5f 70 65 6e 64 69 6e 67 20 30 0a 0a 20 20 20  r_pending 0..   
6660: 20 23 20 43 68 65 63 6b 20 74 68 61 74 20 6e 6f   # Check that no
6670: 20 70 61 67 65 20 72 65 66 65 72 65 6e 63 65 73   page references
6680: 20 77 65 72 65 20 6c 65 61 6b 65 64 2e 20 54 68   were leaked. Th
6690: 65 72 65 20 73 68 6f 75 6c 64 20 62 65 20 0a 20  ere should be . 
66a0: 20 20 20 23 20 61 20 73 69 6e 67 6c 65 20 72 65     # a single re
66b0: 66 65 72 65 6e 63 65 20 69 66 20 74 68 65 72 65  ference if there
66c0: 20 69 73 20 73 74 69 6c 6c 20 61 6e 20 61 63 74   is still an act
66d0: 69 76 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c  ive transaction,
66e0: 20 0a 20 20 20 20 23 20 6f 72 20 7a 65 72 6f 20   .    # or zero 
66f0: 6f 74 68 65 72 77 69 73 65 2e 0a 20 20 20 20 23  otherwise..    #
6700: 0a 20 20 20 20 23 20 55 50 44 41 54 45 3a 20 49  .    # UPDATE: I
6710: 66 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20 6f  f the IO error o
6720: 63 63 75 72 73 20 61 66 74 65 72 20 61 20 27 42  ccurs after a 'B
6730: 45 47 49 4e 27 20 62 75 74 20 62 65 66 6f 72 65  EGIN' but before
6740: 20 61 6e 79 0a 20 20 20 20 23 20 6c 6f 63 6b 73   any.    # locks
6750: 20 61 72 65 20 65 73 74 61 62 6c 69 73 68 65 64   are established
6760: 20 6f 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c   on database fil
6770: 65 73 20 28 69 2e 65 2e 20 69 66 20 74 68 65 20  es (i.e. if the 
6780: 65 72 72 6f 72 20 0a 20 20 20 20 23 20 6f 63 63  error .    # occ
6790: 75 72 73 20 77 68 69 6c 65 20 61 74 74 65 6d 70  urs while attemp
67a0: 74 69 6e 67 20 74 6f 20 64 65 74 65 63 74 20 61  ting to detect a
67b0: 20 68 6f 74 2d 6a 6f 75 72 6e 61 6c 20 66 69 6c   hot-journal fil
67c0: 65 29 2c 20 74 68 65 6e 0a 20 20 20 20 23 20 74  e), then.    # t
67d0: 68 65 72 65 20 6d 61 79 20 30 20 70 61 67 65 20  here may 0 page 
67e0: 72 65 66 65 72 65 6e 63 65 73 20 61 6e 64 20 61  references and a
67f0: 6e 20 61 63 74 69 76 65 20 74 72 61 6e 73 61 63  n active transac
6800: 74 69 6f 6e 20 61 63 63 6f 72 64 69 6e 67 0a 20  tion according. 
6810: 20 20 20 23 20 74 6f 20 5b 73 71 6c 69 74 65 33     # to [sqlite3
6820: 5f 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 5d  _get_autocommit]
6830: 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 20 7b  ..    #.    if {
6840: 24 3a 3a 67 6f 20 26 26 20 24 3a 3a 73 71 6c 69  $::go && $::sqli
6850: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64  te_io_error_hard
6860: 68 69 74 20 26 26 20 24 3a 3a 69 6f 65 72 72 6f  hit && $::ioerro
6870: 70 74 73 28 2d 63 6b 72 65 66 63 6f 75 6e 74 29  pts(-ckrefcount)
6880: 7d 20 7b 0a 20 20 20 20 20 20 64 6f 5f 74 65 73  } {.      do_tes
6890: 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 34  t $testname.$n.4
68a0: 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 62   {.        set b
68b0: 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62  t [btree_from_db
68c0: 20 64 62 5d 0a 20 20 20 20 20 20 20 20 64 62 5f   db].        db_
68d0: 65 6e 74 65 72 20 64 62 0a 20 20 20 20 20 20 20  enter db.       
68e0: 20 61 72 72 61 79 20 73 65 74 20 73 74 61 74 73   array set stats
68f0: 20 5b 62 74 72 65 65 5f 70 61 67 65 72 5f 73 74   [btree_pager_st
6900: 61 74 73 20 24 62 74 5d 0a 20 20 20 20 20 20 20  ats $bt].       
6910: 20 64 62 5f 6c 65 61 76 65 20 64 62 0a 20 20 20   db_leave db.   
6920: 20 20 20 20 20 73 65 74 20 6e 52 65 66 20 24 73       set nRef $s
6930: 74 61 74 73 28 72 65 66 29 0a 20 20 20 20 20 20  tats(ref).      
6940: 20 20 65 78 70 72 20 7b 24 6e 52 65 66 20 3d 3d    expr {$nRef ==
6950: 20 30 20 7c 7c 20 28 5b 73 71 6c 69 74 65 33 5f   0 || ([sqlite3_
6960: 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 20 64  get_autocommit d
6970: 62 5d 3d 3d 30 20 26 26 20 24 6e 52 65 66 20 3d  b]==0 && $nRef =
6980: 3d 20 31 29 7d 0a 20 20 20 20 20 20 7d 20 7b 31  = 1)}.      } {1
6990: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 49  }.    }..    # I
69a0: 66 20 74 68 65 72 65 20 69 73 20 61 6e 20 6f 70  f there is an op
69b0: 65 6e 20 64 61 74 61 62 61 73 65 20 68 61 6e 64  en database hand
69c0: 6c 65 20 61 6e 64 20 6e 6f 20 6f 70 65 6e 20 74  le and no open t
69d0: 72 61 6e 73 61 63 74 69 6f 6e 2c 20 0a 20 20 20  ransaction, .   
69e0: 20 23 20 61 6e 64 20 74 68 65 20 70 61 67 65 72   # and the pager
69f0: 20 69 73 20 6e 6f 74 20 72 75 6e 6e 69 6e 67 20   is not running 
6a00: 69 6e 20 65 78 63 6c 75 73 69 76 65 2d 6c 6f 63  in exclusive-loc
6a10: 6b 69 6e 67 20 6d 6f 64 65 2c 0a 20 20 20 20 23  king mode,.    #
6a20: 20 63 68 65 63 6b 20 74 68 61 74 20 74 68 65 20   check that the 
6a30: 70 61 67 65 72 20 69 73 20 69 6e 20 22 75 6e 6c  pager is in "unl
6a40: 6f 63 6b 65 64 22 20 73 74 61 74 65 2e 20 54 68  ocked" state. Th
6a50: 65 6f 72 65 74 69 63 61 6c 6c 79 2c 0a 20 20 20  eoretically,.   
6a60: 20 23 20 69 66 20 61 20 63 61 6c 6c 20 74 6f 20   # if a call to 
6a70: 78 55 6e 6c 6f 63 6b 28 29 20 66 61 69 6c 65 64  xUnlock() failed
6a80: 20 64 75 65 20 74 6f 20 61 6e 20 49 4f 20 65 72   due to an IO er
6a90: 72 6f 72 20 74 68 65 20 75 6e 64 65 72 6c 79 69  ror the underlyi
6aa0: 6e 67 0a 20 20 20 20 23 20 66 69 6c 65 20 6d 61  ng.    # file ma
6ab0: 79 20 73 74 69 6c 6c 20 62 65 20 6c 6f 63 6b 65  y still be locke
6ac0: 64 2e 0a 20 20 20 20 23 0a 20 20 20 20 69 66 63  d..    #.    ifc
6ad0: 61 70 61 62 6c 65 20 70 72 61 67 6d 61 20 7b 0a  apable pragma {.
6ae0: 20 20 20 20 20 20 69 66 20 7b 20 5b 69 6e 66 6f        if { [info
6af0: 20 63 6f 6d 6d 61 6e 64 73 20 64 62 5d 20 6e 65   commands db] ne
6b00: 20 22 22 0a 20 20 20 20 20 20 20 20 26 26 20 24   "".        && $
6b10: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 72  ::ioerropts(-ckr
6b20: 65 66 63 6f 75 6e 74 29 0a 20 20 20 20 20 20 20  efcount).       
6b30: 20 26 26 20 5b 64 62 20 6f 6e 65 20 7b 70 72 61   && [db one {pra
6b40: 67 6d 61 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65  gma locking_mode
6b50: 7d 5d 20 65 71 20 22 6e 6f 72 6d 61 6c 22 0a 20  }] eq "normal". 
6b60: 20 20 20 20 20 20 20 26 26 20 5b 73 71 6c 69 74         && [sqlit
6b70: 65 33 5f 67 65 74 5f 61 75 74 6f 63 6f 6d 6d 69  e3_get_autocommi
6b80: 74 20 64 62 5d 0a 20 20 20 20 20 20 7d 20 7b 0a  t db].      } {.
6b90: 20 20 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20          do_test 
6ba0: 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 35 20 7b  $testname.$n.5 {
6bb0: 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20 62  .          set b
6bc0: 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62  t [btree_from_db
6bd0: 20 64 62 5d 0a 20 20 20 20 20 20 20 20 20 20 64   db].          d
6be0: 62 5f 65 6e 74 65 72 20 64 62 0a 20 20 20 20 20  b_enter db.     
6bf0: 20 20 20 20 20 61 72 72 61 79 20 73 65 74 20 73       array set s
6c00: 74 61 74 73 20 5b 62 74 72 65 65 5f 70 61 67 65  tats [btree_page
6c10: 72 5f 73 74 61 74 73 20 24 62 74 5d 0a 20 20 20  r_stats $bt].   
6c20: 20 20 20 20 20 20 20 64 62 5f 6c 65 61 76 65 20         db_leave 
6c30: 64 62 0a 20 20 20 20 20 20 20 20 20 20 73 65 74  db.          set
6c40: 20 73 74 61 74 73 28 73 74 61 74 65 29 0a 20 20   stats(state).  
6c50: 20 20 20 20 20 20 7d 20 30 0a 20 20 20 20 20 20        } 0.      
6c60: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 49  }.    }..    # I
6c70: 66 20 61 6e 20 49 4f 20 65 72 72 6f 72 20 6f 63  f an IO error oc
6c80: 63 75 72 65 64 2c 20 74 68 65 6e 20 74 68 65 20  cured, then the 
6c90: 63 68 65 63 6b 73 75 6d 20 6f 66 20 74 68 65 20  checksum of the 
6ca0: 64 61 74 61 62 61 73 65 20 73 68 6f 75 6c 64 0a  database should.
6cb0: 20 20 20 20 23 20 62 65 20 74 68 65 20 73 61 6d      # be the sam
6cc0: 65 20 61 73 20 62 65 66 6f 72 65 20 74 68 65 20  e as before the 
6cd0: 73 63 72 69 70 74 20 74 68 61 74 20 63 61 75 73  script that caus
6ce0: 65 64 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20  ed the IO error 
6cf0: 77 61 73 20 72 75 6e 2e 0a 20 20 20 20 23 0a 20  was run..    #. 
6d00: 20 20 20 69 66 20 7b 24 3a 3a 67 6f 20 26 26 20     if {$::go && 
6d10: 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72  $::sqlite_io_err
6d20: 6f 72 5f 68 61 72 64 68 69 74 20 26 26 20 24 3a  or_hardhit && $:
6d30: 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73 75  :ioerropts(-cksu
6d40: 6d 29 7d 20 7b 0a 20 20 20 20 20 20 64 6f 5f 74  m)} {.      do_t
6d50: 65 73 74 20 24 74 65 73 74 6e 61 6d 65 2e 24 6e  est $testname.$n
6d60: 2e 36 20 7b 0a 20 20 20 20 20 20 20 20 63 61 74  .6 {.        cat
6d70: 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20 20  ch {db close}.  
6d80: 20 20 20 20 20 20 63 61 74 63 68 20 7b 64 62 32        catch {db2
6d90: 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20 20 20   close}.        
6da0: 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74 65  set ::DB [sqlite
6db0: 33 20 64 62 20 74 65 73 74 2e 64 62 3b 20 73 71  3 db test.db; sq
6dc0: 6c 69 74 65 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e  lite3_connection
6dd0: 5f 70 6f 69 6e 74 65 72 20 64 62 5d 0a 20 20 20  _pointer db].   
6de0: 20 20 20 20 20 63 6b 73 75 6d 0a 20 20 20 20 20       cksum.     
6df0: 20 7d 20 24 63 68 65 63 6b 73 75 6d 0a 20 20 20   } $checksum.   
6e00: 20 7d 0a 0a 20 20 20 20 73 65 74 20 3a 3a 73 71   }..    set ::sq
6e10: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 61  lite_io_error_ha
6e20: 72 64 68 69 74 20 30 0a 20 20 20 20 73 65 74 20  rdhit 0.    set 
6e30: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
6e40: 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20 20 20  r_pending 0.    
6e50: 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73  if {[info exists
6e60: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63 6c   ::ioerropts(-cl
6e70: 65 61 6e 75 70 29 5d 7d 20 7b 0a 20 20 20 20 20  eanup)]} {.     
6e80: 20 63 61 74 63 68 20 24 3a 3a 69 6f 65 72 72 6f   catch $::ioerro
6e90: 70 74 73 28 2d 63 6c 65 61 6e 75 70 29 0a 20 20  pts(-cleanup).  
6ea0: 20 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20 3a 3a    }.  }.  set ::
6eb0: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
6ec0: 70 65 6e 64 69 6e 67 20 30 0a 20 20 73 65 74 20  pending 0.  set 
6ed0: 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f  ::sqlite_io_erro
6ee0: 72 5f 70 65 72 73 69 73 74 20 30 0a 20 20 75 6e  r_persist 0.  un
6ef0: 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 0a  set ::ioerropts.
6f00: 7d 0a 0a 23 20 52 65 74 75 72 6e 20 61 20 63 68  }..# Return a ch
6f10: 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e 20  ecksum based on 
6f20: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
6f30: 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73  the main databas
6f40: 65 20 61 73 73 6f 63 69 61 74 65 64 0a 23 20 77  e associated.# w
6f50: 69 74 68 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 24  ith connection $
6f60: 64 62 0a 23 0a 70 72 6f 63 20 63 6b 73 75 6d 20  db.#.proc cksum 
6f70: 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65  {{db db}} {.  se
6f80: 74 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c 20  t txt [$db eval 
6f90: 7b 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e  {.      SELECT n
6fa0: 61 6d 65 2c 20 74 79 70 65 2c 20 73 71 6c 20 46  ame, type, sql F
6fb0: 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65  ROM sqlite_maste
6fc0: 72 20 6f 72 64 65 72 20 62 79 20 6e 61 6d 65 0a  r order by name.
6fd0: 20 20 7d 5d 5c 6e 0a 20 20 66 6f 72 65 61 63 68    }]\n.  foreach
6fe0: 20 74 62 6c 20 5b 24 64 62 20 65 76 61 6c 20 7b   tbl [$db eval {
6ff0: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61  .      SELECT na
7000: 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d  me FROM sqlite_m
7010: 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65  aster WHERE type
7020: 3d 27 74 61 62 6c 65 27 20 6f 72 64 65 72 20 62  ='table' order b
7030: 79 20 6e 61 6d 65 0a 20 20 7d 5d 20 7b 0a 20 20  y name.  }] {.  
7040: 20 20 61 70 70 65 6e 64 20 74 78 74 20 5b 24 64    append txt [$d
7050: 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a  b eval "SELECT *
7060: 20 46 52 4f 4d 20 24 74 62 6c 22 5d 5c 6e 0a 20   FROM $tbl"]\n. 
7070: 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 70 72 61   }.  foreach pra
7080: 67 20 7b 64 65 66 61 75 6c 74 5f 73 79 6e 63 68  g {default_synch
7090: 72 6f 6e 6f 75 73 20 64 65 66 61 75 6c 74 5f 63  ronous default_c
70a0: 61 63 68 65 5f 73 69 7a 65 7d 20 7b 0a 20 20 20  ache_size} {.   
70b0: 20 61 70 70 65 6e 64 20 74 78 74 20 24 70 72 61   append txt $pra
70c0: 67 2d 5b 24 64 62 20 65 76 61 6c 20 22 50 52 41  g-[$db eval "PRA
70d0: 47 4d 41 20 24 70 72 61 67 22 5d 5c 6e 0a 20 20  GMA $prag"]\n.  
70e0: 7d 0a 20 20 73 65 74 20 63 6b 73 75 6d 20 5b 73  }.  set cksum [s
70f0: 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 74 78  tring length $tx
7100: 74 5d 2d 5b 6d 64 35 20 24 74 78 74 5d 0a 20 20  t]-[md5 $txt].  
7110: 23 20 70 75 74 73 20 24 63 6b 73 75 6d 2d 5b 66  # puts $cksum-[f
7120: 69 6c 65 20 73 69 7a 65 20 74 65 73 74 2e 64 62  ile size test.db
7130: 5d 0a 20 20 72 65 74 75 72 6e 20 24 63 6b 73 75  ].  return $cksu
7140: 6d 0a 7d 0a 0a 23 20 47 65 6e 65 72 61 74 65 20  m.}..# Generate 
7150: 61 20 63 68 65 63 6b 73 75 6d 20 62 61 73 65 64  a checksum based
7160: 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e 74 73   on the contents
7170: 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 61 6e 64   of the main and
7180: 20 74 65 6d 70 20 74 61 62 6c 65 73 0a 23 20 64   temp tables.# d
7190: 61 74 61 62 61 73 65 20 24 64 62 2e 20 49 66 20  atabase $db. If 
71a0: 74 68 65 20 63 68 65 63 6b 73 75 6d 20 6f 66 20  the checksum of 
71b0: 74 77 6f 20 64 61 74 61 62 61 73 65 73 20 69 73  two databases is
71c0: 20 74 68 65 20 73 61 6d 65 2c 20 61 6e 64 20 74   the same, and t
71d0: 68 65 0a 23 20 69 6e 74 65 67 72 69 74 79 2d 63  he.# integrity-c
71e0: 68 65 63 6b 20 70 61 73 73 65 73 20 66 6f 72 20  heck passes for 
71f0: 62 6f 74 68 2c 20 74 68 65 20 74 77 6f 20 64 61  both, the two da
7200: 74 61 62 61 73 65 73 20 61 72 65 20 69 64 65 6e  tabases are iden
7210: 74 69 63 61 6c 2e 0a 23 0a 70 72 6f 63 20 61 6c  tical..#.proc al
7220: 6c 63 6b 73 75 6d 20 7b 7b 64 62 20 64 62 7d 7d  lcksum {{db db}}
7230: 20 7b 0a 20 20 73 65 74 20 72 65 74 20 5b 6c 69   {.  set ret [li
7240: 73 74 5d 0a 20 20 69 66 63 61 70 61 62 6c 65 20  st].  ifcapable 
7250: 74 65 6d 70 64 62 20 7b 0a 20 20 20 20 73 65 74  tempdb {.    set
7260: 20 73 71 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c   sql {.      SEL
7270: 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71  ECT name FROM sq
7280: 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52  lite_master WHER
7290: 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65 27  E type = 'table'
72a0: 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c   UNION.      SEL
72b0: 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71  ECT name FROM sq
72c0: 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72  lite_temp_master
72d0: 20 57 48 45 52 45 20 74 79 70 65 20 3d 20 27 74   WHERE type = 't
72e0: 61 62 6c 65 27 20 55 4e 49 4f 4e 0a 20 20 20 20  able' UNION.    
72f0: 20 20 53 45 4c 45 43 54 20 27 73 71 6c 69 74 65    SELECT 'sqlite
7300: 5f 6d 61 73 74 65 72 27 20 55 4e 49 4f 4e 0a 20  _master' UNION. 
7310: 20 20 20 20 20 53 45 4c 45 43 54 20 27 73 71 6c       SELECT 'sql
7320: 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72 27  ite_temp_master'
7330: 20 4f 52 44 45 52 20 42 59 20 31 0a 20 20 20 20   ORDER BY 1.    
7340: 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20  }.  } else {.   
7350: 20 73 65 74 20 73 71 6c 20 7b 0a 20 20 20 20 20   set sql {.     
7360: 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f   SELECT name FRO
7370: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20  M sqlite_master 
7380: 57 48 45 52 45 20 74 79 70 65 20 3d 20 27 74 61  WHERE type = 'ta
7390: 62 6c 65 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20  ble' UNION.     
73a0: 20 53 45 4c 45 43 54 20 27 73 71 6c 69 74 65 5f   SELECT 'sqlite_
73b0: 6d 61 73 74 65 72 27 20 4f 52 44 45 52 20 42 59  master' ORDER BY
73c0: 20 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73   1.    }.  }.  s
73d0: 65 74 20 74 62 6c 6c 69 73 74 20 5b 24 64 62 20  et tbllist [$db 
73e0: 65 76 61 6c 20 24 73 71 6c 5d 0a 20 20 73 65 74  eval $sql].  set
73f0: 20 74 78 74 20 7b 7d 0a 20 20 66 6f 72 65 61 63   txt {}.  foreac
7400: 68 20 74 62 6c 20 24 74 62 6c 6c 69 73 74 20 7b  h tbl $tbllist {
7410: 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78 74 20  .    append txt 
7420: 5b 24 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43  [$db eval "SELEC
7430: 54 20 2a 20 46 52 4f 4d 20 24 74 62 6c 22 5d 0a  T * FROM $tbl"].
7440: 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20 70 72    }.  foreach pr
7450: 61 67 20 7b 64 65 66 61 75 6c 74 5f 63 61 63 68  ag {default_cach
7460: 65 5f 73 69 7a 65 7d 20 7b 0a 20 20 20 20 61 70  e_size} {.    ap
7470: 70 65 6e 64 20 74 78 74 20 24 70 72 61 67 2d 5b  pend txt $prag-[
7480: 24 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41  $db eval "PRAGMA
7490: 20 24 70 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a 20   $prag"]\n.  }. 
74a0: 20 23 20 70 75 74 73 20 74 78 74 3d 24 74 78 74   # puts txt=$txt
74b0: 0a 20 20 72 65 74 75 72 6e 20 5b 6d 64 35 20 24  .  return [md5 $
74c0: 74 78 74 5d 0a 7d 0a 0a 23 20 47 65 6e 65 72 61  txt].}..# Genera
74d0: 74 65 20 61 20 63 68 65 63 6b 73 75 6d 20 62 61  te a checksum ba
74e0: 73 65 64 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65  sed on the conte
74f0: 6e 74 73 20 6f 66 20 61 20 73 69 6e 67 6c 65 20  nts of a single 
7500: 64 61 74 61 62 61 73 65 20 77 69 74 68 0a 23 20  database with.# 
7510: 61 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e 65  a database conne
7520: 63 74 69 6f 6e 2e 20 20 54 68 65 20 6e 61 6d 65  ction.  The name
7530: 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65   of the database
7540: 20 69 73 20 24 64 62 6e 61 6d 65 2e 20 20 0a 23   is $dbname.  .#
7550: 20 45 78 61 6d 70 6c 65 73 20 6f 66 20 24 64 62   Examples of $db
7560: 6e 61 6d 65 20 61 72 65 20 22 74 65 6d 70 22 20  name are "temp" 
7570: 6f 72 20 22 6d 61 69 6e 22 2e 0a 23 0a 70 72 6f  or "main"..#.pro
7580: 63 20 64 62 63 6b 73 75 6d 20 7b 64 62 20 64 62  c dbcksum {db db
7590: 6e 61 6d 65 7d 20 7b 0a 20 20 69 66 20 7b 24 64  name} {.  if {$d
75a0: 62 6e 61 6d 65 3d 3d 22 74 65 6d 70 22 7d 20 7b  bname=="temp"} {
75b0: 0a 20 20 20 20 73 65 74 20 6d 61 73 74 65 72 20  .    set master 
75c0: 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74  sqlite_temp_mast
75d0: 65 72 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  er.  } else {.  
75e0: 20 20 73 65 74 20 6d 61 73 74 65 72 20 24 64 62    set master $db
75f0: 6e 61 6d 65 2e 73 71 6c 69 74 65 5f 6d 61 73 74  name.sqlite_mast
7600: 65 72 0a 20 20 7d 0a 20 20 73 65 74 20 61 6c 6c  er.  }.  set all
7610: 74 61 62 20 5b 24 64 62 20 65 76 61 6c 20 22 53  tab [$db eval "S
7620: 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20  ELECT name FROM 
7630: 24 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79  $master WHERE ty
7640: 70 65 3d 27 74 61 62 6c 65 27 22 5d 0a 20 20 73  pe='table'"].  s
7650: 65 74 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c  et txt [$db eval
7660: 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20   "SELECT * FROM 
7670: 24 6d 61 73 74 65 72 22 5d 5c 6e 0a 20 20 66 6f  $master"]\n.  fo
7680: 72 65 61 63 68 20 74 61 62 20 24 61 6c 6c 74 61  reach tab $allta
7690: 62 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74  b {.    append t
76a0: 78 74 20 5b 24 64 62 20 65 76 61 6c 20 22 53 45  xt [$db eval "SE
76b0: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 24 64 62 6e  LECT * FROM $dbn
76c0: 61 6d 65 2e 24 74 61 62 22 5d 5c 6e 0a 20 20 7d  ame.$tab"]\n.  }
76d0: 0a 20 20 72 65 74 75 72 6e 20 5b 6d 64 35 20 24  .  return [md5 $
76e0: 74 78 74 5d 0a 7d 0a 0a 70 72 6f 63 20 6d 65 6d  txt].}..proc mem
76f0: 64 65 62 75 67 5f 6c 6f 67 5f 73 71 6c 20 7b 7b  debug_log_sql {{
7700: 66 69 6c 65 6e 61 6d 65 20 6d 61 6c 6c 6f 63 73  filename mallocs
7710: 2e 73 71 6c 7d 7d 20 7b 0a 0a 20 20 73 65 74 20  .sql}} {..  set 
7720: 64 61 74 61 20 5b 73 71 6c 69 74 65 33 5f 6d 65  data [sqlite3_me
7730: 6d 64 65 62 75 67 5f 6c 6f 67 20 64 75 6d 70 5d  mdebug_log dump]
7740: 0a 20 20 73 65 74 20 6e 46 72 61 6d 65 20 5b 65  .  set nFrame [e
7750: 78 70 72 20 5b 6c 6c 65 6e 67 74 68 20 5b 6c 69  xpr [llength [li
7760: 6e 64 65 78 20 24 64 61 74 61 20 30 5d 5d 2d 32  ndex $data 0]]-2
7770: 5d 0a 20 20 69 66 20 7b 24 6e 46 72 61 6d 65 20  ].  if {$nFrame 
7780: 3c 20 30 7d 20 7b 20 72 65 74 75 72 6e 20 22 22  < 0} { return ""
7790: 20 7d 0a 0a 20 20 73 65 74 20 64 61 74 61 62 61   }..  set databa
77a0: 73 65 20 74 65 6d 70 0a 0a 20 20 73 65 74 20 74  se temp..  set t
77b0: 62 6c 20 22 43 52 45 41 54 45 20 54 41 42 4c 45  bl "CREATE TABLE
77c0: 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 6d 61 6c   ${database}.mal
77d0: 6c 6f 63 28 7a 54 65 73 74 2c 20 6e 43 61 6c 6c  loc(zTest, nCall
77e0: 2c 20 6e 42 79 74 65 2c 20 6c 53 74 61 63 6b 29  , nByte, lStack)
77f0: 3b 22 0a 0a 20 20 73 65 74 20 73 71 6c 20 22 22  ;"..  set sql ""
7800: 0a 20 20 66 6f 72 65 61 63 68 20 65 20 24 64 61  .  foreach e $da
7810: 74 61 20 7b 0a 20 20 20 20 73 65 74 20 6e 43 61  ta {.    set nCa
7820: 6c 6c 20 5b 6c 69 6e 64 65 78 20 24 65 20 30 5d  ll [lindex $e 0]
7830: 0a 20 20 20 20 73 65 74 20 6e 42 79 74 65 20 5b  .    set nByte [
7840: 6c 69 6e 64 65 78 20 24 65 20 31 5d 0a 20 20 20  lindex $e 1].   
7850: 20 73 65 74 20 6c 53 74 61 63 6b 20 5b 6c 72 61   set lStack [lra
7860: 6e 67 65 20 24 65 20 32 20 65 6e 64 5d 0a 20 20  nge $e 2 end].  
7870: 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22 49 4e    append sql "IN
7880: 53 45 52 54 20 49 4e 54 4f 20 24 7b 64 61 74 61  SERT INTO ${data
7890: 62 61 73 65 7d 2e 6d 61 6c 6c 6f 63 20 56 41 4c  base}.malloc VAL
78a0: 55 45 53 22 0a 20 20 20 20 61 70 70 65 6e 64 20  UES".    append 
78b0: 73 71 6c 20 22 28 27 74 65 73 74 27 2c 20 24 6e  sql "('test', $n
78c0: 43 61 6c 6c 2c 20 24 6e 42 79 74 65 2c 20 27 24  Call, $nByte, '$
78d0: 6c 53 74 61 63 6b 27 29 3b 5c 6e 22 0a 20 20 20  lStack');\n".   
78e0: 20 66 6f 72 65 61 63 68 20 66 20 24 6c 53 74 61   foreach f $lSta
78f0: 63 6b 20 7b 0a 20 20 20 20 20 20 73 65 74 20 66  ck {.      set f
7900: 72 61 6d 65 73 28 24 66 29 20 31 0a 20 20 20 20  rames($f) 1.    
7910: 7d 0a 20 20 7d 0a 0a 20 20 73 65 74 20 74 62 6c  }.  }..  set tbl
7920: 32 20 22 43 52 45 41 54 45 20 54 41 42 4c 45 20  2 "CREATE TABLE 
7930: 24 7b 64 61 74 61 62 61 73 65 7d 2e 66 72 61 6d  ${database}.fram
7940: 65 28 66 72 61 6d 65 20 49 4e 54 45 47 45 52 20  e(frame INTEGER 
7950: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 6c 69 6e  PRIMARY KEY, lin
7960: 65 29 3b 5c 6e 22 0a 20 20 73 65 74 20 74 62 6c  e);\n".  set tbl
7970: 33 20 22 43 52 45 41 54 45 20 54 41 42 4c 45 20  3 "CREATE TABLE 
7980: 24 7b 64 61 74 61 62 61 73 65 7d 2e 66 69 6c 65  ${database}.file
7990: 28 6e 61 6d 65 20 50 52 49 4d 41 52 59 20 4b 45  (name PRIMARY KE
79a0: 59 2c 20 63 6f 6e 74 65 6e 74 29 3b 5c 6e 22 0a  Y, content);\n".
79b0: 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 61 72  .  foreach f [ar
79c0: 72 61 79 20 6e 61 6d 65 73 20 66 72 61 6d 65 73  ray names frames
79d0: 5d 20 7b 0a 20 20 20 20 73 65 74 20 61 64 64 72  ] {.    set addr
79e0: 20 5b 66 6f 72 6d 61 74 20 25 78 20 24 66 5d 0a   [format %x $f].
79f0: 20 20 20 20 73 65 74 20 63 6d 64 20 22 61 64 64      set cmd "add
7a00: 72 32 6c 69 6e 65 20 2d 65 20 5b 69 6e 66 6f 20  r2line -e [info 
7a10: 6e 61 6d 65 6f 66 65 78 65 63 5d 20 24 61 64 64  nameofexec] $add
7a20: 72 22 0a 20 20 20 20 73 65 74 20 6c 69 6e 65 20  r".    set line 
7a30: 5b 65 76 61 6c 20 65 78 65 63 20 24 63 6d 64 5d  [eval exec $cmd]
7a40: 0a 20 20 20 20 61 70 70 65 6e 64 20 73 71 6c 20  .    append sql 
7a50: 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 24 7b 64  "INSERT INTO ${d
7a60: 61 74 61 62 61 73 65 7d 2e 66 72 61 6d 65 20 56  atabase}.frame V
7a70: 41 4c 55 45 53 28 24 66 2c 20 27 24 6c 69 6e 65  ALUES($f, '$line
7a80: 27 29 3b 5c 6e 22 0a 0a 20 20 20 20 73 65 74 20  ');\n"..    set 
7a90: 66 69 6c 65 20 5b 6c 69 6e 64 65 78 20 5b 73 70  file [lindex [sp
7aa0: 6c 69 74 20 24 6c 69 6e 65 20 3a 5d 20 30 5d 0a  lit $line :] 0].
7ab0: 20 20 20 20 73 65 74 20 66 69 6c 65 73 28 24 66      set files($f
7ac0: 69 6c 65 29 20 31 0a 20 20 7d 0a 0a 20 20 66 6f  ile) 1.  }..  fo
7ad0: 72 65 61 63 68 20 66 20 5b 61 72 72 61 79 20 6e  reach f [array n
7ae0: 61 6d 65 73 20 66 69 6c 65 73 5d 20 7b 0a 20 20  ames files] {.  
7af0: 20 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20 22    set contents "
7b00: 22 0a 20 20 20 20 63 61 74 63 68 20 7b 0a 20 20  ".    catch {.  
7b10: 20 20 20 20 73 65 74 20 66 64 20 5b 6f 70 65 6e      set fd [open
7b20: 20 24 66 5d 0a 20 20 20 20 20 20 73 65 74 20 63   $f].      set c
7b30: 6f 6e 74 65 6e 74 73 20 5b 72 65 61 64 20 24 66  ontents [read $f
7b40: 64 5d 0a 20 20 20 20 20 20 63 6c 6f 73 65 20 24  d].      close $
7b50: 66 64 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74  fd.    }.    set
7b60: 20 63 6f 6e 74 65 6e 74 73 20 5b 73 74 72 69 6e   contents [strin
7b70: 67 20 6d 61 70 20 7b 27 20 27 27 7d 20 24 63 6f  g map {' ''} $co
7b80: 6e 74 65 6e 74 73 5d 0a 20 20 20 20 61 70 70 65  ntents].    appe
7b90: 6e 64 20 73 71 6c 20 22 49 4e 53 45 52 54 20 49  nd sql "INSERT I
7ba0: 4e 54 4f 20 24 7b 64 61 74 61 62 61 73 65 7d 2e  NTO ${database}.
7bb0: 66 69 6c 65 20 56 41 4c 55 45 53 28 27 24 66 27  file VALUES('$f'
7bc0: 2c 20 27 24 63 6f 6e 74 65 6e 74 73 27 29 3b 5c  , '$contents');\
7bd0: 6e 22 0a 20 20 7d 0a 0a 20 20 73 65 74 20 66 64  n".  }..  set fd
7be0: 20 5b 6f 70 65 6e 20 24 66 69 6c 65 6e 61 6d 65   [open $filename
7bf0: 20 77 5d 0a 20 20 70 75 74 73 20 24 66 64 20 22   w].  puts $fd "
7c00: 42 45 47 49 4e 3b 20 24 7b 74 62 6c 7d 24 7b 74  BEGIN; ${tbl}${t
7c10: 62 6c 32 7d 24 7b 74 62 6c 33 7d 24 7b 73 71 6c  bl2}${tbl3}${sql
7c20: 7d 20 3b 20 43 4f 4d 4d 49 54 3b 22 0a 20 20 63  } ; COMMIT;".  c
7c30: 6c 6f 73 65 20 24 66 64 0a 7d 0a 0a 23 20 43 6f  lose $fd.}..# Co
7c40: 70 79 20 66 69 6c 65 20 24 66 72 6f 6d 20 69 6e  py file $from in
7c50: 74 6f 20 24 74 6f 2e 20 54 68 69 73 20 69 73 20  to $to. This is 
7c60: 75 73 65 64 20 62 65 63 61 75 73 65 20 73 6f 6d  used because som
7c70: 65 20 76 65 72 73 69 6f 6e 73 20 6f 66 0a 23 20  e versions of.# 
7c80: 54 43 4c 20 66 6f 72 20 77 69 6e 64 6f 77 73 20  TCL for windows 
7c90: 28 6e 6f 74 61 62 6c 79 20 74 68 65 20 38 2e 34  (notably the 8.4
7ca0: 2e 31 20 62 69 6e 61 72 79 20 70 61 63 6b 61 67  .1 binary packag
7cb0: 65 20 73 68 69 70 70 65 64 20 77 69 74 68 20 74  e shipped with t
7cc0: 68 65 0a 23 20 63 75 72 72 65 6e 74 20 6d 69 6e  he.# current min
7cd0: 67 77 20 72 65 6c 65 61 73 65 29 20 68 61 76 65  gw release) have
7ce0: 20 61 20 62 72 6f 6b 65 6e 20 22 66 69 6c 65 20   a broken "file 
7cf0: 63 6f 70 79 22 20 63 6f 6d 6d 61 6e 64 2e 0a 23  copy" command..#
7d00: 0a 70 72 6f 63 20 63 6f 70 79 5f 66 69 6c 65 20  .proc copy_file 
7d10: 7b 66 72 6f 6d 20 74 6f 7d 20 7b 0a 20 20 69 66  {from to} {.  if
7d20: 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72   {$::tcl_platfor
7d30: 6d 28 70 6c 61 74 66 6f 72 6d 29 3d 3d 22 75 6e  m(platform)=="un
7d40: 69 78 22 7d 20 7b 0a 20 20 20 20 66 69 6c 65 20  ix"} {.    file 
7d50: 63 6f 70 79 20 2d 66 6f 72 63 65 20 24 66 72 6f  copy -force $fro
7d60: 6d 20 24 74 6f 0a 20 20 7d 20 65 6c 73 65 20 7b  m $to.  } else {
7d70: 0a 20 20 20 20 73 65 74 20 66 20 5b 6f 70 65 6e  .    set f [open
7d80: 20 24 66 72 6f 6d 5d 0a 20 20 20 20 66 63 6f 6e   $from].    fcon
7d90: 66 69 67 75 72 65 20 24 66 20 2d 74 72 61 6e 73  figure $f -trans
7da0: 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20  lation binary.  
7db0: 20 20 73 65 74 20 74 20 5b 6f 70 65 6e 20 24 74    set t [open $t
7dc0: 6f 20 77 5d 0a 20 20 20 20 66 63 6f 6e 66 69 67  o w].    fconfig
7dd0: 75 72 65 20 24 74 20 2d 74 72 61 6e 73 6c 61 74  ure $t -translat
7de0: 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20 20 20 70  ion binary.    p
7df0: 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 24  uts -nonewline $
7e00: 74 20 5b 72 65 61 64 20 24 66 20 5b 66 69 6c 65  t [read $f [file
7e10: 20 73 69 7a 65 20 24 66 72 6f 6d 5d 5d 0a 20 20   size $from]].  
7e20: 20 20 63 6c 6f 73 65 20 24 74 0a 20 20 20 20 63    close $t.    c
7e30: 6c 6f 73 65 20 24 66 0a 20 20 7d 0a 7d 0a 0a 23  lose $f.  }.}..#
7e40: 20 44 72 6f 70 20 61 6c 6c 20 74 61 62 6c 65 73   Drop all tables
7e50: 20 69 6e 20 64 61 74 61 62 61 73 65 20 5b 64 62   in database [db
7e60: 5d 0a 70 72 6f 63 20 64 72 6f 70 5f 61 6c 6c 5f  ].proc drop_all_
7e70: 74 61 62 6c 65 73 20 7b 7b 64 62 20 64 62 7d 7d  tables {{db db}}
7e80: 20 7b 0a 20 20 69 66 63 61 70 61 62 6c 65 20 74   {.  ifcapable t
7e90: 72 69 67 67 65 72 26 26 66 6f 72 65 69 67 6e 6b  rigger&&foreignk
7ea0: 65 79 20 7b 0a 20 20 20 20 73 65 74 20 70 6b 20  ey {.    set pk 
7eb0: 5b 24 64 62 20 6f 6e 65 20 22 50 52 41 47 4d 41  [$db one "PRAGMA
7ec0: 20 66 6f 72 65 69 67 6e 5f 6b 65 79 73 22 5d 0a   foreign_keys"].
7ed0: 20 20 20 20 24 64 62 20 65 76 61 6c 20 22 50 52      $db eval "PR
7ee0: 41 47 4d 41 20 66 6f 72 65 69 67 6e 5f 6b 65 79  AGMA foreign_key
7ef0: 73 20 3d 20 4f 46 46 22 0a 20 20 7d 0a 20 20 66  s = OFF".  }.  f
7f00: 6f 72 65 61 63 68 20 7b 69 64 78 20 6e 61 6d 65  oreach {idx name
7f10: 20 66 69 6c 65 7d 20 5b 64 62 20 65 76 61 6c 20   file} [db eval 
7f20: 7b 50 52 41 47 4d 41 20 64 61 74 61 62 61 73 65  {PRAGMA database
7f30: 5f 6c 69 73 74 7d 5d 20 7b 0a 20 20 20 20 69 66  _list}] {.    if
7f40: 20 7b 24 69 64 78 3d 3d 31 7d 20 7b 0a 20 20 20   {$idx==1} {.   
7f50: 20 20 20 73 65 74 20 6d 61 73 74 65 72 20 73 71     set master sq
7f60: 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74 65 72  lite_temp_master
7f70: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
7f80: 20 20 20 20 73 65 74 20 6d 61 73 74 65 72 20 24      set master $
7f90: 6e 61 6d 65 2e 73 71 6c 69 74 65 5f 6d 61 73 74  name.sqlite_mast
7fa0: 65 72 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72  er.    }.    for
7fb0: 65 61 63 68 20 7b 74 20 74 79 70 65 7d 20 5b 24  each {t type} [$
7fc0: 64 62 20 65 76 61 6c 20 22 0a 20 20 20 20 20 20  db eval ".      
7fd0: 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20 74 79 70  SELECT name, typ
7fe0: 65 20 46 52 4f 4d 20 24 6d 61 73 74 65 72 0a 20  e FROM $master. 
7ff0: 20 20 20 20 20 57 48 45 52 45 20 74 79 70 65 20       WHERE type 
8000: 49 4e 28 27 74 61 62 6c 65 27 2c 20 27 76 69 65  IN('table', 'vie
8010: 77 27 29 20 41 4e 44 20 6e 61 6d 65 20 4e 4f 54  w') AND name NOT
8020: 20 6c 69 6b 65 20 27 73 71 6c 69 74 65 5f 25 27   like 'sqlite_%'
8030: 0a 20 20 20 20 22 5d 20 7b 0a 20 20 20 20 20 20  .    "] {.      
8040: 24 64 62 20 65 76 61 6c 20 22 44 52 4f 50 20 24  $db eval "DROP $
8050: 74 79 70 65 20 24 74 22 0a 20 20 20 20 7d 0a 20  type $t".    }. 
8060: 20 7d 0a 20 20 69 66 63 61 70 61 62 6c 65 20 74   }.  ifcapable t
8070: 72 69 67 67 65 72 26 26 66 6f 72 65 69 67 6e 6b  rigger&&foreignk
8080: 65 79 20 7b 0a 20 20 20 20 24 64 62 20 65 76 61  ey {.    $db eva
8090: 6c 20 22 50 52 41 47 4d 41 20 66 6f 72 65 69 67  l "PRAGMA foreig
80a0: 6e 5f 6b 65 79 73 20 3d 20 24 70 6b 22 0a 20 20  n_keys = $pk".  
80b0: 7d 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  }.}..#----------
80c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
80d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
80e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
80f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
8100: 23 20 49 66 20 61 20 74 65 73 74 20 73 63 72 69  # If a test scri
8110: 70 74 20 69 73 20 65 78 65 63 75 74 65 64 20 77  pt is executed w
8120: 69 74 68 20 67 6c 6f 62 61 6c 20 76 61 72 69 61  ith global varia
8130: 62 6c 65 20 24 3a 3a 47 28 70 65 72 6d 3a 6e 61  ble $::G(perm:na
8140: 6d 65 29 20 73 65 74 20 74 6f 0a 23 20 22 77 61  me) set to.# "wa
8150: 6c 22 2c 20 74 68 65 6e 20 74 68 65 20 74 65 73  l", then the tes
8160: 74 73 20 61 72 65 20 72 75 6e 20 69 6e 20 57 41  ts are run in WA
8170: 4c 20 6d 6f 64 65 2e 20 4f 74 68 65 72 77 69 73  L mode. Otherwis
8180: 65 2c 20 74 68 65 79 20 73 68 6f 75 6c 64 20 62  e, they should b
8190: 65 20 72 75 6e 20 0a 23 20 69 6e 20 72 6f 6c 6c  e run .# in roll
81a0: 62 61 63 6b 20 6d 6f 64 65 2e 20 54 68 65 20 66  back mode. The f
81b0: 6f 6c 6c 6f 77 69 6e 67 20 54 63 6c 20 70 72 6f  ollowing Tcl pro
81c0: 63 73 20 61 72 65 20 75 73 65 64 20 74 6f 20 6d  cs are used to m
81d0: 61 6b 65 20 74 68 69 73 20 6c 65 73 73 20 0a 23  ake this less .#
81e0: 20 69 6e 74 72 75 73 69 76 65 3a 0a 23 0a 23 20   intrusive:.#.# 
81f0: 20 20 77 61 6c 5f 73 65 74 5f 6a 6f 75 72 6e 61    wal_set_journa
8200: 6c 5f 6d 6f 64 65 20 3f 44 42 3f 0a 23 0a 23 20  l_mode ?DB?.#.# 
8210: 20 20 20 20 49 66 20 72 75 6e 6e 69 6e 67 20 61      If running a
8220: 20 57 41 4c 20 74 65 73 74 2c 20 65 78 65 63 75   WAL test, execu
8230: 74 65 20 22 50 52 41 47 4d 41 20 6a 6f 75 72 6e  te "PRAGMA journ
8240: 61 6c 5f 6d 6f 64 65 20 3d 20 77 61 6c 22 20 75  al_mode = wal" u
8250: 73 69 6e 67 0a 23 20 20 20 20 20 63 6f 6e 6e 65  sing.#     conne
8260: 63 74 69 6f 6e 20 68 61 6e 64 6c 65 20 44 42 2e  ction handle DB.
8270: 20 4f 74 68 65 72 77 69 73 65 2c 20 74 68 69 73   Otherwise, this
8280: 20 63 6f 6d 6d 61 6e 64 20 69 73 20 61 20 6e 6f   command is a no
8290: 2d 6f 70 2e 0a 23 0a 23 20 20 20 77 61 6c 5f 63  -op..#.#   wal_c
82a0: 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64  heck_journal_mod
82b0: 65 20 54 45 53 54 4e 41 4d 45 20 3f 44 42 3f 0a  e TESTNAME ?DB?.
82c0: 23 0a 23 20 20 20 20 20 49 66 20 72 75 6e 6e 69  #.#     If runni
82d0: 6e 67 20 61 20 57 41 4c 20 74 65 73 74 2c 20 65  ng a WAL test, e
82e0: 78 65 63 75 74 65 20 61 20 74 65 73 74 73 20 63  xecute a tests c
82f0: 61 73 65 20 74 68 61 74 20 66 61 69 6c 73 20 69  ase that fails i
8300: 66 20 74 68 65 20 6d 61 69 6e 0a 23 20 20 20 20  f the main.#    
8310: 20 64 61 74 61 62 61 73 65 20 66 6f 72 20 63 6f   database for co
8320: 6e 6e 65 63 74 69 6f 6e 20 68 61 6e 64 6c 65 20  nnection handle 
8330: 44 42 20 69 73 20 6e 6f 74 20 63 75 72 72 65 6e  DB is not curren
8340: 74 6c 79 20 61 20 57 41 4c 20 64 61 74 61 62 61  tly a WAL databa
8350: 73 65 2e 0a 23 20 20 20 20 20 4f 74 68 65 72 77  se..#     Otherw
8360: 69 73 65 20 28 69 66 20 6e 6f 74 20 72 75 6e 6e  ise (if not runn
8370: 69 6e 67 20 61 20 57 41 4c 20 70 65 72 6d 75 74  ing a WAL permut
8380: 61 74 69 6f 6e 29 20 74 68 69 73 20 69 73 20 61  ation) this is a
8390: 20 6e 6f 2d 6f 70 2e 0a 23 0a 23 20 20 20 77 61   no-op..#.#   wa
83a0: 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 0a 23 20  l_is_wal_mode.# 
83b0: 20 20 0a 23 20 20 20 20 20 52 65 74 75 72 6e 73    .#     Returns
83c0: 20 74 72 75 65 20 69 66 20 74 68 69 73 20 74 65   true if this te
83d0: 73 74 20 73 68 6f 75 6c 64 20 62 65 20 72 75 6e  st should be run
83e0: 20 69 6e 20 57 41 4c 20 6d 6f 64 65 2e 20 46 61   in WAL mode. Fa
83f0: 6c 73 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 23  lse otherwise..#
8400: 20 0a 70 72 6f 63 20 77 61 6c 5f 69 73 5f 77 61   .proc wal_is_wa
8410: 6c 5f 6d 6f 64 65 20 7b 7d 20 7b 0a 20 20 65 78  l_mode {} {.  ex
8420: 70 72 20 7b 5b 70 65 72 6d 75 74 61 74 69 6f 6e  pr {[permutation
8430: 5d 20 65 71 20 22 77 61 6c 22 7d 0a 7d 0a 70 72  ] eq "wal"}.}.pr
8440: 6f 63 20 77 61 6c 5f 73 65 74 5f 6a 6f 75 72 6e  oc wal_set_journ
8450: 61 6c 5f 6d 6f 64 65 20 7b 7b 64 62 20 64 62 7d  al_mode {{db db}
8460: 7d 20 7b 0a 20 20 69 66 20 7b 20 5b 77 61 6c 5f  } {.  if { [wal_
8470: 69 73 5f 77 61 6c 5f 6d 6f 64 65 5d 20 7d 20 7b  is_wal_mode] } {
8480: 0a 20 20 20 20 24 64 62 20 65 76 61 6c 20 22 50  .    $db eval "P
8490: 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f  RAGMA journal_mo
84a0: 64 65 20 3d 20 57 41 4c 22 0a 20 20 7d 0a 7d 0a  de = WAL".  }.}.
84b0: 70 72 6f 63 20 77 61 6c 5f 63 68 65 63 6b 5f 6a  proc wal_check_j
84c0: 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 7b 74 65 73  ournal_mode {tes
84d0: 74 6e 61 6d 65 20 7b 64 62 20 64 62 7d 7d 20 7b  tname {db db}} {
84e0: 0a 20 20 69 66 20 7b 20 5b 77 61 6c 5f 69 73 5f  .  if { [wal_is_
84f0: 77 61 6c 5f 6d 6f 64 65 5d 20 7d 20 7b 0a 20 20  wal_mode] } {.  
8500: 20 20 24 64 62 20 65 76 61 6c 20 7b 20 53 45 4c    $db eval { SEL
8510: 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74  ECT * FROM sqlit
8520: 65 5f 6d 61 73 74 65 72 20 7d 0a 20 20 20 20 64  e_master }.    d
8530: 6f 5f 74 65 73 74 20 24 74 65 73 74 6e 61 6d 65  o_test $testname
8540: 20 5b 6c 69 73 74 20 24 64 62 20 65 76 61 6c 20   [list $db eval 
8550: 22 50 52 41 47 4d 41 20 6d 61 69 6e 2e 6a 6f 75  "PRAGMA main.jou
8560: 72 6e 61 6c 5f 6d 6f 64 65 22 5d 20 7b 77 61 6c  rnal_mode"] {wal
8570: 7d 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 70 65  }.  }.}..proc pe
8580: 72 6d 75 74 61 74 69 6f 6e 20 7b 7d 20 7b 0a 20  rmutation {} {. 
8590: 20 73 65 74 20 70 65 72 6d 20 22 22 0a 20 20 63   set perm "".  c
85a0: 61 74 63 68 20 7b 73 65 74 20 70 65 72 6d 20 24  atch {set perm $
85b0: 3a 3a 47 28 70 65 72 6d 3a 6e 61 6d 65 29 7d 0a  ::G(perm:name)}.
85c0: 20 20 73 65 74 20 70 65 72 6d 0a 7d 0a 0a 23 2d    set perm.}..#-
85d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
85e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
85f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8600: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
8610: 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 70 72 6f 63 20  --------.#.proc 
8620: 73 6c 61 76 65 5f 74 65 73 74 5f 73 63 72 69 70  slave_test_scrip
8630: 74 20 7b 73 63 72 69 70 74 7d 20 7b 0a 0a 20 20  t {script} {..  
8640: 23 20 43 72 65 61 74 65 20 74 68 65 20 69 6e 74  # Create the int
8650: 65 72 70 72 65 74 65 72 20 75 73 65 64 20 74 6f  erpreter used to
8660: 20 72 75 6e 20 74 68 65 20 74 65 73 74 20 73 63   run the test sc
8670: 72 69 70 74 2e 0a 20 20 69 6e 74 65 72 70 20 63  ript..  interp c
8680: 72 65 61 74 65 20 74 69 6e 74 65 72 70 0a 0a 20  reate tinterp.. 
8690: 20 23 20 50 6f 70 75 6c 61 74 65 20 73 6f 6d 65   # Populate some
86a0: 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   global variable
86b0: 73 20 74 68 61 74 20 74 65 73 74 65 72 2e 74 63  s that tester.tc
86c0: 6c 20 65 78 70 65 63 74 73 20 74 6f 20 73 65 65  l expects to see
86d0: 2e 0a 20 20 66 6f 72 65 61 63 68 20 7b 76 61 72  ..  foreach {var
86e0: 20 76 61 6c 75 65 7d 20 5b 6c 69 73 74 20 20 20   value} [list   
86f0: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20             \.   
8700: 20 3a 3a 61 72 67 76 30 20 24 3a 3a 61 72 67 76   ::argv0 $::argv
8710: 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0               
8720: 20 20 20 20 20 20 5c 0a 20 20 20 20 3a 3a 61 72        \.    ::ar
8730: 67 76 20 20 7b 7d 20 20 20 20 20 20 20 20 20 20  gv  {}          
8740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8750: 20 5c 0a 20 20 20 20 3a 3a 53 4c 41 56 45 20 31   \.    ::SLAVE 1
8760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8770: 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20              \.  
8780: 5d 20 7b 0a 20 20 20 20 69 6e 74 65 72 70 20 65  ] {.    interp e
8790: 76 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69 73  val tinterp [lis
87a0: 74 20 73 65 74 20 24 76 61 72 20 24 76 61 6c 75  t set $var $valu
87b0: 65 5d 0a 20 20 7d 0a 0a 20 20 23 20 54 68 65 20  e].  }..  # The 
87c0: 61 6c 69 61 73 20 75 73 65 64 20 74 6f 20 61 63  alias used to ac
87d0: 63 65 73 73 20 74 68 65 20 67 6c 6f 62 61 6c 20  cess the global 
87e0: 74 65 73 74 20 63 6f 75 6e 74 65 72 73 2e 0a 20  test counters.. 
87f0: 20 74 69 6e 74 65 72 70 20 61 6c 69 61 73 20 73   tinterp alias s
8800: 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20  et_test_counter 
8810: 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72  set_test_counter
8820: 0a 0a 20 20 23 20 53 65 74 20 75 70 20 74 68 65  ..  # Set up the
8830: 20 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 20 61 72   ::cmdlinearg ar
8840: 72 61 79 20 69 6e 20 74 68 65 20 73 6c 61 76 65  ray in the slave
8850: 2e 0a 20 20 69 6e 74 65 72 70 20 65 76 61 6c 20  ..  interp eval 
8860: 74 69 6e 74 65 72 70 20 5b 6c 69 73 74 20 61 72  tinterp [list ar
8870: 72 61 79 20 73 65 74 20 3a 3a 63 6d 64 6c 69 6e  ray set ::cmdlin
8880: 65 61 72 67 20 5b 61 72 72 61 79 20 67 65 74 20  earg [array get 
8890: 3a 3a 63 6d 64 6c 69 6e 65 61 72 67 5d 5d 0a 0a  ::cmdlinearg]]..
88a0: 20 20 23 20 53 65 74 20 75 70 20 74 68 65 20 3a    # Set up the :
88b0: 3a 47 20 61 72 72 61 79 20 69 6e 20 74 68 65 20  :G array in the 
88c0: 73 6c 61 76 65 2e 0a 20 20 69 6e 74 65 72 70 20  slave..  interp 
88d0: 65 76 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69  eval tinterp [li
88e0: 73 74 20 61 72 72 61 79 20 73 65 74 20 3a 3a 47  st array set ::G
88f0: 20 5b 61 72 72 61 79 20 67 65 74 20 3a 3a 47 5d   [array get ::G]
8900: 5d 0a 0a 20 20 23 20 4c 6f 61 64 20 74 68 65 20  ]..  # Load the 
8910: 76 61 72 69 6f 75 73 20 74 65 73 74 20 69 6e 74  various test int
8920: 65 72 66 61 63 65 73 20 69 6d 70 6c 65 6d 65 6e  erfaces implemen
8930: 74 65 64 20 69 6e 20 43 2e 0a 20 20 6c 6f 61 64  ted in C..  load
8940: 5f 74 65 73 74 66 69 78 74 75 72 65 5f 65 78 74  _testfixture_ext
8950: 65 6e 73 69 6f 6e 73 20 74 69 6e 74 65 72 70 0a  ensions tinterp.
8960: 0a 20 20 23 20 52 75 6e 20 74 68 65 20 74 65 73  .  # Run the tes
8970: 74 20 73 63 72 69 70 74 2e 0a 20 20 69 6e 74 65  t script..  inte
8980: 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70 20  rp eval tinterp 
8990: 24 73 63 72 69 70 74 0a 0a 20 20 23 20 43 68 65  $script..  # Che
89a0: 63 6b 20 69 66 20 74 68 65 20 69 6e 74 65 72 70  ck if the interp
89b0: 72 65 74 65 72 20 63 61 6c 6c 20 5b 72 75 6e 5f  reter call [run_
89c0: 74 68 72 65 61 64 5f 74 65 73 74 73 5d 0a 20 20  thread_tests].  
89d0: 69 66 20 7b 20 5b 69 6e 74 65 72 70 20 65 76 61  if { [interp eva
89e0: 6c 20 74 69 6e 74 65 72 70 20 7b 69 6e 66 6f 20  l tinterp {info 
89f0: 65 78 69 73 74 73 20 3a 3a 72 75 6e 5f 74 68 72  exists ::run_thr
8a00: 65 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64  ead_tests_called
8a10: 7d 5d 20 7d 20 7b 0a 20 20 20 20 73 65 74 20 3a  }] } {.    set :
8a20: 3a 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74  :run_thread_test
8a30: 73 5f 63 61 6c 6c 65 64 20 31 0a 20 20 7d 0a 0a  s_called 1.  }..
8a40: 20 20 23 20 44 65 6c 65 74 65 20 74 68 65 20 69    # Delete the i
8a50: 6e 74 65 72 70 72 65 74 65 72 20 75 73 65 64 20  nterpreter used 
8a60: 74 6f 20 72 75 6e 20 74 68 65 20 74 65 73 74 20  to run the test 
8a70: 73 63 72 69 70 74 2e 0a 20 20 69 6e 74 65 72 70  script..  interp
8a80: 20 64 65 6c 65 74 65 20 74 69 6e 74 65 72 70 0a   delete tinterp.
8a90: 7d 0a 0a 70 72 6f 63 20 73 6c 61 76 65 5f 74 65  }..proc slave_te
8aa0: 73 74 5f 66 69 6c 65 20 7b 7a 46 69 6c 65 7d 20  st_file {zFile} 
8ab0: 7b 0a 20 20 73 65 74 20 74 61 69 6c 20 5b 66 69  {.  set tail [fi
8ac0: 6c 65 20 74 61 69 6c 20 24 7a 46 69 6c 65 5d 0a  le tail $zFile].
8ad0: 0a 20 20 23 20 52 65 6d 65 6d 62 65 72 20 74 68  .  # Remember th
8ae0: 65 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 73  e value of the s
8af0: 68 61 72 65 64 2d 63 61 63 68 65 20 73 65 74 74  hared-cache sett
8b00: 69 6e 67 2e 20 53 6f 20 74 68 61 74 20 69 74 20  ing. So that it 
8b10: 69 73 20 70 6f 73 73 69 62 6c 65 0a 20 20 23 20  is possible.  # 
8b20: 74 6f 20 63 68 65 63 6b 20 61 66 74 65 72 77 61  to check afterwa
8b30: 72 64 73 20 74 68 61 74 20 69 74 20 77 61 73 20  rds that it was 
8b40: 6e 6f 74 20 6d 6f 64 69 66 69 65 64 20 62 79 20  not modified by 
8b50: 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74 2e  the test script.
8b60: 0a 20 20 23 0a 20 20 69 66 63 61 70 61 62 6c 65  .  #.  ifcapable
8b70: 20 73 68 61 72 65 64 5f 63 61 63 68 65 20 7b 20   shared_cache { 
8b80: 73 65 74 20 73 63 73 20 5b 73 71 6c 69 74 65 33  set scs [sqlite3
8b90: 5f 65 6e 61 62 6c 65 5f 73 68 61 72 65 64 5f 63  _enable_shared_c
8ba0: 61 63 68 65 5d 20 7d 0a 0a 20 20 23 20 52 75 6e  ache] }..  # Run
8bb0: 20 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74   the test script
8bc0: 20 69 6e 20 61 20 73 6c 61 76 65 20 69 6e 74 65   in a slave inte
8bd0: 72 70 72 65 74 65 72 2e 0a 20 20 23 0a 20 20 75  rpreter..  #.  u
8be0: 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  nset -nocomplain
8bf0: 20 3a 3a 72 75 6e 5f 74 68 72 65 61 64 5f 74 65   ::run_thread_te
8c00: 73 74 73 5f 63 61 6c 6c 65 64 0a 20 20 72 65 73  sts_called.  res
8c10: 65 74 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20  et_prng_state.  
8c20: 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 6f 70 65  set ::sqlite_ope
8c30: 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 20 30 0a 20  n_file_count 0. 
8c40: 20 73 65 74 20 74 69 6d 65 20 5b 74 69 6d 65 20   set time [time 
8c50: 7b 20 73 6c 61 76 65 5f 74 65 73 74 5f 73 63 72  { slave_test_scr
8c60: 69 70 74 20 5b 6c 69 73 74 20 73 6f 75 72 63 65  ipt [list source
8c70: 20 24 7a 46 69 6c 65 5d 20 7d 5d 0a 20 20 73 65   $zFile] }].  se
8c80: 74 20 6d 73 20 5b 65 78 70 72 20 5b 6c 69 6e 64  t ms [expr [lind
8c90: 65 78 20 24 74 69 6d 65 20 30 5d 20 2f 20 31 30  ex $time 0] / 10
8ca0: 30 30 5d 0a 0a 20 20 23 20 54 65 73 74 20 74 68  00]..  # Test th
8cb0: 61 74 20 61 6c 6c 20 66 69 6c 65 73 20 6f 70 65  at all files ope
8cc0: 6e 65 64 20 62 79 20 74 68 65 20 74 65 73 74 20  ned by the test 
8cd0: 73 63 72 69 70 74 20 77 65 72 65 20 63 6c 6f 73  script were clos
8ce0: 65 64 2e 20 4f 6d 69 74 20 74 68 69 73 0a 20 20  ed. Omit this.  
8cf0: 23 20 69 66 20 74 68 65 20 74 65 73 74 20 73 63  # if the test sc
8d00: 72 69 70 74 20 68 61 73 20 22 74 68 72 65 61 64  ript has "thread
8d10: 22 20 69 6e 20 69 74 73 20 6e 61 6d 65 2e 20 54  " in its name. T
8d20: 68 65 20 6f 70 65 6e 20 66 69 6c 65 20 63 6f 75  he open file cou
8d30: 6e 74 65 72 0a 20 20 23 20 69 73 20 6e 6f 74 20  nter.  # is not 
8d40: 74 68 72 65 61 64 2d 73 61 66 65 2e 0a 20 20 23  thread-safe..  #
8d50: 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69  .  if {[info exi
8d60: 73 74 73 20 3a 3a 72 75 6e 5f 74 68 72 65 61 64  sts ::run_thread
8d70: 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64 5d 3d 3d  _tests_called]==
8d80: 30 7d 20 7b 0a 20 20 20 20 64 6f 5f 74 65 73 74  0} {.    do_test
8d90: 20 24 7b 74 61 69 6c 7d 2d 63 6c 6f 73 65 61 6c   ${tail}-closeal
8da0: 6c 66 69 6c 65 73 20 7b 20 65 78 70 72 20 7b 24  lfiles { expr {$
8db0: 3a 3a 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69  ::sqlite_open_fi
8dc0: 6c 65 5f 63 6f 75 6e 74 3e 30 7d 20 7d 20 7b 30  le_count>0} } {0
8dd0: 7d 0a 20 20 7d 0a 20 20 73 65 74 20 3a 3a 73 71  }.  }.  set ::sq
8de0: 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63  lite_open_file_c
8df0: 6f 75 6e 74 20 30 0a 0a 20 20 23 20 54 65 73 74  ount 0..  # Test
8e00: 20 74 68 61 74 20 74 68 65 20 67 6c 6f 62 61 6c   that the global
8e10: 20 22 73 68 61 72 65 64 2d 63 61 63 68 65 22 20   "shared-cache" 
8e20: 73 65 74 74 69 6e 67 20 77 61 73 20 6e 6f 74 20  setting was not 
8e30: 61 6c 74 65 72 65 64 20 62 79 20 0a 20 20 23 20  altered by .  # 
8e40: 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74 2e  the test script.
8e50: 0a 20 20 23 0a 20 20 69 66 63 61 70 61 62 6c 65  .  #.  ifcapable
8e60: 20 73 68 61 72 65 64 5f 63 61 63 68 65 20 7b 20   shared_cache { 
8e70: 0a 20 20 20 20 73 65 74 20 72 65 73 20 5b 65 78  .    set res [ex
8e80: 70 72 20 7b 5b 73 71 6c 69 74 65 33 5f 65 6e 61  pr {[sqlite3_ena
8e90: 62 6c 65 5f 73 68 61 72 65 64 5f 63 61 63 68 65  ble_shared_cache
8ea0: 5d 20 3d 3d 20 24 73 63 73 7d 5d 0a 20 20 20 20  ] == $scs}].    
8eb0: 64 6f 5f 74 65 73 74 20 24 7b 74 61 69 6c 7d 2d  do_test ${tail}-
8ec0: 73 68 61 72 65 64 63 61 63 68 65 73 65 74 74 69  sharedcachesetti
8ed0: 6e 67 20 5b 6c 69 73 74 20 73 65 74 20 7b 7d 20  ng [list set {} 
8ee0: 24 72 65 73 5d 20 31 0a 20 20 7d 0a 0a 20 20 23  $res] 1.  }..  #
8ef0: 20 41 64 64 20 73 6f 6d 65 20 69 6e 66 6f 20 74   Add some info t
8f00: 6f 20 74 68 65 20 6f 75 74 70 75 74 2e 0a 20 20  o the output..  
8f10: 23 0a 20 20 70 75 74 73 20 22 54 69 6d 65 3a 20  #.  puts "Time: 
8f20: 24 74 61 69 6c 20 24 6d 73 20 6d 73 22 0a 20 20  $tail $ms ms".  
8f30: 73 68 6f 77 5f 6d 65 6d 73 74 61 74 73 0a 7d 0a  show_memstats.}.
8f40: 0a 0a 23 20 49 66 20 74 68 65 20 6c 69 62 72 61  ..# If the libra
8f50: 72 79 20 69 73 20 63 6f 6d 70 69 6c 65 64 20 77  ry is compiled w
8f60: 69 74 68 20 74 68 65 20 53 51 4c 49 54 45 5f 44  ith the SQLITE_D
8f70: 45 46 41 55 4c 54 5f 41 55 54 4f 56 41 43 55 55  EFAULT_AUTOVACUU
8f80: 4d 20 6d 61 63 72 6f 20 73 65 74 0a 23 20 74 6f  M macro set.# to
8f90: 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20   non-zero, then 
8fa0: 73 65 74 20 74 68 65 20 67 6c 6f 62 61 6c 20 76  set the global v
8fb0: 61 72 69 61 62 6c 65 20 24 41 55 54 4f 56 41 43  ariable $AUTOVAC
8fc0: 55 55 4d 20 74 6f 20 31 2e 0a 73 65 74 20 41 55  UUM to 1..set AU
8fd0: 54 4f 56 41 43 55 55 4d 20 24 73 71 6c 69 74 65  TOVACUUM $sqlite
8fe0: 5f 6f 70 74 69 6f 6e 73 28 64 65 66 61 75 6c 74  _options(default
8ff0: 5f 61 75 74 6f 76 61 63 75 75 6d 29 0a 0a 73 6f  _autovacuum)..so
9000: 75 72 63 65 20 24 74 65 73 74 64 69 72 2f 74 68  urce $testdir/th
9010: 72 65 61 64 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a  read_common.tcl.