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

Artifact 4ce5afd5e192db4cae178e1a983b060e0f08c5d6:


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 0a 23 20 74 65 73 74 20 63  reating.# test c
02a0: 61 73 65 73 20 61 72 65 20 61 73 20 66 6f 6c 6c  ases are as foll
02b0: 6f 77 73 3a 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64  ows:.#.# Command
02c0: 73 20 74 6f 20 6d 61 6e 69 70 75 6c 61 74 65 20  s to manipulate 
02d0: 74 68 65 20 64 62 20 61 6e 64 20 74 68 65 20 66  the db and the f
02e0: 69 6c 65 2d 73 79 73 74 65 6d 20 61 74 20 61 20  ile-system at a 
02f0: 68 69 67 68 20 6c 65 76 65 6c 3a 0a 23 0a 23 20  high level:.#.# 
0300: 20 20 20 20 20 69 73 5f 72 65 6c 61 74 69 76 65       is_relative
0310: 5f 66 69 6c 65 0a 23 20 20 20 20 20 20 74 65 73  _file.#      tes
0320: 74 5f 70 77 64 0a 23 20 20 20 20 20 20 67 65 74  t_pwd.#      get
0330: 5f 70 77 64 0a 23 20 20 20 20 20 20 63 6f 70 79  _pwd.#      copy
0340: 5f 66 69 6c 65 20 20 20 20 20 20 20 20 20 20 20  _file           
0350: 20 20 20 46 52 4f 4d 20 54 4f 0a 23 20 20 20 20     FROM TO.#    
0360: 20 20 64 65 6c 65 74 65 5f 66 69 6c 65 20 20 20    delete_file   
0370: 20 20 20 20 20 20 20 20 20 46 49 4c 45 4e 41 4d           FILENAM
0380: 45 0a 23 20 20 20 20 20 20 64 72 6f 70 5f 61 6c  E.#      drop_al
0390: 6c 5f 74 61 62 6c 65 73 20 20 20 20 20 20 20 20  l_tables        
03a0: 3f 44 42 3f 0a 23 20 20 20 20 20 20 64 72 6f 70  ?DB?.#      drop
03b0: 5f 61 6c 6c 5f 69 6e 64 65 78 65 73 20 20 20 20  _all_indexes    
03c0: 20 20 20 3f 44 42 3f 0a 23 20 20 20 20 20 20 66     ?DB?.#      f
03d0: 6f 72 63 65 63 6f 70 79 20 20 20 20 20 20 20 20  orcecopy        
03e0: 20 20 20 20 20 20 46 52 4f 4d 20 54 4f 0a 23 20        FROM TO.# 
03f0: 20 20 20 20 20 66 6f 72 63 65 64 65 6c 65 74 65       forcedelete
0400: 20 20 20 20 20 20 20 20 20 20 20 20 46 49 4c 45              FILE
0410: 4e 41 4d 45 0a 23 0a 23 20 54 65 73 74 20 74 68  NAME.#.# Test th
0420: 65 20 63 61 70 61 62 69 6c 69 74 79 20 6f 66 20  e capability of 
0430: 74 68 65 20 53 51 4c 69 74 65 20 76 65 72 73 69  the SQLite versi
0440: 6f 6e 20 62 75 69 6c 74 20 69 6e 74 6f 20 74 68  on built into th
0450: 65 20 69 6e 74 65 72 70 72 65 74 65 72 20 74 6f  e interpreter to
0460: 0a 23 20 64 65 74 65 72 6d 69 6e 65 20 69 66 20  .# determine if 
0470: 61 20 73 70 65 63 69 66 69 63 20 74 65 73 74 20  a specific test 
0480: 63 61 6e 20 62 65 20 72 75 6e 3a 0a 23 0a 23 20  can be run:.#.# 
0490: 20 20 20 20 20 63 61 70 61 62 6c 65 20 20 20 20       capable    
04a0: 20 20 20 20 20 20 20 20 20 20 20 20 45 58 50 52              EXPR
04b0: 0a 23 20 20 20 20 20 20 69 66 63 61 70 61 62 6c  .#      ifcapabl
04c0: 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20 45  e              E
04d0: 58 50 52 0a 23 0a 23 20 43 61 6c 75 6c 61 74 65  XPR.#.# Calulate
04e0: 20 63 68 65 63 6b 73 75 6d 73 20 62 61 73 65 64   checksums based
04f0: 20 6f 6e 20 64 61 74 61 62 61 73 65 20 63 6f 6e   on database con
0500: 74 65 6e 74 73 3a 0a 23 0a 23 20 20 20 20 20 20  tents:.#.#      
0510: 64 62 63 6b 73 75 6d 20 20 20 20 20 20 20 20 20  dbcksum         
0520: 20 20 20 20 20 20 20 44 42 20 44 42 4e 41 4d 45         DB DBNAME
0530: 0a 23 20 20 20 20 20 20 61 6c 6c 63 6b 73 75 6d  .#      allcksum
0540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 3f                 ?
0550: 44 42 3f 0a 23 20 20 20 20 20 20 63 6b 73 75 6d  DB?.#      cksum
0560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0570: 20 20 3f 44 42 3f 0a 23 0a 23 20 43 6f 6d 6d 61    ?DB?.#.# Comma
0580: 6e 64 73 20 74 6f 20 65 78 65 63 75 74 65 2f 65  nds to execute/e
0590: 78 70 6c 61 69 6e 20 53 51 4c 20 73 74 61 74 65  xplain SQL state
05a0: 6d 65 6e 74 73 3a 0a 23 0a 23 20 20 20 20 20 20  ments:.#.#      
05b0: 6d 65 6d 64 62 73 71 6c 20 20 20 20 20 20 20 20  memdbsql        
05c0: 20 20 20 20 20 20 20 53 51 4c 0a 23 20 20 20 20         SQL.#    
05d0: 20 20 73 74 65 70 73 71 6c 20 20 20 20 20 20 20    stepsql       
05e0: 20 20 20 20 20 20 20 20 20 44 42 20 53 51 4c 0a           DB SQL.
05f0: 23 20 20 20 20 20 20 65 78 65 63 73 71 6c 32 20  #      execsql2 
0600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
0610: 4c 0a 23 20 20 20 20 20 20 65 78 70 6c 61 69 6e  L.#      explain
0620: 5f 6e 6f 5f 74 72 61 63 65 20 20 20 20 20 20 20  _no_trace       
0630: 53 51 4c 0a 23 20 20 20 20 20 20 65 78 70 6c 61  SQL.#      expla
0640: 69 6e 20 20 20 20 20 20 20 20 20 20 20 20 20 20  in              
0650: 20 20 53 51 4c 20 3f 44 42 3f 0a 23 20 20 20 20    SQL ?DB?.#    
0660: 20 20 63 61 74 63 68 73 71 6c 20 20 20 20 20 20    catchsql      
0670: 20 20 20 20 20 20 20 20 20 53 51 4c 20 3f 44 42           SQL ?DB
0680: 3f 0a 23 20 20 20 20 20 20 65 78 65 63 73 71 6c  ?.#      execsql
0690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06a0: 53 51 4c 20 3f 44 42 3f 0a 23 0a 23 20 43 6f 6d  SQL ?DB?.#.# Com
06b0: 6d 61 6e 64 73 20 74 6f 20 72 75 6e 20 74 65 73  mands to run tes
06c0: 74 20 63 61 73 65 73 3a 0a 23 0a 23 20 20 20 20  t cases:.#.#    
06d0: 20 20 64 6f 5f 69 6f 65 72 72 5f 74 65 73 74 20    do_ioerr_test 
06e0: 20 20 20 20 20 20 20 20 20 54 45 53 54 4e 41 4d           TESTNAM
06f0: 45 20 41 52 47 53 2e 2e 2e 0a 23 20 20 20 20 20  E ARGS....#     
0700: 20 63 72 61 73 68 73 71 6c 20 20 20 20 20 20 20   crashsql       
0710: 20 20 20 20 20 20 20 20 41 52 47 53 2e 2e 2e 0a          ARGS....
0720: 23 20 20 20 20 20 20 69 6e 74 65 67 72 69 74 79  #      integrity
0730: 5f 63 68 65 63 6b 20 20 20 20 20 20 20 20 54 45  _check        TE
0740: 53 54 4e 41 4d 45 20 3f 44 42 3f 0a 23 20 20 20  STNAME ?DB?.#   
0750: 20 20 20 76 65 72 69 66 79 5f 65 78 5f 65 72 72     verify_ex_err
0760: 63 6f 64 65 20 20 20 20 20 20 54 45 53 54 4e 41  code      TESTNA
0770: 4d 45 20 45 58 50 45 43 54 45 44 20 3f 44 42 3f  ME EXPECTED ?DB?
0780: 0a 23 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20  .#      do_test 
0790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54                 T
07a0: 45 53 54 4e 41 4d 45 20 53 43 52 49 50 54 20 45  ESTNAME SCRIPT E
07b0: 58 50 45 43 54 45 44 0a 23 20 20 20 20 20 20 64  XPECTED.#      d
07c0: 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73 74 20 20  o_execsql_test  
07d0: 20 20 20 20 20 20 54 45 53 54 4e 41 4d 45 20 53        TESTNAME S
07e0: 51 4c 20 45 58 50 45 43 54 45 44 0a 23 20 20 20  QL EXPECTED.#   
07f0: 20 20 20 64 6f 5f 63 61 74 63 68 73 71 6c 5f 74     do_catchsql_t
0800: 65 73 74 20 20 20 20 20 20 20 54 45 53 54 4e 41  est       TESTNA
0810: 4d 45 20 53 51 4c 20 45 58 50 45 43 54 45 44 0a  ME SQL EXPECTED.
0820: 23 20 20 20 20 20 20 64 6f 5f 74 69 6d 65 64 5f  #      do_timed_
0830: 65 78 65 63 73 71 6c 5f 74 65 73 74 20 20 54 45  execsql_test  TE
0840: 53 54 4e 41 4d 45 20 53 51 4c 20 45 58 50 45 43  STNAME SQL EXPEC
0850: 54 45 44 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 73  TED.#.# Commands
0860: 20 70 72 6f 76 69 64 69 6e 67 20 61 20 6c 6f 77   providing a low
0870: 65 72 20 6c 65 76 65 6c 20 69 6e 74 65 72 66 61  er level interfa
0880: 63 65 20 74 6f 20 74 68 65 20 67 6c 6f 62 61 6c  ce to the global
0890: 20 74 65 73 74 20 63 6f 75 6e 74 65 72 73 3a 0a   test counters:.
08a0: 23 0a 23 20 20 20 20 20 20 73 65 74 5f 74 65 73  #.#      set_tes
08b0: 74 5f 63 6f 75 6e 74 65 72 20 20 20 20 20 20 20  t_counter       
08c0: 43 4f 55 4e 54 45 52 20 3f 56 41 4c 55 45 3f 0a  COUNTER ?VALUE?.
08d0: 23 20 20 20 20 20 20 6f 6d 69 74 5f 74 65 73 74  #      omit_test
08e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 45                TE
08f0: 53 54 4e 41 4d 45 20 52 45 41 53 4f 4e 20 3f 41  STNAME REASON ?A
0900: 50 50 45 4e 44 3f 0a 23 20 20 20 20 20 20 66 61  PPEND?.#      fa
0910: 69 6c 5f 74 65 73 74 20 20 20 20 20 20 20 20 20  il_test         
0920: 20 20 20 20 20 54 45 53 54 4e 41 4d 45 0a 23 20       TESTNAME.# 
0930: 20 20 20 20 20 69 6e 63 72 5f 6e 74 65 73 74 0a       incr_ntest.
0940: 23 0a 23 20 43 6f 6d 6d 61 6e 64 20 72 75 6e 20  #.# Command run 
0950: 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61  at the end of ea
0960: 63 68 20 74 65 73 74 20 66 69 6c 65 3a 0a 23 0a  ch test file:.#.
0970: 23 20 20 20 20 20 20 66 69 6e 69 73 68 5f 74 65  #      finish_te
0980: 73 74 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 73 20  st.#.# Commands 
0990: 74 6f 20 68 65 6c 70 20 63 72 65 61 74 65 20 74  to help create t
09a0: 65 73 74 20 66 69 6c 65 73 20 74 68 61 74 20 72  est files that r
09b0: 75 6e 20 77 69 74 68 20 74 68 65 20 22 57 41 4c  un with the "WAL
09c0: 22 20 61 6e 64 20 6f 74 68 65 72 0a 23 20 70 65  " and other.# pe
09d0: 72 6d 75 74 61 74 69 6f 6e 73 20 28 73 65 65 20  rmutations (see 
09e0: 66 69 6c 65 20 70 65 72 6d 75 74 61 74 69 6f 6e  file permutation
09f0: 73 2e 74 65 73 74 29 3a 0a 23 0a 23 20 20 20 20  s.test):.#.#    
0a00: 20 20 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64    wal_is_wal_mod
0a10: 65 0a 23 20 20 20 20 20 20 77 61 6c 5f 73 65 74  e.#      wal_set
0a20: 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 20 20  _journal_mode   
0a30: 3f 44 42 3f 0a 23 20 20 20 20 20 20 77 61 6c 5f  ?DB?.#      wal_
0a40: 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f  check_journal_mo
0a50: 64 65 20 54 45 53 54 4e 41 4d 45 3f 44 42 3f 0a  de TESTNAME?DB?.
0a60: 23 20 20 20 20 20 20 70 65 72 6d 75 74 61 74 69  #      permutati
0a70: 6f 6e 0a 23 20 20 20 20 20 20 70 72 65 73 71 6c  on.#      presql
0a80: 0a 23 0a 23 20 43 6f 6d 6d 61 6e 64 20 74 6f 20  .#.# Command to 
0a90: 74 65 73 74 20 77 68 65 74 68 65 72 20 6f 72 20  test whether or 
0aa0: 6e 6f 74 20 2d 2d 76 65 72 62 6f 73 65 3d 31 20  not --verbose=1 
0ab0: 77 61 73 20 73 70 65 63 69 66 69 65 64 20 6f 6e  was specified on
0ac0: 20 74 68 65 20 63 6f 6d 6d 61 6e 64 0a 23 20 6c   the command.# l
0ad0: 69 6e 65 20 28 72 65 74 75 72 6e 73 20 30 20 66  ine (returns 0 f
0ae0: 6f 72 20 6e 6f 74 2d 76 65 72 62 6f 73 65 2c 20  or not-verbose, 
0af0: 31 20 66 6f 72 20 76 65 72 62 6f 73 65 20 61 6e  1 for verbose an
0b00: 64 20 32 20 66 6f 72 20 22 76 65 72 62 6f 73 65  d 2 for "verbose
0b10: 20 69 6e 20 74 68 65 0a 23 20 6f 75 74 70 75 74   in the.# output
0b20: 20 66 69 6c 65 20 6f 6e 6c 79 22 29 2e 0a 23 0a   file only")..#.
0b30: 23 20 20 20 20 20 20 76 65 72 62 6f 73 65 0a 23  #      verbose.#
0b40: 0a 0a 23 20 53 65 74 20 74 68 65 20 70 72 65 63  ..# Set the prec
0b50: 69 73 69 6f 6e 20 6f 66 20 46 50 20 61 72 69 74  ision of FP arit
0b60: 68 6d 61 74 69 63 20 75 73 65 64 20 62 79 20 74  hmatic used by t
0b70: 68 65 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20  he interpreter. 
0b80: 41 6e 64 0a 23 20 63 6f 6e 66 69 67 75 72 65 20  And.# configure 
0b90: 53 51 4c 69 74 65 20 74 6f 20 74 61 6b 65 20 64  SQLite to take d
0ba0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 6c 6f 63  atabase file loc
0bb0: 6b 73 20 6f 6e 20 74 68 65 20 70 61 67 65 20 74  ks on the page t
0bc0: 68 61 74 20 62 65 67 69 6e 73 0a 23 20 36 34 4b  hat begins.# 64K
0bd0: 42 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  B into the datab
0be0: 61 73 65 20 66 69 6c 65 20 69 6e 73 74 65 61 64  ase file instead
0bf0: 20 6f 66 20 74 68 65 20 6f 6e 65 20 31 47 42 20   of the one 1GB 
0c00: 69 6e 2e 20 54 68 69 73 20 6d 65 61 6e 73 0a 23  in. This means.#
0c10: 20 74 68 65 20 63 6f 64 65 20 74 68 61 74 20 68   the code that h
0c20: 61 6e 64 6c 65 73 20 74 68 61 74 20 73 70 65 63  andles that spec
0c30: 69 61 6c 20 63 61 73 65 20 63 61 6e 20 62 65 20  ial case can be 
0c40: 74 65 73 74 65 64 20 77 69 74 68 6f 75 74 20 63  tested without c
0c50: 72 65 61 74 69 6e 67 0a 23 20 76 65 72 79 20 6c  reating.# very l
0c60: 61 72 67 65 20 64 61 74 61 62 61 73 65 20 66 69  arge database fi
0c70: 6c 65 73 2e 0a 23 0a 73 65 74 20 74 63 6c 5f 70  les..#.set tcl_p
0c80: 72 65 63 69 73 69 6f 6e 20 31 35 0a 73 71 6c 69  recision 15.sqli
0c90: 74 65 33 5f 74 65 73 74 5f 63 6f 6e 74 72 6f 6c  te3_test_control
0ca0: 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 20 30 78  _pending_byte 0x
0cb0: 30 30 31 30 30 30 30 0a 0a 0a 23 20 49 66 20 74  0010000...# If t
0cc0: 68 65 20 70 61 67 65 72 20 63 6f 64 65 63 20 69  he pager codec i
0cd0: 73 20 61 76 61 69 6c 61 62 6c 65 2c 20 63 72 65  s available, cre
0ce0: 61 74 65 20 61 20 77 72 61 70 70 65 72 20 66 6f  ate a wrapper fo
0cf0: 72 20 74 68 65 20 5b 73 71 6c 69 74 65 33 5d 0a  r the [sqlite3].
0d00: 23 20 63 6f 6d 6d 61 6e 64 20 74 68 61 74 20 61  # command that a
0d10: 70 70 65 6e 64 73 20 22 2d 6b 65 79 20 7b 78 79  ppends "-key {xy
0d20: 7a 7a 79 7d 22 20 74 6f 20 74 68 65 20 63 6f 6d  zzy}" to the com
0d30: 6d 61 6e 64 20 6c 69 6e 65 2e 20 69 2e 65 2e 20  mand line. i.e. 
0d40: 74 68 69 73 3a 0a 23 0a 23 20 20 20 20 20 73 71  this:.#.#     sq
0d50: 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64 62  lite3 db test.db
0d60: 0a 23 0a 23 20 62 65 63 6f 6d 65 73 0a 23 0a 23  .#.# becomes.#.#
0d70: 20 20 20 20 20 73 71 6c 69 74 65 33 20 64 62 20       sqlite3 db 
0d80: 74 65 73 74 2e 64 62 20 2d 6b 65 79 20 7b 78 79  test.db -key {xy
0d90: 7a 7a 79 7d 0a 23 0a 69 66 20 7b 5b 69 6e 66 6f  zzy}.#.if {[info
0da0: 20 63 6f 6d 6d 61 6e 64 20 73 71 6c 69 74 65 5f   command sqlite_
0db0: 6f 72 69 67 5d 3d 3d 22 22 7d 20 7b 0a 20 20 72  orig]==""} {.  r
0dc0: 65 6e 61 6d 65 20 73 71 6c 69 74 65 33 20 73 71  ename sqlite3 sq
0dd0: 6c 69 74 65 5f 6f 72 69 67 0a 20 20 70 72 6f 63  lite_orig.  proc
0de0: 20 73 71 6c 69 74 65 33 20 7b 61 72 67 73 7d 20   sqlite3 {args} 
0df0: 7b 0a 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67  {.    if {[lleng
0e00: 74 68 20 24 61 72 67 73 5d 3e 3d 32 20 26 26 20  th $args]>=2 && 
0e10: 5b 73 74 72 69 6e 67 20 69 6e 64 65 78 20 5b 6c  [string index [l
0e20: 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d 20 30  index $args 0] 0
0e30: 5d 21 3d 22 2d 22 7d 20 7b 0a 20 20 20 20 20 20  ]!="-"} {.      
0e40: 23 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64 20 69  # This command i
0e50: 73 20 6f 70 65 6e 69 6e 67 20 61 20 6e 65 77 20  s opening a new 
0e60: 64 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74  database connect
0e70: 69 6f 6e 2e 0a 20 20 20 20 20 20 23 0a 20 20 20  ion..      #.   
0e80: 20 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69     if {[info exi
0e90: 73 74 73 20 3a 3a 47 28 70 65 72 6d 3a 73 71 6c  sts ::G(perm:sql
0ea0: 69 74 65 33 5f 61 72 67 73 29 5d 7d 20 7b 0a 20  ite3_args)]} {. 
0eb0: 20 20 20 20 20 20 20 73 65 74 20 61 72 67 73 20         set args 
0ec0: 5b 63 6f 6e 63 61 74 20 24 61 72 67 73 20 24 3a  [concat $args $:
0ed0: 3a 47 28 70 65 72 6d 3a 73 71 6c 69 74 65 33 5f  :G(perm:sqlite3_
0ee0: 61 72 67 73 29 5d 0a 20 20 20 20 20 20 7d 0a 20  args)].      }. 
0ef0: 20 20 20 20 20 69 66 20 7b 5b 73 71 6c 69 74 65       if {[sqlite
0f00: 5f 6f 72 69 67 20 2d 68 61 73 2d 63 6f 64 65 63  _orig -has-codec
0f10: 5d 20 26 26 20 21 5b 69 6e 66 6f 20 65 78 69 73  ] && ![info exis
0f20: 74 73 20 3a 3a 64 6f 5f 6e 6f 74 5f 75 73 65 5f  ts ::do_not_use_
0f30: 63 6f 64 65 63 5d 7d 20 7b 0a 20 20 20 20 20 20  codec]} {.      
0f40: 20 20 6c 61 70 70 65 6e 64 20 61 72 67 73 20 2d    lappend args -
0f50: 6b 65 79 20 7b 78 79 7a 7a 79 7d 0a 20 20 20 20  key {xyzzy}.    
0f60: 20 20 7d 0a 0a 20 20 20 20 20 20 73 65 74 20 72    }..      set r
0f70: 65 73 20 5b 75 70 6c 65 76 65 6c 20 31 20 73 71  es [uplevel 1 sq
0f80: 6c 69 74 65 5f 6f 72 69 67 20 24 61 72 67 73 5d  lite_orig $args]
0f90: 0a 20 20 20 20 20 20 69 66 20 7b 5b 69 6e 66 6f  .      if {[info
0fa0: 20 65 78 69 73 74 73 20 3a 3a 47 28 70 65 72 6d   exists ::G(perm
0fb0: 3a 70 72 65 73 71 6c 29 5d 7d 20 7b 0a 20 20 20  :presql)]} {.   
0fc0: 20 20 20 20 20 5b 6c 69 6e 64 65 78 20 24 61 72       [lindex $ar
0fd0: 67 73 20 30 5d 20 65 76 61 6c 20 24 3a 3a 47 28  gs 0] eval $::G(
0fe0: 70 65 72 6d 3a 70 72 65 73 71 6c 29 0a 20 20 20  perm:presql).   
0ff0: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 20 7b 5b     }.      if {[
1000: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
1010: 70 65 72 6d 3a 64 62 63 6f 6e 66 69 67 29 5d 7d  perm:dbconfig)]}
1020: 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a   {.        set :
1030: 3a 64 62 68 61 6e 64 6c 65 20 5b 6c 69 6e 64 65  :dbhandle [linde
1040: 78 20 24 61 72 67 73 20 30 5d 0a 20 20 20 20 20  x $args 0].     
1050: 20 20 20 75 70 6c 65 76 65 6c 20 23 30 20 24 3a     uplevel #0 $:
1060: 3a 47 28 70 65 72 6d 3a 64 62 63 6f 6e 66 69 67  :G(perm:dbconfig
1070: 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ).      }.      
1080: 73 65 74 20 72 65 73 0a 20 20 20 20 7d 20 65 6c  set res.    } el
1090: 73 65 20 7b 0a 20 20 20 20 20 20 23 20 54 68 69  se {.      # Thi
10a0: 73 20 63 6f 6d 6d 61 6e 64 20 69 73 20 6e 6f 74  s command is not
10b0: 20 6f 70 65 6e 69 6e 67 20 61 20 6e 65 77 20 64   opening a new d
10c0: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
10d0: 6f 6e 2e 20 50 61 73 73 20 74 68 65 0a 20 20 20  on. Pass the.   
10e0: 20 20 20 23 20 61 72 67 75 6d 65 6e 74 73 20 74     # arguments t
10f0: 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 43 20  hrough to the C 
1100: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 61  implementation a
1110: 73 20 74 68 65 20 61 72 65 2e 0a 20 20 20 20 20  s the are..     
1120: 20 23 0a 20 20 20 20 20 20 75 70 6c 65 76 65 6c   #.      uplevel
1130: 20 31 20 73 71 6c 69 74 65 5f 6f 72 69 67 20 24   1 sqlite_orig $
1140: 61 72 67 73 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d  args.    }.  }.}
1150: 0a 0a 70 72 6f 63 20 67 65 74 46 69 6c 65 52 65  ..proc getFileRe
1160: 74 72 69 65 73 20 7b 7d 20 7b 0a 20 20 69 66 20  tries {} {.  if 
1170: 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a  {![info exists :
1180: 3a 47 28 66 69 6c 65 2d 72 65 74 72 69 65 73 29  :G(file-retries)
1190: 5d 7d 20 7b 0a 20 20 20 20 23 0a 20 20 20 20 23  ]} {.    #.    #
11a0: 20 4e 4f 54 45 3a 20 52 65 74 75 72 6e 20 74 68   NOTE: Return th
11b0: 65 20 64 65 66 61 75 6c 74 20 6e 75 6d 62 65 72  e default number
11c0: 20 6f 66 20 72 65 74 72 69 65 73 20 66 6f 72 20   of retries for 
11d0: 5b 66 69 6c 65 5d 20 6f 70 65 72 61 74 69 6f 6e  [file] operation
11e0: 73 2e 20 20 41 0a 20 20 20 20 23 20 20 20 20 20  s.  A.    #     
11f0: 20 20 76 61 6c 75 65 20 6f 66 20 7a 65 72 6f 20    value of zero 
1200: 6f 72 20 6c 65 73 73 20 68 65 72 65 20 6d 65 61  or less here mea
1210: 6e 73 20 22 64 69 73 61 62 6c 65 64 22 2e 0a 20  ns "disabled".. 
1220: 20 20 20 23 0a 20 20 20 20 72 65 74 75 72 6e 20     #.    return 
1230: 5b 65 78 70 72 20 7b 24 3a 3a 74 63 6c 5f 70 6c  [expr {$::tcl_pl
1240: 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29  atform(platform)
1250: 20 65 71 20 22 77 69 6e 64 6f 77 73 22 20 3f 20   eq "windows" ? 
1260: 35 30 20 3a 20 30 7d 5d 0a 20 20 7d 0a 20 20 72  50 : 0}].  }.  r
1270: 65 74 75 72 6e 20 24 3a 3a 47 28 66 69 6c 65 2d  eturn $::G(file-
1280: 72 65 74 72 69 65 73 29 0a 7d 0a 0a 70 72 6f 63  retries).}..proc
1290: 20 67 65 74 46 69 6c 65 52 65 74 72 79 44 65 6c   getFileRetryDel
12a0: 61 79 20 7b 7d 20 7b 0a 20 20 69 66 20 7b 21 5b  ay {} {.  if {![
12b0: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28  info exists ::G(
12c0: 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c 61 79  file-retry-delay
12d0: 29 5d 7d 20 7b 0a 20 20 20 20 23 0a 20 20 20 20  )]} {.    #.    
12e0: 23 20 4e 4f 54 45 3a 20 52 65 74 75 72 6e 20 74  # NOTE: Return t
12f0: 68 65 20 64 65 66 61 75 6c 74 20 6e 75 6d 62 65  he default numbe
1300: 72 20 6f 66 20 6d 69 6c 6c 69 73 65 63 6f 6e 64  r of millisecond
1310: 73 20 74 6f 20 77 61 69 74 20 77 68 65 6e 20 72  s to wait when r
1320: 65 74 72 79 69 6e 67 0a 20 20 20 20 23 20 20 20  etrying.    #   
1330: 20 20 20 20 66 61 69 6c 65 64 20 5b 66 69 6c 65      failed [file
1340: 5d 20 6f 70 65 72 61 74 69 6f 6e 73 2e 20 20 41  ] operations.  A
1350: 20 76 61 6c 75 65 20 6f 66 20 7a 65 72 6f 20 6f   value of zero o
1360: 72 20 6c 65 73 73 20 6d 65 61 6e 73 20 22 64 6f  r less means "do
1370: 20 6e 6f 74 0a 20 20 20 20 23 20 20 20 20 20 20   not.    #      
1380: 20 77 61 69 74 22 2e 0a 20 20 20 20 23 0a 20 20   wait"..    #.  
1390: 20 20 72 65 74 75 72 6e 20 31 30 30 3b 20 23 20    return 100; # 
13a0: 54 4f 44 4f 3a 20 47 6f 6f 64 20 64 65 66 61 75  TODO: Good defau
13b0: 6c 74 3f 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  lt?.  }.  return
13c0: 20 24 3a 3a 47 28 66 69 6c 65 2d 72 65 74 72 79   $::G(file-retry
13d0: 2d 64 65 6c 61 79 29 0a 7d 0a 0a 23 20 52 65 74  -delay).}..# Ret
13e0: 75 72 6e 20 74 68 65 20 73 74 72 69 6e 67 20 72  urn the string r
13f0: 65 70 72 65 73 65 6e 74 69 6e 67 20 74 68 65 20  epresenting the 
1400: 6e 61 6d 65 20 6f 66 20 74 68 65 20 63 75 72 72  name of the curr
1410: 65 6e 74 20 64 69 72 65 63 74 6f 72 79 2e 20 20  ent directory.  
1420: 4f 6e 0a 23 20 57 69 6e 64 6f 77 73 2c 20 74 68  On.# Windows, th
1430: 65 20 72 65 73 75 6c 74 20 69 73 20 22 6e 6f 72  e result is "nor
1440: 6d 61 6c 69 7a 65 64 22 20 74 6f 20 77 68 61 74  malized" to what
1450: 65 76 65 72 20 6f 75 72 20 70 61 72 65 6e 74 20  ever our parent 
1460: 63 6f 6d 6d 61 6e 64 20 73 68 65 6c 6c 0a 23 20  command shell.# 
1470: 69 73 20 75 73 69 6e 67 20 74 6f 20 70 72 65 76  is using to prev
1480: 65 6e 74 20 63 61 73 65 2d 6d 69 73 6d 61 74 63  ent case-mismatc
1490: 68 20 69 73 73 75 65 73 2e 0a 23 0a 70 72 6f 63  h issues..#.proc
14a0: 20 67 65 74 5f 70 77 64 20 7b 7d 20 7b 0a 20 20   get_pwd {} {.  
14b0: 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66  if {$::tcl_platf
14c0: 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 20 65 71  orm(platform) eq
14d0: 20 22 77 69 6e 64 6f 77 73 22 7d 20 7b 0a 20 20   "windows"} {.  
14e0: 20 20 23 0a 20 20 20 20 23 20 4e 4f 54 45 3a 20    #.    # NOTE: 
14f0: 43 61 6e 6e 6f 74 20 75 73 65 20 5b 66 69 6c 65  Cannot use [file
1500: 20 6e 6f 72 6d 61 6c 69 7a 65 5d 20 68 65 72 65   normalize] here
1510: 20 62 65 63 61 75 73 65 20 69 74 20 77 6f 75 6c   because it woul
1520: 64 20 61 6c 74 65 72 20 74 68 65 0a 20 20 20 20  d alter the.    
1530: 23 20 20 20 20 20 20 20 63 61 73 65 20 6f 66 20  #       case of 
1540: 74 68 65 20 72 65 73 75 6c 74 20 74 6f 20 77 68  the result to wh
1550: 61 74 20 54 63 6c 20 63 6f 6e 73 69 64 65 72 73  at Tcl considers
1560: 20 63 61 6e 6f 6e 69 63 61 6c 2c 20 77 68 69 63   canonical, whic
1570: 68 20 77 6f 75 6c 64 0a 20 20 20 20 23 20 20 20  h would.    #   
1580: 20 20 20 20 64 65 66 65 61 74 20 74 68 65 20 70      defeat the p
1590: 75 72 70 6f 73 65 20 6f 66 20 74 68 69 73 20 70  urpose of this p
15a0: 72 6f 63 65 64 75 72 65 2e 0a 20 20 20 20 23 0a  rocedure..    #.
15b0: 20 20 20 20 72 65 74 75 72 6e 20 5b 73 74 72 69      return [stri
15c0: 6e 67 20 6d 61 70 20 5b 6c 69 73 74 20 5c 5c 20  ng map [list \\ 
15d0: 2f 5d 20 5c 0a 20 20 20 20 20 20 20 20 5b 73 74  /] \.        [st
15e0: 72 69 6e 67 20 74 72 69 6d 20 5b 65 78 65 63 20  ring trim [exec 
15f0: 2d 2d 20 24 3a 3a 65 6e 76 28 43 6f 6d 53 70 65  -- $::env(ComSpe
1600: 63 29 20 2f 63 20 65 63 68 6f 20 25 43 44 25 5d  c) /c echo %CD%]
1610: 5d 5d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  ]].  } else {.  
1620: 20 20 72 65 74 75 72 6e 20 5b 70 77 64 5d 0a 20    return [pwd]. 
1630: 20 7d 0a 7d 0a 0a 23 20 43 6f 70 79 20 66 69 6c   }.}..# Copy fil
1640: 65 20 24 66 72 6f 6d 20 69 6e 74 6f 20 24 74 6f  e $from into $to
1650: 2e 20 54 68 69 73 20 69 73 20 75 73 65 64 20 62  . This is used b
1660: 65 63 61 75 73 65 20 73 6f 6d 65 20 76 65 72 73  ecause some vers
1670: 69 6f 6e 73 20 6f 66 0a 23 20 54 43 4c 20 66 6f  ions of.# TCL fo
1680: 72 20 77 69 6e 64 6f 77 73 20 28 6e 6f 74 61 62  r windows (notab
1690: 6c 79 20 74 68 65 20 38 2e 34 2e 31 20 62 69 6e  ly the 8.4.1 bin
16a0: 61 72 79 20 70 61 63 6b 61 67 65 20 73 68 69 70  ary package ship
16b0: 70 65 64 20 77 69 74 68 20 74 68 65 0a 23 20 63  ped with the.# c
16c0: 75 72 72 65 6e 74 20 6d 69 6e 67 77 20 72 65 6c  urrent mingw rel
16d0: 65 61 73 65 29 20 68 61 76 65 20 61 20 62 72 6f  ease) have a bro
16e0: 6b 65 6e 20 22 66 69 6c 65 20 63 6f 70 79 22 20  ken "file copy" 
16f0: 63 6f 6d 6d 61 6e 64 2e 0a 23 0a 70 72 6f 63 20  command..#.proc 
1700: 63 6f 70 79 5f 66 69 6c 65 20 7b 66 72 6f 6d 20  copy_file {from 
1710: 74 6f 7d 20 7b 0a 20 20 64 6f 5f 63 6f 70 79 5f  to} {.  do_copy_
1720: 66 69 6c 65 20 66 61 6c 73 65 20 24 66 72 6f 6d  file false $from
1730: 20 24 74 6f 0a 7d 0a 0a 70 72 6f 63 20 66 6f 72   $to.}..proc for
1740: 63 65 63 6f 70 79 20 7b 66 72 6f 6d 20 74 6f 7d  cecopy {from to}
1750: 20 7b 0a 20 20 64 6f 5f 63 6f 70 79 5f 66 69 6c   {.  do_copy_fil
1760: 65 20 74 72 75 65 20 24 66 72 6f 6d 20 24 74 6f  e true $from $to
1770: 0a 7d 0a 0a 70 72 6f 63 20 64 6f 5f 63 6f 70 79  .}..proc do_copy
1780: 5f 66 69 6c 65 20 7b 66 6f 72 63 65 20 66 72 6f  _file {force fro
1790: 6d 20 74 6f 7d 20 7b 0a 20 20 73 65 74 20 6e 52  m to} {.  set nR
17a0: 65 74 72 79 20 5b 67 65 74 46 69 6c 65 52 65 74  etry [getFileRet
17b0: 72 69 65 73 5d 20 20 20 20 20 3b 23 20 4d 61 78  ries]     ;# Max
17c0: 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 72  imum number of r
17d0: 65 74 72 69 65 73 2e 0a 20 20 73 65 74 20 6e 44  etries..  set nD
17e0: 65 6c 61 79 20 5b 67 65 74 46 69 6c 65 52 65 74  elay [getFileRet
17f0: 72 79 44 65 6c 61 79 5d 20 20 3b 23 20 44 65 6c  ryDelay]  ;# Del
1800: 61 79 20 69 6e 20 6d 73 20 62 65 66 6f 72 65 20  ay in ms before 
1810: 72 65 74 72 79 69 6e 67 2e 0a 0a 20 20 23 20 4f  retrying...  # O
1820: 6e 20 77 69 6e 64 6f 77 73 2c 20 73 6f 6d 65 74  n windows, somet
1830: 69 6d 65 73 20 65 76 65 6e 20 61 20 5b 66 69 6c  imes even a [fil
1840: 65 20 63 6f 70 79 20 2d 66 6f 72 63 65 5d 20 63  e copy -force] c
1850: 61 6e 20 66 61 69 6c 2e 20 54 68 65 20 63 61 75  an fail. The cau
1860: 73 65 20 69 73 0a 20 20 23 20 75 73 75 61 6c 6c  se is.  # usuall
1870: 79 20 22 74 61 67 2d 61 6c 6f 6e 67 73 22 20 2d  y "tag-alongs" -
1880: 20 70 72 6f 67 72 61 6d 73 20 6c 69 6b 65 20 61   programs like a
1890: 6e 74 69 2d 76 69 72 75 73 20 73 6f 66 74 77 61  nti-virus softwa
18a0: 72 65 2c 20 61 75 74 6f 6d 61 74 69 63 20 62 61  re, automatic ba
18b0: 63 6b 75 70 0a 20 20 23 20 74 6f 6f 6c 73 20 61  ckup.  # tools a
18c0: 6e 64 20 76 61 72 69 6f 75 73 20 65 78 70 6c 6f  nd various explo
18d0: 72 65 72 20 65 78 74 65 6e 73 69 6f 6e 73 20 74  rer extensions t
18e0: 68 61 74 20 6b 65 65 70 20 61 20 66 69 6c 65 20  hat keep a file 
18f0: 6f 70 65 6e 20 61 20 6c 69 74 74 6c 65 20 6c 6f  open a little lo
1900: 6e 67 65 72 0a 20 20 23 20 74 68 61 6e 20 77 65  nger.  # than we
1910: 20 65 78 70 65 63 74 2c 20 63 61 75 73 69 6e 67   expect, causing
1920: 20 74 68 65 20 64 65 6c 65 74 65 20 74 6f 20 66   the delete to f
1930: 61 69 6c 2e 0a 20 20 23 0a 20 20 23 20 54 68 65  ail..  #.  # The
1940: 20 73 6f 6c 75 74 69 6f 6e 20 69 73 20 74 6f 20   solution is to 
1950: 77 61 69 74 20 61 20 73 68 6f 72 74 20 61 6d 6f  wait a short amo
1960: 75 6e 74 20 6f 66 20 74 69 6d 65 20 62 65 66 6f  unt of time befo
1970: 72 65 20 72 65 74 72 79 69 6e 67 20 74 68 65 20  re retrying the 
1980: 63 6f 70 79 2e 0a 20 20 23 0a 20 20 69 66 20 7b  copy..  #.  if {
1990: 24 6e 52 65 74 72 79 20 3e 20 30 7d 20 7b 0a 20  $nRetry > 0} {. 
19a0: 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d     for {set i 0}
19b0: 20 7b 24 69 3c 24 6e 52 65 74 72 79 7d 20 7b 69   {$i<$nRetry} {i
19c0: 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 73  ncr i} {.      s
19d0: 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b 0a 20  et rc [catch {. 
19e0: 20 20 20 20 20 20 20 69 66 20 7b 24 66 6f 72 63         if {$forc
19f0: 65 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 66  e} {.          f
1a00: 69 6c 65 20 63 6f 70 79 20 2d 66 6f 72 63 65 20  ile copy -force 
1a10: 24 66 72 6f 6d 20 24 74 6f 0a 20 20 20 20 20 20  $from $to.      
1a20: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
1a30: 20 20 20 20 20 66 69 6c 65 20 63 6f 70 79 20 24       file copy $
1a40: 66 72 6f 6d 20 24 74 6f 0a 20 20 20 20 20 20 20  from $to.       
1a50: 20 7d 0a 20 20 20 20 20 20 7d 20 6d 73 67 5d 0a   }.      } msg].
1a60: 20 20 20 20 20 20 69 66 20 7b 24 72 63 3d 3d 30        if {$rc==0
1a70: 7d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 69 66  } break.      if
1a80: 20 7b 24 6e 44 65 6c 61 79 20 3e 20 30 7d 20 7b   {$nDelay > 0} {
1a90: 20 61 66 74 65 72 20 24 6e 44 65 6c 61 79 20 7d   after $nDelay }
1aa0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 24  .    }.    if {$
1ab0: 72 63 7d 20 7b 20 65 72 72 6f 72 20 24 6d 73 67  rc} { error $msg
1ac0: 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20   }.  } else {.  
1ad0: 20 20 69 66 20 7b 24 66 6f 72 63 65 7d 20 7b 0a    if {$force} {.
1ae0: 20 20 20 20 20 20 66 69 6c 65 20 63 6f 70 79 20        file copy 
1af0: 2d 66 6f 72 63 65 20 24 66 72 6f 6d 20 24 74 6f  -force $from $to
1b00: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
1b10: 20 20 20 20 66 69 6c 65 20 63 6f 70 79 20 24 66      file copy $f
1b20: 72 6f 6d 20 24 74 6f 0a 20 20 20 20 7d 0a 20 20  rom $to.    }.  
1b30: 7d 0a 7d 0a 0a 23 20 43 68 65 63 6b 20 69 66 20  }.}..# Check if 
1b40: 61 20 66 69 6c 65 20 6e 61 6d 65 20 69 73 20 72  a file name is r
1b50: 65 6c 61 74 69 76 65 0a 23 0a 70 72 6f 63 20 69  elative.#.proc i
1b60: 73 5f 72 65 6c 61 74 69 76 65 5f 66 69 6c 65 20  s_relative_file 
1b70: 7b 20 66 69 6c 65 20 7d 20 7b 0a 20 20 72 65 74  { file } {.  ret
1b80: 75 72 6e 20 5b 65 78 70 72 20 7b 5b 66 69 6c 65  urn [expr {[file
1b90: 20 70 61 74 68 74 79 70 65 20 24 66 69 6c 65 5d   pathtype $file]
1ba0: 20 21 3d 20 22 61 62 73 6f 6c 75 74 65 22 7d 5d   != "absolute"}]
1bb0: 0a 7d 0a 0a 23 20 49 66 20 74 68 65 20 56 46 53  .}..# If the VFS
1bc0: 20 73 75 70 70 6f 72 74 73 20 75 73 69 6e 67 20   supports using 
1bd0: 74 68 65 20 63 75 72 72 65 6e 74 20 64 69 72 65  the current dire
1be0: 63 74 6f 72 79 2c 20 72 65 74 75 72 6e 73 20 5b  ctory, returns [
1bf0: 70 77 64 5d 3b 0a 23 20 6f 74 68 65 72 77 69 73  pwd];.# otherwis
1c00: 65 2c 20 69 74 20 72 65 74 75 72 6e 73 20 6f 6e  e, it returns on
1c10: 6c 79 20 74 68 65 20 70 72 6f 76 69 64 65 64 20  ly the provided 
1c20: 73 75 66 66 69 78 20 73 74 72 69 6e 67 20 28 77  suffix string (w
1c30: 68 69 63 68 20 69 73 0a 23 20 65 6d 70 74 79 20  hich is.# empty 
1c40: 62 79 20 64 65 66 61 75 6c 74 29 2e 0a 23 0a 70  by default)..#.p
1c50: 72 6f 63 20 74 65 73 74 5f 70 77 64 20 7b 20 61  roc test_pwd { a
1c60: 72 67 73 20 7d 20 7b 0a 20 20 69 66 20 7b 5b 6c  rgs } {.  if {[l
1c70: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 20 3e 20  length $args] > 
1c80: 30 7d 20 7b 0a 20 20 20 20 73 65 74 20 73 75 66  0} {.    set suf
1c90: 66 69 78 31 20 5b 6c 69 6e 64 65 78 20 24 61 72  fix1 [lindex $ar
1ca0: 67 73 20 30 5d 0a 20 20 20 20 69 66 20 7b 5b 6c  gs 0].    if {[l
1cb0: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 20 3e 20  length $args] > 
1cc0: 31 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 73  1} {.      set s
1cd0: 75 66 66 69 78 32 20 5b 6c 69 6e 64 65 78 20 24  uffix2 [lindex $
1ce0: 61 72 67 73 20 31 5d 0a 20 20 20 20 7d 20 65 6c  args 1].    } el
1cf0: 73 65 20 7b 0a 20 20 20 20 20 20 73 65 74 20 73  se {.      set s
1d00: 75 66 66 69 78 32 20 24 73 75 66 66 69 78 31 0a  uffix2 $suffix1.
1d10: 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b      }.  } else {
1d20: 0a 20 20 20 20 73 65 74 20 73 75 66 66 69 78 31  .    set suffix1
1d30: 20 22 22 3b 20 73 65 74 20 73 75 66 66 69 78 32   ""; set suffix2
1d40: 20 22 22 0a 20 20 7d 0a 20 20 69 66 63 61 70 61   "".  }.  ifcapa
1d50: 62 6c 65 20 63 75 72 64 69 72 20 7b 0a 20 20 20  ble curdir {.   
1d60: 20 72 65 74 75 72 6e 20 22 5b 67 65 74 5f 70 77   return "[get_pw
1d70: 64 5d 24 73 75 66 66 69 78 31 22 0a 20 20 7d 20  d]$suffix1".  } 
1d80: 65 6c 73 65 20 7b 0a 20 20 20 20 72 65 74 75 72  else {.    retur
1d90: 6e 20 24 73 75 66 66 69 78 32 0a 20 20 7d 0a 7d  n $suffix2.  }.}
1da0: 0a 0a 23 20 44 65 6c 65 74 65 20 61 20 66 69 6c  ..# Delete a fil
1db0: 65 20 6f 72 20 64 69 72 65 63 74 6f 72 79 0a 23  e or directory.#
1dc0: 0a 70 72 6f 63 20 64 65 6c 65 74 65 5f 66 69 6c  .proc delete_fil
1dd0: 65 20 7b 61 72 67 73 7d 20 7b 0a 20 20 64 6f 5f  e {args} {.  do_
1de0: 64 65 6c 65 74 65 5f 66 69 6c 65 20 66 61 6c 73  delete_file fals
1df0: 65 20 7b 2a 7d 24 61 72 67 73 0a 7d 0a 0a 70 72  e {*}$args.}..pr
1e00: 6f 63 20 66 6f 72 63 65 64 65 6c 65 74 65 20 7b  oc forcedelete {
1e10: 61 72 67 73 7d 20 7b 0a 20 20 64 6f 5f 64 65 6c  args} {.  do_del
1e20: 65 74 65 5f 66 69 6c 65 20 74 72 75 65 20 7b 2a  ete_file true {*
1e30: 7d 24 61 72 67 73 0a 7d 0a 0a 70 72 6f 63 20 64  }$args.}..proc d
1e40: 6f 5f 64 65 6c 65 74 65 5f 66 69 6c 65 20 7b 66  o_delete_file {f
1e50: 6f 72 63 65 20 61 72 67 73 7d 20 7b 0a 20 20 73  orce args} {.  s
1e60: 65 74 20 6e 52 65 74 72 79 20 5b 67 65 74 46 69  et nRetry [getFi
1e70: 6c 65 52 65 74 72 69 65 73 5d 20 20 20 20 20 3b  leRetries]     ;
1e80: 23 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72  # Maximum number
1e90: 20 6f 66 20 72 65 74 72 69 65 73 2e 0a 20 20 73   of retries..  s
1ea0: 65 74 20 6e 44 65 6c 61 79 20 5b 67 65 74 46 69  et nDelay [getFi
1eb0: 6c 65 52 65 74 72 79 44 65 6c 61 79 5d 20 20 3b  leRetryDelay]  ;
1ec0: 23 20 44 65 6c 61 79 20 69 6e 20 6d 73 20 62 65  # Delay in ms be
1ed0: 66 6f 72 65 20 72 65 74 72 79 69 6e 67 2e 0a 0a  fore retrying...
1ee0: 20 20 66 6f 72 65 61 63 68 20 66 69 6c 65 6e 61    foreach filena
1ef0: 6d 65 20 24 61 72 67 73 20 7b 0a 20 20 20 20 23  me $args {.    #
1f00: 20 4f 6e 20 77 69 6e 64 6f 77 73 2c 20 73 6f 6d   On windows, som
1f10: 65 74 69 6d 65 73 20 65 76 65 6e 20 61 20 5b 66  etimes even a [f
1f20: 69 6c 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63  ile delete -forc
1f30: 65 5d 20 63 61 6e 20 66 61 69 6c 20 6a 75 73 74  e] can fail just
1f40: 20 61 66 74 65 72 0a 20 20 20 20 23 20 61 20 66   after.    # a f
1f50: 69 6c 65 20 69 73 20 63 6c 6f 73 65 64 2e 20 54  ile is closed. T
1f60: 68 65 20 63 61 75 73 65 20 69 73 20 75 73 75 61  he cause is usua
1f70: 6c 6c 79 20 22 74 61 67 2d 61 6c 6f 6e 67 73 22  lly "tag-alongs"
1f80: 20 2d 20 70 72 6f 67 72 61 6d 73 20 6c 69 6b 65   - programs like
1f90: 0a 20 20 20 20 23 20 61 6e 74 69 2d 76 69 72 75  .    # anti-viru
1fa0: 73 20 73 6f 66 74 77 61 72 65 2c 20 61 75 74 6f  s software, auto
1fb0: 6d 61 74 69 63 20 62 61 63 6b 75 70 20 74 6f 6f  matic backup too
1fc0: 6c 73 20 61 6e 64 20 76 61 72 69 6f 75 73 20 65  ls and various e
1fd0: 78 70 6c 6f 72 65 72 0a 20 20 20 20 23 20 65 78  xplorer.    # ex
1fe0: 74 65 6e 73 69 6f 6e 73 20 74 68 61 74 20 6b 65  tensions that ke
1ff0: 65 70 20 61 20 66 69 6c 65 20 6f 70 65 6e 20 61  ep a file open a
2000: 20 6c 69 74 74 6c 65 20 6c 6f 6e 67 65 72 20 74   little longer t
2010: 68 61 6e 20 77 65 20 65 78 70 65 63 74 2c 20 63  han we expect, c
2020: 61 75 73 69 6e 67 0a 20 20 20 20 23 20 74 68 65  ausing.    # the
2030: 20 64 65 6c 65 74 65 20 74 6f 20 66 61 69 6c 2e   delete to fail.
2040: 0a 20 20 20 20 23 0a 20 20 20 20 23 20 54 68 65  .    #.    # The
2050: 20 73 6f 6c 75 74 69 6f 6e 20 69 73 20 74 6f 20   solution is to 
2060: 77 61 69 74 20 61 20 73 68 6f 72 74 20 61 6d 6f  wait a short amo
2070: 75 6e 74 20 6f 66 20 74 69 6d 65 20 62 65 66 6f  unt of time befo
2080: 72 65 20 72 65 74 72 79 69 6e 67 20 74 68 65 0a  re retrying the.
2090: 20 20 20 20 23 20 64 65 6c 65 74 65 2e 0a 20 20      # delete..  
20a0: 20 20 23 0a 20 20 20 20 69 66 20 7b 24 6e 52 65    #.    if {$nRe
20b0: 74 72 79 20 3e 20 30 7d 20 7b 0a 20 20 20 20 20  try > 0} {.     
20c0: 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b   for {set i 0} {
20d0: 24 69 3c 24 6e 52 65 74 72 79 7d 20 7b 69 6e 63  $i<$nRetry} {inc
20e0: 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 20 20 73  r i} {.        s
20f0: 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b 0a 20  et rc [catch {. 
2100: 20 20 20 20 20 20 20 20 20 69 66 20 7b 24 66 6f           if {$fo
2110: 72 63 65 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  rce} {.         
2120: 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20 2d     file delete -
2130: 66 6f 72 63 65 20 24 66 69 6c 65 6e 61 6d 65 0a  force $filename.
2140: 20 20 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65            } else
2150: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 66   {.            f
2160: 69 6c 65 20 64 65 6c 65 74 65 20 24 66 69 6c 65  ile delete $file
2170: 6e 61 6d 65 0a 20 20 20 20 20 20 20 20 20 20 7d  name.          }
2180: 0a 20 20 20 20 20 20 20 20 7d 20 6d 73 67 5d 0a  .        } msg].
2190: 20 20 20 20 20 20 20 20 69 66 20 7b 24 72 63 3d          if {$rc=
21a0: 3d 30 7d 20 62 72 65 61 6b 0a 20 20 20 20 20 20  =0} break.      
21b0: 20 20 69 66 20 7b 24 6e 44 65 6c 61 79 20 3e 20    if {$nDelay > 
21c0: 30 7d 20 7b 20 61 66 74 65 72 20 24 6e 44 65 6c  0} { after $nDel
21d0: 61 79 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20  ay }.      }.   
21e0: 20 20 20 69 66 20 7b 24 72 63 7d 20 7b 20 65 72     if {$rc} { er
21f0: 72 6f 72 20 24 6d 73 67 20 7d 0a 20 20 20 20 7d  ror $msg }.    }
2200: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 69 66   else {.      if
2210: 20 7b 24 66 6f 72 63 65 7d 20 7b 0a 20 20 20 20   {$force} {.    
2220: 20 20 20 20 66 69 6c 65 20 64 65 6c 65 74 65 20      file delete 
2230: 2d 66 6f 72 63 65 20 24 66 69 6c 65 6e 61 6d 65  -force $filename
2240: 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  .      } else {.
2250: 20 20 20 20 20 20 20 20 66 69 6c 65 20 64 65 6c          file del
2260: 65 74 65 20 24 66 69 6c 65 6e 61 6d 65 0a 20 20  ete $filename.  
2270: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
2280: 7d 0a 0a 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c  }..if {$::tcl_pl
2290: 61 74 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29  atform(platform)
22a0: 20 65 71 20 22 77 69 6e 64 6f 77 73 22 7d 20 7b   eq "windows"} {
22b0: 0a 20 20 70 72 6f 63 20 64 6f 5f 72 65 6d 6f 76  .  proc do_remov
22c0: 65 5f 77 69 6e 33 32 5f 64 69 72 20 7b 61 72 67  e_win32_dir {arg
22d0: 73 7d 20 7b 0a 20 20 20 20 73 65 74 20 6e 52 65  s} {.    set nRe
22e0: 74 72 79 20 5b 67 65 74 46 69 6c 65 52 65 74 72  try [getFileRetr
22f0: 69 65 73 5d 20 20 20 20 20 3b 23 20 4d 61 78 69  ies]     ;# Maxi
2300: 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 72 65  mum number of re
2310: 74 72 69 65 73 2e 0a 20 20 20 20 73 65 74 20 6e  tries..    set n
2320: 44 65 6c 61 79 20 5b 67 65 74 46 69 6c 65 52 65  Delay [getFileRe
2330: 74 72 79 44 65 6c 61 79 5d 20 20 3b 23 20 44 65  tryDelay]  ;# De
2340: 6c 61 79 20 69 6e 20 6d 73 20 62 65 66 6f 72 65  lay in ms before
2350: 20 72 65 74 72 79 69 6e 67 2e 0a 0a 20 20 20 20   retrying...    
2360: 66 6f 72 65 61 63 68 20 64 69 72 4e 61 6d 65 20  foreach dirName 
2370: 24 61 72 67 73 20 7b 0a 20 20 20 20 20 20 23 20  $args {.      # 
2380: 4f 6e 20 77 69 6e 64 6f 77 73 2c 20 73 6f 6d 65  On windows, some
2390: 74 69 6d 65 73 20 65 76 65 6e 20 61 20 5b 72 65  times even a [re
23a0: 6d 6f 76 65 5f 77 69 6e 33 32 5f 64 69 72 5d 20  move_win32_dir] 
23b0: 63 61 6e 20 66 61 69 6c 20 6a 75 73 74 20 61 66  can fail just af
23c0: 74 65 72 0a 20 20 20 20 20 20 23 20 61 20 64 69  ter.      # a di
23d0: 72 65 63 74 6f 72 79 20 69 73 20 65 6d 70 74 69  rectory is empti
23e0: 65 64 2e 20 54 68 65 20 63 61 75 73 65 20 69 73  ed. The cause is
23f0: 20 75 73 75 61 6c 6c 79 20 22 74 61 67 2d 61 6c   usually "tag-al
2400: 6f 6e 67 73 22 20 2d 20 70 72 6f 67 72 61 6d 73  ongs" - programs
2410: 0a 20 20 20 20 20 20 23 20 6c 69 6b 65 20 61 6e  .      # like an
2420: 74 69 2d 76 69 72 75 73 20 73 6f 66 74 77 61 72  ti-virus softwar
2430: 65 2c 20 61 75 74 6f 6d 61 74 69 63 20 62 61 63  e, automatic bac
2440: 6b 75 70 20 74 6f 6f 6c 73 20 61 6e 64 20 76 61  kup tools and va
2450: 72 69 6f 75 73 20 65 78 70 6c 6f 72 65 72 0a 20  rious explorer. 
2460: 20 20 20 20 20 23 20 65 78 74 65 6e 73 69 6f 6e       # extension
2470: 73 20 74 68 61 74 20 6b 65 65 70 20 61 20 66 69  s that keep a fi
2480: 6c 65 20 6f 70 65 6e 20 61 20 6c 69 74 74 6c 65  le open a little
2490: 20 6c 6f 6e 67 65 72 20 74 68 61 6e 20 77 65 20   longer than we 
24a0: 65 78 70 65 63 74 2c 0a 20 20 20 20 20 20 23 20  expect,.      # 
24b0: 63 61 75 73 69 6e 67 20 74 68 65 20 64 65 6c 65  causing the dele
24c0: 74 65 20 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20  te to fail..    
24d0: 20 20 23 0a 20 20 20 20 20 20 23 20 54 68 65 20    #.      # The 
24e0: 73 6f 6c 75 74 69 6f 6e 20 69 73 20 74 6f 20 77  solution is to w
24f0: 61 69 74 20 61 20 73 68 6f 72 74 20 61 6d 6f 75  ait a short amou
2500: 6e 74 20 6f 66 20 74 69 6d 65 20 62 65 66 6f 72  nt of time befor
2510: 65 20 72 65 74 72 79 69 6e 67 20 74 68 65 0a 20  e retrying the. 
2520: 20 20 20 20 20 23 20 72 65 6d 6f 76 61 6c 2e 0a       # removal..
2530: 20 20 20 20 20 20 23 0a 20 20 20 20 20 20 69 66        #.      if
2540: 20 7b 24 6e 52 65 74 72 79 20 3e 20 30 7d 20 7b   {$nRetry > 0} {
2550: 0a 20 20 20 20 20 20 20 20 66 6f 72 20 7b 73 65  .        for {se
2560: 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 24 6e 52  t i 0} {$i < $nR
2570: 65 74 72 79 7d 20 7b 69 6e 63 72 20 69 7d 20 7b  etry} {incr i} {
2580: 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20 72  .          set r
2590: 63 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20 20  c [catch {.     
25a0: 20 20 20 20 20 20 20 72 65 6d 6f 76 65 5f 77 69         remove_wi
25b0: 6e 33 32 5f 64 69 72 20 24 64 69 72 4e 61 6d 65  n32_dir $dirName
25c0: 0a 20 20 20 20 20 20 20 20 20 20 7d 20 6d 73 67  .          } msg
25d0: 5d 0a 20 20 20 20 20 20 20 20 20 20 69 66 20 7b  ].          if {
25e0: 24 72 63 20 3d 3d 20 30 7d 20 62 72 65 61 6b 0a  $rc == 0} break.
25f0: 20 20 20 20 20 20 20 20 20 20 69 66 20 7b 24 6e            if {$n
2600: 44 65 6c 61 79 20 3e 20 30 7d 20 7b 20 61 66 74  Delay > 0} { aft
2610: 65 72 20 24 6e 44 65 6c 61 79 20 7d 0a 20 20 20  er $nDelay }.   
2620: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69       }.        i
2630: 66 20 7b 24 72 63 7d 20 7b 20 65 72 72 6f 72 20  f {$rc} { error 
2640: 24 6d 73 67 20 7d 0a 20 20 20 20 20 20 7d 20 65  $msg }.      } e
2650: 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 72 65  lse {.        re
2660: 6d 6f 76 65 5f 77 69 6e 33 32 5f 64 69 72 20 24  move_win32_dir $
2670: 64 69 72 4e 61 6d 65 0a 20 20 20 20 20 20 7d 0a  dirName.      }.
2680: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70 72 6f      }.  }..  pro
2690: 63 20 64 6f 5f 64 65 6c 65 74 65 5f 77 69 6e 33  c do_delete_win3
26a0: 32 5f 66 69 6c 65 20 7b 61 72 67 73 7d 20 7b 0a  2_file {args} {.
26b0: 20 20 20 20 73 65 74 20 6e 52 65 74 72 79 20 5b      set nRetry [
26c0: 67 65 74 46 69 6c 65 52 65 74 72 69 65 73 5d 20  getFileRetries] 
26d0: 20 20 20 20 3b 23 20 4d 61 78 69 6d 75 6d 20 6e      ;# Maximum n
26e0: 75 6d 62 65 72 20 6f 66 20 72 65 74 72 69 65 73  umber of retries
26f0: 2e 0a 20 20 20 20 73 65 74 20 6e 44 65 6c 61 79  ..    set nDelay
2700: 20 5b 67 65 74 46 69 6c 65 52 65 74 72 79 44 65   [getFileRetryDe
2710: 6c 61 79 5d 20 20 3b 23 20 44 65 6c 61 79 20 69  lay]  ;# Delay i
2720: 6e 20 6d 73 20 62 65 66 6f 72 65 20 72 65 74 72  n ms before retr
2730: 79 69 6e 67 2e 0a 0a 20 20 20 20 66 6f 72 65 61  ying...    forea
2740: 63 68 20 66 69 6c 65 4e 61 6d 65 20 24 61 72 67  ch fileName $arg
2750: 73 20 7b 0a 20 20 20 20 20 20 23 20 4f 6e 20 77  s {.      # On w
2760: 69 6e 64 6f 77 73 2c 20 73 6f 6d 65 74 69 6d 65  indows, sometime
2770: 73 20 65 76 65 6e 20 61 20 5b 64 65 6c 65 74 65  s even a [delete
2780: 5f 77 69 6e 33 32 5f 66 69 6c 65 5d 20 63 61 6e  _win32_file] can
2790: 20 66 61 69 6c 20 6a 75 73 74 20 61 66 74 65 72   fail just after
27a0: 0a 20 20 20 20 20 20 23 20 61 20 66 69 6c 65 20  .      # a file 
27b0: 69 73 20 63 6c 6f 73 65 64 2e 20 54 68 65 20 63  is closed. The c
27c0: 61 75 73 65 20 69 73 20 75 73 75 61 6c 6c 79 20  ause is usually 
27d0: 22 74 61 67 2d 61 6c 6f 6e 67 73 22 20 2d 20 70  "tag-alongs" - p
27e0: 72 6f 67 72 61 6d 73 20 6c 69 6b 65 0a 20 20 20  rograms like.   
27f0: 20 20 20 23 20 61 6e 74 69 2d 76 69 72 75 73 20     # anti-virus 
2800: 73 6f 66 74 77 61 72 65 2c 20 61 75 74 6f 6d 61  software, automa
2810: 74 69 63 20 62 61 63 6b 75 70 20 74 6f 6f 6c 73  tic backup tools
2820: 20 61 6e 64 20 76 61 72 69 6f 75 73 20 65 78 70   and various exp
2830: 6c 6f 72 65 72 0a 20 20 20 20 20 20 23 20 65 78  lorer.      # ex
2840: 74 65 6e 73 69 6f 6e 73 20 74 68 61 74 20 6b 65  tensions that ke
2850: 65 70 20 61 20 66 69 6c 65 20 6f 70 65 6e 20 61  ep a file open a
2860: 20 6c 69 74 74 6c 65 20 6c 6f 6e 67 65 72 20 74   little longer t
2870: 68 61 6e 20 77 65 20 65 78 70 65 63 74 2c 0a 20  han we expect,. 
2880: 20 20 20 20 20 23 20 63 61 75 73 69 6e 67 20 74       # causing t
2890: 68 65 20 64 65 6c 65 74 65 20 74 6f 20 66 61 69  he delete to fai
28a0: 6c 2e 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20  l..      #.     
28b0: 20 23 20 54 68 65 20 73 6f 6c 75 74 69 6f 6e 20   # The solution 
28c0: 69 73 20 74 6f 20 77 61 69 74 20 61 20 73 68 6f  is to wait a sho
28d0: 72 74 20 61 6d 6f 75 6e 74 20 6f 66 20 74 69 6d  rt amount of tim
28e0: 65 20 62 65 66 6f 72 65 20 72 65 74 72 79 69 6e  e before retryin
28f0: 67 20 74 68 65 0a 20 20 20 20 20 20 23 20 64 65  g the.      # de
2900: 6c 65 74 65 2e 0a 20 20 20 20 20 20 23 0a 20 20  lete..      #.  
2910: 20 20 20 20 69 66 20 7b 24 6e 52 65 74 72 79 20      if {$nRetry 
2920: 3e 20 30 7d 20 7b 0a 20 20 20 20 20 20 20 20 66  > 0} {.        f
2930: 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69  or {set i 0} {$i
2940: 20 3c 20 24 6e 52 65 74 72 79 7d 20 7b 69 6e 63   < $nRetry} {inc
2950: 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  r i} {.         
2960: 20 73 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b   set rc [catch {
2970: 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 65 6c  .            del
2980: 65 74 65 5f 77 69 6e 33 32 5f 66 69 6c 65 20 24  ete_win32_file $
2990: 66 69 6c 65 4e 61 6d 65 0a 20 20 20 20 20 20 20  fileName.       
29a0: 20 20 20 7d 20 6d 73 67 5d 0a 20 20 20 20 20 20     } msg].      
29b0: 20 20 20 20 69 66 20 7b 24 72 63 20 3d 3d 20 30      if {$rc == 0
29c0: 7d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  } break.        
29d0: 20 20 69 66 20 7b 24 6e 44 65 6c 61 79 20 3e 20    if {$nDelay > 
29e0: 30 7d 20 7b 20 61 66 74 65 72 20 24 6e 44 65 6c  0} { after $nDel
29f0: 61 79 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20  ay }.        }. 
2a00: 20 20 20 20 20 20 20 69 66 20 7b 24 72 63 7d 20         if {$rc} 
2a10: 7b 20 65 72 72 6f 72 20 24 6d 73 67 20 7d 0a 20  { error $msg }. 
2a20: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
2a30: 20 20 20 20 20 20 64 65 6c 65 74 65 5f 77 69 6e        delete_win
2a40: 33 32 5f 66 69 6c 65 20 24 66 69 6c 65 4e 61 6d  32_file $fileNam
2a50: 65 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  e.      }.    }.
2a60: 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 65 78 65 63    }.}..proc exec
2a70: 70 72 65 73 71 6c 20 7b 68 61 6e 64 6c 65 20 61  presql {handle a
2a80: 72 67 73 7d 20 7b 0a 20 20 74 72 61 63 65 20 72  rgs} {.  trace r
2a90: 65 6d 6f 76 65 20 65 78 65 63 75 74 69 6f 6e 20  emove execution 
2aa0: 24 68 61 6e 64 6c 65 20 65 6e 74 65 72 20 5b 6c  $handle enter [l
2ab0: 69 73 74 20 65 78 65 63 70 72 65 73 71 6c 20 24  ist execpresql $
2ac0: 68 61 6e 64 6c 65 5d 0a 20 20 69 66 20 7b 5b 69  handle].  if {[i
2ad0: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 70  nfo exists ::G(p
2ae0: 65 72 6d 3a 70 72 65 73 71 6c 29 5d 7d 20 7b 0a  erm:presql)]} {.
2af0: 20 20 20 20 24 68 61 6e 64 6c 65 20 65 76 61 6c      $handle eval
2b00: 20 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73 71   $::G(perm:presq
2b10: 6c 29 0a 20 20 7d 0a 7d 0a 0a 23 20 54 68 69 73  l).  }.}..# This
2b20: 20 63 6f 6d 6d 61 6e 64 20 73 68 6f 75 6c 64 20   command should 
2b30: 62 65 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20  be called after 
2b40: 6c 6f 61 64 69 6e 67 20 74 65 73 74 65 72 2e 74  loading tester.t
2b50: 63 6c 20 66 72 6f 6d 20 77 69 74 68 69 6e 0a 23  cl from within.#
2b60: 20 61 6c 6c 20 74 65 73 74 20 73 63 72 69 70 74   all test script
2b70: 73 20 74 68 61 74 20 61 72 65 20 69 6e 63 6f 6d  s that are incom
2b80: 70 61 74 69 62 6c 65 20 77 69 74 68 20 65 6e 63  patible with enc
2b90: 72 79 70 74 69 6f 6e 20 63 6f 64 65 63 73 2e 0a  ryption codecs..
2ba0: 23 0a 70 72 6f 63 20 64 6f 5f 6e 6f 74 5f 75 73  #.proc do_not_us
2bb0: 65 5f 63 6f 64 65 63 20 7b 7d 20 7b 0a 20 20 73  e_codec {} {.  s
2bc0: 65 74 20 3a 3a 64 6f 5f 6e 6f 74 5f 75 73 65 5f  et ::do_not_use_
2bd0: 63 6f 64 65 63 20 31 0a 20 20 72 65 73 65 74 5f  codec 1.  reset_
2be0: 64 62 0a 7d 0a 75 6e 73 65 74 20 2d 6e 6f 63 6f  db.}.unset -noco
2bf0: 6d 70 6c 61 69 6e 20 64 6f 5f 6e 6f 74 5f 75 73  mplain do_not_us
2c00: 65 5f 63 6f 64 65 63 0a 0a 23 20 52 65 74 75 72  e_codec..# Retur
2c10: 6e 20 74 72 75 65 20 69 66 20 74 68 65 20 22 72  n true if the "r
2c20: 65 73 65 72 76 65 64 5f 62 79 74 65 73 22 20 69  eserved_bytes" i
2c30: 6e 74 65 67 65 72 20 6f 6e 20 64 61 74 61 62 61  nteger on databa
2c40: 73 65 20 66 69 6c 65 73 20 69 73 20 6e 6f 6e 2d  se files is non-
2c50: 7a 65 72 6f 2e 0a 23 0a 70 72 6f 63 20 6e 6f 6e  zero..#.proc non
2c60: 7a 65 72 6f 5f 72 65 73 65 72 76 65 64 5f 62 79  zero_reserved_by
2c70: 74 65 73 20 7b 7d 20 7b 0a 20 20 72 65 74 75 72  tes {} {.  retur
2c80: 6e 20 5b 73 71 6c 69 74 65 33 20 2d 68 61 73 2d  n [sqlite3 -has-
2c90: 63 6f 64 65 63 5d 0a 7d 0a 0a 23 20 50 72 69 6e  codec].}..# Prin
2ca0: 74 20 61 20 48 45 4c 50 20 6d 65 73 73 61 67 65  t a HELP message
2cb0: 20 61 6e 64 20 65 78 69 74 0a 23 0a 70 72 6f 63   and exit.#.proc
2cc0: 20 70 72 69 6e 74 5f 68 65 6c 70 5f 61 6e 64 5f   print_help_and_
2cd0: 71 75 69 74 20 7b 7d 20 7b 0a 20 20 70 75 74 73  quit {} {.  puts
2ce0: 20 7b 4f 70 74 69 6f 6e 73 3a 0a 20 20 2d 2d 70   {Options:.  --p
2cf0: 61 75 73 65 20 20 20 20 20 20 20 20 20 20 20 20  ause            
2d00: 20 20 20 20 20 20 57 61 69 74 20 66 6f 72 20 75        Wait for u
2d10: 73 65 72 20 69 6e 70 75 74 20 62 65 66 6f 72 65  ser input before
2d20: 20 63 6f 6e 74 69 6e 75 69 6e 67 0a 20 20 2d 2d   continuing.  --
2d30: 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 3d  soft-heap-limit=
2d40: 4e 20 20 20 20 20 20 53 65 74 20 74 68 65 20 73  N      Set the s
2d50: 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 20 74  oft-heap-limit t
2d60: 6f 20 4e 0a 20 20 2d 2d 6d 61 78 65 72 72 6f 72  o N.  --maxerror
2d70: 3d 4e 20 20 20 20 20 20 20 20 20 20 20 20 20 51  =N             Q
2d80: 75 69 74 20 61 66 74 65 72 20 4e 20 65 72 72 6f  uit after N erro
2d90: 72 73 0a 20 20 2d 2d 76 65 72 62 6f 73 65 3d 28  rs.  --verbose=(
2da0: 30 7c 31 29 20 20 20 20 20 20 20 20 20 20 43 6f  0|1)          Co
2db0: 6e 74 72 6f 6c 20 74 68 65 20 61 6d 6f 75 6e 74  ntrol the amount
2dc0: 20 6f 66 20 6f 75 74 70 75 74 2e 20 20 44 65 66   of output.  Def
2dd0: 61 75 6c 74 20 27 31 27 0a 20 20 2d 2d 6f 75 74  ault '1'.  --out
2de0: 70 75 74 3d 46 49 4c 45 20 20 20 20 20 20 20 20  put=FILE        
2df0: 20 20 20 20 73 65 74 20 2d 2d 76 65 72 62 6f 73      set --verbos
2e00: 65 3d 32 20 61 6e 64 20 6f 75 74 70 75 74 20 74  e=2 and output t
2e10: 6f 20 46 49 4c 45 2e 20 20 49 6d 70 6c 69 65 73  o FILE.  Implies
2e20: 20 2d 71 0a 20 20 2d 71 20 20 20 20 20 20 20 20   -q.  -q        
2e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53                 S
2e40: 68 6f 72 74 68 61 6e 64 20 66 6f 72 20 2d 2d 76  horthand for --v
2e50: 65 72 62 6f 73 65 3d 30 0a 20 20 2d 2d 68 65 6c  erbose=0.  --hel
2e60: 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p               
2e70: 20 20 20 20 54 68 69 73 20 6d 65 73 73 61 67 65      This message
2e80: 0a 7d 0a 20 20 65 78 69 74 20 31 0a 7d 0a 0a 23  .}.  exit 1.}..#
2e90: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62   The following b
2ea0: 6c 6f 63 6b 20 6f 6e 6c 79 20 72 75 6e 73 20 74  lock only runs t
2eb0: 68 65 20 66 69 72 73 74 20 74 69 6d 65 20 74 68  he first time th
2ec0: 69 73 20 66 69 6c 65 20 69 73 20 73 6f 75 72 63  is file is sourc
2ed0: 65 64 2e 20 49 74 0a 23 20 64 6f 65 73 20 6e 6f  ed. It.# does no
2ee0: 74 20 72 75 6e 20 69 6e 20 73 6c 61 76 65 20 69  t run in slave i
2ef0: 6e 74 65 72 70 72 65 74 65 72 73 20 28 73 69 6e  nterpreters (sin
2f00: 63 65 20 74 68 65 20 3a 3a 63 6d 64 6c 69 6e 65  ce the ::cmdline
2f10: 61 72 67 20 61 72 72 61 79 20 69 73 0a 23 20 70  arg array is.# p
2f20: 6f 70 75 6c 61 74 65 64 20 62 65 66 6f 72 65 20  opulated before 
2f30: 74 68 65 20 74 65 73 74 20 73 63 72 69 70 74 20  the test script 
2f40: 69 73 20 72 75 6e 20 69 6e 20 73 6c 61 76 65 20  is run in slave 
2f50: 69 6e 74 65 72 70 72 65 74 65 72 73 29 2e 0a 23  interpreters)..#
2f60: 0a 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74  .if {[info exist
2f70: 73 20 63 6d 64 6c 69 6e 65 61 72 67 5d 3d 3d 30  s cmdlinearg]==0
2f80: 7d 20 7b 0a 0a 20 20 23 20 50 61 72 73 65 20 61  } {..  # Parse a
2f90: 6e 79 20 6f 70 74 69 6f 6e 73 20 73 70 65 63 69  ny options speci
2fa0: 66 69 65 64 20 69 6e 20 74 68 65 20 24 61 72 67  fied in the $arg
2fb0: 76 20 61 72 72 61 79 2e 20 54 68 69 73 20 73 63  v array. This sc
2fc0: 72 69 70 74 20 61 63 63 65 70 74 73 20 74 68 65  ript accepts the
2fd0: 0a 20 20 23 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f  .  # following o
2fe0: 70 74 69 6f 6e 73 3a 0a 20 20 23 0a 20 20 23 20  ptions:.  #.  # 
2ff0: 20 20 2d 2d 70 61 75 73 65 0a 20 20 23 20 20 20    --pause.  #   
3000: 2d 2d 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69  --soft-heap-limi
3010: 74 3d 4e 4e 0a 20 20 23 20 20 20 2d 2d 6d 61 78  t=NN.  #   --max
3020: 65 72 72 6f 72 3d 4e 4e 0a 20 20 23 20 20 20 2d  error=NN.  #   -
3030: 2d 6d 61 6c 6c 6f 63 74 72 61 63 65 3d 4e 0a 20  -malloctrace=N. 
3040: 20 23 20 20 20 2d 2d 62 61 63 6b 74 72 61 63 65   #   --backtrace
3050: 3d 4e 0a 20 20 23 20 20 20 2d 2d 62 69 6e 61 72  =N.  #   --binar
3060: 79 6c 6f 67 3d 4e 0a 20 20 23 20 20 20 2d 2d 73  ylog=N.  #   --s
3070: 6f 61 6b 3d 4e 0a 20 20 23 20 20 20 2d 2d 66 69  oak=N.  #   --fi
3080: 6c 65 2d 72 65 74 72 69 65 73 3d 4e 0a 20 20 23  le-retries=N.  #
3090: 20 20 20 2d 2d 66 69 6c 65 2d 72 65 74 72 79 2d     --file-retry-
30a0: 64 65 6c 61 79 3d 4e 0a 20 20 23 20 20 20 2d 2d  delay=N.  #   --
30b0: 73 74 61 72 74 3d 5b 24 70 65 72 6d 75 74 61 74  start=[$permutat
30c0: 69 6f 6e 3a 5d 24 74 65 73 74 66 69 6c 65 0a 20  ion:]$testfile. 
30d0: 20 23 20 20 20 2d 2d 6d 61 74 63 68 3d 24 70 61   #   --match=$pa
30e0: 74 74 65 72 6e 0a 20 20 23 20 20 20 2d 2d 76 65  ttern.  #   --ve
30f0: 72 62 6f 73 65 3d 24 76 61 6c 0a 20 20 23 20 20  rbose=$val.  #  
3100: 20 2d 2d 6f 75 74 70 75 74 3d 24 66 69 6c 65 6e   --output=$filen
3110: 61 6d 65 0a 20 20 23 20 20 20 2d 71 20 20 20 20  ame.  #   -q    
3120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3140: 20 20 52 65 64 75 63 65 20 6f 75 74 70 75 74 0a    Reduce output.
3150: 20 20 23 20 20 20 2d 2d 74 65 73 74 64 69 72 3d    #   --testdir=
3160: 24 64 69 72 20 20 20 20 20 20 20 20 20 20 20 20  $dir            
3170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 52 75                Ru
3180: 6e 20 74 65 73 74 73 20 69 6e 20 73 75 62 64 69  n tests in subdi
3190: 72 65 63 74 6f 72 79 20 24 64 69 72 0a 20 20 23  rectory $dir.  #
31a0: 20 20 20 2d 2d 68 65 6c 70 0a 20 20 23 0a 20 20     --help.  #.  
31b0: 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 73  set cmdlinearg(s
31c0: 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 29 20  oft-heap-limit) 
31d0: 20 20 20 30 0a 20 20 73 65 74 20 63 6d 64 6c 69     0.  set cmdli
31e0: 6e 65 61 72 67 28 6d 61 78 65 72 72 6f 72 29 20  nearg(maxerror) 
31f0: 20 20 20 20 20 20 20 31 30 30 30 0a 20 20 73 65         1000.  se
3200: 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 6c  t cmdlinearg(mal
3210: 6c 6f 63 74 72 61 63 65 29 20 20 20 20 20 20 20  loctrace)       
3220: 20 30 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65   0.  set cmdline
3230: 61 72 67 28 62 61 63 6b 74 72 61 63 65 29 20 20  arg(backtrace)  
3240: 20 20 20 20 20 20 20 31 30 0a 20 20 73 65 74 20         10.  set 
3250: 63 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e 61 72  cmdlinearg(binar
3260: 79 6c 6f 67 29 20 20 20 20 20 20 20 20 20 20 30  ylog)          0
3270: 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72  .  set cmdlinear
3280: 67 28 73 6f 61 6b 29 20 20 20 20 20 20 20 20 20  g(soak)         
3290: 20 20 20 20 20 20 30 0a 20 20 73 65 74 20 63 6d        0.  set cm
32a0: 64 6c 69 6e 65 61 72 67 28 66 69 6c 65 2d 72 65  dlinearg(file-re
32b0: 74 72 69 65 73 29 20 20 20 20 20 20 20 30 0a 20  tries)       0. 
32c0: 20 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28   set cmdlinearg(
32d0: 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c 61 79  file-retry-delay
32e0: 29 20 20 20 30 0a 20 20 73 65 74 20 63 6d 64 6c  )   0.  set cmdl
32f0: 69 6e 65 61 72 67 28 73 74 61 72 74 29 20 20 20  inearg(start)   
3300: 20 20 20 20 20 20 20 20 20 20 22 22 0a 20 20 73            "".  s
3310: 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61  et cmdlinearg(ma
3320: 74 63 68 29 20 20 20 20 20 20 20 20 20 20 20 20  tch)            
3330: 20 22 22 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e   "".  set cmdlin
3340: 65 61 72 67 28 76 65 72 62 6f 73 65 29 20 20 20  earg(verbose)   
3350: 20 20 20 20 20 20 20 20 22 22 0a 20 20 73 65 74          "".  set
3360: 20 63 6d 64 6c 69 6e 65 61 72 67 28 6f 75 74 70   cmdlinearg(outp
3370: 75 74 29 20 20 20 20 20 20 20 20 20 20 20 20 22  ut)            "
3380: 22 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61  ".  set cmdlinea
3390: 72 67 28 74 65 73 74 64 69 72 29 20 20 20 20 20  rg(testdir)     
33a0: 20 20 20 20 20 20 22 74 65 73 74 64 69 72 22 0a        "testdir".
33b0: 0a 20 20 73 65 74 20 6c 65 66 74 6f 76 65 72 20  .  set leftover 
33c0: 5b 6c 69 73 74 5d 0a 20 20 66 6f 72 65 61 63 68  [list].  foreach
33d0: 20 61 20 24 61 72 67 76 20 7b 0a 20 20 20 20 73   a $argv {.    s
33e0: 77 69 74 63 68 20 2d 72 65 67 65 78 70 20 2d 2d  witch -regexp --
33f0: 20 24 61 20 7b 0a 20 20 20 20 20 20 7b 5e 2d 2b   $a {.      {^-+
3400: 70 61 75 73 65 24 7d 20 7b 0a 20 20 20 20 20 20  pause$} {.      
3410: 20 20 23 20 57 61 69 74 20 66 6f 72 20 75 73 65    # Wait for use
3420: 72 20 69 6e 70 75 74 20 62 65 66 6f 72 65 20 63  r input before c
3430: 6f 6e 74 69 6e 75 69 6e 67 2e 20 54 68 69 73 20  ontinuing. This 
3440: 69 73 20 74 6f 20 67 69 76 65 20 74 68 65 20 75  is to give the u
3450: 73 65 72 20 61 6e 0a 20 20 20 20 20 20 20 20 23  ser an.        #
3460: 20 6f 70 70 6f 72 74 75 6e 69 74 79 20 74 6f 20   opportunity to 
3470: 63 6f 6e 6e 65 63 74 20 70 72 6f 66 69 6c 69 6e  connect profilin
3480: 67 20 74 6f 6f 6c 73 20 74 6f 20 74 68 65 20 70  g tools to the p
3490: 72 6f 63 65 73 73 2e 0a 20 20 20 20 20 20 20 20  rocess..        
34a0: 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20  puts -nonewline 
34b0: 22 50 72 65 73 73 20 52 45 54 55 52 4e 20 74 6f  "Press RETURN to
34c0: 20 62 65 67 69 6e 2e 2e 2e 22 0a 20 20 20 20 20   begin...".     
34d0: 20 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a     flush stdout.
34e0: 20 20 20 20 20 20 20 20 67 65 74 73 20 73 74 64          gets std
34f0: 69 6e 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  in.      }.     
3500: 20 7b 5e 2d 2b 73 6f 66 74 2d 68 65 61 70 2d 6c   {^-+soft-heap-l
3510: 69 6d 69 74 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20  imit=.+$} {.    
3520: 20 20 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d      foreach {dum
3530: 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67 28 73 6f  my cmdlinearg(so
3540: 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 29 7d 20  ft-heap-limit)} 
3550: 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65  [split $a =] bre
3560: 61 6b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  ak.      }.     
3570: 20 7b 5e 2d 2b 6d 61 78 65 72 72 6f 72 3d 2e 2b   {^-+maxerror=.+
3580: 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72  $} {.        for
3590: 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c  each {dummy cmdl
35a0: 69 6e 65 61 72 67 28 6d 61 78 65 72 72 6f 72 29  inearg(maxerror)
35b0: 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62  } [split $a =] b
35c0: 72 65 61 6b 0a 20 20 20 20 20 20 7d 0a 20 20 20  reak.      }.   
35d0: 20 20 20 7b 5e 2d 2b 6d 61 6c 6c 6f 63 74 72 61     {^-+malloctra
35e0: 63 65 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20  ce=.+$} {.      
35f0: 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79    foreach {dummy
3600: 20 63 6d 64 6c 69 6e 65 61 72 67 28 6d 61 6c 6c   cmdlinearg(mall
3610: 6f 63 74 72 61 63 65 29 7d 20 5b 73 70 6c 69 74  octrace)} [split
3620: 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20   $a =] break.   
3630: 20 20 20 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e       if {$cmdlin
3640: 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72 61 63 65  earg(malloctrace
3650: 29 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 73  )} {.          s
3660: 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f  qlite3_memdebug_
3670: 6c 6f 67 20 73 74 61 72 74 0a 20 20 20 20 20 20  log start.      
3680: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
3690: 20 20 7b 5e 2d 2b 62 61 63 6b 74 72 61 63 65 3d    {^-+backtrace=
36a0: 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66  .+$} {.        f
36b0: 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d  oreach {dummy cm
36c0: 64 6c 69 6e 65 61 72 67 28 62 61 63 6b 74 72 61  dlinearg(backtra
36d0: 63 65 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d  ce)} [split $a =
36e0: 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  ] break.        
36f0: 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67  sqlite3_memdebug
3700: 5f 62 61 63 6b 74 72 61 63 65 20 24 76 61 6c 75  _backtrace $valu
3710: 65 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  e.      }.      
3720: 7b 5e 2d 2b 62 69 6e 61 72 79 6c 6f 67 3d 2e 2b  {^-+binarylog=.+
3730: 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72  $} {.        for
3740: 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c  each {dummy cmdl
3750: 69 6e 65 61 72 67 28 62 69 6e 61 72 79 6c 6f 67  inearg(binarylog
3760: 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20  )} [split $a =] 
3770: 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20 73 65  break.        se
3780: 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e  t cmdlinearg(bin
3790: 61 72 79 6c 6f 67 29 20 5b 66 69 6c 65 20 6e 6f  arylog) [file no
37a0: 72 6d 61 6c 69 7a 65 20 24 63 6d 64 6c 69 6e 65  rmalize $cmdline
37b0: 61 72 67 28 62 69 6e 61 72 79 6c 6f 67 29 5d 0a  arg(binarylog)].
37c0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e        }.      {^
37d0: 2d 2b 73 6f 61 6b 3d 2e 2b 24 7d 20 7b 0a 20 20  -+soak=.+$} {.  
37e0: 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b 64        foreach {d
37f0: 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67 28  ummy cmdlinearg(
3800: 73 6f 61 6b 29 7d 20 5b 73 70 6c 69 74 20 24 61  soak)} [split $a
3810: 20 3d 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20   =] break.      
3820: 20 20 73 65 74 20 3a 3a 47 28 69 73 73 6f 61 6b    set ::G(issoak
3830: 29 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 73 6f  ) $cmdlinearg(so
3840: 61 6b 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak).      }.    
3850: 20 20 7b 5e 2d 2b 66 69 6c 65 2d 72 65 74 72 69    {^-+file-retri
3860: 65 73 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20  es=.+$} {.      
3870: 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79    foreach {dummy
3880: 20 63 6d 64 6c 69 6e 65 61 72 67 28 66 69 6c 65   cmdlinearg(file
3890: 2d 72 65 74 72 69 65 73 29 7d 20 5b 73 70 6c 69  -retries)} [spli
38a0: 74 20 24 61 20 3d 5d 20 62 72 65 61 6b 0a 20 20  t $a =] break.  
38b0: 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 66 69        set ::G(fi
38c0: 6c 65 2d 72 65 74 72 69 65 73 29 20 24 63 6d 64  le-retries) $cmd
38d0: 6c 69 6e 65 61 72 67 28 66 69 6c 65 2d 72 65 74  linearg(file-ret
38e0: 72 69 65 73 29 0a 20 20 20 20 20 20 7d 0a 20 20  ries).      }.  
38f0: 20 20 20 20 7b 5e 2d 2b 66 69 6c 65 2d 72 65 74      {^-+file-ret
3900: 72 79 2d 64 65 6c 61 79 3d 2e 2b 24 7d 20 7b 0a  ry-delay=.+$} {.
3910: 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20          foreach 
3920: 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72  {dummy cmdlinear
3930: 67 28 66 69 6c 65 2d 72 65 74 72 79 2d 64 65 6c  g(file-retry-del
3940: 61 79 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d  ay)} [split $a =
3950: 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  ] break.        
3960: 73 65 74 20 3a 3a 47 28 66 69 6c 65 2d 72 65 74  set ::G(file-ret
3970: 72 79 2d 64 65 6c 61 79 29 20 24 63 6d 64 6c 69  ry-delay) $cmdli
3980: 6e 65 61 72 67 28 66 69 6c 65 2d 72 65 74 72 79  nearg(file-retry
3990: 2d 64 65 6c 61 79 29 0a 20 20 20 20 20 20 7d 0a  -delay).      }.
39a0: 20 20 20 20 20 20 7b 5e 2d 2b 73 74 61 72 74 3d        {^-+start=
39b0: 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20 20 20 66  .+$} {.        f
39c0: 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79 20 63 6d  oreach {dummy cm
39d0: 64 6c 69 6e 65 61 72 67 28 73 74 61 72 74 29 7d  dlinearg(start)}
39e0: 20 5b 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72   [split $a =] br
39f0: 65 61 6b 0a 0a 20 20 20 20 20 20 20 20 73 65 74  eak..        set
3a00: 20 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29   ::G(start:file)
3a10: 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 73 74 61   $cmdlinearg(sta
3a20: 72 74 29 0a 20 20 20 20 20 20 20 20 69 66 20 7b  rt).        if {
3a30: 5b 72 65 67 65 78 70 20 7b 28 2e 2a 29 3a 28 2e  [regexp {(.*):(.
3a40: 2a 29 7d 20 24 63 6d 64 6c 69 6e 65 61 72 67 28  *)} $cmdlinearg(
3a50: 73 74 61 72 74 29 20 2d 3e 20 73 2e 70 65 72 6d  start) -> s.perm
3a60: 20 73 2e 66 69 6c 65 5d 7d 20 7b 0a 20 20 20 20   s.file]} {.    
3a70: 20 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73 74        set ::G(st
3a80: 61 72 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29  art:permutation)
3a90: 20 24 7b 73 2e 70 65 72 6d 7d 0a 20 20 20 20 20   ${s.perm}.     
3aa0: 20 20 20 20 20 73 65 74 20 3a 3a 47 28 73 74 61       set ::G(sta
3ab0: 72 74 3a 66 69 6c 65 29 20 20 20 20 20 20 20 20  rt:file)        
3ac0: 24 7b 73 2e 66 69 6c 65 7d 0a 20 20 20 20 20 20  ${s.file}.      
3ad0: 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 20 7b    }.        if {
3ae0: 24 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29  $::G(start:file)
3af0: 20 3d 3d 20 22 22 7d 20 7b 75 6e 73 65 74 20 3a   == ""} {unset :
3b00: 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 7d 0a  :G(start:file)}.
3b10: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b 5e        }.      {^
3b20: 2d 2b 6d 61 74 63 68 3d 2e 2b 24 7d 20 7b 0a 20  -+match=.+$} {. 
3b30: 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20 7b         foreach {
3b40: 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65 61 72 67  dummy cmdlinearg
3b50: 28 6d 61 74 63 68 29 7d 20 5b 73 70 6c 69 74 20  (match)} [split 
3b60: 24 61 20 3d 5d 20 62 72 65 61 6b 0a 0a 20 20 20  $a =] break..   
3b70: 20 20 20 20 20 73 65 74 20 3a 3a 47 28 6d 61 74       set ::G(mat
3b80: 63 68 29 20 24 63 6d 64 6c 69 6e 65 61 72 67 28  ch) $cmdlinearg(
3b90: 6d 61 74 63 68 29 0a 20 20 20 20 20 20 20 20 69  match).        i
3ba0: 66 20 7b 24 3a 3a 47 28 6d 61 74 63 68 29 20 3d  f {$::G(match) =
3bb0: 3d 20 22 22 7d 20 7b 75 6e 73 65 74 20 3a 3a 47  = ""} {unset ::G
3bc0: 28 6d 61 74 63 68 29 7d 0a 20 20 20 20 20 20 7d  (match)}.      }
3bd0: 0a 0a 20 20 20 20 20 20 7b 5e 2d 2b 6f 75 74 70  ..      {^-+outp
3be0: 75 74 3d 2e 2b 24 7d 20 7b 0a 20 20 20 20 20 20  ut=.+$} {.      
3bf0: 20 20 66 6f 72 65 61 63 68 20 7b 64 75 6d 6d 79    foreach {dummy
3c00: 20 63 6d 64 6c 69 6e 65 61 72 67 28 6f 75 74 70   cmdlinearg(outp
3c10: 75 74 29 7d 20 5b 73 70 6c 69 74 20 24 61 20 3d  ut)} [split $a =
3c20: 5d 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20  ] break.        
3c30: 73 65 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 6f  set cmdlinearg(o
3c40: 75 74 70 75 74 29 20 5b 66 69 6c 65 20 6e 6f 72  utput) [file nor
3c50: 6d 61 6c 69 7a 65 20 24 63 6d 64 6c 69 6e 65 61  malize $cmdlinea
3c60: 72 67 28 6f 75 74 70 75 74 29 5d 0a 20 20 20 20  rg(output)].    
3c70: 20 20 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65      if {$cmdline
3c80: 61 72 67 28 76 65 72 62 6f 73 65 29 3d 3d 22 22  arg(verbose)==""
3c90: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65  } {.          se
3ca0: 74 20 63 6d 64 6c 69 6e 65 61 72 67 28 76 65 72  t cmdlinearg(ver
3cb0: 62 6f 73 65 29 20 32 0a 20 20 20 20 20 20 20 20  bose) 2.        
3cc0: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
3cd0: 7b 5e 2d 2b 76 65 72 62 6f 73 65 3d 2e 2b 24 7d  {^-+verbose=.+$}
3ce0: 20 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61   {.        forea
3cf0: 63 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e  ch {dummy cmdlin
3d00: 65 61 72 67 28 76 65 72 62 6f 73 65 29 7d 20 5b  earg(verbose)} [
3d10: 73 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61  split $a =] brea
3d20: 6b 0a 20 20 20 20 20 20 20 20 69 66 20 7b 24 63  k.        if {$c
3d30: 6d 64 6c 69 6e 65 61 72 67 28 76 65 72 62 6f 73  mdlinearg(verbos
3d40: 65 29 3d 3d 22 66 69 6c 65 22 7d 20 7b 0a 20 20  e)=="file"} {.  
3d50: 20 20 20 20 20 20 20 20 73 65 74 20 63 6d 64 6c          set cmdl
3d60: 69 6e 65 61 72 67 28 76 65 72 62 6f 73 65 29 20  inearg(verbose) 
3d70: 32 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65  2.        } else
3d80: 69 66 20 7b 5b 73 74 72 69 6e 67 20 69 73 20 62  if {[string is b
3d90: 6f 6f 6c 65 61 6e 20 2d 73 74 72 69 63 74 20 24  oolean -strict $
3da0: 63 6d 64 6c 69 6e 65 61 72 67 28 76 65 72 62 6f  cmdlinearg(verbo
3db0: 73 65 29 5d 3d 3d 30 7d 20 7b 0a 20 20 20 20 20  se)]==0} {.     
3dc0: 20 20 20 20 20 65 72 72 6f 72 20 22 6f 70 74 69       error "opti
3dd0: 6f 6e 20 2d 2d 76 65 72 62 6f 73 65 3d 20 6d 75  on --verbose= mu
3de0: 73 74 20 62 65 20 73 65 74 20 74 6f 20 61 20 62  st be set to a b
3df0: 6f 6f 6c 65 61 6e 20 6f 72 20 74 6f 20 5c 22 66  oolean or to \"f
3e00: 69 6c 65 5c 22 22 0a 20 20 20 20 20 20 20 20 7d  ile\"".        }
3e10: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b  .      }.      {
3e20: 5e 2d 2b 74 65 73 74 64 69 72 3d 2e 2a 24 7d 20  ^-+testdir=.*$} 
3e30: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 65 61 63  {.        foreac
3e40: 68 20 7b 64 75 6d 6d 79 20 63 6d 64 6c 69 6e 65  h {dummy cmdline
3e50: 61 72 67 28 74 65 73 74 64 69 72 29 7d 20 5b 73  arg(testdir)} [s
3e60: 70 6c 69 74 20 24 61 20 3d 5d 20 62 72 65 61 6b  plit $a =] break
3e70: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7b  .      }.      {
3e80: 2e 2a 68 65 6c 70 2e 2a 7d 20 7b 0a 20 20 20 20  .*help.*} {.    
3e90: 20 20 20 20 20 70 72 69 6e 74 5f 68 65 6c 70 5f       print_help_
3ea0: 61 6e 64 5f 71 75 69 74 0a 20 20 20 20 20 20 7d  and_quit.      }
3eb0: 0a 20 20 20 20 20 20 7b 5e 2d 71 24 7d 20 7b 0a  .      {^-q$} {.
3ec0: 20 20 20 20 20 20 20 20 73 65 74 20 63 6d 64 6c          set cmdl
3ed0: 69 6e 65 61 72 67 28 6f 75 74 70 75 74 29 20 74  inearg(output) t
3ee0: 65 73 74 2d 6f 75 74 2e 74 78 74 0a 20 20 20 20  est-out.txt.    
3ef0: 20 20 20 20 73 65 74 20 63 6d 64 6c 69 6e 65 61      set cmdlinea
3f00: 72 67 28 76 65 72 62 6f 73 65 29 20 32 0a 20 20  rg(verbose) 2.  
3f10: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 64 65 66      }..      def
3f20: 61 75 6c 74 20 7b 0a 20 20 20 20 20 20 20 20 69  ault {.        i
3f30: 66 20 7b 5b 66 69 6c 65 20 74 61 69 6c 20 24 61  f {[file tail $a
3f40: 5d 3d 3d 24 61 7d 20 7b 0a 20 20 20 20 20 20 20  ]==$a} {.       
3f50: 20 20 20 6c 61 70 70 65 6e 64 20 6c 65 66 74 6f     lappend lefto
3f60: 76 65 72 20 24 61 0a 20 20 20 20 20 20 20 20 7d  ver $a.        }
3f70: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
3f80: 20 20 6c 61 70 70 65 6e 64 20 6c 65 66 74 6f 76    lappend leftov
3f90: 65 72 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69  er [file normali
3fa0: 7a 65 20 24 61 5d 0a 20 20 20 20 20 20 20 20 7d  ze $a].        }
3fb0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3fc0: 20 7d 0a 20 20 73 65 74 20 74 65 73 74 64 69 72   }.  set testdir
3fd0: 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65   [file normalize
3fe0: 20 24 74 65 73 74 64 69 72 5d 0a 20 20 73 65 74   $testdir].  set
3ff0: 20 63 6d 64 6c 69 6e 65 61 72 67 28 54 45 53 54   cmdlinearg(TEST
4000: 46 49 58 54 55 52 45 5f 48 4f 4d 45 29 20 5b 70  FIXTURE_HOME) [p
4010: 77 64 5d 0a 20 20 73 65 74 20 63 6d 64 6c 69 6e  wd].  set cmdlin
4020: 65 61 72 67 28 49 4e 46 4f 5f 53 43 52 49 50 54  earg(INFO_SCRIPT
4030: 29 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a  ) [file normaliz
4040: 65 20 5b 69 6e 66 6f 20 73 63 72 69 70 74 5d 5d  e [info script]]
4050: 0a 20 20 73 65 74 20 61 72 67 76 30 20 5b 66 69  .  set argv0 [fi
4060: 6c 65 20 6e 6f 72 6d 61 6c 69 7a 65 20 24 61 72  le normalize $ar
4070: 67 76 30 5d 0a 20 20 69 66 20 7b 24 63 6d 64 6c  gv0].  if {$cmdl
4080: 69 6e 65 61 72 67 28 74 65 73 74 64 69 72 29 21  inearg(testdir)!
4090: 3d 22 22 7d 20 7b 0a 20 20 20 20 66 69 6c 65 20  =""} {.    file 
40a0: 6d 6b 64 69 72 20 24 63 6d 64 6c 69 6e 65 61 72  mkdir $cmdlinear
40b0: 67 28 74 65 73 74 64 69 72 29 0a 20 20 20 20 63  g(testdir).    c
40c0: 64 20 24 63 6d 64 6c 69 6e 65 61 72 67 28 74 65  d $cmdlinearg(te
40d0: 73 74 64 69 72 29 0a 20 20 7d 0a 20 20 73 65 74  stdir).  }.  set
40e0: 20 61 72 67 76 20 24 6c 65 66 74 6f 76 65 72 0a   argv $leftover.
40f0: 0a 20 20 23 20 49 6e 73 74 61 6c 6c 20 74 68 65  .  # Install the
4100: 20 6d 61 6c 6c 6f 63 20 6c 61 79 65 72 20 75 73   malloc layer us
4110: 65 64 20 74 6f 20 69 6e 6a 65 63 74 20 4f 4f 4d  ed to inject OOM
4120: 20 65 72 72 6f 72 73 2e 20 41 6e 64 20 74 68 65   errors. And the
4130: 20 27 61 75 74 6f 6d 61 74 69 63 27 0a 20 20 23   'automatic'.  #
4140: 20 65 78 74 65 6e 73 69 6f 6e 73 2e 20 54 68 69   extensions. Thi
4150: 73 20 6f 6e 6c 79 20 6e 65 65 64 73 20 74 6f 20  s only needs to 
4160: 62 65 20 64 6f 6e 65 20 6f 6e 63 65 20 66 6f 72  be done once for
4170: 20 74 68 65 20 70 72 6f 63 65 73 73 2e 0a 20 20   the process..  
4180: 23 0a 20 20 73 71 6c 69 74 65 33 5f 73 68 75 74  #.  sqlite3_shut
4190: 64 6f 77 6e 0a 20 20 69 6e 73 74 61 6c 6c 5f 6d  down.  install_m
41a0: 61 6c 6c 6f 63 5f 66 61 75 6c 74 73 69 6d 20 31  alloc_faultsim 1
41b0: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 69 74 69  .  sqlite3_initi
41c0: 61 6c 69 7a 65 0a 20 20 61 75 74 6f 69 6e 73 74  alize.  autoinst
41d0: 61 6c 6c 5f 74 65 73 74 5f 66 75 6e 63 74 69 6f  all_test_functio
41e0: 6e 73 0a 0a 20 20 23 20 49 66 20 74 68 65 20 2d  ns..  # If the -
41f0: 2d 62 69 6e 61 72 79 6c 6f 67 20 6f 70 74 69 6f  -binarylog optio
4200: 6e 20 77 61 73 20 73 70 65 63 69 66 69 65 64 2c  n was specified,
4210: 20 63 72 65 61 74 65 20 74 68 65 20 6c 6f 67 67   create the logg
4220: 69 6e 67 20 56 46 53 2e 20 54 68 69 73 0a 20 20  ing VFS. This.  
4230: 23 20 63 61 6c 6c 20 69 6e 73 74 61 6c 6c 73 20  # call installs 
4240: 74 68 65 20 6e 65 77 20 56 46 53 20 61 73 20 74  the new VFS as t
4250: 68 65 20 64 65 66 61 75 6c 74 20 66 6f 72 20 61  he default for a
4260: 6c 6c 20 53 51 4c 69 74 65 20 63 6f 6e 6e 65 63  ll SQLite connec
4270: 74 69 6f 6e 73 2e 0a 20 20 23 0a 20 20 69 66 20  tions..  #.  if 
4280: 7b 24 63 6d 64 6c 69 6e 65 61 72 67 28 62 69 6e  {$cmdlinearg(bin
4290: 61 72 79 6c 6f 67 29 7d 20 7b 0a 20 20 20 20 76  arylog)} {.    v
42a0: 66 73 6c 6f 67 20 6e 65 77 20 62 69 6e 61 72 79  fslog new binary
42b0: 6c 6f 67 20 7b 7d 20 76 66 73 6c 6f 67 2e 62 69  log {} vfslog.bi
42c0: 6e 0a 20 20 7d 0a 0a 20 20 23 20 53 65 74 20 74  n.  }..  # Set t
42d0: 68 65 20 62 61 63 6b 74 72 61 63 65 20 64 65 70  he backtrace dep
42e0: 74 68 2c 20 69 66 20 6d 61 6c 6c 6f 63 20 74 72  th, if malloc tr
42f0: 61 63 69 6e 67 20 69 73 20 65 6e 61 62 6c 65 64  acing is enabled
4300: 2e 0a 20 20 23 0a 20 20 69 66 20 7b 24 63 6d 64  ..  #.  if {$cmd
4310: 6c 69 6e 65 61 72 67 28 6d 61 6c 6c 6f 63 74 72  linearg(malloctr
4320: 61 63 65 29 7d 20 7b 0a 20 20 20 20 73 71 6c 69  ace)} {.    sqli
4330: 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 62 61 63  te3_memdebug_bac
4340: 6b 74 72 61 63 65 20 24 63 6d 64 6c 69 6e 65 61  ktrace $cmdlinea
4350: 72 67 28 62 61 63 6b 74 72 61 63 65 29 0a 20 20  rg(backtrace).  
4360: 7d 0a 0a 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e  }..  if {$cmdlin
4370: 65 61 72 67 28 6f 75 74 70 75 74 29 21 3d 22 22  earg(output)!=""
4380: 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 22 43 6f  } {.    puts "Co
4390: 70 79 69 6e 67 20 6f 75 74 70 75 74 20 74 6f 20  pying output to 
43a0: 66 69 6c 65 20 24 63 6d 64 6c 69 6e 65 61 72 67  file $cmdlinearg
43b0: 28 6f 75 74 70 75 74 29 22 0a 20 20 20 20 73 65  (output)".    se
43c0: 74 20 3a 3a 47 28 6f 75 74 70 75 74 5f 66 64 29  t ::G(output_fd)
43d0: 20 5b 6f 70 65 6e 20 24 63 6d 64 6c 69 6e 65 61   [open $cmdlinea
43e0: 72 67 28 6f 75 74 70 75 74 29 20 77 5d 0a 20 20  rg(output) w].  
43f0: 20 20 66 63 6f 6e 66 69 67 75 72 65 20 24 3a 3a    fconfigure $::
4400: 47 28 6f 75 74 70 75 74 5f 66 64 29 20 2d 62 75  G(output_fd) -bu
4410: 66 66 65 72 69 6e 67 20 6c 69 6e 65 0a 20 20 7d  ffering line.  }
4420: 0a 0a 20 20 69 66 20 7b 24 63 6d 64 6c 69 6e 65  ..  if {$cmdline
4430: 61 72 67 28 76 65 72 62 6f 73 65 29 3d 3d 22 22  arg(verbose)==""
4440: 7d 20 7b 0a 20 20 20 20 73 65 74 20 63 6d 64 6c  } {.    set cmdl
4450: 69 6e 65 61 72 67 28 76 65 72 62 6f 73 65 29 20  inearg(verbose) 
4460: 31 0a 20 20 7d 0a 7d 0a 0a 23 20 55 70 64 61 74  1.  }.}..# Updat
4470: 65 20 74 68 65 20 73 6f 66 74 2d 68 65 61 70 2d  e the soft-heap-
4480: 6c 69 6d 69 74 20 65 61 63 68 20 74 69 6d 65 20  limit each time 
4490: 74 68 69 73 20 73 63 72 69 70 74 20 69 73 20 72  this script is r
44a0: 75 6e 2e 20 49 6e 20 74 68 61 74 0a 23 20 77 61  un. In that.# wa
44b0: 79 20 69 66 20 61 6e 20 69 6e 64 69 76 69 64 75  y if an individu
44c0: 61 6c 20 74 65 73 74 20 66 69 6c 65 20 63 68 61  al test file cha
44d0: 6e 67 65 73 20 74 68 65 20 73 6f 66 74 2d 68 65  nges the soft-he
44e0: 61 70 2d 6c 69 6d 69 74 2c 20 69 74 0a 23 20 77  ap-limit, it.# w
44f0: 69 6c 6c 20 62 65 20 72 65 73 65 74 20 61 74 20  ill be reset at 
4500: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
4510: 20 6e 65 78 74 20 74 65 73 74 20 66 69 6c 65 2e   next test file.
4520: 0a 23 0a 73 71 6c 69 74 65 33 5f 73 6f 66 74 5f  .#.sqlite3_soft_
4530: 68 65 61 70 5f 6c 69 6d 69 74 20 24 63 6d 64 6c  heap_limit $cmdl
4540: 69 6e 65 61 72 67 28 73 6f 66 74 2d 68 65 61 70  inearg(soft-heap
4550: 2d 6c 69 6d 69 74 29 0a 0a 23 20 43 72 65 61 74  -limit)..# Creat
4560: 65 20 61 20 74 65 73 74 20 64 61 74 61 62 61 73  e a test databas
4570: 65 0a 23 0a 70 72 6f 63 20 72 65 73 65 74 5f 64  e.#.proc reset_d
4580: 62 20 7b 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b  b {} {.  catch {
4590: 64 62 20 63 6c 6f 73 65 7d 0a 20 20 66 6f 72 63  db close}.  forc
45a0: 65 64 65 6c 65 74 65 20 74 65 73 74 2e 64 62 0a  edelete test.db.
45b0: 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65    forcedelete te
45c0: 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 0a 20 20  st.db-journal.  
45d0: 66 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74  forcedelete test
45e0: 2e 64 62 2d 77 61 6c 0a 20 20 73 71 6c 69 74 65  .db-wal.  sqlite
45f0: 33 20 64 62 20 2e 2f 74 65 73 74 2e 64 62 0a 20  3 db ./test.db. 
4600: 20 73 65 74 20 3a 3a 44 42 20 5b 73 71 6c 69 74   set ::DB [sqlit
4610: 65 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f  e3_connection_po
4620: 69 6e 74 65 72 20 64 62 5d 0a 20 20 69 66 20 7b  inter db].  if {
4630: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 53  [info exists ::S
4640: 45 54 55 50 5f 53 51 4c 5d 7d 20 7b 0a 20 20 20  ETUP_SQL]} {.   
4650: 20 64 62 20 65 76 61 6c 20 24 3a 3a 53 45 54 55   db eval $::SETU
4660: 50 5f 53 51 4c 0a 20 20 7d 0a 7d 0a 72 65 73 65  P_SQL.  }.}.rese
4670: 74 5f 64 62 0a 0a 23 20 41 62 6f 72 74 20 65 61  t_db..# Abort ea
4680: 72 6c 79 20 69 66 20 74 68 69 73 20 73 63 72 69  rly if this scri
4690: 70 74 20 68 61 73 20 62 65 65 6e 20 72 75 6e 20  pt has been run 
46a0: 62 65 66 6f 72 65 2e 0a 23 0a 69 66 20 7b 5b 69  before..#.if {[i
46b0: 6e 66 6f 20 65 78 69 73 74 73 20 54 43 28 63 6f  nfo exists TC(co
46c0: 75 6e 74 29 5d 7d 20 72 65 74 75 72 6e 0a 0a 23  unt)]} return..#
46d0: 20 4d 61 6b 65 20 73 75 72 65 20 6d 65 6d 6f 72   Make sure memor
46e0: 79 20 73 74 61 74 69 73 74 69 63 73 20 61 72 65  y statistics are
46f0: 20 65 6e 61 62 6c 65 64 2e 0a 23 0a 73 71 6c 69   enabled..#.sqli
4700: 74 65 33 5f 63 6f 6e 66 69 67 5f 6d 65 6d 73 74  te3_config_memst
4710: 61 74 75 73 20 31 0a 0a 23 20 49 6e 69 74 69 61  atus 1..# Initia
4720: 6c 69 7a 65 20 74 68 65 20 74 65 73 74 20 63 6f  lize the test co
4730: 75 6e 74 65 72 73 20 61 6e 64 20 73 65 74 20 75  unters and set u
4740: 70 20 63 6f 6d 6d 61 6e 64 73 20 74 6f 20 61 63  p commands to ac
4750: 63 65 73 73 20 74 68 65 6d 2e 0a 23 20 4f 72 2c  cess them..# Or,
4760: 20 69 66 20 74 68 69 73 20 69 73 20 61 20 73 6c   if this is a sl
4770: 61 76 65 20 69 6e 74 65 72 70 72 65 74 65 72 2c  ave interpreter,
4780: 20 73 65 74 20 75 70 20 61 6c 69 61 73 65 73 20   set up aliases 
4790: 74 6f 20 77 72 69 74 65 20 74 68 65 0a 23 20 63  to write the.# c
47a0: 6f 75 6e 74 65 72 73 20 69 6e 20 74 68 65 20 70  ounters in the p
47b0: 61 72 65 6e 74 20 69 6e 74 65 72 70 72 65 74 65  arent interprete
47c0: 72 2e 0a 23 0a 69 66 20 7b 30 3d 3d 5b 69 6e 66  r..#.if {0==[inf
47d0: 6f 20 65 78 69 73 74 73 20 3a 3a 53 4c 41 56 45  o exists ::SLAVE
47e0: 5d 7d 20 7b 0a 20 20 73 65 74 20 54 43 28 65 72  ]} {.  set TC(er
47f0: 72 6f 72 73 29 20 20 20 20 30 0a 20 20 73 65 74  rors)    0.  set
4800: 20 54 43 28 63 6f 75 6e 74 29 20 20 20 20 20 30   TC(count)     0
4810: 0a 20 20 73 65 74 20 54 43 28 66 61 69 6c 5f 6c  .  set TC(fail_l
4820: 69 73 74 29 20 5b 6c 69 73 74 5d 0a 20 20 73 65  ist) [list].  se
4830: 74 20 54 43 28 6f 6d 69 74 5f 6c 69 73 74 29 20  t TC(omit_list) 
4840: 5b 6c 69 73 74 5d 0a 20 20 73 65 74 20 54 43 28  [list].  set TC(
4850: 77 61 72 6e 5f 6c 69 73 74 29 20 5b 6c 69 73 74  warn_list) [list
4860: 5d 0a 0a 20 20 70 72 6f 63 20 73 65 74 5f 74 65  ]..  proc set_te
4870: 73 74 5f 63 6f 75 6e 74 65 72 20 7b 63 6f 75 6e  st_counter {coun
4880: 74 65 72 20 61 72 67 73 7d 20 7b 0a 20 20 20 20  ter args} {.    
4890: 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 61 72  if {[llength $ar
48a0: 67 73 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  gs]} {.      set
48b0: 20 3a 3a 54 43 28 24 63 6f 75 6e 74 65 72 29 20   ::TC($counter) 
48c0: 5b 6c 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d  [lindex $args 0]
48d0: 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20 3a  .    }.    set :
48e0: 3a 54 43 28 24 63 6f 75 6e 74 65 72 29 0a 20 20  :TC($counter).  
48f0: 7d 0a 7d 0a 0a 23 20 52 65 63 6f 72 64 20 74 68  }.}..# Record th
4900: 65 20 66 61 63 74 20 74 68 61 74 20 61 20 73 65  e fact that a se
4910: 71 75 65 6e 63 65 20 6f 66 20 74 65 73 74 73 20  quence of tests 
4920: 77 65 72 65 20 6f 6d 69 74 74 65 64 2e 0a 23 0a  were omitted..#.
4930: 70 72 6f 63 20 6f 6d 69 74 5f 74 65 73 74 20 7b  proc omit_test {
4940: 6e 61 6d 65 20 72 65 61 73 6f 6e 20 7b 61 70 70  name reason {app
4950: 65 6e 64 20 31 7d 7d 20 7b 0a 20 20 73 65 74 20  end 1}} {.  set 
4960: 6f 6d 69 74 4c 69 73 74 20 5b 73 65 74 5f 74 65  omitList [set_te
4970: 73 74 5f 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f  st_counter omit_
4980: 6c 69 73 74 5d 0a 20 20 69 66 20 7b 24 61 70 70  list].  if {$app
4990: 65 6e 64 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65  end} {.    lappe
49a0: 6e 64 20 6f 6d 69 74 4c 69 73 74 20 5b 6c 69 73  nd omitList [lis
49b0: 74 20 24 6e 61 6d 65 20 24 72 65 61 73 6f 6e 5d  t $name $reason]
49c0: 0a 20 20 7d 0a 20 20 73 65 74 5f 74 65 73 74 5f  .  }.  set_test_
49d0: 63 6f 75 6e 74 65 72 20 6f 6d 69 74 5f 6c 69 73  counter omit_lis
49e0: 74 20 24 6f 6d 69 74 4c 69 73 74 0a 7d 0a 0a 23  t $omitList.}..#
49f0: 20 52 65 63 6f 72 64 20 74 68 65 20 66 61 63 74   Record the fact
4a00: 20 74 68 61 74 20 61 20 74 65 73 74 20 66 61 69   that a test fai
4a10: 6c 65 64 2e 0a 23 0a 70 72 6f 63 20 66 61 69 6c  led..#.proc fail
4a20: 5f 74 65 73 74 20 7b 6e 61 6d 65 7d 20 7b 0a 20  _test {name} {. 
4a30: 20 73 65 74 20 66 20 5b 73 65 74 5f 74 65 73 74   set f [set_test
4a40: 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69  _counter fail_li
4a50: 73 74 5d 0a 20 20 6c 61 70 70 65 6e 64 20 66 20  st].  lappend f 
4a60: 24 6e 61 6d 65 0a 20 20 73 65 74 5f 74 65 73 74  $name.  set_test
4a70: 5f 63 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69  _counter fail_li
4a80: 73 74 20 24 66 0a 20 20 73 65 74 5f 74 65 73 74  st $f.  set_test
4a90: 5f 63 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 20  _counter errors 
4aa0: 5b 65 78 70 72 20 5b 73 65 74 5f 74 65 73 74 5f  [expr [set_test_
4ab0: 63 6f 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 20  counter errors] 
4ac0: 2b 20 31 5d 0a 0a 20 20 73 65 74 20 6e 46 61 69  + 1]..  set nFai
4ad0: 6c 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f 75 6e  l [set_test_coun
4ae0: 74 65 72 20 65 72 72 6f 72 73 5d 0a 20 20 69 66  ter errors].  if
4af0: 20 7b 24 6e 46 61 69 6c 3e 3d 24 3a 3a 63 6d 64   {$nFail>=$::cmd
4b00: 6c 69 6e 65 61 72 67 28 6d 61 78 65 72 72 6f 72  linearg(maxerror
4b10: 29 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32  )} {.    output2
4b20: 20 22 2a 2a 2a 20 47 69 76 69 6e 67 20 75 70 2e   "*** Giving up.
4b30: 2e 2e 22 0a 20 20 20 20 66 69 6e 61 6c 69 7a 65  ..".    finalize
4b40: 5f 74 65 73 74 69 6e 67 0a 20 20 7d 0a 7d 0a 0a  _testing.  }.}..
4b50: 23 20 52 65 6d 65 6d 62 65 72 20 61 20 77 61 72  # Remember a war
4b60: 6e 69 6e 67 20 6d 65 73 73 61 67 65 20 74 6f 20  ning message to 
4b70: 62 65 20 64 69 73 70 6c 61 79 65 64 20 61 74 20  be displayed at 
4b80: 74 68 65 20 63 6f 6e 63 6c 75 73 69 6f 6e 20 6f  the conclusion o
4b90: 66 20 61 6c 6c 20 74 65 73 74 69 6e 67 0a 23 0a  f all testing.#.
4ba0: 70 72 6f 63 20 77 61 72 6e 69 6e 67 20 7b 6d 73  proc warning {ms
4bb0: 67 20 7b 61 70 70 65 6e 64 20 31 7d 7d 20 7b 0a  g {append 1}} {.
4bc0: 20 20 6f 75 74 70 75 74 32 20 22 57 61 72 6e 69    output2 "Warni
4bd0: 6e 67 3a 20 24 6d 73 67 22 0a 20 20 73 65 74 20  ng: $msg".  set 
4be0: 77 61 72 6e 4c 69 73 74 20 5b 73 65 74 5f 74 65  warnList [set_te
4bf0: 73 74 5f 63 6f 75 6e 74 65 72 20 77 61 72 6e 5f  st_counter warn_
4c00: 6c 69 73 74 5d 0a 20 20 69 66 20 7b 24 61 70 70  list].  if {$app
4c10: 65 6e 64 7d 20 7b 0a 20 20 20 20 6c 61 70 70 65  end} {.    lappe
4c20: 6e 64 20 77 61 72 6e 4c 69 73 74 20 24 6d 73 67  nd warnList $msg
4c30: 0a 20 20 7d 0a 20 20 73 65 74 5f 74 65 73 74 5f  .  }.  set_test_
4c40: 63 6f 75 6e 74 65 72 20 77 61 72 6e 5f 6c 69 73  counter warn_lis
4c50: 74 20 24 77 61 72 6e 4c 69 73 74 0a 7d 0a 0a 0a  t $warnList.}...
4c60: 23 20 49 6e 63 72 65 6d 65 6e 74 20 74 68 65 20  # Increment the 
4c70: 6e 75 6d 62 65 72 20 6f 66 20 74 65 73 74 73 20  number of tests 
4c80: 72 75 6e 0a 23 0a 70 72 6f 63 20 69 6e 63 72 5f  run.#.proc incr_
4c90: 6e 74 65 73 74 20 7b 7d 20 7b 0a 20 20 73 65 74  ntest {} {.  set
4ca0: 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 63 6f  _test_counter co
4cb0: 75 6e 74 20 5b 65 78 70 72 20 5b 73 65 74 5f 74  unt [expr [set_t
4cc0: 65 73 74 5f 63 6f 75 6e 74 65 72 20 63 6f 75 6e  est_counter coun
4cd0: 74 5d 20 2b 20 31 5d 0a 7d 0a 0a 23 20 52 65 74  t] + 1].}..# Ret
4ce0: 75 72 6e 20 74 72 75 65 20 69 66 20 2d 2d 76 65  urn true if --ve
4cf0: 72 62 6f 73 65 3d 31 20 77 61 73 20 73 70 65 63  rbose=1 was spec
4d00: 69 66 69 65 64 20 6f 6e 20 74 68 65 20 63 6f 6d  ified on the com
4d10: 6d 61 6e 64 20 6c 69 6e 65 2e 20 4f 74 68 65 72  mand line. Other
4d20: 77 69 73 65 2c 0a 23 20 72 65 74 75 72 6e 20 66  wise,.# return f
4d30: 61 6c 73 65 2e 0a 23 0a 70 72 6f 63 20 76 65 72  alse..#.proc ver
4d40: 62 6f 73 65 20 7b 7d 20 7b 0a 20 20 72 65 74 75  bose {} {.  retu
4d50: 72 6e 20 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67  rn $::cmdlinearg
4d60: 28 76 65 72 62 6f 73 65 29 0a 7d 0a 0a 23 20 55  (verbose).}..# U
4d70: 73 65 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  se the following
4d80: 20 63 6f 6d 6d 61 6e 64 73 20 69 6e 73 74 65 61   commands instea
4d90: 64 20 6f 66 20 5b 70 75 74 73 5d 20 66 6f 72 20  d of [puts] for 
4da0: 74 65 73 74 20 6f 75 74 70 75 74 20 77 69 74 68  test output with
4db0: 69 6e 0a 23 20 74 68 69 73 20 66 69 6c 65 2e 20  in.# this file. 
4dc0: 54 65 73 74 20 73 63 72 69 70 74 73 20 63 61 6e  Test scripts can
4dd0: 20 73 74 69 6c 6c 20 75 73 65 20 72 65 67 75 6c   still use regul
4de0: 61 72 20 5b 70 75 74 73 5d 2c 20 77 68 69 63 68  ar [puts], which
4df0: 20 69 73 20 64 69 72 65 63 74 65 64 0a 23 20 74   is directed.# t
4e00: 6f 20 73 74 64 6f 75 74 20 61 6e 64 2c 20 69 66  o stdout and, if
4e10: 20 6f 6e 65 20 69 73 20 6f 70 65 6e 2c 20 74 68   one is open, th
4e20: 65 20 2d 2d 6f 75 74 70 75 74 20 66 69 6c 65 2e  e --output file.
4e30: 0a 23 0a 23 20 6f 75 74 70 75 74 31 3a 20 6f 75  .#.# output1: ou
4e40: 74 70 75 74 20 74 68 61 74 20 73 68 6f 75 6c 64  tput that should
4e50: 20 62 65 20 70 72 69 6e 74 65 64 20 69 66 20 2d   be printed if -
4e60: 2d 76 65 72 62 6f 73 65 3d 31 20 77 61 73 20 73  -verbose=1 was s
4e70: 70 65 63 69 66 69 65 64 2e 0a 23 20 6f 75 74 70  pecified..# outp
4e80: 75 74 32 3a 20 6f 75 74 70 75 74 20 74 68 61 74  ut2: output that
4e90: 20 73 68 6f 75 6c 64 20 62 65 20 70 72 69 6e 74   should be print
4ea0: 65 64 20 75 6e 63 6f 6e 64 69 74 69 6f 6e 61 6c  ed unconditional
4eb0: 6c 79 2e 0a 23 20 6f 75 74 70 75 74 32 5f 69 66  ly..# output2_if
4ec0: 5f 6e 6f 5f 76 65 72 62 6f 73 65 3a 20 6f 75 74  _no_verbose: out
4ed0: 70 75 74 20 74 68 61 74 20 73 68 6f 75 6c 64 20  put that should 
4ee0: 62 65 20 70 72 69 6e 74 65 64 20 6f 6e 6c 79 20  be printed only 
4ef0: 69 66 20 2d 2d 76 65 72 62 6f 73 65 3d 30 2e 0a  if --verbose=0..
4f00: 23 0a 70 72 6f 63 20 6f 75 74 70 75 74 31 20 7b  #.proc output1 {
4f10: 61 72 67 73 7d 20 7b 0a 20 20 73 65 74 20 76 20  args} {.  set v 
4f20: 5b 76 65 72 62 6f 73 65 5d 0a 20 20 69 66 20 7b  [verbose].  if {
4f30: 24 76 3d 3d 31 7d 20 7b 0a 20 20 20 20 75 70 6c  $v==1} {.    upl
4f40: 65 76 65 6c 20 6f 75 74 70 75 74 32 20 24 61 72  evel output2 $ar
4f50: 67 73 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 24  gs.  } elseif {$
4f60: 76 3d 3d 32 7d 20 7b 0a 20 20 20 20 75 70 6c 65  v==2} {.    uple
4f70: 76 65 6c 20 70 75 74 73 20 5b 6c 72 61 6e 67 65  vel puts [lrange
4f80: 20 24 61 72 67 73 20 30 20 65 6e 64 2d 31 5d 20   $args 0 end-1] 
4f90: 24 3a 3a 47 28 6f 75 74 70 75 74 5f 66 64 29 20  $::G(output_fd) 
4fa0: 5b 6c 72 61 6e 67 65 20 24 61 72 67 73 20 65 6e  [lrange $args en
4fb0: 64 20 65 6e 64 5d 0a 20 20 7d 0a 7d 0a 70 72 6f  d end].  }.}.pro
4fc0: 63 20 6f 75 74 70 75 74 32 20 7b 61 72 67 73 7d  c output2 {args}
4fd0: 20 7b 0a 20 20 73 65 74 20 6e 41 72 67 20 5b 6c   {.  set nArg [l
4fe0: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 0a 20 20  length $args].  
4ff0: 75 70 6c 65 76 65 6c 20 70 75 74 73 20 24 61 72  uplevel puts $ar
5000: 67 73 0a 7d 0a 70 72 6f 63 20 6f 75 74 70 75 74  gs.}.proc output
5010: 32 5f 69 66 5f 6e 6f 5f 76 65 72 62 6f 73 65 20  2_if_no_verbose 
5020: 7b 61 72 67 73 7d 20 7b 0a 20 20 73 65 74 20 76  {args} {.  set v
5030: 20 5b 76 65 72 62 6f 73 65 5d 0a 20 20 69 66 20   [verbose].  if 
5040: 7b 24 76 3d 3d 30 7d 20 7b 0a 20 20 20 20 75 70  {$v==0} {.    up
5050: 6c 65 76 65 6c 20 6f 75 74 70 75 74 32 20 24 61  level output2 $a
5060: 72 67 73 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b  rgs.  } elseif {
5070: 24 76 3d 3d 32 7d 20 7b 0a 20 20 20 20 75 70 6c  $v==2} {.    upl
5080: 65 76 65 6c 20 70 75 74 73 20 5b 6c 72 61 6e 67  evel puts [lrang
5090: 65 20 24 61 72 67 73 20 30 20 65 6e 64 2d 31 5d  e $args 0 end-1]
50a0: 20 73 74 64 6f 75 74 20 5b 6c 72 61 6e 67 65 20   stdout [lrange 
50b0: 24 61 72 67 73 20 65 6e 64 20 65 6e 64 5d 0a 20  $args end end]. 
50c0: 20 7d 0a 7d 0a 0a 23 20 4f 76 65 72 72 69 64 65   }.}..# Override
50d0: 20 74 68 65 20 5b 70 75 74 73 5d 20 63 6f 6d 6d   the [puts] comm
50e0: 61 6e 64 20 73 6f 20 74 68 61 74 20 69 66 20 6e  and so that if n
50f0: 6f 20 63 68 61 6e 6e 65 6c 20 69 73 20 65 78 70  o channel is exp
5100: 6c 69 63 69 74 6c 79 20 0a 23 20 73 70 65 63 69  licitly .# speci
5110: 66 69 65 64 20 74 68 65 20 73 74 72 69 6e 67 20  fied the string 
5120: 69 73 20 77 72 69 74 74 65 6e 20 74 6f 20 62 6f  is written to bo
5130: 74 68 20 73 74 64 6f 75 74 20 61 6e 64 20 74 6f  th stdout and to
5140: 20 74 68 65 20 66 69 6c 65 20 0a 23 20 73 70 65   the file .# spe
5150: 63 69 66 69 65 64 20 62 79 20 22 2d 2d 6f 75 74  cified by "--out
5160: 70 75 74 3d 22 2c 20 69 66 20 61 6e 79 2e 0a 23  put=", if any..#
5170: 0a 70 72 6f 63 20 70 75 74 73 5f 6f 76 65 72 72  .proc puts_overr
5180: 69 64 65 20 7b 61 72 67 73 7d 20 7b 0a 20 20 73  ide {args} {.  s
5190: 65 74 20 6e 41 72 67 20 5b 6c 6c 65 6e 67 74 68  et nArg [llength
51a0: 20 24 61 72 67 73 5d 0a 20 20 69 66 20 7b 24 6e   $args].  if {$n
51b0: 41 72 67 3d 3d 31 20 7c 7c 20 28 24 6e 41 72 67  Arg==1 || ($nArg
51c0: 3d 3d 32 20 26 26 20 5b 73 74 72 69 6e 67 20 66  ==2 && [string f
51d0: 69 72 73 74 20 5b 6c 69 6e 64 65 78 20 24 61 72  irst [lindex $ar
51e0: 67 73 20 30 5d 20 2d 6e 6f 6e 65 77 6c 69 6e 65  gs 0] -nonewline
51f0: 5d 3d 3d 30 29 7d 20 7b 0a 20 20 20 20 75 70 6c  ]==0)} {.    upl
5200: 65 76 65 6c 20 70 75 74 73 5f 6f 72 69 67 69 6e  evel puts_origin
5210: 61 6c 20 24 61 72 67 73 0a 20 20 20 20 69 66 20  al $args.    if 
5220: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
5230: 47 28 6f 75 74 70 75 74 5f 66 64 29 5d 7d 20 7b  G(output_fd)]} {
5240: 0a 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 70  .      uplevel p
5250: 75 74 73 20 5b 6c 72 61 6e 67 65 20 24 61 72 67  uts [lrange $arg
5260: 73 20 30 20 65 6e 64 2d 31 5d 20 24 3a 3a 47 28  s 0 end-1] $::G(
5270: 6f 75 74 70 75 74 5f 66 64 29 20 5b 6c 72 61 6e  output_fd) [lran
5280: 67 65 20 24 61 72 67 73 20 65 6e 64 20 65 6e 64  ge $args end end
5290: 5d 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65  ].    }.  } else
52a0: 20 7b 0a 20 20 20 20 23 20 41 20 63 68 61 6e 6e   {.    # A chann
52b0: 65 6c 20 77 61 73 20 65 78 70 6c 69 63 69 74 6c  el was explicitl
52c0: 79 20 73 70 65 63 69 66 69 65 64 2e 0a 20 20 20  y specified..   
52d0: 20 75 70 6c 65 76 65 6c 20 70 75 74 73 5f 6f 72   uplevel puts_or
52e0: 69 67 69 6e 61 6c 20 24 61 72 67 73 0a 20 20 7d  iginal $args.  }
52f0: 0a 7d 0a 72 65 6e 61 6d 65 20 70 75 74 73 20 70  .}.rename puts p
5300: 75 74 73 5f 6f 72 69 67 69 6e 61 6c 0a 70 72 6f  uts_original.pro
5310: 63 20 70 75 74 73 20 7b 61 72 67 73 7d 20 7b 20  c puts {args} { 
5320: 75 70 6c 65 76 65 6c 20 70 75 74 73 5f 6f 76 65  uplevel puts_ove
5330: 72 72 69 64 65 20 24 61 72 67 73 20 7d 0a 0a 0a  rride $args }...
5340: 23 20 49 6e 76 6f 6b 65 20 74 68 65 20 64 6f 5f  # Invoke the do_
5350: 74 65 73 74 20 70 72 6f 63 65 64 75 72 65 20 74  test procedure t
5360: 6f 20 72 75 6e 20 61 20 73 69 6e 67 6c 65 20 74  o run a single t
5370: 65 73 74 0a 23 0a 23 20 54 68 65 20 24 65 78 70  est.#.# The $exp
5380: 65 63 74 65 64 20 70 61 72 61 6d 65 74 65 72 20  ected parameter 
5390: 69 73 20 74 68 65 20 65 78 70 65 63 74 65 64 20  is the expected 
53a0: 72 65 73 75 6c 74 2e 20 20 54 68 65 20 72 65 73  result.  The res
53b0: 75 6c 74 20 69 73 20 74 68 65 20 72 65 74 75 72  ult is the retur
53c0: 6e 0a 23 20 76 61 6c 75 65 20 66 72 6f 6d 20 74  n.# value from t
53d0: 68 65 20 6c 61 73 74 20 54 43 4c 20 63 6f 6d 6d  he last TCL comm
53e0: 61 6e 64 20 69 6e 20 24 63 6d 64 2e 0a 23 0a 23  and in $cmd..#.#
53f0: 20 4e 6f 72 6d 61 6c 6c 79 2c 20 24 65 78 70 65   Normally, $expe
5400: 63 74 65 64 20 6d 75 73 74 20 6d 61 74 63 68 20  cted must match 
5410: 65 78 61 63 74 6c 79 2e 20 20 42 75 74 20 69 66  exactly.  But if
5420: 20 24 65 78 70 65 63 74 65 64 20 69 73 20 6f 66   $expected is of
5430: 20 74 68 65 20 66 6f 72 6d 0a 23 20 22 2f 72 65   the form.# "/re
5440: 67 65 78 70 2f 22 20 74 68 65 6e 20 72 65 67 75  gexp/" then regu
5450: 6c 61 72 20 65 78 70 72 65 73 73 69 6f 6e 20 6d  lar expression m
5460: 61 74 63 68 69 6e 67 20 69 73 20 75 73 65 64 2e  atching is used.
5470: 20 20 49 66 20 24 65 78 70 65 63 74 65 64 20 69    If $expected i
5480: 73 0a 23 20 22 7e 2f 72 65 67 65 78 70 2f 22 20  s.# "~/regexp/" 
5490: 74 68 65 6e 20 74 68 65 20 72 65 67 75 6c 61 72  then the regular
54a0: 20 65 78 70 72 65 73 73 69 6f 6e 20 6d 75 73 74   expression must
54b0: 20 4e 4f 54 20 6d 61 74 63 68 2e 20 20 49 66 20   NOT match.  If 
54c0: 24 65 78 70 65 63 74 65 64 20 69 73 0a 23 20 6f  $expected is.# o
54d0: 66 20 74 68 65 20 66 6f 72 6d 20 22 23 2f 76 61  f the form "#/va
54e0: 6c 75 65 2d 6c 69 73 74 2f 22 20 74 68 65 6e 20  lue-list/" then 
54f0: 65 61 63 68 20 74 65 72 6d 20 69 6e 20 76 61 6c  each term in val
5500: 75 65 2d 6c 69 73 74 20 6d 75 73 74 20 62 65 20  ue-list must be 
5510: 6e 75 6d 65 72 69 63 0a 23 20 61 6e 64 20 6d 75  numeric.# and mu
5520: 73 74 20 61 70 70 72 6f 78 69 6d 61 74 65 6c 79  st approximately
5530: 20 6d 61 74 63 68 20 74 68 65 20 63 6f 72 72 65   match the corre
5540: 73 70 6f 6e 64 69 6e 67 20 6e 75 6d 65 72 69 63  sponding numeric
5550: 20 74 65 72 6d 20 69 6e 20 24 72 65 73 75 6c 74   term in $result
5560: 2e 0a 23 20 56 61 6c 75 65 73 20 6d 75 73 74 20  ..# Values must 
5570: 6d 61 74 63 68 20 77 69 74 68 69 6e 20 31 30 25  match within 10%
5580: 2e 20 20 4f 72 20 69 66 20 74 68 65 20 24 65 78  .  Or if the $ex
5590: 70 65 63 74 65 64 20 74 65 72 6d 20 69 73 20 41  pected term is A
55a0: 2e 2e 42 20 74 68 65 6e 20 74 68 65 0a 23 20 24  ..B then the.# $
55b0: 72 65 73 75 6c 74 20 74 65 72 6d 20 6d 75 73 74  result term must
55c0: 20 62 65 20 69 6e 20 62 65 74 77 65 65 6e 20 41   be in between A
55d0: 20 61 6e 64 20 42 2e 0a 23 0a 70 72 6f 63 20 64   and B..#.proc d
55e0: 6f 5f 74 65 73 74 20 7b 6e 61 6d 65 20 63 6d 64  o_test {name cmd
55f0: 20 65 78 70 65 63 74 65 64 7d 20 7b 0a 20 20 67   expected} {.  g
5600: 6c 6f 62 61 6c 20 61 72 67 76 20 63 6d 64 6c 69  lobal argv cmdli
5610: 6e 65 61 72 67 0a 0a 20 20 66 69 78 5f 74 65 73  nearg..  fix_tes
5620: 74 6e 61 6d 65 20 6e 61 6d 65 0a 0a 20 20 73 71  tname name..  sq
5630: 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 73  lite3_memdebug_s
5640: 65 74 74 69 74 6c 65 20 24 6e 61 6d 65 0a 0a 23  ettitle $name..#
5650: 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24    if {[llength $
5660: 61 72 67 76 5d 3d 3d 30 7d 20 7b 0a 23 20 20 20  argv]==0} {.#   
5670: 20 73 65 74 20 67 6f 20 31 0a 23 20 20 7d 20 65   set go 1.#  } e
5680: 6c 73 65 20 7b 0a 23 20 20 20 20 73 65 74 20 67  lse {.#    set g
5690: 6f 20 30 0a 23 20 20 20 20 66 6f 72 65 61 63 68  o 0.#    foreach
56a0: 20 70 61 74 74 65 72 6e 20 24 61 72 67 76 20 7b   pattern $argv {
56b0: 0a 23 20 20 20 20 20 20 69 66 20 7b 5b 73 74 72  .#      if {[str
56c0: 69 6e 67 20 6d 61 74 63 68 20 24 70 61 74 74 65  ing match $patte
56d0: 72 6e 20 24 6e 61 6d 65 5d 7d 20 7b 0a 23 20 20  rn $name]} {.#  
56e0: 20 20 20 20 20 20 73 65 74 20 67 6f 20 31 0a 23        set go 1.#
56f0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 0a 23 20          break.# 
5700: 20 20 20 20 20 7d 0a 23 20 20 20 20 7d 0a 23 20       }.#    }.# 
5710: 20 7d 0a 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20   }..  if {[info 
5720: 65 78 69 73 74 73 20 3a 3a 47 28 70 65 72 6d 3a  exists ::G(perm:
5730: 70 72 65 66 69 78 29 5d 7d 20 7b 0a 20 20 20 20  prefix)]} {.    
5740: 73 65 74 20 6e 61 6d 65 20 22 24 3a 3a 47 28 70  set name "$::G(p
5750: 65 72 6d 3a 70 72 65 66 69 78 29 24 6e 61 6d 65  erm:prefix)$name
5760: 22 0a 20 20 7d 0a 0a 20 20 69 6e 63 72 5f 6e 74  ".  }..  incr_nt
5770: 65 73 74 0a 20 20 6f 75 74 70 75 74 31 20 2d 6e  est.  output1 -n
5780: 6f 6e 65 77 6c 69 6e 65 20 24 6e 61 6d 65 2e 2e  onewline $name..
5790: 2e 0a 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74  ..  flush stdout
57a0: 0a 0a 20 20 69 66 20 7b 21 5b 69 6e 66 6f 20 65  ..  if {![info e
57b0: 78 69 73 74 73 20 3a 3a 47 28 6d 61 74 63 68 29  xists ::G(match)
57c0: 5d 20 7c 7c 20 5b 73 74 72 69 6e 67 20 6d 61 74  ] || [string mat
57d0: 63 68 20 24 3a 3a 47 28 6d 61 74 63 68 29 20 24  ch $::G(match) $
57e0: 6e 61 6d 65 5d 7d 20 7b 0a 20 20 20 20 69 66 20  name]} {.    if 
57f0: 7b 5b 63 61 74 63 68 20 7b 75 70 6c 65 76 65 6c  {[catch {uplevel
5800: 20 23 30 20 22 24 63 6d 64 3b 5c 6e 22 7d 20 72   #0 "$cmd;\n"} r
5810: 65 73 75 6c 74 5d 7d 20 7b 0a 20 20 20 20 20 20  esult]} {.      
5820: 6f 75 74 70 75 74 32 5f 69 66 5f 6e 6f 5f 76 65  output2_if_no_ve
5830: 72 62 6f 73 65 20 2d 6e 6f 6e 65 77 6c 69 6e 65  rbose -nonewline
5840: 20 24 6e 61 6d 65 2e 2e 2e 0a 20 20 20 20 20 20   $name....      
5850: 6f 75 74 70 75 74 32 20 22 5c 6e 45 72 72 6f 72  output2 "\nError
5860: 3a 20 24 72 65 73 75 6c 74 22 0a 20 20 20 20 20  : $result".     
5870: 20 66 61 69 6c 5f 74 65 73 74 20 24 6e 61 6d 65   fail_test $name
5880: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
5890: 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20      if {[regexp 
58a0: 7b 5e 5b 7e 23 5d 3f 2f 2e 2a 2f 24 7d 20 24 65  {^[~#]?/.*/$} $e
58b0: 78 70 65 63 74 65 64 5d 7d 20 7b 0a 20 20 20 20  xpected]} {.    
58c0: 20 20 20 20 23 20 22 65 78 70 65 63 74 65 64 22      # "expected"
58d0: 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d 20   is of the form 
58e0: 22 2f 50 41 54 54 45 52 4e 2f 22 20 74 68 65 6e  "/PATTERN/" then
58f0: 20 74 68 65 20 72 65 73 75 6c 74 20 69 66 20 63   the result if c
5900: 6f 72 72 65 63 74 20 69 66 0a 20 20 20 20 20 20  orrect if.      
5910: 20 20 23 20 72 65 67 75 6c 61 72 20 65 78 70 72    # regular expr
5920: 65 73 73 69 6f 6e 20 50 41 54 54 45 52 4e 20 6d  ession PATTERN m
5930: 61 74 63 68 65 73 20 74 68 65 20 72 65 73 75 6c  atches the resul
5940: 74 2e 20 20 22 7e 2f 50 41 54 54 45 52 4e 2f 22  t.  "~/PATTERN/"
5950: 20 6d 65 61 6e 73 0a 20 20 20 20 20 20 20 20 23   means.        #
5960: 20 74 68 65 20 72 65 67 75 6c 61 72 20 65 78 70   the regular exp
5970: 72 65 73 73 69 6f 6e 20 6d 75 73 74 20 6e 6f 74  ression must not
5980: 20 6d 61 74 63 68 2e 0a 20 20 20 20 20 20 20 20   match..        
5990: 69 66 20 7b 5b 73 74 72 69 6e 67 20 69 6e 64 65  if {[string inde
59a0: 78 20 24 65 78 70 65 63 74 65 64 20 30 5d 3d 3d  x $expected 0]==
59b0: 22 7e 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  "~"} {.         
59c0: 20 73 65 74 20 72 65 20 5b 73 74 72 69 6e 67 20   set re [string 
59d0: 72 61 6e 67 65 20 24 65 78 70 65 63 74 65 64 20  range $expected 
59e0: 32 20 65 6e 64 2d 31 5d 0a 20 20 20 20 20 20 20  2 end-1].       
59f0: 20 20 20 69 66 20 7b 5b 73 74 72 69 6e 67 20 69     if {[string i
5a00: 6e 64 65 78 20 24 72 65 20 30 5d 3d 3d 22 2a 22  ndex $re 0]=="*"
5a10: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  } {.            
5a20: 23 20 49 66 20 74 68 65 20 72 65 67 75 6c 61 72  # If the regular
5a30: 20 65 78 70 72 65 73 73 69 6f 6e 20 62 65 67 69   expression begi
5a40: 6e 73 20 77 69 74 68 20 2a 20 74 68 65 6e 20 74  ns with * then t
5a50: 72 65 61 74 20 69 74 20 61 73 20 61 20 67 6c 6f  reat it as a glo
5a60: 62 20 69 6e 73 74 65 61 64 0a 20 20 20 20 20 20  b instead.      
5a70: 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 73 74        set ok [st
5a80: 72 69 6e 67 20 6d 61 74 63 68 20 24 72 65 20 24  ring match $re $
5a90: 72 65 73 75 6c 74 5d 0a 20 20 20 20 20 20 20 20  result].        
5aa0: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
5ab0: 20 20 20 20 20 20 20 73 65 74 20 72 65 20 5b 73         set re [s
5ac0: 74 72 69 6e 67 20 6d 61 70 20 7b 23 20 7b 5b 2d  tring map {# {[-
5ad0: 30 2d 39 2e 5d 2b 7d 7d 20 24 72 65 5d 0a 20 20  0-9.]+}} $re].  
5ae0: 20 20 20 20 20 20 20 20 20 20 73 65 74 20 6f 6b            set ok
5af0: 20 5b 72 65 67 65 78 70 20 24 72 65 20 24 72 65   [regexp $re $re
5b00: 73 75 6c 74 5d 0a 20 20 20 20 20 20 20 20 20 20  sult].          
5b10: 7d 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20  }.          set 
5b20: 6f 6b 20 5b 65 78 70 72 20 7b 21 24 6f 6b 7d 5d  ok [expr {!$ok}]
5b30: 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65 69  .        } elsei
5b40: 66 20 7b 5b 73 74 72 69 6e 67 20 69 6e 64 65 78  f {[string index
5b50: 20 24 65 78 70 65 63 74 65 64 20 30 5d 3d 3d 22   $expected 0]=="
5b60: 23 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20  #"} {.          
5b70: 23 20 4e 75 6d 65 72 69 63 20 72 61 6e 67 65 20  # Numeric range 
5b80: 76 61 6c 75 65 20 63 6f 6d 70 61 72 69 73 6f 6e  value comparison
5b90: 2e 20 20 45 61 63 68 20 74 65 72 6d 20 6f 66 20  .  Each term of 
5ba0: 74 68 65 20 24 72 65 73 75 6c 74 20 69 73 20 6d  the $result is m
5bb0: 61 74 63 68 65 64 0a 20 20 20 20 20 20 20 20 20  atched.         
5bc0: 20 23 20 61 67 61 69 6e 73 74 20 6f 6e 65 20 74   # against one t
5bd0: 65 72 6d 20 6f 66 20 24 65 78 70 65 63 74 2e 20  erm of $expect. 
5be0: 20 42 6f 74 68 20 24 72 65 73 75 6c 74 20 61 6e   Both $result an
5bf0: 64 20 24 65 78 70 65 63 74 65 64 20 74 65 72 6d  d $expected term
5c00: 73 20 6d 75 73 74 20 62 65 0a 20 20 20 20 20 20  s must be.      
5c10: 20 20 20 20 23 20 6e 75 6d 65 72 69 63 2e 20 20      # numeric.  
5c20: 54 68 65 20 76 61 6c 75 65 73 20 6d 75 73 74 20  The values must 
5c30: 6d 61 74 63 68 20 77 69 74 68 69 6e 20 31 30 25  match within 10%
5c40: 2e 20 20 4f 72 20 69 66 20 24 65 78 70 65 63 74  .  Or if $expect
5c50: 65 64 20 69 73 20 6f 66 20 74 68 65 0a 20 20 20  ed is of the.   
5c60: 20 20 20 20 20 20 20 23 20 66 6f 72 6d 20 41 2e         # form A.
5c70: 2e 42 20 74 68 65 6e 20 74 68 65 20 24 72 65 73  .B then the $res
5c80: 75 6c 74 20 74 65 72 6d 20 6d 75 73 74 20 62 65  ult term must be
5c90: 20 62 65 74 77 65 65 6e 20 41 20 61 6e 64 20 42   between A and B
5ca0: 2e 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20  ..          set 
5cb0: 65 32 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65  e2 [string range
5cc0: 20 24 65 78 70 65 63 74 65 64 20 32 20 65 6e 64   $expected 2 end
5cd0: 2d 31 5d 0a 20 20 20 20 20 20 20 20 20 20 66 6f  -1].          fo
5ce0: 72 65 61 63 68 20 69 20 24 72 65 73 75 6c 74 20  reach i $result 
5cf0: 6a 20 24 65 32 20 7b 0a 20 20 20 20 20 20 20 20  j $e2 {.        
5d00: 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78 70 20      if {[regexp 
5d10: 7b 5e 28 2d 3f 5c 64 2b 29 5c 2e 5c 2e 28 2d 3f  {^(-?\d+)\.\.(-?
5d20: 5c 64 29 24 7d 20 24 6a 20 61 6c 6c 20 41 20 42  \d)$} $j all A B
5d30: 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  ]} {.           
5d40: 20 20 20 73 65 74 20 6f 6b 20 5b 65 78 70 72 20     set ok [expr 
5d50: 7b 24 69 2b 30 3e 3d 24 41 20 26 26 20 24 69 2b  {$i+0>=$A && $i+
5d60: 30 3c 3d 24 42 7d 5d 0a 20 20 20 20 20 20 20 20  0<=$B}].        
5d70: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
5d80: 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20 6f             set o
5d90: 6b 20 5b 65 78 70 72 20 7b 24 69 2b 30 3e 3d 30  k [expr {$i+0>=0
5da0: 2e 39 2a 24 6a 20 26 26 20 24 69 2b 30 3c 3d 31  .9*$j && $i+0<=1
5db0: 2e 31 2a 24 6a 7d 5d 0a 20 20 20 20 20 20 20 20  .1*$j}].        
5dc0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
5dd0: 20 20 69 66 20 7b 21 24 6f 6b 7d 20 62 72 65 61    if {!$ok} brea
5de0: 6b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  k.          }.  
5df0: 20 20 20 20 20 20 20 20 69 66 20 7b 24 6f 6b 20          if {$ok 
5e00: 26 26 20 5b 6c 6c 65 6e 67 74 68 20 24 72 65 73  && [llength $res
5e10: 75 6c 74 5d 21 3d 5b 6c 6c 65 6e 67 74 68 20 24  ult]!=[llength $
5e20: 65 32 5d 7d 20 7b 73 65 74 20 6f 6b 20 30 7d 0a  e2]} {set ok 0}.
5e30: 20 20 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b          } else {
5e40: 0a 20 20 20 20 20 20 20 20 20 20 73 65 74 20 72  .          set r
5e50: 65 20 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20  e [string range 
5e60: 24 65 78 70 65 63 74 65 64 20 31 20 65 6e 64 2d  $expected 1 end-
5e70: 31 5d 0a 20 20 20 20 20 20 20 20 20 20 69 66 20  1].          if 
5e80: 7b 5b 73 74 72 69 6e 67 20 69 6e 64 65 78 20 24  {[string index $
5e90: 72 65 20 30 5d 3d 3d 22 2a 22 7d 20 7b 0a 20 20  re 0]=="*"} {.  
5ea0: 20 20 20 20 20 20 20 20 20 20 23 20 49 66 20 74            # If t
5eb0: 68 65 20 72 65 67 75 6c 61 72 20 65 78 70 72 65  he regular expre
5ec0: 73 73 69 6f 6e 20 62 65 67 69 6e 73 20 77 69 74  ssion begins wit
5ed0: 68 20 2a 20 74 68 65 6e 20 74 72 65 61 74 20 69  h * then treat i
5ee0: 74 20 61 73 20 61 20 67 6c 6f 62 20 69 6e 73 74  t as a glob inst
5ef0: 65 61 64 0a 20 20 20 20 20 20 20 20 20 20 20 20  ead.            
5f00: 73 65 74 20 6f 6b 20 5b 73 74 72 69 6e 67 20 6d  set ok [string m
5f10: 61 74 63 68 20 24 72 65 20 24 72 65 73 75 6c 74  atch $re $result
5f20: 5d 0a 20 20 20 20 20 20 20 20 20 20 7d 20 65 6c  ].          } el
5f30: 73 65 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  se {.           
5f40: 20 73 65 74 20 72 65 20 5b 73 74 72 69 6e 67 20   set re [string 
5f50: 6d 61 70 20 7b 23 20 7b 5b 2d 30 2d 39 2e 5d 2b  map {# {[-0-9.]+
5f60: 7d 7d 20 24 72 65 5d 0a 20 20 20 20 20 20 20 20  }} $re].        
5f70: 20 20 20 20 73 65 74 20 6f 6b 20 5b 72 65 67 65      set ok [rege
5f80: 78 70 20 24 72 65 20 24 72 65 73 75 6c 74 5d 0a  xp $re $result].
5f90: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
5fa0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c      }.      } el
5fb0: 73 65 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e  seif {[regexp {^
5fc0: 7e 3f 5c 2a 2e 2a 5c 2a 24 7d 20 24 65 78 70 65  ~?\*.*\*$} $expe
5fd0: 63 74 65 64 5d 7d 20 7b 0a 20 20 20 20 20 20 20  cted]} {.       
5fe0: 20 23 20 22 65 78 70 65 63 74 65 64 22 20 69 73   # "expected" is
5ff0: 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 22 2a 47   of the form "*G
6000: 4c 4f 42 2a 22 20 74 68 65 6e 20 74 68 65 20 72  LOB*" then the r
6010: 65 73 75 6c 74 20 69 66 20 63 6f 72 72 65 63 74  esult if correct
6020: 20 69 66 0a 20 20 20 20 20 20 20 20 23 20 67 6c   if.        # gl
6030: 6f 62 20 70 61 74 74 65 72 6e 20 47 4c 4f 42 20  ob pattern GLOB 
6040: 6d 61 74 63 68 65 73 20 74 68 65 20 72 65 73 75  matches the resu
6050: 6c 74 2e 20 20 22 7e 2f 47 4c 4f 42 2f 22 20 6d  lt.  "~/GLOB/" m
6060: 65 61 6e 73 0a 20 20 20 20 20 20 20 20 23 20 74  eans.        # t
6070: 68 65 20 67 6c 6f 62 20 6d 75 73 74 20 6e 6f 74  he glob must not
6080: 20 6d 61 74 63 68 2e 0a 20 20 20 20 20 20 20 20   match..        
6090: 69 66 20 7b 5b 73 74 72 69 6e 67 20 69 6e 64 65  if {[string inde
60a0: 78 20 24 65 78 70 65 63 74 65 64 20 30 5d 3d 3d  x $expected 0]==
60b0: 22 7e 22 7d 20 7b 0a 20 20 20 20 20 20 20 20 20  "~"} {.         
60c0: 20 73 65 74 20 65 20 5b 73 74 72 69 6e 67 20 72   set e [string r
60d0: 61 6e 67 65 20 24 65 78 70 65 63 74 65 64 20 31  ange $expected 1
60e0: 20 65 6e 64 5d 0a 20 20 20 20 20 20 20 20 20 20   end].          
60f0: 73 65 74 20 6f 6b 20 5b 65 78 70 72 20 7b 21 5b  set ok [expr {![
6100: 73 74 72 69 6e 67 20 6d 61 74 63 68 20 24 65 20  string match $e 
6110: 24 72 65 73 75 6c 74 5d 7d 5d 0a 20 20 20 20 20  $result]}].     
6120: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
6130: 20 20 20 20 20 20 73 65 74 20 6f 6b 20 5b 73 74        set ok [st
6140: 72 69 6e 67 20 6d 61 74 63 68 20 24 65 78 70 65  ring match $expe
6150: 63 74 65 64 20 24 72 65 73 75 6c 74 5d 0a 20 20  cted $result].  
6160: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 20        }.      } 
6170: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 73  else {.        s
6180: 65 74 20 6f 6b 20 5b 65 78 70 72 20 7b 5b 73 74  et ok [expr {[st
6190: 72 69 6e 67 20 63 6f 6d 70 61 72 65 20 24 72 65  ring compare $re
61a0: 73 75 6c 74 20 24 65 78 70 65 63 74 65 64 5d 3d  sult $expected]=
61b0: 3d 30 7d 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20  =0}].      }.   
61c0: 20 20 20 69 66 20 7b 21 24 6f 6b 7d 20 7b 0a 20     if {!$ok} {. 
61d0: 20 20 20 20 20 20 20 23 20 69 66 20 7b 21 5b 69         # if {![i
61e0: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 74 65 73  nfo exists ::tes
61f0: 74 70 72 65 66 69 78 5d 20 7c 7c 20 24 3a 3a 74  tprefix] || $::t
6200: 65 73 74 70 72 65 66 69 78 20 65 71 20 22 22 7d  estprefix eq ""}
6210: 20 7b 0a 20 20 20 20 20 20 20 20 23 20 20 20 65   {.        #   e
6220: 72 72 6f 72 20 22 6e 6f 20 74 65 73 74 20 70 72  rror "no test pr
6230: 65 66 69 78 22 0a 20 20 20 20 20 20 20 20 23 20  efix".        # 
6240: 7d 0a 20 20 20 20 20 20 20 20 6f 75 74 70 75 74  }.        output
6250: 31 20 22 22 0a 20 20 20 20 20 20 20 20 6f 75 74  1 "".        out
6260: 70 75 74 32 20 22 21 20 24 6e 61 6d 65 20 65 78  put2 "! $name ex
6270: 70 65 63 74 65 64 3a 20 5c 5b 24 65 78 70 65 63  pected: \[$expec
6280: 74 65 64 5c 5d 5c 6e 21 20 24 6e 61 6d 65 20 67  ted\]\n! $name g
6290: 6f 74 3a 20 20 20 20 20 20 5c 5b 24 72 65 73 75  ot:      \[$resu
62a0: 6c 74 5c 5d 22 0a 20 20 20 20 20 20 20 20 66 61  lt\]".        fa
62b0: 69 6c 5f 74 65 73 74 20 24 6e 61 6d 65 0a 20 20  il_test $name.  
62c0: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
62d0: 20 20 20 20 20 6f 75 74 70 75 74 31 20 22 20 4f       output1 " O
62e0: 6b 22 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k".      }.    }
62f0: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
6300: 6f 75 74 70 75 74 31 20 22 20 4f 6d 69 74 74 65  output1 " Omitte
6310: 64 22 0a 20 20 20 20 6f 6d 69 74 5f 74 65 73 74  d".    omit_test
6320: 20 24 6e 61 6d 65 20 22 70 61 74 74 65 72 6e 20   $name "pattern 
6330: 6d 69 73 6d 61 74 63 68 22 20 30 0a 20 20 7d 0a  mismatch" 0.  }.
6340: 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74 0a 7d    flush stdout.}
6350: 0a 0a 70 72 6f 63 20 64 75 6d 70 62 79 74 65 73  ..proc dumpbytes
6360: 20 7b 73 7d 20 7b 0a 20 20 73 65 74 20 72 20 22   {s} {.  set r "
6370: 22 0a 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30  ".  for {set i 0
6380: 7d 20 7b 24 69 20 3c 20 5b 73 74 72 69 6e 67 20  } {$i < [string 
6390: 6c 65 6e 67 74 68 20 24 73 5d 7d 20 7b 69 6e 63  length $s]} {inc
63a0: 72 20 69 7d 20 7b 0a 20 20 20 20 69 66 20 7b 24  r i} {.    if {$
63b0: 69 20 3e 20 30 7d 20 7b 61 70 70 65 6e 64 20 72  i > 0} {append r
63c0: 20 22 20 22 7d 0a 20 20 20 20 61 70 70 65 6e 64   " "}.    append
63d0: 20 72 20 5b 66 6f 72 6d 61 74 20 25 30 32 58 20   r [format %02X 
63e0: 5b 73 63 61 6e 20 5b 73 74 72 69 6e 67 20 69 6e  [scan [string in
63f0: 64 65 78 20 24 73 20 24 69 5d 20 25 63 5d 5d 0a  dex $s $i] %c]].
6400: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 0a    }.  return $r.
6410: 7d 0a 0a 70 72 6f 63 20 63 61 74 63 68 63 6d 64  }..proc catchcmd
6420: 20 7b 64 62 20 7b 63 6d 64 20 22 22 7d 7d 20 7b   {db {cmd ""}} {
6430: 0a 20 20 67 6c 6f 62 61 6c 20 43 4c 49 0a 20 20  .  global CLI.  
6440: 73 65 74 20 6f 75 74 20 5b 6f 70 65 6e 20 63 6d  set out [open cm
6450: 64 73 2e 74 78 74 20 77 5d 0a 20 20 70 75 74 73  ds.txt w].  puts
6460: 20 24 6f 75 74 20 24 63 6d 64 0a 20 20 63 6c 6f   $out $cmd.  clo
6470: 73 65 20 24 6f 75 74 0a 20 20 73 65 74 20 6c 69  se $out.  set li
6480: 6e 65 20 22 65 78 65 63 20 24 43 4c 49 20 24 64  ne "exec $CLI $d
6490: 62 20 3c 20 63 6d 64 73 2e 74 78 74 22 0a 20 20  b < cmds.txt".  
64a0: 73 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b 20  set rc [catch { 
64b0: 65 76 61 6c 20 24 6c 69 6e 65 20 7d 20 6d 73 67  eval $line } msg
64c0: 5d 0a 20 20 6c 69 73 74 20 24 72 63 20 24 6d 73  ].  list $rc $ms
64d0: 67 0a 7d 0a 0a 70 72 6f 63 20 63 61 74 63 68 63  g.}..proc catchc
64e0: 6d 64 65 78 20 7b 64 62 20 7b 63 6d 64 20 22 22  mdex {db {cmd ""
64f0: 7d 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 43 4c  }} {.  global CL
6500: 49 0a 20 20 73 65 74 20 6f 75 74 20 5b 6f 70 65  I.  set out [ope
6510: 6e 20 63 6d 64 73 2e 74 78 74 20 77 5d 0a 20 20  n cmds.txt w].  
6520: 66 63 6f 6e 66 69 67 75 72 65 20 24 6f 75 74 20  fconfigure $out 
6530: 2d 65 6e 63 6f 64 69 6e 67 20 62 69 6e 61 72 79  -encoding binary
6540: 20 2d 74 72 61 6e 73 6c 61 74 69 6f 6e 20 62 69   -translation bi
6550: 6e 61 72 79 0a 20 20 70 75 74 73 20 2d 6e 6f 6e  nary.  puts -non
6560: 65 77 6c 69 6e 65 20 24 6f 75 74 20 24 63 6d 64  ewline $out $cmd
6570: 0a 20 20 63 6c 6f 73 65 20 24 6f 75 74 0a 20 20  .  close $out.  
6580: 73 65 74 20 6c 69 6e 65 20 22 65 78 65 63 20 2d  set line "exec -
6590: 6b 65 65 70 6e 65 77 6c 69 6e 65 20 2d 2d 20 24  keepnewline -- $
65a0: 43 4c 49 20 24 64 62 20 3c 20 63 6d 64 73 2e 74  CLI $db < cmds.t
65b0: 78 74 22 0a 20 20 73 65 74 20 63 68 61 6e 73 20  xt".  set chans 
65c0: 5b 6c 69 73 74 20 73 74 64 69 6e 20 73 74 64 6f  [list stdin stdo
65d0: 75 74 20 73 74 64 65 72 72 5d 0a 20 20 66 6f 72  ut stderr].  for
65e0: 65 61 63 68 20 63 68 61 6e 20 24 63 68 61 6e 73  each chan $chans
65f0: 20 7b 0a 20 20 20 20 63 61 74 63 68 20 7b 0a 20   {.    catch {. 
6600: 20 20 20 20 20 73 65 74 20 6d 6f 64 65 73 28 24       set modes($
6610: 63 68 61 6e 29 20 5b 66 63 6f 6e 66 69 67 75 72  chan) [fconfigur
6620: 65 20 24 63 68 61 6e 5d 0a 20 20 20 20 20 20 66  e $chan].      f
6630: 63 6f 6e 66 69 67 75 72 65 20 24 63 68 61 6e 20  configure $chan 
6640: 2d 65 6e 63 6f 64 69 6e 67 20 62 69 6e 61 72 79  -encoding binary
6650: 20 2d 74 72 61 6e 73 6c 61 74 69 6f 6e 20 62 69   -translation bi
6660: 6e 61 72 79 20 2d 62 75 66 66 65 72 69 6e 67 20  nary -buffering 
6670: 6e 6f 6e 65 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  none.    }.  }. 
6680: 20 73 65 74 20 72 63 20 5b 63 61 74 63 68 20 7b   set rc [catch {
6690: 20 65 76 61 6c 20 24 6c 69 6e 65 20 7d 20 6d 73   eval $line } ms
66a0: 67 5d 0a 20 20 66 6f 72 65 61 63 68 20 63 68 61  g].  foreach cha
66b0: 6e 20 24 63 68 61 6e 73 20 7b 0a 20 20 20 20 63  n $chans {.    c
66c0: 61 74 63 68 20 7b 0a 20 20 20 20 20 20 65 76 61  atch {.      eva
66d0: 6c 20 66 63 6f 6e 66 69 67 75 72 65 20 5b 6c 69  l fconfigure [li
66e0: 73 74 20 24 63 68 61 6e 5d 20 24 6d 6f 64 65 73  st $chan] $modes
66f0: 28 24 63 68 61 6e 29 0a 20 20 20 20 7d 0a 20 20  ($chan).    }.  
6700: 7d 0a 20 20 23 20 70 75 74 73 20 5b 64 75 6d 70  }.  # puts [dump
6710: 62 79 74 65 73 20 24 6d 73 67 5d 0a 20 20 6c 69  bytes $msg].  li
6720: 73 74 20 24 72 63 20 24 6d 73 67 0a 7d 0a 0a 70  st $rc $msg.}..p
6730: 72 6f 63 20 66 69 6c 65 70 61 74 68 5f 6e 6f 72  roc filepath_nor
6740: 6d 61 6c 69 7a 65 20 7b 70 7d 20 7b 0a 20 20 23  malize {p} {.  #
6750: 20 74 65 73 74 20 63 61 73 65 73 20 73 68 6f 75   test cases shou
6760: 6c 64 20 62 65 20 77 72 69 74 74 65 6e 20 74 6f  ld be written to
6770: 20 61 73 73 75 6d 65 20 22 75 6e 69 78 22 2d 6c   assume "unix"-l
6780: 69 6b 65 20 66 69 6c 65 20 70 61 74 68 73 0a 20  ike file paths. 
6790: 20 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74   if {$::tcl_plat
67a0: 66 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 21 3d  form(platform)!=
67b0: 22 75 6e 69 78 22 7d 20 7b 0a 20 20 20 20 23 20  "unix"} {.    # 
67c0: 6c 72 65 76 65 72 73 65 2a 32 20 61 73 20 61 20  lreverse*2 as a 
67d0: 68 61 63 6b 20 74 6f 20 72 65 6d 6f 76 65 20 61  hack to remove a
67e0: 6e 79 20 75 6e 6e 65 65 64 65 64 20 7b 7d 20 61  ny unneeded {} a
67f0: 66 74 65 72 20 74 68 65 20 73 74 72 69 6e 67 20  fter the string 
6800: 6d 61 70 0a 20 20 20 20 6c 72 65 76 65 72 73 65  map.    lreverse
6810: 20 5b 6c 72 65 76 65 72 73 65 20 5b 73 74 72 69   [lreverse [stri
6820: 6e 67 20 6d 61 70 20 7b 5c 5c 20 2f 7d 20 5b 72  ng map {\\ /} [r
6830: 65 67 73 75 62 20 2d 6e 6f 63 61 73 65 20 2d 61  egsub -nocase -a
6840: 6c 6c 20 7b 5b 61 2d 7a 5d 3a 5b 2f 5c 5c 5d 2b  ll {[a-z]:[/\\]+
6850: 7d 20 24 70 20 7b 2f 7d 5d 5d 5d 0a 20 20 7d 20  } $p {/}]]].  } 
6860: 7b 0a 20 20 20 20 73 65 74 20 70 0a 20 20 7d 0a  {.    set p.  }.
6870: 7d 0a 70 72 6f 63 20 64 6f 5f 66 69 6c 65 70 61  }.proc do_filepa
6880: 74 68 5f 74 65 73 74 20 7b 6e 61 6d 65 20 63 6d  th_test {name cm
6890: 64 20 65 78 70 65 63 74 65 64 7d 20 7b 0a 20 20  d expected} {.  
68a0: 75 70 6c 65 76 65 6c 20 5b 6c 69 73 74 20 64 6f  uplevel [list do
68b0: 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b 0a 20 20  _test $name [.  
68c0: 20 20 73 75 62 73 74 20 2d 6e 6f 63 6f 6d 6d 61    subst -nocomma
68d0: 6e 64 73 20 7b 20 66 69 6c 65 70 61 74 68 5f 6e  nds { filepath_n
68e0: 6f 72 6d 61 6c 69 7a 65 20 5b 20 24 63 6d 64 20  ormalize [ $cmd 
68f0: 5d 20 7d 0a 20 20 5d 20 5b 66 69 6c 65 70 61 74  ] }.  ] [filepat
6900: 68 5f 6e 6f 72 6d 61 6c 69 7a 65 20 24 65 78 70  h_normalize $exp
6910: 65 63 74 65 64 5d 5d 0a 7d 0a 0a 70 72 6f 63 20  ected]].}..proc 
6920: 72 65 61 6c 6e 75 6d 5f 6e 6f 72 6d 61 6c 69 7a  realnum_normaliz
6930: 65 20 7b 72 7d 20 7b 0a 20 20 23 20 64 69 66 66  e {r} {.  # diff
6940: 65 72 65 6e 74 20 54 43 4c 20 76 65 72 73 69 6f  erent TCL versio
6950: 6e 73 20 64 69 73 70 6c 61 79 20 66 6c 6f 61 74  ns display float
6960: 69 6e 67 20 70 6f 69 6e 74 20 76 61 6c 75 65 73  ing point values
6970: 20 64 69 66 66 65 72 65 6e 74 6c 79 2e 0a 20 20   differently..  
6980: 73 74 72 69 6e 67 20 6d 61 70 20 7b 31 2e 23 49  string map {1.#I
6990: 4e 46 20 69 6e 66 20 49 6e 66 20 69 6e 66 20 2e  NF inf Inf inf .
69a0: 30 65 20 65 7d 20 5b 72 65 67 73 75 62 20 2d 61  0e e} [regsub -a
69b0: 6c 6c 20 7b 28 65 5b 2b 2d 5d 29 30 2b 7d 20 24  ll {(e[+-])0+} $
69c0: 72 20 7b 5c 31 7d 5d 0a 7d 0a 70 72 6f 63 20 64  r {\1}].}.proc d
69d0: 6f 5f 72 65 61 6c 6e 75 6d 5f 74 65 73 74 20 7b  o_realnum_test {
69e0: 6e 61 6d 65 20 63 6d 64 20 65 78 70 65 63 74 65  name cmd expecte
69f0: 64 7d 20 7b 0a 20 20 75 70 6c 65 76 65 6c 20 5b  d} {.  uplevel [
6a00: 6c 69 73 74 20 64 6f 5f 74 65 73 74 20 24 6e 61  list do_test $na
6a10: 6d 65 20 5b 0a 20 20 20 20 73 75 62 73 74 20 2d  me [.    subst -
6a20: 6e 6f 63 6f 6d 6d 61 6e 64 73 20 7b 20 72 65 61  nocommands { rea
6a30: 6c 6e 75 6d 5f 6e 6f 72 6d 61 6c 69 7a 65 20 5b  lnum_normalize [
6a40: 20 24 63 6d 64 20 5d 20 7d 0a 20 20 5d 20 5b 72   $cmd ] }.  ] [r
6a50: 65 61 6c 6e 75 6d 5f 6e 6f 72 6d 61 6c 69 7a 65  ealnum_normalize
6a60: 20 24 65 78 70 65 63 74 65 64 5d 5d 0a 7d 0a 0a   $expected]].}..
6a70: 70 72 6f 63 20 66 69 78 5f 74 65 73 74 6e 61 6d  proc fix_testnam
6a80: 65 20 7b 76 61 72 6e 61 6d 65 7d 20 7b 0a 20 20  e {varname} {.  
6a90: 75 70 76 61 72 20 24 76 61 72 6e 61 6d 65 20 74  upvar $varname t
6aa0: 65 73 74 6e 61 6d 65 0a 20 20 69 66 20 7b 5b 69  estname.  if {[i
6ab0: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 74 65 73  nfo exists ::tes
6ac0: 74 70 72 65 66 69 78 5d 0a 20 20 20 26 26 20 5b  tprefix].   && [
6ad0: 73 74 72 69 6e 67 20 69 73 20 64 69 67 69 74 20  string is digit 
6ae0: 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 74  [string range $t
6af0: 65 73 74 6e 61 6d 65 20 30 20 30 5d 5d 0a 20 20  estname 0 0]].  
6b00: 7d 20 7b 0a 20 20 20 20 73 65 74 20 74 65 73 74  } {.    set test
6b10: 6e 61 6d 65 20 22 24 7b 3a 3a 74 65 73 74 70 72  name "${::testpr
6b20: 65 66 69 78 7d 2d 24 74 65 73 74 6e 61 6d 65 22  efix}-$testname"
6b30: 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 6e 6f 72  .  }.}..proc nor
6b40: 6d 61 6c 69 7a 65 5f 6c 69 73 74 20 7b 4c 7d 20  malize_list {L} 
6b50: 7b 0a 20 20 73 65 74 20 4c 32 20 5b 6c 69 73 74  {.  set L2 [list
6b60: 5d 0a 20 20 66 6f 72 65 61 63 68 20 6c 20 24 4c  ].  foreach l $L
6b70: 20 7b 6c 61 70 70 65 6e 64 20 4c 32 20 24 6c 7d   {lappend L2 $l}
6b80: 0a 20 20 73 65 74 20 4c 32 0a 7d 0a 0a 70 72 6f  .  set L2.}..pro
6b90: 63 20 64 6f 5f 65 78 65 63 73 71 6c 5f 74 65 73  c do_execsql_tes
6ba0: 74 20 7b 74 65 73 74 6e 61 6d 65 20 73 71 6c 20  t {testname sql 
6bb0: 7b 72 65 73 75 6c 74 20 7b 7d 7d 7d 20 7b 0a 20  {result {}}} {. 
6bc0: 20 66 69 78 5f 74 65 73 74 6e 61 6d 65 20 74 65   fix_testname te
6bd0: 73 74 6e 61 6d 65 0a 20 20 75 70 6c 65 76 65 6c  stname.  uplevel
6be0: 20 64 6f 5f 74 65 73 74 20 5b 6c 69 73 74 20 24   do_test [list $
6bf0: 74 65 73 74 6e 61 6d 65 5d 20 5b 6c 69 73 74 20  testname] [list 
6c00: 22 65 78 65 63 73 71 6c 20 7b 24 73 71 6c 7d 22  "execsql {$sql}"
6c10: 5d 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20 7b 2a  ] [list [list {*
6c20: 7d 24 72 65 73 75 6c 74 5d 5d 0a 7d 0a 70 72 6f  }$result]].}.pro
6c30: 63 20 64 6f 5f 63 61 74 63 68 73 71 6c 5f 74 65  c do_catchsql_te
6c40: 73 74 20 7b 74 65 73 74 6e 61 6d 65 20 73 71 6c  st {testname sql
6c50: 20 72 65 73 75 6c 74 7d 20 7b 0a 20 20 66 69 78   result} {.  fix
6c60: 5f 74 65 73 74 6e 61 6d 65 20 74 65 73 74 6e 61  _testname testna
6c70: 6d 65 0a 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f  me.  uplevel do_
6c80: 74 65 73 74 20 5b 6c 69 73 74 20 24 74 65 73 74  test [list $test
6c90: 6e 61 6d 65 5d 20 5b 6c 69 73 74 20 22 63 61 74  name] [list "cat
6ca0: 63 68 73 71 6c 20 7b 24 73 71 6c 7d 22 5d 20 5b  chsql {$sql}"] [
6cb0: 6c 69 73 74 20 24 72 65 73 75 6c 74 5d 0a 7d 0a  list $result].}.
6cc0: 70 72 6f 63 20 64 6f 5f 74 69 6d 65 64 5f 65 78  proc do_timed_ex
6cd0: 65 63 73 71 6c 5f 74 65 73 74 20 7b 74 65 73 74  ecsql_test {test
6ce0: 6e 61 6d 65 20 73 71 6c 20 7b 72 65 73 75 6c 74  name sql {result
6cf0: 20 7b 7d 7d 7d 20 7b 0a 20 20 66 69 78 5f 74 65   {}}} {.  fix_te
6d00: 73 74 6e 61 6d 65 20 74 65 73 74 6e 61 6d 65 0a  stname testname.
6d10: 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73    uplevel do_tes
6d20: 74 20 5b 6c 69 73 74 20 24 74 65 73 74 6e 61 6d  t [list $testnam
6d30: 65 5d 20 5b 6c 69 73 74 20 22 65 78 65 63 73 71  e] [list "execsq
6d40: 6c 5f 74 69 6d 65 64 20 7b 24 73 71 6c 7d 22 5d  l_timed {$sql}"]
6d50: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  \.              
6d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d70: 20 20 20 20 20 5b 6c 69 73 74 20 5b 6c 69 73 74       [list [list
6d80: 20 7b 2a 7d 24 72 65 73 75 6c 74 5d 5d 0a 7d 0a   {*}$result]].}.
6d90: 70 72 6f 63 20 64 6f 5f 65 71 70 5f 74 65 73 74  proc do_eqp_test
6da0: 20 7b 6e 61 6d 65 20 73 71 6c 20 72 65 73 7d 20   {name sql res} 
6db0: 7b 0a 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 65  {.  uplevel do_e
6dc0: 78 65 63 73 71 6c 5f 74 65 73 74 20 24 6e 61 6d  xecsql_test $nam
6dd0: 65 20 5b 6c 69 73 74 20 22 45 58 50 4c 41 49 4e  e [list "EXPLAIN
6de0: 20 51 55 45 52 59 20 50 4c 41 4e 20 24 73 71 6c   QUERY PLAN $sql
6df0: 22 5d 20 5b 6c 69 73 74 20 24 72 65 73 5d 0a 7d  "] [list $res].}
6e00: 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..#-------------
6e10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6e20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6e30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
6e40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 20  ------------.#  
6e50: 20 55 73 61 67 65 3a 20 64 6f 5f 73 65 6c 65 63   Usage: do_selec
6e60: 74 5f 74 65 73 74 73 20 50 52 45 46 49 58 20 3f  t_tests PREFIX ?
6e70: 53 57 49 54 43 48 45 53 3f 20 54 45 53 54 4c 49  SWITCHES? TESTLI
6e80: 53 54 0a 23 0a 23 20 57 68 65 72 65 20 73 77 69  ST.#.# Where swi
6e90: 74 63 68 65 73 20 61 72 65 3a 0a 23 0a 23 20 20  tches are:.#.#  
6ea0: 20 2d 65 72 72 6f 72 66 6f 72 6d 61 74 20 46 4d   -errorformat FM
6eb0: 54 53 54 52 49 4e 47 0a 23 20 20 20 2d 63 6f 75  TSTRING.#   -cou
6ec0: 6e 74 0a 23 20 20 20 2d 71 75 65 72 79 20 53 51  nt.#   -query SQ
6ed0: 4c 0a 23 20 20 20 2d 74 63 6c 71 75 65 72 79 20  L.#   -tclquery 
6ee0: 54 43 4c 0a 23 20 20 20 2d 72 65 70 61 69 72 20  TCL.#   -repair 
6ef0: 54 43 4c 0a 23 0a 70 72 6f 63 20 64 6f 5f 73 65  TCL.#.proc do_se
6f00: 6c 65 63 74 5f 74 65 73 74 73 20 7b 70 72 65 66  lect_tests {pref
6f10: 69 78 20 61 72 67 73 7d 20 7b 0a 0a 20 20 73 65  ix args} {..  se
6f20: 74 20 74 65 73 74 6c 69 73 74 20 5b 6c 69 6e 64  t testlist [lind
6f30: 65 78 20 24 61 72 67 73 20 65 6e 64 5d 0a 20 20  ex $args end].  
6f40: 73 65 74 20 73 77 69 74 63 68 65 73 20 5b 6c 72  set switches [lr
6f50: 61 6e 67 65 20 24 61 72 67 73 20 30 20 65 6e 64  ange $args 0 end
6f60: 2d 31 5d 0a 0a 20 20 73 65 74 20 65 72 72 66 6d  -1]..  set errfm
6f70: 74 20 22 22 0a 20 20 73 65 74 20 63 6f 75 6e 74  t "".  set count
6f80: 6f 6e 6c 79 20 30 0a 20 20 73 65 74 20 74 63 6c  only 0.  set tcl
6f90: 71 75 65 72 79 20 22 22 0a 20 20 73 65 74 20 72  query "".  set r
6fa0: 65 70 61 69 72 20 22 22 0a 0a 20 20 66 6f 72 20  epair ""..  for 
6fb0: 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20  {set i 0} {$i < 
6fc0: 5b 6c 6c 65 6e 67 74 68 20 24 73 77 69 74 63 68  [llength $switch
6fd0: 65 73 5d 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a  es]} {incr i} {.
6fe0: 20 20 20 20 73 65 74 20 73 20 5b 6c 69 6e 64 65      set s [linde
6ff0: 78 20 24 73 77 69 74 63 68 65 73 20 24 69 5d 0a  x $switches $i].
7000: 20 20 20 20 73 65 74 20 6e 20 5b 73 74 72 69 6e      set n [strin
7010: 67 20 6c 65 6e 67 74 68 20 24 73 5d 0a 20 20 20  g length $s].   
7020: 20 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73   if {$n>=2 && [s
7030: 74 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e  tring equal -len
7040: 67 74 68 20 24 6e 20 24 73 20 22 2d 71 75 65 72  gth $n $s "-quer
7050: 79 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  y"]} {.      set
7060: 20 74 63 6c 71 75 65 72 79 20 5b 6c 69 73 74 20   tclquery [list 
7070: 65 78 65 63 73 71 6c 20 5b 6c 69 6e 64 65 78 20  execsql [lindex 
7080: 24 73 77 69 74 63 68 65 73 20 5b 69 6e 63 72 20  $switches [incr 
7090: 69 5d 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69  i]]].    } elsei
70a0: 66 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73 74 72  f {$n>=2 && [str
70b0: 69 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e 67 74  ing equal -lengt
70c0: 68 20 24 6e 20 24 73 20 22 2d 74 63 6c 71 75 65  h $n $s "-tclque
70d0: 72 79 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65  ry"]} {.      se
70e0: 74 20 74 63 6c 71 75 65 72 79 20 5b 6c 69 6e 64  t tclquery [lind
70f0: 65 78 20 24 73 77 69 74 63 68 65 73 20 5b 69 6e  ex $switches [in
7100: 63 72 20 69 5d 5d 0a 20 20 20 20 7d 20 65 6c 73  cr i]].    } els
7110: 65 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20 5b 73  eif {$n>=2 && [s
7120: 74 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c 65 6e  tring equal -len
7130: 67 74 68 20 24 6e 20 24 73 20 22 2d 65 72 72 6f  gth $n $s "-erro
7140: 72 66 6f 72 6d 61 74 22 5d 7d 20 7b 0a 20 20 20  rformat"]} {.   
7150: 20 20 20 73 65 74 20 65 72 72 66 6d 74 20 5b 6c     set errfmt [l
7160: 69 6e 64 65 78 20 24 73 77 69 74 63 68 65 73 20  index $switches 
7170: 5b 69 6e 63 72 20 69 5d 5d 0a 20 20 20 20 7d 20  [incr i]].    } 
7180: 65 6c 73 65 69 66 20 7b 24 6e 3e 3d 32 20 26 26  elseif {$n>=2 &&
7190: 20 5b 73 74 72 69 6e 67 20 65 71 75 61 6c 20 2d   [string equal -
71a0: 6c 65 6e 67 74 68 20 24 6e 20 24 73 20 22 2d 72  length $n $s "-r
71b0: 65 70 61 69 72 22 5d 7d 20 7b 0a 20 20 20 20 20  epair"]} {.     
71c0: 20 73 65 74 20 72 65 70 61 69 72 20 5b 6c 69 6e   set repair [lin
71d0: 64 65 78 20 24 73 77 69 74 63 68 65 73 20 5b 69  dex $switches [i
71e0: 6e 63 72 20 69 5d 5d 0a 20 20 20 20 7d 20 65 6c  ncr i]].    } el
71f0: 73 65 69 66 20 7b 24 6e 3e 3d 32 20 26 26 20 5b  seif {$n>=2 && [
7200: 73 74 72 69 6e 67 20 65 71 75 61 6c 20 2d 6c 65  string equal -le
7210: 6e 67 74 68 20 24 6e 20 24 73 20 22 2d 63 6f 75  ngth $n $s "-cou
7220: 6e 74 22 5d 7d 20 7b 0a 20 20 20 20 20 20 73 65  nt"]} {.      se
7230: 74 20 63 6f 75 6e 74 6f 6e 6c 79 20 31 0a 20 20  t countonly 1.  
7240: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
7250: 20 65 72 72 6f 72 20 22 75 6e 6b 6e 6f 77 6e 20   error "unknown 
7260: 73 77 69 74 63 68 3a 20 24 73 22 0a 20 20 20 20  switch: $s".    
7270: 7d 0a 20 20 7d 0a 0a 20 20 69 66 20 7b 24 63 6f  }.  }..  if {$co
7280: 75 6e 74 6f 6e 6c 79 20 26 26 20 24 65 72 72 66  untonly && $errf
7290: 6d 74 21 3d 22 22 7d 20 7b 0a 20 20 20 20 65 72  mt!=""} {.    er
72a0: 72 6f 72 20 22 43 61 6e 6e 6f 74 20 75 73 65 20  ror "Cannot use 
72b0: 2d 63 6f 75 6e 74 20 61 6e 64 20 2d 65 72 72 6f  -count and -erro
72c0: 72 66 6f 72 6d 61 74 20 74 6f 67 65 74 68 65 72  rformat together
72d0: 22 0a 20 20 7d 0a 20 20 73 65 74 20 6e 54 65 73  ".  }.  set nTes
72e0: 74 6c 69 73 74 20 5b 6c 6c 65 6e 67 74 68 20 24  tlist [llength $
72f0: 74 65 73 74 6c 69 73 74 5d 0a 20 20 69 66 20 7b  testlist].  if {
7300: 24 6e 54 65 73 74 6c 69 73 74 25 33 20 7c 7c 20  $nTestlist%3 || 
7310: 24 6e 54 65 73 74 6c 69 73 74 3d 3d 30 20 7d 20  $nTestlist==0 } 
7320: 7b 0a 20 20 20 20 65 72 72 6f 72 20 22 53 45 4c  {.    error "SEL
7330: 45 43 54 20 74 65 73 74 20 6c 69 73 74 20 63 6f  ECT test list co
7340: 6e 74 61 69 6e 73 20 5b 6c 6c 65 6e 67 74 68 20  ntains [llength 
7350: 24 74 65 73 74 6c 69 73 74 5d 20 65 6c 65 6d 65  $testlist] eleme
7360: 6e 74 73 22 0a 20 20 7d 0a 0a 20 20 65 76 61 6c  nts".  }..  eval
7370: 20 24 72 65 70 61 69 72 0a 20 20 66 6f 72 65 61   $repair.  forea
7380: 63 68 20 7b 74 6e 20 73 71 6c 20 72 65 73 7d 20  ch {tn sql res} 
7390: 24 74 65 73 74 6c 69 73 74 20 7b 0a 20 20 20 20  $testlist {.    
73a0: 69 66 20 7b 24 74 63 6c 71 75 65 72 79 20 21 3d  if {$tclquery !=
73b0: 20 22 22 7d 20 7b 0a 20 20 20 20 20 20 65 78 65   ""} {.      exe
73c0: 63 73 71 6c 20 24 73 71 6c 0a 20 20 20 20 20 20  csql $sql.      
73d0: 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74 20  uplevel do_test 
73e0: 24 7b 70 72 65 66 69 78 7d 2e 24 74 6e 20 5b 6c  ${prefix}.$tn [l
73f0: 69 73 74 20 24 74 63 6c 71 75 65 72 79 5d 20 5b  ist $tclquery] [
7400: 6c 69 73 74 20 5b 6c 69 73 74 20 7b 2a 7d 24 72  list [list {*}$r
7410: 65 73 5d 5d 0a 20 20 20 20 7d 20 65 6c 73 65 69  es]].    } elsei
7420: 66 20 7b 24 63 6f 75 6e 74 6f 6e 6c 79 7d 20 7b  f {$countonly} {
7430: 0a 20 20 20 20 20 20 73 65 74 20 6e 52 6f 77 20  .      set nRow 
7440: 30 0a 20 20 20 20 20 20 64 62 20 65 76 61 6c 20  0.      db eval 
7450: 24 73 71 6c 20 7b 69 6e 63 72 20 6e 52 6f 77 7d  $sql {incr nRow}
7460: 0a 20 20 20 20 20 20 75 70 6c 65 76 65 6c 20 64  .      uplevel d
7470: 6f 5f 74 65 73 74 20 24 7b 70 72 65 66 69 78 7d  o_test ${prefix}
7480: 2e 24 74 6e 20 5b 6c 69 73 74 20 5b 6c 69 73 74  .$tn [list [list
7490: 20 73 65 74 20 7b 7d 20 24 6e 52 6f 77 5d 5d 20   set {} $nRow]] 
74a0: 5b 6c 69 73 74 20 24 72 65 73 5d 0a 20 20 20 20  [list $res].    
74b0: 7d 20 65 6c 73 65 69 66 20 7b 24 65 72 72 66 6d  } elseif {$errfm
74c0: 74 3d 3d 22 22 7d 20 7b 0a 20 20 20 20 20 20 75  t==""} {.      u
74d0: 70 6c 65 76 65 6c 20 64 6f 5f 65 78 65 63 73 71  plevel do_execsq
74e0: 6c 5f 74 65 73 74 20 24 7b 70 72 65 66 69 78 7d  l_test ${prefix}
74f0: 2e 24 7b 74 6e 7d 20 5b 6c 69 73 74 20 24 73 71  .${tn} [list $sq
7500: 6c 5d 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20 7b  l] [list [list {
7510: 2a 7d 24 72 65 73 5d 5d 0a 20 20 20 20 7d 20 65  *}$res]].    } e
7520: 6c 73 65 20 7b 0a 20 20 20 20 20 20 73 65 74 20  lse {.      set 
7530: 72 65 73 20 5b 6c 69 73 74 20 31 20 5b 73 74 72  res [list 1 [str
7540: 69 6e 67 20 74 72 69 6d 20 5b 66 6f 72 6d 61 74  ing trim [format
7550: 20 24 65 72 72 66 6d 74 20 7b 2a 7d 24 72 65 73   $errfmt {*}$res
7560: 5d 5d 5d 0a 20 20 20 20 20 20 75 70 6c 65 76 65  ]]].      upleve
7570: 6c 20 64 6f 5f 63 61 74 63 68 73 71 6c 5f 74 65  l do_catchsql_te
7580: 73 74 20 24 7b 70 72 65 66 69 78 7d 2e 24 7b 74  st ${prefix}.${t
7590: 6e 7d 20 5b 6c 69 73 74 20 24 73 71 6c 5d 20 5b  n} [list $sql] [
75a0: 6c 69 73 74 20 24 72 65 73 5d 0a 20 20 20 20 7d  list $res].    }
75b0: 0a 20 20 20 20 65 76 61 6c 20 24 72 65 70 61 69  .    eval $repai
75c0: 72 0a 20 20 7d 0a 0a 7d 0a 0a 70 72 6f 63 20 64  r.  }..}..proc d
75d0: 65 6c 65 74 65 5f 61 6c 6c 5f 64 61 74 61 20 7b  elete_all_data {
75e0: 7d 20 7b 0a 20 20 64 62 20 65 76 61 6c 20 7b 53  } {.  db eval {S
75f0: 45 4c 45 43 54 20 74 62 6c 5f 6e 61 6d 65 20 41  ELECT tbl_name A
7600: 53 20 74 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f  S t FROM sqlite_
7610: 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70  master WHERE typ
7620: 65 20 3d 20 27 74 61 62 6c 65 27 7d 20 7b 0a 20  e = 'table'} {. 
7630: 20 20 20 64 62 20 65 76 61 6c 20 22 44 45 4c 45     db eval "DELE
7640: 54 45 20 46 52 4f 4d 20 27 5b 73 74 72 69 6e 67  TE FROM '[string
7650: 20 6d 61 70 20 7b 27 20 27 27 7d 20 24 74 5d 27   map {' ''} $t]'
7660: 22 0a 20 20 7d 0a 7d 0a 0a 23 20 52 75 6e 20 61  ".  }.}..# Run a
7670: 6e 20 53 51 4c 20 73 63 72 69 70 74 2e 0a 23 20  n SQL script..# 
7680: 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65  Return the numbe
7690: 72 20 6f 66 20 6d 69 63 72 6f 73 65 63 6f 6e 64  r of microsecond
76a0: 73 20 70 65 72 20 73 74 61 74 65 6d 65 6e 74 2e  s per statement.
76b0: 0a 23 0a 70 72 6f 63 20 73 70 65 65 64 5f 74 72  .#.proc speed_tr
76c0: 69 61 6c 20 7b 6e 61 6d 65 20 6e 75 6d 73 74 6d  ial {name numstm
76d0: 74 20 75 6e 69 74 73 20 73 71 6c 7d 20 7b 0a 20  t units sql} {. 
76e0: 20 6f 75 74 70 75 74 32 20 2d 6e 6f 6e 65 77 6c   output2 -nonewl
76f0: 69 6e 65 20 5b 66 6f 72 6d 61 74 20 7b 25 2d 32  ine [format {%-2
7700: 31 2e 32 31 73 20 7d 20 24 6e 61 6d 65 2e 2e 2e  1.21s } $name...
7710: 5d 0a 20 20 66 6c 75 73 68 20 73 74 64 6f 75 74  ].  flush stdout
7720: 0a 20 20 73 65 74 20 73 70 65 65 64 20 5b 74 69  .  set speed [ti
7730: 6d 65 20 7b 73 71 6c 69 74 65 33 5f 65 78 65 63  me {sqlite3_exec
7740: 5f 6e 72 20 64 62 20 24 73 71 6c 7d 5d 0a 20 20  _nr db $sql}].  
7750: 73 65 74 20 74 6d 20 5b 6c 69 6e 64 65 78 20 24  set tm [lindex $
7760: 73 70 65 65 64 20 30 5d 0a 20 20 69 66 20 7b 24  speed 0].  if {$
7770: 74 6d 20 3d 3d 20 30 7d 20 7b 0a 20 20 20 20 73  tm == 0} {.    s
7780: 65 74 20 72 61 74 65 20 5b 66 6f 72 6d 61 74 20  et rate [format 
7790: 25 32 30 73 20 22 6d 61 6e 79 22 5d 0a 20 20 7d  %20s "many"].  }
77a0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20   else {.    set 
77b0: 72 61 74 65 20 5b 66 6f 72 6d 61 74 20 25 32 30  rate [format %20
77c0: 2e 35 66 20 5b 65 78 70 72 20 7b 31 30 30 30 30  .5f [expr {10000
77d0: 30 30 2e 30 2a 24 6e 75 6d 73 74 6d 74 2f 24 74  00.0*$numstmt/$t
77e0: 6d 7d 5d 5d 0a 20 20 7d 0a 20 20 73 65 74 20 75  m}]].  }.  set u
77f0: 32 20 24 75 6e 69 74 73 2f 73 0a 20 20 6f 75 74  2 $units/s.  out
7800: 70 75 74 32 20 5b 66 6f 72 6d 61 74 20 7b 25 31  put2 [format {%1
7810: 32 64 20 75 53 20 25 73 20 25 73 7d 20 24 74 6d  2d uS %s %s} $tm
7820: 20 24 72 61 74 65 20 24 75 32 5d 0a 20 20 67 6c   $rate $u2].  gl
7830: 6f 62 61 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a  obal total_time.
7840: 20 20 73 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65    set total_time
7850: 20 5b 65 78 70 72 20 7b 24 74 6f 74 61 6c 5f 74   [expr {$total_t
7860: 69 6d 65 2b 24 74 6d 7d 5d 0a 20 20 6c 61 70 70  ime+$tm}].  lapp
7870: 65 6e 64 20 3a 3a 73 70 65 65 64 5f 74 72 69 61  end ::speed_tria
7880: 6c 5f 74 69 6d 65 73 20 24 6e 61 6d 65 20 24 74  l_times $name $t
7890: 6d 0a 7d 0a 70 72 6f 63 20 73 70 65 65 64 5f 74  m.}.proc speed_t
78a0: 72 69 61 6c 5f 74 63 6c 20 7b 6e 61 6d 65 20 6e  rial_tcl {name n
78b0: 75 6d 73 74 6d 74 20 75 6e 69 74 73 20 73 63 72  umstmt units scr
78c0: 69 70 74 7d 20 7b 0a 20 20 6f 75 74 70 75 74 32  ipt} {.  output2
78d0: 20 2d 6e 6f 6e 65 77 6c 69 6e 65 20 5b 66 6f 72   -nonewline [for
78e0: 6d 61 74 20 7b 25 2d 32 31 2e 32 31 73 20 7d 20  mat {%-21.21s } 
78f0: 24 6e 61 6d 65 2e 2e 2e 5d 0a 20 20 66 6c 75 73  $name...].  flus
7900: 68 20 73 74 64 6f 75 74 0a 20 20 73 65 74 20 73  h stdout.  set s
7910: 70 65 65 64 20 5b 74 69 6d 65 20 7b 65 76 61 6c  peed [time {eval
7920: 20 24 73 63 72 69 70 74 7d 5d 0a 20 20 73 65 74   $script}].  set
7930: 20 74 6d 20 5b 6c 69 6e 64 65 78 20 24 73 70 65   tm [lindex $spe
7940: 65 64 20 30 5d 0a 20 20 69 66 20 7b 24 74 6d 20  ed 0].  if {$tm 
7950: 3d 3d 20 30 7d 20 7b 0a 20 20 20 20 73 65 74 20  == 0} {.    set 
7960: 72 61 74 65 20 5b 66 6f 72 6d 61 74 20 25 32 30  rate [format %20
7970: 73 20 22 6d 61 6e 79 22 5d 0a 20 20 7d 20 65 6c  s "many"].  } el
7980: 73 65 20 7b 0a 20 20 20 20 73 65 74 20 72 61 74  se {.    set rat
7990: 65 20 5b 66 6f 72 6d 61 74 20 25 32 30 2e 35 66  e [format %20.5f
79a0: 20 5b 65 78 70 72 20 7b 31 30 30 30 30 30 30 2e   [expr {1000000.
79b0: 30 2a 24 6e 75 6d 73 74 6d 74 2f 24 74 6d 7d 5d  0*$numstmt/$tm}]
79c0: 5d 0a 20 20 7d 0a 20 20 73 65 74 20 75 32 20 24  ].  }.  set u2 $
79d0: 75 6e 69 74 73 2f 73 0a 20 20 6f 75 74 70 75 74  units/s.  output
79e0: 32 20 5b 66 6f 72 6d 61 74 20 7b 25 31 32 64 20  2 [format {%12d 
79f0: 75 53 20 25 73 20 25 73 7d 20 24 74 6d 20 24 72  uS %s %s} $tm $r
7a00: 61 74 65 20 24 75 32 5d 0a 20 20 67 6c 6f 62 61  ate $u2].  globa
7a10: 6c 20 74 6f 74 61 6c 5f 74 69 6d 65 0a 20 20 73  l total_time.  s
7a20: 65 74 20 74 6f 74 61 6c 5f 74 69 6d 65 20 5b 65  et total_time [e
7a30: 78 70 72 20 7b 24 74 6f 74 61 6c 5f 74 69 6d 65  xpr {$total_time
7a40: 2b 24 74 6d 7d 5d 0a 20 20 6c 61 70 70 65 6e 64  +$tm}].  lappend
7a50: 20 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c 5f 74   ::speed_trial_t
7a60: 69 6d 65 73 20 24 6e 61 6d 65 20 24 74 6d 0a 7d  imes $name $tm.}
7a70: 0a 70 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61  .proc speed_tria
7a80: 6c 5f 69 6e 69 74 20 7b 6e 61 6d 65 7d 20 7b 0a  l_init {name} {.
7a90: 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c 5f 74    global total_t
7aa0: 69 6d 65 0a 20 20 73 65 74 20 74 6f 74 61 6c 5f  ime.  set total_
7ab0: 74 69 6d 65 20 30 0a 20 20 73 65 74 20 3a 3a 73  time 0.  set ::s
7ac0: 70 65 65 64 5f 74 72 69 61 6c 5f 74 69 6d 65 73  peed_trial_times
7ad0: 20 5b 6c 69 73 74 5d 0a 20 20 73 71 6c 69 74 65   [list].  sqlite
7ae0: 33 20 76 65 72 73 64 62 20 3a 6d 65 6d 6f 72 79  3 versdb :memory
7af0: 3a 0a 20 20 73 65 74 20 76 65 72 73 20 5b 76 65  :.  set vers [ve
7b00: 72 73 64 62 20 6f 6e 65 20 7b 53 45 4c 45 43 54  rsdb one {SELECT
7b10: 20 73 71 6c 69 74 65 5f 73 6f 75 72 63 65 5f 69   sqlite_source_i
7b20: 64 28 29 7d 5d 0a 20 20 76 65 72 73 64 62 20 63  d()}].  versdb c
7b30: 6c 6f 73 65 0a 20 20 6f 75 74 70 75 74 32 20 22  lose.  output2 "
7b40: 53 51 4c 69 74 65 20 24 76 65 72 73 22 0a 7d 0a  SQLite $vers".}.
7b50: 70 72 6f 63 20 73 70 65 65 64 5f 74 72 69 61 6c  proc speed_trial
7b60: 5f 73 75 6d 6d 61 72 79 20 7b 6e 61 6d 65 7d 20  _summary {name} 
7b70: 7b 0a 20 20 67 6c 6f 62 61 6c 20 74 6f 74 61 6c  {.  global total
7b80: 5f 74 69 6d 65 0a 20 20 6f 75 74 70 75 74 32 20  _time.  output2 
7b90: 5b 66 6f 72 6d 61 74 20 7b 25 2d 32 31 2e 32 31  [format {%-21.21
7ba0: 73 20 25 31 32 64 20 75 53 20 54 4f 54 41 4c 7d  s %12d uS TOTAL}
7bb0: 20 24 6e 61 6d 65 20 24 74 6f 74 61 6c 5f 74 69   $name $total_ti
7bc0: 6d 65 5d 0a 0a 20 20 69 66 20 7b 20 30 20 7d 20  me]..  if { 0 } 
7bd0: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 20 76 65  {.    sqlite3 ve
7be0: 72 73 64 62 20 3a 6d 65 6d 6f 72 79 3a 0a 20 20  rsdb :memory:.  
7bf0: 20 20 73 65 74 20 76 65 72 73 20 5b 6c 69 6e 64    set vers [lind
7c00: 65 78 20 5b 76 65 72 73 64 62 20 6f 6e 65 20 7b  ex [versdb one {
7c10: 53 45 4c 45 43 54 20 73 71 6c 69 74 65 5f 73 6f  SELECT sqlite_so
7c20: 75 72 63 65 5f 69 64 28 29 7d 5d 20 30 5d 0a 20  urce_id()}] 0]. 
7c30: 20 20 20 76 65 72 73 64 62 20 63 6c 6f 73 65 0a     versdb close.
7c40: 20 20 20 20 6f 75 74 70 75 74 32 20 22 43 52 45      output2 "CRE
7c50: 41 54 45 20 54 41 42 4c 45 20 49 46 20 4e 4f 54  ATE TABLE IF NOT
7c60: 20 45 58 49 53 54 53 20 74 69 6d 65 28 76 65 72   EXISTS time(ver
7c70: 73 69 6f 6e 2c 20 73 63 72 69 70 74 2c 20 74 65  sion, script, te
7c80: 73 74 2c 20 75 73 29 3b 22 0a 20 20 20 20 66 6f  st, us);".    fo
7c90: 72 65 61 63 68 20 7b 74 65 73 74 20 75 73 7d 20  reach {test us} 
7ca0: 24 3a 3a 73 70 65 65 64 5f 74 72 69 61 6c 5f 74  $::speed_trial_t
7cb0: 69 6d 65 73 20 7b 0a 20 20 20 20 20 20 6f 75 74  imes {.      out
7cc0: 70 75 74 32 20 22 49 4e 53 45 52 54 20 49 4e 54  put2 "INSERT INT
7cd0: 4f 20 74 69 6d 65 20 56 41 4c 55 45 53 28 27 24  O time VALUES('$
7ce0: 76 65 72 73 27 2c 20 27 24 6e 61 6d 65 27 2c 20  vers', '$name', 
7cf0: 27 24 74 65 73 74 27 2c 20 24 75 73 29 3b 22 0a  '$test', $us);".
7d00: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 23 20 52      }.  }.}..# R
7d10: 75 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  un this routine 
7d20: 6c 61 73 74 0a 23 0a 70 72 6f 63 20 66 69 6e 69  last.#.proc fini
7d30: 73 68 5f 74 65 73 74 20 7b 7d 20 7b 0a 20 20 63  sh_test {} {.  c
7d40: 61 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a  atch {db close}.
7d50: 20 20 63 61 74 63 68 20 7b 64 62 31 20 63 6c 6f    catch {db1 clo
7d60: 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 32  se}.  catch {db2
7d70: 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20   close}.  catch 
7d80: 7b 64 62 33 20 63 6c 6f 73 65 7d 0a 20 20 69 66  {db3 close}.  if
7d90: 20 7b 30 3d 3d 5b 69 6e 66 6f 20 65 78 69 73 74   {0==[info exist
7da0: 73 20 3a 3a 53 4c 41 56 45 5d 7d 20 7b 20 66 69  s ::SLAVE]} { fi
7db0: 6e 61 6c 69 7a 65 5f 74 65 73 74 69 6e 67 20 7d  nalize_testing }
7dc0: 0a 7d 0a 70 72 6f 63 20 66 69 6e 61 6c 69 7a 65  .}.proc finalize
7dd0: 5f 74 65 73 74 69 6e 67 20 7b 7d 20 7b 0a 20 20  _testing {} {.  
7de0: 67 6c 6f 62 61 6c 20 73 71 6c 69 74 65 5f 6f 70  global sqlite_op
7df0: 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 0a 0a 20  en_file_count.. 
7e00: 20 73 65 74 20 6f 6d 69 74 4c 69 73 74 20 5b 73   set omitList [s
7e10: 65 74 5f 74 65 73 74 5f 63 6f 75 6e 74 65 72 20  et_test_counter 
7e20: 6f 6d 69 74 5f 6c 69 73 74 5d 0a 0a 20 20 63 61  omit_list]..  ca
7e30: 74 63 68 20 7b 64 62 20 63 6c 6f 73 65 7d 0a 20  tch {db close}. 
7e40: 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f 73   catch {db2 clos
7e50: 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 33 20  e}.  catch {db3 
7e60: 63 6c 6f 73 65 7d 0a 0a 20 20 76 66 73 5f 75 6e  close}..  vfs_un
7e70: 6c 69 6e 6b 5f 74 65 73 74 0a 20 20 73 71 6c 69  link_test.  sqli
7e80: 74 65 33 20 64 62 20 7b 7d 0a 20 20 23 20 73 71  te3 db {}.  # sq
7e90: 6c 69 74 65 33 5f 63 6c 65 61 72 5f 74 73 64 5f  lite3_clear_tsd_
7ea0: 6d 65 6d 64 65 62 75 67 0a 20 20 64 62 20 63 6c  memdebug.  db cl
7eb0: 6f 73 65 0a 20 20 73 71 6c 69 74 65 33 5f 72 65  ose.  sqlite3_re
7ec0: 73 65 74 5f 61 75 74 6f 5f 65 78 74 65 6e 73 69  set_auto_extensi
7ed0: 6f 6e 0a 0a 20 20 73 71 6c 69 74 65 33 5f 73 6f  on..  sqlite3_so
7ee0: 66 74 5f 68 65 61 70 5f 6c 69 6d 69 74 20 30 0a  ft_heap_limit 0.
7ef0: 20 20 73 65 74 20 6e 54 65 73 74 20 5b 69 6e 63    set nTest [inc
7f00: 72 5f 6e 74 65 73 74 5d 0a 20 20 73 65 74 20 6e  r_ntest].  set n
7f10: 45 72 72 20 5b 73 65 74 5f 74 65 73 74 5f 63 6f  Err [set_test_co
7f20: 75 6e 74 65 72 20 65 72 72 6f 72 73 5d 0a 0a 20  unter errors].. 
7f30: 20 73 65 74 20 6e 4b 6e 6f 77 6e 20 30 0a 20 20   set nKnown 0.  
7f40: 69 66 20 7b 5b 66 69 6c 65 20 72 65 61 64 61 62  if {[file readab
7f50: 6c 65 20 6b 6e 6f 77 6e 2d 70 72 6f 62 6c 65 6d  le known-problem
7f60: 73 2e 74 78 74 5d 7d 20 7b 0a 20 20 20 20 73 65  s.txt]} {.    se
7f70: 74 20 66 64 20 5b 6f 70 65 6e 20 6b 6e 6f 77 6e  t fd [open known
7f80: 2d 70 72 6f 62 6c 65 6d 73 2e 74 78 74 5d 0a 20  -problems.txt]. 
7f90: 20 20 20 73 65 74 20 63 6f 6e 74 65 6e 74 20 5b     set content [
7fa0: 72 65 61 64 20 24 66 64 5d 0a 20 20 20 20 63 6c  read $fd].    cl
7fb0: 6f 73 65 20 24 66 64 0a 20 20 20 20 66 6f 72 65  ose $fd.    fore
7fc0: 61 63 68 20 78 20 24 63 6f 6e 74 65 6e 74 20 7b  ach x $content {
7fd0: 73 65 74 20 6b 6e 6f 77 6e 5f 65 72 72 6f 72 28  set known_error(
7fe0: 24 78 29 20 31 7d 0a 20 20 20 20 66 6f 72 65 61  $x) 1}.    forea
7ff0: 63 68 20 78 20 5b 73 65 74 5f 74 65 73 74 5f 63  ch x [set_test_c
8000: 6f 75 6e 74 65 72 20 66 61 69 6c 5f 6c 69 73 74  ounter fail_list
8010: 5d 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 5b 69  ] {.      if {[i
8020: 6e 66 6f 20 65 78 69 73 74 73 20 6b 6e 6f 77 6e  nfo exists known
8030: 5f 65 72 72 6f 72 28 24 78 29 5d 7d 20 7b 69 6e  _error($x)]} {in
8040: 63 72 20 6e 4b 6e 6f 77 6e 7d 0a 20 20 20 20 7d  cr nKnown}.    }
8050: 0a 20 20 7d 0a 20 20 69 66 20 7b 24 6e 4b 6e 6f  .  }.  if {$nKno
8060: 77 6e 3e 30 7d 20 7b 0a 20 20 20 20 6f 75 74 70  wn>0} {.    outp
8070: 75 74 32 20 22 5b 65 78 70 72 20 7b 24 6e 45 72  ut2 "[expr {$nEr
8080: 72 2d 24 6e 4b 6e 6f 77 6e 7d 5d 20 6e 65 77 20  r-$nKnown}] new 
8090: 65 72 72 6f 72 73 20 61 6e 64 20 24 6e 4b 6e 6f  errors and $nKno
80a0: 77 6e 20 6b 6e 6f 77 6e 20 65 72 72 6f 72 73 5c  wn known errors\
80b0: 0a 20 20 20 20 20 20 20 20 20 6f 75 74 20 6f 66  .         out of
80c0: 20 24 6e 54 65 73 74 20 74 65 73 74 73 22 0a 20   $nTest tests". 
80d0: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 73 65   } else {.    se
80e0: 74 20 63 70 75 69 6e 66 6f 20 7b 7d 0a 20 20 20  t cpuinfo {}.   
80f0: 20 69 66 20 7b 5b 63 61 74 63 68 20 7b 65 78 65   if {[catch {exe
8100: 63 20 68 6f 73 74 6e 61 6d 65 7d 20 68 6e 61 6d  c hostname} hnam
8110: 65 5d 3d 3d 30 7d 20 7b 73 65 74 20 63 70 75 69  e]==0} {set cpui
8120: 6e 66 6f 20 5b 73 74 72 69 6e 67 20 74 72 69 6d  nfo [string trim
8130: 20 24 68 6e 61 6d 65 5d 7d 0a 20 20 20 20 61 70   $hname]}.    ap
8140: 70 65 6e 64 20 63 70 75 69 6e 66 6f 20 22 20 24  pend cpuinfo " $
8150: 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 6f  ::tcl_platform(o
8160: 73 29 22 0a 20 20 20 20 61 70 70 65 6e 64 20 63  s)".    append c
8170: 70 75 69 6e 66 6f 20 22 20 5b 65 78 70 72 20 7b  puinfo " [expr {
8180: 24 3a 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28  $::tcl_platform(
8190: 70 6f 69 6e 74 65 72 53 69 7a 65 29 2a 38 7d 5d  pointerSize)*8}]
81a0: 2d 62 69 74 22 0a 20 20 20 20 61 70 70 65 6e 64  -bit".    append
81b0: 20 63 70 75 69 6e 66 6f 20 22 20 5b 73 74 72 69   cpuinfo " [stri
81c0: 6e 67 20 6d 61 70 20 7b 45 20 2d 65 7d 20 24 3a  ng map {E -e} $:
81d0: 3a 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 62 79  :tcl_platform(by
81e0: 74 65 4f 72 64 65 72 29 5d 22 0a 20 20 20 20 6f  teOrder)]".    o
81f0: 75 74 70 75 74 32 20 22 53 51 4c 69 74 65 20 5b  utput2 "SQLite [
8200: 73 71 6c 69 74 65 33 20 2d 73 6f 75 72 63 65 69  sqlite3 -sourcei
8210: 64 5d 22 0a 20 20 20 20 6f 75 74 70 75 74 32 20  d]".    output2 
8220: 22 24 6e 45 72 72 20 65 72 72 6f 72 73 20 6f 75  "$nErr errors ou
8230: 74 20 6f 66 20 24 6e 54 65 73 74 20 74 65 73 74  t of $nTest test
8240: 73 20 6f 6e 20 24 63 70 75 69 6e 66 6f 22 0a 20  s on $cpuinfo". 
8250: 20 7d 0a 20 20 69 66 20 7b 24 6e 45 72 72 3e 24   }.  if {$nErr>$
8260: 6e 4b 6e 6f 77 6e 7d 20 7b 0a 20 20 20 20 6f 75  nKnown} {.    ou
8270: 74 70 75 74 32 20 2d 6e 6f 6e 65 77 6c 69 6e 65  tput2 -nonewline
8280: 20 22 21 46 61 69 6c 75 72 65 73 20 6f 6e 20 74   "!Failures on t
8290: 68 65 73 65 20 74 65 73 74 73 3a 22 0a 20 20 20  hese tests:".   
82a0: 20 66 6f 72 65 61 63 68 20 78 20 5b 73 65 74 5f   foreach x [set_
82b0: 74 65 73 74 5f 63 6f 75 6e 74 65 72 20 66 61 69  test_counter fai
82c0: 6c 5f 6c 69 73 74 5d 20 7b 0a 20 20 20 20 20 20  l_list] {.      
82d0: 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74  if {![info exist
82e0: 73 20 6b 6e 6f 77 6e 5f 65 72 72 6f 72 28 24 78  s known_error($x
82f0: 29 5d 7d 20 7b 6f 75 74 70 75 74 32 20 2d 6e 6f  )]} {output2 -no
8300: 6e 65 77 6c 69 6e 65 20 22 20 24 78 22 7d 0a 20  newline " $x"}. 
8310: 20 20 20 7d 0a 20 20 20 20 6f 75 74 70 75 74 32     }.    output2
8320: 20 22 22 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63   "".  }.  foreac
8330: 68 20 77 61 72 6e 69 6e 67 20 5b 73 65 74 5f 74  h warning [set_t
8340: 65 73 74 5f 63 6f 75 6e 74 65 72 20 77 61 72 6e  est_counter warn
8350: 5f 6c 69 73 74 5d 20 7b 0a 20 20 20 20 6f 75 74  _list] {.    out
8360: 70 75 74 32 20 22 57 61 72 6e 69 6e 67 3a 20 24  put2 "Warning: $
8370: 77 61 72 6e 69 6e 67 22 0a 20 20 7d 0a 20 20 72  warning".  }.  r
8380: 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73 20  un_thread_tests 
8390: 31 0a 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68  1.  if {[llength
83a0: 20 24 6f 6d 69 74 4c 69 73 74 5d 3e 30 7d 20 7b   $omitList]>0} {
83b0: 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 4f 6d  .    output2 "Om
83c0: 69 74 74 65 64 20 74 65 73 74 20 63 61 73 65 73  itted test cases
83d0: 3a 22 0a 20 20 20 20 73 65 74 20 70 72 65 63 20  :".    set prec 
83e0: 7b 7d 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b  {}.    foreach {
83f0: 72 65 63 7d 20 5b 6c 73 6f 72 74 20 24 6f 6d 69  rec} [lsort $omi
8400: 74 4c 69 73 74 5d 20 7b 0a 20 20 20 20 20 20 69  tList] {.      i
8410: 66 20 7b 24 72 65 63 3d 3d 24 70 72 65 63 7d 20  f {$rec==$prec} 
8420: 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20 20 73  continue.      s
8430: 65 74 20 70 72 65 63 20 24 72 65 63 0a 20 20 20  et prec $rec.   
8440: 20 20 20 6f 75 74 70 75 74 32 20 5b 66 6f 72 6d     output2 [form
8450: 61 74 20 7b 2e 20 20 25 2d 31 32 73 20 25 73 7d  at {.  %-12s %s}
8460: 20 5b 6c 69 6e 64 65 78 20 24 72 65 63 20 30 5d   [lindex $rec 0]
8470: 20 5b 6c 69 6e 64 65 78 20 24 72 65 63 20 31 5d   [lindex $rec 1]
8480: 5d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ].    }.  }.  if
8490: 20 7b 24 6e 45 72 72 3e 30 20 26 26 20 21 5b 77   {$nErr>0 && ![w
84a0: 6f 72 6b 69 6e 67 5f 36 34 62 69 74 5f 69 6e 74  orking_64bit_int
84b0: 5d 7d 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32  ]} {.    output2
84c0: 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   "**************
84d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
84e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
84f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8500: 2a 2a 2a 2a 22 0a 20 20 20 20 6f 75 74 70 75 74  ****".    output
8510: 32 20 22 4e 2e 42 2e 3a 20 20 54 68 65 20 76 65  2 "N.B.:  The ve
8520: 72 73 69 6f 6e 20 6f 66 20 54 43 4c 20 74 68 61  rsion of TCL tha
8530: 74 20 79 6f 75 20 75 73 65 64 20 74 6f 20 62 75  t you used to bu
8540: 69 6c 64 20 74 68 69 73 20 74 65 73 74 20 68 61  ild this test ha
8550: 72 6e 65 73 73 22 0a 20 20 20 20 6f 75 74 70 75  rness".    outpu
8560: 74 32 20 22 69 73 20 64 65 66 65 63 74 69 76 65  t2 "is defective
8570: 20 69 6e 20 74 68 61 74 20 69 74 20 64 6f 65 73   in that it does
8580: 20 6e 6f 74 20 73 75 70 70 6f 72 74 20 36 34 2d   not support 64-
8590: 62 69 74 20 69 6e 74 65 67 65 72 73 2e 20 20 53  bit integers.  S
85a0: 6f 6d 65 20 6f 72 22 0a 20 20 20 20 6f 75 74 70  ome or".    outp
85b0: 75 74 32 20 22 61 6c 6c 20 6f 66 20 74 68 65 20  ut2 "all of the 
85c0: 74 65 73 74 20 66 61 69 6c 75 72 65 73 20 61 62  test failures ab
85d0: 6f 76 65 20 6d 69 67 68 74 20 62 65 20 61 20 72  ove might be a r
85e0: 65 73 75 6c 74 20 66 72 6f 6d 20 74 68 69 73 20  esult from this 
85f0: 64 65 66 65 63 74 22 0a 20 20 20 20 6f 75 74 70  defect".    outp
8600: 75 74 32 20 22 69 6e 20 79 6f 75 72 20 54 43 4c  ut2 "in your TCL
8610: 20 62 75 69 6c 64 2e 22 0a 20 20 20 20 6f 75 74   build.".    out
8620: 70 75 74 32 20 22 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  put2 "**********
8630: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8640: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8650: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8660: 2a 2a 2a 2a 2a 2a 2a 2a 22 0a 20 20 7d 0a 20 20  ********".  }.  
8670: 69 66 20 7b 24 3a 3a 63 6d 64 6c 69 6e 65 61 72  if {$::cmdlinear
8680: 67 28 62 69 6e 61 72 79 6c 6f 67 29 7d 20 7b 0a  g(binarylog)} {.
8690: 20 20 20 20 76 66 73 6c 6f 67 20 66 69 6e 61 6c      vfslog final
86a0: 69 7a 65 20 62 69 6e 61 72 79 6c 6f 67 0a 20 20  ize binarylog.  
86b0: 7d 0a 20 20 69 66 20 7b 24 73 71 6c 69 74 65 5f  }.  if {$sqlite_
86c0: 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 7d  open_file_count}
86d0: 20 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22   {.    output2 "
86e0: 24 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69 6c  $sqlite_open_fil
86f0: 65 5f 63 6f 75 6e 74 20 66 69 6c 65 73 20 77 65  e_count files we
8700: 72 65 20 6c 65 66 74 20 6f 70 65 6e 22 0a 20 20  re left open".  
8710: 20 20 69 6e 63 72 20 6e 45 72 72 0a 20 20 7d 0a    incr nErr.  }.
8720: 20 20 69 66 20 7b 5b 6c 69 6e 64 65 78 20 5b 73    if {[lindex [s
8730: 71 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51  qlite3_status SQ
8740: 4c 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c  LITE_STATUS_MALL
8750: 4f 43 5f 43 4f 55 4e 54 20 30 5d 20 31 5d 3e 30  OC_COUNT 0] 1]>0
8760: 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20   ||.            
8770: 20 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72    [sqlite3_memor
8780: 79 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a 20 20 20  y_used]>0} {.   
8790: 20 6f 75 74 70 75 74 32 20 22 55 6e 66 72 65 65   output2 "Unfree
87a0: 64 20 6d 65 6d 6f 72 79 3a 20 5b 73 71 6c 69 74  d memory: [sqlit
87b0: 65 33 5f 6d 65 6d 6f 72 79 5f 75 73 65 64 5d 20  e3_memory_used] 
87c0: 62 79 74 65 73 20 69 6e 5c 0a 20 20 20 20 20 20  bytes in\.      
87d0: 20 20 20 5b 6c 69 6e 64 65 78 20 5b 73 71 6c 69     [lindex [sqli
87e0: 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54  te3_status SQLIT
87f0: 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c 4f 43 5f  E_STATUS_MALLOC_
8800: 43 4f 55 4e 54 20 30 5d 20 31 5d 20 61 6c 6c 6f  COUNT 0] 1] allo
8810: 63 61 74 69 6f 6e 73 22 0a 20 20 20 20 69 6e 63  cations".    inc
8820: 72 20 6e 45 72 72 0a 20 20 20 20 69 66 63 61 70  r nErr.    ifcap
8830: 61 62 6c 65 20 6d 65 6d 64 65 62 75 67 7c 7c 6d  able memdebug||m
8840: 65 6d 35 7c 7c 28 6d 65 6d 33 26 26 64 65 62 75  em5||(mem3&&debu
8850: 67 29 20 7b 0a 20 20 20 20 20 20 6f 75 74 70 75  g) {.      outpu
8860: 74 32 20 22 57 72 69 74 69 6e 67 20 75 6e 66 72  t2 "Writing unfr
8870: 65 65 64 20 6d 65 6d 6f 72 79 20 6c 6f 67 20 74  eed memory log t
8880: 6f 20 5c 22 2e 2f 6d 65 6d 6c 65 61 6b 2e 74 78  o \"./memleak.tx
8890: 74 5c 22 22 0a 20 20 20 20 20 20 73 71 6c 69 74  t\"".      sqlit
88a0: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 64 75 6d 70  e3_memdebug_dump
88b0: 20 2e 2f 6d 65 6d 6c 65 61 6b 2e 74 78 74 0a 20   ./memleak.txt. 
88c0: 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a     }.  } else {.
88d0: 20 20 20 20 6f 75 74 70 75 74 32 20 22 41 6c 6c      output2 "All
88e0: 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 69   memory allocati
88f0: 6f 6e 73 20 66 72 65 65 64 20 2d 20 6e 6f 20 6c  ons freed - no l
8900: 65 61 6b 73 22 0a 20 20 20 20 69 66 63 61 70 61  eaks".    ifcapa
8910: 62 6c 65 20 6d 65 6d 64 65 62 75 67 7c 7c 6d 65  ble memdebug||me
8920: 6d 35 20 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  m5 {.      sqlit
8930: 65 33 5f 6d 65 6d 64 65 62 75 67 5f 64 75 6d 70  e3_memdebug_dump
8940: 20 2e 2f 6d 65 6d 75 73 61 67 65 2e 74 78 74 0a   ./memusage.txt.
8950: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 68 6f 77      }.  }.  show
8960: 5f 6d 65 6d 73 74 61 74 73 0a 20 20 6f 75 74 70  _memstats.  outp
8970: 75 74 32 20 22 4d 61 78 69 6d 75 6d 20 6d 65 6d  ut2 "Maximum mem
8980: 6f 72 79 20 75 73 61 67 65 3a 20 5b 73 71 6c 69  ory usage: [sqli
8990: 74 65 33 5f 6d 65 6d 6f 72 79 5f 68 69 67 68 77  te3_memory_highw
89a0: 61 74 65 72 20 31 5d 20 62 79 74 65 73 22 0a 20  ater 1] bytes". 
89b0: 20 6f 75 74 70 75 74 32 20 22 43 75 72 72 65 6e   output2 "Curren
89c0: 74 20 6d 65 6d 6f 72 79 20 75 73 61 67 65 3a 20  t memory usage: 
89d0: 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79 5f  [sqlite3_memory_
89e0: 68 69 67 68 77 61 74 65 72 5d 20 62 79 74 65 73  highwater] bytes
89f0: 22 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 63 6f  ".  if {[info co
8a00: 6d 6d 61 6e 64 73 20 73 71 6c 69 74 65 33 5f 6d  mmands sqlite3_m
8a10: 65 6d 64 65 62 75 67 5f 6d 61 6c 6c 6f 63 5f 63  emdebug_malloc_c
8a20: 6f 75 6e 74 5d 20 6e 65 20 22 22 7d 20 7b 0a 20  ount] ne ""} {. 
8a30: 20 20 20 6f 75 74 70 75 74 32 20 22 4e 75 6d 62     output2 "Numb
8a40: 65 72 20 6f 66 20 6d 61 6c 6c 6f 63 28 29 20 20  er of malloc()  
8a50: 3a 20 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 64 65  : [sqlite3_memde
8a60: 62 75 67 5f 6d 61 6c 6c 6f 63 5f 63 6f 75 6e 74  bug_malloc_count
8a70: 5d 20 63 61 6c 6c 73 22 0a 20 20 7d 0a 20 20 69  ] calls".  }.  i
8a80: 66 20 7b 24 3a 3a 63 6d 64 6c 69 6e 65 61 72 67  f {$::cmdlinearg
8a90: 28 6d 61 6c 6c 6f 63 74 72 61 63 65 29 7d 20 7b  (malloctrace)} {
8aa0: 0a 20 20 20 20 6f 75 74 70 75 74 32 20 22 57 72  .    output2 "Wr
8ab0: 69 74 69 6e 67 20 6d 61 6c 6c 6f 63 73 2e 73 71  iting mallocs.sq
8ac0: 6c 2e 2e 2e 22 0a 20 20 20 20 6d 65 6d 64 65 62  l...".    memdeb
8ad0: 75 67 5f 6c 6f 67 5f 73 71 6c 0a 20 20 20 20 73  ug_log_sql.    s
8ae0: 71 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f  qlite3_memdebug_
8af0: 6c 6f 67 20 73 74 6f 70 0a 20 20 20 20 73 71 6c  log stop.    sql
8b00: 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c 6f  ite3_memdebug_lo
8b10: 67 20 63 6c 65 61 72 0a 0a 20 20 20 20 69 66 20  g clear..    if 
8b20: 7b 5b 73 71 6c 69 74 65 33 5f 6d 65 6d 6f 72 79  {[sqlite3_memory
8b30: 5f 75 73 65 64 5d 3e 30 7d 20 7b 0a 20 20 20 20  _used]>0} {.    
8b40: 20 20 6f 75 74 70 75 74 32 20 22 57 72 69 74 69    output2 "Writi
8b50: 6e 67 20 6c 65 61 6b 73 2e 73 71 6c 2e 2e 2e 22  ng leaks.sql..."
8b60: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  .      sqlite3_m
8b70: 65 6d 64 65 62 75 67 5f 6c 6f 67 20 73 79 6e 63  emdebug_log sync
8b80: 0a 20 20 20 20 20 20 6d 65 6d 64 65 62 75 67 5f  .      memdebug_
8b90: 6c 6f 67 5f 73 71 6c 20 6c 65 61 6b 73 2e 73 71  log_sql leaks.sq
8ba0: 6c 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 66 6f  l.    }.  }.  fo
8bb0: 72 65 61 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e  reach f [glob -n
8bc0: 6f 63 6f 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64  ocomplain test.d
8bd0: 62 2d 2a 2d 6a 6f 75 72 6e 61 6c 5d 20 7b 0a 20  b-*-journal] {. 
8be0: 20 20 20 66 6f 72 63 65 64 65 6c 65 74 65 20 24     forcedelete $
8bf0: 66 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20  f.  }.  foreach 
8c00: 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c  f [glob -nocompl
8c10: 61 69 6e 20 74 65 73 74 2e 64 62 2d 6d 6a 2a 5d  ain test.db-mj*]
8c20: 20 7b 0a 20 20 20 20 66 6f 72 63 65 64 65 6c 65   {.    forcedele
8c30: 74 65 20 24 66 0a 20 20 7d 0a 20 20 65 78 69 74  te $f.  }.  exit
8c40: 20 5b 65 78 70 72 20 7b 24 6e 45 72 72 3e 30 7d   [expr {$nErr>0}
8c50: 5d 0a 7d 0a 0a 23 20 44 69 73 70 6c 61 79 20 6d  ].}..# Display m
8c60: 65 6d 6f 72 79 20 73 74 61 74 69 73 74 69 63 73  emory statistics
8c70: 20 66 6f 72 20 61 6e 61 6c 79 73 69 73 20 61 6e   for analysis an
8c80: 64 20 64 65 62 75 67 67 69 6e 67 20 70 75 72 70  d debugging purp
8c90: 6f 73 65 73 2e 0a 23 0a 70 72 6f 63 20 73 68 6f  oses..#.proc sho
8ca0: 77 5f 6d 65 6d 73 74 61 74 73 20 7b 7d 20 7b 0a  w_memstats {} {.
8cb0: 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65 33    set x [sqlite3
8cc0: 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f 53  _status SQLITE_S
8cd0: 54 41 54 55 53 5f 4d 45 4d 4f 52 59 5f 55 53 45  TATUS_MEMORY_USE
8ce0: 44 20 30 5d 0a 20 20 73 65 74 20 79 20 5b 73 71  D 0].  set y [sq
8cf0: 6c 69 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c  lite3_status SQL
8d00: 49 54 45 5f 53 54 41 54 55 53 5f 4d 41 4c 4c 4f  ITE_STATUS_MALLO
8d10: 43 5f 53 49 5a 45 20 30 5d 0a 20 20 73 65 74 20  C_SIZE 0].  set 
8d20: 76 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77  val [format {now
8d30: 20 25 31 30 64 20 20 6d 61 78 20 25 31 30 64 20   %10d  max %10d 
8d40: 20 6d 61 78 2d 73 69 7a 65 20 25 31 30 64 7d 20   max-size %10d} 
8d50: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  \.              
8d60: 5b 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c  [lindex $x 1] [l
8d70: 69 6e 64 65 78 20 24 78 20 32 5d 20 5b 6c 69 6e  index $x 2] [lin
8d80: 64 65 78 20 24 79 20 32 5d 5d 0a 20 20 6f 75 74  dex $y 2]].  out
8d90: 70 75 74 31 20 22 4d 65 6d 6f 72 79 20 75 73 65  put1 "Memory use
8da0: 64 3a 20 20 20 20 20 20 20 20 20 20 24 76 61 6c  d:          $val
8db0: 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74  ".  set x [sqlit
8dc0: 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45  e3_status SQLITE
8dd0: 5f 53 54 41 54 55 53 5f 4d 41 4c 4c 4f 43 5f 43  _STATUS_MALLOC_C
8de0: 4f 55 4e 54 20 30 5d 0a 20 20 73 65 74 20 76 61  OUNT 0].  set va
8df0: 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25  l [format {now %
8e00: 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20 5b  10d  max %10d} [
8e10: 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69  lindex $x 1] [li
8e20: 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 6f 75  ndex $x 2]].  ou
8e30: 74 70 75 74 31 20 22 41 6c 6c 6f 63 61 74 69 6f  tput1 "Allocatio
8e40: 6e 20 63 6f 75 6e 74 3a 20 20 20 20 20 24 76 61  n count:     $va
8e50: 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69  l".  set x [sqli
8e60: 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54  te3_status SQLIT
8e70: 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43  E_STATUS_PAGECAC
8e80: 48 45 5f 55 53 45 44 20 30 5d 0a 20 20 73 65 74  HE_USED 0].  set
8e90: 20 79 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74   y [sqlite3_stat
8ea0: 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53  us SQLITE_STATUS
8eb0: 5f 50 41 47 45 43 41 43 48 45 5f 53 49 5a 45 20  _PAGECACHE_SIZE 
8ec0: 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b 66 6f  0].  set val [fo
8ed0: 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64 20 20  rmat {now %10d  
8ee0: 6d 61 78 20 25 31 30 64 20 20 6d 61 78 2d 73 69  max %10d  max-si
8ef0: 7a 65 20 25 31 30 64 7d 20 5c 0a 20 20 20 20 20  ze %10d} \.     
8f00: 20 20 20 20 20 20 20 20 20 5b 6c 69 6e 64 65 78           [lindex
8f10: 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24   $x 1] [lindex $
8f20: 78 20 32 5d 20 5b 6c 69 6e 64 65 78 20 24 79 20  x 2] [lindex $y 
8f30: 32 5d 5d 0a 20 20 6f 75 74 70 75 74 31 20 22 50  2]].  output1 "P
8f40: 61 67 65 2d 63 61 63 68 65 20 75 73 65 64 3a 20  age-cache used: 
8f50: 20 20 20 20 20 24 76 61 6c 22 0a 20 20 73 65 74       $val".  set
8f60: 20 78 20 5b 73 71 6c 69 74 65 33 5f 73 74 61 74   x [sqlite3_stat
8f70: 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54 55 53  us SQLITE_STATUS
8f80: 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46  _PAGECACHE_OVERF
8f90: 4c 4f 57 20 30 5d 0a 20 20 73 65 74 20 76 61 6c  LOW 0].  set val
8fa0: 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25 31   [format {now %1
8fb0: 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20 5b 6c  0d  max %10d} [l
8fc0: 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69 6e  index $x 1] [lin
8fd0: 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 6f 75 74  dex $x 2]].  out
8fe0: 70 75 74 31 20 22 50 61 67 65 2d 63 61 63 68 65  put1 "Page-cache
8ff0: 20 6f 76 65 72 66 6c 6f 77 3a 20 20 24 76 61 6c   overflow:  $val
9000: 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74  ".  set x [sqlit
9010: 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45  e3_status SQLITE
9020: 5f 53 54 41 54 55 53 5f 53 43 52 41 54 43 48 5f  _STATUS_SCRATCH_
9030: 55 53 45 44 20 30 5d 0a 20 20 73 65 74 20 76 61  USED 0].  set va
9040: 6c 20 5b 66 6f 72 6d 61 74 20 7b 6e 6f 77 20 25  l [format {now %
9050: 31 30 64 20 20 6d 61 78 20 25 31 30 64 7d 20 5b  10d  max %10d} [
9060: 6c 69 6e 64 65 78 20 24 78 20 31 5d 20 5b 6c 69  lindex $x 1] [li
9070: 6e 64 65 78 20 24 78 20 32 5d 5d 0a 20 20 6f 75  ndex $x 2]].  ou
9080: 74 70 75 74 31 20 22 53 63 72 61 74 63 68 20 6d  tput1 "Scratch m
9090: 65 6d 6f 72 79 20 75 73 65 64 3a 20 20 24 76 61  emory used:  $va
90a0: 6c 22 0a 20 20 73 65 74 20 78 20 5b 73 71 6c 69  l".  set x [sqli
90b0: 74 65 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54  te3_status SQLIT
90c0: 45 5f 53 54 41 54 55 53 5f 53 43 52 41 54 43 48  E_STATUS_SCRATCH
90d0: 5f 4f 56 45 52 46 4c 4f 57 20 30 5d 0a 20 20 73  _OVERFLOW 0].  s
90e0: 65 74 20 79 20 5b 73 71 6c 69 74 65 33 5f 73 74  et y [sqlite3_st
90f0: 61 74 75 73 20 53 51 4c 49 54 45 5f 53 54 41 54  atus SQLITE_STAT
9100: 55 53 5f 53 43 52 41 54 43 48 5f 53 49 5a 45 20  US_SCRATCH_SIZE 
9110: 30 5d 0a 20 20 73 65 74 20 76 61 6c 20 5b 66 6f  0].  set val [fo
9120: 72 6d 61 74 20 7b 6e 6f 77 20 25 31 30 64 20 20  rmat {now %10d  
9130: 6d 61 78 20 25 31 30 64 20 20 6d 61 78 2d 73 69  max %10d  max-si
9140: 7a 65 20 25 31 30 64 7d 20 5c 0a 20 20 20 20 20  ze %10d} \.     
9150: 20 20 20 20 20 20 20 20 20 20 5b 6c 69 6e 64 65            [linde
9160: 78 20 24 78 20 31 5d 20 5b 6c 69 6e 64 65 78 20  x $x 1] [lindex 
9170: 24 78 20 32 5d 20 5b 6c 69 6e 64 65 78 20 24 79  $x 2] [lindex $y
9180: 20 32 5d 5d 0a 20 20 6f 75 74 70 75 74 31 20 22   2]].  output1 "
9190: 53 63 72 61 74 63 68 20 6f 76 65 72 66 6c 6f 77  Scratch overflow
91a0: 3a 20 20 20 20 20 24 76 61 6c 22 0a 20 20 69 66  :     $val".  if
91b0: 63 61 70 61 62 6c 65 20 79 79 74 72 61 63 6b 6d  capable yytrackm
91c0: 61 78 73 74 61 63 6b 64 65 70 74 68 20 7b 0a 20  axstackdepth {. 
91d0: 20 20 20 73 65 74 20 78 20 5b 73 71 6c 69 74 65     set x [sqlite
91e0: 33 5f 73 74 61 74 75 73 20 53 51 4c 49 54 45 5f  3_status SQLITE_
91f0: 53 54 41 54 55 53 5f 50 41 52 53 45 52 5f 53 54  STATUS_PARSER_ST
9200: 41 43 4b 20 30 5d 0a 20 20 20 20 73 65 74 20 76  ACK 0].    set v
9210: 61 6c 20 5b 66 6f 72 6d 61 74 20 7b 20 20 20 20  al [format {    
9220: 20 20 20 20 20 20 20 20 20 20 20 6d 61 78 20 25             max %
9230: 31 30 64 7d 20 5b 6c 69 6e 64 65 78 20 24 78 20  10d} [lindex $x 
9240: 32 5d 5d 0a 20 20 20 20 6f 75 74 70 75 74 32 20  2]].    output2 
9250: 22 50 61 72 73 65 72 20 73 74 61 63 6b 20 64 65  "Parser stack de
9260: 70 74 68 3a 20 20 20 20 24 76 61 6c 22 0a 20 20  pth:    $val".  
9270: 7d 0a 7d 0a 0a 23 20 41 20 70 72 6f 63 65 64 75  }.}..# A procedu
9280: 72 65 20 74 6f 20 65 78 65 63 75 74 65 20 53 51  re to execute SQ
9290: 4c 0a 23 0a 70 72 6f 63 20 65 78 65 63 73 71 6c  L.#.proc execsql
92a0: 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d 20 7b   {sql {db db}} {
92b0: 0a 20 20 23 20 70 75 74 73 20 22 53 51 4c 20 3d  .  # puts "SQL =
92c0: 20 24 73 71 6c 22 0a 20 20 75 70 6c 65 76 65 6c   $sql".  uplevel
92d0: 20 5b 6c 69 73 74 20 24 64 62 20 65 76 61 6c 20   [list $db eval 
92e0: 24 73 71 6c 5d 0a 7d 0a 70 72 6f 63 20 65 78 65  $sql].}.proc exe
92f0: 63 73 71 6c 5f 74 69 6d 65 64 20 7b 73 71 6c 20  csql_timed {sql 
9300: 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74  {db db}} {.  set
9310: 20 74 6d 20 5b 74 69 6d 65 20 7b 0a 20 20 20 20   tm [time {.    
9320: 73 65 74 20 78 20 5b 75 70 6c 65 76 65 6c 20 5b  set x [uplevel [
9330: 6c 69 73 74 20 24 64 62 20 65 76 61 6c 20 24 73  list $db eval $s
9340: 71 6c 5d 5d 0a 20 20 7d 20 31 5d 0a 20 20 73 65  ql]].  } 1].  se
9350: 74 20 74 6d 20 5b 6c 69 6e 64 65 78 20 24 74 6d  t tm [lindex $tm
9360: 20 30 5d 0a 20 20 6f 75 74 70 75 74 31 20 2d 6e   0].  output1 -n
9370: 6f 6e 65 77 6c 69 6e 65 20 22 20 28 5b 65 78 70  onewline " ([exp
9380: 72 20 7b 24 74 6d 2a 30 2e 30 30 31 7d 5d 6d 73  r {$tm*0.001}]ms
9390: 29 20 22 0a 20 20 73 65 74 20 78 0a 7d 0a 0a 23  ) ".  set x.}..#
93a0: 20 45 78 65 63 75 74 65 20 53 51 4c 20 61 6e 64   Execute SQL and
93b0: 20 63 61 74 63 68 20 65 78 63 65 70 74 69 6f 6e   catch exception
93c0: 73 2e 0a 23 0a 70 72 6f 63 20 63 61 74 63 68 73  s..#.proc catchs
93d0: 71 6c 20 7b 73 71 6c 20 7b 64 62 20 64 62 7d 7d  ql {sql {db db}}
93e0: 20 7b 0a 20 20 23 20 70 75 74 73 20 22 53 51 4c   {.  # puts "SQL
93f0: 20 3d 20 24 73 71 6c 22 0a 20 20 73 65 74 20 72   = $sql".  set r
9400: 20 5b 63 61 74 63 68 20 5b 6c 69 73 74 20 75 70   [catch [list up
9410: 6c 65 76 65 6c 20 5b 6c 69 73 74 20 24 64 62 20  level [list $db 
9420: 65 76 61 6c 20 24 73 71 6c 5d 5d 20 6d 73 67 5d  eval $sql]] msg]
9430: 0a 20 20 6c 61 70 70 65 6e 64 20 72 20 24 6d 73  .  lappend r $ms
9440: 67 0a 20 20 72 65 74 75 72 6e 20 24 72 0a 7d 0a  g.  return $r.}.
9450: 0a 23 20 44 6f 20 61 6e 20 56 44 42 45 20 63 6f  .# Do an VDBE co
9460: 64 65 20 64 75 6d 70 20 6f 6e 20 74 68 65 20 53  de dump on the S
9470: 51 4c 20 67 69 76 65 6e 0a 23 0a 70 72 6f 63 20  QL given.#.proc 
9480: 65 78 70 6c 61 69 6e 20 7b 73 71 6c 20 7b 64 62  explain {sql {db
9490: 20 64 62 7d 7d 20 7b 0a 20 20 6f 75 74 70 75 74   db}} {.  output
94a0: 32 20 22 22 0a 20 20 6f 75 74 70 75 74 32 20 22  2 "".  output2 "
94b0: 61 64 64 72 20 20 6f 70 63 6f 64 65 20 20 20 20  addr  opcode    
94c0: 20 20 20 20 70 31 20 20 20 20 20 20 70 32 20 20      p1      p2  
94d0: 20 20 20 20 70 33 20 20 20 20 20 20 70 34 20 20      p3      p4  
94e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 35 20               p5 
94f0: 20 23 22 0a 20 20 6f 75 74 70 75 74 32 20 22 2d   #".  output2 "-
9500: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ---  -----------
9510: 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  -  ------  -----
9520: 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  -  ------  -----
9530: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 20 20  ----------  --  
9540: 2d 22 0a 20 20 24 64 62 20 65 76 61 6c 20 22 65  -".  $db eval "e
9550: 78 70 6c 61 69 6e 20 24 73 71 6c 22 20 7b 7d 20  xplain $sql" {} 
9560: 7b 0a 20 20 20 20 6f 75 74 70 75 74 32 20 5b 66  {.    output2 [f
9570: 6f 72 6d 61 74 20 7b 25 2d 34 64 20 20 25 2d 31  ormat {%-4d  %-1
9580: 32 2e 31 32 73 20 20 25 2d 36 64 20 20 25 2d 36  2.12s  %-6d  %-6
9590: 64 20 20 25 2d 36 64 20 20 25 20 2d 31 37 73 20  d  %-6d  % -17s 
95a0: 25 73 20 20 25 73 7d 20 5c 0a 20 20 20 20 20 20  %s  %s} \.      
95b0: 24 61 64 64 72 20 24 6f 70 63 6f 64 65 20 24 70  $addr $opcode $p
95c0: 31 20 24 70 32 20 24 70 33 20 24 70 34 20 24 70  1 $p2 $p3 $p4 $p
95d0: 35 20 24 63 6f 6d 6d 65 6e 74 0a 20 20 20 20 5d  5 $comment.    ]
95e0: 0a 20 20 7d 0a 7d 0a 0a 70 72 6f 63 20 65 78 70  .  }.}..proc exp
95f0: 6c 61 69 6e 5f 69 20 7b 73 71 6c 20 7b 64 62 20  lain_i {sql {db 
9600: 64 62 7d 7d 20 7b 0a 20 20 6f 75 74 70 75 74 32  db}} {.  output2
9610: 20 22 22 0a 20 20 6f 75 74 70 75 74 32 20 22 61   "".  output2 "a
9620: 64 64 72 20 20 6f 70 63 6f 64 65 20 20 20 20 20  ddr  opcode     
9630: 20 20 20 70 31 20 20 20 20 20 20 70 32 20 20 20     p1      p2   
9640: 20 20 20 70 33 20 20 20 20 20 20 70 34 20 20 20     p3      p4   
9650: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 35 20               p5 
9660: 20 23 22 0a 20 20 6f 75 74 70 75 74 32 20 22 2d   #".  output2 "-
9670: 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ---  -----------
9680: 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  -  ------  -----
9690: 2d 20 20 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d  -  ------  -----
96a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 20  -----------  -- 
96b0: 20 2d 22 0a 0a 0a 20 20 23 20 53 65 74 20 75 70   -"...  # Set up
96c0: 20 63 6f 6c 6f 72 73 20 66 6f 72 20 74 68 65 20   colors for the 
96d0: 64 69 66 66 65 72 65 6e 74 20 6f 70 63 6f 64 65  different opcode
96e0: 73 2e 20 53 63 68 65 6d 65 20 69 73 20 61 73 20  s. Scheme is as 
96f0: 66 6f 6c 6c 6f 77 73 3a 0a 20 20 23 0a 20 20 23  follows:.  #.  #
9700: 20 20 20 52 65 64 3a 20 20 20 4f 70 63 6f 64 65     Red:   Opcode
9710: 73 20 74 68 61 74 20 77 72 69 74 65 20 74 6f 20  s that write to 
9720: 61 20 62 2d 74 72 65 65 2e 0a 20 20 23 20 20 20  a b-tree..  #   
9730: 42 6c 75 65 3a 20 20 4f 70 63 6f 64 65 73 20 74  Blue:  Opcodes t
9740: 68 61 74 20 72 65 70 6f 73 69 74 69 6f 6e 20 6f  hat reposition o
9750: 72 20 73 65 65 6b 20 61 20 63 75 72 73 6f 72 2e  r seek a cursor.
9760: 20 0a 20 20 23 20 20 20 47 72 65 65 6e 3a 20 54   .  #   Green: T
9770: 68 65 20 52 65 73 75 6c 74 52 6f 77 20 6f 70 63  he ResultRow opc
9780: 6f 64 65 2e 0a 20 20 23 0a 20 20 69 66 20 7b 20  ode..  #.  if { 
9790: 5b 63 61 74 63 68 20 7b 66 63 6f 6e 66 69 67 75  [catch {fconfigu
97a0: 72 65 20 73 74 64 6f 75 74 20 2d 6d 6f 64 65 7d  re stdout -mode}
97b0: 5d 3d 3d 30 20 7d 20 7b 0a 20 20 20 20 73 65 74  ]==0 } {.    set
97c0: 20 52 20 22 5c 30 33 33 5c 5b 33 31 3b 31 6d 22   R "\033\[31;1m"
97d0: 20 20 20 20 20 20 20 20 3b 23 20 52 65 64 20 66          ;# Red f
97e0: 67 0a 20 20 20 20 73 65 74 20 47 20 22 5c 30 33  g.    set G "\03
97f0: 33 5c 5b 33 32 3b 31 6d 22 20 20 20 20 20 20 20  3\[32;1m"       
9800: 20 3b 23 20 47 72 65 65 6e 20 66 67 0a 20 20 20   ;# Green fg.   
9810: 20 73 65 74 20 42 20 22 5c 30 33 33 5c 5b 33 34   set B "\033\[34
9820: 3b 31 6d 22 20 20 20 20 20 20 20 20 3b 23 20 52  ;1m"        ;# R
9830: 65 64 20 66 67 0a 20 20 20 20 73 65 74 20 44 20  ed fg.    set D 
9840: 22 5c 30 33 33 5c 5b 33 39 3b 30 6d 22 20 20 20  "\033\[39;0m"   
9850: 20 20 20 20 20 3b 23 20 44 65 66 61 75 6c 74 20       ;# Default 
9860: 66 67 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  fg.  } else {.  
9870: 20 20 73 65 74 20 52 20 22 22 0a 20 20 20 20 73    set R "".    s
9880: 65 74 20 47 20 22 22 0a 20 20 20 20 73 65 74 20  et G "".    set 
9890: 42 20 22 22 0a 20 20 20 20 73 65 74 20 44 20 22  B "".    set D "
98a0: 22 0a 20 20 7d 0a 20 20 66 6f 72 65 61 63 68 20  ".  }.  foreach 
98b0: 6f 70 63 6f 64 65 20 7b 0a 20 20 20 20 20 20 53  opcode {.      S
98c0: 65 65 6b 20 53 65 65 6b 47 45 20 53 65 65 6b 47  eek SeekGE SeekG
98d0: 54 20 53 65 65 6b 4c 45 20 53 65 65 6b 4c 54 20  T SeekLE SeekLT 
98e0: 4e 6f 74 46 6f 75 6e 64 20 4c 61 73 74 20 52 65  NotFound Last Re
98f0: 77 69 6e 64 0a 20 20 20 20 20 20 4e 6f 43 6f 6e  wind.      NoCon
9900: 66 6c 69 63 74 20 4e 65 78 74 20 50 72 65 76 20  flict Next Prev 
9910: 56 4e 65 78 74 20 56 50 72 65 76 20 56 46 69 6c  VNext VPrev VFil
9920: 74 65 72 0a 20 20 20 20 20 20 53 6f 72 74 65 72  ter.      Sorter
9930: 53 6f 72 74 20 53 6f 72 74 65 72 4e 65 78 74 20  Sort SorterNext 
9940: 4e 65 78 74 49 66 4f 70 65 6e 0a 20 20 7d 20 7b  NextIfOpen.  } {
9950: 0a 20 20 20 20 73 65 74 20 63 6f 6c 6f 72 28 24  .    set color($
9960: 6f 70 63 6f 64 65 29 20 24 42 0a 20 20 7d 0a 20  opcode) $B.  }. 
9970: 20 66 6f 72 65 61 63 68 20 6f 70 63 6f 64 65 20   foreach opcode 
9980: 7b 52 65 73 75 6c 74 52 6f 77 7d 20 7b 0a 20 20  {ResultRow} {.  
9990: 20 20 73 65 74 20 63 6f 6c 6f 72 28 24 6f 70 63    set color($opc
99a0: 6f 64 65 29 20 24 47 0a 20 20 7d 0a 20 20 66 6f  ode) $G.  }.  fo
99b0: 72 65 61 63 68 20 6f 70 63 6f 64 65 20 7b 49 64  reach opcode {Id
99c0: 78 49 6e 73 65 72 74 20 49 6e 73 65 72 74 20 44  xInsert Insert D
99d0: 65 6c 65 74 65 20 49 64 78 44 65 6c 65 74 65 7d  elete IdxDelete}
99e0: 20 7b 0a 20 20 20 20 73 65 74 20 63 6f 6c 6f 72   {.    set color
99f0: 28 24 6f 70 63 6f 64 65 29 20 24 52 0a 20 20 7d  ($opcode) $R.  }
9a00: 0a 0a 20 20 73 65 74 20 62 53 65 65 6e 47 6f 74  ..  set bSeenGot
9a10: 6f 20 30 0a 20 20 24 64 62 20 65 76 61 6c 20 22  o 0.  $db eval "
9a20: 65 78 70 6c 61 69 6e 20 24 73 71 6c 22 20 7b 7d  explain $sql" {}
9a30: 20 7b 0a 20 20 20 20 73 65 74 20 78 28 24 61 64   {.    set x($ad
9a40: 64 72 29 20 30 0a 20 20 20 20 73 65 74 20 6f 70  dr) 0.    set op
9a50: 28 24 61 64 64 72 29 20 24 6f 70 63 6f 64 65 0a  ($addr) $opcode.
9a60: 0a 20 20 20 20 69 66 20 7b 24 6f 70 63 6f 64 65  .    if {$opcode
9a70: 20 3d 3d 20 22 47 6f 74 6f 22 20 26 26 20 28 24   == "Goto" && ($
9a80: 62 53 65 65 6e 47 6f 74 6f 3d 3d 30 20 7c 7c 20  bSeenGoto==0 || 
9a90: 28 24 70 32 20 3e 20 24 61 64 64 72 2b 31 30 29  ($p2 > $addr+10)
9aa0: 29 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6c  )} {.      set l
9ab0: 69 6e 65 62 72 65 61 6b 28 24 70 32 29 20 31 0a  inebreak($p2) 1.
9ac0: 20 20 20 20 20 20 73 65 74 20 62 53 65 65 6e 47        set bSeenG
9ad0: 6f 74 6f 20 31 0a 20 20 20 20 7d 0a 0a 20 20 20  oto 1.    }..   
9ae0: 20 69 66 20 7b 24 6f 70 63 6f 64 65 3d 3d 22 4f   if {$opcode=="O
9af0: 6e 63 65 22 7d 20 7b 0a 20 20 20 20 20 20 66 6f  nce"} {.      fo
9b00: 72 20 7b 73 65 74 20 69 20 24 61 64 64 72 7d 20  r {set i $addr} 
9b10: 7b 24 69 3c 24 70 32 7d 20 7b 69 6e 63 72 20 69  {$i<$p2} {incr i
9b20: 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20  } {.        set 
9b30: 73 74 61 72 28 24 69 29 20 24 61 64 64 72 0a 20  star($i) $addr. 
9b40: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
9b50: 20 20 69 66 20 7b 24 6f 70 63 6f 64 65 3d 3d 22    if {$opcode=="
9b60: 4e 65 78 74 22 20 20 7c 7c 20 24 6f 70 63 6f 64  Next"  || $opcod
9b70: 65 3d 3d 22 50 72 65 76 22 20 0a 20 20 20 20 20  e=="Prev" .     
9b80: 7c 7c 20 24 6f 70 63 6f 64 65 3d 3d 22 56 4e 65  || $opcode=="VNe
9b90: 78 74 22 20 7c 7c 20 24 6f 70 63 6f 64 65 3d 3d  xt" || $opcode==
9ba0: 22 56 50 72 65 76 22 0a 20 20 20 20 20 7c 7c 20  "VPrev".     || 
9bb0: 24 6f 70 63 6f 64 65 3d 3d 22 53 6f 72 74 65 72  $opcode=="Sorter
9bc0: 4e 65 78 74 22 20 7c 7c 20 24 6f 70 63 6f 64 65  Next" || $opcode
9bd0: 3d 3d 22 4e 65 78 74 49 66 4f 70 65 6e 22 0a 20  =="NextIfOpen". 
9be0: 20 20 20 7d 20 7b 0a 20 20 20 20 20 20 66 6f 72     } {.      for
9bf0: 20 7b 73 65 74 20 69 20 24 70 32 7d 20 7b 24 69   {set i $p2} {$i
9c00: 3c 24 61 64 64 72 7d 20 7b 69 6e 63 72 20 69 7d  <$addr} {incr i}
9c10: 20 7b 0a 20 20 20 20 20 20 20 20 69 6e 63 72 20   {.        incr 
9c20: 78 28 24 69 29 20 32 0a 20 20 20 20 20 20 7d 0a  x($i) 2.      }.
9c30: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24      }..    if {$
9c40: 6f 70 63 6f 64 65 20 3d 3d 20 22 47 6f 74 6f 22  opcode == "Goto"
9c50: 20 26 26 20 24 70 32 3c 24 61 64 64 72 20 26 26   && $p2<$addr &&
9c60: 20 24 6f 70 28 24 70 32 29 3d 3d 22 59 69 65 6c   $op($p2)=="Yiel
9c70: 64 22 7d 20 7b 0a 20 20 20 20 20 20 66 6f 72 20  d"} {.      for 
9c80: 7b 73 65 74 20 69 20 5b 65 78 70 72 20 24 70 32  {set i [expr $p2
9c90: 2b 31 5d 7d 20 7b 24 69 3c 24 61 64 64 72 7d 20  +1]} {$i<$addr} 
9ca0: 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20  {incr i} {.     
9cb0: 20 20 20 69 6e 63 72 20 78 28 24 69 29 20 32 0a     incr x($i) 2.
9cc0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
9cd0: 20 20 20 69 66 20 7b 24 6f 70 63 6f 64 65 20 3d     if {$opcode =
9ce0: 3d 20 22 48 61 6c 74 22 20 26 26 20 24 63 6f 6d  = "Halt" && $com
9cf0: 6d 65 6e 74 20 3d 3d 20 22 45 6e 64 20 6f 66 20  ment == "End of 
9d00: 63 6f 72 6f 75 74 69 6e 65 22 7d 20 7b 0a 20 20  coroutine"} {.  
9d10: 20 20 20 20 73 65 74 20 6c 69 6e 65 62 72 65 61      set linebrea
9d20: 6b 28 5b 65 78 70 72 20 24 61 64 64 72 2b 31 5d  k([expr $addr+1]
9d30: 29 20 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  ) 1.    }.  }.. 
9d40: 20 24 64 62 20 65 76 61 6c 20 22 65 78 70 6c 61   $db eval "expla
9d50: 69 6e 20 24 73 71 6c 22 20 7b 7d 20 7b 0a 20 20  in $sql" {} {.  
9d60: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
9d70: 74 73 20 6c 69 6e 65 62 72 65 61 6b 28 24 61 64  ts linebreak($ad
9d80: 64 72 29 5d 7d 20 7b 0a 20 20 20 20 20 20 6f 75  dr)]} {.      ou
9d90: 74 70 75 74 32 20 22 22 0a 20 20 20 20 7d 0a 20  tput2 "".    }. 
9da0: 20 20 20 73 65 74 20 49 20 5b 73 74 72 69 6e 67     set I [string
9db0: 20 72 65 70 65 61 74 20 22 20 22 20 24 78 28 24   repeat " " $x($
9dc0: 61 64 64 72 29 5d 0a 0a 20 20 20 20 69 66 20 7b  addr)]..    if {
9dd0: 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 73 74 61  [info exists sta
9de0: 72 28 24 61 64 64 72 29 5d 7d 20 7b 0a 20 20 20  r($addr)]} {.   
9df0: 20 20 20 73 65 74 20 69 69 20 5b 65 78 70 72 20     set ii [expr 
9e00: 24 78 28 24 73 74 61 72 28 24 61 64 64 72 29 29  $x($star($addr))
9e10: 5d 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20 49  ].      append I
9e20: 20 22 20 20 22 0a 20 20 20 20 20 20 73 65 74 20   "  ".      set 
9e30: 49 20 5b 73 74 72 69 6e 67 20 72 65 70 6c 61 63  I [string replac
9e40: 65 20 24 49 20 24 69 69 20 24 69 69 20 2a 5d 0a  e $I $ii $ii *].
9e50: 20 20 20 20 7d 0a 0a 20 20 20 20 73 65 74 20 63      }..    set c
9e60: 6f 6c 20 22 22 0a 20 20 20 20 63 61 74 63 68 20  ol "".    catch 
9e70: 7b 20 73 65 74 20 63 6f 6c 20 24 63 6f 6c 6f 72  { set col $color
9e80: 28 24 6f 70 63 6f 64 65 29 20 7d 0a 0a 20 20 20  ($opcode) }..   
9e90: 20 6f 75 74 70 75 74 32 20 5b 66 6f 72 6d 61 74   output2 [format
9ea0: 20 7b 25 2d 34 64 20 20 25 73 25 73 25 2d 31 32   {%-4d  %s%s%-12
9eb0: 2e 31 32 73 25 73 20 20 25 2d 36 64 20 20 25 2d  .12s%s  %-6d  %-
9ec0: 36 64 20 20 25 2d 36 64 20 20 25 20 2d 31 37 73  6d  %-6d  % -17s
9ed0: 20 25 73 20 20 25 73 7d 20 5c 0a 20 20 20 20 20   %s  %s} \.     
9ee0: 20 24 61 64 64 72 20 24 49 20 24 63 6f 6c 20 24   $addr $I $col $
9ef0: 6f 70 63 6f 64 65 20 24 44 20 24 70 31 20 24 70  opcode $D $p1 $p
9f00: 32 20 24 70 33 20 24 70 34 20 24 70 35 20 24 63  2 $p3 $p4 $p5 $c
9f10: 6f 6d 6d 65 6e 74 0a 20 20 20 20 5d 0a 20 20 7d  omment.    ].  }
9f20: 0a 20 20 6f 75 74 70 75 74 32 20 22 2d 2d 2d 2d  .  output2 "----
9f30: 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20    ------------  
9f40: 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 20 20  ------  ------  
9f50: 2d 2d 2d 2d 2d 2d 20 20 2d 2d 2d 2d 2d 2d 2d 2d  ------  --------
9f60: 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d 2d 20 20 2d 22  --------  --  -"
9f70: 0a 7d 0a 0a 23 20 53 68 6f 77 20 74 68 65 20 56  .}..# Show the V
9f80: 44 42 45 20 70 72 6f 67 72 61 6d 20 66 6f 72 20  DBE program for 
9f90: 61 6e 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  an SQL statement
9fa0: 20 62 75 74 20 6f 6d 69 74 20 74 68 65 20 54 72   but omit the Tr
9fb0: 61 63 65 0a 23 20 6f 70 63 6f 64 65 20 61 74 20  ace.# opcode at 
9fc0: 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 2e 20 20  the beginning.  
9fd0: 54 68 69 73 20 70 72 6f 63 65 64 75 72 65 20 63  This procedure c
9fe0: 61 6e 20 62 65 20 75 73 65 64 20 74 6f 20 70 72  an be used to pr
9ff0: 6f 76 65 0a 23 20 74 68 61 74 20 64 69 66 66 65  ove.# that diffe
a000: 72 65 6e 74 20 53 51 4c 20 73 74 61 74 65 6d 65  rent SQL stateme
a010: 6e 74 73 20 67 65 6e 65 72 61 74 65 20 65 78 61  nts generate exa
a020: 63 74 6c 79 20 74 68 65 20 73 61 6d 65 20 56 44  ctly the same VD
a030: 42 45 20 63 6f 64 65 2e 0a 23 0a 70 72 6f 63 20  BE code..#.proc 
a040: 65 78 70 6c 61 69 6e 5f 6e 6f 5f 74 72 61 63 65  explain_no_trace
a050: 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20 74   {sql} {.  set t
a060: 72 20 5b 64 62 20 65 76 61 6c 20 22 45 58 50 4c  r [db eval "EXPL
a070: 41 49 4e 20 24 73 71 6c 22 5d 0a 20 20 72 65 74  AIN $sql"].  ret
a080: 75 72 6e 20 5b 6c 72 61 6e 67 65 20 24 74 72 20  urn [lrange $tr 
a090: 37 20 65 6e 64 5d 0a 7d 0a 0a 23 20 41 6e 6f 74  7 end].}..# Anot
a0a0: 68 65 72 20 70 72 6f 63 65 64 75 72 65 20 74 6f  her procedure to
a0b0: 20 65 78 65 63 75 74 65 20 53 51 4c 2e 20 20 54   execute SQL.  T
a0c0: 68 69 73 20 6f 6e 65 20 69 6e 63 6c 75 64 65 73  his one includes
a0d0: 20 74 68 65 20 66 69 65 6c 64 0a 23 20 6e 61 6d   the field.# nam
a0e0: 65 73 20 69 6e 20 74 68 65 20 72 65 74 75 72 6e  es in the return
a0f0: 65 64 20 6c 69 73 74 2e 0a 23 0a 70 72 6f 63 20  ed list..#.proc 
a100: 65 78 65 63 73 71 6c 32 20 7b 73 71 6c 7d 20 7b  execsql2 {sql} {
a110: 0a 20 20 73 65 74 20 72 65 73 75 6c 74 20 7b 7d  .  set result {}
a120: 0a 20 20 64 62 20 65 76 61 6c 20 24 73 71 6c 20  .  db eval $sql 
a130: 64 61 74 61 20 7b 0a 20 20 20 20 66 6f 72 65 61  data {.    forea
a140: 63 68 20 66 20 24 64 61 74 61 28 2a 29 20 7b 0a  ch f $data(*) {.
a150: 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20 72 65        lappend re
a160: 73 75 6c 74 20 24 66 20 24 64 61 74 61 28 24 66  sult $f $data($f
a170: 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ).    }.  }.  re
a180: 74 75 72 6e 20 24 72 65 73 75 6c 74 0a 7d 0a 0a  turn $result.}..
a190: 23 20 55 73 65 20 61 20 74 65 6d 70 6f 72 61 72  # Use a temporar
a1a0: 79 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61  y in-memory data
a1b0: 62 61 73 65 20 74 6f 20 65 78 65 63 75 74 65 20  base to execute 
a1c0: 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 73 0a 23  SQL statements.#
a1d0: 0a 70 72 6f 63 20 6d 65 6d 64 62 73 71 6c 20 7b  .proc memdbsql {
a1e0: 73 71 6c 7d 20 7b 0a 20 20 73 71 6c 69 74 65 33  sql} {.  sqlite3
a1f0: 20 6d 65 6d 64 62 20 3a 6d 65 6d 6f 72 79 3a 0a   memdb :memory:.
a200: 20 20 73 65 74 20 72 65 73 75 6c 74 20 5b 6d 65    set result [me
a210: 6d 64 62 20 65 76 61 6c 20 24 73 71 6c 5d 0a 20  mdb eval $sql]. 
a220: 20 6d 65 6d 64 62 20 63 6c 6f 73 65 0a 20 20 72   memdb close.  r
a230: 65 74 75 72 6e 20 24 72 65 73 75 6c 74 0a 7d 0a  eturn $result.}.
a240: 0a 23 20 55 73 65 20 74 68 65 20 6e 6f 6e 2d 63  .# Use the non-c
a250: 61 6c 6c 62 61 63 6b 20 41 50 49 20 74 6f 20 65  allback API to e
a260: 78 65 63 75 74 65 20 6d 75 6c 74 69 70 6c 65 20  xecute multiple 
a270: 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 73 0a 23  SQL statements.#
a280: 0a 70 72 6f 63 20 73 74 65 70 73 71 6c 20 7b 64  .proc stepsql {d
a290: 62 70 74 72 20 73 71 6c 7d 20 7b 0a 20 20 73 65  bptr sql} {.  se
a2a0: 74 20 73 71 6c 20 5b 73 74 72 69 6e 67 20 74 72  t sql [string tr
a2b0: 69 6d 20 24 73 71 6c 5d 0a 20 20 73 65 74 20 72  im $sql].  set r
a2c0: 20 30 0a 20 20 77 68 69 6c 65 20 7b 5b 73 74 72   0.  while {[str
a2d0: 69 6e 67 20 6c 65 6e 67 74 68 20 24 73 71 6c 5d  ing length $sql]
a2e0: 3e 30 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 63  >0} {.    if {[c
a2f0: 61 74 63 68 20 7b 73 71 6c 69 74 65 33 5f 70 72  atch {sqlite3_pr
a300: 65 70 61 72 65 20 24 64 62 70 74 72 20 24 73 71  epare $dbptr $sq
a310: 6c 20 2d 31 20 73 71 6c 74 61 69 6c 7d 20 76 6d  l -1 sqltail} vm
a320: 5d 7d 20 7b 0a 20 20 20 20 20 20 72 65 74 75 72  ]} {.      retur
a330: 6e 20 5b 6c 69 73 74 20 31 20 24 76 6d 5d 0a 20  n [list 1 $vm]. 
a340: 20 20 20 7d 0a 20 20 20 20 73 65 74 20 73 71 6c     }.    set sql
a350: 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 24 73   [string trim $s
a360: 71 6c 74 61 69 6c 5d 0a 23 20 20 20 20 77 68 69  qltail].#    whi
a370: 6c 65 20 7b 5b 73 71 6c 69 74 65 5f 73 74 65 70  le {[sqlite_step
a380: 20 24 76 6d 20 4e 20 56 41 4c 20 43 4f 4c 5d 3d   $vm N VAL COL]=
a390: 3d 22 53 51 4c 49 54 45 5f 52 4f 57 22 7d 20 7b  ="SQLITE_ROW"} {
a3a0: 0a 23 20 20 20 20 20 20 66 6f 72 65 61 63 68 20  .#      foreach 
a3b0: 76 20 24 56 41 4c 20 7b 6c 61 70 70 65 6e 64 20  v $VAL {lappend 
a3c0: 72 20 24 76 7d 0a 23 20 20 20 20 7d 0a 20 20 20  r $v}.#    }.   
a3d0: 20 77 68 69 6c 65 20 7b 5b 73 71 6c 69 74 65 33   while {[sqlite3
a3e0: 5f 73 74 65 70 20 24 76 6d 5d 3d 3d 22 53 51 4c  _step $vm]=="SQL
a3f0: 49 54 45 5f 52 4f 57 22 7d 20 7b 0a 20 20 20 20  ITE_ROW"} {.    
a400: 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30 7d 20    for {set i 0} 
a410: 7b 24 69 3c 5b 73 71 6c 69 74 65 33 5f 64 61 74  {$i<[sqlite3_dat
a420: 61 5f 63 6f 75 6e 74 20 24 76 6d 5d 7d 20 7b 69  a_count $vm]} {i
a430: 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 20  ncr i} {.       
a440: 20 6c 61 70 70 65 6e 64 20 72 20 5b 73 71 6c 69   lappend r [sqli
a450: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 20  te3_column_text 
a460: 24 76 6d 20 24 69 5d 0a 20 20 20 20 20 20 7d 0a  $vm $i].      }.
a470: 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b 5b 63      }.    if {[c
a480: 61 74 63 68 20 7b 73 71 6c 69 74 65 33 5f 66 69  atch {sqlite3_fi
a490: 6e 61 6c 69 7a 65 20 24 76 6d 7d 20 65 72 72 6d  nalize $vm} errm
a4a0: 73 67 5d 7d 20 7b 0a 20 20 20 20 20 20 72 65 74  sg]} {.      ret
a4b0: 75 72 6e 20 5b 6c 69 73 74 20 31 20 24 65 72 72  urn [list 1 $err
a4c0: 6d 73 67 5d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  msg].    }.  }. 
a4d0: 20 72 65 74 75 72 6e 20 24 72 0a 7d 0a 0a 23 20   return $r.}..# 
a4e0: 44 6f 20 61 6e 20 69 6e 74 65 67 72 69 74 79 20  Do an integrity 
a4f0: 63 68 65 63 6b 20 6f 66 20 74 68 65 20 65 6e 74  check of the ent
a500: 69 72 65 20 64 61 74 61 62 61 73 65 0a 23 0a 70  ire database.#.p
a510: 72 6f 63 20 69 6e 74 65 67 72 69 74 79 5f 63 68  roc integrity_ch
a520: 65 63 6b 20 7b 6e 61 6d 65 20 7b 64 62 20 64 62  eck {name {db db
a530: 7d 7d 20 7b 0a 20 20 69 66 63 61 70 61 62 6c 65  }} {.  ifcapable
a540: 20 69 6e 74 65 67 72 69 74 79 63 6b 20 7b 0a 20   integrityck {. 
a550: 20 20 20 64 6f 5f 74 65 73 74 20 24 6e 61 6d 65     do_test $name
a560: 20 5b 6c 69 73 74 20 65 78 65 63 73 71 6c 20 7b   [list execsql {
a570: 50 52 41 47 4d 41 20 69 6e 74 65 67 72 69 74 79  PRAGMA integrity
a580: 5f 63 68 65 63 6b 7d 20 24 64 62 5d 20 7b 6f 6b  _check} $db] {ok
a590: 7d 0a 20 20 7d 0a 7d 0a 0a 23 20 43 68 65 63 6b  }.  }.}..# Check
a5a0: 20 74 68 65 20 65 78 74 65 6e 64 65 64 20 65 72   the extended er
a5b0: 72 6f 72 20 63 6f 64 65 0a 23 0a 70 72 6f 63 20  ror code.#.proc 
a5c0: 76 65 72 69 66 79 5f 65 78 5f 65 72 72 63 6f 64  verify_ex_errcod
a5d0: 65 20 7b 6e 61 6d 65 20 65 78 70 65 63 74 65 64  e {name expected
a5e0: 20 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 64 6f   {db db}} {.  do
a5f0: 5f 74 65 73 74 20 24 6e 61 6d 65 20 5b 6c 69 73  _test $name [lis
a600: 74 20 73 71 6c 69 74 65 33 5f 65 78 74 65 6e 64  t sqlite3_extend
a610: 65 64 5f 65 72 72 63 6f 64 65 20 24 64 62 5d 20  ed_errcode $db] 
a620: 24 65 78 70 65 63 74 65 64 0a 7d 0a 0a 0a 23 20  $expected.}...# 
a630: 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 74  Return true if t
a640: 68 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74  he SQL statement
a650: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73   passed as the s
a660: 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 75  econd argument u
a670: 73 65 73 20 61 0a 23 20 73 74 61 74 65 6d 65 6e  ses a.# statemen
a680: 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 23  t transaction..#
a690: 0a 70 72 6f 63 20 73 71 6c 5f 75 73 65 73 5f 73  .proc sql_uses_s
a6a0: 74 6d 74 20 7b 64 62 20 73 71 6c 7d 20 7b 0a 20  tmt {db sql} {. 
a6b0: 20 73 65 74 20 73 74 6d 74 20 5b 73 71 6c 69 74   set stmt [sqlit
a6c0: 65 33 5f 70 72 65 70 61 72 65 20 24 64 62 20 24  e3_prepare $db $
a6d0: 73 71 6c 20 2d 31 20 64 75 6d 6d 79 5d 0a 20 20  sql -1 dummy].  
a6e0: 73 65 74 20 75 73 65 73 20 5b 75 73 65 73 5f 73  set uses [uses_s
a6f0: 74 6d 74 5f 6a 6f 75 72 6e 61 6c 20 24 73 74 6d  tmt_journal $stm
a700: 74 5d 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e  t].  sqlite3_fin
a710: 61 6c 69 7a 65 20 24 73 74 6d 74 0a 20 20 72 65  alize $stmt.  re
a720: 74 75 72 6e 20 24 75 73 65 73 0a 7d 0a 0a 70 72  turn $uses.}..pr
a730: 6f 63 20 66 69 78 5f 69 66 63 61 70 61 62 6c 65  oc fix_ifcapable
a740: 5f 65 78 70 72 20 7b 65 78 70 72 7d 20 7b 0a 20  _expr {expr} {. 
a750: 20 73 65 74 20 72 65 74 20 22 22 0a 20 20 73 65   set ret "".  se
a760: 74 20 73 74 61 74 65 20 30 0a 20 20 66 6f 72 20  t state 0.  for 
a770: 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20  {set i 0} {$i < 
a780: 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24  [string length $
a790: 65 78 70 72 5d 7d 20 7b 69 6e 63 72 20 69 7d 20  expr]} {incr i} 
a7a0: 7b 0a 20 20 20 20 73 65 74 20 63 68 61 72 20 5b  {.    set char [
a7b0: 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 65 78  string range $ex
a7c0: 70 72 20 24 69 20 24 69 5d 0a 20 20 20 20 73 65  pr $i $i].    se
a7d0: 74 20 6e 65 77 73 74 61 74 65 20 5b 65 78 70 72  t newstate [expr
a7e0: 20 7b 5b 73 74 72 69 6e 67 20 69 73 20 61 6c 6e   {[string is aln
a7f0: 75 6d 20 24 63 68 61 72 5d 20 7c 7c 20 24 63 68  um $char] || $ch
a800: 61 72 20 65 71 20 22 5f 22 7d 5d 0a 20 20 20 20  ar eq "_"}].    
a810: 69 66 20 7b 24 6e 65 77 73 74 61 74 65 20 26 26  if {$newstate &&
a820: 20 21 24 73 74 61 74 65 7d 20 7b 0a 20 20 20 20   !$state} {.    
a830: 20 20 61 70 70 65 6e 64 20 72 65 74 20 7b 24 3a    append ret {$:
a840: 3a 73 71 6c 69 74 65 5f 6f 70 74 69 6f 6e 73 28  :sqlite_options(
a850: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b  }.    }.    if {
a860: 21 24 6e 65 77 73 74 61 74 65 20 26 26 20 24 73  !$newstate && $s
a870: 74 61 74 65 7d 20 7b 0a 20 20 20 20 20 20 61 70  tate} {.      ap
a880: 70 65 6e 64 20 72 65 74 20 29 0a 20 20 20 20 7d  pend ret ).    }
a890: 0a 20 20 20 20 61 70 70 65 6e 64 20 72 65 74 20  .    append ret 
a8a0: 24 63 68 61 72 0a 20 20 20 20 73 65 74 20 73 74  $char.    set st
a8b0: 61 74 65 20 24 6e 65 77 73 74 61 74 65 0a 20 20  ate $newstate.  
a8c0: 7d 0a 20 20 69 66 20 7b 24 73 74 61 74 65 7d 20  }.  if {$state} 
a8d0: 7b 61 70 70 65 6e 64 20 72 65 74 20 29 7d 0a 20  {append ret )}. 
a8e0: 20 72 65 74 75 72 6e 20 24 72 65 74 0a 7d 0a 0a   return $ret.}..
a8f0: 23 20 52 65 74 75 72 6e 73 20 6e 6f 6e 2d 7a 65  # Returns non-ze
a900: 72 6f 20 69 66 20 74 68 65 20 63 61 70 61 62 69  ro if the capabi
a910: 6c 69 74 69 65 73 20 61 72 65 20 70 72 65 73 65  lities are prese
a920: 6e 74 3b 20 7a 65 72 6f 20 6f 74 68 65 72 77 69  nt; zero otherwi
a930: 73 65 2e 0a 23 0a 70 72 6f 63 20 63 61 70 61 62  se..#.proc capab
a940: 6c 65 20 7b 65 78 70 72 7d 20 7b 0a 20 20 73 65  le {expr} {.  se
a950: 74 20 65 20 5b 66 69 78 5f 69 66 63 61 70 61 62  t e [fix_ifcapab
a960: 6c 65 5f 65 78 70 72 20 24 65 78 70 72 5d 3b 20  le_expr $expr]; 
a970: 72 65 74 75 72 6e 20 5b 65 78 70 72 20 28 24 65  return [expr ($e
a980: 29 5d 0a 7d 0a 0a 23 20 45 76 61 6c 75 61 74 65  )].}..# Evaluate
a990: 20 61 20 62 6f 6f 6c 65 61 6e 20 65 78 70 72 65   a boolean expre
a9a0: 73 73 69 6f 6e 20 6f 66 20 63 61 70 61 62 69 6c  ssion of capabil
a9b0: 69 74 69 65 73 2e 20 20 49 66 20 74 72 75 65 2c  ities.  If true,
a9c0: 20 65 78 65 63 75 74 65 20 74 68 65 0a 23 20 63   execute the.# c
a9d0: 6f 64 65 2e 20 20 4f 6d 69 74 20 74 68 65 20 63  ode.  Omit the c
a9e0: 6f 64 65 20 69 66 20 66 61 6c 73 65 2e 0a 23 0a  ode if false..#.
a9f0: 70 72 6f 63 20 69 66 63 61 70 61 62 6c 65 20 7b  proc ifcapable {
aa00: 65 78 70 72 20 63 6f 64 65 20 7b 65 6c 73 65 20  expr code {else 
aa10: 22 22 7d 20 7b 65 6c 73 65 63 6f 64 65 20 22 22  ""} {elsecode ""
aa20: 7d 7d 20 7b 0a 20 20 23 72 65 67 73 75 62 20 2d  }} {.  #regsub -
aa30: 61 6c 6c 20 7b 5b 61 2d 7a 5f 30 2d 39 5d 2b 7d  all {[a-z_0-9]+}
aa40: 20 24 65 78 70 72 20 7b 24 3a 3a 73 71 6c 69 74   $expr {$::sqlit
aa50: 65 5f 6f 70 74 69 6f 6e 73 28 26 29 7d 20 65 32  e_options(&)} e2
aa60: 0a 20 20 73 65 74 20 65 32 20 5b 66 69 78 5f 69  .  set e2 [fix_i
aa70: 66 63 61 70 61 62 6c 65 5f 65 78 70 72 20 24 65  fcapable_expr $e
aa80: 78 70 72 5d 0a 20 20 69 66 20 28 24 65 32 29 20  xpr].  if ($e2) 
aa90: 7b 0a 20 20 20 20 73 65 74 20 63 20 5b 63 61 74  {.    set c [cat
aaa0: 63 68 20 7b 75 70 6c 65 76 65 6c 20 31 20 24 63  ch {uplevel 1 $c
aab0: 6f 64 65 7d 20 72 5d 0a 20 20 7d 20 65 6c 73 65  ode} r].  } else
aac0: 20 7b 0a 20 20 20 20 73 65 74 20 63 20 5b 63 61   {.    set c [ca
aad0: 74 63 68 20 7b 75 70 6c 65 76 65 6c 20 31 20 24  tch {uplevel 1 $
aae0: 65 6c 73 65 63 6f 64 65 7d 20 72 5d 0a 20 20 7d  elsecode} r].  }
aaf0: 0a 20 20 72 65 74 75 72 6e 20 2d 63 6f 64 65 20  .  return -code 
ab00: 24 63 20 24 72 0a 7d 0a 0a 23 20 54 68 69 73 20  $c $r.}..# This 
ab10: 70 72 6f 63 20 65 78 65 63 73 20 61 20 73 65 70  proc execs a sep
ab20: 65 72 61 74 65 20 70 72 6f 63 65 73 73 20 74 68  erate process th
ab30: 61 74 20 63 72 61 73 68 65 73 20 6d 69 64 77 61  at crashes midwa
ab40: 79 20 74 68 72 6f 75 67 68 20 65 78 65 63 75 74  y through execut
ab50: 69 6e 67 0a 23 20 74 68 65 20 53 51 4c 20 73 63  ing.# the SQL sc
ab60: 72 69 70 74 20 24 73 71 6c 20 6f 6e 20 64 61 74  ript $sql on dat
ab70: 61 62 61 73 65 20 74 65 73 74 2e 64 62 2e 0a 23  abase test.db..#
ab80: 0a 23 20 54 68 65 20 63 72 61 73 68 20 6f 63 63  .# The crash occ
ab90: 75 72 73 20 64 75 72 69 6e 67 20 61 20 73 79 6e  urs during a syn
aba0: 63 28 29 20 6f 66 20 66 69 6c 65 20 24 63 72 61  c() of file $cra
abb0: 73 68 66 69 6c 65 2e 20 57 68 65 6e 20 74 68 65  shfile. When the
abc0: 20 63 72 61 73 68 0a 23 20 6f 63 63 75 72 73 20   crash.# occurs 
abd0: 61 20 72 61 6e 64 6f 6d 20 73 75 62 73 65 74 20  a random subset 
abe0: 6f 66 20 61 6c 6c 20 75 6e 73 79 6e 63 65 64 20  of all unsynced 
abf0: 77 72 69 74 65 73 20 6d 61 64 65 20 62 79 20 74  writes made by t
ac00: 68 65 20 70 72 6f 63 65 73 73 20 61 72 65 0a 23  he process are.#
ac10: 20 77 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68   written into th
ac20: 65 20 66 69 6c 65 73 20 6f 6e 20 64 69 73 6b 2e  e files on disk.
ac30: 20 41 72 67 75 6d 65 6e 74 20 24 63 72 61 73 68   Argument $crash
ac40: 64 65 6c 61 79 20 69 6e 64 69 63 61 74 65 73 20  delay indicates 
ac50: 74 68 65 0a 23 20 6e 75 6d 62 65 72 20 6f 66 20  the.# number of 
ac60: 66 69 6c 65 20 73 79 6e 63 73 20 74 6f 20 77 61  file syncs to wa
ac70: 69 74 20 62 65 66 6f 72 65 20 63 72 61 73 68 69  it before crashi
ac80: 6e 67 2e 0a 23 0a 23 20 54 68 65 20 72 65 74 75  ng..#.# The retu
ac90: 72 6e 20 76 61 6c 75 65 20 69 73 20 61 20 6c 69  rn value is a li
aca0: 73 74 20 6f 66 20 74 77 6f 20 65 6c 65 6d 65 6e  st of two elemen
acb0: 74 73 2e 20 54 68 65 20 66 69 72 73 74 20 65 6c  ts. The first el
acc0: 65 6d 65 6e 74 20 69 73 20 61 0a 23 20 62 6f 6f  ement is a.# boo
acd0: 6c 65 61 6e 2c 20 69 6e 64 69 63 61 74 69 6e 67  lean, indicating
ace0: 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f 74 20   whether or not 
acf0: 74 68 65 20 70 72 6f 63 65 73 73 20 61 63 74 75  the process actu
ad00: 61 6c 6c 79 20 63 72 61 73 68 65 64 20 6f 72 0a  ally crashed or.
ad10: 23 20 72 65 70 6f 72 74 65 64 20 73 6f 6d 65 20  # reported some 
ad20: 6f 74 68 65 72 20 65 72 72 6f 72 2e 20 54 68 65  other error. The
ad30: 20 73 65 63 6f 6e 64 20 65 6c 65 6d 65 6e 74 20   second element 
ad40: 69 6e 20 74 68 65 20 72 65 74 75 72 6e 65 64 20  in the returned 
ad50: 6c 69 73 74 20 69 73 20 74 68 65 0a 23 20 65 72  list is the.# er
ad60: 72 6f 72 20 6d 65 73 73 61 67 65 2e 20 54 68 69  ror message. Thi
ad70: 73 20 69 73 20 22 63 68 69 6c 64 20 70 72 6f 63  s is "child proc
ad80: 65 73 73 20 65 78 69 74 65 64 20 61 62 6e 6f 72  ess exited abnor
ad90: 6d 61 6c 6c 79 22 20 69 66 20 74 68 65 20 63 72  mally" if the cr
ada0: 61 73 68 0a 23 20 6f 63 63 75 72 72 65 64 2e 0a  ash.# occurred..
adb0: 23 0a 23 20 20 20 63 72 61 73 68 73 71 6c 20 2d  #.#   crashsql -
adc0: 64 65 6c 61 79 20 43 52 41 53 48 44 45 4c 41 59  delay CRASHDELAY
add0: 20 2d 66 69 6c 65 20 43 52 41 53 48 46 49 4c 45   -file CRASHFILE
ade0: 20 3f 2d 62 6c 6f 63 6b 73 69 7a 65 20 42 4c 4f   ?-blocksize BLO
adf0: 43 4b 53 49 5a 45 3f 20 24 73 71 6c 0a 23 0a 70  CKSIZE? $sql.#.p
ae00: 72 6f 63 20 63 72 61 73 68 73 71 6c 20 7b 61 72  roc crashsql {ar
ae10: 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20 62 6c 6f  gs} {..  set blo
ae20: 63 6b 73 69 7a 65 20 22 22 0a 20 20 73 65 74 20  cksize "".  set 
ae30: 63 72 61 73 68 64 65 6c 61 79 20 31 0a 20 20 73  crashdelay 1.  s
ae40: 65 74 20 70 72 6e 67 73 65 65 64 20 30 0a 20 20  et prngseed 0.  
ae50: 73 65 74 20 6f 70 65 6e 64 62 20 7b 20 73 71 6c  set opendb { sql
ae60: 69 74 65 33 20 64 62 20 74 65 73 74 2e 64 62 20  ite3 db test.db 
ae70: 2d 76 66 73 20 63 72 61 73 68 20 7d 0a 20 20 73  -vfs crash }.  s
ae80: 65 74 20 74 63 6c 62 6f 64 79 20 7b 7d 0a 20 20  et tclbody {}.  
ae90: 73 65 74 20 63 72 61 73 68 66 69 6c 65 20 22 22  set crashfile ""
aea0: 0a 20 20 73 65 74 20 64 63 20 22 22 0a 20 20 73  .  set dc "".  s
aeb0: 65 74 20 73 71 6c 20 5b 6c 69 6e 64 65 78 20 24  et sql [lindex $
aec0: 61 72 67 73 20 65 6e 64 5d 0a 0a 20 20 66 6f 72  args end]..  for
aed0: 20 7b 73 65 74 20 69 69 20 30 7d 20 7b 24 69 69   {set ii 0} {$ii
aee0: 20 3c 20 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67   < [llength $arg
aef0: 73 5d 2d 31 7d 20 7b 69 6e 63 72 20 69 69 20 32  s]-1} {incr ii 2
af00: 7d 20 7b 0a 20 20 20 20 73 65 74 20 7a 20 5b 6c  } {.    set z [l
af10: 69 6e 64 65 78 20 24 61 72 67 73 20 24 69 69 5d  index $args $ii]
af20: 0a 20 20 20 20 73 65 74 20 6e 20 5b 73 74 72 69  .    set n [stri
af30: 6e 67 20 6c 65 6e 67 74 68 20 24 7a 5d 0a 20 20  ng length $z].  
af40: 20 20 73 65 74 20 7a 32 20 5b 6c 69 6e 64 65 78    set z2 [lindex
af50: 20 24 61 72 67 73 20 5b 65 78 70 72 20 24 69 69   $args [expr $ii
af60: 2b 31 5d 5d 0a 0a 20 20 20 20 69 66 20 20 20 20  +1]]..    if    
af70: 20 7b 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e   {$n>1 && [strin
af80: 67 20 66 69 72 73 74 20 24 7a 20 2d 64 65 6c 61  g first $z -dela
af90: 79 5d 3d 3d 30 7d 20 20 20 20 20 7b 73 65 74 20  y]==0}     {set 
afa0: 63 72 61 73 68 64 65 6c 61 79 20 24 7a 32 7d 20  crashdelay $z2} 
afb0: 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e  \.    elseif {$n
afc0: 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69  >1 && [string fi
afd0: 72 73 74 20 24 7a 20 2d 6f 70 65 6e 64 62 5d 3d  rst $z -opendb]=
afe0: 3d 30 7d 20 20 20 20 7b 73 65 74 20 6f 70 65 6e  =0}    {set open
aff0: 64 62 20 24 7a 32 7d 20 5c 0a 20 20 20 20 65 6c  db $z2} \.    el
b000: 73 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73  seif {$n>1 && [s
b010: 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d  tring first $z -
b020: 73 65 65 64 5d 3d 3d 30 7d 20 20 20 20 20 20 7b  seed]==0}      {
b030: 73 65 74 20 70 72 6e 67 73 65 65 64 20 24 7a 32  set prngseed $z2
b040: 7d 20 5c 0a 20 20 20 20 65 6c 73 65 69 66 20 7b  } \.    elseif {
b050: 24 6e 3e 31 20 26 26 20 5b 73 74 72 69 6e 67 20  $n>1 && [string 
b060: 66 69 72 73 74 20 24 7a 20 2d 66 69 6c 65 5d 3d  first $z -file]=
b070: 3d 30 7d 20 20 20 20 20 20 7b 73 65 74 20 63 72  =0}      {set cr
b080: 61 73 68 66 69 6c 65 20 24 7a 32 7d 20 20 5c 0a  ashfile $z2}  \.
b090: 20 20 20 20 65 6c 73 65 69 66 20 7b 24 6e 3e 31      elseif {$n>1
b0a0: 20 26 26 20 5b 73 74 72 69 6e 67 20 66 69 72 73   && [string firs
b0b0: 74 20 24 7a 20 2d 74 63 6c 62 6f 64 79 5d 3d 3d  t $z -tclbody]==
b0c0: 30 7d 20 20 20 7b 73 65 74 20 74 63 6c 62 6f 64  0}   {set tclbod
b0d0: 79 20 24 7a 32 7d 20 20 5c 0a 20 20 20 20 65 6c  y $z2}  \.    el
b0e0: 73 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b 73  seif {$n>1 && [s
b0f0: 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20 2d  tring first $z -
b100: 62 6c 6f 63 6b 73 69 7a 65 5d 3d 3d 30 7d 20 7b  blocksize]==0} {
b110: 73 65 74 20 62 6c 6f 63 6b 73 69 7a 65 20 22 2d  set blocksize "-
b120: 73 20 24 7a 32 22 20 7d 20 5c 0a 20 20 20 20 65  s $z2" } \.    e
b130: 6c 73 65 69 66 20 7b 24 6e 3e 31 20 26 26 20 5b  lseif {$n>1 && [
b140: 73 74 72 69 6e 67 20 66 69 72 73 74 20 24 7a 20  string first $z 
b150: 2d 63 68 61 72 61 63 74 65 72 69 73 74 69 63 73  -characteristics
b160: 5d 3d 3d 30 7d 20 7b 73 65 74 20 64 63 20 22 2d  ]==0} {set dc "-
b170: 63 20 7b 24 7a 32 7d 22 20 7d 20 5c 0a 20 20 20  c {$z2}" } \.   
b180: 20 65 6c 73 65 20 20 20 7b 20 65 72 72 6f 72 20   else   { error 
b190: 22 55 6e 72 65 63 6f 67 6e 69 7a 65 64 20 6f 70  "Unrecognized op
b1a0: 74 69 6f 6e 3a 20 24 7a 22 20 7d 0a 20 20 7d 0a  tion: $z" }.  }.
b1b0: 0a 20 20 69 66 20 7b 24 63 72 61 73 68 66 69 6c  .  if {$crashfil
b1c0: 65 20 65 71 20 22 22 7d 20 7b 0a 20 20 20 20 65  e eq ""} {.    e
b1d0: 72 72 6f 72 20 22 43 6f 6d 70 75 6c 73 6f 72 79  rror "Compulsory
b1e0: 20 6f 70 74 69 6f 6e 20 2d 66 69 6c 65 20 6d 69   option -file mi
b1f0: 73 73 69 6e 67 22 0a 20 20 7d 0a 0a 20 20 23 20  ssing".  }..  # 
b200: 24 63 72 61 73 68 66 69 6c 65 20 67 65 74 73 20  $crashfile gets 
b210: 63 6f 6d 70 61 72 65 64 20 74 6f 20 74 68 65 20  compared to the 
b220: 6e 61 74 69 76 65 20 66 69 6c 65 6e 61 6d 65 20  native filename 
b230: 69 6e 0a 20 20 23 20 63 66 53 79 6e 63 28 29 2c  in.  # cfSync(),
b240: 20 77 68 69 63 68 20 63 61 6e 20 62 65 20 64 69   which can be di
b250: 66 66 65 72 65 6e 74 20 74 68 65 6e 20 77 68 61  fferent then wha
b260: 74 20 54 43 4c 20 75 73 65 73 20 62 79 0a 20 20  t TCL uses by.  
b270: 23 20 64 65 66 61 75 6c 74 2c 20 73 6f 20 68 65  # default, so he
b280: 72 65 20 77 65 20 66 6f 72 63 65 20 69 74 20 74  re we force it t
b290: 6f 20 74 68 65 20 22 6e 61 74 69 76 65 6e 61 6d  o the "nativenam
b2a0: 65 22 20 66 6f 72 6d 61 74 2e 0a 20 20 73 65 74  e" format..  set
b2b0: 20 63 66 69 6c 65 20 5b 73 74 72 69 6e 67 20 6d   cfile [string m
b2c0: 61 70 20 7b 5c 5c 20 5c 5c 5c 5c 7d 20 5b 66 69  ap {\\ \\\\} [fi
b2d0: 6c 65 20 6e 61 74 69 76 65 6e 61 6d 65 20 5b 66  le nativename [f
b2e0: 69 6c 65 20 6a 6f 69 6e 20 5b 67 65 74 5f 70 77  ile join [get_pw
b2f0: 64 5d 20 24 63 72 61 73 68 66 69 6c 65 5d 5d 5d  d] $crashfile]]]
b300: 0a 0a 20 20 73 65 74 20 66 20 5b 6f 70 65 6e 20  ..  set f [open 
b310: 63 72 61 73 68 2e 74 63 6c 20 77 5d 0a 20 20 70  crash.tcl w].  p
b320: 75 74 73 20 24 66 20 22 73 71 6c 69 74 65 33 5f  uts $f "sqlite3_
b330: 63 72 61 73 68 5f 65 6e 61 62 6c 65 20 31 22 0a  crash_enable 1".
b340: 20 20 70 75 74 73 20 24 66 20 22 73 71 6c 69 74    puts $f "sqlit
b350: 65 33 5f 63 72 61 73 68 70 61 72 61 6d 73 20 24  e3_crashparams $
b360: 62 6c 6f 63 6b 73 69 7a 65 20 24 64 63 20 24 63  blocksize $dc $c
b370: 72 61 73 68 64 65 6c 61 79 20 24 63 66 69 6c 65  rashdelay $cfile
b380: 22 0a 20 20 70 75 74 73 20 24 66 20 22 73 71 6c  ".  puts $f "sql
b390: 69 74 65 33 5f 74 65 73 74 5f 63 6f 6e 74 72 6f  ite3_test_contro
b3a0: 6c 5f 70 65 6e 64 69 6e 67 5f 62 79 74 65 20 24  l_pending_byte $
b3b0: 3a 3a 73 71 6c 69 74 65 5f 70 65 6e 64 69 6e 67  ::sqlite_pending
b3c0: 5f 62 79 74 65 22 0a 0a 20 20 23 20 54 68 69 73  _byte"..  # This
b3d0: 20 62 6c 6f 63 6b 20 73 65 74 73 20 74 68 65 20   block sets the 
b3e0: 63 61 63 68 65 20 73 69 7a 65 20 6f 66 20 74 68  cache size of th
b3f0: 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20  e main database 
b400: 74 6f 20 31 30 0a 20 20 23 20 70 61 67 65 73 2e  to 10.  # pages.
b410: 20 54 68 69 73 20 69 73 20 64 6f 6e 65 20 69 6e   This is done in
b420: 20 63 61 73 65 20 74 68 65 20 62 75 69 6c 64 20   case the build 
b430: 69 73 20 63 6f 6e 66 69 67 75 72 65 64 20 74 6f  is configured to
b440: 20 6f 6d 69 74 0a 20 20 23 20 22 50 52 41 47 4d   omit.  # "PRAGM
b450: 41 20 63 61 63 68 65 5f 73 69 7a 65 22 2e 0a 20  A cache_size".. 
b460: 20 69 66 20 7b 24 6f 70 65 6e 64 62 21 3d 22 22   if {$opendb!=""
b470: 7d 20 7b 0a 20 20 20 20 70 75 74 73 20 24 66 20  } {.    puts $f 
b480: 24 6f 70 65 6e 64 62 20 0a 20 20 20 20 70 75 74  $opendb .    put
b490: 73 20 24 66 20 7b 64 62 20 65 76 61 6c 20 7b 53  s $f {db eval {S
b4a0: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 73 71 6c  ELECT * FROM sql
b4b0: 69 74 65 5f 6d 61 73 74 65 72 3b 7d 7d 0a 20 20  ite_master;}}.  
b4c0: 20 20 70 75 74 73 20 24 66 20 7b 73 65 74 20 62    puts $f {set b
b4d0: 74 20 5b 62 74 72 65 65 5f 66 72 6f 6d 5f 64 62  t [btree_from_db
b4e0: 20 64 62 5d 7d 0a 20 20 20 20 70 75 74 73 20 24   db]}.    puts $
b4f0: 66 20 7b 62 74 72 65 65 5f 73 65 74 5f 63 61 63  f {btree_set_cac
b500: 68 65 5f 73 69 7a 65 20 24 62 74 20 31 30 7d 0a  he_size $bt 10}.
b510: 20 20 7d 0a 0a 20 20 69 66 20 7b 24 70 72 6e 67    }..  if {$prng
b520: 73 65 65 64 7d 20 7b 0a 20 20 20 20 73 65 74 20  seed} {.    set 
b530: 73 65 65 64 20 5b 65 78 70 72 20 7b 24 70 72 6e  seed [expr {$prn
b540: 67 73 65 65 64 25 31 30 30 30 37 2b 31 7d 5d 0a  gseed%10007+1}].
b550: 20 20 20 20 23 20 70 75 74 73 20 73 65 65 64 3d      # puts seed=
b560: 24 73 65 65 64 0a 20 20 20 20 70 75 74 73 20 24  $seed.    puts $
b570: 66 20 22 64 62 20 65 76 61 6c 20 7b 53 45 4c 45  f "db eval {SELE
b580: 43 54 20 72 61 6e 64 6f 6d 62 6c 6f 62 28 24 73  CT randomblob($s
b590: 65 65 64 29 7d 22 0a 20 20 7d 0a 0a 20 20 69 66  eed)}".  }..  if
b5a0: 20 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68   {[string length
b5b0: 20 24 74 63 6c 62 6f 64 79 5d 3e 30 7d 20 7b 0a   $tclbody]>0} {.
b5c0: 20 20 20 20 70 75 74 73 20 24 66 20 24 74 63 6c      puts $f $tcl
b5d0: 62 6f 64 79 0a 20 20 7d 0a 20 20 69 66 20 7b 5b  body.  }.  if {[
b5e0: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 73  string length $s
b5f0: 71 6c 5d 3e 30 7d 20 7b 0a 20 20 20 20 70 75 74  ql]>0} {.    put
b600: 73 20 24 66 20 22 64 62 20 65 76 61 6c 20 7b 22  s $f "db eval {"
b610: 0a 20 20 20 20 70 75 74 73 20 24 66 20 20 20 22  .    puts $f   "
b620: 24 73 71 6c 22 0a 20 20 20 20 70 75 74 73 20 24  $sql".    puts $
b630: 66 20 22 7d 22 0a 20 20 7d 0a 20 20 63 6c 6f 73  f "}".  }.  clos
b640: 65 20 24 66 0a 20 20 73 65 74 20 72 20 5b 63 61  e $f.  set r [ca
b650: 74 63 68 20 7b 0a 20 20 20 20 65 78 65 63 20 5b  tch {.    exec [
b660: 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78 65 63 5d  info nameofexec]
b670: 20 63 72 61 73 68 2e 74 63 6c 20 3e 40 73 74 64   crash.tcl >@std
b680: 6f 75 74 0a 20 20 7d 20 6d 73 67 5d 0a 0a 20 20  out.  } msg]..  
b690: 23 20 57 69 6e 64 6f 77 73 2f 41 63 74 69 76 65  # Windows/Active
b6a0: 53 74 61 74 65 20 54 43 4c 20 72 65 74 75 72 6e  State TCL return
b6b0: 73 20 61 20 73 6c 69 67 68 74 6c 79 20 64 69 66  s a slightly dif
b6c0: 66 65 72 65 6e 74 0a 20 20 23 20 65 72 72 6f 72  ferent.  # error
b6d0: 20 6d 65 73 73 61 67 65 2e 20 20 57 65 20 6d 61   message.  We ma
b6e0: 70 20 74 68 61 74 20 74 6f 20 74 68 65 20 65 78  p that to the ex
b6f0: 70 65 63 74 65 64 20 6d 65 73 73 61 67 65 0a 20  pected message. 
b700: 20 23 20 73 6f 20 74 68 61 74 20 77 65 20 64 6f   # so that we do
b710: 6e 27 74 20 68 61 76 65 20 74 6f 20 63 68 61 6e  n't have to chan
b720: 67 65 20 61 6c 6c 20 6f 66 20 74 68 65 20 74 65  ge all of the te
b730: 73 74 0a 20 20 23 20 63 61 73 65 73 2e 0a 20 20  st.  # cases..  
b740: 69 66 20 7b 24 3a 3a 74 63 6c 5f 70 6c 61 74 66  if {$::tcl_platf
b750: 6f 72 6d 28 70 6c 61 74 66 6f 72 6d 29 3d 3d 22  orm(platform)=="
b760: 77 69 6e 64 6f 77 73 22 7d 20 7b 0a 20 20 20 20  windows"} {.    
b770: 69 66 20 7b 24 6d 73 67 3d 3d 22 63 68 69 6c 64  if {$msg=="child
b780: 20 6b 69 6c 6c 65 64 3a 20 75 6e 6b 6e 6f 77 6e   killed: unknown
b790: 20 73 69 67 6e 61 6c 22 7d 20 7b 0a 20 20 20 20   signal"} {.    
b7a0: 20 20 73 65 74 20 6d 73 67 20 22 63 68 69 6c 64    set msg "child
b7b0: 20 70 72 6f 63 65 73 73 20 65 78 69 74 65 64 20   process exited 
b7c0: 61 62 6e 6f 72 6d 61 6c 6c 79 22 0a 20 20 20 20  abnormally".    
b7d0: 7d 0a 20 20 7d 0a 0a 20 20 6c 61 70 70 65 6e 64  }.  }..  lappend
b7e0: 20 72 20 24 6d 73 67 0a 7d 0a 0a 70 72 6f 63 20   r $msg.}..proc 
b7f0: 72 75 6e 5f 69 6f 65 72 72 5f 70 72 65 70 20 7b  run_ioerr_prep {
b800: 7d 20 7b 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69  } {.  set ::sqli
b810: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64  te_io_error_pend
b820: 69 6e 67 20 30 0a 20 20 63 61 74 63 68 20 7b 64  ing 0.  catch {d
b830: 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68  b close}.  catch
b840: 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20 63   {db2 close}.  c
b850: 61 74 63 68 20 7b 66 6f 72 63 65 64 65 6c 65 74  atch {forcedelet
b860: 65 20 74 65 73 74 2e 64 62 7d 0a 20 20 63 61 74  e test.db}.  cat
b870: 63 68 20 7b 66 6f 72 63 65 64 65 6c 65 74 65 20  ch {forcedelete 
b880: 74 65 73 74 2e 64 62 2d 6a 6f 75 72 6e 61 6c 7d  test.db-journal}
b890: 0a 20 20 63 61 74 63 68 20 7b 66 6f 72 63 65 64  .  catch {forced
b8a0: 65 6c 65 74 65 20 74 65 73 74 32 2e 64 62 7d 0a  elete test2.db}.
b8b0: 20 20 63 61 74 63 68 20 7b 66 6f 72 63 65 64 65    catch {forcede
b8c0: 6c 65 74 65 20 74 65 73 74 32 2e 64 62 2d 6a 6f  lete test2.db-jo
b8d0: 75 72 6e 61 6c 7d 0a 20 20 73 65 74 20 3a 3a 44  urnal}.  set ::D
b8e0: 42 20 5b 73 71 6c 69 74 65 33 20 64 62 20 74 65  B [sqlite3 db te
b8f0: 73 74 2e 64 62 3b 20 73 71 6c 69 74 65 33 5f 63  st.db; sqlite3_c
b900: 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69 6e 74 65  onnection_pointe
b910: 72 20 64 62 5d 0a 20 20 73 71 6c 69 74 65 33 5f  r db].  sqlite3_
b920: 65 78 74 65 6e 64 65 64 5f 72 65 73 75 6c 74 5f  extended_result_
b930: 63 6f 64 65 73 20 24 3a 3a 44 42 20 24 3a 3a 69  codes $::DB $::i
b940: 6f 65 72 72 6f 70 74 73 28 2d 65 72 63 29 0a 20  oerropts(-erc). 
b950: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
b960: 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74  s ::ioerropts(-t
b970: 63 6c 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20 20  clprep)]} {.    
b980: 65 76 61 6c 20 24 3a 3a 69 6f 65 72 72 6f 70 74  eval $::ioerropt
b990: 73 28 2d 74 63 6c 70 72 65 70 29 0a 20 20 7d 0a  s(-tclprep).  }.
b9a0: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
b9b0: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
b9c0: 73 71 6c 70 72 65 70 29 5d 7d 20 7b 0a 20 20 20  sqlprep)]} {.   
b9d0: 20 65 78 65 63 73 71 6c 20 24 3a 3a 69 6f 65 72   execsql $::ioer
b9e0: 72 6f 70 74 73 28 2d 73 71 6c 70 72 65 70 29 0a  ropts(-sqlprep).
b9f0: 20 20 7d 0a 20 20 65 78 70 72 20 30 0a 7d 0a 0a    }.  expr 0.}..
ba00: 23 20 55 73 61 67 65 3a 20 64 6f 5f 69 6f 65 72  # Usage: do_ioer
ba10: 72 5f 74 65 73 74 20 3c 74 65 73 74 20 6e 75 6d  r_test <test num
ba20: 62 65 72 3e 20 3c 6f 70 74 69 6f 6e 73 2e 2e 2e  ber> <options...
ba30: 3e 0a 23 0a 23 20 54 68 69 73 20 70 72 6f 63 20  >.#.# This proc 
ba40: 69 73 20 75 73 65 64 20 74 6f 20 69 6d 70 6c 65  is used to imple
ba50: 6d 65 6e 74 20 74 65 73 74 20 63 61 73 65 73 20  ment test cases 
ba60: 74 68 61 74 20 63 68 65 63 6b 20 74 68 61 74 20  that check that 
ba70: 49 4f 20 65 72 72 6f 72 73 0a 23 20 61 72 65 20  IO errors.# are 
ba80: 63 6f 72 72 65 63 74 6c 79 20 68 61 6e 64 6c 65  correctly handle
ba90: 64 2e 20 54 68 65 20 66 69 72 73 74 20 61 72 67  d. The first arg
baa0: 75 6d 65 6e 74 2c 20 3c 74 65 73 74 20 6e 75 6d  ument, <test num
bab0: 62 65 72 3e 2c 20 69 73 20 61 6e 20 69 6e 74 65  ber>, is an inte
bac0: 67 65 72 0a 23 20 75 73 65 64 20 74 6f 20 6e 61  ger.# used to na
bad0: 6d 65 20 74 68 65 20 74 65 73 74 73 20 65 78 65  me the tests exe
bae0: 63 75 74 65 64 20 62 79 20 74 68 69 73 20 70 72  cuted by this pr
baf0: 6f 63 2e 20 4f 70 74 69 6f 6e 73 20 61 72 65 20  oc. Options are 
bb00: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 23 0a 23 20  as follows:.#.# 
bb10: 20 20 20 20 2d 74 63 6c 70 72 65 70 20 20 20 20      -tclprep    
bb20: 20 20 20 20 20 20 54 43 4c 20 73 63 72 69 70 74        TCL script
bb30: 20 74 6f 20 72 75 6e 20 74 6f 20 70 72 65 70 61   to run to prepa
bb40: 72 65 20 74 65 73 74 2e 0a 23 20 20 20 20 20 2d  re test..#     -
bb50: 73 71 6c 70 72 65 70 20 20 20 20 20 20 20 20 20  sqlprep         
bb60: 20 53 51 4c 20 73 63 72 69 70 74 20 74 6f 20 72   SQL script to r
bb70: 75 6e 20 74 6f 20 70 72 65 70 61 72 65 20 74 65  un to prepare te
bb80: 73 74 2e 0a 23 20 20 20 20 20 2d 74 63 6c 62 6f  st..#     -tclbo
bb90: 64 79 20 20 20 20 20 20 20 20 20 20 54 43 4c 20  dy          TCL 
bba0: 73 63 72 69 70 74 20 74 6f 20 72 75 6e 20 77 69  script to run wi
bbb0: 74 68 20 49 4f 20 65 72 72 6f 72 20 73 69 6d 75  th IO error simu
bbc0: 6c 61 74 69 6f 6e 2e 0a 23 20 20 20 20 20 2d 73  lation..#     -s
bbd0: 71 6c 62 6f 64 79 20 20 20 20 20 20 20 20 20 20  qlbody          
bbe0: 54 43 4c 20 73 63 72 69 70 74 20 74 6f 20 72 75  TCL script to ru
bbf0: 6e 20 77 69 74 68 20 49 4f 20 65 72 72 6f 72 20  n with IO error 
bc00: 73 69 6d 75 6c 61 74 69 6f 6e 2e 0a 23 20 20 20  simulation..#   
bc10: 20 20 2d 65 78 63 6c 75 64 65 20 20 20 20 20 20    -exclude      
bc20: 20 20 20 20 4c 69 73 74 20 6f 66 20 27 4e 27 20      List of 'N' 
bc30: 76 61 6c 75 65 73 20 6e 6f 74 20 74 6f 20 74 65  values not to te
bc40: 73 74 2e 0a 23 20 20 20 20 20 2d 65 72 63 20 20  st..#     -erc  
bc50: 20 20 20 20 20 20 20 20 20 20 20 20 55 73 65 20              Use 
bc60: 65 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20  extended result 
bc70: 63 6f 64 65 73 0a 23 20 20 20 20 20 2d 70 65 72  codes.#     -per
bc80: 73 69 73 74 20 20 20 20 20 20 20 20 20 20 4d 61  sist          Ma
bc90: 6b 65 20 73 69 6d 75 6c 61 74 65 64 20 49 2f 4f  ke simulated I/O
bca0: 20 65 72 72 6f 72 73 20 70 65 72 73 69 73 74 65   errors persiste
bcb0: 6e 74 0a 23 20 20 20 20 20 2d 73 74 61 72 74 20  nt.#     -start 
bcc0: 20 20 20 20 20 20 20 20 20 20 20 56 61 6c 75 65             Value
bcd0: 20 6f 66 20 27 4e 27 20 74 6f 20 62 65 67 69 6e   of 'N' to begin
bce0: 20 77 69 74 68 20 28 64 65 66 61 75 6c 74 20 31   with (default 1
bcf0: 29 0a 23 0a 23 20 20 20 20 20 2d 63 6b 73 75 6d  ).#.#     -cksum
bd00: 20 20 20 20 20 20 20 20 20 20 20 20 42 6f 6f 6c              Bool
bd10: 65 61 6e 2e 20 49 66 20 74 72 75 65 2c 20 74 65  ean. If true, te
bd20: 73 74 20 74 68 61 74 20 74 68 65 20 64 61 74 61  st that the data
bd30: 62 61 73 65 20 64 6f 65 73 0a 23 20 20 20 20 20  base does.#     
bd40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bd50: 20 20 6e 6f 74 20 63 68 61 6e 67 65 20 64 75 72    not change dur
bd60: 69 6e 67 20 74 68 65 20 65 78 65 63 75 74 69 6f  ing the executio
bd70: 6e 20 6f 66 20 74 68 65 20 74 65 73 74 20 63 61  n of the test ca
bd80: 73 65 2e 0a 23 0a 70 72 6f 63 20 64 6f 5f 69 6f  se..#.proc do_io
bd90: 65 72 72 5f 74 65 73 74 20 7b 74 65 73 74 6e 61  err_test {testna
bda0: 6d 65 20 61 72 67 73 7d 20 7b 0a 0a 20 20 73 65  me args} {..  se
bdb0: 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73  t ::ioerropts(-s
bdc0: 74 61 72 74 29 20 31 0a 20 20 73 65 74 20 3a 3a  tart) 1.  set ::
bdd0: 69 6f 65 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d  ioerropts(-cksum
bde0: 29 20 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72  ) 0.  set ::ioer
bdf0: 72 6f 70 74 73 28 2d 65 72 63 29 20 30 0a 20 20  ropts(-erc) 0.  
be00: 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28  set ::ioerropts(
be10: 2d 63 6f 75 6e 74 29 20 31 30 30 30 30 30 30 30  -count) 10000000
be20: 30 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f  0.  set ::ioerro
be30: 70 74 73 28 2d 70 65 72 73 69 73 74 29 20 31 0a  pts(-persist) 1.
be40: 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70 74    set ::ioerropt
be50: 73 28 2d 63 6b 72 65 66 63 6f 75 6e 74 29 20 30  s(-ckrefcount) 0
be60: 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 70  .  set ::ioerrop
be70: 74 73 28 2d 72 65 73 74 6f 72 65 70 72 6e 67 29  ts(-restoreprng)
be80: 20 31 0a 20 20 61 72 72 61 79 20 73 65 74 20 3a   1.  array set :
be90: 3a 69 6f 65 72 72 6f 70 74 73 20 24 61 72 67 73  :ioerropts $args
bea0: 0a 0a 20 20 23 20 54 45 4d 50 4f 52 41 52 59 3a  ..  # TEMPORARY:
beb0: 20 46 6f 72 20 33 2e 35 2e 39 2c 20 64 69 73 61   For 3.5.9, disa
bec0: 62 6c 65 20 74 65 73 74 69 6e 67 20 6f 66 20 65  ble testing of e
bed0: 78 74 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63  xtended result c
bee0: 6f 64 65 73 2e 20 54 68 65 72 65 20 61 72 65 0a  odes. There are.
bef0: 20 20 23 20 61 20 63 6f 75 70 6c 65 20 6f 66 20    # a couple of 
bf00: 6f 62 73 63 75 72 65 20 49 4f 20 65 72 72 6f 72  obscure IO error
bf10: 73 20 74 68 61 74 20 64 6f 20 6e 6f 74 20 72 65  s that do not re
bf20: 74 75 72 6e 20 74 68 65 6d 2e 0a 20 20 73 65 74  turn them..  set
bf30: 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72   ::ioerropts(-er
bf40: 63 29 20 30 0a 0a 20 20 23 20 43 72 65 61 74 65  c) 0..  # Create
bf50: 20 61 20 73 69 6e 67 6c 65 20 54 43 4c 20 73 63   a single TCL sc
bf60: 72 69 70 74 20 66 72 6f 6d 20 74 68 65 20 54 43  ript from the TC
bf70: 4c 20 61 6e 64 20 53 51 4c 20 73 70 65 63 69 66  L and SQL specif
bf80: 69 65 64 0a 20 20 23 20 61 73 20 74 68 65 20 62  ied.  # as the b
bf90: 6f 64 79 20 6f 66 20 74 68 65 20 74 65 73 74 2e  ody of the test.
bfa0: 0a 20 20 73 65 74 20 3a 3a 69 6f 65 72 72 6f 72  .  set ::ioerror
bfb0: 62 6f 64 79 20 7b 7d 0a 20 20 69 66 20 7b 5b 69  body {}.  if {[i
bfc0: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65  nfo exists ::ioe
bfd0: 72 72 6f 70 74 73 28 2d 74 63 6c 62 6f 64 79 29  rropts(-tclbody)
bfe0: 5d 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20  ]} {.    append 
bff0: 3a 3a 69 6f 65 72 72 6f 72 62 6f 64 79 20 22 24  ::ioerrorbody "$
c000: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 74 63 6c  ::ioerropts(-tcl
c010: 62 6f 64 79 29 5c 6e 22 0a 20 20 7d 0a 20 20 69  body)\n".  }.  i
c020: 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20  f {[info exists 
c030: 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c  ::ioerropts(-sql
c040: 62 6f 64 79 29 5d 7d 20 7b 0a 20 20 20 20 61 70  body)]} {.    ap
c050: 70 65 6e 64 20 3a 3a 69 6f 65 72 72 6f 72 62 6f  pend ::ioerrorbo
c060: 64 79 20 22 64 62 20 65 76 61 6c 20 7b 24 3a 3a  dy "db eval {$::
c070: 69 6f 65 72 72 6f 70 74 73 28 2d 73 71 6c 62 6f  ioerropts(-sqlbo
c080: 64 79 29 7d 22 0a 20 20 7d 0a 0a 20 20 73 61 76  dy)}".  }..  sav
c090: 65 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20 69  e_prng_state.  i
c0a0: 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  f {$::ioerropts(
c0b0: 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20 20 20 20 72  -cksum)} {.    r
c0c0: 75 6e 5f 69 6f 65 72 72 5f 70 72 65 70 0a 20 20  un_ioerr_prep.  
c0d0: 20 20 65 76 61 6c 20 24 3a 3a 69 6f 65 72 72 6f    eval $::ioerro
c0e0: 72 62 6f 64 79 0a 20 20 20 20 73 65 74 20 3a 3a  rbody.    set ::
c0f0: 67 6f 6f 64 63 6b 73 75 6d 20 5b 63 6b 73 75 6d  goodcksum [cksum
c100: 5d 0a 20 20 7d 0a 0a 20 20 73 65 74 20 3a 3a 67  ].  }..  set ::g
c110: 6f 20 31 0a 20 20 23 72 65 73 65 74 5f 70 72 6e  o 1.  #reset_prn
c120: 67 5f 73 74 61 74 65 0a 20 20 66 6f 72 20 7b 73  g_state.  for {s
c130: 65 74 20 6e 20 24 3a 3a 69 6f 65 72 72 6f 70 74  et n $::ioerropt
c140: 73 28 2d 73 74 61 72 74 29 7d 20 7b 24 3a 3a 67  s(-start)} {$::g
c150: 6f 7d 20 7b 69 6e 63 72 20 6e 7d 20 7b 0a 20 20  o} {incr n} {.  
c160: 20 20 73 65 74 20 3a 3a 54 4e 20 24 6e 0a 20 20    set ::TN $n.  
c170: 20 20 69 6e 63 72 20 3a 3a 69 6f 65 72 72 6f 70    incr ::ioerrop
c180: 74 73 28 2d 63 6f 75 6e 74 29 20 2d 31 0a 20 20  ts(-count) -1.  
c190: 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70    if {$::ioerrop
c1a0: 74 73 28 2d 63 6f 75 6e 74 29 3c 30 7d 20 62 72  ts(-count)<0} br
c1b0: 65 61 6b 0a 0a 20 20 20 20 23 20 53 6b 69 70 20  eak..    # Skip 
c1c0: 74 68 69 73 20 49 4f 20 65 72 72 6f 72 20 69 66  this IO error if
c1d0: 20 69 74 20 77 61 73 20 73 70 65 63 69 66 69 65   it was specifie
c1e0: 64 20 77 69 74 68 20 74 68 65 20 22 2d 65 78 63  d with the "-exc
c1f0: 6c 75 64 65 22 20 6f 70 74 69 6f 6e 2e 0a 20 20  lude" option..  
c200: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73    if {[info exis
c210: 74 73 20 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d  ts ::ioerropts(-
c220: 65 78 63 6c 75 64 65 29 5d 7d 20 7b 0a 20 20 20  exclude)]} {.   
c230: 20 20 20 69 66 20 7b 5b 6c 73 65 61 72 63 68 20     if {[lsearch 
c240: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 78  $::ioerropts(-ex
c250: 63 6c 75 64 65 29 20 24 6e 5d 21 3d 2d 31 7d 20  clude) $n]!=-1} 
c260: 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 7d 0a 20  continue.    }. 
c270: 20 20 20 69 66 20 7b 24 3a 3a 69 6f 65 72 72 6f     if {$::ioerro
c280: 70 74 73 28 2d 72 65 73 74 6f 72 65 70 72 6e 67  pts(-restoreprng
c290: 29 7d 20 7b 0a 20 20 20 20 20 20 72 65 73 74 6f  )} {.      resto
c2a0: 72 65 5f 70 72 6e 67 5f 73 74 61 74 65 0a 20 20  re_prng_state.  
c2b0: 20 20 7d 0a 0a 20 20 20 20 23 20 44 65 6c 65 74    }..    # Delet
c2c0: 65 20 74 68 65 20 66 69 6c 65 73 20 74 65 73 74  e the files test
c2d0: 2e 64 62 20 61 6e 64 20 74 65 73 74 32 2e 64 62  .db and test2.db
c2e0: 2c 20 74 68 65 6e 20 65 78 65 63 75 74 65 20 74  , then execute t
c2f0: 68 65 20 54 43 4c 20 61 6e 64 0a 20 20 20 20 23  he TCL and.    #
c300: 20 53 51 4c 20 28 69 6e 20 74 68 61 74 20 6f 72   SQL (in that or
c310: 64 65 72 29 20 74 6f 20 70 72 65 70 61 72 65 20  der) to prepare 
c320: 66 6f 72 20 74 68 65 20 74 65 73 74 20 63 61 73  for the test cas
c330: 65 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24  e..    do_test $
c340: 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 31 20 7b 0a  testname.$n.1 {.
c350: 20 20 20 20 20 20 72 75 6e 5f 69 6f 65 72 72 5f        run_ioerr_
c360: 70 72 65 70 0a 20 20 20 20 7d 20 7b 30 7d 0a 0a  prep.    } {0}..
c370: 20 20 20 20 23 20 52 65 61 64 20 74 68 65 20 27      # Read the '
c380: 63 68 65 63 6b 73 75 6d 27 20 6f 66 20 74 68 65  checksum' of the
c390: 20 64 61 74 61 62 61 73 65 2e 0a 20 20 20 20 69   database..    i
c3a0: 66 20 7b 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  f {$::ioerropts(
c3b0: 2d 63 6b 73 75 6d 29 7d 20 7b 0a 20 20 20 20 20  -cksum)} {.     
c3c0: 20 73 65 74 20 3a 3a 63 68 65 63 6b 73 75 6d 20   set ::checksum 
c3d0: 5b 63 6b 73 75 6d 5d 0a 20 20 20 20 7d 0a 0a 20  [cksum].    }.. 
c3e0: 20 20 20 23 20 53 65 74 20 74 68 65 20 4e 74 68     # Set the Nth
c3f0: 20 49 4f 20 65 72 72 6f 72 20 74 6f 20 66 61 69   IO error to fai
c400: 6c 2e 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24  l..    do_test $
c410: 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 32 20 5b 73  testname.$n.2 [s
c420: 75 62 73 74 20 7b 0a 20 20 20 20 20 20 73 65 74  ubst {.      set
c430: 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72   ::sqlite_io_err
c440: 6f 72 5f 70 65 72 73 69 73 74 20 24 3a 3a 69 6f  or_persist $::io
c450: 65 72 72 6f 70 74 73 28 2d 70 65 72 73 69 73 74  erropts(-persist
c460: 29 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73 71  ).      set ::sq
c470: 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65  lite_io_error_pe
c480: 6e 64 69 6e 67 20 24 6e 0a 20 20 20 20 7d 5d 20  nding $n.    }] 
c490: 24 6e 0a 0a 20 20 20 20 23 20 45 78 65 63 75 74  $n..    # Execut
c4a0: 65 20 74 68 65 20 54 43 4c 20 73 63 72 69 70 74  e the TCL script
c4b0: 20 63 72 65 61 74 65 64 20 66 6f 72 20 74 68 65   created for the
c4c0: 20 62 6f 64 79 20 6f 66 20 74 68 69 73 20 74 65   body of this te
c4d0: 73 74 2e 20 49 66 0a 20 20 20 20 23 20 61 74 20  st. If.    # at 
c4e0: 6c 65 61 73 74 20 4e 20 49 4f 20 6f 70 65 72 61  least N IO opera
c4f0: 74 69 6f 6e 73 20 70 65 72 66 6f 72 6d 65 64 20  tions performed 
c500: 62 79 20 53 51 4c 69 74 65 20 61 73 20 61 20 72  by SQLite as a r
c510: 65 73 75 6c 74 20 6f 66 0a 20 20 20 20 23 20 74  esult of.    # t
c520: 68 65 20 73 63 72 69 70 74 2c 20 74 68 65 20 4e  he script, the N
c530: 74 68 20 77 69 6c 6c 20 66 61 69 6c 2e 0a 20 20  th will fail..  
c540: 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74 6e    do_test $testn
c550: 61 6d 65 2e 24 6e 2e 33 20 7b 0a 20 20 20 20 20  ame.$n.3 {.     
c560: 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f   set ::sqlite_io
c570: 5f 65 72 72 6f 72 5f 68 69 74 20 30 0a 20 20 20  _error_hit 0.   
c580: 20 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f     set ::sqlite_
c590: 69 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74  io_error_hardhit
c5a0: 20 30 0a 20 20 20 20 20 20 73 65 74 20 72 20 5b   0.      set r [
c5b0: 63 61 74 63 68 20 24 3a 3a 69 6f 65 72 72 6f 72  catch $::ioerror
c5c0: 62 6f 64 79 20 6d 73 67 5d 0a 20 20 20 20 20 20  body msg].      
c5d0: 73 65 74 20 3a 3a 65 72 72 73 65 65 6e 20 24 72  set ::errseen $r
c5e0: 0a 20 20 20 20 20 20 73 65 74 20 72 63 20 5b 73  .      set rc [s
c5f0: 71 6c 69 74 65 33 5f 65 72 72 63 6f 64 65 20 24  qlite3_errcode $
c600: 3a 3a 44 42 5d 0a 20 20 20 20 20 20 69 66 20 7b  ::DB].      if {
c610: 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 65 72  $::ioerropts(-er
c620: 63 29 7d 20 7b 0a 20 20 20 20 20 20 20 20 23 20  c)} {.        # 
c630: 49 66 20 77 65 20 61 72 65 20 69 6e 20 65 78 74  If we are in ext
c640: 65 6e 64 65 64 20 72 65 73 75 6c 74 20 63 6f 64  ended result cod
c650: 65 20 6d 6f 64 65 2c 20 6d 61 6b 65 20 73 75 72  e mode, make sur
c660: 65 20 61 6c 6c 20 6f 66 20 74 68 65 0a 20 20 20  e all of the.   
c670: 20 20 20 20 20 23 20 49 4f 45 52 52 73 20 77 65       # IOERRs we
c680: 20 67 65 74 20 62 61 63 6b 20 72 65 61 6c 6c 79   get back really
c690: 20 64 6f 20 68 61 76 65 20 74 68 65 69 72 20 65   do have their e
c6a0: 78 74 65 6e 64 65 64 20 63 6f 64 65 20 76 61 6c  xtended code val
c6b0: 75 65 73 2e 0a 20 20 20 20 20 20 20 20 23 20 49  ues..        # I
c6c0: 66 20 61 6e 20 65 78 74 65 6e 64 65 64 20 72 65  f an extended re
c6d0: 73 75 6c 74 20 63 6f 64 65 20 69 73 20 72 65 74  sult code is ret
c6e0: 75 72 6e 65 64 2c 20 74 68 65 20 73 71 6c 69 74  urned, the sqlit
c6f0: 65 33 5f 65 72 72 63 6f 64 65 0a 20 20 20 20 20  e3_errcode.     
c700: 20 20 20 23 20 54 43 4c 63 6f 6d 6d 61 6e 64 20     # TCLcommand 
c710: 77 69 6c 6c 20 72 65 74 75 72 6e 20 61 20 73 74  will return a st
c720: 72 69 6e 67 20 6f 66 20 74 68 65 20 66 6f 72 6d  ring of the form
c730: 3a 20 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 2b  :  SQLITE_IOERR+
c740: 6e 6e 6e 6e 0a 20 20 20 20 20 20 20 20 23 20 77  nnnn.        # w
c750: 68 65 72 65 20 6e 6e 6e 6e 20 69 73 20 61 20 6e  here nnnn is a n
c760: 75 6d 62 65 72 0a 20 20 20 20 20 20 20 20 69 66  umber.        if
c770: 20 7b 5b 72 65 67 65 78 70 20 7b 5e 53 51 4c 49   {[regexp {^SQLI
c780: 54 45 5f 49 4f 45 52 52 7d 20 24 72 63 5d 20 26  TE_IOERR} $rc] &
c790: 26 20 21 5b 72 65 67 65 78 70 20 7b 49 4f 45 52  & ![regexp {IOER
c7a0: 52 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a 20  R\+\d} $rc]} {. 
c7b0: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
c7c0: 24 72 63 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  $rc.        }.  
c7d0: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
c7e0: 20 20 20 20 20 23 20 49 66 20 77 65 20 61 72 65       # If we are
c7f0: 20 6e 6f 74 20 69 6e 20 65 78 74 65 6e 64 65 64   not in extended
c800: 20 72 65 73 75 6c 74 20 63 6f 64 65 20 6d 6f 64   result code mod
c810: 65 2c 20 6d 61 6b 65 20 73 75 72 65 20 6e 6f 0a  e, make sure no.
c820: 20 20 20 20 20 20 20 20 23 20 65 78 74 65 6e 64          # extend
c830: 65 64 20 65 72 72 6f 72 20 63 6f 64 65 73 20 61  ed error codes a
c840: 72 65 20 72 65 74 75 72 6e 65 64 2e 0a 20 20 20  re returned..   
c850: 20 20 20 20 20 69 66 20 7b 5b 72 65 67 65 78 70       if {[regexp
c860: 20 7b 5c 2b 5c 64 7d 20 24 72 63 5d 7d 20 7b 0a   {\+\d} $rc]} {.
c870: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
c880: 20 24 72 63 0a 20 20 20 20 20 20 20 20 7d 0a 20   $rc.        }. 
c890: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 23 20 54       }.      # T
c8a0: 68 65 20 74 65 73 74 20 72 65 70 65 61 74 73 20  he test repeats 
c8b0: 61 73 20 6c 6f 6e 67 20 61 73 20 24 3a 3a 67 6f  as long as $::go
c8c0: 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2e 20 20 24   is non-zero.  $
c8d0: 3a 3a 67 6f 20 73 74 61 72 74 73 20 6f 75 74 0a  ::go starts out.
c8e0: 20 20 20 20 20 20 23 20 61 73 20 31 2e 20 20 57        # as 1.  W
c8f0: 68 65 6e 20 61 20 74 65 73 74 20 72 75 6e 73 20  hen a test runs 
c900: 74 6f 20 63 6f 6d 70 6c 65 74 69 6f 6e 20 77 69  to completion wi
c910: 74 68 6f 75 74 20 68 69 74 74 69 6e 67 20 61 6e  thout hitting an
c920: 20 49 2f 4f 0a 20 20 20 20 20 20 23 20 65 72 72   I/O.      # err
c930: 6f 72 2c 20 74 68 61 74 20 6d 65 61 6e 73 20 74  or, that means t
c940: 68 65 72 65 20 69 73 20 6e 6f 20 70 6f 69 6e 74  here is no point
c950: 20 69 6e 20 63 6f 6e 74 69 6e 75 69 6e 67 20 77   in continuing w
c960: 69 74 68 20 74 68 69 73 20 74 65 73 74 0a 20 20  ith this test.  
c970: 20 20 20 20 23 20 63 61 73 65 20 73 6f 20 73 65      # case so se
c980: 74 20 24 3a 3a 67 6f 20 74 6f 20 7a 65 72 6f 2e  t $::go to zero.
c990: 0a 20 20 20 20 20 20 23 0a 20 20 20 20 20 20 69  .      #.      i
c9a0: 66 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f  f {$::sqlite_io_
c9b0: 65 72 72 6f 72 5f 70 65 6e 64 69 6e 67 3e 30 7d  error_pending>0}
c9c0: 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 3a   {.        set :
c9d0: 3a 67 6f 20 30 0a 20 20 20 20 20 20 20 20 73 65  :go 0.        se
c9e0: 74 20 71 20 30 0a 20 20 20 20 20 20 20 20 73 65  t q 0.        se
c9f0: 74 20 3a 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72  t ::sqlite_io_er
ca00: 72 6f 72 5f 70 65 6e 64 69 6e 67 20 30 0a 20 20  ror_pending 0.  
ca10: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
ca20: 20 20 20 20 20 73 65 74 20 71 20 31 0a 20 20 20       set q 1.   
ca30: 20 20 20 7d 0a 0a 20 20 20 20 20 20 73 65 74 20     }..      set 
ca40: 73 20 5b 65 78 70 72 20 24 3a 3a 73 71 6c 69 74  s [expr $::sqlit
ca50: 65 5f 69 6f 5f 65 72 72 6f 72 5f 68 69 74 3d 3d  e_io_error_hit==
ca60: 30 5d 0a 20 20 20 20 20 20 69 66 20 7b 24 3a 3a  0].      if {$::
ca70: 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f  sqlite_io_error_
ca80: 68 69 74 3e 24 3a 3a 73 71 6c 69 74 65 5f 69 6f  hit>$::sqlite_io
ca90: 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20 26  _error_hardhit &
caa0: 26 20 24 72 3d 3d 30 7d 20 7b 0a 20 20 20 20 20  & $r==0} {.     
cab0: 20 20 20 73 65 74 20 72 20 31 0a 20 20 20 20 20     set r 1.     
cac0: 20 7d 0a 20 20 20 20 20 20 73 65 74 20 3a 3a 73   }.      set ::s
cad0: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68  qlite_io_error_h
cae0: 69 74 20 30 0a 0a 20 20 20 20 20 20 23 20 4f 6e  it 0..      # On
caf0: 65 20 6f 66 20 74 77 6f 20 74 68 69 6e 67 73 20  e of two things 
cb00: 6d 75 73 74 20 68 61 76 65 20 68 61 70 70 65 6e  must have happen
cb10: 65 64 2e 20 65 69 74 68 65 72 0a 20 20 20 20 20  ed. either.     
cb20: 20 23 20 20 20 31 2e 20 20 57 65 20 6e 65 76 65   #   1.  We neve
cb30: 72 20 68 69 74 20 74 68 65 20 49 4f 20 65 72 72  r hit the IO err
cb40: 6f 72 20 61 6e 64 20 74 68 65 20 53 51 4c 20 72  or and the SQL r
cb50: 65 74 75 72 6e 65 64 20 4f 4b 0a 20 20 20 20 20  eturned OK.     
cb60: 20 23 20 20 20 32 2e 20 20 41 6e 20 49 4f 20 65   #   2.  An IO e
cb70: 72 72 6f 72 20 77 61 73 20 68 69 74 20 61 6e 64  rror was hit and
cb80: 20 74 68 65 20 53 51 4c 20 66 61 69 6c 65 64 0a   the SQL failed.
cb90: 20 20 20 20 20 20 23 0a 20 20 20 20 20 20 23 70        #.      #p
cba0: 75 74 73 20 22 73 3d 24 73 20 72 3d 24 72 20 71  uts "s=$s r=$r q
cbb0: 3d 24 71 22 0a 20 20 20 20 20 20 65 78 70 72 20  =$q".      expr 
cbc0: 7b 20 28 24 73 20 26 26 20 21 24 72 20 26 26 20  { ($s && !$r && 
cbd0: 21 24 71 29 20 7c 7c 20 28 21 24 73 20 26 26 20  !$q) || (!$s && 
cbe0: 24 72 20 26 26 20 24 71 29 20 7d 0a 20 20 20 20  $r && $q) }.    
cbf0: 7d 20 7b 31 7d 0a 0a 20 20 20 20 73 65 74 20 3a  } {1}..    set :
cc00: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
cc10: 5f 68 69 74 20 30 0a 20 20 20 20 73 65 74 20 3a  _hit 0.    set :
cc20: 3a 73 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72  :sqlite_io_error
cc30: 5f 70 65 6e 64 69 6e 67 20 30 0a 0a 20 20 20 20  _pending 0..    
cc40: 23 20 43 68 65 63 6b 20 74 68 61 74 20 6e 6f 20  # Check that no 
cc50: 70 61 67 65 20 72 65 66 65 72 65 6e 63 65 73 20  page references 
cc60: 77 65 72 65 20 6c 65 61 6b 65 64 2e 20 54 68 65  were leaked. The
cc70: 72 65 20 73 68 6f 75 6c 64 20 62 65 0a 20 20 20  re should be.   
cc80: 20 23 20 61 20 73 69 6e 67 6c 65 20 72 65 66 65   # a single refe
cc90: 72 65 6e 63 65 20 69 66 20 74 68 65 72 65 20 69  rence if there i
cca0: 73 20 73 74 69 6c 6c 20 61 6e 20 61 63 74 69 76  s still an activ
ccb0: 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 0a 20  e transaction,. 
ccc0: 20 20 20 23 20 6f 72 20 7a 65 72 6f 20 6f 74 68     # or zero oth
ccd0: 65 72 77 69 73 65 2e 0a 20 20 20 20 23 0a 20 20  erwise..    #.  
cce0: 20 20 23 20 55 50 44 41 54 45 3a 20 49 66 20 74    # UPDATE: If t
ccf0: 68 65 20 49 4f 20 65 72 72 6f 72 20 6f 63 63 75  he IO error occu
cd00: 72 73 20 61 66 74 65 72 20 61 20 27 42 45 47 49  rs after a 'BEGI
cd10: 4e 27 20 62 75 74 20 62 65 66 6f 72 65 20 61 6e  N' but before an
cd20: 79 0a 20 20 20 20 23 20 6c 6f 63 6b 73 20 61 72  y.    # locks ar
cd30: 65 20 65 73 74 61 62 6c 69 73 68 65 64 20 6f 6e  e established on
cd40: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 73 20   database files 
cd50: 28 69 2e 65 2e 20 69 66 20 74 68 65 20 65 72 72  (i.e. if the err
cd60: 6f 72 0a 20 20 20 20 23 20 6f 63 63 75 72 73 20  or.    # occurs 
cd70: 77 68 69 6c 65 20 61 74 74 65 6d 70 74 69 6e 67  while attempting
cd80: 20 74 6f 20 64 65 74 65 63 74 20 61 20 68 6f 74   to detect a hot
cd90: 2d 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 29 2c 20  -journal file), 
cda0: 74 68 65 6e 0a 20 20 20 20 23 20 74 68 65 72 65  then.    # there
cdb0: 20 6d 61 79 20 30 20 70 61 67 65 20 72 65 66 65   may 0 page refe
cdc0: 72 65 6e 63 65 73 20 61 6e 64 20 61 6e 20 61 63  rences and an ac
cdd0: 74 69 76 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  tive transaction
cde0: 20 61 63 63 6f 72 64 69 6e 67 0a 20 20 20 20 23   according.    #
cdf0: 20 74 6f 20 5b 73 71 6c 69 74 65 33 5f 67 65 74   to [sqlite3_get
ce00: 5f 61 75 74 6f 63 6f 6d 6d 69 74 5d 2e 0a 20 20  _autocommit]..  
ce10: 20 20 23 0a 20 20 20 20 69 66 20 7b 24 3a 3a 67    #.    if {$::g
ce20: 6f 20 26 26 20 24 3a 3a 73 71 6c 69 74 65 5f 69  o && $::sqlite_i
ce30: 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20  o_error_hardhit 
ce40: 26 26 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28  && $::ioerropts(
ce50: 2d 63 6b 72 65 66 63 6f 75 6e 74 29 7d 20 7b 0a  -ckrefcount)} {.
ce60: 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20 24 74        do_test $t
ce70: 65 73 74 6e 61 6d 65 2e 24 6e 2e 34 20 7b 0a 20  estname.$n.4 {. 
ce80: 20 20 20 20 20 20 20 73 65 74 20 62 74 20 5b 62         set bt [b
ce90: 74 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d  tree_from_db db]
cea0: 0a 20 20 20 20 20 20 20 20 64 62 5f 65 6e 74 65  .        db_ente
ceb0: 72 20 64 62 0a 20 20 20 20 20 20 20 20 61 72 72  r db.        arr
cec0: 61 79 20 73 65 74 20 73 74 61 74 73 20 5b 62 74  ay set stats [bt
ced0: 72 65 65 5f 70 61 67 65 72 5f 73 74 61 74 73 20  ree_pager_stats 
cee0: 24 62 74 5d 0a 20 20 20 20 20 20 20 20 64 62 5f  $bt].        db_
cef0: 6c 65 61 76 65 20 64 62 0a 20 20 20 20 20 20 20  leave db.       
cf00: 20 73 65 74 20 6e 52 65 66 20 24 73 74 61 74 73   set nRef $stats
cf10: 28 72 65 66 29 0a 20 20 20 20 20 20 20 20 65 78  (ref).        ex
cf20: 70 72 20 7b 24 6e 52 65 66 20 3d 3d 20 30 20 7c  pr {$nRef == 0 |
cf30: 7c 20 28 5b 73 71 6c 69 74 65 33 5f 67 65 74 5f  | ([sqlite3_get_
cf40: 61 75 74 6f 63 6f 6d 6d 69 74 20 64 62 5d 3d 3d  autocommit db]==
cf50: 30 20 26 26 20 24 6e 52 65 66 20 3d 3d 20 31 29  0 && $nRef == 1)
cf60: 7d 0a 20 20 20 20 20 20 7d 20 7b 31 7d 0a 20 20  }.      } {1}.  
cf70: 20 20 7d 0a 0a 20 20 20 20 23 20 49 66 20 74 68    }..    # If th
cf80: 65 72 65 20 69 73 20 61 6e 20 6f 70 65 6e 20 64  ere is an open d
cf90: 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 20 61  atabase handle a
cfa0: 6e 64 20 6e 6f 20 6f 70 65 6e 20 74 72 61 6e 73  nd no open trans
cfb0: 61 63 74 69 6f 6e 2c 0a 20 20 20 20 23 20 61 6e  action,.    # an
cfc0: 64 20 74 68 65 20 70 61 67 65 72 20 69 73 20 6e  d the pager is n
cfd0: 6f 74 20 72 75 6e 6e 69 6e 67 20 69 6e 20 65 78  ot running in ex
cfe0: 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69 6e 67 20  clusive-locking 
cff0: 6d 6f 64 65 2c 0a 20 20 20 20 23 20 63 68 65 63  mode,.    # chec
d000: 6b 20 74 68 61 74 20 74 68 65 20 70 61 67 65 72  k that the pager
d010: 20 69 73 20 69 6e 20 22 75 6e 6c 6f 63 6b 65 64   is in "unlocked
d020: 22 20 73 74 61 74 65 2e 20 54 68 65 6f 72 65 74  " state. Theoret
d030: 69 63 61 6c 6c 79 2c 0a 20 20 20 20 23 20 69 66  ically,.    # if
d040: 20 61 20 63 61 6c 6c 20 74 6f 20 78 55 6e 6c 6f   a call to xUnlo
d050: 63 6b 28 29 20 66 61 69 6c 65 64 20 64 75 65 20  ck() failed due 
d060: 74 6f 20 61 6e 20 49 4f 20 65 72 72 6f 72 20 74  to an IO error t
d070: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 20 20  he underlying.  
d080: 20 20 23 20 66 69 6c 65 20 6d 61 79 20 73 74 69    # file may sti
d090: 6c 6c 20 62 65 20 6c 6f 63 6b 65 64 2e 0a 20 20  ll be locked..  
d0a0: 20 20 23 0a 20 20 20 20 69 66 63 61 70 61 62 6c    #.    ifcapabl
d0b0: 65 20 70 72 61 67 6d 61 20 7b 0a 20 20 20 20 20  e pragma {.     
d0c0: 20 69 66 20 7b 20 5b 69 6e 66 6f 20 63 6f 6d 6d   if { [info comm
d0d0: 61 6e 64 73 20 64 62 5d 20 6e 65 20 22 22 0a 20  ands db] ne "". 
d0e0: 20 20 20 20 20 20 20 26 26 20 24 3a 3a 69 6f 65         && $::ioe
d0f0: 72 72 6f 70 74 73 28 2d 63 6b 72 65 66 63 6f 75  rropts(-ckrefcou
d100: 6e 74 29 0a 20 20 20 20 20 20 20 20 26 26 20 5b  nt).        && [
d110: 64 62 20 6f 6e 65 20 7b 70 72 61 67 6d 61 20 6c  db one {pragma l
d120: 6f 63 6b 69 6e 67 5f 6d 6f 64 65 7d 5d 20 65 71  ocking_mode}] eq
d130: 20 22 6e 6f 72 6d 61 6c 22 0a 20 20 20 20 20 20   "normal".      
d140: 20 20 26 26 20 5b 73 71 6c 69 74 65 33 5f 67 65    && [sqlite3_ge
d150: 74 5f 61 75 74 6f 63 6f 6d 6d 69 74 20 64 62 5d  t_autocommit db]
d160: 0a 20 20 20 20 20 20 7d 20 7b 0a 20 20 20 20 20  .      } {.     
d170: 20 20 20 64 6f 5f 74 65 73 74 20 24 74 65 73 74     do_test $test
d180: 6e 61 6d 65 2e 24 6e 2e 35 20 7b 0a 20 20 20 20  name.$n.5 {.    
d190: 20 20 20 20 20 20 73 65 74 20 62 74 20 5b 62 74        set bt [bt
d1a0: 72 65 65 5f 66 72 6f 6d 5f 64 62 20 64 62 5d 0a  ree_from_db db].
d1b0: 20 20 20 20 20 20 20 20 20 20 64 62 5f 65 6e 74            db_ent
d1c0: 65 72 20 64 62 0a 20 20 20 20 20 20 20 20 20 20  er db.          
d1d0: 61 72 72 61 79 20 73 65 74 20 73 74 61 74 73 20  array set stats 
d1e0: 5b 62 74 72 65 65 5f 70 61 67 65 72 5f 73 74 61  [btree_pager_sta
d1f0: 74 73 20 24 62 74 5d 0a 20 20 20 20 20 20 20 20  ts $bt].        
d200: 20 20 64 62 5f 6c 65 61 76 65 20 64 62 0a 20 20    db_leave db.  
d210: 20 20 20 20 20 20 20 20 73 65 74 20 73 74 61 74          set stat
d220: 73 28 73 74 61 74 65 29 0a 20 20 20 20 20 20 20  s(state).       
d230: 20 7d 20 30 0a 20 20 20 20 20 20 7d 0a 20 20 20   } 0.      }.   
d240: 20 7d 0a 0a 20 20 20 20 23 20 49 66 20 61 6e 20   }..    # If an 
d250: 49 4f 20 65 72 72 6f 72 20 6f 63 63 75 72 72 65  IO error occurre
d260: 64 2c 20 74 68 65 6e 20 74 68 65 20 63 68 65 63  d, then the chec
d270: 6b 73 75 6d 20 6f 66 20 74 68 65 20 64 61 74 61  ksum of the data
d280: 62 61 73 65 20 73 68 6f 75 6c 64 0a 20 20 20 20  base should.    
d290: 23 20 62 65 20 74 68 65 20 73 61 6d 65 20 61 73  # be the same as
d2a0: 20 62 65 66 6f 72 65 20 74 68 65 20 73 63 72 69   before the scri
d2b0: 70 74 20 74 68 61 74 20 63 61 75 73 65 64 20 74  pt that caused t
d2c0: 68 65 20 49 4f 20 65 72 72 6f 72 20 77 61 73 20  he IO error was 
d2d0: 72 75 6e 2e 0a 20 20 20 20 23 0a 20 20 20 20 69  run..    #.    i
d2e0: 66 20 7b 24 3a 3a 67 6f 20 26 26 20 24 3a 3a 73  f {$::go && $::s
d2f0: 71 6c 69 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 68  qlite_io_error_h
d300: 61 72 64 68 69 74 20 26 26 20 24 3a 3a 69 6f 65  ardhit && $::ioe
d310: 72 72 6f 70 74 73 28 2d 63 6b 73 75 6d 29 7d 20  rropts(-cksum)} 
d320: 7b 0a 20 20 20 20 20 20 64 6f 5f 74 65 73 74 20  {.      do_test 
d330: 24 74 65 73 74 6e 61 6d 65 2e 24 6e 2e 36 20 7b  $testname.$n.6 {
d340: 0a 20 20 20 20 20 20 20 20 63 61 74 63 68 20 7b  .        catch {
d350: 64 62 20 63 6c 6f 73 65 7d 0a 20 20 20 20 20 20  db close}.      
d360: 20 20 63 61 74 63 68 20 7b 64 62 32 20 63 6c 6f    catch {db2 clo
d370: 73 65 7d 0a 20 20 20 20 20 20 20 20 73 65 74 20  se}.        set 
d380: 3a 3a 44 42 20 5b 73 71 6c 69 74 65 33 20 64 62  ::DB [sqlite3 db
d390: 20 74 65 73 74 2e 64 62 3b 20 73 71 6c 69 74 65   test.db; sqlite
d3a0: 33 5f 63 6f 6e 6e 65 63 74 69 6f 6e 5f 70 6f 69  3_connection_poi
d3b0: 6e 74 65 72 20 64 62 5d 0a 20 20 20 20 20 20 20  nter db].       
d3c0: 20 73 65 74 20 6e 6f 77 63 6b 73 75 6d 20 5b 63   set nowcksum [c
d3d0: 6b 73 75 6d 5d 0a 20 20 20 20 20 20 20 20 73 65  ksum].        se
d3e0: 74 20 72 65 73 20 5b 65 78 70 72 20 7b 24 6e 6f  t res [expr {$no
d3f0: 77 63 6b 73 75 6d 3d 3d 24 3a 3a 63 68 65 63 6b  wcksum==$::check
d400: 73 75 6d 20 7c 7c 20 24 6e 6f 77 63 6b 73 75 6d  sum || $nowcksum
d410: 3d 3d 24 3a 3a 67 6f 6f 64 63 6b 73 75 6d 7d 5d  ==$::goodcksum}]
d420: 0a 20 20 20 20 20 20 20 20 69 66 20 7b 24 72 65  .        if {$re
d430: 73 3d 3d 30 7d 20 7b 0a 20 20 20 20 20 20 20 20  s==0} {.        
d440: 20 20 6f 75 74 70 75 74 32 20 22 6e 6f 77 3d 24    output2 "now=$
d450: 6e 6f 77 63 6b 73 75 6d 22 0a 20 20 20 20 20 20  nowcksum".      
d460: 20 20 20 20 6f 75 74 70 75 74 32 20 22 74 68 65      output2 "the
d470: 3d 24 3a 3a 63 68 65 63 6b 73 75 6d 22 0a 20 20  =$::checksum".  
d480: 20 20 20 20 20 20 20 20 6f 75 74 70 75 74 32 20          output2 
d490: 22 66 77 64 3d 24 3a 3a 67 6f 6f 64 63 6b 73 75  "fwd=$::goodcksu
d4a0: 6d 22 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  m".        }.   
d4b0: 20 20 20 20 20 73 65 74 20 72 65 73 0a 20 20 20       set res.   
d4c0: 20 20 20 7d 20 31 0a 20 20 20 20 7d 0a 0a 20 20     } 1.    }..  
d4d0: 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65 5f 69    set ::sqlite_i
d4e0: 6f 5f 65 72 72 6f 72 5f 68 61 72 64 68 69 74 20  o_error_hardhit 
d4f0: 30 0a 20 20 20 20 73 65 74 20 3a 3a 73 71 6c 69  0.    set ::sqli
d500: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64  te_io_error_pend
d510: 69 6e 67 20 30 0a 20 20 20 20 69 66 20 7b 5b 69  ing 0.    if {[i
d520: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 69 6f 65  nfo exists ::ioe
d530: 72 72 6f 70 74 73 28 2d 63 6c 65 61 6e 75 70 29  rropts(-cleanup)
d540: 5d 7d 20 7b 0a 20 20 20 20 20 20 63 61 74 63 68  ]} {.      catch
d550: 20 24 3a 3a 69 6f 65 72 72 6f 70 74 73 28 2d 63   $::ioerropts(-c
d560: 6c 65 61 6e 75 70 29 0a 20 20 20 20 7d 0a 20 20  leanup).    }.  
d570: 7d 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65  }.  set ::sqlite
d580: 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 6e 64 69 6e  _io_error_pendin
d590: 67 20 30 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69  g 0.  set ::sqli
d5a0: 74 65 5f 69 6f 5f 65 72 72 6f 72 5f 70 65 72 73  te_io_error_pers
d5b0: 69 73 74 20 30 0a 20 20 75 6e 73 65 74 20 3a 3a  ist 0.  unset ::
d5c0: 69 6f 65 72 72 6f 70 74 73 0a 7d 0a 0a 23 20 52  ioerropts.}..# R
d5d0: 65 74 75 72 6e 20 61 20 63 68 65 63 6b 73 75 6d  eturn a checksum
d5e0: 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20 63 6f   based on the co
d5f0: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 6d 61  ntents of the ma
d600: 69 6e 20 64 61 74 61 62 61 73 65 20 61 73 73 6f  in database asso
d610: 63 69 61 74 65 64 0a 23 20 77 69 74 68 20 63 6f  ciated.# with co
d620: 6e 6e 65 63 74 69 6f 6e 20 24 64 62 0a 23 0a 70  nnection $db.#.p
d630: 72 6f 63 20 63 6b 73 75 6d 20 7b 7b 64 62 20 64  roc cksum {{db d
d640: 62 7d 7d 20 7b 0a 20 20 73 65 74 20 74 78 74 20  b}} {.  set txt 
d650: 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20  [$db eval {.    
d660: 20 20 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20 74    SELECT name, t
d670: 79 70 65 2c 20 73 71 6c 20 46 52 4f 4d 20 73 71  ype, sql FROM sq
d680: 6c 69 74 65 5f 6d 61 73 74 65 72 20 6f 72 64 65  lite_master orde
d690: 72 20 62 79 20 6e 61 6d 65 0a 20 20 7d 5d 5c 6e  r by name.  }]\n
d6a0: 0a 20 20 66 6f 72 65 61 63 68 20 74 62 6c 20 5b  .  foreach tbl [
d6b0: 24 64 62 20 65 76 61 6c 20 7b 0a 20 20 20 20 20  $db eval {.     
d6c0: 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f   SELECT name FRO
d6d0: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20  M sqlite_master 
d6e0: 57 48 45 52 45 20 74 79 70 65 3d 27 74 61 62 6c  WHERE type='tabl
d6f0: 65 27 20 6f 72 64 65 72 20 62 79 20 6e 61 6d 65  e' order by name
d700: 0a 20 20 7d 5d 20 7b 0a 20 20 20 20 61 70 70 65  .  }] {.    appe
d710: 6e 64 20 74 78 74 20 5b 24 64 62 20 65 76 61 6c  nd txt [$db eval
d720: 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20   "SELECT * FROM 
d730: 24 74 62 6c 22 5d 5c 6e 0a 20 20 7d 0a 20 20 66  $tbl"]\n.  }.  f
d740: 6f 72 65 61 63 68 20 70 72 61 67 20 7b 64 65 66  oreach prag {def
d750: 61 75 6c 74 5f 73 79 6e 63 68 72 6f 6e 6f 75 73  ault_synchronous
d760: 20 64 65 66 61 75 6c 74 5f 63 61 63 68 65 5f 73   default_cache_s
d770: 69 7a 65 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e  ize} {.    appen
d780: 64 20 74 78 74 20 24 70 72 61 67 2d 5b 24 64 62  d txt $prag-[$db
d790: 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 24 70   eval "PRAGMA $p
d7a0: 72 61 67 22 5d 5c 6e 0a 20 20 7d 0a 20 20 73 65  rag"]\n.  }.  se
d7b0: 74 20 63 6b 73 75 6d 20 5b 73 74 72 69 6e 67 20  t cksum [string 
d7c0: 6c 65 6e 67 74 68 20 24 74 78 74 5d 2d 5b 6d 64  length $txt]-[md
d7d0: 35 20 24 74 78 74 5d 0a 20 20 23 20 70 75 74 73  5 $txt].  # puts
d7e0: 20 24 63 6b 73 75 6d 2d 5b 66 69 6c 65 20 73 69   $cksum-[file si
d7f0: 7a 65 20 74 65 73 74 2e 64 62 5d 0a 20 20 72 65  ze test.db].  re
d800: 74 75 72 6e 20 24 63 6b 73 75 6d 0a 7d 0a 0a 23  turn $cksum.}..#
d810: 20 47 65 6e 65 72 61 74 65 20 61 20 63 68 65 63   Generate a chec
d820: 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74 68  ksum based on th
d830: 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68  e contents of th
d840: 65 20 6d 61 69 6e 20 61 6e 64 20 74 65 6d 70 20  e main and temp 
d850: 74 61 62 6c 65 73 0a 23 20 64 61 74 61 62 61 73  tables.# databas
d860: 65 20 24 64 62 2e 20 49 66 20 74 68 65 20 63 68  e $db. If the ch
d870: 65 63 6b 73 75 6d 20 6f 66 20 74 77 6f 20 64 61  ecksum of two da
d880: 74 61 62 61 73 65 73 20 69 73 20 74 68 65 20 73  tabases is the s
d890: 61 6d 65 2c 20 61 6e 64 20 74 68 65 0a 23 20 69  ame, and the.# i
d8a0: 6e 74 65 67 72 69 74 79 2d 63 68 65 63 6b 20 70  ntegrity-check p
d8b0: 61 73 73 65 73 20 66 6f 72 20 62 6f 74 68 2c 20  asses for both, 
d8c0: 74 68 65 20 74 77 6f 20 64 61 74 61 62 61 73 65  the two database
d8d0: 73 20 61 72 65 20 69 64 65 6e 74 69 63 61 6c 2e  s are identical.
d8e0: 0a 23 0a 70 72 6f 63 20 61 6c 6c 63 6b 73 75 6d  .#.proc allcksum
d8f0: 20 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 73   {{db db}} {.  s
d900: 65 74 20 72 65 74 20 5b 6c 69 73 74 5d 0a 20 20  et ret [list].  
d910: 69 66 63 61 70 61 62 6c 65 20 74 65 6d 70 64 62  ifcapable tempdb
d920: 20 7b 0a 20 20 20 20 73 65 74 20 73 71 6c 20 7b   {.    set sql {
d930: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61  .      SELECT na
d940: 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d  me FROM sqlite_m
d950: 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70 65  aster WHERE type
d960: 20 3d 20 27 74 61 62 6c 65 27 20 55 4e 49 4f 4e   = 'table' UNION
d970: 0a 20 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61  .      SELECT na
d980: 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 74  me FROM sqlite_t
d990: 65 6d 70 5f 6d 61 73 74 65 72 20 57 48 45 52 45  emp_master WHERE
d9a0: 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65 27 20   type = 'table' 
d9b0: 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45  UNION.      SELE
d9c0: 43 54 20 27 73 71 6c 69 74 65 5f 6d 61 73 74 65  CT 'sqlite_maste
d9d0: 72 27 20 55 4e 49 4f 4e 0a 20 20 20 20 20 20 53  r' UNION.      S
d9e0: 45 4c 45 43 54 20 27 73 71 6c 69 74 65 5f 74 65  ELECT 'sqlite_te
d9f0: 6d 70 5f 6d 61 73 74 65 72 27 20 4f 52 44 45 52  mp_master' ORDER
da00: 20 42 59 20 31 0a 20 20 20 20 7d 0a 20 20 7d 20   BY 1.    }.  } 
da10: 65 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 73  else {.    set s
da20: 71 6c 20 7b 0a 20 20 20 20 20 20 53 45 4c 45 43  ql {.      SELEC
da30: 54 20 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69  T name FROM sqli
da40: 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20  te_master WHERE 
da50: 74 79 70 65 20 3d 20 27 74 61 62 6c 65 27 20 55  type = 'table' U
da60: 4e 49 4f 4e 0a 20 20 20 20 20 20 53 45 4c 45 43  NION.      SELEC
da70: 54 20 27 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  T 'sqlite_master
da80: 27 20 4f 52 44 45 52 20 42 59 20 31 0a 20 20 20  ' ORDER BY 1.   
da90: 20 7d 0a 20 20 7d 0a 20 20 73 65 74 20 74 62 6c   }.  }.  set tbl
daa0: 6c 69 73 74 20 5b 24 64 62 20 65 76 61 6c 20 24  list [$db eval $
dab0: 73 71 6c 5d 0a 20 20 73 65 74 20 74 78 74 20 7b  sql].  set txt {
dac0: 7d 0a 20 20 66 6f 72 65 61 63 68 20 74 62 6c 20  }.  foreach tbl 
dad0: 24 74 62 6c 6c 69 73 74 20 7b 0a 20 20 20 20 61  $tbllist {.    a
dae0: 70 70 65 6e 64 20 74 78 74 20 5b 24 64 62 20 65  ppend txt [$db e
daf0: 76 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46 52  val "SELECT * FR
db00: 4f 4d 20 24 74 62 6c 22 5d 0a 20 20 7d 0a 20 20  OM $tbl"].  }.  
db10: 66 6f 72 65 61 63 68 20 70 72 61 67 20 7b 64 65  foreach prag {de
db20: 66 61 75 6c 74 5f 63 61 63 68 65 5f 73 69 7a 65  fault_cache_size
db30: 7d 20 7b 0a 20 20 20 20 61 70 70 65 6e 64 20 74  } {.    append t
db40: 78 74 20 24 70 72 61 67 2d 5b 24 64 62 20 65 76  xt $prag-[$db ev
db50: 61 6c 20 22 50 52 41 47 4d 41 20 24 70 72 61 67  al "PRAGMA $prag
db60: 22 5d 5c 6e 0a 20 20 7d 0a 20 20 23 20 70 75 74  "]\n.  }.  # put
db70: 73 20 74 78 74 3d 24 74 78 74 0a 20 20 72 65 74  s txt=$txt.  ret
db80: 75 72 6e 20 5b 6d 64 35 20 24 74 78 74 5d 0a 7d  urn [md5 $txt].}
db90: 0a 0a 23 20 47 65 6e 65 72 61 74 65 20 61 20 63  ..# Generate a c
dba0: 68 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e  hecksum based on
dbb0: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
dbc0: 20 61 20 73 69 6e 67 6c 65 20 64 61 74 61 62 61   a single databa
dbd0: 73 65 20 77 69 74 68 0a 23 20 61 20 64 61 74 61  se with.# a data
dbe0: 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e  base connection.
dbf0: 20 20 54 68 65 20 6e 61 6d 65 20 6f 66 20 74 68    The name of th
dc00: 65 20 64 61 74 61 62 61 73 65 20 69 73 20 24 64  e database is $d
dc10: 62 6e 61 6d 65 2e 0a 23 20 45 78 61 6d 70 6c 65  bname..# Example
dc20: 73 20 6f 66 20 24 64 62 6e 61 6d 65 20 61 72 65  s of $dbname are
dc30: 20 22 74 65 6d 70 22 20 6f 72 20 22 6d 61 69 6e   "temp" or "main
dc40: 22 2e 0a 23 0a 70 72 6f 63 20 64 62 63 6b 73 75  "..#.proc dbcksu
dc50: 6d 20 7b 64 62 20 64 62 6e 61 6d 65 7d 20 7b 0a  m {db dbname} {.
dc60: 20 20 69 66 20 7b 24 64 62 6e 61 6d 65 3d 3d 22    if {$dbname=="
dc70: 74 65 6d 70 22 7d 20 7b 0a 20 20 20 20 73 65 74  temp"} {.    set
dc80: 20 6d 61 73 74 65 72 20 73 71 6c 69 74 65 5f 74   master sqlite_t
dc90: 65 6d 70 5f 6d 61 73 74 65 72 0a 20 20 7d 20 65  emp_master.  } e
dca0: 6c 73 65 20 7b 0a 20 20 20 20 73 65 74 20 6d 61  lse {.    set ma
dcb0: 73 74 65 72 20 24 64 62 6e 61 6d 65 2e 73 71 6c  ster $dbname.sql
dcc0: 69 74 65 5f 6d 61 73 74 65 72 0a 20 20 7d 0a 20  ite_master.  }. 
dcd0: 20 73 65 74 20 61 6c 6c 74 61 62 20 5b 24 64 62   set alltab [$db
dce0: 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 6e 61   eval "SELECT na
dcf0: 6d 65 20 46 52 4f 4d 20 24 6d 61 73 74 65 72 20  me FROM $master 
dd00: 57 48 45 52 45 20 74 79 70 65 3d 27 74 61 62 6c  WHERE type='tabl
dd10: 65 27 22 5d 0a 20 20 73 65 74 20 74 78 74 20 5b  e'"].  set txt [
dd20: 24 64 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54  $db eval "SELECT
dd30: 20 2a 20 46 52 4f 4d 20 24 6d 61 73 74 65 72 22   * FROM $master"
dd40: 5d 5c 6e 0a 20 20 66 6f 72 65 61 63 68 20 74 61  ]\n.  foreach ta
dd50: 62 20 24 61 6c 6c 74 61 62 20 7b 0a 20 20 20 20  b $alltab {.    
dd60: 61 70 70 65 6e 64 20 74 78 74 20 5b 24 64 62 20  append txt [$db 
dd70: 65 76 61 6c 20 22 53 45 4c 45 43 54 20 2a 20 46  eval "SELECT * F
dd80: 52 4f 4d 20 24 64 62 6e 61 6d 65 2e 24 74 61 62  ROM $dbname.$tab
dd90: 22 5d 5c 6e 0a 20 20 7d 0a 20 20 72 65 74 75 72  "]\n.  }.  retur
dda0: 6e 20 5b 6d 64 35 20 24 74 78 74 5d 0a 7d 0a 0a  n [md5 $txt].}..
ddb0: 70 72 6f 63 20 6d 65 6d 64 65 62 75 67 5f 6c 6f  proc memdebug_lo
ddc0: 67 5f 73 71 6c 20 7b 7b 66 69 6c 65 6e 61 6d 65  g_sql {{filename
ddd0: 20 6d 61 6c 6c 6f 63 73 2e 73 71 6c 7d 7d 20 7b   mallocs.sql}} {
dde0: 0a 0a 20 20 73 65 74 20 64 61 74 61 20 5b 73 71  ..  set data [sq
ddf0: 6c 69 74 65 33 5f 6d 65 6d 64 65 62 75 67 5f 6c  lite3_memdebug_l
de00: 6f 67 20 64 75 6d 70 5d 0a 20 20 73 65 74 20 6e  og dump].  set n
de10: 46 72 61 6d 65 20 5b 65 78 70 72 20 5b 6c 6c 65  Frame [expr [lle
de20: 6e 67 74 68 20 5b 6c 69 6e 64 65 78 20 24 64 61  ngth [lindex $da
de30: 74 61 20 30 5d 5d 2d 32 5d 0a 20 20 69 66 20 7b  ta 0]]-2].  if {
de40: 24 6e 46 72 61 6d 65 20 3c 20 30 7d 20 7b 20 72  $nFrame < 0} { r
de50: 65 74 75 72 6e 20 22 22 20 7d 0a 0a 20 20 73 65  eturn "" }..  se
de60: 74 20 64 61 74 61 62 61 73 65 20 74 65 6d 70 0a  t database temp.
de70: 0a 20 20 73 65 74 20 74 62 6c 20 22 43 52 45 41  .  set tbl "CREA
de80: 54 45 20 54 41 42 4c 45 20 24 7b 64 61 74 61 62  TE TABLE ${datab
de90: 61 73 65 7d 2e 6d 61 6c 6c 6f 63 28 7a 54 65 73  ase}.malloc(zTes
dea0: 74 2c 20 6e 43 61 6c 6c 2c 20 6e 42 79 74 65 2c  t, nCall, nByte,
deb0: 20 6c 53 74 61 63 6b 29 3b 22 0a 0a 20 20 73 65   lStack);"..  se
dec0: 74 20 73 71 6c 20 22 22 0a 20 20 66 6f 72 65 61  t sql "".  forea
ded0: 63 68 20 65 20 24 64 61 74 61 20 7b 0a 20 20 20  ch e $data {.   
dee0: 20 73 65 74 20 6e 43 61 6c 6c 20 5b 6c 69 6e 64   set nCall [lind
def0: 65 78 20 24 65 20 30 5d 0a 20 20 20 20 73 65 74  ex $e 0].    set
df00: 20 6e 42 79 74 65 20 5b 6c 69 6e 64 65 78 20 24   nByte [lindex $
df10: 65 20 31 5d 0a 20 20 20 20 73 65 74 20 6c 53 74  e 1].    set lSt
df20: 61 63 6b 20 5b 6c 72 61 6e 67 65 20 24 65 20 32  ack [lrange $e 2
df30: 20 65 6e 64 5d 0a 20 20 20 20 61 70 70 65 6e 64   end].    append
df40: 20 73 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54   sql "INSERT INT
df50: 4f 20 24 7b 64 61 74 61 62 61 73 65 7d 2e 6d 61  O ${database}.ma
df60: 6c 6c 6f 63 20 56 41 4c 55 45 53 22 0a 20 20 20  lloc VALUES".   
df70: 20 61 70 70 65 6e 64 20 73 71 6c 20 22 28 27 74   append sql "('t
df80: 65 73 74 27 2c 20 24 6e 43 61 6c 6c 2c 20 24 6e  est', $nCall, $n
df90: 42 79 74 65 2c 20 27 24 6c 53 74 61 63 6b 27 29  Byte, '$lStack')
dfa0: 3b 5c 6e 22 0a 20 20 20 20 66 6f 72 65 61 63 68  ;\n".    foreach
dfb0: 20 66 20 24 6c 53 74 61 63 6b 20 7b 0a 20 20 20   f $lStack {.   
dfc0: 20 20 20 73 65 74 20 66 72 61 6d 65 73 28 24 66     set frames($f
dfd0: 29 20 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  ) 1.    }.  }.. 
dfe0: 20 73 65 74 20 74 62 6c 32 20 22 43 52 45 41 54   set tbl2 "CREAT
dff0: 45 20 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61  E TABLE ${databa
e000: 73 65 7d 2e 66 72 61 6d 65 28 66 72 61 6d 65 20  se}.frame(frame 
e010: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20  INTEGER PRIMARY 
e020: 4b 45 59 2c 20 6c 69 6e 65 29 3b 5c 6e 22 0a 20  KEY, line);\n". 
e030: 20 73 65 74 20 74 62 6c 33 20 22 43 52 45 41 54   set tbl3 "CREAT
e040: 45 20 54 41 42 4c 45 20 24 7b 64 61 74 61 62 61  E TABLE ${databa
e050: 73 65 7d 2e 66 69 6c 65 28 6e 61 6d 65 20 50 52  se}.file(name PR
e060: 49 4d 41 52 59 20 4b 45 59 2c 20 63 6f 6e 74 65  IMARY KEY, conte
e070: 6e 74 29 3b 5c 6e 22 0a 0a 20 20 66 6f 72 65 61  nt);\n"..  forea
e080: 63 68 20 66 20 5b 61 72 72 61 79 20 6e 61 6d 65  ch f [array name
e090: 73 20 66 72 61 6d 65 73 5d 20 7b 0a 20 20 20 20  s frames] {.    
e0a0: 73 65 74 20 61 64 64 72 20 5b 66 6f 72 6d 61 74  set addr [format
e0b0: 20 25 78 20 24 66 5d 0a 20 20 20 20 73 65 74 20   %x $f].    set 
e0c0: 63 6d 64 20 22 61 64 64 72 32 6c 69 6e 65 20 2d  cmd "addr2line -
e0d0: 65 20 5b 69 6e 66 6f 20 6e 61 6d 65 6f 66 65 78  e [info nameofex
e0e0: 65 63 5d 20 24 61 64 64 72 22 0a 20 20 20 20 73  ec] $addr".    s
e0f0: 65 74 20 6c 69 6e 65 20 5b 65 76 61 6c 20 65 78  et line [eval ex
e100: 65 63 20 24 63 6d 64 5d 0a 20 20 20 20 61 70 70  ec $cmd].    app
e110: 65 6e 64 20 73 71 6c 20 22 49 4e 53 45 52 54 20  end sql "INSERT 
e120: 49 4e 54 4f 20 24 7b 64 61 74 61 62 61 73 65 7d  INTO ${database}
e130: 2e 66 72 61 6d 65 20 56 41 4c 55 45 53 28 24 66  .frame VALUES($f
e140: 2c 20 27 24 6c 69 6e 65 27 29 3b 5c 6e 22 0a 0a  , '$line');\n"..
e150: 20 20 20 20 73 65 74 20 66 69 6c 65 20 5b 6c 69      set file [li
e160: 6e 64 65 78 20 5b 73 70 6c 69 74 20 24 6c 69 6e  ndex [split $lin
e170: 65 20 3a 5d 20 30 5d 0a 20 20 20 20 73 65 74 20  e :] 0].    set 
e180: 66 69 6c 65 73 28 24 66 69 6c 65 29 20 31 0a 20  files($file) 1. 
e190: 20 7d 0a 0a 20 20 66 6f 72 65 61 63 68 20 66 20   }..  foreach f 
e1a0: 5b 61 72 72 61 79 20 6e 61 6d 65 73 20 66 69 6c  [array names fil
e1b0: 65 73 5d 20 7b 0a 20 20 20 20 73 65 74 20 63 6f  es] {.    set co
e1c0: 6e 74 65 6e 74 73 20 22 22 0a 20 20 20 20 63 61  ntents "".    ca
e1d0: 74 63 68 20 7b 0a 20 20 20 20 20 20 73 65 74 20  tch {.      set 
e1e0: 66 64 20 5b 6f 70 65 6e 20 24 66 5d 0a 20 20 20  fd [open $f].   
e1f0: 20 20 20 73 65 74 20 63 6f 6e 74 65 6e 74 73 20     set contents 
e200: 5b 72 65 61 64 20 24 66 64 5d 0a 20 20 20 20 20  [read $fd].     
e210: 20 63 6c 6f 73 65 20 24 66 64 0a 20 20 20 20 7d   close $fd.    }
e220: 0a 20 20 20 20 73 65 74 20 63 6f 6e 74 65 6e 74  .    set content
e230: 73 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b 27  s [string map {'
e240: 20 27 27 7d 20 24 63 6f 6e 74 65 6e 74 73 5d 0a   ''} $contents].
e250: 20 20 20 20 61 70 70 65 6e 64 20 73 71 6c 20 22      append sql "
e260: 49 4e 53 45 52 54 20 49 4e 54 4f 20 24 7b 64 61  INSERT INTO ${da
e270: 74 61 62 61 73 65 7d 2e 66 69 6c 65 20 56 41 4c  tabase}.file VAL
e280: 55 45 53 28 27 24 66 27 2c 20 27 24 63 6f 6e 74  UES('$f', '$cont
e290: 65 6e 74 73 27 29 3b 5c 6e 22 0a 20 20 7d 0a 0a  ents');\n".  }..
e2a0: 20 20 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 24    set fd [open $
e2b0: 66 69 6c 65 6e 61 6d 65 20 77 5d 0a 20 20 70 75  filename w].  pu
e2c0: 74 73 20 24 66 64 20 22 42 45 47 49 4e 3b 20 24  ts $fd "BEGIN; $
e2d0: 7b 74 62 6c 7d 24 7b 74 62 6c 32 7d 24 7b 74 62  {tbl}${tbl2}${tb
e2e0: 6c 33 7d 24 7b 73 71 6c 7d 20 3b 20 43 4f 4d 4d  l3}${sql} ; COMM
e2f0: 49 54 3b 22 0a 20 20 63 6c 6f 73 65 20 24 66 64  IT;".  close $fd
e300: 0a 7d 0a 0a 23 20 44 72 6f 70 20 61 6c 6c 20 74  .}..# Drop all t
e310: 61 62 6c 65 73 20 69 6e 20 64 61 74 61 62 61 73  ables in databas
e320: 65 20 5b 64 62 5d 0a 70 72 6f 63 20 64 72 6f 70  e [db].proc drop
e330: 5f 61 6c 6c 5f 74 61 62 6c 65 73 20 7b 7b 64 62  _all_tables {{db
e340: 20 64 62 7d 7d 20 7b 0a 20 20 69 66 63 61 70 61   db}} {.  ifcapa
e350: 62 6c 65 20 74 72 69 67 67 65 72 26 26 66 6f 72  ble trigger&&for
e360: 65 69 67 6e 6b 65 79 20 7b 0a 20 20 20 20 73 65  eignkey {.    se
e370: 74 20 70 6b 20 5b 24 64 62 20 6f 6e 65 20 22 50  t pk [$db one "P
e380: 52 41 47 4d 41 20 66 6f 72 65 69 67 6e 5f 6b 65  RAGMA foreign_ke
e390: 79 73 22 5d 0a 20 20 20 20 24 64 62 20 65 76 61  ys"].    $db eva
e3a0: 6c 20 22 50 52 41 47 4d 41 20 66 6f 72 65 69 67  l "PRAGMA foreig
e3b0: 6e 5f 6b 65 79 73 20 3d 20 4f 46 46 22 0a 20 20  n_keys = OFF".  
e3c0: 7d 0a 20 20 66 6f 72 65 61 63 68 20 7b 69 64 78  }.  foreach {idx
e3d0: 20 6e 61 6d 65 20 66 69 6c 65 7d 20 5b 64 62 20   name file} [db 
e3e0: 65 76 61 6c 20 7b 50 52 41 47 4d 41 20 64 61 74  eval {PRAGMA dat
e3f0: 61 62 61 73 65 5f 6c 69 73 74 7d 5d 20 7b 0a 20  abase_list}] {. 
e400: 20 20 20 69 66 20 7b 24 69 64 78 3d 3d 31 7d 20     if {$idx==1} 
e410: 7b 0a 20 20 20 20 20 20 73 65 74 20 6d 61 73 74  {.      set mast
e420: 65 72 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d  er sqlite_temp_m
e430: 61 73 74 65 72 0a 20 20 20 20 7d 20 65 6c 73 65  aster.    } else
e440: 20 7b 0a 20 20 20 20 20 20 73 65 74 20 6d 61 73   {.      set mas
e450: 74 65 72 20 24 6e 61 6d 65 2e 73 71 6c 69 74 65  ter $name.sqlite
e460: 5f 6d 61 73 74 65 72 0a 20 20 20 20 7d 0a 20 20  _master.    }.  
e470: 20 20 66 6f 72 65 61 63 68 20 7b 74 20 74 79 70    foreach {t typ
e480: 65 7d 20 5b 24 64 62 20 65 76 61 6c 20 22 0a 20  e} [$db eval ". 
e490: 20 20 20 20 20 53 45 4c 45 43 54 20 6e 61 6d 65       SELECT name
e4a0: 2c 20 74 79 70 65 20 46 52 4f 4d 20 24 6d 61 73  , type FROM $mas
e4b0: 74 65 72 0a 20 20 20 20 20 20 57 48 45 52 45 20  ter.      WHERE 
e4c0: 74 79 70 65 20 49 4e 28 27 74 61 62 6c 65 27 2c  type IN('table',
e4d0: 20 27 76 69 65 77 27 29 20 41 4e 44 20 6e 61 6d   'view') AND nam
e4e0: 65 20 4e 4f 54 20 4c 49 4b 45 20 27 73 71 6c 69  e NOT LIKE 'sqli
e4f0: 74 65 58 5f 25 27 20 45 53 43 41 50 45 20 27 58  teX_%' ESCAPE 'X
e500: 27 0a 20 20 20 20 22 5d 20 7b 0a 20 20 20 20 20  '.    "] {.     
e510: 20 24 64 62 20 65 76 61 6c 20 22 44 52 4f 50 20   $db eval "DROP 
e520: 24 74 79 70 65 20 5c 22 24 74 5c 22 22 0a 20 20  $type \"$t\"".  
e530: 20 20 7d 0a 20 20 7d 0a 20 20 69 66 63 61 70 61    }.  }.  ifcapa
e540: 62 6c 65 20 74 72 69 67 67 65 72 26 26 66 6f 72  ble trigger&&for
e550: 65 69 67 6e 6b 65 79 20 7b 0a 20 20 20 20 24 64  eignkey {.    $d
e560: 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 66  b eval "PRAGMA f
e570: 6f 72 65 69 67 6e 5f 6b 65 79 73 20 3d 20 24 70  oreign_keys = $p
e580: 6b 22 0a 20 20 7d 0a 7d 0a 0a 23 20 44 72 6f 70  k".  }.}..# Drop
e590: 20 61 6c 6c 20 61 75 78 69 6c 69 61 72 79 20 69   all auxiliary i
e5a0: 6e 64 65 78 65 73 20 66 72 6f 6d 20 74 68 65 20  ndexes from the 
e5b0: 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 6f 70  main database op
e5c0: 65 6e 65 64 20 62 79 20 68 61 6e 64 6c 65 20 5b  ened by handle [
e5d0: 64 62 5d 2e 0a 23 0a 70 72 6f 63 20 64 72 6f 70  db]..#.proc drop
e5e0: 5f 61 6c 6c 5f 69 6e 64 65 78 65 73 20 7b 7b 64  _all_indexes {{d
e5f0: 62 20 64 62 7d 7d 20 7b 0a 20 20 73 65 74 20 4c  b db}} {.  set L
e600: 20 5b 24 64 62 20 65 76 61 6c 20 7b 0a 20 20 20   [$db eval {.   
e610: 20 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52 4f   SELECT name FRO
e620: 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20  M sqlite_master 
e630: 57 48 45 52 45 20 74 79 70 65 3d 27 69 6e 64 65  WHERE type='inde
e640: 78 27 20 41 4e 44 20 73 71 6c 20 4c 49 4b 45 20  x' AND sql LIKE 
e650: 27 63 72 65 61 74 65 25 27 0a 20 20 7d 5d 0a 20  'create%'.  }]. 
e660: 20 66 6f 72 65 61 63 68 20 69 64 78 20 24 4c 20   foreach idx $L 
e670: 7b 20 24 64 62 20 65 76 61 6c 20 22 44 52 4f 50  { $db eval "DROP
e680: 20 49 4e 44 45 58 20 24 69 64 78 22 20 7d 0a 7d   INDEX $idx" }.}
e690: 0a 0a 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ...#------------
e6a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e6b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e6c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
e6d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20  -------------.# 
e6e0: 49 66 20 61 20 74 65 73 74 20 73 63 72 69 70 74  If a test script
e6f0: 20 69 73 20 65 78 65 63 75 74 65 64 20 77 69 74   is executed wit
e700: 68 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  h global variabl
e710: 65 20 24 3a 3a 47 28 70 65 72 6d 3a 6e 61 6d 65  e $::G(perm:name
e720: 29 20 73 65 74 20 74 6f 0a 23 20 22 77 61 6c 22  ) set to.# "wal"
e730: 2c 20 74 68 65 6e 20 74 68 65 20 74 65 73 74 73  , then the tests
e740: 20 61 72 65 20 72 75 6e 20 69 6e 20 57 41 4c 20   are run in WAL 
e750: 6d 6f 64 65 2e 20 4f 74 68 65 72 77 69 73 65 2c  mode. Otherwise,
e760: 20 74 68 65 79 20 73 68 6f 75 6c 64 20 62 65 20   they should be 
e770: 72 75 6e 0a 23 20 69 6e 20 72 6f 6c 6c 62 61 63  run.# in rollbac
e780: 6b 20 6d 6f 64 65 2e 20 54 68 65 20 66 6f 6c 6c  k mode. The foll
e790: 6f 77 69 6e 67 20 54 63 6c 20 70 72 6f 63 73 20  owing Tcl procs 
e7a0: 61 72 65 20 75 73 65 64 20 74 6f 20 6d 61 6b 65  are used to make
e7b0: 20 74 68 69 73 20 6c 65 73 73 0a 23 20 69 6e 74   this less.# int
e7c0: 72 75 73 69 76 65 3a 0a 23 0a 23 20 20 20 77 61  rusive:.#.#   wa
e7d0: 6c 5f 73 65 74 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f  l_set_journal_mo
e7e0: 64 65 20 3f 44 42 3f 0a 23 0a 23 20 20 20 20 20  de ?DB?.#.#     
e7f0: 49 66 20 72 75 6e 6e 69 6e 67 20 61 20 57 41 4c  If running a WAL
e800: 20 74 65 73 74 2c 20 65 78 65 63 75 74 65 20 22   test, execute "
e810: 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 6d  PRAGMA journal_m
e820: 6f 64 65 20 3d 20 77 61 6c 22 20 75 73 69 6e 67  ode = wal" using
e830: 0a 23 20 20 20 20 20 63 6f 6e 6e 65 63 74 69 6f  .#     connectio
e840: 6e 20 68 61 6e 64 6c 65 20 44 42 2e 20 4f 74 68  n handle DB. Oth
e850: 65 72 77 69 73 65 2c 20 74 68 69 73 20 63 6f 6d  erwise, this com
e860: 6d 61 6e 64 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  mand is a no-op.
e870: 0a 23 0a 23 20 20 20 77 61 6c 5f 63 68 65 63 6b  .#.#   wal_check
e880: 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20 54 45  _journal_mode TE
e890: 53 54 4e 41 4d 45 20 3f 44 42 3f 0a 23 0a 23 20  STNAME ?DB?.#.# 
e8a0: 20 20 20 20 49 66 20 72 75 6e 6e 69 6e 67 20 61      If running a
e8b0: 20 57 41 4c 20 74 65 73 74 2c 20 65 78 65 63 75   WAL test, execu
e8c0: 74 65 20 61 20 74 65 73 74 73 20 63 61 73 65 20  te a tests case 
e8d0: 74 68 61 74 20 66 61 69 6c 73 20 69 66 20 74 68  that fails if th
e8e0: 65 20 6d 61 69 6e 0a 23 20 20 20 20 20 64 61 74  e main.#     dat
e8f0: 61 62 61 73 65 20 66 6f 72 20 63 6f 6e 6e 65 63  abase for connec
e900: 74 69 6f 6e 20 68 61 6e 64 6c 65 20 44 42 20 69  tion handle DB i
e910: 73 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79 20  s not currently 
e920: 61 20 57 41 4c 20 64 61 74 61 62 61 73 65 2e 0a  a WAL database..
e930: 23 20 20 20 20 20 4f 74 68 65 72 77 69 73 65 20  #     Otherwise 
e940: 28 69 66 20 6e 6f 74 20 72 75 6e 6e 69 6e 67 20  (if not running 
e950: 61 20 57 41 4c 20 70 65 72 6d 75 74 61 74 69 6f  a WAL permutatio
e960: 6e 29 20 74 68 69 73 20 69 73 20 61 20 6e 6f 2d  n) this is a no-
e970: 6f 70 2e 0a 23 0a 23 20 20 20 77 61 6c 5f 69 73  op..#.#   wal_is
e980: 5f 77 61 6c 5f 6d 6f 64 65 0a 23 0a 23 20 20 20  _wal_mode.#.#   
e990: 20 20 52 65 74 75 72 6e 73 20 74 72 75 65 20 69    Returns true i
e9a0: 66 20 74 68 69 73 20 74 65 73 74 20 73 68 6f 75  f this test shou
e9b0: 6c 64 20 62 65 20 72 75 6e 20 69 6e 20 57 41 4c  ld be run in WAL
e9c0: 20 6d 6f 64 65 2e 20 46 61 6c 73 65 20 6f 74 68   mode. False oth
e9d0: 65 72 77 69 73 65 2e 0a 23 0a 70 72 6f 63 20 77  erwise..#.proc w
e9e0: 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65 20 7b  al_is_wal_mode {
e9f0: 7d 20 7b 0a 20 20 65 78 70 72 20 7b 5b 70 65 72  } {.  expr {[per
ea00: 6d 75 74 61 74 69 6f 6e 5d 20 65 71 20 22 77 61  mutation] eq "wa
ea10: 6c 22 7d 0a 7d 0a 70 72 6f 63 20 77 61 6c 5f 73  l"}.}.proc wal_s
ea20: 65 74 5f 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 20  et_journal_mode 
ea30: 7b 7b 64 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66  {{db db}} {.  if
ea40: 20 7b 20 5b 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d   { [wal_is_wal_m
ea50: 6f 64 65 5d 20 7d 20 7b 0a 20 20 20 20 24 64 62  ode] } {.    $db
ea60: 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20 6a 6f   eval "PRAGMA jo
ea70: 75 72 6e 61 6c 5f 6d 6f 64 65 20 3d 20 57 41 4c  urnal_mode = WAL
ea80: 22 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 77 61 6c  ".  }.}.proc wal
ea90: 5f 63 68 65 63 6b 5f 6a 6f 75 72 6e 61 6c 5f 6d  _check_journal_m
eaa0: 6f 64 65 20 7b 74 65 73 74 6e 61 6d 65 20 7b 64  ode {testname {d
eab0: 62 20 64 62 7d 7d 20 7b 0a 20 20 69 66 20 7b 20  b db}} {.  if { 
eac0: 5b 77 61 6c 5f 69 73 5f 77 61 6c 5f 6d 6f 64 65  [wal_is_wal_mode
ead0: 5d 20 7d 20 7b 0a 20 20 20 20 24 64 62 20 65 76  ] } {.    $db ev
eae0: 61 6c 20 7b 20 53 45 4c 45 43 54 20 2a 20 46 52  al { SELECT * FR
eaf0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
eb00: 20 7d 0a 20 20 20 20 64 6f 5f 74 65 73 74 20 24   }.    do_test $
eb10: 74 65 73 74 6e 61 6d 65 20 5b 6c 69 73 74 20 24  testname [list $
eb20: 64 62 20 65 76 61 6c 20 22 50 52 41 47 4d 41 20  db eval "PRAGMA 
eb30: 6d 61 69 6e 2e 6a 6f 75 72 6e 61 6c 5f 6d 6f 64  main.journal_mod
eb40: 65 22 5d 20 7b 77 61 6c 7d 0a 20 20 7d 0a 7d 0a  e"] {wal}.  }.}.
eb50: 0a 70 72 6f 63 20 77 61 6c 5f 69 73 5f 63 61 70  .proc wal_is_cap
eb60: 61 62 6c 65 20 7b 7d 20 7b 0a 20 20 69 66 63 61  able {} {.  ifca
eb70: 70 61 62 6c 65 20 21 77 61 6c 20 7b 20 72 65 74  pable !wal { ret
eb80: 75 72 6e 20 30 20 7d 0a 20 20 69 66 20 7b 5b 70  urn 0 }.  if {[p
eb90: 65 72 6d 75 74 61 74 69 6f 6e 5d 3d 3d 22 6a 6f  ermutation]=="jo
eba0: 75 72 6e 61 6c 74 65 73 74 22 7d 20 7b 20 72 65  urnaltest"} { re
ebb0: 74 75 72 6e 20 30 20 7d 0a 20 20 72 65 74 75 72  turn 0 }.  retur
ebc0: 6e 20 31 0a 7d 0a 0a 70 72 6f 63 20 70 65 72 6d  n 1.}..proc perm
ebd0: 75 74 61 74 69 6f 6e 20 7b 7d 20 7b 0a 20 20 73  utation {} {.  s
ebe0: 65 74 20 70 65 72 6d 20 22 22 0a 20 20 63 61 74  et perm "".  cat
ebf0: 63 68 20 7b 73 65 74 20 70 65 72 6d 20 24 3a 3a  ch {set perm $::
ec00: 47 28 70 65 72 6d 3a 6e 61 6d 65 29 7d 0a 20 20  G(perm:name)}.  
ec10: 73 65 74 20 70 65 72 6d 0a 7d 0a 70 72 6f 63 20  set perm.}.proc 
ec20: 70 72 65 73 71 6c 20 7b 7d 20 7b 0a 20 20 73 65  presql {} {.  se
ec30: 74 20 70 72 65 73 71 6c 20 22 22 0a 20 20 63 61  t presql "".  ca
ec40: 74 63 68 20 7b 73 65 74 20 70 72 65 73 71 6c 20  tch {set presql 
ec50: 24 3a 3a 47 28 70 65 72 6d 3a 70 72 65 73 71 6c  $::G(perm:presql
ec60: 29 7d 0a 20 20 73 65 74 20 70 72 65 73 71 6c 0a  )}.  set presql.
ec70: 7d 0a 0a 70 72 6f 63 20 69 73 71 75 69 63 6b 20  }..proc isquick 
ec80: 7b 7d 20 7b 0a 20 20 73 65 74 20 72 65 74 20 30  {} {.  set ret 0
ec90: 0a 20 20 63 61 74 63 68 20 7b 73 65 74 20 72 65  .  catch {set re
eca0: 74 20 24 3a 3a 47 28 69 73 71 75 69 63 6b 29 7d  t $::G(isquick)}
ecb0: 0a 20 20 73 65 74 20 72 65 74 0a 7d 0a 0a 23 2d  .  set ret.}..#-
ecc0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ecd0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ece0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ecf0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
ed00: 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 70 72 6f 63 20  --------.#.proc 
ed10: 73 6c 61 76 65 5f 74 65 73 74 5f 73 63 72 69 70  slave_test_scrip
ed20: 74 20 7b 73 63 72 69 70 74 7d 20 7b 0a 0a 20 20  t {script} {..  
ed30: 23 20 43 72 65 61 74 65 20 74 68 65 20 69 6e 74  # Create the int
ed40: 65 72 70 72 65 74 65 72 20 75 73 65 64 20 74 6f  erpreter used to
ed50: 20 72 75 6e 20 74 68 65 20 74 65 73 74 20 73 63   run the test sc
ed60: 72 69 70 74 2e 0a 20 20 69 6e 74 65 72 70 20 63  ript..  interp c
ed70: 72 65 61 74 65 20 74 69 6e 74 65 72 70 0a 0a 20  reate tinterp.. 
ed80: 20 23 20 50 6f 70 75 6c 61 74 65 20 73 6f 6d 65   # Populate some
ed90: 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   global variable
eda0: 73 20 74 68 61 74 20 74 65 73 74 65 72 2e 74 63  s that tester.tc
edb0: 6c 20 65 78 70 65 63 74 73 20 74 6f 20 73 65 65  l expects to see
edc0: 2e 0a 20 20 66 6f 72 65 61 63 68 20 7b 76 61 72  ..  foreach {var
edd0: 20 76 61 6c 75 65 7d 20 5b 6c 69 73 74 20 20 20   value} [list   
ede0: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20             \.   
edf0: 20 3a 3a 61 72 67 76 30 20 24 3a 3a 61 72 67 76   ::argv0 $::argv
ee00: 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0               
ee10: 20 20 20 20 20 20 5c 0a 20 20 20 20 3a 3a 61 72        \.    ::ar
ee20: 67 76 20 20 7b 7d 20 20 20 20 20 20 20 20 20 20  gv  {}          
ee30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ee40: 20 5c 0a 20 20 20 20 3a 3a 53 4c 41 56 45 20 31   \.    ::SLAVE 1
ee50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ee60: 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20              \.  
ee70: 5d 20 7b 0a 20 20 20 20 69 6e 74 65 72 70 20 65  ] {.    interp e
ee80: 76 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c 69 73  val tinterp [lis
ee90: 74 20 73 65 74 20 24 76 61 72 20 24 76 61 6c 75  t set $var $valu
eea0: 65 5d 0a 20 20 7d 0a 0a 20 20 23 20 49 66 20 6f  e].  }..  # If o
eeb0: 75 74 70 75 74 20 69 73 20 62 65 69 6e 67 20 63  utput is being c
eec0: 6f 70 69 65 64 20 69 6e 74 6f 20 61 20 66 69 6c  opied into a fil
eed0: 65 2c 20 73 68 61 72 65 20 74 68 65 20 66 69 6c  e, share the fil
eee0: 65 2d 64 65 73 63 72 69 70 74 6f 72 20 77 69 74  e-descriptor wit
eef0: 68 0a 20 20 23 20 74 68 65 20 69 6e 74 65 72 70  h.  # the interp
ef00: 72 65 74 65 72 2e 0a 20 20 69 66 20 7b 5b 69 6e  reter..  if {[in
ef10: 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 6f 75  fo exists ::G(ou
ef20: 74 70 75 74 5f 66 64 29 5d 7d 20 7b 0a 20 20 20  tput_fd)]} {.   
ef30: 20 69 6e 74 65 72 70 20 73 68 61 72 65 20 7b 7d   interp share {}
ef40: 20 24 3a 3a 47 28 6f 75 74 70 75 74 5f 66 64 29   $::G(output_fd)
ef50: 20 74 69 6e 74 65 72 70 0a 20 20 7d 0a 0a 20 20   tinterp.  }..  
ef60: 23 20 54 68 65 20 61 6c 69 61 73 20 75 73 65 64  # The alias used
ef70: 20 74 6f 20 61 63 63 65 73 73 20 74 68 65 20 67   to access the g
ef80: 6c 6f 62 61 6c 20 74 65 73 74 20 63 6f 75 6e 74  lobal test count
ef90: 65 72 73 2e 0a 20 20 74 69 6e 74 65 72 70 20 61  ers..  tinterp a
efa0: 6c 69 61 73 20 73 65 74 5f 74 65 73 74 5f 63 6f  lias set_test_co
efb0: 75 6e 74 65 72 20 73 65 74 5f 74 65 73 74 5f 63  unter set_test_c
efc0: 6f 75 6e 74 65 72 0a 0a 20 20 23 20 53 65 74 20  ounter..  # Set 
efd0: 75 70 20 74 68 65 20 3a 3a 63 6d 64 6c 69 6e 65  up the ::cmdline
efe0: 61 72 67 20 61 72 72 61 79 20 69 6e 20 74 68 65  arg array in the
eff0: 20 73 6c 61 76 65 2e 0a 20 20 69 6e 74 65 72 70   slave..  interp
f000: 20 65 76 61 6c 20 74 69 6e 74 65 72 70 20 5b 6c   eval tinterp [l
f010: 69 73 74 20 61 72 72 61 79 20 73 65 74 20 3a 3a  ist array set ::
f020: 63 6d 64 6c 69 6e 65 61 72 67 20 5b 61 72 72 61  cmdlinearg [arra
f030: 79 20 67 65 74 20 3a 3a 63 6d 64 6c 69 6e 65 61  y get ::cmdlinea
f040: 72 67 5d 5d 0a 0a 20 20 23 20 53 65 74 20 75 70  rg]]..  # Set up
f050: 20 74 68 65 20 3a 3a 47 20 61 72 72 61 79 20 69   the ::G array i
f060: 6e 20 74 68 65 20 73 6c 61 76 65 2e 0a 20 20 69  n the slave..  i
f070: 6e 74 65 72 70 20 65 76 61 6c 20 74 69 6e 74 65  nterp eval tinte
f080: 72 70 20 5b 6c 69 73 74 20 61 72 72 61 79 20 73  rp [list array s
f090: 65 74 20 3a 3a 47 20 5b 61 72 72 61 79 20 67 65  et ::G [array ge
f0a0: 74 20 3a 3a 47 5d 5d 0a 0a 20 20 23 20 4c 6f 61  t ::G]]..  # Loa
f0b0: 64 20 74 68 65 20 76 61 72 69 6f 75 73 20 74 65  d the various te
f0c0: 73 74 20 69 6e 74 65 72 66 61 63 65 73 20 69 6d  st interfaces im
f0d0: 70 6c 65 6d 65 6e 74 65 64 20 69 6e 20 43 2e 0a  plemented in C..
f0e0: 20 20 6c 6f 61 64 5f 74 65 73 74 66 69 78 74 75    load_testfixtu
f0f0: 72 65 5f 65 78 74 65 6e 73 69 6f 6e 73 20 74 69  re_extensions ti
f100: 6e 74 65 72 70 0a 0a 20 20 23 20 52 75 6e 20 74  nterp..  # Run t
f110: 68 65 20 74 65 73 74 20 73 63 72 69 70 74 2e 0a  he test script..
f120: 20 20 69 6e 74 65 72 70 20 65 76 61 6c 20 74 69    interp eval ti
f130: 6e 74 65 72 70 20 24 73 63 72 69 70 74 0a 0a 20  nterp $script.. 
f140: 20 23 20 43 68 65 63 6b 20 69 66 20 74 68 65 20   # Check if the 
f150: 69 6e 74 65 72 70 72 65 74 65 72 20 63 61 6c 6c  interpreter call
f160: 20 5b 72 75 6e 5f 74 68 72 65 61 64 5f 74 65 73   [run_thread_tes
f170: 74 73 5d 0a 20 20 69 66 20 7b 20 5b 69 6e 74 65  ts].  if { [inte
f180: 72 70 20 65 76 61 6c 20 74 69 6e 74 65 72 70 20  rp eval tinterp 
f190: 7b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 72  {info exists ::r
f1a0: 75 6e 5f 74 68 72 65 61 64 5f 74 65 73 74 73 5f  un_thread_tests_
f1b0: 63 61 6c 6c 65 64 7d 5d 20 7d 20 7b 0a 20 20 20  called}] } {.   
f1c0: 20 73 65 74 20 3a 3a 72 75 6e 5f 74 68 72 65 61   set ::run_threa
f1d0: 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64 20 31  d_tests_called 1
f1e0: 0a 20 20 7d 0a 0a 20 20 23 20 44 65 6c 65 74 65  .  }..  # Delete
f1f0: 20 74 68 65 20 69 6e 74 65 72 70 72 65 74 65 72   the interpreter
f200: 20 75 73 65 64 20 74 6f 20 72 75 6e 20 74 68 65   used to run the
f210: 20 74 65 73 74 20 73 63 72 69 70 74 2e 0a 20 20   test script..  
f220: 69 6e 74 65 72 70 20 64 65 6c 65 74 65 20 74 69  interp delete ti
f230: 6e 74 65 72 70 0a 7d 0a 0a 70 72 6f 63 20 73 6c  nterp.}..proc sl
f240: 61 76 65 5f 74 65 73 74 5f 66 69 6c 65 20 7b 7a  ave_test_file {z
f250: 46 69 6c 65 7d 20 7b 0a 20 20 73 65 74 20 74 61  File} {.  set ta
f260: 69 6c 20 5b 66 69 6c 65 20 74 61 69 6c 20 24 7a  il [file tail $z
f270: 46 69 6c 65 5d 0a 0a 20 20 69 66 20 7b 5b 69 6e  File]..  if {[in
f280: 66 6f 20 65 78 69 73 74 73 20 3a 3a 47 28 73 74  fo exists ::G(st
f290: 61 72 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29  art:permutation)
f2a0: 5d 7d 20 7b 0a 20 20 20 20 69 66 20 7b 5b 70 65  ]} {.    if {[pe
f2b0: 72 6d 75 74 61 74 69 6f 6e 5d 20 21 3d 20 24 3a  rmutation] != $:
f2c0: 3a 47 28 73 74 61 72 74 3a 70 65 72 6d 75 74 61  :G(start:permuta
f2d0: 74 69 6f 6e 29 7d 20 72 65 74 75 72 6e 0a 20 20  tion)} return.  
f2e0: 20 20 75 6e 73 65 74 20 3a 3a 47 28 73 74 61 72    unset ::G(star
f2f0: 74 3a 70 65 72 6d 75 74 61 74 69 6f 6e 29 0a 20  t:permutation). 
f300: 20 7d 0a 20 20 69 66 20 7b 5b 69 6e 66 6f 20 65   }.  if {[info e
f310: 78 69 73 74 73 20 3a 3a 47 28 73 74 61 72 74 3a  xists ::G(start:
f320: 66 69 6c 65 29 5d 7d 20 7b 0a 20 20 20 20 69 66  file)]} {.    if
f330: 20 7b 24 74 61 69 6c 20 21 3d 20 24 3a 3a 47 28   {$tail != $::G(
f340: 73 74 61 72 74 3a 66 69 6c 65 29 20 26 26 20 24  start:file) && $
f350: 74 61 69 6c 21 3d 22 24 3a 3a 47 28 73 74 61 72  tail!="$::G(star
f360: 74 3a 66 69 6c 65 29 2e 74 65 73 74 22 7d 20 72  t:file).test"} r
f370: 65 74 75 72 6e 0a 20 20 20 20 75 6e 73 65 74 20  eturn.    unset 
f380: 3a 3a 47 28 73 74 61 72 74 3a 66 69 6c 65 29 0a  ::G(start:file).
f390: 20 20 7d 0a 0a 20 20 23 20 52 65 6d 65 6d 62 65    }..  # Remembe
f3a0: 72 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74  r the value of t
f3b0: 68 65 20 73 68 61 72 65 64 2d 63 61 63 68 65 20  he shared-cache 
f3c0: 73 65 74 74 69 6e 67 2e 20 53 6f 20 74 68 61 74  setting. So that
f3d0: 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c 65 0a   it is possible.
f3e0: 20 20 23 20 74 6f 20 63 68 65 63 6b 20 61 66 74    # to check aft
f3f0: 65 72 77 61 72 64 73 20 74 68 61 74 20 69 74 20  erwards that it 
f400: 77 61 73 20 6e 6f 74 20 6d 6f 64 69 66 69 65 64  was not modified
f410: 20 62 79 20 74 68 65 20 74 65 73 74 20 73 63 72   by the test scr
f420: 69 70 74 2e 0a 20 20 23 0a 20 20 69 66 63 61 70  ipt..  #.  ifcap
f430: 61 62 6c 65 20 73 68 61 72 65 64 5f 63 61 63 68  able shared_cach
f440: 65 20 7b 20 73 65 74 20 73 63 73 20 5b 73 71 6c  e { set scs [sql
f450: 69 74 65 33 5f 65 6e 61 62 6c 65 5f 73 68 61 72  ite3_enable_shar
f460: 65 64 5f 63 61 63 68 65 5d 20 7d 0a 0a 20 20 23  ed_cache] }..  #
f470: 20 52 75 6e 20 74 68 65 20 74 65 73 74 20 73 63   Run the test sc
f480: 72 69 70 74 20 69 6e 20 61 20 73 6c 61 76 65 20  ript in a slave 
f490: 69 6e 74 65 72 70 72 65 74 65 72 2e 0a 20 20 23  interpreter..  #
f4a0: 0a 20 20 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70  .  unset -nocomp
f4b0: 6c 61 69 6e 20 3a 3a 72 75 6e 5f 74 68 72 65 61  lain ::run_threa
f4c0: 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65 64 0a 20  d_tests_called. 
f4d0: 20 72 65 73 65 74 5f 70 72 6e 67 5f 73 74 61 74   reset_prng_stat
f4e0: 65 0a 20 20 73 65 74 20 3a 3a 73 71 6c 69 74 65  e.  set ::sqlite
f4f0: 5f 6f 70 65 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74  _open_file_count
f500: 20 30 0a 20 20 73 65 74 20 74 69 6d 65 20 5b 74   0.  set time [t
f510: 69 6d 65 20 7b 20 73 6c 61 76 65 5f 74 65 73 74  ime { slave_test
f520: 5f 73 63 72 69 70 74 20 5b 6c 69 73 74 20 73 6f  _script [list so
f530: 75 72 63 65 20 24 7a 46 69 6c 65 5d 20 7d 5d 0a  urce $zFile] }].
f540: 20 20 73 65 74 20 6d 73 20 5b 65 78 70 72 20 5b    set ms [expr [
f550: 6c 69 6e 64 65 78 20 24 74 69 6d 65 20 30 5d 20  lindex $time 0] 
f560: 2f 20 31 30 30 30 5d 0a 0a 20 20 23 20 54 65 73  / 1000]..  # Tes
f570: 74 20 74 68 61 74 20 61 6c 6c 20 66 69 6c 65 73  t that all files
f580: 20 6f 70 65 6e 65 64 20 62 79 20 74 68 65 20 74   opened by the t
f590: 65 73 74 20 73 63 72 69 70 74 20 77 65 72 65 20  est script were 
f5a0: 63 6c 6f 73 65 64 2e 20 4f 6d 69 74 20 74 68 69  closed. Omit thi
f5b0: 73 0a 20 20 23 20 69 66 20 74 68 65 20 74 65 73  s.  # if the tes
f5c0: 74 20 73 63 72 69 70 74 20 68 61 73 20 22 74 68  t script has "th
f5d0: 72 65 61 64 22 20 69 6e 20 69 74 73 20 6e 61 6d  read" in its nam
f5e0: 65 2e 20 54 68 65 20 6f 70 65 6e 20 66 69 6c 65  e. The open file
f5f0: 20 63 6f 75 6e 74 65 72 0a 20 20 23 20 69 73 20   counter.  # is 
f600: 6e 6f 74 20 74 68 72 65 61 64 2d 73 61 66 65 2e  not thread-safe.
f610: 0a 20 20 23 0a 20 20 69 66 20 7b 5b 69 6e 66 6f  .  #.  if {[info
f620: 20 65 78 69 73 74 73 20 3a 3a 72 75 6e 5f 74 68   exists ::run_th
f630: 72 65 61 64 5f 74 65 73 74 73 5f 63 61 6c 6c 65  read_tests_calle
f640: 64 5d 3d 3d 30 7d 20 7b 0a 20 20 20 20 64 6f 5f  d]==0} {.    do_
f650: 74 65 73 74 20 24 7b 74 61 69 6c 7d 2d 63 6c 6f  test ${tail}-clo
f660: 73 65 61 6c 6c 66 69 6c 65 73 20 7b 20 65 78 70  seallfiles { exp
f670: 72 20 7b 24 3a 3a 73 71 6c 69 74 65 5f 6f 70 65  r {$::sqlite_ope
f680: 6e 5f 66 69 6c 65 5f 63 6f 75 6e 74 3e 30 7d 20  n_file_count>0} 
f690: 7d 20 7b 30 7d 0a 20 20 7d 0a 20 20 73 65 74 20  } {0}.  }.  set 
f6a0: 3a 3a 73 71 6c 69 74 65 5f 6f 70 65 6e 5f 66 69  ::sqlite_open_fi
f6b0: 6c 65 5f 63 6f 75 6e 74 20 30 0a 0a 20 20 23 20  le_count 0..  # 
f6c0: 54 65 73 74 20 74 68 61 74 20 74 68 65 20 67 6c  Test that the gl
f6d0: 6f 62 61 6c 20 22 73 68 61 72 65 64 2d 63 61 63  obal "shared-cac
f6e0: 68 65 22 20 73 65 74 74 69 6e 67 20 77 61 73 20  he" setting was 
f6f0: 6e 6f 74 20 61 6c 74 65 72 65 64 20 62 79 0a 20  not altered by. 
f700: 20 23 20 74 68 65 20 74 65 73 74 20 73 63 72 69   # the test scri
f710: 70 74 2e 0a 20 20 23 0a 20 20 69 66 63 61 70 61  pt..  #.  ifcapa
f720: 62 6c 65 20 73 68 61 72 65 64 5f 63 61 63 68 65  ble shared_cache
f730: 20 7b 0a 20 20 20 20 73 65 74 20 72 65 73 20 5b   {.    set res [
f740: 65 78 70 72 20 7b 5b 73 71 6c 69 74 65 33 5f 65  expr {[sqlite3_e
f750: 6e 61 62 6c 65 5f 73 68 61 72 65 64 5f 63 61 63  nable_shared_cac
f760: 68 65 5d 20 3d 3d 20 24 73 63 73 7d 5d 0a 20 20  he] == $scs}].  
f770: 20 20 64 6f 5f 74 65 73 74 20 24 7b 74 61 69 6c    do_test ${tail
f780: 7d 2d 73 68 61 72 65 64 63 61 63 68 65 73 65 74  }-sharedcacheset
f790: 74 69 6e 67 20 5b 6c 69 73 74 20 73 65 74 20 7b  ting [list set {
f7a0: 7d 20 24 72 65 73 5d 20 31 0a 20 20 7d 0a 0a 20  } $res] 1.  }.. 
f7b0: 20 23 20 41 64 64 20 73 6f 6d 65 20 69 6e 66 6f   # Add some info
f7c0: 20 74 6f 20 74 68 65 20 6f 75 74 70 75 74 2e 0a   to the output..
f7d0: 20 20 23 0a 20 20 6f 75 74 70 75 74 32 20 22 54    #.  output2 "T
f7e0: 69 6d 65 3a 20 24 74 61 69 6c 20 24 6d 73 20 6d  ime: $tail $ms m
f7f0: 73 22 0a 20 20 73 68 6f 77 5f 6d 65 6d 73 74 61  s".  show_memsta
f800: 74 73 0a 7d 0a 0a 23 20 4f 70 65 6e 20 61 20 6e  ts.}..# Open a n
f810: 65 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 6f 6e  ew connection on
f820: 20 64 61 74 61 62 61 73 65 20 74 65 73 74 2e 64   database test.d
f830: 62 20 61 6e 64 20 65 78 65 63 75 74 65 20 74 68  b and execute th
f840: 65 20 53 51 4c 20 73 63 72 69 70 74 0a 23 20 73  e SQL script.# s
f850: 75 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72  upplied as an ar
f860: 67 75 6d 65 6e 74 2e 20 42 65 66 6f 72 65 20 72  gument. Before r
f870: 65 74 75 72 6e 69 6e 67 2c 20 63 6c 6f 73 65 20  eturning, close 
f880: 74 68 65 20 6e 65 77 20 63 6f 6e 65 63 74 69 6f  the new conectio
f890: 6e 20 61 6e 64 0a 23 20 72 65 73 74 6f 72 65 20  n and.# restore 
f8a0: 74 68 65 20 34 20 62 79 74 65 20 66 69 65 6c 64  the 4 byte field
f8b0: 73 20 73 74 61 72 74 69 6e 67 20 61 74 20 68 65  s starting at he
f8c0: 61 64 65 72 20 6f 66 66 73 65 74 73 20 32 38 2c  ader offsets 28,
f8d0: 20 39 32 20 61 6e 64 20 39 36 0a 23 20 74 6f 20   92 and 96.# to 
f8e0: 74 68 65 20 76 61 6c 75 65 73 20 74 68 65 79 20  the values they 
f8f0: 68 65 6c 64 20 62 65 66 6f 72 65 20 74 68 65 20  held before the 
f900: 53 51 4c 20 77 61 73 20 65 78 65 63 75 74 65 64  SQL was executed
f910: 2e 20 54 68 69 73 20 73 69 6d 75 6c 61 74 65 73  . This simulates
f920: 0a 23 20 61 20 77 72 69 74 65 20 62 79 20 61 20  .# a write by a 
f930: 70 72 65 2d 33 2e 37 2e 30 20 63 6c 69 65 6e 74  pre-3.7.0 client
f940: 2e 0a 23 0a 70 72 6f 63 20 73 71 6c 33 36 32 33  ..#.proc sql3623
f950: 31 20 7b 73 71 6c 7d 20 7b 0a 20 20 73 65 74 20  1 {sql} {.  set 
f960: 42 20 5b 68 65 78 69 6f 5f 72 65 61 64 20 74 65  B [hexio_read te
f970: 73 74 2e 64 62 20 39 32 20 38 5d 0a 20 20 73 65  st.db 92 8].  se
f980: 74 20 41 20 5b 68 65 78 69 6f 5f 72 65 61 64 20  t A [hexio_read 
f990: 74 65 73 74 2e 64 62 20 32 38 20 34 5d 0a 20 20  test.db 28 4].  
f9a0: 73 71 6c 69 74 65 33 20 64 62 33 36 32 33 31 20  sqlite3 db36231 
f9b0: 74 65 73 74 2e 64 62 0a 20 20 63 61 74 63 68 20  test.db.  catch 
f9c0: 7b 20 64 62 33 36 32 33 31 20 66 75 6e 63 20 61  { db36231 func a
f9d0: 5f 73 74 72 69 6e 67 20 61 5f 73 74 72 69 6e 67  _string a_string
f9e0: 20 7d 0a 20 20 65 78 65 63 73 71 6c 20 24 73 71   }.  execsql $sq
f9f0: 6c 20 64 62 33 36 32 33 31 0a 20 20 64 62 33 36  l db36231.  db36
fa00: 32 33 31 20 63 6c 6f 73 65 0a 20 20 68 65 78 69  231 close.  hexi
fa10: 6f 5f 77 72 69 74 65 20 74 65 73 74 2e 64 62 20  o_write test.db 
fa20: 32 38 20 24 41 0a 20 20 68 65 78 69 6f 5f 77 72  28 $A.  hexio_wr
fa30: 69 74 65 20 74 65 73 74 2e 64 62 20 39 32 20 24  ite test.db 92 $
fa40: 42 0a 20 20 72 65 74 75 72 6e 20 22 22 0a 7d 0a  B.  return "".}.
fa50: 0a 70 72 6f 63 20 64 62 5f 73 61 76 65 20 7b 7d  .proc db_save {}
fa60: 20 7b 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b   {.  foreach f [
fa70: 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  glob -nocomplain
fa80: 20 73 76 5f 74 65 73 74 2e 64 62 2a 5d 20 7b 20   sv_test.db*] { 
fa90: 66 6f 72 63 65 64 65 6c 65 74 65 20 24 66 20 7d  forcedelete $f }
faa0: 0a 20 20 66 6f 72 65 61 63 68 20 66 20 5b 67 6c  .  foreach f [gl
fab0: 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 74  ob -nocomplain t
fac0: 65 73 74 2e 64 62 2a 5d 20 7b 0a 20 20 20 20 73  est.db*] {.    s
fad0: 65 74 20 66 32 20 22 73 76 5f 24 66 22 0a 20 20  et f2 "sv_$f".  
fae0: 20 20 66 6f 72 63 65 63 6f 70 79 20 24 66 20 24    forcecopy $f $
faf0: 66 32 0a 20 20 7d 0a 7d 0a 70 72 6f 63 20 64 62  f2.  }.}.proc db
fb00: 5f 73 61 76 65 5f 61 6e 64 5f 63 6c 6f 73 65 20  _save_and_close 
fb10: 7b 7d 20 7b 0a 20 20 64 62 5f 73 61 76 65 0a 20  {} {.  db_save. 
fb20: 20 63 61 74 63 68 20 7b 20 64 62 20 63 6c 6f 73   catch { db clos
fb30: 65 20 7d 0a 20 20 72 65 74 75 72 6e 20 22 22 0a  e }.  return "".
fb40: 7d 0a 70 72 6f 63 20 64 62 5f 72 65 73 74 6f 72  }.proc db_restor
fb50: 65 20 7b 7d 20 7b 0a 20 20 66 6f 72 65 61 63 68  e {} {.  foreach
fb60: 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70   f [glob -nocomp
fb70: 6c 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d 20 7b  lain test.db*] {
fb80: 20 66 6f 72 63 65 64 65 6c 65 74 65 20 24 66 20   forcedelete $f 
fb90: 7d 0a 20 20 66 6f 72 65 61 63 68 20 66 32 20 5b  }.  foreach f2 [
fba0: 67 6c 6f 62 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  glob -nocomplain
fbb0: 20 73 76 5f 74 65 73 74 2e 64 62 2a 5d 20 7b 0a   sv_test.db*] {.
fbc0: 20 20 20 20 73 65 74 20 66 20 5b 73 74 72 69 6e      set f [strin
fbd0: 67 20 72 61 6e 67 65 20 24 66 32 20 33 20 65 6e  g range $f2 3 en
fbe0: 64 5d 0a 20 20 20 20 66 6f 72 63 65 63 6f 70 79  d].    forcecopy
fbf0: 20 24 66 32 20 24 66 0a 20 20 7d 0a 7d 0a 70 72   $f2 $f.  }.}.pr
fc00: 6f 63 20 64 62 5f 72 65 73 74 6f 72 65 5f 61 6e  oc db_restore_an
fc10: 64 5f 72 65 6f 70 65 6e 20 7b 7b 64 62 66 69 6c  d_reopen {{dbfil
fc20: 65 20 74 65 73 74 2e 64 62 7d 7d 20 7b 0a 20 20  e test.db}} {.  
fc30: 63 61 74 63 68 20 7b 20 64 62 20 63 6c 6f 73 65  catch { db close
fc40: 20 7d 0a 20 20 64 62 5f 72 65 73 74 6f 72 65 0a   }.  db_restore.
fc50: 20 20 73 71 6c 69 74 65 33 20 64 62 20 24 64 62    sqlite3 db $db
fc60: 66 69 6c 65 0a 7d 0a 70 72 6f 63 20 64 62 5f 64  file.}.proc db_d
fc70: 65 6c 65 74 65 5f 61 6e 64 5f 72 65 6f 70 65 6e  elete_and_reopen
fc80: 20 7b 7b 66 69 6c 65 20 74 65 73 74 2e 64 62 7d   {{file test.db}
fc90: 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b 20 64 62  } {.  catch { db
fca0: 20 63 6c 6f 73 65 20 7d 0a 20 20 66 6f 72 65 61   close }.  forea
fcb0: 63 68 20 66 20 5b 67 6c 6f 62 20 2d 6e 6f 63 6f  ch f [glob -noco
fcc0: 6d 70 6c 61 69 6e 20 74 65 73 74 2e 64 62 2a 5d  mplain test.db*]
fcd0: 20 7b 20 66 6f 72 63 65 64 65 6c 65 74 65 20 24   { forcedelete $
fce0: 66 20 7d 0a 20 20 73 71 6c 69 74 65 33 20 64 62  f }.  sqlite3 db
fcf0: 20 24 66 69 6c 65 0a 7d 0a 0a 23 20 43 6c 6f 73   $file.}..# Clos
fd00: 65 20 61 6e 79 20 63 6f 6e 6e 65 63 74 69 6f 6e  e any connection
fd10: 73 20 6e 61 6d 65 64 20 5b 64 62 5d 2c 20 5b 64  s named [db], [d
fd20: 62 32 5d 20 6f 72 20 5b 64 62 33 5d 2e 20 54 68  b2] or [db3]. Th
fd30: 65 6e 20 75 73 65 20 73 71 6c 69 74 65 33 5f 63  en use sqlite3_c
fd40: 6f 6e 66 69 67 0a 23 20 74 6f 20 63 6f 6e 66 69  onfig.# to confi
fd50: 67 75 72 65 20 74 68 65 20 73 69 7a 65 20 6f 66  gure the size of
fd60: 20 74 68 65 20 50 41 47 45 43 41 43 48 45 20 61   the PAGECACHE a
fd70: 6c 6c 6f 63 61 74 69 6f 6e 20 75 73 69 6e 67 20  llocation using 
fd80: 74 68 65 20 70 61 72 61 6d 65 74 65 72 73 0a 23  the parameters.#
fd90: 20 70 72 6f 76 69 64 65 64 20 74 6f 20 74 68 69   provided to thi
fda0: 73 20 63 6f 6d 6d 61 6e 64 2e 20 53 61 76 65 20  s command. Save 
fdb0: 74 68 65 20 6f 6c 64 20 50 41 47 45 43 41 43 48  the old PAGECACH
fdc0: 45 20 70 61 72 61 6d 65 74 65 72 73 20 69 6e 20  E parameters in 
fdd0: 61 20 67 6c 6f 62 61 6c 20 0a 23 20 76 61 72 69  a global .# vari
fde0: 61 62 6c 65 20 73 6f 20 74 68 61 74 20 5b 74 65  able so that [te
fdf0: 73 74 5f 72 65 73 74 6f 72 65 5f 63 6f 6e 66 69  st_restore_confi
fe00: 67 5f 70 61 67 65 63 61 63 68 65 5d 20 63 61 6e  g_pagecache] can
fe10: 20 72 65 73 74 6f 72 65 20 74 68 65 20 70 72 65   restore the pre
fe20: 76 69 6f 75 73 0a 23 20 63 6f 6e 66 69 67 75 72  vious.# configur
fe30: 61 74 69 6f 6e 2e 0a 23 0a 23 20 42 65 66 6f 72  ation..#.# Befor
fe40: 65 20 72 65 74 75 72 6e 69 6e 67 2c 20 72 65 6f  e returning, reo
fe50: 70 65 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 5b  pen connection [
fe60: 64 62 5d 20 6f 6e 20 66 69 6c 65 20 74 65 73 74  db] on file test
fe70: 2e 64 62 2e 0a 23 0a 70 72 6f 63 20 74 65 73 74  .db..#.proc test
fe80: 5f 73 65 74 5f 63 6f 6e 66 69 67 5f 70 61 67 65  _set_config_page
fe90: 63 61 63 68 65 20 7b 73 7a 20 6e 50 67 7d 20 7b  cache {sz nPg} {
fea0: 0a 20 20 63 61 74 63 68 20 7b 64 62 20 63 6c 6f  .  catch {db clo
feb0: 73 65 7d 0a 20 20 63 61 74 63 68 20 7b 64 62 32  se}.  catch {db2
fec0: 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63 68 20   close}.  catch 
fed0: 7b 64 62 33 20 63 6c 6f 73 65 7d 0a 0a 20 20 73  {db3 close}..  s
fee0: 71 6c 69 74 65 33 5f 73 68 75 74 64 6f 77 6e 0a  qlite3_shutdown.
fef0: 20 20 73 65 74 20 3a 3a 6f 6c 64 5f 70 61 67 65    set ::old_page
ff00: 63 61 63 68 65 5f 63 6f 6e 66 69 67 20 5b 73 71  cache_config [sq
ff10: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 5f 70 61 67  lite3_config_pag
ff20: 65 63 61 63 68 65 20 24 73 7a 20 24 6e 50 67 5d  ecache $sz $nPg]
ff30: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 69 74 69  .  sqlite3_initi
ff40: 61 6c 69 7a 65 0a 20 20 61 75 74 6f 69 6e 73 74  alize.  autoinst
ff50: 61 6c 6c 5f 74 65 73 74 5f 66 75 6e 63 74 69 6f  all_test_functio
ff60: 6e 73 0a 20 20 72 65 73 65 74 5f 64 62 0a 7d 0a  ns.  reset_db.}.
ff70: 0a 23 20 43 6c 6f 73 65 20 61 6e 79 20 63 6f 6e  .# Close any con
ff80: 6e 65 63 74 69 6f 6e 73 20 6e 61 6d 65 64 20 5b  nections named [
ff90: 64 62 5d 2c 20 5b 64 62 32 5d 20 6f 72 20 5b 64  db], [db2] or [d
ffa0: 62 33 5d 2e 20 54 68 65 6e 20 75 73 65 20 73 71  b3]. Then use sq
ffb0: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 0a 23 20 74  lite3_config.# t
ffc0: 6f 20 63 6f 6e 66 69 67 75 72 65 20 74 68 65 20  o configure the 
ffd0: 73 69 7a 65 20 6f 66 20 74 68 65 20 50 41 47 45  size of the PAGE
ffe0: 43 41 43 48 45 20 61 6c 6c 6f 63 61 74 69 6f 6e  CACHE allocation
fff0: 20 74 6f 20 74 68 65 20 73 69 7a 65 20 73 61 76   to the size sav
10000 65 64 20 69 6e 0a 23 20 74 68 65 20 67 6c 6f 62  ed in.# the glob
10010 61 6c 20 76 61 72 69 61 62 6c 65 20 62 79 20 61  al variable by a
10020 6e 20 65 61 72 6c 69 65 72 20 63 61 6c 6c 20 74  n earlier call t
10030 6f 20 5b 74 65 73 74 5f 73 65 74 5f 63 6f 6e 66  o [test_set_conf
10040 69 67 5f 70 61 67 65 63 61 63 68 65 5d 2e 0a 23  ig_pagecache]..#
10050 0a 23 20 42 65 66 6f 72 65 20 72 65 74 75 72 6e  .# Before return
10060 69 6e 67 2c 20 72 65 6f 70 65 6e 20 63 6f 6e 6e  ing, reopen conn
10070 65 63 74 69 6f 6e 20 5b 64 62 5d 20 6f 6e 20 66  ection [db] on f
10080 69 6c 65 20 74 65 73 74 2e 64 62 2e 0a 23 0a 70  ile test.db..#.p
10090 72 6f 63 20 74 65 73 74 5f 72 65 73 74 6f 72 65  roc test_restore
100a0 5f 63 6f 6e 66 69 67 5f 70 61 67 65 63 61 63 68  _config_pagecach
100b0 65 20 7b 7d 20 7b 0a 20 20 63 61 74 63 68 20 7b  e {} {.  catch {
100c0 64 62 20 63 6c 6f 73 65 7d 0a 20 20 63 61 74 63  db close}.  catc
100d0 68 20 7b 64 62 32 20 63 6c 6f 73 65 7d 0a 20 20  h {db2 close}.  
100e0 63 61 74 63 68 20 7b 64 62 33 20 63 6c 6f 73 65  catch {db3 close
100f0 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 73 68 75  }..  sqlite3_shu
10100 74 64 6f 77 6e 0a 20 20 65 76 61 6c 20 73 71 6c  tdown.  eval sql
10110 69 74 65 33 5f 63 6f 6e 66 69 67 5f 70 61 67 65  ite3_config_page
10120 63 61 63 68 65 20 24 3a 3a 6f 6c 64 5f 70 61 67  cache $::old_pag
10130 65 63 61 63 68 65 5f 63 6f 6e 66 69 67 0a 20 20  ecache_config.  
10140 75 6e 73 65 74 20 3a 3a 6f 6c 64 5f 70 61 67 65  unset ::old_page
10150 63 61 63 68 65 5f 63 6f 6e 66 69 67 20 0a 20 20  cache_config .  
10160 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69  sqlite3_initiali
10170 7a 65 0a 20 20 61 75 74 6f 69 6e 73 74 61 6c 6c  ze.  autoinstall
10180 5f 74 65 73 74 5f 66 75 6e 63 74 69 6f 6e 73 0a  _test_functions.
10190 20 20 73 71 6c 69 74 65 33 20 64 62 20 74 65 73    sqlite3 db tes
101a0 74 2e 64 62 0a 7d 0a 0a 70 72 6f 63 20 74 65 73  t.db.}..proc tes
101b0 74 5f 66 69 6e 64 5f 62 69 6e 61 72 79 20 7b 6e  t_find_binary {n
101c0 6d 7d 20 7b 0a 20 20 69 66 20 7b 24 3a 3a 74 63  m} {.  if {$::tc
101d0 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66  l_platform(platf
101e0 6f 72 6d 29 3d 3d 22 77 69 6e 64 6f 77 73 22 7d  orm)=="windows"}
101f0 20 7b 0a 20 20 20 20 73 65 74 20 72 65 74 20 22   {.    set ret "
10200 24 6e 6d 2e 65 78 65 22 0a 20 20 7d 20 65 6c 73  $nm.exe".  } els
10210 65 20 7b 0a 20 20 20 20 73 65 74 20 72 65 74 20  e {.    set ret 
10220 24 6e 6d 0a 20 20 7d 0a 20 20 73 65 74 20 72 65  $nm.  }.  set re
10230 74 20 5b 66 69 6c 65 20 6e 6f 72 6d 61 6c 69 7a  t [file normaliz
10240 65 20 5b 66 69 6c 65 20 6a 6f 69 6e 20 24 3a 3a  e [file join $::
10250 63 6d 64 6c 69 6e 65 61 72 67 28 54 45 53 54 46  cmdlinearg(TESTF
10260 49 58 54 55 52 45 5f 48 4f 4d 45 29 20 24 72 65  IXTURE_HOME) $re
10270 74 5d 5d 0a 20 20 69 66 20 7b 21 5b 66 69 6c 65  t]].  if {![file
10280 20 65 78 65 63 75 74 61 62 6c 65 20 24 72 65 74   executable $ret
10290 5d 7d 20 7b 0a 20 20 20 20 66 69 6e 69 73 68 5f  ]} {.    finish_
102a0 74 65 73 74 0a 20 20 20 20 72 65 74 75 72 6e 20  test.    return 
102b0 22 22 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  "".  }.  return 
102c0 24 72 65 74 0a 7d 0a 0a 23 20 46 69 6e 64 20 74  $ret.}..# Find t
102d0 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 27  he name of the '
102e0 73 68 65 6c 6c 27 20 65 78 65 63 75 74 61 62 6c  shell' executabl
102f0 65 20 28 65 2e 67 2e 20 22 73 71 6c 69 74 65 33  e (e.g. "sqlite3
10300 2e 65 78 65 22 29 20 74 6f 20 75 73 65 20 66 6f  .exe") to use fo
10310 72 0a 23 20 74 68 65 20 74 65 73 74 73 20 69 6e  r.# the tests in
10320 20 73 68 65 6c 6c 5b 31 2d 35 5d 2e 74 65 73 74   shell[1-5].test
10330 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 65 78 65  . If no such exe
10340 63 75 74 61 62 6c 65 20 63 61 6e 20 62 65 20 66  cutable can be f
10350 6f 75 6e 64 2c 20 69 6e 76 6f 6b 65 0a 23 20 5b  ound, invoke.# [
10360 66 69 6e 69 73 68 5f 74 65 73 74 20 3b 20 72 65  finish_test ; re
10370 74 75 72 6e 5d 20 69 6e 20 74 68 65 20 63 61 6c  turn] in the cal
10380 6c 65 72 73 20 63 6f 6e 74 65 78 74 2e 0a 23 0a  lers context..#.
10390 70 72 6f 63 20 74 65 73 74 5f 66 69 6e 64 5f 63  proc test_find_c
103a0 6c 69 20 7b 7d 20 7b 0a 20 20 73 65 74 20 70 72  li {} {.  set pr
103b0 6f 67 20 5b 74 65 73 74 5f 66 69 6e 64 5f 62 69  og [test_find_bi
103c0 6e 61 72 79 20 73 71 6c 69 74 65 33 5d 0a 20 20  nary sqlite3].  
103d0 69 66 20 7b 24 70 72 6f 67 3d 3d 22 22 7d 20 7b  if {$prog==""} {
103e0 20 72 65 74 75 72 6e 20 2d 63 6f 64 65 20 72 65   return -code re
103f0 74 75 72 6e 20 7d 0a 20 20 72 65 74 75 72 6e 20  turn }.  return 
10400 24 70 72 6f 67 0a 7d 0a 0a 23 20 46 69 6e 64 20  $prog.}..# Find 
10410 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20  the name of the 
10420 27 73 71 6c 64 69 66 66 27 20 65 78 65 63 75 74  'sqldiff' execut
10430 61 62 6c 65 20 28 65 2e 67 2e 20 22 73 71 6c 69  able (e.g. "sqli
10440 74 65 33 2e 65 78 65 22 29 20 74 6f 20 75 73 65  te3.exe") to use
10450 20 66 6f 72 0a 23 20 74 68 65 20 74 65 73 74 73   for.# the tests
10460 20 69 6e 20 73 71 6c 64 69 66 66 20 74 65 73 74   in sqldiff test
10470 73 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 65 78  s. If no such ex
10480 65 63 75 74 61 62 6c 65 20 63 61 6e 20 62 65 20  ecutable can be 
10490 66 6f 75 6e 64 2c 20 69 6e 76 6f 6b 65 0a 23 20  found, invoke.# 
104a0 5b 66 69 6e 69 73 68 5f 74 65 73 74 20 3b 20 72  [finish_test ; r
104b0 65 74 75 72 6e 5d 20 69 6e 20 74 68 65 20 63 61  eturn] in the ca
104c0 6c 6c 65 72 73 20 63 6f 6e 74 65 78 74 2e 0a 23  llers context..#
104d0 0a 70 72 6f 63 20 74 65 73 74 5f 66 69 6e 64 5f  .proc test_find_
104e0 73 71 6c 64 69 66 66 20 7b 7d 20 7b 0a 20 20 73  sqldiff {} {.  s
104f0 65 74 20 70 72 6f 67 20 5b 74 65 73 74 5f 66 69  et prog [test_fi
10500 6e 64 5f 62 69 6e 61 72 79 20 73 71 6c 64 69 66  nd_binary sqldif
10510 66 5d 0a 20 20 69 66 20 7b 24 70 72 6f 67 3d 3d  f].  if {$prog==
10520 22 22 7d 20 7b 20 72 65 74 75 72 6e 20 2d 63 6f  ""} { return -co
10530 64 65 20 72 65 74 75 72 6e 20 7d 0a 20 20 72 65  de return }.  re
10540 74 75 72 6e 20 24 70 72 6f 67 0a 7d 0a 0a 0a 23  turn $prog.}...#
10550 20 49 66 20 74 68 65 20 6c 69 62 72 61 72 79 20   If the library 
10560 69 73 20 63 6f 6d 70 69 6c 65 64 20 77 69 74 68  is compiled with
10570 20 74 68 65 20 53 51 4c 49 54 45 5f 44 45 46 41   the SQLITE_DEFA
10580 55 4c 54 5f 41 55 54 4f 56 41 43 55 55 4d 20 6d  ULT_AUTOVACUUM m
10590 61 63 72 6f 20 73 65 74 0a 23 20 74 6f 20 6e 6f  acro set.# to no
105a0 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 73 65 74  n-zero, then set
105b0 20 74 68 65 20 67 6c 6f 62 61 6c 20 76 61 72 69   the global vari
105c0 61 62 6c 65 20 24 41 55 54 4f 56 41 43 55 55 4d  able $AUTOVACUUM
105d0 20 74 6f 20 31 2e 0a 73 65 74 20 41 55 54 4f 56   to 1..set AUTOV
105e0 41 43 55 55 4d 20 24 73 71 6c 69 74 65 5f 6f 70  ACUUM $sqlite_op
105f0 74 69 6f 6e 73 28 64 65 66 61 75 6c 74 5f 61 75  tions(default_au
10600 74 6f 76 61 63 75 75 6d 29 0a 0a 23 20 4d 61 6b  tovacuum)..# Mak
10610 65 20 73 75 72 65 20 74 68 65 20 46 54 53 20 65  e sure the FTS e
10620 6e 68 61 6e 63 65 64 20 71 75 65 72 79 20 73 79  nhanced query sy
10630 6e 74 61 78 20 69 73 20 64 69 73 61 62 6c 65 64  ntax is disabled
10640 2e 0a 73 65 74 20 73 71 6c 69 74 65 5f 66 74 73  ..set sqlite_fts
10650 33 5f 65 6e 61 62 6c 65 5f 70 61 72 65 6e 74 68  3_enable_parenth
10660 65 73 65 73 20 30 0a 0a 23 20 44 75 72 69 6e 67  eses 0..# During
10670 20 74 65 73 74 69 6e 67 2c 20 61 73 73 75 6d 65   testing, assume
10680 20 74 68 61 74 20 61 6c 6c 20 64 61 74 61 62 61   that all databa
10690 73 65 20 66 69 6c 65 73 20 61 72 65 20 77 65 6c  se files are wel
106a0 6c 2d 66 6f 72 6d 65 64 2e 20 20 54 68 65 0a 23  l-formed.  The.#
106b0 20 66 65 77 20 74 65 73 74 20 63 61 73 65 73 20   few test cases 
106c0 74 68 61 74 20 64 65 6c 69 62 65 72 61 74 65 6c  that deliberatel
106d0 79 20 63 6f 72 72 75 70 74 20 64 61 74 61 62 61  y corrupt databa
106e0 73 65 20 66 69 6c 65 73 20 73 68 6f 75 6c 64 20  se files should 
106f0 72 65 73 63 69 6e 64 20 0a 23 20 74 68 69 73 20  rescind .# this 
10700 73 65 74 74 69 6e 67 20 62 79 20 69 6e 76 6f 6b  setting by invok
10710 69 6e 67 20 22 64 61 74 61 62 61 73 65 5f 63 61  ing "database_ca
10720 6e 5f 62 65 5f 63 6f 72 72 75 70 74 22 0a 23 0a  n_be_corrupt".#.
10730 64 61 74 61 62 61 73 65 5f 6e 65 76 65 72 5f 63  database_never_c
10740 6f 72 72 75 70 74 0a 0a 73 6f 75 72 63 65 20 24  orrupt..source $
10750 74 65 73 74 64 69 72 2f 74 68 72 65 61 64 5f 63  testdir/thread_c
10760 6f 6d 6d 6f 6e 2e 74 63 6c 0a 73 6f 75 72 63 65  ommon.tcl.source
10770 20 24 74 65 73 74 64 69 72 2f 6d 61 6c 6c 6f 63   $testdir/malloc
10780 5f 63 6f 6d 6d 6f 6e 2e 74 63 6c 0a              _common.tcl.